sequel 3.11.0 → 3.12.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 +70 -0
- data/Rakefile +1 -1
- data/doc/active_record.rdoc +896 -0
- data/doc/advanced_associations.rdoc +46 -31
- data/doc/association_basics.rdoc +14 -9
- data/doc/dataset_basics.rdoc +3 -3
- data/doc/migration.rdoc +1011 -0
- data/doc/model_hooks.rdoc +198 -0
- data/doc/querying.rdoc +811 -86
- data/doc/release_notes/3.12.0.txt +304 -0
- data/doc/sharding.rdoc +17 -0
- data/doc/sql.rdoc +537 -0
- data/doc/validations.rdoc +501 -0
- data/lib/sequel/adapters/jdbc.rb +19 -27
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -7
- data/lib/sequel/adapters/mysql.rb +5 -4
- data/lib/sequel/adapters/odbc.rb +3 -2
- data/lib/sequel/adapters/shared/mssql.rb +7 -6
- data/lib/sequel/adapters/shared/mysql.rb +2 -7
- data/lib/sequel/adapters/shared/postgres.rb +2 -8
- data/lib/sequel/adapters/shared/sqlite.rb +2 -5
- data/lib/sequel/adapters/sqlite.rb +4 -4
- data/lib/sequel/core.rb +0 -1
- data/lib/sequel/database.rb +2 -1060
- data/lib/sequel/database/connecting.rb +227 -0
- data/lib/sequel/database/dataset.rb +58 -0
- data/lib/sequel/database/dataset_defaults.rb +127 -0
- data/lib/sequel/database/logging.rb +62 -0
- data/lib/sequel/database/misc.rb +246 -0
- data/lib/sequel/database/query.rb +390 -0
- data/lib/sequel/database/schema_generator.rb +7 -3
- data/lib/sequel/database/schema_methods.rb +351 -7
- data/lib/sequel/dataset/actions.rb +9 -2
- data/lib/sequel/dataset/misc.rb +6 -2
- data/lib/sequel/dataset/mutation.rb +3 -11
- data/lib/sequel/dataset/query.rb +49 -6
- data/lib/sequel/exceptions.rb +3 -0
- data/lib/sequel/extensions/migration.rb +395 -113
- data/lib/sequel/extensions/schema_dumper.rb +21 -13
- data/lib/sequel/model.rb +27 -25
- data/lib/sequel/model/associations.rb +72 -34
- data/lib/sequel/model/base.rb +74 -18
- data/lib/sequel/model/errors.rb +8 -1
- data/lib/sequel/plugins/active_model.rb +8 -0
- data/lib/sequel/plugins/association_pks.rb +87 -0
- data/lib/sequel/plugins/association_proxies.rb +8 -0
- data/lib/sequel/plugins/boolean_readers.rb +12 -6
- data/lib/sequel/plugins/caching.rb +14 -7
- data/lib/sequel/plugins/class_table_inheritance.rb +15 -9
- data/lib/sequel/plugins/composition.rb +2 -1
- data/lib/sequel/plugins/force_encoding.rb +10 -7
- data/lib/sequel/plugins/hook_class_methods.rb +12 -11
- data/lib/sequel/plugins/identity_map.rb +9 -0
- data/lib/sequel/plugins/instance_hooks.rb +23 -13
- data/lib/sequel/plugins/lazy_attributes.rb +4 -1
- data/lib/sequel/plugins/many_through_many.rb +18 -4
- data/lib/sequel/plugins/nested_attributes.rb +1 -0
- data/lib/sequel/plugins/optimistic_locking.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +9 -8
- data/lib/sequel/plugins/schema.rb +8 -0
- data/lib/sequel/plugins/serialization.rb +1 -3
- data/lib/sequel/plugins/sharding.rb +135 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +117 -25
- data/lib/sequel/plugins/skip_create_refresh.rb +35 -0
- data/lib/sequel/plugins/string_stripper.rb +26 -0
- data/lib/sequel/plugins/tactical_eager_loading.rb +8 -0
- data/lib/sequel/plugins/timestamps.rb +15 -2
- data/lib/sequel/plugins/touch.rb +13 -0
- data/lib/sequel/plugins/update_primary_key.rb +48 -0
- data/lib/sequel/plugins/validation_class_methods.rb +8 -0
- data/lib/sequel/plugins/validation_helpers.rb +1 -1
- data/lib/sequel/sql.rb +17 -20
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +5 -5
- data/spec/core/core_sql_spec.rb +17 -1
- data/spec/core/database_spec.rb +17 -5
- data/spec/core/dataset_spec.rb +31 -8
- data/spec/core/schema_generator_spec.rb +8 -1
- data/spec/core/schema_spec.rb +13 -0
- data/spec/extensions/association_pks_spec.rb +85 -0
- data/spec/extensions/hook_class_methods_spec.rb +9 -9
- data/spec/extensions/migration_spec.rb +339 -219
- data/spec/extensions/schema_dumper_spec.rb +28 -17
- data/spec/extensions/sharding_spec.rb +272 -0
- data/spec/extensions/single_table_inheritance_spec.rb +92 -4
- data/spec/extensions/skip_create_refresh_spec.rb +17 -0
- data/spec/extensions/string_stripper_spec.rb +23 -0
- data/spec/extensions/update_primary_key_spec.rb +65 -0
- data/spec/extensions/validation_class_methods_spec.rb +5 -5
- data/spec/files/bad_down_migration/001_create_alt_basic.rb +4 -0
- data/spec/files/bad_down_migration/002_create_alt_advanced.rb +4 -0
- data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +9 -0
- data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +9 -0
- data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +3 -0
- data/spec/files/bad_up_migration/001_create_alt_basic.rb +4 -0
- data/spec/files/bad_up_migration/002_create_alt_advanced.rb +3 -0
- data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +9 -0
- data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +9 -0
- data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +4 -0
- data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +9 -0
- data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +9 -0
- data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +4 -0
- data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +9 -0
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +9 -0
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +4 -0
- data/spec/files/integer_migrations/001_create_sessions.rb +9 -0
- data/spec/files/integer_migrations/002_create_nodes.rb +9 -0
- data/spec/files/integer_migrations/003_3_create_users.rb +4 -0
- data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +9 -0
- data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +9 -0
- data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +9 -0
- data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +9 -0
- data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +4 -0
- data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +4 -0
- data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +9 -0
- data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +4 -0
- data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +9 -0
- data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +9 -0
- data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +4 -0
- data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +9 -0
- data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +9 -0
- data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +4 -0
- data/spec/integration/eager_loader_test.rb +20 -20
- data/spec/integration/migrator_test.rb +187 -0
- data/spec/integration/plugin_test.rb +150 -0
- data/spec/integration/schema_test.rb +13 -2
- data/spec/model/associations_spec.rb +41 -14
- data/spec/model/base_spec.rb +69 -0
- data/spec/model/eager_loading_spec.rb +7 -3
- data/spec/model/record_spec.rb +79 -4
- data/spec/model/validations_spec.rb +21 -9
- metadata +66 -5
- data/doc/schema.rdoc +0 -36
- data/lib/sequel/database/schema_sql.rb +0 -320
|
@@ -12,10 +12,10 @@ describe "Eagerly loading a tree structure" do
|
|
|
12
12
|
one_to_many :children, :key=>:parent_id
|
|
13
13
|
|
|
14
14
|
# Only useful when eager loading
|
|
15
|
-
many_to_one :ancestors, :eager_loader=>(proc do |
|
|
15
|
+
many_to_one :ancestors, :eager_loader=>(proc do |eo|
|
|
16
16
|
# Handle cases where the root node has the same parent_id as primary_key
|
|
17
17
|
# and also when it is NULL
|
|
18
|
-
non_root_nodes =
|
|
18
|
+
non_root_nodes = eo[:rows].reject do |n|
|
|
19
19
|
if [nil, n.pk].include?(n.parent_id)
|
|
20
20
|
# Make sure root nodes have their parent association set to nil
|
|
21
21
|
n.associations[:parent] = nil
|
|
@@ -36,9 +36,9 @@ describe "Eagerly loading a tree structure" do
|
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
end)
|
|
39
|
-
many_to_one :descendants, :eager_loader=>(proc do |
|
|
39
|
+
many_to_one :descendants, :eager_loader=>(proc do |eo|
|
|
40
40
|
id_map = {}
|
|
41
|
-
|
|
41
|
+
eo[:rows].each do |n|
|
|
42
42
|
# Initialize an empty array of child associations for each parent node
|
|
43
43
|
n.associations[:children] = []
|
|
44
44
|
# Populate identity map of nodes
|
|
@@ -186,9 +186,9 @@ describe "has_many :through has_many and has_one :through belongs_to" do
|
|
|
186
186
|
inv.client.associations[:firm] = inv.associations[:firm] = firm
|
|
187
187
|
end
|
|
188
188
|
end), \
|
|
189
|
-
:eager_loader=>(proc do |
|
|
190
|
-
id_map = key_hash[Firm.primary_key]
|
|
191
|
-
|
|
189
|
+
:eager_loader=>(proc do |eo|
|
|
190
|
+
id_map = eo[:key_hash][Firm.primary_key]
|
|
191
|
+
eo[:rows].each{|firm| firm.associations[:invoices] = []}
|
|
192
192
|
Invoice.eager_graph(:client).filter(:client__firm_id=>id_map.keys).all do |inv|
|
|
193
193
|
id_map[inv.client.firm_id].each do |firm|
|
|
194
194
|
firm.associations[:invoices] << inv
|
|
@@ -222,9 +222,9 @@ describe "has_many :through has_many and has_one :through belongs_to" do
|
|
|
222
222
|
end
|
|
223
223
|
inv.associations[:client] ||= firm.associations[:invoice_client]
|
|
224
224
|
end), \
|
|
225
|
-
:eager_loader=>(proc do |
|
|
225
|
+
:eager_loader=>(proc do |eo|
|
|
226
226
|
id_map = {}
|
|
227
|
-
|
|
227
|
+
eo[:rows].each do |inv|
|
|
228
228
|
inv.associations[:firm] = nil
|
|
229
229
|
(id_map[inv.client_id] ||= []) << inv
|
|
230
230
|
end
|
|
@@ -338,9 +338,9 @@ describe "Polymorphic Associations" do
|
|
|
338
338
|
klass = m.call(attachable_type)
|
|
339
339
|
klass.filter(klass.primary_key=>attachable_id)
|
|
340
340
|
end), \
|
|
341
|
-
:eager_loader=>(proc do |
|
|
341
|
+
:eager_loader=>(proc do |eo|
|
|
342
342
|
id_map = {}
|
|
343
|
-
|
|
343
|
+
eo[:rows].each do |asset|
|
|
344
344
|
asset.associations[:attachable] = nil
|
|
345
345
|
((id_map[asset.attachable_type] ||= {})[asset.attachable_id] ||= []) << asset
|
|
346
346
|
end
|
|
@@ -492,9 +492,9 @@ describe "many_to_one/one_to_many not referencing primary key" do
|
|
|
492
492
|
class ::Client < Sequel::Model
|
|
493
493
|
one_to_many :invoices, :reciprocal=>:client, \
|
|
494
494
|
:dataset=>proc{Invoice.filter(:client_name=>name)}, \
|
|
495
|
-
:eager_loader=>(proc do |
|
|
495
|
+
:eager_loader=>(proc do |eo|
|
|
496
496
|
id_map = {}
|
|
497
|
-
|
|
497
|
+
eo[:rows].each do |client|
|
|
498
498
|
id_map[client.name] = client
|
|
499
499
|
client.associations[:invoices] = []
|
|
500
500
|
end
|
|
@@ -526,9 +526,9 @@ describe "many_to_one/one_to_many not referencing primary key" do
|
|
|
526
526
|
class ::Invoice < Sequel::Model
|
|
527
527
|
many_to_one :client, :key=>:client_name, \
|
|
528
528
|
:dataset=>proc{Client.filter(:name=>client_name)}, \
|
|
529
|
-
:eager_loader=>(proc do |
|
|
530
|
-
id_map = key_hash[:client_name]
|
|
531
|
-
|
|
529
|
+
:eager_loader=>(proc do |eo|
|
|
530
|
+
id_map = eo[:key_hash][:client_name]
|
|
531
|
+
eo[:rows].each{|inv| inv.associations[:client] = nil}
|
|
532
532
|
Client.filter(:name=>id_map.keys).all do |client|
|
|
533
533
|
id_map[client.name].each{|inv| inv.associations[:client] = client}
|
|
534
534
|
end
|
|
@@ -626,13 +626,13 @@ describe "statistics associations" do
|
|
|
626
626
|
class ::Project < Sequel::Model
|
|
627
627
|
many_to_one :ticket_hours, :read_only=>true, :key=>:id, :class=>:Ticket,
|
|
628
628
|
:dataset=>proc{Ticket.filter(:project_id=>id).select{sum(hours).as(hours)}},
|
|
629
|
-
:eager_loader=>(proc do |
|
|
630
|
-
|
|
631
|
-
Ticket.filter(:project_id=>
|
|
629
|
+
:eager_loader=>(proc do |eo|
|
|
630
|
+
eo[:rows].each{|p| p.associations[:ticket_hours] = nil}
|
|
631
|
+
Ticket.filter(:project_id=>eo[:key_hash][:id].keys).
|
|
632
632
|
group(:project_id).
|
|
633
633
|
select{[project_id.as(project_id), sum(hours).as(hours)]}.
|
|
634
634
|
all do |t|
|
|
635
|
-
p =
|
|
635
|
+
p = eo[:key_hash][:id][t.values.delete(:project_id)].first
|
|
636
636
|
p.associations[:ticket_hours] = t
|
|
637
637
|
end
|
|
638
638
|
end)
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
|
2
|
+
|
|
3
|
+
Sequel.extension :migration
|
|
4
|
+
describe Sequel::Migrator do
|
|
5
|
+
before do
|
|
6
|
+
@db = INTEGRATION_DB
|
|
7
|
+
@m = Sequel::Migrator
|
|
8
|
+
end
|
|
9
|
+
after do
|
|
10
|
+
[:schema_info, :schema_migrations, :sm1111, :sm1122, :sm2222, :sm2233, :sm3333, :sm11111, :sm22222].each{|n| @db.drop_table(n) rescue nil}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
specify "should be able to migrate up and down all the way successfully" do
|
|
14
|
+
@dir = 'spec/files/integer_migrations'
|
|
15
|
+
@m.apply(@db, @dir)
|
|
16
|
+
[:schema_info, :sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_true}
|
|
17
|
+
@db[:schema_info].get(:version).should == 3
|
|
18
|
+
@m.apply(@db, @dir, 0)
|
|
19
|
+
[:sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_false}
|
|
20
|
+
@db[:schema_info].get(:version).should == 0
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
specify "should be able to migrate up and down to specific versions successfully" do
|
|
24
|
+
@dir = 'spec/files/integer_migrations'
|
|
25
|
+
@m.apply(@db, @dir, 2)
|
|
26
|
+
[:schema_info, :sm1111, :sm2222].each{|n| @db.table_exists?(n).should be_true}
|
|
27
|
+
@db.table_exists?(:sm3333).should be_false
|
|
28
|
+
@db[:schema_info].get(:version).should == 2
|
|
29
|
+
@m.apply(@db, @dir, 1)
|
|
30
|
+
[:sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_false}
|
|
31
|
+
@db.table_exists?(:sm1111).should be_true
|
|
32
|
+
@db[:schema_info].get(:version).should == 1
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
specify "should correctly set migration version to the last successful migration if the migration raises an error when migrating up" do
|
|
36
|
+
@dir = 'spec/files/bad_up_migration'
|
|
37
|
+
proc{@m.apply(@db, @dir)}.should raise_error
|
|
38
|
+
[:schema_info, :sm11111].each{|n| @db.table_exists?(n).should be_true}
|
|
39
|
+
@db.table_exists?(:sm22222).should be_false
|
|
40
|
+
@db[:schema_info].get(:version).should == 1
|
|
41
|
+
@m.apply(@db, @dir, 0)
|
|
42
|
+
[:sm11111, :sm22222].each{|n| @db.table_exists?(n).should be_false}
|
|
43
|
+
@db[:schema_info].get(:version).should == 0
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
specify "should correctly set migration version to the last successful migration if the migration raises an error when migrating down" do
|
|
47
|
+
@dir = 'spec/files/bad_down_migration'
|
|
48
|
+
@m.apply(@db, @dir)
|
|
49
|
+
[:schema_info, :sm11111, :sm22222].each{|n| @db.table_exists?(n).should be_true}
|
|
50
|
+
@db[:schema_info].get(:version).should == 2
|
|
51
|
+
proc{@m.apply(@db, @dir, 0)}.should raise_error
|
|
52
|
+
[:sm22222].each{|n| @db.table_exists?(n).should be_false}
|
|
53
|
+
@db.table_exists?(:sm11111).should be_true
|
|
54
|
+
@db[:schema_info].get(:version).should == 1
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
specify "should handle migrating up or down all the way with timestamped migrations" do
|
|
58
|
+
@dir = 'spec/files/timestamped_migrations'
|
|
59
|
+
@m.apply(@db, @dir)
|
|
60
|
+
[:schema_migrations, :sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_true}
|
|
61
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb 1273253851_create_nodes.rb 1273253853_3_create_users.rb'
|
|
62
|
+
@m.apply(@db, @dir, 0)
|
|
63
|
+
[:sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_false}
|
|
64
|
+
@db[:schema_migrations].select_order_map(:filename).should == []
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
specify "should handle migrating up or down to specific timestamps with timestamped migrations" do
|
|
68
|
+
@dir = 'spec/files/timestamped_migrations'
|
|
69
|
+
@m.apply(@db, @dir, 1273253851)
|
|
70
|
+
[:schema_migrations, :sm1111, :sm2222].each{|n| @db.table_exists?(n).should be_true}
|
|
71
|
+
@db.table_exists?(:sm3333).should be_false
|
|
72
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb 1273253851_create_nodes.rb'
|
|
73
|
+
@m.apply(@db, @dir, 1273253849)
|
|
74
|
+
[:sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_false}
|
|
75
|
+
@db.table_exists?(:sm1111).should be_true
|
|
76
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
specify "should apply all missing files when migrating up with timestamped migrations" do
|
|
80
|
+
@dir = 'spec/files/timestamped_migrations'
|
|
81
|
+
@m.apply(@db, @dir)
|
|
82
|
+
@dir = 'spec/files/interleaved_timestamped_migrations'
|
|
83
|
+
@m.apply(@db, @dir)
|
|
84
|
+
[:schema_migrations, :sm1111, :sm1122, :sm2222, :sm2233, :sm3333].each{|n| @db.table_exists?(n).should be_true}
|
|
85
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb 1273253850_create_artists.rb 1273253851_create_nodes.rb 1273253852_create_albums.rb 1273253853_3_create_users.rb'
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
specify "should not apply down action to migrations where up action hasn't been applied" do
|
|
89
|
+
@dir = 'spec/files/timestamped_migrations'
|
|
90
|
+
@m.apply(@db, @dir)
|
|
91
|
+
@dir = 'spec/files/interleaved_timestamped_migrations'
|
|
92
|
+
@m.apply(@db, @dir, 0)
|
|
93
|
+
[:sm1111, :sm1122, :sm2222, :sm2233, :sm3333].each{|n| @db.table_exists?(n).should be_false}
|
|
94
|
+
@db[:schema_migrations].select_order_map(:filename).should == []
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
specify "should handle updating to a specific timestamp when interleaving migrations with timestamps" do
|
|
98
|
+
@dir = 'spec/files/timestamped_migrations'
|
|
99
|
+
@m.apply(@db, @dir)
|
|
100
|
+
@dir = 'spec/files/interleaved_timestamped_migrations'
|
|
101
|
+
@m.apply(@db, @dir, 1273253851)
|
|
102
|
+
[:schema_migrations, :sm1111, :sm1122, :sm2222].each{|n| @db.table_exists?(n).should be_true}
|
|
103
|
+
[:sm2233, :sm3333].each{|n| @db.table_exists?(n).should be_false}
|
|
104
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb 1273253850_create_artists.rb 1273253851_create_nodes.rb'
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
specify "should correctly update schema_migrations table when an error occurs when migrating up or down using timestamped migrations" do
|
|
108
|
+
@dir = 'spec/files/bad_timestamped_migrations'
|
|
109
|
+
proc{@m.apply(@db, @dir)}.should raise_error
|
|
110
|
+
[:schema_migrations, :sm1111, :sm2222].each{|n| @db.table_exists?(n).should be_true}
|
|
111
|
+
@db.table_exists?(:sm3333).should be_false
|
|
112
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb 1273253851_create_nodes.rb'
|
|
113
|
+
proc{@m.apply(@db, @dir, 0)}.should raise_error
|
|
114
|
+
[:sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_false}
|
|
115
|
+
@db.table_exists?(:sm1111).should be_true
|
|
116
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb'
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
specify "should handle multiple migrations with the same timestamp correctly" do
|
|
120
|
+
@dir = 'spec/files/duplicate_timestamped_migrations'
|
|
121
|
+
@m.apply(@db, @dir)
|
|
122
|
+
[:schema_migrations, :sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_true}
|
|
123
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb 1273253853_create_nodes.rb 1273253853_create_users.rb'
|
|
124
|
+
@m.apply(@db, @dir, 1273253853)
|
|
125
|
+
[:sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_true}
|
|
126
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb 1273253853_create_nodes.rb 1273253853_create_users.rb'
|
|
127
|
+
@m.apply(@db, @dir, 1273253849)
|
|
128
|
+
[:sm1111].each{|n| @db.table_exists?(n).should be_true}
|
|
129
|
+
[:sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_false}
|
|
130
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb'
|
|
131
|
+
@m.apply(@db, @dir, 1273253848)
|
|
132
|
+
[:sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_false}
|
|
133
|
+
@db[:schema_migrations].select_order_map(:filename).should == []
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
specify "should convert schema_info table to schema_migrations table" do
|
|
137
|
+
@dir = 'spec/files/integer_migrations'
|
|
138
|
+
@m.apply(@db, @dir)
|
|
139
|
+
[:schema_info, :sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_true}
|
|
140
|
+
[:schema_migrations, :sm1122, :sm2233].each{|n| @db.table_exists?(n).should be_false}
|
|
141
|
+
|
|
142
|
+
@dir = 'spec/files/convert_to_timestamp_migrations'
|
|
143
|
+
@m.apply(@db, @dir)
|
|
144
|
+
[:schema_info, :sm1111, :sm2222, :sm3333, :schema_migrations, :sm1122, :sm2233].each{|n| @db.table_exists?(n).should be_true}
|
|
145
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'001_create_sessions.rb 002_create_nodes.rb 003_3_create_users.rb 1273253850_create_artists.rb 1273253852_create_albums.rb'
|
|
146
|
+
|
|
147
|
+
@m.apply(@db, @dir, 4)
|
|
148
|
+
[:schema_info, :schema_migrations, :sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_true}
|
|
149
|
+
[:sm1122, :sm2233].each{|n| @db.table_exists?(n).should be_false}
|
|
150
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'001_create_sessions.rb 002_create_nodes.rb 003_3_create_users.rb'
|
|
151
|
+
|
|
152
|
+
@m.apply(@db, @dir, 0)
|
|
153
|
+
[:schema_info, :schema_migrations].each{|n| @db.table_exists?(n).should be_true}
|
|
154
|
+
[:sm1111, :sm2222, :sm3333, :sm1122, :sm2233].each{|n| @db.table_exists?(n).should be_false}
|
|
155
|
+
@db[:schema_migrations].select_order_map(:filename).should == []
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
specify "should handle unapplied migrations when migrating schema_info table to schema_migrations table" do
|
|
159
|
+
@dir = 'spec/files/integer_migrations'
|
|
160
|
+
@m.apply(@db, @dir, 2)
|
|
161
|
+
[:schema_info, :sm1111, :sm2222].each{|n| @db.table_exists?(n).should be_true}
|
|
162
|
+
[:schema_migrations, :sm3333, :sm1122, :sm2233].each{|n| @db.table_exists?(n).should be_false}
|
|
163
|
+
|
|
164
|
+
@dir = 'spec/files/convert_to_timestamp_migrations'
|
|
165
|
+
@m.apply(@db, @dir, 1273253850)
|
|
166
|
+
[:schema_info, :sm1111, :sm2222, :sm3333, :schema_migrations, :sm1122].each{|n| @db.table_exists?(n).should be_true}
|
|
167
|
+
[:sm2233].each{|n| @db.table_exists?(n).should be_false}
|
|
168
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'001_create_sessions.rb 002_create_nodes.rb 003_3_create_users.rb 1273253850_create_artists.rb'
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
specify "should handle unapplied migrations when migrating schema_info table to schema_migrations table and target is less than last integer migration version" do
|
|
172
|
+
@dir = 'spec/files/integer_migrations'
|
|
173
|
+
@m.apply(@db, @dir, 1)
|
|
174
|
+
[:schema_info, :sm1111].each{|n| @db.table_exists?(n).should be_true}
|
|
175
|
+
[:schema_migrations, :sm2222, :sm3333, :sm1122, :sm2233].each{|n| @db.table_exists?(n).should be_false}
|
|
176
|
+
|
|
177
|
+
@dir = 'spec/files/convert_to_timestamp_migrations'
|
|
178
|
+
@m.apply(@db, @dir, 2)
|
|
179
|
+
[:schema_info, :sm1111, :sm2222, :schema_migrations].each{|n| @db.table_exists?(n).should be_true}
|
|
180
|
+
[:sm3333, :sm1122, :sm2233].each{|n| @db.table_exists?(n).should be_false}
|
|
181
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'001_create_sessions.rb 002_create_nodes.rb'
|
|
182
|
+
|
|
183
|
+
@m.apply(@db, @dir)
|
|
184
|
+
[:schema_info, :sm1111, :sm2222, :schema_migrations, :sm3333, :sm1122, :sm2233].each{|n| @db.table_exists?(n).should be_true}
|
|
185
|
+
@db[:schema_migrations].select_order_map(:filename).should == %w'001_create_sessions.rb 002_create_nodes.rb 003_3_create_users.rb 1273253850_create_artists.rb 1273253852_create_albums.rb'
|
|
186
|
+
end
|
|
187
|
+
end
|
|
@@ -812,3 +812,153 @@ describe "Instance Filters plugin" do
|
|
|
812
812
|
proc{@i.destroy}.should raise_error(Sequel::Error)
|
|
813
813
|
end
|
|
814
814
|
end
|
|
815
|
+
|
|
816
|
+
describe "UpdatePrimaryKey plugin" do
|
|
817
|
+
before do
|
|
818
|
+
@db = INTEGRATION_DB
|
|
819
|
+
@db.create_table!(:t) do
|
|
820
|
+
Integer :a, :primary_key=>true
|
|
821
|
+
Integer :b
|
|
822
|
+
end
|
|
823
|
+
@ds = @db[:t]
|
|
824
|
+
@ds.insert(:a=>1, :b=>3)
|
|
825
|
+
@c = Class.new(Sequel::Model(@ds))
|
|
826
|
+
@c.set_primary_key(:a)
|
|
827
|
+
@c.unrestrict_primary_key
|
|
828
|
+
@c.plugin :update_primary_key
|
|
829
|
+
end
|
|
830
|
+
after do
|
|
831
|
+
@db.drop_table(:t)
|
|
832
|
+
end
|
|
833
|
+
|
|
834
|
+
specify "should handle regular updates" do
|
|
835
|
+
@c.first.update(:b=>4)
|
|
836
|
+
@db[:t].all.should == [{:a=>1, :b=>4}]
|
|
837
|
+
@c.first.set(:b=>5).save
|
|
838
|
+
@db[:t].all.should == [{:a=>1, :b=>5}]
|
|
839
|
+
@c.first.set(:b=>6).save(:b)
|
|
840
|
+
@db[:t].all.should == [{:a=>1, :b=>6}]
|
|
841
|
+
end
|
|
842
|
+
|
|
843
|
+
specify "should handle updating the primary key field with another field" do
|
|
844
|
+
@c.first.update(:a=>2, :b=>4)
|
|
845
|
+
@db[:t].all.should == [{:a=>2, :b=>4}]
|
|
846
|
+
end
|
|
847
|
+
|
|
848
|
+
specify "should handle updating just the primary key field when saving changes" do
|
|
849
|
+
@c.first.update(:a=>2)
|
|
850
|
+
@db[:t].all.should == [{:a=>2, :b=>3}]
|
|
851
|
+
@c.first.set(:a=>3).save(:a)
|
|
852
|
+
@db[:t].all.should == [{:a=>3, :b=>3}]
|
|
853
|
+
end
|
|
854
|
+
|
|
855
|
+
specify "should handle saving after modifying the primary key field with another field" do
|
|
856
|
+
@c.first.set(:a=>2, :b=>4).save
|
|
857
|
+
@db[:t].all.should == [{:a=>2, :b=>4}]
|
|
858
|
+
end
|
|
859
|
+
|
|
860
|
+
specify "should handle saving after modifying just the primary key field" do
|
|
861
|
+
@c.first.set(:a=>2).save
|
|
862
|
+
@db[:t].all.should == [{:a=>2, :b=>3}]
|
|
863
|
+
end
|
|
864
|
+
|
|
865
|
+
specify "should handle saving after updating the primary key" do
|
|
866
|
+
@c.first.update(:a=>2).update(:b=>4).set(:b=>5).save
|
|
867
|
+
@db[:t].all.should == [{:a=>2, :b=>5}]
|
|
868
|
+
end
|
|
869
|
+
end
|
|
870
|
+
|
|
871
|
+
describe "AssociationPks plugin" do
|
|
872
|
+
before do
|
|
873
|
+
@db = INTEGRATION_DB
|
|
874
|
+
@db.create_table!(:artists) do
|
|
875
|
+
primary_key :id
|
|
876
|
+
String :name
|
|
877
|
+
end
|
|
878
|
+
@db.create_table!(:albums) do
|
|
879
|
+
primary_key :id
|
|
880
|
+
String :name
|
|
881
|
+
foreign_key :artist_id, :artists
|
|
882
|
+
end
|
|
883
|
+
@db.create_table!(:tags) do
|
|
884
|
+
primary_key :id
|
|
885
|
+
String :name
|
|
886
|
+
end
|
|
887
|
+
@db.create_table!(:albums_tags) do
|
|
888
|
+
foreign_key :album_id, :albums
|
|
889
|
+
foreign_key :tag_id, :tags
|
|
890
|
+
end
|
|
891
|
+
class ::Artist < Sequel::Model
|
|
892
|
+
plugin :association_pks
|
|
893
|
+
one_to_many :albums, :order=>:id
|
|
894
|
+
end
|
|
895
|
+
class ::Album < Sequel::Model
|
|
896
|
+
plugin :association_pks
|
|
897
|
+
many_to_many :tags, :order=>:id
|
|
898
|
+
end
|
|
899
|
+
class ::Tag < Sequel::Model
|
|
900
|
+
end
|
|
901
|
+
|
|
902
|
+
@ar1 =@db[:artists].insert(:name=>'YJM')
|
|
903
|
+
@ar2 =@db[:artists].insert(:name=>'AS')
|
|
904
|
+
@al1 =@db[:albums].insert(:name=>'RF', :artist_id=>@ar1)
|
|
905
|
+
@al2 =@db[:albums].insert(:name=>'MO', :artist_id=>@ar1)
|
|
906
|
+
@al3 =@db[:albums].insert(:name=>'T', :artist_id=>@ar1)
|
|
907
|
+
@t1 = @db[:tags].insert(:name=>'A')
|
|
908
|
+
@t2 = @db[:tags].insert(:name=>'B')
|
|
909
|
+
@t3 = @db[:tags].insert(:name=>'C')
|
|
910
|
+
{@al1=>[@t1, @t2, @t3], @al2=>[@t2]}.each do |aid, tids|
|
|
911
|
+
tids.each{|tid| @db[:albums_tags].insert([aid, tid])}
|
|
912
|
+
end
|
|
913
|
+
end
|
|
914
|
+
after do
|
|
915
|
+
@db.drop_table :albums_tags, :tags, :albums, :artists
|
|
916
|
+
[:Artist, :Album, :Tag].each{|s| Object.send(:remove_const, s)}
|
|
917
|
+
end
|
|
918
|
+
|
|
919
|
+
specify "should return correct associated pks for one_to_many associations" do
|
|
920
|
+
Artist.order(:id).all.map{|a| a.album_pks}.should == [[@al1, @al2, @al3], []]
|
|
921
|
+
end
|
|
922
|
+
|
|
923
|
+
specify "should return correct associated pks for many_to_many associations" do
|
|
924
|
+
Album.order(:id).all.map{|a| a.tag_pks.sort}.should == [[@t1, @t2, @t3], [@t2], []]
|
|
925
|
+
end
|
|
926
|
+
|
|
927
|
+
specify "should set associated pks correctly for a one_to_many association" do
|
|
928
|
+
Artist.use_transactions = true
|
|
929
|
+
Album.order(:id).select_map(:artist_id).should == [@ar1, @ar1, @ar1]
|
|
930
|
+
|
|
931
|
+
Artist[@ar2].album_pks = [@t1, @t3]
|
|
932
|
+
Artist[@ar1].album_pks.should == [@t2]
|
|
933
|
+
Album.order(:id).select_map(:artist_id).should == [@ar2, @ar1, @ar2]
|
|
934
|
+
|
|
935
|
+
Artist[@ar1].album_pks = [@t1]
|
|
936
|
+
Artist[@ar2].album_pks.should == [@t3]
|
|
937
|
+
Album.order(:id).select_map(:artist_id).should == [@ar1, nil, @ar2]
|
|
938
|
+
|
|
939
|
+
Artist[@ar1].album_pks = [@t1, @t2]
|
|
940
|
+
Artist[@ar2].album_pks.should == [@t3]
|
|
941
|
+
Album.order(:id).select_map(:artist_id).should == [@ar1, @ar1, @ar2]
|
|
942
|
+
end
|
|
943
|
+
|
|
944
|
+
specify "should set associated pks correctly for a many_to_many association" do
|
|
945
|
+
Artist.use_transactions = true
|
|
946
|
+
@db[:albums_tags].filter(:album_id=>@al1).select_order_map(:tag_id).should == [@t1, @t2, @t3]
|
|
947
|
+
Album[@al1].tag_pks = [@t1, @t3]
|
|
948
|
+
@db[:albums_tags].filter(:album_id=>@al1).select_order_map(:tag_id).should == [@t1, @t3]
|
|
949
|
+
Album[@al1].tag_pks = []
|
|
950
|
+
@db[:albums_tags].filter(:album_id=>@al1).select_order_map(:tag_id).should == []
|
|
951
|
+
|
|
952
|
+
@db[:albums_tags].filter(:album_id=>@al2).select_order_map(:tag_id).should == [@t2]
|
|
953
|
+
Album[@al2].tag_pks = [@t1, @t2]
|
|
954
|
+
@db[:albums_tags].filter(:album_id=>@al2).select_order_map(:tag_id).should == [@t1, @t2]
|
|
955
|
+
Album[@al2].tag_pks = []
|
|
956
|
+
@db[:albums_tags].filter(:album_id=>@al1).select_order_map(:tag_id).should == []
|
|
957
|
+
|
|
958
|
+
@db[:albums_tags].filter(:album_id=>@al3).select_order_map(:tag_id).should == []
|
|
959
|
+
Album[@al3].tag_pks = [@t1, @t3]
|
|
960
|
+
@db[:albums_tags].filter(:album_id=>@al3).select_order_map(:tag_id).should == [@t1, @t3]
|
|
961
|
+
Album[@al3].tag_pks = []
|
|
962
|
+
@db[:albums_tags].filter(:album_id=>@al1).select_order_map(:tag_id).should == []
|
|
963
|
+
end
|
|
964
|
+
end
|
|
@@ -109,7 +109,11 @@ describe "Database schema parser" do
|
|
|
109
109
|
end
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
begin
|
|
113
|
+
INTEGRATION_DB.drop_table(:blah) rescue nil
|
|
114
|
+
INTEGRATION_DB.indexes(:blah)
|
|
115
|
+
rescue Sequel::NotImplemented
|
|
116
|
+
rescue
|
|
113
117
|
describe "Database index parsing" do
|
|
114
118
|
after do
|
|
115
119
|
INTEGRATION_DB.drop_table(:items)
|
|
@@ -159,6 +163,10 @@ describe "Database schema modifiers" do
|
|
|
159
163
|
@ds.columns!.should == [:number]
|
|
160
164
|
end
|
|
161
165
|
|
|
166
|
+
specify "should create temporary tables without raising an exception" do
|
|
167
|
+
@db.create_table!(:items, :temp=>true){Integer :number}
|
|
168
|
+
end
|
|
169
|
+
|
|
162
170
|
specify "should rename tables correctly" do
|
|
163
171
|
@db.drop_table(:items) rescue nil
|
|
164
172
|
@db.create_table!(:items2){Integer :number}
|
|
@@ -328,7 +336,10 @@ describe "Database schema modifiers" do
|
|
|
328
336
|
end
|
|
329
337
|
end
|
|
330
338
|
|
|
331
|
-
|
|
339
|
+
begin
|
|
340
|
+
INTEGRATION_DB.tables
|
|
341
|
+
rescue Sequel::NotImplemented
|
|
342
|
+
rescue
|
|
332
343
|
describe "Database#tables" do
|
|
333
344
|
before do
|
|
334
345
|
class ::String
|