sequel 4.13.0 → 4.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +24 -0
- data/doc/active_record.rdoc +4 -4
- data/doc/advanced_associations.rdoc +2 -2
- data/doc/association_basics.rdoc +11 -11
- data/doc/cheat_sheet.rdoc +7 -7
- data/doc/core_extensions.rdoc +1 -1
- data/doc/dataset_filtering.rdoc +1 -1
- data/doc/extensions.rdoc +1 -1
- data/doc/migration.rdoc +3 -3
- data/doc/model_hooks.rdoc +1 -1
- data/doc/opening_databases.rdoc +4 -0
- data/doc/postgresql.rdoc +2 -2
- data/doc/prepared_statements.rdoc +1 -1
- data/doc/querying.rdoc +31 -31
- data/doc/release_notes/4.13.0.txt +1 -1
- data/doc/release_notes/4.14.0.txt +68 -0
- data/doc/schema_modification.rdoc +1 -1
- data/doc/sharding.rdoc +2 -2
- data/doc/sql.rdoc +1 -1
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/jdbc/jtds.rb +4 -0
- data/lib/sequel/adapters/mysql.rb +18 -18
- data/lib/sequel/adapters/mysql2.rb +7 -7
- data/lib/sequel/adapters/shared/mysql.rb +15 -5
- data/lib/sequel/adapters/shared/postgres.rb +71 -58
- data/lib/sequel/adapters/shared/sqlite.rb +2 -2
- data/lib/sequel/ast_transformer.rb +1 -1
- data/lib/sequel/connection_pool/sharded_single.rb +8 -8
- data/lib/sequel/connection_pool/sharded_threaded.rb +8 -8
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/schema_generator.rb +12 -0
- data/lib/sequel/database/schema_methods.rb +8 -7
- data/lib/sequel/database/transactions.rb +1 -2
- data/lib/sequel/dataset/actions.rb +4 -4
- data/lib/sequel/dataset/graph.rb +4 -0
- data/lib/sequel/dataset/query.rb +18 -18
- data/lib/sequel/dataset/sql.rb +3 -3
- data/lib/sequel/extensions/_pretty_table.rb +1 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +3 -2
- data/lib/sequel/extensions/columns_introspection.rb +1 -0
- data/lib/sequel/extensions/connection_validator.rb +1 -0
- data/lib/sequel/extensions/constraint_validations.rb +1 -0
- data/lib/sequel/extensions/current_datetime_timestamp.rb +1 -0
- data/lib/sequel/extensions/dataset_source_alias.rb +1 -0
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +1 -0
- data/lib/sequel/extensions/error_sql.rb +1 -0
- data/lib/sequel/extensions/eval_inspect.rb +1 -0
- data/lib/sequel/extensions/filter_having.rb +1 -0
- data/lib/sequel/extensions/from_block.rb +1 -0
- data/lib/sequel/extensions/graph_each.rb +1 -0
- data/lib/sequel/extensions/hash_aliases.rb +1 -0
- data/lib/sequel/extensions/looser_typecasting.rb +1 -0
- data/lib/sequel/extensions/meta_def.rb +1 -0
- data/lib/sequel/extensions/migration.rb +1 -0
- data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +1 -0
- data/lib/sequel/extensions/named_timezones.rb +1 -0
- data/lib/sequel/extensions/null_dataset.rb +1 -0
- data/lib/sequel/extensions/pagination.rb +1 -0
- data/lib/sequel/extensions/pg_array.rb +2 -2
- data/lib/sequel/extensions/pg_array_ops.rb +1 -0
- data/lib/sequel/extensions/pg_enum.rb +1 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +1 -0
- data/lib/sequel/extensions/pg_json_ops.rb +1 -0
- data/lib/sequel/extensions/pg_loose_count.rb +1 -0
- data/lib/sequel/extensions/pg_range_ops.rb +1 -0
- data/lib/sequel/extensions/pg_row_ops.rb +1 -0
- data/lib/sequel/extensions/pg_static_cache_updater.rb +1 -0
- data/lib/sequel/extensions/pretty_table.rb +1 -0
- data/lib/sequel/extensions/query.rb +1 -0
- data/lib/sequel/extensions/query_literals.rb +1 -0
- data/lib/sequel/extensions/schema_caching.rb +1 -0
- data/lib/sequel/extensions/schema_dumper.rb +1 -1
- data/lib/sequel/extensions/select_remove.rb +1 -0
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +1 -0
- data/lib/sequel/extensions/server_block.rb +1 -0
- data/lib/sequel/extensions/set_overrides.rb +1 -0
- data/lib/sequel/extensions/split_array_nil.rb +1 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -0
- data/lib/sequel/extensions/to_dot.rb +1 -0
- data/lib/sequel/model/associations.rb +5 -5
- data/lib/sequel/model/base.rb +3 -3
- data/lib/sequel/plugins/association_proxies.rb +1 -1
- data/lib/sequel/plugins/caching.rb +8 -3
- data/lib/sequel/plugins/class_table_inheritance.rb +20 -11
- data/lib/sequel/plugins/composition.rb +18 -18
- data/lib/sequel/plugins/json_serializer.rb +3 -3
- data/lib/sequel/plugins/lazy_attributes.rb +23 -9
- data/lib/sequel/plugins/many_through_many.rb +21 -21
- data/lib/sequel/plugins/nested_attributes.rb +7 -3
- data/lib/sequel/plugins/pg_row.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +13 -13
- data/lib/sequel/plugins/sharding.rb +6 -6
- data/lib/sequel/plugins/timestamps.rb +4 -4
- data/lib/sequel/plugins/touch.rb +7 -7
- data/lib/sequel/plugins/tree.rb +1 -1
- data/lib/sequel/plugins/validation_class_methods.rb +36 -36
- data/lib/sequel/plugins/validation_helpers.rb +3 -4
- data/lib/sequel/plugins/xml_serializer.rb +29 -29
- data/lib/sequel/sql.rb +22 -11
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +10 -0
- data/spec/core/database_spec.rb +3 -4
- data/spec/core/dataset_spec.rb +16 -1
- data/spec/core/expression_filters_spec.rb +12 -0
- data/spec/core/object_graph_spec.rb +5 -0
- data/spec/core/placeholder_literalizer_spec.rb +8 -0
- data/spec/extensions/caching_spec.rb +18 -0
- data/spec/extensions/class_table_inheritance_spec.rb +34 -0
- data/spec/extensions/many_through_many_spec.rb +4 -0
- data/spec/extensions/nested_attributes_spec.rb +59 -4
- data/spec/extensions/pg_array_associations_spec.rb +5 -0
- data/spec/extensions/single_table_inheritance_spec.rb +23 -1
- data/spec/integration/plugin_test.rb +17 -0
- data/spec/model/eager_loading_spec.rb +8 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b817d0bad633a1df7f0a331264d8ce67e0a2c40
|
4
|
+
data.tar.gz: e46c816ef87e537d58a982e876011f14ab42c6a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d88876ee4814e172d6ed262b14a87f253e5864d03f8f3167420e10d6d3a873625a1fb797b406bc2438a28d7df846535f9af38f2dc90cc57c6167d6c333723345
|
7
|
+
data.tar.gz: c0a61d9260147f6fa4d458242b7ebb6139eacee710e84eb1361d9527a15dea1ecbad377893b3a0dede352af92061308c4e5fd76d4741df60cdc1cf0f3819ddc3
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
=== 4.14.0 (2014-09-01)
|
2
|
+
|
3
|
+
* Raise original exception if there is an exception raised when rolling back transaction/savepoint (jeremyevans) (#875)
|
4
|
+
|
5
|
+
* Allow delayed evaluation blocks to take dataset as an argument (jeremyevans)
|
6
|
+
|
7
|
+
* Allow more types as filter expressions, only specifically disallow Numeric/String expressions (jeremyevans)
|
8
|
+
|
9
|
+
* Remove objects from cached association array at time of nested_attributes call instead of waiting until save (jeremyevans)
|
10
|
+
|
11
|
+
* Handle composite primary keys when working around validation issues for one_to_(one|many) associations in nested_attributes plugin (jeremyevans) (#870)
|
12
|
+
|
13
|
+
* Recognize additional disconnect error in jdbc/jtds adapter (jeremyevans)
|
14
|
+
|
15
|
+
* Have association_join work with existing model selections (jeremyevans)
|
16
|
+
|
17
|
+
* Fix regression in class_table_inheritance plugin when lazily loading column in middle table (jeremyevans) (#862)
|
18
|
+
|
19
|
+
* Add cache_key_prefix method to caching plugin, which can be overridden for custom handling (pete) (#861)
|
20
|
+
|
21
|
+
* Add :when option to PostgreSQL create_trigger method, for adding a filter to the trigger (aschrab) (#860)
|
22
|
+
|
23
|
+
* Recognize an additional serialization failure on PostgreSQL (tmtm) (#857)
|
24
|
+
|
1
25
|
=== 4.13.0 (2014-08-01)
|
2
26
|
|
3
27
|
* Use copy constructors instead of overriding Model#dup and #clone (ged, jeremyevans) (#852)
|
data/doc/active_record.rdoc
CHANGED
@@ -327,8 +327,8 @@ ActiveRecord 2 tries to guess whether to use preloading or JOINs for eager loadi
|
|
327
327
|
|
328
328
|
With either way of eager loading, you must call +all+ to retrieve all records at once. You cannot use +each+, +map+, or one of the other Enumerable methods. Just like +each+, +all+ takes a block that iterates over the records:
|
329
329
|
|
330
|
-
Artist.eager(:albums=>[:tags, :tracks]).each{|a|
|
331
|
-
Artist.eager(:albums=>[:tags, :tracks]).all{|a|
|
330
|
+
Artist.eager(:albums=>[:tags, :tracks]).each{|a| } # No cookie
|
331
|
+
Artist.eager(:albums=>[:tags, :tracks]).all{|a| } # Cookie
|
332
332
|
|
333
333
|
Like ActiveRecord, Sequel supports cascading of eager loading for both methods of eager loading.
|
334
334
|
|
@@ -495,7 +495,7 @@ Note that +test_connection+ will return true if a connection can be made, but wi
|
|
495
495
|
Sequel only uses connections for the minimum amount of time necessary, checking them out to do a query, and returning them as soon as the query finishes. If you do want direct access to the connection object:
|
496
496
|
|
497
497
|
Sequel::Model.db.synchronize do |connection|
|
498
|
-
...
|
498
|
+
# ...
|
499
499
|
end
|
500
500
|
|
501
501
|
Note that the connection is yielded to the block, and the block ensures it is returned to the pool. Sequel doesn't have a method that returns a connection, since that would check it out with no ability to ensure it is returned to the pool.
|
@@ -532,7 +532,7 @@ If you really want to destroy all rows in the table,call +destroy+ on the Model'
|
|
532
532
|
|
533
533
|
If you want to use a specific <tt>Sequel::Database</tt> object, you can use <tt>db=</tt>:
|
534
534
|
|
535
|
-
BACKUP_DB = Sequel.connect(
|
535
|
+
BACKUP_DB = Sequel.connect('postgres://...')
|
536
536
|
Album.db = BACKUP_DB
|
537
537
|
|
538
538
|
If you want a specific dataset in that database, you can use +set_dataset+ or <tt>dataset=</tt>:
|
@@ -194,7 +194,7 @@ artist or tracks method on the album will not do another database lookup.
|
|
194
194
|
|
195
195
|
So putting everything together, the artist eager loader looks like:
|
196
196
|
|
197
|
-
:eager_loader=>(proc do |eo_opts|
|
197
|
+
Album.many_to_one :artist, :eager_loader=>(proc do |eo_opts|
|
198
198
|
eo_opts[:rows].each{|album| album.associations[:artist] = nil}
|
199
199
|
id_map = eo_opts[:id_map]
|
200
200
|
Artist.where(:id=>id_map.keys).all do |artist|
|
@@ -208,7 +208,7 @@ So putting everything together, the artist eager loader looks like:
|
|
208
208
|
|
209
209
|
and the tracks eager loader looks like:
|
210
210
|
|
211
|
-
:eager_loader=>(proc do |eo_opts|
|
211
|
+
Album.one_to_many :tracks, :eager_loader=>(proc do |eo_opts|
|
212
212
|
eo_opts[:rows].each{|album| album.associations[:tracks] = []}
|
213
213
|
id_map = eo_opts[:id_map]
|
214
214
|
Track.where(:id=>id_map.keys).all do |tracks|
|
data/doc/association_basics.rdoc
CHANGED
@@ -697,7 +697,7 @@ and a new associated object will be created from them:
|
|
697
697
|
|
698
698
|
@artist.add_album(:name=>'RF') # creates Album object
|
699
699
|
|
700
|
-
The add_<i>association</i> method returns the
|
700
|
+
The add_<i>association</i> method returns the new associated object:
|
701
701
|
|
702
702
|
@album = @artist.add_album(:name=>'RF')
|
703
703
|
|
@@ -817,7 +817,7 @@ artist using the artist= method, this approach may perform better.
|
|
817
817
|
|
818
818
|
=== \_add_<i>association</i> (:adder option)
|
819
819
|
|
820
|
-
Continuing with the same example, here's how would
|
820
|
+
Continuing with the same example, here's how you would handle the same case if
|
821
821
|
you also wanted to handle the Artist#add_album method:
|
822
822
|
|
823
823
|
class Artist < Sequel::Model
|
@@ -832,7 +832,7 @@ you also wanted to handle the Artist#add_album method:
|
|
832
832
|
|
833
833
|
=== \_remove_<i>association</i> (:remover option)
|
834
834
|
|
835
|
-
Continuing with the same example, here's how would
|
835
|
+
Continuing with the same example, here's how you would handle the same case if
|
836
836
|
you also wanted to handle the Artist#remove_album method:
|
837
837
|
|
838
838
|
class Artist < Sequel::Model
|
@@ -847,7 +847,7 @@ you also wanted to handle the Artist#remove_album method:
|
|
847
847
|
|
848
848
|
=== \_remove_all_<i>association</i> (:clearer option)
|
849
849
|
|
850
|
-
Continuing with the same example, here's how would
|
850
|
+
Continuing with the same example, here's how you would handle the same case if
|
851
851
|
you also wanted to handle the Artist#remove_all_albums method:
|
852
852
|
|
853
853
|
class Artist < Sequel::Model
|
@@ -909,10 +909,10 @@ or a String:
|
|
909
909
|
|
910
910
|
==== :key
|
911
911
|
|
912
|
-
For +many_to_one+ associations, is the foreign_key in current model's
|
913
|
-
that references associated model's primary key
|
914
|
-
:<i>association</i>_id. Can use an array of symbols for a
|
915
|
-
association.
|
912
|
+
For +many_to_one+ associations, this is the foreign_key in the current model's
|
913
|
+
table that references the associated model's primary key as a symbol.
|
914
|
+
Defaults to :<i>association</i>_id. Can use an array of symbols for a
|
915
|
+
composite key association.
|
916
916
|
|
917
917
|
Album.many_to_one :artist # :key=>:artist_id
|
918
918
|
|
@@ -1583,7 +1583,7 @@ using the association setter method.
|
|
1583
1583
|
|
1584
1584
|
==== :adder [*_to_many associations]
|
1585
1585
|
|
1586
|
-
Continuing with the same example, here's how would
|
1586
|
+
Continuing with the same example, here's how you would handle the same case if
|
1587
1587
|
you also wanted to handle the Artist#add_album method:
|
1588
1588
|
|
1589
1589
|
class Artist < Sequel::Model
|
@@ -1594,7 +1594,7 @@ you also wanted to handle the Artist#add_album method:
|
|
1594
1594
|
|
1595
1595
|
==== :remover [*_to_many associations]
|
1596
1596
|
|
1597
|
-
Continuing with the same example, here's how would
|
1597
|
+
Continuing with the same example, here's how you would handle the same case if
|
1598
1598
|
you also wanted to handle the Artist#remove_album method:
|
1599
1599
|
|
1600
1600
|
class Artist < Sequel::Model
|
@@ -1605,7 +1605,7 @@ you also wanted to handle the Artist#remove_album method:
|
|
1605
1605
|
|
1606
1606
|
==== :clearer [*_to_many associations]
|
1607
1607
|
|
1608
|
-
Continuing with the same example, here's how would
|
1608
|
+
Continuing with the same example, here's how you would handle the same case if
|
1609
1609
|
you also wanted to handle the Artist#remove_all_albums method:
|
1610
1610
|
|
1611
1611
|
class Artist < Sequel::Model
|
data/doc/cheat_sheet.rdoc
CHANGED
@@ -20,7 +20,7 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
|
|
20
20
|
require 'logger'
|
21
21
|
DB = Sequel.sqlite '', :loggers => [Logger.new($stdout)]
|
22
22
|
# or
|
23
|
-
DB.loggers << Logger.new(
|
23
|
+
DB.loggers << Logger.new($stdout)
|
24
24
|
|
25
25
|
== Using raw SQL
|
26
26
|
|
@@ -100,7 +100,7 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
|
|
100
100
|
DB[:items].where{(x > 5) & (y > 10)}.sql
|
101
101
|
# SELECT * FROM items WHERE ((x > 5) AND (y > 10))
|
102
102
|
|
103
|
-
DB[:items].where(Sequel.or(:x => 1, :y => 2)
|
103
|
+
DB[:items].where(Sequel.or(:x => 1, :y => 2) & Sequel.~(:z => 3)).sql
|
104
104
|
# SELECT * FROM items WHERE (((x = 1) OR (y = 2)) AND (z != 3))
|
105
105
|
|
106
106
|
=== Mathematical operators
|
@@ -150,7 +150,7 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
|
|
150
150
|
dataset.update(:updated_at => Sequel.function(:NOW))
|
151
151
|
dataset.update(:updated_at => Sequel.lit('NOW()'))
|
152
152
|
|
153
|
-
dataset.update(:updated_at => Sequel.lit("DateValue('1/1/2001')")
|
153
|
+
dataset.update(:updated_at => Sequel.lit("DateValue('1/1/2001')"))
|
154
154
|
dataset.update(:updated_at => Sequel.function(:DateValue, '1/1/2001'))
|
155
155
|
|
156
156
|
== Schema Manipulation
|
@@ -184,7 +184,7 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
|
|
184
184
|
Database#transaction is re-entrant:
|
185
185
|
|
186
186
|
DB.transaction do # BEGIN issued only here
|
187
|
-
DB.transaction
|
187
|
+
DB.transaction do
|
188
188
|
dataset << {:first_name => 'Inigo', :last_name => 'Montoya'}
|
189
189
|
end
|
190
190
|
end # COMMIT issued only here
|
@@ -205,7 +205,7 @@ Savepoints can be used if the database supports it:
|
|
205
205
|
|
206
206
|
DB.transaction do
|
207
207
|
dataset << {:first_name => 'Farm', :last_name => 'Boy'} # Inserted
|
208
|
-
DB.transaction(:savepoint=>true) # This savepoint is rolled back
|
208
|
+
DB.transaction(:savepoint=>true) do # This savepoint is rolled back
|
209
209
|
dataset << {:first_name => 'Inigo', :last_name => 'Montoya'} # Not inserted
|
210
210
|
raise(Sequel::Rollback) if something_bad_happened
|
211
211
|
end
|
@@ -216,5 +216,5 @@ Savepoints can be used if the database supports it:
|
|
216
216
|
|
217
217
|
dataset.sql # "SELECT * FROM items"
|
218
218
|
dataset.delete_sql # "DELETE FROM items"
|
219
|
-
dataset.columns
|
220
|
-
DB.schema(:items) => [[:id, {:type=>:integer, ...}], [:name, {:type=>:string, ...}], ...]
|
219
|
+
dataset.columns # => array of columns in the result set, does a SELECT
|
220
|
+
DB.schema(:items) # => [[:id, {:type=>:integer, ...}], [:name, {:type=>:string, ...}], ...]
|
data/doc/core_extensions.rdoc
CHANGED
data/doc/dataset_filtering.rdoc
CHANGED
@@ -110,7 +110,7 @@ This works with other hash values, such as arrays and ranges:
|
|
110
110
|
items.where{Sequel.|({:category => ['ruby', 'other']}, (:price - 100 > 200))}.sql
|
111
111
|
#=> "SELECT * FROM items WHERE ((category IN ('ruby', 'other')) OR ((price - 100) <= 200))"
|
112
112
|
|
113
|
-
items.where{Sequel.&({:price => (100..200)}, :active)
|
113
|
+
items.where{Sequel.&({:price => (100..200)}, :active)}.sql
|
114
114
|
#=> "SELECT * FROM items WHERE ((price >= 100 AND price <= 200) AND active)"
|
115
115
|
|
116
116
|
=== Negating conditions
|
data/doc/extensions.rdoc
CHANGED
@@ -79,6 +79,6 @@ The first argument is the name of the extension as a symbol, and the second is t
|
|
79
79
|
|
80
80
|
You can also call <tt>Sequel::Dataset.register_extension</tt> with a proc:
|
81
81
|
|
82
|
-
Sequel::Dataset.register_extension(:extension_name){|ds|
|
82
|
+
Sequel::Dataset.register_extension(:extension_name){|ds| }
|
83
83
|
|
84
84
|
Note that if you use a proc, a corresponding Database extension will not be created automatically (you can still call <tt>Sequel::Database.register_extension</tt> manually in this case).
|
data/doc/migration.rdoc
CHANGED
@@ -385,14 +385,14 @@ However, the migrations you write should contain an +up+ block that does somethi
|
|
385
385
|
reverses the changes made by the +up+ block:
|
386
386
|
|
387
387
|
Sequel.migration do
|
388
|
-
up{
|
389
|
-
down{
|
388
|
+
up{}
|
389
|
+
down{}
|
390
390
|
end
|
391
391
|
|
392
392
|
or they should use the reversible migrations feature with a +change+ block:
|
393
393
|
|
394
394
|
Sequel.migration do
|
395
|
-
change{
|
395
|
+
change{}
|
396
396
|
end
|
397
397
|
|
398
398
|
== What to put in your migration's +down+ block
|
data/doc/model_hooks.rdoc
CHANGED
@@ -121,7 +121,7 @@ However, skipping hooks is a bad idea in general and should be avoided. As ment
|
|
121
121
|
|
122
122
|
The +this+ dataset works just like any other dataset, so you can call +update+ on it to modify it:
|
123
123
|
|
124
|
-
album.this.update(:copies_sold=>album.copies_sold + 1)
|
124
|
+
album.this.update(:copies_sold=>album.copies_sold + 1)
|
125
125
|
|
126
126
|
If you want to insert a row into the model's table without running the creation hooks, you can use <tt>Model.insert</tt> instead of <tt>Model.create</tt>:
|
127
127
|
|
data/doc/opening_databases.rdoc
CHANGED
@@ -381,6 +381,10 @@ The following additional options are supported:
|
|
381
381
|
to handle notice/warning messages differently. Only respected if using the pg library).
|
382
382
|
:sslmode :: Set to 'disable', 'allow', 'prefer', 'require' to choose how to treat SSL (only
|
383
383
|
respected if using the pg library)
|
384
|
+
:search_path :: Set to the schema search_path. This can either be a single string containing the schemas
|
385
|
+
separated by commas (for use via a URL: <tt>postgres:///?search_path=schema1,schema2</tt>), or it
|
386
|
+
can be an array of strings (for use via an option:
|
387
|
+
<tt>Sequel.postgres(:search_path=>['schema1', 'schema2'])</tt>).
|
384
388
|
:use_iso_date_format :: This can be set to false to not force the ISO date format. Sequel forces
|
385
389
|
it by default to allow for an optimization.
|
386
390
|
|
data/doc/postgresql.rdoc
CHANGED
@@ -160,8 +160,8 @@ 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
|
164
|
-
# CREATE TRIGGER trg_updated_at BEFORE
|
163
|
+
DB.create_trigger(:table, :trg_updated_at, :set_updated_at, :events=>:update, :each_row=>true, :when => {:new__updated_at => :old__updated_at})
|
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"
|
167
167
|
|
@@ -57,7 +57,7 @@ may itself contain placeholders:
|
|
57
57
|
# Insert record with 'Jim', note that the previous filter is ignored
|
58
58
|
ds.call(:insert, {:n=>'Jim'}, :name=>:$n)
|
59
59
|
# Change name to 'Bob' for all records with name of 'Jim'
|
60
|
-
ds.call(:update, {:n=>'Jim', :new_n=>'Bob'}, :name
|
60
|
+
ds.call(:update, {:n=>'Jim', :new_n=>'Bob'}, :name=>:$new_n)
|
61
61
|
|
62
62
|
== Prepared Statements
|
63
63
|
|
data/doc/querying.rdoc
CHANGED
@@ -40,7 +40,7 @@ by its primary key value:
|
|
40
40
|
# Find artist with primary key (id) 1
|
41
41
|
artist = Artist[1]
|
42
42
|
# SELECT * FROM artists WHERE id = 1
|
43
|
-
=> #<Artist @values={:name=>"YJM", :id=>1}>
|
43
|
+
# => #<Artist @values={:name=>"YJM", :id=>1}>
|
44
44
|
|
45
45
|
If there is no record with the given primary key, nil will be returned. If you want
|
46
46
|
to raise an exception if no record is found, you can use <tt>Sequel::Model.with_pk!</tt>:
|
@@ -54,17 +54,17 @@ If you just want the first record in the dataset,
|
|
54
54
|
|
55
55
|
artist = Artist.first
|
56
56
|
# SELECT * FROM artists LIMIT 1
|
57
|
-
=> #<Artist @values={:name=>"YJM", :id=>1}>
|
57
|
+
# => #<Artist @values={:name=>"YJM", :id=>1}>
|
58
58
|
|
59
59
|
Any options you pass to +first+ will be used as a filter:
|
60
60
|
|
61
61
|
artist = Artist.first(:name => 'YJM')
|
62
62
|
# SELECT * FROM artists WHERE (name = 'YJM') LIMIT 1
|
63
|
-
=> #<Artist @values={:name=>"YJM", :id=>1}>
|
63
|
+
# => #<Artist @values={:name=>"YJM", :id=>1}>
|
64
64
|
|
65
65
|
artist = Artist.first(Sequel.like(:name, 'Y%'))
|
66
66
|
# SELECT * FROM artists WHERE (name LIKE 'Y%' ESCAPE '\') LIMIT 1
|
67
|
-
=> #<Artist @values={:name=>"YJM", :id=>1}>
|
67
|
+
# => #<Artist @values={:name=>"YJM", :id=>1}>
|
68
68
|
|
69
69
|
If there is no matching row, +first+ will return nil. If you want to
|
70
70
|
raise an exception instead, use <tt>first!</tt>.
|
@@ -74,7 +74,7 @@ requires an argument:
|
|
74
74
|
|
75
75
|
DB[:artists][:name => 'YJM']
|
76
76
|
# SELECT * FROM artists WHERE (name = 'YJM') LIMIT 1
|
77
|
-
=> {:name=>"YJM", :id=>1}
|
77
|
+
# => {:name=>"YJM", :id=>1}
|
78
78
|
|
79
79
|
Note that while Model.[] allows you to pass a primary key directly,
|
80
80
|
Dataset#[] does not (unless it is a model dataset).
|
@@ -89,7 +89,7 @@ reverse order by the primary key field:
|
|
89
89
|
|
90
90
|
artist = Artist.last
|
91
91
|
# SELECT * FROM artists ORDER BY id DESC LIMIT 1
|
92
|
-
=> #<Artist @values={:name=>"YJM", :id=>1}>
|
92
|
+
# => #<Artist @values={:name=>"YJM", :id=>1}>
|
93
93
|
|
94
94
|
Note that what +last+ does is reverse the order of the dataset and then
|
95
95
|
call +first+. This is why +last+ raises a Sequel::Error if there is no
|
@@ -107,7 +107,7 @@ you want:
|
|
107
107
|
|
108
108
|
artist_name = Artist.get(:name)
|
109
109
|
# SELECT name FROM artists LIMIT 1
|
110
|
-
=> "YJM"
|
110
|
+
# => "YJM"
|
111
111
|
|
112
112
|
=== Retrieving Multiple Objects
|
113
113
|
|
@@ -119,8 +119,8 @@ want to use:
|
|
119
119
|
|
120
120
|
artists = Artist.all
|
121
121
|
# SELECT * FROM artists
|
122
|
-
=> [#<Artist @values={:name=>"YJM", :id=>1}>,
|
123
|
-
|
122
|
+
# => [#<Artist @values={:name=>"YJM", :id=>1}>,
|
123
|
+
# #<Artist @values={:name=>"AS", :id=>2}>]
|
124
124
|
|
125
125
|
==== Using an Enumerable Interface
|
126
126
|
|
@@ -138,7 +138,7 @@ such as +map+:
|
|
138
138
|
|
139
139
|
artist_names = Artist.map{|x| x.name}
|
140
140
|
# SELECT * FROM artists
|
141
|
-
=> ["YJM", "AS"]
|
141
|
+
# => ["YJM", "AS"]
|
142
142
|
|
143
143
|
==== As an Array of Column Values
|
144
144
|
|
@@ -148,7 +148,7 @@ given column. So the previous example can be handled more easily with:
|
|
148
148
|
|
149
149
|
artist_names = Artist.map(:name)
|
150
150
|
# SELECT * FROM artists
|
151
|
-
=> ["YJM", "AS"]
|
151
|
+
# => ["YJM", "AS"]
|
152
152
|
|
153
153
|
One difference between these two ways of returning an array of values is
|
154
154
|
that providing +map+ with an argument is really doing:
|
@@ -162,21 +162,21 @@ single column and return an array of the columns values, you can use
|
|
162
162
|
|
163
163
|
artist_names = Artist.select_map(:name)
|
164
164
|
# SELECT name FROM artists
|
165
|
-
=> ["YJM", "AS"]
|
165
|
+
# => ["YJM", "AS"]
|
166
166
|
|
167
167
|
It's also common to want to order such a map, so Sequel provides a
|
168
168
|
+select_order_map+ method as well:
|
169
169
|
|
170
170
|
artist_names = Artist.select_order_map(:name)
|
171
171
|
# SELECT name FROM artists ORDER BY name
|
172
|
-
=> ["AS", "YJM"]
|
172
|
+
# => ["AS", "YJM"]
|
173
173
|
|
174
174
|
In all of these cases, you can provide an array of column symbols and
|
175
175
|
an array of arrays of values will be returned:
|
176
176
|
|
177
177
|
artist_names = Artist.select_map([:id, :name])
|
178
178
|
# SELECT id, name FROM artists
|
179
|
-
=> [[1, "YJM"], [2, "AS"]]
|
179
|
+
# => [[1, "YJM"], [2, "AS"]]
|
180
180
|
|
181
181
|
==== As a Hash
|
182
182
|
|
@@ -185,7 +185,7 @@ using the +to_hash+ method:
|
|
185
185
|
|
186
186
|
artist_names = Artist.to_hash(:id, :name)
|
187
187
|
# SELECT * FROM artists
|
188
|
-
=> {1=>"YJM", 2=>"AS"}
|
188
|
+
# => {1=>"YJM", 2=>"AS"}
|
189
189
|
|
190
190
|
As you can see, the +to_hash+ method uses the first symbol as the key
|
191
191
|
and the second symbol as the value. So if you swap the two arguments the hash
|
@@ -193,7 +193,7 @@ will have its keys and values transposed:
|
|
193
193
|
|
194
194
|
artist_names = Artist.to_hash(:name, :id)
|
195
195
|
# SELECT * FROM artists
|
196
|
-
=> {"YJM"=>1, "AS"=>2}
|
196
|
+
# => {"YJM"=>1, "AS"=>2}
|
197
197
|
|
198
198
|
Now what if you have multiple values for the same key? By default, +to_hash+
|
199
199
|
will just have the last matching value. If you care about all matching values,
|
@@ -202,20 +202,20 @@ values, in the order they were received:
|
|
202
202
|
|
203
203
|
artist_names = Artist.to_hash_groups(:name, :id)
|
204
204
|
# SELECT * FROM artists
|
205
|
-
=> {"YJM"=>[1, 10, ...], "AS"=>[2, 20, ...]}
|
205
|
+
# => {"YJM"=>[1, 10, ...], "AS"=>[2, 20, ...]}
|
206
206
|
|
207
207
|
If you only provide one argument to +to_hash+, it uses the entire hash
|
208
208
|
or model object as the value:
|
209
209
|
|
210
210
|
artist_names = DB[:artists].to_hash(:name)
|
211
211
|
# SELECT * FROM artists
|
212
|
-
=> {"YJM"=>{:id=>1, :name=>"YJM"}, "AS"=>{:id=>2, :name=>"AS"}}
|
212
|
+
# => {"YJM"=>{:id=>1, :name=>"YJM"}, "AS"=>{:id=>2, :name=>"AS"}}
|
213
213
|
|
214
214
|
and +to_hash_groups+ works similarly:
|
215
215
|
|
216
216
|
artist_names = DB[:artists].to_hash_groups(:name)
|
217
217
|
# SELECT * FROM artists
|
218
|
-
=> {"YJM"=>[{:id=>1, :name=>"YJM"}, {:id=>10, :name=>"YJM"}], ...}
|
218
|
+
# => {"YJM"=>[{:id=>1, :name=>"YJM"}, {:id=>10, :name=>"YJM"}], ...}
|
219
219
|
|
220
220
|
Model datasets have a +to_hash+ method that can be called without any
|
221
221
|
arguments, in which case it will use the primary key as the key and
|
@@ -224,8 +224,8 @@ identity map:
|
|
224
224
|
|
225
225
|
artist_names = Artist.to_hash
|
226
226
|
# SELECT * FROM artists
|
227
|
-
=> {1=>#<Artist @values={:id=>1, :name=>"YGM"}>,
|
228
|
-
|
227
|
+
# => {1=>#<Artist @values={:id=>1, :name=>"YGM"}>,
|
228
|
+
# 2=>#<Artist @values={:id=>2, :name=>"AS"}>}
|
229
229
|
|
230
230
|
There is no equivalent handling to +to_hash_groups+, since there would
|
231
231
|
only be one matching record, as the primary key must be unique.
|
@@ -237,13 +237,13 @@ columns selected and return a hash:
|
|
237
237
|
|
238
238
|
artist_names = Artist.select_hash(:name, :id)
|
239
239
|
# SELECT name, id FROM artists
|
240
|
-
=> {"YJM"=>1, "AS"=>2}
|
240
|
+
# => {"YJM"=>1, "AS"=>2}
|
241
241
|
|
242
242
|
Likewise, +select_hash_groups+ also exists:
|
243
243
|
|
244
244
|
artist_names = Artist.select_hash_groups(:name, :id)
|
245
245
|
# SELECT name, id FROM artists
|
246
|
-
=> {"YJM"=>[1, 10, ...], "AS"=>[2, 20, ...]}
|
246
|
+
# => {"YJM"=>[1, 10, ...], "AS"=>[2, 20, ...]}
|
247
247
|
|
248
248
|
== Modifying datasets
|
249
249
|
|
@@ -975,15 +975,15 @@ If you just want to know whether the current dataset would return any rows, use
|
|
975
975
|
|
976
976
|
Album.empty?
|
977
977
|
# SELECT 1 FROM albums LIMIT 1
|
978
|
-
=> false
|
978
|
+
# => false
|
979
979
|
|
980
980
|
Album.where(:id=>0).empty?
|
981
981
|
# SELECT 1 FROM albums WHERE id = 0 LIMIT 1
|
982
|
-
=> true
|
982
|
+
# => true
|
983
983
|
|
984
984
|
Album.where(Sequel.like(:name, 'R%')).empty?
|
985
985
|
# SELECT 1 FROM albums WHERE name LIKE 'R%' ESCAPE '\' LIMIT 1
|
986
|
-
=> false
|
986
|
+
# => false
|
987
987
|
|
988
988
|
== Aggregate Calculations
|
989
989
|
|
@@ -995,23 +995,23 @@ for each of these aggregate functions.
|
|
995
995
|
|
996
996
|
Album.count
|
997
997
|
# SELECT count(*) AS count FROM albums LIMIT 1
|
998
|
-
=> 2
|
998
|
+
# => 2
|
999
999
|
|
1000
1000
|
The other methods take a column argument and call the aggregate function with
|
1001
1001
|
the argument:
|
1002
1002
|
|
1003
1003
|
Album.sum(:id)
|
1004
1004
|
# SELECT sum(id) FROM albums LIMIT 1
|
1005
|
-
=> 3
|
1005
|
+
# => 3
|
1006
1006
|
|
1007
1007
|
Album.avg(:id)
|
1008
1008
|
# SELECT avg(id) FROM albums LIMIT 1
|
1009
|
-
=> 1.5
|
1009
|
+
# => 1.5
|
1010
1010
|
|
1011
1011
|
Album.min(:id)
|
1012
1012
|
# SELECT min(id) FROM albums LIMIT 1
|
1013
|
-
=> 1
|
1013
|
+
# => 1
|
1014
1014
|
|
1015
1015
|
Album.max(:id)
|
1016
1016
|
# SELECT max(id) FROM albums LIMIT 1
|
1017
|
-
=> 2
|
1017
|
+
# => 2
|