sequel 3.21.0 → 3.29.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.
Files changed (200) hide show
  1. data/CHANGELOG +413 -3
  2. data/README.rdoc +20 -6
  3. data/Rakefile +23 -16
  4. data/bin/sequel +1 -5
  5. data/doc/association_basics.rdoc +210 -43
  6. data/doc/dataset_basics.rdoc +4 -4
  7. data/doc/mass_assignment.rdoc +54 -0
  8. data/doc/migration.rdoc +15 -538
  9. data/doc/model_hooks.rdoc +72 -27
  10. data/doc/opening_databases.rdoc +86 -50
  11. data/doc/prepared_statements.rdoc +40 -13
  12. data/doc/reflection.rdoc +8 -2
  13. data/doc/release_notes/3.22.0.txt +39 -0
  14. data/doc/release_notes/3.23.0.txt +172 -0
  15. data/doc/release_notes/3.24.0.txt +420 -0
  16. data/doc/release_notes/3.25.0.txt +88 -0
  17. data/doc/release_notes/3.26.0.txt +88 -0
  18. data/doc/release_notes/3.27.0.txt +82 -0
  19. data/doc/release_notes/3.28.0.txt +304 -0
  20. data/doc/release_notes/3.29.0.txt +459 -0
  21. data/doc/schema_modification.rdoc +547 -0
  22. data/doc/sharding.rdoc +7 -1
  23. data/doc/testing.rdoc +115 -0
  24. data/doc/transactions.rdoc +137 -0
  25. data/doc/virtual_rows.rdoc +2 -2
  26. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  27. data/lib/sequel/adapters/ado.rb +40 -18
  28. data/lib/sequel/adapters/amalgalite.rb +15 -7
  29. data/lib/sequel/adapters/db2.rb +175 -86
  30. data/lib/sequel/adapters/dbi.rb +15 -15
  31. data/lib/sequel/adapters/do/mysql.rb +0 -5
  32. data/lib/sequel/adapters/do/postgres.rb +0 -5
  33. data/lib/sequel/adapters/do/sqlite.rb +0 -5
  34. data/lib/sequel/adapters/do.rb +17 -36
  35. data/lib/sequel/adapters/firebird.rb +27 -208
  36. data/lib/sequel/adapters/ibmdb.rb +448 -0
  37. data/lib/sequel/adapters/informix.rb +6 -23
  38. data/lib/sequel/adapters/jdbc/as400.rb +5 -31
  39. data/lib/sequel/adapters/jdbc/db2.rb +44 -0
  40. data/lib/sequel/adapters/jdbc/derby.rb +217 -0
  41. data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
  42. data/lib/sequel/adapters/jdbc/h2.rb +26 -17
  43. data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
  44. data/lib/sequel/adapters/jdbc/informix.rb +26 -0
  45. data/lib/sequel/adapters/jdbc/jtds.rb +29 -0
  46. data/lib/sequel/adapters/jdbc/mssql.rb +0 -32
  47. data/lib/sequel/adapters/jdbc/mysql.rb +9 -10
  48. data/lib/sequel/adapters/jdbc/oracle.rb +67 -25
  49. data/lib/sequel/adapters/jdbc/postgresql.rb +6 -11
  50. data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
  51. data/lib/sequel/adapters/jdbc/sqlserver.rb +41 -0
  52. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  53. data/lib/sequel/adapters/jdbc.rb +107 -38
  54. data/lib/sequel/adapters/mock.rb +315 -0
  55. data/lib/sequel/adapters/mysql.rb +78 -182
  56. data/lib/sequel/adapters/mysql2.rb +24 -23
  57. data/lib/sequel/adapters/odbc/db2.rb +17 -0
  58. data/lib/sequel/adapters/odbc/mssql.rb +0 -5
  59. data/lib/sequel/adapters/odbc.rb +28 -9
  60. data/lib/sequel/adapters/openbase.rb +2 -4
  61. data/lib/sequel/adapters/oracle.rb +349 -51
  62. data/lib/sequel/adapters/postgres.rb +169 -21
  63. data/lib/sequel/adapters/shared/access.rb +21 -6
  64. data/lib/sequel/adapters/shared/db2.rb +288 -0
  65. data/lib/sequel/adapters/shared/firebird.rb +214 -0
  66. data/lib/sequel/adapters/shared/informix.rb +45 -0
  67. data/lib/sequel/adapters/shared/mssql.rb +108 -65
  68. data/lib/sequel/adapters/shared/mysql.rb +56 -13
  69. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
  70. data/lib/sequel/adapters/shared/oracle.rb +185 -34
  71. data/lib/sequel/adapters/shared/postgres.rb +107 -58
  72. data/lib/sequel/adapters/shared/progress.rb +0 -6
  73. data/lib/sequel/adapters/shared/sqlite.rb +168 -41
  74. data/lib/sequel/adapters/sqlite.rb +27 -18
  75. data/lib/sequel/adapters/swift/mysql.rb +9 -5
  76. data/lib/sequel/adapters/swift/postgres.rb +0 -5
  77. data/lib/sequel/adapters/swift/sqlite.rb +6 -4
  78. data/lib/sequel/adapters/swift.rb +5 -5
  79. data/lib/sequel/adapters/tinytds.rb +152 -17
  80. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +63 -0
  81. data/lib/sequel/ast_transformer.rb +190 -0
  82. data/lib/sequel/connection_pool/threaded.rb +3 -2
  83. data/lib/sequel/connection_pool.rb +1 -1
  84. data/lib/sequel/core.rb +46 -5
  85. data/lib/sequel/database/connecting.rb +5 -6
  86. data/lib/sequel/database/dataset.rb +4 -4
  87. data/lib/sequel/database/dataset_defaults.rb +59 -1
  88. data/lib/sequel/database/logging.rb +1 -1
  89. data/lib/sequel/database/misc.rb +100 -19
  90. data/lib/sequel/database/query.rb +153 -58
  91. data/lib/sequel/database/schema_generator.rb +8 -5
  92. data/lib/sequel/database/schema_methods.rb +59 -29
  93. data/lib/sequel/dataset/actions.rb +194 -57
  94. data/lib/sequel/dataset/features.rb +81 -8
  95. data/lib/sequel/dataset/graph.rb +8 -7
  96. data/lib/sequel/dataset/misc.rb +50 -23
  97. data/lib/sequel/dataset/mutation.rb +5 -6
  98. data/lib/sequel/dataset/prepared_statements.rb +32 -15
  99. data/lib/sequel/dataset/query.rb +223 -42
  100. data/lib/sequel/dataset/sql.rb +58 -61
  101. data/lib/sequel/dataset.rb +8 -0
  102. data/lib/sequel/exceptions.rb +4 -0
  103. data/lib/sequel/extensions/columns_introspection.rb +61 -0
  104. data/lib/sequel/extensions/migration.rb +6 -4
  105. data/lib/sequel/extensions/named_timezones.rb +5 -0
  106. data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
  107. data/lib/sequel/extensions/to_dot.rb +95 -83
  108. data/lib/sequel/model/associations.rb +997 -331
  109. data/lib/sequel/model/base.rb +386 -129
  110. data/lib/sequel/model/errors.rb +1 -1
  111. data/lib/sequel/model/exceptions.rb +5 -1
  112. data/lib/sequel/model.rb +15 -8
  113. data/lib/sequel/plugins/association_pks.rb +22 -4
  114. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  115. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  116. data/lib/sequel/plugins/defaults_setter.rb +58 -0
  117. data/lib/sequel/plugins/force_encoding.rb +6 -6
  118. data/lib/sequel/plugins/identity_map.rb +114 -7
  119. data/lib/sequel/plugins/many_through_many.rb +65 -7
  120. data/lib/sequel/plugins/prepared_statements.rb +151 -0
  121. data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
  122. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  123. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  124. data/lib/sequel/plugins/rcte_tree.rb +29 -15
  125. data/lib/sequel/plugins/serialization.rb +6 -1
  126. data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
  127. data/lib/sequel/plugins/sharding.rb +12 -25
  128. data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
  129. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  130. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  131. data/lib/sequel/plugins/xml_serializer.rb +3 -3
  132. data/lib/sequel/sql.rb +107 -51
  133. data/lib/sequel/timezones.rb +44 -35
  134. data/lib/sequel/version.rb +1 -1
  135. data/spec/adapters/db2_spec.rb +146 -0
  136. data/spec/adapters/mssql_spec.rb +65 -29
  137. data/spec/adapters/mysql_spec.rb +122 -123
  138. data/spec/adapters/oracle_spec.rb +48 -76
  139. data/spec/adapters/postgres_spec.rb +213 -61
  140. data/spec/adapters/spec_helper.rb +6 -5
  141. data/spec/adapters/sqlite_spec.rb +35 -21
  142. data/spec/core/connection_pool_spec.rb +71 -92
  143. data/spec/core/core_sql_spec.rb +20 -31
  144. data/spec/core/database_spec.rb +729 -508
  145. data/spec/core/dataset_spec.rb +980 -1044
  146. data/spec/core/expression_filters_spec.rb +159 -42
  147. data/spec/core/mock_adapter_spec.rb +378 -0
  148. data/spec/core/object_graph_spec.rb +48 -114
  149. data/spec/core/schema_generator_spec.rb +3 -3
  150. data/spec/core/schema_spec.rb +298 -38
  151. data/spec/core/spec_helper.rb +6 -48
  152. data/spec/extensions/association_pks_spec.rb +38 -0
  153. data/spec/extensions/class_table_inheritance_spec.rb +1 -1
  154. data/spec/extensions/columns_introspection_spec.rb +91 -0
  155. data/spec/extensions/dataset_associations_spec.rb +199 -0
  156. data/spec/extensions/defaults_setter_spec.rb +64 -0
  157. data/spec/extensions/identity_map_spec.rb +162 -0
  158. data/spec/extensions/instance_hooks_spec.rb +71 -0
  159. data/spec/extensions/many_through_many_spec.rb +195 -20
  160. data/spec/extensions/migration_spec.rb +17 -17
  161. data/spec/extensions/named_timezones_spec.rb +22 -2
  162. data/spec/extensions/nested_attributes_spec.rb +4 -0
  163. data/spec/extensions/prepared_statements_associations_spec.rb +126 -0
  164. data/spec/extensions/prepared_statements_safe_spec.rb +79 -0
  165. data/spec/extensions/prepared_statements_spec.rb +72 -0
  166. data/spec/extensions/prepared_statements_with_pk_spec.rb +38 -0
  167. data/spec/extensions/schema_dumper_spec.rb +2 -2
  168. data/spec/extensions/schema_spec.rb +13 -21
  169. data/spec/extensions/serialization_modification_detection_spec.rb +37 -0
  170. data/spec/extensions/serialization_spec.rb +5 -8
  171. data/spec/extensions/single_table_inheritance_spec.rb +11 -0
  172. data/spec/extensions/spec_helper.rb +7 -1
  173. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  174. data/spec/extensions/to_dot_spec.rb +3 -5
  175. data/spec/extensions/typecast_on_load_spec.rb +1 -6
  176. data/spec/extensions/xml_serializer_spec.rb +16 -4
  177. data/spec/integration/associations_test.rb +522 -21
  178. data/spec/integration/database_test.rb +4 -2
  179. data/spec/integration/dataset_test.rb +375 -62
  180. data/spec/integration/eager_loader_test.rb +19 -21
  181. data/spec/integration/model_test.rb +80 -1
  182. data/spec/integration/plugin_test.rb +304 -116
  183. data/spec/integration/prepared_statement_test.rb +200 -120
  184. data/spec/integration/schema_test.rb +161 -30
  185. data/spec/integration/spec_helper.rb +39 -30
  186. data/spec/integration/timezone_test.rb +38 -12
  187. data/spec/integration/transaction_test.rb +172 -5
  188. data/spec/integration/type_test.rb +17 -3
  189. data/spec/model/association_reflection_spec.rb +174 -7
  190. data/spec/model/associations_spec.rb +849 -661
  191. data/spec/model/base_spec.rb +255 -95
  192. data/spec/model/dataset_methods_spec.rb +7 -27
  193. data/spec/model/eager_loading_spec.rb +640 -676
  194. data/spec/model/hooks_spec.rb +309 -67
  195. data/spec/model/model_spec.rb +207 -167
  196. data/spec/model/plugins_spec.rb +24 -13
  197. data/spec/model/record_spec.rb +321 -218
  198. data/spec/model/spec_helper.rb +13 -71
  199. data/spec/model/validations_spec.rb +11 -0
  200. metadata +95 -38
@@ -1,28 +1,34 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  # H2 and MSSQL don't support USING joins
4
- unless [:h2, :mssql].include?(INTEGRATION_DB.database_type)
4
+ # DB2 does not seem to support USING joins in every version; it seems to be
5
+ # valid expression in DB2 iSeries UDB though.
6
+ unless Sequel.guarded?(:h2, :mssql, :db2)
5
7
  describe "Class Table Inheritance Plugin" do
6
- before do
8
+ before(:all) do
7
9
  @db = INTEGRATION_DB
8
10
  @db.instance_variable_set(:@schemas, {})
9
- @db.create_table!(:employees) do
11
+ [:staff, :executives, :managers, :employees].each{|t| @db.drop_table(t) if @db.table_exists?(t)}
12
+ @db.create_table(:employees) do
10
13
  primary_key :id
11
14
  String :name
12
15
  String :kind
13
16
  end
14
- @db.create_table!(:managers) do
17
+ @db.create_table(:managers) do
15
18
  foreign_key :id, :employees, :primary_key=>true
16
19
  Integer :num_staff
17
20
  end
18
- @db.create_table!(:executives) do
21
+ @db.create_table(:executives) do
19
22
  foreign_key :id, :managers, :primary_key=>true
20
23
  Integer :num_managers
21
24
  end
22
- @db.create_table!(:staff) do
25
+ @db.create_table(:staff) do
23
26
  foreign_key :id, :employees, :primary_key=>true
24
27
  foreign_key :manager_id, :managers
25
28
  end
29
+ end
30
+ before do
31
+ [:staff, :executives, :managers, :employees].each{|t| @db[t].delete}
26
32
  class ::Employee < Sequel::Model(@db)
27
33
  plugin :class_table_inheritance, :key=>:kind, :table_map=>{:Staff=>:staff}
28
34
  end
@@ -32,7 +38,7 @@ describe "Class Table Inheritance Plugin" do
32
38
  class ::Executive < Manager
33
39
  end
34
40
  class ::Staff < Employee
35
- many_to_one :manager
41
+ many_to_one :manager, :qualify=>false
36
42
  end
37
43
 
38
44
  @i1 =@db[:employees].insert(:name=>'E', :kind=>'Employee')
@@ -43,13 +49,13 @@ describe "Class Table Inheritance Plugin" do
43
49
  @db[:managers].insert(:id=>@i4, :num_staff=>5)
44
50
  @db[:executives].insert(:id=>@i4, :num_managers=>6)
45
51
  @db[:staff].insert(:id=>@i2, :manager_id=>@i4)
46
-
47
- clear_sqls
48
52
  end
49
53
  after do
50
- @db.drop_table :staff, :executives, :managers, :employees
51
54
  [:Executive, :Manager, :Staff, :Employee].each{|s| Object.send(:remove_const, s)}
52
55
  end
56
+ after(:all) do
57
+ @db.drop_table :staff, :executives, :managers, :employees
58
+ end
53
59
 
54
60
  specify "should return rows as subclass instances" do
55
61
  Employee.order(:id).all.should == [
@@ -110,17 +116,17 @@ describe "Class Table Inheritance Plugin" do
110
116
  @db[:executives][:id=>@i4].should == {:id=>@i4, :num_managers=>8}
111
117
  end
112
118
 
113
- cspecify "should handle many_to_one relationships", :sqlite do
119
+ specify "should handle many_to_one relationships" do
114
120
  m = Staff.first.manager
115
121
  m.should == Manager[@i4]
116
122
  m.should be_a_kind_of(Executive)
117
123
  end
118
124
 
119
- cspecify "should handle eagerly loading many_to_one relationships", :sqlite do
125
+ specify "should handle eagerly loading many_to_one relationships" do
120
126
  Staff.limit(1).eager(:manager).all.map{|x| x.manager}.should == [Manager[@i4]]
121
127
  end
122
128
 
123
- cspecify "should handle eagerly graphing many_to_one relationships", :sqlite do
129
+ specify "should handle eagerly graphing many_to_one relationships" do
124
130
  ss = Staff.eager_graph(:manager).all
125
131
  ss.should == [Staff[@i2]]
126
132
  ss.map{|x| x.manager}.should == [Manager[@i4]]
@@ -143,21 +149,25 @@ end
143
149
  end
144
150
 
145
151
  describe "Many Through Many Plugin" do
146
- before do
152
+ before(:all) do
147
153
  @db = INTEGRATION_DB
148
154
  @db.instance_variable_set(:@schemas, {})
149
- @db.create_table!(:albums) do
155
+ [:albums_artists, :albums, :artists].each{|t| @db.drop_table(t) if @db.table_exists?(t)}
156
+ @db.create_table(:albums) do
150
157
  primary_key :id
151
158
  String :name
152
159
  end
153
- @db.create_table!(:artists) do
160
+ @db.create_table(:artists) do
154
161
  primary_key :id
155
162
  String :name
156
163
  end
157
- @db.create_table!(:albums_artists) do
164
+ @db.create_table(:albums_artists) do
158
165
  foreign_key :album_id, :albums
159
166
  foreign_key :artist_id, :artists
160
167
  end
168
+ end
169
+ before do
170
+ [:albums_artists, :albums, :artists].each{|t| @db[t].delete}
161
171
  class ::Album < Sequel::Model(@db)
162
172
  many_to_many :artists
163
173
  end
@@ -181,21 +191,27 @@ describe "Many Through Many Plugin" do
181
191
  @album4 = Album.create(:name=>'D')
182
192
  @album4.add_artist(@artist1)
183
193
  @album4.add_artist(@artist4)
184
-
185
- clear_sqls
186
194
  end
187
195
  after do
188
- @db.drop_table :albums_artists, :albums, :artists
189
196
  [:Album, :Artist].each{|s| Object.send(:remove_const, s)}
190
197
  end
198
+ after(:all) do
199
+ @db.drop_table :albums_artists, :albums, :artists
200
+ end
191
201
 
192
202
  specify "should handle super simple case with 1 join table" do
193
203
  Artist.many_through_many :albums, [[:albums_artists, :artist_id, :album_id]]
194
- Artist[1].albums.map{|x| x.name}.sort.should == %w'A D'
195
- Artist[2].albums.map{|x| x.name}.sort.should == %w'A C'
196
- Artist[3].albums.map{|x| x.name}.sort.should == %w'B C'
197
- Artist[4].albums.map{|x| x.name}.sort.should == %w'B D'
204
+ Artist[@artist1.id].albums.map{|x| x.name}.sort.should == %w'A D'
205
+ Artist[@artist2.id].albums.map{|x| x.name}.sort.should == %w'A C'
206
+ Artist[@artist3.id].albums.map{|x| x.name}.sort.should == %w'B C'
207
+ Artist[@artist4.id].albums.map{|x| x.name}.sort.should == %w'B D'
198
208
 
209
+ Artist.plugin :prepared_statements_associations
210
+ Artist[@artist1.id].albums.map{|x| x.name}.sort.should == %w'A D'
211
+ Artist[@artist2.id].albums.map{|x| x.name}.sort.should == %w'A C'
212
+ Artist[@artist3.id].albums.map{|x| x.name}.sort.should == %w'B C'
213
+ Artist[@artist4.id].albums.map{|x| x.name}.sort.should == %w'B D'
214
+
199
215
  Artist.filter(:id=>1).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'A D'
200
216
  Artist.filter(:id=>2).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'A C'
201
217
  Artist.filter(:id=>3).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'B C'
@@ -205,24 +221,65 @@ describe "Many Through Many Plugin" do
205
221
  Artist.filter(:artists__id=>2).eager_graph(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'A C'
206
222
  Artist.filter(:artists__id=>3).eager_graph(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'B C'
207
223
  Artist.filter(:artists__id=>4).eager_graph(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.should == %w'B D'
224
+
225
+ Artist.filter(:albums=>@album1).all.map{|a| a.name}.sort.should == %w'1 2'
226
+ Artist.filter(:albums=>@album2).all.map{|a| a.name}.sort.should == %w'3 4'
227
+ Artist.filter(:albums=>@album3).all.map{|a| a.name}.sort.should == %w'2 3'
228
+ Artist.filter(:albums=>@album4).all.map{|a| a.name}.sort.should == %w'1 4'
229
+
230
+ Artist.exclude(:albums=>@album1).all.map{|a| a.name}.sort.should == %w'3 4'
231
+ Artist.exclude(:albums=>@album2).all.map{|a| a.name}.sort.should == %w'1 2'
232
+ Artist.exclude(:albums=>@album3).all.map{|a| a.name}.sort.should == %w'1 4'
233
+ Artist.exclude(:albums=>@album4).all.map{|a| a.name}.sort.should == %w'2 3'
234
+
235
+ Artist.filter(:albums=>[@album1, @album3]).all.map{|a| a.name}.sort.should == %w'1 2 3'
236
+ Artist.filter(:albums=>[@album2, @album4]).all.map{|a| a.name}.sort.should == %w'1 3 4'
237
+
238
+ Artist.exclude(:albums=>[@album1, @album3]).all.map{|a| a.name}.sort.should == %w'4'
239
+ Artist.exclude(:albums=>[@album2, @album4]).all.map{|a| a.name}.sort.should == %w'2'
240
+
241
+ Artist.filter(:albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.should == %w'1 2 3'
242
+ Artist.exclude(:albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.should == %w'4'
208
243
  end
209
244
 
210
245
  specify "should handle typical case with 3 join tables" do
211
246
  Artist.many_through_many :related_artists, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_artists, :album_id, :artist_id]], :class=>Artist, :distinct=>true
212
- Artist[1].related_artists.map{|x| x.name}.sort.should == %w'1 2 4'
213
- Artist[2].related_artists.map{|x| x.name}.sort.should == %w'1 2 3'
214
- Artist[3].related_artists.map{|x| x.name}.sort.should == %w'2 3 4'
215
- Artist[4].related_artists.map{|x| x.name}.sort.should == %w'1 3 4'
247
+ Artist[@artist1.id].related_artists.map{|x| x.name}.sort.should == %w'1 2 4'
248
+ Artist[@artist2.id].related_artists.map{|x| x.name}.sort.should == %w'1 2 3'
249
+ Artist[@artist3.id].related_artists.map{|x| x.name}.sort.should == %w'2 3 4'
250
+ Artist[@artist4.id].related_artists.map{|x| x.name}.sort.should == %w'1 3 4'
216
251
 
217
- Artist.filter(:id=>1).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 4'
218
- Artist.filter(:id=>2).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 3'
219
- Artist.filter(:id=>3).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'2 3 4'
220
- Artist.filter(:id=>4).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 3 4'
252
+ Artist.plugin :prepared_statements_associations
253
+ Artist[@artist1.id].related_artists.map{|x| x.name}.sort.should == %w'1 2 4'
254
+ Artist[@artist2.id].related_artists.map{|x| x.name}.sort.should == %w'1 2 3'
255
+ Artist[@artist3.id].related_artists.map{|x| x.name}.sort.should == %w'2 3 4'
256
+ Artist[@artist4.id].related_artists.map{|x| x.name}.sort.should == %w'1 3 4'
221
257
 
222
- Artist.filter(:artists__id=>1).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 4'
223
- Artist.filter(:artists__id=>2).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 3'
224
- Artist.filter(:artists__id=>3).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'2 3 4'
225
- Artist.filter(:artists__id=>4).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 3 4'
258
+ Artist.filter(:id=>@artist1.id).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 4'
259
+ Artist.filter(:id=>@artist2.id).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 3'
260
+ Artist.filter(:id=>@artist3.id).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'2 3 4'
261
+ Artist.filter(:id=>@artist4.id).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 3 4'
262
+
263
+ Artist.filter(:artists__id=>@artist1.id).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 4'
264
+ Artist.filter(:artists__id=>@artist2.id).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 2 3'
265
+ Artist.filter(:artists__id=>@artist3.id).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'2 3 4'
266
+ Artist.filter(:artists__id=>@artist4.id).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.should == %w'1 3 4'
267
+
268
+ Artist.filter(:related_artists=>@artist1).all.map{|a| a.name}.sort.should == %w'1 2 4'
269
+ Artist.filter(:related_artists=>@artist2).all.map{|a| a.name}.sort.should == %w'1 2 3'
270
+ Artist.filter(:related_artists=>@artist3).all.map{|a| a.name}.sort.should == %w'2 3 4'
271
+ Artist.filter(:related_artists=>@artist4).all.map{|a| a.name}.sort.should == %w'1 3 4'
272
+
273
+ Artist.exclude(:related_artists=>@artist1).all.map{|a| a.name}.sort.should == %w'3'
274
+ Artist.exclude(:related_artists=>@artist2).all.map{|a| a.name}.sort.should == %w'4'
275
+ Artist.exclude(:related_artists=>@artist3).all.map{|a| a.name}.sort.should == %w'1'
276
+ Artist.exclude(:related_artists=>@artist4).all.map{|a| a.name}.sort.should == %w'2'
277
+
278
+ Artist.filter(:related_artists=>[@artist1, @artist4]).all.map{|a| a.name}.sort.should == %w'1 2 3 4'
279
+ Artist.exclude(:related_artists=>[@artist1, @artist4]).all.map{|a| a.name}.sort.should == %w''
280
+
281
+ Artist.filter(:related_artists=>Artist.filter(:id=>@artist1.id)).all.map{|a| a.name}.sort.should == %w'1 2 4'
282
+ Artist.exclude(:related_artists=>Artist.filter(:id=>@artist1.id)).all.map{|a| a.name}.sort.should == %w'3'
226
283
  end
227
284
 
228
285
  specify "should handle extreme case with 5 join tables" do
@@ -236,37 +293,63 @@ describe "Many Through Many Plugin" do
236
293
  @album4.add_artist(@artist3)
237
294
  @album4.add_artist(@artist4)
238
295
 
239
- Artist[1].related_albums.map{|x| x.name}.sort.should == %w'A B C'
240
- Artist[2].related_albums.map{|x| x.name}.sort.should == %w'A B C D'
241
- Artist[3].related_albums.map{|x| x.name}.sort.should == %w'A B D'
242
- Artist[4].related_albums.map{|x| x.name}.sort.should == %w'B D'
296
+ Artist[@artist1.id].related_albums.map{|x| x.name}.sort.should == %w'A B C'
297
+ Artist[@artist2.id].related_albums.map{|x| x.name}.sort.should == %w'A B C D'
298
+ Artist[@artist3.id].related_albums.map{|x| x.name}.sort.should == %w'A B D'
299
+ Artist[@artist4.id].related_albums.map{|x| x.name}.sort.should == %w'B D'
300
+
301
+ Artist.plugin :prepared_statements_associations
302
+ Artist[@artist1.id].related_albums.map{|x| x.name}.sort.should == %w'A B C'
303
+ Artist[@artist2.id].related_albums.map{|x| x.name}.sort.should == %w'A B C D'
304
+ Artist[@artist3.id].related_albums.map{|x| x.name}.sort.should == %w'A B D'
305
+ Artist[@artist4.id].related_albums.map{|x| x.name}.sort.should == %w'B D'
243
306
 
244
- Artist.filter(:id=>1).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C'
245
- Artist.filter(:id=>2).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C D'
246
- Artist.filter(:id=>3).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B D'
247
- Artist.filter(:id=>4).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'B D'
307
+ Artist.filter(:id=>@artist1.id).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C'
308
+ Artist.filter(:id=>@artist2.id).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C D'
309
+ Artist.filter(:id=>@artist3.id).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B D'
310
+ Artist.filter(:id=>@artist4.id).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'B D'
248
311
 
249
- Artist.filter(:artists__id=>1).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C'
250
- Artist.filter(:artists__id=>2).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C D'
251
- Artist.filter(:artists__id=>3).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B D'
252
- Artist.filter(:artists__id=>4).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'B D'
312
+ Artist.filter(:artists__id=>@artist1.id).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C'
313
+ Artist.filter(:artists__id=>@artist2.id).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B C D'
314
+ Artist.filter(:artists__id=>@artist3.id).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'A B D'
315
+ Artist.filter(:artists__id=>@artist4.id).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.should == %w'B D'
316
+
317
+ Artist.filter(:related_albums=>@album1).all.map{|a| a.name}.sort.should == %w'1 2 3'
318
+ Artist.filter(:related_albums=>@album2).all.map{|a| a.name}.sort.should == %w'1 2 3 4'
319
+ Artist.filter(:related_albums=>@album3).all.map{|a| a.name}.sort.should == %w'1 2'
320
+ Artist.filter(:related_albums=>@album4).all.map{|a| a.name}.sort.should == %w'2 3 4'
321
+
322
+ Artist.exclude(:related_albums=>@album1).all.map{|a| a.name}.sort.should == %w'4'
323
+ Artist.exclude(:related_albums=>@album2).all.map{|a| a.name}.sort.should == %w''
324
+ Artist.exclude(:related_albums=>@album3).all.map{|a| a.name}.sort.should == %w'3 4'
325
+ Artist.exclude(:related_albums=>@album4).all.map{|a| a.name}.sort.should == %w'1'
326
+
327
+ Artist.filter(:related_albums=>[@album1, @album3]).all.map{|a| a.name}.sort.should == %w'1 2 3'
328
+ Artist.filter(:related_albums=>[@album3, @album4]).all.map{|a| a.name}.sort.should == %w'1 2 3 4'
329
+
330
+ Artist.exclude(:related_albums=>[@album1, @album3]).all.map{|a| a.name}.sort.should == %w'4'
331
+ Artist.exclude(:related_albums=>[@album2, @album4]).all.map{|a| a.name}.sort.should == %w''
332
+
333
+ Artist.filter(:related_albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.should == %w'1 2 3'
334
+ Artist.exclude(:related_albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.should == %w'4'
253
335
  end
254
336
  end
255
337
 
256
338
  describe "Lazy Attributes plugin" do
257
- before do
339
+ before(:all) do
258
340
  @db = INTEGRATION_DB
259
341
  @db.create_table!(:items) do
260
342
  primary_key :id
261
343
  String :name
262
344
  Integer :num
263
345
  end
346
+ @db[:items].delete
264
347
  class ::Item < Sequel::Model(@db)
265
348
  plugin :lazy_attributes, :num
266
349
  end
267
350
  Item.create(:name=>'J', :num=>1)
268
351
  end
269
- after do
352
+ after(:all) do
270
353
  @db.drop_table(:items)
271
354
  Object.send(:remove_const, :Item)
272
355
  end
@@ -299,7 +382,7 @@ describe "Lazy Attributes plugin" do
299
382
  end
300
383
 
301
384
  describe "Tactical Eager Loading Plugin" do
302
- before do
385
+ before(:all) do
303
386
  @db = INTEGRATION_DB
304
387
  @db.instance_variable_set(:@schemas, {})
305
388
  @db.create_table!(:artists) do
@@ -311,6 +394,10 @@ describe "Tactical Eager Loading Plugin" do
311
394
  String :name
312
395
  foreign_key :artist_id, :artists
313
396
  end
397
+ end
398
+ before do
399
+ @db[:albums].delete
400
+ @db[:artists].delete
314
401
  class ::Album < Sequel::Model(@db)
315
402
  plugin :tactical_eager_loading
316
403
  many_to_one :artist
@@ -328,13 +415,13 @@ describe "Tactical Eager Loading Plugin" do
328
415
  @album2 = Album.create(:name=>'B', :artist=>@artist1)
329
416
  @album3 = Album.create(:name=>'C', :artist=>@artist2)
330
417
  @album4 = Album.create(:name=>'D', :artist=>@artist3)
331
-
332
- clear_sqls
333
418
  end
334
419
  after do
335
- @db.drop_table :albums, :artists
336
420
  [:Album, :Artist].each{|s| Object.send(:remove_const, s)}
337
421
  end
422
+ after(:all) do
423
+ @db.drop_table :albums, :artists
424
+ end
338
425
 
339
426
  specify "should eagerly load associations for all items when accessing any item" do
340
427
  a = Artist.order(:name).all
@@ -382,7 +469,7 @@ describe "Identity Map plugin" do
382
469
  end
383
470
 
384
471
  describe "Touch plugin" do
385
- before do
472
+ before(:all) do
386
473
  @db = INTEGRATION_DB
387
474
  @db.instance_variable_set(:@schemas, {})
388
475
  @db.create_table!(:artists) do
@@ -396,6 +483,10 @@ describe "Touch plugin" do
396
483
  foreign_key :artist_id, :artists
397
484
  DateTime :updated_at
398
485
  end
486
+ end
487
+ before do
488
+ @db[:albums].delete
489
+ @db[:artists].delete
399
490
  class ::Album < Sequel::Model(@db)
400
491
  many_to_one :artist
401
492
  plugin :touch, :associations=>:artist
@@ -407,9 +498,11 @@ describe "Touch plugin" do
407
498
  @album = Album.create(:name=>'A', :artist=>@artist)
408
499
  end
409
500
  after do
410
- @db.drop_table :albums, :artists
411
501
  [:Album, :Artist].each{|s| Object.send(:remove_const, s)}
412
502
  end
503
+ after(:all) do
504
+ @db.drop_table :albums, :artists
505
+ end
413
506
 
414
507
  specify "should update the timestamp column when touching the record" do
415
508
  @album.updated_at.should == nil
@@ -464,7 +557,7 @@ describe "Serialization plugin" do
464
557
  end
465
558
 
466
559
  describe "OptimisticLocking plugin" do
467
- before do
560
+ before(:all) do
468
561
  @db = INTEGRATION_DB
469
562
  @db.create_table!(:people) do
470
563
  primary_key :id
@@ -473,30 +566,33 @@ describe "OptimisticLocking plugin" do
473
566
  end
474
567
  class ::Person < Sequel::Model(@db)
475
568
  plugin :optimistic_locking
476
- create(:name=>'John')
477
569
  end
478
570
  end
479
- after do
571
+ before do
572
+ @db[:people].delete
573
+ @p = Person.create(:name=>'John')
574
+ end
575
+ after(:all) do
480
576
  @db.drop_table(:people)
481
577
  Object.send(:remove_const, :Person)
482
578
  end
483
579
 
484
580
  specify "should raise an error when updating a stale record" do
485
- p1 = Person[1]
486
- p2 = Person[1]
581
+ p1 = Person[@p.id]
582
+ p2 = Person[@p.id]
487
583
  p1.update(:name=>'Jim')
488
584
  proc{p2.update(:name=>'Bob')}.should raise_error(Sequel::Plugins::OptimisticLocking::Error)
489
585
  end
490
586
 
491
587
  specify "should raise an error when destroying a stale record" do
492
- p1 = Person[1]
493
- p2 = Person[1]
588
+ p1 = Person[@p.id]
589
+ p2 = Person[@p.id]
494
590
  p1.update(:name=>'Jim')
495
591
  proc{p2.destroy}.should raise_error(Sequel::Plugins::OptimisticLocking::Error)
496
592
  end
497
593
 
498
594
  specify "should not raise an error when updating the same record twice" do
499
- p1 = Person[1]
595
+ p1 = Person[@p.id]
500
596
  p1.update(:name=>'Jim')
501
597
  proc{p1.update(:name=>'Bob')}.should_not raise_error
502
598
  end
@@ -525,7 +621,7 @@ describe "Composition plugin" do
525
621
  composition :date, :mapping=>[:year, :month, :day]
526
622
  end
527
623
  @e1 = Event.create(:year=>2010, :month=>2, :day=>15)
528
- @e2 = Event.create({})
624
+ @e2 = Event.create(:year=>nil)
529
625
  end
530
626
  after do
531
627
  @db.drop_table(:events)
@@ -555,9 +651,10 @@ describe "Composition plugin" do
555
651
  end
556
652
  end
557
653
 
558
- if INTEGRATION_DB.dataset.supports_cte?
654
+ # DB2's implemention of CTE is too limited to use this plugin
655
+ if INTEGRATION_DB.dataset.supports_cte? and !Sequel.guarded?(:db2)
559
656
  describe "RcteTree Plugin" do
560
- before do
657
+ before(:all) do
561
658
  @db = INTEGRATION_DB
562
659
  @db.create_table!(:nodes) do
563
660
  primary_key :id
@@ -568,21 +665,25 @@ if INTEGRATION_DB.dataset.supports_cte?
568
665
  plugin :rcte_tree, :order=>:name
569
666
  end
570
667
 
571
- @a = Node.create(:name=>'a')
572
- @b = Node.create(:name=>'b')
573
- @aa = Node.create(:name=>'aa', :parent=>@a)
574
- @ab = Node.create(:name=>'ab', :parent=>@a)
575
- @ba = Node.create(:name=>'ba', :parent=>@b)
576
- @bb = Node.create(:name=>'bb', :parent=>@b)
577
- @aaa = Node.create(:name=>'aaa', :parent=>@aa)
578
- @aab = Node.create(:name=>'aab', :parent=>@aa)
579
- @aba = Node.create(:name=>'aba', :parent=>@ab)
580
- @abb = Node.create(:name=>'abb', :parent=>@ab)
581
- @aaaa = Node.create(:name=>'aaaa', :parent=>@aaa)
582
- @aaab = Node.create(:name=>'aaab', :parent=>@aaa)
583
- @aaaaa = Node.create(:name=>'aaaaa', :parent=>@aaaa)
584
- end
585
- after do
668
+ @nodes = []
669
+ @nodes << @a = Node.create(:name=>'a')
670
+ @nodes << @b = Node.create(:name=>'b')
671
+ @nodes << @aa = Node.create(:name=>'aa', :parent=>@a)
672
+ @nodes << @ab = Node.create(:name=>'ab', :parent=>@a)
673
+ @nodes << @ba = Node.create(:name=>'ba', :parent=>@b)
674
+ @nodes << @bb = Node.create(:name=>'bb', :parent=>@b)
675
+ @nodes << @aaa = Node.create(:name=>'aaa', :parent=>@aa)
676
+ @nodes << @aab = Node.create(:name=>'aab', :parent=>@aa)
677
+ @nodes << @aba = Node.create(:name=>'aba', :parent=>@ab)
678
+ @nodes << @abb = Node.create(:name=>'abb', :parent=>@ab)
679
+ @nodes << @aaaa = Node.create(:name=>'aaaa', :parent=>@aaa)
680
+ @nodes << @aaab = Node.create(:name=>'aaab', :parent=>@aaa)
681
+ @nodes << @aaaaa = Node.create(:name=>'aaaaa', :parent=>@aaaa)
682
+ end
683
+ before do
684
+ @nodes.each{|n| n.associations.clear}
685
+ end
686
+ after(:all) do
586
687
  @db.drop_table :nodes
587
688
  Object.send(:remove_const, :Node)
588
689
  end
@@ -659,13 +760,15 @@ if INTEGRATION_DB.dataset.supports_cte?
659
760
  end
660
761
 
661
762
  specify "should work correctly if not all columns are selected" do
662
- Node.plugin :lazy_attributes, :name
663
- @aaaa.descendants.should == [Node.load(:parent_id=>11, :id=>13)]
664
- @aa.ancestors.should == [Node.load(:parent_id=>nil, :id=>1)]
665
- nodes = Node.filter(:id=>[@a.id, @b.id, @aaa.id]).order(:name).eager(:ancestors, :descendants).all
666
- nodes.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>3, :id=>7}, {:parent_id=>nil, :id=>2}].map{|x| Node.load(x)}
667
- nodes[2].descendants.should == [{:parent_id=>2, :id=>5}, {:parent_id=>2, :id=>6}].map{|x| Node.load(x)}
668
- nodes[1].ancestors.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>1, :id=>3}].map{|x| Node.load(x)}
763
+ c = Class.new(Sequel::Model(@db[:nodes]))
764
+ c.plugin :rcte_tree, :order=>:name
765
+ c.plugin :lazy_attributes, :name
766
+ c[:name=>'aaaa'].descendants.should == [c.load(:parent_id=>11, :id=>13)]
767
+ c[:name=>'aa'].ancestors.should == [c.load(:parent_id=>nil, :id=>1)]
768
+ nodes = c.filter(:id=>[@a.id, @b.id, @aaa.id]).order(:name).eager(:ancestors, :descendants).all
769
+ nodes.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>3, :id=>7}, {:parent_id=>nil, :id=>2}].map{|x| c.load(x)}
770
+ nodes[2].descendants.should == [{:parent_id=>2, :id=>5}, {:parent_id=>2, :id=>6}].map{|x| c.load(x)}
771
+ nodes[1].ancestors.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>1, :id=>3}].map{|x| c.load(x)}
669
772
  end
670
773
 
671
774
  specify "should eagerly load descendants to a given level" do
@@ -783,7 +886,7 @@ if INTEGRATION_DB.dataset.supports_cte?
783
886
  end
784
887
 
785
888
  describe "Instance Filters plugin" do
786
- before do
889
+ before(:all) do
787
890
  @db = INTEGRATION_DB
788
891
  @db.create_table!(:items) do
789
892
  primary_key :id
@@ -794,11 +897,14 @@ describe "Instance Filters plugin" do
794
897
  class ::Item < Sequel::Model(@db)
795
898
  plugin :instance_filters
796
899
  end
900
+ end
901
+ before do
902
+ @db[:items].delete
797
903
  @i = Item.create(:name=>'J', :number=>1, :cost=>2)
798
904
  @i.instance_filter(:number=>1)
799
905
  @i.set(:name=>'K')
800
906
  end
801
- after do
907
+ after(:all) do
802
908
  @db.drop_table(:items)
803
909
  Object.send(:remove_const, :Item)
804
910
  end
@@ -843,20 +949,23 @@ describe "Instance Filters plugin" do
843
949
  end
844
950
 
845
951
  describe "UpdatePrimaryKey plugin" do
846
- before do
952
+ before(:all) do
847
953
  @db = INTEGRATION_DB
848
954
  @db.create_table!(:t) do
849
955
  Integer :a, :primary_key=>true
850
956
  Integer :b
851
957
  end
852
958
  @ds = @db[:t]
853
- @ds.insert(:a=>1, :b=>3)
854
959
  @c = Class.new(Sequel::Model(@ds))
855
960
  @c.set_primary_key(:a)
856
961
  @c.unrestrict_primary_key
857
962
  @c.plugin :update_primary_key
858
963
  end
859
- after do
964
+ before do
965
+ @ds.delete
966
+ @ds.insert(:a=>1, :b=>3)
967
+ end
968
+ after(:all) do
860
969
  @db.drop_table(:t)
861
970
  end
862
971
 
@@ -898,22 +1007,23 @@ describe "UpdatePrimaryKey plugin" do
898
1007
  end
899
1008
 
900
1009
  describe "AssociationPks plugin" do
901
- before do
1010
+ before(:all) do
902
1011
  @db = INTEGRATION_DB
903
- @db.create_table!(:artists) do
1012
+ [:albums_tags, :tags, :albums, :artists].each{|t| @db.drop_table(t) if @db.table_exists?(t)}
1013
+ @db.create_table(:artists) do
904
1014
  primary_key :id
905
1015
  String :name
906
1016
  end
907
- @db.create_table!(:albums) do
1017
+ @db.create_table(:albums) do
908
1018
  primary_key :id
909
1019
  String :name
910
1020
  foreign_key :artist_id, :artists
911
1021
  end
912
- @db.create_table!(:tags) do
1022
+ @db.create_table(:tags) do
913
1023
  primary_key :id
914
1024
  String :name
915
1025
  end
916
- @db.create_table!(:albums_tags) do
1026
+ @db.create_table(:albums_tags) do
917
1027
  foreign_key :album_id, :albums
918
1028
  foreign_key :tag_id, :tags
919
1029
  end
@@ -927,7 +1037,9 @@ describe "AssociationPks plugin" do
927
1037
  end
928
1038
  class ::Tag < Sequel::Model
929
1039
  end
930
-
1040
+ end
1041
+ before do
1042
+ [:albums_tags, :tags, :albums, :artists].each{|t| @db[t].delete}
931
1043
  @ar1 =@db[:artists].insert(:name=>'YJM')
932
1044
  @ar2 =@db[:artists].insert(:name=>'AS')
933
1045
  @al1 =@db[:albums].insert(:name=>'RF', :artist_id=>@ar1)
@@ -940,7 +1052,7 @@ describe "AssociationPks plugin" do
940
1052
  tids.each{|tid| @db[:albums_tags].insert([aid, tid])}
941
1053
  end
942
1054
  end
943
- after do
1055
+ after(:all) do
944
1056
  @db.drop_table :albums_tags, :tags, :albums, :artists
945
1057
  [:Artist, :Album, :Tag].each{|s| Object.send(:remove_const, s)}
946
1058
  end
@@ -994,9 +1106,9 @@ end
994
1106
 
995
1107
 
996
1108
  describe "List plugin without a scope" do
997
- before do
1109
+ before(:all) do
998
1110
  @db = INTEGRATION_DB
999
- @db.create_table :sites do
1111
+ @db.create_table!(:sites) do
1000
1112
  primary_key :id
1001
1113
  String :name
1002
1114
  Integer :position
@@ -1004,13 +1116,14 @@ describe "List plugin without a scope" do
1004
1116
 
1005
1117
  @c = Class.new(Sequel::Model(@db[:sites]))
1006
1118
  @c.plugin :list
1119
+ end
1120
+ before do
1007
1121
  @c.delete
1008
1122
  @c.create :name => "hig", :position => 3
1009
1123
  @c.create :name => "def", :position => 2
1010
1124
  @c.create :name => "abc", :position => 1
1011
1125
  end
1012
-
1013
- after do
1126
+ after(:all) do
1014
1127
  @db.drop_table(:sites)
1015
1128
  end
1016
1129
 
@@ -1067,9 +1180,9 @@ describe "List plugin without a scope" do
1067
1180
  end
1068
1181
 
1069
1182
  describe "List plugin with a scope" do
1070
- before do
1183
+ before(:all) do
1071
1184
  @db = INTEGRATION_DB
1072
- @db.create_table :pages do
1185
+ @db.create_table!(:pages) do
1073
1186
  primary_key :id
1074
1187
  String :name
1075
1188
  Integer :pos
@@ -1078,6 +1191,9 @@ describe "List plugin with a scope" do
1078
1191
 
1079
1192
  @c = Class.new(Sequel::Model(@db[:pages]))
1080
1193
  @c.plugin :list, :field => :pos, :scope => :parent_id
1194
+ end
1195
+ before do
1196
+ @c.delete
1081
1197
  p1 = @c.create :name => "Hm", :pos => 1, :parent_id => 0
1082
1198
  p2 = @c.create :name => "Ps", :pos => 1, :parent_id => p1.id
1083
1199
  @c.create :name => "P1", :pos => 1, :parent_id => p2.id
@@ -1085,8 +1201,7 @@ describe "List plugin with a scope" do
1085
1201
  @c.create :name => "P3", :pos => 3, :parent_id => p2.id
1086
1202
  @c.create :name => "Au", :pos => 2, :parent_id => p1.id
1087
1203
  end
1088
-
1089
- after do
1204
+ after(:all) do
1090
1205
  @db.drop_table(:pages)
1091
1206
  end
1092
1207
 
@@ -1143,12 +1258,12 @@ describe "List plugin with a scope" do
1143
1258
  end
1144
1259
 
1145
1260
  describe "Sequel::Plugins::Tree" do
1146
- before do
1261
+ before(:all) do
1147
1262
  @db = INTEGRATION_DB
1148
1263
  end
1149
1264
 
1150
1265
  describe "with natural database order" do
1151
- before do
1266
+ before(:all) do
1152
1267
  @db.create_table!(:nodes) do
1153
1268
  Integer :id, :primary_key=>true
1154
1269
  String :name
@@ -1174,7 +1289,7 @@ describe "Sequel::Plugins::Tree" do
1174
1289
  plugin :tree
1175
1290
  end
1176
1291
  end
1177
- after do
1292
+ after(:all) do
1178
1293
  @db.drop_table(:nodes)
1179
1294
  Object.send(:remove_const, :Node)
1180
1295
  end
@@ -1249,12 +1364,12 @@ describe "Sequel::Plugins::Tree" do
1249
1364
  end
1250
1365
 
1251
1366
  describe "Nodes in specified order" do
1252
- before do
1367
+ before(:all) do
1253
1368
  class ::OrderedNode < Sequel::Model(:nodes)
1254
1369
  plugin :tree, :order => :position
1255
1370
  end
1256
1371
  end
1257
- after do
1372
+ after(:all) do
1258
1373
  Object.send(:remove_const, :OrderedNode)
1259
1374
  end
1260
1375
 
@@ -1272,7 +1387,7 @@ describe "Sequel::Plugins::Tree" do
1272
1387
  end
1273
1388
 
1274
1389
  describe "Lorems in specified order" do
1275
- before do
1390
+ before(:all) do
1276
1391
  @db.create_table!(:lorems) do
1277
1392
  Integer :id, :primary_key=>true
1278
1393
  String :name
@@ -1290,7 +1405,7 @@ describe "Sequel::Plugins::Tree" do
1290
1405
  plugin :tree, :key => :ipsum_id, :order => :neque
1291
1406
  end
1292
1407
  end
1293
- after do
1408
+ after(:all) do
1294
1409
  @db.drop_table(:lorems)
1295
1410
  Object.send(:remove_const, :Lorem)
1296
1411
  end
@@ -1306,3 +1421,76 @@ describe "Sequel::Plugins::Tree" do
1306
1421
  end
1307
1422
  end
1308
1423
  end
1424
+
1425
+ describe "Sequel::Plugins::PreparedStatements" do
1426
+ before(:all) do
1427
+ @db = INTEGRATION_DB
1428
+ @db.create_table!(:ps_test) do
1429
+ primary_key :id
1430
+ String :name
1431
+ Integer :i
1432
+ end
1433
+ @c = Class.new(Sequel::Model(@db[:ps_test]))
1434
+ @c.plugin :prepared_statements_with_pk
1435
+ end
1436
+ before do
1437
+ @c.delete
1438
+ @foo = @c.create(:name=>'foo', :i=>10)
1439
+ @bar = @c.create(:name=>'bar', :i=>20)
1440
+ end
1441
+ after(:all) do
1442
+ @db.drop_table(:ps_test)
1443
+ end
1444
+
1445
+ it "should work with looking up using Model.[]" do
1446
+ @c[@foo.id].should == @foo
1447
+ @c[@bar.id].should == @bar
1448
+ @c[0].should == nil
1449
+ @c[nil].should == nil
1450
+ end
1451
+
1452
+ it "should work with looking up using Dataset#with_pk" do
1453
+ @c.dataset.with_pk(@foo.id).should == @foo
1454
+ @c.dataset.with_pk(@bar.id).should == @bar
1455
+ @c.dataset.with_pk(0).should == nil
1456
+ @c.dataset.with_pk(nil).should == nil
1457
+
1458
+ @c.dataset.filter(:i=>0).with_pk(@foo.id).should == nil
1459
+ @c.dataset.filter(:i=>10).with_pk(@foo.id).should == @foo
1460
+ @c.dataset.filter(:i=>20).with_pk(@bar.id).should == @bar
1461
+ @c.dataset.filter(:i=>10).with_pk(nil).should == nil
1462
+ @c.dataset.filter(:name=>'foo').with_pk(@foo.id).should == @foo
1463
+ @c.dataset.filter(:name=>'bar').with_pk(@bar.id).should == @bar
1464
+ @c.dataset.filter(:name=>'baz').with_pk(@bar.id).should == nil
1465
+ @c.dataset.filter(:name=>'bar').with_pk(nil).should == nil
1466
+ end
1467
+
1468
+ it "should work with Model#destroy" do
1469
+ @foo.destroy
1470
+ @bar.destroy
1471
+ @c[@foo.id].should == nil
1472
+ @c[@bar.id].should == nil
1473
+ end
1474
+
1475
+ it "should work with Model#update" do
1476
+ @foo.update(:name=>'foo2', :i=>30)
1477
+ @c[@foo.id].should == @c.load(:id=>@foo.id, :name=>'foo2', :i=>30)
1478
+ @foo.update(:name=>'foo3')
1479
+ @c[@foo.id].should == @c.load(:id=>@foo.id, :name=>'foo3', :i=>30)
1480
+ @foo.update(:i=>40)
1481
+ @c[@foo.id].should == @c.load(:id=>@foo.id, :name=>'foo3', :i=>40)
1482
+ @foo.update(:i=>nil)
1483
+ @c[@foo.id].should == @c.load(:id=>@foo.id, :name=>'foo3', :i=>nil)
1484
+ end
1485
+
1486
+ it "should work with Model#create" do
1487
+ o = @c.create(:name=>'foo2', :i=>30)
1488
+ @c[o.id].should == @c.load(:id=>o.id, :name=>'foo2', :i=>30)
1489
+ o = @c.create(:name=>'foo2')
1490
+ @c[o.id].should == @c.load(:id=>o.id, :name=>'foo2', :i=>nil)
1491
+ o = @c.create(:i=>30)
1492
+ @c[o.id].should == @c.load(:id=>o.id, :name=>nil, :i=>30)
1493
+ o = @c.create(:name=>nil, :i=>40)
1494
+ @c[o.id].should == @c.load(:id=>o.id, :name=>nil, :i=>40)
1495
+ end
1496
+ end