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,89 +1,58 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
2
2
 
3
3
  describe "Sequel sql_expr extension" do
4
+ before do
5
+ @ds = Sequel.mock.dataset
6
+ end
7
+
4
8
  specify "Object#sql_expr should wrap the object in a GenericComplexExpression" do
5
9
  o = Object.new
10
+ def o.sql_literal(ds) 'foo' end
6
11
  s = o.sql_expr
7
- s.should be_a_kind_of(Sequel::SQL::GenericComplexExpression)
8
- s.op.should == :NOOP
9
- s.args.should == [o]
10
- (s+1).should be_a_kind_of(Sequel::SQL::NumericExpression)
11
- (s & true).should be_a_kind_of(Sequel::SQL::BooleanExpression)
12
- (s < 1).should be_a_kind_of(Sequel::SQL::BooleanExpression)
13
- s.sql_subscript(1).should be_a_kind_of(Sequel::SQL::Subscript)
14
- s.like('a').should be_a_kind_of(Sequel::SQL::BooleanExpression)
15
- s.as(:a).should be_a_kind_of(Sequel::SQL::AliasedExpression)
16
- s.cast(Integer).should be_a_kind_of(Sequel::SQL::Cast)
17
- s.desc.should be_a_kind_of(Sequel::SQL::OrderedExpression)
18
- s.sql_string.should be_a_kind_of(Sequel::SQL::StringExpression)
12
+ @ds.literal(s).should == "foo"
13
+ @ds.literal(s+1).should == "(foo + 1)"
14
+ @ds.literal(s & true).should == "(foo AND 't')"
15
+ @ds.literal(s < 1).should == "(foo < 1)"
16
+ @ds.literal(s.sql_subscript(1)).should == "foo[1]"
17
+ @ds.literal(s.like('a')).should == "(foo LIKE 'a')"
18
+ @ds.literal(s.as(:a)).should == "foo AS a"
19
+ @ds.literal(s.cast(Integer)).should == "CAST(foo AS integer)"
20
+ @ds.literal(s.desc).should == "foo DESC"
21
+ @ds.literal(s.sql_string + '1').should == "(foo || '1')"
19
22
  end
20
23
 
21
24
  specify "Numeric#sql_expr should wrap the object in a NumericExpression" do
22
- [1, 2.0, 2^40, BigDecimal.new('1.0')].each do |o|
23
- s = o.sql_expr
24
- s.should be_a_kind_of(Sequel::SQL::NumericExpression)
25
- s.op.should == :NOOP
26
- s.args.should == [o]
25
+ [1, 2.0, 2^70, BigDecimal.new('1.0')].each do |o|
26
+ @ds.literal(o.sql_expr).should == @ds.literal(o)
27
+ @ds.literal(o.sql_expr + 1).should == "(#{@ds.literal(o)} + 1)"
27
28
  end
28
29
  end
29
30
 
30
31
  specify "String#sql_expr should wrap the object in a StringExpression" do
31
- o = ""
32
- s = o.sql_expr
33
- s.should be_a_kind_of(Sequel::SQL::StringExpression)
34
- s.op.should == :NOOP
35
- s.args.should == [o]
32
+ @ds.literal("".sql_expr).should == "''"
33
+ @ds.literal("".sql_expr + :a).should == "('' || a)"
36
34
  end
37
35
 
38
36
  specify "NilClass, TrueClass, and FalseClass#sql_expr should wrap the object in a BooleanExpression" do
39
37
  [nil, true, false].each do |o|
40
- s = o.sql_expr
41
- s.should be_a_kind_of(Sequel::SQL::BooleanExpression)
42
- s.op.should == :NOOP
43
- s.args.should == [o]
38
+ @ds.literal(o.sql_expr).should == @ds.literal(o)
39
+ @ds.literal(o.sql_expr & :a).should == "(#{@ds.literal(o)} AND a)"
44
40
  end
45
41
  end
46
42
 
47
43
  specify "Proc#sql_expr should should treat the object as a virtual row block" do
48
- s = proc{a}.sql_expr
49
- s.should be_a_kind_of(Sequel::SQL::Identifier)
50
- s.value.should == :a
51
-
52
- s = proc{a__b}.sql_expr
53
- s.should be_a_kind_of(Sequel::SQL::QualifiedIdentifier)
54
- s.table.should == "a"
55
- s.column.should == "b"
56
-
57
- s = proc{a(b)}.sql_expr
58
- s.should be_a_kind_of(Sequel::SQL::Function)
59
- s.f.should == :a
60
- s.args.length.should == 1
61
- s.args.first.should be_a_kind_of(Sequel::SQL::Identifier)
62
- s.args.first.value.should == :b
44
+ @ds.literal(proc{a}.sql_expr).should == "a"
45
+ @ds.literal(proc{a__b}.sql_expr).should == "a.b"
46
+ @ds.literal(proc{a(b)}.sql_expr).should == "a(b)"
63
47
  end
64
48
 
65
49
  specify "Proc#sql_expr should should wrap the object in a GenericComplexExpression if the object is not already an expression" do
66
- s = proc{1}.sql_expr
67
- s.should be_a_kind_of(Sequel::SQL::GenericComplexExpression)
68
- s.op.should == :NOOP
69
- s.args.should == [1]
50
+ @ds.literal(proc{1}.sql_expr).should == "1"
51
+ @ds.literal(proc{1}.sql_expr + 2).should == "(1 + 2)"
70
52
  end
71
53
 
72
54
  specify "Proc#sql_expr should should convert a hash or array of two element arrays to a BooleanExpression" do
73
- s = proc{{a=>b}}.sql_expr
74
- s.should be_a_kind_of(Sequel::SQL::BooleanExpression)
75
- s.op.should == :"="
76
- s.args.first.should be_a_kind_of(Sequel::SQL::Identifier)
77
- s.args.first.value.should == :a
78
- s.args.last.should be_a_kind_of(Sequel::SQL::Identifier)
79
- s.args.last.value.should == :b
80
-
81
- s = proc{[[a,b]]}.sql_expr
82
- s.should be_a_kind_of(Sequel::SQL::BooleanExpression)
83
- s.op.should == :"="
84
- s.args.first.should be_a_kind_of(Sequel::SQL::Identifier)
85
- s.args.first.value.should == :a
86
- s.args.last.should be_a_kind_of(Sequel::SQL::Identifier)
87
- s.args.last.value.should == :b
55
+ @ds.literal(proc{{a=>b}}.sql_expr).should == "(a = b)"
56
+ @ds.literal(proc{[[a, b]]}.sql_expr & :a).should == "((a = b) AND a)"
88
57
  end
89
58
  end
@@ -0,0 +1,145 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Sequel::Plugins::StaticCache" do
4
+ before do
5
+ @db = Sequel.mock
6
+ @db.fetch = [{:id=>1}, {:id=>2}]
7
+ @c = Class.new(Sequel::Model(@db[:t]))
8
+ @c.columns :id
9
+ @c.plugin :static_cache
10
+ @c1 = @c.cache[1]
11
+ @c2 = @c.cache[2]
12
+ @db.sqls
13
+ end
14
+
15
+ it "should use a ruby hash as a cache of all model instances" do
16
+ @c.cache.should == {1=>@c.load(:id=>1), 2=>@c.load(:id=>2)}
17
+ end
18
+
19
+ it "should work correctly with composite keys" do
20
+ @db.fetch = [{:id=>1, :id2=>1}, {:id=>2, :id2=>1}]
21
+ @c = Class.new(Sequel::Model(@db[:t]))
22
+ @c.columns :id, :id2
23
+ @c.set_primary_key([:id, :id2])
24
+ @c.plugin :static_cache
25
+ @db.sqls
26
+ @c1 = @c.cache[[1, 2]]
27
+ @c2 = @c.cache[[2, 1]]
28
+ @c[[1, 2]].should equal(@c1)
29
+ @c[[2, 1]].should equal(@c2)
30
+ @db.sqls.should == []
31
+ end
32
+
33
+ it "should make .[] method with primary key use the cache" do
34
+ @c[1].should equal(@c1)
35
+ @c[2].should equal(@c2)
36
+ @c[3].should be_nil
37
+ @c[[1, 2]].should be_nil
38
+ @c[nil].should be_nil
39
+ @c[].should be_nil
40
+ @db.sqls.should == []
41
+ end
42
+
43
+ it "should have .[] with a hash not use the cache" do
44
+ @db.fetch = {:id=>2}
45
+ @c[:id=>2].should == @c2
46
+ @db.sqls.should == ['SELECT * FROM t WHERE (id = 2) LIMIT 1']
47
+ end
48
+
49
+ it "should support cache_get_pk" do
50
+ @c.cache_get_pk(1).should equal(@c1)
51
+ @c.cache_get_pk(2).should equal(@c2)
52
+ @c.cache_get_pk(3).should be_nil
53
+ @db.sqls.should == []
54
+ end
55
+
56
+ it "should have each just iterate over the hash's values without sending a query" do
57
+ a = []
58
+ @c.each{|o| a << o}
59
+ a = a.sort_by{|o| o.id}
60
+ a.first.should equal(@c1)
61
+ a.last.should equal(@c2)
62
+ @db.sqls.should == []
63
+ end
64
+
65
+ it "should have map just iterate over the hash's values without sending a query if no argument is given" do
66
+ @c.map{|v| v.id}.sort.should == [1, 2]
67
+ @db.sqls.should == []
68
+ end
69
+
70
+ it "should have map send a query if given an argument" do
71
+ @c.map(:id).sort.should == [1, 2]
72
+ @db.sqls.should == ["SELECT * FROM t"]
73
+ end
74
+
75
+ it "should have map without a block or argument not raise an exception or issue a query" do
76
+ @c.map
77
+ @db.sqls.should == []
78
+ end
79
+
80
+ it "should have map without a block not return a frozen object" do
81
+ @c.map.frozen?.should be_false
82
+ end
83
+
84
+ it "should have other enumerable methods work without sending a query" do
85
+ a = @c.sort_by{|o| o.id}
86
+ a.first.should equal(@c1)
87
+ a.last.should equal(@c2)
88
+ @db.sqls.should == []
89
+ end
90
+
91
+ it "should have all just return the hashes' values" do
92
+ a = @c.all.sort_by{|o| o.id}
93
+ a.first.should equal(@c1)
94
+ a.last.should equal(@c2)
95
+ @db.sqls.should == []
96
+ end
97
+
98
+ it "should have all not return a frozen object" do
99
+ @c.all.frozen?.should be_false
100
+ end
101
+
102
+ it "should have all return things in dataset order" do
103
+ @c.all.should == [@c1, @c2]
104
+ end
105
+
106
+ it "should have to_hash without arguments return the cached objects without a query" do
107
+ a = @c.to_hash
108
+ a[1].should equal(@c1)
109
+ a[2].should equal(@c2)
110
+ @db.sqls.should == []
111
+ end
112
+
113
+ it "should have to_hash with any arguments use a query" do
114
+ @c.to_hash(:id).should == {1=>@c1, 2=>@c2}
115
+ @db.sqls.should == ['SELECT * FROM t']
116
+ @c.to_hash(:id, :id).should == {1=>1, 2=>2}
117
+ @db.sqls.should == ['SELECT * FROM t']
118
+ end
119
+
120
+ it "should have all not return a frozen object" do
121
+ @c.to_hash.frozen?.should be_false
122
+ end
123
+
124
+ it "all of the static cache values (model instances) should be frozen" do
125
+ @c.all.all?{|o| o.frozen?}.should be_true
126
+ end
127
+
128
+ it "subclasses should work correctly" do
129
+ c = Class.new(@c)
130
+ c.all.should == [c.load(:id=>1), c.load(:id=>2)]
131
+ c.to_hash.should == {1=>c.load(:id=>1), 2=>c.load(:id=>2)}
132
+ @db.sqls.should == ['SELECT * FROM t']
133
+ end
134
+
135
+ it "set_dataset should work correctly" do
136
+ ds = @c.dataset.from(:t2)
137
+ ds.instance_variable_set(:@columns, [:id])
138
+ ds._fetch = {:id=>3}
139
+ @c.dataset = ds
140
+ @c.all.should == [@c.load(:id=>3)]
141
+ @c.to_hash.should == {3=>@c.load(:id=>3)}
142
+ @c.to_hash[3].should equal(@c.all.first)
143
+ @db.sqls.should == ['SELECT * FROM t2']
144
+ end
145
+ end
@@ -49,4 +49,18 @@ describe Sequel::Model, "Subclasses plugin" do
49
49
  ssc1.descendents.should == [sssc1]
50
50
  sssc1.descendents.should == []
51
51
  end
52
+
53
+ specify "plugin block should be called with each subclass created" do
54
+ c = Class.new(Sequel::Model)
55
+ a = []
56
+ c.plugin(:subclasses){|sc| a << sc}
57
+ sc1 = Class.new(c)
58
+ a.should == [sc1]
59
+ sc2 = Class.new(c)
60
+ a.should == [sc1, sc2]
61
+ sc3 = Class.new(sc1)
62
+ a.should == [sc1, sc2, sc3]
63
+ sc4 = Class.new(sc3)
64
+ a.should == [sc1, sc2, sc3, sc4]
65
+ end
52
66
  end
@@ -7,23 +7,13 @@ describe "Sequel::Plugins::TacticalEagerLoading" do
7
7
  columns :id, :parent_id
8
8
  many_to_one :parent, :class=>self
9
9
  one_to_many :children, :class=>self, :key=>:parent_id
10
- ds = dataset
11
- def ds.fetch_rows(sql)
12
- execute(sql)
13
- where = @opts[:where]
14
- if !where
15
- yield(:id=>1, :parent_id=>101)
16
- yield(:id=>2, :parent_id=>102)
17
- yield(:id=>101, :parent_id=>nil)
18
- yield(:id=>102, :parent_id=>nil)
19
- elsif where.args.first.column == :id
20
- Array(where.args.last).each do |x|
21
- yield(:id=>x, :parent_id=>nil)
22
- end
23
- elsif where.args.first.column == :parent_id
24
- Array(where.args.last).each do |x|
25
- yield(:id=>x-100, :parent_id=>x) if x > 100
26
- end
10
+ dataset._fetch = proc do |sql|
11
+ if sql !~ /WHERE/
12
+ [{:id=>1, :parent_id=>101}, {:id=>2, :parent_id=>102}, {:id=>101, :parent_id=>nil}, {:id=>102, :parent_id=>nil}]
13
+ elsif sql =~ /WHERE.*\bid IN \(([\d, ]*)\)/
14
+ $1.split(', ').map{|x| {:id=>x.to_i, :parent_id=>nil}}
15
+ elsif sql =~ /WHERE.*\bparent_id IN \(([\d, ]*)\)/
16
+ $1.split(', ').map{|x| {:id=>x.to_i - 100, :parent_id=>x.to_i} if x.to_i > 100}.compact
27
17
  end
28
18
  end
29
19
  end
@@ -49,9 +39,9 @@ describe "Sequel::Plugins::TacticalEagerLoading" do
49
39
  ts = @c.all
50
40
  MODEL_DB.sqls.length.should == 1
51
41
  ts.map{|x| x.parent}.should == [ts[2], ts[3], nil, nil]
52
- MODEL_DB.sqls.length.should == 2
42
+ MODEL_DB.sqls.length.should == 1
53
43
  ts.map{|x| x.children}.should == [[], [], [ts[0]], [ts[1]]]
54
- MODEL_DB.sqls.length.should == 3
44
+ MODEL_DB.sqls.length.should == 1
55
45
  end
56
46
 
57
47
  it "association getter methods should not eagerly load the association if the association is cached" do
@@ -62,4 +52,12 @@ describe "Sequel::Plugins::TacticalEagerLoading" do
62
52
  @ds.should_not_receive(:eager_load)
63
53
  ts.map{|x| x.parent}.should == [ts[2], ts[3], nil, nil]
64
54
  end
55
+
56
+ it "should handle case where an association is valid on an instance, but not on all instances" do
57
+ c = Class.new(@c)
58
+ c.many_to_one :parent2, :class=>@c, :key=>:parent_id
59
+ @c.dataset.row_proc = proc{|r| (r[:parent_id] == 101 ? c : @c).call(r)}
60
+ @c.all{|x| x.parent2 if x.is_a?(c)}
61
+ end
62
+
65
63
  end
@@ -39,7 +39,27 @@ describe "Sequel thread_local_timezones extension" do
39
39
  end
40
40
 
41
41
  it "should be thread safe" do
42
- [Thread.new{Sequel.thread_application_timezone = :utc; sleep 0.03; Sequel.application_timezone.should == :utc},
43
- Thread.new{sleep 0.01; Sequel.thread_application_timezone = :local; sleep 0.01; Sequel.application_timezone.should == :local}].each{|x| x.join}
42
+ q, q1, q2 = Queue.new, Queue.new, Queue.new
43
+ tz1, tz2 = nil, nil
44
+ t1 = Thread.new do
45
+ Sequel.thread_application_timezone = :utc
46
+ q2.push nil
47
+ q.pop
48
+ tz1 = Sequel.application_timezone
49
+ end
50
+ t2 = Thread.new do
51
+ Sequel.thread_application_timezone = :local
52
+ q2.push nil
53
+ q1.pop
54
+ tz2 = Sequel.application_timezone
55
+ end
56
+ q2.pop
57
+ q2.pop
58
+ q.push nil
59
+ q1.push nil
60
+ t1.join
61
+ t2.join
62
+ tz1.should == :utc
63
+ tz2.should == :local
44
64
  end
45
65
  end
@@ -13,9 +13,10 @@ describe "Sequel::Plugins::Timestamps" do
13
13
  @c.class_eval do
14
14
  columns :id, :created_at, :updated_at
15
15
  plugin :timestamps
16
+ def _save_refresh(*) end
16
17
  db.reset
17
- def _refresh(ds); self end
18
18
  end
19
+ @c.dataset.autoid = nil
19
20
  end
20
21
  after do
21
22
  Sequel.datetime_class = Time
@@ -40,8 +41,9 @@ describe "Sequel::Plugins::Timestamps" do
40
41
  it "should use the same value for the creation and update timestamps when creating if the :update_on_create option is given" do
41
42
  @c.plugin :timestamps, :update_on_create=>true
42
43
  o = @c.create
43
- @c.db.sqls.length.should == 1
44
- @c.db.sqls.first.should =~ /INSERT INTO t \((creat|updat)ed_at, (creat|updat)ed_at\) VALUES \('2009-08-01', '2009-08-01'\)/
44
+ sqls = @c.db.sqls
45
+ sqls.shift.should =~ /INSERT INTO t \((creat|updat)ed_at, (creat|updat)ed_at\) VALUES \('2009-08-01', '2009-08-01'\)/
46
+ sqls.should == []
45
47
  o.created_at.should === o.updated_at
46
48
  end
47
49
 
@@ -50,8 +52,7 @@ describe "Sequel::Plugins::Timestamps" do
50
52
  c.class_eval do
51
53
  columns :id, :c
52
54
  plugin :timestamps, :create=>:c
53
- db.reset
54
- def _refresh(ds); self end
55
+ def _save_refresh(*) end
55
56
  end
56
57
  o = c.create
57
58
  c.db.sqls.should == ["INSERT INTO t (c) VALUES ('2009-08-01')"]
@@ -64,7 +65,6 @@ describe "Sequel::Plugins::Timestamps" do
64
65
  columns :id, :u
65
66
  plugin :timestamps, :update=>:u
66
67
  db.reset
67
- def _refresh(ds); self end
68
68
  end
69
69
  o = c.load(:id=>1).save
70
70
  c.db.sqls.should == ["UPDATE t SET u = '2009-08-01' WHERE (id = 1)"]
@@ -2,9 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe Sequel::Model, "to_dot extension" do
4
4
  def dot(ds)
5
- a = []
6
- ds.send(:_to_dot, a, "", 0, ds, 0)
7
- a[2..-1]
5
+ Sequel::ToDot.new(ds).instance_variable_get(:@dot)[4...-1]
8
6
  end
9
7
 
10
8
  before do
@@ -13,14 +11,13 @@ describe Sequel::Model, "to_dot extension" do
13
11
  end
14
12
 
15
13
  it "should output a string suitable for input to the graphviz dot program" do
16
- @ds.to_dot.should == (<<END
14
+ @ds.to_dot.should == (<<END).strip
17
15
  digraph G {
18
16
  0 [label="self"];
19
17
  0 -> 1 [label=""];
20
18
  1 [label="Dataset"];
21
19
  }
22
20
  END
23
- ).strip
24
21
  end
25
22
 
26
23
  it "should handle an empty dataset" do
@@ -103,19 +100,19 @@ END
103
100
  end
104
101
 
105
102
  it "should handle SQL::OrderedExpressions" do
106
- dot(@ds.order(:a.desc(:nulls=>:last))).should == ["1 -> 2 [label=\"order\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"OrderedExpression: DESC NULLS LAST\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":a\"];"]
103
+ dot(@ds.order(Sequel.desc(:a, :nulls=>:last))).should == ["1 -> 2 [label=\"order\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"OrderedExpression: DESC NULLS LAST\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":a\"];"]
107
104
  end
108
105
 
109
106
  it "should handle SQL::AliasedExpressions" do
110
- dot(@ds.from(:a.as(:b))).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"AliasedExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"alias\"];", "5 [label=\":b\"];"]
107
+ dot(@ds.from(Sequel.as(:a, :b))).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"AliasedExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"alias\"];", "5 [label=\":b\"];"]
111
108
  end
112
109
 
113
110
  it "should handle SQL::CaseExpressions" do
114
- dot(@ds.select({:a=>:b}.case(:c, :d))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"CaseExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":d\"];", "3 -> 5 [label=\"conditions\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\":a\"];", "6 -> 8 [label=\"1\"];", "8 [label=\":b\"];", "3 -> 9 [label=\"default\"];", "9 [label=\":c\"];"]
111
+ dot(@ds.select(Sequel.case({:a=>:b}, :c, :d))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"CaseExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":d\"];", "3 -> 5 [label=\"conditions\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\":a\"];", "6 -> 8 [label=\"1\"];", "8 [label=\":b\"];", "3 -> 9 [label=\"default\"];", "9 [label=\":c\"];"]
115
112
  end
116
113
 
117
114
  it "should handle SQL::Cast" do
118
- dot(@ds.select(:a.cast(Integer))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Cast\"];", "3 -> 4 [label=\"expr\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"type\"];", "5 [label=\"Integer\"];"]
115
+ dot(@ds.select(Sequel.cast(:a, Integer))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Cast\"];", "3 -> 4 [label=\"expr\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"type\"];", "5 [label=\"Integer\"];"]
119
116
  end
120
117
 
121
118
  it "should handle SQL::Function" do
@@ -123,7 +120,7 @@ END
123
120
  end
124
121
 
125
122
  it "should handle SQL::Subscript" do
126
- dot(@ds.select(:a.sql_subscript(1))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Subscript: a\"];", "3 -> 4 [label=\"f\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"sub\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"1\"];"]
123
+ dot(@ds.select(Sequel.subscript(:a, 1))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Subscript\"];", "3 -> 4 [label=\"f\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"sub\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"1\"];"]
127
124
  end
128
125
 
129
126
  it "should handle SQL::WindowFunction" do
@@ -135,7 +132,7 @@ END
135
132
  end
136
133
 
137
134
  it "should handle JOIN ON" do
138
- dot(@ds.from(:a).join(:d, :b=>:c)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "1 -> 4 [label=\"join\"];", "4 [label=\"Array\"];", "4 -> 5 [label=\"0\"];", "5 [label=\"INNER JOIN ON\"];", "5 -> 6 [label=\"table\"];", "6 [label=\":d\"];", "5 -> 7 [label=\"on\"];", "7 [label=\"Array\"];", "7 -> 8 [label=\"0\"];", "8 [label=\"Array\"];", "8 -> 9 [label=\"0\"];", "9 [label=\"QualifiedIdentifier\"];", "9 -> 10 [label=\"table\"];", "10 [label=\"\\\"d\\\"\"];", "9 -> 11 [label=\"column\"];", "11 [label=\"\\\"b\\\"\"];", "8 -> 12 [label=\"1\"];", "12 [label=\"QualifiedIdentifier\"];", "12 -> 13 [label=\"table\"];", "13 [label=\"\\\"a\\\"\"];", "12 -> 14 [label=\"column\"];", "14 [label=\"\\\"c\\\"\"];"]
135
+ dot(@ds.from(:a).join(:d, :b=>:c)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "1 -> 4 [label=\"join\"];", "4 [label=\"Array\"];", "4 -> 5 [label=\"0\"];", "5 [label=\"INNER JOIN ON\"];", "5 -> 6 [label=\"table\"];", "6 [label=\":d\"];", "5 -> 7 [label=\"on\"];", "7 [label=\"ComplexExpression: =\"];", "7 -> 8 [label=\"0\"];", "8 [label=\"QualifiedIdentifier\"];", "8 -> 9 [label=\"table\"];", "9 [label=\"\\\"d\\\"\"];", "8 -> 10 [label=\"column\"];", "10 [label=\"\\\"b\\\"\"];", "7 -> 11 [label=\"1\"];", "11 [label=\"QualifiedIdentifier\"];", "11 -> 12 [label=\"table\"];", "12 [label=\"\\\"a\\\"\"];", "11 -> 13 [label=\"column\"];", "13 [label=\"\\\"c\\\"\"];"]
139
136
  end
140
137
 
141
138
  it "should handle JOIN USING" do
@@ -2,9 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "Touch plugin" do
4
4
  before do
5
- @c = Class.new(Sequel::Model) do
6
- def _refresh(*); end
7
- end
5
+ @c = Class.new(Sequel::Model)
8
6
  p = proc{def touch_instance_value; touch_association_value; end}
9
7
  @Artist = Class.new(@c, &p).set_dataset(:artists)
10
8
  @Album = Class.new(@c, &p).set_dataset(:albums)
@@ -63,8 +61,9 @@ describe "Touch plugin" do
63
61
  specify "should be able to give an array to the :associations option specifying multiple associations" do
64
62
  @Album.plugin :touch, :associations=>[:artist, :followup_albums]
65
63
  @Album.load(:id=>4, :artist_id=>1).touch
66
- MODEL_DB.sqls.shift.should == "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
67
- MODEL_DB.sqls.sort.should == ["UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
64
+ sqls = MODEL_DB.sqls
65
+ sqls.shift.should == "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
66
+ sqls.sort.should == ["UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
68
67
  "UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
69
68
  end
70
69
 
@@ -85,8 +84,9 @@ describe "Touch plugin" do
85
84
  specify "should allow the mixed use of symbols and hashes inside an array for the :associations option" do
86
85
  @Album.plugin :touch, :associations=>[:artist, {:followup_albums=>:modified_on}]
87
86
  @Album.load(:id=>4, :artist_id=>1).touch
88
- MODEL_DB.sqls.shift.should == "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
89
- MODEL_DB.sqls.sort.should == ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
87
+ sqls = MODEL_DB.sqls
88
+ sqls.shift.should == "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
89
+ sqls.sort.should == ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
90
90
  "UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
91
91
  end
92
92
 
@@ -94,8 +94,9 @@ describe "Touch plugin" do
94
94
  @Album.plugin :touch
95
95
  @Album.touch_associations(:artist, {:followup_albums=>:modified_on})
96
96
  @Album.load(:id=>4, :artist_id=>1).touch
97
- MODEL_DB.sqls.shift.should == "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
98
- MODEL_DB.sqls.sort.should == ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
97
+ sqls = MODEL_DB.sqls
98
+ sqls.shift.should == "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
99
+ sqls.sort.should == ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
99
100
  "UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
100
101
  end
101
102
 
@@ -103,8 +104,9 @@ describe "Touch plugin" do
103
104
  @Album.plugin :touch
104
105
  @Album.touch_associations(:artist, {:followup_albums=>:modified_on})
105
106
  @Album.load(:id=>4, :artist_id=>1).destroy
106
- MODEL_DB.sqls.shift.should == "DELETE FROM albums WHERE (id = 4)"
107
- MODEL_DB.sqls.sort.should == ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
107
+ sqls = MODEL_DB.sqls
108
+ sqls.shift.should == "DELETE FROM albums WHERE id = 4"
109
+ sqls.sort.should == ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
108
110
  "UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
109
111
  end
110
112
 
@@ -133,18 +135,15 @@ describe "Touch plugin" do
133
135
  c1 = Class.new(@Artist)
134
136
  c1.load(:id=>4).touch
135
137
  MODEL_DB.sqls.should == ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"]
136
- MODEL_DB.reset
137
138
 
138
139
  c1.touch_column = :modified_on
139
140
  c1.touch_associations :albums
140
141
  c1.load(:id=>1).touch
141
142
  MODEL_DB.sqls.should == ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 1)",
142
143
  "UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.artist_id = 1)"]
143
- MODEL_DB.reset
144
144
 
145
145
  @a.touch
146
146
  MODEL_DB.sqls.should == ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)"]
147
- MODEL_DB.reset
148
147
 
149
148
  @Artist.plugin :touch, :column=>:modified_on, :associations=>:albums
150
149
  c2 = Class.new(@Artist)