litestack 0.3.0 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.standard.yml +3 -0
  3. data/BENCHMARKS.md +34 -7
  4. data/CHANGELOG.md +21 -0
  5. data/Gemfile +1 -5
  6. data/Gemfile.lock +92 -0
  7. data/README.md +120 -6
  8. data/ROADMAP.md +45 -0
  9. data/Rakefile +3 -1
  10. data/WHYLITESTACK.md +1 -1
  11. data/assets/litecache_metrics.png +0 -0
  12. data/assets/litedb_metrics.png +0 -0
  13. data/assets/litemetric_logo_teal.png +0 -0
  14. data/assets/litesearch_logo_teal.png +0 -0
  15. data/bench/bench.rb +17 -10
  16. data/bench/bench_cache_rails.rb +10 -13
  17. data/bench/bench_cache_raw.rb +17 -22
  18. data/bench/bench_jobs_rails.rb +19 -13
  19. data/bench/bench_jobs_raw.rb +17 -10
  20. data/bench/bench_queue.rb +4 -6
  21. data/bench/rails_job.rb +5 -7
  22. data/bench/skjob.rb +4 -4
  23. data/bench/uljob.rb +6 -6
  24. data/lib/action_cable/subscription_adapter/litecable.rb +5 -8
  25. data/lib/active_job/queue_adapters/litejob_adapter.rb +6 -8
  26. data/lib/active_record/connection_adapters/litedb_adapter.rb +65 -75
  27. data/lib/active_support/cache/litecache.rb +38 -41
  28. data/lib/generators/litestack/install/install_generator.rb +3 -3
  29. data/lib/generators/litestack/install/templates/database.yml +7 -1
  30. data/lib/litestack/liteboard/liteboard.rb +269 -149
  31. data/lib/litestack/litecable.rb +44 -40
  32. data/lib/litestack/litecable.sql.yml +22 -11
  33. data/lib/litestack/litecache.rb +80 -89
  34. data/lib/litestack/litecache.sql.yml +81 -22
  35. data/lib/litestack/litecache.yml +1 -1
  36. data/lib/litestack/litedb.rb +39 -38
  37. data/lib/litestack/litejob.rb +31 -31
  38. data/lib/litestack/litejobqueue.rb +107 -106
  39. data/lib/litestack/litemetric.rb +83 -95
  40. data/lib/litestack/litemetric.sql.yml +244 -234
  41. data/lib/litestack/litemetric_collector.sql.yml +38 -41
  42. data/lib/litestack/litequeue.rb +39 -41
  43. data/lib/litestack/litequeue.sql.yml +39 -31
  44. data/lib/litestack/litescheduler.rb +84 -0
  45. data/lib/litestack/litesearch/index.rb +260 -0
  46. data/lib/litestack/litesearch/model.rb +179 -0
  47. data/lib/litestack/litesearch/schema.rb +190 -0
  48. data/lib/litestack/litesearch/schema_adapters/backed_adapter.rb +143 -0
  49. data/lib/litestack/litesearch/schema_adapters/basic_adapter.rb +137 -0
  50. data/lib/litestack/litesearch/schema_adapters/contentless_adapter.rb +14 -0
  51. data/lib/litestack/litesearch/schema_adapters/standalone_adapter.rb +31 -0
  52. data/lib/litestack/litesearch/schema_adapters.rb +4 -0
  53. data/lib/litestack/litesearch.rb +34 -0
  54. data/lib/litestack/litesupport.rb +85 -186
  55. data/lib/litestack/railtie.rb +1 -1
  56. data/lib/litestack/version.rb +2 -2
  57. data/lib/litestack.rb +7 -4
  58. data/lib/railties/rails/commands/dbconsole.rb +11 -15
  59. data/lib/sequel/adapters/litedb.rb +18 -22
  60. data/lib/sequel/adapters/shared/litedb.rb +168 -168
  61. data/scripts/build_metrics.rb +91 -0
  62. data/scripts/test_cable.rb +30 -0
  63. data/scripts/test_job_retry.rb +33 -0
  64. data/scripts/test_metrics.rb +60 -0
  65. data/template.rb +2 -2
  66. metadata +112 -7
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- require_relative '../utils/replace'
4
- require_relative '../utils/unmodified_identifiers'
3
+ require_relative "../utils/replace"
4
+ require_relative "../utils/unmodified_identifiers"
5
5
 
6
6
  module Sequel
7
7
  module Litedb
@@ -17,7 +17,7 @@ module Sequel
17
17
  singleton_class.send(:private, :schema_parse_table)
18
18
  end
19
19
  end
20
-
20
+
21
21
  # No matter how you connect to SQLite, the following Database options
22
22
  # can be used to set PRAGMAs on connections in a thread-safe manner:
23
23
  # :auto_vacuum, :foreign_keys, :synchronous, and :temp_store.
@@ -28,10 +28,10 @@ module Sequel
28
28
  SYNCHRONOUS = [:off, :normal, :full].freeze
29
29
  TEMP_STORE = [:default, :file, :memory].freeze
30
30
  TRANSACTION_MODE = {
31
- :deferred => "BEGIN DEFERRED TRANSACTION".freeze,
32
- :immediate => "BEGIN IMMEDIATE TRANSACTION".freeze,
33
- :exclusive => "BEGIN EXCLUSIVE TRANSACTION".freeze,
34
- nil => "BEGIN".freeze
31
+ :deferred => "BEGIN DEFERRED TRANSACTION",
32
+ :immediate => "BEGIN IMMEDIATE TRANSACTION",
33
+ :exclusive => "BEGIN EXCLUSIVE TRANSACTION",
34
+ nil => "BEGIN"
35
35
  }.freeze
36
36
 
37
37
  # Whether to use integers for booleans in the database. SQLite recommends
@@ -58,7 +58,7 @@ module Sequel
58
58
  def database_type
59
59
  :litedb
60
60
  end
61
-
61
+
62
62
  # Set the integer_booleans option using the passed in :integer_boolean option.
63
63
  def set_integer_booleans
64
64
  @integer_booleans = @opts.has_key?(:integer_booleans) ? typecast_value_boolean(@opts[:integer_booleans]) : true
@@ -66,15 +66,15 @@ module Sequel
66
66
 
67
67
  # Return the array of foreign key info hashes using the foreign_key_list PRAGMA,
68
68
  # including information for the :on_update and :on_delete entries.
69
- def foreign_key_list(table, opts=OPTS)
69
+ def foreign_key_list(table, opts = OPTS)
70
70
  m = output_identifier_meth
71
71
  h = {}
72
72
  _foreign_key_list_ds(table).each do |row|
73
- if r = h[row[:id]]
73
+ if (r = h[row[:id]])
74
74
  r[:columns] << m.call(row[:from])
75
75
  r[:key] << m.call(row[:to]) if r[:key]
76
76
  else
77
- h[row[:id]] = {:columns=>[m.call(row[:from])], :table=>m.call(row[:table]), :key=>([m.call(row[:to])] if row[:to]), :on_update=>on_delete_sql_to_sym(row[:on_update]), :on_delete=>on_delete_sql_to_sym(row[:on_delete])}
77
+ h[row[:id]] = {columns: [m.call(row[:from])], table: m.call(row[:table]), key: ([m.call(row[:to])] if row[:to]), on_update: on_delete_sql_to_sym(row[:on_update]), on_delete: on_delete_sql_to_sym(row[:on_delete])}
78
78
  end
79
79
  end
80
80
  h.values
@@ -87,7 +87,7 @@ module Sequel
87
87
  end
88
88
 
89
89
  # Use the index_list and index_info PRAGMAs to determine the indexes on the table.
90
- def indexes(table, opts=OPTS)
90
+ def indexes(table, opts = OPTS)
91
91
  m = output_identifier_meth
92
92
  im = input_identifier_meth
93
93
  indexes = {}
@@ -95,20 +95,20 @@ module Sequel
95
95
  metadata_dataset.with_sql("PRAGMA index_list(?)", im.call(table)).each do |r|
96
96
  if opts[:only_autocreated]
97
97
  # If specifically asked for only autocreated indexes, then return those an only those
98
- next unless r[:name] =~ /\Asqlite_autoindex_/
98
+ next unless r[:name].start_with?("sqlite_autoindex_")
99
99
  elsif r.has_key?(:origin)
100
100
  # If origin is set, then only exclude primary key indexes and partial indexes
101
- next if r[:origin] == 'pk'
101
+ next if r[:origin] == "pk"
102
102
  next if r[:partial].to_i == 1
103
- else
104
- # When :origin key not present, assume any autoindex could be a primary key one and exclude it
105
- next if r[:name] =~ /\Asqlite_autoindex_/
103
+ elsif r[:name].start_with?("sqlite_autoindex_")
104
+ next
106
105
  end
106
+ # When :origin key not present, assume any autoindex could be a primary key one and exclude it
107
107
 
108
- indexes[m.call(r[:name])] = {:unique=>r[:unique].to_i==1}
108
+ indexes[m.call(r[:name])] = {unique: r[:unique].to_i == 1}
109
109
  end
110
110
  indexes.each do |k, v|
111
- v[:columns] = metadata_dataset.with_sql("PRAGMA index_info(?)", im.call(k)).map(:name).map{|x| m.call(x)}
111
+ v[:columns] = metadata_dataset.with_sql("PRAGMA index_info(?)", im.call(k)).map(:name).map { |x| m.call(x) }
112
112
  end
113
113
  indexes
114
114
  end
@@ -118,18 +118,18 @@ module Sequel
118
118
  def sqlite_version
119
119
  return @sqlite_version if defined?(@sqlite_version)
120
120
  @sqlite_version = begin
121
- v = fetch('SELECT sqlite_version()').single_value
122
- [10000, 100, 1].zip(v.split('.')).inject(0){|a, m| a + m[0] * Integer(m[1])}
121
+ v = fetch("SELECT sqlite_version()").single_value
122
+ [10000, 100, 1].zip(v.split(".")).inject(0) { |a, m| a + m[0] * Integer(m[1]) }
123
123
  rescue
124
124
  0
125
125
  end
126
126
  end
127
-
127
+
128
128
  # SQLite supports CREATE TABLE IF NOT EXISTS syntax since 3.3.0.
129
129
  def supports_create_table_if_not_exists?
130
130
  sqlite_version >= 30300
131
131
  end
132
-
132
+
133
133
  # SQLite 3.6.19+ supports deferrable foreign key constraints.
134
134
  def supports_deferrable_foreign_key_constraints?
135
135
  sqlite_version >= 30619
@@ -140,7 +140,7 @@ module Sequel
140
140
  sqlite_version >= 30800
141
141
  end
142
142
 
143
- # SQLite 3.6.8+ supports savepoints.
143
+ # SQLite 3.6.8+ supports savepoints.
144
144
  def supports_savepoints?
145
145
  sqlite_version >= 30608
146
146
  end
@@ -160,25 +160,25 @@ module Sequel
160
160
  #
161
161
  # Options:
162
162
  # :server :: Set the server to use.
163
- def tables(opts=OPTS)
164
- tables_and_views(Sequel.~(:name=>'sqlite_sequence') & {:type => 'table'}, opts)
163
+ def tables(opts = OPTS)
164
+ tables_and_views(Sequel.~(name: "sqlite_sequence") & {type: "table"}, opts)
165
165
  end
166
-
166
+
167
167
  # Creates a dataset that uses the VALUES clause:
168
168
  #
169
169
  # DB.values([[1, 2], [3, 4]])
170
170
  # # VALUES ((1, 2), (3, 4))
171
171
  def values(v)
172
172
  raise Error, "Cannot provide an empty array for values" if v.empty?
173
- @default_dataset.clone(:values=>v)
173
+ @default_dataset.clone(values: v)
174
174
  end
175
175
 
176
176
  # Array of symbols specifying the view names in the current database.
177
177
  #
178
178
  # Options:
179
179
  # :server :: Set the server to use.
180
- def views(opts=OPTS)
181
- tables_and_views({:type => 'view'}, opts)
180
+ def views(opts = OPTS)
181
+ tables_and_views({type: "view"}, opts)
182
182
  end
183
183
 
184
184
  private
@@ -190,7 +190,7 @@ module Sequel
190
190
 
191
191
  # Dataset used for parsing schema
192
192
  def _parse_pragma_ds(table_name, opts)
193
- metadata_dataset.with_sql("PRAGMA table_#{'x' if sqlite_version > 33100}info(?)", input_identifier_meth(opts[:dataset]).call(table_name))
193
+ metadata_dataset.with_sql("PRAGMA table_#{"x" if sqlite_version > 33100}info(?)", input_identifier_meth(opts[:dataset]).call(table_name))
194
194
  end
195
195
 
196
196
  # Run all alter_table commands in a transaction. This is technically only
@@ -201,20 +201,20 @@ module Sequel
201
201
  run "PRAGMA foreign_keys = 0"
202
202
  run "PRAGMA legacy_alter_table = 1" if sqlite_version >= 32600
203
203
  end
204
- transaction do
205
- if ops.length > 1 && ops.all?{|op| op[:op] == :add_constraint || op[:op] == :set_column_null}
206
- null_ops, ops = ops.partition{|op| op[:op] == :set_column_null}
204
+ transaction do
205
+ if ops.length > 1 && ops.all? { |op| op[:op] == :add_constraint || op[:op] == :set_column_null }
206
+ null_ops, ops = ops.partition { |op| op[:op] == :set_column_null }
207
207
 
208
208
  # Apply NULL/NOT NULL ops first, since those should be purely idependent of the constraints.
209
- null_ops.each{|op| alter_table_sql_list(table, [op]).flatten.each{|sql| execute_ddl(sql)}}
209
+ null_ops.each { |op| alter_table_sql_list(table, [op]).flatten.each { |sql| execute_ddl(sql) } }
210
210
 
211
211
  # If you are just doing constraints, apply all of them at the same time,
212
212
  # as otherwise all but the last one get lost.
213
- alter_table_sql_list(table, [{:op=>:add_constraints, :ops=>ops}]).flatten.each{|sql| execute_ddl(sql)}
213
+ alter_table_sql_list(table, [{op: :add_constraints, ops: ops}]).flatten.each { |sql| execute_ddl(sql) }
214
214
  else
215
215
  # Run each operation separately, as later operations may depend on the
216
216
  # results of earlier operations.
217
- ops.each{|op| alter_table_sql_list(table, [op]).flatten.each{|sql| execute_ddl(sql)}}
217
+ ops.each { |op| alter_table_sql_list(table, [op]).flatten.each { |sql| execute_ddl(sql) } }
218
218
  end
219
219
  end
220
220
  remove_cached_schema(table)
@@ -235,7 +235,7 @@ module Sequel
235
235
  super
236
236
  when :add_column
237
237
  if op[:unique] || op[:primary_key]
238
- duplicate_table(table){|columns| columns.push(op)}
238
+ duplicate_table(table) { |columns| columns.push(op) }
239
239
  else
240
240
  super
241
241
  end
@@ -243,22 +243,22 @@ module Sequel
243
243
  if sqlite_version >= 33500
244
244
  super
245
245
  else
246
- ocp = lambda{|oc| oc.delete_if{|c| c.to_s == op[:name].to_s}}
247
- duplicate_table(table, :old_columns_proc=>ocp){|columns| columns.delete_if{|s| s[:name].to_s == op[:name].to_s}}
246
+ ocp = lambda { |oc| oc.delete_if { |c| c.to_s == op[:name].to_s } }
247
+ duplicate_table(table, old_columns_proc: ocp) { |columns| columns.delete_if { |s| s[:name].to_s == op[:name].to_s } }
248
248
  end
249
249
  when :rename_column
250
250
  if sqlite_version >= 32500
251
251
  super
252
252
  else
253
- ncp = lambda{|nc| nc.map!{|c| c.to_s == op[:name].to_s ? op[:new_name] : c}}
254
- duplicate_table(table, :new_columns_proc=>ncp){|columns| columns.each{|s| s[:name] = op[:new_name] if s[:name].to_s == op[:name].to_s}}
253
+ ncp = lambda { |nc| nc.map! { |c| (c.to_s == op[:name].to_s) ? op[:new_name] : c } }
254
+ duplicate_table(table, new_columns_proc: ncp) { |columns| columns.each { |s| s[:name] = op[:new_name] if s[:name].to_s == op[:name].to_s } }
255
255
  end
256
256
  when :set_column_default
257
- duplicate_table(table){|columns| columns.each{|s| s[:default] = op[:default] if s[:name].to_s == op[:name].to_s}}
257
+ duplicate_table(table) { |columns| columns.each { |s| s[:default] = op[:default] if s[:name].to_s == op[:name].to_s } }
258
258
  when :set_column_null
259
- duplicate_table(table){|columns| columns.each{|s| s[:null] = op[:null] if s[:name].to_s == op[:name].to_s}}
259
+ duplicate_table(table) { |columns| columns.each { |s| s[:null] = op[:null] if s[:name].to_s == op[:name].to_s } }
260
260
  when :set_column_type
261
- duplicate_table(table){|columns| columns.each{|s| s.merge!(op) if s[:name].to_s == op[:name].to_s}}
261
+ duplicate_table(table) { |columns| columns.each { |s| s.merge!(op) if s[:name].to_s == op[:name].to_s } }
262
262
  when :drop_constraint
263
263
  case op[:type]
264
264
  when :primary_key
@@ -270,19 +270,19 @@ module Sequel
270
270
  end
271
271
  when :foreign_key
272
272
  if op[:columns]
273
- duplicate_table(table, :skip_foreign_key_columns=>op[:columns])
273
+ duplicate_table(table, skip_foreign_key_columns: op[:columns])
274
274
  else
275
- duplicate_table(table, :no_foreign_keys=>true)
275
+ duplicate_table(table, no_foreign_keys: true)
276
276
  end
277
277
  when :unique
278
- duplicate_table(table, :no_unique=>true)
278
+ duplicate_table(table, no_unique: true)
279
279
  else
280
280
  duplicate_table(table)
281
281
  end
282
282
  when :add_constraint
283
- duplicate_table(table, :constraints=>[op])
283
+ duplicate_table(table, constraints: [op])
284
284
  when :add_constraints
285
- duplicate_table(table, :constraints=>op[:ops])
285
+ duplicate_table(table, constraints: op[:ops])
286
286
  else
287
287
  raise Error, "Unsupported ALTER TABLE operation: #{op[:op].inspect}"
288
288
  end
@@ -296,9 +296,9 @@ module Sequel
296
296
  end
297
297
 
298
298
  # A name to use for the backup table
299
- def backup_table_name(table, opts=OPTS)
300
- table = table.gsub('`', '')
301
- (opts[:times]||1000).times do |i|
299
+ def backup_table_name(table, opts = OPTS)
300
+ table = table.delete("`")
301
+ (opts[:times] || 1000).times do |i|
302
302
  table_name = "#{table}_backup#{i}"
303
303
  return table_name unless table_exists?(table_name)
304
304
  end
@@ -320,12 +320,12 @@ module Sequel
320
320
  sql << " GENERATED ALWAYS AS (#{literal(generated)}) #{generated_type}"
321
321
  end
322
322
  end
323
-
323
+
324
324
  # SQLite does not restrict the integer or decimal type to a specific range.
325
325
  def column_schema_integer_min_max_values(column)
326
326
  nil
327
327
  end
328
- alias column_schema_decimal_min_max_values column_schema_integer_min_max_values
328
+ alias_method :column_schema_decimal_min_max_values, :column_schema_integer_min_max_values
329
329
 
330
330
  # Array of PRAGMA SQL statements based on the Database options that should be applied to
331
331
  # new connections.
@@ -336,8 +336,8 @@ module Sequel
336
336
  v = typecast_value_boolean(opts.fetch(:case_sensitive_like, 1))
337
337
  ps << "PRAGMA case_sensitive_like = #{v ? 1 : 0}"
338
338
  [[:auto_vacuum, AUTO_VACUUM], [:synchronous, SYNCHRONOUS], [:temp_store, TEMP_STORE]].each do |prag, con|
339
- if v = opts[prag]
340
- raise(Error, "Value for PRAGMA #{prag} not supported, should be one of #{con.join(', ')}") unless v = con.index(v.to_sym)
339
+ if (v = opts[prag])
340
+ raise(Error, "Value for PRAGMA #{prag} not supported, should be one of #{con.join(", ")}") unless (v = con.index(v.to_sym))
341
341
  ps << "PRAGMA #{prag} = #{v}"
342
342
  end
343
343
  end
@@ -346,12 +346,12 @@ module Sequel
346
346
 
347
347
  # Support creating STRICT tables via :strict option
348
348
  def create_table_sql(name, generator, options)
349
- "#{super}#{' STRICT' if options[:strict]}"
349
+ "#{super}#{" STRICT" if options[:strict]}"
350
350
  end
351
351
 
352
352
  # SQLite support creating temporary views.
353
353
  def create_view_prefix_sql(name, options)
354
- create_view_sql_append_columns("CREATE #{'TEMPORARY 'if options[:temp]}VIEW #{quote_schema_table(name)}", options[:columns])
354
+ create_view_sql_append_columns("CREATE #{"TEMPORARY " if options[:temp]}VIEW #{quote_schema_table(name)}", options[:columns])
355
355
  end
356
356
 
357
357
  DATABASE_ERROR_REGEXPS = {
@@ -401,20 +401,20 @@ module Sequel
401
401
  # Duplicate an existing table by creating a new table, copying all records
402
402
  # from the existing table into the new table, deleting the existing table
403
403
  # and renaming the new table to the existing table's name.
404
- def duplicate_table(table, opts=OPTS)
404
+ def duplicate_table(table, opts = OPTS)
405
405
  remove_cached_schema(table)
406
406
  def_columns = defined_columns_for(table)
407
- old_columns = def_columns.map{|c| c[:name]}
408
- opts[:old_columns_proc].call(old_columns) if opts[:old_columns_proc]
407
+ old_columns = def_columns.map { |c| c[:name] }
408
+ opts[:old_columns_proc]&.call(old_columns)
409
409
 
410
410
  yield def_columns if defined?(yield)
411
411
 
412
412
  constraints = (opts[:constraints] || []).dup
413
413
  pks = []
414
- def_columns.each{|c| pks << c[:name] if c[:primary_key]}
414
+ def_columns.each { |c| pks << c[:name] if c[:primary_key] }
415
415
  if pks.length > 1
416
- constraints << {:type=>:primary_key, :columns=>pks}
417
- def_columns.each{|c| c[:primary_key] = false if c[:primary_key]}
416
+ constraints << {type: :primary_key, columns: pks}
417
+ def_columns.each { |c| c[:primary_key] = false if c[:primary_key] }
418
418
  end
419
419
 
420
420
  # If dropping a foreign key constraint, drop all foreign key constraints,
@@ -424,56 +424,56 @@ module Sequel
424
424
 
425
425
  # If dropping a column, if there is a foreign key with that
426
426
  # column, don't include it when building a copy of the table.
427
- if ocp = opts[:old_columns_proc]
428
- fks.delete_if{|c| ocp.call(c[:columns].dup) != c[:columns]}
427
+ if (ocp = opts[:old_columns_proc])
428
+ fks.delete_if { |c| ocp.call(c[:columns].dup) != c[:columns] }
429
429
  end
430
-
430
+
431
431
  # Skip any foreign key columns where a constraint for those
432
432
  # foreign keys is being dropped.
433
- if sfkc = opts[:skip_foreign_key_columns]
434
- fks.delete_if{|c| c[:columns] == sfkc}
433
+ if (sfkc = opts[:skip_foreign_key_columns])
434
+ fks.delete_if { |c| c[:columns] == sfkc }
435
435
  end
436
436
 
437
- constraints.concat(fks.each{|h| h[:type] = :foreign_key})
437
+ constraints.concat(fks.each { |h| h[:type] = :foreign_key })
438
438
  end
439
439
 
440
440
  # Determine unique constraints and make sure the new columns have them
441
441
  unique_columns = []
442
442
  skip_indexes = []
443
- indexes(table, :only_autocreated=>true).each do |name, h|
443
+ indexes(table, only_autocreated: true).each do |name, h|
444
444
  skip_indexes << name
445
445
  if h[:unique] && !opts[:no_unique]
446
446
  if h[:columns].length == 1
447
447
  unique_columns.concat(h[:columns])
448
448
  elsif h[:columns].map(&:to_s) != pks
449
- constraints << {:type=>:unique, :columns=>h[:columns]}
449
+ constraints << {type: :unique, columns: h[:columns]}
450
450
  end
451
451
  end
452
452
  end
453
453
  unique_columns -= pks
454
454
  unless unique_columns.empty?
455
- unique_columns.map!{|c| quote_identifier(c)}
455
+ unique_columns.map! { |c| quote_identifier(c) }
456
456
  def_columns.each do |c|
457
457
  c[:unique] = true if unique_columns.include?(quote_identifier(c[:name])) && c[:unique] != false
458
458
  end
459
459
  end
460
-
461
- def_columns_str = (def_columns.map{|c| column_definition_sql(c)} + constraints.map{|c| constraint_definition_sql(c)}).join(', ')
460
+
461
+ def_columns_str = (def_columns.map { |c| column_definition_sql(c) } + constraints.map { |c| constraint_definition_sql(c) }).join(", ")
462
462
  new_columns = old_columns.dup
463
- opts[:new_columns_proc].call(new_columns) if opts[:new_columns_proc]
463
+ opts[:new_columns_proc]&.call(new_columns)
464
464
 
465
465
  qt = quote_schema_table(table)
466
466
  bt = quote_identifier(backup_table_name(qt))
467
467
  a = [
468
- "ALTER TABLE #{qt} RENAME TO #{bt}",
469
- "CREATE TABLE #{qt}(#{def_columns_str})",
470
- "INSERT INTO #{qt}(#{dataset.send(:identifier_list, new_columns)}) SELECT #{dataset.send(:identifier_list, old_columns)} FROM #{bt}",
471
- "DROP TABLE #{bt}"
468
+ "ALTER TABLE #{qt} RENAME TO #{bt}",
469
+ "CREATE TABLE #{qt}(#{def_columns_str})",
470
+ "INSERT INTO #{qt}(#{dataset.send(:identifier_list, new_columns)}) SELECT #{dataset.send(:identifier_list, old_columns)} FROM #{bt}",
471
+ "DROP TABLE #{bt}"
472
472
  ]
473
473
  indexes(table).each do |name, h|
474
474
  next if skip_indexes.include?(name)
475
475
  if (h[:columns].map(&:to_s) - new_columns).empty?
476
- a << alter_table_sql(table, h.merge(:op=>:add_index, :name=>name))
476
+ a << alter_table_sql(table, h.merge(op: :add_index, name: name))
477
477
  end
478
478
  end
479
479
  a
@@ -483,15 +483,15 @@ module Sequel
483
483
  # to symbols +:set_null+.
484
484
  def on_delete_sql_to_sym(str)
485
485
  case str
486
- when 'RESTRICT'
486
+ when "RESTRICT"
487
487
  :restrict
488
- when 'CASCADE'
488
+ when "CASCADE"
489
489
  :cascade
490
- when 'SET NULL'
490
+ when "SET NULL"
491
491
  :set_null
492
- when 'SET DEFAULT'
492
+ when "SET DEFAULT"
493
493
  :set_default
494
- when 'NO ACTION'
494
+ when "NO ACTION"
495
495
  :no_action
496
496
  end
497
497
  end
@@ -503,23 +503,23 @@ module Sequel
503
503
  if sqlite_version > 33100
504
504
  # table_xinfo PRAGMA used, remove hidden columns
505
505
  # that are not generated columns
506
- if row[:generated] = (row.delete(:hidden) != 0)
507
- next unless row[:type].end_with?(' GENERATED ALWAYS')
508
- row[:type] = row[:type].sub(' GENERATED ALWAYS', '')
506
+ if row[:generated] == (row.delete(:hidden) != 0)
507
+ next unless row[:type].end_with?(" GENERATED ALWAYS")
508
+ row[:type] = row[:type].sub(" GENERATED ALWAYS", "")
509
509
  end
510
510
  end
511
511
 
512
512
  row.delete(:cid)
513
513
  row[:allow_null] = row.delete(:notnull).to_i == 0
514
514
  row[:default] = row.delete(:dflt_value)
515
- row[:default] = nil if blank_object?(row[:default]) || row[:default] == 'NULL'
515
+ row[:default] = nil if blank_object?(row[:default]) || row[:default] == "NULL"
516
516
  row[:db_type] = row.delete(:type)
517
- if row[:primary_key] = row.delete(:pk).to_i > 0
517
+ if row[:primary_key] == row.delete(:pk).to_i > 0
518
518
  pks += 1
519
519
  # Guess that an integer primary key uses auto increment,
520
520
  # since that is Sequel's default and SQLite does not provide
521
521
  # a way to introspect whether it is actually autoincrementing.
522
- row[:auto_increment] = row[:db_type].downcase == 'integer'
522
+ row[:auto_increment] = row[:db_type].downcase == "integer"
523
523
  end
524
524
  row[:type] = schema_column_type(row[:db_type])
525
525
  row
@@ -531,12 +531,12 @@ module Sequel
531
531
  # SQLite does not allow use of auto increment for tables
532
532
  # with composite primary keys, so remove auto_increment
533
533
  # if composite primary keys are detected.
534
- sch.each{|r| r.delete(:auto_increment)}
534
+ sch.each { |r| r.delete(:auto_increment) }
535
535
  end
536
536
 
537
537
  sch
538
538
  end
539
-
539
+
540
540
  # SQLite supports schema parsing using the table_info PRAGMA, so
541
541
  # parse the output of that into the format Sequel expects.
542
542
  def schema_parse_table(table_name, opts)
@@ -545,7 +545,7 @@ module Sequel
545
545
  [m.call(row.delete(:name)), row]
546
546
  end
547
547
  end
548
-
548
+
549
549
  # Don't support SQLite error codes for exceptions by default.
550
550
  def sqlite_error_code(exception)
551
551
  nil
@@ -554,7 +554,7 @@ module Sequel
554
554
  # Backbone of the tables and views support.
555
555
  def tables_and_views(filter, opts)
556
556
  m = output_identifier_meth
557
- metadata_dataset.from(:sqlite_master).server(opts[:server]).where(filter).map{|r| m.call(r[:name])}
557
+ metadata_dataset.from(:sqlite_master).server(opts[:server]).where(filter).map { |r| m.call(r[:name]) }
558
558
  end
559
559
 
560
560
  # SQLite only supports AUTOINCREMENT on integer columns, not
@@ -564,32 +564,32 @@ module Sequel
564
564
  column[:auto_increment] ? :integer : super
565
565
  end
566
566
  end
567
-
567
+
568
568
  module DatasetMethods
569
569
  include Dataset::Replace
570
570
  include UnmodifiedIdentifiers::DatasetMethods
571
571
 
572
572
  # The allowed values for insert_conflict
573
- INSERT_CONFLICT_RESOLUTIONS = %w'ROLLBACK ABORT FAIL IGNORE REPLACE'.each(&:freeze).freeze
573
+ INSERT_CONFLICT_RESOLUTIONS = %w[ROLLBACK ABORT FAIL IGNORE REPLACE].each(&:freeze).freeze
574
574
 
575
- CONSTANT_MAP = {:CURRENT_DATE=>"date(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIMESTAMP=>"datetime(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIME=>"time(CURRENT_TIMESTAMP, 'localtime')".freeze}.freeze
576
- EXTRACT_MAP = {:year=>"'%Y'", :month=>"'%m'", :day=>"'%d'", :hour=>"'%H'", :minute=>"'%M'", :second=>"'%f'"}.freeze
575
+ CONSTANT_MAP = {CURRENT_DATE: "date(CURRENT_TIMESTAMP, 'localtime')", CURRENT_TIMESTAMP: "datetime(CURRENT_TIMESTAMP, 'localtime')", CURRENT_TIME: "time(CURRENT_TIMESTAMP, 'localtime')"}.freeze
576
+ EXTRACT_MAP = {year: "'%Y'", month: "'%m'", day: "'%d'", hour: "'%H'", minute: "'%M'", second: "'%f'"}.freeze
577
577
  EXTRACT_MAP.each_value(&:freeze)
578
578
 
579
- Dataset.def_sql_method(self, :delete, [['if db.sqlite_version >= 33500', %w'with delete from where returning'], ['elsif db.sqlite_version >= 30803', %w'with delete from where'], ["else", %w'delete from where']])
580
- Dataset.def_sql_method(self, :insert, [['if db.sqlite_version >= 33500', %w'with insert conflict into columns values on_conflict returning'], ['elsif db.sqlite_version >= 30803', %w'with insert conflict into columns values on_conflict'], ["else", %w'insert conflict into columns values']])
581
- Dataset.def_sql_method(self, :select, [['if opts[:values]', %w'with values compounds'], ['else', %w'with select distinct columns from join where group having window compounds order limit lock']])
582
- Dataset.def_sql_method(self, :update, [['if db.sqlite_version >= 33500', %w'with update table set from where returning'], ['elsif db.sqlite_version >= 33300', %w'with update table set from where'], ['elsif db.sqlite_version >= 30803', %w'with update table set where'], ["else", %w'update table set where']])
579
+ Dataset.def_sql_method(self, :delete, [["if db.sqlite_version >= 33500", %w[with delete from where returning]], ["elsif db.sqlite_version >= 30803", %w[with delete from where]], ["else", %w[delete from where]]])
580
+ Dataset.def_sql_method(self, :insert, [["if db.sqlite_version >= 33500", %w[with insert conflict into columns values on_conflict returning]], ["elsif db.sqlite_version >= 30803", %w[with insert conflict into columns values on_conflict]], ["else", %w[insert conflict into columns values]]])
581
+ Dataset.def_sql_method(self, :select, [["if opts[:values]", %w[with values compounds]], ["else", %w[with select distinct columns from join where group having window compounds order limit lock]]])
582
+ Dataset.def_sql_method(self, :update, [["if db.sqlite_version >= 33500", %w[with update table set from where returning]], ["elsif db.sqlite_version >= 33300", %w[with update table set from where]], ["elsif db.sqlite_version >= 30803", %w[with update table set where]], ["else", %w[update table set where]]])
583
583
 
584
584
  def cast_sql_append(sql, expr, type)
585
- if type == Time or type == DateTime
585
+ if type == Time || type == DateTime
586
586
  sql << "datetime("
587
587
  literal_append(sql, expr)
588
- sql << ')'
588
+ sql << ")"
589
589
  elsif type == Date
590
590
  sql << "date("
591
591
  literal_append(sql, expr)
592
- sql << ')'
592
+ sql << ")"
593
593
  else
594
594
  super
595
595
  end
@@ -600,46 +600,46 @@ module Sequel
600
600
  def complex_expression_sql_append(sql, op, args)
601
601
  case op
602
602
  when :"NOT LIKE", :"NOT ILIKE"
603
- sql << 'NOT '
604
- complex_expression_sql_append(sql, (op == :"NOT ILIKE" ? :ILIKE : :LIKE), args)
603
+ sql << "NOT "
604
+ complex_expression_sql_append(sql, ((op == :"NOT ILIKE") ? :ILIKE : :LIKE), args)
605
605
  when :^
606
- complex_expression_arg_pairs_append(sql, args){|a, b| Sequel.lit(["((~(", " & ", ")) & (", " | ", "))"], a, b, a, b)}
606
+ complex_expression_arg_pairs_append(sql, args) { |a, b| Sequel.lit(["((~(", " & ", ")) & (", " | ", "))"], a, b, a, b) }
607
607
  when :**
608
608
  unless (exp = args[1]).is_a?(Integer)
609
609
  raise(Sequel::Error, "can only emulate exponentiation on SQLite if exponent is an integer, given #{exp.inspect}")
610
610
  end
611
611
  case exp
612
612
  when 0
613
- sql << '1'
613
+ sql << "1"
614
614
  else
615
- sql << '('
615
+ sql << "("
616
616
  arg = args[0]
617
617
  if exp < 0
618
618
  invert = true
619
619
  exp = exp.abs
620
- sql << '(1.0 / ('
620
+ sql << "(1.0 / ("
621
621
  end
622
- (exp - 1).times do
622
+ (exp - 1).times do
623
623
  literal_append(sql, arg)
624
624
  sql << " * "
625
625
  end
626
626
  literal_append(sql, arg)
627
- sql << ')'
627
+ sql << ")"
628
628
  if invert
629
629
  sql << "))"
630
630
  end
631
631
  end
632
632
  when :extract
633
633
  part = args[0]
634
- raise(Sequel::Error, "unsupported extract argument: #{part.inspect}") unless format = EXTRACT_MAP[part]
635
- sql << "CAST(strftime(" << format << ', '
634
+ raise(Sequel::Error, "unsupported extract argument: #{part.inspect}") unless (format = EXTRACT_MAP[part])
635
+ sql << "CAST(strftime(" << format << ", "
636
636
  literal_append(sql, args[1])
637
- sql << ') AS ' << (part == :second ? 'NUMERIC' : 'INTEGER') << ')'
637
+ sql << ") AS " << ((part == :second) ? "NUMERIC" : "INTEGER") << ")"
638
638
  else
639
639
  super
640
640
  end
641
641
  end
642
-
642
+
643
643
  # SQLite has CURRENT_TIMESTAMP and related constants in UTC instead
644
644
  # of in localtime, so convert those constants to local time.
645
645
  def constant_sql_append(sql, constant)
@@ -649,14 +649,14 @@ module Sequel
649
649
  super
650
650
  end
651
651
  end
652
-
652
+
653
653
  # SQLite performs a TRUNCATE style DELETE if no filter is specified.
654
654
  # Since we want to always return the count of records, add a condition
655
655
  # that is always true and then delete.
656
656
  def delete(&block)
657
- @opts[:where] ? super : where(1=>1).delete(&block)
657
+ @opts[:where] ? super : where(1 => 1).delete(&block)
658
658
  end
659
-
659
+
660
660
  # Always return false when using VALUES
661
661
  def empty?
662
662
  return false if @opts[:values]
@@ -666,21 +666,21 @@ module Sequel
666
666
  # Return an array of strings specifying a query explanation for a SELECT of the
667
667
  # current dataset. Currently, the options are ignored, but it accepts options
668
668
  # to be compatible with other adapters.
669
- def explain(opts=nil)
669
+ def explain(opts = nil)
670
670
  # Load the PrettyTable class, needed for explain output
671
671
  Sequel.extension(:_pretty_table) unless defined?(Sequel::PrettyTable)
672
672
 
673
- ds = db.send(:metadata_dataset).clone(:sql=>"EXPLAIN #{select_sql}")
673
+ ds = db.send(:metadata_dataset).clone(sql: "EXPLAIN #{select_sql}")
674
674
  rows = ds.all
675
675
  Sequel::PrettyTable.string(rows, ds.columns)
676
676
  end
677
-
677
+
678
678
  # HAVING requires GROUP BY on SQLite
679
679
  def having(*cond)
680
680
  raise(InvalidOperation, "Can only specify a HAVING clause on a grouped dataset") if !@opts[:group] && db.sqlite_version < 33900
681
681
  super
682
682
  end
683
-
683
+
684
684
  # Support insert select for associations, so that the model code can use
685
685
  # returning instead of a separate query.
686
686
  def insert_select(*values)
@@ -698,16 +698,16 @@ module Sequel
698
698
 
699
699
  # SQLite uses the nonstandard ` (backtick) for quoting identifiers.
700
700
  def quoted_identifier_append(sql, c)
701
- sql << '`' << c.to_s.gsub('`', '``') << '`'
701
+ sql << "`" << c.to_s.gsub("`", "``") << "`"
702
702
  end
703
-
703
+
704
704
  # When a qualified column is selected on SQLite and the qualifier
705
705
  # is a subselect, the column name used is the full qualified name
706
706
  # (including the qualifier) instead of just the column name. To
707
707
  # get correct column names, you must use an alias.
708
708
  def select(*cols)
709
- if ((f = @opts[:from]) && f.any?{|t| t.is_a?(Dataset) || (t.is_a?(SQL::AliasedExpression) && t.expression.is_a?(Dataset))}) || ((j = @opts[:join]) && j.any?{|t| t.table.is_a?(Dataset)})
710
- super(*cols.map{|c| alias_qualified_column(c)})
709
+ if ((f = @opts[:from]) && f.any? { |t| t.is_a?(Dataset) || (t.is_a?(SQL::AliasedExpression) && t.expression.is_a?(Dataset)) }) || ((j = @opts[:join]) && j.any? { |t| t.table.is_a?(Dataset) })
710
+ super(*cols.map { |c| alias_qualified_column(c) })
711
711
  else
712
712
  super
713
713
  end
@@ -737,7 +737,7 @@ module Sequel
737
737
  # DB[:table].insert_conflict({}).insert(a: 1, b: 2)
738
738
  # # INSERT INTO TABLE (a, b) VALUES (1, 2)
739
739
  # # ON CONFLICT DO NOTHING
740
- #
740
+ #
741
741
  # DB[:table].insert_conflict(target: :a).insert(a: 1, b: 2)
742
742
  # # INSERT INTO TABLE (a, b) VALUES (1, 2)
743
743
  # # ON CONFLICT (a) DO NOTHING
@@ -745,11 +745,11 @@ module Sequel
745
745
  # DB[:table].insert_conflict(target: :a, conflict_where: {c: true}).insert(a: 1, b: 2)
746
746
  # # INSERT INTO TABLE (a, b) VALUES (1, 2)
747
747
  # # ON CONFLICT (a) WHERE (c IS TRUE) DO NOTHING
748
- #
748
+ #
749
749
  # DB[:table].insert_conflict(target: :a, update: {b: Sequel[:excluded][:b]}).insert(a: 1, b: 2)
750
750
  # # INSERT INTO TABLE (a, b) VALUES (1, 2)
751
751
  # # ON CONFLICT (a) DO UPDATE SET b = excluded.b
752
- #
752
+ #
753
753
  # DB[:table].insert_conflict(target: :a,
754
754
  # update: {b: Sequel[:excluded][:b]}, update_where: {Sequel[:table][:status_id] => 1}).insert(a: 1, b: 2)
755
755
  # # INSERT INTO TABLE (a, b) VALUES (1, 2)
@@ -760,9 +760,9 @@ module Sequel
760
760
  unless INSERT_CONFLICT_RESOLUTIONS.include?(opts.to_s.upcase)
761
761
  raise Error, "Invalid symbol or string passed to Dataset#insert_conflict: #{opts.inspect}. The allowed values are: :rollback, :abort, :fail, :ignore, or :replace"
762
762
  end
763
- clone(:insert_conflict => opts)
763
+ clone(insert_conflict: opts)
764
764
  when Hash
765
- clone(:insert_on_conflict => opts)
765
+ clone(insert_on_conflict: opts)
766
766
  else
767
767
  raise Error, "Invalid value passed to Dataset#insert_conflict: #{opts.inspect}, should use a symbol or a hash"
768
768
  end
@@ -781,11 +781,11 @@ module Sequel
781
781
  def returning(*values)
782
782
  return super if values.empty?
783
783
  raise Error, "RETURNING is not supported on #{db.database_type}" unless supports_returning?(:insert)
784
- clone(:returning=>_returning_values(values).freeze)
784
+ clone(returning: _returning_values(values).freeze)
785
785
  end
786
786
 
787
787
  # SQLite 3.8.3+ supports common table expressions.
788
- def supports_cte?(type=:select)
788
+ def supports_cte?(type = :select)
789
789
  db.sqlite_version >= 30803
790
790
  end
791
791
 
@@ -813,7 +813,7 @@ module Sequel
813
813
  def supports_is_true?
814
814
  false
815
815
  end
816
-
816
+
817
817
  # SQLite 3.33.0 supports modifying joined datasets
818
818
  def supports_modifying_joins?
819
819
  db.sqlite_version >= 33300
@@ -823,7 +823,7 @@ module Sequel
823
823
  def supports_multiple_column_in?
824
824
  false
825
825
  end
826
-
826
+
827
827
  # SQLite 3.35.0 supports RETURNING on INSERT/UPDATE/DELETE.
828
828
  def supports_returning?(_)
829
829
  db.sqlite_version >= 33500
@@ -845,7 +845,7 @@ module Sequel
845
845
  def supports_window_clause?
846
846
  db.sqlite_version >= 32800
847
847
  end
848
-
848
+
849
849
  # SQLite 3.25+ supports window functions. However, support is only enabled
850
850
  # on SQLite 3.26.0+ because internal Sequel usage of window functions
851
851
  # to implement eager loading of limited associations triggers
@@ -853,14 +853,14 @@ module Sequel
853
853
  def supports_window_functions?
854
854
  db.sqlite_version >= 32600
855
855
  end
856
-
856
+
857
857
  # SQLite 3.28.0+ supports all window frame options that Sequel supports
858
858
  def supports_window_function_frame_option?(option)
859
- db.sqlite_version >= 32800 ? true : super
859
+ (db.sqlite_version >= 32800) ? true : super
860
860
  end
861
861
 
862
862
  private
863
-
863
+
864
864
  # Add aliases to symbols and identifiers to work around SQLite bug.
865
865
  def _returning_values(values)
866
866
  values.map do |v|
@@ -880,12 +880,12 @@ module Sequel
880
880
  def aggreate_dataset_use_from_self?
881
881
  super || @opts[:values]
882
882
  end
883
-
883
+
884
884
  # SQLite uses string literals instead of identifiers in AS clauses.
885
- def as_sql_append(sql, aliaz, column_aliases=nil)
885
+ def as_sql_append(sql, aliaz, column_aliases = nil)
886
886
  raise Error, "sqlite does not support derived column lists" if column_aliases
887
887
  aliaz = aliaz.value if aliaz.is_a?(SQL::Identifier)
888
- sql << ' AS '
888
+ sql << " AS "
889
889
  literal_append(sql, aliaz.to_s)
890
890
  end
891
891
 
@@ -911,7 +911,7 @@ module Sequel
911
911
  raise(InvalidOperation, "Grouped datasets cannot be modified") if opts[:group]
912
912
  raise(InvalidOperation, "Joined datasets cannot be modified") if joined_dataset?
913
913
  end
914
- alias check_delete_allowed! check_insert_allowed!
914
+ alias_method :check_delete_allowed!, :check_insert_allowed!
915
915
 
916
916
  # SQLite supports a maximum of 500 rows in a VALUES clause.
917
917
  def default_import_slice
@@ -920,37 +920,37 @@ module Sequel
920
920
 
921
921
  # SQL fragment specifying a list of identifiers
922
922
  def identifier_list(columns)
923
- columns.map{|i| quote_identifier(i)}.join(', ')
923
+ columns.map { |i| quote_identifier(i) }.join(", ")
924
924
  end
925
-
925
+
926
926
  # Add OR clauses to SQLite INSERT statements
927
927
  def insert_conflict_sql(sql)
928
- if resolution = @opts[:insert_conflict]
928
+ if (resolution = @opts[:insert_conflict])
929
929
  sql << " OR " << resolution.to_s.upcase
930
930
  end
931
931
  end
932
932
 
933
933
  # Add ON CONFLICT clause if it should be used
934
934
  def insert_on_conflict_sql(sql)
935
- if opts = @opts[:insert_on_conflict]
935
+ if (opts = @opts[:insert_on_conflict])
936
936
  sql << " ON CONFLICT"
937
937
 
938
- if target = opts[:constraint]
938
+ if (target = opts[:constraint])
939
939
  sql << " ON CONSTRAINT "
940
940
  identifier_append(sql, target)
941
- elsif target = opts[:target]
942
- sql << ' '
941
+ elsif (target = opts[:target])
942
+ sql << " "
943
943
  identifier_append(sql, Array(target))
944
- if conflict_where = opts[:conflict_where]
944
+ if (conflict_where = opts[:conflict_where])
945
945
  sql << " WHERE "
946
946
  literal_append(sql, conflict_where)
947
947
  end
948
948
  end
949
949
 
950
- if values = opts[:update]
950
+ if (values = opts[:update])
951
951
  sql << " DO UPDATE SET "
952
952
  update_sql_values_hash(sql, values)
953
- if update_where = opts[:update_where]
953
+ if (update_where = opts[:update_where])
954
954
  sql << " WHERE "
955
955
  literal_append(sql, update_where)
956
956
  end
@@ -962,29 +962,29 @@ module Sequel
962
962
 
963
963
  # SQLite uses a preceding X for hex escaping strings
964
964
  def literal_blob_append(sql, v)
965
- sql << "X'" << v.unpack("H*").first << "'"
965
+ sql << "X'" << v.unpack1("H*") << "'"
966
966
  end
967
967
 
968
968
  # Respect the database integer_booleans setting, using 0 or 'f'.
969
969
  def literal_false
970
- @db.integer_booleans ? '0' : "'f'"
970
+ @db.integer_booleans ? "0" : "'f'"
971
971
  end
972
972
 
973
973
  # Respect the database integer_booleans setting, using 1 or 't'.
974
974
  def literal_true
975
- @db.integer_booleans ? '1' : "'t'"
975
+ @db.integer_booleans ? "1" : "'t'"
976
976
  end
977
977
 
978
978
  # SQLite only supporting multiple rows in the VALUES clause
979
979
  # starting in 3.7.11. On older versions, fallback to using a UNION.
980
980
  def multi_insert_sql_strategy
981
- db.sqlite_version >= 30711 ? :values : :union
981
+ (db.sqlite_version >= 30711) ? :values : :union
982
982
  end
983
983
 
984
984
  # Emulate the char_length function with length
985
985
  def native_function_name(emulated_function)
986
986
  if emulated_function == :char_length
987
- 'length'
987
+ "length"
988
988
  else
989
989
  super
990
990
  end
@@ -1006,7 +1006,7 @@ module Sequel
1006
1006
  sql << " LIMIT -1 OFFSET "
1007
1007
  literal_append(sql, @opts[:offset])
1008
1008
  end
1009
-
1009
+
1010
1010
  # Support VALUES clause instead of the SELECT clause to return rows.
1011
1011
  def select_values_sql(sql)
1012
1012
  sql << "VALUES "
@@ -1035,10 +1035,10 @@ module Sequel
1035
1035
 
1036
1036
  # Use FROM to specify additional tables in an update query
1037
1037
  def update_from_sql(sql)
1038
- if(from = @opts[:from][1..-1]).empty?
1039
- raise(Error, 'Need multiple FROM tables if updating/deleting a dataset with JOINs') if @opts[:join]
1038
+ if (from = @opts[:from][1..]).empty?
1039
+ raise(Error, "Need multiple FROM tables if updating/deleting a dataset with JOINs") if @opts[:join]
1040
1040
  else
1041
- sql << ' FROM '
1041
+ sql << " FROM "
1042
1042
  source_list_append(sql, from)
1043
1043
  select_join_sql(sql)
1044
1044
  end
@@ -1046,7 +1046,7 @@ module Sequel
1046
1046
 
1047
1047
  # Only include the primary table in the main update clause
1048
1048
  def update_table_sql(sql)
1049
- sql << ' '
1049
+ sql << " "
1050
1050
  source_list_append(sql, @opts[:from][0..0])
1051
1051
  end
1052
1052
  end