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
@@ -1,6 +1,5 @@
1
- require 'mysql2' unless defined? Mysql2
2
-
3
- Sequel.require %w'shared/mysql', 'adapters'
1
+ require 'mysql2'
2
+ Sequel.require %w'shared/mysql_prepared_statements', 'adapters'
4
3
 
5
4
  module Sequel
6
5
  # Module for holding all Mysql2-related classes and modules for Sequel.
@@ -8,11 +7,21 @@ module Sequel
8
7
  # Database class for MySQL databases used with Sequel.
9
8
  class Database < Sequel::Database
10
9
  include Sequel::MySQL::DatabaseMethods
10
+ include Sequel::MySQL::PreparedStatements::DatabaseMethods
11
11
 
12
12
  # Mysql::Error messages that indicate the current connection should be disconnected
13
- MYSQL_DATABASE_DISCONNECT_ERRORS = /\A(Commands out of sync; you can't run this command now|Can't connect to local MySQL server through socket|MySQL server has gone away)/
13
+ MYSQL_DATABASE_DISCONNECT_ERRORS = /\A(Commands out of sync; you can't run this command now|Can't connect to local MySQL server through socket|MySQL server has gone away|This connection is still waiting for a result, try again once you have the result|closed MySQL connection)/
14
14
 
15
15
  set_adapter_scheme :mysql2
16
+
17
+ # Whether to convert tinyint columns to bool for this database
18
+ attr_accessor :convert_tinyint_to_bool
19
+
20
+ # Set the convert_tinyint_to_bool setting based on the default value.
21
+ def initialize(opts={})
22
+ super
23
+ self.convert_tinyint_to_bool = Sequel::MySQL.convert_tinyint_to_bool
24
+ end
16
25
 
17
26
  # Connect to the database. In addition to the usual database options,
18
27
  # the following options have effect:
@@ -21,7 +30,6 @@ module Sequel
21
30
  # a filter for an autoincrement column equals NULL to return the last
22
31
  # inserted row.
23
32
  # * :charset - Same as :encoding (:encoding takes precendence)
24
- # * :compress - Set to false to not compress results from the server
25
33
  # * :config_default_group - The default group to read from the in
26
34
  # the MySQL config file.
27
35
  # * :config_local_infile - If provided, sets the Mysql::OPT_LOCAL_INFILE
@@ -37,42 +45,34 @@ module Sequel
37
45
  opts = server_opts(server)
38
46
  opts[:host] ||= 'localhost'
39
47
  opts[:username] ||= opts[:user]
48
+ opts[:flags] = ::Mysql2::Client::FOUND_ROWS if ::Mysql2::Client.const_defined?(:FOUND_ROWS)
40
49
  conn = ::Mysql2::Client.new(opts)
50
+ conn.query_options.merge!(:symbolize_keys=>true, :cache_rows=>false)
51
+
52
+ sqls = mysql_connection_setting_sqls
41
53
 
42
- sqls = []
43
54
  # Set encoding a slightly different way after connecting,
44
55
  # in case the READ_DEFAULT_GROUP overrode the provided encoding.
45
56
  # Doesn't work across implicit reconnects, but Sequel doesn't turn on
46
57
  # that feature.
47
58
  if encoding = opts[:encoding] || opts[:charset]
48
- sqls << "SET NAMES #{conn.escape(encoding.to_s)}"
59
+ sqls.unshift("SET NAMES #{conn.escape(encoding.to_s)}")
49
60
  end
50
61
 
51
- # Increase timeout so mysql server doesn't disconnect us.
52
- # Value used by default is maximum allowed value on Windows.
53
- sqls << "SET @@wait_timeout = #{opts[:timeout] || 2147483}"
54
-
55
- # By default, MySQL 'where id is null' selects the last inserted id
56
- sqls << "SET SQL_AUTO_IS_NULL=0" unless opts[:auto_is_null]
57
-
58
62
  sqls.each{|sql| log_yield(sql){conn.query(sql)}}
59
63
 
64
+ add_prepared_statements_cache(conn)
60
65
  conn
61
66
  end
62
67
 
63
- # Returns instance of Sequel::MySQL::Dataset with the given options.
64
- def dataset(opts = nil)
65
- Mysql2::Dataset.new(self, opts)
68
+ # Return the number of matched rows when executing a delete/update statement.
69
+ def execute_dui(sql, opts={})
70
+ execute(sql, opts){|c| return c.affected_rows}
66
71
  end
67
72
 
68
- # Executes the given SQL using an available connection, yielding the
69
- # connection if the block is given.
70
- def execute(sql, opts={}, &block)
71
- if opts[:sproc]
72
- call_sproc(sql, opts, &block)
73
- else
74
- synchronize(opts[:server]){|conn| _execute(conn, sql, opts, &block)}
75
- end
73
+ # Return the last inserted id when executing an insert statement.
74
+ def execute_insert(sql, opts={})
75
+ execute(sql, opts){|c| return c.last_id}
76
76
  end
77
77
 
78
78
  # Return the version of the MySQL server two which we are connecting.
@@ -87,14 +87,14 @@ module Sequel
87
87
  # yield the connection if a block is given.
88
88
  def _execute(conn, sql, opts)
89
89
  begin
90
- r = log_yield(sql){conn.query(sql, :symbolize_keys => true, :database_timezone => Sequel.database_timezone, :application_timezone => Sequel.application_timezone)}
90
+ r = log_yield((log_sql = opts[:log_sql]) ? sql + log_sql : sql){conn.query(sql, :database_timezone => timezone, :application_timezone => Sequel.application_timezone)}
91
91
  if opts[:type] == :select
92
92
  yield r if r
93
93
  elsif block_given?
94
94
  yield conn
95
95
  end
96
96
  rescue ::Mysql2::Error => e
97
- raise_error(e, :disconnect=>MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message))
97
+ raise_error(e)
98
98
  end
99
99
  end
100
100
 
@@ -108,6 +108,17 @@ module Sequel
108
108
  [::Mysql2::Error]
109
109
  end
110
110
 
111
+ # If a connection object is available, try pinging it. Otherwise, if the
112
+ # error is a Mysql2::Error, check the SQL state and exception message for
113
+ # disconnects.
114
+ def disconnect_error?(e, opts)
115
+ super ||
116
+ ((conn = opts[:conn]) && !conn.ping) ||
117
+ (e.is_a?(::Mysql2::Error) &&
118
+ (e.sql_state =~ /\A08/ ||
119
+ MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message)))
120
+ end
121
+
111
122
  # The database name when using the native adapter is always stored in
112
123
  # the :database option.
113
124
  def database_name
@@ -121,58 +132,56 @@ module Sequel
121
132
 
122
133
  # Convert tinyint(1) type to boolean if convert_tinyint_to_bool is true
123
134
  def schema_column_type(db_type)
124
- Sequel::MySQL.convert_tinyint_to_bool && db_type == 'tinyint(1)' ? :boolean : super
135
+ convert_tinyint_to_bool && db_type == 'tinyint(1)' ? :boolean : super
125
136
  end
126
137
  end
127
138
 
128
139
  # Dataset class for MySQL datasets accessed via the native driver.
129
140
  class Dataset < Sequel::Dataset
130
141
  include Sequel::MySQL::DatasetMethods
142
+ include Sequel::MySQL::PreparedStatements::DatasetMethods
131
143
 
132
- # Delete rows matching this dataset
133
- def delete
134
- execute_dui(delete_sql){|c| return c.affected_rows}
135
- end
144
+ Database::DatasetClass = self
136
145
 
137
146
  # Yield all rows matching this dataset.
138
- def fetch_rows(sql, &block)
147
+ def fetch_rows(sql)
139
148
  execute(sql) do |r|
140
- @columns = r.fields
141
- r.each(:cast_booleans => Sequel::MySQL.convert_tinyint_to_bool, &block)
149
+ if identifier_output_method
150
+ cols = r.fields
151
+ @columns = cols2 = cols.map{|c| output_identifier(c.to_s)}
152
+ cs = cols.zip(cols2)
153
+ r.each(:cast_booleans=>convert_tinyint_to_bool?) do |row|
154
+ h = {}
155
+ cs.each do |a, b|
156
+ h[b] = row[a]
157
+ end
158
+ yield h
159
+ end
160
+ else
161
+ @columns = r.fields
162
+ r.each(:cast_booleans=>convert_tinyint_to_bool?){|h| yield h}
163
+ end
142
164
  end
143
165
  self
144
166
  end
145
167
 
146
- # Insert a new value into this dataset
147
- def insert(*values)
148
- execute_dui(insert_sql(*values)){|c| return c.last_id}
149
- end
150
-
151
- # Replace (update or insert) the matching row.
152
- def replace(*args)
153
- execute_dui(replace_sql(*args)){|c| return c.last_id}
154
- end
168
+ private
155
169
 
156
- # Update the matching rows.
157
- def update(values={})
158
- execute_dui(update_sql(values)){|c| return c.affected_rows}
170
+ # Whether to cast tinyint(1) columns to integer instead of boolean.
171
+ # By default, uses the opposite of the database's convert_tinyint_to_bool
172
+ # setting. Exists for compatibility with the mysql adapter.
173
+ def convert_tinyint_to_bool?
174
+ @db.convert_tinyint_to_bool
159
175
  end
160
176
 
161
- private
162
-
163
177
  # Set the :type option to :select if it hasn't been set.
164
178
  def execute(sql, opts={}, &block)
165
179
  super(sql, {:type=>:select}.merge(opts), &block)
166
180
  end
167
181
 
168
- # Set the :type option to :dui if it hasn't been set.
169
- def execute_dui(sql, opts={}, &block)
170
- super(sql, {:type=>:dui}.merge(opts), &block)
171
- end
172
-
173
182
  # Handle correct quoting of strings using ::Mysql2::Client#escape.
174
- def literal_string(v)
175
- db.synchronize{|c| "'#{c.escape(v)}'"}
183
+ def literal_string_append(sql, v)
184
+ sql << "'" << db.synchronize{|c| c.escape(v)} << "'"
176
185
  end
177
186
  end
178
187
  end
@@ -7,12 +7,7 @@ module Sequel
7
7
  module MSSQL
8
8
  module DatabaseMethods
9
9
  include Sequel::MSSQL::DatabaseMethods
10
- LAST_INSERT_ID_SQL='SELECT SCOPE_IDENTITY()'
11
-
12
- # Return an instance of Sequel::ODBC::MSSQL::Dataset with the given opts.
13
- def dataset(opts=nil)
14
- Sequel::ODBC::MSSQL::Dataset.new(self, opts)
15
- end
10
+ LAST_INSERT_ID_SQL='SELECT SCOPE_IDENTITY()'.freeze
16
11
 
17
12
  # Return the last inserted identity value.
18
13
  def execute_insert(sql, opts={})
@@ -21,8 +16,8 @@ module Sequel
21
16
  log_yield(sql){conn.do(sql)}
22
17
  begin
23
18
  s = log_yield(LAST_INSERT_ID_SQL){conn.run(LAST_INSERT_ID_SQL)}
24
- if (rows = s.fetch_all) and (row = rows.first)
25
- Integer(row.first)
19
+ if (rows = s.fetch_all) and (row = rows.first) and (v = row.first)
20
+ Integer(v)
26
21
  end
27
22
  ensure
28
23
  s.drop if s
@@ -33,9 +28,22 @@ module Sequel
33
28
  end
34
29
  end
35
30
  end
36
-
37
31
  class Dataset < ODBC::Dataset
38
32
  include Sequel::MSSQL::DatasetMethods
33
+
34
+ private
35
+
36
+ # Use ODBC format, not Microsoft format, as the ODBC layer does
37
+ # some translation.
38
+ def default_timestamp_format
39
+ TIMESTAMP_FORMAT
40
+ end
41
+
42
+ # Use ODBC format, not Microsoft format, as the ODBC layer does
43
+ # some translation.
44
+ def literal_date(v)
45
+ v.strftime(ODBC_DATE_FORMAT)
46
+ end
39
47
  end
40
48
  end
41
49
  end
@@ -15,9 +15,16 @@ module Sequel
15
15
  when 'mssql'
16
16
  Sequel.ts_require 'adapters/odbc/mssql'
17
17
  extend Sequel::ODBC::MSSQL::DatabaseMethods
18
+ @dataset_class = Sequel::ODBC::MSSQL::Dataset
19
+ set_mssql_unicode_strings
18
20
  when 'progress'
19
21
  Sequel.ts_require 'adapters/shared/progress'
20
22
  extend Sequel::Progress::DatabaseMethods
23
+ extend_datasets(Sequel::Progress::DatasetMethods)
24
+ when 'db2'
25
+ Sequel.ts_require 'adapters/shared/db2'
26
+ extend ::Sequel::DB2::DatabaseMethods
27
+ extend_datasets ::Sequel::DB2::DatasetMethods
21
28
  end
22
29
  end
23
30
 
@@ -41,17 +48,13 @@ module Sequel
41
48
  conn
42
49
  end
43
50
 
44
- def dataset(opts = nil)
45
- ODBC::Dataset.new(self, opts)
46
- end
47
-
48
51
  def execute(sql, opts={})
49
52
  synchronize(opts[:server]) do |conn|
50
53
  begin
51
54
  r = log_yield(sql){conn.run(sql)}
52
55
  yield(r) if block_given?
53
56
  rescue ::ODBC::Error, ArgumentError => e
54
- raise_error(e, :disconnect=>DISCONNECT_ERRORS.match(e.message))
57
+ raise_error(e)
55
58
  ensure
56
59
  r.drop if r
57
60
  end
@@ -64,7 +67,7 @@ module Sequel
64
67
  begin
65
68
  log_yield(sql){conn.do(sql)}
66
69
  rescue ::ODBC::Error, ArgumentError => e
67
- raise_error(e, :disconnect=>DISCONNECT_ERRORS.match(e.message))
70
+ raise_error(e)
68
71
  end
69
72
  end
70
73
  end
@@ -76,9 +79,17 @@ module Sequel
76
79
  :do
77
80
  end
78
81
 
82
+ def database_error_classes
83
+ [::ODBC::Error]
84
+ end
85
+
79
86
  def disconnect_connection(c)
80
87
  c.disconnect
81
88
  end
89
+
90
+ def disconnect_error?(e, opts)
91
+ super || (e.is_a?(::ODBC::Error) && DISCONNECT_ERRORS.match(e.message))
92
+ end
82
93
  end
83
94
 
84
95
  class Dataset < Sequel::Dataset
@@ -87,15 +98,23 @@ module Sequel
87
98
  ODBC_DATE_FORMAT = "{d '%Y-%m-%d'}".freeze
88
99
  TIMESTAMP_FORMAT="{ts '%Y-%m-%d %H:%M:%S'}".freeze
89
100
 
101
+ Database::DatasetClass = self
102
+
90
103
  def fetch_rows(sql)
91
104
  execute(sql) do |s|
92
105
  i = -1
93
106
  cols = s.columns(true).map{|c| [output_identifier(c.name), i+=1]}
94
- @columns = cols.map{|c| c.at(0)}
107
+ columns = cols.map{|c| c.at(0)}
108
+ if opts[:offset] && offset_returns_row_number_column?
109
+ rn = row_number_column
110
+ columns.delete(rn)
111
+ end
112
+ @columns = columns
95
113
  if rows = s.fetch_all
96
114
  rows.each do |row|
97
115
  hash = {}
98
116
  cols.each{|n,i| hash[n] = convert_odbc_value(row[i])}
117
+ hash.delete(rn) if rn
99
118
  yield hash
100
119
  end
101
120
  end
@@ -114,9 +133,9 @@ module Sequel
114
133
  # ODBCColumn#mapSqlTypeToGenericType and Column#klass.
115
134
  case v
116
135
  when ::ODBC::TimeStamp
117
- Sequel.database_to_application_timestamp([v.year, v.month, v.day, v.hour, v.minute, v.second])
136
+ db.to_application_timestamp([v.year, v.month, v.day, v.hour, v.minute, v.second])
118
137
  when ::ODBC::Time
119
- Sequel.database_to_application_timestamp([now.year, now.month, now.day, v.hour, v.minute, v.second])
138
+ Sequel::SQLTime.create(v.hour, v.minute, v.second)
120
139
  when ::ODBC::Date
121
140
  Date.new(v.year, v.month, v.day)
122
141
  else
@@ -15,10 +15,6 @@ module Sequel
15
15
  )
16
16
  end
17
17
 
18
- def dataset(opts = nil)
19
- OpenBase::Dataset.new(self, opts)
20
- end
21
-
22
18
  def execute(sql, opts={})
23
19
  synchronize(opts[:server]) do |conn|
24
20
  r = log_yield(sql){conn.execute(sql)}
@@ -36,7 +32,9 @@ module Sequel
36
32
  end
37
33
 
38
34
  class Dataset < Sequel::Dataset
39
- SELECT_CLAUSE_METHODS = clause_methods(:select, %w'distinct columns from join where group having compounds order limit')
35
+ SELECT_CLAUSE_METHODS = clause_methods(:select, %w'select distinct columns from join where group having compounds order limit')
36
+
37
+ Database::DatasetClass = self
40
38
 
41
39
  def fetch_rows(sql)
42
40
  execute(sql) do |result|