sequel 5.8.0 → 5.38.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 (510) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +409 -1795
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/bin/sequel +4 -0
  6. data/doc/advanced_associations.rdoc +136 -18
  7. data/doc/association_basics.rdoc +10 -5
  8. data/doc/cheat_sheet.rdoc +1 -0
  9. data/doc/code_order.rdoc +12 -2
  10. data/doc/dataset_filtering.rdoc +17 -2
  11. data/doc/mass_assignment.rdoc +3 -3
  12. data/doc/model_dataset_method_design.rdoc +1 -1
  13. data/doc/model_plugins.rdoc +1 -1
  14. data/doc/opening_databases.rdoc +30 -8
  15. data/doc/postgresql.rdoc +107 -2
  16. data/doc/release_notes/5.10.0.txt +84 -0
  17. data/doc/release_notes/5.11.0.txt +83 -0
  18. data/doc/release_notes/5.12.0.txt +141 -0
  19. data/doc/release_notes/5.13.0.txt +27 -0
  20. data/doc/release_notes/5.14.0.txt +63 -0
  21. data/doc/release_notes/5.15.0.txt +39 -0
  22. data/doc/release_notes/5.16.0.txt +110 -0
  23. data/doc/release_notes/5.17.0.txt +31 -0
  24. data/doc/release_notes/5.18.0.txt +69 -0
  25. data/doc/release_notes/5.19.0.txt +28 -0
  26. data/doc/release_notes/5.20.0.txt +89 -0
  27. data/doc/release_notes/5.21.0.txt +87 -0
  28. data/doc/release_notes/5.22.0.txt +48 -0
  29. data/doc/release_notes/5.23.0.txt +56 -0
  30. data/doc/release_notes/5.24.0.txt +56 -0
  31. data/doc/release_notes/5.25.0.txt +32 -0
  32. data/doc/release_notes/5.26.0.txt +35 -0
  33. data/doc/release_notes/5.27.0.txt +21 -0
  34. data/doc/release_notes/5.28.0.txt +16 -0
  35. data/doc/release_notes/5.29.0.txt +22 -0
  36. data/doc/release_notes/5.30.0.txt +20 -0
  37. data/doc/release_notes/5.31.0.txt +148 -0
  38. data/doc/release_notes/5.32.0.txt +46 -0
  39. data/doc/release_notes/5.33.0.txt +24 -0
  40. data/doc/release_notes/5.34.0.txt +40 -0
  41. data/doc/release_notes/5.35.0.txt +56 -0
  42. data/doc/release_notes/5.36.0.txt +60 -0
  43. data/doc/release_notes/5.37.0.txt +30 -0
  44. data/doc/release_notes/5.38.0.txt +28 -0
  45. data/doc/release_notes/5.9.0.txt +99 -0
  46. data/doc/security.rdoc +10 -0
  47. data/doc/sharding.rdoc +42 -28
  48. data/doc/sql.rdoc +12 -0
  49. data/doc/testing.rdoc +24 -17
  50. data/doc/transactions.rdoc +78 -0
  51. data/doc/validations.rdoc +2 -2
  52. data/lib/sequel/adapters/ado.rb +26 -18
  53. data/lib/sequel/adapters/ado/access.rb +2 -2
  54. data/lib/sequel/adapters/ado/mssql.rb +5 -8
  55. data/lib/sequel/adapters/amalgalite.rb +1 -1
  56. data/lib/sequel/adapters/jdbc.rb +71 -27
  57. data/lib/sequel/adapters/jdbc/mysql.rb +6 -6
  58. data/lib/sequel/adapters/jdbc/oracle.rb +7 -6
  59. data/lib/sequel/adapters/jdbc/postgresql.rb +17 -28
  60. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +5 -6
  61. data/lib/sequel/adapters/jdbc/sqlite.rb +33 -2
  62. data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -3
  63. data/lib/sequel/adapters/jdbc/transactions.rb +14 -28
  64. data/lib/sequel/adapters/mysql.rb +14 -15
  65. data/lib/sequel/adapters/mysql2.rb +5 -3
  66. data/lib/sequel/adapters/odbc.rb +4 -6
  67. data/lib/sequel/adapters/oracle.rb +7 -7
  68. data/lib/sequel/adapters/postgres.rb +52 -16
  69. data/lib/sequel/adapters/shared/access.rb +16 -12
  70. data/lib/sequel/adapters/shared/db2.rb +5 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +41 -18
  72. data/lib/sequel/adapters/shared/mysql.rb +66 -19
  73. data/lib/sequel/adapters/shared/oracle.rb +29 -23
  74. data/lib/sequel/adapters/shared/postgres.rb +341 -95
  75. data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
  76. data/lib/sequel/adapters/shared/sqlite.rb +174 -21
  77. data/lib/sequel/adapters/sqlanywhere.rb +33 -17
  78. data/lib/sequel/adapters/sqlite.rb +78 -68
  79. data/lib/sequel/adapters/tinytds.rb +14 -6
  80. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +2 -5
  81. data/lib/sequel/adapters/utils/mysql_mysql2.rb +5 -1
  82. data/lib/sequel/connection_pool.rb +2 -6
  83. data/lib/sequel/connection_pool/sharded_single.rb +7 -4
  84. data/lib/sequel/connection_pool/sharded_threaded.rb +32 -21
  85. data/lib/sequel/connection_pool/single.rb +1 -1
  86. data/lib/sequel/connection_pool/threaded.rb +26 -11
  87. data/lib/sequel/core.rb +327 -319
  88. data/lib/sequel/database/connecting.rb +7 -8
  89. data/lib/sequel/database/logging.rb +7 -1
  90. data/lib/sequel/database/misc.rb +68 -34
  91. data/lib/sequel/database/query.rb +6 -4
  92. data/lib/sequel/database/schema_generator.rb +31 -11
  93. data/lib/sequel/database/schema_methods.rb +32 -22
  94. data/lib/sequel/database/transactions.rb +129 -25
  95. data/lib/sequel/dataset.rb +4 -2
  96. data/lib/sequel/dataset/actions.rb +34 -23
  97. data/lib/sequel/dataset/features.rb +34 -0
  98. data/lib/sequel/dataset/graph.rb +27 -11
  99. data/lib/sequel/dataset/misc.rb +17 -3
  100. data/lib/sequel/dataset/placeholder_literalizer.rb +50 -21
  101. data/lib/sequel/dataset/prepared_statements.rb +96 -26
  102. data/lib/sequel/dataset/query.rb +43 -8
  103. data/lib/sequel/dataset/sql.rb +189 -41
  104. data/lib/sequel/deprecated.rb +3 -1
  105. data/lib/sequel/exceptions.rb +2 -0
  106. data/lib/sequel/extensions/_pretty_table.rb +1 -2
  107. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  108. data/lib/sequel/extensions/caller_logging.rb +79 -0
  109. data/lib/sequel/extensions/columns_introspection.rb +1 -2
  110. data/lib/sequel/extensions/connection_expiration.rb +6 -6
  111. data/lib/sequel/extensions/connection_validator.rb +7 -6
  112. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  113. data/lib/sequel/extensions/constraint_validations.rb +53 -28
  114. data/lib/sequel/extensions/core_refinements.rb +2 -0
  115. data/lib/sequel/extensions/duplicate_columns_handler.rb +2 -0
  116. data/lib/sequel/extensions/escaped_like.rb +100 -0
  117. data/lib/sequel/extensions/eval_inspect.rb +3 -1
  118. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  119. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  120. data/lib/sequel/extensions/index_caching.rb +9 -7
  121. data/lib/sequel/extensions/integer64.rb +3 -1
  122. data/lib/sequel/extensions/looser_typecasting.rb +3 -3
  123. data/lib/sequel/extensions/migration.rb +13 -6
  124. data/lib/sequel/extensions/named_timezones.rb +84 -23
  125. data/lib/sequel/extensions/pg_array.rb +87 -79
  126. data/lib/sequel/extensions/pg_array_ops.rb +14 -6
  127. data/lib/sequel/extensions/pg_enum.rb +34 -18
  128. data/lib/sequel/extensions/pg_extended_date_support.rb +34 -14
  129. data/lib/sequel/extensions/pg_hstore.rb +6 -0
  130. data/lib/sequel/extensions/pg_hstore_ops.rb +2 -0
  131. data/lib/sequel/extensions/pg_inet.rb +15 -5
  132. data/lib/sequel/extensions/pg_interval.rb +2 -0
  133. data/lib/sequel/extensions/pg_json.rb +387 -123
  134. data/lib/sequel/extensions/pg_json_ops.rb +168 -0
  135. data/lib/sequel/extensions/pg_range.rb +20 -10
  136. data/lib/sequel/extensions/pg_range_ops.rb +2 -0
  137. data/lib/sequel/extensions/pg_row.rb +3 -2
  138. data/lib/sequel/extensions/pg_row_ops.rb +24 -0
  139. data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
  140. data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
  141. data/lib/sequel/extensions/query.rb +1 -0
  142. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  143. data/lib/sequel/extensions/s.rb +2 -0
  144. data/lib/sequel/extensions/schema_dumper.rb +13 -7
  145. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +4 -2
  146. data/lib/sequel/extensions/server_block.rb +18 -7
  147. data/lib/sequel/extensions/sql_comments.rb +2 -2
  148. data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
  149. data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
  150. data/lib/sequel/extensions/to_dot.rb +9 -3
  151. data/lib/sequel/model.rb +3 -1
  152. data/lib/sequel/model/associations.rb +403 -69
  153. data/lib/sequel/model/base.rb +170 -90
  154. data/lib/sequel/model/plugins.rb +105 -0
  155. data/lib/sequel/plugins/after_initialize.rb +1 -1
  156. data/lib/sequel/plugins/association_dependencies.rb +3 -3
  157. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  158. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  159. data/lib/sequel/plugins/association_pks.rb +74 -22
  160. data/lib/sequel/plugins/association_proxies.rb +6 -2
  161. data/lib/sequel/plugins/auto_validations.rb +36 -17
  162. data/lib/sequel/plugins/blacklist_security.rb +1 -2
  163. data/lib/sequel/plugins/boolean_subsets.rb +4 -1
  164. data/lib/sequel/plugins/caching.rb +3 -0
  165. data/lib/sequel/plugins/class_table_inheritance.rb +62 -34
  166. data/lib/sequel/plugins/composition.rb +13 -9
  167. data/lib/sequel/plugins/csv_serializer.rb +28 -9
  168. data/lib/sequel/plugins/defaults_setter.rb +2 -2
  169. data/lib/sequel/plugins/dirty.rb +60 -22
  170. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  171. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  172. data/lib/sequel/plugins/finder.rb +2 -2
  173. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  174. data/lib/sequel/plugins/hook_class_methods.rb +17 -5
  175. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  176. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  177. data/lib/sequel/plugins/inverted_subsets.rb +2 -2
  178. data/lib/sequel/plugins/json_serializer.rb +21 -14
  179. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  180. data/lib/sequel/plugins/list.rb +22 -10
  181. data/lib/sequel/plugins/many_through_many.rb +1 -1
  182. data/lib/sequel/plugins/nested_attributes.rb +27 -5
  183. data/lib/sequel/plugins/pg_array_associations.rb +12 -9
  184. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +149 -61
  185. data/lib/sequel/plugins/prepared_statements.rb +6 -12
  186. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
  187. data/lib/sequel/plugins/rcte_tree.rb +20 -22
  188. data/lib/sequel/plugins/sharding.rb +13 -7
  189. data/lib/sequel/plugins/single_table_inheritance.rb +20 -15
  190. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  191. data/lib/sequel/plugins/static_cache.rb +36 -17
  192. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  193. data/lib/sequel/plugins/string_stripper.rb +1 -1
  194. data/lib/sequel/plugins/subclasses.rb +2 -0
  195. data/lib/sequel/plugins/subset_conditions.rb +2 -2
  196. data/lib/sequel/plugins/tactical_eager_loading.rb +73 -2
  197. data/lib/sequel/plugins/throw_failures.rb +110 -0
  198. data/lib/sequel/plugins/tree.rb +49 -31
  199. data/lib/sequel/plugins/typecast_on_load.rb +3 -2
  200. data/lib/sequel/plugins/validation_class_methods.rb +11 -5
  201. data/lib/sequel/plugins/validation_helpers.rb +2 -2
  202. data/lib/sequel/sql.rb +120 -30
  203. data/lib/sequel/timezones.rb +55 -14
  204. data/lib/sequel/version.rb +6 -1
  205. metadata +101 -361
  206. data/Rakefile +0 -151
  207. data/doc/release_notes/4.0.0.txt +0 -262
  208. data/doc/release_notes/4.1.0.txt +0 -85
  209. data/doc/release_notes/4.10.0.txt +0 -226
  210. data/doc/release_notes/4.11.0.txt +0 -147
  211. data/doc/release_notes/4.12.0.txt +0 -105
  212. data/doc/release_notes/4.13.0.txt +0 -169
  213. data/doc/release_notes/4.14.0.txt +0 -68
  214. data/doc/release_notes/4.15.0.txt +0 -56
  215. data/doc/release_notes/4.16.0.txt +0 -36
  216. data/doc/release_notes/4.17.0.txt +0 -38
  217. data/doc/release_notes/4.18.0.txt +0 -36
  218. data/doc/release_notes/4.19.0.txt +0 -45
  219. data/doc/release_notes/4.2.0.txt +0 -129
  220. data/doc/release_notes/4.20.0.txt +0 -79
  221. data/doc/release_notes/4.21.0.txt +0 -94
  222. data/doc/release_notes/4.22.0.txt +0 -72
  223. data/doc/release_notes/4.23.0.txt +0 -65
  224. data/doc/release_notes/4.24.0.txt +0 -99
  225. data/doc/release_notes/4.25.0.txt +0 -181
  226. data/doc/release_notes/4.26.0.txt +0 -44
  227. data/doc/release_notes/4.27.0.txt +0 -78
  228. data/doc/release_notes/4.28.0.txt +0 -57
  229. data/doc/release_notes/4.29.0.txt +0 -41
  230. data/doc/release_notes/4.3.0.txt +0 -40
  231. data/doc/release_notes/4.30.0.txt +0 -37
  232. data/doc/release_notes/4.31.0.txt +0 -57
  233. data/doc/release_notes/4.32.0.txt +0 -132
  234. data/doc/release_notes/4.33.0.txt +0 -88
  235. data/doc/release_notes/4.34.0.txt +0 -86
  236. data/doc/release_notes/4.35.0.txt +0 -130
  237. data/doc/release_notes/4.36.0.txt +0 -116
  238. data/doc/release_notes/4.37.0.txt +0 -50
  239. data/doc/release_notes/4.38.0.txt +0 -67
  240. data/doc/release_notes/4.39.0.txt +0 -127
  241. data/doc/release_notes/4.4.0.txt +0 -92
  242. data/doc/release_notes/4.40.0.txt +0 -179
  243. data/doc/release_notes/4.41.0.txt +0 -77
  244. data/doc/release_notes/4.42.0.txt +0 -221
  245. data/doc/release_notes/4.43.0.txt +0 -87
  246. data/doc/release_notes/4.44.0.txt +0 -125
  247. data/doc/release_notes/4.45.0.txt +0 -370
  248. data/doc/release_notes/4.46.0.txt +0 -404
  249. data/doc/release_notes/4.47.0.txt +0 -56
  250. data/doc/release_notes/4.48.0.txt +0 -293
  251. data/doc/release_notes/4.49.0.txt +0 -222
  252. data/doc/release_notes/4.5.0.txt +0 -34
  253. data/doc/release_notes/4.6.0.txt +0 -30
  254. data/doc/release_notes/4.7.0.txt +0 -103
  255. data/doc/release_notes/4.8.0.txt +0 -175
  256. data/doc/release_notes/4.9.0.txt +0 -190
  257. data/spec/adapter_spec.rb +0 -4
  258. data/spec/adapters/db2_spec.rb +0 -170
  259. data/spec/adapters/mssql_spec.rb +0 -804
  260. data/spec/adapters/mysql_spec.rb +0 -1041
  261. data/spec/adapters/oracle_spec.rb +0 -327
  262. data/spec/adapters/postgres_spec.rb +0 -4000
  263. data/spec/adapters/spec_helper.rb +0 -43
  264. data/spec/adapters/sqlanywhere_spec.rb +0 -97
  265. data/spec/adapters/sqlite_spec.rb +0 -600
  266. data/spec/bin_spec.rb +0 -269
  267. data/spec/core/connection_pool_spec.rb +0 -1228
  268. data/spec/core/database_spec.rb +0 -2673
  269. data/spec/core/dataset_spec.rb +0 -5419
  270. data/spec/core/deprecated_spec.rb +0 -70
  271. data/spec/core/expression_filters_spec.rb +0 -1344
  272. data/spec/core/mock_adapter_spec.rb +0 -722
  273. data/spec/core/object_graph_spec.rb +0 -306
  274. data/spec/core/placeholder_literalizer_spec.rb +0 -166
  275. data/spec/core/schema_generator_spec.rb +0 -214
  276. data/spec/core/schema_spec.rb +0 -1820
  277. data/spec/core/spec_helper.rb +0 -23
  278. data/spec/core/version_spec.rb +0 -7
  279. data/spec/core_extensions_spec.rb +0 -762
  280. data/spec/core_model_spec.rb +0 -2
  281. data/spec/core_spec.rb +0 -1
  282. data/spec/deprecation_helper.rb +0 -30
  283. data/spec/extensions/accessed_columns_spec.rb +0 -51
  284. data/spec/extensions/active_model_spec.rb +0 -99
  285. data/spec/extensions/after_initialize_spec.rb +0 -24
  286. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  287. data/spec/extensions/association_dependencies_spec.rb +0 -125
  288. data/spec/extensions/association_pks_spec.rb +0 -423
  289. data/spec/extensions/association_proxies_spec.rb +0 -100
  290. data/spec/extensions/auto_literal_strings_spec.rb +0 -205
  291. data/spec/extensions/auto_validations_spec.rb +0 -202
  292. data/spec/extensions/blacklist_security_spec.rb +0 -95
  293. data/spec/extensions/blank_spec.rb +0 -69
  294. data/spec/extensions/boolean_readers_spec.rb +0 -93
  295. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  296. data/spec/extensions/caching_spec.rb +0 -273
  297. data/spec/extensions/class_table_inheritance_spec.rb +0 -568
  298. data/spec/extensions/column_conflicts_spec.rb +0 -75
  299. data/spec/extensions/column_select_spec.rb +0 -129
  300. data/spec/extensions/columns_introspection_spec.rb +0 -90
  301. data/spec/extensions/columns_updated_spec.rb +0 -35
  302. data/spec/extensions/composition_spec.rb +0 -248
  303. data/spec/extensions/connection_expiration_spec.rb +0 -133
  304. data/spec/extensions/connection_validator_spec.rb +0 -127
  305. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
  306. data/spec/extensions/constraint_validations_spec.rb +0 -395
  307. data/spec/extensions/core_refinements_spec.rb +0 -528
  308. data/spec/extensions/csv_serializer_spec.rb +0 -183
  309. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  310. data/spec/extensions/dataset_associations_spec.rb +0 -365
  311. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  312. data/spec/extensions/date_arithmetic_spec.rb +0 -181
  313. data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
  314. data/spec/extensions/def_dataset_method_spec.rb +0 -100
  315. data/spec/extensions/defaults_setter_spec.rb +0 -141
  316. data/spec/extensions/delay_add_association_spec.rb +0 -73
  317. data/spec/extensions/dirty_spec.rb +0 -189
  318. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
  319. data/spec/extensions/eager_each_spec.rb +0 -62
  320. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  321. data/spec/extensions/error_splitter_spec.rb +0 -18
  322. data/spec/extensions/error_sql_spec.rb +0 -20
  323. data/spec/extensions/eval_inspect_spec.rb +0 -74
  324. data/spec/extensions/finder_spec.rb +0 -260
  325. data/spec/extensions/force_encoding_spec.rb +0 -126
  326. data/spec/extensions/freeze_datasets_spec.rb +0 -31
  327. data/spec/extensions/graph_each_spec.rb +0 -113
  328. data/spec/extensions/hook_class_methods_spec.rb +0 -380
  329. data/spec/extensions/identifier_mangling_spec.rb +0 -201
  330. data/spec/extensions/implicit_subquery_spec.rb +0 -58
  331. data/spec/extensions/index_caching_spec.rb +0 -66
  332. data/spec/extensions/inflector_spec.rb +0 -183
  333. data/spec/extensions/input_transformer_spec.rb +0 -69
  334. data/spec/extensions/insert_returning_select_spec.rb +0 -72
  335. data/spec/extensions/instance_filters_spec.rb +0 -79
  336. data/spec/extensions/instance_hooks_spec.rb +0 -246
  337. data/spec/extensions/integer64_spec.rb +0 -22
  338. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  339. data/spec/extensions/json_serializer_spec.rb +0 -336
  340. data/spec/extensions/lazy_attributes_spec.rb +0 -183
  341. data/spec/extensions/list_spec.rb +0 -275
  342. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  343. data/spec/extensions/many_through_many_spec.rb +0 -2177
  344. data/spec/extensions/migration_spec.rb +0 -840
  345. data/spec/extensions/modification_detection_spec.rb +0 -93
  346. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
  347. data/spec/extensions/named_timezones_spec.rb +0 -109
  348. data/spec/extensions/nested_attributes_spec.rb +0 -703
  349. data/spec/extensions/null_dataset_spec.rb +0 -85
  350. data/spec/extensions/optimistic_locking_spec.rb +0 -127
  351. data/spec/extensions/pagination_spec.rb +0 -116
  352. data/spec/extensions/pg_array_associations_spec.rb +0 -802
  353. data/spec/extensions/pg_array_ops_spec.rb +0 -144
  354. data/spec/extensions/pg_array_spec.rb +0 -398
  355. data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -165
  356. data/spec/extensions/pg_enum_spec.rb +0 -113
  357. data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
  358. data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
  359. data/spec/extensions/pg_hstore_spec.rb +0 -219
  360. data/spec/extensions/pg_inet_ops_spec.rb +0 -102
  361. data/spec/extensions/pg_inet_spec.rb +0 -72
  362. data/spec/extensions/pg_interval_spec.rb +0 -103
  363. data/spec/extensions/pg_json_ops_spec.rb +0 -289
  364. data/spec/extensions/pg_json_spec.rb +0 -262
  365. data/spec/extensions/pg_loose_count_spec.rb +0 -23
  366. data/spec/extensions/pg_range_ops_spec.rb +0 -60
  367. data/spec/extensions/pg_range_spec.rb +0 -487
  368. data/spec/extensions/pg_row_ops_spec.rb +0 -61
  369. data/spec/extensions/pg_row_plugin_spec.rb +0 -60
  370. data/spec/extensions/pg_row_spec.rb +0 -363
  371. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
  372. data/spec/extensions/pg_timestamptz_spec.rb +0 -17
  373. data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
  374. data/spec/extensions/prepared_statements_spec.rb +0 -182
  375. data/spec/extensions/pretty_table_spec.rb +0 -123
  376. data/spec/extensions/query_spec.rb +0 -94
  377. data/spec/extensions/rcte_tree_spec.rb +0 -381
  378. data/spec/extensions/round_timestamps_spec.rb +0 -39
  379. data/spec/extensions/s_spec.rb +0 -60
  380. data/spec/extensions/schema_caching_spec.rb +0 -64
  381. data/spec/extensions/schema_dumper_spec.rb +0 -868
  382. data/spec/extensions/select_remove_spec.rb +0 -38
  383. data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
  384. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  385. data/spec/extensions/serialization_spec.rb +0 -365
  386. data/spec/extensions/server_block_spec.rb +0 -97
  387. data/spec/extensions/server_logging_spec.rb +0 -45
  388. data/spec/extensions/sharding_spec.rb +0 -189
  389. data/spec/extensions/shared_caching_spec.rb +0 -151
  390. data/spec/extensions/single_table_inheritance_spec.rb +0 -347
  391. data/spec/extensions/singular_table_names_spec.rb +0 -22
  392. data/spec/extensions/skip_create_refresh_spec.rb +0 -18
  393. data/spec/extensions/spec_helper.rb +0 -61
  394. data/spec/extensions/split_array_nil_spec.rb +0 -24
  395. data/spec/extensions/split_values_spec.rb +0 -57
  396. data/spec/extensions/sql_comments_spec.rb +0 -33
  397. data/spec/extensions/sql_expr_spec.rb +0 -59
  398. data/spec/extensions/static_cache_spec.rb +0 -410
  399. data/spec/extensions/string_agg_spec.rb +0 -90
  400. data/spec/extensions/string_date_time_spec.rb +0 -95
  401. data/spec/extensions/string_stripper_spec.rb +0 -68
  402. data/spec/extensions/subclasses_spec.rb +0 -79
  403. data/spec/extensions/subset_conditions_spec.rb +0 -38
  404. data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
  405. data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
  406. data/spec/extensions/synchronize_sql_spec.rb +0 -124
  407. data/spec/extensions/table_select_spec.rb +0 -83
  408. data/spec/extensions/tactical_eager_loading_spec.rb +0 -141
  409. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  410. data/spec/extensions/timestamps_spec.rb +0 -209
  411. data/spec/extensions/to_dot_spec.rb +0 -153
  412. data/spec/extensions/touch_spec.rb +0 -226
  413. data/spec/extensions/tree_spec.rb +0 -284
  414. data/spec/extensions/typecast_on_load_spec.rb +0 -86
  415. data/spec/extensions/unlimited_update_spec.rb +0 -21
  416. data/spec/extensions/update_or_create_spec.rb +0 -83
  417. data/spec/extensions/update_primary_key_spec.rb +0 -105
  418. data/spec/extensions/update_refresh_spec.rb +0 -59
  419. data/spec/extensions/uuid_spec.rb +0 -101
  420. data/spec/extensions/validate_associated_spec.rb +0 -52
  421. data/spec/extensions/validation_class_methods_spec.rb +0 -1040
  422. data/spec/extensions/validation_contexts_spec.rb +0 -31
  423. data/spec/extensions/validation_helpers_spec.rb +0 -525
  424. data/spec/extensions/whitelist_security_spec.rb +0 -157
  425. data/spec/extensions/xml_serializer_spec.rb +0 -213
  426. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  427. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  428. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  429. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  430. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  431. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  432. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  433. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  434. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  435. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  436. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  437. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  438. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  439. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  440. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  441. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  442. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  443. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  444. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  445. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  446. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  447. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  448. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  449. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  450. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  451. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  452. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  453. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  454. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  455. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  456. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  457. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  458. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  459. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  460. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  461. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  462. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  463. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  464. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  465. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  466. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  467. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  468. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  469. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  470. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  471. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  472. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  473. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  474. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  475. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  476. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  477. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  478. data/spec/guards_helper.rb +0 -58
  479. data/spec/integration/associations_test.rb +0 -2513
  480. data/spec/integration/database_test.rb +0 -113
  481. data/spec/integration/dataset_test.rb +0 -1880
  482. data/spec/integration/eager_loader_test.rb +0 -687
  483. data/spec/integration/migrator_test.rb +0 -262
  484. data/spec/integration/model_test.rb +0 -203
  485. data/spec/integration/plugin_test.rb +0 -2302
  486. data/spec/integration/prepared_statement_test.rb +0 -398
  487. data/spec/integration/schema_test.rb +0 -869
  488. data/spec/integration/spec_helper.rb +0 -64
  489. data/spec/integration/timezone_test.rb +0 -86
  490. data/spec/integration/transaction_test.rb +0 -354
  491. data/spec/integration/type_test.rb +0 -127
  492. data/spec/model/association_reflection_spec.rb +0 -803
  493. data/spec/model/associations_spec.rb +0 -4538
  494. data/spec/model/base_spec.rb +0 -817
  495. data/spec/model/class_dataset_methods_spec.rb +0 -146
  496. data/spec/model/dataset_methods_spec.rb +0 -198
  497. data/spec/model/eager_loading_spec.rb +0 -2262
  498. data/spec/model/hooks_spec.rb +0 -370
  499. data/spec/model/inflector_spec.rb +0 -26
  500. data/spec/model/model_spec.rb +0 -953
  501. data/spec/model/plugins_spec.rb +0 -318
  502. data/spec/model/record_spec.rb +0 -2107
  503. data/spec/model/spec_helper.rb +0 -45
  504. data/spec/model/validations_spec.rb +0 -193
  505. data/spec/model_no_assoc_spec.rb +0 -1
  506. data/spec/model_spec.rb +0 -1
  507. data/spec/plugin_spec.rb +0 -1
  508. data/spec/sequel_coverage.rb +0 -15
  509. data/spec/sequel_warning.rb +0 -4
  510. data/spec/spec_config.rb +0 -12
@@ -178,11 +178,29 @@ module Sequel
178
178
  true
179
179
  end
180
180
 
181
+ # Whether the dataset supports the WINDOW clause to define windows used by multiple
182
+ # window functions, false by default.
183
+ def supports_window_clause?
184
+ false
185
+ end
186
+
181
187
  # Whether the dataset supports window functions, false by default.
182
188
  def supports_window_functions?
183
189
  false
184
190
  end
185
191
 
192
+ # Whether the dataset supports the given window function option. True by default.
193
+ # This should only be called if supports_window_functions? is true. Possible options
194
+ # are :rows, :range, :groups, :offset, :exclude.
195
+ def supports_window_function_frame_option?(option)
196
+ case option
197
+ when :rows, :range, :offset
198
+ true
199
+ else
200
+ false
201
+ end
202
+ end
203
+
186
204
  # Whether the dataset supports WHERE TRUE (or WHERE 1 for databases that
187
205
  # that use 1 for true), true by default.
188
206
  def supports_where_true?
@@ -197,11 +215,27 @@ module Sequel
197
215
  true
198
216
  end
199
217
 
218
+ # Whether the dataset needs ESCAPE for LIKE for correct behavior.
219
+ def requires_like_escape?
220
+ true
221
+ end
222
+
223
+ # Whether ORDER BY col NULLS FIRST/LAST must be emulated.
224
+ def requires_emulating_nulls_first?
225
+ false
226
+ end
227
+
200
228
  # Whether common table expressions are supported in UNION/INTERSECT/EXCEPT clauses.
201
229
  def supports_cte_in_compounds?
202
230
  supports_cte_in_subqueries?
203
231
  end
204
232
 
233
+ # Whether the dataset supports the FILTER clause for aggregate functions.
234
+ # If not, support is emulated using CASE.
235
+ def supports_filtered_aggregates?
236
+ false
237
+ end
238
+
205
239
  # Whether the database supports quoting function names.
206
240
  def supports_quoted_function_names?
207
241
  false
@@ -21,7 +21,7 @@ module Sequel
21
21
  raise Error, "cannot call add_graph_aliases on a dataset that has not been called with graph or set_graph_aliases"
22
22
  end
23
23
  columns, graph_aliases = graph_alias_columns(graph_aliases)
24
- select_append(*columns).clone(:graph => Hash[graph].merge!(:column_aliases=>Hash[ga].merge!(graph_aliases).freeze).freeze)
24
+ select_append(*columns).clone(:graph => graph.merge(:column_aliases=>ga.merge(graph_aliases).freeze).freeze)
25
25
  end
26
26
 
27
27
  # Similar to Dataset#join_table, but uses unambiguous aliases for selected
@@ -96,10 +96,30 @@ module Sequel
96
96
 
97
97
  table_alias_qualifier = qualifier_from_alias_symbol(table_alias, table)
98
98
  implicit_qualifier = options[:implicit_qualifier]
99
+ joined_dataset = joined_dataset?
99
100
  ds = self
101
+ graph = opts[:graph]
102
+
103
+ if !graph && (select = @opts[:select]) && !select.empty?
104
+ select_columns = nil
105
+
106
+ unless !joined_dataset && select.length == 1 && (select[0].is_a?(SQL::ColumnAll))
107
+ force_from_self = false
108
+ select_columns = select.map do |sel|
109
+ unless col = _hash_key_symbol(sel)
110
+ force_from_self = true
111
+ break
112
+ end
113
+
114
+ [sel, col]
115
+ end
116
+
117
+ select_columns = nil if force_from_self
118
+ end
119
+ end
100
120
 
101
121
  # Use a from_self if this is already a joined table (or from_self specifically disabled for graphs)
102
- if (@opts[:graph_from_self] != false && !@opts[:graph] && joined_dataset?)
122
+ if (@opts[:graph_from_self] != false && !graph && (joined_dataset || force_from_self))
103
123
  from_selfed = true
104
124
  implicit_qualifier = options[:from_self_alias] || first_source
105
125
  ds = ds.from_self(:alias=>implicit_qualifier)
@@ -115,7 +135,7 @@ module Sequel
115
135
  # Whether to include the table in the result set
116
136
  add_table = options[:select] == false ? false : true
117
137
 
118
- if graph = opts[:graph]
138
+ if graph
119
139
  graph = graph.dup
120
140
  select = opts[:select].dup
121
141
  [:column_aliases, :table_aliases, :column_alias_num].each{|k| graph[k] = graph[k].dup}
@@ -137,12 +157,8 @@ module Sequel
137
157
  # Keep track of the alias numbers used
138
158
  ca_num = graph[:column_alias_num] = Hash.new(0)
139
159
 
140
- # All columns in the master table are never
141
- # aliased, but are not included if set_graph_aliases
142
- # has been used.
143
- if (select = @opts[:select]) && !select.empty? && !(select.length == 1 && (select.first.is_a?(SQL::ColumnAll)))
144
- select = select.map do |sel|
145
- raise Error, "can't figure out alias to use for graphing for #{sel.inspect}" unless column = _hash_key_symbol(sel)
160
+ select = if select_columns
161
+ select_columns.map do |sel, column|
146
162
  column_aliases[column] = [master, column]
147
163
  if from_selfed
148
164
  # Initial dataset was wrapped in subselect, selected all
@@ -155,7 +171,7 @@ module Sequel
155
171
  end
156
172
  end
157
173
  else
158
- select = columns.map do |column|
174
+ columns.map do |column|
159
175
  column_aliases[column] = [master, column]
160
176
  SQL::QualifiedIdentifier.new(qualifier, column)
161
177
  end
@@ -228,7 +244,7 @@ module Sequel
228
244
  def set_graph_aliases(graph_aliases)
229
245
  columns, graph_aliases = graph_alias_columns(graph_aliases)
230
246
  if graph = opts[:graph]
231
- select(*columns).clone(:graph => Hash[graph].merge!(:column_aliases=>graph_aliases.freeze).freeze)
247
+ select(*columns).clone(:graph => graph.merge(:column_aliases=>graph_aliases.freeze).freeze)
232
248
  else
233
249
  raise Error, "cannot call #set_graph_aliases on an ungraphed dataset"
234
250
  end
@@ -226,7 +226,7 @@ module Sequel
226
226
  used_aliases += opts[:join].map{|j| j.table_alias ? alias_alias_symbol(j.table_alias) : alias_symbol(j.table)} if opts[:join]
227
227
  if used_aliases.include?(table_alias)
228
228
  i = 0
229
- loop do
229
+ while true
230
230
  ta = :"#{table_alias}_#{i}"
231
231
  return ta unless used_aliases.include?(ta)
232
232
  i += 1
@@ -309,13 +309,27 @@ module Sequel
309
309
  loader
310
310
  end
311
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
+
312
326
  # Set the columns for the current dataset.
313
327
  def columns=(v)
314
328
  cache_set(:_columns, v)
315
329
  end
316
330
 
317
331
  # Set the db, opts, and cache for the copy of the dataset.
318
- def initialize_copy(c)
332
+ def initialize_clone(c, _=nil)
319
333
  @db = c.db
320
334
  @opts = Hash[c.opts]
321
335
  if cols = c.cache_get(:_columns)
@@ -324,7 +338,7 @@ module Sequel
324
338
  @cache = {}
325
339
  end
326
340
  end
327
- alias initialize_clone initialize_copy
341
+ alias initialize_copy initialize_clone
328
342
 
329
343
  # Internal recursive version of unqualified_column_for, handling Strings inside
330
344
  # of other objects.
@@ -77,23 +77,8 @@ module Sequel
77
77
  # Yields the receiver and the dataset to the block, which should
78
78
  # call #arg on the receiver for each placeholder argument, and
79
79
  # return the dataset that you want to load.
80
- def loader(dataset)
81
- @argn = -1
82
- @args = []
83
- ds = yield self, dataset
84
- sql = ds.clone(:placeholder_literalizer=>self).sql
85
-
86
- last_offset = 0
87
- fragments = @args.map do |used_sql, offset, arg, t|
88
- raise Error, "placeholder literalizer argument literalized into different string than dataset returned" unless used_sql.equal?(sql)
89
- a = [sql[last_offset...offset], arg, t]
90
- last_offset = offset
91
- a
92
- end
93
- final_sql = sql[last_offset..-1]
94
-
95
- arity = @argn+1
96
- PlaceholderLiteralizer.new(ds.clone, fragments, final_sql, arity)
80
+ def loader(dataset, &block)
81
+ PlaceholderLiteralizer.new(*process(dataset, &block))
97
82
  end
98
83
 
99
84
  # Return an Argument with the specified position, or the next position. In
@@ -111,6 +96,49 @@ module Sequel
111
96
  def use(sql, arg, transformer)
112
97
  @args << [sql, sql.length, arg, transformer]
113
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
114
142
  end
115
143
 
116
144
  # Create a PlaceholderLiteralizer by yielding a Recorder and dataset to the
@@ -140,7 +168,10 @@ module Sequel
140
168
  # receiver's dataset to the block, and the block should return the new dataset
141
169
  # to use.
142
170
  def with_dataset
143
- dup.instance_exec{@dataset = yield @dataset; self}.freeze
171
+ dataset = yield @dataset
172
+ other = dup
173
+ other.instance_variable_set(:@dataset, dataset)
174
+ other.freeze
144
175
  end
145
176
 
146
177
  # Return an array of all objects by running the SQL query for the given arguments.
@@ -180,9 +211,7 @@ module Sequel
180
211
  end
181
212
  ds.literal_append(s, v)
182
213
  end
183
- if sql = @final_sql
184
- s << sql
185
- end
214
+ s << @final_sql
186
215
  s
187
216
  end
188
217
  end
@@ -52,7 +52,7 @@ module Sequel
52
52
  end
53
53
 
54
54
  # Set the bind arguments based on the hash and call super.
55
- def call(bind_vars={}, &block)
55
+ def call(bind_vars=OPTS, &block)
56
56
  sql = prepared_sql
57
57
  prepared_args.freeze
58
58
  ps = bind(bind_vars)
@@ -67,6 +67,14 @@ module Sequel
67
67
  end
68
68
  cache_set(:_prepared_sql, super)
69
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
77
+ end
70
78
  end
71
79
 
72
80
  # Backbone of the prepared statement support. Grafts bind variable
@@ -83,7 +91,7 @@ module Sequel
83
91
  end
84
92
 
85
93
  # The type of prepared statement, should be one of :select, :first,
86
- # :insert, :update, or :delete
94
+ # :insert, :update, :delete, or :single_value
87
95
  def prepared_type
88
96
  @opts[:prepared_type]
89
97
  end
@@ -106,7 +114,7 @@ module Sequel
106
114
 
107
115
  # Sets the prepared_args to the given hash and runs the
108
116
  # prepared statement.
109
- def call(bind_vars={}, &block)
117
+ def call(bind_vars=OPTS, &block)
110
118
  bind(bind_vars).run(&block)
111
119
  end
112
120
 
@@ -136,7 +144,7 @@ module Sequel
136
144
  when :select, :all, :each
137
145
  # Most common scenario, so listed first.
138
146
  select_sql
139
- when :first
147
+ when :first, :single_value
140
148
  clone(:limit=>1).select_sql
141
149
  when :insert_select
142
150
  insert_select_sql(*prepared_modify_values)
@@ -155,13 +163,8 @@ module Sequel
155
163
  # prepared_args is present. If so, they are considered placeholders,
156
164
  # and they are substituted using prepared_arg.
157
165
  def literal_symbol_append(sql, v)
158
- if @opts[:bind_vars] and match = /\A\$(.*)\z/.match(v.to_s)
159
- s = match[1].to_sym
160
- if prepared_arg?(s)
161
- literal_append(sql, prepared_arg(s))
162
- else
163
- sql << v.to_s
164
- end
166
+ if @opts[:bind_vars] && /\A\$(.*)\z/ =~ v
167
+ literal_append(sql, prepared_arg($1.to_sym))
165
168
  else
166
169
  super
167
170
  end
@@ -202,6 +205,8 @@ module Sequel
202
205
  when :map, :as_hash, :to_hash, :to_hash_groups
203
206
  public_send(*prepared_type, &block)
204
207
  end
208
+ when :single_value
209
+ single_value
205
210
  else
206
211
  raise Error, "unsupported prepared statement type used: #{prepared_type.inspect}"
207
212
  end
@@ -214,11 +219,6 @@ module Sequel
214
219
  @opts[:bind_vars][k]
215
220
  end
216
221
 
217
- # Whether there is a bound value for the given key.
218
- def prepared_arg?(k)
219
- @opts[:bind_vars].has_key?(k)
220
- end
221
-
222
222
  # The symbol cache should always be skipped, since placeholders are symbols.
223
223
  def skip_symbol_cache?
224
224
  true
@@ -228,9 +228,12 @@ module Sequel
228
228
  # support and using the same argument hash so that you can use
229
229
  # bind variables/prepared arguments in subselects.
230
230
  def subselect_sql_append(sql, ds)
231
- ds.clone(:append_sql=>sql, :prepared_args=>prepared_args, :bind_vars=>@opts[:bind_vars]).
232
- send(:to_prepared_statement, :select, nil, :extend=>prepared_statement_modules).
233
- 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)
234
237
  end
235
238
  end
236
239
 
@@ -258,11 +261,63 @@ module Sequel
258
261
  prepared_args << k
259
262
  prepared_arg_placeholder
260
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
261
283
 
262
- # Always assume there is a prepared arg in the argument mapper.
263
- def prepared_arg?(k)
284
+ # Turn emulation of prepared statements back on, since ArgumentMapper
285
+ # turns it off.
286
+ def emulate_prepared_statements?
264
287
  true
265
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
266
321
  end
267
322
 
268
323
  # Set the bind variables to use for the call. If bind variables have
@@ -272,9 +327,9 @@ module Sequel
272
327
  # DB[:table].where(id: :$id).bind(id: 1).call(:first)
273
328
  # # SELECT * FROM table WHERE id = ? LIMIT 1 -- (1)
274
329
  # # => {:id=>1}
275
- def bind(bind_vars={})
330
+ def bind(bind_vars=OPTS)
276
331
  bind_vars = if bv = @opts[:bind_vars]
277
- Hash[bv].merge!(bind_vars).freeze
332
+ bv.merge(bind_vars).freeze
278
333
  else
279
334
  if bind_vars.frozen?
280
335
  bind_vars
@@ -286,14 +341,14 @@ module Sequel
286
341
  clone(:bind_vars=>bind_vars)
287
342
  end
288
343
 
289
- # 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),
290
345
  # run the sql with the bind variables specified in the hash. +values+ is a hash passed to
291
346
  # insert or update (if one of those types is used), which may contain placeholders.
292
347
  #
293
348
  # DB[:table].where(id: :$id).call(:first, id: 1)
294
349
  # # SELECT * FROM table WHERE id = ? LIMIT 1 -- (1)
295
350
  # # => {:id=>1}
296
- def call(type, bind_variables={}, *values, &block)
351
+ def call(type, bind_variables=OPTS, *values, &block)
297
352
  to_prepared_statement(type, values, :extend=>bound_variable_modules).call(bind_variables, &block)
298
353
  end
299
354
 
@@ -315,7 +370,16 @@ module Sequel
315
370
  # DB.call(:select_by_name, name: 'Blah') # Same thing
316
371
  def prepare(type, name, *values)
317
372
  ps = to_prepared_statement(type, values, :name=>name, :extend=>prepared_statement_modules, :no_delayed_evaluations=>true)
318
- ps.prepared_sql
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
+
319
383
  db.set_prepared_statement(name, ps)
320
384
  ps
321
385
  end
@@ -344,6 +408,12 @@ module Sequel
344
408
  prepared_statement_modules
345
409
  end
346
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
+
347
417
  def prepared_statement_modules
348
418
  []
349
419
  end