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,453 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Sequel Mock Adapter" do
4
+ specify "should have an adapter method" do
5
+ db = Sequel.mock
6
+ db.should be_a_kind_of(Sequel::Mock::Database)
7
+ db.adapter_scheme.should == :mock
8
+ end
9
+
10
+ specify "should have constructor accept no arguments" do
11
+ Sequel::Mock::Database.new.should be_a_kind_of(Sequel::Mock::Database)
12
+ end
13
+
14
+ specify "should each not return any rows by default" do
15
+ called = false
16
+ Sequel.mock[:t].each{|r| called = true}
17
+ called.should be_false
18
+ end
19
+
20
+ specify "should return 0 for update/delete/with_sql_delete/execute_dui by default" do
21
+ Sequel.mock[:t].update(:a=>1).should == 0
22
+ Sequel.mock[:t].delete.should == 0
23
+ Sequel.mock[:t].with_sql_delete('DELETE FROM t').should == 0
24
+ Sequel.mock.execute_dui('DELETE FROM t').should == 0
25
+ end
26
+
27
+ specify "should return nil for insert/execute_insert by default" do
28
+ Sequel.mock[:t].insert(:a=>1).should be_nil
29
+ Sequel.mock.execute_insert('INSERT INTO a () DEFAULT VALUES').should be_nil
30
+ end
31
+
32
+ specify "should be able to set the rows returned by each using :fetch option with a single hash" do
33
+ rs = []
34
+ db = Sequel.mock(:fetch=>{:a=>1})
35
+ db[:t].each{|r| rs << r}
36
+ rs.should == [{:a=>1}]
37
+ db[:t].each{|r| rs << r}
38
+ rs.should == [{:a=>1}, {:a=>1}]
39
+ db[:t].each{|r| r[:a] = 2; rs << r}
40
+ rs.should == [{:a=>1}, {:a=>1}, {:a=>2}]
41
+ db[:t].each{|r| rs << r}
42
+ rs.should == [{:a=>1}, {:a=>1}, {:a=>2}, {:a=>1}]
43
+ end
44
+
45
+ specify "should be able to set the rows returned by each using :fetch option with an array of hashes" do
46
+ rs = []
47
+ db = Sequel.mock(:fetch=>[{:a=>1}, {:a=>2}])
48
+ db[:t].each{|r| rs << r}
49
+ rs.should == [{:a=>1}, {:a=>2}]
50
+ db[:t].each{|r| rs << r}
51
+ rs.should == [{:a=>1}, {:a=>2}, {:a=>1}, {:a=>2}]
52
+ db[:t].each{|r| r[:a] += 2; rs << r}
53
+ rs.should == [{:a=>1}, {:a=>2}, {:a=>1}, {:a=>2}, {:a=>3}, {:a=>4}]
54
+ db[:t].each{|r| rs << r}
55
+ rs.should == [{:a=>1}, {:a=>2}, {:a=>1}, {:a=>2}, {:a=>3}, {:a=>4}, {:a=>1}, {:a=>2}]
56
+ end
57
+
58
+ specify "should be able to set the rows returned by each using :fetch option with an array or arrays of hashes" do
59
+ rs = []
60
+ db = Sequel.mock(:fetch=>[[{:a=>1}, {:a=>2}], [{:a=>3}, {:a=>4}]])
61
+ db[:t].each{|r| rs << r}
62
+ rs.should == [{:a=>1}, {:a=>2}]
63
+ db[:t].each{|r| rs << r}
64
+ rs.should == [{:a=>1}, {:a=>2}, {:a=>3}, {:a=>4}]
65
+ db[:t].each{|r| rs << r}
66
+ rs.should == [{:a=>1}, {:a=>2}, {:a=>3}, {:a=>4}]
67
+ end
68
+
69
+ specify "should be able to set the rows returned by each using :fetch option with a proc that takes sql" do
70
+ rs = []
71
+ db = Sequel.mock(:fetch=>proc{|sql| sql =~ /FROM t/ ? {:b=>1} : [{:a=>1}, {:a=>2}]})
72
+ db[:t].each{|r| rs << r}
73
+ rs.should == [{:b=>1}]
74
+ db[:b].each{|r| rs << r}
75
+ rs.should == [{:b=>1}, {:a=>1}, {:a=>2}]
76
+ db[:t].each{|r| r[:b] += 1; rs << r}
77
+ db[:b].each{|r| r[:a] += 2; rs << r}
78
+ rs.should == [{:b=>1}, {:a=>1}, {:a=>2}, {:b=>2}, {:a=>3}, {:a=>4}]
79
+ db[:t].each{|r| rs << r}
80
+ db[:b].each{|r| rs << r}
81
+ rs.should == [{:b=>1}, {:a=>1}, {:a=>2}, {:b=>2}, {:a=>3}, {:a=>4}, {:b=>1}, {:a=>1}, {:a=>2}]
82
+ end
83
+
84
+ specify "should have a fetch= method for setting rows returned by each after the fact" do
85
+ rs = []
86
+ db = Sequel.mock
87
+ db.fetch = {:a=>1}
88
+ db[:t].each{|r| rs << r}
89
+ rs.should == [{:a=>1}]
90
+ db[:t].each{|r| rs << r}
91
+ rs.should == [{:a=>1}] * 2
92
+ end
93
+
94
+ specify "should be able to set an exception to raise by setting the :fetch option to an exception class " do
95
+ db = Sequel.mock(:fetch=>ArgumentError)
96
+ proc{db[:t].all}.should raise_error(Sequel::DatabaseError)
97
+ begin
98
+ db[:t].all
99
+ rescue => e
100
+ end
101
+ e.should be_a_kind_of(Sequel::DatabaseError)
102
+ e.wrapped_exception.should be_a_kind_of(ArgumentError)
103
+ end
104
+
105
+ specify "should be able to set separate kinds of results for fetch using an array" do
106
+ rs = []
107
+ db = Sequel.mock(:fetch=>[{:a=>1}, [{:a=>2}, {:a=>3}], proc{|s| {:a=>4}}, proc{|s| }, nil, ArgumentError])
108
+ db[:t].each{|r| rs << r}
109
+ rs.should == [{:a=>1}]
110
+ db[:t].each{|r| rs << r}
111
+ rs.should == [{:a=>1}, {:a=>2}, {:a=>3}]
112
+ db[:t].each{|r| rs << r}
113
+ rs.should == [{:a=>1}, {:a=>2}, {:a=>3}, {:a=>4}]
114
+ db[:t].each{|r| rs << r}
115
+ rs.should == [{:a=>1}, {:a=>2}, {:a=>3}, {:a=>4}]
116
+ db[:t].each{|r| rs << r}
117
+ rs.should == [{:a=>1}, {:a=>2}, {:a=>3}, {:a=>4}]
118
+ proc{db[:t].all}.should raise_error(Sequel::DatabaseError)
119
+ end
120
+
121
+ specify "should be able to set the rows returned by each on a per dataset basis using _fetch" do
122
+ rs = []
123
+ db = Sequel.mock(:fetch=>{:a=>1})
124
+ ds = db[:t]
125
+ ds.each{|r| rs << r}
126
+ rs.should == [{:a=>1}]
127
+ ds._fetch = {:b=>2}
128
+ ds.each{|r| rs << r}
129
+ rs.should == [{:a=>1}, {:b=>2}]
130
+ end
131
+
132
+ specify "should raise Error if given an invalid object to fetch" do
133
+ proc{Sequel.mock(:fetch=>Class.new).get(1)}.should raise_error(Sequel::Error)
134
+ proc{Sequel.mock(:fetch=>Object.new).get(1)}.should raise_error(Sequel::Error)
135
+ end
136
+
137
+ specify "should be able to set the number of rows modified by update and delete using :numrows option as an integer" do
138
+ db = Sequel.mock(:numrows=>2)
139
+ db[:t].update(:a=>1).should == 2
140
+ db[:t].delete.should == 2
141
+ db[:t].update(:a=>1).should == 2
142
+ db[:t].delete.should == 2
143
+ end
144
+
145
+ specify "should be able to set the number of rows modified by update and delete using :numrows option as an array of integers" do
146
+ db = Sequel.mock(:numrows=>[2, 1])
147
+ db[:t].update(:a=>1).should == 2
148
+ db[:t].delete.should == 1
149
+ db[:t].update(:a=>1).should == 0
150
+ db[:t].delete.should == 0
151
+ end
152
+
153
+ specify "should be able to set the number of rows modified by update and delete using :numrows option as a proc" do
154
+ db = Sequel.mock(:numrows=>proc{|sql| sql =~ / t/ ? 2 : 1})
155
+ db[:t].update(:a=>1).should == 2
156
+ db[:t].delete.should == 2
157
+ db[:b].update(:a=>1).should == 1
158
+ db[:b].delete.should == 1
159
+ end
160
+
161
+ specify "should be able to set an exception to raise by setting the :numrows option to an exception class " do
162
+ db = Sequel.mock(:numrows=>ArgumentError)
163
+ proc{db[:t].update(:a=>1)}.should raise_error(Sequel::DatabaseError)
164
+ begin
165
+ db[:t].delete
166
+ rescue => e
167
+ end
168
+ e.should be_a_kind_of(Sequel::DatabaseError)
169
+ e.wrapped_exception.should be_a_kind_of(ArgumentError)
170
+ end
171
+
172
+ specify "should be able to set separate kinds of results for numrows using an array" do
173
+ db = Sequel.mock(:numrows=>[1, proc{|s| 2}, nil, ArgumentError])
174
+ db[:t].delete.should == 1
175
+ db[:t].update(:a=>1).should == 2
176
+ db[:t].delete.should == 0
177
+ proc{db[:t].delete}.should raise_error(Sequel::DatabaseError)
178
+ end
179
+
180
+ specify "should have a numrows= method to set the number of rows modified by update and delete after the fact" do
181
+ db = Sequel.mock
182
+ db.numrows = 2
183
+ db[:t].update(:a=>1).should == 2
184
+ db[:t].delete.should == 2
185
+ db[:t].update(:a=>1).should == 2
186
+ db[:t].delete.should == 2
187
+ end
188
+
189
+ specify "should be able to set the number of rows modified by update and delete on a per dataset basis" do
190
+ db = Sequel.mock(:numrows=>2)
191
+ ds = db[:t]
192
+ ds.update(:a=>1).should == 2
193
+ ds.delete.should == 2
194
+ ds.numrows = 3
195
+ ds.update(:a=>1).should == 3
196
+ ds.delete.should == 3
197
+ end
198
+
199
+ specify "should raise Error if given an invalid object for numrows or autoid" do
200
+ proc{Sequel.mock(:numrows=>Class.new)[:a].delete}.should raise_error(Sequel::Error)
201
+ proc{Sequel.mock(:numrows=>Object.new)[:a].delete}.should raise_error(Sequel::Error)
202
+ proc{Sequel.mock(:autoid=>Class.new)[:a].insert}.should raise_error(Sequel::Error)
203
+ proc{Sequel.mock(:autoid=>Object.new)[:a].insert}.should raise_error(Sequel::Error)
204
+ end
205
+
206
+ specify "should be able to set the autogenerated primary key returned by insert using :autoid option as an integer" do
207
+ db = Sequel.mock(:autoid=>1)
208
+ db[:t].insert(:a=>1).should == 1
209
+ db[:t].insert(:a=>1).should == 2
210
+ db[:t].insert(:a=>1).should == 3
211
+ end
212
+
213
+ specify "should be able to set the autogenerated primary key returned by insert using :autoid option as an array of integers" do
214
+ db = Sequel.mock(:autoid=>[1, 3, 5])
215
+ db[:t].insert(:a=>1).should == 1
216
+ db[:t].insert(:a=>1).should == 3
217
+ db[:t].insert(:a=>1).should == 5
218
+ db[:t].insert(:a=>1).should be_nil
219
+ end
220
+
221
+ specify "should be able to set the autogenerated primary key returned by insert using :autoid option as a proc" do
222
+ db = Sequel.mock(:autoid=>proc{|sql| sql =~ /INTO t / ? 2 : 1})
223
+ db[:t].insert(:a=>1).should == 2
224
+ db[:t].insert(:a=>1).should == 2
225
+ db[:b].insert(:a=>1).should == 1
226
+ db[:b].insert(:a=>1).should == 1
227
+ end
228
+
229
+ specify "should be able to set an exception to raise by setting the :autoid option to an exception class " do
230
+ db = Sequel.mock(:autoid=>ArgumentError)
231
+ proc{db[:t].insert(:a=>1)}.should raise_error(Sequel::DatabaseError)
232
+ begin
233
+ db[:t].insert
234
+ rescue => e
235
+ end
236
+ e.should be_a_kind_of(Sequel::DatabaseError)
237
+ e.wrapped_exception.should be_a_kind_of(ArgumentError)
238
+ end
239
+
240
+ specify "should be able to set separate kinds of results for autoid using an array" do
241
+ db = Sequel.mock(:autoid=>[1, proc{|s| 2}, nil, ArgumentError])
242
+ db[:t].insert.should == 1
243
+ db[:t].insert.should == 2
244
+ db[:t].insert.should == nil
245
+ proc{db[:t].insert}.should raise_error(Sequel::DatabaseError)
246
+ end
247
+
248
+ specify "should have an autoid= method to set the autogenerated primary key returned by insert after the fact" do
249
+ db = Sequel.mock
250
+ db.autoid = 1
251
+ db[:t].insert(:a=>1).should == 1
252
+ db[:t].insert(:a=>1).should == 2
253
+ db[:t].insert(:a=>1).should == 3
254
+ end
255
+
256
+ specify "should be able to set the autogenerated primary key returned by insert on a per dataset basis" do
257
+ db = Sequel.mock(:autoid=>1)
258
+ ds = db[:t]
259
+ ds.insert(:a=>1).should == 1
260
+ ds.autoid = 5
261
+ ds.insert(:a=>1).should == 5
262
+ ds.insert(:a=>1).should == 6
263
+ db[:t].insert(:a=>1).should == 2
264
+ end
265
+
266
+ specify "should be able to set the columns to set in the dataset as an array of symbols" do
267
+ db = Sequel.mock(:columns=>[:a, :b])
268
+ db[:t].columns.should == [:a, :b]
269
+ db.sqls.should == ["SELECT * FROM t LIMIT 1"]
270
+ ds = db[:t]
271
+ ds.all
272
+ db.sqls.should == ["SELECT * FROM t"]
273
+ ds.columns.should == [:a, :b]
274
+ db.sqls.should == []
275
+ db[:t].columns.should == [:a, :b]
276
+ end
277
+
278
+ specify "should be able to set the columns to set in the dataset as an array of arrays of symbols" do
279
+ db = Sequel.mock(:columns=>[[:a, :b], [:c, :d]])
280
+ db[:t].columns.should == [:a, :b]
281
+ db[:t].columns.should == [:c, :d]
282
+ end
283
+
284
+ specify "should be able to set the columns to set in the dataset as a proc" do
285
+ db = Sequel.mock(:columns=>proc{|sql| (sql =~ / t/) ? [:a, :b] : [:c, :d]})
286
+ db[:b].columns.should == [:c, :d]
287
+ db[:t].columns.should == [:a, :b]
288
+ end
289
+
290
+ specify "should have a columns= method to set the columns to set after the fact" do
291
+ db = Sequel.mock
292
+ db.columns = [[:a, :b], [:c, :d]]
293
+ db[:t].columns.should == [:a, :b]
294
+ db[:t].columns.should == [:c, :d]
295
+ end
296
+
297
+ specify "should raise Error if given an invalid columns" do
298
+ proc{Sequel.mock(:columns=>Object.new)[:a].columns}.should raise_error(Sequel::Error)
299
+ end
300
+
301
+ specify "should not quote identifiers by default" do
302
+ Sequel.mock.send(:quote_identifiers_default).should be_false
303
+ end
304
+
305
+ specify "should allow overriding of server_version" do
306
+ db = Sequel.mock
307
+ db.server_version.should == nil
308
+ db.server_version = 80102
309
+ db.server_version.should == 80102
310
+ end
311
+
312
+ specify "should not have identifier input/output methods by default" do
313
+ Sequel.mock.send(:identifier_input_method_default).should be_nil
314
+ Sequel.mock.send(:identifier_output_method_default).should be_nil
315
+ end
316
+
317
+ specify "should keep a record of all executed SQL in #sqls" do
318
+ db = Sequel.mock
319
+ db[:t].all
320
+ db[:b].delete
321
+ db[:c].insert(:a=>1)
322
+ db[:d].update(:a=>1)
323
+ db.sqls.should == ['SELECT * FROM t', 'DELETE FROM b', 'INSERT INTO c (a) VALUES (1)', 'UPDATE d SET a = 1']
324
+ end
325
+
326
+ specify "should clear sqls on retrieval" do
327
+ db = Sequel.mock
328
+ db[:t].all
329
+ db.sqls.should == ['SELECT * FROM t']
330
+ db.sqls.should == []
331
+ end
332
+
333
+ specify "should also log SQL executed to the given loggers" do
334
+ a = []
335
+ def a.method_missing(m, *x) push(*x) end
336
+ db = Sequel.mock(:loggers=>[a])
337
+ db[:t].all
338
+ db[:b].delete
339
+ db[:c].insert(:a=>1)
340
+ db[:d].update(:a=>1)
341
+ a.should == ['SELECT * FROM t', 'DELETE FROM b', 'INSERT INTO c (a) VALUES (1)', 'UPDATE d SET a = 1']
342
+ end
343
+
344
+ specify "should correctly handle transactions" do
345
+ db = Sequel.mock
346
+ db.transaction{db[:a].all}
347
+ db.sqls.should == ['BEGIN', 'SELECT * FROM a', 'COMMIT']
348
+ db.transaction{db[:a].all; raise Sequel::Rollback}
349
+ db.sqls.should == ['BEGIN', 'SELECT * FROM a', 'ROLLBACK']
350
+ proc{db.transaction{db[:a].all; raise ArgumentError}}.should raise_error(ArgumentError)
351
+ db.sqls.should == ['BEGIN', 'SELECT * FROM a', 'ROLLBACK']
352
+ proc{db.transaction(:rollback=>:reraise){db[:a].all; raise Sequel::Rollback}}.should raise_error(Sequel::Rollback)
353
+ db.sqls.should == ['BEGIN', 'SELECT * FROM a', 'ROLLBACK']
354
+ db.transaction(:rollback=>:always){db[:a].all}
355
+ db.sqls.should == ['BEGIN', 'SELECT * FROM a', 'ROLLBACK']
356
+ db.transaction{db.transaction{db[:a].all; raise Sequel::Rollback}}
357
+ db.sqls.should == ['BEGIN', 'SELECT * FROM a', 'ROLLBACK']
358
+ db.transaction{db.transaction(:savepoint=>true){db[:a].all; raise Sequel::Rollback}}
359
+ db.sqls.should == ['BEGIN', 'SAVEPOINT autopoint_1', 'SELECT * FROM a', 'ROLLBACK TO SAVEPOINT autopoint_1', 'COMMIT']
360
+ db.transaction{db.transaction(:savepoint=>true){db[:a].all}; raise Sequel::Rollback}
361
+ db.sqls.should == ['BEGIN', 'SAVEPOINT autopoint_1', 'SELECT * FROM a', 'RELEASE SAVEPOINT autopoint_1', 'ROLLBACK']
362
+ end
363
+
364
+ specify "should correctly handle transactions when sharding" do
365
+ db = Sequel.mock(:servers=>{:test=>{}})
366
+ db.transaction{db.transaction(:server=>:test){db[:a].all; db[:t].server(:test).all}}
367
+ db.sqls.should == ['BEGIN', 'BEGIN -- test', 'SELECT * FROM a', 'SELECT * FROM t -- test', 'COMMIT -- test', 'COMMIT']
368
+ end
369
+
370
+ specify "should yield a mock connection object from synchronize" do
371
+ c = Sequel.mock.synchronize{|conn| conn}
372
+ c.should be_a_kind_of(Sequel::Mock::Connection)
373
+ end
374
+
375
+ specify "should deal correctly with sharding" do
376
+ db = Sequel.mock(:servers=>{:test=>{}})
377
+ c1 = db.synchronize{|conn| conn}
378
+ c2 = db.synchronize(:test){|conn| conn}
379
+ c1.server.should == :default
380
+ c2.server.should == :test
381
+ end
382
+
383
+ specify "should disconnect correctly" do
384
+ db = Sequel.mock
385
+ db.test_connection
386
+ proc{db.disconnect}.should_not raise_error
387
+ end
388
+
389
+ specify "should accept :extend option for extending the object with a module" do
390
+ Sequel.mock(:extend=>Module.new{def foo(v) v * 2 end}).foo(3).should == 6
391
+ end
392
+
393
+ specify "should accept :sqls option for where to store the SQL queries" do
394
+ a = []
395
+ Sequel.mock(:sqls=>a)[:t].all
396
+ a.should == ['SELECT * FROM t']
397
+ end
398
+
399
+ specify "should include :append option in SQL if it is given" do
400
+ db = Sequel.mock(:append=>'a')
401
+ db[:t].all
402
+ db.sqls.should == ['SELECT * FROM t -- a']
403
+ end
404
+
405
+ specify "should append :arguments option to execute to the SQL if present" do
406
+ db = Sequel.mock
407
+ db.execute('SELECT * FROM t', :arguments=>[1, 2])
408
+ db.sqls.should == ['SELECT * FROM t -- args: [1, 2]']
409
+ end
410
+
411
+ specify "should have Dataset#columns take columns to set and return self" do
412
+ db = Sequel.mock
413
+ ds = db[:t].columns(:id, :a, :b)
414
+ ds.should be_a_kind_of(Sequel::Mock::Dataset)
415
+ ds.columns.should == [:id, :a, :b]
416
+ end
417
+
418
+ specify "should be able to load dialects based on the database name" do
419
+ begin
420
+ qi = class Sequel::Database; @@quote_identifiers; end
421
+ ii = class Sequel::Database; @@identifier_input_method; end
422
+ io = class Sequel::Database; @@identifier_output_method; end
423
+ Sequel.quote_identifiers = nil
424
+ class Sequel::Database; @@identifier_input_method=nil; end
425
+ class Sequel::Database; @@identifier_output_method=nil; end
426
+ Sequel.mock(:host=>'access').select(Date.new(2011, 12, 13)).sql.should == 'SELECT #2011-12-13#'
427
+ Sequel.mock(:host=>'db2').select(1).sql.should == 'SELECT 1 FROM "SYSIBM"."SYSDUMMY1"'
428
+ Sequel.mock(:host=>'firebird')[:a].distinct.limit(1, 2).sql.should == 'SELECT DISTINCT FIRST 1 SKIP 2 * FROM "A"'
429
+ Sequel.mock(:host=>'informix')[:a].distinct.limit(1, 2).sql.should == 'SELECT SKIP 2 FIRST 1 DISTINCT * FROM A'
430
+ Sequel.mock(:host=>'mssql')[:a].full_text_search(:b, 'c').sql.should == "SELECT * FROM [A] WHERE (CONTAINS ([B], 'c'))"
431
+ Sequel.mock(:host=>'mysql')[:a].full_text_search(:b, 'c').sql.should == "SELECT * FROM `a` WHERE (MATCH (`b`) AGAINST ('c'))"
432
+ Sequel.mock(:host=>'oracle')[:a].limit(1).sql.should == 'SELECT * FROM (SELECT * FROM "A") "T1" WHERE (ROWNUM <= 1)'
433
+ Sequel.mock(:host=>'postgres')[:a].full_text_search(:b, 'c').sql.should == "SELECT * FROM \"a\" WHERE (to_tsvector('simple'::regconfig, (COALESCE(\"b\", ''))) @@ to_tsquery('simple'::regconfig, 'c'))"
434
+ Sequel.mock(:host=>'sqlite')[:a___b].sql.should == "SELECT * FROM `a` AS 'b'"
435
+ ensure
436
+ Sequel.quote_identifiers = qi
437
+ Sequel::Database.send(:class_variable_set, :@@identifier_input_method, ii)
438
+ Sequel::Database.send(:class_variable_set, :@@identifier_output_method, io)
439
+ end
440
+ end
441
+
442
+ specify "should automatically set version for postgres" do
443
+ Sequel.mock(:host=>'postgres').server_version.should == 90103
444
+ end
445
+
446
+ specify "should stub out the primary_key method for postgres" do
447
+ Sequel.mock(:host=>'postgres').primary_key(:t).should == :id
448
+ end
449
+
450
+ specify "should handle creating tables on oracle" do
451
+ proc{Sequel.mock(:host=>'oracle').create_table(:a){String :b}}.should_not raise_error
452
+ end
453
+ end