sequel 3.28.0 → 3.29.0

Sign up to get free protection for your applications and to get access to all the features.
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