sequel 5.20.0 → 5.49.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 (511) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +398 -1922
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +7 -7
  5. data/doc/advanced_associations.rdoc +4 -4
  6. data/doc/association_basics.rdoc +80 -16
  7. data/doc/cheat_sheet.rdoc +6 -5
  8. data/doc/code_order.rdoc +10 -12
  9. data/doc/dataset_filtering.rdoc +17 -2
  10. data/doc/fork_safety.rdoc +84 -0
  11. data/doc/migration.rdoc +11 -5
  12. data/doc/model_dataset_method_design.rdoc +1 -1
  13. data/doc/model_plugins.rdoc +1 -1
  14. data/doc/opening_databases.rdoc +10 -2
  15. data/doc/postgresql.rdoc +82 -3
  16. data/doc/querying.rdoc +4 -4
  17. data/doc/release_notes/5.21.0.txt +87 -0
  18. data/doc/release_notes/5.22.0.txt +48 -0
  19. data/doc/release_notes/5.23.0.txt +56 -0
  20. data/doc/release_notes/5.24.0.txt +56 -0
  21. data/doc/release_notes/5.25.0.txt +32 -0
  22. data/doc/release_notes/5.26.0.txt +35 -0
  23. data/doc/release_notes/5.27.0.txt +21 -0
  24. data/doc/release_notes/5.28.0.txt +16 -0
  25. data/doc/release_notes/5.29.0.txt +22 -0
  26. data/doc/release_notes/5.30.0.txt +20 -0
  27. data/doc/release_notes/5.31.0.txt +148 -0
  28. data/doc/release_notes/5.32.0.txt +46 -0
  29. data/doc/release_notes/5.33.0.txt +24 -0
  30. data/doc/release_notes/5.34.0.txt +40 -0
  31. data/doc/release_notes/5.35.0.txt +56 -0
  32. data/doc/release_notes/5.36.0.txt +60 -0
  33. data/doc/release_notes/5.37.0.txt +30 -0
  34. data/doc/release_notes/5.38.0.txt +28 -0
  35. data/doc/release_notes/5.39.0.txt +19 -0
  36. data/doc/release_notes/5.40.0.txt +40 -0
  37. data/doc/release_notes/5.41.0.txt +25 -0
  38. data/doc/release_notes/5.42.0.txt +136 -0
  39. data/doc/release_notes/5.43.0.txt +98 -0
  40. data/doc/release_notes/5.44.0.txt +32 -0
  41. data/doc/release_notes/5.45.0.txt +34 -0
  42. data/doc/release_notes/5.46.0.txt +87 -0
  43. data/doc/release_notes/5.47.0.txt +59 -0
  44. data/doc/release_notes/5.48.0.txt +14 -0
  45. data/doc/release_notes/5.49.0.txt +59 -0
  46. data/doc/sharding.rdoc +2 -0
  47. data/doc/sql.rdoc +13 -1
  48. data/doc/testing.rdoc +20 -7
  49. data/doc/transactions.rdoc +0 -8
  50. data/doc/validations.rdoc +1 -1
  51. data/doc/virtual_rows.rdoc +1 -1
  52. data/lib/sequel/adapters/ado/access.rb +1 -1
  53. data/lib/sequel/adapters/ado.rb +43 -35
  54. data/lib/sequel/adapters/ibmdb.rb +2 -2
  55. data/lib/sequel/adapters/jdbc/mysql.rb +6 -6
  56. data/lib/sequel/adapters/jdbc/postgresql.rb +11 -17
  57. data/lib/sequel/adapters/jdbc/sqlite.rb +29 -0
  58. data/lib/sequel/adapters/jdbc.rb +24 -6
  59. data/lib/sequel/adapters/mysql.rb +1 -1
  60. data/lib/sequel/adapters/mysql2.rb +2 -3
  61. data/lib/sequel/adapters/odbc.rb +8 -6
  62. data/lib/sequel/adapters/oracle.rb +5 -4
  63. data/lib/sequel/adapters/postgres.rb +15 -9
  64. data/lib/sequel/adapters/shared/access.rb +6 -6
  65. data/lib/sequel/adapters/shared/mssql.rb +66 -21
  66. data/lib/sequel/adapters/shared/mysql.rb +27 -10
  67. data/lib/sequel/adapters/shared/oracle.rb +29 -23
  68. data/lib/sequel/adapters/shared/postgres.rb +271 -32
  69. data/lib/sequel/adapters/shared/sqlanywhere.rb +9 -9
  70. data/lib/sequel/adapters/shared/sqlite.rb +161 -19
  71. data/lib/sequel/adapters/sqlanywhere.rb +1 -1
  72. data/lib/sequel/adapters/sqlite.rb +1 -1
  73. data/lib/sequel/adapters/tinytds.rb +15 -2
  74. data/lib/sequel/adapters/utils/mysql_mysql2.rb +4 -1
  75. data/lib/sequel/ast_transformer.rb +6 -0
  76. data/lib/sequel/connection_pool/sharded_single.rb +4 -1
  77. data/lib/sequel/connection_pool/sharded_threaded.rb +12 -12
  78. data/lib/sequel/connection_pool/single.rb +1 -1
  79. data/lib/sequel/connection_pool/threaded.rb +2 -2
  80. data/lib/sequel/core.rb +333 -319
  81. data/lib/sequel/database/connecting.rb +3 -4
  82. data/lib/sequel/database/logging.rb +7 -1
  83. data/lib/sequel/database/misc.rb +31 -12
  84. data/lib/sequel/database/query.rb +3 -1
  85. data/lib/sequel/database/schema_generator.rb +53 -51
  86. data/lib/sequel/database/schema_methods.rb +38 -23
  87. data/lib/sequel/database/transactions.rb +17 -18
  88. data/lib/sequel/dataset/actions.rb +14 -9
  89. data/lib/sequel/dataset/features.rb +16 -0
  90. data/lib/sequel/dataset/misc.rb +2 -2
  91. data/lib/sequel/dataset/placeholder_literalizer.rb +3 -7
  92. data/lib/sequel/dataset/prepared_statements.rb +2 -0
  93. data/lib/sequel/dataset/query.rb +26 -9
  94. data/lib/sequel/dataset/sql.rb +76 -25
  95. data/lib/sequel/dataset.rb +4 -2
  96. data/lib/sequel/deprecated.rb +3 -1
  97. data/lib/sequel/exceptions.rb +2 -0
  98. data/lib/sequel/extensions/_pretty_table.rb +1 -2
  99. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  100. data/lib/sequel/extensions/async_thread_pool.rb +438 -0
  101. data/lib/sequel/extensions/blank.rb +8 -0
  102. data/lib/sequel/extensions/columns_introspection.rb +1 -2
  103. data/lib/sequel/extensions/connection_expiration.rb +2 -2
  104. data/lib/sequel/extensions/connection_validator.rb +2 -2
  105. data/lib/sequel/extensions/core_refinements.rb +2 -0
  106. data/lib/sequel/extensions/date_arithmetic.rb +36 -24
  107. data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -1
  108. data/lib/sequel/extensions/eval_inspect.rb +2 -0
  109. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  110. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  111. data/lib/sequel/extensions/index_caching.rb +9 -7
  112. data/lib/sequel/extensions/inflector.rb +9 -1
  113. data/lib/sequel/extensions/integer64.rb +2 -0
  114. data/lib/sequel/extensions/migration.rb +11 -3
  115. data/lib/sequel/extensions/named_timezones.rb +56 -8
  116. data/lib/sequel/extensions/pagination.rb +1 -1
  117. data/lib/sequel/extensions/pg_array.rb +5 -0
  118. data/lib/sequel/extensions/pg_array_ops.rb +14 -6
  119. data/lib/sequel/extensions/pg_enum.rb +11 -3
  120. data/lib/sequel/extensions/pg_extended_date_support.rb +2 -2
  121. data/lib/sequel/extensions/pg_hstore.rb +6 -0
  122. data/lib/sequel/extensions/pg_hstore_ops.rb +54 -2
  123. data/lib/sequel/extensions/pg_inet.rb +15 -5
  124. data/lib/sequel/extensions/pg_interval.rb +36 -8
  125. data/lib/sequel/extensions/pg_json.rb +387 -123
  126. data/lib/sequel/extensions/pg_json_ops.rb +238 -0
  127. data/lib/sequel/extensions/pg_loose_count.rb +3 -1
  128. data/lib/sequel/extensions/pg_range.rb +17 -9
  129. data/lib/sequel/extensions/pg_range_ops.rb +2 -0
  130. data/lib/sequel/extensions/pg_row.rb +4 -2
  131. data/lib/sequel/extensions/pg_row_ops.rb +24 -0
  132. data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
  133. data/lib/sequel/extensions/query.rb +3 -0
  134. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  135. data/lib/sequel/extensions/s.rb +2 -0
  136. data/lib/sequel/extensions/schema_dumper.rb +24 -7
  137. data/lib/sequel/extensions/server_block.rb +18 -7
  138. data/lib/sequel/extensions/sql_comments.rb +2 -2
  139. data/lib/sequel/extensions/string_agg.rb +1 -1
  140. data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
  141. data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
  142. data/lib/sequel/extensions/to_dot.rb +9 -3
  143. data/lib/sequel/model/associations.rb +356 -117
  144. data/lib/sequel/model/base.rb +107 -68
  145. data/lib/sequel/model/errors.rb +10 -1
  146. data/lib/sequel/model/inflections.rb +1 -1
  147. data/lib/sequel/model/plugins.rb +9 -3
  148. data/lib/sequel/model.rb +3 -1
  149. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  150. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  151. data/lib/sequel/plugins/association_pks.rb +60 -18
  152. data/lib/sequel/plugins/association_proxies.rb +8 -2
  153. data/lib/sequel/plugins/async_thread_pool.rb +39 -0
  154. data/lib/sequel/plugins/auto_validations.rb +39 -5
  155. data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
  156. data/lib/sequel/plugins/blacklist_security.rb +1 -2
  157. data/lib/sequel/plugins/boolean_subsets.rb +4 -1
  158. data/lib/sequel/plugins/caching.rb +3 -0
  159. data/lib/sequel/plugins/class_table_inheritance.rb +33 -28
  160. data/lib/sequel/plugins/column_encryption.rb +728 -0
  161. data/lib/sequel/plugins/composition.rb +7 -2
  162. data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
  163. data/lib/sequel/plugins/constraint_validations.rb +2 -1
  164. data/lib/sequel/plugins/csv_serializer.rb +28 -9
  165. data/lib/sequel/plugins/dataset_associations.rb +4 -1
  166. data/lib/sequel/plugins/dirty.rb +60 -22
  167. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  168. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  169. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  170. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  171. data/lib/sequel/plugins/json_serializer.rb +57 -35
  172. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  173. data/lib/sequel/plugins/many_through_many.rb +108 -9
  174. data/lib/sequel/plugins/nested_attributes.rb +15 -3
  175. data/lib/sequel/plugins/pg_array_associations.rb +58 -41
  176. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +91 -30
  177. data/lib/sequel/plugins/prepared_statements.rb +15 -12
  178. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
  179. data/lib/sequel/plugins/rcte_tree.rb +43 -35
  180. data/lib/sequel/plugins/serialization.rb +8 -3
  181. data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
  182. data/lib/sequel/plugins/sharding.rb +11 -5
  183. data/lib/sequel/plugins/single_table_inheritance.rb +22 -15
  184. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  185. data/lib/sequel/plugins/static_cache.rb +9 -4
  186. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  187. data/lib/sequel/plugins/string_stripper.rb +1 -1
  188. data/lib/sequel/plugins/subclasses.rb +2 -0
  189. data/lib/sequel/plugins/throw_failures.rb +1 -1
  190. data/lib/sequel/plugins/timestamps.rb +1 -1
  191. data/lib/sequel/plugins/tree.rb +9 -4
  192. data/lib/sequel/plugins/typecast_on_load.rb +3 -2
  193. data/lib/sequel/plugins/unused_associations.rb +521 -0
  194. data/lib/sequel/plugins/update_or_create.rb +1 -1
  195. data/lib/sequel/plugins/validation_class_methods.rb +5 -1
  196. data/lib/sequel/plugins/validation_helpers.rb +18 -11
  197. data/lib/sequel/plugins/xml_serializer.rb +1 -1
  198. data/lib/sequel/sql.rb +20 -5
  199. data/lib/sequel/timezones.rb +63 -17
  200. data/lib/sequel/version.rb +1 -1
  201. metadata +113 -381
  202. data/Rakefile +0 -151
  203. data/doc/release_notes/4.0.0.txt +0 -262
  204. data/doc/release_notes/4.1.0.txt +0 -85
  205. data/doc/release_notes/4.10.0.txt +0 -226
  206. data/doc/release_notes/4.11.0.txt +0 -147
  207. data/doc/release_notes/4.12.0.txt +0 -105
  208. data/doc/release_notes/4.13.0.txt +0 -169
  209. data/doc/release_notes/4.14.0.txt +0 -68
  210. data/doc/release_notes/4.15.0.txt +0 -56
  211. data/doc/release_notes/4.16.0.txt +0 -36
  212. data/doc/release_notes/4.17.0.txt +0 -38
  213. data/doc/release_notes/4.18.0.txt +0 -36
  214. data/doc/release_notes/4.19.0.txt +0 -45
  215. data/doc/release_notes/4.2.0.txt +0 -129
  216. data/doc/release_notes/4.20.0.txt +0 -79
  217. data/doc/release_notes/4.21.0.txt +0 -94
  218. data/doc/release_notes/4.22.0.txt +0 -72
  219. data/doc/release_notes/4.23.0.txt +0 -65
  220. data/doc/release_notes/4.24.0.txt +0 -99
  221. data/doc/release_notes/4.25.0.txt +0 -181
  222. data/doc/release_notes/4.26.0.txt +0 -44
  223. data/doc/release_notes/4.27.0.txt +0 -78
  224. data/doc/release_notes/4.28.0.txt +0 -57
  225. data/doc/release_notes/4.29.0.txt +0 -41
  226. data/doc/release_notes/4.3.0.txt +0 -40
  227. data/doc/release_notes/4.30.0.txt +0 -37
  228. data/doc/release_notes/4.31.0.txt +0 -57
  229. data/doc/release_notes/4.32.0.txt +0 -132
  230. data/doc/release_notes/4.33.0.txt +0 -88
  231. data/doc/release_notes/4.34.0.txt +0 -86
  232. data/doc/release_notes/4.35.0.txt +0 -130
  233. data/doc/release_notes/4.36.0.txt +0 -116
  234. data/doc/release_notes/4.37.0.txt +0 -50
  235. data/doc/release_notes/4.38.0.txt +0 -67
  236. data/doc/release_notes/4.39.0.txt +0 -127
  237. data/doc/release_notes/4.4.0.txt +0 -92
  238. data/doc/release_notes/4.40.0.txt +0 -179
  239. data/doc/release_notes/4.41.0.txt +0 -77
  240. data/doc/release_notes/4.42.0.txt +0 -221
  241. data/doc/release_notes/4.43.0.txt +0 -87
  242. data/doc/release_notes/4.44.0.txt +0 -125
  243. data/doc/release_notes/4.45.0.txt +0 -370
  244. data/doc/release_notes/4.46.0.txt +0 -404
  245. data/doc/release_notes/4.47.0.txt +0 -56
  246. data/doc/release_notes/4.48.0.txt +0 -293
  247. data/doc/release_notes/4.49.0.txt +0 -222
  248. data/doc/release_notes/4.5.0.txt +0 -34
  249. data/doc/release_notes/4.6.0.txt +0 -30
  250. data/doc/release_notes/4.7.0.txt +0 -103
  251. data/doc/release_notes/4.8.0.txt +0 -175
  252. data/doc/release_notes/4.9.0.txt +0 -190
  253. data/spec/adapter_spec.rb +0 -4
  254. data/spec/adapters/db2_spec.rb +0 -170
  255. data/spec/adapters/mssql_spec.rb +0 -804
  256. data/spec/adapters/mysql_spec.rb +0 -1065
  257. data/spec/adapters/oracle_spec.rb +0 -371
  258. data/spec/adapters/postgres_spec.rb +0 -4125
  259. data/spec/adapters/spec_helper.rb +0 -44
  260. data/spec/adapters/sqlanywhere_spec.rb +0 -97
  261. data/spec/adapters/sqlite_spec.rb +0 -652
  262. data/spec/bin_spec.rb +0 -278
  263. data/spec/core/connection_pool_spec.rb +0 -1250
  264. data/spec/core/database_spec.rb +0 -2865
  265. data/spec/core/dataset_spec.rb +0 -5515
  266. data/spec/core/deprecated_spec.rb +0 -70
  267. data/spec/core/expression_filters_spec.rb +0 -1455
  268. data/spec/core/mock_adapter_spec.rb +0 -722
  269. data/spec/core/object_graph_spec.rb +0 -336
  270. data/spec/core/placeholder_literalizer_spec.rb +0 -166
  271. data/spec/core/schema_generator_spec.rb +0 -214
  272. data/spec/core/schema_spec.rb +0 -1826
  273. data/spec/core/spec_helper.rb +0 -24
  274. data/spec/core/version_spec.rb +0 -14
  275. data/spec/core_extensions_spec.rb +0 -763
  276. data/spec/core_model_spec.rb +0 -2
  277. data/spec/core_spec.rb +0 -1
  278. data/spec/deprecation_helper.rb +0 -30
  279. data/spec/extensions/accessed_columns_spec.rb +0 -51
  280. data/spec/extensions/active_model_spec.rb +0 -99
  281. data/spec/extensions/after_initialize_spec.rb +0 -28
  282. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  283. data/spec/extensions/association_dependencies_spec.rb +0 -125
  284. data/spec/extensions/association_pks_spec.rb +0 -423
  285. data/spec/extensions/association_proxies_spec.rb +0 -100
  286. data/spec/extensions/auto_literal_strings_spec.rb +0 -205
  287. data/spec/extensions/auto_validations_spec.rb +0 -229
  288. data/spec/extensions/blacklist_security_spec.rb +0 -95
  289. data/spec/extensions/blank_spec.rb +0 -69
  290. data/spec/extensions/boolean_readers_spec.rb +0 -93
  291. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  292. data/spec/extensions/caching_spec.rb +0 -273
  293. data/spec/extensions/caller_logging_spec.rb +0 -52
  294. data/spec/extensions/class_table_inheritance_spec.rb +0 -750
  295. data/spec/extensions/column_conflicts_spec.rb +0 -75
  296. data/spec/extensions/column_select_spec.rb +0 -129
  297. data/spec/extensions/columns_introspection_spec.rb +0 -90
  298. data/spec/extensions/columns_updated_spec.rb +0 -35
  299. data/spec/extensions/composition_spec.rb +0 -248
  300. data/spec/extensions/connection_expiration_spec.rb +0 -151
  301. data/spec/extensions/connection_validator_spec.rb +0 -144
  302. data/spec/extensions/constant_sql_override_spec.rb +0 -24
  303. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
  304. data/spec/extensions/constraint_validations_spec.rb +0 -439
  305. data/spec/extensions/core_refinements_spec.rb +0 -528
  306. data/spec/extensions/csv_serializer_spec.rb +0 -183
  307. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  308. data/spec/extensions/dataset_associations_spec.rb +0 -365
  309. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  310. data/spec/extensions/date_arithmetic_spec.rb +0 -181
  311. data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
  312. data/spec/extensions/def_dataset_method_spec.rb +0 -100
  313. data/spec/extensions/defaults_setter_spec.rb +0 -150
  314. data/spec/extensions/delay_add_association_spec.rb +0 -73
  315. data/spec/extensions/dirty_spec.rb +0 -189
  316. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
  317. data/spec/extensions/eager_each_spec.rb +0 -62
  318. data/spec/extensions/eager_graph_eager_spec.rb +0 -100
  319. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  320. data/spec/extensions/error_splitter_spec.rb +0 -18
  321. data/spec/extensions/error_sql_spec.rb +0 -20
  322. data/spec/extensions/escaped_like_spec.rb +0 -40
  323. data/spec/extensions/eval_inspect_spec.rb +0 -81
  324. data/spec/extensions/finder_spec.rb +0 -260
  325. data/spec/extensions/force_encoding_spec.rb +0 -126
  326. data/spec/extensions/freeze_datasets_spec.rb +0 -31
  327. data/spec/extensions/graph_each_spec.rb +0 -113
  328. data/spec/extensions/hook_class_methods_spec.rb +0 -402
  329. data/spec/extensions/identifier_mangling_spec.rb +0 -201
  330. data/spec/extensions/implicit_subquery_spec.rb +0 -58
  331. data/spec/extensions/index_caching_spec.rb +0 -66
  332. data/spec/extensions/inflector_spec.rb +0 -183
  333. data/spec/extensions/input_transformer_spec.rb +0 -69
  334. data/spec/extensions/insert_returning_select_spec.rb +0 -72
  335. data/spec/extensions/instance_filters_spec.rb +0 -79
  336. data/spec/extensions/instance_hooks_spec.rb +0 -246
  337. data/spec/extensions/integer64_spec.rb +0 -22
  338. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  339. data/spec/extensions/json_serializer_spec.rb +0 -336
  340. data/spec/extensions/lazy_attributes_spec.rb +0 -183
  341. data/spec/extensions/list_spec.rb +0 -291
  342. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  343. data/spec/extensions/many_through_many_spec.rb +0 -2177
  344. data/spec/extensions/migration_spec.rb +0 -864
  345. data/spec/extensions/modification_detection_spec.rb +0 -93
  346. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
  347. data/spec/extensions/named_timezones_spec.rb +0 -111
  348. data/spec/extensions/nested_attributes_spec.rb +0 -767
  349. data/spec/extensions/null_dataset_spec.rb +0 -85
  350. data/spec/extensions/optimistic_locking_spec.rb +0 -127
  351. data/spec/extensions/pagination_spec.rb +0 -116
  352. data/spec/extensions/pg_array_associations_spec.rb +0 -802
  353. data/spec/extensions/pg_array_ops_spec.rb +0 -144
  354. data/spec/extensions/pg_array_spec.rb +0 -398
  355. data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -172
  356. data/spec/extensions/pg_enum_spec.rb +0 -118
  357. data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
  358. data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
  359. data/spec/extensions/pg_hstore_spec.rb +0 -219
  360. data/spec/extensions/pg_inet_ops_spec.rb +0 -102
  361. data/spec/extensions/pg_inet_spec.rb +0 -72
  362. data/spec/extensions/pg_interval_spec.rb +0 -103
  363. data/spec/extensions/pg_json_ops_spec.rb +0 -289
  364. data/spec/extensions/pg_json_spec.rb +0 -262
  365. data/spec/extensions/pg_loose_count_spec.rb +0 -23
  366. data/spec/extensions/pg_range_ops_spec.rb +0 -60
  367. data/spec/extensions/pg_range_spec.rb +0 -519
  368. data/spec/extensions/pg_row_ops_spec.rb +0 -61
  369. data/spec/extensions/pg_row_plugin_spec.rb +0 -60
  370. data/spec/extensions/pg_row_spec.rb +0 -363
  371. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
  372. data/spec/extensions/pg_timestamptz_spec.rb +0 -17
  373. data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
  374. data/spec/extensions/prepared_statements_spec.rb +0 -177
  375. data/spec/extensions/pretty_table_spec.rb +0 -123
  376. data/spec/extensions/query_spec.rb +0 -94
  377. data/spec/extensions/rcte_tree_spec.rb +0 -381
  378. data/spec/extensions/round_timestamps_spec.rb +0 -39
  379. data/spec/extensions/s_spec.rb +0 -60
  380. data/spec/extensions/schema_caching_spec.rb +0 -64
  381. data/spec/extensions/schema_dumper_spec.rb +0 -870
  382. data/spec/extensions/select_remove_spec.rb +0 -38
  383. data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
  384. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  385. data/spec/extensions/serialization_spec.rb +0 -365
  386. data/spec/extensions/server_block_spec.rb +0 -97
  387. data/spec/extensions/server_logging_spec.rb +0 -45
  388. data/spec/extensions/sharding_spec.rb +0 -189
  389. data/spec/extensions/shared_caching_spec.rb +0 -151
  390. data/spec/extensions/single_table_inheritance_spec.rb +0 -347
  391. data/spec/extensions/singular_table_names_spec.rb +0 -22
  392. data/spec/extensions/skip_create_refresh_spec.rb +0 -18
  393. data/spec/extensions/spec_helper.rb +0 -63
  394. data/spec/extensions/split_array_nil_spec.rb +0 -24
  395. data/spec/extensions/split_values_spec.rb +0 -57
  396. data/spec/extensions/sql_comments_spec.rb +0 -33
  397. data/spec/extensions/sql_expr_spec.rb +0 -59
  398. data/spec/extensions/static_cache_spec.rb +0 -471
  399. data/spec/extensions/string_agg_spec.rb +0 -90
  400. data/spec/extensions/string_date_time_spec.rb +0 -95
  401. data/spec/extensions/string_stripper_spec.rb +0 -68
  402. data/spec/extensions/subclasses_spec.rb +0 -79
  403. data/spec/extensions/subset_conditions_spec.rb +0 -38
  404. data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
  405. data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
  406. data/spec/extensions/synchronize_sql_spec.rb +0 -124
  407. data/spec/extensions/table_select_spec.rb +0 -83
  408. data/spec/extensions/tactical_eager_loading_spec.rb +0 -402
  409. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  410. data/spec/extensions/throw_failures_spec.rb +0 -74
  411. data/spec/extensions/timestamps_spec.rb +0 -209
  412. data/spec/extensions/to_dot_spec.rb +0 -153
  413. data/spec/extensions/touch_spec.rb +0 -226
  414. data/spec/extensions/tree_spec.rb +0 -334
  415. data/spec/extensions/typecast_on_load_spec.rb +0 -86
  416. data/spec/extensions/unlimited_update_spec.rb +0 -21
  417. data/spec/extensions/update_or_create_spec.rb +0 -83
  418. data/spec/extensions/update_primary_key_spec.rb +0 -105
  419. data/spec/extensions/update_refresh_spec.rb +0 -59
  420. data/spec/extensions/uuid_spec.rb +0 -101
  421. data/spec/extensions/validate_associated_spec.rb +0 -52
  422. data/spec/extensions/validation_class_methods_spec.rb +0 -1040
  423. data/spec/extensions/validation_contexts_spec.rb +0 -31
  424. data/spec/extensions/validation_helpers_spec.rb +0 -525
  425. data/spec/extensions/whitelist_security_spec.rb +0 -157
  426. data/spec/extensions/xml_serializer_spec.rb +0 -213
  427. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  428. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  429. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  430. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  431. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  432. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  433. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  434. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  435. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  436. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  437. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  438. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  439. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  440. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  441. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  442. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  443. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  444. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  445. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  446. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  447. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  448. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  449. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  450. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  451. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  452. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  453. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  454. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  455. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  456. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  457. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  458. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  459. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  460. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  461. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  462. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  463. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  464. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  465. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  466. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  467. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  468. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  469. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  470. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  471. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  472. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  473. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  474. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  475. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  476. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  477. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  478. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  479. data/spec/guards_helper.rb +0 -59
  480. data/spec/integration/associations_test.rb +0 -2597
  481. data/spec/integration/database_test.rb +0 -113
  482. data/spec/integration/dataset_test.rb +0 -1981
  483. data/spec/integration/eager_loader_test.rb +0 -687
  484. data/spec/integration/migrator_test.rb +0 -262
  485. data/spec/integration/model_test.rb +0 -203
  486. data/spec/integration/plugin_test.rb +0 -2396
  487. data/spec/integration/prepared_statement_test.rb +0 -405
  488. data/spec/integration/schema_test.rb +0 -889
  489. data/spec/integration/spec_helper.rb +0 -65
  490. data/spec/integration/timezone_test.rb +0 -86
  491. data/spec/integration/transaction_test.rb +0 -603
  492. data/spec/integration/type_test.rb +0 -127
  493. data/spec/model/association_reflection_spec.rb +0 -803
  494. data/spec/model/associations_spec.rb +0 -4738
  495. data/spec/model/base_spec.rb +0 -875
  496. data/spec/model/class_dataset_methods_spec.rb +0 -146
  497. data/spec/model/dataset_methods_spec.rb +0 -198
  498. data/spec/model/eager_loading_spec.rb +0 -2377
  499. data/spec/model/hooks_spec.rb +0 -370
  500. data/spec/model/inflector_spec.rb +0 -26
  501. data/spec/model/model_spec.rb +0 -956
  502. data/spec/model/plugins_spec.rb +0 -429
  503. data/spec/model/record_spec.rb +0 -2118
  504. data/spec/model/spec_helper.rb +0 -46
  505. data/spec/model/validations_spec.rb +0 -220
  506. data/spec/model_no_assoc_spec.rb +0 -1
  507. data/spec/model_spec.rb +0 -1
  508. data/spec/plugin_spec.rb +0 -1
  509. data/spec/sequel_coverage.rb +0 -15
  510. data/spec/sequel_warning.rb +0 -4
  511. data/spec/spec_config.rb +0 -12
@@ -1,2118 +0,0 @@
1
- require_relative "spec_helper"
2
-
3
- describe "Model#values" do
4
- before do
5
- @c = Class.new(Sequel::Model(:items))
6
- end
7
-
8
- it "should return the hash of model values" do
9
- hash = {:x=>1}
10
- @c.load(hash).values.must_be_same_as(hash)
11
- end
12
-
13
- it "should be aliased as to_hash" do
14
- hash = {:x=>1}
15
- @c.load(hash).to_hash.must_be_same_as(hash)
16
- end
17
- end
18
-
19
- describe "Model#get_column_value and set_column_value" do
20
- before do
21
- @c = Class.new(Sequel::Model(:items))
22
- @c.columns :x
23
- @o = @c.load(:x=>1)
24
- end
25
-
26
- it "should get and set column values" do
27
- @o.get_column_value(:x).must_equal 1
28
- @o.set_column_value(:x=, 2)
29
- @o.get_column_value(:x).must_equal 2
30
- @o.x.must_equal 2
31
- end
32
- end
33
-
34
- describe "Model#save server use" do
35
- before do
36
- @db = Sequel.mock(:autoid=>proc{|sql| 10}, :fetch=>{:x=>1, :id=>10}, :numrows=>1, :servers=>{:blah=>{}, :read_only=>{}})
37
- @c = Class.new(Sequel::Model(@db[:items]))
38
- @c.columns :id, :x, :y
39
- @c.dataset.columns(:id, :x, :y)
40
- @db.sqls
41
- end
42
-
43
- it "should use the :default server if the model doesn't have one already specified" do
44
- @c.new(:x=>1).save.must_equal @c.load(:x=>1, :id=>10)
45
- @db.sqls.must_equal ["INSERT INTO items (x) VALUES (1)", 'SELECT * FROM items WHERE (id = 10) LIMIT 1']
46
- end
47
-
48
- it "should use the model's server if the model has one already specified" do
49
- @c.dataset = @c.dataset.server(:blah)
50
- @c.new(:x=>1).save.must_equal @c.load(:x=>1, :id=>10)
51
- @db.sqls.must_equal ["INSERT INTO items (x) VALUES (1) -- blah", 'SELECT * FROM items WHERE (id = 10) LIMIT 1 -- blah']
52
- end
53
-
54
- it "should use transactions on the correct server" do
55
- @c.use_transactions = true
56
- @c.dataset = @c.dataset.server(:blah)
57
- @c.new(:x=>1).save.must_equal @c.load(:x=>1, :id=>10)
58
- @db.sqls.must_equal ["BEGIN -- blah", "INSERT INTO items (x) VALUES (1) -- blah", 'SELECT * FROM items WHERE (id = 10) LIMIT 1 -- blah', 'COMMIT -- blah']
59
-
60
- o = @c.load(:id=>1)
61
- o.x = 2
62
- o.this
63
- o.save
64
- @db.sqls.must_equal ["BEGIN -- blah", "UPDATE items SET x = 2 WHERE (id = 1) -- blah", 'COMMIT -- blah']
65
- end
66
- end
67
-
68
- describe "Model#save" do
69
- before do
70
- @c = Class.new(Sequel::Model(:items)) do
71
- columns :id, :x, :y
72
- end
73
- @c.dataset = @c.dataset.with_autoid(13)
74
- DB.reset
75
- end
76
-
77
- it "should insert a record for a new model instance" do
78
- o = @c.new(:x => 1)
79
- o.save
80
- DB.sqls.must_equal ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE id = 13"]
81
- end
82
-
83
- it "should raise if the object can't be refreshed after save" do
84
- o = @c.new(:x => 1)
85
- @c.dataset = @c.dataset.with_fetch([])
86
- proc{o.save}.must_raise(Sequel::NoExistingObject)
87
- end
88
-
89
- it "should use dataset's insert_select method if present" do
90
- @c.dataset = @c.dataset.with_fetch(:y=>2).with_extend do
91
- def supports_insert_select?; true end
92
- def insert_select(hash)
93
- with_sql_first("INSERT INTO items (y) VALUES (2) RETURNING *")
94
- end
95
- end
96
- o = @c.new(:x => 1)
97
- o.save
98
-
99
- o.values.must_equal(:y=>2)
100
- DB.sqls.must_equal ["INSERT INTO items (y) VALUES (2) RETURNING *"]
101
- end
102
-
103
- it "should issue regular insert query if insert_select returns nil" do
104
- @c.dataset = @c.dataset.with_fetch(:id=>4, :x=>2).with_autoid(4).with_extend do
105
- def supports_insert_select?; true end
106
- def insert_select(hash)
107
- end
108
- end
109
- o = @c.new(:x => 1)
110
- o.save
111
-
112
- DB.sqls.must_equal ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE id = 4"]
113
- o.values.must_equal(:id=>4, :x=>2)
114
- end
115
-
116
- it "should assume insert statement already ran if insert_select returns false" do
117
- @c.dataset = @c.dataset.with_fetch(:y=>2).with_extend do
118
- def supports_insert_select?; true end
119
- def insert_select(hash)
120
- with_sql_first("INSERT INTO items (y) VALUES (2) RETURNING *")
121
- false
122
- end
123
- end
124
- o = @c.new(:x => 1)
125
- o.save
126
-
127
- o.values.must_equal(:x=>1)
128
- DB.sqls.must_equal ["INSERT INTO items (y) VALUES (2) RETURNING *"]
129
- end
130
-
131
- it "should not use dataset's insert_select method if specific columns are selected" do
132
- @c.dataset = @c.dataset.select(:y).with_extend{def insert_select(*) raise; end}
133
- @c.new(:x => 1).save
134
- end
135
-
136
- it "should use dataset's insert_select method if the dataset uses returning, even if specific columns are selected" do
137
- @c.dataset = @c.dataset.select(:y).with_fetch(:y=>2).with_extend do
138
- def supports_returning?(_) true end
139
- def supports_insert_select?; true end
140
- def insert_select(hash)
141
- with_sql_first("INSERT INTO items (y) VALUES (2) RETURNING y")
142
- end
143
- end.returning(:y)
144
- DB.reset
145
- o = @c.new(:x => 1)
146
- o.save
147
-
148
- o.values.must_equal(:y=>2)
149
- DB.sqls.must_equal ["INSERT INTO items (y) VALUES (2) RETURNING y"]
150
- end
151
-
152
- it "should use value returned by insert as the primary key and refresh the object" do
153
- o = @c.new(:x => 11)
154
- o.save
155
- DB.sqls.must_equal ["INSERT INTO items (x) VALUES (11)", "SELECT * FROM items WHERE id = 13"]
156
- end
157
-
158
- it "should allow you to skip refreshing by overridding _save_refresh" do
159
- @c.send(:define_method, :_save_refresh){}
160
- @c.create(:x => 11)
161
- DB.sqls.must_equal ["INSERT INTO items (x) VALUES (11)"]
162
- end
163
-
164
- it "should work correctly for inserting a record without a primary key" do
165
- @c.no_primary_key
166
- o = @c.new(:x => 11)
167
- o.save
168
- DB.sqls.must_equal ["INSERT INTO items (x) VALUES (11)"]
169
- end
170
-
171
- it "should set the autoincrementing_primary_key value to the value returned by insert" do
172
- @c.unrestrict_primary_key
173
- @c.set_primary_key [:x, :y]
174
- o = @c.new(:x => 11)
175
- def o.autoincrementing_primary_key() :y end
176
- o.save
177
- DB.sqls.must_equal ["INSERT INTO items (x) VALUES (11)",
178
- 'SELECT * FROM items WHERE ((x = 11) AND (y = 13)) LIMIT 1']
179
- end
180
-
181
- it "should update a record for an existing model instance" do
182
- o = @c.load(:id => 3, :x => 1)
183
- o.save
184
- DB.sqls.must_equal ["UPDATE items SET x = 1 WHERE (id = 3)"]
185
- end
186
-
187
- it "should raise a NoExistingObject exception if the dataset update call doesn't return 1, unless require_modification is false" do
188
- i = 0
189
- @c.dataset = @c.dataset.with_extend{define_method(:numrows){i}}
190
- o = @c.load(:id => 3, :x => 1)
191
- proc{o.save}.must_raise(Sequel::NoExistingObject)
192
- i = 2
193
- proc{o.save}.must_raise(Sequel::NoExistingObject)
194
- i = 1
195
- o.save
196
-
197
- o.require_modification = false
198
- i = 0
199
- o.save
200
- i = 2
201
- o.save
202
- end
203
-
204
- it "should respect the :columns option to specify the columns to save" do
205
- o = @c.load(:id => 3, :x => 1, :y => nil)
206
- o.save(:columns=>:y)
207
- DB.sqls.first.must_equal "UPDATE items SET y = NULL WHERE (id = 3)"
208
- end
209
-
210
- it "should mark saved columns as not changed" do
211
- o = @c.load(:id => 3, :x => 1, :y => nil)
212
- o[:y] = 4
213
- o.changed_columns.must_equal [:y]
214
- o.save(:columns=>:x)
215
- o.changed_columns.must_equal [:y]
216
- o.save(:columns=>:y)
217
- o.changed_columns.must_equal []
218
- end
219
-
220
- it "should mark all columns as not changed if this is a new record" do
221
- o = @c.new(:x => 1, :y => nil)
222
- o.x = 4
223
- o.changed_columns.must_equal [:x]
224
- o.save
225
- o.changed_columns.must_equal []
226
- end
227
-
228
- it "should mark all columns as not changed if this is a new record and insert_select was used" do
229
- @c.dataset = @c.dataset.with_extend{def insert_select(h) h.merge(:id=>1) end}
230
- o = @c.new(:x => 1, :y => nil)
231
- o.x = 4
232
- o.changed_columns.must_equal [:x]
233
- o.save
234
- o.changed_columns.must_equal []
235
- end
236
-
237
- it "should use Model's use_transactions setting by default" do
238
- @c.use_transactions = true
239
- @c.load(:id => 3, :x => 1, :y => nil).save(:columns=>:y)
240
- DB.sqls.must_equal ["BEGIN", "UPDATE items SET y = NULL WHERE (id = 3)", "COMMIT"]
241
- @c.use_transactions = false
242
- @c.load(:id => 3, :x => 1, :y => nil).save(:columns=>:y)
243
- DB.sqls.must_equal ["UPDATE items SET y = NULL WHERE (id = 3)"]
244
- end
245
-
246
- it "should inherit Model's use_transactions setting" do
247
- @c.use_transactions = true
248
- Class.new(@c).load(:id => 3, :x => 1, :y => nil).save(:columns=>:y)
249
- DB.sqls.must_equal ["BEGIN", "UPDATE items SET y = NULL WHERE (id = 3)", "COMMIT"]
250
- @c.use_transactions = false
251
- Class.new(@c).load(:id => 3, :x => 1, :y => nil).save(:columns=>:y)
252
- DB.sqls.must_equal ["UPDATE items SET y = NULL WHERE (id = 3)"]
253
- end
254
-
255
- it "should use object's use_transactions setting" do
256
- o = @c.load(:id => 3, :x => 1, :y => nil)
257
- o.use_transactions = false
258
- @c.use_transactions = true
259
- o.save(:columns=>:y)
260
- DB.sqls.must_equal ["UPDATE items SET y = NULL WHERE (id = 3)"]
261
- o = @c.load(:id => 3, :x => 1, :y => nil)
262
- o.use_transactions = true
263
- @c.use_transactions = false
264
- o.save(:columns=>:y)
265
- DB.sqls.must_equal ["BEGIN", "UPDATE items SET y = NULL WHERE (id = 3)", "COMMIT"]
266
- end
267
-
268
- it "should use :transaction option if given" do
269
- o = @c.load(:id => 3, :x => 1, :y => nil)
270
- o.use_transactions = true
271
- o.save(:columns=>:y, :transaction=>false)
272
- DB.sqls.must_equal ["UPDATE items SET y = NULL WHERE (id = 3)"]
273
- o = @c.load(:id => 3, :x => 1, :y => nil)
274
- o.use_transactions = false
275
- o.save(:columns=>:y, :transaction=>true)
276
- DB.sqls.must_equal ["BEGIN", "UPDATE items SET y = NULL WHERE (id = 3)", "COMMIT"]
277
- end
278
-
279
- it "should rollback if before_save calls cancel_action and raise_on_save_failure = true" do
280
- o = @c.load(:id => 3, :x => 1, :y => nil)
281
- o.use_transactions = true
282
- o.raise_on_save_failure = true
283
- def o.before_save
284
- cancel_action
285
- end
286
- proc { o.save(:columns=>:y) }.must_raise(Sequel::HookFailed)
287
- DB.sqls.must_equal ["BEGIN", "ROLLBACK"]
288
- end
289
-
290
- it "should rollback if before_save calls cancel_action and :raise_on_failure option is true" do
291
- o = @c.load(:id => 3, :x => 1, :y => nil)
292
- o.use_transactions = true
293
- o.raise_on_save_failure = false
294
- def o.before_save
295
- cancel_action
296
- end
297
- proc { o.save(:columns=>:y, :raise_on_failure => true) }.must_raise(Sequel::HookFailed)
298
- DB.sqls.must_equal ["BEGIN", "ROLLBACK"]
299
- end
300
-
301
- it "should not rollback outer transactions if before_save calls cancel_action and raise_on_save_failure = false" do
302
- o = @c.load(:id => 3, :x => 1, :y => nil)
303
- o.use_transactions = true
304
- o.raise_on_save_failure = false
305
- def o.before_save
306
- cancel_action
307
- end
308
- DB.transaction do
309
- o.save(:columns=>:y).must_be_nil
310
- DB.run "BLAH"
311
- end
312
- DB.sqls.must_equal ["BEGIN", "BLAH", "COMMIT"]
313
- end
314
-
315
- it "should rollback if before_save calls cancel_action and raise_on_save_failure = false" do
316
- o = @c.load(:id => 3, :x => 1, :y => nil)
317
- o.use_transactions = true
318
- o.raise_on_save_failure = false
319
- def o.before_save
320
- cancel_action
321
- end
322
- o.save(:columns=>:y).must_be_nil
323
- DB.sqls.must_equal ["BEGIN", "ROLLBACK"]
324
- end
325
-
326
- it "should not rollback if before_save throws Rollback and use_transactions = false" do
327
- o = @c.load(:id => 3, :x => 1, :y => nil)
328
- o.use_transactions = false
329
- def o.before_save
330
- raise Sequel::Rollback
331
- end
332
- proc { o.save(:columns=>:y) }.must_raise(Sequel::Rollback)
333
- DB.sqls.must_equal []
334
- end
335
-
336
- it "should support a :server option to set the server/shard to use" do
337
- db = Sequel.mock(:fetch=>{:id=>13, :x=>1}, :autoid=>proc{13}, :numrows=>1, :servers=>{:s1=>{}})
338
- c = Class.new(Sequel::Model(db[:items]))
339
- c.columns :id, :x
340
- db.sqls
341
- o = c.new(:x => 1)
342
- o.save(:server=>:s1)
343
- db.sqls.must_equal ["INSERT INTO items (x) VALUES (1) -- s1", "SELECT * FROM items WHERE (id = 13) LIMIT 1 -- s1"]
344
- o.save(:server=>:s1, :transaction=>true)
345
- db.sqls.must_equal ["BEGIN -- s1", "UPDATE items SET x = 1 WHERE (id = 13) -- s1", 'COMMIT -- s1']
346
- end
347
- end
348
-
349
- describe "Model#set_server" do
350
- before do
351
- @db = Sequel.mock(:fetch=>{:id=>13, :x=>1}, :autoid=>proc{13}, :numrows=>1, :servers=>{:s1=>{}})
352
- @c = Class.new(Sequel::Model(@db[:items])) do
353
- columns :id, :x
354
- end
355
- @db.sqls
356
- end
357
-
358
- it "should set the server to use when inserting" do
359
- @c.new(:x => 1).set_server(:s1).save
360
- @db.sqls.must_equal ["INSERT INTO items (x) VALUES (1) -- s1", "SELECT * FROM items WHERE (id = 13) LIMIT 1 -- s1"]
361
- end
362
-
363
- it "should set the server to use when updating" do
364
- @c.load(:id=>13, :x => 1).set_server(:s1).save
365
- @db.sqls.must_equal ["UPDATE items SET x = 1 WHERE (id = 13) -- s1"]
366
- end
367
-
368
- it "should set the server to use for transactions when saving" do
369
- @c.load(:id=>13, :x => 1).set_server(:s1).save(:transaction=>true)
370
- @db.sqls.must_equal ["BEGIN -- s1", "UPDATE items SET x = 1 WHERE (id = 13) -- s1", 'COMMIT -- s1']
371
- end
372
-
373
- it "should set the server to use when deleting" do
374
- @c.load(:id=>13).set_server(:s1).delete
375
- @db.sqls.must_equal ["DELETE FROM items WHERE (id = 13) -- s1"]
376
- end
377
-
378
- it "should set the server to use when deleting when using optimized delete" do
379
- @c.set_primary_key :id
380
- @c.load(:id=>13).set_server(:s1).delete
381
- @db.sqls.must_equal ["DELETE FROM items WHERE id = 13 -- s1"]
382
- end
383
-
384
- it "should set the server to use for transactions when destroying" do
385
- o = @c.load(:id=>13).set_server(:s1)
386
- o.use_transactions = true
387
- o.destroy
388
- @db.sqls.must_equal ["BEGIN -- s1", "DELETE FROM items WHERE (id = 13) -- s1", 'COMMIT -- s1']
389
- end
390
-
391
- it "should set the server on this if this is already loaded" do
392
- o = @c.load(:id=>13, :x => 1)
393
- o.this
394
- o.set_server(:s1)
395
- o.this.opts[:server].must_equal :s1
396
- end
397
-
398
- it "should set the server on this if this is not already loaded" do
399
- @c.load(:id=>13, :x => 1).set_server(:s1).this.opts[:server].must_equal :s1
400
- end
401
- end
402
-
403
- describe "Model#freeze" do
404
- before do
405
- class ::Album < Sequel::Model
406
- columns :id
407
- class B < Sequel::Model
408
- columns :id, :album_id
409
- end
410
- end
411
- @o = Album.load(:id=>1).freeze
412
- DB.sqls
413
- end
414
- after do
415
- Object.send(:remove_const, :Album)
416
- end
417
-
418
- it "should freeze the object" do
419
- @o.frozen?.must_equal true
420
- end
421
-
422
- it "should freeze the object if the model doesn't have a primary key" do
423
- Album.no_primary_key
424
- @o = Album.load(:id=>1).freeze
425
- @o.frozen?.must_equal true
426
- end
427
-
428
- it "should freeze the object's values, associations, changed_columns, errors, and this" do
429
- @o.values.frozen?.must_equal true
430
- @o.changed_columns.frozen?.must_equal true
431
- @o.errors.frozen?.must_equal true
432
- @o.this.frozen?.must_equal true
433
- end
434
-
435
- it "should still have working class attr overriddable methods" do
436
- [:typecast_empty_string_to_nil, :typecast_on_assignment, :strict_param_setting, :raise_on_save_failure, :raise_on_typecast_failure, :require_modification, :use_transactions].each{|m| @o.send(m) == Album.send(m)}
437
- end
438
-
439
- it "should have working new? method" do
440
- @o.new?.must_equal false
441
- Album.new.freeze.new?.must_equal true
442
- end
443
-
444
- it "should have working valid? method" do
445
- @o.valid?.must_equal true
446
- o = Album.new
447
- def o.validate() errors.add(:foo, '') end
448
- o.freeze
449
- o.valid?.must_equal false
450
- end
451
-
452
- it "should not call validate if errors is already frozen" do
453
- @o.valid?.must_equal true
454
- o = Album.new
455
- o.errors.freeze
456
- def o.validate() errors.add(:foo, '') end
457
- o.freeze
458
- o.valid?.must_equal true
459
- end
460
-
461
- it "should raise an Error if trying to save/destroy/delete/refresh" do
462
- proc{@o.save}.must_raise(Sequel::Error)
463
- proc{@o.destroy}.must_raise(Sequel::Error)
464
- proc{@o.delete}.must_raise(Sequel::Error)
465
- proc{@o.refresh}.must_raise(Sequel::Error)
466
- @o.db.sqls.must_equal []
467
- end
468
- end
469
-
470
- describe "Model#dup" do
471
- before do
472
- @Album = Class.new(Sequel::Model(:albums))
473
- @o = @Album.load(:id=>1)
474
- DB.sqls
475
- end
476
-
477
- it "should be equal to existing object" do
478
- @o.dup.must_equal @o
479
- @o.dup.values.must_equal @o.values
480
- @o.dup.changed_columns.must_equal @o.changed_columns
481
- @o.dup.errors.must_equal @o.errors
482
- @o.dup.this.must_equal @o.this
483
- end
484
-
485
- it "should not use identical structures" do
486
- @o.dup.wont_be_same_as(@o)
487
- @o.dup.values.wont_be_same_as(@o.values)
488
- @o.dup.changed_columns.wont_be_same_as(@o.changed_columns)
489
- @o.dup.errors.wont_be_same_as(@o.errors)
490
- @o.dup.this.wont_be_same_as(@o.this)
491
- end
492
-
493
- it "should keep new status" do
494
- @o.dup.new?.must_equal false
495
- @Album.new.dup.new?.must_equal true
496
- end
497
-
498
- it "should not copy frozen status" do
499
- this_frozen = @o.this.frozen?
500
- d = @o.freeze.dup
501
- d.wont_be :frozen?
502
- d.values.wont_be :frozen?
503
- d.changed_columns.wont_be :frozen?
504
- d.errors.wont_be :frozen?
505
- d.this.frozen?.must_equal this_frozen
506
- end
507
- end
508
-
509
- describe "Model#clone" do
510
- before do
511
- @Album = Class.new(Sequel::Model(:albums))
512
- @o = @Album.load(:id=>1)
513
- DB.sqls
514
- end
515
-
516
- it "should be equal to existing object" do
517
- @o.clone.must_equal @o
518
- @o.clone.values.must_equal @o.values
519
- @o.clone.changed_columns.must_equal @o.changed_columns
520
- @o.clone.errors.must_equal @o.errors
521
- @o.clone.this.must_equal @o.this
522
- end
523
-
524
- it "should not use identical structures" do
525
- @o.clone.wont_be_same_as(@o)
526
- @o.clone.values.wont_be_same_as(@o.values)
527
- @o.clone.changed_columns.wont_be_same_as(@o.changed_columns)
528
- @o.clone.errors.wont_be_same_as(@o.errors)
529
- @o.clone.this.wont_be_same_as(@o.this)
530
- end
531
-
532
- it "should keep new status" do
533
- @o.clone.new?.must_equal false
534
- @Album.new.clone.new?.must_equal true
535
- end
536
-
537
- it "should copy frozen status" do
538
- @o.freeze.clone.must_be :frozen?
539
- @o.freeze.clone.values.must_be :frozen?
540
- @o.freeze.clone.changed_columns.must_be :frozen?
541
- @o.freeze.clone.errors.must_be :frozen?
542
- @o.freeze.clone.this.must_be :frozen?
543
- end
544
- end
545
-
546
- describe "Model#marshallable" do
547
- before do
548
- class ::Album < Sequel::Model
549
- columns :id, :x
550
- end
551
- end
552
- after do
553
- Object.send(:remove_const, :Album)
554
- end
555
-
556
- it "should make an object marshallable" do
557
- i = Album.new(:x=>2)
558
- s = nil
559
- i2 = nil
560
- i.marshallable!
561
- s = Marshal.dump(i)
562
- i2 = Marshal.load(s)
563
- i2.must_equal i
564
-
565
- i.save
566
- i.marshallable!
567
- s = Marshal.dump(i)
568
- i2 = Marshal.load(s)
569
- i2.must_equal i
570
-
571
- i.save
572
- i.marshallable!
573
- s = Marshal.dump(i)
574
- i2 = Marshal.load(s)
575
- i2.must_equal i
576
- end
577
- end
578
-
579
- describe "Model#modified?" do
580
- before do
581
- @c = Class.new(Sequel::Model(:items))
582
- @c.class_eval do
583
- columns :id, :x
584
- @db_schema = {:x => {:type => :integer}}
585
- end
586
- DB.reset
587
- end
588
-
589
- it "should be true if the object is new" do
590
- @c.new.modified?.must_equal true
591
- end
592
-
593
- it "should be false if the object has not been modified" do
594
- @c.load(:id=>1).modified?.must_equal false
595
- end
596
-
597
- it "should be true if the object has been modified" do
598
- o = @c.load(:id=>1, :x=>2)
599
- o.x = 3
600
- o.modified?.must_equal true
601
- end
602
-
603
- it "should be true if the object is marked modified!" do
604
- o = @c.load(:id=>1, :x=>2)
605
- o.modified!
606
- o.modified?.must_equal true
607
- end
608
-
609
- it "should be false if the object is marked modified! after saving until modified! again" do
610
- o = @c.load(:id=>1, :x=>2)
611
- o.modified!
612
- o.save
613
- o.modified?.must_equal false
614
- o.modified!
615
- o.modified?.must_equal true
616
- end
617
-
618
- it "should be false if a column value is set that is the same as the current value after typecasting" do
619
- o = @c.load(:id=>1, :x=>2)
620
- o.x = '2'
621
- o.modified?.must_equal false
622
- end
623
-
624
- it "should be true if a column value is set that is the different as the current value after typecasting" do
625
- o = @c.load(:id=>1, :x=>'2')
626
- o.x = '2'
627
- o.modified?.must_equal true
628
- end
629
-
630
- it "should be true if given a column argument and the column has been changed" do
631
- o = @c.new
632
- o.modified?(:id).must_equal false
633
- o.id = 1
634
- o.modified?(:id).must_equal true
635
- end
636
- end
637
-
638
- describe "Model#modified!" do
639
- before do
640
- @c = Class.new(Sequel::Model(:items))
641
- @c.class_eval do
642
- columns :id, :x
643
- end
644
- DB.reset
645
- end
646
-
647
- it "should mark the object as modified so that save_changes still runs the callbacks" do
648
- o = @c.load(:id=>1, :x=>2)
649
- def o.after_save
650
- values[:x] = 3
651
- end
652
- o.update({})
653
- o.x.must_equal 2
654
-
655
- o.modified!
656
- o.update({})
657
- o.x.must_equal 3
658
- o.db.sqls.must_equal []
659
- end
660
-
661
- it "should mark given column argument as modified" do
662
- o = @c.load(:id=>1, :x=>2)
663
- o.modified!(:x)
664
- o.changed_columns.must_equal [:x]
665
- o.save
666
- o.db.sqls.must_equal ["UPDATE items SET x = 2 WHERE (id = 1)"]
667
- end
668
- end
669
-
670
- describe "Model#save_changes" do
671
- before do
672
- @c = Class.new(Sequel::Model(:items)) do
673
- unrestrict_primary_key
674
- columns :id, :x, :y
675
- end
676
- DB.reset
677
- end
678
-
679
- it "should always save if the object is new" do
680
- o = @c.new(:x => 1)
681
- o.save_changes
682
- DB.sqls.first.must_equal "INSERT INTO items (x) VALUES (1)"
683
- end
684
-
685
- it "should take options passed to save" do
686
- o = @c.load(:id=>1, :x => 1)
687
- o.x = 2
688
- o.save_changes
689
- DB.sqls.must_equal ["UPDATE items SET x = 2 WHERE (id = 1)"]
690
-
691
- o.x = 3
692
- o.save_changes(:transaction=>true)
693
- DB.sqls.must_equal ["BEGIN", "UPDATE items SET x = 3 WHERE (id = 1)", "COMMIT"]
694
- end
695
-
696
- it "should do nothing if no changed columns" do
697
- o = @c.load(:id => 3, :x => 1, :y => nil)
698
- o.save_changes
699
- DB.sqls.must_equal []
700
- end
701
-
702
- it "should do nothing if modified? is false" do
703
- o = @c.load(:id => 3, :x => 1, :y => nil)
704
- def o.modified?; false; end
705
- o.save_changes
706
- DB.sqls.must_equal []
707
- end
708
-
709
- it "should update only changed columns" do
710
- o = @c.load(:id => 3, :x => 1, :y => nil)
711
- o.x = 2
712
-
713
- o.save_changes
714
- DB.sqls.must_equal ["UPDATE items SET x = 2 WHERE (id = 3)"]
715
- o.save_changes
716
- o.save_changes
717
- DB.sqls.must_equal []
718
-
719
- o.y = 4
720
- o.save_changes
721
- DB.sqls.must_equal ["UPDATE items SET y = 4 WHERE (id = 3)"]
722
- o.save_changes
723
- o.save_changes
724
- DB.sqls.must_equal []
725
- end
726
-
727
- it "should not consider columns changed if the values did not change" do
728
- o = @c.load(:id => 3, :x => 1, :y => nil)
729
- o.x = 1
730
-
731
- o.save_changes
732
- DB.sqls.must_equal []
733
- o.x = 3
734
- o.save_changes
735
- DB.sqls.must_equal ["UPDATE items SET x = 3 WHERE (id = 3)"]
736
-
737
- o[:y] = nil
738
- o.save_changes
739
- DB.sqls.must_equal []
740
- o[:y] = 4
741
- o.save_changes
742
- DB.sqls.must_equal ["UPDATE items SET y = 4 WHERE (id = 3)"]
743
- end
744
-
745
- it "should clear changed_columns" do
746
- o = @c.load(:id => 3, :x => 1, :y => nil)
747
- o.x = 4
748
- o.changed_columns.must_equal [:x]
749
- o.save_changes
750
- o.changed_columns.must_equal []
751
- end
752
-
753
- it "should update columns changed in a before_update hook" do
754
- o = @c.load(:id => 3, :x => 1, :y => nil)
755
- @c.send(:define_method, :before_update){self.x += 1}
756
- o.save_changes
757
- DB.sqls.must_equal []
758
- o.x = 2
759
- o.save_changes
760
- DB.sqls.must_equal ["UPDATE items SET x = 3 WHERE (id = 3)"]
761
- o.save_changes
762
- DB.sqls.must_equal []
763
- o.x = 4
764
- o.save_changes
765
- DB.sqls.must_equal ["UPDATE items SET x = 5 WHERE (id = 3)"]
766
- end
767
-
768
- it "should update columns changed in a before_save hook" do
769
- o = @c.load(:id => 3, :x => 1, :y => nil)
770
- @c.send(:define_method, :before_update){self.x += 1}
771
- o.save_changes
772
- DB.sqls.must_equal []
773
- o.x = 2
774
- o.save_changes
775
- DB.sqls.must_equal ["UPDATE items SET x = 3 WHERE (id = 3)"]
776
- o.save_changes
777
- DB.sqls.must_equal []
778
- o.x = 4
779
- o.save_changes
780
- DB.sqls.must_equal ["UPDATE items SET x = 5 WHERE (id = 3)"]
781
- end
782
- end
783
-
784
- describe "Model#new?" do
785
- before do
786
- @c = Class.new(Sequel::Model(:items)) do
787
- unrestrict_primary_key
788
- columns :x
789
- end
790
- DB.reset
791
- end
792
-
793
- it "should be true for a new instance" do
794
- n = @c.new(:x => 1)
795
- n.must_be :new?
796
- end
797
-
798
- it "should be false after saving" do
799
- n = @c.new(:x => 1)
800
- n.save
801
- n.wont_be :new?
802
- end
803
- end
804
-
805
- describe Sequel::Model, "with a primary key" do
806
- it "should default to :id" do
807
- model_a = Class.new Sequel::Model
808
- model_a.primary_key.must_equal :id
809
- end
810
-
811
- it "should be changed through 'set_primary_key'" do
812
- model_a = Class.new(Sequel::Model){ set_primary_key :a }
813
- model_a.primary_key.must_equal :a
814
- end
815
-
816
- it "should accept single argument composite keys" do
817
- model_a = Class.new(Sequel::Model){ set_primary_key [:a, :b] }
818
- model_a.primary_key.must_equal [:a, :b]
819
- end
820
- end
821
-
822
- describe Sequel::Model, "without a primary key" do
823
- it "should return nil for primary key" do
824
- Class.new(Sequel::Model){no_primary_key}.primary_key.must_be_nil
825
- end
826
-
827
- it "should raise a Sequel::Error on 'this'" do
828
- instance = Class.new(Sequel::Model){no_primary_key}.new
829
- proc{instance.this}.must_raise(Sequel::Error)
830
- end
831
- end
832
-
833
- describe Sequel::Model, "#this" do
834
- before do
835
- @example = Class.new(Sequel::Model(:examples))
836
- @example.columns :id, :a, :x, :y
837
- end
838
-
839
- it "should return a dataset identifying the record" do
840
- instance = @example.load(:id => 3)
841
- instance.this.sql.must_equal "SELECT * FROM examples WHERE (id = 3) LIMIT 1"
842
- end
843
-
844
- it "should support arbitary primary keys" do
845
- @example.set_primary_key :a
846
-
847
- instance = @example.load(:a => 3)
848
- instance.this.sql.must_equal "SELECT * FROM examples WHERE (a = 3) LIMIT 1"
849
- end
850
-
851
- it "should use a subquery if the dataset is joined" do
852
- @example.dataset = @example.dataset.cross_join(:a)
853
- instance = @example.load(:id => 3)
854
- instance.this.sql.must_equal "SELECT * FROM (SELECT * FROM examples CROSS JOIN a) AS examples WHERE (id = 3) LIMIT 1"
855
- end
856
-
857
- it "should use a primary key if the dataset uses a subquery" do
858
- @example.dataset = @example.dataset.cross_join(:a).from_self(:alias=>:b)
859
- instance = @example.load(:id => 3)
860
- instance.this.sql.must_equal "SELECT * FROM (SELECT * FROM examples CROSS JOIN a) AS b WHERE (id = 3) LIMIT 1"
861
- end
862
-
863
- it "should support composite primary keys" do
864
- @example.set_primary_key [:x, :y]
865
- instance = @example.load(:x => 4, :y => 5)
866
- instance.this.sql.must_equal 'SELECT * FROM examples WHERE ((x = 4) AND (y = 5)) LIMIT 1'
867
- end
868
- end
869
-
870
- describe "Model#pk" do
871
- before do
872
- @m = Class.new(Sequel::Model)
873
- @m.columns :id, :x, :y
874
- end
875
-
876
- it "should by default return the value of the :id column" do
877
- m = @m.load(:id => 111, :x => 2, :y => 3)
878
- m.pk.must_equal 111
879
- end
880
-
881
- it "should return the primary key value for custom primary key" do
882
- @m.set_primary_key :x
883
- m = @m.load(:id => 111, :x => 2, :y => 3)
884
- m.pk.must_equal 2
885
- end
886
-
887
- it "should return the primary key value for composite primary key" do
888
- @m.set_primary_key [:y, :x]
889
- m = @m.load(:id => 111, :x => 2, :y => 3)
890
- m.pk.must_equal [3, 2]
891
- end
892
-
893
- it "should raise if no primary key" do
894
- @m.set_primary_key nil
895
- m = @m.new(:id => 111, :x => 2, :y => 3)
896
- proc {m.pk}.must_raise(Sequel::Error)
897
-
898
- @m.no_primary_key
899
- m = @m.new(:id => 111, :x => 2, :y => 3)
900
- proc {m.pk}.must_raise(Sequel::Error)
901
- end
902
- end
903
-
904
- describe "Model#pk_hash" do
905
- before do
906
- @m = Class.new(Sequel::Model)
907
- @m.columns :id, :x, :y
908
- end
909
-
910
- it "should by default return a hash with the value of the :id column" do
911
- m = @m.load(:id => 111, :x => 2, :y => 3)
912
- m.pk_hash.must_equal(:id => 111)
913
- end
914
-
915
- it "should return a hash with the primary key value for custom primary key" do
916
- @m.set_primary_key :x
917
- m = @m.load(:id => 111, :x => 2, :y => 3)
918
- m.pk_hash.must_equal(:x => 2)
919
- end
920
-
921
- it "should return a hash with the primary key values for composite primary key" do
922
- @m.set_primary_key [:y, :x]
923
- m = @m.load(:id => 111, :x => 2, :y => 3)
924
- m.pk_hash.must_equal(:y => 3, :x => 2)
925
- end
926
-
927
- it "should raise if no primary key" do
928
- @m.set_primary_key nil
929
- m = @m.new(:id => 111, :x => 2, :y => 3)
930
- proc{m.pk_hash}.must_raise(Sequel::Error)
931
-
932
- @m.no_primary_key
933
- m = @m.new(:id => 111, :x => 2, :y => 3)
934
- proc{m.pk_hash}.must_raise(Sequel::Error)
935
- end
936
- end
937
-
938
- describe "Model#qualified_pk_hash" do
939
- before do
940
- @m = Class.new(Sequel::Model(:items))
941
- @m.columns :id, :x, :y
942
- end
943
-
944
- it "should by default return a hash with the value of the :id column" do
945
- m = @m.load(:id => 111, :x => 2, :y => 3)
946
- m.qualified_pk_hash.must_equal(Sequel.qualify(:items, :id) => 111)
947
- end
948
-
949
- it "should accept a custom qualifier" do
950
- m = @m.load(:id => 111, :x => 2, :y => 3)
951
- m.qualified_pk_hash(:foo).must_equal(Sequel.qualify(:foo, :id) => 111)
952
- end
953
-
954
- it "should return a hash with the primary key value for custom primary key" do
955
- @m.set_primary_key :x
956
- m = @m.load(:id => 111, :x => 2, :y => 3)
957
- m.qualified_pk_hash.must_equal(Sequel.qualify(:items, :x) => 2)
958
- end
959
-
960
- it "should return a hash with the primary key values for composite primary key" do
961
- @m.set_primary_key [:y, :x]
962
- m = @m.load(:id => 111, :x => 2, :y => 3)
963
- m.qualified_pk_hash.must_equal(Sequel.qualify(:items, :y) => 3, Sequel.qualify(:items, :x) => 2)
964
- end
965
-
966
- it "should raise if no primary key" do
967
- @m.set_primary_key nil
968
- m = @m.new(:id => 111, :x => 2, :y => 3)
969
- proc{m.qualified_pk_hash}.must_raise(Sequel::Error)
970
-
971
- @m.no_primary_key
972
- m = @m.new(:id => 111, :x => 2, :y => 3)
973
- proc{m.qualified_pk_hash}.must_raise(Sequel::Error)
974
- end
975
- end
976
-
977
- describe Sequel::Model, "#set" do
978
- before do
979
- @c = Class.new(Sequel::Model(:items)) do
980
- set_primary_key :id
981
- columns :x, :y, :id
982
- end
983
- @c.strict_param_setting = false
984
- @o1 = @c.new
985
- @o2 = @c.load(:id => 5)
986
- DB.reset
987
- end
988
-
989
- it "should filter the given params using the model columns" do
990
- @o1.set(:x => 1, :z => 2)
991
- @o1.values.must_equal(:x => 1)
992
- DB.sqls.must_equal []
993
-
994
- @o2.set(:y => 1, :abc => 2)
995
- @o2.values.must_equal(:y => 1, :id=> 5)
996
- DB.sqls.must_equal []
997
- end
998
-
999
- it "should work with both strings and symbols" do
1000
- @o1.set('x'=> 1, 'z'=> 2)
1001
- @o1.values.must_equal(:x => 1)
1002
- DB.sqls.must_equal []
1003
-
1004
- @o2.set('y'=> 1, 'abc'=> 2)
1005
- @o2.values.must_equal(:y => 1, :id=> 5)
1006
- DB.sqls.must_equal []
1007
- end
1008
-
1009
- it "should support virtual attributes" do
1010
- @c.send(:define_method, :blah=){|v| self.x = v}
1011
- @o1.set(:blah => 333)
1012
- @o1.values.must_equal(:x => 333)
1013
- DB.sqls.must_equal []
1014
- @o1.set('blah'=> 334)
1015
- @o1.values.must_equal(:x => 334)
1016
- DB.sqls.must_equal []
1017
- end
1018
-
1019
- it "should not modify the primary key" do
1020
- @o1.set(:x => 1, :id => 2)
1021
- @o1.values.must_equal(:x => 1)
1022
- DB.sqls.must_equal []
1023
- @o2.set('y'=> 1, 'id'=> 2)
1024
- @o2.values.must_equal(:y => 1, :id=> 5)
1025
- DB.sqls.must_equal []
1026
- end
1027
-
1028
- it "should return self" do
1029
- returned_value = @o1.set(:x => 1, :z => 2)
1030
- returned_value.must_equal @o1
1031
- DB.sqls.must_equal []
1032
- end
1033
-
1034
- it "should raise error if strict_param_setting is true and method does not exist" do
1035
- @o1.strict_param_setting = true
1036
- proc{@o1.set('foo' => 1)}.must_raise(Sequel::MassAssignmentRestriction)
1037
- end
1038
-
1039
- it "should raise error if strict_param_setting is true and column is a primary key" do
1040
- @o1.strict_param_setting = true
1041
- proc{@o1.set('id' => 1)}.must_raise(Sequel::MassAssignmentRestriction)
1042
- end
1043
-
1044
- it "should raise error if strict_param_setting is true and column is restricted" do
1045
- @o1.strict_param_setting = true
1046
- @c.setter_methods.delete("x=")
1047
- proc{@o1.set('x' => 1)}.must_raise(Sequel::MassAssignmentRestriction)
1048
- end
1049
-
1050
- it "should not create a symbol if strict_param_setting is true and string is given" do
1051
- @o1.strict_param_setting = true
1052
- proc{@o1.set('sadojafdso' => 1)}.must_raise(Sequel::MassAssignmentRestriction)
1053
- Symbol.all_symbols.map(&:to_s).wont_include('sadojafdso')
1054
- end
1055
-
1056
- it "#set should correctly handle cases where an instance method is added to the class" do
1057
- @o1.set(:x => 1)
1058
- @o1.values.must_equal(:x => 1)
1059
-
1060
- @c.class_eval do
1061
- def z=(v)
1062
- self[:z] = v
1063
- end
1064
- end
1065
- @o1.set(:x => 2, :z => 3)
1066
- @o1.values.must_equal(:x => 2, :z=>3)
1067
- end
1068
-
1069
- it "#set should correctly handle cases where a singleton method is added to the object" do
1070
- @o1.set(:x => 1)
1071
- @o1.values.must_equal(:x => 1)
1072
-
1073
- def @o1.z=(v)
1074
- self[:z] = v
1075
- end
1076
- @o1.set(:x => 2, :z => 3)
1077
- @o1.values.must_equal(:x => 2, :z=>3)
1078
- end
1079
-
1080
- it "#set should correctly handle cases where a module with a setter method is included in the class" do
1081
- @o1.set(:x => 1)
1082
- @o1.values.must_equal(:x => 1)
1083
-
1084
- @c.send(:include, Module.new do
1085
- def z=(v)
1086
- self[:z] = v
1087
- end
1088
- end)
1089
- @o1.set(:x => 2, :z => 3)
1090
- @o1.values.must_equal(:x => 2, :z=>3)
1091
- end
1092
-
1093
- it "#set should correctly handle cases where the object extends a module with a setter method " do
1094
- @o1.set(:x => 1)
1095
- @o1.values.must_equal(:x => 1)
1096
-
1097
- @o1.extend(Module.new do
1098
- def z=(v)
1099
- self[:z] = v
1100
- end
1101
- end)
1102
- @o1.set(:x => 2, :z => 3)
1103
- @o1.values.must_equal(:x => 2, :z=>3)
1104
- end
1105
- end
1106
-
1107
- describe Sequel::Model, "#update" do
1108
- before do
1109
- @c = Class.new(Sequel::Model(:items)) do
1110
- set_primary_key :id
1111
- columns :x, :y, :id
1112
- end
1113
- @c.strict_param_setting = false
1114
- @o1 = @c.new
1115
- @o2 = @c.load(:id => 5)
1116
- DB.reset
1117
- end
1118
-
1119
- it "should filter the given params using the model columns" do
1120
- @o1.update(:x => 1, :z => 2)
1121
- DB.sqls.must_equal ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE id = 10"]
1122
-
1123
- DB.reset
1124
- @o2.update(:y => 1, :abc => 2)
1125
- DB.sqls.must_equal ["UPDATE items SET y = 1 WHERE (id = 5)"]
1126
- end
1127
-
1128
- it "should support virtual attributes" do
1129
- @c.send(:define_method, :blah=){|v| self.x = v}
1130
- @o1.update(:blah => 333)
1131
- DB.sqls.must_equal ["INSERT INTO items (x) VALUES (333)", "SELECT * FROM items WHERE id = 10"]
1132
- end
1133
-
1134
- it "should not modify the primary key" do
1135
- @o1.update(:x => 1, :id => 2)
1136
- DB.sqls.must_equal ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE id = 10"]
1137
- DB.reset
1138
- @o2.update('y'=> 1, 'id'=> 2)
1139
- @o2.values.must_equal(:y => 1, :id=> 5)
1140
- DB.sqls.must_equal ["UPDATE items SET y = 1 WHERE (id = 5)"]
1141
- end
1142
- end
1143
-
1144
- describe Sequel::Model, "#set_fields" do
1145
- before do
1146
- @c = Class.new(Sequel::Model(:items)) do
1147
- set_primary_key :id
1148
- columns :x, :y, :z, :id
1149
- end
1150
- @o1 = @c.new
1151
- DB.reset
1152
- end
1153
-
1154
- it "should set only the given fields" do
1155
- @o1.set_fields({:x => 1, :y => 2, :z=>3, :id=>4}, [:x, :y])
1156
- @o1.values.must_equal(:x => 1, :y => 2)
1157
- @o1.set_fields({:x => 9, :y => 8, :z=>6, :id=>7}, [:x, :y, :id])
1158
- @o1.values.must_equal(:x => 9, :y => 8, :id=>7)
1159
- DB.sqls.must_equal []
1160
- end
1161
-
1162
- it "should lookup into the hash without checking if the entry exists" do
1163
- @o1.set_fields({:x => 1}, [:x, :y])
1164
- @o1.values.must_equal(:x => 1, :y => nil)
1165
- @o1.set_fields(Hash.new(2), [:x, :y])
1166
- @o1.values.must_equal(:x => 2, :y => 2)
1167
- end
1168
-
1169
- it "should skip missing fields if :missing=>:skip option is used" do
1170
- @o1.set_fields({:x => 3}, [:x, :y], :missing=>:skip)
1171
- @o1.values.must_equal(:x => 3)
1172
- @o1.set_fields({"x" => 4}, [:x, :y], :missing=>:skip)
1173
- @o1.values.must_equal(:x => 4)
1174
- @o1.set_fields(Hash.new(2).merge(:x=>2), [:x, :y], :missing=>:skip)
1175
- @o1.values.must_equal(:x => 2)
1176
- @o1.set_fields({:x => 1, :y => 2, :z=>3, :id=>4}, [:x, :y], :missing=>:skip)
1177
- @o1.values.must_equal(:x => 1, :y => 2)
1178
- end
1179
-
1180
- it "should raise for missing fields if :missing=>:raise option is used" do
1181
- proc{@o1.set_fields({:x => 1}, [:x, :y], :missing=>:raise)}.must_raise(Sequel::Error)
1182
- proc{@o1.set_fields(Hash.new(2).merge(:x=>2), [:x, :y], :missing=>:raise)}.must_raise(Sequel::Error)
1183
- proc{@o1.set_fields({"x" => 1}, [:x, :y], :missing=>:raise)}.must_raise(Sequel::Error)
1184
- @o1.set_fields({:x => 5, "y"=>2}, [:x, :y], :missing=>:raise)
1185
- @o1.values.must_equal(:x => 5, :y => 2)
1186
- @o1.set_fields({:x => 1, :y => 3, :z=>3, :id=>4}, [:x, :y], :missing=>:raise)
1187
- @o1.values.must_equal(:x => 1, :y => 3)
1188
- end
1189
-
1190
- it "should use default behavior for an unrecognized :missing option" do
1191
- @o1.set_fields({:x => 1, :y => 2, :z=>3, :id=>4}, [:x, :y], :missing=>:foo)
1192
- @o1.values.must_equal(:x => 1, :y => 2)
1193
- @o1.set_fields({:x => 9, :y => 8, :z=>6, :id=>7}, [:x, :y, :id], :missing=>:foo)
1194
- @o1.values.must_equal(:x => 9, :y => 8, :id=>7)
1195
- DB.sqls.must_equal []
1196
- end
1197
-
1198
- it "should respect model's default_set_fields_options" do
1199
- @c.default_set_fields_options = {:missing=>:skip}
1200
- @o1.set_fields({:x => 3}, [:x, :y])
1201
- @o1.values.must_equal(:x => 3)
1202
- @o1.set_fields({:x => 4}, [:x, :y], {})
1203
- @o1.values.must_equal(:x => 4)
1204
- proc{@o1.set_fields({:x => 3}, [:x, :y], :missing=>:raise)}.must_raise(Sequel::Error)
1205
- @c.default_set_fields_options = {:missing=>:raise}
1206
- proc{@o1.set_fields({:x => 3}, [:x, :y])}.must_raise(Sequel::Error)
1207
- proc{@o1.set_fields({:x => 3}, [:x, :y], {})}.must_raise(Sequel::Error)
1208
- @o1.set_fields({:x => 5}, [:x, :y], :missing=>:skip)
1209
- @o1.values.must_equal(:x => 5)
1210
- @o1.set_fields({:x => 5}, [:x, :y], :missing=>nil)
1211
- @o1.values.must_equal(:x => 5, :y=>nil)
1212
- DB.sqls.must_equal []
1213
- end
1214
-
1215
- it "should respect model's default_set_fields_options in a subclass" do
1216
- @c.default_set_fields_options = {:missing=>:skip}
1217
- o = Class.new(@c).new
1218
- o.set_fields({:x => 3}, [:x, :y])
1219
- o.values.must_equal(:x => 3)
1220
- end
1221
-
1222
- it "should respect set_column_value" do
1223
- @c.class_eval do
1224
- def set_column_value(c, v)
1225
- if c.to_s == 'model='
1226
- self[:model] = v
1227
- else
1228
- send(c, v)
1229
- end
1230
- end
1231
- end
1232
- @o1.set_fields({:model=>2, :x=>3}, [:model, :x])
1233
- @o1[:model].must_equal 2
1234
- @o1.x.must_equal 3
1235
- end
1236
- end
1237
-
1238
- describe Sequel::Model, "#update_fields" do
1239
- before do
1240
- @c = Class.new(Sequel::Model(:items)) do
1241
- set_primary_key :id
1242
- columns :x, :y, :z, :id
1243
- end
1244
- @c.strict_param_setting = true
1245
- @o1 = @c.load(:id=>1)
1246
- DB.reset
1247
- end
1248
-
1249
- it "should set only the given fields, and then save the changes to the record" do
1250
- @o1.update_fields({:x => 1, :y => 2, :z=>3, :id=>4}, [:x, :y])
1251
- @o1.values.must_equal(:x => 1, :y => 2, :id=>1)
1252
- DB.sqls.must_equal ['UPDATE items SET x = 1, y = 2 WHERE (id = 1)']
1253
-
1254
- @o1.update_fields({:x => 1, :y => 5, :z=>6, :id=>7}, [:x, :y])
1255
- @o1.values.must_equal(:x => 1, :y => 5, :id=>1)
1256
- DB.sqls.must_equal ["UPDATE items SET y = 5 WHERE (id = 1)"]
1257
- end
1258
-
1259
- it "should support :missing=>:skip option" do
1260
- @o1.update_fields({:x => 1, :z=>3, :id=>4}, [:x, :y], :missing=>:skip)
1261
- @o1.values.must_equal(:x => 1, :id=>1)
1262
- DB.sqls.must_equal ["UPDATE items SET x = 1 WHERE (id = 1)"]
1263
- end
1264
-
1265
- it "should support :missing=>:raise option" do
1266
- proc{@o1.update_fields({:x => 1}, [:x, :y], :missing=>:raise)}.must_raise(Sequel::Error)
1267
- end
1268
-
1269
- it "should respect model's default_set_fields_options" do
1270
- @c.default_set_fields_options = {:missing=>:skip}
1271
- @o1.update_fields({:x => 3}, [:x, :y])
1272
- @o1.values.must_equal(:x => 3, :id=>1)
1273
- DB.sqls.must_equal ["UPDATE items SET x = 3 WHERE (id = 1)"]
1274
-
1275
- @c.default_set_fields_options = {:missing=>:raise}
1276
- proc{@o1.update_fields({:x => 3}, [:x, :y])}.must_raise(Sequel::Error)
1277
- DB.sqls.must_equal []
1278
- end
1279
- end
1280
-
1281
- describe Sequel::Model, "#destroy with filtered dataset" do
1282
- before do
1283
- @model = Class.new(Sequel::Model(DB[:items].where(:a=>1)))
1284
- @model.columns :id, :a
1285
- @instance = @model.load(:id => 1234)
1286
- DB.reset
1287
- end
1288
-
1289
- it "should raise a NoExistingObject exception if the dataset delete call doesn't return 1" do
1290
- i = 0
1291
- @model.dataset = @model.dataset.with_extend{define_method(:execute_dui){|*| i}}
1292
- proc{@instance.delete}.must_raise(Sequel::NoExistingObject)
1293
- i = 2
1294
- proc{@instance.delete}.must_raise(Sequel::NoExistingObject)
1295
- i = 1
1296
- @instance.delete
1297
-
1298
- @instance.require_modification = false
1299
- i = 0
1300
- @instance.delete
1301
- i = 2
1302
- @instance.delete
1303
- end
1304
-
1305
- it "should include WHERE clause when deleting" do
1306
- @instance.destroy
1307
- DB.sqls.must_equal ["DELETE FROM items WHERE ((a = 1) AND (id = 1234))"]
1308
- end
1309
- end
1310
-
1311
- describe Sequel::Model, "#destroy" do
1312
- before do
1313
- @model = Class.new(Sequel::Model(:items))
1314
- @model.columns :id
1315
- @instance = @model.load(:id => 1234)
1316
- DB.reset
1317
- end
1318
-
1319
- it "should return self" do
1320
- @model.send(:define_method, :after_destroy){3}
1321
- @instance.destroy.must_equal @instance
1322
- end
1323
-
1324
- it "should raise a NoExistingObject exception if the dataset delete call doesn't return 1" do
1325
- i = 0
1326
- @model.dataset = @model.dataset.with_extend{define_method(:execute_dui){|*| i}}
1327
- proc{@instance.delete}.must_raise(Sequel::NoExistingObject)
1328
- i = 2
1329
- proc{@instance.delete}.must_raise(Sequel::NoExistingObject)
1330
- i = 1
1331
- @instance.delete
1332
-
1333
- @instance.require_modification = false
1334
- i = 0
1335
- @instance.delete
1336
- i = 2
1337
- @instance.delete
1338
- end
1339
-
1340
- it "should run within a transaction if use_transactions is true" do
1341
- @instance.use_transactions = true
1342
- @instance.destroy
1343
- DB.sqls.must_equal ["BEGIN", "DELETE FROM items WHERE id = 1234", "COMMIT"]
1344
- end
1345
-
1346
- it "should not run within a transaction if use_transactions is false" do
1347
- @instance.use_transactions = false
1348
- @instance.destroy
1349
- DB.sqls.must_equal ["DELETE FROM items WHERE id = 1234"]
1350
- end
1351
-
1352
- it "should run within a transaction if :transaction option is true" do
1353
- @instance.use_transactions = false
1354
- @instance.destroy(:transaction => true)
1355
- DB.sqls.must_equal ["BEGIN", "DELETE FROM items WHERE id = 1234", "COMMIT"]
1356
- end
1357
-
1358
- it "should not run within a transaction if :transaction option is false" do
1359
- @instance.use_transactions = true
1360
- @instance.destroy(:transaction => false)
1361
- DB.sqls.must_equal ["DELETE FROM items WHERE id = 1234"]
1362
- end
1363
-
1364
- it "should run before_destroy and after_destroy hooks" do
1365
- @model.send(:define_method, :before_destroy){DB.execute('before blah')}
1366
- @model.send(:define_method, :after_destroy){DB.execute('after blah')}
1367
- @instance.destroy
1368
- DB.sqls.must_equal ["before blah", "DELETE FROM items WHERE id = 1234", "after blah"]
1369
- end
1370
- end
1371
-
1372
- describe Sequel::Model, "#exists?" do
1373
- before do
1374
- @model = Class.new(Sequel::Model(:items))
1375
- @model.dataset = @model.dataset.with_fetch(proc{|sql| {:x=>1} if sql =~ /id = 1/})
1376
- DB.reset
1377
- end
1378
-
1379
- it "should do a query to check if the record exists" do
1380
- @model.load(:id=>1).exists?.must_equal true
1381
- DB.sqls.must_equal ['SELECT 1 AS one FROM items WHERE (id = 1) LIMIT 1']
1382
- end
1383
-
1384
- it "should return false when #this.count == 0" do
1385
- @model.load(:id=>2).exists?.must_equal false
1386
- DB.sqls.must_equal ['SELECT 1 AS one FROM items WHERE (id = 2) LIMIT 1']
1387
- end
1388
-
1389
- it "should return false without issuing a query if the model object is new" do
1390
- @model.new.exists?.must_equal false
1391
- DB.sqls.must_equal []
1392
- end
1393
- end
1394
-
1395
- describe Sequel::Model, "#each" do
1396
- before do
1397
- @model = Class.new(Sequel::Model(:items))
1398
- @model.columns :a, :b, :id
1399
- @m = @model.load(:a => 1, :b => 2, :id => 4444)
1400
- end
1401
-
1402
- it "should iterate over the values" do
1403
- h = {}
1404
- @m.each{|k, v| h[k] = v}
1405
- h.must_equal(:a => 1, :b => 2, :id => 4444)
1406
- end
1407
- end
1408
-
1409
- describe Sequel::Model, "#keys" do
1410
- before do
1411
- @model = Class.new(Sequel::Model(:items))
1412
- @model.columns :a, :b, :id
1413
- @m = @model.load(:a => 1, :b => 2, :id => 4444)
1414
- end
1415
-
1416
- it "should return the value keys" do
1417
- @m.keys.sort_by{|k| k.to_s}.must_equal [:a, :b, :id]
1418
- @model.new.keys.must_equal []
1419
- end
1420
- end
1421
-
1422
- describe Sequel::Model, "#==" do
1423
- it "should compare instances by values" do
1424
- z = Class.new(Sequel::Model)
1425
- z.columns :id, :x
1426
- a = z.load(:id => 1, :x => 3)
1427
- b = z.load(:id => 1, :x => 4)
1428
- c = z.load(:id => 1, :x => 3)
1429
-
1430
- a.wont_equal b
1431
- a.must_equal c
1432
- b.wont_equal c
1433
- end
1434
-
1435
- it "should be aliased to #eql?" do
1436
- z = Class.new(Sequel::Model)
1437
- z.columns :id, :x
1438
- a = z.load(:id => 1, :x => 3)
1439
- b = z.load(:id => 1, :x => 4)
1440
- c = z.load(:id => 1, :x => 3)
1441
-
1442
- a.eql?(b).must_equal false
1443
- a.eql?(c).must_equal true
1444
- b.eql?(c).must_equal false
1445
- end
1446
- end
1447
-
1448
- [:===, :pk_equal?].each do |method_name|
1449
- describe Sequel::Model, "##{method_name}" do
1450
- it "should compare instances by class and pk if pk is not nil" do
1451
- z = Class.new(Sequel::Model)
1452
- z.columns :id, :x
1453
- y = Class.new(Sequel::Model)
1454
- y.columns :id, :x
1455
- a = z.load(:id => 1, :x => 3)
1456
- b = z.load(:id => 1, :x => 4)
1457
- c = z.load(:id => 2, :x => 3)
1458
- d = y.load(:id => 1, :x => 3)
1459
-
1460
- a.must_be method_name, b
1461
- a.wont_be method_name, c
1462
- a.wont_be method_name, d
1463
- end
1464
-
1465
- it "should always be false if the primary key is nil" do
1466
- z = Class.new(Sequel::Model)
1467
- z.columns :id, :x
1468
- y = Class.new(Sequel::Model)
1469
- y.columns :id, :x
1470
- a = z.new(:x => 3)
1471
- b = z.new(:x => 4)
1472
- c = z.new(:x => 3)
1473
- d = y.new(:x => 3)
1474
-
1475
- a.wont_be method_name, b
1476
- a.wont_be method_name, c
1477
- a.wont_be method_name, d
1478
- end
1479
-
1480
- it "should always be false if the primary key is an array containing nil" do
1481
- z = Class.new(Sequel::Model)
1482
- z.columns :id, :x
1483
- z.set_primary_key [:id, :x]
1484
- z.load(:id => nil, :x => nil).wont_be method_name, z.load(:id => nil, :x => nil)
1485
- z.load(:id => 1, :x => nil).wont_be method_name, z.load(:id => 1, :x => nil)
1486
- z.load(:id => nil, :x => 2).wont_be method_name, z.load(:id => nil, :x => 2)
1487
- end
1488
- end
1489
- end
1490
-
1491
- describe Sequel::Model, "#hash" do
1492
- it "should be the same only for objects with the same class and pk if the pk is not nil" do
1493
- z = Class.new(Sequel::Model)
1494
- z.columns :id, :x
1495
- y = Class.new(Sequel::Model)
1496
- y.columns :id, :x
1497
- a = z.load(:id => 1, :x => 3)
1498
-
1499
- a.hash.must_equal z.load(:id => 1, :x => 4).hash
1500
- a.hash.wont_equal z.load(:id => 2, :x => 3).hash
1501
- a.hash.wont_equal y.load(:id => 1, :x => 3).hash
1502
- end
1503
-
1504
- it "should be the same only for objects with the same class and values if the pk is nil" do
1505
- z = Class.new(Sequel::Model)
1506
- z.columns :id, :x
1507
- y = Class.new(Sequel::Model)
1508
- y.columns :id, :x
1509
- a = z.new(:x => 3)
1510
-
1511
- a.hash.wont_equal z.new(:x => 4).hash
1512
- a.hash.must_equal z.new(:x => 3).hash
1513
- a.hash.wont_equal y.new(:x => 3).hash
1514
- end
1515
-
1516
- it "should be the same only for objects with the same class and pk if pk is composite and all values are non-NULL" do
1517
- z = Class.new(Sequel::Model)
1518
- z.columns :id, :id2, :x
1519
- z.set_primary_key([:id, :id2])
1520
- y = Class.new(Sequel::Model)
1521
- y.columns :id, :id2, :x
1522
- y.set_primary_key([:id, :id2])
1523
- a = z.load(:id => 1, :id2=>2, :x => 3)
1524
-
1525
- a.hash.must_equal z.load(:id => 1, :id2=>2, :x => 4).hash
1526
- a.hash.wont_equal z.load(:id => 2, :id2=>1, :x => 3).hash
1527
- a.hash.wont_equal y.load(:id => 1, :id2=>1, :x => 3).hash
1528
- end
1529
-
1530
- it "should be the same only for objects with the same class and value if pk is composite and one values is NULL" do
1531
- z = Class.new(Sequel::Model)
1532
- z.columns :id, :id2, :x
1533
- z.set_primary_key([:id, :id2])
1534
- y = Class.new(Sequel::Model)
1535
- y.columns :id, :id2, :x
1536
- y.set_primary_key([:id, :id2])
1537
-
1538
- a = z.load(:id => 1, :id2 => nil, :x => 3)
1539
- a.hash.must_equal z.load(:id => 1, :id2=>nil, :x => 3).hash
1540
- a.hash.wont_equal z.load(:id => 1, :id2=>nil, :x => 4).hash
1541
- a.hash.wont_equal y.load(:id => 1, :id2=>nil, :x => 3).hash
1542
-
1543
- a = z.load(:id =>nil, :id2 => nil, :x => 3)
1544
- a.hash.must_equal z.load(:id => nil, :id2=>nil, :x => 3).hash
1545
- a.hash.wont_equal z.load(:id => nil, :id2=>nil, :x => 4).hash
1546
- a.hash.wont_equal y.load(:id => nil, :id2=>nil, :x => 3).hash
1547
-
1548
- a = z.load(:id => 1, :x => 3)
1549
- a.hash.must_equal z.load(:id => 1, :x => 3).hash
1550
- a.hash.wont_equal z.load(:id => 1, :id2=>nil, :x => 3).hash
1551
- a.hash.wont_equal z.load(:id => 1, :x => 4).hash
1552
- a.hash.wont_equal y.load(:id => 1, :x => 3).hash
1553
-
1554
- a = z.load(:x => 3)
1555
- a.hash.must_equal z.load(:x => 3).hash
1556
- a.hash.wont_equal z.load(:id => nil, :id2=>nil, :x => 3).hash
1557
- a.hash.wont_equal z.load(:x => 4).hash
1558
- a.hash.wont_equal y.load(:x => 3).hash
1559
- end
1560
-
1561
- it "should be the same only for objects with the same class and values if the no primary key" do
1562
- z = Class.new(Sequel::Model)
1563
- z.columns :id, :x
1564
- z.no_primary_key
1565
- y = Class.new(Sequel::Model)
1566
- y.columns :id, :x
1567
- y.no_primary_key
1568
- a = z.new(:x => 3)
1569
-
1570
- a.hash.wont_equal z.new(:x => 4).hash
1571
- a.hash.must_equal z.new(:x => 3).hash
1572
- a.hash.wont_equal y.new(:x => 3).hash
1573
- end
1574
-
1575
- end
1576
-
1577
- describe Sequel::Model, "#initialize" do
1578
- before do
1579
- @c = Class.new(Sequel::Model) do
1580
- columns :id, :x
1581
- end
1582
- @c.strict_param_setting = false
1583
- end
1584
-
1585
- it "should accept values" do
1586
- m = @c.new(:x => 2)
1587
- m.values.must_equal(:x => 2)
1588
- end
1589
-
1590
- it "should not modify the primary key" do
1591
- m = @c.new(:id => 1, :x => 2)
1592
- m.values.must_equal(:x => 2)
1593
- end
1594
-
1595
- it "should accept no values" do
1596
- m = @c.new
1597
- m.values.must_equal({})
1598
- end
1599
-
1600
- it "should accept a block to execute" do
1601
- m = @c.new {|o| o[:id] = 1234}
1602
- m.id.must_equal 1234
1603
- end
1604
-
1605
- it "should accept virtual attributes" do
1606
- @c.send(:define_method, :blah=){|x| @blah = x}
1607
- @c.send(:define_method, :blah){@blah}
1608
-
1609
- m = @c.new(:x => 2, :blah => 3)
1610
- m.values.must_equal(:x => 2)
1611
- m.blah.must_equal 3
1612
- end
1613
-
1614
- it "should convert string keys into symbol keys" do
1615
- m = @c.new('x' => 2)
1616
- m.values.must_equal(:x => 2)
1617
- end
1618
- end
1619
-
1620
- describe Sequel::Model, "#initialize_set" do
1621
- before do
1622
- @c = Class.new(Sequel::Model){columns :id, :x, :y}
1623
- end
1624
-
1625
- it "should be called by initialize to set the column values" do
1626
- @c.send(:define_method, :initialize_set){|h| set(:y => 3)}
1627
- @c.new(:x => 2).values.must_equal(:y => 3)
1628
- end
1629
-
1630
- it "should be called with the hash given to initialize " do
1631
- x = nil
1632
- @c.send(:define_method, :initialize_set){|y| x = y}
1633
- @c.new(:x => 2)
1634
- x.must_equal(:x => 2)
1635
- end
1636
-
1637
- it "should not cause columns modified by the method to be considered as changed" do
1638
- @c.send(:define_method, :initialize_set){|h| set(:y => 3)}
1639
- @c.new(:x => 2).changed_columns.must_equal []
1640
- end
1641
- end
1642
-
1643
- describe Sequel::Model, ".create" do
1644
- before do
1645
- DB.reset
1646
- @c = Class.new(Sequel::Model(:items)) do
1647
- unrestrict_primary_key
1648
- columns :x
1649
- end
1650
- end
1651
-
1652
- it "should be able to create rows in the associated table" do
1653
- o = @c.create(:x => 1)
1654
- o.class.must_equal @c
1655
- DB.sqls.must_equal ['INSERT INTO items (x) VALUES (1)', "SELECT * FROM items WHERE id = 10"]
1656
- end
1657
-
1658
- it "should be able to create rows without any values specified" do
1659
- o = @c.create
1660
- o.class.must_equal @c
1661
- DB.sqls.must_equal ["INSERT INTO items DEFAULT VALUES", "SELECT * FROM items WHERE id = 10"]
1662
- end
1663
-
1664
- it "should accept a block and call it" do
1665
- o1, o2, o3 = nil, nil, nil
1666
- o = @c.create {|o4| o1 = o4; o3 = o4; o2 = :blah; o3.x = 333}
1667
- o.class.must_equal @c
1668
- o1.must_be :===, o
1669
- o3.must_be :===, o
1670
- o2.must_equal :blah
1671
- DB.sqls.must_equal ["INSERT INTO items (x) VALUES (333)", "SELECT * FROM items WHERE id = 10"]
1672
- end
1673
-
1674
- it "should create a row for a model with custom primary key" do
1675
- @c.set_primary_key :x
1676
- o = @c.create(:x => 30)
1677
- o.class.must_equal @c
1678
- DB.sqls.must_equal ["INSERT INTO items (x) VALUES (30)", "SELECT * FROM items WHERE x = 30"]
1679
- end
1680
- end
1681
-
1682
- describe Sequel::Model, "#refresh" do
1683
- before do
1684
- @c = Class.new(Sequel::Model(:items)) do
1685
- unrestrict_primary_key
1686
- columns :id, :x
1687
- end
1688
- DB.reset
1689
- end
1690
-
1691
- it "should reload the instance values from the database" do
1692
- @m = @c.new(:id => 555)
1693
- @m[:x] = 'blah'
1694
- @c.dataset = @c.dataset.with_fetch(:x => 'kaboom', :id => 555)
1695
- @m.refresh
1696
- @m[:x].must_equal 'kaboom'
1697
- DB.sqls.must_equal ["SELECT * FROM items WHERE id = 555"]
1698
- end
1699
-
1700
- it "should raise if the instance is not found" do
1701
- @m = @c.new(:id => 555)
1702
- @c.dataset = @c.dataset.with_fetch([])
1703
- proc {@m.refresh}.must_raise(Sequel::NoExistingObject)
1704
- DB.sqls.must_equal ["SELECT * FROM items WHERE id = 555"]
1705
- end
1706
-
1707
- it "should be aliased by #reload" do
1708
- @m = @c.new(:id => 555)
1709
- @c.dataset = @c.dataset.with_fetch(:x => 'kaboom', :id => 555)
1710
- @m.reload
1711
- @m[:x].must_equal 'kaboom'
1712
- DB.sqls.must_equal ["SELECT * FROM items WHERE id = 555"]
1713
- end
1714
- end
1715
-
1716
- describe Sequel::Model, "typecasting" do
1717
- before do
1718
- @c = Class.new(Sequel::Model(:items)) do
1719
- columns :x
1720
- end
1721
- @c.db_schema = {:x=>{:type=>:integer}}
1722
- @c.raise_on_typecast_failure = true
1723
- DB.reset
1724
- end
1725
-
1726
- after do
1727
- Sequel.datetime_class = Time
1728
- end
1729
-
1730
- it "should not convert if typecasting is turned off" do
1731
- @c.typecast_on_assignment = false
1732
- m = @c.new
1733
- m.x = '1'
1734
- m.x.must_equal '1'
1735
- end
1736
-
1737
- it "should convert to integer for an integer field" do
1738
- @c.db_schema = {:x=>{:type=>:integer}}
1739
- m = @c.new
1740
- m.x = '1'
1741
- m.x.must_equal 1
1742
- m.x = 1
1743
- m.x.must_equal 1
1744
- m.x = 1.3
1745
- m.x.must_equal 1
1746
- end
1747
-
1748
- it "should typecast '' to nil unless type is string or blob" do
1749
- [:integer, :float, :decimal, :boolean, :date, :time, :datetime].each do |x|
1750
- @c.db_schema = {:x=>{:type=>x}}
1751
- m = @c.new
1752
- m.x = ''
1753
- m.x.must_be_nil
1754
- end
1755
- [:string, :blob].each do |x|
1756
- @c.db_schema = {:x=>{:type=>x}}
1757
- m = @c.new
1758
- m.x = ''
1759
- m.x.must_equal ''
1760
- end
1761
- end
1762
-
1763
- it "should not typecast '' to nil if typecast_empty_string_to_nil is false" do
1764
- m = @c.new
1765
- m.typecast_empty_string_to_nil = false
1766
- proc{m.x = ''}.must_raise Sequel::InvalidValue
1767
- @c.typecast_empty_string_to_nil = false
1768
- proc{@c.new.x = ''}.must_raise Sequel::InvalidValue
1769
- end
1770
-
1771
- it "should handle typecasting where == raises an error on the object" do
1772
- m = @c.new
1773
- o = Object.new
1774
- def o.==(v) raise ArgumentError end
1775
- def o.to_i() 4 end
1776
- m.x = o
1777
- m.x.must_equal 4
1778
- end
1779
-
1780
- it "should not typecast nil if NULLs are allowed" do
1781
- @c.db_schema[:x][:allow_null] = true
1782
- m = @c.new
1783
- m.x = nil
1784
- m.x.must_be_nil
1785
- end
1786
-
1787
- it "should raise an error if attempting to typecast nil and NULLs are not allowed" do
1788
- @c.db_schema[:x][:allow_null] = false
1789
- proc{@c.new.x = nil}.must_raise(Sequel::InvalidValue)
1790
- proc{@c.new.x = ''}.must_raise(Sequel::InvalidValue)
1791
- end
1792
-
1793
- it "should not raise an error if NULLs are not allowed and typecasting is turned off" do
1794
- @c.typecast_on_assignment = false
1795
- @c.db_schema[:x][:allow_null] = false
1796
- m = @c.new
1797
- m.x = nil
1798
- m.x.must_be_nil
1799
- end
1800
-
1801
- it "should not raise when typecasting nil to NOT NULL column but raise_on_typecast_failure is off" do
1802
- @c.raise_on_typecast_failure = false
1803
- @c.typecast_on_assignment = true
1804
- m = @c.new
1805
- m.x = ''
1806
- m.x.must_be_nil
1807
- m.x = nil
1808
- m.x.must_be_nil
1809
- end
1810
-
1811
- it "should raise an error if invalid data is used in an integer field" do
1812
- proc{@c.new.x = 'a'}.must_raise(Sequel::InvalidValue)
1813
- end
1814
-
1815
- it "should assign value if raise_on_typecast_failure is off and assigning invalid integer" do
1816
- @c.raise_on_typecast_failure = false
1817
- model = @c.new
1818
- model.x = '1d'
1819
- model.x.must_equal '1d'
1820
- end
1821
-
1822
- it "should convert to float for a float field" do
1823
- @c.db_schema = {:x=>{:type=>:float}}
1824
- m = @c.new
1825
- m.x = '1.3'
1826
- m.x.must_equal 1.3
1827
- m.x = 1
1828
- m.x.must_equal 1.0
1829
- m.x = 1.3
1830
- m.x.must_equal 1.3
1831
- end
1832
-
1833
- it "should raise an error if invalid data is used in an float field" do
1834
- @c.db_schema = {:x=>{:type=>:float}}
1835
- proc{@c.new.x = 'a'}.must_raise(Sequel::InvalidValue)
1836
- end
1837
-
1838
- it "should assign value if raise_on_typecast_failure is off and assigning invalid float" do
1839
- @c.raise_on_typecast_failure = false
1840
- @c.db_schema = {:x=>{:type=>:float}}
1841
- model = @c.new
1842
- model.x = '1d'
1843
- model.x.must_equal '1d'
1844
- end
1845
-
1846
- it "should convert to BigDecimal for a decimal field" do
1847
- @c.db_schema = {:x=>{:type=>:decimal}}
1848
- m = @c.new
1849
- bd = BigDecimal('1.0')
1850
- m.x = '1.0'
1851
- m.x.must_equal bd
1852
- m.x = 1.0
1853
- m.x.must_equal bd
1854
- m.x = 1
1855
- m.x.must_equal bd
1856
- m.x = bd
1857
- m.x.must_equal bd
1858
- m.x = '0'
1859
- m.x.must_equal 0
1860
- end
1861
-
1862
- it "should raise an error if invalid data is used in an decimal field" do
1863
- @c.db_schema = {:x=>{:type=>:decimal}}
1864
- proc{@c.new.x = Date.today}.must_raise(Sequel::InvalidValue)
1865
- proc{@c.new.x = 'foo'}.must_raise(Sequel::InvalidValue)
1866
- end
1867
-
1868
- it "should assign value if raise_on_typecast_failure is off and assigning invalid decimal" do
1869
- @c.raise_on_typecast_failure = false
1870
- @c.db_schema = {:x=>{:type=>:decimal}}
1871
- model = @c.new
1872
- time = Time.now
1873
- model.x = time
1874
- model.x.must_equal time
1875
- end
1876
-
1877
- it "should convert to string for a string field" do
1878
- @c.db_schema = {:x=>{:type=>:string}}
1879
- m = @c.new
1880
- m.x = '1.3'
1881
- m.x.must_equal '1.3'
1882
- m.x = 1
1883
- m.x.must_equal '1'
1884
- m.x = 1.3
1885
- m.x.must_equal '1.3'
1886
- end
1887
-
1888
- it "should convert to boolean for a boolean field" do
1889
- @c.db_schema = {:x=>{:type=>:boolean}}
1890
- m = @c.new
1891
- m.x = '1.3'
1892
- m.x.must_equal true
1893
- m.x = 1
1894
- m.x.must_equal true
1895
- m.x = 1.3
1896
- m.x.must_equal true
1897
- m.x = 't'
1898
- m.x.must_equal true
1899
- m.x = 'T'
1900
- m.x.must_equal true
1901
- m.x = 'y'
1902
- m.x.must_equal true
1903
- m.x = 'Y'
1904
- m.x.must_equal true
1905
- m.x = true
1906
- m.x.must_equal true
1907
- m.x = nil
1908
- m.x.must_be_nil
1909
- m.x = ''
1910
- m.x.must_be_nil
1911
- m.x = []
1912
- m.x.must_be_nil
1913
- m.x = 'f'
1914
- m.x.must_equal false
1915
- m.x = 'F'
1916
- m.x.must_equal false
1917
- m.x = 'false'
1918
- m.x.must_equal false
1919
- m.x = 'FALSE'
1920
- m.x.must_equal false
1921
- m.x = 'n'
1922
- m.x.must_equal false
1923
- m.x = 'N'
1924
- m.x.must_equal false
1925
- m.x = 'no'
1926
- m.x.must_equal false
1927
- m.x = 'NO'
1928
- m.x.must_equal false
1929
- m.x = '0'
1930
- m.x.must_equal false
1931
- m.x = 0
1932
- m.x.must_equal false
1933
- m.x = false
1934
- m.x.must_equal false
1935
- end
1936
-
1937
- it "should convert to date for a date field" do
1938
- @c.db_schema = {:x=>{:type=>:date}}
1939
- m = @c.new
1940
- y = Date.new(2007,10,21)
1941
- m.x = '2007-10-21'
1942
- m.x.must_equal y
1943
- m.x = Date.parse('2007-10-21')
1944
- m.x.must_equal y
1945
- m.x = Time.parse('2007-10-21')
1946
- m.x.must_equal y
1947
- m.x = DateTime.parse('2007-10-21')
1948
- m.x.must_equal y
1949
- end
1950
-
1951
- it "should accept a hash with symbol or string keys for a date field" do
1952
- @c.db_schema = {:x=>{:type=>:date}}
1953
- m = @c.new
1954
- y = Date.new(2007,10,21)
1955
- m.x = {:year=>2007, :month=>10, :day=>21}
1956
- m.x.must_equal y
1957
- m.x = {'year'=>'2007', 'month'=>'10', 'day'=>'21'}
1958
- m.x.must_equal y
1959
- end
1960
-
1961
- it "should raise an error if invalid data is used in a date field" do
1962
- @c.db_schema = {:x=>{:type=>:date}}
1963
- proc{@c.new.x = 'a'}.must_raise(Sequel::InvalidValue)
1964
- proc{@c.new.x = 100}.must_raise(Sequel::InvalidValue)
1965
- end
1966
-
1967
- it "should assign value if raise_on_typecast_failure is off and assigning invalid date" do
1968
- @c.raise_on_typecast_failure = false
1969
- @c.db_schema = {:x=>{:type=>:date}}
1970
- model = @c.new
1971
- model.x = 4
1972
- model.x.must_equal 4
1973
- end
1974
-
1975
- it "should convert to Sequel::SQLTime for a time field" do
1976
- @c.db_schema = {:x=>{:type=>:time}}
1977
- m = @c.new
1978
- x = '10:20:30'
1979
- y = Sequel::SQLTime.parse(x)
1980
- m.x = x
1981
- m.x.must_equal y
1982
- m.x = y
1983
- m.x.must_equal y
1984
- m.x.must_be_kind_of(Sequel::SQLTime)
1985
- end
1986
-
1987
- it "should accept a hash with symbol or string keys for a time field" do
1988
- @c.db_schema = {:x=>{:type=>:time}}
1989
- m = @c.new
1990
- y = Time.parse('10:20:30')
1991
- m.x = {:hour=>10, :minute=>20, :second=>30}
1992
- m.x.must_equal y
1993
- m.x = {'hour'=>'10', 'minute'=>'20', 'second'=>'30'}
1994
- m.x.must_equal y
1995
- end
1996
-
1997
- it "should raise an error if invalid data is used in a time field" do
1998
- @c.db_schema = {:x=>{:type=>:time}}
1999
- proc{@c.new.x = '0000'}.must_raise(Sequel::InvalidValue)
2000
- proc{@c.new.x = Date.parse('2008-10-21')}.must_raise(Sequel::InvalidValue)
2001
- proc{@c.new.x = DateTime.parse('2008-10-21')}.must_raise(Sequel::InvalidValue)
2002
- end
2003
-
2004
- it "should assign value if raise_on_typecast_failure is off and assigning invalid time" do
2005
- @c.raise_on_typecast_failure = false
2006
- @c.db_schema = {:x=>{:type=>:time}}
2007
- model = @c.new
2008
- model.x = '0000'
2009
- model.x.must_equal '0000'
2010
- end
2011
-
2012
- it "should convert to the Sequel.datetime_class for a datetime field" do
2013
- @c.db_schema = {:x=>{:type=>:datetime}}
2014
- m = @c.new
2015
- x = '2007-10-21T10:20:30-07:00'
2016
- y = Time.parse(x)
2017
- m.x = x
2018
- m.x.must_equal y
2019
- m.x = DateTime.parse(x)
2020
- m.x.must_equal y
2021
- m.x = Time.parse(x)
2022
- m.x.must_equal y
2023
- m.x = Date.parse('2007-10-21')
2024
- m.x.must_equal Time.parse('2007-10-21')
2025
- Sequel.datetime_class = DateTime
2026
- y = DateTime.parse(x)
2027
- m.x = x
2028
- m.x.must_equal y
2029
- m.x = DateTime.parse(x)
2030
- m.x.must_equal y
2031
- m.x = Time.parse(x)
2032
- m.x.must_equal y
2033
- m.x = Date.parse('2007-10-21')
2034
- m.x.must_equal DateTime.parse('2007-10-21')
2035
- end
2036
-
2037
- it "should accept a hash with symbol or string keys for a datetime field" do
2038
- @c.db_schema = {:x=>{:type=>:datetime}}
2039
- m = @c.new
2040
- y = Time.parse('2007-10-21 10:20:30')
2041
- m.x = {:year=>2007, :month=>10, :day=>21, :hour=>10, :minute=>20, :second=>30}
2042
- m.x.must_equal y
2043
- m.x = {'year'=>'2007', 'month'=>'10', 'day'=>'21', 'hour'=>'10', 'minute'=>'20', 'second'=>'30'}
2044
- m.x.must_equal y
2045
- Sequel.datetime_class = DateTime
2046
- y = DateTime.parse('2007-10-21 10:20:30')
2047
- m.x = {:year=>2007, :month=>10, :day=>21, :hour=>10, :minute=>20, :second=>30}
2048
- m.x.must_equal y
2049
- m.x = {'year'=>'2007', 'month'=>'10', 'day'=>'21', 'hour'=>'10', 'minute'=>'20', 'second'=>'30'}
2050
- m.x.must_equal y
2051
- end
2052
-
2053
- it "should raise an error if invalid data is used in a datetime field" do
2054
- @c.db_schema = {:x=>{:type=>:datetime}}
2055
- proc{@c.new.x = '0000'}.must_raise(Sequel::InvalidValue)
2056
- Sequel.datetime_class = DateTime
2057
- proc{@c.new.x = '0000'}.must_raise(Sequel::InvalidValue)
2058
- proc{@c.new.x = 'a'}.must_raise(Sequel::InvalidValue)
2059
- end
2060
-
2061
- it "should assign value if raise_on_typecast_failure is off and assigning invalid datetime" do
2062
- @c.raise_on_typecast_failure = false
2063
- @c.db_schema = {:x=>{:type=>:datetime}}
2064
- model = @c.new
2065
- model.x = '0000'
2066
- model.x.must_equal '0000'
2067
- Sequel.datetime_class = DateTime
2068
- model = @c.new
2069
- model.x = '0000'
2070
- model.x.must_equal '0000'
2071
- model.x = 'a'
2072
- model.x.must_equal 'a'
2073
- end
2074
- end
2075
-
2076
- describe "Model#lock!" do
2077
- before do
2078
- @c = Class.new(Sequel::Model(:items)) do
2079
- columns :id
2080
- end
2081
- @c.dataset = @c.dataset.with_fetch(:id=>1)
2082
- DB.reset
2083
- end
2084
-
2085
- it "should do nothing if the record is a new record" do
2086
- o = @c.new
2087
- def o._refresh(x) raise Sequel::Error; super(x) end
2088
- x = o.lock!
2089
- x.must_equal o
2090
- DB.sqls.must_equal []
2091
- end
2092
-
2093
- it "should refresh the record using for_update if it is not a new record" do
2094
- o = @c.load(:id => 1)
2095
- def o._refresh(x) instance_variable_set(:@a, 1); super(x) end
2096
- x = o.lock!
2097
- x.must_equal o
2098
- o.instance_variable_get(:@a).must_equal 1
2099
- DB.sqls.must_equal ["SELECT * FROM items WHERE (id = 1) LIMIT 1 FOR UPDATE"]
2100
- end
2101
-
2102
- it "should refresh the record using the specified lock when it is not a new record and a style is given" do
2103
- o = @c.load(:id => 1)
2104
- def o._refresh(x) instance_variable_set(:@a, 1); super(x) end
2105
- x = o.lock!('FOR NO KEY UPDATE')
2106
- x.must_equal o
2107
- o.instance_variable_get(:@a).must_equal 1
2108
- DB.sqls.must_equal ["SELECT * FROM items WHERE (id = 1) LIMIT 1 FOR NO KEY UPDATE"]
2109
- end
2110
- end
2111
-
2112
- describe "Model#schema_type_class" do
2113
- it "should return the class or array of classes for the given type symbol" do
2114
- @c = Class.new(Sequel::Model(:items))
2115
- @c.class_eval{@db_schema = {:id=>{:type=>:integer}}}
2116
- @c.new.send(:schema_type_class, :id).must_equal Integer
2117
- end
2118
- end