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