sequel 4.39.0 → 4.40.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.
- checksums.yaml +4 -4
- data/CHANGELOG +34 -0
- data/README.rdoc +8 -4
- data/doc/active_record.rdoc +1 -1
- data/doc/advanced_associations.rdoc +7 -7
- data/doc/association_basics.rdoc +7 -7
- data/doc/cheat_sheet.rdoc +5 -3
- data/doc/core_extensions.rdoc +3 -3
- data/doc/dataset_filtering.rdoc +1 -1
- data/doc/object_model.rdoc +16 -7
- data/doc/postgresql.rdoc +3 -3
- data/doc/querying.rdoc +3 -3
- data/doc/release_notes/4.40.0.txt +179 -0
- data/doc/security.rdoc +2 -1
- data/doc/sql.rdoc +34 -18
- data/doc/testing.rdoc +1 -0
- data/doc/virtual_rows.rdoc +11 -2
- data/lib/sequel/adapters/jdbc/derby.rb +7 -1
- data/lib/sequel/adapters/jdbc/h2.rb +15 -1
- data/lib/sequel/adapters/oracle.rb +9 -5
- data/lib/sequel/adapters/postgres.rb +0 -1
- data/lib/sequel/adapters/shared/cubrid.rb +11 -11
- data/lib/sequel/adapters/shared/db2.rb +4 -8
- data/lib/sequel/adapters/shared/mssql.rb +41 -28
- data/lib/sequel/adapters/shared/mysql.rb +9 -6
- data/lib/sequel/adapters/shared/oracle.rb +16 -5
- data/lib/sequel/adapters/shared/postgres.rb +84 -45
- data/lib/sequel/adapters/shared/sqlanywhere.rb +29 -15
- data/lib/sequel/adapters/shared/sqlite.rb +6 -6
- data/lib/sequel/core.rb +61 -10
- data/lib/sequel/database/connecting.rb +2 -1
- data/lib/sequel/database/features.rb +7 -0
- data/lib/sequel/database/query.rb +1 -1
- data/lib/sequel/database/schema_methods.rb +30 -3
- data/lib/sequel/database/transactions.rb +4 -2
- data/lib/sequel/dataset/actions.rb +1 -1
- data/lib/sequel/dataset/graph.rb +6 -1
- data/lib/sequel/dataset/query.rb +14 -7
- data/lib/sequel/dataset/sql.rb +2 -2
- data/lib/sequel/extensions/core_extensions.rb +2 -1
- data/lib/sequel/extensions/pg_row.rb +2 -2
- data/lib/sequel/extensions/s.rb +57 -0
- data/lib/sequel/extensions/set_overrides.rb +5 -1
- data/lib/sequel/extensions/sql_expr.rb +1 -0
- data/lib/sequel/extensions/symbol_aref.rb +71 -0
- data/lib/sequel/extensions/symbol_aref_refinement.rb +41 -0
- data/lib/sequel/extensions/symbol_as.rb +23 -0
- data/lib/sequel/extensions/symbol_as_refinement.rb +35 -0
- data/lib/sequel/model/base.rb +3 -3
- data/lib/sequel/plugins/class_table_inheritance.rb +14 -3
- data/lib/sequel/plugins/column_select.rb +4 -2
- data/lib/sequel/plugins/dataset_associations.rb +12 -4
- data/lib/sequel/plugins/insert_returning_select.rb +1 -1
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +1 -1
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/sql.rb +40 -8
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/firebird_spec.rb +3 -3
- data/spec/adapters/mssql_spec.rb +40 -40
- data/spec/adapters/mysql_spec.rb +5 -5
- data/spec/adapters/oracle_spec.rb +4 -4
- data/spec/adapters/postgres_spec.rb +135 -124
- data/spec/adapters/spec_helper.rb +1 -0
- data/spec/adapters/sqlite_spec.rb +6 -6
- data/spec/core/dataset_spec.rb +2 -2
- data/spec/core/expression_filters_spec.rb +43 -2
- data/spec/core/schema_spec.rb +35 -1
- data/spec/core_extensions_spec.rb +27 -0
- data/spec/extensions/class_table_inheritance_spec.rb +8 -0
- data/spec/extensions/column_select_spec.rb +8 -0
- data/spec/extensions/core_refinements_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +9 -0
- data/spec/extensions/insert_returning_select_spec.rb +20 -0
- data/spec/extensions/prepared_statements_spec.rb +7 -0
- data/spec/extensions/s_spec.rb +60 -0
- data/spec/extensions/symbol_aref_refinement_spec.rb +28 -0
- data/spec/extensions/symbol_as_refinement_spec.rb +21 -0
- data/spec/integration/associations_test.rb +62 -57
- data/spec/integration/dataset_test.rb +54 -54
- data/spec/integration/eager_loader_test.rb +7 -7
- data/spec/integration/plugin_test.rb +20 -20
- data/spec/integration/prepared_statement_test.rb +1 -1
- data/spec/integration/schema_test.rb +21 -0
- data/spec/integration/spec_helper.rb +1 -0
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7036daa139080700c287bce9f5c7c2d068d5476e
|
4
|
+
data.tar.gz: cd75becb35bf05f4a74b70c6468bbfbd214359e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46cb6f09318eab28fa222d4e37484bb5781d1f94cbe4e341dd2c70c521819513e3f877e74a31dd90b998fa35abeea4ab1366e67a3bd883f85d8eec531f1841c3
|
7
|
+
data.tar.gz: 71ec283114e83204a544ccdc22fd5f73cad5cd403e6c2c17d55318a6dccbe1ae5b131d62ff9cd6a3552047f4808bc41bce1f04755d123ece61a16020aa7dffe9
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,37 @@
|
|
1
|
+
=== 4.40.0 (2016-10-28)
|
2
|
+
|
3
|
+
* Make column_select plugin not raise an exception if the model's table does not exist (jeremyevans)
|
4
|
+
|
5
|
+
* Make dataset_associations plugin correctly handle (many|one)_through_many associations with single join table (jeremyevans) (#1253)
|
6
|
+
|
7
|
+
* Add s extension, with adds Sequel::S module that includes private #S method for calling Sequel.expr, including use as refinement (jeremyevans)
|
8
|
+
|
9
|
+
* Add symbol_as and symbol_as_refinement extensions so that :column.as(:alias) is treated as Sequel.as(:column, :alias) (jeremyevans)
|
10
|
+
|
11
|
+
* Add symbol_aref and symbol_aref_refinement extensions so that :table[:column] is treated as Sequel.qualify(:table, :column) (jeremyevans)
|
12
|
+
|
13
|
+
* Add Sequel.split_symbols=, to support the disabling of splitting symbols with double/triple underscores (jeremyevans)
|
14
|
+
|
15
|
+
* Make SQL::QualifiedIdentifier convert SQL::Identifier arguments to strings, fixing Sequel[:schema][:table] usage in schema methods (jeremyevans)
|
16
|
+
|
17
|
+
* Do not attempt to combine non-associative operators (jeremyevans) (#1246)
|
18
|
+
|
19
|
+
* Automatically add NOT NULL to columns when adding primary keys if the database doesn't handle it (jeremyevans)
|
20
|
+
|
21
|
+
* Make prepared_statements plugin correctly handle lookup on joined datasets (jeremyevans) (#1244)
|
22
|
+
|
23
|
+
* Make Database#tables with :qualify=>true option handle table names with double underscores correctly (jeremyevans) (#1241)
|
24
|
+
|
25
|
+
* Add SQL::Identifier#[] and SQL::QualifiedIdentifier#[] for creating qualified identifiers (jeremyevans)
|
26
|
+
|
27
|
+
* Add support for Dataset#insert_conflict :conflict_where option, for a predicate to use in ON CONFLICT clauses (chanks) (#1240)
|
28
|
+
|
29
|
+
* Freeze Dataset::NON_SQL_OPTIONS, add private Dataset#non_sql_options, fixing thread safety issues during require (jeremyevans)
|
30
|
+
|
31
|
+
* Make the callable returned by Database#rollback_checker thread safe (jeremyevans)
|
32
|
+
|
33
|
+
* Make lazy_attributes and dataset_associations plugins work if insert_returning_select plugin is loaded before on model with no dataset (jeremyevans)
|
34
|
+
|
1
35
|
=== 4.39.0 (2016-10-01)
|
2
36
|
|
3
37
|
* Make active_model plugin use rollback_checker instead of after_rollback hook (jeremyevans)
|
data/README.rdoc
CHANGED
@@ -453,14 +453,14 @@ Ruby strings are generally treated as SQL strings:
|
|
453
453
|
=== Qualifying identifiers (column/table names)
|
454
454
|
|
455
455
|
An identifier in SQL is a name that represents a column, table, or schema.
|
456
|
-
|
456
|
+
By default, identifiers can be qualified by using the double underscore special notation <tt>:table__column</tt>:
|
457
457
|
|
458
458
|
items.literal(:items__price)
|
459
459
|
# items.price
|
460
460
|
|
461
|
-
Another way to qualify columns is to use the <tt>Sequel
|
461
|
+
Another way to qualify columns is to use the <tt>Sequel[][]</tt> method:
|
462
462
|
|
463
|
-
items.literal(Sequel
|
463
|
+
items.literal(Sequel[:items][:price])
|
464
464
|
# items.price
|
465
465
|
|
466
466
|
While it is more common to qualify column identifiers with table identifiers, you can also qualify table identifiers with schema identifiers
|
@@ -471,7 +471,7 @@ to select from a qualified table:
|
|
471
471
|
|
472
472
|
=== Identifier aliases
|
473
473
|
|
474
|
-
|
474
|
+
By default, you can also alias identifiers by using the triple underscore special notation <tt>:column___alias</tt> or <tt>:table__column___alias</tt>:
|
475
475
|
|
476
476
|
items.literal(:price___p)
|
477
477
|
# price AS p
|
@@ -488,6 +488,10 @@ You can use the <tt>Sequel.as</tt> method to alias arbitrary expressions, not ju
|
|
488
488
|
items.literal(Sequel.as(DB[:posts].select{max(id)}, :p))
|
489
489
|
# (SELECT max(id) FROM posts) AS p
|
490
490
|
|
491
|
+
You can turn off the splitting of symbols containing double and triple underscores, and treat all symbols as regular identifiers, by using:
|
492
|
+
|
493
|
+
Sequel.split_symbols = false
|
494
|
+
|
491
495
|
== Sequel Models
|
492
496
|
|
493
497
|
A model class wraps a dataset, and an instance of that class wraps a single record in the dataset.
|
data/doc/active_record.rdoc
CHANGED
@@ -260,7 +260,7 @@ You just use:
|
|
260
260
|
At the instance level, this means that if you select columns that aren't in the models table, you need to use <tt>Model#[]</tt> to access them:
|
261
261
|
|
262
262
|
album = Album.join(:artist, :id=>:artist_id).
|
263
|
-
select
|
263
|
+
select{[albums[:id], albums[:name], artists[:name].as(:artist)]}.first
|
264
264
|
# SELECT albums.id, albums.name, artists.name AS artist
|
265
265
|
|
266
266
|
album.artist # Error!
|
@@ -50,12 +50,12 @@ These can be used like this:
|
|
50
50
|
|
51
51
|
# Only returns albums that have sold more than 500,000 copies
|
52
52
|
Artist.one_to_many :gold_albums, :class=>:Album, \
|
53
|
-
:graph_block=>proc{|j,lj,js| Sequel
|
53
|
+
:graph_block=>proc{|j,lj,js| Sequel[j][:copies_sold] > 500000}
|
54
54
|
|
55
55
|
# Handles the case where the tables are associated by a case insensitive name string
|
56
56
|
Artist.one_to_many :albums, :key=>:artist_name, \
|
57
57
|
:graph_only_conditions=>nil, \
|
58
|
-
:graph_block=>proc{|j,lj,js| {Sequel.function(:lower, Sequel
|
58
|
+
:graph_block=>proc{|j,lj,js| {Sequel.function(:lower, Sequel[j][:artist_name])=>Sequel.function(:lower, Sequel[lj][:name])}}
|
59
59
|
|
60
60
|
# Handles the case where both key columns have the name artist_name, and you want to use
|
61
61
|
# a JOIN USING
|
@@ -73,8 +73,8 @@ ordered by the albums name, you can do:
|
|
73
73
|
|
74
74
|
albums = Artist.
|
75
75
|
eager_graph(:albums).
|
76
|
-
where
|
77
|
-
order
|
76
|
+
where{Sequel.like(albums[:name], 'A%')}.
|
77
|
+
order{albums[:name]}.
|
78
78
|
all
|
79
79
|
|
80
80
|
For lazy loading (e.g. Model[1].association), the <tt>:dataset</tt> option can be used
|
@@ -780,16 +780,16 @@ What you want to do is get all songs for a given artist, ordered by the song's
|
|
780
780
|
name, with no duplicates?
|
781
781
|
|
782
782
|
class Artist < Sequel::Model
|
783
|
-
one_to_many :songs, :order
|
783
|
+
one_to_many :songs, :order=>Sequel[:songs][:name], \
|
784
784
|
:dataset=>proc{Song.select_all(:songs).join(Lyric, :id=>:lyric_id, id=>[:composer_id, :arranger_id, :vocalist_id, :lyricist_id])}, \
|
785
785
|
:eager_loader=>(proc do |eo|
|
786
786
|
h = eo[:id_map]
|
787
787
|
ids = h.keys
|
788
788
|
eo[:rows].each{|r| r.associations[:songs] = []}
|
789
789
|
Song.select_all(:songs).
|
790
|
-
select_append
|
790
|
+
select_append{[lyrics[:composer_id], lyrics[:arranger_id], lyrics[:vocalist_id], lyrics[:lyricist_id]}.
|
791
791
|
join(Lyric, :id=>:lyric_id){Sequel.or(:composer_id=>ids, :arranger_id=>ids, :vocalist_id=>ids, :lyricist_id=>ids)}.
|
792
|
-
order
|
792
|
+
order{songs[:name]}.all do |song|
|
793
793
|
[:composer_id, :arranger_id, :vocalist_id, :lyricist_id].each do |x|
|
794
794
|
recs = h[song.values.delete(x)]
|
795
795
|
recs.each{|r| r.associations[:songs] << song} if recs
|
data/doc/association_basics.rdoc
CHANGED
@@ -993,7 +993,7 @@ columns that have the same name in both the join table and the associated
|
|
993
993
|
table. Example:
|
994
994
|
|
995
995
|
Artist.one_to_many :albums, :select=>[:id, :name]
|
996
|
-
Album.many_to_many :tags, :select=>[Sequel[:tags].*, :
|
996
|
+
Album.many_to_many :tags, :select=>[Sequel[:tags].*, Sequel[:albums_tags][:number]]
|
997
997
|
|
998
998
|
==== :limit
|
999
999
|
|
@@ -1332,11 +1332,11 @@ association based on dependent associations:
|
|
1332
1332
|
|
1333
1333
|
Artist.one_to_many :albums_with_short_tracks, :class=>:Album,
|
1334
1334
|
:eager_graph=>:tracks do |ds|
|
1335
|
-
ds.where{
|
1335
|
+
ds.where{tracks[:seconds] < 120}
|
1336
1336
|
end
|
1337
1337
|
Artist.one_to_many :albums_by_track_name, :class=>:Album,
|
1338
1338
|
:eager_graph=>:tracks do |ds|
|
1339
|
-
ds.order
|
1339
|
+
ds.order{tracks[:name]}
|
1340
1340
|
end
|
1341
1341
|
|
1342
1342
|
You can also use a hash or array of arguments for :eager_graph, similar to
|
@@ -1364,7 +1364,7 @@ via eager_graph. This is useful to specify conditions that can't be specified
|
|
1364
1364
|
in a hash or array of two element arrays.
|
1365
1365
|
|
1366
1366
|
Artist.one_to_many :gold_albums, :class=>:Album,
|
1367
|
-
:graph_block=>proc{|j,lj,js| Sequel
|
1367
|
+
:graph_block=>proc{|j,lj,js| Sequel[j][:copies_sold] > 500000}
|
1368
1368
|
|
1369
1369
|
==== :graph_join_type
|
1370
1370
|
|
@@ -1396,8 +1396,8 @@ where the artist's name differs in case:
|
|
1396
1396
|
|
1397
1397
|
Artist.one_to_many :albums, :key=>:artist_name,
|
1398
1398
|
:graph_only_conditions=>nil,
|
1399
|
-
:graph_block=>proc{|j,lj,js| {Sequel.function(:lower, Sequel
|
1400
|
-
Sequel.function(:lower, Sequel
|
1399
|
+
:graph_block=>proc{|j,lj,js| {Sequel.function(:lower, Sequel[j][:artist_name])=>
|
1400
|
+
Sequel.function(:lower, Sequel[lj][:name])}}
|
1401
1401
|
|
1402
1402
|
Note how :graph_only_conditions is set to nil to ignore any existing conditions,
|
1403
1403
|
and :graph_block is used to set up the case insensitive comparison.
|
@@ -1504,7 +1504,7 @@ has received a bachelor's degree (degree starting with B):
|
|
1504
1504
|
|
1505
1505
|
Person.many_to_many :bachelor_degree_colleges, :class=>:College,
|
1506
1506
|
:join_table=>:degrees_received,
|
1507
|
-
:graph_join_table_block=>proc{|j,lj,js| Sequel
|
1507
|
+
:graph_join_table_block=>proc{|j,lj,js| Sequel[j][:degree].like('B%')}
|
1508
1508
|
|
1509
1509
|
This should be done when graphing the join table, instead of when graphing the
|
1510
1510
|
final table, as :degree is a column of the join table.
|
data/doc/cheat_sheet.rdoc
CHANGED
@@ -129,7 +129,7 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
|
|
129
129
|
# SELECT * FROM items
|
130
130
|
# LEFT OUTER JOIN categories ON categories.id = items.category_id
|
131
131
|
|
132
|
-
DB[:items].join(:categories, :id => :category_id).join(:groups, :id => :
|
132
|
+
DB[:items].join(:categories, :id => :category_id).join(:groups, :id => Sequel[:items][:group_id])
|
133
133
|
# SELECT * FROM items
|
134
134
|
# INNER JOIN categories ON categories.id = items.category_id
|
135
135
|
# INNER JOIN groups ON groups.id = items.group_id
|
@@ -170,8 +170,10 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
|
|
170
170
|
== Aliasing
|
171
171
|
|
172
172
|
DB[:items].select(Sequel.as(:name, :item_name))
|
173
|
-
DB[:items].select(:
|
174
|
-
|
173
|
+
DB[:items].select{name.as(:item_name)}
|
174
|
+
# SELECT name AS item_name FROM items
|
175
|
+
|
176
|
+
DB[Sequel[:items].as(:items_table)].select{items_table[:name].as(:item_name)}
|
175
177
|
# SELECT items_table.name AS item_name FROM items AS items_table
|
176
178
|
|
177
179
|
== Transactions
|
data/doc/core_extensions.rdoc
CHANGED
@@ -170,11 +170,11 @@ Symbol#qualify qualifies the identifier (e.g. a column) with a another identifie
|
|
170
170
|
|
171
171
|
:column.qualify(:table) # SQL: table.column
|
172
172
|
|
173
|
-
Alternative: Sequel
|
173
|
+
Alternative: Sequel[][]:
|
174
174
|
|
175
|
-
Sequel
|
175
|
+
Sequel[:table][:column]
|
176
176
|
|
177
|
-
Note the reversed order of the arguments. For the Symbol#qualify method, the argument is the qualifier, while for Sequel
|
177
|
+
Note the reversed order of the arguments. For the Symbol#qualify method, the argument is the qualifier, while for Sequel[][], the first [] is the qualifier, and the second [] is the identifier.
|
178
178
|
|
179
179
|
==== like
|
180
180
|
|
data/doc/dataset_filtering.rdoc
CHANGED
data/doc/object_model.rdoc
CHANGED
@@ -126,21 +126,29 @@ For example, ruby symbols represent SQL identifiers (tables, columns, schemas):
|
|
126
126
|
:table # "table"
|
127
127
|
:column # "column"
|
128
128
|
|
129
|
-
|
130
|
-
|
129
|
+
By default, Sequel supports splitting symbols using double or triple underscores
|
130
|
+
to represent qualified and aliased identifiers. A symbol with a double underscore
|
131
|
+
is treated as a qualified identifier:
|
131
132
|
|
132
133
|
:table__column # "table"."column"
|
133
134
|
|
134
|
-
|
135
|
-
inside a symbol:
|
135
|
+
A symbol with a triple underscore is treated as an aliased identifier:
|
136
136
|
|
137
137
|
:column___alias # "column" AS "alias"
|
138
138
|
|
139
|
-
|
140
|
-
|
139
|
+
A symbol with a double underscore followed by a triple underscore is treated
|
140
|
+
as an aliased qualified identifer:
|
141
141
|
|
142
142
|
:table__column___alias # "table"."column" AS "alias"
|
143
143
|
|
144
|
+
By allowing the creation of qualified and aliased identifiers via symbols,
|
145
|
+
Sequel makes it simpler to represent more SQL expressions. However, if you
|
146
|
+
are using double or triple underscores in your own identifiers, Sequel's
|
147
|
+
automatic splitting of identifiers can be problematic, in which case you
|
148
|
+
may want to turn them off via:
|
149
|
+
|
150
|
+
Sequel.split_symbols = false
|
151
|
+
|
144
152
|
=== Integer, Float, BigDecimal, String, Date, Time, DateTime
|
145
153
|
|
146
154
|
Ruby's Integer, Float, BigDecimal, String, Date, Time, and DateTime classes
|
@@ -283,6 +291,7 @@ Sequel::SQL::QualifiedIdentifier objects represent qualified identifiers:
|
|
283
291
|
The following shortcuts exist for creating Sequel::SQL::QualifiedIdentifier objects:
|
284
292
|
|
285
293
|
Sequel[:table__column]
|
294
|
+
Sequel[:table][:column]
|
286
295
|
Sequel.qualify(:table, :column)
|
287
296
|
:column.qualify(:table) # core_extensions extension
|
288
297
|
|
@@ -302,7 +311,7 @@ The following shortcuts exist for creating Sequel::SQL::AliasedExpression object
|
|
302
311
|
Sequel[:column___alias]
|
303
312
|
Sequel.as(:column, :alias)
|
304
313
|
Sequel.as(:column, :alias, [:column_alias1, :column_alias2])
|
305
|
-
:column.as(:alias) # core_extensions extension
|
314
|
+
:column.as(:alias) # core_extensions or symbol_as extension
|
306
315
|
|
307
316
|
=== Sequel::SQL::ComplexExpression
|
308
317
|
|
data/doc/postgresql.rdoc
CHANGED
@@ -160,7 +160,7 @@ Sequel has built in support for creating and dropping PostgreSQL schemas, proced
|
|
160
160
|
DB.drop_function(:set_updated_at)
|
161
161
|
# DROP FUNCTION set_updated_at()
|
162
162
|
|
163
|
-
DB.create_trigger(:table, :trg_updated_at, :set_updated_at, :events=>:update, :each_row=>true, :when => {:
|
163
|
+
DB.create_trigger(:table, :trg_updated_at, :set_updated_at, :events=>:update, :each_row=>true, :when => {Sequel[:new][:updated_at] => Sequel[:old][:updated_at]})
|
164
164
|
# CREATE TRIGGER trg_updated_at BEFORE UPDATE ON "table" FOR EACH ROW WHEN ("new"."updated_at" = "old"."updated_at") EXECUTE PROCEDURE set_updated_at()
|
165
165
|
DB.drop_trigger(:table, :trg_updated_at)
|
166
166
|
# DROP TRIGGER trg_updated_at ON "table"
|
@@ -231,7 +231,7 @@ If you want to update the existing row instead of ignoring the constraint violat
|
|
231
231
|
can pass an +:update+ option with a hash of values to update. You must pass either the
|
232
232
|
+:target+ or +:constraint+ options when passing the +:update+ option:
|
233
233
|
|
234
|
-
DB[:table].insert_conflict(:target=>:a, :update=>{:b
|
234
|
+
DB[:table].insert_conflict(:target=>:a, :update=>{:b=>Sequel[:excluded][:b]}).insert(:a=>1, :b=>2)
|
235
235
|
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
236
236
|
# ON CONFLICT (a) DO UPDATE SET b = excluded.b
|
237
237
|
|
@@ -240,7 +240,7 @@ Additionally, if you only want to do the update in certain cases, you can specif
|
|
240
240
|
conditions, the constraint violation will be ignored, but the row will not be updated:
|
241
241
|
|
242
242
|
DB[:table].insert_conflict(:constraint=>:table_a_uidx,
|
243
|
-
:update=>{:b
|
243
|
+
:update=>{:b=>Sequel[:excluded][:b]}, :update_where=>{Sequel[:table][:status_id]=>1}).insert(:a=>1, :b=>2)
|
244
244
|
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
245
245
|
# ON CONFLICT ON CONSTRAINT table_a_uidx
|
246
246
|
# DO UPDATE SET b = excluded.b WHERE (table.status_id = 1)
|
data/doc/querying.rdoc
CHANGED
@@ -804,7 +804,7 @@ is wrong as the foreign key <tt>tracks.album_id</tt> refers to <tt>albums.id</tt
|
|
804
804
|
<tt>artists.id</tt>. To fix this, you need to explicitly qualify when joining:
|
805
805
|
|
806
806
|
Album.join(:artists, :id=>:artist_id).
|
807
|
-
join(:tracks, :album_id
|
807
|
+
join(:tracks, :album_id=>Sequel[:albums][:id])
|
808
808
|
# SELECT * FROM albums
|
809
809
|
# INNER JOIN artists ON artists.id = albums.artist_id
|
810
810
|
# INNER JOIN tracks ON tracks.album_id = albums.id
|
@@ -876,7 +876,7 @@ and artists tables, but only want albums where the artist's name
|
|
876
876
|
comes before the album's name.
|
877
877
|
|
878
878
|
Album.join(:artists, :id=>:artist_id) do |j, lj, js|
|
879
|
-
Sequel
|
879
|
+
Sequel[j][:name] < Sequel[lj][:name]
|
880
880
|
end
|
881
881
|
# SELECT * FROM albums INNER JOIN artists
|
882
882
|
# ON artists.id = albums.artist_id
|
@@ -904,7 +904,7 @@ number of old albums.
|
|
904
904
|
Using multiple FROM tables and setting conditions in the WHERE clause is
|
905
905
|
an old-school way of joining tables:
|
906
906
|
|
907
|
-
DB.from(:albums, :artists).where
|
907
|
+
DB.from(:albums, :artists).where{{artists[:id]=>albums[:artist_id]}}
|
908
908
|
# SELECT * FROM albums, artists WHERE artists.id = albums.artist_id
|
909
909
|
|
910
910
|
=== Using the current dataset in a subselect
|
@@ -0,0 +1,179 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* A Sequel.split_symbols setting has been added. This setting is
|
4
|
+
true by default, so there is no change to backwards compatibility
|
5
|
+
by default. However, users can now do:
|
6
|
+
|
7
|
+
Sequel.split_symbols = false
|
8
|
+
|
9
|
+
to disable the splitting of symbols. This will make Sequel no
|
10
|
+
longer treat symbols with double or triple underscores as qualified
|
11
|
+
or aliased identifiers, instead treating them as plain identifiers.
|
12
|
+
It will also make Sequel no longer treat virtual row methods with
|
13
|
+
double underscores as qualified identifiers. Examples:
|
14
|
+
|
15
|
+
# Sequel.split_symbols = true
|
16
|
+
:column # "column"
|
17
|
+
:table__column # "table"."column"
|
18
|
+
:column___alias # "column" AS "alias"
|
19
|
+
:table__column___alias # "table"."column" AS "alias"
|
20
|
+
Sequel.expr{table__column} # "table"."column"
|
21
|
+
|
22
|
+
# Sequel.split_symbols = false
|
23
|
+
:column # "column"
|
24
|
+
:table__column # "table__column"
|
25
|
+
:column___alias # "column___alias"
|
26
|
+
:table__column___alias # "table__column___alias"
|
27
|
+
Sequel.expr{table__column} # "table__column"
|
28
|
+
|
29
|
+
Disabling symbol splitting can make things much easier if leading
|
30
|
+
trailing, double, or triple underscores are used in identifiers
|
31
|
+
in your database.
|
32
|
+
|
33
|
+
Disabling symbol splitting makes Sequel simpler, even if it does
|
34
|
+
make it slightly less easy to create qualified and aliased
|
35
|
+
identifiers. It is possible that the symbol splitting will be
|
36
|
+
disabled by default starting in Sequel 5.
|
37
|
+
|
38
|
+
Note that due to Database symbol literal caching, you should not
|
39
|
+
change the Sequel.split_symbols setting after creating a
|
40
|
+
Database instance.
|
41
|
+
|
42
|
+
* SQL::Identifier#[] and SQL::QualifiedIdentifier#[] have been added
|
43
|
+
for creating qualified identifiers. This makes it easier and more
|
44
|
+
natural to create qualified identifiers from existing identifiers.
|
45
|
+
Previously, you could do:
|
46
|
+
|
47
|
+
Sequel[:column].qualify(:table)
|
48
|
+
|
49
|
+
You can now use the more natural:
|
50
|
+
|
51
|
+
Sequel[:table][:column]
|
52
|
+
|
53
|
+
This can also be used in virtual rows:
|
54
|
+
|
55
|
+
Sequel.expr{table[:column]}
|
56
|
+
|
57
|
+
This offers a easy way to create qualified identifers when symbol
|
58
|
+
splitting has been disabled.
|
59
|
+
|
60
|
+
* A symbol_aref extension has been added, allowing the use of
|
61
|
+
Symbol#[] to create qualified identifiers if passed a Symbol,
|
62
|
+
SQL::Identifier, or SQL::QualifiedIdentifier. This doesn't
|
63
|
+
break any existing ruby behavior, as ruby currrently raises
|
64
|
+
an exception in such cases. Example:
|
65
|
+
|
66
|
+
:table[:column] # "table"."column"
|
67
|
+
|
68
|
+
This extension can make it easier to create qualified identifiers
|
69
|
+
if symbol splitting is disabled.
|
70
|
+
|
71
|
+
A symbol_aref_refinement extension has also been added, which
|
72
|
+
adds a refinement version of the extension that can be enabled via:
|
73
|
+
|
74
|
+
using Sequel::SymbolAref
|
75
|
+
|
76
|
+
* A symbol_as extension has been added, which adds the Symbol#as method
|
77
|
+
to create aliased identifiers. This was previously part of the core
|
78
|
+
extensions, but has been separated so it can be included by itself.
|
79
|
+
Example:
|
80
|
+
|
81
|
+
:column.as(:alias) # "column" AS "alias"
|
82
|
+
|
83
|
+
This extension can make it easier to create aliased identifiers if
|
84
|
+
symbol splitting is disabled.
|
85
|
+
|
86
|
+
A symbol_as_refinement extension has also been added, which
|
87
|
+
adds a refinement version of the extension that can be enabled via:
|
88
|
+
|
89
|
+
using Sequel::SymbolAs
|
90
|
+
|
91
|
+
* An s extension has been added, which adds the Sequel::S module,
|
92
|
+
containing a private #S method that calls Sequel.expr. You can
|
93
|
+
include this module in any module or class where you would like the
|
94
|
+
S method to be available:
|
95
|
+
|
96
|
+
class Album < Sequel::Model
|
97
|
+
extend Sequel::S
|
98
|
+
one_to_many :tracks, :order=>S(:number).desc
|
99
|
+
end
|
100
|
+
|
101
|
+
You can include this in Object if you want the S method to be
|
102
|
+
available globally:
|
103
|
+
|
104
|
+
Object.send(:include, Sequel::S)
|
105
|
+
|
106
|
+
Sequel::S also works if it is used as a refinement, adding the S
|
107
|
+
method to Object while the refinement is active:
|
108
|
+
|
109
|
+
using Sequel::S
|
110
|
+
|
111
|
+
This extension can make it easier to create qualified and aliased
|
112
|
+
identifiers if symbol splitting is disabled:
|
113
|
+
|
114
|
+
S(:table)[:column]
|
115
|
+
S(:column).as(:alias)
|
116
|
+
|
117
|
+
* Dataset#insert_conflict on PostgreSQL now supports a :conflict_where
|
118
|
+
option, allowing for the handling of insert conflicts when using a
|
119
|
+
partial unique index:
|
120
|
+
|
121
|
+
DB[:table].insert_conflict(:target=>:a,
|
122
|
+
:conflict_where=>{:c=>true}).insert(:a=>1, :b=>2)
|
123
|
+
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
124
|
+
# ON CONFLICT (a) WHERE (c IS TRUE) DO NOTHING
|
125
|
+
|
126
|
+
= Other Improvements
|
127
|
+
|
128
|
+
* Sequel no longer attempts to combine arguments for non-associative
|
129
|
+
operators, as doing so leads to invalid code in cases such as:
|
130
|
+
|
131
|
+
Sequel.expr{column1 - (column2 - 1)}
|
132
|
+
|
133
|
+
* Sequel now automatically adds NOT NULL constraints on columns when
|
134
|
+
adding a primary key constraint on the columns, if the database
|
135
|
+
doesn't handle that situation correctly.
|
136
|
+
|
137
|
+
* Database#rollback_checker now returns a thread-safe object.
|
138
|
+
|
139
|
+
* SQL::QualifiedIdentifier#initialize now converts SQL::Identifier
|
140
|
+
arguments to strings, fixing usage of such objects in the
|
141
|
+
schema methods.
|
142
|
+
|
143
|
+
* The prepared_statements plugin now correctly handles lookup by
|
144
|
+
primary key on models with joined datasets.
|
145
|
+
|
146
|
+
* The dataset_associations plugin now handles many_through_many and
|
147
|
+
one_through_many associations that use a single join table. Note
|
148
|
+
there is no reason to create such associations, as many_to_many
|
149
|
+
and one_through_one associations will work for such cases.
|
150
|
+
|
151
|
+
* The insert_returning_select plugin now handles cases where the
|
152
|
+
model doesn't have a valid dataset, fixing usage with the
|
153
|
+
lazy_attributes and dataset_associations plugins, and potentially
|
154
|
+
other plugins.
|
155
|
+
|
156
|
+
* The column_select plugin no longer raises an exception if the
|
157
|
+
model's table does not exist.
|
158
|
+
|
159
|
+
* The class_table_inheritance plugin now works when the
|
160
|
+
prepared_statements plugin is also used.
|
161
|
+
|
162
|
+
* Some adapters now avoid thread-safety issues during loading on
|
163
|
+
ruby implementations without a GVL by avoiding the modification of
|
164
|
+
shared datastructures.
|
165
|
+
|
166
|
+
* When using Database#tables with the :qualify=>true option on
|
167
|
+
PostgreSQL, table names with double or triple underscores are
|
168
|
+
now handled correctly.
|
169
|
+
|
170
|
+
= Backwards Compatibility
|
171
|
+
|
172
|
+
* The following Dataset constants are now frozen: NON_SQL_OPTIONS,
|
173
|
+
ACTION_METHODS, QUERY_METHODS, CONDITIONED_JOIN_TYPES,
|
174
|
+
UNCONDITIONED_JOIN_TYPES, and JOIN_METHODS. Of these,
|
175
|
+
NON_SQL_OPTIONS was previously modified in a non-thread-safe manner
|
176
|
+
by some adapters. External adapters should switch to having the
|
177
|
+
adapter's dataset non_sql_options method return an array of options
|
178
|
+
that do not affect the SELECT SQL for the adapter's datasets, rather
|
179
|
+
than modifying NON_SQL_OPTIONS.
|