sequel 4.41.0 → 4.42.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (256) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +98 -0
  3. data/README.rdoc +23 -10
  4. data/doc/active_record.rdoc +4 -4
  5. data/doc/advanced_associations.rdoc +2 -2
  6. data/doc/association_basics.rdoc +5 -2
  7. data/doc/cheat_sheet.rdoc +3 -3
  8. data/doc/core_extensions.rdoc +2 -2
  9. data/doc/dataset_basics.rdoc +4 -4
  10. data/doc/dataset_filtering.rdoc +1 -1
  11. data/doc/migration.rdoc +19 -1
  12. data/doc/prepared_statements.rdoc +2 -2
  13. data/doc/release_notes/4.42.0.txt +221 -0
  14. data/doc/testing.rdoc +3 -1
  15. data/lib/sequel/adapters/ado/access.rb +0 -1
  16. data/lib/sequel/adapters/ado/mssql.rb +0 -1
  17. data/lib/sequel/adapters/do/mysql.rb +0 -1
  18. data/lib/sequel/adapters/do/postgres.rb +0 -1
  19. data/lib/sequel/adapters/do/sqlite3.rb +0 -1
  20. data/lib/sequel/adapters/ibmdb.rb +21 -25
  21. data/lib/sequel/adapters/jdbc.rb +8 -16
  22. data/lib/sequel/adapters/jdbc/as400.rb +0 -1
  23. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -1
  24. data/lib/sequel/adapters/jdbc/db2.rb +0 -1
  25. data/lib/sequel/adapters/jdbc/derby.rb +0 -1
  26. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -1
  27. data/lib/sequel/adapters/jdbc/h2.rb +0 -1
  28. data/lib/sequel/adapters/jdbc/hsqldb.rb +0 -1
  29. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -1
  30. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -1
  31. data/lib/sequel/adapters/jdbc/jtds.rb +0 -1
  32. data/lib/sequel/adapters/jdbc/mssql.rb +0 -1
  33. data/lib/sequel/adapters/jdbc/mysql.rb +0 -1
  34. data/lib/sequel/adapters/jdbc/oracle.rb +0 -1
  35. data/lib/sequel/adapters/jdbc/postgresql.rb +0 -13
  36. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +0 -1
  37. data/lib/sequel/adapters/jdbc/sqlite.rb +0 -1
  38. data/lib/sequel/adapters/jdbc/sqlserver.rb +3 -4
  39. data/lib/sequel/adapters/mock.rb +54 -12
  40. data/lib/sequel/adapters/mysql.rb +1 -1
  41. data/lib/sequel/adapters/mysql2.rb +11 -17
  42. data/lib/sequel/adapters/odbc/mssql.rb +0 -1
  43. data/lib/sequel/adapters/oracle.rb +8 -20
  44. data/lib/sequel/adapters/postgres.rb +11 -29
  45. data/lib/sequel/adapters/shared/access.rb +5 -12
  46. data/lib/sequel/adapters/shared/cubrid.rb +4 -13
  47. data/lib/sequel/adapters/shared/db2.rb +4 -2
  48. data/lib/sequel/adapters/shared/firebird.rb +2 -4
  49. data/lib/sequel/adapters/shared/informix.rb +4 -2
  50. data/lib/sequel/adapters/shared/mssql.rb +3 -5
  51. data/lib/sequel/adapters/shared/mysql.rb +4 -14
  52. data/lib/sequel/adapters/shared/oracle.rb +1 -3
  53. data/lib/sequel/adapters/shared/postgres.rb +16 -38
  54. data/lib/sequel/adapters/shared/progress.rb +0 -2
  55. data/lib/sequel/adapters/shared/sqlanywhere.rb +0 -2
  56. data/lib/sequel/adapters/shared/sqlite.rb +20 -16
  57. data/lib/sequel/adapters/sqlite.rb +8 -20
  58. data/lib/sequel/adapters/swift/mysql.rb +0 -1
  59. data/lib/sequel/adapters/swift/postgres.rb +0 -1
  60. data/lib/sequel/adapters/swift/sqlite.rb +0 -1
  61. data/lib/sequel/adapters/tinytds.rb +4 -12
  62. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
  63. data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -2
  64. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +11 -34
  65. data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
  66. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +26 -0
  67. data/lib/sequel/ast_transformer.rb +2 -2
  68. data/lib/sequel/database/dataset.rb +1 -1
  69. data/lib/sequel/database/dataset_defaults.rb +0 -66
  70. data/lib/sequel/database/features.rb +6 -0
  71. data/lib/sequel/database/misc.rb +31 -17
  72. data/lib/sequel/database/query.rb +7 -4
  73. data/lib/sequel/database/schema_methods.rb +1 -1
  74. data/lib/sequel/dataset.rb +8 -8
  75. data/lib/sequel/dataset/actions.rb +140 -46
  76. data/lib/sequel/dataset/features.rb +1 -5
  77. data/lib/sequel/dataset/graph.rb +7 -8
  78. data/lib/sequel/dataset/misc.rb +127 -56
  79. data/lib/sequel/dataset/mutation.rb +9 -20
  80. data/lib/sequel/dataset/placeholder_literalizer.rb +10 -1
  81. data/lib/sequel/dataset/prepared_statements.rb +102 -46
  82. data/lib/sequel/dataset/query.rb +155 -72
  83. data/lib/sequel/dataset/sql.rb +26 -9
  84. data/lib/sequel/extensions/columns_introspection.rb +3 -1
  85. data/lib/sequel/extensions/core_extensions.rb +5 -5
  86. data/lib/sequel/extensions/core_refinements.rb +5 -5
  87. data/lib/sequel/extensions/duplicate_columns_handler.rb +4 -2
  88. data/lib/sequel/extensions/freeze_datasets.rb +69 -0
  89. data/lib/sequel/extensions/identifier_mangling.rb +196 -0
  90. data/lib/sequel/extensions/looser_typecasting.rb +11 -7
  91. data/lib/sequel/extensions/migration.rb +1 -1
  92. data/lib/sequel/extensions/null_dataset.rb +5 -2
  93. data/lib/sequel/extensions/pagination.rb +42 -23
  94. data/lib/sequel/extensions/pg_enum.rb +3 -3
  95. data/lib/sequel/extensions/query.rb +3 -3
  96. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +15 -8
  97. data/lib/sequel/model/associations.rb +25 -8
  98. data/lib/sequel/model/base.rb +88 -29
  99. data/lib/sequel/model/dataset_module.rb +37 -0
  100. data/lib/sequel/plugins/association_pks.rb +4 -4
  101. data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
  102. data/lib/sequel/plugins/constraint_validations.rb +1 -2
  103. data/lib/sequel/plugins/csv_serializer.rb +2 -2
  104. data/lib/sequel/plugins/dataset_associations.rb +8 -8
  105. data/lib/sequel/plugins/eager_each.rb +2 -2
  106. data/lib/sequel/plugins/instance_filters.rb +1 -1
  107. data/lib/sequel/plugins/json_serializer.rb +2 -2
  108. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  109. data/lib/sequel/plugins/list.rb +4 -4
  110. data/lib/sequel/plugins/prepared_statements.rb +2 -4
  111. data/lib/sequel/plugins/prepared_statements_associations.rb +1 -3
  112. data/lib/sequel/plugins/prepared_statements_with_pk.rb +1 -1
  113. data/lib/sequel/plugins/rcte_tree.rb +13 -13
  114. data/lib/sequel/plugins/sharding.rb +1 -1
  115. data/lib/sequel/plugins/single_table_inheritance.rb +9 -4
  116. data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
  117. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  118. data/lib/sequel/plugins/validation_helpers.rb +1 -1
  119. data/lib/sequel/plugins/xml_serializer.rb +2 -2
  120. data/lib/sequel/sql.rb +69 -36
  121. data/lib/sequel/version.rb +1 -1
  122. data/spec/adapters/db2_spec.rb +10 -0
  123. data/spec/adapters/firebird_spec.rb +1 -1
  124. data/spec/adapters/mssql_spec.rb +4 -5
  125. data/spec/adapters/mysql_spec.rb +9 -9
  126. data/spec/adapters/postgres_spec.rb +67 -68
  127. data/spec/adapters/spec_helper.rb +6 -1
  128. data/spec/adapters/sqlite_spec.rb +29 -15
  129. data/spec/core/connection_pool_spec.rb +14 -14
  130. data/spec/core/database_spec.rb +38 -180
  131. data/spec/core/dataset_mutation_spec.rb +253 -0
  132. data/spec/core/dataset_spec.rb +394 -537
  133. data/spec/core/expression_filters_spec.rb +34 -32
  134. data/spec/core/mock_adapter_spec.rb +27 -35
  135. data/spec/core/placeholder_literalizer_spec.rb +2 -4
  136. data/spec/core/schema_generator_spec.rb +4 -4
  137. data/spec/core/schema_spec.rb +1 -2
  138. data/spec/core_extensions_spec.rb +22 -29
  139. data/spec/extensions/active_model_spec.rb +6 -6
  140. data/spec/extensions/association_dependencies_spec.rb +2 -2
  141. data/spec/extensions/blacklist_security_spec.rb +3 -3
  142. data/spec/extensions/boolean_readers_spec.rb +12 -12
  143. data/spec/extensions/caching_spec.rb +13 -10
  144. data/spec/extensions/class_table_inheritance_spec.rb +38 -43
  145. data/spec/extensions/column_conflicts_spec.rb +1 -3
  146. data/spec/extensions/columns_introspection_spec.rb +2 -3
  147. data/spec/extensions/composition_spec.rb +5 -3
  148. data/spec/extensions/constraint_validations_plugin_spec.rb +5 -5
  149. data/spec/extensions/constraint_validations_spec.rb +14 -8
  150. data/spec/extensions/core_refinements_spec.rb +22 -29
  151. data/spec/extensions/csv_serializer_spec.rb +7 -6
  152. data/spec/extensions/date_arithmetic_spec.rb +15 -15
  153. data/spec/extensions/defaults_setter_spec.rb +2 -2
  154. data/spec/extensions/delay_add_association_spec.rb +1 -1
  155. data/spec/extensions/dirty_spec.rb +19 -10
  156. data/spec/extensions/duplicate_columns_handler_spec.rb +12 -18
  157. data/spec/extensions/eager_each_spec.rb +12 -16
  158. data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
  159. data/spec/extensions/eval_inspect_spec.rb +4 -3
  160. data/spec/extensions/force_encoding_spec.rb +12 -12
  161. data/spec/extensions/freeze_datasets_spec.rb +31 -0
  162. data/spec/extensions/graph_each_spec.rb +6 -18
  163. data/spec/extensions/hook_class_methods_spec.rb +7 -7
  164. data/spec/extensions/identifier_mangling_spec.rb +307 -0
  165. data/spec/extensions/instance_filters_spec.rb +5 -6
  166. data/spec/extensions/instance_hooks_spec.rb +12 -12
  167. data/spec/extensions/json_serializer_spec.rb +12 -15
  168. data/spec/extensions/lazy_attributes_spec.rb +4 -4
  169. data/spec/extensions/list_spec.rb +19 -21
  170. data/spec/extensions/many_through_many_spec.rb +108 -163
  171. data/spec/extensions/meta_def_spec.rb +7 -2
  172. data/spec/extensions/migration_spec.rb +10 -12
  173. data/spec/extensions/mssql_optimistic_locking_spec.rb +4 -3
  174. data/spec/extensions/named_timezones_spec.rb +4 -3
  175. data/spec/extensions/nested_attributes_spec.rb +2 -2
  176. data/spec/extensions/null_dataset_spec.rb +17 -12
  177. data/spec/extensions/optimistic_locking_spec.rb +4 -5
  178. data/spec/extensions/pagination_spec.rb +8 -10
  179. data/spec/extensions/pg_array_associations_spec.rb +28 -27
  180. data/spec/extensions/pg_array_ops_spec.rb +2 -1
  181. data/spec/extensions/pg_array_spec.rb +6 -2
  182. data/spec/extensions/pg_enum_spec.rb +5 -3
  183. data/spec/extensions/pg_hstore_ops_spec.rb +3 -1
  184. data/spec/extensions/pg_hstore_spec.rb +7 -6
  185. data/spec/extensions/pg_inet_ops_spec.rb +2 -1
  186. data/spec/extensions/pg_inet_spec.rb +2 -1
  187. data/spec/extensions/pg_interval_spec.rb +2 -1
  188. data/spec/extensions/pg_json_ops_spec.rb +2 -1
  189. data/spec/extensions/pg_json_spec.rb +6 -3
  190. data/spec/extensions/pg_loose_count_spec.rb +1 -0
  191. data/spec/extensions/pg_range_ops_spec.rb +3 -1
  192. data/spec/extensions/pg_range_spec.rb +9 -5
  193. data/spec/extensions/pg_row_ops_spec.rb +2 -1
  194. data/spec/extensions/pg_row_plugin_spec.rb +4 -6
  195. data/spec/extensions/pg_row_spec.rb +5 -3
  196. data/spec/extensions/pg_static_cache_updater_spec.rb +2 -1
  197. data/spec/extensions/pg_typecast_on_load_spec.rb +1 -1
  198. data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
  199. data/spec/extensions/prepared_statements_spec.rb +12 -11
  200. data/spec/extensions/pretty_table_spec.rb +1 -1
  201. data/spec/extensions/query_spec.rb +8 -5
  202. data/spec/extensions/rcte_tree_spec.rb +39 -39
  203. data/spec/extensions/round_timestamps_spec.rb +2 -2
  204. data/spec/extensions/schema_dumper_spec.rb +3 -2
  205. data/spec/extensions/schema_spec.rb +2 -2
  206. data/spec/extensions/scissors_spec.rb +1 -2
  207. data/spec/extensions/sequel_3_dataset_methods_spec.rb +30 -17
  208. data/spec/extensions/serialization_modification_detection_spec.rb +2 -2
  209. data/spec/extensions/serialization_spec.rb +15 -13
  210. data/spec/extensions/set_overrides_spec.rb +14 -8
  211. data/spec/extensions/sharding_spec.rb +9 -18
  212. data/spec/extensions/shared_caching_spec.rb +3 -4
  213. data/spec/extensions/single_table_inheritance_spec.rb +11 -11
  214. data/spec/extensions/skip_create_refresh_spec.rb +2 -1
  215. data/spec/extensions/spec_helper.rb +1 -1
  216. data/spec/extensions/split_values_spec.rb +2 -2
  217. data/spec/extensions/sql_comments_spec.rb +6 -0
  218. data/spec/extensions/static_cache_spec.rb +7 -9
  219. data/spec/extensions/string_agg_spec.rb +30 -29
  220. data/spec/extensions/tactical_eager_loading_spec.rb +4 -5
  221. data/spec/extensions/thread_local_timezones_spec.rb +2 -2
  222. data/spec/extensions/timestamps_spec.rb +28 -3
  223. data/spec/extensions/to_dot_spec.rb +1 -2
  224. data/spec/extensions/tree_spec.rb +33 -29
  225. data/spec/extensions/typecast_on_load_spec.rb +1 -1
  226. data/spec/extensions/unlimited_update_spec.rb +1 -0
  227. data/spec/extensions/update_primary_key_spec.rb +11 -7
  228. data/spec/extensions/update_refresh_spec.rb +1 -1
  229. data/spec/extensions/uuid_spec.rb +0 -1
  230. data/spec/extensions/validate_associated_spec.rb +1 -1
  231. data/spec/extensions/validation_class_methods_spec.rb +10 -10
  232. data/spec/extensions/validation_helpers_spec.rb +10 -10
  233. data/spec/extensions/xml_serializer_spec.rb +7 -3
  234. data/spec/integration/associations_test.rb +31 -31
  235. data/spec/integration/dataset_test.rb +17 -19
  236. data/spec/integration/eager_loader_test.rb +24 -24
  237. data/spec/integration/model_test.rb +6 -6
  238. data/spec/integration/plugin_test.rb +43 -43
  239. data/spec/integration/prepared_statement_test.rb +6 -6
  240. data/spec/integration/schema_test.rb +63 -52
  241. data/spec/integration/spec_helper.rb +6 -1
  242. data/spec/integration/transaction_test.rb +13 -13
  243. data/spec/model/association_reflection_spec.rb +17 -17
  244. data/spec/model/associations_spec.rb +101 -96
  245. data/spec/model/base_spec.rb +175 -49
  246. data/spec/model/class_dataset_methods_spec.rb +5 -9
  247. data/spec/model/dataset_methods_spec.rb +5 -5
  248. data/spec/model/eager_loading_spec.rb +209 -235
  249. data/spec/model/hooks_spec.rb +15 -15
  250. data/spec/model/model_spec.rb +28 -21
  251. data/spec/model/plugins_spec.rb +4 -5
  252. data/spec/model/record_spec.rb +59 -57
  253. data/spec/model/spec_helper.rb +1 -1
  254. data/spec/model/validations_spec.rb +6 -6
  255. data/spec/spec_config.rb +1 -1
  256. metadata +10 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '04857dbc303fa5d8cd9cb242dee35021eada5410'
4
- data.tar.gz: f05247db19fc6bfb7afdb6730d301eed82fd398e
3
+ metadata.gz: 950d9818b7e057e8728dde0e8bc5460dc3a91679
4
+ data.tar.gz: e0cec40c01a7eeb1a6ca8d6d993155a74b032f9d
5
5
  SHA512:
6
- metadata.gz: 320e1e83b8f39e3baa396ec77fefd70f780cd96960c5e86353419d3f2f905f4fbdfc3acf18bb1e37c35620e5dca9d2401a7895b77a205ccf52d31dd8d25b07b6
7
- data.tar.gz: f1ea15ae50f0b4e398966a5fbedde61f943032a157406e6e4d39fdc01dbcae4dc3b97432395267ae82b848af251f39ece08cf20f65893258f636d9397483fb70
6
+ metadata.gz: e0bda9bf194bd56954f1647775b8de2d6ed2ace58691c32cf58f2d11717980492dbd0f2dad3f4a13ee2cc45eaa033e2b18456b556b9166a24163e1f7eb8fd41d
7
+ data.tar.gz: 5c8f48cee321a25826ac480fa09c82289f105d5ff793fee90a58c47f9b91ae4daf2ccd0dbd516391c45fff54ee3036726a9cb0fd22a7d832d77a86e98ddd866f
data/CHANGELOG CHANGED
@@ -1,3 +1,101 @@
1
+ === 4.42.0 (2017-01-01)
2
+
3
+ * Handle eager load callbacks correctly for one_to_one associations with orders or offsets when window functions are not supported (jeremyevans)
4
+
5
+ * Raise Sequel::Error if using an :eager_limit dataset option when eager loading a singular association (jeremyevans)
6
+
7
+ * Replace internal uses of Dataset#select_more with #select_append to save a method call (jeremyevans)
8
+
9
+ * Make Dataset#order_append the primary method, and #order_more the alias, for similarity to #select_append and #select_more (jeremyevans)
10
+
11
+ * Replace internal uses of Dataset#filter with #where to save a method call (jeremyevans)
12
+
13
+ * Do not set :auto_increment in the schema information for integer columns that are part of a composite primary key on SQLite (jeremyevans)
14
+
15
+ * Use autoincrement setting on integer primary key columns when emulating table modification methods on SQLite (thenrio, jeremyevans) (#1277, #1278)
16
+
17
+ * Make the pagination extension work on frozen datasets (jeremyevans)
18
+
19
+ * Make Dataset#server work for frozen model datasets using the sharding plugin (jeremyevans)
20
+
21
+ * Make Dataset#nullify in the null_dataset extension work on frozen datasets (jeremyevans)
22
+
23
+ * Make Model#set_server work when using a frozen model dataset (jeremyevans)
24
+
25
+ * Make Dataset#ungraphed work on a frozen model dataset (jeremyevans)
26
+
27
+ * Add Dataset#with_{autoid,fetch,numrows} to the mock adapter, returning cloned datasets with the setting changed (jeremyevans)
28
+
29
+ * Make looser_typecasting extension handle the strict BigDecimal parsing introduced in ruby 2.4rc1 (jeremyevans)
30
+
31
+ * Make Database#{db,opts}= in the sequel_3_dataset_methods extension raise for frozen datasets (jeremyevans)
32
+
33
+ * Speed up repeated calls to Dataset#{interval,range} for frozen datasets using a cached placeholder literalizer (jeremyevans)
34
+
35
+ * Speed up repeated calls to Dataset#get with a single argument for frozen datasets using a cached placeholder literalizer (jeremyevans)
36
+
37
+ * Speed up repeated calls to Dataset#{first,last} with arguments/blocks for frozen datasets using a cached placeholder literalizer (jeremyevans)
38
+
39
+ * Speed up repeated calls to Dataset#{avg,min,max,sum} for frozen datasets using a cached placeholder literalizer (jeremyevans)
40
+
41
+ * Cache dataset returned by Dataset#skip_locked for frozen datasets (jeremyevans)
42
+
43
+ * Cache dataset returned by Dataset#for_update for frozen datasets (jeremyevans)
44
+
45
+ * Cache dataset returned by Dataset#un{filtered,grouped,limited,ordered} for frozen datasets (jeremyevans)
46
+
47
+ * Cache dataset returned by Dataset#reverse (no args) for frozen datasets (jeremyevans)
48
+
49
+ * Cache dataset returned by Dataset#invert for frozen datasets (jeremyevans)
50
+
51
+ * Speed up repeated calls to Dataset#count with an argument or block for frozen datasets using a cached placeholder literalizer (jeremyevans)
52
+
53
+ * Using :on_duplicate_columns=>:warn Database option with duplicate_columns_handler now prepends file/line to the warning message (jeremyevans)
54
+
55
+ * Move identifier mangling code to identifier_mangling extension, load by default unless using :identifier_mangling=>false Database option (jeremyevans)
56
+
57
+ * Allow Dataset#with_extend to accept a block and create a module with that block that the object is extended with (jeremyevans)
58
+
59
+ * Speed up repeated calls to with_pk on the same frozen model dataset using a cached placeholder literalizer (jeremyevans)
60
+
61
+ * Add dataset_module methods such as select and order that define dataset methods which support caching for frozen datasets (jeremyevans)
62
+
63
+ * Cache subset datasets if they don't use blocks or procs for frozen model datasets (jeremyevans)
64
+
65
+ * Cache intermediate dataset used in Dataset#{last,paged_each} for frozen model datasets without an order (jeremyevans)
66
+
67
+ * Cache dataset returned by Dataset#naked for frozen datasets (jeremyevans)
68
+
69
+ * Cache intermediate dataset used in Dataset#last (no args) for frozen datasets (jeremyevans)
70
+
71
+ * Cache intermediate dataset used in Dataset#first (no args) and #single_record for frozen datasets (jeremyevans)
72
+
73
+ * Cache intermediate dataset used in Dataset#empty? for frozen datasets (jeremyevans)
74
+
75
+ * Cache intermediate dataset used in Dataset#count (no args) for frozen datasets (jeremyevans)
76
+
77
+ * Warn if :conditions option may be unexpectedly ignored during eager_graph/association_join (jeremyevans) (#1272)
78
+
79
+ * Cache SELECT and DELETE SQL for most frozen datasets (jeremyevans)
80
+
81
+ * Freeze most SQL::Expression objects and internal state by default (jeremyevans)
82
+
83
+ * Freeze Dataset::PlaceholderLiteralizer and Dataset::PlaceholderLiteralizer::Argument instances (jeremyevans)
84
+
85
+ * Freeze most dataset opts values to avoid unintentional modification (jeremyevans)
86
+
87
+ * Add Dataset#with_convert_smallint_to_bool on DB2, returning a clone with convert_smallint_to_bool set (jeremyevans)
88
+
89
+ * Make Dataset#freeze actually freeze the dataset on ruby 2.4+ (jeremyevans)
90
+
91
+ * Avoid using instance variables other than @opts for dataset data storage (jeremyevans)
92
+
93
+ * Add freeze_datasets extension, making all datasets for a given Database frozen (jeremyevans)
94
+
95
+ * Refactor prepared statement internals, using opts instead of instance variables (jeremyevans)
96
+
97
+ * Model.set_dataset now operates on a clone of the dataset given instead of modifying it, so it works with frozen datasets (jeremyevans)
98
+
1
99
  === 4.41.0 (2016-12-01)
2
100
 
3
101
  * Add Dataset#with_mssql_unicode_strings on Microsoft SQL Server, returning a clone with mssql_unicode_strings set (jeremyevans)
data/README.rdoc CHANGED
@@ -83,7 +83,7 @@ Sequel uses the concept of datasets to retrieve data. A Dataset object encapsula
83
83
 
84
84
  For example, the following one-liner returns the average GDP for countries in the middle east region:
85
85
 
86
- DB[:countries].filter(:region => 'Middle East').avg(:GDP)
86
+ DB[:countries].where(:region => 'Middle East').avg(:GDP)
87
87
 
88
88
  Which is equivalent to:
89
89
 
@@ -91,7 +91,7 @@ Which is equivalent to:
91
91
 
92
92
  Since datasets retrieve records only when needed, they can be stored and later reused. Records are fetched as hashes (or custom model objects), and are accessed using an +Enumerable+ interface:
93
93
 
94
- middle_east = DB[:countries].filter(:region => 'Middle East')
94
+ middle_east = DB[:countries].where(:region => 'Middle East')
95
95
  middle_east.order(:name).each{|r| puts r[:name]}
96
96
 
97
97
  Sequel also offers convenience methods for extracting data from Datasets, such as an extended +map+ method:
@@ -404,7 +404,7 @@ and not raise an exception outside the block, you can raise the
404
404
 
405
405
  DB.transaction do
406
406
  posts.insert(:category => 'ruby', :author => 'david')
407
- if posts.filter('stamp < ?', Date.today - 7).update(:state => 'archived') == 0
407
+ if posts.where('stamp < ?', Date.today - 7).update(:state => 'archived') == 0
408
408
  raise Sequel::Rollback
409
409
  end
410
410
  end
@@ -791,27 +791,40 @@ The recommended way to implement table-wide logic by defining methods on the dat
791
791
 
792
792
  class Post < Sequel::Model
793
793
  dataset_module do
794
- def posts_with_few_comments
794
+ def with_few_comments
795
795
  where{num_comments < 30}
796
796
  end
797
797
 
798
- def clean_posts_with_few_comments
799
- posts_with_few_comments.delete
798
+ def clean_boring
799
+ with_few_comments.delete
800
800
  end
801
801
  end
802
802
  end
803
803
 
804
804
  This allows you to have access to your model API from filtered datasets as well:
805
805
 
806
- Post.where(:category => 'ruby').clean_posts_with_few_comments
806
+ Post.where(:category => 'ruby').clean_boring
807
+ # DELETE FROM posts WHERE ((category = 'ruby') AND (num_comments < 30))
807
808
 
808
- Sequel models also provide a +subset+ class method that creates a dataset method with a simple filter:
809
+ Inside +dataset_module+ blocks, there are numerous methods that support easy creation of dataset methods.
810
+ Most of these methods are named after the dataset methods themselves, such as +select+, +order+, and
811
+ +group+, and there is also a method named +subset+ which uses a filter:
809
812
 
810
813
  class Post < Sequel::Model
811
- subset(:posts_with_few_comments){num_comments < 30}
812
- subset :invisible, Sequel.~(:visible)
814
+ dataset_module do
815
+ subset(:with_few_comments){num_comments < 30}
816
+ select :with_title_and_date, :id, :title, :post_date
817
+ order :by_post_date, :post_date
818
+ limit :top10, 10
819
+ end
813
820
  end
814
821
 
822
+ Post.with_few_comments.with_title_and_date.by_post_date.top10
823
+ # SELECT id, title, post_date
824
+ # FROM posts
825
+ # ORDER BY post_date
826
+ # LIMIT 10
827
+
815
828
  === Model Validations
816
829
 
817
830
  You can define a +validate+ method for your model, which +save+
@@ -195,7 +195,7 @@ Sequel keeps datasets in an abstract format, allowing for powerful capabilities.
195
195
 
196
196
  This isn't possible when you use an SQL string fragment. Another case where using an SQL string fragment hurts you is when the SQL syntax cannot handle all cases:
197
197
 
198
- Album.filter('id NOT IN ?', ids_array)
198
+ Album.where('id NOT IN ?', ids_array)
199
199
 
200
200
  That will work fine if +ids_array+ is not empty, but will not work correctly if it is empty. With Sequel, you do:
201
201
 
@@ -205,11 +205,11 @@ That will handle cases where +ids_array+ is empty correctly.
205
205
 
206
206
  A third reason to not use SQL string fragments is database independence. For example, if you want a case insensitive search that works on both PostgreSQL and MySQL, the following won't work:
207
207
 
208
- Album.filter('name LIKE ?', 'A%')
208
+ Album.where('name LIKE ?', 'A%')
209
209
 
210
210
  This is because LIKE is case sensitive on PostgreSQL, but case insensitive on MySQL. With Sequel, you would do:
211
211
 
212
- Album.filter(Sequel.ilike(:name, 'A%'))
212
+ Album.where(Sequel.ilike(:name, 'A%'))
213
213
 
214
214
  This will do a case insensitive search on both databases. If you want a case sensitive search on both, you can use +like+ instead of +ilike+.
215
215
 
@@ -569,7 +569,7 @@ If you are using <tt>find(:last, ...)</tt>, you need to specify an order in Sequ
569
569
 
570
570
  Album.where(:artist_id=>1).order(:name).last
571
571
  # You could also do:
572
- Album.where(:artist_id=>1).reverse_order(:name).first
572
+ Album.where(:artist_id=>1).reverse(:name).first
573
573
 
574
574
  If you are using <tt>find(:all, ...)</tt>, you use a method chain instead of passing the options, and end it with +all+:
575
575
 
@@ -700,9 +700,9 @@ You can easily get a node's parent with node.parent, and a node's children with
700
700
  node.children. You can even eager load the relationship up to a certain depth:
701
701
 
702
702
  # Eager load three generations of generations of children for a given node
703
- Node.filter(:id=>1).eager(:children=>{:children=>:children}).all.first
703
+ Node.where(:id=>1).eager(:children=>{:children=>:children}).all.first
704
704
  # Load parents and grandparents for a group of nodes
705
- Node.filter{id < 10}.eager(:parent=>:parent).all
705
+ Node.where{id < 10}.eager(:parent=>:parent).all
706
706
 
707
707
  What if you want to get all ancestors up to the root node, or all descendents,
708
708
  without knowing the depth of the tree?
@@ -16,7 +16,7 @@ database tables. Without associations, if you had classes such as:
16
16
  And you wanted to get all of the albums for a given artist (assuming each
17
17
  album was associated with only one artist):
18
18
 
19
- Album.filter(:artist_id=>@artist.id).all
19
+ Album.where(:artist_id=>@artist.id).all
20
20
 
21
21
  Or maybe you want to add an album for a given artist:
22
22
 
@@ -962,7 +962,10 @@ In both cases an array of symbols can be used for a composite key association:
962
962
 
963
963
  The conditions to use to filter the association, can be any argument passed to +where+.
964
964
  If you use a hash or an array of two element arrays, this will also be used as a
965
- filter when using eager_graph to load the association.
965
+ filter when using eager_graph or association_join to load the association. If you
966
+ do not use a hash or array of two element arrays, consider also using the :graph_block
967
+ option to specifying a similar condition if you plan to use this association with
968
+ eager_graph or association_join.
966
969
 
967
970
  Artist.one_to_many :good_albums, :class=>:Album, :conditions=>{:good=>true}
968
971
  @artist.good_albums
data/doc/cheat_sheet.rdoc CHANGED
@@ -113,9 +113,9 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
113
113
 
114
114
  == Ordering
115
115
 
116
- dataset.order(:kind)
117
- dataset.reverse_order(:kind)
118
- dataset.order(Sequel.desc(:kind), :name)
116
+ dataset.order(:kind) # kind
117
+ dataset.reverse(:kind) # kind DESC
118
+ dataset.order(Sequel.desc(:kind), :name) # kind DESC, name
119
119
 
120
120
  == Limit/Offset
121
121
 
@@ -332,8 +332,8 @@ Alternative: Sequel.or:
332
332
 
333
333
  Array#sql_value_list wraps the array in an array subclass, which Sequel will always treat as a value list and not a conditions specifier. By default, Sequel treats arrays of two element arrays as a conditions specifier.
334
334
 
335
- DB[:a].filter('(a, b) IN ?', [[1, 2], [3, 4]]) # SQL: (a, b) IN ((1 = 2) AND (3 = 4))
336
- DB[:a].filter('(a, b) IN ?', [[1, 2], [3, 4]].sql_value_list) # SQL: (a, b) IN ((1, 2), (3, 4))
335
+ DB[:a].where('(a, b) IN ?', [[1, 2], [3, 4]]) # SQL: (a, b) IN ((1 = 2) AND (3 = 4))
336
+ DB[:a].where('(a, b) IN ?', [[1, 2], [3, 4]].sql_value_list) # SQL: (a, b) IN ((1, 2), (3, 4))
337
337
 
338
338
  Alternative: Sequel.value_list:
339
339
 
@@ -48,7 +48,7 @@ Thread safety you don't really need to worry about, but chainability is core to
48
48
  Another important thing to realize is that dataset methods that return modified datasets do not execute the dataset's code on the database. Only dataset methods that return or yield results will execute the code on the database:
49
49
 
50
50
  # No SQL queries sent:
51
- ds3 = ds.select(:id, :name).order(:name).filter{id < 100}
51
+ ds3 = ds.select(:id, :name).order(:name).where{id < 100}
52
52
 
53
53
  # Until you call a method that returns results
54
54
  results = ds3.all
@@ -56,12 +56,12 @@ Another important thing to realize is that dataset methods that return modified
56
56
  One important consequence of this API style is that if you use a method chain that includes both methods that return modified copies and a method that executes the SQL, the method that executes the SQL should generally be the last method in the chain:
57
57
 
58
58
  # Good
59
- ds.select(:id, :name).order(:name).filter{id < 100}.all
59
+ ds.select(:id, :name).order(:name).where{id < 100}.all
60
60
 
61
61
  # Bad
62
- ds.all.select(:id, :name).order(:name).filter{id < 100}
62
+ ds.all.select(:id, :name).order(:name).where{id < 100}
63
63
 
64
- This is because all will return an array of hashes, and select, order, and filter are dataset methods, not array methods.
64
+ This is because all will return an array of hashes, and +select+, +order+, and +where+ are dataset methods, not array methods.
65
65
 
66
66
  == Methods
67
67
 
@@ -191,7 +191,7 @@ You can concatenate SQL strings using Sequel.join:
191
191
 
192
192
  Sequel.join also takes a join argument:
193
193
 
194
- items.filter(Sequel.join([:name, :comment], ':').like('John:%nice%')).sql
194
+ items.where(Sequel.join([:name, :comment], ':').like('John:%nice%')).sql
195
195
  #=> "SELECT * FROM items WHERE ((name || ':' || comment) LIKE 'John:%nice%' ESCAPE '\')"
196
196
 
197
197
  == Filtering using sub-queries
data/doc/migration.rdoc CHANGED
@@ -437,7 +437,7 @@ artist per album to multiple artists per album:
437
437
  having{artist_id > 0}.
438
438
  all do |r|
439
439
  self[:artists].
440
- filter(:id=>r[:album_id]).
440
+ where(:id=>r[:album_id]).
441
441
  update(:artist_id=>r[:artist_id])
442
442
  end
443
443
 
@@ -635,3 +635,21 @@ database the migration is being run on, and operate accordingly:
635
635
  end
636
636
  end
637
637
  end
638
+
639
+ == Using Database Extensions in Migrations
640
+
641
+ If you need to use database extensions in migrations (e.g. +:pg_enum+), you should load the extension in the up or down block as appropriate.
642
+
643
+ Sequel.migration do
644
+ up do
645
+ extension :pg_enum
646
+
647
+ # migration here
648
+ end
649
+
650
+ down do
651
+ extension :pg_enum
652
+
653
+ # migration here
654
+ end
655
+ end
@@ -64,7 +64,7 @@ may itself contain placeholders:
64
64
  Prepared statement support is similar to bound variable support, but you
65
65
  use <tt>Dataset#prepare</tt> with a name, and <tt>Dataset#call</tt> or <tt>Database#call</tt> later with the values:
66
66
 
67
- ds = DB[:items].filter(:name=>:$n)
67
+ ds = DB[:items].where(:name=>:$n)
68
68
  ps = ds.prepare(:select, :select_by_name)
69
69
  ps.call(:n=>'Jim')
70
70
  DB.call(:select_by_name, :n=>'Jim') # same as above
@@ -76,7 +76,7 @@ and update queries, the hash to insert/update is passed to +prepare+:
76
76
  ps1 = DB[:items].prepare(:insert, :insert_with_name, :name=>:$n)
77
77
  ps1.call(:n=>'Jim')
78
78
  DB.call(:insert_with_name, :n=>'Jim') # same as above
79
- ds = DB[:items].filter(:name=>:$n)
79
+ ds = DB[:items].where(:name=>:$n)
80
80
  ps2 = ds.prepare(:update, :update_name, :name=>:$new_n)
81
81
  ps2.call(:n=>'Jim', :new_n=>'Bob')
82
82
  DB.call(:update_name, :n=>'Jim', :new_n=>'Bob') # same as above
@@ -0,0 +1,221 @@
1
+ = New Features
2
+
3
+ * There have been numerous improvements this release related to
4
+ frozen datasets. Frozen datasets now work in almost all cases,
5
+ except when calling a dataset mutation method.
6
+
7
+ When using ruby 2.4, Sequel uses the new support for
8
+ clone(:freeze=>false) to actually freeze datasets while allowing
9
+ them to copy singleton classes/extended modules from the dataset
10
+ calling clone. On earlier versions of ruby, the dataset opts
11
+ are now frozen, preventing more types of accidental modification.
12
+
13
+ The dataset internals were refactored to reduce the number of
14
+ instance variables. Now, datasets store all of their state
15
+ in opts. Additionally, all datasets now use a thread-safe
16
+ cache for storing cached state such as the dataset's columns.
17
+ Previously, accessing/setting the columns was not thread-safe,
18
+ unless the ruby interpreter used thread-safe methods for
19
+ instance variable getting/setting.
20
+
21
+ Frozen datasets use this new cache to optimize repeated method
22
+ calls, resulting in substantial performance speedups. This can
23
+ include caching returned and/or intermediate datasets, SELECT and
24
+ DELETE SQL generated, as well as internal objects designed to
25
+ optimize the building of SQL strings with different arguments.
26
+
27
+ Even for fairly simple datasets, this can result in up to 10x
28
+ performance improvements for dataset methods that don't require
29
+ database access, and up to 3x performance improvements for dataset
30
+ methods that do require database access.
31
+
32
+ * A freeze_datasets Database extension has been added which
33
+ automatically freezes all datasets for the Database instance.
34
+ This also enables dataset caching when creating datasets using
35
+ Database#[] and #from using a single symbol, such as
36
+ DB[:table_name]. In addition to speeding up the methods
37
+ themselves, this also allows code such as:
38
+
39
+ DB[:foo].for_update.first
40
+
41
+ To run much faster by avoiding any dataset creation or SQL
42
+ string building after the first call.
43
+
44
+ The freeze_datasets extension makes #dup an alias of #clone,
45
+ ensuring that all cloned datasets that were originally created
46
+ by the Database instance are frozen.
47
+
48
+ It is highly recommended that you start using the
49
+ freeze_datasets extension in your applications using Sequel,
50
+ as this extension will become the default and only behavior
51
+ in Sequel 5. Unfrozen datasets and dataset mutation will
52
+ not be supported in Sequel 5.
53
+
54
+ * The dataset methods created by Model#subset and
55
+ Model::DatasetModule#subset now cache the returned dataset if the
56
+ current dataset is frozen, none of the arguments are Procs, and a
57
+ block is not provided. This can result in up to a 3x performance
58
+ improvement for method chains that use subsets, such as:
59
+
60
+ ModelClass.subset1.subset2.subset3.first
61
+
62
+ * Model::DatasetModule has had the following methods added to it:
63
+ distinct, exclude, exclude_having, grep, group, group_and_count,
64
+ group_append, having, limit, offset, order, order_append,
65
+ order_prepend, select, select_all, select_append, select_group,
66
+ where, and server. These methods create dataset methods that
67
+ when called call the dataset method with the same name on the
68
+ receiver. Example:
69
+
70
+ class ModelClass < Sequel::Model
71
+ dataset_module do
72
+ select :with_id_and_name, :id, :name
73
+ where :active, :active
74
+ order :by_name, :name
75
+ end
76
+ end
77
+
78
+ ModelClass.active.by_name.with_id_and_name.all
79
+ # SELECT id, name FROM model_classes WHERE active ORDER BY name
80
+ # Equivalent to:
81
+ ModelClass.
82
+ where(:active).
83
+ order(:name).
84
+ select(:id, :name).
85
+ all
86
+
87
+ In addition to being easier than defining the methods manually, this
88
+ also enables caching of the datasets in most cases, so that the
89
+ above method chain does not create any additional datasets after the
90
+ first call.
91
+
92
+ * Dataset#with_extend now accepts a block and will create a module
93
+ with that block that will be used to extend the object, after any
94
+ modules given as arguments have been applied:
95
+
96
+ DB[:table].with_extend{def foo; 1 end}.foo => 1
97
+
98
+ * The identifier mangling support for datasets
99
+ (identifier_input_method and identifier_output_method) has been
100
+ moved to a identifier_mangling database extension, but it is still
101
+ loaded by default. You can disable the loading of this extension
102
+ by using the :identifier_mangling=>false Database option. Sequel
103
+ 5 will stop loading of this extension by default, requiring you to
104
+ load it manually via Database#extension if you need it.
105
+
106
+ Sequel's default remains the same as before, to convert identifiers
107
+ to uppercase on input and lowercase on output on databases that
108
+ fold unquoted identifiers to uppercase (per the SQL standard), and
109
+ to not mangle identifiers at all on databases that fold unquoted
110
+ identifiers to lowercase (MySQL, PostgreSQL, SQLite). The
111
+ identifier_mangling extension just allows you to change the default
112
+ behavior.
113
+
114
+ * On DB2, Dataset#with_convert_smallint_to_bool has been added,
115
+ which returns a modified dataset with the
116
+ convert_smallint_to_bool setting changed. Previously,
117
+ chaging the smallint_to_bool setting required mutating a
118
+ dataset.
119
+
120
+ * The mock adapter now supports Dataset#with_{autoid,fetch,numrows},
121
+ allowing mocking of results when using frozen datasets.
122
+
123
+ = Other Improvements
124
+
125
+ * Using an eager load callback when eager loading a one_to_one
126
+ association that uses an order or offset now works correctly
127
+ on databases that do not support window functions.
128
+
129
+ * Dataset#== and Dataset#hash are now faster as they don't need
130
+ to generate SQL. As all internal state is now stored in the
131
+ opts, it just considers the class, db, and opts.
132
+
133
+ * The prepared statement/bound variable internals were heavily
134
+ refactored to be simpler and more robust, to more easily
135
+ support native prepared statements, and to work with frozen
136
+ datasets.
137
+
138
+ * When emulating alter table operations on SQLite, integer
139
+ primary keys now use AUTOINCREMENT, since that is Sequel's
140
+ default when creating tables on SQLite.
141
+
142
+ * On SQLite, Database#schema no longer uses :auto_increment entries
143
+ when the table has a composite primary key.
144
+
145
+ * Most dataset opts values are now frozen to prevent accidental
146
+ modification and allow for thread-safe access.
147
+
148
+ * SQL::Expression subclass instances are now always frozen.
149
+
150
+ * Dataset::PlaceholderLiteralizer and
151
+ Dataset::PlaceholderLiteralizer::Argument instances are now
152
+ always frozen.
153
+
154
+ * Dataset#ungraphed now works on a frozen model dataset.
155
+
156
+ * Model#set_server now works when the model uses a frozen dataset.
157
+
158
+ * The pagination and null_dataset extensions now work on frozen
159
+ datasets.
160
+
161
+ * Dataset#server now works for frozen model datasets when the
162
+ model uses the sharding plugin.
163
+
164
+ * Calling eager_graph or association_join on a model dataset
165
+ is now deprecated if it would ignore the association's
166
+ :conditions option and the :graph_conditions, :graph_block,
167
+ or :graph_only_conditions association option is not used.
168
+
169
+ * Using the :eager_limit dataset option in an eager_load
170
+ callback with a singular association now raises an Error.
171
+ Previously, the behavior was undefined.
172
+
173
+ * Calling Dataset#prepare without a name argument is now
174
+ deprecated. Previously, it raised an Error in the mysql, mysql2,
175
+ and postgres adapters, but was allowed on other adapters.
176
+
177
+ * The looser_typecasting extension now handles the strict
178
+ BigDecimal parsing introduced in ruby 2.4.
179
+
180
+ * When using the duplicate_columns_handler extension with
181
+ :on_duplicate_columns=>:warn, the warning message is now
182
+ prepend with the file and line.
183
+
184
+ * Internally, Sequel uses Dataset#where instead of #filter,
185
+ reverse instead of reverse_order, and select_append instead
186
+ of select_more to save a method call and array creation.
187
+
188
+ * Dataset#db= and #opts= in the sequel_3_dataset_methods
189
+ extension now raise a RuntimeError if the dataset is frozen.
190
+
191
+ * Sequel's tests now run without warnings when using Minitest
192
+ 5.10.
193
+
194
+ * Sequel now issues a deprecation message instead of a warning
195
+ when used with PostgreSQL <8.2.
196
+
197
+ = Backwards Compatibility
198
+
199
+ * Any external dataset extensions or adapters that modified or
200
+ directly accessed dataset instance variables other than @db and
201
+ @opts (such as @columns) needs to be updated to work with the
202
+ new dataset internals.
203
+
204
+ * Any external adapters that implemented native prepared statements/
205
+ bound variables need to be updated to work with the new internal
206
+ prepared statement API.
207
+
208
+ * Model.set_dataset and .dataset= now operate on a clone of the
209
+ dataset given, instead of mutating the dataset that is passed in.
210
+ This allows them to work with frozen datasets, but can change
211
+ the behavior if you mutate a dataset after passing it to one
212
+ of these methods. Anyone doing that needs to change their code
213
+ to get the current copy of the model's dataset, and mutate that,
214
+ or better yet, avoid mutating datasets at all.
215
+
216
+ * Dataset#columns now calls #columns! instead of the other way around,
217
+ which may require external plugins/extensions that override #columns
218
+ to switch to overriding #columns!.
219
+
220
+ * External adapters that want to disable identifier mangling by
221
+ default need to be updated.