sequel 3.36.1 → 3.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +84 -0
- data/Rakefile +13 -0
- data/bin/sequel +12 -16
- data/doc/advanced_associations.rdoc +36 -67
- data/doc/association_basics.rdoc +11 -16
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/schema_modification.rdoc +4 -0
- data/lib/sequel/adapters/jdbc/h2.rb +1 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +26 -8
- data/lib/sequel/adapters/mysql2.rb +4 -3
- data/lib/sequel/adapters/odbc/mssql.rb +2 -2
- data/lib/sequel/adapters/postgres.rb +4 -60
- data/lib/sequel/adapters/shared/mssql.rb +2 -1
- data/lib/sequel/adapters/shared/mysql.rb +0 -5
- data/lib/sequel/adapters/shared/postgres.rb +68 -2
- data/lib/sequel/adapters/shared/sqlite.rb +17 -1
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +12 -1
- data/lib/sequel/adapters/utils/pg_types.rb +76 -0
- data/lib/sequel/core.rb +13 -0
- data/lib/sequel/database/misc.rb +41 -1
- data/lib/sequel/database/schema_generator.rb +23 -10
- data/lib/sequel/database/schema_methods.rb +26 -4
- data/lib/sequel/dataset/graph.rb +2 -1
- data/lib/sequel/dataset/query.rb +62 -2
- data/lib/sequel/extensions/_pretty_table.rb +7 -3
- data/lib/sequel/extensions/arbitrary_servers.rb +5 -4
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +13 -2
- data/lib/sequel/extensions/core_extensions.rb +6 -0
- data/lib/sequel/extensions/eval_inspect.rb +158 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +4 -1
- data/lib/sequel/extensions/named_timezones.rb +4 -0
- data/lib/sequel/extensions/null_dataset.rb +4 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +219 -168
- data/lib/sequel/extensions/pg_array_ops.rb +7 -2
- data/lib/sequel/extensions/pg_auto_parameterize.rb +10 -4
- data/lib/sequel/extensions/pg_hstore.rb +3 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +7 -2
- data/lib/sequel/extensions/pg_inet.rb +28 -3
- data/lib/sequel/extensions/pg_interval.rb +192 -0
- data/lib/sequel/extensions/pg_json.rb +21 -9
- data/lib/sequel/extensions/pg_range.rb +487 -0
- data/lib/sequel/extensions/pg_range_ops.rb +122 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +3 -2
- data/lib/sequel/extensions/pretty_table.rb +12 -1
- data/lib/sequel/extensions/query.rb +4 -0
- data/lib/sequel/extensions/query_literals.rb +6 -6
- data/lib/sequel/extensions/schema_dumper.rb +39 -38
- data/lib/sequel/extensions/select_remove.rb +4 -0
- data/lib/sequel/extensions/server_block.rb +3 -2
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +4 -0
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +9 -3
- data/lib/sequel/extensions/to_dot.rb +4 -0
- data/lib/sequel/model/associations.rb +150 -91
- data/lib/sequel/plugins/identity_map.rb +2 -2
- data/lib/sequel/plugins/list.rb +1 -0
- data/lib/sequel/plugins/many_through_many.rb +33 -32
- data/lib/sequel/plugins/nested_attributes.rb +11 -3
- data/lib/sequel/plugins/rcte_tree.rb +2 -2
- data/lib/sequel/plugins/schema.rb +1 -1
- data/lib/sequel/sql.rb +14 -14
- data/lib/sequel/version.rb +2 -2
- data/spec/adapters/mysql_spec.rb +25 -0
- data/spec/adapters/postgres_spec.rb +572 -28
- data/spec/adapters/sqlite_spec.rb +16 -1
- data/spec/core/database_spec.rb +61 -2
- data/spec/core/dataset_spec.rb +92 -0
- data/spec/core/expression_filters_spec.rb +12 -0
- data/spec/extensions/arbitrary_servers_spec.rb +1 -1
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/eval_inspect_spec.rb +58 -0
- data/spec/extensions/json_serializer_spec.rb +0 -6
- data/spec/extensions/list_spec.rb +1 -1
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +81 -0
- data/spec/extensions/nested_attributes_spec.rb +21 -4
- data/spec/extensions/pg_array_ops_spec.rb +1 -11
- data/spec/extensions/pg_array_spec.rb +181 -90
- data/spec/extensions/pg_auto_parameterize_spec.rb +3 -3
- data/spec/extensions/pg_hstore_spec.rb +1 -3
- data/spec/extensions/pg_inet_spec.rb +6 -1
- data/spec/extensions/pg_interval_spec.rb +73 -0
- data/spec/extensions/pg_json_spec.rb +5 -9
- data/spec/extensions/pg_range_ops_spec.rb +49 -0
- data/spec/extensions/pg_range_spec.rb +372 -0
- data/spec/extensions/pg_statement_cache_spec.rb +1 -2
- data/spec/extensions/query_literals_spec.rb +1 -2
- data/spec/extensions/schema_dumper_spec.rb +48 -89
- data/spec/extensions/serialization_spec.rb +1 -5
- data/spec/extensions/server_block_spec.rb +2 -2
- data/spec/extensions/spec_helper.rb +12 -2
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/integration/associations_test.rb +4 -4
- data/spec/integration/database_test.rb +2 -2
- data/spec/integration/dataset_test.rb +4 -4
- data/spec/integration/eager_loader_test.rb +6 -6
- data/spec/integration/plugin_test.rb +2 -2
- data/spec/integration/spec_helper.rb +2 -2
- data/spec/model/association_reflection_spec.rb +5 -0
- data/spec/model/associations_spec.rb +156 -49
- data/spec/model/eager_loading_spec.rb +137 -2
- data/spec/model/model_spec.rb +10 -10
- metadata +15 -2
data/CHANGELOG
CHANGED
|
@@ -1,3 +1,87 @@
|
|
|
1
|
+
=== 3.37.0 (2012-07-02)
|
|
2
|
+
|
|
3
|
+
* Allow specifying eager_graph alias base on a per-call basis using an AliasedExpression (jeremyevans)
|
|
4
|
+
|
|
5
|
+
* Allow bin/sequel to respect multiple -l options for logging to multiple files (jeremyevans)
|
|
6
|
+
|
|
7
|
+
* Correctly handle cases where SCOPE_IDENTITY is nil in the odbc/mssql adapter (stnoonan, jeremyevans)
|
|
8
|
+
|
|
9
|
+
* Add pg_interval extension, for returning interval types as ActiveSupport::Duration instances (jeremyevans)
|
|
10
|
+
|
|
11
|
+
* Save a new one_to_one associated object once instead of twice in the nested_attributes plugin (jeremyevans)
|
|
12
|
+
|
|
13
|
+
* Don't add unnecessary filter condition when passing a new object to a one_to_one setter method (jeremyevans)
|
|
14
|
+
|
|
15
|
+
* Differentiate between column references and method references in many_through_many associations (jeremyevans)
|
|
16
|
+
|
|
17
|
+
* Use :qualify=>:deep option when joining tables in model association datasets (jeremyevans)
|
|
18
|
+
|
|
19
|
+
* Support :qualify=>:deep option to Dataset#join_table to qualify subexpressions in the expression tree (jeremyevans)
|
|
20
|
+
|
|
21
|
+
* Support :qualify=>false option to Dataset#join_table to not automatically qualify keys/values (jeremyevans)
|
|
22
|
+
|
|
23
|
+
* Make filter by associations support use column references and method references correctly (jeremyevans)
|
|
24
|
+
|
|
25
|
+
* Call super in list plugin before_create (jeremyevans) (#504)
|
|
26
|
+
|
|
27
|
+
* Do not automatically cast String to text in pg_auto_parameterize extension (jeremyevans)
|
|
28
|
+
|
|
29
|
+
* Support alter_table validate_constraint on PostgreSQL for validating constraints previously declared with NOT VALID (jeremyevans)
|
|
30
|
+
|
|
31
|
+
* Support :not_valid option when adding foreign key constraints on PostgreSQL (jeremyevans)
|
|
32
|
+
|
|
33
|
+
* Support exclusion constraints on PostgreSQL (jeremyevans)
|
|
34
|
+
|
|
35
|
+
* Allow for overriding the create/alter table generators used per Database object (jeremyevans)
|
|
36
|
+
|
|
37
|
+
* Make casting to Date/(Time/DateTime) use date/datetime functions on SQLite (jeremyevans)
|
|
38
|
+
|
|
39
|
+
* Add pg_range_ops extension for DSL support for PostgreSQL range operators and functions (jeremyevans)
|
|
40
|
+
|
|
41
|
+
* The json library is now required when running the plugin/extension specs (jeremyevans)
|
|
42
|
+
|
|
43
|
+
* Use change migrations instead of up/down migrations in the schema_dumper (jeremyevans)
|
|
44
|
+
|
|
45
|
+
* Dump unsigned integer columns with a check >= 0 constraint in the schema_dumper (stu314)
|
|
46
|
+
|
|
47
|
+
* Switch the :key_hash entry to the association :eager_loader option to use the method symbol(s) instead of the column symbol(s) (jeremyevans)
|
|
48
|
+
|
|
49
|
+
* Add :id_map entry to the hash passed to the association :eager_loader option, for easier custom eager loading (jeremyevans)
|
|
50
|
+
|
|
51
|
+
* Fix dumping of non-integer foreign key columns in the schema_dumper (jeremyevans) (#502)
|
|
52
|
+
|
|
53
|
+
* Add nested_attributes :fields option to be a proc that is called with the associated object (chanks) (#498)
|
|
54
|
+
|
|
55
|
+
* Add split_array_nil extension, for compiling :col=>[1, nil] to col IN (1) OR col IS NULL (jeremyevans)
|
|
56
|
+
|
|
57
|
+
* Add Database#extension and Dataset#extension for loading extension modules into objects automatically (jeremyevans)
|
|
58
|
+
|
|
59
|
+
* Respect an existing dataset limit when updating on Microsoft SQL Server (jeremyevans)
|
|
60
|
+
|
|
61
|
+
* Add pg_range extension, for dealing with PostgreSQL 9.2+ range types (jeremyevans)
|
|
62
|
+
|
|
63
|
+
* Make pg_array extension convert array members when typecasting Array to PGArray (jeremyevans)
|
|
64
|
+
|
|
65
|
+
* Make jdbc/postgres adapter convert array type elements (e.g. date[] arrays are returned as arrays of Date instances) (jeremyevans)
|
|
66
|
+
|
|
67
|
+
* Make the pg_inet extension handle inet[]/cidr[]/macaddr[] types when used with the pg_array extension (jeremyevans)
|
|
68
|
+
|
|
69
|
+
* Make the pg_json extension handle json[] type when used with the pg_array extension (jeremyevans)
|
|
70
|
+
|
|
71
|
+
* Fix schema parsing of h2 clob types (jeremyevans)
|
|
72
|
+
|
|
73
|
+
* Make the pg_array extension handle array types for scalar types handled by the native postgres adapter (jeremyevans)
|
|
74
|
+
|
|
75
|
+
* Generalize handling of array types in the pg_array extension, allowing easy support of custom array types (jeremyevans)
|
|
76
|
+
|
|
77
|
+
* Remove type conversion of int2vector and money types on PostgreSQL, since previous conversions were wrong (jeremyevans)
|
|
78
|
+
|
|
79
|
+
* Add eval_inspect extension, which makes Sequel::SQL::Expression#inspect attempt to return a string suitable for eval (jeremyevans)
|
|
80
|
+
|
|
81
|
+
* When emulating offset with ROW_NUMBER, default to ordering by all columns if no specific order is given (stnoonan, jeremyevans) (#490)
|
|
82
|
+
|
|
83
|
+
* Work around JRuby 1.6 ruby 1.9 mode bug in Time -> SQLTime conversion (jeremyevans)
|
|
84
|
+
|
|
1
85
|
=== 3.36.1 (2012-06-01)
|
|
2
86
|
|
|
3
87
|
* Fix jdbc adapter when DriverManager#getConnection fails (aportnov) (#488)
|
data/Rakefile
CHANGED
|
@@ -138,6 +138,19 @@ begin
|
|
|
138
138
|
%w'postgres sqlite mysql informix oracle firebird mssql db2'.each do |adapter|
|
|
139
139
|
spec_with_cov.call("spec_#{adapter}", ["spec/adapters/#{adapter}_spec.rb"] + Dir["spec/integration/*_test.rb"], "Run #{adapter} specs"){|t| t.rcov_opts.concat(%w'--exclude "lib/sequel/([a-z_]+\.rb|connection_pool|database|dataset|model|extensions|plugins)"')}
|
|
140
140
|
end
|
|
141
|
+
|
|
142
|
+
task :spec_travis=>[:spec, :spec_plugin, :spec_sqlite] do
|
|
143
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
|
144
|
+
ENV['SEQUEL_PG_SPEC_DB'] = "jdbc:postgresql://localhost/sequel_test?user=postgres"
|
|
145
|
+
ENV['SEQUEL_MY_SPEC_DB'] = "jdbc:mysql://localhost/sequel_test?user=root"
|
|
146
|
+
else
|
|
147
|
+
ENV['SEQUEL_PG_SPEC_DB'] = "postgres://localhost/sequel_test?user=postgres"
|
|
148
|
+
ENV['SEQUEL_MY_SPEC_DB'] = "mysql2://localhost/sequel_test?user=root"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
Rake::Task['spec_postgres'].invoke
|
|
152
|
+
Rake::Task['spec_mysql'].invoke
|
|
153
|
+
end
|
|
141
154
|
|
|
142
155
|
desc "Run model specs without the associations code"
|
|
143
156
|
task :spec_model_no_assoc do
|
data/bin/sequel
CHANGED
|
@@ -4,18 +4,17 @@ require 'rubygems'
|
|
|
4
4
|
require 'optparse'
|
|
5
5
|
require 'sequel'
|
|
6
6
|
|
|
7
|
-
db_opts = {:test=>true}
|
|
8
7
|
copy_databases = nil
|
|
9
8
|
dump_migration = nil
|
|
10
9
|
dump_schema = nil
|
|
11
|
-
echo = nil
|
|
12
10
|
env = nil
|
|
13
|
-
logfile = nil
|
|
14
11
|
migrate_dir = nil
|
|
15
12
|
migrate_ver = nil
|
|
16
13
|
backtrace = nil
|
|
14
|
+
test = true
|
|
17
15
|
load_dirs = []
|
|
18
16
|
exclusive_options = []
|
|
17
|
+
loggers = []
|
|
19
18
|
|
|
20
19
|
opts = OptionParser.new do |opts|
|
|
21
20
|
opts.banner = "Sequel: The Database Toolkit for Ruby"
|
|
@@ -54,7 +53,8 @@ opts = OptionParser.new do |opts|
|
|
|
54
53
|
end
|
|
55
54
|
|
|
56
55
|
opts.on("-E", "--echo", "echo SQL statements") do
|
|
57
|
-
|
|
56
|
+
require 'logger'
|
|
57
|
+
loggers << Logger.new($stdout)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
opts.on("-I", "--include dir", "specify $LOAD_PATH directory") do |v|
|
|
@@ -62,7 +62,8 @@ opts = OptionParser.new do |opts|
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
opts.on("-l", "--log logfile", "log SQL statements to log file") do |v|
|
|
65
|
-
|
|
65
|
+
require 'logger'
|
|
66
|
+
loggers << Logger.new(v)
|
|
66
67
|
end
|
|
67
68
|
|
|
68
69
|
opts.on("-L", "--load-dir DIR", "loads all *.rb under specifed directory") do |v|
|
|
@@ -79,7 +80,7 @@ opts = OptionParser.new do |opts|
|
|
|
79
80
|
end
|
|
80
81
|
|
|
81
82
|
opts.on("-N", "--no-test-connection", "do not test the connection") do
|
|
82
|
-
|
|
83
|
+
test = false
|
|
83
84
|
end
|
|
84
85
|
|
|
85
86
|
opts.on("-r", "--require lib", "require the library, before executing your script") do |v|
|
|
@@ -112,26 +113,21 @@ end
|
|
|
112
113
|
error_proc["Error: Must specify -m if using -M"] if migrate_ver && !migrate_dir
|
|
113
114
|
error_proc["Error: Cannot specify #{exclusive_options.map{|v| "-#{v}"}.join(' and ')} together"] if exclusive_options.length > 1
|
|
114
115
|
|
|
115
|
-
if logfile || echo
|
|
116
|
-
require 'logger'
|
|
117
|
-
db_opts[:loggers] = []
|
|
118
|
-
db_opts[:loggers] << Logger.new(logfile) if logfile
|
|
119
|
-
db_opts[:loggers] << Logger.new($stdout) if echo
|
|
120
|
-
end
|
|
121
|
-
|
|
122
116
|
connect_proc = lambda do |database|
|
|
123
117
|
db = if database.nil? || database.empty?
|
|
124
|
-
Sequel.connect('mock:///'
|
|
118
|
+
Sequel.connect('mock:///')
|
|
125
119
|
elsif File.exist?(database)
|
|
126
120
|
require 'yaml'
|
|
127
121
|
env ||= "development"
|
|
128
122
|
db_config = YAML.load_file(database)
|
|
129
123
|
db_config = db_config[env] || db_config[env.to_sym] || db_config
|
|
130
124
|
db_config.keys.each{|k| db_config[k.to_sym] = db_config.delete(k)}
|
|
131
|
-
Sequel.connect(db_config
|
|
125
|
+
Sequel.connect(db_config)
|
|
132
126
|
else
|
|
133
|
-
Sequel.connect(database
|
|
127
|
+
Sequel.connect(database)
|
|
134
128
|
end
|
|
129
|
+
db.loggers = loggers
|
|
130
|
+
db.test_connection if test
|
|
135
131
|
db
|
|
136
132
|
end
|
|
137
133
|
|
|
@@ -75,19 +75,15 @@ option. Though it can often be verbose (compared to other things in Sequel),
|
|
|
75
75
|
it allows you complete control over how to eagerly load associations for a
|
|
76
76
|
group of objects.
|
|
77
77
|
|
|
78
|
-
:eager_loader should be a proc that takes
|
|
79
|
-
|
|
78
|
+
:eager_loader should be a proc that takes a single hash argument, which will
|
|
79
|
+
have at least the following keys:
|
|
80
80
|
|
|
81
|
-
:
|
|
81
|
+
:id_map :: A mapping of key values to arrays of current model instances,
|
|
82
|
+
usage described below
|
|
82
83
|
:rows :: An array of model objects
|
|
83
84
|
:associations :: A hash of dependent associations to eagerly load
|
|
84
85
|
:self :: The dataset that is doing the eager loading
|
|
85
|
-
|
|
86
|
-
If the proc takes three arguments, it gets passed the :key_hash, :rows,
|
|
87
|
-
and :associations values. The only way to get the :self value is to
|
|
88
|
-
accept one argument. The 3 argument procs are allowed for backwards
|
|
89
|
-
compatibility, and it is recommended to use the 1 argument proc format
|
|
90
|
-
for new code.
|
|
86
|
+
:eager_block :: A dynamic callback for this eager load.
|
|
91
87
|
|
|
92
88
|
Since you are given all of the records, you can do things like filter on
|
|
93
89
|
associations that are specified by multiple keys, or do multiple
|
|
@@ -98,13 +94,12 @@ associations cache for all objects in the array of records. The hash
|
|
|
98
94
|
of dependent associations is available for you to cascade the eager
|
|
99
95
|
loading down multiple levels, but it is up to you to use it.
|
|
100
96
|
|
|
101
|
-
The
|
|
102
|
-
association loaders and is also available to you. It is a hash with keys
|
|
103
|
-
foreign/primary key
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
give an example. Let's say you have the following associations
|
|
97
|
+
The id_map is a performance enhancement that is used by the default
|
|
98
|
+
association loaders and is also available to you. It is a hash with keys
|
|
99
|
+
foreign/primary key values, and values being arrays of current model
|
|
100
|
+
objects having the foreign/primary key value associated with the key.
|
|
101
|
+
This may be hard to visualize, so I'll give an example. Let's say you
|
|
102
|
+
have the following associations
|
|
108
103
|
|
|
109
104
|
Album.many_to_one :artist
|
|
110
105
|
Album.one_to_many :tracks
|
|
@@ -113,53 +108,30 @@ and the following two albums in the database:
|
|
|
113
108
|
|
|
114
109
|
album1 = Album.create(:artist_id=>3) # id: 1
|
|
115
110
|
album2 = Album.create(:artist_id=>3) # id: 2
|
|
111
|
+
album3 = Album.create(:artist_id=>2) # id: 3
|
|
116
112
|
|
|
117
113
|
If you try to eager load this dataset:
|
|
118
114
|
|
|
119
115
|
Album.eager(:artist, :tracks).all
|
|
120
116
|
|
|
121
|
-
Then the
|
|
122
|
-
|
|
123
|
-
{:id=>{1=>[album1], 2=>[album2]}, :artist_id=>{3=>[album1, album2]}}
|
|
124
|
-
|
|
125
|
-
Let's break down the reason for the makeup of this key_hash. The hash has keys for
|
|
126
|
-
each of foreign/primary keys used in the association. In this case, the artist
|
|
127
|
-
association needs the artist_id foreign key (since it is a many_to_one), and the
|
|
128
|
-
tracks association needs the id primary key (since it is a one_to_many).
|
|
129
|
-
|
|
130
|
-
If you only eagerly loaded the artist association:
|
|
131
|
-
|
|
132
|
-
Album.eager(:artist).all
|
|
133
|
-
|
|
134
|
-
Then the key_hash would only contain artist_id information:
|
|
135
|
-
|
|
136
|
-
{:artist_id=>{3=>[album1, album2]}}
|
|
137
|
-
|
|
138
|
-
Likewise, if you only eagerly loaded the tracks association:
|
|
139
|
-
|
|
140
|
-
Album.eager(:tracks).all
|
|
141
|
-
|
|
142
|
-
Then the key_hash would only contain id information:
|
|
143
|
-
|
|
144
|
-
{:id=>{1=>[album1], 2=>[album2]}}
|
|
145
|
-
|
|
146
|
-
Now, the eager loader for the artist association is only going to care about the
|
|
147
|
-
value of the artist_id key in the hash, so it's going to do the equivalent of:
|
|
117
|
+
Then the id_map provided to the artist :eager_loader proc would be:
|
|
148
118
|
|
|
149
|
-
|
|
119
|
+
{3=>[album1, album2], 2=>[album3]}
|
|
150
120
|
|
|
151
|
-
The
|
|
152
|
-
album objects. Since
|
|
153
|
-
|
|
121
|
+
The artist id_map contains a mapping of artist_id values to arrays of
|
|
122
|
+
album objects. Since both album1 and album2 have the same artist_id,
|
|
123
|
+
the are both in the array related to that key. album3 has a different
|
|
124
|
+
artist_id, so it is in a different array. Eager loading of artists is
|
|
125
|
+
done by looking for any artist having one of the keys in the hash:
|
|
154
126
|
|
|
155
|
-
artists = Artist.where(:id=>
|
|
127
|
+
artists = Artist.where(:id=>id_map.keys).all
|
|
156
128
|
|
|
157
129
|
When the artists are retrieved, you can iterate over them, find entries
|
|
158
130
|
with matching keys, and manually associate them to the albums:
|
|
159
131
|
|
|
160
132
|
artists.each do |artist|
|
|
161
133
|
# Find related albums using the artist_id_map
|
|
162
|
-
if albums =
|
|
134
|
+
if albums = id_map[artist.id]
|
|
163
135
|
# Iterate over the albums
|
|
164
136
|
albums.each do |album|
|
|
165
137
|
# Manually set the artist association for each album
|
|
@@ -168,15 +140,14 @@ with matching keys, and manually associate them to the albums:
|
|
|
168
140
|
end
|
|
169
141
|
end
|
|
170
142
|
|
|
171
|
-
|
|
172
|
-
value of the id key in the hash:
|
|
143
|
+
The id_map provided to the tracks :eager_loader proc would be:
|
|
173
144
|
|
|
174
|
-
|
|
145
|
+
{1=>[album1], 2=>[album2], 3=>[album3]}
|
|
175
146
|
|
|
176
147
|
Now the id_map contains a mapping of id values to arrays of album objects (in this
|
|
177
148
|
case each array only has a single object, because id is the primary key). So when
|
|
178
149
|
looking for tracks to eagerly load, you only need to look for ones that have an
|
|
179
|
-
album_id of
|
|
150
|
+
album_id with one of the keys in the hash:
|
|
180
151
|
|
|
181
152
|
tracks = Track.where(:album_id=>id_map.keys).all
|
|
182
153
|
|
|
@@ -213,9 +184,9 @@ So putting everything together, the artist eager loader looks like:
|
|
|
213
184
|
|
|
214
185
|
:eager_loader=>(proc do |eo_opts|
|
|
215
186
|
eo_opts[:rows].each{|album| album.associations[:artist] = nil}
|
|
216
|
-
|
|
217
|
-
Artist.where(:id=>
|
|
218
|
-
if albums =
|
|
187
|
+
id_map = eo_opts[:id_map]
|
|
188
|
+
Artist.where(:id=>id_map.keys).all do |artist|
|
|
189
|
+
if albums = id_map[artist.id]
|
|
219
190
|
albums.each do |album|
|
|
220
191
|
album.associations[:artist] = artist
|
|
221
192
|
end
|
|
@@ -227,7 +198,7 @@ and the tracks eager loader looks like:
|
|
|
227
198
|
|
|
228
199
|
:eager_loader=>(proc do |eo_opts|
|
|
229
200
|
eo_opts[:rows].each{|album| album.associations[:tracks] = []}
|
|
230
|
-
id_map = eo_opts[:
|
|
201
|
+
id_map = eo_opts[:id_map]
|
|
231
202
|
Track.where(:id=>id_map.keys).all do |tracks|
|
|
232
203
|
if albums = id_map[track.album_id]
|
|
233
204
|
albums.each do |album|
|
|
@@ -245,14 +216,12 @@ the custom eager loaders described later in this page are more complex.
|
|
|
245
216
|
Basically, the eager loading steps can be broken down into:
|
|
246
217
|
|
|
247
218
|
1. Set default association values (nil/[]) for each of the current objects
|
|
248
|
-
2.
|
|
249
|
-
|
|
250
|
-
3.
|
|
251
|
-
|
|
252
|
-
4. Iterating over the returned associated objects, indexing into the custom key
|
|
253
|
-
map using the foreign/primary key value in the associated object to get
|
|
219
|
+
2. Return just related associated objects by filtering the associated class
|
|
220
|
+
to include only rows with keys present in the id_map.
|
|
221
|
+
3. Iterating over the returned associated objects, indexing into the id_map
|
|
222
|
+
using the foreign/primary key value in the associated object to get
|
|
254
223
|
current values associated to that specific object.
|
|
255
|
-
|
|
224
|
+
4. For each of those current values, updating the cached association value to
|
|
256
225
|
include that specific object.
|
|
257
226
|
|
|
258
227
|
Using the :eager_loader proc, you should be able to eagerly load all associations
|
|
@@ -631,7 +600,7 @@ name, with no duplicates?
|
|
|
631
600
|
one_to_many :songs, :order=>:songs__name, \
|
|
632
601
|
:dataset=>proc{Song.select(:songs.*).join(Lyric, :id=>:lyric_id, id=>[:composer_id, :arranger_id, :vocalist_id, :lyricist_id])}, \
|
|
633
602
|
:eager_loader=>(proc do |eo|
|
|
634
|
-
h = eo[:
|
|
603
|
+
h = eo[:id_map]
|
|
635
604
|
ids = h.keys
|
|
636
605
|
eo[:rows].each{|r| r.associations[:songs] = []}
|
|
637
606
|
Song.select(:songs.*, :lyrics__composer_id, :lyrics__arranger_id, :lyrics__vocalist_id, :lyrics__lyricist_id)\
|
|
@@ -662,11 +631,11 @@ associated tickets.
|
|
|
662
631
|
:dataset=>proc{Ticket.filter(:project_id=>id).select{sum(hours).as(hours)}},
|
|
663
632
|
:eager_loader=>(proc do |eo|
|
|
664
633
|
eo[:rows].each{|p| p.associations[:ticket_hours] = nil}
|
|
665
|
-
Ticket.filter(:project_id=>eo[:
|
|
634
|
+
Ticket.filter(:project_id=>eo[:id_map].keys).
|
|
666
635
|
group(:project_id).
|
|
667
636
|
select{[project_id, sum(hours).as(hours)]}.
|
|
668
637
|
all do |t|
|
|
669
|
-
p = eo[:
|
|
638
|
+
p = eo[:id_map][t.values.delete(:project_id)].first
|
|
670
639
|
p.associations[:ticket_hours] = t
|
|
671
640
|
end
|
|
672
641
|
end)
|
data/doc/association_basics.rdoc
CHANGED
|
@@ -473,7 +473,7 @@ associations (ones without conditions).
|
|
|
473
473
|
== Name Collisions
|
|
474
474
|
|
|
475
475
|
Because associations create instance methods, it's possible to override
|
|
476
|
-
existing instance methods if you name an
|
|
476
|
+
existing instance methods if you name an association the same as an
|
|
477
477
|
existing method. For example, <tt>values</tt> and <tt>associations</tt>
|
|
478
478
|
would be bad association names.
|
|
479
479
|
|
|
@@ -1050,7 +1050,7 @@ Column in associated table that :right_key points to, as a symbol.
|
|
|
1050
1050
|
Defaults to primary key of the associated table.
|
|
1051
1051
|
|
|
1052
1052
|
Tag.set_primary_key :tid
|
|
1053
|
-
Album.many_to_many :tags # :
|
|
1053
|
+
Album.many_to_many :tags # :right_primary_key=>:tid
|
|
1054
1054
|
|
|
1055
1055
|
Can use an array of symbols for a composite key association.
|
|
1056
1056
|
|
|
@@ -1135,8 +1135,6 @@ Called after removing an object from the association:
|
|
|
1135
1135
|
|
|
1136
1136
|
Called before the _<i>association</i>= method is called to modify the objects:
|
|
1137
1137
|
|
|
1138
|
-
Called before removing an object from the association:
|
|
1139
|
-
|
|
1140
1138
|
class Album
|
|
1141
1139
|
# Don't associate the album with an artist if the year the album was
|
|
1142
1140
|
# released is less than the year the artist/band started.
|
|
@@ -1223,13 +1221,9 @@ For many details and examples of custom eager loaders, please see the
|
|
|
1223
1221
|
==== :eager_loader_key
|
|
1224
1222
|
|
|
1225
1223
|
A symbol for the key column to use to populate the key hash for the eager
|
|
1226
|
-
loader.
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
eagerly load any associated objects for that association. If you have a
|
|
1230
|
-
custom eager loader and aren't sure of a good value to use here, and you
|
|
1231
|
-
aren't using the key_hash (first argument to the eager_loader proc), then
|
|
1232
|
-
you can probably use the primary key column of the model.
|
|
1224
|
+
loader. Generally does not need to be set manually, defaults to the key
|
|
1225
|
+
method used. Can be set to nil to not populate the key hash (better for
|
|
1226
|
+
performance if a custom eager loader does not use the key_hash).
|
|
1233
1227
|
|
|
1234
1228
|
==== :eager_block
|
|
1235
1229
|
|
|
@@ -1340,6 +1334,11 @@ This is mostly useful if you have associations with the same name in many models
|
|
|
1340
1334
|
to be able to easily tell which table alias corresponds to which association when eagerly
|
|
1341
1335
|
graphing multiple associations with the same name.
|
|
1342
1336
|
|
|
1337
|
+
You can override this option on a per-graph basis by specifying the association as an
|
|
1338
|
+
SQL::AliasedExpression instead of a symbol:
|
|
1339
|
+
|
|
1340
|
+
Album.eager_graph(Sequel.as(:artist, :a))
|
|
1341
|
+
|
|
1343
1342
|
==== :eager_grapher
|
|
1344
1343
|
|
|
1345
1344
|
Sets up a custom grapher to use when eager loading the objects via eager_graph.
|
|
@@ -1465,13 +1464,9 @@ aliases defined with <tt>Model.def_column_alias</tt>:
|
|
|
1465
1464
|
def_column_alias(:obj_id, :object_id)
|
|
1466
1465
|
end
|
|
1467
1466
|
class Obj < Sequel::Model
|
|
1468
|
-
|
|
1467
|
+
one_to_many :things, :key=>:object_id, :key_method=>:obj_id
|
|
1469
1468
|
end
|
|
1470
1469
|
|
|
1471
|
-
Note that for eager loading purposes, you generally need to set the
|
|
1472
|
-
<tt>:eager_loader_key</tt> option as well, specifying the underlying
|
|
1473
|
-
column(s) to use.
|
|
1474
|
-
|
|
1475
1470
|
==== :key_column [+many_to_one+]
|
|
1476
1471
|
|
|
1477
1472
|
Like the :key option, but :key references the method name, while
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
= New Features
|
|
2
|
+
|
|
3
|
+
* Database#extension and Dataset#extension have been added and
|
|
4
|
+
make it much easier to use extensions that just define modules,
|
|
5
|
+
where you previously had to manually extend a Database or
|
|
6
|
+
Dataset object with the module to get the extension's behavior.
|
|
7
|
+
These methods operate similarly to model plugins, where you just
|
|
8
|
+
specify the extension symbol, except that you can specify multiple
|
|
9
|
+
extensions at once:
|
|
10
|
+
|
|
11
|
+
DB.extension(:pg_array, :pg_hstore)
|
|
12
|
+
|
|
13
|
+
For databases, these modify the Database itself (and
|
|
14
|
+
potentially all of its datasets). Dataset#extension operates
|
|
15
|
+
like other dataset methods, returning a modified clone of
|
|
16
|
+
the dataset with the extension added:
|
|
17
|
+
|
|
18
|
+
dataset = dataset.extension(:columns_introspection)
|
|
19
|
+
|
|
20
|
+
Dataset#extension! has also been added for modifying the
|
|
21
|
+
receiver instead of returning a clone.
|
|
22
|
+
|
|
23
|
+
Not all extensions are usable by Database#extension or
|
|
24
|
+
Dataset#extension, the extension has to have specific support
|
|
25
|
+
for it. The following extensions support both
|
|
26
|
+
Database#extension and Dataset#extension:
|
|
27
|
+
|
|
28
|
+
* columns_introspection
|
|
29
|
+
* query_literals
|
|
30
|
+
* split_array_nil
|
|
31
|
+
|
|
32
|
+
The following extensions support just Database#extension:
|
|
33
|
+
|
|
34
|
+
* arbitrary_servers
|
|
35
|
+
* looser_typecasting
|
|
36
|
+
* pg_array
|
|
37
|
+
* pg_auto_parameterize
|
|
38
|
+
* pg_hstore
|
|
39
|
+
* pg_inet
|
|
40
|
+
* pg_interval
|
|
41
|
+
* pg_json
|
|
42
|
+
* pg_range
|
|
43
|
+
* pg_statement_cache
|
|
44
|
+
* server_block
|
|
45
|
+
|
|
46
|
+
Any user that was loading these extensions with Sequel.extension
|
|
47
|
+
and then manually extending objects with the extension's module
|
|
48
|
+
is encouraged to switch to Database#extension and/or
|
|
49
|
+
Dataset#extension.
|
|
50
|
+
|
|
51
|
+
* Dataset join methods now respect a :qualify=>:deep option
|
|
52
|
+
to do deep qualification of expressions, allowing qualification
|
|
53
|
+
of subexpressions in the expression tree. This can allow you
|
|
54
|
+
to do things like:
|
|
55
|
+
|
|
56
|
+
DB[:a].join(:b, {:c.cast(Integer)=>:d.cast(Integer)},
|
|
57
|
+
:qualify=>:deep)
|
|
58
|
+
# SELECT * FROM a INNER JOIN b
|
|
59
|
+
# ON (CAST(b.c AS INTEGER) = CAST(a.d AS INTEGER))
|
|
60
|
+
|
|
61
|
+
For backwards compatibility, by default Sequel will only do
|
|
62
|
+
automatic qualification if the arguments are simple symbols.
|
|
63
|
+
This may change in a future version, if automatic qualification
|
|
64
|
+
of only symbols is desired, switch to using :qualify=>:symbol.
|
|
65
|
+
|
|
66
|
+
You can also choose to do no automatic qualification using the
|
|
67
|
+
:qualify=>false option.
|
|
68
|
+
|
|
69
|
+
* All of Sequel's model associations now work with key expressions
|
|
70
|
+
that are not simple column references, without creating a fully
|
|
71
|
+
custom association. So you can create associations where the
|
|
72
|
+
primary/foreign key values are stored in PostgreSQL array or
|
|
73
|
+
hstore columns, for example.
|
|
74
|
+
|
|
75
|
+
* The pg_array extension has now been made more generic, so that it
|
|
76
|
+
is easy to support array types for any scalar type that is
|
|
77
|
+
currently supported. All scalar types that Sequel's postgres
|
|
78
|
+
adapter supports now have corresponding array types supported in
|
|
79
|
+
the pg_array extension. So if you load the pg_array extension and
|
|
80
|
+
return a date array column, the returned values will be arrays of
|
|
81
|
+
ruby Date objects.
|
|
82
|
+
|
|
83
|
+
Other pg_* extensions that add support for PostgreSQL-specific
|
|
84
|
+
scalar types now support array versions of those types if the
|
|
85
|
+
pg_array extension is loaded first.
|
|
86
|
+
|
|
87
|
+
* A pg_range extension has been added, making it easy to deal
|
|
88
|
+
with PostgreSQL 9.2+'s range types. As ruby's Range class does
|
|
89
|
+
not support all PostgreSQL range type values (such as empty ranges,
|
|
90
|
+
unbounded ranges, or ranges with an exlusive beginning), range
|
|
91
|
+
types are returned as instances of Sequel::Postgres::PGRange, which
|
|
92
|
+
has an API similar to Range. You can turn a PGRange into a Range
|
|
93
|
+
using PGRange#to_range, assuming that the range type value does not
|
|
94
|
+
use features that are incompatible with ruby's Range class.
|
|
95
|
+
|
|
96
|
+
The pg_range extension supports all range types supported by
|
|
97
|
+
default in PostgreSQL 9.2, and makes it easy to support custom
|
|
98
|
+
range types.
|
|
99
|
+
|
|
100
|
+
* A pg_range_ops extension has been added, which adds DSL support for
|
|
101
|
+
PostgreSQL range operators and functions, similar to the
|
|
102
|
+
pg_array_ops and pg_hstore_ops extensions.
|
|
103
|
+
|
|
104
|
+
* A pg_interval extension has been added, which makes Sequel return
|
|
105
|
+
PostgreSQL interval types as instances of ActiveSupport::Duration.
|
|
106
|
+
This is useful if you want to take the interval value and use it in
|
|
107
|
+
calculations in ruby (assuming you load the appropriate parts of
|
|
108
|
+
ActiveSupport).
|
|
109
|
+
|
|
110
|
+
* A split_array_nil extension has been added, which changes how Sequel
|
|
111
|
+
compiles IN/NOT IN expressions with arrays with nil values.
|
|
112
|
+
|
|
113
|
+
where(:col=>[1, nil])
|
|
114
|
+
# Default:
|
|
115
|
+
# WHERE (col IN (1, NULL))
|
|
116
|
+
# with split_array_nil extension:
|
|
117
|
+
# WHERE ((col IN (1)) OR (col IS NULL))
|
|
118
|
+
|
|
119
|
+
exclude(:col=>[1, nil])
|
|
120
|
+
# Default:
|
|
121
|
+
# WHERE (col NOT IN (1, NULL))
|
|
122
|
+
# with split_array_nil extension:
|
|
123
|
+
# WHERE ((col NOT IN (1)) AND (col IS NOT NULL))
|
|
124
|
+
|
|
125
|
+
* The nested_attributes plugin now allows the :fields option to
|
|
126
|
+
be a proc, which is called with the associated object and should
|
|
127
|
+
return an array of allowable fields.
|
|
128
|
+
|
|
129
|
+
* You can now specify the graph alias base when using eager_graph on
|
|
130
|
+
a per-call basis. Previously, it could only be set on a per
|
|
131
|
+
association basis. This is helpful if you have multiple
|
|
132
|
+
associations to the same class, and are cascading the eager graph to
|
|
133
|
+
dependent associations of that class for both of the associations.
|
|
134
|
+
Previously, there was no way to manually give descriptive names to
|
|
135
|
+
the tables in the cascaded associations, but you can now do so
|
|
136
|
+
by passing the association as an Sequel::SQL::AliasedExpression
|
|
137
|
+
instance instead of a plain Symbol. Here's a usage example:
|
|
138
|
+
|
|
139
|
+
ds = Game.eager_graph(:winner=>:players.as(:winning_players),
|
|
140
|
+
:loser=>:players.as(:losing_players)).
|
|
141
|
+
where(:winning_players__name=>'A',
|
|
142
|
+
:losing_players__name=>'B')
|
|
143
|
+
|
|
144
|
+
* many_through_many associations now differentiate between column
|
|
145
|
+
references and method references, by supporting the
|
|
146
|
+
:left_primary_key_column and :right_primary_key_method options that
|
|
147
|
+
many_to_many associations support.
|
|
148
|
+
|
|
149
|
+
* Custom :eager_loader procs that accept a single hash argument now
|
|
150
|
+
have an additional entry passed in the hash, :id_map, which is
|
|
151
|
+
easier to use than the :key_hash entry (which is still present for
|
|
152
|
+
backwards compatibility). Anyone with custom :eager_loader procs is
|
|
153
|
+
encouraged to switch from using :key_hash to :id_map.
|
|
154
|
+
|
|
155
|
+
* You can now override the create_table/alter_table schema generators
|
|
156
|
+
per database/adapter. This allows for database specific generator
|
|
157
|
+
subclasses, which have methods for unique features for that
|
|
158
|
+
database.
|
|
159
|
+
|
|
160
|
+
* You can now setup exclusion constraints on PostgreSQL using the
|
|
161
|
+
create_table and alter_table schema generators:
|
|
162
|
+
|
|
163
|
+
DB.create_table(:t) do
|
|
164
|
+
...
|
|
165
|
+
exclusion_constraint([[:col1, '&&'], [:col2, '=']])
|
|
166
|
+
# EXCLUDE USING gist (col1 WITH &&, col2 WITH =)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
One common use for exclusion constraints is to make sure that no two
|
|
170
|
+
rows have overlapping values/ranges/circles.
|
|
171
|
+
|
|
172
|
+
* When adding foreign key constraints to an existing table on
|
|
173
|
+
PostgreSQL, you can use the :not_valid option to mark the constraint
|
|
174
|
+
as not yet valid. This will make it so that future changes to the
|
|
175
|
+
table need to respect the foreign key constraint, but existing rows
|
|
176
|
+
do not. After cleaning up the existing data, you can then use the
|
|
177
|
+
alter_table validate_constraint method to mark the constraint as
|
|
178
|
+
valid.
|
|
179
|
+
|
|
180
|
+
* An eval_inspect extension has been added that attempts to do
|
|
181
|
+
do the following for Sequel::SQL::Expression instances:
|
|
182
|
+
|
|
183
|
+
eval(obj.inspect) == obj # => true
|
|
184
|
+
|
|
185
|
+
There are a lot of cases that this extension does not handle, but
|
|
186
|
+
it does a decent job in most cases. This is currently only used
|
|
187
|
+
internally in a specific case in the schema_dumper extension.
|
|
188
|
+
|
|
189
|
+
= Other Improvements
|
|
190
|
+
|
|
191
|
+
* The filter by associations support now respects the method
|
|
192
|
+
reference vs column reference distinction that other parts of the
|
|
193
|
+
association code have respected since 3.32.0.
|
|
194
|
+
|
|
195
|
+
* In the nested_attributes plugin, new one_to_one associated
|
|
196
|
+
values are saved once instead of twice. Previously it attempted to
|
|
197
|
+
save them before they were associated to the current model object,
|
|
198
|
+
which can violate some validations/constraints.
|
|
199
|
+
|
|
200
|
+
* When saving an associated object in the one_to_one association
|
|
201
|
+
setter method, Sequel no longer adds an unnecessary filter
|
|
202
|
+
condition when nullifying the foreign key for existing rows
|
|
203
|
+
in the associated table.
|
|
204
|
+
|
|
205
|
+
* The list plugin's before_create method now calls super, which
|
|
206
|
+
fixes usage when other plugins that define before_create are loaded
|
|
207
|
+
before it.
|
|
208
|
+
|
|
209
|
+
* In the pg_array extension, when typecasting an Array to PGArray,
|
|
210
|
+
a recursive map is done on the input array to convert each value
|
|
211
|
+
in the input array to the expected type, using the typecasting
|
|
212
|
+
method that would be used for the scalar value. For example, for
|
|
213
|
+
model objects, where ids is an integer array column:
|
|
214
|
+
|
|
215
|
+
model.set(:ids=>['1', '2']).ids.to_a # => [1, 2]
|
|
216
|
+
|
|
217
|
+
* The pg_array extension now correctly handles bytea arrays used
|
|
218
|
+
in bound variables.
|
|
219
|
+
|
|
220
|
+
* The pg_array extension no longer uses the JSON-based parser for
|
|
221
|
+
floating point types, since it doesn't handle NaN and Infinity
|
|
222
|
+
values correctly.
|
|
223
|
+
|
|
224
|
+
* When typecasting in the pg_array extension, PGArray values are
|
|
225
|
+
only returned verbatim if they have a matching database type.
|
|
226
|
+
Otherwise, the underlying array is rewrapped in a new PGArray
|
|
227
|
+
value with the correct database type.
|
|
228
|
+
|
|
229
|
+
* H2 clob types are now recognized as strings instead of blobs.
|
|
230
|
+
Previously the code attempted to do this, but it didn't do so
|
|
231
|
+
correctly.
|
|
232
|
+
|
|
233
|
+
* The jdbc/postgres adapter now converts scalar values of
|
|
234
|
+
the array to the appropriate type. Previously, if you retrieved
|
|
235
|
+
a date array, you got back a ruby array of JavaSQL::SQL::Date
|
|
236
|
+
instances. Now, you get back a ruby array of ruby Date instances.
|
|
237
|
+
|
|
238
|
+
* The schema_dumper extension now dumps migrations as change
|
|
239
|
+
migrations, instead of separate up/down migrations, resulting in
|
|
240
|
+
simpler code.
|
|
241
|
+
|
|
242
|
+
* When dumping non-integer foreign keys in the schema dumper, an
|
|
243
|
+
explicit type is now used. Previously, the column would have been
|
|
244
|
+
dumped as an integer column.
|
|
245
|
+
|
|
246
|
+
* When dumping unsigned integer columns in the schema dumper, add a
|
|
247
|
+
column > 0 constraint in the dumped migration.
|
|
248
|
+
|
|
249
|
+
* On Microsoft SQL Server, when updating a dataset with a limit,
|
|
250
|
+
the limit is now respected.
|
|
251
|
+
|
|
252
|
+
* When emulating offset using the ROW_NUMBER window function,
|
|
253
|
+
do not require that the dataset be ordered. If an order is
|
|
254
|
+
not provided, default to ordering on all of the columns in
|
|
255
|
+
the dataset. If you want to override the default order used
|
|
256
|
+
in such a case, you need to override the default_offset_order
|
|
257
|
+
method for the dataset.
|
|
258
|
+
|
|
259
|
+
* On SQLite, casting to Date/Time/DateTime now calls an SQLite
|
|
260
|
+
date/datetime function instead of using a cast, as SQLite treats
|
|
261
|
+
such a cast as a cast to integer.
|
|
262
|
+
|
|
263
|
+
* When using JRuby 1.6 in ruby 1.9 mode and typecasting a time
|
|
264
|
+
column, workaround a bug where Time#nsec is 0 even though
|
|
265
|
+
Time#usec is not.
|
|
266
|
+
|
|
267
|
+
* The odbc/mssql adapter now correctly handles the case where
|
|
268
|
+
SCOPE_IDENTITY returns NULL after an insert.
|
|
269
|
+
|
|
270
|
+
* bin/sequel now accepts multiple -l options for logging to multiple
|
|
271
|
+
output files.
|
|
272
|
+
|
|
273
|
+
* In addition to Sequel's rigorous pre-push testing, Sequel now
|
|
274
|
+
also uses TravisCI for continuous integration testing across
|
|
275
|
+
a wider range of ruby implementations.
|
|
276
|
+
|
|
277
|
+
= Backwards Compatibility
|
|
278
|
+
|
|
279
|
+
* The keys in the :key_hash entry passed to the :eager_loader proc
|
|
280
|
+
are now method references instead of column references. For most
|
|
281
|
+
associations, they are the same thing, but for associations using
|
|
282
|
+
the :key_column/:primary_key_column/:left_primary_key_column
|
|
283
|
+
options, the values could be different. If you were using one
|
|
284
|
+
of those options and had a custom eager_loader, you should switch
|
|
285
|
+
from indexing into the :key_hash option to just using the :id_map
|
|
286
|
+
option.
|
|
287
|
+
|
|
288
|
+
* The :key_hash entry passed to the :eager_loader proc is now no
|
|
289
|
+
longer guaranteed to contain key maps for associations other than
|
|
290
|
+
the one currently being eagerly loaded. Previously, it contained
|
|
291
|
+
key maps for all associations that were being eagerly loaded. If
|
|
292
|
+
you have a custom :eager_loader proc that accessed a key map for
|
|
293
|
+
a separate association that was being loaded concurrently, you'll
|
|
294
|
+
now have to build the key map manually if it doesn't exist.
|
|
295
|
+
|
|
296
|
+
* If you previously explicitly specified an :eager_loader_key option
|
|
297
|
+
when defining an association, you may need to change it so that it
|
|
298
|
+
is a method reference instead of a column reference, or possibly
|
|
299
|
+
just omit the option.
|
|
300
|
+
|
|
301
|
+
* If you have a custom :eager_loader proc for an association where
|
|
302
|
+
the default :eager_loader_key option references a method that
|
|
303
|
+
the model does not respond to (or raises an exception), you may
|
|
304
|
+
need to specify the :eager_loader_key=>nil option.
|
|
305
|
+
|
|
306
|
+
* In the pg_auto_parameterize extension, String values are no longer
|
|
307
|
+
automatically casted to text. This is because the default type of
|
|
308
|
+
a string literal in PostgreSQL is unknown, not text. This makes it
|
|
309
|
+
much less likely to require manual casts, but has the potential to
|
|
310
|
+
break existing code relying on the automatic cast to text. As a
|
|
311
|
+
work around, any query that can no longer be automatically
|
|
312
|
+
parameterized after this query just needs to add manual casting
|
|
313
|
+
to text.
|
|
314
|
+
|
|
315
|
+
* Sequel now raises an exception if you attempt to clone associations
|
|
316
|
+
with different types, except if one type is one_to_many and the
|
|
317
|
+
other is one_to_one. Cloning from other types was usually a bug,
|
|
318
|
+
and raising an exception early will make it much easier to track
|
|
319
|
+
such bugs down.
|
|
320
|
+
|
|
321
|
+
* When running the plugin/extension and PostgreSQL adapter specs,
|
|
322
|
+
a json library is now required.
|
|
323
|
+
|
|
324
|
+
* The json/postgres adapter array typecasting internals have been
|
|
325
|
+
modified, if you were relying on the internals, you may need to
|
|
326
|
+
update your code.
|
|
327
|
+
|
|
328
|
+
* The pg_array extension internals changed significantly. PGArray
|
|
329
|
+
no longer has any subclasses by default, as parsing is now done
|
|
330
|
+
in separate objects. Anyone relying on the pg_array internals
|
|
331
|
+
will need to update their code.
|
|
332
|
+
|
|
333
|
+
* The postgres adapter no longer sets up type conversion of int2vector
|
|
334
|
+
and money types, since in both cases the conversion was incorrect in
|
|
335
|
+
most cases. These types will now be returned as strings. If you are
|
|
336
|
+
relying on the conversion, you'll need to add your own custom type
|
|
337
|
+
procs.
|
|
338
|
+
|