sequel 3.21.0 → 3.39.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 (352) hide show
  1. data/CHANGELOG +1061 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +103 -63
  4. data/Rakefile +59 -27
  5. data/bin/sequel +50 -26
  6. data/doc/active_record.rdoc +67 -51
  7. data/doc/advanced_associations.rdoc +189 -75
  8. data/doc/association_basics.rdoc +327 -79
  9. data/doc/cheat_sheet.rdoc +21 -21
  10. data/doc/core_extensions.rdoc +374 -0
  11. data/doc/dataset_basics.rdoc +10 -10
  12. data/doc/dataset_filtering.rdoc +54 -42
  13. data/doc/mass_assignment.rdoc +56 -0
  14. data/doc/migration.rdoc +89 -557
  15. data/doc/model_hooks.rdoc +80 -29
  16. data/doc/object_model.rdoc +547 -0
  17. data/doc/opening_databases.rdoc +114 -53
  18. data/doc/prepared_statements.rdoc +41 -15
  19. data/doc/querying.rdoc +137 -56
  20. data/doc/reflection.rdoc +36 -10
  21. data/doc/release_notes/3.22.0.txt +39 -0
  22. data/doc/release_notes/3.23.0.txt +172 -0
  23. data/doc/release_notes/3.24.0.txt +420 -0
  24. data/doc/release_notes/3.25.0.txt +88 -0
  25. data/doc/release_notes/3.26.0.txt +88 -0
  26. data/doc/release_notes/3.27.0.txt +82 -0
  27. data/doc/release_notes/3.28.0.txt +304 -0
  28. data/doc/release_notes/3.29.0.txt +459 -0
  29. data/doc/release_notes/3.30.0.txt +135 -0
  30. data/doc/release_notes/3.31.0.txt +146 -0
  31. data/doc/release_notes/3.32.0.txt +202 -0
  32. data/doc/release_notes/3.33.0.txt +157 -0
  33. data/doc/release_notes/3.34.0.txt +671 -0
  34. data/doc/release_notes/3.35.0.txt +144 -0
  35. data/doc/release_notes/3.36.0.txt +245 -0
  36. data/doc/release_notes/3.37.0.txt +338 -0
  37. data/doc/release_notes/3.38.0.txt +234 -0
  38. data/doc/release_notes/3.39.0.txt +237 -0
  39. data/doc/schema_modification.rdoc +585 -0
  40. data/doc/sharding.rdoc +99 -8
  41. data/doc/sql.rdoc +154 -112
  42. data/doc/testing.rdoc +169 -0
  43. data/doc/thread_safety.rdoc +17 -0
  44. data/doc/transactions.rdoc +137 -0
  45. data/doc/validations.rdoc +1 -1
  46. data/doc/virtual_rows.rdoc +78 -43
  47. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  48. data/lib/sequel/adapters/ado.rb +40 -18
  49. data/lib/sequel/adapters/amalgalite.rb +17 -9
  50. data/lib/sequel/adapters/db2.rb +175 -86
  51. data/lib/sequel/adapters/dbi.rb +15 -15
  52. data/lib/sequel/adapters/do/mysql.rb +17 -11
  53. data/lib/sequel/adapters/do/postgres.rb +2 -61
  54. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  55. data/lib/sequel/adapters/do.rb +18 -36
  56. data/lib/sequel/adapters/firebird.rb +27 -208
  57. data/lib/sequel/adapters/ibmdb.rb +453 -0
  58. data/lib/sequel/adapters/informix.rb +6 -23
  59. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  60. data/lib/sequel/adapters/jdbc/db2.rb +56 -0
  61. data/lib/sequel/adapters/jdbc/derby.rb +325 -0
  62. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  63. data/lib/sequel/adapters/jdbc/h2.rb +73 -31
  64. data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
  65. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  66. data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
  67. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  68. data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
  69. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  70. data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
  71. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  72. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  73. data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
  74. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  75. data/lib/sequel/adapters/jdbc.rb +279 -97
  76. data/lib/sequel/adapters/mock.rb +372 -0
  77. data/lib/sequel/adapters/mysql.rb +125 -222
  78. data/lib/sequel/adapters/mysql2.rb +65 -56
  79. data/lib/sequel/adapters/odbc/mssql.rb +17 -9
  80. data/lib/sequel/adapters/odbc.rb +28 -9
  81. data/lib/sequel/adapters/openbase.rb +3 -5
  82. data/lib/sequel/adapters/oracle.rb +349 -53
  83. data/lib/sequel/adapters/postgres.rb +368 -138
  84. data/lib/sequel/adapters/shared/access.rb +32 -9
  85. data/lib/sequel/adapters/shared/db2.rb +343 -0
  86. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  87. data/lib/sequel/adapters/shared/informix.rb +53 -0
  88. data/lib/sequel/adapters/shared/mssql.rb +401 -116
  89. data/lib/sequel/adapters/shared/mysql.rb +424 -89
  90. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
  91. data/lib/sequel/adapters/shared/oracle.rb +257 -45
  92. data/lib/sequel/adapters/shared/postgres.rb +675 -279
  93. data/lib/sequel/adapters/shared/progress.rb +5 -8
  94. data/lib/sequel/adapters/shared/sqlite.rb +285 -96
  95. data/lib/sequel/adapters/sqlite.rb +101 -39
  96. data/lib/sequel/adapters/swift/mysql.rb +10 -12
  97. data/lib/sequel/adapters/swift/postgres.rb +13 -79
  98. data/lib/sequel/adapters/swift/sqlite.rb +9 -6
  99. data/lib/sequel/adapters/swift.rb +28 -19
  100. data/lib/sequel/adapters/tinytds.rb +174 -22
  101. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
  102. data/lib/sequel/adapters/utils/pg_types.rb +81 -0
  103. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  104. data/lib/sequel/ast_transformer.rb +194 -0
  105. data/lib/sequel/connection_pool/sharded_single.rb +11 -1
  106. data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
  107. data/lib/sequel/connection_pool/single.rb +5 -0
  108. data/lib/sequel/connection_pool/threaded.rb +43 -14
  109. data/lib/sequel/connection_pool.rb +10 -2
  110. data/lib/sequel/core.rb +143 -11
  111. data/lib/sequel/database/connecting.rb +38 -28
  112. data/lib/sequel/database/dataset.rb +4 -4
  113. data/lib/sequel/database/dataset_defaults.rb +63 -2
  114. data/lib/sequel/database/logging.rb +7 -2
  115. data/lib/sequel/database/misc.rb +190 -46
  116. data/lib/sequel/database/query.rb +272 -110
  117. data/lib/sequel/database/schema_generator.rb +103 -36
  118. data/lib/sequel/database/schema_methods.rb +300 -67
  119. data/lib/sequel/dataset/actions.rb +344 -90
  120. data/lib/sequel/dataset/features.rb +101 -8
  121. data/lib/sequel/dataset/graph.rb +42 -15
  122. data/lib/sequel/dataset/misc.rb +52 -25
  123. data/lib/sequel/dataset/mutation.rb +12 -7
  124. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  125. data/lib/sequel/dataset/query.rb +305 -54
  126. data/lib/sequel/dataset/sql.rb +720 -292
  127. data/lib/sequel/dataset.rb +8 -0
  128. data/lib/sequel/exceptions.rb +4 -0
  129. data/lib/sequel/extensions/_pretty_table.rb +83 -0
  130. data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
  131. data/lib/sequel/extensions/blank.rb +4 -0
  132. data/lib/sequel/extensions/columns_introspection.rb +72 -0
  133. data/lib/sequel/extensions/constraint_validations.rb +451 -0
  134. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
  135. data/lib/sequel/extensions/eval_inspect.rb +173 -0
  136. data/lib/sequel/extensions/inflector.rb +4 -0
  137. data/lib/sequel/extensions/looser_typecasting.rb +5 -4
  138. data/lib/sequel/extensions/migration.rb +100 -11
  139. data/lib/sequel/extensions/named_timezones.rb +9 -0
  140. data/lib/sequel/extensions/null_dataset.rb +94 -0
  141. data/lib/sequel/extensions/pagination.rb +4 -0
  142. data/lib/sequel/extensions/pg_array.rb +537 -0
  143. data/lib/sequel/extensions/pg_array_ops.rb +263 -0
  144. data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
  145. data/lib/sequel/extensions/pg_hstore.rb +313 -0
  146. data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
  147. data/lib/sequel/extensions/pg_inet.rb +113 -0
  148. data/lib/sequel/extensions/pg_interval.rb +191 -0
  149. data/lib/sequel/extensions/pg_json.rb +208 -0
  150. data/lib/sequel/extensions/pg_range.rb +512 -0
  151. data/lib/sequel/extensions/pg_range_ops.rb +150 -0
  152. data/lib/sequel/extensions/pg_row.rb +572 -0
  153. data/lib/sequel/extensions/pg_row_ops.rb +182 -0
  154. data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
  155. data/lib/sequel/extensions/pretty_table.rb +17 -72
  156. data/lib/sequel/extensions/query.rb +8 -4
  157. data/lib/sequel/extensions/query_literals.rb +79 -0
  158. data/lib/sequel/extensions/schema_caching.rb +76 -0
  159. data/lib/sequel/extensions/schema_dumper.rb +282 -76
  160. data/lib/sequel/extensions/select_remove.rb +39 -0
  161. data/lib/sequel/extensions/server_block.rb +140 -0
  162. data/lib/sequel/extensions/split_array_nil.rb +65 -0
  163. data/lib/sequel/extensions/sql_expr.rb +8 -110
  164. data/lib/sequel/extensions/string_date_time.rb +4 -0
  165. data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
  166. data/lib/sequel/extensions/to_dot.rb +99 -83
  167. data/lib/sequel/model/associations.rb +1263 -409
  168. data/lib/sequel/model/base.rb +624 -171
  169. data/lib/sequel/model/errors.rb +1 -1
  170. data/lib/sequel/model/exceptions.rb +24 -2
  171. data/lib/sequel/model/inflections.rb +1 -1
  172. data/lib/sequel/model.rb +30 -11
  173. data/lib/sequel/no_core_ext.rb +2 -0
  174. data/lib/sequel/plugins/active_model.rb +13 -1
  175. data/lib/sequel/plugins/association_pks.rb +22 -4
  176. data/lib/sequel/plugins/caching.rb +25 -18
  177. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  178. data/lib/sequel/plugins/composition.rb +44 -12
  179. data/lib/sequel/plugins/constraint_validations.rb +198 -0
  180. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  181. data/lib/sequel/plugins/defaults_setter.rb +72 -0
  182. data/lib/sequel/plugins/dirty.rb +214 -0
  183. data/lib/sequel/plugins/eager_each.rb +59 -0
  184. data/lib/sequel/plugins/force_encoding.rb +6 -6
  185. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  186. data/lib/sequel/plugins/identity_map.rb +134 -15
  187. data/lib/sequel/plugins/instance_filters.rb +10 -0
  188. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  189. data/lib/sequel/plugins/json_serializer.rb +58 -6
  190. data/lib/sequel/plugins/list.rb +13 -2
  191. data/lib/sequel/plugins/many_through_many.rb +103 -51
  192. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  193. data/lib/sequel/plugins/nested_attributes.rb +150 -66
  194. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  195. data/lib/sequel/plugins/pg_row.rb +121 -0
  196. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  197. data/lib/sequel/plugins/prepared_statements.rb +167 -0
  198. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  199. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  200. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  201. data/lib/sequel/plugins/rcte_tree.rb +31 -17
  202. data/lib/sequel/plugins/schema.rb +8 -3
  203. data/lib/sequel/plugins/serialization.rb +98 -49
  204. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  205. data/lib/sequel/plugins/sharding.rb +21 -54
  206. data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
  207. data/lib/sequel/plugins/static_cache.rb +99 -0
  208. data/lib/sequel/plugins/subclasses.rb +29 -3
  209. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  210. data/lib/sequel/plugins/timestamps.rb +1 -1
  211. data/lib/sequel/plugins/tree.rb +3 -3
  212. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  213. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  214. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  215. data/lib/sequel/plugins/validation_helpers.rb +55 -4
  216. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  217. data/lib/sequel/sql.rb +649 -122
  218. data/lib/sequel/timezones.rb +67 -40
  219. data/lib/sequel/version.rb +1 -1
  220. data/spec/adapters/db2_spec.rb +146 -0
  221. data/spec/adapters/firebird_spec.rb +1 -1
  222. data/spec/adapters/mssql_spec.rb +194 -66
  223. data/spec/adapters/mysql_spec.rb +475 -306
  224. data/spec/adapters/oracle_spec.rb +92 -117
  225. data/spec/adapters/postgres_spec.rb +1982 -325
  226. data/spec/adapters/spec_helper.rb +9 -6
  227. data/spec/adapters/sqlite_spec.rb +203 -75
  228. data/spec/core/connection_pool_spec.rb +218 -93
  229. data/spec/core/database_spec.rb +956 -522
  230. data/spec/core/dataset_spec.rb +1631 -1242
  231. data/spec/core/expression_filters_spec.rb +690 -334
  232. data/spec/core/mock_adapter_spec.rb +453 -0
  233. data/spec/core/object_graph_spec.rb +88 -129
  234. data/spec/core/schema_generator_spec.rb +4 -4
  235. data/spec/core/schema_spec.rb +556 -53
  236. data/spec/core/spec_helper.rb +7 -48
  237. data/spec/core_extensions_spec.rb +626 -0
  238. data/spec/extensions/active_model_spec.rb +13 -0
  239. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  240. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  241. data/spec/extensions/association_dependencies_spec.rb +15 -25
  242. data/spec/extensions/association_pks_spec.rb +66 -32
  243. data/spec/extensions/association_proxies_spec.rb +4 -4
  244. data/spec/extensions/boolean_readers_spec.rb +25 -25
  245. data/spec/extensions/caching_spec.rb +47 -51
  246. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  247. data/spec/extensions/columns_introspection_spec.rb +91 -0
  248. data/spec/extensions/composition_spec.rb +18 -13
  249. data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
  250. data/spec/extensions/constraint_validations_spec.rb +316 -0
  251. data/spec/extensions/dataset_associations_spec.rb +199 -0
  252. data/spec/extensions/defaults_setter_spec.rb +88 -0
  253. data/spec/extensions/dirty_spec.rb +155 -0
  254. data/spec/extensions/eager_each_spec.rb +34 -0
  255. data/spec/extensions/eval_inspect_spec.rb +67 -0
  256. data/spec/extensions/force_encoding_spec.rb +4 -2
  257. data/spec/extensions/hook_class_methods_spec.rb +97 -128
  258. data/spec/extensions/identity_map_spec.rb +142 -24
  259. data/spec/extensions/inflector_spec.rb +0 -4
  260. data/spec/extensions/instance_filters_spec.rb +11 -21
  261. data/spec/extensions/instance_hooks_spec.rb +72 -0
  262. data/spec/extensions/json_serializer_spec.rb +49 -12
  263. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  264. data/spec/extensions/list_spec.rb +49 -40
  265. data/spec/extensions/looser_typecasting_spec.rb +7 -7
  266. data/spec/extensions/many_through_many_spec.rb +368 -254
  267. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  268. data/spec/extensions/migration_spec.rb +140 -35
  269. data/spec/extensions/named_timezones_spec.rb +29 -11
  270. data/spec/extensions/nested_attributes_spec.rb +268 -89
  271. data/spec/extensions/null_dataset_spec.rb +85 -0
  272. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  273. data/spec/extensions/pg_array_ops_spec.rb +112 -0
  274. data/spec/extensions/pg_array_spec.rb +320 -0
  275. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  276. data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
  277. data/spec/extensions/pg_hstore_spec.rb +194 -0
  278. data/spec/extensions/pg_inet_spec.rb +47 -0
  279. data/spec/extensions/pg_interval_spec.rb +72 -0
  280. data/spec/extensions/pg_json_spec.rb +99 -0
  281. data/spec/extensions/pg_range_ops_spec.rb +56 -0
  282. data/spec/extensions/pg_range_spec.rb +395 -0
  283. data/spec/extensions/pg_row_ops_spec.rb +58 -0
  284. data/spec/extensions/pg_row_plugin_spec.rb +49 -0
  285. data/spec/extensions/pg_row_spec.rb +323 -0
  286. data/spec/extensions/pg_statement_cache_spec.rb +208 -0
  287. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  288. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  289. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  290. data/spec/extensions/prepared_statements_spec.rb +87 -0
  291. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  292. data/spec/extensions/pretty_table_spec.rb +7 -6
  293. data/spec/extensions/query_literals_spec.rb +167 -0
  294. data/spec/extensions/query_spec.rb +9 -3
  295. data/spec/extensions/rcte_tree_spec.rb +50 -43
  296. data/spec/extensions/schema_caching_spec.rb +41 -0
  297. data/spec/extensions/schema_dumper_spec.rb +434 -49
  298. data/spec/extensions/schema_spec.rb +30 -49
  299. data/spec/extensions/select_remove_spec.rb +38 -0
  300. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  301. data/spec/extensions/serialization_spec.rb +86 -48
  302. data/spec/extensions/server_block_spec.rb +90 -0
  303. data/spec/extensions/sharding_spec.rb +69 -143
  304. data/spec/extensions/single_table_inheritance_spec.rb +23 -29
  305. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  306. data/spec/extensions/spec_helper.rb +34 -67
  307. data/spec/extensions/split_array_nil_spec.rb +24 -0
  308. data/spec/extensions/sql_expr_spec.rb +29 -60
  309. data/spec/extensions/static_cache_spec.rb +145 -0
  310. data/spec/extensions/subclasses_spec.rb +14 -0
  311. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  312. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  313. data/spec/extensions/timestamps_spec.rb +6 -6
  314. data/spec/extensions/to_dot_spec.rb +8 -11
  315. data/spec/extensions/touch_spec.rb +13 -14
  316. data/spec/extensions/tree_spec.rb +11 -26
  317. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  318. data/spec/extensions/update_primary_key_spec.rb +30 -24
  319. data/spec/extensions/validation_class_methods_spec.rb +58 -67
  320. data/spec/extensions/validation_helpers_spec.rb +31 -37
  321. data/spec/extensions/xml_serializer_spec.rb +29 -4
  322. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  323. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  324. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  325. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  326. data/spec/integration/associations_test.rb +659 -21
  327. data/spec/integration/database_test.rb +11 -5
  328. data/spec/integration/dataset_test.rb +717 -129
  329. data/spec/integration/eager_loader_test.rb +38 -54
  330. data/spec/integration/migrator_test.rb +2 -3
  331. data/spec/integration/model_test.rb +81 -2
  332. data/spec/integration/plugin_test.rb +604 -147
  333. data/spec/integration/prepared_statement_test.rb +272 -128
  334. data/spec/integration/schema_test.rb +367 -57
  335. data/spec/integration/spec_helper.rb +42 -32
  336. data/spec/integration/timezone_test.rb +38 -12
  337. data/spec/integration/transaction_test.rb +183 -8
  338. data/spec/integration/type_test.rb +31 -8
  339. data/spec/model/association_reflection_spec.rb +207 -8
  340. data/spec/model/associations_spec.rb +1206 -693
  341. data/spec/model/base_spec.rb +334 -100
  342. data/spec/model/dataset_methods_spec.rb +45 -27
  343. data/spec/model/eager_loading_spec.rb +828 -692
  344. data/spec/model/hooks_spec.rb +355 -67
  345. data/spec/model/model_spec.rb +251 -179
  346. data/spec/model/plugins_spec.rb +24 -13
  347. data/spec/model/record_spec.rb +506 -232
  348. data/spec/model/spec_helper.rb +16 -77
  349. data/spec/model/validations_spec.rb +38 -2
  350. data/spec/rcov.opts +2 -0
  351. metadata +209 -80
  352. data/spec/core/core_sql_spec.rb +0 -451
@@ -7,26 +7,11 @@ describe Sequel::Model, "tree plugin" do
7
7
  c.class_eval do
8
8
  def self.name; 'Node'; end
9
9
  columns :id, :name, :parent_id, :i, :pi
10
+ plugin :tree, opts
10
11
  end
11
- ds = c.dataset
12
- class << ds
13
- attr_accessor :row_sets
14
- def fetch_rows(sql)
15
- @db << sql
16
- if rs = row_sets.shift
17
- rs.each{|row| yield row}
18
- end
19
- end
20
- end
21
- c.plugin :tree, opts
22
12
  c
23
13
  end
24
14
 
25
- def y(c, *hs)
26
- ds = c.dataset
27
- ds.row_sets = hs
28
- end
29
-
30
15
  before do
31
16
  @c = klass
32
17
  @ds = @c.dataset
@@ -71,7 +56,7 @@ describe Sequel::Model, "tree plugin" do
71
56
  end
72
57
 
73
58
  it "should have roots return an array of the tree's roots" do
74
- y(@c, [{:id=>1, :parent_id=>nil, :name=>'r'}])
59
+ @ds._fetch = [{:id=>1, :parent_id=>nil, :name=>'r'}]
75
60
  @c.roots.should == [@c.load(:id=>1, :parent_id=>nil, :name=>'r')]
76
61
  @db.sqls.should == ["SELECT * FROM nodes WHERE (parent_id IS NULL)"]
77
62
  end
@@ -81,14 +66,14 @@ describe Sequel::Model, "tree plugin" do
81
66
  end
82
67
 
83
68
  it "should have ancestors return the ancestors of the current node" do
84
- y(@c, [{:id=>1, :parent_id=>5, :name=>'r'}], [{:id=>5, :parent_id=>nil, :name=>'r2'}])
69
+ @ds._fetch = [[{:id=>1, :parent_id=>5, :name=>'r'}], [{:id=>5, :parent_id=>nil, :name=>'r2'}]]
85
70
  @o.ancestors.should == [@c.load(:id=>1, :parent_id=>5, :name=>'r'), @c.load(:id=>5, :parent_id=>nil, :name=>'r2')]
86
71
  @db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 1) LIMIT 1",
87
72
  "SELECT * FROM nodes WHERE (nodes.id = 5) LIMIT 1"]
88
73
  end
89
74
 
90
75
  it "should have descendants return the descendants of the current node" do
91
- y(@c, [{:id=>3, :parent_id=>2, :name=>'r'}, {:id=>4, :parent_id=>2, :name=>'r2'}], [{:id=>5, :parent_id=>4, :name=>'r3'}], [])
76
+ @ds._fetch = [[{:id=>3, :parent_id=>2, :name=>'r'}, {:id=>4, :parent_id=>2, :name=>'r2'}], [{:id=>5, :parent_id=>4, :name=>'r3'}], []]
92
77
  @o.descendants.should == [@c.load(:id=>3, :parent_id=>2, :name=>'r'), @c.load(:id=>4, :parent_id=>2, :name=>'r2'), @c.load(:id=>5, :parent_id=>4, :name=>'r3')]
93
78
  @db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.parent_id = 2)",
94
79
  "SELECT * FROM nodes WHERE (nodes.parent_id = 3)",
@@ -97,7 +82,7 @@ describe Sequel::Model, "tree plugin" do
97
82
  end
98
83
 
99
84
  it "should have root return the root of the current node" do
100
- y(@c, [{:id=>1, :parent_id=>5, :name=>'r'}], [{:id=>5, :parent_id=>nil, :name=>'r2'}])
85
+ @ds._fetch = [[{:id=>1, :parent_id=>5, :name=>'r'}], [{:id=>5, :parent_id=>nil, :name=>'r2'}]]
101
86
  @o.root.should == @c.load(:id=>5, :parent_id=>nil, :name=>'r2')
102
87
  @db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 1) LIMIT 1",
103
88
  "SELECT * FROM nodes WHERE (nodes.id = 5) LIMIT 1"]
@@ -113,14 +98,14 @@ describe Sequel::Model, "tree plugin" do
113
98
  end
114
99
 
115
100
  it "should have self_and_siblings return the children of the current node's parent" do
116
- y(@c, [{:id=>1, :parent_id=>3, :name=>'r'}], [{:id=>7, :parent_id=>1, :name=>'r2'}, @o.values.dup])
101
+ @ds._fetch = [[{:id=>1, :parent_id=>3, :name=>'r'}], [{:id=>7, :parent_id=>1, :name=>'r2'}, @o.values.dup]]
117
102
  @o.self_and_siblings.should == [@c.load(:id=>7, :parent_id=>1, :name=>'r2'), @o]
118
103
  @db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 1) LIMIT 1",
119
104
  "SELECT * FROM nodes WHERE (nodes.parent_id = 1)"]
120
105
  end
121
106
 
122
107
  it "should have siblings return the children of the current node's parent, except for the current node" do
123
- y(@c, [{:id=>1, :parent_id=>3, :name=>'r'}], [{:id=>7, :parent_id=>1, :name=>'r2'}, @o.values.dup])
108
+ @ds._fetch = [[{:id=>1, :parent_id=>3, :name=>'r'}], [{:id=>7, :parent_id=>1, :name=>'r2'}, @o.values.dup]]
124
109
  @o.siblings.should == [@c.load(:id=>7, :parent_id=>1, :name=>'r2')]
125
110
  @db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 1) LIMIT 1",
126
111
  "SELECT * FROM nodes WHERE (nodes.parent_id = 1)"]
@@ -132,23 +117,23 @@ describe Sequel::Model, "tree plugin" do
132
117
  end
133
118
 
134
119
  it "should have root class method return the root" do
135
- y(@c, [{:id=>1, :parent_id=>nil, :name=>'r'}])
120
+ @c.dataset._fetch = [{:id=>1, :parent_id=>nil, :name=>'r'}]
136
121
  @c.root.should == @c.load(:id=>1, :parent_id=>nil, :name=>'r')
137
122
  end
138
123
 
139
124
  it "prevents creating a second root" do
140
- y(@c, [{:id=>1, :parent_id=>nil, :name=>'r'}])
125
+ @c.dataset._fetch = [{:id=>1, :parent_id=>nil, :name=>'r'}]
141
126
  lambda { @c.create }.should raise_error(Sequel::Plugins::Tree::TreeMultipleRootError)
142
127
  end
143
128
 
144
129
  it "errors when promoting an existing record to a second root" do
145
- y(@c, [{:id=>1, :parent_id=>nil, :name=>'r'}])
130
+ @c.dataset._fetch = [{:id=>1, :parent_id=>nil, :name=>'r'}]
146
131
  n = @c.load(:id => 2, :parent_id => 1)
147
132
  lambda { n.update(:parent_id => nil) }.should raise_error(Sequel::Plugins::Tree::TreeMultipleRootError)
148
133
  end
149
134
 
150
135
  it "allows updating existing root" do
151
- y(@c, [{:id=>1, :parent_id=>nil, :name=>'r'}])
136
+ @c.dataset._fetch = [{:id=>1, :parent_id=>nil, :name=>'r'}]
152
137
  lambda { @c.root.update(:name => 'fdsa') }.should_not raise_error
153
138
  end
154
139
  end
@@ -2,22 +2,17 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe Sequel::Model, "TypecastOnLoad plugin" do
4
4
  before do
5
- @db = Sequel::Database.new({})
5
+ @db = Sequel.mock(:fetch=>{:id=>1, :b=>"1", :y=>"0"}, :columns=>[:id, :b, :y], :numrows=>1)
6
6
  def @db.schema(*args)
7
7
  [[:id, {}], [:y, {:type=>:boolean, :db_type=>'tinyint(1)'}], [:b, {:type=>:integer, :db_type=>'integer'}]]
8
8
  end
9
9
  @c = Class.new(Sequel::Model(@db[:items])) do
10
- include(Module.new{def _refresh(ds); values[:b] = b.to_s; self; end})
11
10
  attr_accessor :bset
12
11
  def b=(x)
13
12
  self.bset = true
14
13
  super
15
14
  end
16
15
  end
17
- @c.instance_eval do
18
- @columns = [:id, :b, :y]
19
- def columns; @columns; end
20
- end
21
16
  end
22
17
 
23
18
  specify "should call setter method with value when loading the object, for all given columns" do
@@ -35,6 +30,14 @@ describe Sequel::Model, "TypecastOnLoad plugin" do
35
30
  o.bset.should == true
36
31
  end
37
32
 
33
+ specify "should call setter method with value when automatically reloading the object on creation via insert_select" do
34
+ @c.plugin :typecast_on_load, :b
35
+ @c.dataset.meta_def(:insert_select){|h| insert(h); first}
36
+ o = @c.new({:id=>1, :b=>"1", :y=>"0"}, true)
37
+ o.save.values.should == {:id=>1, :b=>1, :y=>"0"}
38
+ o.bset.should == true
39
+ end
40
+
38
41
  specify "should allowing setting columns separately via add_typecast_on_load_columns" do
39
42
  @c.plugin :typecast_on_load
40
43
  @c.load(:id=>1, :b=>"1", :y=>"0").values.should == {:id=>1, :b=>"1", :y=>"0"}
@@ -9,57 +9,63 @@ describe "Sequel::Plugins::UpdatePrimaryKey" do
9
9
  @c.unrestrict_primary_key
10
10
  @o = @c.new
11
11
  @ds = @c.dataset
12
- @ds.extend(Module.new do
13
- attr_accessor :a
14
- def fetch_rows(sql)
15
- yield(a.dup)
16
- end
17
-
18
- def update(h)
19
- if literal(opts[:where]) =~ /a = (\d)/ and $1.to_i == a[:a]
20
- a.update(h)
21
- end
22
- super
23
- end
24
- end)
25
- @ds.a = {:a=>1, :b=>3}
26
- @ds2 = @ds.naked
27
12
  MODEL_DB.reset
28
13
  end
29
14
 
30
15
  specify "should handle regular updates" do
16
+ @ds._fetch = [[{:a=>1, :b=>3}], [{:a=>1, :b=>4}], [{:a=>1, :b=>4}], [{:a=>1, :b=>5}], [{:a=>1, :b=>5}], [{:a=>1, :b=>6}], [{:a=>1, :b=>6}]]
31
17
  @c.first.update(:b=>4)
32
- @ds2.all.should == [{:a=>1, :b=>4}]
18
+ @c.all.should == [@c.load(:a=>1, :b=>4)]
19
+ MODEL_DB.sqls.should == ["SELECT * FROM a LIMIT 1", "UPDATE a SET b = 4 WHERE (a = 1)", "SELECT * FROM a"]
33
20
  @c.first.set(:b=>5).save
34
- @ds2.all.should == [{:a=>1, :b=>5}]
21
+ @c.all.should == [@c.load(:a=>1, :b=>5)]
22
+ MODEL_DB.sqls.should == ["SELECT * FROM a LIMIT 1", "UPDATE a SET b = 5 WHERE (a = 1)", "SELECT * FROM a"]
35
23
  @c.first.set(:b=>6).save(:b)
36
- @ds2.all.should == [{:a=>1, :b=>6}]
24
+ @c.all.should == [@c.load(:a=>1, :b=>6)]
25
+ MODEL_DB.sqls.should == ["SELECT * FROM a LIMIT 1", "UPDATE a SET b = 6 WHERE (a = 1)", "SELECT * FROM a"]
37
26
  end
38
27
 
39
28
  specify "should handle updating the primary key field with another field" do
29
+ @ds._fetch = [[{:a=>1, :b=>3}], [{:a=>2, :b=>4}]]
40
30
  @c.first.update(:a=>2, :b=>4)
41
- @ds2.all.should == [{:a=>2, :b=>4}]
31
+ @c.all.should == [@c.load(:a=>2, :b=>4)]
32
+ sqls = MODEL_DB.sqls
33
+ ["UPDATE a SET a = 2, b = 4 WHERE (a = 1)", "UPDATE a SET b = 4, a = 2 WHERE (a = 1)"].should include(sqls.slice!(1))
34
+ sqls.should == ["SELECT * FROM a LIMIT 1", "SELECT * FROM a"]
42
35
  end
43
36
 
44
37
  specify "should handle updating just the primary key field when saving changes" do
38
+ @ds._fetch = [[{:a=>1, :b=>3}], [{:a=>2, :b=>3}], [{:a=>2, :b=>3}], [{:a=>3, :b=>3}]]
45
39
  @c.first.update(:a=>2)
46
- @ds2.all.should == [{:a=>2, :b=>3}]
40
+ @c.all.should == [@c.load(:a=>2, :b=>3)]
41
+ MODEL_DB.sqls.should == ["SELECT * FROM a LIMIT 1", "UPDATE a SET a = 2 WHERE (a = 1)", "SELECT * FROM a"]
47
42
  @c.first.set(:a=>3).save(:a)
48
- @ds2.all.should == [{:a=>3, :b=>3}]
43
+ @c.all.should == [@c.load(:a=>3, :b=>3)]
44
+ MODEL_DB.sqls.should == ["SELECT * FROM a LIMIT 1", "UPDATE a SET a = 3 WHERE (a = 2)", "SELECT * FROM a"]
49
45
  end
50
46
 
51
47
  specify "should handle saving after modifying the primary key field with another field" do
48
+ @ds._fetch = [[{:a=>1, :b=>3}], [{:a=>2, :b=>4}]]
52
49
  @c.first.set(:a=>2, :b=>4).save
53
- @ds2.all.should == [{:a=>2, :b=>4}]
50
+ @c.all.should == [@c.load(:a=>2, :b=>4)]
51
+ sqls = MODEL_DB.sqls
52
+ ["UPDATE a SET a = 2, b = 4 WHERE (a = 1)", "UPDATE a SET b = 4, a = 2 WHERE (a = 1)"].should include(sqls.slice!(1))
53
+ sqls.should == ["SELECT * FROM a LIMIT 1", "SELECT * FROM a"]
54
54
  end
55
55
 
56
56
  specify "should handle saving after modifying just the primary key field" do
57
+ @ds._fetch = [[{:a=>1, :b=>3}], [{:a=>2, :b=>3}]]
57
58
  @c.first.set(:a=>2).save
58
- @ds2.all.should == [{:a=>2, :b=>3}]
59
+ @c.all.should == [@c.load(:a=>2, :b=>3)]
60
+ sqls = MODEL_DB.sqls
61
+ ["UPDATE a SET a = 2, b = 3 WHERE (a = 1)", "UPDATE a SET b = 3, a = 2 WHERE (a = 1)"].should include(sqls.slice!(1))
62
+ sqls.should == ["SELECT * FROM a LIMIT 1", "SELECT * FROM a"]
59
63
  end
60
64
 
61
65
  specify "should handle saving after updating the primary key" do
66
+ @ds._fetch = [[{:a=>1, :b=>3}], [{:a=>2, :b=>5}]]
62
67
  @c.first.update(:a=>2).update(:b=>4).set(:b=>5).save
63
- @ds2.all.should == [{:a=>2, :b=>5}]
68
+ @c.all.should == [@c.load(:a=>2, :b=>5)]
69
+ MODEL_DB.sqls.should == ["SELECT * FROM a LIMIT 1", "UPDATE a SET a = 2 WHERE (a = 1)", "UPDATE a SET b = 4 WHERE (a = 2)", "UPDATE a SET b = 5 WHERE (a = 2)", "SELECT * FROM a"]
64
70
  end
65
71
  end
@@ -1,8 +1,15 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
+ model_class = proc do |klass, &block|
4
+ c = Class.new(klass)
5
+ c.plugin :validation_class_methods
6
+ c.class_eval(&block) if block
7
+ c
8
+ end
9
+
3
10
  describe Sequel::Model do
4
11
  before do
5
- @c = Class.new(Sequel::Model) do
12
+ @c = model_class.call Sequel::Model do
6
13
  def self.validates_coolness_of(attr)
7
14
  validates_each(attr) {|o, a, v| o.errors[a] << 'is not cool' if v != :cool}
8
15
  end
@@ -135,8 +142,7 @@ end
135
142
 
136
143
  describe Sequel::Model do
137
144
  before do
138
- @c = Class.new(Sequel::Model)
139
- @c.class_eval do
145
+ @c = model_class.call Sequel::Model do
140
146
  columns :score
141
147
  validates_each :score do |o, a, v|
142
148
  o.errors[a] << 'too low' if v < 87
@@ -165,11 +171,11 @@ describe Sequel::Model do
165
171
  end
166
172
  end
167
173
 
168
- describe Sequel::Plugins::ValidationClassMethods::ClassMethods::Generator do
174
+ describe "Sequel::Plugins::ValidationClassMethods::ClassMethods::Generator" do
169
175
  before do
170
176
  $testit = nil
171
177
 
172
- @c = Class.new(Sequel::Model) do
178
+ @c = model_class.call Sequel::Model do
173
179
  def self.validates_blah
174
180
  $testit = 1324
175
181
  end
@@ -186,7 +192,7 @@ end
186
192
 
187
193
  describe Sequel::Model do
188
194
  before do
189
- @c = Class.new(Sequel::Model) do
195
+ @c = model_class.call Sequel::Model do
190
196
  columns :value
191
197
 
192
198
  def self.filter(*args)
@@ -527,13 +533,8 @@ describe Sequel::Model do
527
533
  end
528
534
 
529
535
  specify "should raise an error if inclusion_of doesn't receive a valid :in option" do
530
- lambda {
531
- @c.validates_inclusion_of :value
532
- }.should raise_error(ArgumentError)
533
-
534
- lambda {
535
- @c.validates_inclusion_of :value, :in => 1
536
- }.should raise_error(ArgumentError)
536
+ lambda{@c.validates_inclusion_of :value}.should raise_error(ArgumentError)
537
+ lambda{@c.validates_inclusion_of :value, :in => 1}.should raise_error(ArgumentError)
537
538
  end
538
539
 
539
540
  specify "should raise an error if inclusion_of handles :allow_nil too" do
@@ -570,7 +571,6 @@ describe Sequel::Model do
570
571
 
571
572
  specify "should validate uniqueness_of with if => false" do
572
573
  @c.validates_uniqueness_of :value, :if => :skip
573
-
574
574
  @m.value = 'a'
575
575
  @m.should be_valid
576
576
  end
@@ -585,8 +585,7 @@ end
585
585
 
586
586
  describe "Superclass validations" do
587
587
  before do
588
- @c1 = Class.new(Sequel::Model)
589
- @c1.class_eval do
588
+ @c1 = model_class.call Sequel::Model do
590
589
  columns :value
591
590
  validates_length_of :value, :minimum => 5
592
591
  end
@@ -602,16 +601,11 @@ describe "Superclass validations" do
602
601
  o = @c2.new
603
602
  o.value = 'ab'
604
603
  o.valid?.should == false
605
- o.errors.full_messages.should == [
606
- 'value is too short'
607
- ]
604
+ o.errors.full_messages.should == ['value is too short']
608
605
 
609
606
  o.value = '12'
610
607
  o.valid?.should == false
611
- o.errors.full_messages.should == [
612
- 'value is too short',
613
- 'value is invalid'
614
- ]
608
+ o.errors.full_messages.should == ['value is too short', 'value is invalid']
615
609
 
616
610
  o.value = 'abcde'
617
611
  o.valid?.should be_true
@@ -626,9 +620,7 @@ describe "Superclass validations" do
626
620
 
627
621
  o.value = '12'
628
622
  o.valid?.should == false
629
- o.errors.full_messages.should == [
630
- 'value is invalid'
631
- ]
623
+ o.errors.full_messages.should == ['value is invalid']
632
624
 
633
625
  o.value = 'abcde'
634
626
  o.valid?.should be_true
@@ -637,8 +629,7 @@ end
637
629
 
638
630
  describe ".validates with block" do
639
631
  specify "should support calling .each" do
640
- @c = Class.new(Sequel::Model)
641
- @c.class_eval do
632
+ @c = model_class.call Sequel::Model do
642
633
  columns :vvv
643
634
  validates do
644
635
  each :vvv do |o, a, v|
@@ -659,24 +650,36 @@ describe Sequel::Model, "Validations" do
659
650
 
660
651
  before(:all) do
661
652
  class ::Person < Sequel::Model
653
+ plugin :validation_class_methods
662
654
  columns :id,:name,:first_name,:last_name,:middle_name,:initials,:age, :terms
663
655
  end
664
656
 
665
657
  class ::Smurf < Person
666
658
  end
659
+
660
+ class ::Can < Sequel::Model
661
+ plugin :validation_class_methods
662
+ columns :id, :name
663
+ end
667
664
 
668
665
  class ::Cow < Sequel::Model
666
+ plugin :validation_class_methods
669
667
  columns :id, :name, :got_milk
670
668
  end
671
669
 
672
670
  class ::User < Sequel::Model
671
+ plugin :validation_class_methods
673
672
  columns :id, :username, :password
674
673
  end
675
674
 
676
675
  class ::Address < Sequel::Model
676
+ plugin :validation_class_methods
677
677
  columns :id, :zip_code
678
678
  end
679
679
  end
680
+ after(:all) do
681
+ [:Person, :Smurf, :Cow, :User, :Address].each{|c| Object.send(:remove_const, c)}
682
+ end
680
683
 
681
684
  it "should validate the acceptance of a column" do
682
685
  class ::Cow < Sequel::Model
@@ -754,8 +757,7 @@ describe Sequel::Model, "Validations" do
754
757
  end
755
758
 
756
759
  it "should validate that a column doesn't have a string value" do
757
- p = Class.new(Sequel::Model)
758
- p.class_eval do
760
+ p = model_class.call Sequel::Model do
759
761
  columns :age, :price, :confirmed
760
762
  self.raise_on_typecast_failure = false
761
763
  validates_not_string :age
@@ -824,22 +826,18 @@ describe Sequel::Model, "Validations" do
824
826
  uniqueness_of :username
825
827
  end
826
828
  end
827
- User.dataset.extend(Module.new {
828
- def fetch_rows(sql)
829
- @db << sql
830
-
831
- case sql
832
- when /COUNT.*username = '0records'/
833
- yield({:v => 0})
834
- when /COUNT.*username = '2records'/
835
- yield({:v => 2})
836
- when /COUNT.*username = '1record'/
837
- yield({:v => 1})
838
- when /username = '1record'/
839
- yield({:id => 3, :username => "1record", :password => "test"})
840
- end
829
+ User.dataset._fetch = proc do |sql|
830
+ case sql
831
+ when /COUNT.*username = '0records'/
832
+ {:v => 0}
833
+ when /COUNT.*username = '2records'/
834
+ {:v => 2}
835
+ when /COUNT.*username = '1record'/
836
+ {:v => 1}
837
+ when /username = '1record'/
838
+ {:id => 3, :username => "1record", :password => "test"}
841
839
  end
842
- })
840
+ end
843
841
 
844
842
  @user = User.new(:username => "2records", :password => "anothertest")
845
843
  @user.should_not be_valid
@@ -869,26 +867,22 @@ describe Sequel::Model, "Validations" do
869
867
  uniqueness_of [:username, :password]
870
868
  end
871
869
  end
872
- User.dataset.extend(Module.new {
873
- def fetch_rows(sql)
874
- @db << sql
875
-
876
- case sql
877
- when /COUNT.*username = '0records'/
878
- yield({:v => 0})
879
- when /COUNT.*username = '2records'/
880
- yield({:v => 2})
881
- when /COUNT.*username = '1record'/
882
- yield({:v => 1})
883
- when /username = '1record'/
884
- if sql =~ /password = 'anothertest'/
885
- yield({:id => 3, :username => "1record", :password => "anothertest"})
886
- else
887
- yield({:id => 4, :username => "1record", :password => "test"})
888
- end
870
+ User.dataset._fetch = proc do |sql|
871
+ case sql
872
+ when /COUNT.*username = '0records'/
873
+ {:v => 0}
874
+ when /COUNT.*username = '2records'/
875
+ {:v => 2}
876
+ when /COUNT.*username = '1record'/
877
+ {:v => 1}
878
+ when /username = '1record'/
879
+ if sql =~ /password = 'anothertest'/
880
+ {:id => 3, :username => "1record", :password => "anothertest"}
881
+ else
882
+ {:id => 4, :username => "1record", :password => "test"}
889
883
  end
890
884
  end
891
- })
885
+ end
892
886
 
893
887
  @user = User.new(:username => "2records", :password => "anothertest")
894
888
  @user.should_not be_valid
@@ -962,8 +956,6 @@ describe Sequel::Model, "Validations" do
962
956
 
963
957
  it "should validate correctly instances initialized with string keys" do
964
958
  class ::Can < Sequel::Model
965
- columns :id, :name
966
-
967
959
  validates_length_of :name, :minimum => 4
968
960
  end
969
961
 
@@ -975,8 +967,7 @@ end
975
967
 
976
968
  describe "Model#save" do
977
969
  before do
978
- @c = Class.new(Sequel::Model(:people))
979
- @c.class_eval do
970
+ @c = model_class.call Sequel::Model(:people) do
980
971
  columns :id, :x
981
972
 
982
973
  validates_each :x do |o, a, v|
@@ -317,18 +317,14 @@ describe "Sequel::Plugins::ValidationHelpers" do
317
317
  @c.columns(:id, :username, :password)
318
318
  @c.set_dataset MODEL_DB[:items]
319
319
  @c.set_validations{validates_unique(:username)}
320
- @c.dataset.extend(Module.new {
321
- def fetch_rows(sql)
322
- @db << sql
323
-
324
- case sql
325
- when /COUNT.*username = '0records'/
326
- yield({:v => 0})
327
- when /COUNT.*username = '1record'/
328
- yield({:v => 1})
329
- end
320
+ @c.dataset._fetch = proc do |sql|
321
+ case sql
322
+ when /COUNT.*username = '0records'/
323
+ {:v => 0}
324
+ when /COUNT.*username = '1record'/
325
+ {:v => 1}
330
326
  end
331
- })
327
+ end
332
328
 
333
329
  @user = @c.new(:username => "0records", :password => "anothertest")
334
330
  @user.should be_valid
@@ -344,7 +340,7 @@ describe "Sequel::Plugins::ValidationHelpers" do
344
340
 
345
341
  ds1 = @c.dataset.filter([[:username, '0records']])
346
342
  ds2 = ds1.exclude(:id=>1)
347
- @c.dataset.should_receive(:filter).with([[:username, '0records']]).twice.and_return(ds1)
343
+ @c.dataset.should_receive(:where).with([[:username, '0records']]).twice.and_return(ds1)
348
344
  ds1.should_receive(:exclude).with(:id=>1).once.and_return(ds2)
349
345
 
350
346
  @user = @c.load(:id=>1, :username => "0records", :password => "anothertest")
@@ -359,18 +355,14 @@ describe "Sequel::Plugins::ValidationHelpers" do
359
355
  @c.columns(:id, :username, :password)
360
356
  @c.set_dataset MODEL_DB[:items]
361
357
  @c.set_validations{validates_unique([:username, :password])}
362
- @c.dataset.extend(Module.new {
363
- def fetch_rows(sql)
364
- @db << sql
365
-
366
- case sql
367
- when /COUNT.*username = '0records'/
368
- yield({:v => 0})
369
- when /COUNT.*username = '1record'/
370
- yield({:v => 1})
371
- end
358
+ @c.dataset._fetch = proc do |sql|
359
+ case sql
360
+ when /COUNT.*username = '0records'/
361
+ {:v => 0}
362
+ when /COUNT.*username = '1record'/
363
+ {:v => 1}
372
364
  end
373
- })
365
+ end
374
366
 
375
367
  @user = @c.new(:username => "0records", :password => "anothertest")
376
368
  @user.should be_valid
@@ -386,7 +378,7 @@ describe "Sequel::Plugins::ValidationHelpers" do
386
378
 
387
379
  ds1 = @c.dataset.filter([[:username, '0records'], [:password, 'anothertest']])
388
380
  ds2 = ds1.exclude(:id=>1)
389
- @c.dataset.should_receive(:filter).with([[:username, '0records'], [:password, 'anothertest']]).twice.and_return(ds1)
381
+ @c.dataset.should_receive(:where).with([[:username, '0records'], [:password, 'anothertest']]).twice.and_return(ds1)
390
382
  ds1.should_receive(:exclude).with(:id=>1).once.and_return(ds2)
391
383
 
392
384
  @user = @c.load(:id=>1, :username => "0records", :password => "anothertest")
@@ -401,12 +393,7 @@ describe "Sequel::Plugins::ValidationHelpers" do
401
393
  @c.columns(:id, :username, :password)
402
394
  @c.set_dataset MODEL_DB[:items]
403
395
  @c.set_validations{validates_unique(:username){|ds| ds.filter(:active)}}
404
- @c.dataset.extend(Module.new {
405
- def fetch_rows (sql)
406
- @db << sql
407
- yield({:v => 0})
408
- end
409
- })
396
+ @c.dataset._fetch = {:v=>0}
410
397
 
411
398
  MODEL_DB.reset
412
399
  @c.new(:username => "0records", :password => "anothertest").should be_valid
@@ -415,17 +402,24 @@ describe "Sequel::Plugins::ValidationHelpers" do
415
402
  "SELECT COUNT(*) AS count FROM items WHERE ((username = '0records') AND active AND (id != 3)) LIMIT 1"]
416
403
  end
417
404
 
405
+ it "should support validates_unique with a custom filter" do
406
+ @c.columns(:id, :username, :password)
407
+ @c.set_dataset MODEL_DB[:items]
408
+ @c.set_validations{validates_unique(:username, :where=>proc{|ds, obj, cols| ds.where(cols.map{|c| [Sequel.function(:lower, c), obj.send(c).downcase]})})}
409
+ @c.dataset._fetch = {:v=>0}
410
+
411
+ MODEL_DB.reset
412
+ @c.new(:username => "0RECORDS", :password => "anothertest").should be_valid
413
+ @c.load(:id=>3, :username => "0RECORDS", :password => "anothertest").should be_valid
414
+ MODEL_DB.sqls.should == ["SELECT COUNT(*) AS count FROM items WHERE (lower(username) = '0records') LIMIT 1",
415
+ "SELECT COUNT(*) AS count FROM items WHERE ((lower(username) = '0records') AND (id != 3)) LIMIT 1"]
416
+ end
417
+
418
418
  it "should support :only_if_modified option for validates_unique, and not check uniqueness for existing records if values haven't changed" do
419
419
  @c.columns(:id, :username, :password)
420
420
  @c.set_dataset MODEL_DB[:items]
421
421
  @c.set_validations{validates_unique([:username, :password], :only_if_modified=>true)}
422
-
423
- @c.dataset.extend(Module.new {
424
- def fetch_rows (sql)
425
- @db << sql
426
- yield({:v => 0})
427
- end
428
- })
422
+ @c.dataset._fetch = {:v=>0}
429
423
 
430
424
  MODEL_DB.reset
431
425
  @c.new(:username => "0records", :password => "anothertest").should be_valid
@@ -36,6 +36,18 @@ describe "Sequel::Plugins::XmlSerializer" do
36
36
  Album.from_xml(@album.to_xml).should == @album
37
37
  end
38
38
 
39
+ it "should round trip successfully for namespaced models" do
40
+ module XmlSerializerTest
41
+ class Artist < Sequel::Model
42
+ plugin :xml_serializer
43
+ columns :id, :name
44
+ @db_schema = {:id=>{:type=>:integer}, :name=>{:type=>:string}}
45
+ end
46
+ end
47
+ artist = XmlSerializerTest::Artist.load(:id=>2, :name=>'YJM')
48
+ XmlSerializerTest::Artist.from_xml(artist.to_xml).should == artist
49
+ end
50
+
39
51
  it "should round trip successfully with empty strings" do
40
52
  artist = Artist.load(:id=>2, :name=>'')
41
53
  Artist.from_xml(artist.to_xml).should == artist
@@ -106,13 +118,13 @@ describe "Sequel::Plugins::XmlSerializer" do
106
118
  end
107
119
 
108
120
  it "should support an :encoding option when serializing" do
109
- ["<?xml version=\"1.0\" encoding=\"utf-8\"?><artist><id>2</id><name>YJM</name></artist>",
110
- "<?xml version=\"1.0\" encoding=\"utf-8\"?><artist><name>YJM</name><id>2</id></artist>"].should include(@artist.to_xml(:encoding=>'utf-8').gsub(/\n */m, ''))
121
+ ["<?xml version=\"1.0\" encoding=\"UTF-8\"?><artist><id>2</id><name>YJM</name></artist>",
122
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><artist><name>YJM</name><id>2</id></artist>"].should include(@artist.to_xml(:encoding=>'UTF-8').gsub(/\n */m, ''))
111
123
  end
112
124
 
113
125
  it "should support a :builder_opts option when serializing" do
114
- ["<?xml version=\"1.0\" encoding=\"utf-8\"?><artist><id>2</id><name>YJM</name></artist>",
115
- "<?xml version=\"1.0\" encoding=\"utf-8\"?><artist><name>YJM</name><id>2</id></artist>"].should include(@artist.to_xml(:builder_opts=>{:encoding=>'utf-8'}).gsub(/\n */m, ''))
126
+ ["<?xml version=\"1.0\" encoding=\"UTF-8\"?><artist><id>2</id><name>YJM</name></artist>",
127
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><artist><name>YJM</name><id>2</id></artist>"].should include(@artist.to_xml(:builder_opts=>{:encoding=>'UTF-8'}).gsub(/\n */m, ''))
116
128
  end
117
129
 
118
130
  it "should support an :types option when serializing" do
@@ -145,6 +157,19 @@ describe "Sequel::Plugins::XmlSerializer" do
145
157
  Album.array_from_xml(Album.dataset.to_xml(:only=>:name)).should == [Album.load(:name=>@album.name)]
146
158
  end
147
159
 
160
+ it "should have to_xml dataset method respect an :array option" do
161
+ a = Album.load(:id=>1, :name=>'RF', :artist_id=>3)
162
+ Album.array_from_xml(Album.to_xml(:array=>[a])).should == [a]
163
+
164
+ a.associations[:artist] = artist = Artist.load(:id=>3, :name=>'YJM')
165
+ Album.array_from_xml(Album.to_xml(:array=>[a], :include=>:artist)).first.artist.should == artist
166
+
167
+ artist.associations[:albums] = [a]
168
+ x = Artist.array_from_xml(Artist.to_xml(:array=>[artist], :include=>:albums))
169
+ x.should == [artist]
170
+ x.first.albums.should == [a]
171
+ end
172
+
148
173
  it "should raise an error if the dataset does not have a row_proc" do
149
174
  proc{Album.dataset.naked.to_xml}.should raise_error(Sequel::Error)
150
175
  end