sequel 4.39.0 → 4.40.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +34 -0
  3. data/README.rdoc +8 -4
  4. data/doc/active_record.rdoc +1 -1
  5. data/doc/advanced_associations.rdoc +7 -7
  6. data/doc/association_basics.rdoc +7 -7
  7. data/doc/cheat_sheet.rdoc +5 -3
  8. data/doc/core_extensions.rdoc +3 -3
  9. data/doc/dataset_filtering.rdoc +1 -1
  10. data/doc/object_model.rdoc +16 -7
  11. data/doc/postgresql.rdoc +3 -3
  12. data/doc/querying.rdoc +3 -3
  13. data/doc/release_notes/4.40.0.txt +179 -0
  14. data/doc/security.rdoc +2 -1
  15. data/doc/sql.rdoc +34 -18
  16. data/doc/testing.rdoc +1 -0
  17. data/doc/virtual_rows.rdoc +11 -2
  18. data/lib/sequel/adapters/jdbc/derby.rb +7 -1
  19. data/lib/sequel/adapters/jdbc/h2.rb +15 -1
  20. data/lib/sequel/adapters/oracle.rb +9 -5
  21. data/lib/sequel/adapters/postgres.rb +0 -1
  22. data/lib/sequel/adapters/shared/cubrid.rb +11 -11
  23. data/lib/sequel/adapters/shared/db2.rb +4 -8
  24. data/lib/sequel/adapters/shared/mssql.rb +41 -28
  25. data/lib/sequel/adapters/shared/mysql.rb +9 -6
  26. data/lib/sequel/adapters/shared/oracle.rb +16 -5
  27. data/lib/sequel/adapters/shared/postgres.rb +84 -45
  28. data/lib/sequel/adapters/shared/sqlanywhere.rb +29 -15
  29. data/lib/sequel/adapters/shared/sqlite.rb +6 -6
  30. data/lib/sequel/core.rb +61 -10
  31. data/lib/sequel/database/connecting.rb +2 -1
  32. data/lib/sequel/database/features.rb +7 -0
  33. data/lib/sequel/database/query.rb +1 -1
  34. data/lib/sequel/database/schema_methods.rb +30 -3
  35. data/lib/sequel/database/transactions.rb +4 -2
  36. data/lib/sequel/dataset/actions.rb +1 -1
  37. data/lib/sequel/dataset/graph.rb +6 -1
  38. data/lib/sequel/dataset/query.rb +14 -7
  39. data/lib/sequel/dataset/sql.rb +2 -2
  40. data/lib/sequel/extensions/core_extensions.rb +2 -1
  41. data/lib/sequel/extensions/pg_row.rb +2 -2
  42. data/lib/sequel/extensions/s.rb +57 -0
  43. data/lib/sequel/extensions/set_overrides.rb +5 -1
  44. data/lib/sequel/extensions/sql_expr.rb +1 -0
  45. data/lib/sequel/extensions/symbol_aref.rb +71 -0
  46. data/lib/sequel/extensions/symbol_aref_refinement.rb +41 -0
  47. data/lib/sequel/extensions/symbol_as.rb +23 -0
  48. data/lib/sequel/extensions/symbol_as_refinement.rb +35 -0
  49. data/lib/sequel/model/base.rb +3 -3
  50. data/lib/sequel/plugins/class_table_inheritance.rb +14 -3
  51. data/lib/sequel/plugins/column_select.rb +4 -2
  52. data/lib/sequel/plugins/dataset_associations.rb +12 -4
  53. data/lib/sequel/plugins/insert_returning_select.rb +1 -1
  54. data/lib/sequel/plugins/mssql_optimistic_locking.rb +1 -1
  55. data/lib/sequel/plugins/prepared_statements.rb +1 -0
  56. data/lib/sequel/sql.rb +40 -8
  57. data/lib/sequel/version.rb +1 -1
  58. data/spec/adapters/firebird_spec.rb +3 -3
  59. data/spec/adapters/mssql_spec.rb +40 -40
  60. data/spec/adapters/mysql_spec.rb +5 -5
  61. data/spec/adapters/oracle_spec.rb +4 -4
  62. data/spec/adapters/postgres_spec.rb +135 -124
  63. data/spec/adapters/spec_helper.rb +1 -0
  64. data/spec/adapters/sqlite_spec.rb +6 -6
  65. data/spec/core/dataset_spec.rb +2 -2
  66. data/spec/core/expression_filters_spec.rb +43 -2
  67. data/spec/core/schema_spec.rb +35 -1
  68. data/spec/core_extensions_spec.rb +27 -0
  69. data/spec/extensions/class_table_inheritance_spec.rb +8 -0
  70. data/spec/extensions/column_select_spec.rb +8 -0
  71. data/spec/extensions/core_refinements_spec.rb +1 -1
  72. data/spec/extensions/dataset_associations_spec.rb +9 -0
  73. data/spec/extensions/insert_returning_select_spec.rb +20 -0
  74. data/spec/extensions/prepared_statements_spec.rb +7 -0
  75. data/spec/extensions/s_spec.rb +60 -0
  76. data/spec/extensions/symbol_aref_refinement_spec.rb +28 -0
  77. data/spec/extensions/symbol_as_refinement_spec.rb +21 -0
  78. data/spec/integration/associations_test.rb +62 -57
  79. data/spec/integration/dataset_test.rb +54 -54
  80. data/spec/integration/eager_loader_test.rb +7 -7
  81. data/spec/integration/plugin_test.rb +20 -20
  82. data/spec/integration/prepared_statement_test.rb +1 -1
  83. data/spec/integration/schema_test.rb +21 -0
  84. data/spec/integration/spec_helper.rb +1 -0
  85. metadata +12 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: faeae955d80275ae969500515f7a62f6db3ee1d2
4
- data.tar.gz: 69e8bed296f9a6044bdbecfb29317562f2890bb8
3
+ metadata.gz: 7036daa139080700c287bce9f5c7c2d068d5476e
4
+ data.tar.gz: cd75becb35bf05f4a74b70c6468bbfbd214359e5
5
5
  SHA512:
6
- metadata.gz: 6f87b9f699854635a13c664b49e0a9be073a6f1daf1dc00ccfa7c352d211939d514a39b5a057f4fd90a5f8ed7737ea8afc2f54afcbd68d0b8ca07babeed88e22
7
- data.tar.gz: 9ff3136d2113273d89d4dd1552aa5ba30bea4e39edbfc4535f2762d35e6c21badfd5131e1f726be4d534b9f2f5960e498f9d7e3944e858716b7180c2a23c06ba
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)
@@ -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
- Identifiers can be qualified by using the double underscore special notation <tt>:table__column</tt>:
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.qualify</tt> method:
461
+ Another way to qualify columns is to use the <tt>Sequel[][]</tt> method:
462
462
 
463
- items.literal(Sequel.qualify(:items, :price))
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
- You can also alias identifiers by using the triple underscore special notation <tt>:column___alias</tt> or <tt>:table__column___alias</tt>:
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.
@@ -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(:albums__id, :albums__name, :artists__name___artist).first
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.qualify(j, :copies_sold) > 500000}
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.qualify(j, :artist_name))=>Sequel.function(:lower, Sequel.qualify(lj, :name))}}
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(Sequel.like(:albums__name, 'A%')).
77
- order(:albums__name).
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=>:songs__name, \
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(:lyrics__composer_id, :lyrics__arranger_id, :lyrics__vocalist_id, :lyrics__lyricist_id).
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(:songs__name).all do |song|
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
@@ -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].*, :albums_tags__number]
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{tracks__seconds < 120}
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(:tracks__name)
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.qualify(j, :copies_sold) > 500000}
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.qualify(j, :artist_name))=>
1400
- Sequel.function(:lower, Sequel.qualify(lj, :name))}}
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.qualify(j, :degree).like('B%')}
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.
@@ -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 => :items__group_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(:name___item_name)
174
- DB[:items___items_table].select(:items_table__name___item_name)
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
@@ -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.qualify:
173
+ Alternative: Sequel[][]:
174
174
 
175
- Sequel.qualify(:table, :column)
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.qualify, the qualifier is the first argument.
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
 
@@ -47,7 +47,7 @@ Sequel can check for null values:
47
47
 
48
48
  Or compare two columns:
49
49
 
50
- items.where(:x => :some_table__y).sql
50
+ items.where{{:x => some_table[:y]}}.sql
51
51
  #=> "SELECT * FROM items WHERE (x = some_table.y)"
52
52
 
53
53
  And also compare against multiple values:
@@ -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
- However, they can also represent qualified identifiers by including a double
130
- underscore inside a symbol:
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
- They can also represent an aliased identifier by including a triple underscore
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
- You can combine both qualification and aliasing by using a double underscore
140
- and a triple underscore:
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
 
@@ -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 => {:new__updated_at => :old__updated_at})
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=>:excluded__b}).insert(:a=>1, :b=>2)
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=>:excluded__b}, :update_where=>{:table__status_id=>1}).insert(:a=>1, :b=>2)
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)
@@ -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=>:albums__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.qualify(j, :name) < Sequel.qualify(lj, :name)
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(:artists__id=>:albums__artist_id)
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.