viking-sequel 3.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (237) hide show
  1. data/CHANGELOG +3134 -0
  2. data/COPYING +19 -0
  3. data/README.rdoc +723 -0
  4. data/Rakefile +193 -0
  5. data/bin/sequel +196 -0
  6. data/doc/advanced_associations.rdoc +644 -0
  7. data/doc/cheat_sheet.rdoc +218 -0
  8. data/doc/dataset_basics.rdoc +106 -0
  9. data/doc/dataset_filtering.rdoc +158 -0
  10. data/doc/opening_databases.rdoc +296 -0
  11. data/doc/prepared_statements.rdoc +104 -0
  12. data/doc/reflection.rdoc +84 -0
  13. data/doc/release_notes/1.0.txt +38 -0
  14. data/doc/release_notes/1.1.txt +143 -0
  15. data/doc/release_notes/1.3.txt +101 -0
  16. data/doc/release_notes/1.4.0.txt +53 -0
  17. data/doc/release_notes/1.5.0.txt +155 -0
  18. data/doc/release_notes/2.0.0.txt +298 -0
  19. data/doc/release_notes/2.1.0.txt +271 -0
  20. data/doc/release_notes/2.10.0.txt +328 -0
  21. data/doc/release_notes/2.11.0.txt +215 -0
  22. data/doc/release_notes/2.12.0.txt +534 -0
  23. data/doc/release_notes/2.2.0.txt +253 -0
  24. data/doc/release_notes/2.3.0.txt +88 -0
  25. data/doc/release_notes/2.4.0.txt +106 -0
  26. data/doc/release_notes/2.5.0.txt +137 -0
  27. data/doc/release_notes/2.6.0.txt +157 -0
  28. data/doc/release_notes/2.7.0.txt +166 -0
  29. data/doc/release_notes/2.8.0.txt +171 -0
  30. data/doc/release_notes/2.9.0.txt +97 -0
  31. data/doc/release_notes/3.0.0.txt +221 -0
  32. data/doc/release_notes/3.1.0.txt +406 -0
  33. data/doc/release_notes/3.10.0.txt +286 -0
  34. data/doc/release_notes/3.2.0.txt +268 -0
  35. data/doc/release_notes/3.3.0.txt +192 -0
  36. data/doc/release_notes/3.4.0.txt +325 -0
  37. data/doc/release_notes/3.5.0.txt +510 -0
  38. data/doc/release_notes/3.6.0.txt +366 -0
  39. data/doc/release_notes/3.7.0.txt +179 -0
  40. data/doc/release_notes/3.8.0.txt +151 -0
  41. data/doc/release_notes/3.9.0.txt +233 -0
  42. data/doc/schema.rdoc +36 -0
  43. data/doc/sharding.rdoc +113 -0
  44. data/doc/virtual_rows.rdoc +205 -0
  45. data/lib/sequel.rb +1 -0
  46. data/lib/sequel/adapters/ado.rb +90 -0
  47. data/lib/sequel/adapters/ado/mssql.rb +30 -0
  48. data/lib/sequel/adapters/amalgalite.rb +176 -0
  49. data/lib/sequel/adapters/db2.rb +139 -0
  50. data/lib/sequel/adapters/dbi.rb +113 -0
  51. data/lib/sequel/adapters/do.rb +188 -0
  52. data/lib/sequel/adapters/do/mysql.rb +49 -0
  53. data/lib/sequel/adapters/do/postgres.rb +91 -0
  54. data/lib/sequel/adapters/do/sqlite.rb +40 -0
  55. data/lib/sequel/adapters/firebird.rb +283 -0
  56. data/lib/sequel/adapters/informix.rb +77 -0
  57. data/lib/sequel/adapters/jdbc.rb +587 -0
  58. data/lib/sequel/adapters/jdbc/as400.rb +58 -0
  59. data/lib/sequel/adapters/jdbc/h2.rb +133 -0
  60. data/lib/sequel/adapters/jdbc/mssql.rb +57 -0
  61. data/lib/sequel/adapters/jdbc/mysql.rb +78 -0
  62. data/lib/sequel/adapters/jdbc/oracle.rb +50 -0
  63. data/lib/sequel/adapters/jdbc/postgresql.rb +108 -0
  64. data/lib/sequel/adapters/jdbc/sqlite.rb +55 -0
  65. data/lib/sequel/adapters/mysql.rb +421 -0
  66. data/lib/sequel/adapters/odbc.rb +143 -0
  67. data/lib/sequel/adapters/odbc/mssql.rb +42 -0
  68. data/lib/sequel/adapters/openbase.rb +64 -0
  69. data/lib/sequel/adapters/oracle.rb +131 -0
  70. data/lib/sequel/adapters/postgres.rb +504 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +490 -0
  72. data/lib/sequel/adapters/shared/mysql.rb +498 -0
  73. data/lib/sequel/adapters/shared/oracle.rb +195 -0
  74. data/lib/sequel/adapters/shared/postgres.rb +830 -0
  75. data/lib/sequel/adapters/shared/progress.rb +44 -0
  76. data/lib/sequel/adapters/shared/sqlite.rb +389 -0
  77. data/lib/sequel/adapters/sqlite.rb +224 -0
  78. data/lib/sequel/adapters/utils/stored_procedures.rb +84 -0
  79. data/lib/sequel/connection_pool.rb +99 -0
  80. data/lib/sequel/connection_pool/sharded_single.rb +84 -0
  81. data/lib/sequel/connection_pool/sharded_threaded.rb +211 -0
  82. data/lib/sequel/connection_pool/single.rb +29 -0
  83. data/lib/sequel/connection_pool/threaded.rb +150 -0
  84. data/lib/sequel/core.rb +293 -0
  85. data/lib/sequel/core_sql.rb +241 -0
  86. data/lib/sequel/database.rb +1079 -0
  87. data/lib/sequel/database/schema_generator.rb +327 -0
  88. data/lib/sequel/database/schema_methods.rb +203 -0
  89. data/lib/sequel/database/schema_sql.rb +320 -0
  90. data/lib/sequel/dataset.rb +32 -0
  91. data/lib/sequel/dataset/actions.rb +441 -0
  92. data/lib/sequel/dataset/features.rb +86 -0
  93. data/lib/sequel/dataset/graph.rb +254 -0
  94. data/lib/sequel/dataset/misc.rb +119 -0
  95. data/lib/sequel/dataset/mutation.rb +64 -0
  96. data/lib/sequel/dataset/prepared_statements.rb +227 -0
  97. data/lib/sequel/dataset/query.rb +709 -0
  98. data/lib/sequel/dataset/sql.rb +996 -0
  99. data/lib/sequel/exceptions.rb +51 -0
  100. data/lib/sequel/extensions/blank.rb +43 -0
  101. data/lib/sequel/extensions/inflector.rb +242 -0
  102. data/lib/sequel/extensions/looser_typecasting.rb +21 -0
  103. data/lib/sequel/extensions/migration.rb +239 -0
  104. data/lib/sequel/extensions/named_timezones.rb +61 -0
  105. data/lib/sequel/extensions/pagination.rb +100 -0
  106. data/lib/sequel/extensions/pretty_table.rb +82 -0
  107. data/lib/sequel/extensions/query.rb +52 -0
  108. data/lib/sequel/extensions/schema_dumper.rb +271 -0
  109. data/lib/sequel/extensions/sql_expr.rb +122 -0
  110. data/lib/sequel/extensions/string_date_time.rb +46 -0
  111. data/lib/sequel/extensions/thread_local_timezones.rb +48 -0
  112. data/lib/sequel/metaprogramming.rb +9 -0
  113. data/lib/sequel/model.rb +120 -0
  114. data/lib/sequel/model/associations.rb +1514 -0
  115. data/lib/sequel/model/base.rb +1069 -0
  116. data/lib/sequel/model/default_inflections.rb +45 -0
  117. data/lib/sequel/model/errors.rb +39 -0
  118. data/lib/sequel/model/exceptions.rb +21 -0
  119. data/lib/sequel/model/inflections.rb +162 -0
  120. data/lib/sequel/model/plugins.rb +70 -0
  121. data/lib/sequel/plugins/active_model.rb +59 -0
  122. data/lib/sequel/plugins/association_dependencies.rb +103 -0
  123. data/lib/sequel/plugins/association_proxies.rb +41 -0
  124. data/lib/sequel/plugins/boolean_readers.rb +53 -0
  125. data/lib/sequel/plugins/caching.rb +141 -0
  126. data/lib/sequel/plugins/class_table_inheritance.rb +214 -0
  127. data/lib/sequel/plugins/composition.rb +138 -0
  128. data/lib/sequel/plugins/force_encoding.rb +72 -0
  129. data/lib/sequel/plugins/hook_class_methods.rb +126 -0
  130. data/lib/sequel/plugins/identity_map.rb +116 -0
  131. data/lib/sequel/plugins/instance_filters.rb +98 -0
  132. data/lib/sequel/plugins/instance_hooks.rb +57 -0
  133. data/lib/sequel/plugins/lazy_attributes.rb +77 -0
  134. data/lib/sequel/plugins/many_through_many.rb +208 -0
  135. data/lib/sequel/plugins/nested_attributes.rb +206 -0
  136. data/lib/sequel/plugins/optimistic_locking.rb +81 -0
  137. data/lib/sequel/plugins/rcte_tree.rb +281 -0
  138. data/lib/sequel/plugins/schema.rb +66 -0
  139. data/lib/sequel/plugins/serialization.rb +166 -0
  140. data/lib/sequel/plugins/single_table_inheritance.rb +74 -0
  141. data/lib/sequel/plugins/subclasses.rb +45 -0
  142. data/lib/sequel/plugins/tactical_eager_loading.rb +61 -0
  143. data/lib/sequel/plugins/timestamps.rb +87 -0
  144. data/lib/sequel/plugins/touch.rb +118 -0
  145. data/lib/sequel/plugins/typecast_on_load.rb +72 -0
  146. data/lib/sequel/plugins/validation_class_methods.rb +405 -0
  147. data/lib/sequel/plugins/validation_helpers.rb +223 -0
  148. data/lib/sequel/sql.rb +1020 -0
  149. data/lib/sequel/timezones.rb +161 -0
  150. data/lib/sequel/version.rb +12 -0
  151. data/lib/sequel_core.rb +1 -0
  152. data/lib/sequel_model.rb +1 -0
  153. data/spec/adapters/firebird_spec.rb +407 -0
  154. data/spec/adapters/informix_spec.rb +97 -0
  155. data/spec/adapters/mssql_spec.rb +403 -0
  156. data/spec/adapters/mysql_spec.rb +1019 -0
  157. data/spec/adapters/oracle_spec.rb +286 -0
  158. data/spec/adapters/postgres_spec.rb +969 -0
  159. data/spec/adapters/spec_helper.rb +51 -0
  160. data/spec/adapters/sqlite_spec.rb +432 -0
  161. data/spec/core/connection_pool_spec.rb +808 -0
  162. data/spec/core/core_sql_spec.rb +417 -0
  163. data/spec/core/database_spec.rb +1662 -0
  164. data/spec/core/dataset_spec.rb +3827 -0
  165. data/spec/core/expression_filters_spec.rb +595 -0
  166. data/spec/core/object_graph_spec.rb +296 -0
  167. data/spec/core/schema_generator_spec.rb +159 -0
  168. data/spec/core/schema_spec.rb +830 -0
  169. data/spec/core/spec_helper.rb +56 -0
  170. data/spec/core/version_spec.rb +7 -0
  171. data/spec/extensions/active_model_spec.rb +76 -0
  172. data/spec/extensions/association_dependencies_spec.rb +127 -0
  173. data/spec/extensions/association_proxies_spec.rb +50 -0
  174. data/spec/extensions/blank_spec.rb +67 -0
  175. data/spec/extensions/boolean_readers_spec.rb +92 -0
  176. data/spec/extensions/caching_spec.rb +250 -0
  177. data/spec/extensions/class_table_inheritance_spec.rb +252 -0
  178. data/spec/extensions/composition_spec.rb +194 -0
  179. data/spec/extensions/force_encoding_spec.rb +117 -0
  180. data/spec/extensions/hook_class_methods_spec.rb +470 -0
  181. data/spec/extensions/identity_map_spec.rb +202 -0
  182. data/spec/extensions/inflector_spec.rb +181 -0
  183. data/spec/extensions/instance_filters_spec.rb +55 -0
  184. data/spec/extensions/instance_hooks_spec.rb +133 -0
  185. data/spec/extensions/lazy_attributes_spec.rb +153 -0
  186. data/spec/extensions/looser_typecasting_spec.rb +39 -0
  187. data/spec/extensions/many_through_many_spec.rb +884 -0
  188. data/spec/extensions/migration_spec.rb +332 -0
  189. data/spec/extensions/named_timezones_spec.rb +72 -0
  190. data/spec/extensions/nested_attributes_spec.rb +396 -0
  191. data/spec/extensions/optimistic_locking_spec.rb +100 -0
  192. data/spec/extensions/pagination_spec.rb +99 -0
  193. data/spec/extensions/pretty_table_spec.rb +91 -0
  194. data/spec/extensions/query_spec.rb +85 -0
  195. data/spec/extensions/rcte_tree_spec.rb +205 -0
  196. data/spec/extensions/schema_dumper_spec.rb +357 -0
  197. data/spec/extensions/schema_spec.rb +127 -0
  198. data/spec/extensions/serialization_spec.rb +209 -0
  199. data/spec/extensions/single_table_inheritance_spec.rb +96 -0
  200. data/spec/extensions/spec_helper.rb +91 -0
  201. data/spec/extensions/sql_expr_spec.rb +89 -0
  202. data/spec/extensions/string_date_time_spec.rb +93 -0
  203. data/spec/extensions/subclasses_spec.rb +52 -0
  204. data/spec/extensions/tactical_eager_loading_spec.rb +65 -0
  205. data/spec/extensions/thread_local_timezones_spec.rb +45 -0
  206. data/spec/extensions/timestamps_spec.rb +150 -0
  207. data/spec/extensions/touch_spec.rb +155 -0
  208. data/spec/extensions/typecast_on_load_spec.rb +69 -0
  209. data/spec/extensions/validation_class_methods_spec.rb +984 -0
  210. data/spec/extensions/validation_helpers_spec.rb +438 -0
  211. data/spec/integration/associations_test.rb +281 -0
  212. data/spec/integration/database_test.rb +26 -0
  213. data/spec/integration/dataset_test.rb +963 -0
  214. data/spec/integration/eager_loader_test.rb +734 -0
  215. data/spec/integration/model_test.rb +130 -0
  216. data/spec/integration/plugin_test.rb +814 -0
  217. data/spec/integration/prepared_statement_test.rb +213 -0
  218. data/spec/integration/schema_test.rb +361 -0
  219. data/spec/integration/spec_helper.rb +73 -0
  220. data/spec/integration/timezone_test.rb +55 -0
  221. data/spec/integration/transaction_test.rb +122 -0
  222. data/spec/integration/type_test.rb +96 -0
  223. data/spec/model/association_reflection_spec.rb +175 -0
  224. data/spec/model/associations_spec.rb +2633 -0
  225. data/spec/model/base_spec.rb +418 -0
  226. data/spec/model/dataset_methods_spec.rb +78 -0
  227. data/spec/model/eager_loading_spec.rb +1391 -0
  228. data/spec/model/hooks_spec.rb +240 -0
  229. data/spec/model/inflector_spec.rb +26 -0
  230. data/spec/model/model_spec.rb +593 -0
  231. data/spec/model/plugins_spec.rb +236 -0
  232. data/spec/model/record_spec.rb +1500 -0
  233. data/spec/model/spec_helper.rb +97 -0
  234. data/spec/model/validations_spec.rb +153 -0
  235. data/spec/rcov.opts +6 -0
  236. data/spec/spec_config.rb.example +10 -0
  237. metadata +346 -0
@@ -0,0 +1,418 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe "Model attribute setters" do
4
+
5
+ before(:each) do
6
+ MODEL_DB.reset
7
+
8
+ @c = Class.new(Sequel::Model(:items)) do
9
+ columns :id, :x, :y, :"x y"
10
+ end
11
+ @o = @c.new
12
+ end
13
+
14
+ it "should mark the column value as changed" do
15
+ @o.changed_columns.should == []
16
+
17
+ @o.x = 2
18
+ @o.changed_columns.should == [:x]
19
+
20
+ @o.y = 3
21
+ @o.changed_columns.should == [:x, :y]
22
+
23
+ @o.changed_columns.clear
24
+
25
+ @o[:x] = 2
26
+ @o.changed_columns.should == [:x]
27
+
28
+ @o[:y] = 3
29
+ @o.changed_columns.should == [:x, :y]
30
+ end
31
+
32
+ it "should have columns that can't be called like normal ruby methods" do
33
+ @o.send(:"x y=", 3)
34
+ @o.changed_columns.should == [:"x y"]
35
+ @o.values.should == {:"x y"=>3}
36
+ @o.send(:"x y").should == 3
37
+ end
38
+ end
39
+
40
+ describe Sequel::Model, "dataset" do
41
+ before do
42
+ @a = Class.new(Sequel::Model(:items))
43
+ @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
56
+ end
57
+
58
+ specify "should default to the plural of the class name" do
59
+ Maggot.dataset.sql.should == 'SELECT * FROM maggots'
60
+ ShoeSize.dataset.sql.should == 'SELECT * FROM shoe_sizes'
61
+ end
62
+
63
+ specify "should return the dataset for the superclass if available" do
64
+ BootSize.dataset.sql.should == 'SELECT * FROM shoe_sizes'
65
+ end
66
+
67
+ specify "should return the correct dataset if set explicitly" do
68
+ Elephant.dataset.sql.should == 'SELECT * FROM ele1'
69
+ @a.dataset.sql.should == 'SELECT * FROM items'
70
+ end
71
+
72
+ specify "should raise if no dataset is explicitly set and the class is anonymous" do
73
+ proc {@b.dataset}.should raise_error(Sequel::Error)
74
+ end
75
+
76
+ specify "should disregard namespaces for the table name" do
77
+ module BlahBlah
78
+ class MwaHaHa < Sequel::Model
79
+ end
80
+ end
81
+
82
+ BlahBlah::MwaHaHa.dataset.sql.should == 'SELECT * FROM mwa_ha_has'
83
+ end
84
+ end
85
+
86
+ describe Sequel::Model, ".def_dataset_method" do
87
+ before do
88
+ @c = Class.new(Sequel::Model(:items)) do
89
+ end
90
+ end
91
+
92
+ 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
96
+ @c.return_3.should == 3
97
+ @c.dataset.return_3.should == 3
98
+ end
99
+
100
+ it "should add all passed methods to the model if called without a block argument" do
101
+ @c.instance_eval do
102
+ def_dataset_method(:return_3, :return_4)
103
+ end
104
+ proc{@c.return_3}.should raise_error(NoMethodError)
105
+ proc{@c.return_4}.should raise_error(NoMethodError)
106
+ @c.dataset.instance_eval do
107
+ def return_3; 3; end
108
+ def return_4; 4; end
109
+ end
110
+ @c.return_3.should == 3
111
+ @c.return_4.should == 4
112
+ end
113
+
114
+ 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
118
+ @c.set_dataset :items
119
+ @c.return_3.should == 3
120
+ @c.dataset.return_3.should == 3
121
+ end
122
+
123
+ 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
127
+ c = Class.new(@c)
128
+ c.set_dataset :items
129
+ c.return_3.should == 3
130
+ c.dataset.return_3.should == 3
131
+ end
132
+ end
133
+
134
+ describe "A model class with implicit table name" do
135
+ before do
136
+ class Donkey < Sequel::Model
137
+ end
138
+ end
139
+
140
+ specify "should have a dataset associated with the model class" do
141
+ Donkey.dataset.model.should == Donkey
142
+ end
143
+ end
144
+
145
+ describe "A model inheriting from a model" do
146
+ before do
147
+ class Feline < Sequel::Model
148
+ end
149
+
150
+ class Leopard < Feline
151
+ end
152
+ end
153
+
154
+ specify "should have a dataset associated with itself" do
155
+ Feline.dataset.model.should == Feline
156
+ Leopard.dataset.model.should == Leopard
157
+ end
158
+ end
159
+
160
+ describe "Model.db=" do
161
+ before do
162
+ $db1 = MockDatabase.new
163
+ $db2 = MockDatabase.new
164
+
165
+ class BlueBlue < Sequel::Model(:items)
166
+ set_dataset $db1[:blue].filter(:x=>1)
167
+ end
168
+ end
169
+
170
+ specify "should affect the underlying dataset" do
171
+ BlueBlue.db = $db2
172
+
173
+ BlueBlue.dataset.db.should === $db2
174
+ BlueBlue.dataset.db.should_not === $db1
175
+ end
176
+
177
+ specify "should keep the same dataset options" do
178
+ BlueBlue.db = $db2
179
+ BlueBlue.dataset.sql.should == 'SELECT * FROM blue WHERE (x = 1)'
180
+ end
181
+
182
+ specify "should use the database for subclasses" do
183
+ BlueBlue.db = $db2
184
+ Class.new(BlueBlue).db.should === $db2
185
+ end
186
+ end
187
+
188
+ describe Sequel::Model, ".(allowed|restricted)_columns " do
189
+ before do
190
+ @c = Class.new(Sequel::Model(:blahblah)) do
191
+ columns :x, :y, :z
192
+ def _refresh(ds)
193
+ self
194
+ end
195
+ end
196
+ @c.strict_param_setting = false
197
+ @c.instance_variable_set(:@columns, [:x, :y, :z])
198
+ end
199
+
200
+ it "should set the allowed columns correctly" do
201
+ @c.allowed_columns.should == nil
202
+ @c.set_allowed_columns :x
203
+ @c.allowed_columns.should == [:x]
204
+ @c.set_allowed_columns :x, :y
205
+ @c.allowed_columns.should == [:x, :y]
206
+ end
207
+
208
+ it "should set the restricted columns correctly" do
209
+ @c.restricted_columns.should == nil
210
+ @c.set_restricted_columns :x
211
+ @c.restricted_columns.should == [:x]
212
+ @c.set_restricted_columns :x, :y
213
+ @c.restricted_columns.should == [:x, :y]
214
+ end
215
+
216
+ it "should only set allowed columns by default" do
217
+ @c.set_allowed_columns :x, :y
218
+ i = @c.new(:x => 1, :y => 2, :z => 3)
219
+ i.values.should == {:x => 1, :y => 2}
220
+ i.set(:x => 4, :y => 5, :z => 6)
221
+ i.values.should == {:x => 4, :y => 5}
222
+ i.update(:x => 7, :y => 8, :z => 9)
223
+ i.values.delete(:id) # stupid specs
224
+ i.values.should == {:x => 7, :y => 8}
225
+ end
226
+
227
+ it "should not set restricted columns by default" do
228
+ @c.set_restricted_columns :z
229
+ i = @c.new(:x => 1, :y => 2, :z => 3)
230
+ i.values.should == {:x => 1, :y => 2}
231
+ i.set(:x => 4, :y => 5, :z => 6)
232
+ i.values.should == {:x => 4, :y => 5}
233
+ i.update(:x => 7, :y => 8, :z => 9)
234
+ i.values.delete(:id) # stupid specs
235
+ i.values.should == {:x => 7, :y => 8}
236
+ end
237
+
238
+ it "should have allowed take precedence over restricted" do
239
+ @c.set_allowed_columns :x, :y
240
+ @c.set_restricted_columns :y, :z
241
+ i = @c.new(:x => 1, :y => 2, :z => 3)
242
+ i.values.should == {:x => 1, :y => 2}
243
+ i.set(:x => 4, :y => 5, :z => 6)
244
+ i.values.should == {:x => 4, :y => 5}
245
+ i.update(:x => 7, :y => 8, :z => 9)
246
+ i.values.delete(:id) # stupid specs
247
+ i.values.should == {:x => 7, :y => 8}
248
+ end
249
+ end
250
+
251
+ describe Sequel::Model, ".(un)?restrict_primary_key\\??" do
252
+ before do
253
+ @c = Class.new(Sequel::Model(:blahblah)) do
254
+ set_primary_key :id
255
+ columns :x, :y, :z, :id
256
+ def refresh
257
+ self
258
+ end
259
+ end
260
+ @c.strict_param_setting = false
261
+ @c.instance_variable_set(:@columns, [:x, :y, :z])
262
+ end
263
+
264
+ it "should restrict updates to primary key by default" do
265
+ i = @c.new(:x => 1, :y => 2, :id => 3)
266
+ i.values.should == {:x => 1, :y => 2}
267
+ i.set(:x => 4, :y => 5, :id => 6)
268
+ i.values.should == {:x => 4, :y => 5}
269
+ end
270
+
271
+ it "should allow updates to primary key if unrestrict_primary_key is used" do
272
+ @c.unrestrict_primary_key
273
+ i = @c.new(:x => 1, :y => 2, :id => 3)
274
+ i.values.should == {:x => 1, :y => 2, :id=>3}
275
+ i.set(:x => 4, :y => 5, :id => 6)
276
+ i.values.should == {:x => 4, :y => 5, :id=>6}
277
+ end
278
+
279
+ it "should have restrict_primary_key? return true or false depending" do
280
+ @c.restrict_primary_key?.should == true
281
+ @c.unrestrict_primary_key
282
+ @c.restrict_primary_key?.should == false
283
+ c1 = Class.new(@c)
284
+ c1.restrict_primary_key?.should == false
285
+ @c.restrict_primary_key
286
+ @c.restrict_primary_key?.should == true
287
+ c1.restrict_primary_key?.should == false
288
+ c2 = Class.new(@c)
289
+ c2.restrict_primary_key?.should == true
290
+ end
291
+ end
292
+
293
+ describe Sequel::Model, ".strict_param_setting" do
294
+ before do
295
+ @c = Class.new(Sequel::Model(:blahblah)) do
296
+ columns :x, :y, :z, :id
297
+ set_restricted_columns :z
298
+ def refresh
299
+ self
300
+ end
301
+ end
302
+ @c.instance_variable_set(:@columns, [:x, :y, :z])
303
+ end
304
+
305
+ it "should be enabled by default" do
306
+ @c.strict_param_setting.should == true
307
+ end
308
+
309
+ it "should raise an error if a missing/restricted column/method is accessed" do
310
+ proc{@c.new(:z=>1)}.should raise_error(Sequel::Error)
311
+ proc{@c.create(:z=>1)}.should raise_error(Sequel::Error)
312
+ c = @c.new
313
+ proc{c.set(:z=>1)}.should raise_error(Sequel::Error)
314
+ proc{c.set_all(:id=>1)}.should raise_error(Sequel::Error)
315
+ proc{c.set_only({:x=>1}, :y)}.should raise_error(Sequel::Error)
316
+ proc{c.set_except({:x=>1}, :x)}.should raise_error(Sequel::Error)
317
+ proc{c.update(:z=>1)}.should raise_error(Sequel::Error)
318
+ proc{c.update_all(:id=>1)}.should raise_error(Sequel::Error)
319
+ proc{c.update_only({:x=>1}, :y)}.should raise_error(Sequel::Error)
320
+ proc{c.update_except({:x=>1}, :x)}.should raise_error(Sequel::Error)
321
+ end
322
+
323
+ it "should be disabled by strict_param_setting = false" do
324
+ @c.strict_param_setting = false
325
+ @c.strict_param_setting.should == false
326
+ proc{@c.new(:z=>1)}.should_not raise_error
327
+ end
328
+ end
329
+
330
+ describe Sequel::Model, ".require_modification" do
331
+ before do
332
+ @ds1 = MODEL_DB[:items]
333
+ @ds1.meta_def(:provides_accurate_rows_matched?){false}
334
+ @ds2 = MODEL_DB[:items]
335
+ @ds2.meta_def(:provides_accurate_rows_matched?){true}
336
+ end
337
+ after do
338
+ Sequel::Model.require_modification = nil
339
+ end
340
+
341
+ it "should depend on whether the dataset provides an accurate number of rows matched by default" do
342
+ Class.new(Sequel::Model(@ds1)).require_modification.should == false
343
+ Class.new(Sequel::Model(@ds2)).require_modification.should == true
344
+ end
345
+
346
+ it "should obey global setting regardless of dataset support if set" do
347
+ Sequel::Model.require_modification = true
348
+ Class.new(Sequel::Model(@ds1)).require_modification.should == true
349
+ Class.new(Sequel::Model(@ds2)).require_modification.should == true
350
+
351
+ Sequel::Model.require_modification = false
352
+ Class.new(Sequel::Model(@ds1)).require_modification.should == false
353
+ Class.new(Sequel::Model(@ds2)).require_modification.should == false
354
+ end
355
+ end
356
+
357
+ describe Sequel::Model, ".[] optimization" do
358
+ before do
359
+ @c = Class.new(Sequel::Model(:a))
360
+ @c.instance_eval do
361
+ def simple_table
362
+ @simple_table
363
+ end
364
+ end
365
+ end
366
+
367
+ it "should set simple_pk to the literalized primary key column name if a single primary key" do
368
+ @c.simple_pk.should == 'id'
369
+ @c.set_primary_key :b
370
+ @c.simple_pk.should == 'b'
371
+ @c.set_primary_key :b__a.identifier
372
+ @c.simple_pk.should == 'b__a'
373
+ end
374
+
375
+ it "should have simple_pk be blank if compound or no primary key" do
376
+ @c.no_primary_key
377
+ @c.simple_pk.should == nil
378
+ @c.set_primary_key :b, :a
379
+ @c.simple_pk.should == nil
380
+ @c.set_primary_key [:b, :a]
381
+ @c.simple_pk.should == nil
382
+ end
383
+
384
+ it "should have simple table set if passed a Symbol to set_dataset" do
385
+ @c.set_dataset :a
386
+ @c.simple_table.should == 'a'
387
+ @c.set_dataset :b
388
+ @c.simple_table.should == 'b'
389
+ @c.set_dataset :b__a
390
+ @c.simple_table.should == 'b.a'
391
+ end
392
+
393
+ it "should have simple_table = nil if passed a dataset to set_dataset" do
394
+ @c.set_dataset @c.db[:a]
395
+ @c.simple_table.should == nil
396
+ end
397
+
398
+ it "should have simple_table superclasses setting if inheriting" do
399
+ @c.set_dataset :a
400
+ Class.new(@c).simple_table.should == 'a'
401
+ @c.instance_variable_set(:@simple_table, nil)
402
+ Class.new(@c).simple_table.should == nil
403
+ @c.instance_variable_set(:@simple_table, "'b'")
404
+ Class.new(@c).simple_table.should == "'b'"
405
+ end
406
+
407
+ it "should use Dataset#with_sql if simple_table and simple_pk are true" do
408
+ @c.set_dataset :a
409
+ @c.dataset.should_receive(:with_sql).and_return(@c.dataset)
410
+ @c[1]
411
+ end
412
+
413
+ it "should not use Dataset#with_sql if either simple_table or simple_pk is nil" do
414
+ @c.set_dataset @c.dataset
415
+ @c.dataset.should_not_receive(:with_sql)
416
+ @c[1]
417
+ end
418
+ end
@@ -0,0 +1,78 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe Sequel::Model::DatasetMethods, "#destroy" do
4
+ before do
5
+ @c = Class.new(Sequel::Model(:items)) do
6
+ @@destroyed = []
7
+ def destroy
8
+ @@destroyed << self
9
+ end
10
+ def self.destroyed
11
+ @@destroyed
12
+ end
13
+ end
14
+ @d = @c.dataset
15
+ end
16
+
17
+ it "should instantiate objects in the dataset and call destroy on each" do
18
+ def @d.fetch_rows(sql)
19
+ yield({:id=>1})
20
+ yield({:id=>2})
21
+ end
22
+ @d.destroy
23
+ @c.destroyed.collect{|x| x.values}.should == [{:id=>1}, {:id=>2}]
24
+ end
25
+
26
+ it "should return the number of records destroyed" do
27
+ def @d.fetch_rows(sql)
28
+ yield({:id=>1})
29
+ yield({:id=>2})
30
+ end
31
+ @d.destroy.should == 2
32
+ def @d.fetch_rows(sql)
33
+ yield({:id=>1})
34
+ end
35
+ @d.destroy.should == 1
36
+ def @d.fetch_rows(sql)
37
+ end
38
+ @d.destroy.should == 0
39
+ end
40
+ end
41
+
42
+ describe Sequel::Model::DatasetMethods, "#to_hash" do
43
+ before do
44
+ @c = Class.new(Sequel::Model(:items)) do
45
+ set_primary_key :name
46
+ end
47
+ @d = @c.dataset
48
+ end
49
+
50
+ it "should result in a hash with primary key value keys and model object values" do
51
+ def @d.fetch_rows(sql)
52
+ yield({:name=>1})
53
+ yield({:name=>2})
54
+ end
55
+ h = @d.to_hash
56
+ h.should be_a_kind_of(Hash)
57
+ a = h.to_a
58
+ a.collect{|x| x[1].class}.should == [@c, @c]
59
+ a.sort_by{|x| x[0]}.collect{|x| [x[0], x[1].values]}.should == [[1, {:name=>1}], [2, {:name=>2}]]
60
+ end
61
+
62
+ it "should result in a hash with given value keys and model object values" do
63
+ def @d.fetch_rows(sql)
64
+ yield({:name=>1, :number=>3})
65
+ yield({:name=>2, :number=>4})
66
+ end
67
+ h = @d.to_hash(:number)
68
+ h.should be_a_kind_of(Hash)
69
+ a = h.to_a
70
+ a.collect{|x| x[1].class}.should == [@c, @c]
71
+ a.sort_by{|x| x[0]}.collect{|x| [x[0], x[1].values]}.should == [[3, {:name=>1, :number=>3}], [4, {:name=>2, :number=>4}]]
72
+ end
73
+
74
+ it "should raise an error if the class doesn't have a primary key" do
75
+ @c.no_primary_key
76
+ proc{@d.to_hash}.should raise_error(Sequel::Error)
77
+ end
78
+ end