sequel 3.21.0 → 3.39.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 (352) hide show
  1. data/CHANGELOG +1061 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +103 -63
  4. data/Rakefile +59 -27
  5. data/bin/sequel +50 -26
  6. data/doc/active_record.rdoc +67 -51
  7. data/doc/advanced_associations.rdoc +189 -75
  8. data/doc/association_basics.rdoc +327 -79
  9. data/doc/cheat_sheet.rdoc +21 -21
  10. data/doc/core_extensions.rdoc +374 -0
  11. data/doc/dataset_basics.rdoc +10 -10
  12. data/doc/dataset_filtering.rdoc +54 -42
  13. data/doc/mass_assignment.rdoc +56 -0
  14. data/doc/migration.rdoc +89 -557
  15. data/doc/model_hooks.rdoc +80 -29
  16. data/doc/object_model.rdoc +547 -0
  17. data/doc/opening_databases.rdoc +114 -53
  18. data/doc/prepared_statements.rdoc +41 -15
  19. data/doc/querying.rdoc +137 -56
  20. data/doc/reflection.rdoc +36 -10
  21. data/doc/release_notes/3.22.0.txt +39 -0
  22. data/doc/release_notes/3.23.0.txt +172 -0
  23. data/doc/release_notes/3.24.0.txt +420 -0
  24. data/doc/release_notes/3.25.0.txt +88 -0
  25. data/doc/release_notes/3.26.0.txt +88 -0
  26. data/doc/release_notes/3.27.0.txt +82 -0
  27. data/doc/release_notes/3.28.0.txt +304 -0
  28. data/doc/release_notes/3.29.0.txt +459 -0
  29. data/doc/release_notes/3.30.0.txt +135 -0
  30. data/doc/release_notes/3.31.0.txt +146 -0
  31. data/doc/release_notes/3.32.0.txt +202 -0
  32. data/doc/release_notes/3.33.0.txt +157 -0
  33. data/doc/release_notes/3.34.0.txt +671 -0
  34. data/doc/release_notes/3.35.0.txt +144 -0
  35. data/doc/release_notes/3.36.0.txt +245 -0
  36. data/doc/release_notes/3.37.0.txt +338 -0
  37. data/doc/release_notes/3.38.0.txt +234 -0
  38. data/doc/release_notes/3.39.0.txt +237 -0
  39. data/doc/schema_modification.rdoc +585 -0
  40. data/doc/sharding.rdoc +99 -8
  41. data/doc/sql.rdoc +154 -112
  42. data/doc/testing.rdoc +169 -0
  43. data/doc/thread_safety.rdoc +17 -0
  44. data/doc/transactions.rdoc +137 -0
  45. data/doc/validations.rdoc +1 -1
  46. data/doc/virtual_rows.rdoc +78 -43
  47. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  48. data/lib/sequel/adapters/ado.rb +40 -18
  49. data/lib/sequel/adapters/amalgalite.rb +17 -9
  50. data/lib/sequel/adapters/db2.rb +175 -86
  51. data/lib/sequel/adapters/dbi.rb +15 -15
  52. data/lib/sequel/adapters/do/mysql.rb +17 -11
  53. data/lib/sequel/adapters/do/postgres.rb +2 -61
  54. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  55. data/lib/sequel/adapters/do.rb +18 -36
  56. data/lib/sequel/adapters/firebird.rb +27 -208
  57. data/lib/sequel/adapters/ibmdb.rb +453 -0
  58. data/lib/sequel/adapters/informix.rb +6 -23
  59. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  60. data/lib/sequel/adapters/jdbc/db2.rb +56 -0
  61. data/lib/sequel/adapters/jdbc/derby.rb +325 -0
  62. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  63. data/lib/sequel/adapters/jdbc/h2.rb +73 -31
  64. data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
  65. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  66. data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
  67. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  68. data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
  69. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  70. data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
  71. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  72. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  73. data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
  74. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  75. data/lib/sequel/adapters/jdbc.rb +279 -97
  76. data/lib/sequel/adapters/mock.rb +372 -0
  77. data/lib/sequel/adapters/mysql.rb +125 -222
  78. data/lib/sequel/adapters/mysql2.rb +65 -56
  79. data/lib/sequel/adapters/odbc/mssql.rb +17 -9
  80. data/lib/sequel/adapters/odbc.rb +28 -9
  81. data/lib/sequel/adapters/openbase.rb +3 -5
  82. data/lib/sequel/adapters/oracle.rb +349 -53
  83. data/lib/sequel/adapters/postgres.rb +368 -138
  84. data/lib/sequel/adapters/shared/access.rb +32 -9
  85. data/lib/sequel/adapters/shared/db2.rb +343 -0
  86. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  87. data/lib/sequel/adapters/shared/informix.rb +53 -0
  88. data/lib/sequel/adapters/shared/mssql.rb +401 -116
  89. data/lib/sequel/adapters/shared/mysql.rb +424 -89
  90. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
  91. data/lib/sequel/adapters/shared/oracle.rb +257 -45
  92. data/lib/sequel/adapters/shared/postgres.rb +675 -279
  93. data/lib/sequel/adapters/shared/progress.rb +5 -8
  94. data/lib/sequel/adapters/shared/sqlite.rb +285 -96
  95. data/lib/sequel/adapters/sqlite.rb +101 -39
  96. data/lib/sequel/adapters/swift/mysql.rb +10 -12
  97. data/lib/sequel/adapters/swift/postgres.rb +13 -79
  98. data/lib/sequel/adapters/swift/sqlite.rb +9 -6
  99. data/lib/sequel/adapters/swift.rb +28 -19
  100. data/lib/sequel/adapters/tinytds.rb +174 -22
  101. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
  102. data/lib/sequel/adapters/utils/pg_types.rb +81 -0
  103. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  104. data/lib/sequel/ast_transformer.rb +194 -0
  105. data/lib/sequel/connection_pool/sharded_single.rb +11 -1
  106. data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
  107. data/lib/sequel/connection_pool/single.rb +5 -0
  108. data/lib/sequel/connection_pool/threaded.rb +43 -14
  109. data/lib/sequel/connection_pool.rb +10 -2
  110. data/lib/sequel/core.rb +143 -11
  111. data/lib/sequel/database/connecting.rb +38 -28
  112. data/lib/sequel/database/dataset.rb +4 -4
  113. data/lib/sequel/database/dataset_defaults.rb +63 -2
  114. data/lib/sequel/database/logging.rb +7 -2
  115. data/lib/sequel/database/misc.rb +190 -46
  116. data/lib/sequel/database/query.rb +272 -110
  117. data/lib/sequel/database/schema_generator.rb +103 -36
  118. data/lib/sequel/database/schema_methods.rb +300 -67
  119. data/lib/sequel/dataset/actions.rb +344 -90
  120. data/lib/sequel/dataset/features.rb +101 -8
  121. data/lib/sequel/dataset/graph.rb +42 -15
  122. data/lib/sequel/dataset/misc.rb +52 -25
  123. data/lib/sequel/dataset/mutation.rb +12 -7
  124. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  125. data/lib/sequel/dataset/query.rb +305 -54
  126. data/lib/sequel/dataset/sql.rb +720 -292
  127. data/lib/sequel/dataset.rb +8 -0
  128. data/lib/sequel/exceptions.rb +4 -0
  129. data/lib/sequel/extensions/_pretty_table.rb +83 -0
  130. data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
  131. data/lib/sequel/extensions/blank.rb +4 -0
  132. data/lib/sequel/extensions/columns_introspection.rb +72 -0
  133. data/lib/sequel/extensions/constraint_validations.rb +451 -0
  134. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
  135. data/lib/sequel/extensions/eval_inspect.rb +173 -0
  136. data/lib/sequel/extensions/inflector.rb +4 -0
  137. data/lib/sequel/extensions/looser_typecasting.rb +5 -4
  138. data/lib/sequel/extensions/migration.rb +100 -11
  139. data/lib/sequel/extensions/named_timezones.rb +9 -0
  140. data/lib/sequel/extensions/null_dataset.rb +94 -0
  141. data/lib/sequel/extensions/pagination.rb +4 -0
  142. data/lib/sequel/extensions/pg_array.rb +537 -0
  143. data/lib/sequel/extensions/pg_array_ops.rb +263 -0
  144. data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
  145. data/lib/sequel/extensions/pg_hstore.rb +313 -0
  146. data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
  147. data/lib/sequel/extensions/pg_inet.rb +113 -0
  148. data/lib/sequel/extensions/pg_interval.rb +191 -0
  149. data/lib/sequel/extensions/pg_json.rb +208 -0
  150. data/lib/sequel/extensions/pg_range.rb +512 -0
  151. data/lib/sequel/extensions/pg_range_ops.rb +150 -0
  152. data/lib/sequel/extensions/pg_row.rb +572 -0
  153. data/lib/sequel/extensions/pg_row_ops.rb +182 -0
  154. data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
  155. data/lib/sequel/extensions/pretty_table.rb +17 -72
  156. data/lib/sequel/extensions/query.rb +8 -4
  157. data/lib/sequel/extensions/query_literals.rb +79 -0
  158. data/lib/sequel/extensions/schema_caching.rb +76 -0
  159. data/lib/sequel/extensions/schema_dumper.rb +282 -76
  160. data/lib/sequel/extensions/select_remove.rb +39 -0
  161. data/lib/sequel/extensions/server_block.rb +140 -0
  162. data/lib/sequel/extensions/split_array_nil.rb +65 -0
  163. data/lib/sequel/extensions/sql_expr.rb +8 -110
  164. data/lib/sequel/extensions/string_date_time.rb +4 -0
  165. data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
  166. data/lib/sequel/extensions/to_dot.rb +99 -83
  167. data/lib/sequel/model/associations.rb +1263 -409
  168. data/lib/sequel/model/base.rb +624 -171
  169. data/lib/sequel/model/errors.rb +1 -1
  170. data/lib/sequel/model/exceptions.rb +24 -2
  171. data/lib/sequel/model/inflections.rb +1 -1
  172. data/lib/sequel/model.rb +30 -11
  173. data/lib/sequel/no_core_ext.rb +2 -0
  174. data/lib/sequel/plugins/active_model.rb +13 -1
  175. data/lib/sequel/plugins/association_pks.rb +22 -4
  176. data/lib/sequel/plugins/caching.rb +25 -18
  177. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  178. data/lib/sequel/plugins/composition.rb +44 -12
  179. data/lib/sequel/plugins/constraint_validations.rb +198 -0
  180. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  181. data/lib/sequel/plugins/defaults_setter.rb +72 -0
  182. data/lib/sequel/plugins/dirty.rb +214 -0
  183. data/lib/sequel/plugins/eager_each.rb +59 -0
  184. data/lib/sequel/plugins/force_encoding.rb +6 -6
  185. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  186. data/lib/sequel/plugins/identity_map.rb +134 -15
  187. data/lib/sequel/plugins/instance_filters.rb +10 -0
  188. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  189. data/lib/sequel/plugins/json_serializer.rb +58 -6
  190. data/lib/sequel/plugins/list.rb +13 -2
  191. data/lib/sequel/plugins/many_through_many.rb +103 -51
  192. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  193. data/lib/sequel/plugins/nested_attributes.rb +150 -66
  194. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  195. data/lib/sequel/plugins/pg_row.rb +121 -0
  196. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  197. data/lib/sequel/plugins/prepared_statements.rb +167 -0
  198. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  199. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  200. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  201. data/lib/sequel/plugins/rcte_tree.rb +31 -17
  202. data/lib/sequel/plugins/schema.rb +8 -3
  203. data/lib/sequel/plugins/serialization.rb +98 -49
  204. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  205. data/lib/sequel/plugins/sharding.rb +21 -54
  206. data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
  207. data/lib/sequel/plugins/static_cache.rb +99 -0
  208. data/lib/sequel/plugins/subclasses.rb +29 -3
  209. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  210. data/lib/sequel/plugins/timestamps.rb +1 -1
  211. data/lib/sequel/plugins/tree.rb +3 -3
  212. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  213. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  214. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  215. data/lib/sequel/plugins/validation_helpers.rb +55 -4
  216. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  217. data/lib/sequel/sql.rb +649 -122
  218. data/lib/sequel/timezones.rb +67 -40
  219. data/lib/sequel/version.rb +1 -1
  220. data/spec/adapters/db2_spec.rb +146 -0
  221. data/spec/adapters/firebird_spec.rb +1 -1
  222. data/spec/adapters/mssql_spec.rb +194 -66
  223. data/spec/adapters/mysql_spec.rb +475 -306
  224. data/spec/adapters/oracle_spec.rb +92 -117
  225. data/spec/adapters/postgres_spec.rb +1982 -325
  226. data/spec/adapters/spec_helper.rb +9 -6
  227. data/spec/adapters/sqlite_spec.rb +203 -75
  228. data/spec/core/connection_pool_spec.rb +218 -93
  229. data/spec/core/database_spec.rb +956 -522
  230. data/spec/core/dataset_spec.rb +1631 -1242
  231. data/spec/core/expression_filters_spec.rb +690 -334
  232. data/spec/core/mock_adapter_spec.rb +453 -0
  233. data/spec/core/object_graph_spec.rb +88 -129
  234. data/spec/core/schema_generator_spec.rb +4 -4
  235. data/spec/core/schema_spec.rb +556 -53
  236. data/spec/core/spec_helper.rb +7 -48
  237. data/spec/core_extensions_spec.rb +626 -0
  238. data/spec/extensions/active_model_spec.rb +13 -0
  239. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  240. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  241. data/spec/extensions/association_dependencies_spec.rb +15 -25
  242. data/spec/extensions/association_pks_spec.rb +66 -32
  243. data/spec/extensions/association_proxies_spec.rb +4 -4
  244. data/spec/extensions/boolean_readers_spec.rb +25 -25
  245. data/spec/extensions/caching_spec.rb +47 -51
  246. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  247. data/spec/extensions/columns_introspection_spec.rb +91 -0
  248. data/spec/extensions/composition_spec.rb +18 -13
  249. data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
  250. data/spec/extensions/constraint_validations_spec.rb +316 -0
  251. data/spec/extensions/dataset_associations_spec.rb +199 -0
  252. data/spec/extensions/defaults_setter_spec.rb +88 -0
  253. data/spec/extensions/dirty_spec.rb +155 -0
  254. data/spec/extensions/eager_each_spec.rb +34 -0
  255. data/spec/extensions/eval_inspect_spec.rb +67 -0
  256. data/spec/extensions/force_encoding_spec.rb +4 -2
  257. data/spec/extensions/hook_class_methods_spec.rb +97 -128
  258. data/spec/extensions/identity_map_spec.rb +142 -24
  259. data/spec/extensions/inflector_spec.rb +0 -4
  260. data/spec/extensions/instance_filters_spec.rb +11 -21
  261. data/spec/extensions/instance_hooks_spec.rb +72 -0
  262. data/spec/extensions/json_serializer_spec.rb +49 -12
  263. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  264. data/spec/extensions/list_spec.rb +49 -40
  265. data/spec/extensions/looser_typecasting_spec.rb +7 -7
  266. data/spec/extensions/many_through_many_spec.rb +368 -254
  267. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  268. data/spec/extensions/migration_spec.rb +140 -35
  269. data/spec/extensions/named_timezones_spec.rb +29 -11
  270. data/spec/extensions/nested_attributes_spec.rb +268 -89
  271. data/spec/extensions/null_dataset_spec.rb +85 -0
  272. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  273. data/spec/extensions/pg_array_ops_spec.rb +112 -0
  274. data/spec/extensions/pg_array_spec.rb +320 -0
  275. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  276. data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
  277. data/spec/extensions/pg_hstore_spec.rb +194 -0
  278. data/spec/extensions/pg_inet_spec.rb +47 -0
  279. data/spec/extensions/pg_interval_spec.rb +72 -0
  280. data/spec/extensions/pg_json_spec.rb +99 -0
  281. data/spec/extensions/pg_range_ops_spec.rb +56 -0
  282. data/spec/extensions/pg_range_spec.rb +395 -0
  283. data/spec/extensions/pg_row_ops_spec.rb +58 -0
  284. data/spec/extensions/pg_row_plugin_spec.rb +49 -0
  285. data/spec/extensions/pg_row_spec.rb +323 -0
  286. data/spec/extensions/pg_statement_cache_spec.rb +208 -0
  287. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  288. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  289. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  290. data/spec/extensions/prepared_statements_spec.rb +87 -0
  291. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  292. data/spec/extensions/pretty_table_spec.rb +7 -6
  293. data/spec/extensions/query_literals_spec.rb +167 -0
  294. data/spec/extensions/query_spec.rb +9 -3
  295. data/spec/extensions/rcte_tree_spec.rb +50 -43
  296. data/spec/extensions/schema_caching_spec.rb +41 -0
  297. data/spec/extensions/schema_dumper_spec.rb +434 -49
  298. data/spec/extensions/schema_spec.rb +30 -49
  299. data/spec/extensions/select_remove_spec.rb +38 -0
  300. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  301. data/spec/extensions/serialization_spec.rb +86 -48
  302. data/spec/extensions/server_block_spec.rb +90 -0
  303. data/spec/extensions/sharding_spec.rb +69 -143
  304. data/spec/extensions/single_table_inheritance_spec.rb +23 -29
  305. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  306. data/spec/extensions/spec_helper.rb +34 -67
  307. data/spec/extensions/split_array_nil_spec.rb +24 -0
  308. data/spec/extensions/sql_expr_spec.rb +29 -60
  309. data/spec/extensions/static_cache_spec.rb +145 -0
  310. data/spec/extensions/subclasses_spec.rb +14 -0
  311. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  312. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  313. data/spec/extensions/timestamps_spec.rb +6 -6
  314. data/spec/extensions/to_dot_spec.rb +8 -11
  315. data/spec/extensions/touch_spec.rb +13 -14
  316. data/spec/extensions/tree_spec.rb +11 -26
  317. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  318. data/spec/extensions/update_primary_key_spec.rb +30 -24
  319. data/spec/extensions/validation_class_methods_spec.rb +58 -67
  320. data/spec/extensions/validation_helpers_spec.rb +31 -37
  321. data/spec/extensions/xml_serializer_spec.rb +29 -4
  322. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  323. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  324. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  325. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  326. data/spec/integration/associations_test.rb +659 -21
  327. data/spec/integration/database_test.rb +11 -5
  328. data/spec/integration/dataset_test.rb +717 -129
  329. data/spec/integration/eager_loader_test.rb +38 -54
  330. data/spec/integration/migrator_test.rb +2 -3
  331. data/spec/integration/model_test.rb +81 -2
  332. data/spec/integration/plugin_test.rb +604 -147
  333. data/spec/integration/prepared_statement_test.rb +272 -128
  334. data/spec/integration/schema_test.rb +367 -57
  335. data/spec/integration/spec_helper.rb +42 -32
  336. data/spec/integration/timezone_test.rb +38 -12
  337. data/spec/integration/transaction_test.rb +183 -8
  338. data/spec/integration/type_test.rb +31 -8
  339. data/spec/model/association_reflection_spec.rb +207 -8
  340. data/spec/model/associations_spec.rb +1206 -693
  341. data/spec/model/base_spec.rb +334 -100
  342. data/spec/model/dataset_methods_spec.rb +45 -27
  343. data/spec/model/eager_loading_spec.rb +828 -692
  344. data/spec/model/hooks_spec.rb +355 -67
  345. data/spec/model/model_spec.rb +251 -179
  346. data/spec/model/plugins_spec.rb +24 -13
  347. data/spec/model/record_spec.rb +506 -232
  348. data/spec/model/spec_helper.rb +16 -77
  349. data/spec/model/validations_spec.rb +38 -2
  350. data/spec/rcov.opts +2 -0
  351. metadata +209 -80
  352. data/spec/core/core_sql_spec.rb +0 -451
@@ -0,0 +1,372 @@
1
+ module Sequel
2
+ module Mock
3
+ # Connection class for Sequel's mock adapter.
4
+ class Connection
5
+ # Sequel::Mock::Database object that created this connection
6
+ attr_reader :db
7
+
8
+ # Shard this connection operates on, when using Sequel's
9
+ # sharding support (always :default for databases not using
10
+ # sharding).
11
+ attr_reader :server
12
+
13
+ # The specific database options for this connection.
14
+ attr_reader :opts
15
+
16
+ # Store the db, server, and opts.
17
+ def initialize(db, server, opts)
18
+ @db = db
19
+ @server = server
20
+ @opts = opts
21
+ end
22
+
23
+ # Delegate to the db's #_execute method.
24
+ def execute(sql)
25
+ @db.send(:_execute, self, sql, :log=>false)
26
+ end
27
+ end
28
+
29
+ # Database class for Sequel's mock adapter.
30
+ class Database < Sequel::Database
31
+ set_adapter_scheme :mock
32
+
33
+ # Map of database type names to module names, used for handling
34
+ # mock adapters for specific database types.
35
+ SHARED_ADAPTERS = {
36
+ 'access'=>'Access',
37
+ 'db2'=>'DB2',
38
+ 'firebird'=>'Firebird',
39
+ 'informix'=>'Informix',
40
+ 'mssql'=>'MSSQL',
41
+ 'mysql'=>'MySQL',
42
+ 'oracle'=>'Oracle',
43
+ 'postgres'=>'Postgres',
44
+ 'sqlite'=>'SQLite'
45
+ }
46
+
47
+ # Procs to run for specific database types to get the mock adapter
48
+ # to work with the shared adapter
49
+ SHARED_ADAPTER_SETUP = {
50
+ 'postgres' => lambda do |db|
51
+ db.instance_eval do
52
+ @server_version = 90103
53
+ initialize_postgres_adapter
54
+ end
55
+ db.extend(Module.new do
56
+ def bound_variable_arg(arg, conn)
57
+ arg
58
+ end
59
+
60
+ def primary_key(table)
61
+ :id
62
+ end
63
+ end)
64
+ end,
65
+ 'oracle' => lambda do |db|
66
+ db.instance_eval do
67
+ @primary_key_sequences = {}
68
+ end
69
+ end
70
+ }
71
+
72
+ # Set the autogenerated primary key integer
73
+ # to be returned when running an insert query.
74
+ # Argument types supported:
75
+ #
76
+ # nil :: Return nil for all inserts
77
+ # Integer :: Starting integer for next insert, with
78
+ # futher inserts getting an incremented
79
+ # value
80
+ # Array :: First insert gets the first value in the
81
+ # array, second gets the second value, etc.
82
+ # Proc :: Called with the insert SQL query, uses
83
+ # the value returned
84
+ # Class :: Should be an Exception subclass, will create a new
85
+ # instance an raise it wrapped in a DatabaseError.
86
+ attr_writer :autoid
87
+
88
+ # Set the columns to set in the dataset when the dataset fetches
89
+ # rows. Argument types supported:
90
+ # nil :: Set no columns
91
+ # Array of Symbols: Used for all datasets
92
+ # Array (otherwise): First retrieval gets the first value in the
93
+ # array, second gets the second value, etc.
94
+ # Proc :: Called with the select SQL query, uses the value
95
+ # returned, which should be an array of symbols
96
+ attr_writer :columns
97
+
98
+ # Set the hashes to yield by execute when retrieving rows.
99
+ # Argument types supported:
100
+ #
101
+ # nil :: Yield no rows
102
+ # Hash :: Always yield a single row with this hash
103
+ # Array of Hashes :: Yield separately for each hash in this array
104
+ # Array (otherwise) :: First retrieval gets the first value
105
+ # in the array, second gets the second value, etc.
106
+ # Proc :: Called with the select SQL query, uses
107
+ # the value returned, which should be a hash or
108
+ # array of hashes.
109
+ # Class :: Should be an Exception subclass, will create a new
110
+ # instance an raise it wrapped in a DatabaseError.
111
+ attr_writer :fetch
112
+
113
+ # Set the number of rows to return from update or delete.
114
+ # Argument types supported:
115
+ #
116
+ # nil :: Return 0 for all updates and deletes
117
+ # Integer :: Used for all updates and deletes
118
+ # Array :: First update/delete gets the first value in the
119
+ # array, second gets the second value, etc.
120
+ # Proc :: Called with the update/delete SQL query, uses
121
+ # the value returned.
122
+ # Class :: Should be an Exception subclass, will create a new
123
+ # instance an raise it wrapped in a DatabaseError.
124
+ attr_writer :numrows
125
+
126
+ # Mock the server version, useful when using the shared adapters
127
+ attr_accessor :server_version
128
+
129
+ # Additional options supported:
130
+ #
131
+ # :autoid :: Call #autoid= with the value
132
+ # :columns :: Call #columns= with the value
133
+ # :fetch :: Call #fetch= with the value
134
+ # :numrows :: Call #numrows= with the value
135
+ # :extend :: A module the object is extended with.
136
+ # :sqls :: The array to store the SQL queries in.
137
+ def initialize(opts={})
138
+ super
139
+ opts = @opts
140
+ @sqls = opts[:sqls] || []
141
+ if mod_name = SHARED_ADAPTERS[opts[:host]]
142
+ @shared_adapter = true
143
+ require "sequel/adapters/shared/#{opts[:host]}"
144
+ extend Sequel.const_get(mod_name)::DatabaseMethods
145
+ extend_datasets Sequel.const_get(mod_name)::DatasetMethods
146
+ if pr = SHARED_ADAPTER_SETUP[opts[:host]]
147
+ pr.call(self)
148
+ end
149
+ end
150
+ self.autoid = opts[:autoid]
151
+ self.columns = opts[:columns]
152
+ self.fetch = opts[:fetch]
153
+ self.numrows = opts[:numrows]
154
+ extend(opts[:extend]) if opts[:extend]
155
+ sqls
156
+ end
157
+
158
+ # Return a related Connection option connecting to the given shard.
159
+ def connect(server)
160
+ Connection.new(self, server, server_opts(server))
161
+ end
162
+
163
+ # Store the sql used for later retrieval with #sqls, and return
164
+ # the appropriate value using either the #autoid, #fetch, or
165
+ # #numrows methods.
166
+ def execute(sql, opts={}, &block)
167
+ synchronize(opts[:server]){|c| _execute(c, sql, opts, &block)}
168
+ end
169
+ alias execute_ddl execute
170
+
171
+ # Store the sql used, and return the value of the #numrows method.
172
+ def execute_dui(sql, opts={})
173
+ execute(sql, opts.merge(:meth=>:numrows))
174
+ end
175
+
176
+ # Store the sql used, and return the value of the #autoid method.
177
+ def execute_insert(sql, opts={})
178
+ execute(sql, opts.merge(:meth=>:autoid))
179
+ end
180
+
181
+ # Return all stored SQL queries, and clear the cache
182
+ # of SQL queries.
183
+ def sqls
184
+ s = @sqls.dup
185
+ @sqls.clear
186
+ s
187
+ end
188
+
189
+ # Enable use of savepoints.
190
+ def supports_savepoints?
191
+ shared_adapter? ? super : true
192
+ end
193
+
194
+ private
195
+
196
+ def _autoid(sql, v, ds=nil)
197
+ case v
198
+ when Integer
199
+ if ds
200
+ ds.autoid += 1 if ds.autoid.is_a?(Integer)
201
+ else
202
+ @autoid += 1
203
+ end
204
+ v
205
+ else
206
+ _nextres(v, sql, nil)
207
+ end
208
+ end
209
+
210
+ def _execute(c, sql, opts={}, &block)
211
+ sql += " -- args: #{opts[:arguments].inspect}" if opts[:arguments]
212
+ sql += " -- #{@opts[:append]}" if @opts[:append]
213
+ sql += " -- #{c.server.is_a?(Symbol) ? c.server : c.server.inspect}" if c.server != :default
214
+ log_info(sql) unless opts[:log] == false
215
+ @sqls << sql
216
+
217
+ ds = opts[:dataset]
218
+ begin
219
+ if block
220
+ columns(ds, sql) if ds
221
+ _fetch(sql, (ds._fetch if ds) || @fetch, &block)
222
+ elsif meth = opts[:meth]
223
+ if meth == :numrows
224
+ _numrows(sql, (ds.numrows if ds) || @numrows)
225
+ else
226
+ v = ds.autoid if ds
227
+ _autoid(sql, v || @autoid, (ds if v))
228
+ end
229
+ end
230
+ rescue => e
231
+ raise_error(e)
232
+ end
233
+ end
234
+
235
+ def _fetch(sql, f, &block)
236
+ case f
237
+ when Hash
238
+ yield f.dup
239
+ when Array
240
+ if f.all?{|h| h.is_a?(Hash)}
241
+ f.each{|h| yield h.dup}
242
+ else
243
+ _fetch(sql, f.shift, &block)
244
+ end
245
+ when Proc
246
+ h = f.call(sql)
247
+ if h.is_a?(Hash)
248
+ yield h.dup
249
+ elsif h
250
+ h.each{|h1| yield h1.dup}
251
+ end
252
+ when Class
253
+ if f < Exception
254
+ raise f
255
+ else
256
+ raise Error, "Invalid @autoid/@numrows attribute: #{v.inspect}"
257
+ end
258
+ when nil
259
+ # nothing
260
+ else
261
+ raise Error, "Invalid @fetch attribute: #{f.inspect}"
262
+ end
263
+ end
264
+
265
+ def _nextres(v, sql, default)
266
+ case v
267
+ when Integer
268
+ v
269
+ when Array
270
+ v.empty? ? default : _nextres(v.shift, sql, default)
271
+ when Proc
272
+ v.call(sql)
273
+ when Class
274
+ if v < Exception
275
+ raise v
276
+ else
277
+ raise Error, "Invalid @autoid/@numrows attribute: #{v.inspect}"
278
+ end
279
+ when nil
280
+ default
281
+ else
282
+ raise Error, "Invalid @autoid/@numrows attribute: #{v.inspect}"
283
+ end
284
+ end
285
+
286
+ def _numrows(sql, v)
287
+ _nextres(v, sql, 0)
288
+ end
289
+
290
+ def columns(ds, sql, cs=@columns)
291
+ case cs
292
+ when Array
293
+ unless cs.empty?
294
+ if cs.all?{|c| c.is_a?(Symbol)}
295
+ ds.columns(*cs)
296
+ else
297
+ columns(ds, sql, cs.shift)
298
+ end
299
+ end
300
+ when Proc
301
+ ds.columns(*cs.call(sql))
302
+ when nil
303
+ # nothing
304
+ else
305
+ raise Error, "Invalid @columns attribute: #{cs.inspect}"
306
+ end
307
+ end
308
+
309
+ def disconnect_connection(c)
310
+ end
311
+
312
+ def quote_identifiers_default
313
+ shared_adapter? ? super : false
314
+ end
315
+
316
+ def identifier_input_method_default
317
+ shared_adapter? ? super : nil
318
+ end
319
+
320
+ def identifier_output_method_default
321
+ shared_adapter? ? super : nil
322
+ end
323
+
324
+ def shared_adapter?
325
+ @shared_adapter
326
+ end
327
+ end
328
+
329
+ class Dataset < Sequel::Dataset
330
+ Database::DatasetClass = self
331
+
332
+ # Override the databases's autoid setting for this dataset
333
+ attr_accessor :autoid
334
+
335
+ # Override the databases's fetch setting for this dataset
336
+ attr_accessor :_fetch
337
+
338
+ # Override the databases's numrows setting for this dataset
339
+ attr_accessor :numrows
340
+
341
+ # If arguments are provided, use them to set the columns
342
+ # for this dataset and return self. Otherwise, use the
343
+ # default Sequel behavior and return the columns.
344
+ def columns(*cs)
345
+ if cs.empty?
346
+ super
347
+ else
348
+ @columns = cs
349
+ self
350
+ end
351
+ end
352
+
353
+ def fetch_rows(sql, &block)
354
+ execute(sql, &block)
355
+ end
356
+
357
+ private
358
+
359
+ def execute(sql, opts={}, &block)
360
+ super(sql, opts.merge(:dataset=>self), &block)
361
+ end
362
+
363
+ def execute_dui(sql, opts={}, &block)
364
+ super(sql, opts.merge(:dataset=>self), &block)
365
+ end
366
+
367
+ def execute_insert(sql, opts={}, &block)
368
+ super(sql, opts.merge(:dataset=>self), &block)
369
+ end
370
+ end
371
+ end
372
+ end