viking-sequel 3.10.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 (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