sequel 4.13.0 → 4.14.0

Sign up to get free protection for your applications and to get access to all the features.
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