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
@@ -2,19 +2,20 @@ require 'rubygems'
2
2
  require 'logger'
3
3
  unless Object.const_defined?('Sequel')
4
4
  $:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), "../../lib/"))
5
- require 'sequel'
5
+ require 'sequel/no_core_ext'
6
6
  end
7
7
  begin
8
8
  require File.join(File.dirname(File.dirname(__FILE__)), 'spec_config.rb') unless defined?(INTEGRATION_DB)
9
9
  rescue LoadError
10
10
  end
11
11
 
12
- Sequel::Model.use_transactions = false
12
+ if ENV['SEQUEL_COLUMNS_INTROSPECTION']
13
+ Sequel.extension :columns_introspection
14
+ Sequel::Dataset.introspect_all_columns
15
+ end
13
16
 
14
- $sqls = []
15
- def clear_sqls
16
- $sqls.clear
17
- end
17
+ Sequel::Model.use_transactions = false
18
+ Sequel::Model.cache_anonymous_models = false
18
19
 
19
20
  unless defined?(RSpec)
20
21
  module Spec::Matchers
@@ -29,46 +30,46 @@ unless defined?(RSpec)
29
30
  end
30
31
  end
31
32
 
32
- (defined?(RSpec) ? RSpec::Core::ExampleGroup : Spec::Example::ExampleGroup).class_eval do
33
- def log
34
- begin
35
- INTEGRATION_DB.loggers << Logger.new(STDOUT)
36
- yield
37
- ensure
38
- INTEGRATION_DB.loggers.pop
39
- end
40
- end
41
-
42
- def self.log_specify(message, &block)
43
- specify(message){log{instance_eval(&block)}}
44
- end
45
-
46
- def self.cspecify(message, *checked, &block)
47
- pending = false
33
+ def Sequel.guarded?(*checked)
34
+ unless ENV['SEQUEL_NO_PENDING']
48
35
  checked.each do |c|
49
36
  case c
50
37
  when INTEGRATION_DB.database_type
51
- pending = c
38
+ return c
52
39
  when Array
53
40
  case c.length
54
41
  when 1
55
- pending = c if c.first == INTEGRATION_DB.adapter_scheme
42
+ return c if c.first == INTEGRATION_DB.adapter_scheme
56
43
  when 2
57
44
  if c.first.is_a?(Proc)
58
- pending = c if c.first.call(INTEGRATION_DB) && c.last == INTEGRATION_DB.database_type
45
+ return c if c.last == INTEGRATION_DB.database_type && c.first.call(INTEGRATION_DB)
59
46
  elsif c.last.is_a?(Proc)
60
- pending = c if c.first == INTEGRATION_DB.adapter_scheme && c.last.call(INTEGRATION_DB)
47
+ return c if c.first == INTEGRATION_DB.adapter_scheme && c.last.call(INTEGRATION_DB)
61
48
  else
62
- pending = c if c.first == INTEGRATION_DB.adapter_scheme && c.last == INTEGRATION_DB.database_type
49
+ return c if c.first == INTEGRATION_DB.adapter_scheme && c.last == INTEGRATION_DB.database_type
63
50
  end
64
51
  when 3
65
- pending = c if c[0] == INTEGRATION_DB.adapter_scheme && c[1] == INTEGRATION_DB.database_type && c[2].call(INTEGRATION_DB)
52
+ return c if c[0] == INTEGRATION_DB.adapter_scheme && c[1] == INTEGRATION_DB.database_type && c[2].call(INTEGRATION_DB)
66
53
  end
67
54
  end
68
- break if pending
69
55
  end
70
- if pending
71
- specify(message){pending("Not yet working on #{Array(pending).join(', ')}", &block)}
56
+ end
57
+ false
58
+ end
59
+
60
+ (defined?(RSpec) ? RSpec::Core::ExampleGroup : Spec::Example::ExampleGroup).class_eval do
61
+ def log
62
+ begin
63
+ INTEGRATION_DB.loggers << Logger.new(STDOUT)
64
+ yield
65
+ ensure
66
+ INTEGRATION_DB.loggers.pop
67
+ end
68
+ end
69
+
70
+ def self.cspecify(message, *checked, &block)
71
+ if pending = Sequel.guarded?(*checked)
72
+ specify(message){pending("Not yet working on #{Array(pending).map{|x| x.is_a?(Proc) ? :proc : x}.join(', ')}", &block)}
72
73
  else
73
74
  specify(message, &block)
74
75
  end
@@ -82,5 +83,14 @@ if defined?(INTEGRATION_DB) || defined?(INTEGRATION_URL) || ENV['SEQUEL_INTEGRAT
82
83
  #INTEGRATION_DB.instance_variable_set(:@server_version, 80100)
83
84
  end
84
85
  else
85
- INTEGRATION_DB = Sequel.sqlite('', :quote_identifiers=>false)
86
+ INTEGRATION_DB = Sequel.sqlite
87
+ end
88
+
89
+ if INTEGRATION_DB.adapter_scheme == :ibmdb
90
+ def INTEGRATION_DB.drop_table(*tables)
91
+ super
92
+ rescue Sequel::DatabaseError
93
+ disconnect
94
+ super
95
+ end
86
96
  end
@@ -1,15 +1,17 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  describe "Sequel timezone support" do
4
- def test_timezone
4
+ def test_timezone(timezone=Sequel.application_timezone)
5
+ tz = timezone
6
+ Sequel.datetime_class = Time
5
7
  # Tests should cover both DST and non-DST times.
6
8
  [Time.now, Time.local(2010,1,1,12), Time.local(2010,6,1,12)].each do |t|
7
9
  @db[:t].insert(t)
8
10
  t2 = @db[:t].single_value
9
- t2 = Sequel.database_to_application_timestamp(t2.to_s) unless t2.is_a?(Time)
11
+ t2 = @db.to_application_timestamp(t2.to_s) unless t2.is_a?(Time)
10
12
  (t2 - t).should be_within(2).of(0)
11
- t2.utc_offset.should == 0 if Sequel.application_timezone == :utc
12
- t2.utc_offset.should == t.getlocal.utc_offset if Sequel.application_timezone == :local
13
+ t2.utc_offset.should == 0 if timezone == :utc
14
+ t2.utc_offset.should == t.getlocal.utc_offset if timezone == :local
13
15
  @db[:t].delete
14
16
  end
15
17
 
@@ -19,10 +21,10 @@ describe "Sequel timezone support" do
19
21
  [DateTime.now, DateTime.civil(2010,1,1,12,0,0,local_std_offset), DateTime.civil(2010,6,1,12,0,0,local_dst_offset)].each do |dt|
20
22
  @db[:t].insert(dt)
21
23
  dt2 = @db[:t].single_value
22
- dt2 = Sequel.database_to_application_timestamp(dt2.to_s) unless dt2.is_a?(DateTime)
24
+ dt2 = @db.to_application_timestamp(dt2.to_s) unless dt2.is_a?(DateTime)
23
25
  (dt2 - dt).should be_within(0.00002).of(0)
24
- dt2.offset.should == 0 if Sequel.application_timezone == :utc
25
- dt2.offset.should == dt.offset if Sequel.application_timezone == :local
26
+ dt2.offset.should == 0 if timezone == :utc
27
+ dt2.offset.should == dt.offset if timezone == :local
26
28
  @db[:t].delete
27
29
  end
28
30
  end
@@ -32,30 +34,54 @@ describe "Sequel timezone support" do
32
34
  @db.create_table!(:t){DateTime :t}
33
35
  end
34
36
  after do
35
- @db.drop_table(:t)
37
+ @db.timezone = nil
36
38
  Sequel.default_timezone = nil
37
39
  Sequel.datetime_class = Time
40
+ @db.drop_table(:t)
38
41
  end
39
42
 
40
- cspecify "should support using UTC for database storage and local time for the application", [:swift], [:tinytds], [:do, proc{|db| db.database_type != :sqlite}] do
43
+ cspecify "should support using UTC for database storage and local time for the application", [:swift], [:tinytds], [:do, :mysql], [:do, :postgres], [:oracle] do
41
44
  Sequel.database_timezone = :utc
42
45
  Sequel.application_timezone = :local
43
46
  test_timezone
47
+ Sequel.database_timezone = nil
48
+ @db.timezone = :utc
49
+ test_timezone
44
50
  end
45
51
 
46
- cspecify "should support using local time for database storage and UTC for the application", [:swift], [:tinytds], [:do, proc{|db| db.database_type != :sqlite}] do
52
+ cspecify "should support using local time for database storage and UTC for the application", [:swift], [:tinytds], [:do, :mysql], [:do, :postgres], [:oracle] do
47
53
  Sequel.database_timezone = :local
48
54
  Sequel.application_timezone = :utc
49
55
  test_timezone
56
+ Sequel.database_timezone = nil
57
+ @db.timezone = :local
58
+ test_timezone
50
59
  end
51
60
 
52
- cspecify "should support using UTC for both database storage and for application", [:swift], [:do, proc{|db| db.database_type != :sqlite}] do
61
+ cspecify "should support using UTC for both database storage and for application", [:do, :mysql], [:do, :postgres], [:oracle] do
53
62
  Sequel.default_timezone = :utc
54
63
  test_timezone
64
+ Sequel.database_timezone = :local
65
+ @db.timezone = :utc
66
+ test_timezone
55
67
  end
56
68
 
57
- cspecify "should support using local time for both database storage and for application", [:do, proc{|db| db.database_type != :sqlite}] do
69
+ cspecify "should support using local time for both database storage and for application", [:do, :mysql], [:do, :postgres], [:oracle], [:swift, :postgres], [:swift, :mysql] do
58
70
  Sequel.default_timezone = :local
59
71
  test_timezone
72
+ Sequel.database_timezone = :utc
73
+ @db.timezone = :local
74
+ test_timezone
75
+ end
76
+
77
+ specify "should allow overriding the database_timezone on a per-database basis" do
78
+ Sequel.database_timezone = :utc
79
+ @db.timezone = :local
80
+ t = Time.now
81
+ @db[:t].insert(t)
82
+ s = @db[:t].get(Sequel.cast(:t, String))
83
+ if o = Date._parse(s)[:offset]
84
+ o.should == t.utc_offset
85
+ end
60
86
  end
61
87
  end
@@ -1,15 +1,16 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  describe "Database transactions" do
4
- before do
4
+ before(:all) do
5
5
  @db = INTEGRATION_DB
6
- @db.drop_table(:items) if @db.table_exists?(:items)
7
- @db.create_table(:items, :engine=>'InnoDB'){String :name; Integer :value}
6
+ @db.create_table!(:items, :engine=>'InnoDB'){String :name; Integer :value}
8
7
  @d = @db[:items]
9
- clear_sqls
10
8
  end
11
- after do
12
- @db.drop_table(:items) if @db.table_exists?(:items)
9
+ before do
10
+ @d.delete
11
+ end
12
+ after(:all) do
13
+ @db.drop_table?(:items)
13
14
  end
14
15
 
15
16
  specify "should support transactions" do
@@ -21,6 +22,13 @@ describe "Database transactions" do
21
22
  @db.transaction{|conn| conn.should_not == nil}
22
23
  end
23
24
 
25
+ specify "should have #in_transaction? work correctly" do
26
+ @db.in_transaction?.should be_false
27
+ c = nil
28
+ @db.transaction{c = @db.in_transaction?}
29
+ c.should be_true
30
+ end
31
+
24
32
  specify "should correctly rollback transactions" do
25
33
  proc do
26
34
  @db.transaction do
@@ -29,12 +37,22 @@ describe "Database transactions" do
29
37
  end
30
38
  end.should raise_error(Interrupt)
31
39
 
40
+ @db.transaction do
41
+ @d << {:name => 'abc', :value => 1}
42
+ raise Sequel::Rollback
43
+ end.should be_nil
44
+
32
45
  proc do
33
- @db.transaction do
46
+ @db.transaction(:rollback=>:reraise) do
34
47
  @d << {:name => 'abc', :value => 1}
35
48
  raise Sequel::Rollback
36
49
  end
37
- end.should_not raise_error
50
+ end.should raise_error(Sequel::Rollback)
51
+
52
+ @db.transaction(:rollback=>:always) do
53
+ @d << {:name => 'abc', :value => 1}
54
+ 2
55
+ end.should be_nil
38
56
 
39
57
  @d.count.should == 0
40
58
  end
@@ -115,6 +133,16 @@ describe "Database transactions" do
115
133
  end
116
134
 
117
135
  if INTEGRATION_DB.supports_prepared_transactions?
136
+ specify "should allow saving and destroying of model objects" do
137
+ c = Class.new(Sequel::Model(@d))
138
+ c.set_primary_key :name
139
+ c.unrestrict_primary_key
140
+ c.use_after_commit_rollback = false
141
+ @db.transaction(:prepare=>'XYZ'){c.create(:name => '1'); c.create(:name => '2').destroy}
142
+ @db.commit_prepared_transaction('XYZ')
143
+ @d.select_order_map(:name).should == ['1']
144
+ end
145
+
118
146
  specify "should commit prepared transactions using commit_prepared_transaction" do
119
147
  @db.transaction(:prepare=>'XYZ'){@d << {:name => '1'}}
120
148
  @db.commit_prepared_transaction('XYZ')
@@ -126,6 +154,14 @@ describe "Database transactions" do
126
154
  @db.rollback_prepared_transaction('XYZ')
127
155
  @d.select_order_map(:name).should == []
128
156
  end
157
+
158
+ if INTEGRATION_DB.supports_savepoints_in_prepared_transactions?
159
+ specify "should support savepoints when using prepared transactions" do
160
+ @db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@d << {:name => '1'}}}
161
+ @db.commit_prepared_transaction('XYZ')
162
+ @d.select_order_map(:name).should == ['1']
163
+ end
164
+ end
129
165
  end
130
166
 
131
167
  specify "should support all transaction isolation levels" do
@@ -134,4 +170,143 @@ describe "Database transactions" do
134
170
  @d.count.should == i + 1
135
171
  end
136
172
  end
173
+
174
+ specify "should support after_commit outside transactions" do
175
+ c = nil
176
+ @db.after_commit{c = 1}
177
+ c.should == 1
178
+ end
179
+
180
+ specify "should support after_rollback outside transactions" do
181
+ c = nil
182
+ @db.after_rollback{c = 1}
183
+ c.should be_nil
184
+ end
185
+
186
+ specify "should support after_commit inside transactions" do
187
+ c = nil
188
+ @db.transaction{@db.after_commit{c = 1}; c.should be_nil}
189
+ c.should == 1
190
+ end
191
+
192
+ specify "should support after_rollback inside transactions" do
193
+ c = nil
194
+ @db.transaction{@db.after_rollback{c = 1}; c.should be_nil}
195
+ c.should be_nil
196
+ end
197
+
198
+ specify "should not call after_commit if the transaction rolls back" do
199
+ c = nil
200
+ @db.transaction{@db.after_commit{c = 1}; c.should be_nil; raise Sequel::Rollback}
201
+ c.should be_nil
202
+ end
203
+
204
+ specify "should call after_rollback if the transaction rolls back" do
205
+ c = nil
206
+ @db.transaction{@db.after_rollback{c = 1}; c.should be_nil; raise Sequel::Rollback}
207
+ c.should == 1
208
+ end
209
+
210
+ specify "should support multiple after_commit blocks inside transactions" do
211
+ c = []
212
+ @db.transaction{@db.after_commit{c << 1}; @db.after_commit{c << 2}; c.should == []}
213
+ c.should == [1, 2]
214
+ end
215
+
216
+ specify "should support multiple after_rollback blocks inside transactions" do
217
+ c = []
218
+ @db.transaction{@db.after_rollback{c << 1}; @db.after_rollback{c << 2}; c.should == []; raise Sequel::Rollback}
219
+ c.should == [1, 2]
220
+ end
221
+
222
+ specify "should support after_commit inside nested transactions" do
223
+ c = nil
224
+ @db.transaction{@db.transaction{@db.after_commit{c = 1}}; c.should be_nil}
225
+ c.should == 1
226
+ end
227
+
228
+ specify "should support after_rollback inside nested transactions" do
229
+ c = nil
230
+ @db.transaction{@db.transaction{@db.after_rollback{c = 1}}; c.should be_nil; raise Sequel::Rollback}
231
+ c.should == 1
232
+ end
233
+
234
+ if INTEGRATION_DB.supports_savepoints?
235
+ specify "should support after_commit inside savepoints" do
236
+ c = nil
237
+ @db.transaction{@db.transaction(:savepoint=>true){@db.after_commit{c = 1}}; c.should be_nil}
238
+ c.should == 1
239
+ end
240
+
241
+ specify "should support after_rollback inside savepoints" do
242
+ c = nil
243
+ @db.transaction{@db.transaction(:savepoint=>true){@db.after_rollback{c = 1}}; c.should be_nil; raise Sequel::Rollback}
244
+ c.should == 1
245
+ end
246
+ end
247
+
248
+ if INTEGRATION_DB.supports_prepared_transactions?
249
+ specify "should raise an error if you attempt to use after_commit or after_rollback inside a prepared transaction" do
250
+ proc{@db.transaction(:prepare=>'XYZ'){@db.after_commit{}}}.should raise_error(Sequel::Error)
251
+ proc{@db.transaction(:prepare=>'XYZ'){@db.after_rollback{}}}.should raise_error(Sequel::Error)
252
+ end
253
+
254
+ if INTEGRATION_DB.supports_savepoints_in_prepared_transactions?
255
+ specify "should raise an error if you attempt to use after_commit or after rollback inside a savepoint in a prepared transaction" do
256
+ proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_commit{}}}}.should raise_error(Sequel::Error)
257
+ proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_rollback{}}}}.should raise_error(Sequel::Error)
258
+ end
259
+ end
260
+ end
261
+ end
262
+
263
+ if (! defined?(RUBY_ENGINE) or RUBY_ENGINE == 'ruby' or (RUBY_ENGINE == 'rbx' && !Sequel.guarded?([:do, :sqlite], [:tinytds, :mssql]))) and RUBY_VERSION < '1.9'
264
+ describe "Database transactions and Thread#kill" do
265
+ before do
266
+ @db = INTEGRATION_DB
267
+ @db.create_table!(:items, :engine=>'InnoDB'){String :name; Integer :value}
268
+ @d = @db[:items]
269
+ end
270
+ after do
271
+ @db.drop_table?(:items)
272
+ end
273
+
274
+ specify "should handle transactions inside threads" do
275
+ q = Queue.new
276
+ q1 = Queue.new
277
+ t = Thread.new do
278
+ @db.transaction do
279
+ @d << {:name => 'abc', :value => 1}
280
+ q1.push nil
281
+ q.pop
282
+ @d << {:name => 'def', :value => 2}
283
+ end
284
+ end
285
+ q1.pop
286
+ t.kill
287
+ @d.count.should == 0
288
+ end
289
+
290
+ if INTEGRATION_DB.supports_savepoints?
291
+ specify "should handle transactions with savepoints inside threads" do
292
+ q = Queue.new
293
+ q1 = Queue.new
294
+ t = Thread.new do
295
+ @db.transaction do
296
+ @d << {:name => 'abc', :value => 1}
297
+ @db.transaction(:savepoint=>true) do
298
+ @d << {:name => 'def', :value => 2}
299
+ q1.push nil
300
+ q.pop
301
+ @d << {:name => 'ghi', :value => 3}
302
+ end
303
+ @d << {:name => 'jkl', :value => 4}
304
+ end
305
+ end
306
+ q1.pop
307
+ t.kill
308
+ @d.count.should == 0
309
+ end
310
+ end
311
+ end
137
312
  end
@@ -6,13 +6,13 @@ describe "Supported types" do
6
6
  INTEGRATION_DB[:items]
7
7
  end
8
8
 
9
- cspecify "should support casting correctly", [:sqlite, :sqlite] do
9
+ specify "should support casting correctly" do
10
10
  ds = create_items_table_with_column(:number, Integer)
11
11
  ds.insert(:number => 1)
12
- ds.select(:number.cast_string.as(:n)).map(:n).should == %w'1'
12
+ ds.select(Sequel.cast(:number, String).as(:n)).map(:n).should == %w'1'
13
13
  ds = create_items_table_with_column(:name, String)
14
14
  ds.insert(:name=> '1')
15
- ds.select(:name.cast_numeric.as(:n)).map(:n).should == [1]
15
+ ds.select(Sequel.cast(:name, Integer).as(:n)).map(:n).should == [1]
16
16
  end
17
17
 
18
18
  specify "should support NULL correctly" do
@@ -60,7 +60,7 @@ describe "Supported types" do
60
60
  ds.all.should == [{:name=>'Test User'}]
61
61
  end
62
62
 
63
- cspecify "should support generic date type", [:do, :sqlite], [:jdbc, :sqlite], :mssql do
63
+ cspecify "should support generic date type", [:do, :sqlite], [:jdbc, :sqlite], :mssql, :oracle do
64
64
  ds = create_items_table_with_column(:dat, Date)
65
65
  d = Date.today
66
66
  ds.insert(:dat => d)
@@ -68,6 +68,20 @@ describe "Supported types" do
68
68
  ds.first[:dat].to_s.should == d.to_s
69
69
  end
70
70
 
71
+ cspecify "should support generic time type", [:do], [:swift], [:odbc], [:jdbc, :mssql], [:jdbc, :sqlite], [:mysql2], [:tinytds], :oracle do
72
+ ds = create_items_table_with_column(:tim, Time, :only_time=>true)
73
+ t = Sequel::SQLTime.now
74
+ ds.insert(:tim => t)
75
+ v = ds.first[:tim]
76
+ ds.literal(v).should == ds.literal(t)
77
+ v.should be_a_kind_of(Sequel::SQLTime)
78
+ ds.delete
79
+ ds.insert(:tim => v)
80
+ v2 = ds.first[:tim]
81
+ ds.literal(v2).should == ds.literal(t)
82
+ v2.should be_a_kind_of(Sequel::SQLTime)
83
+ end
84
+
71
85
  cspecify "should support generic datetime type", [:do, :sqlite], [:jdbc, :sqlite] do
72
86
  ds = create_items_table_with_column(:tim, DateTime)
73
87
  t = DateTime.now
@@ -79,14 +93,14 @@ describe "Supported types" do
79
93
  ds.first[:tim].strftime('%Y%m%d%H%M%S').should == t.strftime('%Y%m%d%H%M%S')
80
94
  end
81
95
 
82
- cspecify "should support generic file type", [:do], [:odbc, :mssql], [:mysql2], [:swift], [:tinytds] do
96
+ cspecify "should support generic file type", [:do], [:odbc, :mssql], [:mysql2], [:tinytds] do
83
97
  ds = create_items_table_with_column(:name, File)
84
- ds.insert(:name => ("a\0"*300).to_sequel_blob)
85
- ds.all.should == [{:name=>("a\0"*300).to_sequel_blob}]
98
+ ds.insert(:name =>Sequel.blob("a\0"*300))
99
+ ds.all.should == [{:name=>Sequel.blob("a\0"*300)}]
86
100
  ds.first[:name].should be_a_kind_of(::Sequel::SQL::Blob)
87
101
  end
88
102
 
89
- cspecify "should support generic boolean type", [:do, :sqlite], [:jdbc, :sqlite], [:odbc, :mssql] do
103
+ cspecify "should support generic boolean type", [:do, :sqlite], [:jdbc, :sqlite], [:jdbc, :db2], [:odbc, :mssql], :oracle do
90
104
  ds = create_items_table_with_column(:number, TrueClass)
91
105
  ds.insert(:number => true)
92
106
  ds.all.should == [{:number=>true}]
@@ -94,4 +108,13 @@ describe "Supported types" do
94
108
  ds.insert(:number => true)
95
109
  ds.all.should == [{:number=>true}]
96
110
  end
111
+
112
+ cspecify "should support generic boolean type with defaults", [:do, :sqlite], [:jdbc, :sqlite], [:jdbc, :db2], [:odbc, :mssql], :oracle do
113
+ ds = create_items_table_with_column(:number, TrueClass, :default=>true)
114
+ ds.insert
115
+ ds.all.should == [{:number=>true}]
116
+ ds = create_items_table_with_column(:number, FalseClass, :default=>false)
117
+ ds.insert
118
+ ds.all.should == [{:number=>false}]
119
+ end
97
120
  end