sequel 3.28.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 (148) hide show
  1. data/CHANGELOG +119 -3
  2. data/Rakefile +5 -3
  3. data/bin/sequel +1 -5
  4. data/doc/model_hooks.rdoc +9 -1
  5. data/doc/opening_databases.rdoc +49 -40
  6. data/doc/prepared_statements.rdoc +27 -6
  7. data/doc/release_notes/3.28.0.txt +2 -2
  8. data/doc/release_notes/3.29.0.txt +459 -0
  9. data/doc/sharding.rdoc +7 -1
  10. data/doc/testing.rdoc +18 -9
  11. data/doc/transactions.rdoc +41 -1
  12. data/lib/sequel/adapters/ado.rb +28 -17
  13. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  14. data/lib/sequel/adapters/amalgalite.rb +11 -7
  15. data/lib/sequel/adapters/db2.rb +122 -70
  16. data/lib/sequel/adapters/dbi.rb +15 -15
  17. data/lib/sequel/adapters/do.rb +5 -36
  18. data/lib/sequel/adapters/do/mysql.rb +0 -5
  19. data/lib/sequel/adapters/do/postgres.rb +0 -5
  20. data/lib/sequel/adapters/do/sqlite.rb +0 -5
  21. data/lib/sequel/adapters/firebird.rb +3 -6
  22. data/lib/sequel/adapters/ibmdb.rb +24 -16
  23. data/lib/sequel/adapters/informix.rb +2 -4
  24. data/lib/sequel/adapters/jdbc.rb +47 -11
  25. data/lib/sequel/adapters/jdbc/as400.rb +5 -24
  26. data/lib/sequel/adapters/jdbc/db2.rb +0 -5
  27. data/lib/sequel/adapters/jdbc/derby.rb +217 -0
  28. data/lib/sequel/adapters/jdbc/firebird.rb +0 -5
  29. data/lib/sequel/adapters/jdbc/h2.rb +10 -12
  30. data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
  31. data/lib/sequel/adapters/jdbc/informix.rb +0 -5
  32. data/lib/sequel/adapters/jdbc/jtds.rb +0 -5
  33. data/lib/sequel/adapters/jdbc/mysql.rb +0 -10
  34. data/lib/sequel/adapters/jdbc/oracle.rb +70 -3
  35. data/lib/sequel/adapters/jdbc/postgresql.rb +0 -11
  36. data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
  37. data/lib/sequel/adapters/jdbc/sqlserver.rb +0 -5
  38. data/lib/sequel/adapters/jdbc/transactions.rb +56 -7
  39. data/lib/sequel/adapters/mock.rb +315 -0
  40. data/lib/sequel/adapters/mysql.rb +64 -51
  41. data/lib/sequel/adapters/mysql2.rb +15 -9
  42. data/lib/sequel/adapters/odbc.rb +13 -6
  43. data/lib/sequel/adapters/odbc/db2.rb +0 -4
  44. data/lib/sequel/adapters/odbc/mssql.rb +0 -5
  45. data/lib/sequel/adapters/openbase.rb +2 -4
  46. data/lib/sequel/adapters/oracle.rb +333 -51
  47. data/lib/sequel/adapters/postgres.rb +80 -27
  48. data/lib/sequel/adapters/shared/access.rb +0 -6
  49. data/lib/sequel/adapters/shared/db2.rb +13 -15
  50. data/lib/sequel/adapters/shared/firebird.rb +6 -6
  51. data/lib/sequel/adapters/shared/mssql.rb +23 -18
  52. data/lib/sequel/adapters/shared/mysql.rb +6 -6
  53. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +6 -0
  54. data/lib/sequel/adapters/shared/oracle.rb +185 -30
  55. data/lib/sequel/adapters/shared/postgres.rb +35 -18
  56. data/lib/sequel/adapters/shared/progress.rb +0 -6
  57. data/lib/sequel/adapters/shared/sqlite.rb +116 -37
  58. data/lib/sequel/adapters/sqlite.rb +16 -8
  59. data/lib/sequel/adapters/swift.rb +5 -5
  60. data/lib/sequel/adapters/swift/mysql.rb +0 -5
  61. data/lib/sequel/adapters/swift/postgres.rb +0 -5
  62. data/lib/sequel/adapters/swift/sqlite.rb +6 -4
  63. data/lib/sequel/adapters/tinytds.rb +13 -10
  64. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +8 -0
  65. data/lib/sequel/core.rb +40 -0
  66. data/lib/sequel/database/connecting.rb +1 -2
  67. data/lib/sequel/database/dataset.rb +3 -3
  68. data/lib/sequel/database/dataset_defaults.rb +58 -0
  69. data/lib/sequel/database/misc.rb +62 -2
  70. data/lib/sequel/database/query.rb +113 -49
  71. data/lib/sequel/database/schema_methods.rb +7 -2
  72. data/lib/sequel/dataset/actions.rb +37 -19
  73. data/lib/sequel/dataset/features.rb +24 -0
  74. data/lib/sequel/dataset/graph.rb +7 -6
  75. data/lib/sequel/dataset/misc.rb +11 -3
  76. data/lib/sequel/dataset/mutation.rb +2 -3
  77. data/lib/sequel/dataset/prepared_statements.rb +6 -4
  78. data/lib/sequel/dataset/query.rb +46 -15
  79. data/lib/sequel/dataset/sql.rb +28 -4
  80. data/lib/sequel/extensions/named_timezones.rb +5 -0
  81. data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
  82. data/lib/sequel/model.rb +2 -1
  83. data/lib/sequel/model/associations.rb +115 -33
  84. data/lib/sequel/model/base.rb +91 -31
  85. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  86. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  87. data/lib/sequel/plugins/force_encoding.rb +6 -6
  88. data/lib/sequel/plugins/identity_map.rb +1 -1
  89. data/lib/sequel/plugins/many_through_many.rb +6 -10
  90. data/lib/sequel/plugins/prepared_statements.rb +12 -1
  91. data/lib/sequel/plugins/prepared_statements_associations.rb +1 -1
  92. data/lib/sequel/plugins/rcte_tree.rb +29 -15
  93. data/lib/sequel/plugins/serialization.rb +6 -1
  94. data/lib/sequel/plugins/sharding.rb +0 -5
  95. data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
  96. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  97. data/lib/sequel/plugins/update_primary_key.rb +1 -1
  98. data/lib/sequel/timezones.rb +42 -42
  99. data/lib/sequel/version.rb +1 -1
  100. data/spec/adapters/mssql_spec.rb +29 -29
  101. data/spec/adapters/mysql_spec.rb +86 -104
  102. data/spec/adapters/oracle_spec.rb +48 -76
  103. data/spec/adapters/postgres_spec.rb +98 -33
  104. data/spec/adapters/spec_helper.rb +0 -5
  105. data/spec/adapters/sqlite_spec.rb +24 -21
  106. data/spec/core/connection_pool_spec.rb +9 -15
  107. data/spec/core/core_sql_spec.rb +20 -31
  108. data/spec/core/database_spec.rb +491 -227
  109. data/spec/core/dataset_spec.rb +638 -1051
  110. data/spec/core/expression_filters_spec.rb +0 -1
  111. data/spec/core/mock_adapter_spec.rb +378 -0
  112. data/spec/core/object_graph_spec.rb +48 -114
  113. data/spec/core/schema_generator_spec.rb +3 -3
  114. data/spec/core/schema_spec.rb +51 -114
  115. data/spec/core/spec_helper.rb +3 -90
  116. data/spec/extensions/class_table_inheritance_spec.rb +1 -1
  117. data/spec/extensions/dataset_associations_spec.rb +199 -0
  118. data/spec/extensions/instance_hooks_spec.rb +71 -0
  119. data/spec/extensions/named_timezones_spec.rb +22 -2
  120. data/spec/extensions/nested_attributes_spec.rb +3 -0
  121. data/spec/extensions/schema_spec.rb +1 -1
  122. data/spec/extensions/serialization_modification_detection_spec.rb +1 -0
  123. data/spec/extensions/serialization_spec.rb +5 -8
  124. data/spec/extensions/spec_helper.rb +4 -0
  125. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  126. data/spec/extensions/typecast_on_load_spec.rb +1 -6
  127. data/spec/integration/associations_test.rb +123 -12
  128. data/spec/integration/dataset_test.rb +140 -47
  129. data/spec/integration/eager_loader_test.rb +19 -21
  130. data/spec/integration/model_test.rb +80 -1
  131. data/spec/integration/plugin_test.rb +179 -128
  132. data/spec/integration/prepared_statement_test.rb +92 -91
  133. data/spec/integration/schema_test.rb +42 -23
  134. data/spec/integration/spec_helper.rb +25 -31
  135. data/spec/integration/timezone_test.rb +38 -12
  136. data/spec/integration/transaction_test.rb +161 -34
  137. data/spec/integration/type_test.rb +3 -3
  138. data/spec/model/association_reflection_spec.rb +83 -7
  139. data/spec/model/associations_spec.rb +393 -676
  140. data/spec/model/base_spec.rb +186 -116
  141. data/spec/model/dataset_methods_spec.rb +7 -27
  142. data/spec/model/eager_loading_spec.rb +343 -867
  143. data/spec/model/hooks_spec.rb +160 -79
  144. data/spec/model/model_spec.rb +118 -165
  145. data/spec/model/plugins_spec.rb +7 -13
  146. data/spec/model/record_spec.rb +138 -207
  147. data/spec/model/spec_helper.rb +10 -73
  148. metadata +14 -8
@@ -1,14 +1,12 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "Model attribute setters" do
4
-
5
- before(:each) do
6
- MODEL_DB.reset
7
-
4
+ before do
8
5
  @c = Class.new(Sequel::Model(:items)) do
9
6
  columns :id, :x, :y, :"x y"
10
7
  end
11
8
  @o = @c.new
9
+ MODEL_DB.reset
12
10
  end
13
11
 
14
12
  it "should mark the column value as changed" do
@@ -41,18 +39,13 @@ describe Sequel::Model, "dataset" do
41
39
  before do
42
40
  @a = Class.new(Sequel::Model(:items))
43
41
  @b = Class.new(Sequel::Model)
44
-
45
- class Elephant < Sequel::Model(:ele1)
46
- end
47
-
48
- class Maggot < Sequel::Model
49
- end
50
-
51
- class ShoeSize < Sequel::Model
52
- end
53
-
54
- class BootSize < ShoeSize
55
- end
42
+ class ::Elephant < Sequel::Model(:ele1); end
43
+ class ::Maggot < Sequel::Model; end
44
+ class ::ShoeSize < Sequel::Model; end
45
+ class ::BootSize < ShoeSize; end
46
+ end
47
+ after do
48
+ [:Elephant, :Maggot, :ShoeSize, :BootSize].each{|x| Object.send(:remove_const, x)}
56
49
  end
57
50
 
58
51
  specify "should default to the plural of the class name" do
@@ -74,33 +67,59 @@ describe Sequel::Model, "dataset" do
74
67
  end
75
68
 
76
69
  specify "should disregard namespaces for the table name" do
77
- module BlahBlah
78
- class MwaHaHa < Sequel::Model
70
+ begin
71
+ module ::BlahBlah
72
+ class MwaHaHa < Sequel::Model
73
+ end
79
74
  end
80
- end
81
75
 
82
- BlahBlah::MwaHaHa.dataset.sql.should == 'SELECT * FROM mwa_ha_has'
76
+ BlahBlah::MwaHaHa.dataset.sql.should == 'SELECT * FROM mwa_ha_has'
77
+ ensure
78
+ Object.send(:remove_const, :BlahBlah)
79
+ end
83
80
  end
84
81
  end
85
82
 
86
83
  describe Sequel::Model, ".def_dataset_method" do
87
84
  before do
88
- @c = Class.new(Sequel::Model(:items)) do
89
- end
85
+ @c = Class.new(Sequel::Model(:items))
90
86
  end
91
87
 
92
88
  it "should add a method to the dataset and model if called with a block argument" do
93
- @c.instance_eval do
94
- def_dataset_method(:return_3){3}
95
- end
89
+ @c.def_dataset_method(:return_3){3}
96
90
  @c.return_3.should == 3
97
91
  @c.dataset.return_3.should == 3
98
92
  end
99
93
 
100
- it "should add all passed methods to the model if called without a block argument" do
94
+ it "should handle weird method names" do
95
+ @c.def_dataset_method(:"return 3"){3}
96
+ @c.send(:"return 3").should == 3
97
+ @c.dataset.send(:"return 3").should == 3
98
+ end
99
+
100
+ it "should not add a model method if the model already responds to the method" do
101
101
  @c.instance_eval do
102
- def_dataset_method(:return_3, :return_4)
102
+ def foo
103
+ 1
104
+ end
105
+
106
+ private
107
+
108
+ def bar
109
+ 2
110
+ end
111
+
112
+ def_dataset_method(:foo){3}
113
+ def_dataset_method(:bar){4}
103
114
  end
115
+ @c.foo.should == 1
116
+ @c.dataset.foo.should == 3
117
+ @c.send(:bar).should == 2
118
+ @c.dataset.bar.should == 4
119
+ end
120
+
121
+ it "should add all passed methods to the model if called without a block argument" do
122
+ @c.def_dataset_method(:return_3, :return_4)
104
123
  proc{@c.return_3}.should raise_error(NoMethodError)
105
124
  proc{@c.return_4}.should raise_error(NoMethodError)
106
125
  @c.dataset.instance_eval do
@@ -112,18 +131,14 @@ describe Sequel::Model, ".def_dataset_method" do
112
131
  end
113
132
 
114
133
  it "should cache calls and readd methods if set_dataset is used" do
115
- @c.instance_eval do
116
- def_dataset_method(:return_3){3}
117
- end
134
+ @c.def_dataset_method(:return_3){3}
118
135
  @c.set_dataset :items
119
136
  @c.return_3.should == 3
120
137
  @c.dataset.return_3.should == 3
121
138
  end
122
139
 
123
140
  it "should readd methods to subclasses, if set_dataset is used in a subclass" do
124
- @c.instance_eval do
125
- def_dataset_method(:return_3){3}
126
- end
141
+ @c.def_dataset_method(:return_3){3}
127
142
  c = Class.new(@c)
128
143
  c.set_dataset :items
129
144
  c.return_3.should == 3
@@ -137,24 +152,24 @@ describe Sequel::Model, ".dataset_module" do
137
152
  end
138
153
 
139
154
  it "should extend the dataset with the module if the model has a dataset" do
140
- @c.instance_eval{dataset_module{def return_3() 3 end}}
155
+ @c.dataset_module{def return_3() 3 end}
141
156
  @c.dataset.return_3.should == 3
142
157
  end
143
158
 
144
159
  it "should add methods defined in the module to the class" do
145
- @c.instance_eval{dataset_module{def return_3() 3 end}}
160
+ @c.dataset_module{def return_3() 3 end}
146
161
  @c.return_3.should == 3
147
162
  end
148
163
 
149
164
  it "should cache calls and readd methods if set_dataset is used" do
150
- @c.instance_eval{dataset_module{def return_3() 3 end}}
165
+ @c.dataset_module{def return_3() 3 end}
151
166
  @c.set_dataset :items
152
167
  @c.return_3.should == 3
153
168
  @c.dataset.return_3.should == 3
154
169
  end
155
170
 
156
171
  it "should readd methods to subclasses, if set_dataset is used in a subclass" do
157
- @c.instance_eval{dataset_module{def return_3() 3 end}}
172
+ @c.dataset_module{def return_3() 3 end}
158
173
  c = Class.new(@c)
159
174
  c.set_dataset :items
160
175
  c.return_3.should == 3
@@ -162,24 +177,67 @@ describe Sequel::Model, ".dataset_module" do
162
177
  end
163
178
 
164
179
  it "should only have a single dataset_module per class" do
165
- @c.instance_eval{dataset_module{def return_3() 3 end}}
166
- @c.instance_eval{dataset_module{def return_3() 3 + (begin; super; rescue NoMethodError; 1; end) end}}
180
+ @c.dataset_module{def return_3() 3 end}
181
+ @c.dataset_module{def return_3() 3 + (begin; super; rescue NoMethodError; 1; end) end}
167
182
  @c.return_3.should == 4
168
183
  end
169
184
 
170
185
  it "should not have subclasses share the dataset_module" do
171
- @c.instance_eval{dataset_module{def return_3() 3 end}}
186
+ @c.dataset_module{def return_3() 3 end}
172
187
  c = Class.new(@c)
173
- c.instance_eval{dataset_module{def return_3() 3 + (begin; super; rescue NoMethodError; 1; end) end}}
188
+ c.dataset_module{def return_3() 3 + (begin; super; rescue NoMethodError; 1; end) end}
174
189
  c.return_3.should == 6
175
190
  end
191
+
192
+ it "should accept a module object and extend the dataset with it" do
193
+ @c.dataset_module Module.new{def return_3() 3 end}
194
+ @c.dataset.return_3.should == 3
195
+ end
196
+
197
+ it "should be able to call dataset_module with a module multiple times" do
198
+ @c.dataset_module Module.new{def return_3() 3 end}
199
+ @c.dataset_module Module.new{def return_4() 4 end}
200
+ @c.dataset.return_3.should == 3
201
+ @c.dataset.return_4.should == 4
202
+ end
203
+
204
+ it "should be able mix dataset_module calls with and without arguments" do
205
+ @c.dataset_module{def return_3() 3 end}
206
+ @c.dataset_module Module.new{def return_4() 4 end}
207
+ @c.dataset.return_3.should == 3
208
+ @c.dataset.return_4.should == 4
209
+ end
210
+
211
+ it "should have modules provided to dataset_module extend subclass datasets" do
212
+ @c.dataset_module{def return_3() 3 end}
213
+ @c.dataset_module Module.new{def return_4() 4 end}
214
+ c = Class.new(@c)
215
+ c.set_dataset :a
216
+ c.dataset.return_3.should == 3
217
+ c.dataset.return_4.should == 4
218
+ end
219
+
220
+ it "should return the dataset module if given a block" do
221
+ Object.new.extend(@c.dataset_module{def return_3() 3 end}).return_3.should == 3
222
+ end
223
+
224
+ it "should return the argument if given one" do
225
+ Object.new.extend(@c.dataset_module Module.new{def return_3() 3 end}).return_3.should == 3
226
+ end
227
+
228
+ it "should raise error if called with both an argument and ablock" do
229
+ proc{@c.dataset_module(Module.new{def return_3() 3 end}){}}.should raise_error(Sequel::Error)
230
+ end
176
231
  end
177
232
 
178
233
  describe "A model class with implicit table name" do
179
234
  before do
180
- class Donkey < Sequel::Model
235
+ class ::Donkey < Sequel::Model
181
236
  end
182
237
  end
238
+ after do
239
+ Object.send(:remove_const, :Donkey)
240
+ end
183
241
 
184
242
  specify "should have a dataset associated with the model class" do
185
243
  Donkey.dataset.model.should == Donkey
@@ -188,11 +246,12 @@ end
188
246
 
189
247
  describe "A model inheriting from a model" do
190
248
  before do
191
- class Feline < Sequel::Model
192
- end
193
-
194
- class Leopard < Feline
195
- end
249
+ class ::Feline < Sequel::Model; end
250
+ class ::Leopard < Feline; end
251
+ end
252
+ after do
253
+ Object.send(:remove_const, :Leopard)
254
+ Object.send(:remove_const, :Feline)
196
255
  end
197
256
 
198
257
  specify "should have a dataset associated with itself" do
@@ -272,29 +331,27 @@ end
272
331
 
273
332
  describe "Model.db=" do
274
333
  before do
275
- $db1 = MockDatabase.new
276
- $db2 = MockDatabase.new
334
+ @db1 = Sequel.mock
335
+ @db2 = Sequel.mock
277
336
 
278
- class BlueBlue < Sequel::Model(:items)
279
- set_dataset $db1[:blue].filter(:x=>1)
280
- end
337
+ @m = Class.new(Sequel::Model(@db1[:blue].filter(:x=>1)))
281
338
  end
282
339
 
283
340
  specify "should affect the underlying dataset" do
284
- BlueBlue.db = $db2
341
+ @m.db = @db2
285
342
 
286
- BlueBlue.dataset.db.should === $db2
287
- BlueBlue.dataset.db.should_not === $db1
343
+ @m.dataset.db.should === @db2
344
+ @m.dataset.db.should_not === @db1
288
345
  end
289
346
 
290
347
  specify "should keep the same dataset options" do
291
- BlueBlue.db = $db2
292
- BlueBlue.dataset.sql.should == 'SELECT * FROM blue WHERE (x = 1)'
348
+ @m.db = @db2
349
+ @m.dataset.sql.should == 'SELECT * FROM blue WHERE (x = 1)'
293
350
  end
294
351
 
295
352
  specify "should use the database for subclasses" do
296
- BlueBlue.db = $db2
297
- Class.new(BlueBlue).db.should === $db2
353
+ @m.db = @db2
354
+ Class.new(@m).db.should === @db2
298
355
  end
299
356
  end
300
357
 
@@ -302,9 +359,6 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
302
359
  before do
303
360
  @c = Class.new(Sequel::Model(:blahblah)) do
304
361
  columns :x, :y, :z
305
- def _save_refresh
306
- self
307
- end
308
362
  end
309
363
  @c.strict_param_setting = false
310
364
  @c.instance_variable_set(:@columns, [:x, :y, :z])
@@ -332,9 +386,12 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
332
386
  i.values.should == {:x => 1, :y => 2}
333
387
  i.set(:x => 4, :y => 5, :z => 6)
334
388
  i.values.should == {:x => 4, :y => 5}
335
- i.update(:x => 7, :y => 8, :z => 9)
336
- i.values.delete(:id) # stupid specs
337
- i.values.should == {:x => 7, :y => 8}
389
+
390
+ @c.dataset._fetch = {:x => 7}
391
+ i = @c.new
392
+ i.update(:x => 7, :z => 9)
393
+ i.values.should == {:x => 7}
394
+ MODEL_DB.sqls.should == ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
338
395
  end
339
396
 
340
397
  it "should not set restricted columns by default" do
@@ -343,9 +400,12 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
343
400
  i.values.should == {:x => 1, :y => 2}
344
401
  i.set(:x => 4, :y => 5, :z => 6)
345
402
  i.values.should == {:x => 4, :y => 5}
346
- i.update(:x => 7, :y => 8, :z => 9)
347
- i.values.delete(:id) # stupid specs
348
- i.values.should == {:x => 7, :y => 8}
403
+
404
+ @c.dataset._fetch = {:x => 7}
405
+ i = @c.new
406
+ i.update(:x => 7, :z => 9)
407
+ i.values.should == {:x => 7}
408
+ MODEL_DB.sqls.should == ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
349
409
  end
350
410
 
351
411
  it "should have allowed take precedence over restricted" do
@@ -355,9 +415,12 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
355
415
  i.values.should == {:x => 1, :y => 2}
356
416
  i.set(:x => 4, :y => 5, :z => 6)
357
417
  i.values.should == {:x => 4, :y => 5}
358
- i.update(:x => 7, :y => 8, :z => 9)
359
- i.values.delete(:id) # stupid specs
360
- i.values.should == {:x => 7, :y => 8}
418
+
419
+ @c.dataset._fetch = {:y => 7}
420
+ i = @c.new
421
+ i.update(:y => 7, :z => 9)
422
+ i.values.should == {:y => 7}
423
+ MODEL_DB.sqls.should == ["INSERT INTO blahblah (y) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
361
424
  end
362
425
  end
363
426
 
@@ -366,12 +429,8 @@ describe Sequel::Model, ".(un)?restrict_primary_key\\??" do
366
429
  @c = Class.new(Sequel::Model(:blahblah)) do
367
430
  set_primary_key :id
368
431
  columns :x, :y, :z, :id
369
- def refresh
370
- self
371
- end
372
432
  end
373
433
  @c.strict_param_setting = false
374
- @c.instance_variable_set(:@columns, [:x, :y, :z])
375
434
  end
376
435
 
377
436
  it "should restrict updates to primary key by default" do
@@ -408,11 +467,7 @@ describe Sequel::Model, ".strict_param_setting" do
408
467
  @c = Class.new(Sequel::Model(:blahblah)) do
409
468
  columns :x, :y, :z, :id
410
469
  set_restricted_columns :z
411
- def refresh
412
- self
413
- end
414
470
  end
415
- @c.instance_variable_set(:@columns, [:x, :y, :z])
416
471
  end
417
472
 
418
473
  it "should be enabled by default" do
@@ -469,20 +524,18 @@ end
469
524
 
470
525
  describe Sequel::Model, ".[] optimization" do
471
526
  before do
472
- @c = Class.new(Sequel::Model(:a))
473
- @c.instance_eval do
474
- def simple_table
475
- @simple_table
476
- end
477
- end
527
+ @db = MODEL_DB.clone
528
+ @db.quote_identifiers = true
529
+ @c = Class.new(Sequel::Model(@db))
478
530
  end
479
531
 
480
532
  it "should set simple_pk to the literalized primary key column name if a single primary key" do
481
- @c.simple_pk.should == 'id'
533
+ @c.set_primary_key :id
534
+ @c.simple_pk.should == '"id"'
482
535
  @c.set_primary_key :b
483
- @c.simple_pk.should == 'b'
536
+ @c.simple_pk.should == '"b"'
484
537
  @c.set_primary_key :b__a.identifier
485
- @c.simple_pk.should == 'b__a'
538
+ @c.simple_pk.should == '"b__a"'
486
539
  end
487
540
 
488
541
  it "should have simple_pk be blank if compound or no primary key" do
@@ -496,37 +549,57 @@ describe Sequel::Model, ".[] optimization" do
496
549
 
497
550
  it "should have simple table set if passed a Symbol to set_dataset" do
498
551
  @c.set_dataset :a
499
- @c.simple_table.should == 'a'
552
+ @c.simple_table.should == '"a"'
500
553
  @c.set_dataset :b
501
- @c.simple_table.should == 'b'
554
+ @c.simple_table.should == '"b"'
502
555
  @c.set_dataset :b__a
503
- @c.simple_table.should == 'b.a'
556
+ @c.simple_table.should == '"b"."a"'
557
+ end
558
+
559
+ it "should have simple_table set if passed a simple select all dataset to set_dataset" do
560
+ @c.set_dataset @db[:a]
561
+ @c.simple_table.should == '"a"'
562
+ @c.set_dataset @db[:b]
563
+ @c.simple_table.should == '"b"'
564
+ @c.set_dataset @db[:b__a]
565
+ @c.simple_table.should == '"b"."a"'
566
+ end
567
+
568
+ it "should simple_pk and simple_table respect dataset's identifier input methods" do
569
+ ds = @db[:ab]
570
+ ds.identifier_input_method = :reverse
571
+ @c.set_dataset ds
572
+ @c.simple_table.should == '"ba"'
573
+ @c.set_primary_key :cd
574
+ @c.simple_pk.should == '"dc"'
575
+
576
+ @c.set_dataset ds.from(:ef__gh)
577
+ @c.simple_table.should == '"fe"."hg"'
504
578
  end
505
579
 
506
- it "should have simple_table = nil if passed a dataset to set_dataset" do
507
- @c.set_dataset @c.db[:a]
580
+ it "should have simple_table = nil if passed a non-simple select all dataset to set_dataset" do
581
+ @c.set_dataset @c.db[:a].filter(:active)
508
582
  @c.simple_table.should == nil
509
583
  end
510
584
 
511
585
  it "should have simple_table superclasses setting if inheriting" do
512
- @c.set_dataset :a
513
- Class.new(@c).simple_table.should == 'a'
514
- @c.instance_variable_set(:@simple_table, nil)
515
586
  Class.new(@c).simple_table.should == nil
516
- @c.instance_variable_set(:@simple_table, "'b'")
517
- Class.new(@c).simple_table.should == "'b'"
587
+ @c.set_dataset :a
588
+ Class.new(@c).simple_table.should == '"a"'
518
589
  end
519
590
 
520
591
  it "should use Dataset#with_sql if simple_table and simple_pk are true" do
521
592
  @c.set_dataset :a
522
- @c.dataset.should_receive(:with_sql).and_return(@c.dataset)
523
- @c[1]
593
+ @c.dataset._fetch = {:id => 1}
594
+ @c[1].should == @c.load(:id=>1)
595
+ @db.sqls.should == ['SELECT * FROM "a" WHERE "id" = 1']
524
596
  end
525
597
 
526
598
  it "should not use Dataset#with_sql if either simple_table or simple_pk is nil" do
527
- @c.set_dataset @c.dataset
528
- @c.dataset.should_not_receive(:with_sql)
529
- @c[1]
599
+ @c.set_dataset @db[:a].filter(:active)
600
+ @c.dataset._fetch = {:id => 1}
601
+ @c[1].should == @c.load(:id=>1)
602
+ @db.sqls.should == ['SELECT * FROM "a" WHERE ("active" AND ("id" = 1)) LIMIT 1']
530
603
  end
531
604
  end
532
605
 
@@ -534,44 +607,41 @@ describe "Model datasets #with_pk" do
534
607
  before do
535
608
  @c = Class.new(Sequel::Model(:a))
536
609
  @ds = @c.dataset
537
- def @ds.fetch_rows(sql)
538
- db << sql
539
- yield(:id=>1)
540
- end
541
- @sqls = MODEL_DB.sqls
542
- @sqls.clear
610
+ @ds._fetch = {:id=>1}
611
+ MODEL_DB.reset
543
612
  end
544
613
 
545
614
  it "should return the first record where the primary key matches" do
546
615
  @ds.with_pk(1).should == @c.load(:id=>1)
547
- @sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
616
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
548
617
  end
549
618
 
550
619
  it "should handle existing filters" do
551
620
  @ds.filter(:a=>2).with_pk(1)
552
- @sqls.should == ["SELECT * FROM a WHERE ((a = 2) AND (a.id = 1)) LIMIT 1"]
621
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE ((a = 2) AND (a.id = 1)) LIMIT 1"]
553
622
  end
554
623
 
555
624
  it "should work with string values" do
556
625
  @ds.with_pk("foo")
557
- @sqls.should == ["SELECT * FROM a WHERE (a.id = 'foo') LIMIT 1"]
626
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 'foo') LIMIT 1"]
558
627
  end
559
628
 
560
629
  it "should handle an array for composite primary keys" do
561
630
  @c.set_primary_key :id1, :id2
562
631
  @ds.with_pk([1, 2])
632
+ sqls = MODEL_DB.sqls
563
633
  ["SELECT * FROM a WHERE ((a.id1 = 1) AND (a.id2 = 2)) LIMIT 1",
564
- "SELECT * FROM a WHERE ((a.id2 = 2) AND (a.id1 = 1)) LIMIT 1"].should include(@sqls.first)
565
- @sqls.length.should == 1
634
+ "SELECT * FROM a WHERE ((a.id2 = 2) AND (a.id1 = 1)) LIMIT 1"].should include(sqls.pop)
635
+ sqls.should == []
566
636
  end
567
637
 
568
638
  it "should have #[] consider an integer as a primary key lookup" do
569
639
  @ds[1].should == @c.load(:id=>1)
570
- @sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
640
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
571
641
  end
572
642
 
573
643
  it "should not have #[] consider a string as a primary key lookup" do
574
644
  @ds['foo'].should == @c.load(:id=>1)
575
- @sqls.should == ["SELECT * FROM a WHERE (foo) LIMIT 1"]
645
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (foo) LIMIT 1"]
576
646
  end
577
647
  end