sequel 3.21.0 → 3.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +485 -3
- data/README.rdoc +20 -6
- data/Rakefile +37 -19
- data/bin/sequel +1 -5
- data/doc/association_basics.rdoc +249 -43
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/dataset_filtering.rdoc +8 -0
- data/doc/mass_assignment.rdoc +54 -0
- data/doc/migration.rdoc +15 -538
- data/doc/model_hooks.rdoc +72 -27
- data/doc/opening_databases.rdoc +89 -50
- data/doc/prepared_statements.rdoc +40 -13
- data/doc/reflection.rdoc +8 -2
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/schema_modification.rdoc +547 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +129 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +5 -7
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/do.rb +17 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +448 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +45 -0
- data/lib/sequel/adapters/jdbc/derby.rb +247 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +56 -29
- data/lib/sequel/adapters/jdbc/hsqldb.rb +170 -0
- data/lib/sequel/adapters/jdbc/informix.rb +26 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +11 -11
- data/lib/sequel/adapters/jdbc/oracle.rb +81 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +9 -13
- data/lib/sequel/adapters/jdbc/sqlite.rb +2 -6
- data/lib/sequel/adapters/jdbc/sqlserver.rb +71 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +231 -78
- data/lib/sequel/adapters/mock.rb +335 -0
- data/lib/sequel/adapters/mysql.rb +82 -184
- data/lib/sequel/adapters/mysql2.rb +26 -25
- data/lib/sequel/adapters/odbc/db2.rb +17 -0
- data/lib/sequel/adapters/odbc/mssql.rb +1 -6
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +351 -53
- data/lib/sequel/adapters/postgres.rb +194 -33
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +321 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +231 -106
- data/lib/sequel/adapters/shared/mysql.rb +181 -63
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +231 -41
- data/lib/sequel/adapters/shared/postgres.rb +214 -82
- data/lib/sequel/adapters/shared/progress.rb +4 -7
- data/lib/sequel/adapters/shared/sqlite.rb +201 -57
- data/lib/sequel/adapters/sqlite.rb +29 -21
- data/lib/sequel/adapters/swift/mysql.rb +12 -7
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +8 -6
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/tinytds.rb +160 -19
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +190 -0
- data/lib/sequel/connection_pool/threaded.rb +3 -2
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +46 -5
- data/lib/sequel/database/connecting.rb +5 -6
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +59 -1
- data/lib/sequel/database/logging.rb +1 -1
- data/lib/sequel/database/misc.rb +104 -19
- data/lib/sequel/database/query.rb +153 -58
- data/lib/sequel/database/schema_generator.rb +17 -7
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +231 -76
- data/lib/sequel/dataset/features.rb +91 -8
- data/lib/sequel/dataset/graph.rb +38 -11
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +5 -6
- data/lib/sequel/dataset/prepared_statements.rb +48 -27
- data/lib/sequel/dataset/query.rb +236 -43
- data/lib/sequel/dataset/sql.rb +665 -253
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/extensions/migration.rb +6 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +1020 -337
- data/lib/sequel/model/base.rb +414 -132
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +15 -8
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +114 -7
- data/lib/sequel/plugins/many_through_many.rb +65 -7
- data/lib/sequel/plugins/prepared_statements.rb +151 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +88 -44
- data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +109 -52
- data/lib/sequel/timezones.rb +57 -38
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/mssql_spec.rb +111 -29
- data/spec/adapters/mysql_spec.rb +135 -123
- data/spec/adapters/oracle_spec.rb +49 -77
- data/spec/adapters/postgres_spec.rb +267 -78
- data/spec/adapters/spec_helper.rb +6 -5
- data/spec/adapters/sqlite_spec.rb +35 -21
- data/spec/core/connection_pool_spec.rb +71 -92
- data/spec/core/core_sql_spec.rb +21 -30
- data/spec/core/database_spec.rb +788 -512
- data/spec/core/dataset_spec.rb +1073 -1053
- data/spec/core/expression_filters_spec.rb +159 -42
- data/spec/core/mock_adapter_spec.rb +419 -0
- data/spec/core/object_graph_spec.rb +86 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +298 -38
- data/spec/core/spec_helper.rb +6 -48
- data/spec/extensions/association_autoreloading_spec.rb +1 -10
- data/spec/extensions/association_dependencies_spec.rb +2 -12
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/caching_spec.rb +23 -50
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/hook_class_methods_spec.rb +65 -91
- data/spec/extensions/identity_map_spec.rb +114 -22
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +53 -0
- data/spec/extensions/json_serializer_spec.rb +4 -5
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +17 -39
- data/spec/extensions/many_through_many_spec.rb +283 -250
- data/spec/extensions/migration_spec.rb +35 -32
- data/spec/extensions/named_timezones_spec.rb +23 -3
- data/spec/extensions/nested_attributes_spec.rb +97 -88
- data/spec/extensions/optimistic_locking_spec.rb +9 -20
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +53 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +1 -6
- data/spec/extensions/rcte_tree_spec.rb +41 -43
- data/spec/extensions/schema_dumper_spec.rb +5 -8
- data/spec/extensions/schema_spec.rb +13 -21
- data/spec/extensions/serialization_modification_detection_spec.rb +37 -0
- data/spec/extensions/serialization_spec.rb +72 -43
- data/spec/extensions/sharding_spec.rb +66 -140
- data/spec/extensions/single_table_inheritance_spec.rb +18 -29
- data/spec/extensions/spec_helper.rb +13 -61
- data/spec/extensions/sql_expr_spec.rb +20 -60
- data/spec/extensions/tactical_eager_loading_spec.rb +9 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +4 -7
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +30 -51
- data/spec/extensions/validation_helpers_spec.rb +16 -35
- data/spec/extensions/xml_serializer_spec.rb +16 -4
- data/spec/integration/associations_test.rb +537 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +461 -65
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +304 -116
- data/spec/integration/prepared_statement_test.rb +212 -122
- data/spec/integration/schema_test.rb +161 -30
- data/spec/integration/spec_helper.rb +39 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +172 -5
- data/spec/integration/type_test.rb +17 -3
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +865 -662
- data/spec/model/base_spec.rb +275 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +677 -676
- data/spec/model/hooks_spec.rb +309 -67
- data/spec/model/model_spec.rb +222 -168
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +381 -218
- data/spec/model/spec_helper.rb +13 -71
- data/spec/model/validations_spec.rb +11 -0
- metadata +115 -73
|
@@ -6,30 +6,55 @@ describe "Database schema parser" do
|
|
|
6
6
|
@iom = INTEGRATION_DB.identifier_output_method
|
|
7
7
|
@iim = INTEGRATION_DB.identifier_input_method
|
|
8
8
|
@defsch = INTEGRATION_DB.default_schema
|
|
9
|
-
|
|
9
|
+
@qi = INTEGRATION_DB.quote_identifiers?
|
|
10
10
|
end
|
|
11
11
|
after do
|
|
12
12
|
INTEGRATION_DB.identifier_output_method = @iom
|
|
13
13
|
INTEGRATION_DB.identifier_input_method = @iim
|
|
14
14
|
INTEGRATION_DB.default_schema = @defsch
|
|
15
|
+
INTEGRATION_DB.quote_identifiers = @qi
|
|
15
16
|
INTEGRATION_DB.drop_table(:items) if INTEGRATION_DB.table_exists?(:items)
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
specify "should handle a database with a
|
|
19
|
+
specify "should handle a database with a identifier methods" do
|
|
19
20
|
INTEGRATION_DB.identifier_output_method = :reverse
|
|
20
21
|
INTEGRATION_DB.identifier_input_method = :reverse
|
|
22
|
+
INTEGRATION_DB.quote_identifiers = true
|
|
21
23
|
INTEGRATION_DB.default_schema = nil if INTEGRATION_DB.default_schema
|
|
22
24
|
INTEGRATION_DB.create_table!(:items){Integer :number}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
begin
|
|
26
|
+
INTEGRATION_DB.schema(:items, :reload=>true).should be_a_kind_of(Array)
|
|
27
|
+
INTEGRATION_DB.schema(:items, :reload=>true).first.first.should == :number
|
|
28
|
+
ensure
|
|
29
|
+
INTEGRATION_DB.drop_table(:items)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
specify "should handle a dataset with identifier methods different than the database's" do
|
|
34
|
+
INTEGRATION_DB.identifier_output_method = :reverse
|
|
35
|
+
INTEGRATION_DB.identifier_input_method = :reverse
|
|
36
|
+
INTEGRATION_DB.quote_identifiers = true
|
|
37
|
+
INTEGRATION_DB.default_schema = nil if INTEGRATION_DB.default_schema
|
|
38
|
+
INTEGRATION_DB.create_table!(:items){Integer :number}
|
|
39
|
+
INTEGRATION_DB.identifier_output_method = @iom
|
|
40
|
+
INTEGRATION_DB.identifier_input_method = @iim
|
|
41
|
+
ds = INTEGRATION_DB[:items]
|
|
42
|
+
ds.identifier_output_method = :reverse
|
|
43
|
+
ds.identifier_input_method = :reverse
|
|
44
|
+
begin
|
|
45
|
+
INTEGRATION_DB.schema(ds, :reload=>true).should be_a_kind_of(Array)
|
|
46
|
+
INTEGRATION_DB.schema(ds, :reload=>true).first.first.should == :number
|
|
47
|
+
ensure
|
|
48
|
+
INTEGRATION_DB.identifier_output_method = :reverse
|
|
49
|
+
INTEGRATION_DB.identifier_input_method = :reverse
|
|
50
|
+
INTEGRATION_DB.drop_table(:items)
|
|
51
|
+
end
|
|
25
52
|
end
|
|
26
53
|
|
|
27
54
|
specify "should not issue an sql query if the schema has been loaded unless :reload is true" do
|
|
28
55
|
INTEGRATION_DB.create_table!(:items){Integer :number}
|
|
29
56
|
INTEGRATION_DB.schema(:items, :reload=>true)
|
|
30
|
-
clear_sqls
|
|
31
57
|
INTEGRATION_DB.schema(:items)
|
|
32
|
-
clear_sqls
|
|
33
58
|
INTEGRATION_DB.schema(:items, :reload=>true)
|
|
34
59
|
end
|
|
35
60
|
|
|
@@ -56,11 +81,10 @@ describe "Database schema parser" do
|
|
|
56
81
|
col_info = col.last
|
|
57
82
|
col_info.should be_a_kind_of(Hash)
|
|
58
83
|
col_info[:type].should == :integer
|
|
59
|
-
clear_sqls
|
|
60
84
|
INTEGRATION_DB.schema(:items)
|
|
61
85
|
end
|
|
62
86
|
|
|
63
|
-
|
|
87
|
+
specify "should parse primary keys from the schema properly" do
|
|
64
88
|
INTEGRATION_DB.create_table!(:items){Integer :number}
|
|
65
89
|
INTEGRATION_DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.should == []
|
|
66
90
|
INTEGRATION_DB.create_table!(:items){primary_key :number}
|
|
@@ -85,7 +109,7 @@ describe "Database schema parser" do
|
|
|
85
109
|
INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == 'blah'
|
|
86
110
|
end
|
|
87
111
|
|
|
88
|
-
|
|
112
|
+
cspecify "should parse types from the schema properly", [:jdbc, :db2], :oracle do
|
|
89
113
|
INTEGRATION_DB.create_table!(:items){Integer :number}
|
|
90
114
|
INTEGRATION_DB.schema(:items).first.last[:type].should == :integer
|
|
91
115
|
INTEGRATION_DB.create_table!(:items){Fixnum :number}
|
|
@@ -156,7 +180,6 @@ describe "Database schema modifiers" do
|
|
|
156
180
|
before do
|
|
157
181
|
@db = INTEGRATION_DB
|
|
158
182
|
@ds = @db[:items]
|
|
159
|
-
clear_sqls
|
|
160
183
|
end
|
|
161
184
|
after do
|
|
162
185
|
@db.drop_table(:items) if @db.table_exists?(:items)
|
|
@@ -174,6 +197,24 @@ describe "Database schema modifiers" do
|
|
|
174
197
|
@db.create_table!(:items, :temp=>true){Integer :number}
|
|
175
198
|
end
|
|
176
199
|
|
|
200
|
+
specify "should have create_table? only create the table if it doesn't already exist" do
|
|
201
|
+
@db.create_table!(:items){String :a}
|
|
202
|
+
@db.create_table?(:items){String :b}
|
|
203
|
+
@db[:items].columns.should == [:a]
|
|
204
|
+
@db.drop_table(:items) rescue nil
|
|
205
|
+
@db.create_table?(:items){String :b}
|
|
206
|
+
@db[:items].columns.should == [:b]
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
specify "should have create_table? work correctly with indexes" do
|
|
210
|
+
@db.create_table!(:items){String :a, :index=>true}
|
|
211
|
+
@db.create_table?(:items){String :b, :index=>true}
|
|
212
|
+
@db[:items].columns.should == [:a]
|
|
213
|
+
@db.drop_table(:items) rescue nil
|
|
214
|
+
@db.create_table?(:items){String :b, :index=>true}
|
|
215
|
+
@db[:items].columns.should == [:b]
|
|
216
|
+
end
|
|
217
|
+
|
|
177
218
|
specify "should rename tables correctly" do
|
|
178
219
|
@db.drop_table(:items) rescue nil
|
|
179
220
|
@db.create_table!(:items2){Integer :number}
|
|
@@ -215,24 +256,34 @@ describe "Database schema modifiers" do
|
|
|
215
256
|
specify "should add columns to tables correctly" do
|
|
216
257
|
@db.create_table!(:items){Integer :number}
|
|
217
258
|
@ds.insert(:number=>10)
|
|
218
|
-
@db.alter_table(:items){add_column :name,
|
|
259
|
+
@db.alter_table(:items){add_column :name, String}
|
|
219
260
|
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :name]
|
|
220
261
|
@ds.columns!.should == [:number, :name]
|
|
221
262
|
@ds.all.should == [{:number=>10, :name=>nil}]
|
|
222
263
|
end
|
|
223
264
|
|
|
224
|
-
cspecify "should add primary key columns to tables correctly", :h2 do
|
|
265
|
+
cspecify "should add primary key columns to tables correctly", :h2, :derby do
|
|
225
266
|
@db.create_table!(:items){Integer :number}
|
|
226
267
|
@ds.insert(:number=>10)
|
|
227
268
|
@db.alter_table(:items){add_primary_key :id}
|
|
228
269
|
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :id]
|
|
229
270
|
@ds.columns!.should == [:number, :id]
|
|
230
271
|
@ds.map(:number).should == [10]
|
|
272
|
+
proc{@ds.insert(:id=>@ds.map(:id).first)}.should raise_error
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
specify "should drop primary key constraints from tables correctly" do
|
|
276
|
+
@db.create_table!(:items){Integer :number; primary_key [:number], :name=>:items_pk}
|
|
277
|
+
@ds.insert(:number=>10)
|
|
278
|
+
@db.alter_table(:items){drop_constraint :items_pk, :type=>:primary_key}
|
|
279
|
+
@ds.map(:number).should == [10]
|
|
280
|
+
proc{@ds.insert(10)}.should_not raise_error
|
|
231
281
|
end
|
|
232
282
|
|
|
233
283
|
specify "should add foreign key columns to tables correctly" do
|
|
234
284
|
@db.create_table!(:items){primary_key :id}
|
|
235
|
-
|
|
285
|
+
@ds.insert
|
|
286
|
+
i = @ds.get(:id)
|
|
236
287
|
@db.alter_table(:items){add_foreign_key :item_id, :items}
|
|
237
288
|
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
|
238
289
|
@ds.columns!.should == [:id, :item_id]
|
|
@@ -269,7 +320,7 @@ describe "Database schema modifiers" do
|
|
|
269
320
|
proc{@ds.insert(:n=>nil)}.should raise_error(Sequel::DatabaseError)
|
|
270
321
|
end
|
|
271
322
|
|
|
272
|
-
|
|
323
|
+
cspecify "should set column NULL/NOT NULL correctly", [:jdbc, :db2], [:db2] do
|
|
273
324
|
@db.create_table!(:items, :engine=>:InnoDB){Integer :id}
|
|
274
325
|
@ds.insert(:id=>10)
|
|
275
326
|
@db.alter_table(:items){set_column_allow_null :id, false}
|
|
@@ -277,7 +328,7 @@ describe "Database schema modifiers" do
|
|
|
277
328
|
@ds.columns!.should == [:id]
|
|
278
329
|
proc{@ds.insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
|
|
279
330
|
@db.alter_table(:items){set_column_allow_null :id, true}
|
|
280
|
-
@ds.insert
|
|
331
|
+
@ds.insert(:id=>nil)
|
|
281
332
|
@ds.all.should == [{:id=>10}, {:id=>nil}]
|
|
282
333
|
end
|
|
283
334
|
|
|
@@ -291,27 +342,60 @@ describe "Database schema modifiers" do
|
|
|
291
342
|
@ds.all.should == [{:id=>10}, {:id=>20}]
|
|
292
343
|
end
|
|
293
344
|
|
|
294
|
-
|
|
345
|
+
cspecify "should set column types correctly", [:jdbc, :db2], [:db2], :oracle do
|
|
295
346
|
@db.create_table!(:items){Integer :id}
|
|
296
347
|
@ds.insert(:id=>10)
|
|
297
348
|
@db.alter_table(:items){set_column_type :id, String}
|
|
298
349
|
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
|
299
350
|
@ds.columns!.should == [:id]
|
|
300
|
-
@ds.insert(:id=>20)
|
|
351
|
+
@ds.insert(:id=>'20')
|
|
301
352
|
@ds.all.should == [{:id=>"10"}, {:id=>"20"}]
|
|
302
353
|
end
|
|
303
354
|
|
|
304
|
-
|
|
305
|
-
@db.create_table!(:items){Integer :id; Integer :item_id}
|
|
355
|
+
specify "should add unnamed unique constraints and foreign key table constraints correctly" do
|
|
356
|
+
@db.create_table!(:items, :engine=>:InnoDB){Integer :id; Integer :item_id}
|
|
306
357
|
@db.alter_table(:items) do
|
|
307
358
|
add_unique_constraint [:item_id, :id]
|
|
308
359
|
add_foreign_key [:id, :item_id], :items, :key=>[:item_id, :id]
|
|
309
360
|
end
|
|
310
361
|
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
|
311
362
|
@ds.columns!.should == [:id, :item_id]
|
|
363
|
+
proc{@ds.insert(1, 1)}.should_not raise_error
|
|
364
|
+
proc{@ds.insert(1, 1)}.should raise_error
|
|
365
|
+
proc{@ds.insert(1, 2)}.should raise_error
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
specify "should add named unique constraints and foreign key table constraints correctly" do
|
|
369
|
+
@db.create_table!(:items, :engine=>:InnoDB){Integer :id, :null=>false; Integer :item_id, :null=>false}
|
|
370
|
+
@db.alter_table(:items) do
|
|
371
|
+
add_unique_constraint [:item_id, :id], :name=>:unique_iii
|
|
372
|
+
add_foreign_key [:id, :item_id], :items, :key=>[:item_id, :id], :name=>:fk_iii
|
|
373
|
+
end
|
|
374
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
|
375
|
+
@ds.columns!.should == [:id, :item_id]
|
|
376
|
+
proc{@ds.insert(1, 1)}.should_not raise_error
|
|
377
|
+
proc{@ds.insert(1, 1)}.should raise_error
|
|
378
|
+
proc{@ds.insert(1, 2)}.should raise_error
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
specify "should drop unique constraints and foreign key table constraints correctly" do
|
|
382
|
+
@db.create_table!(:items) do
|
|
383
|
+
Integer :id
|
|
384
|
+
Integer :item_id
|
|
385
|
+
unique [:item_id, :id], :name=>:items_uk
|
|
386
|
+
foreign_key [:id, :item_id], :items, :key=>[:item_id, :id], :name=>:items_fk
|
|
387
|
+
end
|
|
388
|
+
@db.alter_table(:items) do
|
|
389
|
+
drop_constraint(:items_fk, :type=>:foreign_key)
|
|
390
|
+
drop_constraint(:items_uk, :type=>:unique)
|
|
391
|
+
end
|
|
392
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
|
393
|
+
@ds.columns!.should == [:id, :item_id]
|
|
394
|
+
proc{@ds.insert(1, 2)}.should_not raise_error
|
|
395
|
+
proc{@ds.insert(1, 2)}.should_not raise_error
|
|
312
396
|
end
|
|
313
397
|
|
|
314
|
-
cspecify "should remove columns from tables correctly", :h2, :mssql do
|
|
398
|
+
cspecify "should remove columns from tables correctly", :h2, :mssql, [:jdbc, :db2], :hsqldb do
|
|
315
399
|
@db.create_table!(:items) do
|
|
316
400
|
primary_key :id
|
|
317
401
|
String :name
|
|
@@ -332,7 +416,7 @@ describe "Database schema modifiers" do
|
|
|
332
416
|
@ds.columns!.should == [:id]
|
|
333
417
|
end
|
|
334
418
|
|
|
335
|
-
|
|
419
|
+
cspecify "should remove multiple columns in a single alter_table block", [:jdbc, :db2] do
|
|
336
420
|
@db.create_table!(:items) do
|
|
337
421
|
primary_key :id
|
|
338
422
|
String :name
|
|
@@ -362,25 +446,72 @@ describe "Database#tables" do
|
|
|
362
446
|
"xxxxx#{@@xxxxx += 1}"
|
|
363
447
|
end
|
|
364
448
|
end
|
|
365
|
-
@
|
|
366
|
-
@
|
|
367
|
-
|
|
449
|
+
@db = INTEGRATION_DB
|
|
450
|
+
@db.create_table(:sequel_test_table){Integer :a}
|
|
451
|
+
@db.create_view :sequel_test_view, @db[:sequel_test_table]
|
|
452
|
+
@iom = @db.identifier_output_method
|
|
453
|
+
@iim = @db.identifier_input_method
|
|
368
454
|
end
|
|
369
455
|
after do
|
|
370
|
-
|
|
371
|
-
|
|
456
|
+
@db.identifier_output_method = @iom
|
|
457
|
+
@db.identifier_input_method = @iim
|
|
458
|
+
@db.drop_view :sequel_test_view
|
|
459
|
+
@db.drop_table :sequel_test_table
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
specify "should return an array of symbols" do
|
|
463
|
+
ts = @db.tables
|
|
464
|
+
ts.should be_a_kind_of(Array)
|
|
465
|
+
ts.each{|t| t.should be_a_kind_of(Symbol)}
|
|
466
|
+
ts.should include(:sequel_test_table)
|
|
467
|
+
ts.should_not include(:sequel_test_view)
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
specify "should respect the database's identifier_output_method" do
|
|
471
|
+
@db.identifier_output_method = :xxxxx
|
|
472
|
+
@db.identifier_input_method = :xxxxx
|
|
473
|
+
@db.tables.each{|t| t.to_s.should =~ /\Ax{5}\d+\z/}
|
|
474
|
+
end
|
|
475
|
+
end
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
begin
|
|
479
|
+
INTEGRATION_DB.views
|
|
480
|
+
rescue Sequel::NotImplemented
|
|
481
|
+
rescue
|
|
482
|
+
describe "Database#views" do
|
|
483
|
+
before do
|
|
484
|
+
class ::String
|
|
485
|
+
@@xxxxx = 0
|
|
486
|
+
def xxxxx
|
|
487
|
+
"xxxxx#{@@xxxxx += 1}"
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
@db = INTEGRATION_DB
|
|
491
|
+
@db.create_table(:sequel_test_table){Integer :a}
|
|
492
|
+
@db.create_view :sequel_test_view, @db[:sequel_test_table]
|
|
493
|
+
@iom = @db.identifier_output_method
|
|
494
|
+
@iim = @db.identifier_input_method
|
|
495
|
+
end
|
|
496
|
+
after do
|
|
497
|
+
@db.identifier_output_method = @iom
|
|
498
|
+
@db.identifier_input_method = @iim
|
|
499
|
+
@db.drop_view :sequel_test_view
|
|
500
|
+
@db.drop_table :sequel_test_table
|
|
372
501
|
end
|
|
373
502
|
|
|
374
503
|
specify "should return an array of symbols" do
|
|
375
|
-
ts =
|
|
504
|
+
ts = @db.views
|
|
376
505
|
ts.should be_a_kind_of(Array)
|
|
377
506
|
ts.each{|t| t.should be_a_kind_of(Symbol)}
|
|
507
|
+
ts.should_not include(:sequel_test_table)
|
|
508
|
+
ts.should include(:sequel_test_view)
|
|
378
509
|
end
|
|
379
510
|
|
|
380
511
|
specify "should respect the database's identifier_output_method" do
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
512
|
+
@db.identifier_output_method = :xxxxx
|
|
513
|
+
@db.identifier_input_method = :xxxxx
|
|
514
|
+
@db.views.each{|t| t.to_s.should =~ /\Ax{5}\d+\z/}
|
|
384
515
|
end
|
|
385
516
|
end
|
|
386
517
|
end
|
|
@@ -9,12 +9,12 @@ begin
|
|
|
9
9
|
rescue LoadError
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
if ENV['SEQUEL_COLUMNS_INTROSPECTION']
|
|
13
|
+
Sequel.extension :columns_introspection
|
|
14
|
+
Sequel::Dataset.introspect_all_columns
|
|
15
|
+
end
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
def clear_sqls
|
|
16
|
-
$sqls.clear
|
|
17
|
-
end
|
|
17
|
+
Sequel::Model.use_transactions = false
|
|
18
18
|
|
|
19
19
|
unless defined?(RSpec)
|
|
20
20
|
module Spec::Matchers
|
|
@@ -29,45 +29,45 @@ unless defined?(RSpec)
|
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
begin
|
|
35
|
-
INTEGRATION_DB.loggers << Logger.new(STDOUT)
|
|
36
|
-
yield
|
|
37
|
-
ensure
|
|
38
|
-
INTEGRATION_DB.loggers.pop
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def self.log_specify(message, &block)
|
|
43
|
-
specify(message){log{instance_eval(&block)}}
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def self.cspecify(message, *checked, &block)
|
|
47
|
-
pending = false
|
|
32
|
+
def Sequel.guarded?(*checked)
|
|
33
|
+
unless ENV['SEQUEL_NO_PENDING']
|
|
48
34
|
checked.each do |c|
|
|
49
35
|
case c
|
|
50
36
|
when INTEGRATION_DB.database_type
|
|
51
|
-
|
|
37
|
+
return c
|
|
52
38
|
when Array
|
|
53
39
|
case c.length
|
|
54
40
|
when 1
|
|
55
|
-
|
|
41
|
+
return c if c.first == INTEGRATION_DB.adapter_scheme
|
|
56
42
|
when 2
|
|
57
43
|
if c.first.is_a?(Proc)
|
|
58
|
-
|
|
44
|
+
return c if c.first.call(INTEGRATION_DB) && c.last == INTEGRATION_DB.database_type
|
|
59
45
|
elsif c.last.is_a?(Proc)
|
|
60
|
-
|
|
46
|
+
return c if c.first == INTEGRATION_DB.adapter_scheme && c.last.call(INTEGRATION_DB)
|
|
61
47
|
else
|
|
62
|
-
|
|
48
|
+
return c if c.first == INTEGRATION_DB.adapter_scheme && c.last == INTEGRATION_DB.database_type
|
|
63
49
|
end
|
|
64
50
|
when 3
|
|
65
|
-
|
|
51
|
+
return c if c[0] == INTEGRATION_DB.adapter_scheme && c[1] == INTEGRATION_DB.database_type && c[2].call(INTEGRATION_DB)
|
|
66
52
|
end
|
|
67
53
|
end
|
|
68
|
-
break if pending
|
|
69
54
|
end
|
|
70
|
-
|
|
55
|
+
end
|
|
56
|
+
false
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
(defined?(RSpec) ? RSpec::Core::ExampleGroup : Spec::Example::ExampleGroup).class_eval do
|
|
60
|
+
def log
|
|
61
|
+
begin
|
|
62
|
+
INTEGRATION_DB.loggers << Logger.new(STDOUT)
|
|
63
|
+
yield
|
|
64
|
+
ensure
|
|
65
|
+
INTEGRATION_DB.loggers.pop
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def self.cspecify(message, *checked, &block)
|
|
70
|
+
if pending = Sequel.guarded?(*checked)
|
|
71
71
|
specify(message){pending("Not yet working on #{Array(pending).join(', ')}", &block)}
|
|
72
72
|
else
|
|
73
73
|
specify(message, &block)
|
|
@@ -82,5 +82,14 @@ if defined?(INTEGRATION_DB) || defined?(INTEGRATION_URL) || ENV['SEQUEL_INTEGRAT
|
|
|
82
82
|
#INTEGRATION_DB.instance_variable_set(:@server_version, 80100)
|
|
83
83
|
end
|
|
84
84
|
else
|
|
85
|
-
INTEGRATION_DB = Sequel.sqlite
|
|
85
|
+
INTEGRATION_DB = Sequel.sqlite
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
if INTEGRATION_DB.adapter_scheme == :ibmdb
|
|
89
|
+
def INTEGRATION_DB.drop_table(*tables)
|
|
90
|
+
super
|
|
91
|
+
rescue Sequel::DatabaseError
|
|
92
|
+
disconnect
|
|
93
|
+
super
|
|
94
|
+
end
|
|
86
95
|
end
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
|
2
2
|
|
|
3
3
|
describe "Sequel timezone support" do
|
|
4
|
-
def test_timezone
|
|
4
|
+
def test_timezone(timezone=Sequel.application_timezone)
|
|
5
|
+
tz = timezone
|
|
6
|
+
Sequel.datetime_class = Time
|
|
5
7
|
# Tests should cover both DST and non-DST times.
|
|
6
8
|
[Time.now, Time.local(2010,1,1,12), Time.local(2010,6,1,12)].each do |t|
|
|
7
9
|
@db[:t].insert(t)
|
|
8
10
|
t2 = @db[:t].single_value
|
|
9
|
-
t2 =
|
|
11
|
+
t2 = @db.to_application_timestamp(t2.to_s) unless t2.is_a?(Time)
|
|
10
12
|
(t2 - t).should be_within(2).of(0)
|
|
11
|
-
t2.utc_offset.should == 0 if
|
|
12
|
-
t2.utc_offset.should == t.getlocal.utc_offset if
|
|
13
|
+
t2.utc_offset.should == 0 if timezone == :utc
|
|
14
|
+
t2.utc_offset.should == t.getlocal.utc_offset if timezone == :local
|
|
13
15
|
@db[:t].delete
|
|
14
16
|
end
|
|
15
17
|
|
|
@@ -19,10 +21,10 @@ describe "Sequel timezone support" do
|
|
|
19
21
|
[DateTime.now, DateTime.civil(2010,1,1,12,0,0,local_std_offset), DateTime.civil(2010,6,1,12,0,0,local_dst_offset)].each do |dt|
|
|
20
22
|
@db[:t].insert(dt)
|
|
21
23
|
dt2 = @db[:t].single_value
|
|
22
|
-
dt2 =
|
|
24
|
+
dt2 = @db.to_application_timestamp(dt2.to_s) unless dt2.is_a?(DateTime)
|
|
23
25
|
(dt2 - dt).should be_within(0.00002).of(0)
|
|
24
|
-
dt2.offset.should == 0 if
|
|
25
|
-
dt2.offset.should == dt.offset if
|
|
26
|
+
dt2.offset.should == 0 if timezone == :utc
|
|
27
|
+
dt2.offset.should == dt.offset if timezone == :local
|
|
26
28
|
@db[:t].delete
|
|
27
29
|
end
|
|
28
30
|
end
|
|
@@ -32,30 +34,54 @@ describe "Sequel timezone support" do
|
|
|
32
34
|
@db.create_table!(:t){DateTime :t}
|
|
33
35
|
end
|
|
34
36
|
after do
|
|
35
|
-
@db.
|
|
37
|
+
@db.timezone = nil
|
|
36
38
|
Sequel.default_timezone = nil
|
|
37
39
|
Sequel.datetime_class = Time
|
|
40
|
+
@db.drop_table(:t)
|
|
38
41
|
end
|
|
39
42
|
|
|
40
|
-
cspecify "should support using UTC for database storage and local time for the application", [:swift], [:tinytds], [:do,
|
|
43
|
+
cspecify "should support using UTC for database storage and local time for the application", [:swift], [:tinytds], [:do, :mysql], [:do, :postgres], [:oracle] do
|
|
41
44
|
Sequel.database_timezone = :utc
|
|
42
45
|
Sequel.application_timezone = :local
|
|
43
46
|
test_timezone
|
|
47
|
+
Sequel.database_timezone = nil
|
|
48
|
+
@db.timezone = :utc
|
|
49
|
+
test_timezone
|
|
44
50
|
end
|
|
45
51
|
|
|
46
|
-
cspecify "should support using local time for database storage and UTC for the application", [:swift], [:tinytds], [:do,
|
|
52
|
+
cspecify "should support using local time for database storage and UTC for the application", [:swift], [:tinytds], [:do, :mysql], [:do, :postgres], [:oracle] do
|
|
47
53
|
Sequel.database_timezone = :local
|
|
48
54
|
Sequel.application_timezone = :utc
|
|
49
55
|
test_timezone
|
|
56
|
+
Sequel.database_timezone = nil
|
|
57
|
+
@db.timezone = :local
|
|
58
|
+
test_timezone
|
|
50
59
|
end
|
|
51
60
|
|
|
52
|
-
cspecify "should support using UTC for both database storage and for application", [:swift], [:do,
|
|
61
|
+
cspecify "should support using UTC for both database storage and for application", [:swift], [:do, :mysql], [:do, :postgres], [:oracle] do
|
|
53
62
|
Sequel.default_timezone = :utc
|
|
54
63
|
test_timezone
|
|
64
|
+
Sequel.database_timezone = :local
|
|
65
|
+
@db.timezone = :utc
|
|
66
|
+
test_timezone
|
|
55
67
|
end
|
|
56
68
|
|
|
57
|
-
cspecify "should support using local time for both database storage and for application", [:do,
|
|
69
|
+
cspecify "should support using local time for both database storage and for application", [:do, :mysql], [:do, :postgres], [:oracle] do
|
|
58
70
|
Sequel.default_timezone = :local
|
|
59
71
|
test_timezone
|
|
72
|
+
Sequel.database_timezone = :utc
|
|
73
|
+
@db.timezone = :local
|
|
74
|
+
test_timezone
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
specify "should allow overriding the database_timezone on a per-database basis" do
|
|
78
|
+
Sequel.database_timezone = :utc
|
|
79
|
+
@db.timezone = :local
|
|
80
|
+
t = Time.now
|
|
81
|
+
@db[:t].insert(t)
|
|
82
|
+
s = @db[:t].get(:t.cast(String))
|
|
83
|
+
if o = Date._parse(s)[:offset]
|
|
84
|
+
o.should == t.utc_offset
|
|
85
|
+
end
|
|
60
86
|
end
|
|
61
87
|
end
|