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,510 @@
1
+ New Plugins
2
+ -----------
3
+
4
+ * A class_table_inheritance plugin has been added, supporting model
5
+ inheritance in the database using a table-per-model-class approach.
6
+ Each table stores only attributes unique to that model or subclass
7
+ hierarchy.
8
+
9
+ For example, with this hierarchy:
10
+
11
+ Employee
12
+ / \
13
+ Staff Manager
14
+ |
15
+ Executive
16
+
17
+ the following database schema may be used (table - columns):
18
+
19
+ * employees - id, name, kind
20
+ * staff - id, manager_id
21
+ * managers - id, num_staff
22
+ * executives - id, num_managers
23
+
24
+ The class_table_inheritance plugin assumes that the main table
25
+ (e.g. employees) has a primary key field (usually
26
+ autoincrementing), and all other tables have a foreign key of the
27
+ same name that points to the same key in their superclass's table.
28
+ For example:
29
+
30
+ * employees.id - primary key, autoincrementing
31
+ * staff.id - foreign key referencing employees(id)
32
+ * managers.id - foreign key referencing employees(id)
33
+ * executives.id - foreign key referencing managers(id)
34
+
35
+ When using the class_table_inheritance plugin, subclasses use joined
36
+ datasets:
37
+
38
+ Employee.dataset.sql # SELECT * FROM employees
39
+ Manager.dataset.sql # SELECT * FROM employees
40
+ # INNER JOIN managers USING (id)
41
+ Executive.dataset.sql # SELECT * FROM employees
42
+ # INNER JOIN managers USING (id)
43
+ # INNER JOIN executives USING (id)
44
+
45
+ This allows Executive.all to return instances with all attributes
46
+ loaded. The plugin overrides deleting, inserting, and updating
47
+ in the model to work with multiple tables, by handling each table
48
+ individually.
49
+
50
+ This plugin allows and encourages the use of a :key option to mark
51
+ a column holding the class name. This allows methods on the
52
+ superclass to return instances of specific subclasses.
53
+
54
+ a = Employee.all # [<#Staff>, <#Manager>, <#Executive>]
55
+
56
+ This plugin requires the lazy_attributes plugin and uses it to
57
+ handle subclass specific attributes that would not be loaded
58
+ when calling superclass methods (since those wouldn't join
59
+ to the subclass tables). For example:
60
+
61
+ a.first.values # {:id=>1, name=>'S', :kind=>'Staff'}
62
+ a.first.manager_id # Loads the manager_id attribute from the
63
+ # database
64
+
65
+ The class_table_inheritance plugin requires JOIN USING and
66
+ therefore is not supported on H2 or Microsoft SQL Server, which do
67
+ not support that SQL-92 feature.
68
+
69
+ * An associations_dependencies plugin was added for deleting,
70
+ destroying, or nullifying associated objects when destroying a
71
+ model object. This just gives an easy way to add the necessary
72
+ before and after destroy hooks. The following association types
73
+ support the following dependency actions:
74
+
75
+ * :many_to_many - :nullify (removes all related entries in join
76
+ table)
77
+ * :many_to_one - :delete, :destroy
78
+ * :one_to_many - :delete, :destroy, :nullify (sets foreign key to
79
+ NULL for all associated objects)
80
+
81
+ This plugin works directly with the association datasets and does
82
+ not use any cached association values. The :delete action will
83
+ delete all associated objects from the database in a single SQL
84
+ call. The :destroy action will load each associated object from the
85
+ database and call the destroy method on it.
86
+
87
+ The plugin call takes a hash of association symbol keys and
88
+ dependency action symbol values. Alternatively, you can specify
89
+ additional dependencies later using add_association_dependencies:
90
+
91
+ Business.plugin :association_dependencies, :address=>:delete
92
+ # or:
93
+ Artist.plugin :association_dependencies
94
+ Artist.add_association_dependencies :albums=>:destroy,
95
+ :reviews=>:delete, :tags=>:nullify
96
+
97
+ * A force_encoding plugin was added that forces the encoding of
98
+ strings used in model instances. When model instances are loaded
99
+ from the database, all values in the hash that are strings are
100
+ forced to the given encoding. Whenever you update a model column
101
+ attribute, the resulting value is forced to a given encoding if the
102
+ value is a string. There are two ways to specify the encoding.
103
+ You can either do so in the plugin call itself, or via the
104
+ forced_encoding class accessor:
105
+
106
+ class Album < Sequel::Model
107
+ plugin :force_encoding, 'UTF-8'
108
+ # or
109
+ plugin :force_encoding
110
+ self.forced_encoding = 'UTF-8'
111
+ end
112
+
113
+ This plugin only works on ruby 1.9, since strings don't have
114
+ encodings in 1.8.
115
+
116
+ * A typecast_on_load plugin was added, for fixing bad database
117
+ typecasting when loading model objects. Most of Sequel's database
118
+ adapters don't have complete control over typecasting, and may
119
+ return columns that aren't typecast correctly (with correct being
120
+ defined as how the model object would typecast the same column
121
+ values).
122
+
123
+ This plugin modifies Model.load to call the setter methods (which
124
+ typecast by default) for all columns given. You can either specify
125
+ the columns to typecast on load in the plugin call itself, or
126
+ afterwards using add_typecast_on_load_columns:
127
+
128
+ Album.plugin :typecast_on_load, :release_date, :record_date
129
+ # or:
130
+ Album.plugin :typecast_on_load
131
+ Album.add_typecast_on_load_columns :release_date, :record_date
132
+
133
+ If the database returns release_date and record_date columns as
134
+ strings instead of dates, this will ensure that if you access those
135
+ columns through the model object, you'll get Date objects instead of
136
+ strings.
137
+
138
+ * A touch plugin was added, which adds Model#touch for updating an
139
+ instance's timestamp, as well as touching associations when an
140
+ instance is updated or destroyed.
141
+
142
+ The Model#touch instance method saves the object with a modified
143
+ timestamp. By default, it uses the :updated_at column, but you can
144
+ set which column to use. It also supports touching of associations,
145
+ so that when the current model object is updated or destroyed, the
146
+ associated rows in the database can have their modified timestamp
147
+ updated to the current timestamp. Example:
148
+
149
+ class Album < Sequel::Model
150
+ plugin :touch, :column=>:modified_on, :associations=>:artist
151
+ end
152
+
153
+ * A subclasses plugin was added, for recording all of a models
154
+ subclasses and descendent classes. Direct subclasses are available
155
+ via the subclasses method, and all descendent classes are available
156
+ via the descendents method:
157
+
158
+ c = Class.new(Sequel::Model)
159
+ c.plugin :subclasses
160
+ sc1 = Class.new(c)
161
+ sc2 = Class.new(c)
162
+ ssc1 = Class.new(sc1)
163
+ c.subclasses # [sc1, sc2]
164
+ sc1.subclasses # [ssc1]
165
+ sc2.subclasses # []
166
+ ssc1.subclasses # []
167
+ c.descendents # [sc1, ssc1, sc2]
168
+
169
+ The main use case for this is if you want to modify all models
170
+ after the model subclasses have been created. Since mutable
171
+ options are copied when subclassing, modifying parent classes
172
+ does not affect current subclasses, only future ones. The
173
+ subclasses plugin allows you get all subclasses so that you can
174
+ easily modify them. The plugin only records subclasses
175
+ created after the plugin call, though.
176
+
177
+ * An active_model plugin was added, giving Sequel::Model an
178
+ ActiveModel complaint API, in so much as it passes the
179
+ ActiveModel::Lint tests.
180
+
181
+ New Extensions
182
+ --------------
183
+
184
+ * A named_timezones extension was added, allowing you to use named
185
+ timezones such as "America/Los_Angeles" (the default Sequel
186
+ timezone support only supports UTC or local time). This extension
187
+ requires TZInfo. It also sets the Sequel.datetime_class to
188
+ DateTime, so database timestamps will be returned as DateTime
189
+ instances instead of Time instances. This is because ruby's
190
+ Time class doesn't support timezones other than UTC and local time.
191
+
192
+ This plugin allows you to pass either strings or TZInfo::Timezone
193
+ instance to Sequel.database_timezone=, application_timezone=, and
194
+ typecast_timezone=. If a string is passed, it is converted to a
195
+ TZInfo::Timezone using TZInfo::Timezone.get.
196
+
197
+ Let's say you have the database server in New York and the
198
+ application server in Los Angeles. For historical reasons, data
199
+ is stored in local New York time, but the application server only
200
+ services clients in Los Angeles, so you want to use New York
201
+ time in the database and Los Angeles time in the application. This
202
+ is easily done via:
203
+
204
+ Sequel.database_timezone = 'America/New_York'
205
+ Sequel.application_timezone = 'America/Los_Angeles'
206
+
207
+ Then, before timestamps are stored in the database, they are
208
+ converted to New York time. When timestamps are retrieved from the
209
+ database, they are converted to Los Angeles time.
210
+
211
+ * A thread_local_timezones extension was added. This allows you to
212
+ set a per-thread timezone that will override the default global
213
+ timezone while the thread is executing. The main use case is for
214
+ web applications that execute each request in its own thread, and
215
+ want to set the timezones based on the request. The most common
216
+ example is having the database always store time in UTC, but have
217
+ the application deal with the timezone of the current user. That
218
+ can be done with:
219
+
220
+ Sequel.database_timezone = :utc
221
+ # In each thread:
222
+ Sequel.thread_application_timezone = current_user.timezone
223
+
224
+ This extension is designed to work with the named_timezones
225
+ extension.
226
+
227
+ * An sql_expr extension was added that adds .sql_expr methods to
228
+ all objects, giving them easy access to Sequel's DSL:
229
+
230
+ 1.sql_expr < :a # 1 < a
231
+ false.sql_expr & :a # FALSE AND a
232
+ true.sql_expr | :a # TRUE OR a
233
+ ~nil.sql_expr # NOT NULL
234
+ "a".sql_expr + "b" # 'a' || 'b'
235
+
236
+ Proc#sql_expr uses a virtual row:
237
+
238
+ proc{[[a, b], [a, c]]}.sql_expr | :x
239
+ # (((a = b) AND (a = c)) OR x)
240
+
241
+ * A looser_typecasting extension was added, for using to_f and to_i
242
+ instead of the more strict Kernel.Float and Kernel.Integer when
243
+ typecasting floats and integers. To use it, you should extend the
244
+ database with the Sequel::LooserTypecasting module after loading
245
+ the extension:
246
+
247
+ Sequel.extension :looser_typecasting
248
+ DB.extend(Sequel::LooserTypecasting)
249
+
250
+ This makes the behavior more like ActiveRecord:
251
+
252
+ a = Artist.new(:num_albums=>'a')
253
+ a.num_albums # => 0
254
+
255
+ Other New Features
256
+ ------------------
257
+
258
+ * Associations now support composite keys. All of the :*key options
259
+ options now accept arrays of symbols instead of plain symbols.
260
+ Example:
261
+
262
+ Artist.primary_key # [:name, :city]
263
+ Album.many_to_one :artist, :key=>[:artist_name, :artist_city]
264
+ Artist.one_to_many :albums, :key=>[:artist_name, :artist_city]
265
+
266
+ All association types are supported, including the built-in
267
+ many_to_many association and the many_through_many plugin. Both
268
+ methods of eager loading work with composite keys for all
269
+ association types. Setter and add/remove/remove_all methods
270
+ also now work with composite keys.
271
+
272
+ * Associations now respect a :validate option, which can be set to
273
+ false to not validate when implicitly saving associated objects.
274
+
275
+ There isn't a lot of implicit saving in Sequel's association
276
+ methods, but this gives the user the control over validation when
277
+ the association methods implicitly save an object.
278
+
279
+ * In addition to the regular association methods, the
280
+ nested_attributes plugin was also updated to respect the
281
+ :validate_association option. It was also modified to not validate
282
+ associated objects twice, once when the parent object was validated
283
+ and again when the associated object was saved. Additionally, if
284
+ you pass :validate=>false to the save method when saving the parent
285
+ object, it will not longer attempt to validate associated objects
286
+ when saving them.
287
+
288
+ * Dataset#insert and #insert_sql were refactored and now support the
289
+ following API:
290
+
291
+ * No arguments - Treat as a single empty hash argument
292
+ * Single argument:
293
+ * Hash - Use keys as columns and values as values
294
+ * Array - Use as values, without specifying columns
295
+ * Dataset - Use a subselect, without specifying columns
296
+ * LiteralString - Use as the values
297
+ * 2 arguments:
298
+ * Array, Array - Use first array as keys, second as values
299
+ * Array, Dataset - Use a subselect, with the array as columns
300
+ * Array, LiteralString - Use LiteralString as the values, with
301
+ the array as the columns
302
+ * Anything else: Treat all given values an an array of values
303
+
304
+ * Graphing now works with previously joined datasets. The main use
305
+ case of this is when eagerly loading (via eager_graph) model
306
+ associations for models backed by joined datasets, such as those
307
+ created by the class_table_inheritance plugin.
308
+
309
+ * Sequel.virtual_row was added allowing you to easily use the
310
+ VirtualRow support outside of select, order, and filter calls:
311
+
312
+ net_benefit = Sequel.virtual_row{revenue > cost}
313
+ good_employee = Sequel.virtual_row{num_commendations > 0}
314
+ fire = ~net_benefit & ~good_employee
315
+ demote = ~net_benefit & good_employee
316
+ promote = net_benefit & good_employee
317
+ DB[:employees].filter(fire).update(:employed=>false)
318
+ DB[:employees].filter(demote).update(:rank=>:rank-1)
319
+ DB[:employees].filter(promote).update(:rank=>:rank+1)
320
+
321
+ * When Sequel wraps exception in its own classes (to provide database
322
+ independence), it now keeps the wrapped exception available in
323
+ a wrapped_exception accessor. This allows you to more easily
324
+ determine the wrapped exception class, without resorting to parsing
325
+ the exception message.
326
+
327
+ begin
328
+ DB.run('...')
329
+ rescue Sequel::DatabaseError => e
330
+ case e.wrapped_exception
331
+ when Mysql::Error
332
+ ...
333
+ when PGError
334
+ ...
335
+ end
336
+ end
337
+
338
+ * The MySQL adapter now supports a Dataset#split_multiple_result_sets
339
+ method that yields arrays of rows (one per result set), instead of
340
+ rows. This allows you to submit multiple statements at the same
341
+ time (or call a stored procedure that returns multiple result
342
+ sets), and know which rows are related to which result sets.
343
+
344
+ This violates a lot of Sequel's internal assumptions and should be
345
+ used with care. Existing row_procs are modified to work correctly,
346
+ but graphing will not work on these datasets.
347
+
348
+ * The ADO adapter now accepts a :conn_string option and uses that
349
+ as the full ADO connection string. This can be used to connect to
350
+ any datasource ADO supports, such as Microsoft Excel.
351
+
352
+ * The Microsoft SQL Server shared adapter now supports a
353
+ Database#server_version method.
354
+
355
+ * The Microsoft SQL Server shared adapter now supports updating and
356
+ deleting from joined datasets.
357
+
358
+ * The Microsoft SQL Server shared adapter now supports a
359
+ Dataset#output method that uses the OUTPUT clause.
360
+
361
+ * Model#_save now calls either Model#_insert or Model#_update for
362
+ inserting/updating the row in the database. This allows for easier
363
+ overriding when you want to allow creating and updating model
364
+ objects backed by a joined dataset.
365
+
366
+ * Dataset#graph now takes a :from_self_alias option specifying the
367
+ alias to use for the subselect created if the receiver is a joined
368
+ but not yet graphed dataset. It defaults to the first source table
369
+ in the receiver.
370
+
371
+ Other Improvements
372
+ ------------------
373
+
374
+ * Typecasting model attributes is now done before checking existing
375
+ values, instead of after. Before, the code for the model attribute
376
+ setters would compare the given value to the existing entry. If it
377
+ didn't match, the value was typecasted and then assigned. That led
378
+ to the following situation:
379
+
380
+ a = Album[1]
381
+ a.num_tracks # => 10
382
+ params # => {'num_tracks'=>'10'}
383
+ a.set(params)
384
+ a.changed_columns # => [:num_tracks]
385
+
386
+ The new behavior typecasts the value first, and only sets it and
387
+ records the column as changed if it doesn't match the typecasted
388
+ value.
389
+
390
+ * Model#modified? is now always true if the record is new. modified?
391
+ indicates the instance's status relative to the database, and since
392
+ a new object is not yet in the database, and saving the object
393
+ would add it, the object is considered modified. A consequence of
394
+ this is that Model#save_changes now always saves if the object is
395
+ new.
396
+
397
+ If you want to check if there were changes to columns since the
398
+ object was first initialized, you should use
399
+ !changed_columns.empty?, which was the historical way to handle
400
+ the situation.
401
+
402
+ * The DataObjects (do) adpater now supports DataObjects 0.10.
403
+
404
+ * Dataset#select_more and Dataset#order_more no longer affect the
405
+ receiver. They are supposed to just return a modified copy of the
406
+ receiver instead of modifying the receiver itself. For a few
407
+ versions they have been broken in that they modified the receiver
408
+ in addition to returning a modified copy.
409
+
410
+ * Performance was increased for execution of prepared statements
411
+ with multiple bound variables on MySQL.
412
+
413
+ * On MySQL, database errors raised when preparing statements or
414
+ setting bound variable values are now caught and raised as
415
+ Sequel::DatabaseErrors.
416
+
417
+ * On MySQL, more types of disconnection errors are detected.
418
+
419
+ * When altering columns in MySQL, options such as :unsigned,
420
+ :elements, and :size that are given in the call are now respected.
421
+
422
+ * MySQL enum defaults are now handled correctly in the schema dumper.
423
+
424
+ * The schema dumper no longer attempts to use unparseable defaults
425
+ as literals on MySQL, since MySQL does not provide defaults as
426
+ valid literals.
427
+
428
+ * The emulated offset support in the shared Microsoft SQL Server
429
+ adapter now works better with model classes (or any datasets with
430
+ row_procs).
431
+
432
+ * Microsoft SQL Server now supports using the WITH clause in delete,
433
+ update, and insert calls.
434
+
435
+ * Parsed indexes when connecting to Microsoft SQL Server via JDBC no
436
+ longer include primary key indexes.
437
+
438
+ * Dataset#insert_select now returns nil if disable_insert_returning
439
+ is used in the shared PostgreSQL adapter. This makes it work as
440
+ expected with model object creation.
441
+
442
+ * Calling Model.set_primary_key with an array of symbols to set
443
+ a composite primary key is now supported. You can also provide
444
+ multiple symbol arguments to do the same thing. Before, specifying
445
+ an array of symbols broke the Model.[] optimization.
446
+
447
+ * Literalization of timezones in timestamps now works correctly on
448
+ Oracle.
449
+
450
+ * __FILE__ and __LINE__ are now used everywhere that eval is called
451
+ with a string, which makes for better backtraces.
452
+
453
+ * The native MySQL adapter now correctly handles returning before
454
+ yielding all result sets. Previously, this caused a commands out
455
+ of sync error.
456
+
457
+ * Table names in common table expressions are now quoted.
458
+
459
+ * The Oracle adapter's Dataset#except now accepts a hash, giving it
460
+ the same API as the default Dataset#except.
461
+
462
+ * When connecting to Microsoft SQL Server via ADO, allow
463
+ Dataset#insert to take multiple arguments.
464
+
465
+ * Fractional timestamps are no longer used on ODBC.
466
+
467
+ * Schema parsing now works on MSSQL when the database is set to not
468
+ quote identifiers.
469
+
470
+ * Timezone offsets are no longer used on Microsoft SQL Server, since
471
+ they only work for the datetimeoffset type.
472
+
473
+ * Only 3 fractional digits in timestamps are used in Microsoft SQL
474
+ Server, since an error is raised if the use the datetime type
475
+ with more than that.
476
+
477
+ * The integration test suite now has guards for expected failures
478
+ when run on known databases. Expected failures are marked as
479
+ pending.
480
+
481
+ Backwards Compatibility
482
+ -----------------------
483
+
484
+ * Graphing to an previously joined (but not graphed) dataset now
485
+ causes the receiver to be wrapped in a subselect, so if you
486
+ graph a dataset to a previously joined dataset, and then filter
487
+ the dataset referring to tables that were in the joined dataset
488
+ (other than the first table), the SQL produced will probably no
489
+ longer be valid. You should either filter the dataset before
490
+ graphing or use the name of the first source of the joined
491
+ dataset (which is what the subselected is aliased to) if filtering
492
+ afterward.
493
+
494
+ In certain cases, this change can cause tables to be aliased
495
+ differently, so if you were graphing previously joined datasets
496
+ and then filtering using the automatically generated aliases, you
497
+ might need to modify your code.
498
+
499
+ * The DataObjects (do) adpater no longer supports DataObjects 0.9.x.
500
+
501
+ * The Dataset#virtual_row_block_call private instance method has
502
+ been removed.
503
+
504
+ * Sequel's timezone support was significantly refactored, so if you
505
+ had any custom modifications to the timezone support, they might
506
+ need to be refactored as well.
507
+
508
+ * The SQL generation code was significantly refactored, so if you
509
+ had any custom modifications in that area, you might need to
510
+ refactor as well.