sequel 3.3.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +62 -0
- data/README.rdoc +4 -4
- data/doc/release_notes/3.3.0.txt +1 -1
- data/doc/release_notes/3.4.0.txt +325 -0
- data/doc/sharding.rdoc +3 -3
- data/lib/sequel/adapters/amalgalite.rb +1 -1
- data/lib/sequel/adapters/firebird.rb +4 -9
- data/lib/sequel/adapters/jdbc.rb +21 -7
- data/lib/sequel/adapters/mysql.rb +2 -1
- data/lib/sequel/adapters/odbc.rb +7 -21
- data/lib/sequel/adapters/oracle.rb +1 -1
- data/lib/sequel/adapters/postgres.rb +6 -1
- data/lib/sequel/adapters/shared/mssql.rb +11 -0
- data/lib/sequel/adapters/shared/mysql.rb +8 -12
- data/lib/sequel/adapters/shared/oracle.rb +13 -0
- data/lib/sequel/adapters/shared/postgres.rb +5 -10
- data/lib/sequel/adapters/shared/sqlite.rb +21 -1
- data/lib/sequel/adapters/sqlite.rb +2 -2
- data/lib/sequel/core.rb +147 -11
- data/lib/sequel/database.rb +21 -9
- data/lib/sequel/dataset.rb +31 -6
- data/lib/sequel/dataset/convenience.rb +1 -1
- data/lib/sequel/dataset/sql.rb +76 -18
- data/lib/sequel/extensions/inflector.rb +2 -51
- data/lib/sequel/model.rb +16 -10
- data/lib/sequel/model/associations.rb +4 -1
- data/lib/sequel/model/base.rb +13 -6
- data/lib/sequel/model/default_inflections.rb +46 -0
- data/lib/sequel/model/inflections.rb +1 -51
- data/lib/sequel/plugins/boolean_readers.rb +52 -0
- data/lib/sequel/plugins/instance_hooks.rb +57 -0
- data/lib/sequel/plugins/lazy_attributes.rb +13 -1
- data/lib/sequel/plugins/nested_attributes.rb +171 -0
- data/lib/sequel/plugins/serialization.rb +35 -16
- data/lib/sequel/plugins/timestamps.rb +87 -0
- data/lib/sequel/plugins/validation_helpers.rb +8 -1
- data/lib/sequel/sql.rb +33 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +11 -6
- data/spec/core/core_sql_spec.rb +29 -0
- data/spec/core/database_spec.rb +16 -7
- data/spec/core/dataset_spec.rb +264 -20
- data/spec/extensions/boolean_readers_spec.rb +86 -0
- data/spec/extensions/inflector_spec.rb +67 -4
- data/spec/extensions/instance_hooks_spec.rb +133 -0
- data/spec/extensions/lazy_attributes_spec.rb +45 -5
- data/spec/extensions/nested_attributes_spec.rb +272 -0
- data/spec/extensions/serialization_spec.rb +64 -1
- data/spec/extensions/timestamps_spec.rb +150 -0
- data/spec/extensions/validation_helpers_spec.rb +18 -0
- data/spec/integration/dataset_test.rb +79 -2
- data/spec/integration/schema_test.rb +17 -0
- data/spec/integration/timezone_test.rb +55 -0
- data/spec/model/associations_spec.rb +19 -7
- data/spec/model/model_spec.rb +29 -0
- data/spec/model/record_spec.rb +36 -0
- data/spec/spec_config.rb +1 -1
- metadata +14 -2
@@ -202,7 +202,6 @@ module Sequel
|
|
202
202
|
BOOL_FALSE = '0'.freeze
|
203
203
|
NULL = LiteralString.new('NULL').freeze
|
204
204
|
COMMA_SEPARATOR = ', '.freeze
|
205
|
-
FIREBIRD_TIMESTAMP_FORMAT = "TIMESTAMP '%Y-%m-%d %H:%M:%S".freeze
|
206
205
|
SELECT_CLAUSE_ORDER = %w'with distinct limit columns from join where group having compounds order'.freeze
|
207
206
|
|
208
207
|
# Yield all rows returned by executing the given SQL and converting
|
@@ -248,6 +247,10 @@ module Sequel
|
|
248
247
|
def insert_select(*values)
|
249
248
|
naked.clone(default_server_opts(:sql=>insert_returning_sql(nil, *values))).single_record
|
250
249
|
end
|
250
|
+
|
251
|
+
def requires_sql_standard_datetimes?
|
252
|
+
true
|
253
|
+
end
|
251
254
|
|
252
255
|
# The order of clauses in the SELECT SQL statement
|
253
256
|
def select_clause_order
|
@@ -273,18 +276,10 @@ module Sequel
|
|
273
276
|
end
|
274
277
|
end
|
275
278
|
|
276
|
-
def literal_datetime(v)
|
277
|
-
"#{v.strftime(FIREBIRD_TIMESTAMP_FORMAT)}.#{sprintf("%04d",(v.sec_fraction * 864000000))}'"
|
278
|
-
end
|
279
|
-
|
280
279
|
def literal_false
|
281
280
|
BOOL_FALSE
|
282
281
|
end
|
283
282
|
|
284
|
-
def literal_time(v)
|
285
|
-
"#{v.strftime(FIREBIRD_TIMESTAMP_FORMAT)}.#{sprintf("%04d",v.usec / 100)}'"
|
286
|
-
end
|
287
|
-
|
288
283
|
def literal_true
|
289
284
|
BOOL_TRUE
|
290
285
|
end
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -197,13 +197,18 @@ module Sequel
|
|
197
197
|
# Values are subhashes with two keys, :columns and :unique. The value of :columns
|
198
198
|
# is an array of symbols of column names. The value of :unique is true or false
|
199
199
|
# depending on if the index is unique.
|
200
|
-
def indexes(table)
|
201
|
-
indexes = {}
|
200
|
+
def indexes(table, opts={})
|
202
201
|
m = output_identifier_meth
|
203
|
-
|
202
|
+
im = input_identifier_meth
|
203
|
+
schema, table = schema_and_table(table)
|
204
|
+
schema ||= opts[:schema]
|
205
|
+
schema = im.call(schema) if schema
|
206
|
+
table = im.call(table)
|
207
|
+
indexes = {}
|
208
|
+
metadata(:getIndexInfo, nil, schema, table, false, true) do |r|
|
204
209
|
next unless name = r[:column_name]
|
205
210
|
next if respond_to?(:primary_key_index_re, true) and r[:index_name] =~ primary_key_index_re
|
206
|
-
i = indexes[m.call(r[:index_name])] ||= {:columns=>[], :unique
|
211
|
+
i = indexes[m.call(r[:index_name])] ||= {:columns=>[], :unique=>[false, 0].include?(r[:non_unique])}
|
207
212
|
i[:columns] << m.call(name)
|
208
213
|
end
|
209
214
|
indexes
|
@@ -324,6 +329,8 @@ module Sequel
|
|
324
329
|
case arg
|
325
330
|
when Integer
|
326
331
|
cps.setInt(i, arg)
|
332
|
+
when Sequel::SQL::Blob
|
333
|
+
cps.setBytes(i, arg.to_java_bytes)
|
327
334
|
when String
|
328
335
|
cps.setString(i, arg)
|
329
336
|
when Date, Java::JavaSql::Date
|
@@ -332,8 +339,12 @@ module Sequel
|
|
332
339
|
cps.setTimestamp(i, arg)
|
333
340
|
when Float
|
334
341
|
cps.setDouble(i, arg)
|
342
|
+
when TrueClass, FalseClass
|
343
|
+
cps.setBoolean(i, arg)
|
335
344
|
when nil
|
336
345
|
cps.setNull(i, JavaSQL::Types::NULL)
|
346
|
+
else
|
347
|
+
cps.setObject(i, arg)
|
337
348
|
end
|
338
349
|
end
|
339
350
|
|
@@ -348,12 +359,13 @@ module Sequel
|
|
348
359
|
conn
|
349
360
|
end
|
350
361
|
|
351
|
-
#
|
362
|
+
# Parse the table schema for the given table.
|
352
363
|
def schema_parse_table(table, opts={})
|
353
364
|
m = output_identifier_meth
|
354
365
|
im = input_identifier_meth
|
355
366
|
ds = dataset
|
356
367
|
schema, table = schema_and_table(table)
|
368
|
+
schema ||= opts[:schema]
|
357
369
|
schema = im.call(schema) if schema
|
358
370
|
table = im.call(table)
|
359
371
|
pks, ts = [], []
|
@@ -361,7 +373,7 @@ module Sequel
|
|
361
373
|
pks << h[:column_name]
|
362
374
|
end
|
363
375
|
metadata(:getColumns, nil, schema, table, nil) do |h|
|
364
|
-
ts << [m.call(h[:column_name]), {:type=>schema_column_type(h[:type_name]), :db_type=>h[:type_name], :default=>(h[:column_def] == '' ? nil : h[:column_def]), :allow_null=>(h[:nullable] != 0), :primary_key=>pks.include?(h[:column_name])}]
|
376
|
+
ts << [m.call(h[:column_name]), {:type=>schema_column_type(h[:type_name]), :db_type=>h[:type_name], :default=>(h[:column_def] == '' ? nil : h[:column_def]), :allow_null=>(h[:nullable] != 0), :primary_key=>pks.include?(h[:column_name]), :column_size=>h[:column_size]}]
|
365
377
|
end
|
366
378
|
ts
|
367
379
|
end
|
@@ -459,7 +471,7 @@ module Sequel
|
|
459
471
|
def convert_type(v)
|
460
472
|
case v
|
461
473
|
when Java::JavaSQL::Timestamp, Java::JavaSQL::Time
|
462
|
-
Sequel.
|
474
|
+
Sequel.database_to_application_timestamp(v.to_string)
|
463
475
|
when Java::JavaSQL::Date
|
464
476
|
Sequel.string_to_date(v.to_string)
|
465
477
|
when Java::JavaIo::BufferedReader
|
@@ -468,6 +480,8 @@ module Sequel
|
|
468
480
|
lines.join("\n")
|
469
481
|
when Java::JavaMath::BigDecimal
|
470
482
|
BigDecimal.new(v.to_string)
|
483
|
+
when Java::byte[]
|
484
|
+
Sequel::SQL::Blob.new(String.from_java_bytes(v))
|
471
485
|
else
|
472
486
|
v
|
473
487
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'mysql'
|
2
|
+
raise(LoadError, "require 'mysql' did not define Mysql::CLIENT_MULTI_RESULTS!\n You are probably using the pure ruby mysql.rb driver,\n which Sequel does not support. You need to install\n the C based adapter, and make sure that the mysql.so\n file is loaded instead of the mysql.rb file.\n") unless defined?(Mysql::CLIENT_MULTI_RESULTS)
|
2
3
|
Sequel.require %w'shared/mysql utils/stored_procedures', 'adapters'
|
3
4
|
|
4
5
|
module Sequel
|
@@ -28,7 +29,7 @@ module Sequel
|
|
28
29
|
[2, 3, 8, 9, 13, 247, 248] => lambda{|v| v.to_i}, # integer
|
29
30
|
[4, 5] => lambda{|v| v.to_f}, # float
|
30
31
|
[10, 14] => lambda{|v| convert_date_time(:string_to_date, v)}, # date
|
31
|
-
[7, 12] => lambda{|v| convert_date_time(:
|
32
|
+
[7, 12] => lambda{|v| convert_date_time(:database_to_application_timestamp, v)}, # datetime
|
32
33
|
[11] => lambda{|v| convert_date_time(:string_to_time, v)}, # time
|
33
34
|
[249, 250, 251, 252] => lambda{|v| Sequel::SQL::Blob.new(v)} # blob
|
34
35
|
}
|
data/lib/sequel/adapters/odbc.rb
CHANGED
@@ -89,9 +89,8 @@ module Sequel
|
|
89
89
|
class Dataset < Sequel::Dataset
|
90
90
|
BOOL_TRUE = '1'.freeze
|
91
91
|
BOOL_FALSE = '0'.freeze
|
92
|
-
ODBC_TIMESTAMP_FORMAT = "{ts '%Y-%m-%d %H:%M:%S'}".freeze
|
93
|
-
ODBC_TIMESTAMP_FORMAT_USEC = "{ts '%Y-%m-%d %H:%M:%S.%%i'}".freeze
|
94
92
|
ODBC_DATE_FORMAT = "{d '%Y-%m-%d'}".freeze
|
93
|
+
TIMESTAMP_FORMAT="{ts '%Y-%m-%d %H:%M:%S%N'}".freeze
|
95
94
|
|
96
95
|
def fetch_rows(sql, &block)
|
97
96
|
execute(sql) do |s|
|
@@ -110,14 +109,6 @@ module Sequel
|
|
110
109
|
end
|
111
110
|
|
112
111
|
private
|
113
|
-
|
114
|
-
def _literal_datetime(v, usec)
|
115
|
-
if usec >= 1000
|
116
|
-
v.strftime(ODBC_TIMESTAMP_FORMAT_USEC) % (usec.to_f/1000).round
|
117
|
-
else
|
118
|
-
v.strftime(ODBC_TIMESTAMP_FORMAT)
|
119
|
-
end
|
120
|
-
end
|
121
112
|
|
122
113
|
def convert_odbc_value(v)
|
123
114
|
# When fetching a result set, the Ruby ODBC driver converts all ODBC
|
@@ -128,25 +119,24 @@ module Sequel
|
|
128
119
|
# ODBCColumn#mapSqlTypeToGenericType and Column#klass.
|
129
120
|
case v
|
130
121
|
when ::ODBC::TimeStamp
|
131
|
-
|
122
|
+
Sequel.database_to_application_timestamp([v.year, v.month, v.day, v.hour, v.minute, v.second])
|
132
123
|
when ::ODBC::Time
|
133
|
-
now
|
134
|
-
Time.gm(now.year, now.month, now.day, v.hour, v.minute, v.second)
|
124
|
+
Sequel.database_to_application_timestamp([now.year, now.month, now.day, v.hour, v.minute, v.second])
|
135
125
|
when ::ODBC::Date
|
136
126
|
Date.new(v.year, v.month, v.day)
|
137
127
|
else
|
138
128
|
v
|
139
129
|
end
|
140
130
|
end
|
131
|
+
|
132
|
+
def default_timestamp_format
|
133
|
+
TIMESTAMP_FORMAT
|
134
|
+
end
|
141
135
|
|
142
136
|
def literal_date(v)
|
143
137
|
v.strftime(ODBC_DATE_FORMAT)
|
144
138
|
end
|
145
139
|
|
146
|
-
def literal_datetime(v)
|
147
|
-
_literal_datetime(v, v.sec_fraction * 86400000000)
|
148
|
-
end
|
149
|
-
|
150
140
|
def literal_false
|
151
141
|
BOOL_FALSE
|
152
142
|
end
|
@@ -154,10 +144,6 @@ module Sequel
|
|
154
144
|
def literal_true
|
155
145
|
BOOL_TRUE
|
156
146
|
end
|
157
|
-
|
158
|
-
def literal_time(v)
|
159
|
-
_literal_datetime(v, v.usec)
|
160
|
-
end
|
161
147
|
end
|
162
148
|
end
|
163
149
|
end
|
@@ -65,6 +65,11 @@ rescue LoadError => e
|
|
65
65
|
unless defined?(CONNECTION_OK)
|
66
66
|
CONNECTION_OK = -1
|
67
67
|
end
|
68
|
+
unless method_defined?(:status)
|
69
|
+
def status
|
70
|
+
CONNECTION_OK
|
71
|
+
end
|
72
|
+
end
|
68
73
|
end
|
69
74
|
class PGresult
|
70
75
|
alias_method :nfields, :num_fields unless method_defined?(:nfields)
|
@@ -94,7 +99,7 @@ module Sequel
|
|
94
99
|
[790, 1700] => lambda{|s| BigDecimal.new(s)}, # numeric
|
95
100
|
[1082] => lambda{|s| @use_iso_date_format ? Date.new(*s.split("-").map{|x| x.to_i}) : Sequel.string_to_date(s)}, # date
|
96
101
|
[1083, 1266] => lambda{|s| Sequel.string_to_time(s)}, # time
|
97
|
-
[1114, 1184] => lambda{|s| Sequel.
|
102
|
+
[1114, 1184] => lambda{|s| Sequel.database_to_application_timestamp(s)}, # timestamp
|
98
103
|
}
|
99
104
|
PG_TYPE_PROCS.each do |k,v|
|
100
105
|
k.each{|n| PG_TYPES[n] = v}
|
@@ -148,6 +148,7 @@ module Sequel
|
|
148
148
|
SELECT_CLAUSE_ORDER = %w'with limit distinct columns from table_options join where group order having compounds'.freeze
|
149
149
|
TIMESTAMP_FORMAT = "'%Y-%m-%d %H:%M:%S'".freeze
|
150
150
|
WILDCARD = LiteralString.new('*').freeze
|
151
|
+
CONSTANT_MAP = {:CURRENT_DATE=>'CAST(CURRENT_TIMESTAMP AS DATE)'.freeze, :CURRENT_TIME=>'CAST(CURRENT_TIMESTAMP AS TIME)'.freeze}
|
151
152
|
|
152
153
|
# MSSQL uses + for string concatenation
|
153
154
|
def complex_expression_sql(op, args)
|
@@ -159,6 +160,11 @@ module Sequel
|
|
159
160
|
end
|
160
161
|
end
|
161
162
|
|
163
|
+
# MSSQL doesn't support the SQL standard CURRENT_DATE or CURRENT_TIME
|
164
|
+
def constant_sql(constant)
|
165
|
+
CONSTANT_MAP[constant] || super
|
166
|
+
end
|
167
|
+
|
162
168
|
# When returning all rows, if an offset is used, delete the row_number column
|
163
169
|
# before yielding the row.
|
164
170
|
def each(&block)
|
@@ -222,6 +228,11 @@ module Sequel
|
|
222
228
|
false
|
223
229
|
end
|
224
230
|
|
231
|
+
# MSSQL supports timezones in literal timestamps
|
232
|
+
def supports_timestamp_timezones?
|
233
|
+
true
|
234
|
+
end
|
235
|
+
|
225
236
|
# MSSQL 2005+ supports window functions
|
226
237
|
def supports_window_functions?
|
227
238
|
true
|
@@ -198,7 +198,6 @@ module Sequel
|
|
198
198
|
module DatasetMethods
|
199
199
|
BOOL_TRUE = '1'.freeze
|
200
200
|
BOOL_FALSE = '0'.freeze
|
201
|
-
TIMESTAMP_FORMAT = "'%Y-%m-%d %H:%M:%S'".freeze
|
202
201
|
COMMA_SEPARATOR = ', '.freeze
|
203
202
|
SELECT_CLAUSE_ORDER = %w'distinct columns from join where group having compounds order limit'.freeze
|
204
203
|
|
@@ -360,6 +359,13 @@ module Sequel
|
|
360
359
|
def supports_intersect_except?
|
361
360
|
false
|
362
361
|
end
|
362
|
+
|
363
|
+
# MySQL does support fractional timestamps in literal timestamps, but it
|
364
|
+
# ignores them. Also, using them seems to cause problems on 1.9. Since
|
365
|
+
# they are ignored anyway, not using them is probably best.
|
366
|
+
def supports_timestamp_usecs?
|
367
|
+
false
|
368
|
+
end
|
363
369
|
|
364
370
|
# MySQL supports ORDER and LIMIT clauses in UPDATE statements.
|
365
371
|
def update_sql(values)
|
@@ -385,22 +391,12 @@ module Sequel
|
|
385
391
|
def insert_default_values_sql
|
386
392
|
"#{insert_sql_base}#{source_list(@opts[:from])} () VALUES ()"
|
387
393
|
end
|
388
|
-
|
389
|
-
# Use MySQL Timestamp format
|
390
|
-
def literal_datetime(v)
|
391
|
-
v.strftime(TIMESTAMP_FORMAT)
|
392
|
-
end
|
393
|
-
|
394
|
+
|
394
395
|
# Use 0 for false on MySQL
|
395
396
|
def literal_false
|
396
397
|
BOOL_FALSE
|
397
398
|
end
|
398
399
|
|
399
|
-
# Use MySQL Timestamp format
|
400
|
-
def literal_time(v)
|
401
|
-
v.strftime(TIMESTAMP_FORMAT)
|
402
|
-
end
|
403
|
-
|
404
400
|
# Use 1 for true on MySQL
|
405
401
|
def literal_true
|
406
402
|
BOOL_TRUE
|
@@ -121,6 +121,11 @@ module Sequel
|
|
121
121
|
false
|
122
122
|
end
|
123
123
|
|
124
|
+
# Oracle supports timezones in literal timestamps.
|
125
|
+
def supports_timestamp_timezones?
|
126
|
+
true
|
127
|
+
end
|
128
|
+
|
124
129
|
# Oracle supports window functions
|
125
130
|
def supports_window_functions?
|
126
131
|
true
|
@@ -143,6 +148,14 @@ module Sequel
|
|
143
148
|
SELECT_CLAUSE_ORDER
|
144
149
|
end
|
145
150
|
|
151
|
+
# Modify the SQL to add the list of tables to select FROM
|
152
|
+
# Oracle doesn't support select without FROM clause
|
153
|
+
# so add the dummy DUAL table if the dataset doesn't select
|
154
|
+
# from a table.
|
155
|
+
def select_from_sql(sql)
|
156
|
+
sql << " FROM #{source_list(@opts[:from] || ['DUAL'])}"
|
157
|
+
end
|
158
|
+
|
146
159
|
# Oracle requires a subselect to do limit and offset
|
147
160
|
def select_limit_sql(sql)
|
148
161
|
if limit = @opts[:limit]
|
@@ -693,6 +693,11 @@ module Sequel
|
|
693
693
|
["#{insert_sql_base}#{source_list(@opts[:from])} (#{identifier_list(columns)}) VALUES #{values}"]
|
694
694
|
end
|
695
695
|
|
696
|
+
# PostgreSQL supports timezones in literal timestamps
|
697
|
+
def supports_timestamp_timezones?
|
698
|
+
true
|
699
|
+
end
|
700
|
+
|
696
701
|
# PostgreSQL 8.4+ supports window functions
|
697
702
|
def supports_window_functions?
|
698
703
|
server_version >= 80400
|
@@ -716,11 +721,6 @@ module Sequel
|
|
716
721
|
"'#{v.gsub(/[\000-\037\047\134\177-\377]/){|b| "\\#{("%o" % b[0..1].unpack("C")[0]).rjust(3, '0')}"}}'"
|
717
722
|
end
|
718
723
|
|
719
|
-
# PostgreSQL supports fractional timestamps
|
720
|
-
def literal_datetime(v)
|
721
|
-
"#{v.strftime(PG_TIMESTAMP_FORMAT)}.#{sprintf("%06d", (v.sec_fraction * 86400000000).to_i)}'"
|
722
|
-
end
|
723
|
-
|
724
724
|
# PostgreSQL uses FALSE for false values
|
725
725
|
def literal_false
|
726
726
|
BOOL_FALSE
|
@@ -736,11 +736,6 @@ module Sequel
|
|
736
736
|
BOOL_TRUE
|
737
737
|
end
|
738
738
|
|
739
|
-
# PostgreSQL supports fractional times
|
740
|
-
def literal_time(v)
|
741
|
-
"#{v.strftime(PG_TIMESTAMP_FORMAT)}.#{sprintf("%06d",v.usec)}'"
|
742
|
-
end
|
743
|
-
|
744
739
|
# The order of clauses in the SELECT SQL statement
|
745
740
|
def select_clause_order
|
746
741
|
server_version >= 80400 ? SELECT_CLAUSE_ORDER_84 : SELECT_CLAUSE_ORDER
|
@@ -10,7 +10,9 @@ module Sequel
|
|
10
10
|
# Run all alter_table commands in a transaction. This is technically only
|
11
11
|
# needed for drop column.
|
12
12
|
def alter_table(name, generator=nil, &block)
|
13
|
-
|
13
|
+
remove_cached_schema(name)
|
14
|
+
generator ||= Schema::AlterTableGenerator.new(self, &block)
|
15
|
+
transaction{generator.operations.each{|op| alter_table_sql_list(name, [op]).flatten.each{|sql| execute_ddl(sql)}}}
|
14
16
|
end
|
15
17
|
|
16
18
|
# A symbol signifying the value of the auto_vacuum PRAGMA.
|
@@ -164,6 +166,7 @@ module Sequel
|
|
164
166
|
# from the existing table into the new table, deleting the existing table
|
165
167
|
# and renaming the new table to the existing table's name.
|
166
168
|
def duplicate_table(table, opts={})
|
169
|
+
remove_cached_schema(table)
|
167
170
|
def_columns = defined_columns_for(table)
|
168
171
|
old_columns = def_columns.map{|c| c[:name]}
|
169
172
|
opts[:old_columns_proc].call(old_columns) if opts[:old_columns_proc]
|
@@ -233,6 +236,7 @@ module Sequel
|
|
233
236
|
# Instance methods for datasets that connect to an SQLite database
|
234
237
|
module DatasetMethods
|
235
238
|
SELECT_CLAUSE_ORDER = %w'distinct columns from join where group having compounds order limit'.freeze
|
239
|
+
CONSTANT_MAP = {:CURRENT_DATE=>"date(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIMESTAMP=>"datetime(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIME=>"time(CURRENT_TIMESTAMP, 'localtime')".freeze}
|
236
240
|
|
237
241
|
# SQLite does not support pattern matching via regular expressions.
|
238
242
|
# SQLite is case insensitive (depending on pragma), so use LIKE for
|
@@ -249,6 +253,11 @@ module Sequel
|
|
249
253
|
end
|
250
254
|
end
|
251
255
|
|
256
|
+
# MSSQL doesn't support the SQL standard CURRENT_DATE or CURRENT_TIME
|
257
|
+
def constant_sql(constant)
|
258
|
+
CONSTANT_MAP[constant] || super
|
259
|
+
end
|
260
|
+
|
252
261
|
# SQLite performs a TRUNCATE style DELETE if no filter is specified.
|
253
262
|
# Since we want to always return the count of records, add a condition
|
254
263
|
# that is always true and then delete.
|
@@ -284,6 +293,12 @@ module Sequel
|
|
284
293
|
def supports_is_true?
|
285
294
|
false
|
286
295
|
end
|
296
|
+
|
297
|
+
# SQLite supports timezones in literal timestamps, since it stores them
|
298
|
+
# as text.
|
299
|
+
def supports_timestamp_timezones?
|
300
|
+
true
|
301
|
+
end
|
287
302
|
|
288
303
|
private
|
289
304
|
|
@@ -304,6 +319,11 @@ module Sequel
|
|
304
319
|
def select_clause_order
|
305
320
|
SELECT_CLAUSE_ORDER
|
306
321
|
end
|
322
|
+
|
323
|
+
# SQLite treats a DELETE with no WHERE clause as a TRUNCATE
|
324
|
+
def _truncate_sql(table)
|
325
|
+
"DELETE FROM #{table}"
|
326
|
+
end
|
307
327
|
end
|
308
328
|
end
|
309
329
|
end
|