viking-sequel 3.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +3134 -0
- data/COPYING +19 -0
- data/README.rdoc +723 -0
- data/Rakefile +193 -0
- data/bin/sequel +196 -0
- data/doc/advanced_associations.rdoc +644 -0
- data/doc/cheat_sheet.rdoc +218 -0
- data/doc/dataset_basics.rdoc +106 -0
- data/doc/dataset_filtering.rdoc +158 -0
- data/doc/opening_databases.rdoc +296 -0
- data/doc/prepared_statements.rdoc +104 -0
- data/doc/reflection.rdoc +84 -0
- data/doc/release_notes/1.0.txt +38 -0
- data/doc/release_notes/1.1.txt +143 -0
- data/doc/release_notes/1.3.txt +101 -0
- data/doc/release_notes/1.4.0.txt +53 -0
- data/doc/release_notes/1.5.0.txt +155 -0
- data/doc/release_notes/2.0.0.txt +298 -0
- data/doc/release_notes/2.1.0.txt +271 -0
- data/doc/release_notes/2.10.0.txt +328 -0
- data/doc/release_notes/2.11.0.txt +215 -0
- data/doc/release_notes/2.12.0.txt +534 -0
- data/doc/release_notes/2.2.0.txt +253 -0
- data/doc/release_notes/2.3.0.txt +88 -0
- data/doc/release_notes/2.4.0.txt +106 -0
- data/doc/release_notes/2.5.0.txt +137 -0
- data/doc/release_notes/2.6.0.txt +157 -0
- data/doc/release_notes/2.7.0.txt +166 -0
- data/doc/release_notes/2.8.0.txt +171 -0
- data/doc/release_notes/2.9.0.txt +97 -0
- data/doc/release_notes/3.0.0.txt +221 -0
- data/doc/release_notes/3.1.0.txt +406 -0
- data/doc/release_notes/3.10.0.txt +286 -0
- data/doc/release_notes/3.2.0.txt +268 -0
- data/doc/release_notes/3.3.0.txt +192 -0
- data/doc/release_notes/3.4.0.txt +325 -0
- data/doc/release_notes/3.5.0.txt +510 -0
- data/doc/release_notes/3.6.0.txt +366 -0
- data/doc/release_notes/3.7.0.txt +179 -0
- data/doc/release_notes/3.8.0.txt +151 -0
- data/doc/release_notes/3.9.0.txt +233 -0
- data/doc/schema.rdoc +36 -0
- data/doc/sharding.rdoc +113 -0
- data/doc/virtual_rows.rdoc +205 -0
- data/lib/sequel.rb +1 -0
- data/lib/sequel/adapters/ado.rb +90 -0
- data/lib/sequel/adapters/ado/mssql.rb +30 -0
- data/lib/sequel/adapters/amalgalite.rb +176 -0
- data/lib/sequel/adapters/db2.rb +139 -0
- data/lib/sequel/adapters/dbi.rb +113 -0
- data/lib/sequel/adapters/do.rb +188 -0
- data/lib/sequel/adapters/do/mysql.rb +49 -0
- data/lib/sequel/adapters/do/postgres.rb +91 -0
- data/lib/sequel/adapters/do/sqlite.rb +40 -0
- data/lib/sequel/adapters/firebird.rb +283 -0
- data/lib/sequel/adapters/informix.rb +77 -0
- data/lib/sequel/adapters/jdbc.rb +587 -0
- data/lib/sequel/adapters/jdbc/as400.rb +58 -0
- data/lib/sequel/adapters/jdbc/h2.rb +133 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +57 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +78 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +50 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +108 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +55 -0
- data/lib/sequel/adapters/mysql.rb +421 -0
- data/lib/sequel/adapters/odbc.rb +143 -0
- data/lib/sequel/adapters/odbc/mssql.rb +42 -0
- data/lib/sequel/adapters/openbase.rb +64 -0
- data/lib/sequel/adapters/oracle.rb +131 -0
- data/lib/sequel/adapters/postgres.rb +504 -0
- data/lib/sequel/adapters/shared/mssql.rb +490 -0
- data/lib/sequel/adapters/shared/mysql.rb +498 -0
- data/lib/sequel/adapters/shared/oracle.rb +195 -0
- data/lib/sequel/adapters/shared/postgres.rb +830 -0
- data/lib/sequel/adapters/shared/progress.rb +44 -0
- data/lib/sequel/adapters/shared/sqlite.rb +389 -0
- data/lib/sequel/adapters/sqlite.rb +224 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +84 -0
- data/lib/sequel/connection_pool.rb +99 -0
- data/lib/sequel/connection_pool/sharded_single.rb +84 -0
- data/lib/sequel/connection_pool/sharded_threaded.rb +211 -0
- data/lib/sequel/connection_pool/single.rb +29 -0
- data/lib/sequel/connection_pool/threaded.rb +150 -0
- data/lib/sequel/core.rb +293 -0
- data/lib/sequel/core_sql.rb +241 -0
- data/lib/sequel/database.rb +1079 -0
- data/lib/sequel/database/schema_generator.rb +327 -0
- data/lib/sequel/database/schema_methods.rb +203 -0
- data/lib/sequel/database/schema_sql.rb +320 -0
- data/lib/sequel/dataset.rb +32 -0
- data/lib/sequel/dataset/actions.rb +441 -0
- data/lib/sequel/dataset/features.rb +86 -0
- data/lib/sequel/dataset/graph.rb +254 -0
- data/lib/sequel/dataset/misc.rb +119 -0
- data/lib/sequel/dataset/mutation.rb +64 -0
- data/lib/sequel/dataset/prepared_statements.rb +227 -0
- data/lib/sequel/dataset/query.rb +709 -0
- data/lib/sequel/dataset/sql.rb +996 -0
- data/lib/sequel/exceptions.rb +51 -0
- data/lib/sequel/extensions/blank.rb +43 -0
- data/lib/sequel/extensions/inflector.rb +242 -0
- data/lib/sequel/extensions/looser_typecasting.rb +21 -0
- data/lib/sequel/extensions/migration.rb +239 -0
- data/lib/sequel/extensions/named_timezones.rb +61 -0
- data/lib/sequel/extensions/pagination.rb +100 -0
- data/lib/sequel/extensions/pretty_table.rb +82 -0
- data/lib/sequel/extensions/query.rb +52 -0
- data/lib/sequel/extensions/schema_dumper.rb +271 -0
- data/lib/sequel/extensions/sql_expr.rb +122 -0
- data/lib/sequel/extensions/string_date_time.rb +46 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +48 -0
- data/lib/sequel/metaprogramming.rb +9 -0
- data/lib/sequel/model.rb +120 -0
- data/lib/sequel/model/associations.rb +1514 -0
- data/lib/sequel/model/base.rb +1069 -0
- data/lib/sequel/model/default_inflections.rb +45 -0
- data/lib/sequel/model/errors.rb +39 -0
- data/lib/sequel/model/exceptions.rb +21 -0
- data/lib/sequel/model/inflections.rb +162 -0
- data/lib/sequel/model/plugins.rb +70 -0
- data/lib/sequel/plugins/active_model.rb +59 -0
- data/lib/sequel/plugins/association_dependencies.rb +103 -0
- data/lib/sequel/plugins/association_proxies.rb +41 -0
- data/lib/sequel/plugins/boolean_readers.rb +53 -0
- data/lib/sequel/plugins/caching.rb +141 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +214 -0
- data/lib/sequel/plugins/composition.rb +138 -0
- data/lib/sequel/plugins/force_encoding.rb +72 -0
- data/lib/sequel/plugins/hook_class_methods.rb +126 -0
- data/lib/sequel/plugins/identity_map.rb +116 -0
- data/lib/sequel/plugins/instance_filters.rb +98 -0
- data/lib/sequel/plugins/instance_hooks.rb +57 -0
- data/lib/sequel/plugins/lazy_attributes.rb +77 -0
- data/lib/sequel/plugins/many_through_many.rb +208 -0
- data/lib/sequel/plugins/nested_attributes.rb +206 -0
- data/lib/sequel/plugins/optimistic_locking.rb +81 -0
- data/lib/sequel/plugins/rcte_tree.rb +281 -0
- data/lib/sequel/plugins/schema.rb +66 -0
- data/lib/sequel/plugins/serialization.rb +166 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +74 -0
- data/lib/sequel/plugins/subclasses.rb +45 -0
- data/lib/sequel/plugins/tactical_eager_loading.rb +61 -0
- data/lib/sequel/plugins/timestamps.rb +87 -0
- data/lib/sequel/plugins/touch.rb +118 -0
- data/lib/sequel/plugins/typecast_on_load.rb +72 -0
- data/lib/sequel/plugins/validation_class_methods.rb +405 -0
- data/lib/sequel/plugins/validation_helpers.rb +223 -0
- data/lib/sequel/sql.rb +1020 -0
- data/lib/sequel/timezones.rb +161 -0
- data/lib/sequel/version.rb +12 -0
- data/lib/sequel_core.rb +1 -0
- data/lib/sequel_model.rb +1 -0
- data/spec/adapters/firebird_spec.rb +407 -0
- data/spec/adapters/informix_spec.rb +97 -0
- data/spec/adapters/mssql_spec.rb +403 -0
- data/spec/adapters/mysql_spec.rb +1019 -0
- data/spec/adapters/oracle_spec.rb +286 -0
- data/spec/adapters/postgres_spec.rb +969 -0
- data/spec/adapters/spec_helper.rb +51 -0
- data/spec/adapters/sqlite_spec.rb +432 -0
- data/spec/core/connection_pool_spec.rb +808 -0
- data/spec/core/core_sql_spec.rb +417 -0
- data/spec/core/database_spec.rb +1662 -0
- data/spec/core/dataset_spec.rb +3827 -0
- data/spec/core/expression_filters_spec.rb +595 -0
- data/spec/core/object_graph_spec.rb +296 -0
- data/spec/core/schema_generator_spec.rb +159 -0
- data/spec/core/schema_spec.rb +830 -0
- data/spec/core/spec_helper.rb +56 -0
- data/spec/core/version_spec.rb +7 -0
- data/spec/extensions/active_model_spec.rb +76 -0
- data/spec/extensions/association_dependencies_spec.rb +127 -0
- data/spec/extensions/association_proxies_spec.rb +50 -0
- data/spec/extensions/blank_spec.rb +67 -0
- data/spec/extensions/boolean_readers_spec.rb +92 -0
- data/spec/extensions/caching_spec.rb +250 -0
- data/spec/extensions/class_table_inheritance_spec.rb +252 -0
- data/spec/extensions/composition_spec.rb +194 -0
- data/spec/extensions/force_encoding_spec.rb +117 -0
- data/spec/extensions/hook_class_methods_spec.rb +470 -0
- data/spec/extensions/identity_map_spec.rb +202 -0
- data/spec/extensions/inflector_spec.rb +181 -0
- data/spec/extensions/instance_filters_spec.rb +55 -0
- data/spec/extensions/instance_hooks_spec.rb +133 -0
- data/spec/extensions/lazy_attributes_spec.rb +153 -0
- data/spec/extensions/looser_typecasting_spec.rb +39 -0
- data/spec/extensions/many_through_many_spec.rb +884 -0
- data/spec/extensions/migration_spec.rb +332 -0
- data/spec/extensions/named_timezones_spec.rb +72 -0
- data/spec/extensions/nested_attributes_spec.rb +396 -0
- data/spec/extensions/optimistic_locking_spec.rb +100 -0
- data/spec/extensions/pagination_spec.rb +99 -0
- data/spec/extensions/pretty_table_spec.rb +91 -0
- data/spec/extensions/query_spec.rb +85 -0
- data/spec/extensions/rcte_tree_spec.rb +205 -0
- data/spec/extensions/schema_dumper_spec.rb +357 -0
- data/spec/extensions/schema_spec.rb +127 -0
- data/spec/extensions/serialization_spec.rb +209 -0
- data/spec/extensions/single_table_inheritance_spec.rb +96 -0
- data/spec/extensions/spec_helper.rb +91 -0
- data/spec/extensions/sql_expr_spec.rb +89 -0
- data/spec/extensions/string_date_time_spec.rb +93 -0
- data/spec/extensions/subclasses_spec.rb +52 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +65 -0
- data/spec/extensions/thread_local_timezones_spec.rb +45 -0
- data/spec/extensions/timestamps_spec.rb +150 -0
- data/spec/extensions/touch_spec.rb +155 -0
- data/spec/extensions/typecast_on_load_spec.rb +69 -0
- data/spec/extensions/validation_class_methods_spec.rb +984 -0
- data/spec/extensions/validation_helpers_spec.rb +438 -0
- data/spec/integration/associations_test.rb +281 -0
- data/spec/integration/database_test.rb +26 -0
- data/spec/integration/dataset_test.rb +963 -0
- data/spec/integration/eager_loader_test.rb +734 -0
- data/spec/integration/model_test.rb +130 -0
- data/spec/integration/plugin_test.rb +814 -0
- data/spec/integration/prepared_statement_test.rb +213 -0
- data/spec/integration/schema_test.rb +361 -0
- data/spec/integration/spec_helper.rb +73 -0
- data/spec/integration/timezone_test.rb +55 -0
- data/spec/integration/transaction_test.rb +122 -0
- data/spec/integration/type_test.rb +96 -0
- data/spec/model/association_reflection_spec.rb +175 -0
- data/spec/model/associations_spec.rb +2633 -0
- data/spec/model/base_spec.rb +418 -0
- data/spec/model/dataset_methods_spec.rb +78 -0
- data/spec/model/eager_loading_spec.rb +1391 -0
- data/spec/model/hooks_spec.rb +240 -0
- data/spec/model/inflector_spec.rb +26 -0
- data/spec/model/model_spec.rb +593 -0
- data/spec/model/plugins_spec.rb +236 -0
- data/spec/model/record_spec.rb +1500 -0
- data/spec/model/spec_helper.rb +97 -0
- data/spec/model/validations_spec.rb +153 -0
- data/spec/rcov.opts +6 -0
- data/spec/spec_config.rb.example +10 -0
- metadata +346 -0
@@ -0,0 +1,253 @@
|
|
1
|
+
The Most Powerful and Flexible Associations of Any Ruby ORM
|
2
|
+
-----------------------------------------------------------
|
3
|
+
|
4
|
+
Sequel can now support any association type supported by
|
5
|
+
ActiveRecord, and many association types ActiveRecord doesn't
|
6
|
+
support.
|
7
|
+
|
8
|
+
Association callbacks (:before_add, :after_add, :before_remove,
|
9
|
+
:after_remove) have been added, and work for all association
|
10
|
+
types. Each of the callback options can be a Symbol specifying an
|
11
|
+
instance method that takes one argument (the associated object), or a
|
12
|
+
Proc that takes two arguments (the current object and the associated
|
13
|
+
object), or an array of Symbols and Procs. Additionally, an
|
14
|
+
:after_load callback is available, which is running after loading the
|
15
|
+
associated record(s) from the database.
|
16
|
+
|
17
|
+
Association extensions are now supported:
|
18
|
+
|
19
|
+
class FindOrCreate
|
20
|
+
def find_or_create(vals)
|
21
|
+
first(vals) || create(vals)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
class Author < Sequel::Model
|
25
|
+
one_to_many :authorships, :extend=>FindOrCreate
|
26
|
+
end
|
27
|
+
Author.first.authorships_dataset.find_or_create(:name=>'Bob')
|
28
|
+
|
29
|
+
Sequel has been able to support most has_many :through style
|
30
|
+
associations since 1.3, via many_to_many (since it doesn't break on
|
31
|
+
join tables that are also model tables, unlike ActiveRecord's
|
32
|
+
has_and_belongs_to_many). Now it can also support has_many :through
|
33
|
+
style associations where it goes through a has_many association.
|
34
|
+
|
35
|
+
Sequel can now support polymorphic associations. Polymorphic
|
36
|
+
associations are really a design flaw, so Sequel doesn't support them
|
37
|
+
directly, but the tools that Sequel gives you make them pretty easy
|
38
|
+
to implement.
|
39
|
+
|
40
|
+
Sequel can also support associations that ActiveRecord does not. For
|
41
|
+
example, a belongs_to association where the column referenced in the
|
42
|
+
associated table is not the primary key, an association that depends
|
43
|
+
on multiple columns in each table, or even situations where the
|
44
|
+
association has a column in the primary table that can be referenced
|
45
|
+
by any of multiple columns in a second table that has a has_one style
|
46
|
+
association with the table you want to associate with.
|
47
|
+
|
48
|
+
Some of those associations can be supported for a single object using
|
49
|
+
custom SQL in ActiveRecord, but none are supported when eager
|
50
|
+
loading or allow further filtering.
|
51
|
+
|
52
|
+
Not only can all of these cases be supported with Sequel::Model, all
|
53
|
+
can be supported with eager loading, and can allow for further
|
54
|
+
filtering. See
|
55
|
+
http://sequel.rubyforge.org/files/sequel/doc/advanced_associations_rdoc.html
|
56
|
+
for details and example code for all association types covered above.
|
57
|
+
|
58
|
+
There have also been many additional options added for controlling
|
59
|
+
eager loading via eager_graph. Every part of the SQL JOINs can now
|
60
|
+
be controlled via one of the options, so you can use JOIN USING,
|
61
|
+
NATURAL JOIN, or arbitrary JOIN ON conditions.
|
62
|
+
|
63
|
+
Finally, just to show off the power that Sequel gives you when eager
|
64
|
+
loading, here is example code that will eagerly load all descendants
|
65
|
+
and ancestors in a tree structure, without knowing the depth of the
|
66
|
+
tree:
|
67
|
+
|
68
|
+
class Node < Sequel::Model
|
69
|
+
set_schema do
|
70
|
+
primary_key :id
|
71
|
+
foreign_key :parent_id, :nodes
|
72
|
+
end
|
73
|
+
create_table
|
74
|
+
|
75
|
+
many_to_one :parent
|
76
|
+
one_to_many :children, :key=>:parent_id
|
77
|
+
|
78
|
+
# Only useful when eager loading
|
79
|
+
many_to_one :ancestors, :eager_loader=>(proc do |key_hash, nodes,
|
80
|
+
associations|
|
81
|
+
# Handle cases where the root node has the same parent_id as
|
82
|
+
primary_key
|
83
|
+
# and also when it is NULL
|
84
|
+
non_root_nodes = nodes.reject do |n|
|
85
|
+
if [nil, n.pk].include?(n.parent_id)
|
86
|
+
# Make sure root nodes have their parent association set to
|
87
|
+
nil
|
88
|
+
n.associations[:parent] = nil
|
89
|
+
true
|
90
|
+
else
|
91
|
+
false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
unless non_root_nodes.empty?
|
95
|
+
id_map = {}
|
96
|
+
# Create an map of parent_ids to nodes that have that parent id
|
97
|
+
non_root_nodes.each{|n| (id_map[n.parent_id] ||= []) << n}
|
98
|
+
# Doesn't cause an infinte loop, because when only the root node
|
99
|
+
# is left, this is not called.
|
100
|
+
Node.filter(Node.primary_key=>id_map.keys).eager(:ancestors).all
|
101
|
+
do |node|
|
102
|
+
# Populate the parent association for each node
|
103
|
+
id_map[node.pk].each{|n| n.associations[:parent] = node}
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end)
|
107
|
+
many_to_one :descendants, :eager_loader=>(proc do |key_hash, nodes,
|
108
|
+
associations|
|
109
|
+
id_map = {}
|
110
|
+
nodes.each do |n|
|
111
|
+
# Initialize an empty array of child associations for each
|
112
|
+
parent node
|
113
|
+
n.associations[:children] = []
|
114
|
+
# Populate identity map of nodes
|
115
|
+
id_map[n.pk] = n
|
116
|
+
end
|
117
|
+
# Doesn't cause an infinite loop, because the :eager_loader is not
|
118
|
+
called
|
119
|
+
# if no records are returned. Exclude id = parent_id to avoid
|
120
|
+
infinite loop
|
121
|
+
# if the root note is one of the returned records and it has
|
122
|
+
parent_id = id
|
123
|
+
# instead of parent_id = NULL.
|
124
|
+
Node.filter(:parent_id=>id_map.keys).exclude(:id=>:parent_id).eager(:descendants).all
|
125
|
+
do |node|
|
126
|
+
# Get the parent from the identity map
|
127
|
+
parent = id_map[node.parent_id]
|
128
|
+
# Set the child's parent association to the parent
|
129
|
+
node.associations[:parent] = parent
|
130
|
+
# Add the child association to the array of children in the
|
131
|
+
parent
|
132
|
+
parent.associations[:children] << node
|
133
|
+
end
|
134
|
+
end)
|
135
|
+
end
|
136
|
+
|
137
|
+
nodes = Node.filter(:id < 10).eager(:ancestors, :descendants).all
|
138
|
+
|
139
|
+
New Adapter Features
|
140
|
+
--------------------
|
141
|
+
|
142
|
+
* PostgreSQL bytea fields are now fully supported.
|
143
|
+
|
144
|
+
* The PostgreSQL adapter now uses the safer connection-specific
|
145
|
+
string escaping if you are using ruby-pg.
|
146
|
+
|
147
|
+
* The SQLite adapter supports drop_column and add_index.
|
148
|
+
|
149
|
+
* You can now use URL parameters in the connection string, enabling
|
150
|
+
you to connect to PostgreSQL via a socket using
|
151
|
+
postgres://user:password@blah/database?host=/tmp
|
152
|
+
|
153
|
+
Other New Features
|
154
|
+
------------------
|
155
|
+
|
156
|
+
* Dataset#graph now takes a block which it passes to join_table.
|
157
|
+
|
158
|
+
* Symbol#identifier has been added, which can be used if another
|
159
|
+
library defines the same operator(s) on Symbol that Sequel defines.
|
160
|
+
|
161
|
+
* Filter blocks now yield a VirtualRow instance, which can yield
|
162
|
+
Identifiers, QualifiedIdentifiers, or Functions. Like
|
163
|
+
Symbol#identifier, this is useful if another library defines the
|
164
|
+
same operator(s) on Symbol that Sequel defines.
|
165
|
+
|
166
|
+
* You can now call Model.to_hash to get an identity map for all
|
167
|
+
rows (before this required Model.dataset.to_hash).
|
168
|
+
|
169
|
+
* A model that can get it's column information from the schema will
|
170
|
+
set it in the dataset, potentially saving many queries.
|
171
|
+
|
172
|
+
* Model.validates_presence_of now works correctly for boolean
|
173
|
+
columns.
|
174
|
+
|
175
|
+
Notable Bug Fixes
|
176
|
+
-----------------
|
177
|
+
|
178
|
+
* Caching now works with Model subclasses.
|
179
|
+
|
180
|
+
* Model validation methods now work with source reloading.
|
181
|
+
|
182
|
+
* The PostgreSQL adapter no longer raises an Error if you try to
|
183
|
+
insert a record with the primary key already specified.
|
184
|
+
|
185
|
+
* Sequel no longer messes with the native MySQL adapter, so you can
|
186
|
+
use Sequel and ActiveRecord with MySQL in the same process.
|
187
|
+
|
188
|
+
* Dataset#count now works correctly for limited dataset.
|
189
|
+
|
190
|
+
* PostgreSQL Database#transaction method yields a connection, similar
|
191
|
+
to the other adapters.
|
192
|
+
|
193
|
+
* Using a hash argument in #distinct, #order, or #group is treated
|
194
|
+
as an expression instead of a column alias.
|
195
|
+
|
196
|
+
* Cloned datasets no longer ignore the existing columns unless it is
|
197
|
+
necessary.
|
198
|
+
|
199
|
+
* The :quote_identifiers and :single_threaded Database options now
|
200
|
+
work correctly.
|
201
|
+
|
202
|
+
Backwards Incompatible Changes
|
203
|
+
------------------------------
|
204
|
+
|
205
|
+
* ParseTree support, deprecated in 2.1.0, has been removed in 2.2.0.
|
206
|
+
You should use the expression filter syntax instead, perferably
|
207
|
+
without the block (though it can be used inside a block as well).
|
208
|
+
This usually involves the following types of changes:
|
209
|
+
|
210
|
+
filter{:x == :y} => filter(:x => :y)
|
211
|
+
filter{:x << :y} => filter(:x => :y)
|
212
|
+
filter{:x && :y} => filter(:x & :y) # Don't forget about change
|
213
|
+
filter{:x || :y} => filter(:x | :y) # in operator precedence
|
214
|
+
filter{:x.like?('%blah%')} => filter(:x.like('%blah%'))
|
215
|
+
filter do => filter((:x > 1) & (:y < 2))
|
216
|
+
:x > 1
|
217
|
+
:y < 2
|
218
|
+
end
|
219
|
+
|
220
|
+
* Attempts to save an invalid Model instance will raise an error by
|
221
|
+
default. To revert to returning a nil value, use:
|
222
|
+
|
223
|
+
Sequel::Model.raise_on_save_failure = false # Global
|
224
|
+
Album.raise_on_save_failure = false # Class
|
225
|
+
album = Album.new
|
226
|
+
album.raise_on_save_failure = false # Instance
|
227
|
+
|
228
|
+
Note that before, save would return false where now it returns nil
|
229
|
+
if you disable raising on save failure.
|
230
|
+
|
231
|
+
* Dataset#update no longer takes a block, as it's use of the block
|
232
|
+
depended on ParseTree. With the introduction of the expression
|
233
|
+
syntax in 2.0.0, it's no longer necessary. You should use a hash
|
234
|
+
with an expression as the value instead:
|
235
|
+
|
236
|
+
DB[:table].update(:column=>:column + 1)
|
237
|
+
|
238
|
+
* validates_presence of now considers false as present instead of
|
239
|
+
absent. This is so it works with boolean columns.
|
240
|
+
|
241
|
+
* Dataset#graph ignores any previously selected columns when it is
|
242
|
+
called for the first time.
|
243
|
+
|
244
|
+
* Dataset#columns ignores any filtering, ordering, or distinct
|
245
|
+
clauses. This shouldn't cause issues unless you were using
|
246
|
+
SQL functions with side effects and expecting them to be called
|
247
|
+
when columns was called (unlikely at best).
|
248
|
+
|
249
|
+
One significant point of note is that the 2.2.0 release will be the
|
250
|
+
last release with both a sequel_core and sequel gem. Starting
|
251
|
+
with 2.3.0 they will be combined into one sequel gem. You will still
|
252
|
+
be able to get just the sequel_core part by requiring 'sequel_core',
|
253
|
+
but they will be packaged together.
|
@@ -0,0 +1,88 @@
|
|
1
|
+
JRuby and Ruby 1.9 Officially Supported
|
2
|
+
---------------------------------------
|
3
|
+
|
4
|
+
Sequel now officially supports JRuby 1.1.3 and Ruby 1.9 (svn revision
|
5
|
+
18194 at least). Using JRuby with the JDBC adapter, PostgreSQL,
|
6
|
+
MySQL, and SQLite now enjoy almost full support, though not
|
7
|
+
everything works the same as using the native adapter. Depending on
|
8
|
+
what you are doing, it may make sense to use postgres-pr on JRuby
|
9
|
+
instead of PostgreSQL-JDBC.
|
10
|
+
|
11
|
+
To use the new JDBC support, the database connection string you give
|
12
|
+
Sequel is now passed directly to JDBC, here are a few examples:
|
13
|
+
|
14
|
+
Sequel.connect('jdbc:postgresql://host/database?user=*&password=*')
|
15
|
+
Sequel.connect('jdbc:mysql://host/database?user=*&password=*')
|
16
|
+
Sequel.connect('jdbc:sqlite::memory:')
|
17
|
+
Sequel.connect('jdbc:sqlite:relative/path.db')
|
18
|
+
Sequel.connect('jdbc:sqlite:/absolute/path.db')
|
19
|
+
|
20
|
+
Single Gem
|
21
|
+
----------
|
22
|
+
|
23
|
+
Sequel is now distributed as a single gem named sequel, by combining
|
24
|
+
the previous sequel_core and sequel gems. You can still just
|
25
|
+
"require 'sequel_core'" if you don't want the model functionality.
|
26
|
+
|
27
|
+
Database Adapter Improvements
|
28
|
+
-----------------------------
|
29
|
+
|
30
|
+
* Dataset#empty? now works using the MySQL adapter.
|
31
|
+
|
32
|
+
* The Oracle adapter now works with a nonstandard database port.
|
33
|
+
|
34
|
+
* The JDBC adapter should load JDBC drivers automatically for
|
35
|
+
PostgreSQL, MySQL, SQLite, Oracle, and MSSQL. For PostgreSQL,
|
36
|
+
MySQL, and SQLite, the jdbc-* gem can be used, for the others, you
|
37
|
+
must have the correct .jar in your CLASSPATH.
|
38
|
+
|
39
|
+
* The PostgreSQL adapter no longer raises an error when inserting
|
40
|
+
records into a table without a primary key.
|
41
|
+
|
42
|
+
* Database#disconnect now works for the ADO adapter.
|
43
|
+
|
44
|
+
* The ADO adapter no longer raises an error if the dataset contains
|
45
|
+
no records.
|
46
|
+
|
47
|
+
* The ODBC adapter no longer errors when converting ::ODBC::Time
|
48
|
+
values.
|
49
|
+
|
50
|
+
Backwards Incompatible Changes
|
51
|
+
------------------------------
|
52
|
+
|
53
|
+
* Sequel::Worker has been removed. There are no known users, and the
|
54
|
+
specs caused problems on JRuby.
|
55
|
+
|
56
|
+
* Assigning an empty string to a non-string, non-blob model attribute
|
57
|
+
converts it to nil by default. You can use
|
58
|
+
"Model.typecast_empty_string_to_nil = false" to get the old
|
59
|
+
behavior. This should make web development with Sequel
|
60
|
+
significantly easier, hopefully at no expense to other uses.
|
61
|
+
|
62
|
+
* Database.uri_to_options is now a private class method.
|
63
|
+
|
64
|
+
* Model.create_table! now acts the same as Database.create_table!,
|
65
|
+
dropping the table unconditionally and then creating it. This was
|
66
|
+
done for consistency. If you are using Model.create_table! in
|
67
|
+
production code, you should change it to
|
68
|
+
"Model.create_table unless Model.table_exists?", otherwise you risk
|
69
|
+
wiping out your production data. I recommended you use the
|
70
|
+
migration feature instead of Model.set_schema, as that handles
|
71
|
+
altering existing tables.
|
72
|
+
|
73
|
+
Other Notable Changes
|
74
|
+
---------------------
|
75
|
+
|
76
|
+
* Using validates_length_of more than once on the same attribute with
|
77
|
+
different options without a tag no longer causes the first use to
|
78
|
+
be ignored. This was a side effect of the validation tags added
|
79
|
+
in 2.2.0.
|
80
|
+
|
81
|
+
* Other than the adapters, Sequel now has 100% code coverage (line
|
82
|
+
coverage).
|
83
|
+
|
84
|
+
* Model#set* methods now return self.
|
85
|
+
|
86
|
+
* An integration test suite was added, testing Sequel against a live
|
87
|
+
database with nothing mocked, which helped greatly when testing the
|
88
|
+
new support for JDBC adapters.
|
@@ -0,0 +1,106 @@
|
|
1
|
+
Prepared Statements/Bound Variables
|
2
|
+
===================================
|
3
|
+
|
4
|
+
Sequel now supports prepared statements and bound variables. No
|
5
|
+
matter which database you are using, Sequel uses exactly the same API.
|
6
|
+
To specify placeholders, you use the :$placeholder syntax:
|
7
|
+
|
8
|
+
ds = DB[:items].filter(:name=>:$n)
|
9
|
+
|
10
|
+
To use a bound variable:
|
11
|
+
|
12
|
+
ds.call(:select, :n=>'Jim')
|
13
|
+
|
14
|
+
This will do the equivalent of selecting records that have the name
|
15
|
+
'Jim'. In addition to :select, you can use :first or :delete. There
|
16
|
+
is also support for bound variables when inserting or updating
|
17
|
+
records:
|
18
|
+
|
19
|
+
ds.call(:update, {:n=>'Jim', :new_n=>'Bob'}, :name=>:$new_n)
|
20
|
+
|
21
|
+
Which will update all records that have the name 'Jim' to have the
|
22
|
+
name 'Bob'.
|
23
|
+
|
24
|
+
Prepared statement support is very similar to bound variable support,
|
25
|
+
except that the statement is first prepared with a name:
|
26
|
+
|
27
|
+
ps = ds.prepare(:select, :select_by_name)
|
28
|
+
|
29
|
+
It is then called later with the bound arguments to use:
|
30
|
+
|
31
|
+
ps.call(:n=>'Jim')
|
32
|
+
DB.call(:select_by_name, :n=>'Jim') # same as above
|
33
|
+
|
34
|
+
For inserting or updating, the hash to use when inserting or updating
|
35
|
+
is given to prepare:
|
36
|
+
|
37
|
+
ps2 = ds.prepare(:update, :update_name, :name=>:$new_n)
|
38
|
+
ps2.call(:n=>'Jim', :new_n=>'Bob')
|
39
|
+
|
40
|
+
There is some level of native support for these features in the
|
41
|
+
PostgreSQL, MySQL, SQLite, and JDBC adapters. For other adapters,
|
42
|
+
support is emulated, but it shouldn't be too difficult to add native
|
43
|
+
support for them.
|
44
|
+
|
45
|
+
For more details see:
|
46
|
+
http://sequel.rubyforge.org/rdoc/files/doc/prepared_statements_rdoc.html
|
47
|
+
|
48
|
+
Read-Only Slave/Writable Master and Database Sharding
|
49
|
+
=====================================================
|
50
|
+
|
51
|
+
Sequel now has built in support for master/slave database
|
52
|
+
configurations, just by setting an option in Sequel.connect:
|
53
|
+
|
54
|
+
DB=Sequel.connect('postgres://master_server/database', \
|
55
|
+
:servers=>{:read_only=>{:host=>'slave_server'}})
|
56
|
+
|
57
|
+
That will use slave_server for SELECT queries and master_server for
|
58
|
+
other queries. It's fairly easy to use multiple slaves or even
|
59
|
+
multiple masters, examples are included in the link below.
|
60
|
+
|
61
|
+
Sharding support requires some code other than the database
|
62
|
+
configuration, but is still fairly simple. For example, to set up
|
63
|
+
a 16 shard configuration based on a hex character:
|
64
|
+
|
65
|
+
servers = {}
|
66
|
+
(('0'..'9').to_a + ('a'..'f').to_a).each do |hex|
|
67
|
+
servers[hex.to_sym] = {:host=>"hash_host_#{hex}"}
|
68
|
+
end
|
69
|
+
DB=Sequel.connect('postgres://hash_host/hashes', :servers=>servers)
|
70
|
+
|
71
|
+
To set which shard to use for a query, use the Dataset#server method:
|
72
|
+
|
73
|
+
DB[:hashes].server(:a).filter(:hash=>/31337/)
|
74
|
+
|
75
|
+
For more details see:
|
76
|
+
http://sequel.rubyforge.org/rdoc/files/doc/sharding_rdoc.html
|
77
|
+
|
78
|
+
Other Changes
|
79
|
+
=============
|
80
|
+
|
81
|
+
* The sequel.rubyforge.org website has a new design thanks to boof.
|
82
|
+
The online RDoc is now located at http://sequel.rubyforge.org/rdoc.
|
83
|
+
|
84
|
+
* Support was added for anonymous column names in the ADO adapter.
|
85
|
+
|
86
|
+
* Better MSSQL support in the ADO, ODBC, and JDBC adapters. The
|
87
|
+
odbc_mssql adapter has been removed. If you use MSSQL with ODBC,
|
88
|
+
please use the odbc adapter with a :db_type=>'mssql' option.
|
89
|
+
|
90
|
+
* The following Sequel::Error exception subclasses were removed:
|
91
|
+
InvalidExpression, InvalidFilter, InvalidJoinType, and WorkerStop.
|
92
|
+
|
93
|
+
* Documentation was added for the PostgreSQL, MySQL, SQLite, and
|
94
|
+
JDBC adapters.
|
95
|
+
|
96
|
+
* Various internal interfaces were refactored. For example, if you
|
97
|
+
use an adapter not included with Sequel, it probably won't work
|
98
|
+
until you update it to the new internal API.
|
99
|
+
|
100
|
+
* Many low level methods (such as Database#transaction), now take
|
101
|
+
an optional server argument to indicate which server to use.
|
102
|
+
|
103
|
+
* Model plugins that have a DatasetMethods module with non-public
|
104
|
+
methods no longer have Model methods created that call those
|
105
|
+
methods.
|
106
|
+
|
@@ -0,0 +1,137 @@
|
|
1
|
+
New Features
|
2
|
+
------------
|
3
|
+
|
4
|
+
* The values that are used to insert/update records can now be
|
5
|
+
scoped similar to how filter expressions can be scoped.
|
6
|
+
set_defaults is used to set defaults which can be overridden,
|
7
|
+
and set_overrides is used to set defaults which cannot be
|
8
|
+
overridden:
|
9
|
+
|
10
|
+
DB[:t].set_defaults(:x=>1).insert_sql
|
11
|
+
# => INSERT INTO t (x) VALUES (1)
|
12
|
+
DB[:t].set_defaults(:x=>1).insert_sql(:x=>2)
|
13
|
+
# => INSERT INTO t (x) VALUES (2)
|
14
|
+
DB[:t].set_defaults(:x=>1).insert_sql(:y=>2)
|
15
|
+
# => INSERT INTO t (x, y) VALUES (1, 2)
|
16
|
+
DB[:t].set_overrides(:x=>1).insert_sql(:x=>2)
|
17
|
+
# => INSERT INTO t (x) VALUES (1)
|
18
|
+
|
19
|
+
The difference between set_defaults and set_overrides is that
|
20
|
+
with set_defaults, the last value takes precedence, while with
|
21
|
+
set_overrides, the first value takes precedence.
|
22
|
+
|
23
|
+
* The schema generators now support creating and altering tables
|
24
|
+
with composite primary and/or foreign keys:
|
25
|
+
|
26
|
+
DB.create_table(:items) do
|
27
|
+
integer :id
|
28
|
+
text :name
|
29
|
+
primary_key [:id, :name]
|
30
|
+
foreign_key [:id, :name], :other_table, \
|
31
|
+
:key=>[:item_id, :item_name]
|
32
|
+
end
|
33
|
+
|
34
|
+
DB.alter_table(:items) do
|
35
|
+
add_primary_key [:id, :name]
|
36
|
+
add_foreign_key [:id, :name], :other_table, \
|
37
|
+
:key=>[:item_id, :item_name]
|
38
|
+
end
|
39
|
+
|
40
|
+
* The AlterTableGenerator now supports unique constraints:
|
41
|
+
|
42
|
+
DB.alter_table(:items) do
|
43
|
+
add_unique_constraint [:aaa, :bbb, :ccc], :name => :con3
|
44
|
+
end
|
45
|
+
|
46
|
+
* The schema generators now support ON UPDATE (previously, they only
|
47
|
+
supported ON DELETE):
|
48
|
+
|
49
|
+
DB.create_table(:items) do
|
50
|
+
foreign_key :project_id, :projects, :on_update => :cascade
|
51
|
+
end
|
52
|
+
|
53
|
+
* When connecting to a PostgreSQL server version 8.2 and higher,
|
54
|
+
Sequel now uses the INSERT ... RETURNING ... syntax, which should
|
55
|
+
speed up row inserts on PostgreSQL. In addition, Sequel Models
|
56
|
+
use RETURNING * to speed up model object creation.
|
57
|
+
|
58
|
+
* You can now validate multiple attributes at once. This is useful
|
59
|
+
if the combination of two or more attribute values is important,
|
60
|
+
such as checking the uniqueness of multiple columns.
|
61
|
+
validates_uniqueness_of now supports this directly:
|
62
|
+
|
63
|
+
validates_uniqueness_of [:column1, :column2]
|
64
|
+
|
65
|
+
This protects against the database having multiple rows with the
|
66
|
+
same values for both :column1 and :column2. This is different
|
67
|
+
from:
|
68
|
+
|
69
|
+
validates_uniqueness_of :column1, :column2
|
70
|
+
|
71
|
+
Which checks that the value of column1 is unique in the table, and
|
72
|
+
that the value of column2 is unique in the table (which is much
|
73
|
+
more restrictive).
|
74
|
+
|
75
|
+
Other Improvements
|
76
|
+
------------------
|
77
|
+
|
78
|
+
* Dataset methods insert_sql, delete_sql, and update_sql respect the
|
79
|
+
:sql option, allowing you to do things such as:
|
80
|
+
|
81
|
+
ds = DB['INSERT INTO t (time) VALUES (CURRENT_TIMESTAMP)']
|
82
|
+
ds.insert
|
83
|
+
ds.insert
|
84
|
+
|
85
|
+
* The database adapters (at least MySQL, PostgreSQL, SQLite, and
|
86
|
+
JDBC) generally raise Sequel::DatabaseError for database problems,
|
87
|
+
making it easier to tell what is a true database error versus an
|
88
|
+
error raised by Sequel itself.
|
89
|
+
|
90
|
+
* Sequel uses the async features of ruby-pg so that the entire
|
91
|
+
interpreter is not blocked while waiting for the results of
|
92
|
+
queries.
|
93
|
+
|
94
|
+
* Sequel now supports the 2008.08.17 version of ruby-pg.
|
95
|
+
|
96
|
+
* MSSQL support has been improved when using the ODBC and ADO
|
97
|
+
adapters.
|
98
|
+
|
99
|
+
* Index names are quoted and creating or dropping indexes.
|
100
|
+
|
101
|
+
* Automatically generated column accessor methods no longer override
|
102
|
+
instance methods specified by plugins.
|
103
|
+
|
104
|
+
* Inserting a row with an already specified primary key inside a
|
105
|
+
transaction now works correctly when using PostgreSQL.
|
106
|
+
|
107
|
+
* before_save and before_update hooks now work as expected when using
|
108
|
+
save_changes.
|
109
|
+
|
110
|
+
* count and paginate now work correctly on graphed datasets.
|
111
|
+
|
112
|
+
Backwards Compatibility
|
113
|
+
-----------------------
|
114
|
+
|
115
|
+
* The SQLite adapter now raises Sequel::DatabaseError instead of
|
116
|
+
Sequel::Error::InvalidStatement whenever an SQLite3::Exception is
|
117
|
+
raised by the SQLite3 driver.
|
118
|
+
|
119
|
+
* Date and DateTime conversions now convert 2 digit years. To revert
|
120
|
+
to the previous behavior:
|
121
|
+
|
122
|
+
Sequel.convert_two_digit_years = false
|
123
|
+
|
124
|
+
Note that Ruby 1.8 and 1.9 handle Date parsing differently, so
|
125
|
+
there is no backwards compatibility change for Ruby 1.9. However,
|
126
|
+
this also means that the MM/DD/YY date syntax commonly used in the
|
127
|
+
United States is not always parsed correctly on Ruby 1.9, greatly
|
128
|
+
limiting the use of 2 digit year conversion.
|
129
|
+
|
130
|
+
* You can no longer abuse the SQL function syntax for specifying
|
131
|
+
database types. For example, you must change:
|
132
|
+
|
133
|
+
:type=>:varchar[255]
|
134
|
+
|
135
|
+
to:
|
136
|
+
|
137
|
+
:type=>:varchar, :size=>255
|