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,209 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ require 'yaml'
4
+ require 'json'
5
+
6
+ describe "Serialization plugin" do
7
+ before do
8
+ @c = Class.new(Sequel::Model(:items)) do
9
+ include(Module.new do
10
+ def before_save
11
+ end
12
+ end)
13
+ no_primary_key
14
+ columns :id, :abc, :def, :ghi
15
+ end
16
+ MODEL_DB.reset
17
+ end
18
+
19
+ it "should allow setting additional serializable attributes via plugin :serialization call" do
20
+ @c.plugin :serialization, :yaml, :abc
21
+ @c.create(:abc => 1, :def=> 2)
22
+ MODEL_DB.sqls.last.should =~ /INSERT INTO items \((abc, def|def, abc)\) VALUES \(('--- 1\n', 2|2, '--- 1\n')\)/
23
+
24
+ @c.plugin :serialization, :marshal, :def
25
+ @c.create(:abc => 1, :def=> 1)
26
+ MODEL_DB.sqls.last.should =~ /INSERT INTO items \((abc, def|def, abc)\) VALUES \(('--- 1\n', 'BAhpBg==\n'|'BAhpBg==\n', '--- 1\n')\)/
27
+
28
+ @c.plugin :serialization, :json, :ghi
29
+ @c.create(:ghi => [123])
30
+ MODEL_DB.sqls.last.should =~ /INSERT INTO items \((ghi)\) VALUES \('\[123\]'\)/
31
+ end
32
+
33
+ it "should allow serializing attributes to yaml" do
34
+ @c.plugin :serialization, :yaml, :abc
35
+ @c.create(:abc => 1)
36
+ @c.create(:abc => "hello")
37
+
38
+ MODEL_DB.sqls.should == [ \
39
+ "INSERT INTO items (abc) VALUES ('--- 1\n')", \
40
+ "INSERT INTO items (abc) VALUES ('--- hello\n')", \
41
+ ]
42
+ end
43
+
44
+ it "serialization_format should be the serialization format used" do
45
+ @c.plugin :serialization, :yaml, :abc
46
+ @c.serialization_format.should == :yaml
47
+ end
48
+
49
+ it "serialized_columns should be the columns serialized" do
50
+ @c.plugin :serialization, :yaml, :abc
51
+ @c.serialized_columns.should == [:abc]
52
+ end
53
+
54
+ it "should allow serializing attributes to marshal" do
55
+ @c.plugin :serialization, :marshal, :abc
56
+ @c.create(:abc => 1)
57
+ @c.create(:abc => "hello")
58
+ x = [Marshal.dump("hello")].pack('m')
59
+
60
+ MODEL_DB.sqls.should == [ \
61
+ "INSERT INTO items (abc) VALUES ('BAhpBg==\n')", \
62
+ "INSERT INTO items (abc) VALUES ('#{x}')", \
63
+ ]
64
+ end
65
+
66
+ it "should allow serializing attributes to json" do
67
+ @c.plugin :serialization, :json, :ghi
68
+ @c.create(:ghi => [1])
69
+ @c.create(:ghi => ["hello"])
70
+
71
+ x = JSON.generate ["hello"]
72
+ MODEL_DB.sqls.should == [ \
73
+ "INSERT INTO items (ghi) VALUES ('[1]')", \
74
+ "INSERT INTO items (ghi) VALUES ('#{x}')", \
75
+ ]
76
+ end
77
+
78
+ it "should translate values to and from yaml serialization format using accessor methods" do
79
+ @c.set_primary_key :id
80
+ @c.plugin :serialization, :yaml, :abc, :def
81
+ vals = nil
82
+
83
+ ds = @c.dataset
84
+ def ds.fetch_rows(sql, &block)
85
+ block.call(:id => 1, :abc => "--- 1\n", :def => "--- hello\n")
86
+ end
87
+
88
+ o = @c.first
89
+ o.id.should == 1
90
+ o.abc.should == 1
91
+ o.abc.should == 1
92
+ o.def.should == "hello"
93
+ o.def.should == "hello"
94
+
95
+ o.update(:abc => 23)
96
+ @c.create(:abc => [1, 2, 3])
97
+ MODEL_DB.sqls.should == ["UPDATE items SET abc = '--- 23\n' WHERE (id = 1)",
98
+ "INSERT INTO items (abc) VALUES ('#{[1, 2, 3].to_yaml}')"]
99
+ end
100
+
101
+ it "should translate values to and from marshal serialization format using accessor methods" do
102
+ @c.set_primary_key :id
103
+ @c.plugin :serialization, :marshal, :abc, :def
104
+
105
+ ds = @c.dataset
106
+ def ds.fetch_rows(sql, &block)
107
+ block.call(:id => 1, :abc =>[Marshal.dump(1)].pack('m'), :def =>[Marshal.dump('hello')].pack('m'))
108
+ end
109
+
110
+ o = @c.first
111
+ o.id.should == 1
112
+ o.abc.should == 1
113
+ o.abc.should == 1
114
+ o.def.should == "hello"
115
+ o.def.should == "hello"
116
+
117
+ o.update(:abc => 23)
118
+ @c.create(:abc => [1, 2, 3])
119
+ MODEL_DB.sqls.should == ["UPDATE items SET abc = '#{[Marshal.dump(23)].pack('m')}' WHERE (id = 1)",
120
+ "INSERT INTO items (abc) VALUES ('#{[Marshal.dump([1, 2, 3])].pack('m')}')"]
121
+ end
122
+
123
+ it "should translate values to and from json serialization format using accessor methods" do
124
+ @c.set_primary_key :id
125
+ @c.plugin :serialization, :json, :abc, :def
126
+
127
+ ds = @c.dataset
128
+ def ds.fetch_rows(sql, &block)
129
+ block.call(:id => 1, :abc => JSON.generate([1]), :def => JSON.generate(["hello"]))
130
+ end
131
+
132
+ o = @c.first
133
+ o.id.should == 1
134
+ o.abc.should == [1]
135
+ o.abc.should == [1]
136
+ o.def.should == ["hello"]
137
+ o.def.should == ["hello"]
138
+
139
+ o.update(:abc => [23])
140
+ @c.create(:abc => [1,2,3])
141
+
142
+ MODEL_DB.sqls.should == ["UPDATE items SET abc = '#{JSON.generate([23])}' WHERE (id = 1)",
143
+ "INSERT INTO items (abc) VALUES ('#{JSON.generate([1,2,3])}')"]
144
+ end
145
+
146
+ it "should copy serialization formats and columns to subclasses" do
147
+ @c.set_primary_key :id
148
+ @c.plugin :serialization, :yaml, :abc, :def
149
+
150
+ ds = @c.dataset
151
+ def ds.fetch_rows(sql, &block)
152
+ block.call(:id => 1, :abc => "--- 1\n", :def => "--- hello\n")
153
+ end
154
+
155
+ o = Class.new(@c).first
156
+ o.id.should == 1
157
+ o.abc.should == 1
158
+ o.abc.should == 1
159
+ o.def.should == "hello"
160
+ o.def.should == "hello"
161
+
162
+ o.update(:abc => 23)
163
+ Class.new(@c).create(:abc => [1, 2, 3])
164
+ MODEL_DB.sqls.should == ["UPDATE items SET abc = '--- 23\n' WHERE (id = 1)",
165
+ "INSERT INTO items (abc) VALUES ('#{[1, 2, 3].to_yaml}')"]
166
+ end
167
+
168
+ it "should clear the deserialized columns when refreshing" do
169
+ @c.set_primary_key :id
170
+ @c.plugin :serialization, :yaml, :abc, :def
171
+ o = @c.load(:id => 1, :abc => "--- 1\n", :def => "--- hello\n")
172
+ o.abc = 23
173
+ o.deserialized_values.length.should == 1
174
+ o.abc.should == 23
175
+ o.refresh
176
+ o.deserialized_values.length.should == 0
177
+ end
178
+
179
+ it "should raise an error if calling internal serialization methods with bad columns" do
180
+ @c.set_primary_key :id
181
+ @c.plugin :serialization
182
+ o = @c.load(:id => 1, :abc => "--- 1\n", :def => "--- hello\n")
183
+ lambda{o.send(:serialize_value, :abc, 1)}.should raise_error(Sequel::Error)
184
+ lambda{o.send(:deserialize_value, :abc, "--- hello\n")}.should raise_error(Sequel::Error)
185
+ end
186
+
187
+ it "should add the accessors to a module included in the class, so they can be easily overridden" do
188
+ @c.class_eval do
189
+ def abc
190
+ "#{super}-blah"
191
+ end
192
+ end
193
+ @c.plugin :serialization, :yaml, :abc
194
+ o = @c.load(:abc => "--- 1\n")
195
+ o.abc.should == "1-blah"
196
+ end
197
+
198
+ it "should call super to get the deserialized value from a previous accessor" do
199
+ m = Module.new do
200
+ def abc
201
+ "--- #{@values[:abc]*3}\n"
202
+ end
203
+ end
204
+ @c.send(:include, m)
205
+ @c.plugin :serialization, :yaml, :abc
206
+ o = @c.load(:abc => 3)
207
+ o.abc.should == 9
208
+ end
209
+ end
@@ -0,0 +1,96 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe Sequel::Model, "#sti_key" do
4
+ before do
5
+ class ::StiTest < Sequel::Model
6
+ def kind; self[:kind]; end
7
+ def kind=(x); self[:kind] = x; end
8
+ def _refresh(x); end
9
+ plugin :single_table_inheritance, :kind
10
+ end
11
+ class ::StiTestSub1 < StiTest
12
+ end
13
+ class ::StiTestSub2 < StiTest
14
+ end
15
+ @ds = StiTest.dataset
16
+ MODEL_DB.reset
17
+ end
18
+ after do
19
+ Object.send(:remove_const, :StiTestSub1)
20
+ Object.send(:remove_const, :StiTestSub2)
21
+ Object.send(:remove_const, :StiTest)
22
+ end
23
+
24
+ specify "should have simple_table = nil" do
25
+ StiTest.simple_table.should == nil
26
+ StiTestSub1.simple_table.should == nil
27
+ end
28
+
29
+ it "should allow changing the inheritance column via a plugin :single_table_inheritance call" do
30
+ StiTest.plugin :single_table_inheritance, :blah
31
+ Object.send(:remove_const, :StiTestSub1)
32
+ Object.send(:remove_const, :StiTestSub2)
33
+ class ::StiTestSub1 < StiTest
34
+ end
35
+ class ::StiTestSub2 < StiTest
36
+ end
37
+ def @ds.fetch_rows(sql)
38
+ yield({:blah=>'StiTest'})
39
+ yield({:blah=>'StiTestSub1'})
40
+ yield({:blah=>'StiTestSub2'})
41
+ end
42
+ StiTest.all.collect{|x| x.class}.should == [StiTest, StiTestSub1, StiTestSub2]
43
+ StiTest.dataset.sql.should == "SELECT * FROM sti_tests"
44
+ StiTestSub1.dataset.sql.should == "SELECT * FROM sti_tests WHERE (sti_tests.blah = 'StiTestSub1')"
45
+ StiTestSub2.dataset.sql.should == "SELECT * FROM sti_tests WHERE (sti_tests.blah = 'StiTestSub2')"
46
+ end
47
+
48
+ it "should return rows with the correct class based on the polymorphic_key value" do
49
+ def @ds.fetch_rows(sql)
50
+ yield({:kind=>'StiTest'})
51
+ yield({:kind=>'StiTestSub1'})
52
+ yield({:kind=>'StiTestSub2'})
53
+ end
54
+ StiTest.all.collect{|x| x.class}.should == [StiTest, StiTestSub1, StiTestSub2]
55
+ end
56
+
57
+ it "should fallback to the main class if the given class does not exist" do
58
+ def @ds.fetch_rows(sql)
59
+ yield({:kind=>'StiTestSub3'})
60
+ end
61
+ StiTest.all.collect{|x| x.class}.should == [StiTest]
62
+ end
63
+
64
+ it "should fallback to the main class if the sti_key field is empty or nil without calling constantize" do
65
+ called = false
66
+ StiTest.meta_def(:constantize) do |s|
67
+ called = true
68
+ Object
69
+ end
70
+ StiTest.plugin :single_table_inheritance, :kind
71
+ def @ds.fetch_rows(sql)
72
+ yield({:kind=>''})
73
+ yield({:kind=>nil})
74
+ end
75
+ StiTest.all.collect{|x| x.class}.should == [StiTest, StiTest]
76
+ called.should == false
77
+ end
78
+
79
+ it "should add a before_create hook that sets the model class name for the key" do
80
+ StiTest.new.save
81
+ StiTestSub1.new.save
82
+ StiTestSub2.new.save
83
+ MODEL_DB.sqls.should == ["INSERT INTO sti_tests (kind) VALUES ('StiTest')", "INSERT INTO sti_tests (kind) VALUES ('StiTestSub1')", "INSERT INTO sti_tests (kind) VALUES ('StiTestSub2')"]
84
+ end
85
+
86
+ it "should have the before_create hook not override an existing value" do
87
+ StiTest.create(:kind=>'StiTestSub1')
88
+ MODEL_DB.sqls.should == ["INSERT INTO sti_tests (kind) VALUES ('StiTestSub1')"]
89
+ end
90
+
91
+ it "should add a filter to model datasets inside subclasses hook to only retreive objects with the matching key" do
92
+ StiTest.dataset.sql.should == "SELECT * FROM sti_tests"
93
+ StiTestSub1.dataset.sql.should == "SELECT * FROM sti_tests WHERE (sti_tests.kind = 'StiTestSub1')"
94
+ StiTestSub2.dataset.sql.should == "SELECT * FROM sti_tests WHERE (sti_tests.kind = 'StiTestSub2')"
95
+ end
96
+ end
@@ -0,0 +1,91 @@
1
+ require 'rubygems'
2
+ unless Object.const_defined?('Sequel')
3
+ $:.unshift(File.join(File.dirname(__FILE__), "../../lib/"))
4
+ require 'sequel/core'
5
+ end
6
+ unless Sequel.const_defined?('Model')
7
+ $:.unshift(File.join(File.dirname(__FILE__), "../../lib/"))
8
+ require 'sequel/model'
9
+ end
10
+
11
+ Sequel.extension(*%w'string_date_time inflector pagination query pretty_table blank migration schema_dumper looser_typecasting sql_expr thread_local_timezones')
12
+ {:hook_class_methods=>[], :schema=>[], :validation_class_methods=>[]}.each{|p, opts| Sequel::Model.plugin(p, *opts)}
13
+
14
+ class MockDataset < Sequel::Dataset
15
+ def insert(*args)
16
+ @db.execute insert_sql(*args)
17
+ end
18
+
19
+ def update(*args)
20
+ @db.execute update_sql(*args)
21
+ 1
22
+ end
23
+
24
+ def delete(*args)
25
+ @db.execute delete_sql(*args)
26
+ 1
27
+ end
28
+
29
+ def fetch_rows(sql)
30
+ return if sql =~ /information_schema/
31
+ @db.execute(sql)
32
+ yield({:id => 1, :x => 1})
33
+ end
34
+
35
+ def quoted_identifier(c)
36
+ "\"#{c}\""
37
+ end
38
+ end
39
+
40
+ class MockDatabase < Sequel::Database
41
+ @@quote_identifiers = false
42
+ self.identifier_input_method = nil
43
+ self.identifier_output_method = nil
44
+ attr_reader :sqls
45
+
46
+ def execute(sql, opts={})
47
+ @sqls ||= []
48
+ @sqls << sql
49
+ end
50
+
51
+ def new_sqls
52
+ s = sqls
53
+ reset
54
+ s
55
+ end
56
+
57
+ def reset
58
+ @sqls = []
59
+ end
60
+
61
+ def schema(table_name, opts)
62
+ if table_name
63
+ [[:id, {:primary_key=>true}]]
64
+ else
65
+ {table_name=>[[:id, {:primary_key=>true}]]}
66
+ end
67
+ end
68
+
69
+ def transaction(opts={}); yield; end
70
+
71
+ def dataset(opts=nil); MockDataset.new(self, opts); end
72
+ end
73
+
74
+ class << Sequel::Model
75
+ alias orig_columns columns
76
+ def columns(*cols)
77
+ return if cols.empty?
78
+ define_method(:columns){cols}
79
+ @dataset.instance_variable_set(:@columns, cols) if @dataset
80
+ def_column_accessor(*cols)
81
+ @columns = cols
82
+ @db_schema = {}
83
+ cols.each{|c| @db_schema[c] = {}}
84
+ end
85
+ def simple_table
86
+ nil
87
+ end
88
+ end
89
+
90
+ Sequel::Model.db = MODEL_DB = MockDatabase.new
91
+ Sequel::Model.use_transactions = false
@@ -0,0 +1,89 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ context "Sequel sql_expr extension" do
4
+ specify "Object#sql_expr should wrap the object in a GenericComplexExpression" do
5
+ o = Object.new
6
+ s = o.sql_expr
7
+ s.should be_a_kind_of(Sequel::SQL::GenericComplexExpression)
8
+ s.op.should == :NOOP
9
+ s.args.should == [o]
10
+ (s+1).should be_a_kind_of(Sequel::SQL::NumericExpression)
11
+ (s & true).should be_a_kind_of(Sequel::SQL::BooleanExpression)
12
+ (s < 1).should be_a_kind_of(Sequel::SQL::BooleanExpression)
13
+ s.sql_subscript(1).should be_a_kind_of(Sequel::SQL::Subscript)
14
+ s.like('a').should be_a_kind_of(Sequel::SQL::BooleanExpression)
15
+ s.as(:a).should be_a_kind_of(Sequel::SQL::AliasedExpression)
16
+ s.cast(Integer).should be_a_kind_of(Sequel::SQL::Cast)
17
+ s.desc.should be_a_kind_of(Sequel::SQL::OrderedExpression)
18
+ s.sql_string.should be_a_kind_of(Sequel::SQL::StringExpression)
19
+ end
20
+
21
+ specify "Numeric#sql_expr should wrap the object in a NumericExpression" do
22
+ [1, 2.0, 2^40, BigDecimal.new('1.0')].each do |o|
23
+ s = o.sql_expr
24
+ s.should be_a_kind_of(Sequel::SQL::NumericExpression)
25
+ s.op.should == :NOOP
26
+ s.args.should == [o]
27
+ end
28
+ end
29
+
30
+ specify "String#sql_expr should wrap the object in a StringExpression" do
31
+ o = ""
32
+ s = o.sql_expr
33
+ s.should be_a_kind_of(Sequel::SQL::StringExpression)
34
+ s.op.should == :NOOP
35
+ s.args.should == [o]
36
+ end
37
+
38
+ specify "NilClass, TrueClass, and FalseClass#sql_expr should wrap the object in a BooleanExpression" do
39
+ [nil, true, false].each do |o|
40
+ s = o.sql_expr
41
+ s.should be_a_kind_of(Sequel::SQL::BooleanExpression)
42
+ s.op.should == :NOOP
43
+ s.args.should == [o]
44
+ end
45
+ end
46
+
47
+ specify "Proc#sql_expr should should treat the object as a virtual row block" do
48
+ s = proc{a}.sql_expr
49
+ s.should be_a_kind_of(Sequel::SQL::Identifier)
50
+ s.value.should == :a
51
+
52
+ s = proc{a__b}.sql_expr
53
+ s.should be_a_kind_of(Sequel::SQL::QualifiedIdentifier)
54
+ s.table.should == "a"
55
+ s.column.should == "b"
56
+
57
+ s = proc{a(b)}.sql_expr
58
+ s.should be_a_kind_of(Sequel::SQL::Function)
59
+ s.f.should == :a
60
+ s.args.length.should == 1
61
+ s.args.first.should be_a_kind_of(Sequel::SQL::Identifier)
62
+ s.args.first.value.should == :b
63
+ end
64
+
65
+ specify "Proc#sql_expr should should wrap the object in a GenericComplexExpression if the object is not already an expression" do
66
+ s = proc{1}.sql_expr
67
+ s.should be_a_kind_of(Sequel::SQL::GenericComplexExpression)
68
+ s.op.should == :NOOP
69
+ s.args.should == [1]
70
+ end
71
+
72
+ specify "Proc#sql_expr should should convert a hash or array of two element arrays to a BooleanExpression" do
73
+ s = proc{{a=>b}}.sql_expr
74
+ s.should be_a_kind_of(Sequel::SQL::BooleanExpression)
75
+ s.op.should == :"="
76
+ s.args.first.should be_a_kind_of(Sequel::SQL::Identifier)
77
+ s.args.first.value.should == :a
78
+ s.args.last.should be_a_kind_of(Sequel::SQL::Identifier)
79
+ s.args.last.value.should == :b
80
+
81
+ s = proc{[[a,b]]}.sql_expr
82
+ s.should be_a_kind_of(Sequel::SQL::BooleanExpression)
83
+ s.op.should == :"="
84
+ s.args.first.should be_a_kind_of(Sequel::SQL::Identifier)
85
+ s.args.first.value.should == :a
86
+ s.args.last.should be_a_kind_of(Sequel::SQL::Identifier)
87
+ s.args.last.value.should == :b
88
+ end
89
+ end