Module | Sequel::MySQL::DatasetMethods
In: | lib/sequel/adapters/shared/mysql.rb

Dataset methods shared by datasets that use MySQL databases.

### Methods

complex_expression_sql delete_sql distinct full_text_search full_text_sql having insert_default_values_sql insert_ignore join_table join_type_sql multi_insert_sql on_duplicate_key_update quoted_identifier replace_sql update_sql

### Included Modules

Dataset::UnsupportedIntersectExcept

### Constants

BOOL_TRUE | = | '1'.freeze
BOOL_FALSE | = | '0'.freeze
TIMESTAMP_FORMAT | = | "'%Y-%m-%d %H:%M:%S'".freeze
COMMA_SEPARATOR | = | ', '.freeze

### Public Instance methods

complex_expression_sql(op, args)

MySQL specific syntax for LIKE/REGEXP searches, as well as string concatenation.

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 197
    197:       def complex_expression_sql(op, args)
    198:         case op
    199:         when :~, '!~''!~', '~*''~*', '!~*''!~*', :LIKE, 'NOT LIKE''NOT LIKE', :ILIKE, 'NOT ILIKE''NOT ILIKE'
    200:           "(#{literal(args.at(0))} #{'NOT ' if [:'NOT LIKE', :'NOT ILIKE', :'!~', :'!~*'].include?(op)}#{[:~, :'!~', :'~*', :'!~*'].include?(op) ? 'REGEXP' : 'LIKE'} #{'BINARY ' if [:~, :'!~', :LIKE, :'NOT LIKE'].include?(op)}#{literal(args.at(1))})"
    201:         when '||''||'
    202:           if args.length > 1
    203:             "CONCAT(#{args.collect{|a| literal(a)}.join(', ')})"
    204:           else
    205:             literal(args.at(0))
    206:           end
    207:         else
    208:           super(op, args)
    209:         end
    210:       end

delete_sql()

MySQL supports ORDER and LIMIT clauses in DELETE statements.

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 213
    213:       def delete_sql
    214:         sql = super
    215:         sql << " ORDER BY #{expression_list(opts[:order])}" if opts[:order]
    216:         sql << " LIMIT #{opts[:limit]}" if opts[:limit]
    217:         sql
    218:       end

distinct(*columns)

MySQL doesn‘t support DISTINCT ON

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 221
    221:       def distinct(*columns)
    222:         raise(Error, "DISTINCT ON not supported by MySQL") unless columns.empty?
    223:         super
    224:       end

full_text_search(cols, terms, opts = {})

Adds full text filter

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 227
    227:       def full_text_search(cols, terms, opts = {})
    228:         filter(full_text_sql(cols, terms, opts))
    229:       end

full_text_sql(cols, term, opts = {})

MySQL specific full text search syntax.

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 232
    232:       def full_text_sql(cols, term, opts = {})
    233:         "MATCH #{literal(Array(cols))} AGAINST (#{literal(Array(term).join(' '))}#{" IN BOOLEAN MODE" if opts[:boolean]})"
    234:       end

having(*cond, &block)

MySQL allows HAVING clause on ungrouped datasets.

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 237
    237:       def having(*cond, &block)
    238:         _filter(:having, *cond, &block)
    239:       end

insert_default_values_sql()

MySQL doesn‘t use the SQL standard DEFAULT VALUES.

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 242
    242:       def insert_default_values_sql
    243:         "INSERT INTO #{source_list(@opts[:from])} () VALUES ()"
    244:       end

insert_ignore()

Sets up multi_insert or import to use INSERT IGNORE. Useful if you have a unique key and want to just skip inserting rows that violate the unique key restriction.

Example:

dataset.insert_ignore.multi_insert(

     [{:name => 'a', :value => 1}, {:name => 'b', :value => 2}]

)

INSERT IGNORE INTO tablename (name, value) VALUES (a, 1), (b, 2)

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 276
    276:       def insert_ignore
    277:         clone(:insert_ignore=>true)
    278:       end

join_table(type, table, expr=nil, table_alias={})

Transforms an CROSS JOIN to an INNER JOIN if the expr is not nil. Raises an error on use of :full_outer type, since MySQL doesn‘t support it.

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 248
    248:       def join_table(type, table, expr=nil, table_alias={})
    249:         type = :inner if (type == :cross) && !expr.nil?
    250:         raise(Sequel::Error, "MySQL doesn't support FULL OUTER JOIN") if type == :full_outer
    251:         super(type, table, expr, table_alias)
    252:       end

join_type_sql(join_type)

Transforms :natural_inner to NATURAL LEFT JOIN and straight to STRAIGHT_JOIN.

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 256
    256:       def join_type_sql(join_type)
    257:         case join_type
    258:         when :straight then 'STRAIGHT_JOIN'
    259:         when :natural_inner then 'NATURAL LEFT JOIN'
    260:         else super
    261:         end
    262:       end

multi_insert_sql(columns, values)

MySQL specific syntax for inserting multiple values at once.

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 309
    309:       def multi_insert_sql(columns, values)
    310:         if update_cols = opts[:on_duplicate_key_update]
    311:           update_cols = columns if update_cols.empty?
    312:           update_string = update_cols.map{|c| "#{quote_identifier(c)}=VALUES(#{quote_identifier(c)})"}.join(COMMA_SEPARATOR)
    313:         end
    314:         values = values.map {|r| literal(Array(r))}.join(COMMA_SEPARATOR)
    315:         ["INSERT#{' IGNORE' if opts[:insert_ignore]} INTO #{source_list(@opts[:from])} (#{identifier_list(columns)}) VALUES #{values}#{" ON DUPLICATE KEY UPDATE #{update_string}" if update_string}"]
    316:       end

on_duplicate_key_update(*args)

Sets up multi_insert or import to use ON DUPLICATE KEY UPDATE If you pass no arguments, ALL fields will be updated with the new values. If you pass the fields you want then ONLY those field will be updated.

Useful if you have a unique key and want to update inserting rows that violate the unique key restriction.

Examples:

dataset.on_duplicate_key_update.multi_insert(

     [{:name => 'a', :value => 1}, {:name => 'b', :value => 2}]

)

INSERT INTO tablename (name, value) VALUES (a, 1), (b, 2) ON DUPLICATE KEY UPDATE name=VALUES(name), value=VALUES(value)

dataset.on_duplicate_key_update(:value).multi_insert(

     [{:name => 'a', :value => 1}, {:name => 'b', :value => 2}]

)

INSERT INTO tablename (name, value) VALUES (a, 1), (b, 2) ON DUPLICATE KEY UPDATE value=VALUES(value)

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 304
    304:       def on_duplicate_key_update(*args)
    305:         clone(:on_duplicate_key_update => args)
    306:       end

quoted_identifier(c)

MySQL uses the nonstandard ` (backtick) for quoting identifiers.

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 319
    319:       def quoted_identifier(c)
    320:         "`#{c}`"
    321:       end

replace_sql(*values)

MySQL specific syntax for REPLACE (aka UPSERT, or update if exists, insert if it doesn‘t).

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 325
    325:       def replace_sql(*values)
    326:         from = source_list(@opts[:from])
    327:         if values.empty?
    328:           "REPLACE INTO #{from} DEFAULT VALUES"
    329:         else
    330:           values = values[0] if values.size == 1
    331:
    332:           case values
    333:           when Array
    334:             if values.empty?
    335:               "REPLACE INTO #{from} DEFAULT VALUES"
    336:             else
    337:               "REPLACE INTO #{from} VALUES #{literal(values)}"
    338:             end
    339:           when Hash
    340:             if values.empty?
    341:               "REPLACE INTO #{from} DEFAULT VALUES"
    342:             else
    343:               fl, vl = [], []
    344:               values.each {|k, v| fl << literal(k.is_a?(String) ? k.to_sym : k); vl << literal(v)}
    345:               "REPLACE INTO #{from} (#{fl.join(COMMA_SEPARATOR)}) VALUES (#{vl.join(COMMA_SEPARATOR)})"
    346:             end
    347:           when Dataset
    348:             "REPLACE INTO #{from} #{literal(values)}"
    349:           else
    350:             if values.respond_to?(:values)
    351:               replace_sql(values.values)
    352:             else
    353:               "REPLACE INTO #{from} VALUES (#{literal(values)})"
    354:             end
    355:           end
    356:         end
    357:       end

update_sql(values)

MySQL supports ORDER and LIMIT clauses in UPDATE statements.

[Source]

         # File lib/sequel/adapters/shared/mysql.rb, line 360
    360:       def update_sql(values)
    361:         sql = super
    362:         sql << " ORDER BY #{expression_list(opts[:order])}" if opts[:order]
    363:         sql << " LIMIT #{opts[:limit]}" if opts[:limit]
    364:         sql
    365:       end

[Validate]