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
@@ -13,7 +13,7 @@ module Sequel
13
13
  # get the reviews for all of those albums:
14
14
  #
15
15
  # Album.plugin :lazy_attributes, :review
16
- # Album.filter{id<100}.all do |a|
16
+ # Album.where{id < 100}.all do |a|
17
17
  # a.review
18
18
  # end
19
19
  #
@@ -38,9 +38,12 @@ module Sequel
38
38
  end
39
39
 
40
40
  module ClassMethods
41
- # Module to store the lazy attribute getter methods, so they can
42
- # be overridden and call super to get the lazy attribute behavior
43
- attr_accessor :lazy_attributes_module
41
+ # Freeze lazy attributes module when freezing model class.
42
+ def freeze
43
+ @lazy_attributes_module.freeze if @lazy_attributes_module
44
+
45
+ super
46
+ end
44
47
 
45
48
  # Remove the given attributes from the list of columns selected by default.
46
49
  # For each attribute given, create an accessor method that allows a lazy
@@ -49,7 +52,9 @@ module Sequel
49
52
  unless select = dataset.opts[:select]
50
53
  select = dataset.columns.map{|c| Sequel.qualify(dataset.first_source, c)}
51
54
  end
55
+ db_schema = @db_schema
52
56
  set_dataset(dataset.select(*select.reject{|c| attrs.include?(dataset.send(:_hash_key_symbol, c))}))
57
+ @db_schema = db_schema
53
58
  attrs.each{|a| define_lazy_attribute_getter(a)}
54
59
  end
55
60
 
@@ -59,8 +64,8 @@ module Sequel
59
64
  # :dataset :: The base dataset to use for the lazy attribute lookup
60
65
  # :table :: The table name to use to qualify the attribute and primary key columns.
61
66
  def define_lazy_attribute_getter(a, opts=OPTS)
62
- include(self.lazy_attributes_module ||= Module.new) unless lazy_attributes_module
63
- lazy_attributes_module.class_eval do
67
+ include(@lazy_attributes_module ||= Module.new) unless @lazy_attributes_module
68
+ @lazy_attributes_module.class_eval do
64
69
  define_method(a) do
65
70
  if !values.has_key?(a) && !new?
66
71
  lazy_attribute_lookup(a, opts)
@@ -68,6 +73,7 @@ module Sequel
68
73
  super()
69
74
  end
70
75
  end
76
+ alias_method(a, a)
71
77
  end
72
78
  end
73
79
  end
@@ -80,9 +86,8 @@ module Sequel
80
86
  # the attribute for just the current object. Return the value of
81
87
  # the attribute for the current object.
82
88
  def lazy_attribute_lookup(a, opts=OPTS)
83
- unless table = opts[:table]
84
- table = model.table_name
85
- end
89
+ table = opts[:table] || model.table_name
90
+ selection = Sequel.qualify(table, a)
86
91
 
87
92
  if base_ds = opts[:dataset]
88
93
  ds = base_ds.where(qualified_pk_hash(table))
@@ -91,19 +96,21 @@ module Sequel
91
96
  ds = this
92
97
  end
93
98
 
94
- selection = Sequel.qualify(table, a)
95
-
96
99
  if frozen?
97
- return ds.dup.get(selection)
100
+ return ds.get(selection)
98
101
  end
99
102
 
100
103
  if retrieved_with
101
- raise(Error, "Invalid primary key column for #{model}: #{pkc.inspect}") unless primary_key = model.primary_key
104
+ primary_key = model.primary_key
102
105
  composite_pk = true if primary_key.is_a?(Array)
103
106
  id_map = {}
104
107
  retrieved_with.each{|o| id_map[o.pk] = o unless o.values.has_key?(a) || o.frozen?}
105
108
  predicate_key = composite_pk ? primary_key.map{|k| Sequel.qualify(table, k)} : Sequel.qualify(table, primary_key)
106
- base_ds.select(*(Array(primary_key).map{|k| Sequel.qualify(table, k)} + [selection])).where(predicate_key=>id_map.keys).naked.each do |row|
109
+ base_ds.
110
+ select(*(Array(primary_key).map{|k| Sequel.qualify(table, k)} + [selection])).
111
+ where(predicate_key=>id_map.keys).
112
+ naked.
113
+ each do |row|
107
114
  obj = id_map[composite_pk ? row.values_at(*primary_key) : row[primary_key]]
108
115
  if obj && !obj.values.has_key?(a)
109
116
  obj.values[a] = row[a]
@@ -11,7 +11,7 @@ module Sequel
11
11
  #
12
12
  # class Item < Sequel::Model(:items)
13
13
  # plugin :list # will use :position field for position
14
- # plugin :list, :field=>:pos # will use :pos field for position
14
+ # plugin :list, field: :pos # will use :pos field for position
15
15
  # end
16
16
  #
17
17
  # item = Item[1]
@@ -33,39 +33,48 @@ module Sequel
33
33
  # You can provide a <tt>:scope</tt> option to scope the list. This option
34
34
  # can be a symbol or array of symbols specifying column name(s), or a proc
35
35
  # that accepts a model instance and returns a dataset representing the list
36
- # the object is in.
36
+ # the object is in. You will need to provide a <tt>:scope</tt> option if
37
+ # the model's dataset uses a subquery (such as when using the class_table_inheritance
38
+ # plugin).
37
39
  #
38
40
  # For example, if each item has a +user_id+ field, and you want every user
39
41
  # to have their own list:
40
42
  #
41
- # Item.plugin :list, :scope=>:user_id
43
+ # Item.plugin :list, scope: :user_id
42
44
  #
43
45
  # Note that using this plugin modifies the order of the model's dataset to
44
46
  # sort by the position and scope fields. Also note that this plugin is subject to
45
47
  # race conditions, and is not safe when concurrent modifications are made
46
48
  # to the same list.
47
49
  #
48
- # Additionally, note that unlike ruby arrays, the list plugin assumes that the
49
- # first entry in the list has position 1, not position 0.
50
+ # Note that by default, unlike ruby arrays, the list plugin assumes the first
51
+ # entry in the list has position 1, not position 0.
52
+ #
53
+ # You can change this by providing an integer <tt>:top</tt> option:
54
+ #
55
+ # Item.plugin :list, top: 0
50
56
  #
51
57
  # Copyright (c) 2007-2010 Sharon Rosner, Wayne E. Seguin, Aman Gupta, Adrian Madrid, Jeremy Evans
52
58
  module List
53
- # Set the +position_field+ and +scope_proc+ attributes for the model,
54
- # using the <tt>:field</tt> and <tt>:scope</tt> options, respectively.
59
+ # Set the +position_field+, +scope_proc+ and +top_of_list+ attributes for the model,
60
+ # using the <tt>:field</tt>, <tt>:scope</tt>, and <tt>:top</tt> options, respectively.
55
61
  # The <tt>:scope</tt> option can be a symbol, array of symbols, or a proc that
56
62
  # accepts a model instance and returns a dataset representing the list.
57
63
  # Also, modify the model dataset's order to order by the position and scope fields.
58
64
  def self.configure(model, opts = OPTS)
59
65
  model.position_field = opts[:field] || :position
60
66
  model.dataset = model.dataset.order_prepend(model.position_field)
67
+ model.instance_exec do
68
+ @top_of_list = opts[:top] || 1
69
+ end
61
70
 
62
71
  model.scope_proc = case scope = opts[:scope]
63
72
  when Symbol
64
73
  model.dataset = model.dataset.order_prepend(scope)
65
- proc{|obj| obj.model.filter(scope=>obj.send(scope))}
74
+ proc{|obj| obj.model.where(scope=>obj.public_send(scope))}
66
75
  when Array
67
76
  model.dataset = model.dataset.order_prepend(*scope)
68
- proc{|obj| obj.model.filter(scope.map{|s| [s, obj.get_column_value(s)]})}
77
+ proc{|obj| obj.model.where(scope.map{|s| [s, obj.get_column_value(s)]})}
69
78
  else
70
79
  scope
71
80
  end
@@ -80,7 +89,10 @@ module Sequel
80
89
  # proc should accept an instance and return a dataset representing the list.
81
90
  attr_accessor :scope_proc
82
91
 
83
- Plugins.inherited_instance_variables(self, :@position_field=>nil, :@scope_proc=>nil)
92
+ # An Integer to use as the position of the top of the list. Defaults to 1.
93
+ attr_reader :top_of_list
94
+
95
+ Plugins.inherited_instance_variables(self, :@position_field=>nil, :@scope_proc=>nil, :@top_of_list=>nil)
84
96
  end
85
97
 
86
98
  module InstanceMethods
@@ -94,7 +106,7 @@ module Sequel
94
106
  def after_destroy
95
107
  super
96
108
 
97
- f = Sequel.expr(position_field)
109
+ f = Sequel[position_field]
98
110
  list_dataset.where(f > position_value).update(f => f - 1)
99
111
  end
100
112
 
@@ -114,20 +126,22 @@ module Sequel
114
126
  move_to(position_value + n)
115
127
  end
116
128
 
117
- # Move this instance to the given place in the list. Raises an
118
- # exception if target is less than 1 or greater than the last position in the list.
129
+ # Move this instance to the given place in the list. If lp is not
130
+ # given or greater than the last list position, uses the last list
131
+ # position. If lp is less than the top list position, uses the
132
+ # top list position.
119
133
  def move_to(target, lp = nil)
120
134
  current = position_value
121
135
  if target != current
122
136
  checked_transaction do
123
137
  ds = list_dataset
124
138
  op, ds = if target < current
125
- target = 1 if target < 1
126
- [:+, ds.filter(position_field=>target...current)]
139
+ target = model.top_of_list if target < model.top_of_list
140
+ [:+, ds.where(position_field=>target...current)]
127
141
  else
128
142
  lp ||= last_position
129
143
  target = lp if target > lp
130
- [:-, ds.filter(position_field=>(current + 1)..target)]
144
+ [:-, ds.where(position_field=>(current + 1)..target)]
131
145
  end
132
146
  ds.update(position_field => Sequel::SQL::NumericExpression.new(op, position_field, 1))
133
147
  update(position_field => target)
@@ -142,9 +156,9 @@ module Sequel
142
156
  move_to(lp, lp)
143
157
  end
144
158
 
145
- # Move this instance to the top (first position, position 1) of the list.
159
+ # Move this instance to the top (first position, usually position 1) of the list.
146
160
  def move_to_top
147
- move_to(1)
161
+ move_to(model.top_of_list)
148
162
  end
149
163
 
150
164
  # Move this instance the given number of places up in the list, or 1 place
@@ -170,17 +184,17 @@ module Sequel
170
184
  self.next(n * -1)
171
185
  end
172
186
 
173
- private
174
-
175
187
  # Set the value of the position_field to the maximum value plus 1 unless the
176
188
  # position field already has a value.
177
- def _before_validation
189
+ def before_validation
178
190
  unless get_column_value(position_field)
179
191
  set_column_value("#{position_field}=", list_dataset.max(position_field).to_i+1)
180
192
  end
181
193
  super
182
194
  end
183
195
 
196
+ private
197
+
184
198
  # The model's position field, an instance method for ease of use.
185
199
  def position_field
186
200
  model.position_field
@@ -46,18 +46,18 @@ module Sequel
46
46
  # Artist.many_through_many :artists, [[:albums_artists, :artist_id, :album_id], [:albums_artists, :album_id, :artist_id]]
47
47
  #
48
48
  # # All albums by artists that are associated to any album that this artist is associated to
49
- # Artist.many_through_many :artist_albums, [[:albums_artists, :artist_id, :album_id], \
50
- # [:albums_artists, :album_id, :artist_id], [:albums_artists, :artist_id, :album_id]], \
51
- # :class=>:Album
49
+ # Artist.many_through_many :artist_albums, [[:albums_artists, :artist_id, :album_id],
50
+ # [:albums_artists, :album_id, :artist_id], [:albums_artists, :artist_id, :album_id]],
51
+ # class: :Album
52
52
  #
53
53
  # # All tracks on albums by this artist (also could be a many_to_many)
54
- # Artist.many_through_many :tracks, [[:albums_artists, :artist_id, :album_id]], \
55
- # :right_primary_key=>:album_id
54
+ # Artist.many_through_many :tracks, [[:albums_artists, :artist_id, :album_id]],
55
+ # right_primary_key: :album_id
56
56
  #
57
57
  # Often you don't want the current object to appear in the array of associated objects. This is easiest to handle via an :after_load hook:
58
58
  #
59
59
  # Artist.many_through_many :artists, [[:albums_artists, :artist_id, :album_id], [:albums_artists, :album_id, :artist_id]],
60
- # :after_load=>proc{|artist, associated_artists| associated_artists.delete(artist)}
60
+ # after_load: lambda{|artist, associated_artists| associated_artists.delete(artist)}
61
61
  #
62
62
  # You can also handle it by adding a dataset block that excludes the current record (so it won't be retrieved at all), but
63
63
  # that won't work when eagerly loading, which is why the :after_load proc is recommended instead.
@@ -65,7 +65,7 @@ module Sequel
65
65
  # It's also common to not want duplicate records, in which case the :distinct option can be used:
66
66
  #
67
67
  # Artist.many_through_many :artists, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_artists, :album_id, :artist_id]],
68
- # :distinct=>true
68
+ # distinct: true
69
69
  #
70
70
  # In addition to many_through_many, this plugin also adds one_through_many, for an association to a single object through multiple join tables.
71
71
  # This is useful if there are unique constraints on the foreign keys in the join tables that reference back to the current table, or if you want
@@ -81,7 +81,7 @@ module Sequel
81
81
  module ManyThroughMany
82
82
  # The AssociationReflection subclass for many_through_many associations.
83
83
  class ManyThroughManyAssociationReflection < Sequel::Model::Associations::ManyToManyAssociationReflection
84
- Sequel::Model::Associations::ASSOCIATION_TYPES[:many_through_many] = self
84
+ Sequel.synchronize{Sequel::Model::Associations::ASSOCIATION_TYPES[:many_through_many] = self}
85
85
 
86
86
  # many_through_many and one_through_many associations can be clones
87
87
  def cloneable?(ref)
@@ -102,6 +102,17 @@ module Sequel
102
102
  END
103
103
  end
104
104
 
105
+ FINALIZE_SETTINGS = superclass::FINALIZE_SETTINGS.merge(
106
+ :associated_key_table=>:associated_key_table,
107
+ :edges=>:edges,
108
+ :final_edge=>:final_edge,
109
+ :final_reverse_edge=>:final_reverse_edge,
110
+ :reverse_edges=>:reverse_edges
111
+ ).freeze
112
+ def finalize_settings
113
+ FINALIZE_SETTINGS
114
+ end
115
+
105
116
  # The alias for the first join table.
106
117
  def join_table_alias
107
118
  final_reverse_edge[:alias]
@@ -112,16 +123,25 @@ module Sequel
112
123
  nil
113
124
  end
114
125
 
126
+ # Whether a separate query should be used for each join table.
127
+ def separate_query_per_table?
128
+ self[:separate_query_per_table]
129
+ end
130
+
115
131
  private
116
132
 
117
133
  def _associated_dataset
118
134
  ds = associated_class
119
- (reverse_edges + [final_reverse_edge]).each do |t|
120
- h = {:qualify=>:deep}
121
- if t[:alias] != t[:table]
122
- h[:table_alias] = t[:alias]
135
+ if separate_query_per_table?
136
+ ds = ds.dataset
137
+ else
138
+ (reverse_edges + [final_reverse_edge]).each do |t|
139
+ h = {:qualify=>:deep}
140
+ if t[:alias] != t[:table]
141
+ h[:table_alias] = t[:alias]
142
+ end
143
+ ds = ds.join(t[:table], Array(t[:left]).zip(Array(t[:right])), h)
123
144
  end
124
- ds = ds.join(t[:table], Array(t[:left]).zip(Array(t[:right])), h)
125
145
  end
126
146
  ds
127
147
  end
@@ -133,7 +153,7 @@ module Sequel
133
153
  table_alias = e[:table]
134
154
  if aliases.include?(table_alias)
135
155
  i = 0
136
- table_alias = loop do
156
+ table_alias = while true
137
157
  ta = :"#{table_alias}_#{i}"
138
158
  break ta unless aliases.include?(ta)
139
159
  i += 1
@@ -181,7 +201,7 @@ module Sequel
181
201
  end
182
202
 
183
203
  class OneThroughManyAssociationReflection < ManyThroughManyAssociationReflection
184
- Sequel::Model::Associations::ASSOCIATION_TYPES[:one_through_many] = self
204
+ Sequel.synchronize{Sequel::Model::Associations::ASSOCIATION_TYPES[:one_through_many] = self}
185
205
  include Sequel::Model::Associations::SingularAssociationReflection
186
206
  end
187
207
 
@@ -197,6 +217,7 @@ module Sequel
197
217
  # :right (last array element) :: The key joining the table to the next table. Can use an
198
218
  # array of symbols for a composite key association.
199
219
  # If a hash is provided, the following keys are respected when using eager_graph:
220
+ # :db :: The Database containing the table. This changes lookup to use a separate query for each join table.
200
221
  # :block :: A proc to use as the block argument to join.
201
222
  # :conditions :: Extra conditions to add to the JOIN ON clause. Must be a hash or array of two pairs.
202
223
  # :join_type :: The join type to use for the join, defaults to :left_outer.
@@ -217,34 +238,126 @@ module Sequel
217
238
  def def_many_through_many(opts)
218
239
  one_through_many = opts[:type] == :one_through_many
219
240
  opts[:read_only] = true
220
- opts[:after_load].unshift(:array_uniq!) if opts[:uniq]
241
+ if opts[:uniq]
242
+ opts[:after_load] ||= []
243
+ opts[:after_load].unshift(:array_uniq!)
244
+ end
221
245
  opts[:cartesian_product_number] ||= one_through_many ? 0 : 2
222
- opts[:through] = opts[:through].map do |e|
246
+ separate_query_per_table = false
247
+ through = opts[:through] = opts[:through].map do |e|
223
248
  case e
224
249
  when Array
225
250
  raise(Error, "array elements of the through option/argument for many_through_many associations must have at least three elements") unless e.length == 3
226
251
  {:table=>e[0], :left=>e[1], :right=>e[2]}
227
252
  when Hash
228
253
  raise(Error, "hash elements of the through option/argument for many_through_many associations must contain :table, :left, and :right keys") unless e[:table] && e[:left] && e[:right]
254
+ separate_query_per_table = true if e[:db]
229
255
  e
230
256
  else
231
257
  raise(Error, "the through option/argument for many_through_many associations must be an enumerable of arrays or hashes")
232
258
  end
233
259
  end
260
+ opts[:separate_query_per_table] = separate_query_per_table
234
261
 
235
262
  left_key = opts[:left_key] = opts[:through].first[:left]
236
263
  opts[:left_keys] = Array(left_key)
237
- opts[:uses_left_composite_keys] = left_key.is_a?(Array)
264
+ uses_lcks = opts[:uses_left_composite_keys] = left_key.is_a?(Array)
238
265
  left_pk = (opts[:left_primary_key] ||= self.primary_key)
239
266
  raise(Error, "no primary key specified for #{inspect}") unless left_pk
240
267
  opts[:eager_loader_key] = left_pk unless opts.has_key?(:eager_loader_key)
241
268
  opts[:left_primary_keys] = Array(left_pk)
242
269
  lpkc = opts[:left_primary_key_column] ||= left_pk
243
270
  lpkcs = opts[:left_primary_key_columns] ||= Array(lpkc)
244
- opts[:dataset] ||= opts.association_dataset_proc
245
271
 
246
272
  opts[:left_key_alias] ||= opts.default_associated_key_alias
247
- opts[:eager_loader] ||= opts.method(:default_eager_loader)
273
+ if separate_query_per_table
274
+ opts[:use_placeholder_loader] = false
275
+ opts[:allow_eager_graph] = false
276
+ opts[:allow_filtering_by] = false
277
+ opts[:eager_limit_strategy] = nil
278
+
279
+ opts[:dataset] ||= proc do |r|
280
+ def_db = r.associated_class.db
281
+ vals = uses_lcks ? [lpkcs.map{|k| get_column_value(k)}] : get_column_value(left_pk)
282
+
283
+ has_results = through.each do |edge|
284
+ ds = (edge[:db] || def_db).from(edge[:table]).where(edge[:left]=>vals)
285
+ ds = ds.where(edge[:conditions]) if edge[:conditions]
286
+ right = edge[:right]
287
+ vals = ds.select_map(right)
288
+ if right.is_a?(Array)
289
+ vals.delete_if{|v| v.any?(&:nil?)}
290
+ else
291
+ vals.delete(nil)
292
+ end
293
+ break if vals.empty?
294
+ end
295
+
296
+ ds = r.associated_dataset.where(opts.right_primary_key=>vals)
297
+ ds = ds.clone(:no_results=>true) unless has_results
298
+ ds
299
+ end
300
+ opts[:eager_loader] ||= proc do |eo|
301
+ h = eo[:id_map]
302
+ assign_singular = opts.assign_singular?
303
+ uses_rcks = opts.right_primary_key.is_a?(Array)
304
+ rpk = uses_rcks ? opts.right_primary_keys : opts.right_primary_key
305
+ name = opts[:name]
306
+ def_db = opts.associated_class.db
307
+ join_map = h
308
+
309
+ run_query = through.each do |edge|
310
+ ds = (edge[:db] || def_db).from(edge[:table])
311
+ ds = ds.where(edge[:conditions]) if edge[:conditions]
312
+ left = edge[:left]
313
+ right = edge[:right]
314
+ prev_map = join_map
315
+ join_map = ds.where(left=>join_map.keys).select_hash_groups(right, left)
316
+ if right.is_a?(Array)
317
+ join_map.delete_if{|v,| v.any?(&:nil?)}
318
+ else
319
+ join_map.delete(nil)
320
+ end
321
+ break if join_map.empty?
322
+ join_map.each_value do |vs|
323
+ vs.replace(vs.flat_map{|v| prev_map[v]})
324
+ vs.uniq!
325
+ end
326
+ end
327
+
328
+ eo = Hash[eo]
329
+
330
+ if run_query
331
+ eo[:loader] = false
332
+ eo[:right_keys] = join_map.keys
333
+ else
334
+ eo[:no_results] = true
335
+ end
336
+
337
+ opts[:model].eager_load_results(opts, eo) do |assoc_record|
338
+ rpkv = if uses_rcks
339
+ assoc_record.values.values_at(*rpk)
340
+ else
341
+ assoc_record.values[rpk]
342
+ end
343
+
344
+ objects = join_map[rpkv]
345
+
346
+ if assign_singular
347
+ objects.each do |object|
348
+ object.associations[name] ||= assoc_record
349
+ end
350
+ else
351
+ objects.each do |object|
352
+ object.associations[name].push(assoc_record)
353
+ end
354
+ end
355
+ end
356
+ end
357
+ else
358
+ opts[:dataset] ||= opts.association_dataset_proc
359
+ opts[:eager_loader] ||= opts.method(:default_eager_loader)
360
+ end
248
361
 
249
362
  join_type = opts[:graph_join_type]
250
363
  select = opts[:graph_select]
@@ -272,7 +385,7 @@ module Sequel
272
385
  iq = nil
273
386
  end
274
387
  fe = opts.final_edge
275
- ds.graph(opts.associated_class, use_only_conditions ? only_conditions : (Array(opts.right_primary_key).zip(Array(fe[:left])) + conditions), :select=>select, :table_alias=>eo[:table_alias], :qualify=>:deep, :join_type=>eo[:join_type]||join_type, :join_only=>eo[:join_only], &graph_block)
388
+ ds.graph(opts.associated_class.dataset, use_only_conditions ? only_conditions : (Array(opts.right_primary_key).zip(Array(fe[:left])) + conditions), :select=>select, :table_alias=>eo[:table_alias], :qualify=>:deep, :join_type=>eo[:join_type]||join_type, :join_only=>eo[:join_only], &graph_block)
276
389
  end
277
390
  end
278
391
  end
@@ -17,6 +17,9 @@ module Sequel
17
17
  # Note that for this plugin to work correctly, the column values must
18
18
  # correctly implement the #hash method, returning the same value if
19
19
  # the object is equal, and a different value if the object is not equal.
20
+ # As this solely uses hash values to check for modification, there may
21
+ # be cases where a modification is made and the hash value is the same,
22
+ # resulting in a false negative.
20
23
  #
21
24
  # Note that this plugin causes a performance hit for all retrieved
22
25
  # objects, so it shouldn't be used in cases where performance is a
@@ -55,13 +58,20 @@ module Sequel
55
58
  # Detect which columns have been modified by comparing the cached hash
56
59
  # value to the hash of the current value.
57
60
  def changed_columns
58
- cc = super
59
- changed = []
60
- v = @values
61
+ changed = super
61
62
  if vh = @values_hashes
62
- (vh.keys - cc).each{|c| changed << c unless v.has_key?(c) && vh[c] == v[c].hash}
63
+ values = @values
64
+ changed = changed.dup if frozen?
65
+ vh.each do |c, v|
66
+ match = values.has_key?(c) && v == values[c].hash
67
+ if changed.include?(c)
68
+ changed.delete(c) if match
69
+ else
70
+ changed << c unless match
71
+ end
72
+ end
63
73
  end
64
- cc + changed
74
+ changed
65
75
  end
66
76
 
67
77
  private
@@ -12,15 +12,15 @@ module Sequel
12
12
  # end
13
13
  # p1 = Person[1]
14
14
  # p2 = Person[1]
15
- # p1.update(:name=>'Jim') # works
16
- # p2.update(:name=>'Bob') # raises Sequel::NoExistingObject
15
+ # p1.update(name: 'Jim') # works
16
+ # p2.update(name: 'Bob') # raises Sequel::NoExistingObject
17
17
  #
18
18
  # In order for this plugin to work, you need to make sure that the database
19
19
  # table has a column of timestamp or rowversion. The plugin uses a default
20
20
  # name of timestamp for this columns, but you can override that using the
21
21
  # :lock_column option:
22
22
  #
23
- # plugin :mssql_optimistic_locking, :lock_column=>:column_name
23
+ # plugin :mssql_optimistic_locking, lock_column: :column_name
24
24
  #
25
25
  # This plugin relies on the instance_filters plugin.
26
26
  module MssqlOptimisticLocking
@@ -75,7 +75,8 @@ module Sequel
75
75
  # it to be assigned.
76
76
  def _save_update_all_columns_hash
77
77
  v = @values.dup
78
- Array(primary_key).each{|x| v.delete(x) unless changed_columns.include?(x)}
78
+ cc = changed_columns
79
+ Array(primary_key).each{|x| v.delete(x) unless cc.include?(x)}
79
80
  v.delete(model.lock_column)
80
81
  v
81
82
  end
@@ -84,7 +85,7 @@ module Sequel
84
85
  def _update_without_checking(columns)
85
86
  ds = _update_dataset
86
87
  lc = model.lock_column
87
- rows = ds.clone(ds.send(:default_server_opts, :sql=>ds.output(nil, [Sequel.qualify(:inserted, lc)]).update_sql(columns))).all
88
+ rows = ds.clone(ds.send(:default_server_opts, :sql=>ds.output(nil, [Sequel[:inserted][lc]]).update_sql(columns))).all
88
89
  values[lc] = rows.first[lc] unless rows.empty?
89
90
  rows.length
90
91
  end