sequel 4.13.0 → 4.14.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.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +24 -0
  3. data/doc/active_record.rdoc +4 -4
  4. data/doc/advanced_associations.rdoc +2 -2
  5. data/doc/association_basics.rdoc +11 -11
  6. data/doc/cheat_sheet.rdoc +7 -7
  7. data/doc/core_extensions.rdoc +1 -1
  8. data/doc/dataset_filtering.rdoc +1 -1
  9. data/doc/extensions.rdoc +1 -1
  10. data/doc/migration.rdoc +3 -3
  11. data/doc/model_hooks.rdoc +1 -1
  12. data/doc/opening_databases.rdoc +4 -0
  13. data/doc/postgresql.rdoc +2 -2
  14. data/doc/prepared_statements.rdoc +1 -1
  15. data/doc/querying.rdoc +31 -31
  16. data/doc/release_notes/4.13.0.txt +1 -1
  17. data/doc/release_notes/4.14.0.txt +68 -0
  18. data/doc/schema_modification.rdoc +1 -1
  19. data/doc/sharding.rdoc +2 -2
  20. data/doc/sql.rdoc +1 -1
  21. data/doc/virtual_rows.rdoc +2 -2
  22. data/lib/sequel/adapters/jdbc/jtds.rb +4 -0
  23. data/lib/sequel/adapters/mysql.rb +18 -18
  24. data/lib/sequel/adapters/mysql2.rb +7 -7
  25. data/lib/sequel/adapters/shared/mysql.rb +15 -5
  26. data/lib/sequel/adapters/shared/postgres.rb +71 -58
  27. data/lib/sequel/adapters/shared/sqlite.rb +2 -2
  28. data/lib/sequel/ast_transformer.rb +1 -1
  29. data/lib/sequel/connection_pool/sharded_single.rb +8 -8
  30. data/lib/sequel/connection_pool/sharded_threaded.rb +8 -8
  31. data/lib/sequel/database/connecting.rb +1 -1
  32. data/lib/sequel/database/schema_generator.rb +12 -0
  33. data/lib/sequel/database/schema_methods.rb +8 -7
  34. data/lib/sequel/database/transactions.rb +1 -2
  35. data/lib/sequel/dataset/actions.rb +4 -4
  36. data/lib/sequel/dataset/graph.rb +4 -0
  37. data/lib/sequel/dataset/query.rb +18 -18
  38. data/lib/sequel/dataset/sql.rb +3 -3
  39. data/lib/sequel/extensions/_pretty_table.rb +1 -0
  40. data/lib/sequel/extensions/arbitrary_servers.rb +3 -2
  41. data/lib/sequel/extensions/columns_introspection.rb +1 -0
  42. data/lib/sequel/extensions/connection_validator.rb +1 -0
  43. data/lib/sequel/extensions/constraint_validations.rb +1 -0
  44. data/lib/sequel/extensions/current_datetime_timestamp.rb +1 -0
  45. data/lib/sequel/extensions/dataset_source_alias.rb +1 -0
  46. data/lib/sequel/extensions/date_arithmetic.rb +1 -0
  47. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +1 -0
  48. data/lib/sequel/extensions/error_sql.rb +1 -0
  49. data/lib/sequel/extensions/eval_inspect.rb +1 -0
  50. data/lib/sequel/extensions/filter_having.rb +1 -0
  51. data/lib/sequel/extensions/from_block.rb +1 -0
  52. data/lib/sequel/extensions/graph_each.rb +1 -0
  53. data/lib/sequel/extensions/hash_aliases.rb +1 -0
  54. data/lib/sequel/extensions/looser_typecasting.rb +1 -0
  55. data/lib/sequel/extensions/meta_def.rb +1 -0
  56. data/lib/sequel/extensions/migration.rb +1 -0
  57. data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +1 -0
  58. data/lib/sequel/extensions/named_timezones.rb +1 -0
  59. data/lib/sequel/extensions/null_dataset.rb +1 -0
  60. data/lib/sequel/extensions/pagination.rb +1 -0
  61. data/lib/sequel/extensions/pg_array.rb +2 -2
  62. data/lib/sequel/extensions/pg_array_ops.rb +1 -0
  63. data/lib/sequel/extensions/pg_enum.rb +1 -0
  64. data/lib/sequel/extensions/pg_hstore_ops.rb +1 -0
  65. data/lib/sequel/extensions/pg_json_ops.rb +1 -0
  66. data/lib/sequel/extensions/pg_loose_count.rb +1 -0
  67. data/lib/sequel/extensions/pg_range_ops.rb +1 -0
  68. data/lib/sequel/extensions/pg_row_ops.rb +1 -0
  69. data/lib/sequel/extensions/pg_static_cache_updater.rb +1 -0
  70. data/lib/sequel/extensions/pretty_table.rb +1 -0
  71. data/lib/sequel/extensions/query.rb +1 -0
  72. data/lib/sequel/extensions/query_literals.rb +1 -0
  73. data/lib/sequel/extensions/schema_caching.rb +1 -0
  74. data/lib/sequel/extensions/schema_dumper.rb +1 -1
  75. data/lib/sequel/extensions/select_remove.rb +1 -0
  76. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +1 -0
  77. data/lib/sequel/extensions/server_block.rb +1 -0
  78. data/lib/sequel/extensions/set_overrides.rb +1 -0
  79. data/lib/sequel/extensions/split_array_nil.rb +1 -0
  80. data/lib/sequel/extensions/thread_local_timezones.rb +1 -0
  81. data/lib/sequel/extensions/to_dot.rb +1 -0
  82. data/lib/sequel/model/associations.rb +5 -5
  83. data/lib/sequel/model/base.rb +3 -3
  84. data/lib/sequel/plugins/association_proxies.rb +1 -1
  85. data/lib/sequel/plugins/caching.rb +8 -3
  86. data/lib/sequel/plugins/class_table_inheritance.rb +20 -11
  87. data/lib/sequel/plugins/composition.rb +18 -18
  88. data/lib/sequel/plugins/json_serializer.rb +3 -3
  89. data/lib/sequel/plugins/lazy_attributes.rb +23 -9
  90. data/lib/sequel/plugins/many_through_many.rb +21 -21
  91. data/lib/sequel/plugins/nested_attributes.rb +7 -3
  92. data/lib/sequel/plugins/pg_row.rb +1 -1
  93. data/lib/sequel/plugins/rcte_tree.rb +13 -13
  94. data/lib/sequel/plugins/sharding.rb +6 -6
  95. data/lib/sequel/plugins/timestamps.rb +4 -4
  96. data/lib/sequel/plugins/touch.rb +7 -7
  97. data/lib/sequel/plugins/tree.rb +1 -1
  98. data/lib/sequel/plugins/validation_class_methods.rb +36 -36
  99. data/lib/sequel/plugins/validation_helpers.rb +3 -4
  100. data/lib/sequel/plugins/xml_serializer.rb +29 -29
  101. data/lib/sequel/sql.rb +22 -11
  102. data/lib/sequel/version.rb +1 -1
  103. data/spec/adapters/postgres_spec.rb +10 -0
  104. data/spec/core/database_spec.rb +3 -4
  105. data/spec/core/dataset_spec.rb +16 -1
  106. data/spec/core/expression_filters_spec.rb +12 -0
  107. data/spec/core/object_graph_spec.rb +5 -0
  108. data/spec/core/placeholder_literalizer_spec.rb +8 -0
  109. data/spec/extensions/caching_spec.rb +18 -0
  110. data/spec/extensions/class_table_inheritance_spec.rb +34 -0
  111. data/spec/extensions/many_through_many_spec.rb +4 -0
  112. data/spec/extensions/nested_attributes_spec.rb +59 -4
  113. data/spec/extensions/pg_array_associations_spec.rb +5 -0
  114. data/spec/extensions/single_table_inheritance_spec.rb +23 -1
  115. data/spec/integration/plugin_test.rb +17 -0
  116. data/spec/model/eager_loading_spec.rb +8 -0
  117. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 22556ea07ee280b6aeb118f6079e84cd50079cd4
4
- data.tar.gz: 011dbf4ff522233e9bed8a1b2bab18347237345b
3
+ metadata.gz: 9b817d0bad633a1df7f0a331264d8ce67e0a2c40
4
+ data.tar.gz: e46c816ef87e537d58a982e876011f14ab42c6a3
5
5
  SHA512:
6
- metadata.gz: 9dc9163ebb7f4066cd44da3bdd85b1f5f26cea75b4af812f50ef2c950742b38b992b5c0fbdf61428395b3624788b31cf9f42a9da9b7bfac4ea4976cd29c73b69
7
- data.tar.gz: 0ba493e43d63d2fe3d750a621199bb5f43b39e72858424e0089ff977045a3bc6b1c472751ad4c629bbf83680de7bad227cd29c4d7f705389ee212ee638e5c77f
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)
@@ -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| ...} # No cookie
331
- Artist.eager(:albums=>[:tags, :tracks]).all{|a| ...} # Cookie
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|
@@ -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 now associated object:
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 you handle the same case if
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 you handle the same case if
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 you handle the same case if
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 table
913
- that references associated model's primary key, as a symbol. Defaults to
914
- :<i>association</i>_id. Can use an array of symbols for a composite key
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 you handle the same case if
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 you handle the same case if
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 you handle the same case if
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)) & Sequel.~(:z => 3)).sql
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 #=> array of columns in the result set, does a SELECT
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, ...}], ...]
@@ -275,7 +275,7 @@ Array#case and Hash#case return an SQL CASE expression, where the keys are condi
275
275
 
276
276
  Alternative: Sequel.case:
277
277
 
278
- Sequel.case({:a=>[2,3]}=>1}, 0)
278
+ Sequel.case({{:a=>[2,3]}=>1}, 0)
279
279
 
280
280
  ==== sql_expr
281
281
 
@@ -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)).sql
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
 
@@ -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=>[:insert, :update], :each_row=>true)
164
- # CREATE TRIGGER trg_updated_at BEFORE INSERT OR UPDATE ON "table" FOR EACH ROW EXECUTE PROCEDURE set_updated_at()
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=>$:new_n)
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
- #<Artist @values={:name=>"AS", :id=>2}>]
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
- 2=>#<Artist @values={:id=>2, :name=>"AS"}>}
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