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
@@ -96,7 +96,7 @@
|
|
96
96
|
returning the unqualified version of a possibly qualified column.
|
97
97
|
|
98
98
|
* The composition and serialization plugins now support validations
|
99
|
-
on the underlying columns. Previously,
|
99
|
+
on the underlying columns. Previously, they didn't update the
|
100
100
|
underlying columns until after validations were performed. This
|
101
101
|
works better when using the auto_validations plugin.
|
102
102
|
|
@@ -0,0 +1,68 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* Delayed evaluation blocks can now accept the dataset literalizing
|
4
|
+
the delayed evaluation as an argument. This makes it so the
|
5
|
+
delayed evaluation result can depend on the dataset doing the
|
6
|
+
literalization:
|
7
|
+
|
8
|
+
ds = DB[:a].where(Sequel.delay do |ds|
|
9
|
+
{Sequel.qualify(ds.first_source, :col)=>1}
|
10
|
+
end)
|
11
|
+
ds.sql # SELECT * FROM a WHERE (a.col = 1)
|
12
|
+
ds.from(:b).sql # SELECT * FROM b WHERE (b.col = 1)
|
13
|
+
|
14
|
+
* Database#create_trigger on PostgreSQL now supports a :when option
|
15
|
+
to create a filter for the trigger, so that it is only triggered
|
16
|
+
when the filter condition is true.
|
17
|
+
|
18
|
+
* You can now override the cache key prefix in the caching plugin
|
19
|
+
by overriding the cache_key_prefix class method. This can be
|
20
|
+
useful when using a table inheritance plugin.
|
21
|
+
|
22
|
+
= Other Improvements
|
23
|
+
|
24
|
+
* You can now pass arbitrary types to Dataset#where and related
|
25
|
+
methods. Previously, if a type was not explicitly handled, an
|
26
|
+
exception would be raised. Now you can pass any object that can
|
27
|
+
be literalized. The only exception is that you can't pass
|
28
|
+
Numeric objects, since #where and similar methods should
|
29
|
+
only deal with boolean expressions.
|
30
|
+
|
31
|
+
* association_join and related methods now work correctly if the
|
32
|
+
dataset already has an explicit selection.
|
33
|
+
|
34
|
+
* A regression has been fixed in the class_table_inheritance plugin
|
35
|
+
when using a hierarchy of more than 2 levels, when using the
|
36
|
+
superclass to load a subclass instance more than 2 levels below,
|
37
|
+
and later attempting to load a column contained in one of the
|
38
|
+
middle tables.
|
39
|
+
|
40
|
+
* When using _delete or _remove keys in the nested_attributes plugin
|
41
|
+
to remove existing associated objects, the associated objects are
|
42
|
+
now deleted from the cached association array at time of call.
|
43
|
+
This is for consistency when adding new associated objects, where
|
44
|
+
the new associated objects are added to the cached association
|
45
|
+
array at time of call.
|
46
|
+
|
47
|
+
* The nested_attributes plugin now handles composite primary keys
|
48
|
+
correctly when working around validation issues for one_to_one
|
49
|
+
and one_to_many associations.
|
50
|
+
|
51
|
+
* If exception A is raised during a transaction, and exception B
|
52
|
+
is raised while attempting to rollback the transaction, the
|
53
|
+
transaction code will now raise exception A instead of exception B.
|
54
|
+
|
55
|
+
* An additional serialization failure is now detected on PostgreSQL.
|
56
|
+
|
57
|
+
* An additional disconnect error is now recognized in the jdbc/jtds
|
58
|
+
adapter.
|
59
|
+
|
60
|
+
* The code examples in the RDoc are now syntax highlighted, and
|
61
|
+
many minor fixes to the code examples in the RDoc were made.
|
62
|
+
Additionally, many other improvements were made to the RDoc.
|
63
|
+
|
64
|
+
= Backwards Compatibility
|
65
|
+
|
66
|
+
* Dataset#delayed_evaluation_sql_append now accepts the delayed
|
67
|
+
evaluation as an argument, instead of the callable contained by the
|
68
|
+
delayed evaluation.
|
@@ -32,7 +32,7 @@ convert to database types:
|
|
32
32
|
String :a3, :fixed=>true # char(255)
|
33
33
|
String :a4, :fixed=>true, :size=>50 # char(50)
|
34
34
|
String :a5, :text=>true # text
|
35
|
-
File :b
|
35
|
+
File :b # blob
|
36
36
|
Fixnum :c # integer
|
37
37
|
Bignum :d # bigint
|
38
38
|
Float :e # double precision
|
data/doc/sharding.rdoc
CHANGED
@@ -134,12 +134,12 @@ to assume the :default shard. However, you can specify a
|
|
134
134
|
different shard using the :servers_hash option when connecting
|
135
135
|
to the database:
|
136
136
|
|
137
|
-
DB = Sequel.connect(
|
137
|
+
DB = Sequel.connect('postgres://...', :servers_hash=>Hash.new(:some_shard))
|
138
138
|
|
139
139
|
You can also use this feature to raise an exception if an
|
140
140
|
unconfigured shard is used:
|
141
141
|
|
142
|
-
DB = Sequel.connect(
|
142
|
+
DB = Sequel.connect('postgres://...', :servers_hash=>Hash.new{raise 'foo'})
|
143
143
|
|
144
144
|
If you specify a :servers_hash option to raise an exception for non configured
|
145
145
|
shards you should also explicitly specify a :read_only entry in your :servers option
|
data/doc/sql.rdoc
CHANGED
@@ -506,7 +506,7 @@ To select all columns in a table, Sequel supports the * method on identifiers wi
|
|
506
506
|
|
507
507
|
Sequel allows the easy production of SQL CASE statements using the <tt>Sequel.case</tt> method. The first argument is a hash or array of two element arrays representing the conditions, the second argument is the default value (ELSE). The keys of the hash (or first element in each array) is the WHEN condition, and the values of the hash (or second element in each array) is the THEN result. Here are some examples:
|
508
508
|
|
509
|
-
Sequel.case({:column=>1, 0) # (CASE WHEN "column" THEN 1 ELSE 0 END)
|
509
|
+
Sequel.case({:column=>1}, 0) # (CASE WHEN "column" THEN 1 ELSE 0 END)
|
510
510
|
Sequel.case([[column, 1]], 0) # (CASE WHEN "column" THEN 1 ELSE 0 END)
|
511
511
|
Sequel.case({{:column=>nil}=>1}, 0) # (CASE WHEN (column IS NULL) THEN 1 ELSE 0 END)
|
512
512
|
|
data/doc/virtual_rows.rdoc
CHANGED
@@ -157,7 +157,7 @@ function without arguments, then call the * method on the function:
|
|
157
157
|
To append the DISTINCT keyword before the method arguments, just call the
|
158
158
|
distinct method on the returned Function:
|
159
159
|
|
160
|
-
ds.select{|o| o.count(o.col1).distinct
|
160
|
+
ds.select{|o| o.count(o.col1).distinct}
|
161
161
|
ds.select{count(col1).distinct}
|
162
162
|
# SELECT count(DISTINCT col1)
|
163
163
|
|
@@ -230,7 +230,7 @@ virtual row block to create a literal string:
|
|
230
230
|
You can use this on a regular virtual row block too, but it
|
231
231
|
doesn't look as nice:
|
232
232
|
|
233
|
-
ds.where{|o| o.>(:a, o.`('some SQL')}
|
233
|
+
ds.where{|o| o.>(:a, o.`('some SQL'))}
|
234
234
|
|
235
235
|
== Returning multiple values
|
236
236
|
|
@@ -26,6 +26,10 @@ module Sequel
|
|
26
26
|
false
|
27
27
|
end
|
28
28
|
|
29
|
+
def disconnect_error?(exception, opts)
|
30
|
+
super || exception.message =~ /\AInvalid state, the Connection object is closed\.\z/
|
31
|
+
end
|
32
|
+
|
29
33
|
# Handle nil values by using setNull with the correct parameter type.
|
30
34
|
def set_ps_arg_nil(cps, i)
|
31
35
|
cps.setNull(i, cps.getParameterMetaData.getParameterType(i))
|
@@ -62,24 +62,24 @@ module Sequel
|
|
62
62
|
# Connect to the database. In addition to the usual database options,
|
63
63
|
# the following options have effect:
|
64
64
|
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
65
|
+
# :auto_is_null :: Set to true to use MySQL default behavior of having
|
66
|
+
# a filter for an autoincrement column equals NULL to return the last
|
67
|
+
# inserted row.
|
68
|
+
# :charset :: Same as :encoding (:encoding takes precendence)
|
69
|
+
# :compress :: Set to false to not compress results from the server
|
70
|
+
# :config_default_group :: The default group to read from the in
|
71
|
+
# the MySQL config file.
|
72
|
+
# :config_local_infile :: If provided, sets the Mysql::OPT_LOCAL_INFILE
|
73
|
+
# option on the connection with the given value.
|
74
|
+
# :connect_timeout :: Set the timeout in seconds before a connection
|
75
|
+
# attempt is abandoned.
|
76
|
+
# :encoding :: Set all the related character sets for this
|
77
|
+
# connection (connection, client, database, server, and results).
|
78
|
+
# :read_timeout :: Set the timeout in seconds for reading back results
|
79
|
+
# to a query.
|
80
|
+
# :socket :: Use a unix socket file instead of connecting via TCP/IP.
|
81
|
+
# :timeout :: Set the timeout in seconds before the server will
|
82
|
+
# disconnect this connection (a.k.a @@wait_timeout).
|
83
83
|
def connect(server)
|
84
84
|
opts = server_opts(server)
|
85
85
|
conn = Mysql.init
|
@@ -17,12 +17,12 @@ module Sequel
|
|
17
17
|
# Connect to the database. In addition to the usual database options,
|
18
18
|
# the following options have effect:
|
19
19
|
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
20
|
+
# :auto_is_null :: Set to true to use MySQL default behavior of having
|
21
|
+
# a filter for an autoincrement column equals NULL to return the last
|
22
|
+
# inserted row.
|
23
|
+
# :charset :: Same as :encoding (:encoding takes precendence)
|
24
|
+
# :encoding :: Set all the related character sets for this
|
25
|
+
# connection (connection, client, database, server, and results).
|
26
26
|
#
|
27
27
|
# The options hash is also passed to mysql2, and can include mysql2
|
28
28
|
# options such as :local_infile.
|
@@ -61,7 +61,7 @@ module Sequel
|
|
61
61
|
execute(sql, opts){|c| return c.last_id}
|
62
62
|
end
|
63
63
|
|
64
|
-
# Return the version of the MySQL server
|
64
|
+
# Return the version of the MySQL server to which we are connecting.
|
65
65
|
def server_version(server=nil)
|
66
66
|
@server_version ||= (synchronize(server){|conn| conn.server_info[:id]} || super)
|
67
67
|
end
|
@@ -161,7 +161,7 @@ module Sequel
|
|
161
161
|
# Return an array of symbols specifying table names in the current database.
|
162
162
|
#
|
163
163
|
# Options:
|
164
|
-
#
|
164
|
+
# :server :: Set the server to use
|
165
165
|
def tables(opts=OPTS)
|
166
166
|
full_tables('BASE TABLE', opts)
|
167
167
|
end
|
@@ -178,7 +178,7 @@ module Sequel
|
|
178
178
|
# Return an array of symbols specifying view names in the current database.
|
179
179
|
#
|
180
180
|
# Options:
|
181
|
-
#
|
181
|
+
# :server :: Set the server to use
|
182
182
|
def views(opts=OPTS)
|
183
183
|
full_tables('VIEW', opts)
|
184
184
|
end
|
@@ -363,8 +363,8 @@ module Sequel
|
|
363
363
|
end
|
364
364
|
|
365
365
|
# Split column constraints into table constraints in some cases:
|
366
|
-
#
|
367
|
-
#
|
366
|
+
# foreign key - Always
|
367
|
+
# unique, primary_key - Only if constraint has a name
|
368
368
|
generator.columns.each do |c|
|
369
369
|
if t = c.delete(:table)
|
370
370
|
same_table = t == name
|
@@ -733,7 +733,9 @@ module Sequel
|
|
733
733
|
# Sets up the insert methods to use ON DUPLICATE KEY UPDATE
|
734
734
|
# If you pass no arguments, ALL fields will be
|
735
735
|
# updated with the new values. If you pass the fields you
|
736
|
-
# want then ONLY those field will be updated.
|
736
|
+
# want then ONLY those field will be updated. If you pass a
|
737
|
+
# hash you can customize the values (for example, to increment
|
738
|
+
# a numeric field).
|
737
739
|
#
|
738
740
|
# Useful if you have a unique key and want to update
|
739
741
|
# inserting rows that violate the unique key restriction.
|
@@ -749,6 +751,14 @@ module Sequel
|
|
749
751
|
# )
|
750
752
|
# # INSERT INTO tablename (name, value) VALUES (a, 1), (b, 2)
|
751
753
|
# # ON DUPLICATE KEY UPDATE value=VALUES(value)
|
754
|
+
#
|
755
|
+
# dataset.on_duplicate_key_update(
|
756
|
+
# :value => Sequel.lit('value + VALUES(value)')
|
757
|
+
# ).multi_insert(
|
758
|
+
# [{:name => 'a', :value => 1}, {:name => 'b', :value => 2}]
|
759
|
+
# )
|
760
|
+
# # INSERT INTO tablename (name, value) VALUES (a, 1), (b, 2)
|
761
|
+
# # ON DUPLICATE KEY UPDATE value=value + VALUES(value)
|
752
762
|
def on_duplicate_key_update(*args)
|
753
763
|
clone(:on_duplicate_key_update => args)
|
754
764
|
end
|
@@ -161,59 +161,60 @@ module Sequel
|
|
161
161
|
end
|
162
162
|
|
163
163
|
# Creates the function in the database. Arguments:
|
164
|
-
#
|
165
|
-
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
169
|
-
#
|
170
|
-
#
|
171
|
-
#
|
172
|
-
#
|
173
|
-
#
|
174
|
-
#
|
175
|
-
#
|
176
|
-
#
|
177
|
-
#
|
178
|
-
#
|
179
|
-
#
|
180
|
-
#
|
181
|
-
#
|
182
|
-
#
|
164
|
+
# name :: name of the function to create
|
165
|
+
# definition :: string definition of the function, or object file for a dynamically loaded C function.
|
166
|
+
# opts :: options hash:
|
167
|
+
# :args :: function arguments, can be either a symbol or string specifying a type or an array of 1-3 elements:
|
168
|
+
# 1 :: argument data type
|
169
|
+
# 2 :: argument name
|
170
|
+
# 3 :: argument mode (e.g. in, out, inout)
|
171
|
+
# :behavior :: Should be IMMUTABLE, STABLE, or VOLATILE. PostgreSQL assumes VOLATILE by default.
|
172
|
+
# :cost :: The estimated cost of the function, used by the query planner.
|
173
|
+
# :language :: The language the function uses. SQL is the default.
|
174
|
+
# :link_symbol :: For a dynamically loaded see function, the function's link symbol if different from the definition argument.
|
175
|
+
# :returns :: The data type returned by the function. If you are using OUT or INOUT argument modes, this is ignored.
|
176
|
+
# Otherwise, if this is not specified, void is used by default to specify the function is not supposed to return a value.
|
177
|
+
# :rows :: The estimated number of rows the function will return. Only use if the function returns SETOF something.
|
178
|
+
# :security_definer :: Makes the privileges of the function the same as the privileges of the user who defined the function instead of
|
179
|
+
# the privileges of the user who runs the function. There are security implications when doing this, see the PostgreSQL documentation.
|
180
|
+
# :set :: Configuration variables to set while the function is being run, can be a hash or an array of two pairs. search_path is
|
181
|
+
# often used here if :security_definer is used.
|
182
|
+
# :strict :: Makes the function return NULL when any argument is NULL.
|
183
183
|
def create_function(name, definition, opts=OPTS)
|
184
184
|
self << create_function_sql(name, definition, opts)
|
185
185
|
end
|
186
186
|
|
187
187
|
# Create the procedural language in the database. Arguments:
|
188
|
-
#
|
189
|
-
#
|
190
|
-
#
|
191
|
-
#
|
192
|
-
#
|
193
|
-
#
|
188
|
+
# name :: Name of the procedural language (e.g. plpgsql)
|
189
|
+
# opts :: options hash:
|
190
|
+
# :handler :: The name of a previously registered function used as a call handler for this language.
|
191
|
+
# :replace :: Replace the installed language if it already exists (on PostgreSQL 9.0+).
|
192
|
+
# :trusted :: Marks the language being created as trusted, allowing unprivileged users to create functions using this language.
|
193
|
+
# :validator :: The name of previously registered function used as a validator of functions defined in this language.
|
194
194
|
def create_language(name, opts=OPTS)
|
195
195
|
self << create_language_sql(name, opts)
|
196
196
|
end
|
197
197
|
|
198
198
|
# Create a schema in the database. Arguments:
|
199
|
-
#
|
200
|
-
#
|
201
|
-
#
|
202
|
-
#
|
199
|
+
# name :: Name of the schema (e.g. admin)
|
200
|
+
# opts :: options hash:
|
201
|
+
# :if_not_exists :: Don't raise an error if the schema already exists (PostgreSQL 9.3+)
|
202
|
+
# :owner :: The owner to set for the schema (defaults to current user if not specified)
|
203
203
|
def create_schema(name, opts=OPTS)
|
204
204
|
self << create_schema_sql(name, opts)
|
205
205
|
end
|
206
206
|
|
207
207
|
# Create a trigger in the database. Arguments:
|
208
|
-
#
|
209
|
-
#
|
210
|
-
#
|
211
|
-
#
|
212
|
-
#
|
213
|
-
#
|
214
|
-
#
|
215
|
-
#
|
216
|
-
#
|
208
|
+
# table :: the table on which this trigger operates
|
209
|
+
# name :: the name of this trigger
|
210
|
+
# function :: the function to call for this trigger, which should return type trigger.
|
211
|
+
# opts :: options hash:
|
212
|
+
# :after :: Calls the trigger after execution instead of before.
|
213
|
+
# :args :: An argument or array of arguments to pass to the function.
|
214
|
+
# :each_row :: Calls the trigger for each row instead of for each statement.
|
215
|
+
# :events :: Can be :insert, :update, :delete, or an array of any of those. Calls the trigger whenever that type of statement is used. By default,
|
216
|
+
# the trigger is called for insert, update, or delete.
|
217
|
+
# :when :: A filter to use for the trigger
|
217
218
|
def create_trigger(table, name, function, opts=OPTS)
|
218
219
|
self << create_trigger_sql(table, name, function, opts)
|
219
220
|
end
|
@@ -234,39 +235,39 @@ module Sequel
|
|
234
235
|
end
|
235
236
|
|
236
237
|
# Drops the function from the database. Arguments:
|
237
|
-
#
|
238
|
-
#
|
239
|
-
#
|
240
|
-
#
|
241
|
-
#
|
238
|
+
# name :: name of the function to drop
|
239
|
+
# opts :: options hash:
|
240
|
+
# :args :: The arguments for the function. See create_function_sql.
|
241
|
+
# :cascade :: Drop other objects depending on this function.
|
242
|
+
# :if_exists :: Don't raise an error if the function doesn't exist.
|
242
243
|
def drop_function(name, opts=OPTS)
|
243
244
|
self << drop_function_sql(name, opts)
|
244
245
|
end
|
245
246
|
|
246
247
|
# Drops a procedural language from the database. Arguments:
|
247
|
-
#
|
248
|
-
#
|
249
|
-
#
|
250
|
-
#
|
248
|
+
# name :: name of the procedural language to drop
|
249
|
+
# opts :: options hash:
|
250
|
+
# :cascade :: Drop other objects depending on this function.
|
251
|
+
# :if_exists :: Don't raise an error if the function doesn't exist.
|
251
252
|
def drop_language(name, opts=OPTS)
|
252
253
|
self << drop_language_sql(name, opts)
|
253
254
|
end
|
254
255
|
|
255
256
|
# Drops a schema from the database. Arguments:
|
256
|
-
#
|
257
|
-
#
|
258
|
-
#
|
259
|
-
#
|
257
|
+
# name :: name of the schema to drop
|
258
|
+
# opts :: options hash:
|
259
|
+
# :cascade :: Drop all objects in this schema.
|
260
|
+
# :if_exists :: Don't raise an error if the schema doesn't exist.
|
260
261
|
def drop_schema(name, opts=OPTS)
|
261
262
|
self << drop_schema_sql(name, opts)
|
262
263
|
end
|
263
264
|
|
264
265
|
# Drops a trigger from the database. Arguments:
|
265
|
-
#
|
266
|
-
#
|
267
|
-
#
|
268
|
-
#
|
269
|
-
#
|
266
|
+
# table :: table from which to drop the trigger
|
267
|
+
# name :: name of the trigger to drop
|
268
|
+
# opts :: options hash:
|
269
|
+
# :cascade :: Drop other objects depending on this function.
|
270
|
+
# :if_exists :: Don't raise an error if the function doesn't exist.
|
270
271
|
def drop_trigger(table, name, opts=OPTS)
|
271
272
|
self << drop_trigger_sql(table, name, opts)
|
272
273
|
end
|
@@ -482,6 +483,11 @@ module Sequel
|
|
482
483
|
true
|
483
484
|
end
|
484
485
|
|
486
|
+
# PostgreSQL 9.0+ supports trigger conditions.
|
487
|
+
def supports_trigger_conditions?
|
488
|
+
server_version >= 90000
|
489
|
+
end
|
490
|
+
|
485
491
|
# PostgreSQL supports prepared transactions (two-phase commit) if
|
486
492
|
# max_prepared_transactions is greater than 0.
|
487
493
|
def supports_prepared_transactions?
|
@@ -708,9 +714,12 @@ module Sequel
|
|
708
714
|
end
|
709
715
|
|
710
716
|
EXCLUSION_CONSTRAINT_SQL_STATE = '23P01'.freeze
|
717
|
+
DEADLOCK_SQL_STATE = '40P01'.freeze
|
711
718
|
def database_specific_error_class_from_sqlstate(sqlstate)
|
712
719
|
if sqlstate == EXCLUSION_CONSTRAINT_SQL_STATE
|
713
720
|
ExclusionConstraintViolation
|
721
|
+
elsif sqlstate == DEADLOCK_SQL_STATE
|
722
|
+
SerializationFailure
|
714
723
|
else
|
715
724
|
super
|
716
725
|
end
|
@@ -841,7 +850,11 @@ module Sequel
|
|
841
850
|
def create_trigger_sql(table, name, function, opts=OPTS)
|
842
851
|
events = opts[:events] ? Array(opts[:events]) : [:insert, :update, :delete]
|
843
852
|
whence = opts[:after] ? 'AFTER' : 'BEFORE'
|
844
|
-
|
853
|
+
if filter = opts[:when]
|
854
|
+
raise Error, "Trigger conditions are not supported for this database" unless supports_trigger_conditions?
|
855
|
+
filter = " WHEN #{filter_expr(filter)}"
|
856
|
+
end
|
857
|
+
"CREATE TRIGGER #{name} #{whence} #{events.map{|e| e.to_s.upcase}.join(' OR ')} ON #{quote_schema_table(table)}#{' FOR EACH ROW' if opts[:each_row]}#{filter} EXECUTE PROCEDURE #{function}(#{Array(opts[:args]).map{|a| literal(a)}.join(', ')})"
|
845
858
|
end
|
846
859
|
|
847
860
|
# DDL fragment for initial part of CREATE VIEW statement
|
@@ -1387,7 +1400,7 @@ module Sequel
|
|
1387
1400
|
#
|
1388
1401
|
# Options:
|
1389
1402
|
# :cascade :: whether to use the CASCADE option, useful when truncating
|
1390
|
-
#
|
1403
|
+
# tables with foreign keys.
|
1391
1404
|
# :only :: truncate using ONLY, so child tables are unaffected
|
1392
1405
|
# :restart :: use RESTART IDENTITY to restart any related sequences
|
1393
1406
|
#
|