sequel 4.26.0 → 5.37.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 (692) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG +405 -5656
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +232 -157
  5. data/bin/sequel +32 -9
  6. data/doc/advanced_associations.rdoc +252 -188
  7. data/doc/association_basics.rdoc +231 -273
  8. data/doc/bin_sequel.rdoc +5 -3
  9. data/doc/cheat_sheet.rdoc +75 -48
  10. data/doc/code_order.rdoc +28 -10
  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/mass_assignment.rdoc +74 -31
  16. data/doc/migration.rdoc +72 -46
  17. data/doc/model_dataset_method_design.rdoc +129 -0
  18. data/doc/model_hooks.rdoc +15 -25
  19. data/doc/model_plugins.rdoc +12 -12
  20. data/doc/mssql_stored_procedures.rdoc +3 -3
  21. data/doc/object_model.rdoc +59 -69
  22. data/doc/opening_databases.rdoc +84 -94
  23. data/doc/postgresql.rdoc +268 -38
  24. data/doc/prepared_statements.rdoc +29 -24
  25. data/doc/querying.rdoc +184 -164
  26. data/doc/reflection.rdoc +5 -6
  27. data/doc/release_notes/5.0.0.txt +159 -0
  28. data/doc/release_notes/5.1.0.txt +31 -0
  29. data/doc/release_notes/5.10.0.txt +84 -0
  30. data/doc/release_notes/5.11.0.txt +83 -0
  31. data/doc/release_notes/5.12.0.txt +141 -0
  32. data/doc/release_notes/5.13.0.txt +27 -0
  33. data/doc/release_notes/5.14.0.txt +63 -0
  34. data/doc/release_notes/5.15.0.txt +39 -0
  35. data/doc/release_notes/5.16.0.txt +110 -0
  36. data/doc/release_notes/5.17.0.txt +31 -0
  37. data/doc/release_notes/5.18.0.txt +69 -0
  38. data/doc/release_notes/5.19.0.txt +28 -0
  39. data/doc/release_notes/5.2.0.txt +33 -0
  40. data/doc/release_notes/5.20.0.txt +89 -0
  41. data/doc/release_notes/5.21.0.txt +87 -0
  42. data/doc/release_notes/5.22.0.txt +48 -0
  43. data/doc/release_notes/5.23.0.txt +56 -0
  44. data/doc/release_notes/5.24.0.txt +56 -0
  45. data/doc/release_notes/5.25.0.txt +32 -0
  46. data/doc/release_notes/5.26.0.txt +35 -0
  47. data/doc/release_notes/5.27.0.txt +21 -0
  48. data/doc/release_notes/5.28.0.txt +16 -0
  49. data/doc/release_notes/5.29.0.txt +22 -0
  50. data/doc/release_notes/5.3.0.txt +121 -0
  51. data/doc/release_notes/5.30.0.txt +20 -0
  52. data/doc/release_notes/5.31.0.txt +148 -0
  53. data/doc/release_notes/5.32.0.txt +46 -0
  54. data/doc/release_notes/5.33.0.txt +24 -0
  55. data/doc/release_notes/5.34.0.txt +40 -0
  56. data/doc/release_notes/5.35.0.txt +56 -0
  57. data/doc/release_notes/5.36.0.txt +60 -0
  58. data/doc/release_notes/5.37.0.txt +30 -0
  59. data/doc/release_notes/5.4.0.txt +80 -0
  60. data/doc/release_notes/5.5.0.txt +61 -0
  61. data/doc/release_notes/5.6.0.txt +31 -0
  62. data/doc/release_notes/5.7.0.txt +108 -0
  63. data/doc/release_notes/5.8.0.txt +170 -0
  64. data/doc/release_notes/5.9.0.txt +99 -0
  65. data/doc/schema_modification.rdoc +102 -77
  66. data/doc/security.rdoc +160 -87
  67. data/doc/sharding.rdoc +74 -47
  68. data/doc/sql.rdoc +135 -122
  69. data/doc/testing.rdoc +34 -18
  70. data/doc/thread_safety.rdoc +2 -4
  71. data/doc/transactions.rdoc +101 -19
  72. data/doc/validations.rdoc +64 -51
  73. data/doc/virtual_rows.rdoc +90 -109
  74. data/lib/sequel.rb +3 -1
  75. data/lib/sequel/adapters/ado.rb +154 -22
  76. data/lib/sequel/adapters/ado/access.rb +21 -21
  77. data/lib/sequel/adapters/ado/mssql.rb +8 -15
  78. data/lib/sequel/adapters/amalgalite.rb +17 -25
  79. data/lib/sequel/adapters/ibmdb.rb +52 -58
  80. data/lib/sequel/adapters/jdbc.rb +149 -127
  81. data/lib/sequel/adapters/jdbc/db2.rb +32 -40
  82. data/lib/sequel/adapters/jdbc/derby.rb +56 -58
  83. data/lib/sequel/adapters/jdbc/h2.rb +40 -30
  84. data/lib/sequel/adapters/jdbc/hsqldb.rb +22 -33
  85. data/lib/sequel/adapters/jdbc/jtds.rb +4 -10
  86. data/lib/sequel/adapters/jdbc/mssql.rb +6 -12
  87. data/lib/sequel/adapters/jdbc/mysql.rb +17 -18
  88. data/lib/sequel/adapters/jdbc/oracle.rb +25 -19
  89. data/lib/sequel/adapters/jdbc/postgresql.rb +90 -69
  90. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +14 -24
  91. data/lib/sequel/adapters/jdbc/sqlite.rb +50 -12
  92. data/lib/sequel/adapters/jdbc/sqlserver.rb +36 -9
  93. data/lib/sequel/adapters/jdbc/transactions.rb +25 -39
  94. data/lib/sequel/adapters/mock.rb +104 -113
  95. data/lib/sequel/adapters/mysql.rb +42 -61
  96. data/lib/sequel/adapters/mysql2.rb +126 -35
  97. data/lib/sequel/adapters/odbc.rb +21 -28
  98. data/lib/sequel/adapters/odbc/db2.rb +3 -1
  99. data/lib/sequel/adapters/odbc/mssql.rb +11 -15
  100. data/lib/sequel/adapters/odbc/oracle.rb +11 -0
  101. data/lib/sequel/adapters/oracle.rb +62 -68
  102. data/lib/sequel/adapters/postgres.rb +257 -311
  103. data/lib/sequel/adapters/postgresql.rb +3 -1
  104. data/lib/sequel/adapters/shared/access.rb +75 -79
  105. data/lib/sequel/adapters/shared/db2.rb +96 -74
  106. data/lib/sequel/adapters/shared/mssql.rb +258 -213
  107. data/lib/sequel/adapters/shared/mysql.rb +284 -216
  108. data/lib/sequel/adapters/shared/oracle.rb +175 -60
  109. data/lib/sequel/adapters/shared/postgres.rb +829 -383
  110. data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -127
  111. data/lib/sequel/adapters/shared/sqlite.rb +382 -159
  112. data/lib/sequel/adapters/sqlanywhere.rb +53 -38
  113. data/lib/sequel/adapters/sqlite.rb +111 -105
  114. data/lib/sequel/adapters/tinytds.rb +38 -46
  115. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +8 -9
  116. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +7 -5
  117. data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
  118. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
  119. data/lib/sequel/adapters/utils/replace.rb +3 -4
  120. data/lib/sequel/adapters/utils/split_alter_table.rb +2 -0
  121. data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
  122. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
  123. data/lib/sequel/ast_transformer.rb +13 -89
  124. data/lib/sequel/connection_pool.rb +54 -26
  125. data/lib/sequel/connection_pool/sharded_single.rb +19 -12
  126. data/lib/sequel/connection_pool/sharded_threaded.rb +160 -111
  127. data/lib/sequel/connection_pool/single.rb +21 -12
  128. data/lib/sequel/connection_pool/threaded.rb +137 -119
  129. data/lib/sequel/core.rb +352 -320
  130. data/lib/sequel/database.rb +19 -2
  131. data/lib/sequel/database/connecting.rb +70 -55
  132. data/lib/sequel/database/dataset.rb +15 -5
  133. data/lib/sequel/database/dataset_defaults.rb +20 -102
  134. data/lib/sequel/database/features.rb +20 -4
  135. data/lib/sequel/database/logging.rb +25 -7
  136. data/lib/sequel/database/misc.rb +132 -118
  137. data/lib/sequel/database/query.rb +51 -28
  138. data/lib/sequel/database/schema_generator.rb +188 -75
  139. data/lib/sequel/database/schema_methods.rb +161 -92
  140. data/lib/sequel/database/transactions.rb +260 -58
  141. data/lib/sequel/dataset.rb +28 -12
  142. data/lib/sequel/dataset/actions.rb +354 -170
  143. data/lib/sequel/dataset/dataset_module.rb +46 -0
  144. data/lib/sequel/dataset/features.rb +81 -34
  145. data/lib/sequel/dataset/graph.rb +82 -58
  146. data/lib/sequel/dataset/misc.rb +139 -47
  147. data/lib/sequel/dataset/placeholder_literalizer.rb +66 -26
  148. data/lib/sequel/dataset/prepared_statements.rb +188 -85
  149. data/lib/sequel/dataset/query.rb +428 -214
  150. data/lib/sequel/dataset/sql.rb +446 -339
  151. data/lib/sequel/deprecated.rb +14 -2
  152. data/lib/sequel/exceptions.rb +48 -16
  153. data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
  154. data/lib/sequel/extensions/_model_pg_row.rb +43 -0
  155. data/lib/sequel/extensions/_pretty_table.rb +10 -9
  156. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  157. data/lib/sequel/extensions/arbitrary_servers.rb +15 -11
  158. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  159. data/lib/sequel/extensions/blank.rb +2 -0
  160. data/lib/sequel/extensions/caller_logging.rb +79 -0
  161. data/lib/sequel/extensions/columns_introspection.rb +9 -4
  162. data/lib/sequel/extensions/connection_expiration.rb +99 -0
  163. data/lib/sequel/extensions/connection_validator.rb +26 -13
  164. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  165. data/lib/sequel/extensions/constraint_validations.rb +93 -38
  166. data/lib/sequel/extensions/core_extensions.rb +45 -53
  167. data/lib/sequel/extensions/core_refinements.rb +44 -46
  168. data/lib/sequel/extensions/current_datetime_timestamp.rb +5 -4
  169. data/lib/sequel/extensions/dataset_source_alias.rb +4 -0
  170. data/lib/sequel/extensions/date_arithmetic.rb +42 -16
  171. data/lib/sequel/extensions/datetime_parse_to_time.rb +37 -0
  172. data/lib/sequel/extensions/duplicate_columns_handler.rb +94 -0
  173. data/lib/sequel/extensions/empty_array_consider_nulls.rb +7 -3
  174. data/lib/sequel/extensions/error_sql.rb +7 -3
  175. data/lib/sequel/extensions/escaped_like.rb +100 -0
  176. data/lib/sequel/extensions/eval_inspect.rb +14 -15
  177. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  178. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  179. data/lib/sequel/extensions/freeze_datasets.rb +3 -0
  180. data/lib/sequel/extensions/from_block.rb +2 -31
  181. data/lib/sequel/extensions/graph_each.rb +19 -6
  182. data/lib/sequel/extensions/identifier_mangling.rb +180 -0
  183. data/lib/sequel/extensions/implicit_subquery.rb +48 -0
  184. data/lib/sequel/extensions/index_caching.rb +109 -0
  185. data/lib/sequel/extensions/inflector.rb +8 -4
  186. data/lib/sequel/extensions/integer64.rb +32 -0
  187. data/lib/sequel/extensions/looser_typecasting.rb +19 -9
  188. data/lib/sequel/extensions/migration.rb +132 -80
  189. data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +4 -0
  190. data/lib/sequel/extensions/named_timezones.rb +88 -23
  191. data/lib/sequel/extensions/no_auto_literal_strings.rb +4 -0
  192. data/lib/sequel/extensions/null_dataset.rb +12 -8
  193. data/lib/sequel/extensions/pagination.rb +35 -28
  194. data/lib/sequel/extensions/pg_array.rb +227 -316
  195. data/lib/sequel/extensions/pg_array_ops.rb +19 -7
  196. data/lib/sequel/extensions/pg_enum.rb +69 -24
  197. data/lib/sequel/extensions/pg_extended_date_support.rb +250 -0
  198. data/lib/sequel/extensions/pg_hstore.rb +50 -59
  199. data/lib/sequel/extensions/pg_hstore_ops.rb +9 -3
  200. data/lib/sequel/extensions/pg_inet.rb +34 -15
  201. data/lib/sequel/extensions/pg_inet_ops.rb +5 -1
  202. data/lib/sequel/extensions/pg_interval.rb +26 -26
  203. data/lib/sequel/extensions/pg_json.rb +422 -141
  204. data/lib/sequel/extensions/pg_json_ops.rb +248 -9
  205. data/lib/sequel/extensions/pg_loose_count.rb +5 -1
  206. data/lib/sequel/extensions/pg_range.rb +162 -146
  207. data/lib/sequel/extensions/pg_range_ops.rb +10 -5
  208. data/lib/sequel/extensions/pg_row.rb +53 -87
  209. data/lib/sequel/extensions/pg_row_ops.rb +36 -13
  210. data/lib/sequel/extensions/pg_static_cache_updater.rb +6 -2
  211. data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
  212. data/lib/sequel/extensions/pretty_table.rb +4 -0
  213. data/lib/sequel/extensions/query.rb +12 -7
  214. data/lib/sequel/extensions/round_timestamps.rb +6 -9
  215. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  216. data/lib/sequel/extensions/s.rb +59 -0
  217. data/lib/sequel/extensions/schema_caching.rb +14 -1
  218. data/lib/sequel/extensions/schema_dumper.rb +83 -55
  219. data/lib/sequel/extensions/select_remove.rb +8 -4
  220. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
  221. data/lib/sequel/extensions/server_block.rb +50 -17
  222. data/lib/sequel/extensions/server_logging.rb +61 -0
  223. data/lib/sequel/extensions/split_array_nil.rb +8 -4
  224. data/lib/sequel/extensions/sql_comments.rb +96 -0
  225. data/lib/sequel/extensions/sql_expr.rb +4 -1
  226. data/lib/sequel/extensions/string_agg.rb +181 -0
  227. data/lib/sequel/extensions/string_date_time.rb +2 -0
  228. data/lib/sequel/extensions/symbol_aref.rb +53 -0
  229. data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
  230. data/lib/sequel/extensions/symbol_as.rb +23 -0
  231. data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
  232. data/lib/sequel/extensions/synchronize_sql.rb +45 -0
  233. data/lib/sequel/extensions/thread_local_timezones.rb +4 -0
  234. data/lib/sequel/extensions/to_dot.rb +15 -5
  235. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  236. data/lib/sequel/model.rb +36 -126
  237. data/lib/sequel/model/associations.rb +850 -257
  238. data/lib/sequel/model/base.rb +652 -764
  239. data/lib/sequel/model/dataset_module.rb +13 -10
  240. data/lib/sequel/model/default_inflections.rb +3 -1
  241. data/lib/sequel/model/errors.rb +3 -3
  242. data/lib/sequel/model/exceptions.rb +12 -12
  243. data/lib/sequel/model/inflections.rb +8 -19
  244. data/lib/sequel/model/plugins.rb +111 -0
  245. data/lib/sequel/plugins/accessed_columns.rb +2 -0
  246. data/lib/sequel/plugins/active_model.rb +32 -7
  247. data/lib/sequel/plugins/after_initialize.rb +3 -1
  248. data/lib/sequel/plugins/association_dependencies.rb +27 -18
  249. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  250. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  251. data/lib/sequel/plugins/association_pks.rb +181 -83
  252. data/lib/sequel/plugins/association_proxies.rb +33 -9
  253. data/lib/sequel/plugins/auto_validations.rb +58 -23
  254. data/lib/sequel/plugins/before_after_save.rb +8 -0
  255. data/lib/sequel/plugins/blacklist_security.rb +23 -12
  256. data/lib/sequel/plugins/boolean_readers.rb +9 -6
  257. data/lib/sequel/plugins/boolean_subsets.rb +64 -0
  258. data/lib/sequel/plugins/caching.rb +27 -16
  259. data/lib/sequel/plugins/class_table_inheritance.rb +192 -94
  260. data/lib/sequel/plugins/column_conflicts.rb +18 -3
  261. data/lib/sequel/plugins/column_select.rb +9 -5
  262. data/lib/sequel/plugins/columns_updated.rb +42 -0
  263. data/lib/sequel/plugins/composition.rb +36 -24
  264. data/lib/sequel/plugins/constraint_validations.rb +37 -16
  265. data/lib/sequel/plugins/csv_serializer.rb +58 -35
  266. data/lib/sequel/plugins/dataset_associations.rb +60 -18
  267. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  268. data/lib/sequel/plugins/defaults_setter.rb +74 -13
  269. data/lib/sequel/plugins/delay_add_association.rb +4 -1
  270. data/lib/sequel/plugins/dirty.rb +65 -24
  271. data/lib/sequel/plugins/eager_each.rb +27 -3
  272. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  273. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  274. data/lib/sequel/plugins/error_splitter.rb +19 -12
  275. data/lib/sequel/plugins/finder.rb +246 -0
  276. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  277. data/lib/sequel/plugins/force_encoding.rb +9 -12
  278. data/lib/sequel/plugins/hook_class_methods.rb +39 -54
  279. data/lib/sequel/plugins/input_transformer.rb +20 -10
  280. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  281. data/lib/sequel/plugins/insert_returning_select.rb +4 -2
  282. data/lib/sequel/plugins/instance_filters.rb +12 -8
  283. data/lib/sequel/plugins/instance_hooks.rb +36 -17
  284. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  285. data/lib/sequel/plugins/inverted_subsets.rb +24 -13
  286. data/lib/sequel/plugins/json_serializer.rb +123 -47
  287. data/lib/sequel/plugins/lazy_attributes.rb +20 -14
  288. data/lib/sequel/plugins/list.rb +40 -26
  289. data/lib/sequel/plugins/many_through_many.rb +28 -12
  290. data/lib/sequel/plugins/modification_detection.rb +17 -5
  291. data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -5
  292. data/lib/sequel/plugins/nested_attributes.rb +55 -28
  293. data/lib/sequel/plugins/optimistic_locking.rb +5 -3
  294. data/lib/sequel/plugins/pg_array_associations.rb +52 -18
  295. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +348 -0
  296. data/lib/sequel/plugins/pg_row.rb +7 -51
  297. data/lib/sequel/plugins/prepared_statements.rb +53 -72
  298. data/lib/sequel/plugins/prepared_statements_safe.rb +13 -5
  299. data/lib/sequel/plugins/rcte_tree.rb +43 -63
  300. data/lib/sequel/plugins/serialization.rb +37 -44
  301. data/lib/sequel/plugins/serialization_modification_detection.rb +3 -1
  302. data/lib/sequel/plugins/sharding.rb +17 -10
  303. data/lib/sequel/plugins/single_table_inheritance.rb +62 -28
  304. data/lib/sequel/plugins/singular_table_names.rb +2 -0
  305. data/lib/sequel/plugins/skip_create_refresh.rb +5 -3
  306. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  307. data/lib/sequel/plugins/split_values.rb +13 -6
  308. data/lib/sequel/plugins/static_cache.rb +79 -53
  309. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  310. data/lib/sequel/plugins/string_stripper.rb +5 -3
  311. data/lib/sequel/plugins/subclasses.rb +20 -2
  312. data/lib/sequel/plugins/subset_conditions.rb +48 -0
  313. data/lib/sequel/plugins/table_select.rb +4 -2
  314. data/lib/sequel/plugins/tactical_eager_loading.rb +120 -6
  315. data/lib/sequel/plugins/throw_failures.rb +110 -0
  316. data/lib/sequel/plugins/timestamps.rb +22 -8
  317. data/lib/sequel/plugins/touch.rb +21 -8
  318. data/lib/sequel/plugins/tree.rb +57 -30
  319. data/lib/sequel/plugins/typecast_on_load.rb +14 -4
  320. data/lib/sequel/plugins/unlimited_update.rb +3 -7
  321. data/lib/sequel/plugins/update_or_create.rb +6 -4
  322. data/lib/sequel/plugins/update_primary_key.rb +3 -1
  323. data/lib/sequel/plugins/update_refresh.rb +28 -15
  324. data/lib/sequel/plugins/uuid.rb +70 -0
  325. data/lib/sequel/plugins/validate_associated.rb +20 -0
  326. data/lib/sequel/plugins/validation_class_methods.rb +40 -19
  327. data/lib/sequel/plugins/validation_contexts.rb +49 -0
  328. data/lib/sequel/plugins/validation_helpers.rb +49 -31
  329. data/lib/sequel/plugins/whitelist_security.rb +122 -0
  330. data/lib/sequel/plugins/xml_serializer.rb +31 -30
  331. data/lib/sequel/sql.rb +479 -329
  332. data/lib/sequel/timezones.rb +62 -32
  333. data/lib/sequel/version.rb +10 -3
  334. metadata +177 -477
  335. data/Rakefile +0 -165
  336. data/doc/active_record.rdoc +0 -912
  337. data/doc/release_notes/1.0.txt +0 -38
  338. data/doc/release_notes/1.1.txt +0 -143
  339. data/doc/release_notes/1.3.txt +0 -101
  340. data/doc/release_notes/1.4.0.txt +0 -53
  341. data/doc/release_notes/1.5.0.txt +0 -155
  342. data/doc/release_notes/2.0.0.txt +0 -298
  343. data/doc/release_notes/2.1.0.txt +0 -271
  344. data/doc/release_notes/2.10.0.txt +0 -328
  345. data/doc/release_notes/2.11.0.txt +0 -215
  346. data/doc/release_notes/2.12.0.txt +0 -534
  347. data/doc/release_notes/2.2.0.txt +0 -253
  348. data/doc/release_notes/2.3.0.txt +0 -88
  349. data/doc/release_notes/2.4.0.txt +0 -106
  350. data/doc/release_notes/2.5.0.txt +0 -137
  351. data/doc/release_notes/2.6.0.txt +0 -157
  352. data/doc/release_notes/2.7.0.txt +0 -166
  353. data/doc/release_notes/2.8.0.txt +0 -171
  354. data/doc/release_notes/2.9.0.txt +0 -97
  355. data/doc/release_notes/3.0.0.txt +0 -221
  356. data/doc/release_notes/3.1.0.txt +0 -406
  357. data/doc/release_notes/3.10.0.txt +0 -286
  358. data/doc/release_notes/3.11.0.txt +0 -254
  359. data/doc/release_notes/3.12.0.txt +0 -304
  360. data/doc/release_notes/3.13.0.txt +0 -210
  361. data/doc/release_notes/3.14.0.txt +0 -118
  362. data/doc/release_notes/3.15.0.txt +0 -78
  363. data/doc/release_notes/3.16.0.txt +0 -45
  364. data/doc/release_notes/3.17.0.txt +0 -58
  365. data/doc/release_notes/3.18.0.txt +0 -120
  366. data/doc/release_notes/3.19.0.txt +0 -67
  367. data/doc/release_notes/3.2.0.txt +0 -268
  368. data/doc/release_notes/3.20.0.txt +0 -41
  369. data/doc/release_notes/3.21.0.txt +0 -87
  370. data/doc/release_notes/3.22.0.txt +0 -39
  371. data/doc/release_notes/3.23.0.txt +0 -172
  372. data/doc/release_notes/3.24.0.txt +0 -420
  373. data/doc/release_notes/3.25.0.txt +0 -88
  374. data/doc/release_notes/3.26.0.txt +0 -88
  375. data/doc/release_notes/3.27.0.txt +0 -82
  376. data/doc/release_notes/3.28.0.txt +0 -304
  377. data/doc/release_notes/3.29.0.txt +0 -459
  378. data/doc/release_notes/3.3.0.txt +0 -192
  379. data/doc/release_notes/3.30.0.txt +0 -135
  380. data/doc/release_notes/3.31.0.txt +0 -146
  381. data/doc/release_notes/3.32.0.txt +0 -202
  382. data/doc/release_notes/3.33.0.txt +0 -157
  383. data/doc/release_notes/3.34.0.txt +0 -671
  384. data/doc/release_notes/3.35.0.txt +0 -144
  385. data/doc/release_notes/3.36.0.txt +0 -245
  386. data/doc/release_notes/3.37.0.txt +0 -338
  387. data/doc/release_notes/3.38.0.txt +0 -234
  388. data/doc/release_notes/3.39.0.txt +0 -237
  389. data/doc/release_notes/3.4.0.txt +0 -325
  390. data/doc/release_notes/3.40.0.txt +0 -73
  391. data/doc/release_notes/3.41.0.txt +0 -155
  392. data/doc/release_notes/3.42.0.txt +0 -74
  393. data/doc/release_notes/3.43.0.txt +0 -105
  394. data/doc/release_notes/3.44.0.txt +0 -152
  395. data/doc/release_notes/3.45.0.txt +0 -179
  396. data/doc/release_notes/3.46.0.txt +0 -122
  397. data/doc/release_notes/3.47.0.txt +0 -270
  398. data/doc/release_notes/3.48.0.txt +0 -477
  399. data/doc/release_notes/3.5.0.txt +0 -510
  400. data/doc/release_notes/3.6.0.txt +0 -366
  401. data/doc/release_notes/3.7.0.txt +0 -179
  402. data/doc/release_notes/3.8.0.txt +0 -151
  403. data/doc/release_notes/3.9.0.txt +0 -233
  404. data/doc/release_notes/4.0.0.txt +0 -262
  405. data/doc/release_notes/4.1.0.txt +0 -85
  406. data/doc/release_notes/4.10.0.txt +0 -226
  407. data/doc/release_notes/4.11.0.txt +0 -147
  408. data/doc/release_notes/4.12.0.txt +0 -105
  409. data/doc/release_notes/4.13.0.txt +0 -169
  410. data/doc/release_notes/4.14.0.txt +0 -68
  411. data/doc/release_notes/4.15.0.txt +0 -56
  412. data/doc/release_notes/4.16.0.txt +0 -36
  413. data/doc/release_notes/4.17.0.txt +0 -38
  414. data/doc/release_notes/4.18.0.txt +0 -36
  415. data/doc/release_notes/4.19.0.txt +0 -45
  416. data/doc/release_notes/4.2.0.txt +0 -129
  417. data/doc/release_notes/4.20.0.txt +0 -79
  418. data/doc/release_notes/4.21.0.txt +0 -94
  419. data/doc/release_notes/4.22.0.txt +0 -72
  420. data/doc/release_notes/4.23.0.txt +0 -65
  421. data/doc/release_notes/4.24.0.txt +0 -99
  422. data/doc/release_notes/4.25.0.txt +0 -181
  423. data/doc/release_notes/4.26.0.txt +0 -44
  424. data/doc/release_notes/4.3.0.txt +0 -40
  425. data/doc/release_notes/4.4.0.txt +0 -92
  426. data/doc/release_notes/4.5.0.txt +0 -34
  427. data/doc/release_notes/4.6.0.txt +0 -30
  428. data/doc/release_notes/4.7.0.txt +0 -103
  429. data/doc/release_notes/4.8.0.txt +0 -175
  430. data/doc/release_notes/4.9.0.txt +0 -190
  431. data/lib/sequel/adapters/cubrid.rb +0 -142
  432. data/lib/sequel/adapters/do.rb +0 -156
  433. data/lib/sequel/adapters/do/mysql.rb +0 -64
  434. data/lib/sequel/adapters/do/postgres.rb +0 -42
  435. data/lib/sequel/adapters/do/sqlite3.rb +0 -40
  436. data/lib/sequel/adapters/jdbc/as400.rb +0 -82
  437. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -62
  438. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -34
  439. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -31
  440. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -31
  441. data/lib/sequel/adapters/odbc/progress.rb +0 -8
  442. data/lib/sequel/adapters/shared/cubrid.rb +0 -243
  443. data/lib/sequel/adapters/shared/firebird.rb +0 -245
  444. data/lib/sequel/adapters/shared/informix.rb +0 -52
  445. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -150
  446. data/lib/sequel/adapters/shared/progress.rb +0 -38
  447. data/lib/sequel/adapters/swift.rb +0 -158
  448. data/lib/sequel/adapters/swift/mysql.rb +0 -47
  449. data/lib/sequel/adapters/swift/postgres.rb +0 -45
  450. data/lib/sequel/adapters/swift/sqlite.rb +0 -47
  451. data/lib/sequel/adapters/utils/pg_types.rb +0 -68
  452. data/lib/sequel/dataset/mutation.rb +0 -109
  453. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -3
  454. data/lib/sequel/extensions/filter_having.rb +0 -59
  455. data/lib/sequel/extensions/hash_aliases.rb +0 -45
  456. data/lib/sequel/extensions/meta_def.rb +0 -31
  457. data/lib/sequel/extensions/query_literals.rb +0 -80
  458. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -22
  459. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -118
  460. data/lib/sequel/extensions/set_overrides.rb +0 -72
  461. data/lib/sequel/no_core_ext.rb +0 -1
  462. data/lib/sequel/plugins/association_autoreloading.rb +0 -7
  463. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -7
  464. data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -78
  465. data/lib/sequel/plugins/prepared_statements_associations.rb +0 -117
  466. data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -59
  467. data/lib/sequel/plugins/schema.rb +0 -80
  468. data/lib/sequel/plugins/scissors.rb +0 -33
  469. data/spec/adapters/db2_spec.rb +0 -160
  470. data/spec/adapters/firebird_spec.rb +0 -411
  471. data/spec/adapters/informix_spec.rb +0 -100
  472. data/spec/adapters/mssql_spec.rb +0 -706
  473. data/spec/adapters/mysql_spec.rb +0 -1287
  474. data/spec/adapters/oracle_spec.rb +0 -313
  475. data/spec/adapters/postgres_spec.rb +0 -3725
  476. data/spec/adapters/spec_helper.rb +0 -43
  477. data/spec/adapters/sqlanywhere_spec.rb +0 -170
  478. data/spec/adapters/sqlite_spec.rb +0 -653
  479. data/spec/bin_spec.rb +0 -254
  480. data/spec/core/connection_pool_spec.rb +0 -1016
  481. data/spec/core/database_spec.rb +0 -2531
  482. data/spec/core/dataset_spec.rb +0 -5098
  483. data/spec/core/deprecated_spec.rb +0 -70
  484. data/spec/core/expression_filters_spec.rb +0 -1243
  485. data/spec/core/mock_adapter_spec.rb +0 -462
  486. data/spec/core/object_graph_spec.rb +0 -303
  487. data/spec/core/placeholder_literalizer_spec.rb +0 -163
  488. data/spec/core/schema_generator_spec.rb +0 -179
  489. data/spec/core/schema_spec.rb +0 -1659
  490. data/spec/core/spec_helper.rb +0 -34
  491. data/spec/core/version_spec.rb +0 -7
  492. data/spec/core_extensions_spec.rb +0 -699
  493. data/spec/extensions/accessed_columns_spec.rb +0 -51
  494. data/spec/extensions/active_model_spec.rb +0 -123
  495. data/spec/extensions/after_initialize_spec.rb +0 -24
  496. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  497. data/spec/extensions/association_dependencies_spec.rb +0 -117
  498. data/spec/extensions/association_pks_spec.rb +0 -365
  499. data/spec/extensions/association_proxies_spec.rb +0 -86
  500. data/spec/extensions/auto_validations_spec.rb +0 -192
  501. data/spec/extensions/blacklist_security_spec.rb +0 -88
  502. data/spec/extensions/blank_spec.rb +0 -69
  503. data/spec/extensions/boolean_readers_spec.rb +0 -93
  504. data/spec/extensions/caching_spec.rb +0 -270
  505. data/spec/extensions/class_table_inheritance_spec.rb +0 -420
  506. data/spec/extensions/column_conflicts_spec.rb +0 -60
  507. data/spec/extensions/column_select_spec.rb +0 -108
  508. data/spec/extensions/columns_introspection_spec.rb +0 -91
  509. data/spec/extensions/composition_spec.rb +0 -242
  510. data/spec/extensions/connection_validator_spec.rb +0 -120
  511. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -274
  512. data/spec/extensions/constraint_validations_spec.rb +0 -325
  513. data/spec/extensions/core_refinements_spec.rb +0 -519
  514. data/spec/extensions/csv_serializer_spec.rb +0 -173
  515. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  516. data/spec/extensions/dataset_associations_spec.rb +0 -311
  517. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  518. data/spec/extensions/date_arithmetic_spec.rb +0 -150
  519. data/spec/extensions/defaults_setter_spec.rb +0 -101
  520. data/spec/extensions/delay_add_association_spec.rb +0 -52
  521. data/spec/extensions/dirty_spec.rb +0 -180
  522. data/spec/extensions/eager_each_spec.rb +0 -42
  523. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  524. data/spec/extensions/error_splitter_spec.rb +0 -18
  525. data/spec/extensions/error_sql_spec.rb +0 -20
  526. data/spec/extensions/eval_inspect_spec.rb +0 -73
  527. data/spec/extensions/filter_having_spec.rb +0 -40
  528. data/spec/extensions/force_encoding_spec.rb +0 -114
  529. data/spec/extensions/from_block_spec.rb +0 -21
  530. data/spec/extensions/graph_each_spec.rb +0 -109
  531. data/spec/extensions/hash_aliases_spec.rb +0 -24
  532. data/spec/extensions/hook_class_methods_spec.rb +0 -429
  533. data/spec/extensions/inflector_spec.rb +0 -183
  534. data/spec/extensions/input_transformer_spec.rb +0 -54
  535. data/spec/extensions/insert_returning_select_spec.rb +0 -46
  536. data/spec/extensions/instance_filters_spec.rb +0 -79
  537. data/spec/extensions/instance_hooks_spec.rb +0 -276
  538. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  539. data/spec/extensions/json_serializer_spec.rb +0 -291
  540. data/spec/extensions/lazy_attributes_spec.rb +0 -170
  541. data/spec/extensions/list_spec.rb +0 -267
  542. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  543. data/spec/extensions/many_through_many_spec.rb +0 -2172
  544. data/spec/extensions/meta_def_spec.rb +0 -21
  545. data/spec/extensions/migration_spec.rb +0 -712
  546. data/spec/extensions/modification_detection_spec.rb +0 -80
  547. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
  548. data/spec/extensions/named_timezones_spec.rb +0 -108
  549. data/spec/extensions/nested_attributes_spec.rb +0 -697
  550. data/spec/extensions/null_dataset_spec.rb +0 -85
  551. data/spec/extensions/optimistic_locking_spec.rb +0 -128
  552. data/spec/extensions/pagination_spec.rb +0 -118
  553. data/spec/extensions/pg_array_associations_spec.rb +0 -736
  554. data/spec/extensions/pg_array_ops_spec.rb +0 -143
  555. data/spec/extensions/pg_array_spec.rb +0 -395
  556. data/spec/extensions/pg_enum_spec.rb +0 -92
  557. data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
  558. data/spec/extensions/pg_hstore_spec.rb +0 -206
  559. data/spec/extensions/pg_inet_ops_spec.rb +0 -101
  560. data/spec/extensions/pg_inet_spec.rb +0 -52
  561. data/spec/extensions/pg_interval_spec.rb +0 -76
  562. data/spec/extensions/pg_json_ops_spec.rb +0 -229
  563. data/spec/extensions/pg_json_spec.rb +0 -218
  564. data/spec/extensions/pg_loose_count_spec.rb +0 -17
  565. data/spec/extensions/pg_range_ops_spec.rb +0 -58
  566. data/spec/extensions/pg_range_spec.rb +0 -404
  567. data/spec/extensions/pg_row_ops_spec.rb +0 -60
  568. data/spec/extensions/pg_row_plugin_spec.rb +0 -62
  569. data/spec/extensions/pg_row_spec.rb +0 -360
  570. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
  571. data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
  572. data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
  573. data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
  574. data/spec/extensions/prepared_statements_spec.rb +0 -103
  575. data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
  576. data/spec/extensions/pretty_table_spec.rb +0 -92
  577. data/spec/extensions/query_literals_spec.rb +0 -183
  578. data/spec/extensions/query_spec.rb +0 -102
  579. data/spec/extensions/rcte_tree_spec.rb +0 -392
  580. data/spec/extensions/round_timestamps_spec.rb +0 -43
  581. data/spec/extensions/schema_caching_spec.rb +0 -41
  582. data/spec/extensions/schema_dumper_spec.rb +0 -789
  583. data/spec/extensions/schema_spec.rb +0 -117
  584. data/spec/extensions/scissors_spec.rb +0 -26
  585. data/spec/extensions/select_remove_spec.rb +0 -38
  586. data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
  587. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  588. data/spec/extensions/serialization_spec.rb +0 -362
  589. data/spec/extensions/server_block_spec.rb +0 -90
  590. data/spec/extensions/set_overrides_spec.rb +0 -61
  591. data/spec/extensions/sharding_spec.rb +0 -198
  592. data/spec/extensions/shared_caching_spec.rb +0 -175
  593. data/spec/extensions/single_table_inheritance_spec.rb +0 -297
  594. data/spec/extensions/singular_table_names_spec.rb +0 -22
  595. data/spec/extensions/skip_create_refresh_spec.rb +0 -17
  596. data/spec/extensions/spec_helper.rb +0 -71
  597. data/spec/extensions/split_array_nil_spec.rb +0 -24
  598. data/spec/extensions/split_values_spec.rb +0 -22
  599. data/spec/extensions/sql_expr_spec.rb +0 -60
  600. data/spec/extensions/static_cache_spec.rb +0 -361
  601. data/spec/extensions/string_date_time_spec.rb +0 -95
  602. data/spec/extensions/string_stripper_spec.rb +0 -68
  603. data/spec/extensions/subclasses_spec.rb +0 -66
  604. data/spec/extensions/table_select_spec.rb +0 -71
  605. data/spec/extensions/tactical_eager_loading_spec.rb +0 -82
  606. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  607. data/spec/extensions/timestamps_spec.rb +0 -175
  608. data/spec/extensions/to_dot_spec.rb +0 -154
  609. data/spec/extensions/touch_spec.rb +0 -203
  610. data/spec/extensions/tree_spec.rb +0 -274
  611. data/spec/extensions/typecast_on_load_spec.rb +0 -80
  612. data/spec/extensions/unlimited_update_spec.rb +0 -20
  613. data/spec/extensions/update_or_create_spec.rb +0 -87
  614. data/spec/extensions/update_primary_key_spec.rb +0 -100
  615. data/spec/extensions/update_refresh_spec.rb +0 -53
  616. data/spec/extensions/validate_associated_spec.rb +0 -52
  617. data/spec/extensions/validation_class_methods_spec.rb +0 -1027
  618. data/spec/extensions/validation_helpers_spec.rb +0 -541
  619. data/spec/extensions/xml_serializer_spec.rb +0 -207
  620. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  621. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  622. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  623. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  624. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  625. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  626. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  627. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  628. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  629. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  630. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  631. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  632. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  633. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  634. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  635. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  636. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  637. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  638. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  639. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  640. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  641. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  642. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  643. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  644. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  645. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  646. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  647. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  648. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  649. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  650. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  651. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  652. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  653. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  654. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  655. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  656. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  657. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  658. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  659. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  660. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  661. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  662. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  663. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  664. data/spec/guards_helper.rb +0 -55
  665. data/spec/integration/associations_test.rb +0 -2454
  666. data/spec/integration/database_test.rb +0 -113
  667. data/spec/integration/dataset_test.rb +0 -1808
  668. data/spec/integration/eager_loader_test.rb +0 -687
  669. data/spec/integration/migrator_test.rb +0 -240
  670. data/spec/integration/model_test.rb +0 -226
  671. data/spec/integration/plugin_test.rb +0 -2240
  672. data/spec/integration/prepared_statement_test.rb +0 -467
  673. data/spec/integration/schema_test.rb +0 -817
  674. data/spec/integration/spec_helper.rb +0 -48
  675. data/spec/integration/timezone_test.rb +0 -86
  676. data/spec/integration/transaction_test.rb +0 -374
  677. data/spec/integration/type_test.rb +0 -133
  678. data/spec/model/association_reflection_spec.rb +0 -525
  679. data/spec/model/associations_spec.rb +0 -4426
  680. data/spec/model/base_spec.rb +0 -759
  681. data/spec/model/class_dataset_methods_spec.rb +0 -146
  682. data/spec/model/dataset_methods_spec.rb +0 -149
  683. data/spec/model/eager_loading_spec.rb +0 -2137
  684. data/spec/model/hooks_spec.rb +0 -604
  685. data/spec/model/inflector_spec.rb +0 -26
  686. data/spec/model/model_spec.rb +0 -982
  687. data/spec/model/plugins_spec.rb +0 -299
  688. data/spec/model/record_spec.rb +0 -2147
  689. data/spec/model/spec_helper.rb +0 -46
  690. data/spec/model/validations_spec.rb +0 -193
  691. data/spec/sequel_coverage.rb +0 -15
  692. data/spec/spec_config.rb +0 -10
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Sequel
2
4
  class Dataset
3
5
  # ---------------------
@@ -5,11 +7,6 @@ module Sequel
5
7
  # These methods don't fit cleanly into another section.
6
8
  # ---------------------
7
9
 
8
- NOTIMPL_MSG = "This method must be overridden in Sequel adapters".freeze
9
- ARRAY_ACCESS_ERROR_MSG = 'You cannot call Dataset#[] with an integer or with no arguments.'.freeze
10
- ARG_BLOCK_ERROR_MSG = 'Must use either an argument or a block, not both'.freeze
11
- IMPORT_ERROR_MSG = 'Using Sequel::Dataset#import an empty column array is not allowed'.freeze
12
-
13
10
  # The database related to this dataset. This is the Database instance that
14
11
  # will execute all of this dataset's queries.
15
12
  attr_reader :db
@@ -28,12 +25,14 @@ module Sequel
28
25
  def initialize(db)
29
26
  @db = db
30
27
  @opts = OPTS
28
+ @cache = {}
29
+ freeze
31
30
  end
32
31
 
33
- # Define a hash value such that datasets with the same DB, opts, and SQL
32
+ # Define a hash value such that datasets with the same class, DB, and opts
34
33
  # will be considered equal.
35
34
  def ==(o)
36
- o.is_a?(self.class) && db == o.db && opts == o.opts && sql == o.sql
35
+ o.is_a?(self.class) && db == o.db && opts == o.opts
37
36
  end
38
37
 
39
38
  # An object representing the current date or time, should be an instance
@@ -47,18 +46,16 @@ module Sequel
47
46
  self == o
48
47
  end
49
48
 
50
- # Similar to #clone, but returns an unfrozen clone if the receiver is frozen.
49
+ # Return self, as datasets are always frozen.
51
50
  def dup
52
- o = clone
53
- o.instance_variable_set(:@frozen, false) if frozen?
54
- o
51
+ self
55
52
  end
56
53
 
57
54
  # Yield a dataset for each server in the connection pool that is tied to that server.
58
55
  # Intended for use in sharded environments where all servers need to be modified
59
56
  # with the same data:
60
57
  #
61
- # DB[:configs].where(:key=>'setting').each_server{|ds| ds.update(:value=>'new_value')}
58
+ # DB[:configs].where(key: 'setting').each_server{|ds| ds.update(value: 'new_value')}
62
59
  def each_server
63
60
  db.servers.each{|s| yield server(s)}
64
61
  end
@@ -72,15 +69,22 @@ module Sequel
72
69
  string.gsub(/[\\%_]/){|m| "\\#{m}"}
73
70
  end
74
71
 
75
- # Sets the frozen flag on the dataset, so you can't modify it. Returns the receiver.
76
- def freeze
77
- @frozen = true
78
- self
79
- end
72
+ if TRUE_FREEZE
73
+ # Freeze the opts when freezing the dataset.
74
+ def freeze
75
+ @opts.freeze
76
+ super
77
+ end
78
+ else
79
+ # :nocov:
80
+ def freeze # :nodoc:
81
+ self
82
+ end
80
83
 
81
- # Whether the object is frozen.
82
- def frozen?
83
- @frozen == true
84
+ def frozen? # :nodoc:
85
+ true
86
+ end
87
+ # :nocov:
84
88
  end
85
89
 
86
90
  # Alias of +first_source_alias+
@@ -94,7 +98,7 @@ module Sequel
94
98
  # DB[:table].first_source_alias
95
99
  # # => :table
96
100
  #
97
- # DB[:table___t].first_source_alias
101
+ # DB[Sequel[:table].as(:t)].first_source_alias
98
102
  # # => :t
99
103
  def first_source_alias
100
104
  source = @opts[:from]
@@ -119,7 +123,7 @@ module Sequel
119
123
  # DB[:table].first_source_table
120
124
  # # => :table
121
125
  #
122
- # DB[:table___t].first_source_table
126
+ # DB[Sequel[:table].as(:t)].first_source_table
123
127
  # # => :table
124
128
  def first_source_table
125
129
  source = @opts[:from]
@@ -137,30 +141,10 @@ module Sequel
137
141
  end
138
142
  end
139
143
 
140
- # Define a hash value such that datasets with the same DB, opts, and SQL
141
- # will have the same hash value
144
+ # Define a hash value such that datasets with the same class, DB, and opts,
145
+ # will have the same hash value.
142
146
  def hash
143
- [db, opts, sql].hash
144
- end
145
-
146
- # The String instance method to call on identifiers before sending them to
147
- # the database.
148
- def identifier_input_method
149
- if defined?(@identifier_input_method)
150
- @identifier_input_method
151
- else
152
- @identifier_input_method = db.identifier_input_method
153
- end
154
- end
155
-
156
- # The String instance method to call on identifiers before sending them to
157
- # the database.
158
- def identifier_output_method
159
- if defined?(@identifier_output_method)
160
- @identifier_output_method
161
- else
162
- @identifier_output_method = db.identifier_output_method
163
- end
147
+ [self.class, db, opts].hash
164
148
  end
165
149
 
166
150
  # Returns a string representation of the dataset including the class name
@@ -180,6 +164,12 @@ module Sequel
180
164
  :x_sequel_row_number_x
181
165
  end
182
166
 
167
+ # The row_proc for this database, should be any object that responds to +call+ with
168
+ # a single hash argument and returns the object you want #each to return.
169
+ def row_proc
170
+ @opts[:row_proc]
171
+ end
172
+
183
173
  # Splits a possible implicit alias in +c+, handling both SQL::AliasedExpressions
184
174
  # and Symbols. Returns an array of two elements, with the first being the
185
175
  # main expression, and the second being the alias.
@@ -201,7 +191,7 @@ module Sequel
201
191
  # SQL identifier that represents the unqualified column for the given value.
202
192
  # The given value should be a Symbol, SQL::Identifier, SQL::QualifiedIdentifier,
203
193
  # or SQL::AliasedExpression containing one of those. In other cases, this
204
- # returns nil
194
+ # returns nil.
205
195
  def unqualified_column_for(v)
206
196
  unless v.is_a?(String)
207
197
  _unqualified_column_for(v)
@@ -236,7 +226,7 @@ module Sequel
236
226
  used_aliases += opts[:join].map{|j| j.table_alias ? alias_alias_symbol(j.table_alias) : alias_symbol(j.table)} if opts[:join]
237
227
  if used_aliases.include?(table_alias)
238
228
  i = 0
239
- loop do
229
+ while true
240
230
  ta = :"#{table_alias}_#{i}"
241
231
  return ta unless used_aliases.include?(ta)
242
232
  i += 1
@@ -246,8 +236,110 @@ module Sequel
246
236
  end
247
237
  end
248
238
 
239
+ # Return a modified dataset with quote_identifiers set.
240
+ def with_quote_identifiers(v)
241
+ clone(:quote_identifiers=>v, :skip_symbol_cache=>true)
242
+ end
243
+
244
+ protected
245
+
246
+ # Access the cache for the current dataset. Should be used with caution,
247
+ # as access to the cache is not thread safe without a mutex if other
248
+ # threads can reference the dataset. Symbol keys prefixed with an
249
+ # underscore are reserved for internal use.
250
+ attr_reader :cache
251
+
252
+ # Retreive a value from the dataset's cache in a thread safe manner.
253
+ def cache_get(k)
254
+ Sequel.synchronize{@cache[k]}
255
+ end
256
+
257
+ # Set a value in the dataset's cache in a thread safe manner.
258
+ def cache_set(k, v)
259
+ Sequel.synchronize{@cache[k] = v}
260
+ end
261
+
262
+ # Clear the columns hash for the current dataset. This is not a
263
+ # thread safe operation, so it should only be used if the dataset
264
+ # could not be used by another thread (such as one that was just
265
+ # created via clone).
266
+ def clear_columns_cache
267
+ @cache.delete(:_columns)
268
+ end
269
+
270
+ # The cached columns for the current dataset.
271
+ def _columns
272
+ cache_get(:_columns)
273
+ end
274
+
249
275
  private
250
276
 
277
+ # Check the cache for the given key, returning the value.
278
+ # Otherwise, yield to get the dataset and cache the dataset under the given key.
279
+ def cached_dataset(key)
280
+ unless ds = cache_get(key)
281
+ ds = yield
282
+ cache_set(key, ds)
283
+ end
284
+
285
+ ds
286
+ end
287
+
288
+ # Return a cached placeholder literalizer for the given key if there
289
+ # is one for this dataset. If there isn't one, increment the counter
290
+ # for the number of calls for the key, and if the counter is at least
291
+ # three, then create a placeholder literalizer by yielding to the block,
292
+ # and cache it.
293
+ def cached_placeholder_literalizer(key)
294
+ if loader = cache_get(key)
295
+ return loader unless loader.is_a?(Integer)
296
+ loader += 1
297
+
298
+ if loader >= 3
299
+ loader = Sequel::Dataset::PlaceholderLiteralizer.loader(self){|pl, _| yield pl}
300
+ cache_set(key, loader)
301
+ else
302
+ cache_set(key, loader + 1)
303
+ loader = nil
304
+ end
305
+ elsif cache_sql?
306
+ cache_set(key, 1)
307
+ end
308
+
309
+ loader
310
+ end
311
+
312
+ # Return a cached placeholder literalizer for the key, unless where_block is
313
+ # nil and where_args is an empty array or hash. This is designed to guard
314
+ # against placeholder literalizer use when passing arguments to where
315
+ # in the uncached case and filter_expr if a cached placeholder literalizer
316
+ # is used.
317
+ def cached_where_placeholder_literalizer(where_args, where_block, key, &block)
318
+ where_args = where_args[0] if where_args.length == 1
319
+ unless where_block
320
+ return if where_args == OPTS || where_args == EMPTY_ARRAY
321
+ end
322
+
323
+ cached_placeholder_literalizer(key, &block)
324
+ end
325
+
326
+ # Set the columns for the current dataset.
327
+ def columns=(v)
328
+ cache_set(:_columns, v)
329
+ end
330
+
331
+ # Set the db, opts, and cache for the copy of the dataset.
332
+ def initialize_clone(c, _=nil)
333
+ @db = c.db
334
+ @opts = Hash[c.opts]
335
+ if cols = c.cache_get(:_columns)
336
+ @cache = {:_columns=>cols}
337
+ else
338
+ @cache = {}
339
+ end
340
+ end
341
+ alias initialize_copy initialize_clone
342
+
251
343
  # Internal recursive version of unqualified_column_for, handling Strings inside
252
344
  # of other objects.
253
345
  def _unqualified_column_for(v)
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Sequel
2
4
  class Dataset
3
5
  # PlaceholderLiteralizer allows you to record the application of arbitrary changes
@@ -13,7 +15,7 @@ module Sequel
13
15
  # Example:
14
16
  #
15
17
  # loader = Sequel::Dataset::PlaceholderLiteralizer.loader(DB[:items]) do |pl, ds|
16
- # ds.where(:id=>pl.arg).exclude(:name=>pl.arg).limit(1)
18
+ # ds.where(id: pl.arg).exclude(name: pl.arg).limit(1)
17
19
  # end
18
20
  # loader.first(1, "foo")
19
21
  # # SELECT * FROM items WHERE ((id = 1) AND (name != 'foo')) LIMIT 1
@@ -25,7 +27,7 @@ module Sequel
25
27
  # Note that this method does not handle all possible cases. For example:
26
28
  #
27
29
  # loader = Sequel::Dataset::PlaceholderLiteralizer.loader(DB[:items]) do |pl, ds|
28
- # ds.join(pl.arg, :item_id=>:id)
30
+ # ds.join(pl.arg, item_id: :id)
29
31
  # end
30
32
  # loader.all(:cart_items)
31
33
  #
@@ -33,7 +35,7 @@ module Sequel
33
35
  # best to add a table alias when joining:
34
36
  #
35
37
  # loader = Sequel::Dataset::PlaceholderLiteralizer.loader(DB[:items]) do |pl, ds|
36
- # ds.join(Sequel.as(pl.arg, :t), :item_id=>:id)
38
+ # ds.join(Sequel.as(pl.arg, :t), item_id: :id)
37
39
  # end
38
40
  # loader.all(:cart_items)
39
41
  #
@@ -49,6 +51,7 @@ module Sequel
49
51
  @recorder = recorder
50
52
  @pos = pos
51
53
  @transformer = transformer
54
+ freeze
52
55
  end
53
56
 
54
57
  # Record the SQL query offset, argument position, and transforming block where the
@@ -74,23 +77,8 @@ module Sequel
74
77
  # Yields the receiver and the dataset to the block, which should
75
78
  # call #arg on the receiver for each placeholder argument, and
76
79
  # return the dataset that you want to load.
77
- def loader(dataset)
78
- @argn = -1
79
- @args = []
80
- ds = yield self, dataset
81
- sql = ds.clone(:placeholder_literalizer=>self).sql
82
-
83
- last_offset = 0
84
- fragments = @args.map do |used_sql, offset, arg, t|
85
- raise Error, "placeholder literalizer argument literalized into different string than dataset returned" unless used_sql.equal?(sql)
86
- a = [sql[last_offset...offset], arg, t]
87
- last_offset = offset
88
- a
89
- end
90
- final_sql = sql[last_offset..-1]
91
-
92
- arity = @argn+1
93
- PlaceholderLiteralizer.new(ds.clone, fragments, final_sql, arity)
80
+ def loader(dataset, &block)
81
+ PlaceholderLiteralizer.new(*process(dataset, &block))
94
82
  end
95
83
 
96
84
  # Return an Argument with the specified position, or the next position. In
@@ -104,10 +92,53 @@ module Sequel
104
92
  end
105
93
 
106
94
  # Record the offset at which the argument is used in the SQL query, and any
107
- # transforming
95
+ # transforming block.
108
96
  def use(sql, arg, transformer)
109
97
  @args << [sql, sql.length, arg, transformer]
110
98
  end
99
+
100
+ private
101
+
102
+ # Return an array with two elements, the first being an
103
+ # SQL string with interpolated prepared argument placeholders
104
+ # (suitable for inspect), the the second being an array of
105
+ # SQL fragments suitable for using for creating a
106
+ # Sequel::SQL::PlaceholderLiteralString. Designed for use with
107
+ # emulated prepared statements.
108
+ def prepared_sql_and_frags(dataset, prepared_args, &block)
109
+ _, frags, final_sql, _ = process(dataset, &block)
110
+
111
+ frags = frags.map(&:first)
112
+ prepared_sql = String.new
113
+ frags.each_with_index do |sql, i|
114
+ prepared_sql << sql
115
+ prepared_sql << "$#{prepared_args[i]}"
116
+ end
117
+ frags << final_sql
118
+ prepared_sql << final_sql
119
+
120
+ [prepared_sql, frags]
121
+ end
122
+
123
+ # Internals of #loader and #prepared_sql_and_frags.
124
+ def process(dataset)
125
+ @argn = -1
126
+ @args = []
127
+ ds = yield self, dataset
128
+ sql = ds.clone(:placeholder_literalizer=>self).sql
129
+
130
+ last_offset = 0
131
+ fragments = @args.map do |used_sql, offset, arg, t|
132
+ raise Error, "placeholder literalizer argument literalized into different string than dataset returned" unless used_sql.equal?(sql)
133
+ a = [sql[last_offset...offset], arg, t]
134
+ last_offset = offset
135
+ a
136
+ end
137
+ final_sql = sql[last_offset..-1]
138
+
139
+ arity = @argn+1
140
+ [ds, fragments, final_sql, arity]
141
+ end
111
142
  end
112
143
 
113
144
  # Create a PlaceholderLiteralizer by yielding a Recorder and dataset to the
@@ -123,13 +154,24 @@ module Sequel
123
154
  @fragments = fragments
124
155
  @final_sql = final_sql
125
156
  @arity = arity
157
+ freeze
158
+ end
159
+
160
+ # Freeze the fragments and final SQL when freezing the literalizer.
161
+ def freeze
162
+ @fragments.freeze
163
+ @final_sql.freeze
164
+ super
126
165
  end
127
166
 
128
167
  # Return a new PlaceholderLiteralizer with a modified dataset. This yields the
129
168
  # receiver's dataset to the block, and the block should return the new dataset
130
169
  # to use.
131
170
  def with_dataset
132
- dup.instance_exec{@dataset = yield @dataset; self}
171
+ dataset = yield @dataset
172
+ other = dup
173
+ other.instance_variable_set(:@dataset, dataset)
174
+ other.freeze
133
175
  end
134
176
 
135
177
  # Return an array of all objects by running the SQL query for the given arguments.
@@ -157,7 +199,7 @@ module Sequel
157
199
  # Return the SQL query to use for the given arguments.
158
200
  def sql(*args)
159
201
  raise Error, "wrong number of arguments (#{args.length} for #{@arity})" unless args.length == @arity
160
- s = ''
202
+ s = String.new
161
203
  ds = @dataset
162
204
  @fragments.each do |sql, i, transformer|
163
205
  s << sql
@@ -169,9 +211,7 @@ module Sequel
169
211
  end
170
212
  ds.literal_append(s, v)
171
213
  end
172
- if sql = @final_sql
173
- s << sql
174
- end
214
+ s << @final_sql
175
215
  s
176
216
  end
177
217
  end
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Sequel
2
4
  class Dataset
3
5
  # ---------------------
@@ -34,33 +36,44 @@ module Sequel
34
36
  end
35
37
  end
36
38
  private_class_method :prepared_statements_module
37
-
39
+
38
40
  # Default implementation of the argument mapper to allow
39
41
  # native database support for bind variables and prepared
40
42
  # statements (as opposed to the emulated ones used by default).
41
43
  module ArgumentMapper
42
44
  # The name of the prepared statement, if any.
43
- attr_accessor :prepared_statement_name
44
-
45
+ def prepared_statement_name
46
+ @opts[:prepared_statement_name]
47
+ end
48
+
45
49
  # The bind arguments to use for running this prepared statement
46
- attr_accessor :bind_arguments
50
+ def bind_arguments
51
+ @opts[:bind_arguments]
52
+ end
47
53
 
48
54
  # Set the bind arguments based on the hash and call super.
49
- def call(bind_vars={}, &block)
50
- ds = bind(bind_vars)
51
- ds.prepared_sql
52
- ds.bind_arguments = ds.map_to_prepared_args(ds.opts[:bind_vars])
53
- ds.run(&block)
55
+ def call(bind_vars=OPTS, &block)
56
+ sql = prepared_sql
57
+ prepared_args.freeze
58
+ ps = bind(bind_vars)
59
+ ps.clone(:bind_arguments=>ps.map_to_prepared_args(ps.opts[:bind_vars]), :sql=>sql, :prepared_sql=>sql).run(&block)
54
60
  end
55
61
 
56
62
  # Override the given *_sql method based on the type, and
57
63
  # cache the result of the sql.
58
64
  def prepared_sql
59
- return @prepared_sql if @prepared_sql
60
- @prepared_args ||= []
61
- @prepared_sql = super
62
- @opts[:sql] = @prepared_sql
63
- @prepared_sql
65
+ if sql = @opts[:prepared_sql] || cache_get(:_prepared_sql)
66
+ return sql
67
+ end
68
+ cache_set(:_prepared_sql, super)
69
+ end
70
+
71
+ private
72
+
73
+ # Report that prepared statements are not emulated, since
74
+ # all adapters that use this use native prepared statements.
75
+ def emulate_prepared_statements?
76
+ false
64
77
  end
65
78
  end
66
79
 
@@ -71,29 +84,37 @@ module Sequel
71
84
  # into the query, which works on all databases, as it is no different
72
85
  # from using the dataset without bind variables.
73
86
  module PreparedStatementMethods
74
- PLACEHOLDER_RE = /\A\$(.*)\z/
75
-
76
87
  # Whether to log the full SQL query. By default, just the prepared statement
77
88
  # name is generally logged on adapters that support native prepared statements.
78
- attr_accessor :log_sql
89
+ def log_sql
90
+ @opts[:log_sql]
91
+ end
79
92
 
80
93
  # The type of prepared statement, should be one of :select, :first,
81
- # :insert, :update, or :delete
82
- attr_accessor :prepared_type
94
+ # :insert, :update, :delete, or :single_value
95
+ def prepared_type
96
+ @opts[:prepared_type]
97
+ end
83
98
 
84
99
  # The array/hash of bound variable placeholder names.
85
- attr_accessor :prepared_args
100
+ def prepared_args
101
+ @opts[:prepared_args]
102
+ end
86
103
 
87
104
  # The dataset that created this prepared statement.
88
- attr_accessor :orig_dataset
105
+ def orig_dataset
106
+ @opts[:orig_dataset]
107
+ end
89
108
 
90
109
  # The argument to supply to insert and update, which may use
91
110
  # placeholders specified by prepared_args
92
- attr_accessor :prepared_modify_values
111
+ def prepared_modify_values
112
+ @opts[:prepared_modify_values]
113
+ end
93
114
 
94
115
  # Sets the prepared_args to the given hash and runs the
95
116
  # prepared statement.
96
- def call(bind_vars={}, &block)
117
+ def call(bind_vars=OPTS, &block)
97
118
  bind(bind_vars).run(&block)
98
119
  end
99
120
 
@@ -110,21 +131,27 @@ module Sequel
110
131
  orig_dataset.columns
111
132
  end
112
133
 
134
+ # Disallow use of delayed evaluations in prepared statements.
135
+ def delayed_evaluation_sql_append(sql, delay)
136
+ raise Error, "delayed evaluations cannot be used in prepared statements" if @opts[:no_delayed_evaluations]
137
+ super
138
+ end
139
+
113
140
  # Returns the SQL for the prepared statement, depending on
114
141
  # the type of the statement and the prepared_modify_values.
115
142
  def prepared_sql
116
- case @prepared_type
143
+ case prepared_type
117
144
  when :select, :all, :each
118
145
  # Most common scenario, so listed first.
119
146
  select_sql
120
- when :first
147
+ when :first, :single_value
121
148
  clone(:limit=>1).select_sql
122
149
  when :insert_select
123
- insert_select_sql(*@prepared_modify_values)
124
- when :insert
125
- insert_sql(*@prepared_modify_values)
150
+ insert_select_sql(*prepared_modify_values)
151
+ when :insert, :insert_pk
152
+ insert_sql(*prepared_modify_values)
126
153
  when :update
127
- update_sql(*@prepared_modify_values)
154
+ update_sql(*prepared_modify_values)
128
155
  when :delete
129
156
  delete_sql
130
157
  else
@@ -136,13 +163,8 @@ module Sequel
136
163
  # prepared_args is present. If so, they are considered placeholders,
137
164
  # and they are substituted using prepared_arg.
138
165
  def literal_symbol_append(sql, v)
139
- if @opts[:bind_vars] and match = PLACEHOLDER_RE.match(v.to_s)
140
- s = match[1].to_sym
141
- if prepared_arg?(s)
142
- literal_append(sql, prepared_arg(s))
143
- else
144
- sql << v.to_s
145
- end
166
+ if @opts[:bind_vars] && /\A\$(.*)\z/ =~ v
167
+ literal_append(sql, prepared_arg($1.to_sym))
146
168
  else
147
169
  super
148
170
  end
@@ -157,13 +179,10 @@ module Sequel
157
179
 
158
180
  protected
159
181
 
160
- # Run the method based on the type of prepared statement, with
161
- # :select running #all to get all of the rows, and the other
162
- # types running the method with the same name as the type.
182
+ # Run the method based on the type of prepared statement.
163
183
  def run(&block)
164
- case @prepared_type
184
+ case prepared_type
165
185
  when :select, :all
166
- # Most common scenario, so listed first
167
186
  all(&block)
168
187
  when :each
169
188
  each(&block)
@@ -172,20 +191,24 @@ module Sequel
172
191
  when :first
173
192
  first
174
193
  when :insert, :update, :delete
175
- if opts[:returning] && supports_returning?(@prepared_type)
194
+ if opts[:returning] && supports_returning?(prepared_type)
176
195
  returning_fetch_rows(prepared_sql)
177
- elsif @prepared_type == :delete
196
+ elsif prepared_type == :delete
178
197
  delete
179
198
  else
180
- send(@prepared_type, *@prepared_modify_values)
199
+ public_send(prepared_type, *prepared_modify_values)
181
200
  end
201
+ when :insert_pk
202
+ fetch_rows(prepared_sql){|r| return r.values.first}
182
203
  when Array
183
- case @prepared_type.at(0)
184
- when :map, :to_hash, :to_hash_groups
185
- send(*@prepared_type, &block)
204
+ case prepared_type[0]
205
+ when :map, :as_hash, :to_hash, :to_hash_groups
206
+ public_send(*prepared_type, &block)
186
207
  end
208
+ when :single_value
209
+ single_value
187
210
  else
188
- all(&block)
211
+ raise Error, "unsupported prepared statement type used: #{prepared_type.inspect}"
189
212
  end
190
213
  end
191
214
 
@@ -196,13 +219,7 @@ module Sequel
196
219
  @opts[:bind_vars][k]
197
220
  end
198
221
 
199
- # Whether there is a bound value for the given key.
200
- def prepared_arg?(k)
201
- @opts[:bind_vars].has_key?(k)
202
- end
203
-
204
- # The symbol cache should always be skipped, since placeholders
205
- # are symbols.
222
+ # The symbol cache should always be skipped, since placeholders are symbols.
206
223
  def skip_symbol_cache?
207
224
  true
208
225
  end
@@ -211,10 +228,12 @@ module Sequel
211
228
  # support and using the same argument hash so that you can use
212
229
  # bind variables/prepared arguments in subselects.
213
230
  def subselect_sql_append(sql, ds)
214
- ps = ds.clone(:append_sql=>sql).prepare(:select)
215
- ps = ps.bind(@opts[:bind_vars]) if @opts[:bind_vars]
216
- ps.prepared_args = prepared_args
217
- ps.prepared_sql
231
+ subselect_sql_dataset(sql, ds).prepared_sql
232
+ end
233
+
234
+ def subselect_sql_dataset(sql, ds)
235
+ super.clone(:prepared_args=>prepared_args, :bind_vars=>@opts[:bind_vars]).
236
+ send(:to_prepared_statement, :select, nil, :extend=>prepared_statement_modules)
218
237
  end
219
238
  end
220
239
 
@@ -242,56 +261,126 @@ module Sequel
242
261
  prepared_args << k
243
262
  prepared_arg_placeholder
244
263
  end
264
+ end
265
+
266
+ # Prepared statements emulation support for adapters that don't
267
+ # support native prepared statements. Uses a placeholder
268
+ # literalizer to hold the prepared sql with the ability to
269
+ # interpolate arguments to prepare the final SQL string.
270
+ module EmulatePreparedStatementMethods
271
+ include UnnumberedArgumentMapper
272
+
273
+ def run(&block)
274
+ if @opts[:prepared_sql_frags]
275
+ sql = literal(Sequel::SQL::PlaceholderLiteralString.new(@opts[:prepared_sql_frags], @opts[:bind_arguments], false))
276
+ clone(:prepared_sql_frags=>nil, :sql=>sql, :prepared_sql=>sql).run(&block)
277
+ else
278
+ super
279
+ end
280
+ end
281
+
282
+ private
245
283
 
246
- # Always assume there is a prepared arg in the argument mapper.
247
- def prepared_arg?(k)
284
+ # Turn emulation of prepared statements back on, since ArgumentMapper
285
+ # turns it off.
286
+ def emulate_prepared_statements?
248
287
  true
249
288
  end
289
+
290
+ def emulated_prepared_statement(type, name, values)
291
+ prepared_sql, frags = Sequel::Dataset::PlaceholderLiteralizer::Recorder.new.send(:prepared_sql_and_frags, self, prepared_args) do |pl, ds|
292
+ ds = ds.clone(:recorder=>pl)
293
+
294
+ case type
295
+ when :first, :single_value
296
+ ds.limit(1)
297
+ when :update, :insert, :insert_select, :delete
298
+ ds.with_sql(:"#{type}_sql", *values)
299
+ when :insert_pk
300
+ ds.with_sql(:insert_sql, *values)
301
+ else
302
+ ds
303
+ end
304
+ end
305
+
306
+ prepared_args.freeze
307
+ clone(:prepared_sql_frags=>frags, :prepared_sql=>prepared_sql, :sql=>prepared_sql)
308
+ end
309
+
310
+ # Associates the argument with name k with the next position in
311
+ # the output array.
312
+ def prepared_arg(k)
313
+ prepared_args << k
314
+ @opts[:recorder].arg
315
+ end
316
+
317
+ def subselect_sql_dataset(sql, ds)
318
+ super.clone(:recorder=>@opts[:recorder]).
319
+ with_extend(EmulatePreparedStatementMethods)
320
+ end
250
321
  end
251
322
 
252
323
  # Set the bind variables to use for the call. If bind variables have
253
324
  # already been set for this dataset, they are updated with the contents
254
325
  # of bind_vars.
255
326
  #
256
- # DB[:table].filter(:id=>:$id).bind(:id=>1).call(:first)
327
+ # DB[:table].where(id: :$id).bind(id: 1).call(:first)
257
328
  # # SELECT * FROM table WHERE id = ? LIMIT 1 -- (1)
258
329
  # # => {:id=>1}
259
- def bind(bind_vars={})
260
- clone(:bind_vars=>@opts[:bind_vars] ? Hash[@opts[:bind_vars]].merge!(bind_vars) : bind_vars)
330
+ def bind(bind_vars=OPTS)
331
+ bind_vars = if bv = @opts[:bind_vars]
332
+ bv.merge(bind_vars).freeze
333
+ else
334
+ if bind_vars.frozen?
335
+ bind_vars
336
+ else
337
+ Hash[bind_vars]
338
+ end
339
+ end
340
+
341
+ clone(:bind_vars=>bind_vars)
261
342
  end
262
343
 
263
- # For the given type (:select, :first, :insert, :insert_select, :update, or :delete),
344
+ # For the given type (:select, :first, :insert, :insert_select, :update, :delete, or :single_value),
264
345
  # run the sql with the bind variables specified in the hash. +values+ is a hash passed to
265
346
  # insert or update (if one of those types is used), which may contain placeholders.
266
347
  #
267
- # DB[:table].filter(:id=>:$id).call(:first, :id=>1)
348
+ # DB[:table].where(id: :$id).call(:first, id: 1)
268
349
  # # SELECT * FROM table WHERE id = ? LIMIT 1 -- (1)
269
350
  # # => {:id=>1}
270
- def call(type, bind_variables={}, *values, &block)
271
- prepare(type, nil, *values).call(bind_variables, &block)
351
+ def call(type, bind_variables=OPTS, *values, &block)
352
+ to_prepared_statement(type, values, :extend=>bound_variable_modules).call(bind_variables, &block)
272
353
  end
273
354
 
274
355
  # Prepare an SQL statement for later execution. Takes a type similar to #call,
275
- # and the +name+ symbol of the prepared statement. While +name+ defaults to +nil+,
276
- # it should always be provided as a symbol for the name of the prepared statement,
277
- # as some databases require that prepared statements have names.
356
+ # and the +name+ symbol of the prepared statement.
278
357
  #
279
358
  # This returns a clone of the dataset extended with PreparedStatementMethods,
280
359
  # which you can +call+ with the hash of bind variables to use.
281
360
  # The prepared statement is also stored in
282
- # the associated database, where it can be called by name.
361
+ # the associated Database, where it can be called by name.
283
362
  # The following usage is identical:
284
363
  #
285
- # ps = DB[:table].filter(:name=>:$name).prepare(:first, :select_by_name)
364
+ # ps = DB[:table].where(name: :$name).prepare(:first, :select_by_name)
286
365
  #
287
- # ps.call(:name=>'Blah')
366
+ # ps.call(name: 'Blah')
288
367
  # # SELECT * FROM table WHERE name = ? -- ('Blah')
289
368
  # # => {:id=>1, :name=>'Blah'}
290
369
  #
291
- # DB.call(:select_by_name, :name=>'Blah') # Same thing
292
- def prepare(type, name=nil, *values)
293
- ps = to_prepared_statement(type, values)
294
- db.set_prepared_statement(name, ps) if name
370
+ # DB.call(:select_by_name, name: 'Blah') # Same thing
371
+ def prepare(type, name, *values)
372
+ ps = to_prepared_statement(type, values, :name=>name, :extend=>prepared_statement_modules, :no_delayed_evaluations=>true)
373
+
374
+ ps = if ps.send(:emulate_prepared_statements?)
375
+ ps = ps.with_extend(EmulatePreparedStatementMethods)
376
+ ps.send(:emulated_prepared_statement, type, name, values)
377
+ else
378
+ sql = ps.prepared_sql
379
+ ps.prepared_args.freeze
380
+ ps.clone(:prepared_sql=>sql, :sql=>sql)
381
+ end
382
+
383
+ db.set_prepared_statement(name, ps)
295
384
  ps
296
385
  end
297
386
 
@@ -299,13 +388,13 @@ module Sequel
299
388
 
300
389
  # Return a cloned copy of the current dataset extended with
301
390
  # PreparedStatementMethods, setting the type and modify values.
302
- def to_prepared_statement(type, values=nil)
303
- ps = bind
304
- ps.extend(PreparedStatementMethods)
305
- ps.orig_dataset = self
306
- ps.prepared_type = type
307
- ps.prepared_modify_values = values
308
- ps
391
+ def to_prepared_statement(type, values=nil, opts=OPTS)
392
+ mods = opts[:extend] || []
393
+ mods += [PreparedStatementMethods]
394
+
395
+ bind.
396
+ clone(:prepared_statement_name=>opts[:name], :prepared_type=>type, :prepared_modify_values=>values, :orig_dataset=>self, :no_cache_sql=>true, :prepared_args=>@opts[:prepared_args]||[], :no_delayed_evaluations=>opts[:no_delayed_evaluations]).
397
+ with_extend(*mods)
309
398
  end
310
399
 
311
400
  private
@@ -315,6 +404,20 @@ module Sequel
315
404
  false
316
405
  end
317
406
 
407
+ def bound_variable_modules
408
+ prepared_statement_modules
409
+ end
410
+
411
+ # Whether prepared statements should be emulated. True by
412
+ # default so that adapters have to opt in.
413
+ def emulate_prepared_statements?
414
+ true
415
+ end
416
+
417
+ def prepared_statement_modules
418
+ []
419
+ end
420
+
318
421
  # The argument placeholder. Most databases used unnumbered
319
422
  # arguments with question marks, so that is the default.
320
423
  def prepared_arg_placeholder