viking-sequel 3.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (237) hide show
  1. data/CHANGELOG +3134 -0
  2. data/COPYING +19 -0
  3. data/README.rdoc +723 -0
  4. data/Rakefile +193 -0
  5. data/bin/sequel +196 -0
  6. data/doc/advanced_associations.rdoc +644 -0
  7. data/doc/cheat_sheet.rdoc +218 -0
  8. data/doc/dataset_basics.rdoc +106 -0
  9. data/doc/dataset_filtering.rdoc +158 -0
  10. data/doc/opening_databases.rdoc +296 -0
  11. data/doc/prepared_statements.rdoc +104 -0
  12. data/doc/reflection.rdoc +84 -0
  13. data/doc/release_notes/1.0.txt +38 -0
  14. data/doc/release_notes/1.1.txt +143 -0
  15. data/doc/release_notes/1.3.txt +101 -0
  16. data/doc/release_notes/1.4.0.txt +53 -0
  17. data/doc/release_notes/1.5.0.txt +155 -0
  18. data/doc/release_notes/2.0.0.txt +298 -0
  19. data/doc/release_notes/2.1.0.txt +271 -0
  20. data/doc/release_notes/2.10.0.txt +328 -0
  21. data/doc/release_notes/2.11.0.txt +215 -0
  22. data/doc/release_notes/2.12.0.txt +534 -0
  23. data/doc/release_notes/2.2.0.txt +253 -0
  24. data/doc/release_notes/2.3.0.txt +88 -0
  25. data/doc/release_notes/2.4.0.txt +106 -0
  26. data/doc/release_notes/2.5.0.txt +137 -0
  27. data/doc/release_notes/2.6.0.txt +157 -0
  28. data/doc/release_notes/2.7.0.txt +166 -0
  29. data/doc/release_notes/2.8.0.txt +171 -0
  30. data/doc/release_notes/2.9.0.txt +97 -0
  31. data/doc/release_notes/3.0.0.txt +221 -0
  32. data/doc/release_notes/3.1.0.txt +406 -0
  33. data/doc/release_notes/3.10.0.txt +286 -0
  34. data/doc/release_notes/3.2.0.txt +268 -0
  35. data/doc/release_notes/3.3.0.txt +192 -0
  36. data/doc/release_notes/3.4.0.txt +325 -0
  37. data/doc/release_notes/3.5.0.txt +510 -0
  38. data/doc/release_notes/3.6.0.txt +366 -0
  39. data/doc/release_notes/3.7.0.txt +179 -0
  40. data/doc/release_notes/3.8.0.txt +151 -0
  41. data/doc/release_notes/3.9.0.txt +233 -0
  42. data/doc/schema.rdoc +36 -0
  43. data/doc/sharding.rdoc +113 -0
  44. data/doc/virtual_rows.rdoc +205 -0
  45. data/lib/sequel.rb +1 -0
  46. data/lib/sequel/adapters/ado.rb +90 -0
  47. data/lib/sequel/adapters/ado/mssql.rb +30 -0
  48. data/lib/sequel/adapters/amalgalite.rb +176 -0
  49. data/lib/sequel/adapters/db2.rb +139 -0
  50. data/lib/sequel/adapters/dbi.rb +113 -0
  51. data/lib/sequel/adapters/do.rb +188 -0
  52. data/lib/sequel/adapters/do/mysql.rb +49 -0
  53. data/lib/sequel/adapters/do/postgres.rb +91 -0
  54. data/lib/sequel/adapters/do/sqlite.rb +40 -0
  55. data/lib/sequel/adapters/firebird.rb +283 -0
  56. data/lib/sequel/adapters/informix.rb +77 -0
  57. data/lib/sequel/adapters/jdbc.rb +587 -0
  58. data/lib/sequel/adapters/jdbc/as400.rb +58 -0
  59. data/lib/sequel/adapters/jdbc/h2.rb +133 -0
  60. data/lib/sequel/adapters/jdbc/mssql.rb +57 -0
  61. data/lib/sequel/adapters/jdbc/mysql.rb +78 -0
  62. data/lib/sequel/adapters/jdbc/oracle.rb +50 -0
  63. data/lib/sequel/adapters/jdbc/postgresql.rb +108 -0
  64. data/lib/sequel/adapters/jdbc/sqlite.rb +55 -0
  65. data/lib/sequel/adapters/mysql.rb +421 -0
  66. data/lib/sequel/adapters/odbc.rb +143 -0
  67. data/lib/sequel/adapters/odbc/mssql.rb +42 -0
  68. data/lib/sequel/adapters/openbase.rb +64 -0
  69. data/lib/sequel/adapters/oracle.rb +131 -0
  70. data/lib/sequel/adapters/postgres.rb +504 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +490 -0
  72. data/lib/sequel/adapters/shared/mysql.rb +498 -0
  73. data/lib/sequel/adapters/shared/oracle.rb +195 -0
  74. data/lib/sequel/adapters/shared/postgres.rb +830 -0
  75. data/lib/sequel/adapters/shared/progress.rb +44 -0
  76. data/lib/sequel/adapters/shared/sqlite.rb +389 -0
  77. data/lib/sequel/adapters/sqlite.rb +224 -0
  78. data/lib/sequel/adapters/utils/stored_procedures.rb +84 -0
  79. data/lib/sequel/connection_pool.rb +99 -0
  80. data/lib/sequel/connection_pool/sharded_single.rb +84 -0
  81. data/lib/sequel/connection_pool/sharded_threaded.rb +211 -0
  82. data/lib/sequel/connection_pool/single.rb +29 -0
  83. data/lib/sequel/connection_pool/threaded.rb +150 -0
  84. data/lib/sequel/core.rb +293 -0
  85. data/lib/sequel/core_sql.rb +241 -0
  86. data/lib/sequel/database.rb +1079 -0
  87. data/lib/sequel/database/schema_generator.rb +327 -0
  88. data/lib/sequel/database/schema_methods.rb +203 -0
  89. data/lib/sequel/database/schema_sql.rb +320 -0
  90. data/lib/sequel/dataset.rb +32 -0
  91. data/lib/sequel/dataset/actions.rb +441 -0
  92. data/lib/sequel/dataset/features.rb +86 -0
  93. data/lib/sequel/dataset/graph.rb +254 -0
  94. data/lib/sequel/dataset/misc.rb +119 -0
  95. data/lib/sequel/dataset/mutation.rb +64 -0
  96. data/lib/sequel/dataset/prepared_statements.rb +227 -0
  97. data/lib/sequel/dataset/query.rb +709 -0
  98. data/lib/sequel/dataset/sql.rb +996 -0
  99. data/lib/sequel/exceptions.rb +51 -0
  100. data/lib/sequel/extensions/blank.rb +43 -0
  101. data/lib/sequel/extensions/inflector.rb +242 -0
  102. data/lib/sequel/extensions/looser_typecasting.rb +21 -0
  103. data/lib/sequel/extensions/migration.rb +239 -0
  104. data/lib/sequel/extensions/named_timezones.rb +61 -0
  105. data/lib/sequel/extensions/pagination.rb +100 -0
  106. data/lib/sequel/extensions/pretty_table.rb +82 -0
  107. data/lib/sequel/extensions/query.rb +52 -0
  108. data/lib/sequel/extensions/schema_dumper.rb +271 -0
  109. data/lib/sequel/extensions/sql_expr.rb +122 -0
  110. data/lib/sequel/extensions/string_date_time.rb +46 -0
  111. data/lib/sequel/extensions/thread_local_timezones.rb +48 -0
  112. data/lib/sequel/metaprogramming.rb +9 -0
  113. data/lib/sequel/model.rb +120 -0
  114. data/lib/sequel/model/associations.rb +1514 -0
  115. data/lib/sequel/model/base.rb +1069 -0
  116. data/lib/sequel/model/default_inflections.rb +45 -0
  117. data/lib/sequel/model/errors.rb +39 -0
  118. data/lib/sequel/model/exceptions.rb +21 -0
  119. data/lib/sequel/model/inflections.rb +162 -0
  120. data/lib/sequel/model/plugins.rb +70 -0
  121. data/lib/sequel/plugins/active_model.rb +59 -0
  122. data/lib/sequel/plugins/association_dependencies.rb +103 -0
  123. data/lib/sequel/plugins/association_proxies.rb +41 -0
  124. data/lib/sequel/plugins/boolean_readers.rb +53 -0
  125. data/lib/sequel/plugins/caching.rb +141 -0
  126. data/lib/sequel/plugins/class_table_inheritance.rb +214 -0
  127. data/lib/sequel/plugins/composition.rb +138 -0
  128. data/lib/sequel/plugins/force_encoding.rb +72 -0
  129. data/lib/sequel/plugins/hook_class_methods.rb +126 -0
  130. data/lib/sequel/plugins/identity_map.rb +116 -0
  131. data/lib/sequel/plugins/instance_filters.rb +98 -0
  132. data/lib/sequel/plugins/instance_hooks.rb +57 -0
  133. data/lib/sequel/plugins/lazy_attributes.rb +77 -0
  134. data/lib/sequel/plugins/many_through_many.rb +208 -0
  135. data/lib/sequel/plugins/nested_attributes.rb +206 -0
  136. data/lib/sequel/plugins/optimistic_locking.rb +81 -0
  137. data/lib/sequel/plugins/rcte_tree.rb +281 -0
  138. data/lib/sequel/plugins/schema.rb +66 -0
  139. data/lib/sequel/plugins/serialization.rb +166 -0
  140. data/lib/sequel/plugins/single_table_inheritance.rb +74 -0
  141. data/lib/sequel/plugins/subclasses.rb +45 -0
  142. data/lib/sequel/plugins/tactical_eager_loading.rb +61 -0
  143. data/lib/sequel/plugins/timestamps.rb +87 -0
  144. data/lib/sequel/plugins/touch.rb +118 -0
  145. data/lib/sequel/plugins/typecast_on_load.rb +72 -0
  146. data/lib/sequel/plugins/validation_class_methods.rb +405 -0
  147. data/lib/sequel/plugins/validation_helpers.rb +223 -0
  148. data/lib/sequel/sql.rb +1020 -0
  149. data/lib/sequel/timezones.rb +161 -0
  150. data/lib/sequel/version.rb +12 -0
  151. data/lib/sequel_core.rb +1 -0
  152. data/lib/sequel_model.rb +1 -0
  153. data/spec/adapters/firebird_spec.rb +407 -0
  154. data/spec/adapters/informix_spec.rb +97 -0
  155. data/spec/adapters/mssql_spec.rb +403 -0
  156. data/spec/adapters/mysql_spec.rb +1019 -0
  157. data/spec/adapters/oracle_spec.rb +286 -0
  158. data/spec/adapters/postgres_spec.rb +969 -0
  159. data/spec/adapters/spec_helper.rb +51 -0
  160. data/spec/adapters/sqlite_spec.rb +432 -0
  161. data/spec/core/connection_pool_spec.rb +808 -0
  162. data/spec/core/core_sql_spec.rb +417 -0
  163. data/spec/core/database_spec.rb +1662 -0
  164. data/spec/core/dataset_spec.rb +3827 -0
  165. data/spec/core/expression_filters_spec.rb +595 -0
  166. data/spec/core/object_graph_spec.rb +296 -0
  167. data/spec/core/schema_generator_spec.rb +159 -0
  168. data/spec/core/schema_spec.rb +830 -0
  169. data/spec/core/spec_helper.rb +56 -0
  170. data/spec/core/version_spec.rb +7 -0
  171. data/spec/extensions/active_model_spec.rb +76 -0
  172. data/spec/extensions/association_dependencies_spec.rb +127 -0
  173. data/spec/extensions/association_proxies_spec.rb +50 -0
  174. data/spec/extensions/blank_spec.rb +67 -0
  175. data/spec/extensions/boolean_readers_spec.rb +92 -0
  176. data/spec/extensions/caching_spec.rb +250 -0
  177. data/spec/extensions/class_table_inheritance_spec.rb +252 -0
  178. data/spec/extensions/composition_spec.rb +194 -0
  179. data/spec/extensions/force_encoding_spec.rb +117 -0
  180. data/spec/extensions/hook_class_methods_spec.rb +470 -0
  181. data/spec/extensions/identity_map_spec.rb +202 -0
  182. data/spec/extensions/inflector_spec.rb +181 -0
  183. data/spec/extensions/instance_filters_spec.rb +55 -0
  184. data/spec/extensions/instance_hooks_spec.rb +133 -0
  185. data/spec/extensions/lazy_attributes_spec.rb +153 -0
  186. data/spec/extensions/looser_typecasting_spec.rb +39 -0
  187. data/spec/extensions/many_through_many_spec.rb +884 -0
  188. data/spec/extensions/migration_spec.rb +332 -0
  189. data/spec/extensions/named_timezones_spec.rb +72 -0
  190. data/spec/extensions/nested_attributes_spec.rb +396 -0
  191. data/spec/extensions/optimistic_locking_spec.rb +100 -0
  192. data/spec/extensions/pagination_spec.rb +99 -0
  193. data/spec/extensions/pretty_table_spec.rb +91 -0
  194. data/spec/extensions/query_spec.rb +85 -0
  195. data/spec/extensions/rcte_tree_spec.rb +205 -0
  196. data/spec/extensions/schema_dumper_spec.rb +357 -0
  197. data/spec/extensions/schema_spec.rb +127 -0
  198. data/spec/extensions/serialization_spec.rb +209 -0
  199. data/spec/extensions/single_table_inheritance_spec.rb +96 -0
  200. data/spec/extensions/spec_helper.rb +91 -0
  201. data/spec/extensions/sql_expr_spec.rb +89 -0
  202. data/spec/extensions/string_date_time_spec.rb +93 -0
  203. data/spec/extensions/subclasses_spec.rb +52 -0
  204. data/spec/extensions/tactical_eager_loading_spec.rb +65 -0
  205. data/spec/extensions/thread_local_timezones_spec.rb +45 -0
  206. data/spec/extensions/timestamps_spec.rb +150 -0
  207. data/spec/extensions/touch_spec.rb +155 -0
  208. data/spec/extensions/typecast_on_load_spec.rb +69 -0
  209. data/spec/extensions/validation_class_methods_spec.rb +984 -0
  210. data/spec/extensions/validation_helpers_spec.rb +438 -0
  211. data/spec/integration/associations_test.rb +281 -0
  212. data/spec/integration/database_test.rb +26 -0
  213. data/spec/integration/dataset_test.rb +963 -0
  214. data/spec/integration/eager_loader_test.rb +734 -0
  215. data/spec/integration/model_test.rb +130 -0
  216. data/spec/integration/plugin_test.rb +814 -0
  217. data/spec/integration/prepared_statement_test.rb +213 -0
  218. data/spec/integration/schema_test.rb +361 -0
  219. data/spec/integration/spec_helper.rb +73 -0
  220. data/spec/integration/timezone_test.rb +55 -0
  221. data/spec/integration/transaction_test.rb +122 -0
  222. data/spec/integration/type_test.rb +96 -0
  223. data/spec/model/association_reflection_spec.rb +175 -0
  224. data/spec/model/associations_spec.rb +2633 -0
  225. data/spec/model/base_spec.rb +418 -0
  226. data/spec/model/dataset_methods_spec.rb +78 -0
  227. data/spec/model/eager_loading_spec.rb +1391 -0
  228. data/spec/model/hooks_spec.rb +240 -0
  229. data/spec/model/inflector_spec.rb +26 -0
  230. data/spec/model/model_spec.rb +593 -0
  231. data/spec/model/plugins_spec.rb +236 -0
  232. data/spec/model/record_spec.rb +1500 -0
  233. data/spec/model/spec_helper.rb +97 -0
  234. data/spec/model/validations_spec.rb +153 -0
  235. data/spec/rcov.opts +6 -0
  236. data/spec/spec_config.rb.example +10 -0
  237. metadata +346 -0
@@ -0,0 +1,298 @@
1
+ Blockless Filter Expressions
2
+ ----------------------------
3
+
4
+ Before 2.0.0, in order to specify complex SQL expressions, you
5
+ either had to resort to writing the SQL yourself in a string or
6
+ using an expression inside a block that was parsed by ParseTree.
7
+ Because ParseTree was required, only ruby 1.8.* was supported, and
8
+ supporting other ruby versions (ruby 1.9, JRuby, Rubinius) would
9
+ never be possible.
10
+
11
+ With 2.0.0, you no longer need to use a block to write complex SQL
12
+ expressions. The basics of the blockless filters are the usual
13
+ arithmetic, inequality, and binary operators:
14
+
15
+ + = addition
16
+ - = subtraction
17
+ * = multiplication
18
+ / = division
19
+ > = greater than
20
+ < = less than
21
+ >= = greater than or equal to
22
+ <= = less than or equal to
23
+ ~ = negation
24
+ & = AND
25
+ | = OR
26
+
27
+ You can use these operators on Symbols, LiteralStrings, and other
28
+ Sequel::SQL::Expressions. Note that there is no equal operator or
29
+ not equal operator, to specify those, you use a Hash.
30
+
31
+ Here are some examples:
32
+
33
+ # Ruby code => SQL WHERE clause
34
+ :active => active
35
+ ~:active => NOT active
36
+ ~~:active => active
37
+ ~~~:active => NOT active
38
+ :is_true[] => is_true()
39
+ ~:is_true[] => NOT is_true()
40
+ :x > 100 => (x > 100)
41
+ :x < 100.01 => (x < 100.01)
42
+ :x <= 0 => (x <= 0)
43
+ :x >= 1 => (x >= 1)
44
+ ~(:x > 100) => (x <= 100)
45
+ {:x => 100} => (x = 100)
46
+ {:x => 'a'} => (x = 'a')
47
+ {:x => nil} => (x IS NULL)
48
+ ~{:x => 100} => (x != 100)
49
+ ~{:x => 'a'} => (x != 'a')
50
+ ~{:x => nil} => (x IS NOT NULL)
51
+ {:x => /a/} => (x ~ 'blah') # Default, MySQL different
52
+ ~{:x => /a/} => (x !~ 'blah') # Default, MySQL different
53
+ :x.like('a') => (x LIKE 'a')
54
+ ~:x.like('a') => (x NOT LIKE 'a')
55
+ :x.like(/a/) => (x ~ 'a') # Default, MySQL different
56
+ ~:x.like('a', /b/) => ((x NOT LIKE 'a') AND (x !~ 'b')) # Default
57
+ ~{:x => 1..5} => ((x < 1) OR (x > 5))
58
+ ~{:x => DB[:items].select(:i)} => (x NOT IN (SELECT i FROM items))
59
+ ~{:x => [1,2,3]} => (x NOT IN (1, 2, 3))
60
+ :x + 1 > 100 => ((x + 1) > 100)
61
+ (:x * :y) < 100.01 => ((x * y) < 100.01)
62
+ (:x - :y/2) >= 100 => ((x - (y / 2)) >= 100)
63
+ (((:x - :y)/(:x + :y))*:z) <= 100 => ((((x - y) / (x + y)) * z) <=
64
+ 100)
65
+ ~((((:x - :y)/(:x + :y))*:z) <= 100) => ((((x - y) / (x + y)) * z) >
66
+ 100)
67
+ :x & :y => (x AND y)
68
+ :x & :y & :z => ((x AND y) AND z)
69
+ :x & {:y => :z} => (x AND (y = z))
70
+ {:y => :z} & :x => ((y = z) AND x)
71
+ {:x => :a} & {:y => :z} => ((x = a) AND (y = z))
72
+ (:x > 200) & (:y < 200) => ((x > 200) AND (y < 200))
73
+ :x | :y => (x OR y)
74
+ :x | :y | :z => ((x OR y) OR z)
75
+ :x | {:y => :z} => (x OR (y = z))
76
+ {:y => :z} | :x => ((y = z) OR x)
77
+ {:x => :a} | {:y => :z} => ((x = a) OR (y = z))
78
+ (:x > 200) | (:y < 200) => ((x > 200) OR (y < 200))
79
+ (:x | :y) & :z => ((x OR y) AND z)
80
+ :x | (:y & :z) => (x OR (y AND z))
81
+ (:x & :w) | (:y & :z) => ((x AND w) OR (y AND z))
82
+ ~((:x | :y) & :z) => ((NOT x AND NOT y) OR NOT z)
83
+ ~((:x & :w) | (:y & :z)) => ((NOT x OR NOT w) AND (NOT y OR NOT z))
84
+ ~((:x > 200) | (:y & :z)) => ((x <= 200) AND (NOT y OR NOT z))
85
+ ~('x'.lit + 1 > 100) => ((x + 1) <= 100)
86
+ 'x'.lit.like(/a/) => (x ~ 'a') # (x ~ \'a\')
87
+
88
+ None of these require blocks, you can use any directly in a call to
89
+ filter:
90
+
91
+ DB[:items].filter((:price * :tax) - :discount > 100)
92
+ # => SELECT * FROM items WHERE (((price * tax) - discount) > 100)
93
+ DB[:items].filter(:active & ~:archived)
94
+ # => SELECT * FROM items WHERE (active AND NOT archived)
95
+
96
+ SQL String Concatenation
97
+ ------------------------
98
+
99
+ Sequel now has support for expressing SQL string concatenation in an
100
+ easy way:
101
+
102
+ [:name, :title].sql_string_join(" - ")
103
+ # SQL: name || ' - ' || title
104
+
105
+ You can use this in selecting columns, creating filters, ordering
106
+ datasets, and possibly elsewhere.
107
+
108
+ Schema Reflection Support/Typecasting on Assignment
109
+ ---------------------------------------------------
110
+
111
+ When used with PostgreSQL, MySQL, or SQLite, Sequel now has the
112
+ ability to get information from the database's schema in regards
113
+ to column types:
114
+
115
+ DB.schema(:artist)
116
+ => [[:id, {:type=>:integer, :db_type=>"integer", :max_chars=>0
117
+ :numeric_precision=>32, :allow_null=>false,
118
+ :default=>"nextval('artist_id_seq'::regclass)"}], [:name,
119
+ {:type=>:string, :default=>nil, :db_type=>"text",
120
+ :numeric_precision=>0, :allow_null=>true, :max_chars=>0}]]
121
+
122
+ Models now use this information to typecast values on attribute
123
+ assignment. For example, if you have an integer column named number
124
+ and a text (e.g. varchar) column named title:
125
+
126
+ 1.5.1:
127
+ model.number = '1'
128
+ model.number # => '1'
129
+ model.title = 1
130
+ model.title # => 1
131
+ 2.0.0:
132
+ model.number = '1'
133
+ model.number # => 1
134
+ model.title = 1
135
+ model.title # => '1'
136
+
137
+ Typecasting can be turned off on a global, per class, and per object
138
+ basis:
139
+
140
+ Sequel::Model.typecast_on_assignment = false # Global
141
+ Album.typecast_on_assignment = false # Per Class
142
+ Album.new.typecast_on_assignment = false # Per Object
143
+
144
+ Typecasting is somewhat strict, it does not allow obviously bogus
145
+ data to be used:
146
+
147
+ model.number = 'a' # Raises error
148
+
149
+ This is in contrast to how some other ORMs handle the situation:
150
+
151
+ model.number = 'a'
152
+ model.number # => 0
153
+
154
+ If Sequel is being used with a web framework and you want to display
155
+ friendly error messages to the user, you should probably turn
156
+ typecasting off and set up the necessary validations in your models.
157
+
158
+ Model Association Improvements
159
+ ------------------------------
160
+
161
+ Associations can now be eagerly loaded even if they have a block,
162
+ though the block should not rely on being evaluated in the context
163
+ of an instance. This allows you filter on associations when eagerly
164
+ loading:
165
+
166
+ Artist.one_to_many :albums_with_10_tracks, :class=>:Album do |ds|
167
+ ds.filter(:num_tracks => 10)
168
+ end
169
+ Artist.filter(:name.like('A%)).eager(:albums_with_10_tracks).all
170
+ # SELECT * FROM artists WHERE (name LIKE 'A%')
171
+ # SELECT albums.* FROM albums WHERE ((artist_id IN (...)) AND
172
+ # (num_tracks = 10))
173
+
174
+ Associations now have a remove_all_ method for removing all
175
+ associated objects in a single query:
176
+
177
+ Artist.many_to_many :albums
178
+ Artist[1].remove_all_albums
179
+ # DELETE FROM albums_artists WHERE artist_id = 1
180
+
181
+ Artist.one_to_many :albums
182
+ Artist[1].remove_all_albums
183
+ # UPDATE albums SET artist_id = NULL WHERE artist_id = 1
184
+
185
+ All associations can specify a :select option to change which columns
186
+ are selected. Previously only many to many associations suppported
187
+ this.
188
+
189
+ The SQL used when eagerly loading through eager_graph can be
190
+ modified via the :graph_join_type, :graph_conditions, and
191
+ :graph_join_conditions options.
192
+
193
+ :graph_join_type changes the join type from the default of
194
+ :left_outer. This can be useful if you do not want any
195
+ albums that don't have an artist in the result set:
196
+
197
+ Album.many_to_one :artist, :graph_join_type=>:inner
198
+ Album.eager_graph(:artist).sql
199
+ # SELECT ... FROM albums INNER JOIN artists ...
200
+
201
+ :graph_conditions adds conditions on the join to the table you are
202
+ joining, the eager_graph equivalent of an association block argument
203
+ in eager. It takes either a hash or an array where all elements
204
+ are arrays of length two, similar to join_table, where key symbols
205
+ specify columns in the joined table and value symbols specify
206
+ columns in the last joined or primary table:
207
+
208
+ Album.many_to_one :artist, :graph_conditions=>{:active=>true}
209
+ Album.eager_graph(:artist).sql
210
+ # SELECT ... FROM albums LEFT OUTER JOIN artists ON ((artists.id =
211
+ # albums.artist_id) AND (artists.active = 't'))
212
+
213
+ :graph_join_table_conditions exists for many to many associations only,
214
+ and operates the same as :graph_conditions, except it specifies a
215
+ condition on the many to many join table instead of the associated
216
+ model's table. This is necessary if the join table is also model
217
+ table with other columns on which you may want to filter:
218
+
219
+ Album.many_to_many :genres, :join_table=>:ag, \
220
+ :graph_join_table_conditions=>{:active=>true}
221
+ Album.eager_graph(:genres).sql
222
+ # SELECT ... FROM albums LEFT OUTER JOIN ag ON ((ag.album_id =
223
+ albums.id) AND (ag.active = 't')) LEFT OUTER JOIN genres ON
224
+ (genres.id = ag.genre_id)
225
+
226
+ Other Small Improvements
227
+ ------------------------
228
+
229
+ * Dataset#invert returns a dataset that matches all records not
230
+ matching the current filter.
231
+ * Dataset#unfiltered returns a dataset that has any filters removed.
232
+ * Dataset#last_page? and Dataset#first_page? for paginated datasets.
233
+ * The sequel command line tool now support an -E or --echo argument
234
+ that logs all SQL to the standard output. It also can take a path
235
+ to a yaml file with database connection options, in addition to a
236
+ database URL.
237
+ * Databases can now have multiple SQL loggers, so you can log to the
238
+ standard output as well as a file.
239
+ * SQL identifiers (columns and tables) are now quoted by default (you
240
+ can turn this off via Sequel.quote_identifiers = false if need be).
241
+ * Sequel.connect now takes an optional block that will disconnect the
242
+ database when the block finishes.
243
+ * AlterTableGenerator now has add_primary_key and add_foreign_key
244
+ methods.
245
+ * Running the specs without ParseTree installed skips the specs that
246
+ require ParseTree.
247
+ * You can use an array of arrays instead of a hash when specifying
248
+ conditions, which may be necessary in certain situations where
249
+ you would be using the same hash key more than once.
250
+ * Almost all documentation for Sequel was updated for 2.0.0, so if you
251
+ found Sequel documentation lacking before, check out the new RDoc
252
+ pages.
253
+ * There have been many minor refactoring improvements, the code
254
+ should now be easier to read and follow.
255
+ * Sequel now has no external dependencies.
256
+ * Sequel::Models now have before_validation and after_validation
257
+ hooks.
258
+ * Sequel::Model hooks that return false cause the methods that call
259
+ them (such as save) to return false.
260
+ * Sequel::Models can now load their schema on first instantiation,
261
+ instead of when they are created, via
262
+ Sequel::Model.lazy_load_schema=. This is helpful for certain
263
+ web frameworks that reload all models on every request.
264
+ * Hook methods that use blocks can now include an optional tag,
265
+ which allows them to work well with web frameworks that load source
266
+ files every time they are modified.
267
+
268
+ The PostgreSQL adapter has been rewritten and now supports ruby-pg.
269
+ There have also been improvements in the following adapters: DBI,
270
+ MySQL, SQLite, Oracle, and MSSQL.
271
+
272
+ All of the methods that have been deprecated in 1.5.0 have now been
273
+ removed. If you are want to upgrade to Sequel 2.0.0 from version 1.4.0
274
+ or previous, upgrade to 1.5.1 first, fix all of the deprecation
275
+ warnings that show up, and then upgrade to 2.0.0.
276
+
277
+ There were some backwards incompatible changes made in 2.0.0 beyond the
278
+ removal of deprecated methods. These are:
279
+
280
+ * Inflector is no longer used, the inflection methods were moved
281
+ directly into String (where they belong because inflections only
282
+ make sense for strings). So to override singularization
283
+ or pluralization rules, use String.inflections instead of
284
+ Inflector.inflections.
285
+ * MySQL tinyints are now returned as boolean values instead of
286
+ integers. MySQL doesn't have a boolean type, and usually it
287
+ is recommended to use tinyint for a boolean column.
288
+ * You can no longer pass an array to Dataset#order or Dataset#select,
289
+ you need to pass each argument separately (the * operator is your
290
+ friend).
291
+ * You must use '?' instead of '(?)' when interpolating an array
292
+ argument into a string (e.g. filter('x IN ?', [1,2,3]))
293
+ * You must pass an explicit table alias argument to join_table and
294
+ related methods, you can no longer include the table alias
295
+ inside the table argument.
296
+ * sqlite:// URLs now operate the same as file:// URLs (2 slashes
297
+ for a relative path, 3 for an absolute path).
298
+
@@ -0,0 +1,271 @@
1
+ Model Improvements
2
+ ------------------
3
+
4
+ * one_to_many/many_to_many associations now support a :limit option,
5
+ adding a limit/offset to the records returned. This was possible
6
+ before using a block, so it is just added for convenience.
7
+
8
+ * Associations now support a :read_only option, which doesn't create
9
+ methods that modify the database.
10
+
11
+ * Associations now support a :graph_select option, which allows
12
+ specifying the columns of associated models to include when using
13
+ eager_graph.
14
+
15
+ * one_to_many associations now have a :one_to_one option. When used
16
+ it creates a getter and setter method similar to many_to_one. This
17
+ fills the same role as ActiveRecord's has_one, but it is
18
+ implemented as a couple of convenience methods over one_to_many, so
19
+ it still requires that you specify the association name as a
20
+ plural.
21
+
22
+ * Model datasets now have to_hash augmented so that it can be called
23
+ without any arguments, in which case it yields an identity map (a
24
+ hash with keys being primary key values and values being model
25
+ instances).
26
+
27
+ * The Model.set_sti_key method was added, for easily setting up
28
+ single table inheritance. It should be called only in the parent
29
+ class.
30
+
31
+ * Calls to def_dataset_method with a block are now cached and
32
+ reapplied to the new dataset if set_dataset is called afterward,
33
+ or in a subclass.
34
+
35
+ * All validation methods can now be made conditional via an :if
36
+ option, which takes either a symbol (which specifies an instance
37
+ method) or a proc (which is instance_evaled).
38
+
39
+ * Model#set and Model#update have been added back, they are now
40
+ aliases of #set_with_params and #update_with_params.
41
+
42
+ * Models now have set_only/set_except/update_only/update_except
43
+ instance methods that take a hash (like you would provide to
44
+ set or update) and additional arguments specifying which columns
45
+ to allow or disallow.
46
+
47
+ * Models now have a set_allowed_columns and set_restricted_columns
48
+ methods, which operate similarly to ActiveRecord's attr_accessible
49
+ and attr_protected. It is recommend that you use the set_only or
50
+ update_only instead of these methods, though. You can ignore the
51
+ allowed or restricted columns by using #set_all or #update_all.
52
+
53
+ * The primary key column(s) is restricted by default. To allow it to
54
+ be set via new/set/update, use:
55
+
56
+ Sequel::Model.unrestrict_primary_key # Global
57
+ Artist.unrestrict_primary_key # Per Class
58
+
59
+ * It is now easy to override the one_to_many/many_to_many association
60
+ methods that modify the database (add_/remove_/remove_all_), as
61
+ they have been broken into two methods, one that handles the
62
+ caching features and a private one (prepended with an _) that
63
+ handles the database changes (and which you can easily override
64
+ without worrying about the caching).
65
+
66
+ Table Joining
67
+ -------------
68
+
69
+ Dataset#join_table got a nice overhaul. You can now use any join
70
+ type your database allows:
71
+
72
+ DB[:artist].join_table(:natural, :albums)
73
+ DB[:numbers].join_table(:cross, :numbers)
74
+
75
+ You can now specify the conditions as
76
+
77
+ * String: "a.b = c.d" # ON a.b = c.d
78
+ * Expression :x < :y # ON x < y
79
+ * Array of Symbols: [:x, :y, :z] # USING (x, y, z)
80
+ * nil # no conditions, used for NATURAL or CROSS joins
81
+
82
+ Dataset#join_table also takes a block that yields three arguments:
83
+
84
+ * join_table_alias - The alias/name of the table currently being
85
+ joined
86
+ * last_join_table_alias - The alias name of the last table joined
87
+ (if there was one) or the first FROM table (if not).
88
+ * joins - An array of JoinClause objects for all previous joins in
89
+ the query.
90
+
91
+ Using the block you can specify conditions for complex joins without
92
+ needing to know in advance what table aliases will be used.
93
+
94
+ Expanded SQL Syntax Support
95
+ ---------------------------
96
+
97
+ SQL Case statements are now supported directly using hashes or
98
+ arrays:
99
+
100
+ {:x > 1 => 1}.case(0)
101
+ # CASE WHEN x > 1 THEN 1 ELSE 0 END
102
+ [[{:x=>1}, 0], [:x < 1, 1], [:x > 1, 2]].case(-1)
103
+ # CASE WHEN x = 1 THEN 0 WHEN x < 1 THEN 1 WHEN x > 1 THEN 2
104
+ ELSE -1 END
105
+
106
+ You should use an array instead of a hash for multiple conditions
107
+ unless all conditions are orthogonal.
108
+
109
+ The SQL extract function has special syntax:
110
+
111
+ EXTRACT(day FROM date)
112
+
113
+ This syntax is now supported via the following ruby code:
114
+
115
+ :date.extract(:day)
116
+
117
+ Other Notable Changes
118
+ ---------------------
119
+
120
+ * The sequel command line tool can now run migrations. The -m
121
+ option specifies the directory holding the migration files,
122
+ and the -M options specifies the version to which to migrate.
123
+
124
+ * The PostgreSQL adapter supports nested transactions/savepoints.
125
+
126
+ * The schema parser now understands decimal fields, and will
127
+ typecast to BigDecimal.
128
+
129
+ * PostgreSQL's numeric type is now recognized and returned as
130
+ BigDecimal.
131
+
132
+ * HAVING now comes before ORDER BY, which most databases seem to
133
+ prefer. If your database wants HAVING after ORDER BY, please
134
+ let us know.
135
+
136
+ * Symbol#qualify now exists, to specify the table name for a given
137
+ symbol, similar to the use of #as to specify an alias. This is
138
+ mainly helpful in conjuction with the #join_table block, as that
139
+ provides the table aliases to use to qualify the columns inside
140
+ the block.
141
+
142
+ * BitwiseMethods (&, |, ^, ~, <<, >>) have been added to the
143
+ NumericExpression class, so you can do the following:
144
+
145
+ (x + 1) ^ 10 # SQL: (x + 1) ^ 10
146
+ ~(x + 1) # SQL: ~(x + 1)
147
+
148
+ Usually, &, |, and ~ operate in a logical manner, but for
149
+ NumericExpressions, they take on their usual bitwise meaning,
150
+ since logical operations only make sense for booleans.
151
+
152
+ * #cast_numeric and #cast_string exist for Symbols, Strings, and
153
+ other Sequel Expressions, which return the results casted and
154
+ wrapped in either NumericExpression or StringExpression, so you
155
+ can use the BitwiseMethods (&, |, ^, ~, <<, >>) or
156
+ StringConcatenationMethods (+) directly.
157
+
158
+ # Dataset#to_hash can take only one argument, in which case it uses
159
+ that argument to specify the key, and uses the entire hash for the
160
+ value.
161
+
162
+ # Dataset#graph can now take an array of columns to select from the
163
+ joined table via the :select option.
164
+
165
+ # Dataset#filter and similar methods now combine the block and
166
+ regular argument conditions if both are given, instead of ignoring
167
+ the regular argument conditions.
168
+
169
+ # Dataset#filter(false) can now be used to make sure that no records
170
+ are returned. Dataset#filter(true) also works, but it's a no-op.
171
+ Before, these raised errors.
172
+
173
+ # Dataset#count does a subquery for a dataset using DISTINCT, since
174
+ the otherwise it would yield a count for the query without
175
+ DISTINCT.
176
+
177
+ ParseTree Support Officially Deprecated
178
+ ---------------------------------------
179
+
180
+ The support for ParseTree-based block filters has officially been
181
+ deprecated and will be removed in Sequel 2.2. To use the
182
+ expression filters (which don't require ParseTree) inside blocks,
183
+ use:
184
+
185
+ SEQUEL_NO_PARSE_TREE = true
186
+ require 'sequel'
187
+ # OR
188
+ require 'sequel'
189
+ Sequel.use_parse_tree = false
190
+
191
+ This is the default if ParseTree cannot be loaded. If ParseTree
192
+ can be loaded, it remains the default, in order not to immediately
193
+ break existing code.
194
+
195
+ With this set, you can use the expression filters inside of blocks:
196
+
197
+ dataset.filter{((:x + 1) & 10 < :y) & :z}
198
+
199
+ That doesn't gain you all that much, but there are some methods
200
+ that feed block arguments into filter, such as the following:
201
+
202
+ dataset.first(5){((:x + 1) & 10 < :y) & :z}
203
+
204
+ Which will get you the first 5 records matching the condition.
205
+
206
+ Backwards Incompatible Changes
207
+ ------------------------------
208
+
209
+ * To change the datetime classe used from Time to DateTime, you
210
+ now use:
211
+
212
+ Sequel.datetime_class = DateTime # instead of Sequel.time_class
213
+
214
+ * Models now raise errors if you try to access a missing or
215
+ restricted method via new/set/update, instead of just silently
216
+ skipping that parameter. To get the old behavior:
217
+
218
+ Sequel::Model.strict_param_setting = false
219
+
220
+ * The association_dataset method now takes into account the :eager
221
+ option and the block argument, where it didn't before. It also
222
+ takes into account the new :limit option.
223
+
224
+ * Association methods now raise errors in most cases if the model
225
+ doesn't have a valid primary key.
226
+
227
+ * Dataset#join_table used to allow a symbol as a conditions argument
228
+ as a shortcut for a hash:
229
+
230
+ DB[:artist].join(:albums, :artist_id)
231
+ # ON albums.artist_id = artists.id
232
+
233
+ With the changes to #join_table, this no longer works. It would
234
+ now be interpreted as a boolean column:
235
+
236
+ DB[:artist].join(:albums, :artist_id)
237
+ # ON artists.id
238
+
239
+ Use the following slightly longer version for the old behavior:
240
+
241
+ DB[:artist].join(:albums, :artist_id=>:id)
242
+ # ON albums.artist_id = artists.id
243
+
244
+ * MySQL users need to be careful when upgrading, the following code
245
+ will once again cause an error:
246
+
247
+ DB[:artists].each{|artist| DB[:albums].each{|album| ...}}
248
+
249
+ To fix it, change the code to:
250
+
251
+ DB[:artists].all{|artist| DB[:albums].each{|album| ...}}
252
+
253
+ The issue is the MySQL adapter doesn't release the database
254
+ connection while running each, and the second call to each gets the
255
+ same database connection (while the other query is still running),
256
+ because it is in the same thread. Using #all for the outside query
257
+ ensures that the database connection is released before the block is
258
+ called.
259
+
260
+ The reason for this change was that the workaround provided for
261
+ MySQL could potentially cause issues with transactions for all
262
+ adapters.
263
+
264
+ * String#asc and String#desc are no longer defined, as ordering on a
265
+ plain string column should be a no-op. They are still defined
266
+ on LiteralStrings.
267
+
268
+ * You can no longer abuse the SQL::Function syntax to use a table
269
+ alias with specified columns (e.g. :table[:col1, :col2, :col3])
270
+ or to cast to types (e.g. :x.cast_as(:varchar[20])). Use a
271
+ LiteralString in both cases.