sequel 4.21.0 → 4.22.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +32 -0
- data/README.rdoc +3 -4
- data/doc/opening_databases.rdoc +10 -75
- data/doc/release_notes/4.22.0.txt +72 -0
- data/lib/sequel/adapters/ado/access.rb +1 -1
- data/lib/sequel/adapters/cubrid.rb +3 -3
- data/lib/sequel/adapters/db2.rb +1 -0
- data/lib/sequel/adapters/dbi.rb +1 -0
- data/lib/sequel/adapters/fdbsql.rb +3 -2
- data/lib/sequel/adapters/firebird.rb +1 -0
- data/lib/sequel/adapters/ibmdb.rb +1 -21
- data/lib/sequel/adapters/informix.rb +1 -0
- data/lib/sequel/adapters/jdbc.rb +37 -49
- data/lib/sequel/adapters/jdbc/fdbsql.rb +1 -0
- data/lib/sequel/adapters/mysql.rb +5 -3
- data/lib/sequel/adapters/mysql2.rb +5 -2
- data/lib/sequel/adapters/odbc.rb +8 -4
- data/lib/sequel/adapters/openbase.rb +1 -0
- data/lib/sequel/adapters/oracle.rb +3 -46
- data/lib/sequel/adapters/postgres.rb +3 -36
- data/lib/sequel/adapters/shared/access.rb +1 -1
- data/lib/sequel/adapters/shared/fdbsql.rb +3 -3
- data/lib/sequel/adapters/shared/mssql.rb +1 -1
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +12 -44
- data/lib/sequel/adapters/shared/oracle.rb +6 -2
- data/lib/sequel/adapters/shared/postgres.rb +6 -6
- data/lib/sequel/adapters/shared/sqlite.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +3 -46
- data/lib/sequel/adapters/tinytds.rb +12 -28
- data/lib/sequel/adapters/utils/pg_types.rb +1 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +63 -16
- data/lib/sequel/connection_pool/threaded.rb +72 -18
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database/connecting.rb +2 -2
- data/lib/sequel/database/misc.rb +5 -5
- data/lib/sequel/database/query.rb +3 -2
- data/lib/sequel/database/schema_generator.rb +19 -19
- data/lib/sequel/database/schema_methods.rb +2 -2
- data/lib/sequel/database/transactions.rb +3 -3
- data/lib/sequel/dataset/actions.rb +18 -8
- data/lib/sequel/dataset/graph.rb +2 -2
- data/lib/sequel/dataset/prepared_statements.rb +28 -1
- data/lib/sequel/dataset/query.rb +7 -7
- data/lib/sequel/exceptions.rb +27 -24
- data/lib/sequel/extensions/_pretty_table.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +2 -2
- data/lib/sequel/extensions/date_arithmetic.rb +2 -2
- data/lib/sequel/extensions/pg_array.rb +10 -1
- data/lib/sequel/extensions/pg_row.rb +1 -1
- data/lib/sequel/extensions/pg_static_cache_updater.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +8 -8
- data/lib/sequel/extensions/split_array_nil.rb +1 -1
- data/lib/sequel/model.rb +1 -1
- data/lib/sequel/model/associations.rb +18 -11
- data/lib/sequel/model/base.rb +15 -15
- data/lib/sequel/model/exceptions.rb +11 -2
- data/lib/sequel/plugins/accessed_columns.rb +1 -1
- data/lib/sequel/plugins/auto_validations.rb +1 -1
- data/lib/sequel/plugins/boolean_readers.rb +1 -1
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -7
- data/lib/sequel/plugins/composition.rb +1 -1
- data/lib/sequel/plugins/constraint_validations.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +171 -0
- data/lib/sequel/plugins/dirty.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +5 -5
- data/lib/sequel/plugins/pg_array_associations.rb +4 -4
- data/lib/sequel/plugins/prepared_statements.rb +2 -2
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -1
- data/lib/sequel/plugins/serialization.rb +6 -6
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +3 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +5 -13
- data/lib/sequel/plugins/static_cache.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +1 -1
- data/lib/sequel/plugins/tree.rb +1 -1
- data/lib/sequel/plugins/validation_class_methods.rb +2 -2
- data/lib/sequel/plugins/validation_helpers.rb +4 -4
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +17 -0
- data/spec/core/connection_pool_spec.rb +1 -1
- data/spec/core/dataset_spec.rb +22 -0
- data/spec/extensions/auto_validations_spec.rb +1 -1
- data/spec/extensions/blacklist_security_spec.rb +2 -2
- data/spec/extensions/csv_serializer_spec.rb +173 -0
- data/spec/extensions/json_serializer_spec.rb +2 -2
- data/spec/extensions/nested_attributes_spec.rb +9 -9
- data/spec/extensions/pg_array_spec.rb +5 -0
- data/spec/extensions/single_table_inheritance_spec.rb +21 -0
- data/spec/extensions/touch_spec.rb +1 -1
- data/spec/extensions/tree_spec.rb +4 -0
- data/spec/extensions/xml_serializer_spec.rb +3 -3
- data/spec/integration/prepared_statement_test.rb +1 -1
- data/spec/integration/schema_test.rb +7 -0
- data/spec/integration/type_test.rb +2 -2
- data/spec/model/associations_spec.rb +108 -14
- data/spec/model/base_spec.rb +8 -8
- data/spec/model/record_spec.rb +7 -7
- metadata +6 -2
@@ -119,7 +119,7 @@ module Sequel
|
|
119
119
|
# :no_index :: Set to true not to create the second index.
|
120
120
|
# :no_primary_key :: Set to true to not create the primary key.
|
121
121
|
def create_join_table(hash, options=OPTS)
|
122
|
-
keys = hash.keys.sort_by
|
122
|
+
keys = hash.keys.sort_by(&:to_s)
|
123
123
|
create_table(join_table_name(hash, options), options) do
|
124
124
|
keys.each do |key|
|
125
125
|
v = hash[key]
|
@@ -781,7 +781,7 @@ module Sequel
|
|
781
781
|
options[:name]
|
782
782
|
else
|
783
783
|
table_names = entries.map{|e| join_table_name_extract(e)}
|
784
|
-
table_names.map
|
784
|
+
table_names.map(&:to_s).sort.join('_')
|
785
785
|
end
|
786
786
|
end
|
787
787
|
|
@@ -80,7 +80,7 @@ module Sequel
|
|
80
80
|
tot_retries = opts.fetch(:num_retries, 5)
|
81
81
|
num_retries = 0 unless tot_retries.nil?
|
82
82
|
begin
|
83
|
-
transaction(opts.merge(:retry_on=>nil, :retrying=>true), &block)
|
83
|
+
transaction(Hash[opts].merge!(:retry_on=>nil, :retrying=>true), &block)
|
84
84
|
rescue *retry_on => e
|
85
85
|
if num_retries
|
86
86
|
num_retries += 1
|
@@ -100,7 +100,7 @@ module Sequel
|
|
100
100
|
raise Sequel::Error, "cannot set :retry_on options if you are already inside a transaction"
|
101
101
|
end
|
102
102
|
if opts[:savepoint] != false && (stack = _trans(conn)[:savepoints]) && stack.last
|
103
|
-
_transaction(conn, opts.merge(:savepoint=>true), &block)
|
103
|
+
_transaction(conn, Hash[opts].merge!(:savepoint=>true), &block)
|
104
104
|
else
|
105
105
|
return yield(conn)
|
106
106
|
end
|
@@ -277,7 +277,7 @@ module Sequel
|
|
277
277
|
callbacks = _trans(conn)[committed ? :after_commit : :after_rollback]
|
278
278
|
Sequel.synchronize{@transactions.delete(conn)}
|
279
279
|
if callbacks
|
280
|
-
callbacks.each
|
280
|
+
callbacks.each(&:call)
|
281
281
|
end
|
282
282
|
end
|
283
283
|
end
|
@@ -8,7 +8,7 @@ module Sequel
|
|
8
8
|
# ---------------------
|
9
9
|
|
10
10
|
# Action methods defined by Sequel that execute code on the database.
|
11
|
-
ACTION_METHODS = (<<-METHS).split.map
|
11
|
+
ACTION_METHODS = (<<-METHS).split.map(&:to_sym)
|
12
12
|
<< [] all avg count columns columns! delete each
|
13
13
|
empty? fetch_rows first first! get import insert interval last
|
14
14
|
map max min multi_insert paged_each range select_hash select_hash_groups select_map select_order_map
|
@@ -493,7 +493,8 @@ module Sequel
|
|
493
493
|
total_limit = @opts[:limit]
|
494
494
|
offset = @opts[:offset]
|
495
495
|
if server = @opts[:server]
|
496
|
-
opts = opts
|
496
|
+
opts = Hash[opts]
|
497
|
+
opts[:server] = server
|
497
498
|
end
|
498
499
|
|
499
500
|
rows_per_fetch = opts[:rows_per_fetch] || 1000
|
@@ -701,7 +702,7 @@ module Sequel
|
|
701
702
|
end
|
702
703
|
end
|
703
704
|
elsif key_column.is_a?(Array)
|
704
|
-
each{|r| h[r
|
705
|
+
each{|r| h[key_column.map{|k| r[k]}] = r}
|
705
706
|
else
|
706
707
|
each{|r| h[r[key_column]] = r}
|
707
708
|
end
|
@@ -744,7 +745,7 @@ module Sequel
|
|
744
745
|
end
|
745
746
|
end
|
746
747
|
elsif key_column.is_a?(Array)
|
747
|
-
each{|r| (h[r
|
748
|
+
each{|r| (h[key_column.map{|k| r[k]}] ||= []) << r}
|
748
749
|
else
|
749
750
|
each{|r| (h[r[key_column]] ||= []) << r}
|
750
751
|
end
|
@@ -833,7 +834,7 @@ module Sequel
|
|
833
834
|
# separate insert commands for each row. Otherwise, call #multi_insert_sql
|
834
835
|
# and execute each statement it gives separately.
|
835
836
|
def _import(columns, values, opts)
|
836
|
-
trans_opts = opts.merge(:server=>@opts[:server])
|
837
|
+
trans_opts = Hash[opts].merge!(:server=>@opts[:server])
|
837
838
|
if opts[:return] == :primary_key
|
838
839
|
@db.transaction(trans_opts){values.map{|v| insert(columns, v)}}
|
839
840
|
else
|
@@ -901,14 +902,23 @@ module Sequel
|
|
901
902
|
|
902
903
|
# Set the server to use to :default unless it is already set in the passed opts
|
903
904
|
def default_server_opts(opts)
|
904
|
-
@db.sharded?
|
905
|
+
if @db.sharded?
|
906
|
+
opts = Hash[opts]
|
907
|
+
opts[:server] = @opts[:server] || :default
|
908
|
+
end
|
909
|
+
opts
|
905
910
|
end
|
906
911
|
|
907
912
|
# Execute the given select SQL on the database using execute. Use the
|
908
913
|
# :read_only server unless a specific server is set.
|
909
914
|
def execute(sql, opts=OPTS, &block)
|
910
915
|
db = @db
|
911
|
-
|
916
|
+
if db.sharded?
|
917
|
+
opts = Hash[opts]
|
918
|
+
opts[:server] = @opts[:server] || :read_only
|
919
|
+
opts
|
920
|
+
end
|
921
|
+
db.execute(sql, opts, &block)
|
912
922
|
end
|
913
923
|
|
914
924
|
# Execute the given SQL on the database using execute_ddl.
|
@@ -982,7 +992,7 @@ module Sequel
|
|
982
992
|
[v, descending]
|
983
993
|
end
|
984
994
|
|
985
|
-
row_values = yield(row, order_exprs.map
|
995
|
+
row_values = yield(row, order_exprs.map(&:first))
|
986
996
|
|
987
997
|
last_expr = []
|
988
998
|
cond = order_exprs.zip(row_values).map do |(v, descending), value|
|
data/lib/sequel/dataset/graph.rb
CHANGED
@@ -18,7 +18,7 @@ module Sequel
|
|
18
18
|
raise Error, "cannot call add_graph_aliases on a dataset that has not been called with graph or set_graph_aliases"
|
19
19
|
end
|
20
20
|
columns, graph_aliases = graph_alias_columns(graph_aliases)
|
21
|
-
select_more(*columns).clone(:graph_aliases => ga.merge(graph_aliases))
|
21
|
+
select_more(*columns).clone(:graph_aliases => Hash[ga].merge!(graph_aliases))
|
22
22
|
end
|
23
23
|
|
24
24
|
# Similar to Dataset#join_table, but uses unambiguous aliases for selected
|
@@ -72,7 +72,7 @@ module Sequel
|
|
72
72
|
when SQL::QualifiedIdentifier
|
73
73
|
table_alias ||= split_qualifiers(table).last
|
74
74
|
when SQL::AliasedExpression
|
75
|
-
return graph(table.expression, join_conditions, {:table_alias=>table.alias}.merge(options), &block)
|
75
|
+
return graph(table.expression, join_conditions, {:table_alias=>table.alias}.merge!(options), &block)
|
76
76
|
else
|
77
77
|
raise Error, "The dataset argument should be a symbol or dataset"
|
78
78
|
end
|
@@ -7,6 +7,33 @@ module Sequel
|
|
7
7
|
# ---------------------
|
8
8
|
|
9
9
|
PREPARED_ARG_PLACEHOLDER = LiteralString.new('?').freeze
|
10
|
+
|
11
|
+
DEFAULT_PREPARED_STATEMENT_MODULE_METHODS = %w'execute execute_dui execute_insert'.freeze.each(&:freeze)
|
12
|
+
PREPARED_STATEMENT_MODULE_CODE = {
|
13
|
+
:bind => "opts = Hash[opts]; opts[:arguments] = bind_arguments".freeze,
|
14
|
+
:prepare => "sql = prepared_statement_name".freeze,
|
15
|
+
:prepare_bind => "sql = prepared_statement_name; opts = Hash[opts]; opts[:arguments] = bind_arguments".freeze
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
def self.prepared_statements_module(code, mods, meths=DEFAULT_PREPARED_STATEMENT_MODULE_METHODS, &block)
|
19
|
+
code = PREPARED_STATEMENT_MODULE_CODE[code] || code
|
20
|
+
|
21
|
+
Module.new do
|
22
|
+
Array(mods).each do |mod|
|
23
|
+
include mod
|
24
|
+
end
|
25
|
+
|
26
|
+
if block
|
27
|
+
module_eval(&block)
|
28
|
+
end
|
29
|
+
|
30
|
+
meths.each do |meth|
|
31
|
+
module_eval("def #{meth}(sql, opts=Sequel::OPTS) #{code}; super end", __FILE__, __LINE__)
|
32
|
+
end
|
33
|
+
private *meths
|
34
|
+
end
|
35
|
+
end
|
36
|
+
private_class_method :prepared_statements_module
|
10
37
|
|
11
38
|
# Default implementation of the argument mapper to allow
|
12
39
|
# native database support for bind variables and prepared
|
@@ -221,7 +248,7 @@ module Sequel
|
|
221
248
|
# # SELECT * FROM table WHERE id = ? LIMIT 1 -- (1)
|
222
249
|
# # => {:id=>1}
|
223
250
|
def bind(bind_vars={})
|
224
|
-
clone(:bind_vars=>@opts[:bind_vars] ? @opts[:bind_vars].merge(bind_vars) : bind_vars)
|
251
|
+
clone(:bind_vars=>@opts[:bind_vars] ? Hash[@opts[:bind_vars]].merge!(bind_vars) : bind_vars)
|
225
252
|
end
|
226
253
|
|
227
254
|
# For the given type (:select, :first, :insert, :insert_select, :update, or :delete),
|
data/lib/sequel/dataset/query.rb
CHANGED
@@ -32,7 +32,7 @@ module Sequel
|
|
32
32
|
JOIN_METHODS = (CONDITIONED_JOIN_TYPES + UNCONDITIONED_JOIN_TYPES).map{|x| "#{x}_join".to_sym} + [:join, :join_table]
|
33
33
|
|
34
34
|
# Methods that return modified datasets
|
35
|
-
QUERY_METHODS = (<<-METHS).split.map
|
35
|
+
QUERY_METHODS = (<<-METHS).split.map(&:to_sym) + JOIN_METHODS
|
36
36
|
add_graph_aliases and distinct except exclude exclude_having exclude_where
|
37
37
|
filter for_update from from_self graph grep group group_and_count group_by having intersect invert
|
38
38
|
limit lock_style naked offset or order order_append order_by order_more order_prepend qualify
|
@@ -74,10 +74,10 @@ module Sequel
|
|
74
74
|
def clone(opts = nil)
|
75
75
|
c = super()
|
76
76
|
if opts
|
77
|
-
c.instance_variable_set(:@opts, @opts.merge(opts))
|
77
|
+
c.instance_variable_set(:@opts, Hash[@opts].merge!(opts))
|
78
78
|
c.instance_variable_set(:@columns, nil) if @columns && !opts.each_key{|o| break if COLUMN_CHANGE_OPTS.include?(o)}
|
79
79
|
else
|
80
|
-
c.instance_variable_set(:@opts, @opts
|
80
|
+
c.instance_variable_set(:@opts, Hash[@opts])
|
81
81
|
end
|
82
82
|
c
|
83
83
|
end
|
@@ -584,7 +584,7 @@ module Sequel
|
|
584
584
|
# Returns a cloned dataset without a row_proc.
|
585
585
|
#
|
586
586
|
# ds = DB[:items]
|
587
|
-
# ds.row_proc = proc
|
587
|
+
# ds.row_proc = proc(&:invert)
|
588
588
|
# ds.all # => [{2=>:id}]
|
589
589
|
# ds.naked.all # => [{:id=>2}]
|
590
590
|
def naked
|
@@ -939,7 +939,7 @@ module Sequel
|
|
939
939
|
s, ds = hoist_cte(dataset)
|
940
940
|
s.with(name, ds, opts)
|
941
941
|
else
|
942
|
-
clone(:with=>(@opts[:with]||[]) + [opts.merge(:name=>name, :dataset=>dataset)])
|
942
|
+
clone(:with=>(@opts[:with]||[]) + [Hash[opts].merge!(:name=>name, :dataset=>dataset)])
|
943
943
|
end
|
944
944
|
end
|
945
945
|
|
@@ -968,7 +968,7 @@ module Sequel
|
|
968
968
|
s, ds = hoist_cte(recursive)
|
969
969
|
s.with_recursive(name, nonrecursive, ds, opts)
|
970
970
|
else
|
971
|
-
clone(:with=>(@opts[:with]||[]) + [opts.merge(:recursive=>true, :name=>name, :dataset=>nonrecursive.union(recursive, {:all=>opts[:union_all] != false, :from_self=>false}))])
|
971
|
+
clone(:with=>(@opts[:with]||[]) + [Hash[opts].merge!(:recursive=>true, :name=>name, :dataset=>nonrecursive.union(recursive, {:all=>opts[:union_all] != false, :from_self=>false}))])
|
972
972
|
end
|
973
973
|
end
|
974
974
|
|
@@ -1001,7 +1001,7 @@ module Sequel
|
|
1001
1001
|
s, ds = hoist_cte(dataset)
|
1002
1002
|
return s.compound_clone(type, ds, opts)
|
1003
1003
|
end
|
1004
|
-
ds = compound_from_self.clone(:compounds=>Array(@opts[:compounds]).map
|
1004
|
+
ds = compound_from_self.clone(:compounds=>Array(@opts[:compounds]).map(&:dup) + [[type, dataset.compound_from_self, opts[:all]]])
|
1005
1005
|
opts[:from_self] == false ? ds : ds.from_self(opts)
|
1006
1006
|
end
|
1007
1007
|
|
data/lib/sequel/exceptions.rb
CHANGED
@@ -8,70 +8,73 @@ module Sequel
|
|
8
8
|
end
|
9
9
|
|
10
10
|
# Error raised when the adapter requested doesn't exist or can't be loaded.
|
11
|
-
|
11
|
+
AdapterNotFound = Class.new(Error)
|
12
12
|
|
13
13
|
# Generic error raised by the database adapters, indicating a
|
14
14
|
# problem originating from the database server. Usually raised
|
15
15
|
# because incorrect SQL syntax is used.
|
16
|
-
|
16
|
+
DatabaseError = Class.new(Error)
|
17
17
|
|
18
18
|
# Error raised when the Sequel is unable to connect to the database with the
|
19
19
|
# connection parameters it was given.
|
20
|
-
|
20
|
+
DatabaseConnectionError = Class.new(DatabaseError)
|
21
21
|
|
22
22
|
# Error raised by adapters when they determine that the connection
|
23
23
|
# to the database has been lost. Instructs the connection pool code to
|
24
24
|
# remove that connection from the pool so that other connections can be acquired
|
25
25
|
# automatically.
|
26
|
-
|
26
|
+
DatabaseDisconnectError = Class.new(DatabaseError)
|
27
27
|
|
28
28
|
# Generic error raised when Sequel determines a database constraint has been violated.
|
29
|
-
|
29
|
+
ConstraintViolation = Class.new(DatabaseError)
|
30
30
|
|
31
31
|
# Error raised when Sequel determines a database check constraint has been violated.
|
32
|
-
|
32
|
+
CheckConstraintViolation = Class.new(ConstraintViolation)
|
33
33
|
|
34
34
|
# Error raised when Sequel determines a database foreign key constraint has been violated.
|
35
|
-
|
35
|
+
ForeignKeyConstraintViolation = Class.new(ConstraintViolation)
|
36
36
|
|
37
37
|
# Error raised when Sequel determines a database NOT NULL constraint has been violated.
|
38
|
-
|
38
|
+
NotNullConstraintViolation = Class.new(ConstraintViolation)
|
39
39
|
|
40
40
|
# Error raised when Sequel determines a database unique constraint has been violated.
|
41
|
-
|
41
|
+
UniqueConstraintViolation = Class.new(ConstraintViolation)
|
42
42
|
|
43
43
|
# Error raised when Sequel determines a serialization failure/deadlock in the database.
|
44
|
-
|
44
|
+
SerializationFailure = Class.new(DatabaseError)
|
45
45
|
|
46
46
|
# Error raised on an invalid operation, such as trying to update or delete
|
47
47
|
# a joined or grouped dataset.
|
48
|
-
|
48
|
+
InvalidOperation = Class.new(Error)
|
49
49
|
|
50
50
|
# Error raised when attempting an invalid type conversion.
|
51
|
-
|
51
|
+
InvalidValue = Class.new(Error)
|
52
52
|
|
53
53
|
# Error raised when the user requests a record via the first! or similar
|
54
54
|
# method, and the dataset does not yield any rows.
|
55
|
-
|
55
|
+
NoMatchingRow = Class.new(Error)
|
56
56
|
|
57
57
|
# Error raised when the connection pool cannot acquire a database connection
|
58
58
|
# before the timeout.
|
59
|
-
|
59
|
+
PoolTimeout = Class.new(Error)
|
60
60
|
|
61
61
|
# Error that you should raise to signal a rollback of the current transaction.
|
62
62
|
# The transaction block will catch this exception, rollback the current transaction,
|
63
63
|
# and won't reraise it (unless a reraise is requested).
|
64
|
-
|
64
|
+
Rollback = Class.new(Error)
|
65
65
|
|
66
66
|
# Error raised when unbinding a dataset that has multiple different values
|
67
67
|
# for a given variable.
|
68
|
-
|
69
|
-
|
70
|
-
class
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
68
|
+
UnbindDuplicate = Class.new(Error)
|
69
|
+
|
70
|
+
# Call name on each class to set the name for the class, so it gets cached.
|
71
|
+
constants.map{|c| const_get(c)}.each do |c|
|
72
|
+
Class === c && c.name
|
73
|
+
end
|
74
|
+
|
75
|
+
Error::AdapterNotFound = AdapterNotFound
|
76
|
+
Error::InvalidOperation = InvalidOperation
|
77
|
+
Error::InvalidValue = InvalidValue
|
78
|
+
Error::PoolTimeoutError = PoolTimeout
|
79
|
+
Error::Rollback = Rollback
|
77
80
|
end
|
@@ -23,7 +23,7 @@ module Sequel
|
|
23
23
|
|
24
24
|
# Return the string that #print will print via puts.
|
25
25
|
def self.string(records, columns = nil) # records is an array of hashes
|
26
|
-
columns ||= records.first.keys.sort_by
|
26
|
+
columns ||= records.first.keys.sort_by(&:to_s)
|
27
27
|
sizes = column_sizes(records, columns)
|
28
28
|
sep_line = separator_line(columns, sizes)
|
29
29
|
|
@@ -146,7 +146,7 @@ module Sequel
|
|
146
146
|
%w'presence unique'.each do |v|
|
147
147
|
class_eval(<<-END, __FILE__, __LINE__+1)
|
148
148
|
def #{v}(columns, opts=OPTS)
|
149
|
-
@generator.validation({:type=>:#{v}, :columns=>Array(columns)}.merge(opts))
|
149
|
+
@generator.validation({:type=>:#{v}, :columns=>Array(columns)}.merge!(opts))
|
150
150
|
end
|
151
151
|
END
|
152
152
|
end
|
@@ -155,7 +155,7 @@ module Sequel
|
|
155
155
|
%w'exact_length min_length max_length length_range format like ilike includes'.each do |v|
|
156
156
|
class_eval(<<-END, __FILE__, __LINE__+1)
|
157
157
|
def #{v}(arg, columns, opts=OPTS)
|
158
|
-
@generator.validation({:type=>:#{v}, :columns=>Array(columns), :arg=>arg}.merge(opts))
|
158
|
+
@generator.validation({:type=>:#{v}, :columns=>Array(columns), :arg=>arg}.merge!(opts))
|
159
159
|
end
|
160
160
|
END
|
161
161
|
end
|
@@ -60,7 +60,7 @@ module Sequel
|
|
60
60
|
MSSQL_DURATION_UNITS = DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit(s.to_s[0...-1]).freeze}).freeze
|
61
61
|
H2_DURATION_UNITS = DURATION_UNITS.zip(DURATION_UNITS.map{|s| s.to_s[0...-1].freeze}).freeze
|
62
62
|
DERBY_DURATION_UNITS = DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit("SQL_TSI_#{s.to_s.upcase[0...-1]}").freeze}).freeze
|
63
|
-
ACCESS_DURATION_UNITS = DURATION_UNITS.zip(%w'yyyy m d h n s'.map
|
63
|
+
ACCESS_DURATION_UNITS = DURATION_UNITS.zip(%w'yyyy m d h n s'.map(&:freeze)).freeze
|
64
64
|
DB2_DURATION_UNITS = DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit(s.to_s).freeze}).freeze
|
65
65
|
FDBSQL_DURATION_UNITS = DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit(s.to_s.chop).freeze}).freeze
|
66
66
|
|
@@ -180,7 +180,7 @@ module Sequel
|
|
180
180
|
else
|
181
181
|
h = Hash.new(0)
|
182
182
|
interval.parts.each{|unit, value| h[unit] += value}
|
183
|
-
|
183
|
+
Hash[h]
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
@@ -227,7 +227,7 @@ module Sequel
|
|
227
227
|
# affect global state, unlike PGArray.register. See PGArray.register for
|
228
228
|
# possible options.
|
229
229
|
def register_array_type(db_type, opts=OPTS, &block)
|
230
|
-
opts = {:type_procs=>conversion_procs, :typecast_method_map=>@pg_array_schema_types, :typecast_methods_module=>(class << self; self; end)}.merge(opts)
|
230
|
+
opts = {:type_procs=>conversion_procs, :typecast_method_map=>@pg_array_schema_types, :typecast_methods_module=>(class << self; self; end)}.merge!(opts)
|
231
231
|
unless (opts.has_key?(:scalar_oid) || block) && opts.has_key?(:oid)
|
232
232
|
array_oid, scalar_oid = from(:pg_type).where(:typname=>db_type.to_s).get([:typarray, :oid])
|
233
233
|
opts[:scalar_oid] = scalar_oid unless opts.has_key?(:scalar_oid) || block
|
@@ -300,6 +300,15 @@ module Sequel
|
|
300
300
|
end
|
301
301
|
end
|
302
302
|
|
303
|
+
# Convert ruby arrays to PostgreSQL arrays when used as default values.
|
304
|
+
def column_definition_default_sql(sql, column)
|
305
|
+
if (d = column[:default]) && d.is_a?(Array) && !Sequel.condition_specifier?(d)
|
306
|
+
sql << " DEFAULT (#{literal(Sequel.pg_array(d))}::#{type_literal(column)})"
|
307
|
+
else
|
308
|
+
super
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
303
312
|
# Given a value to typecast and the type of PGArray subclass:
|
304
313
|
# * If given a PGArray with a matching array_type, use it directly.
|
305
314
|
# * If given a PGArray with a different array_type, return a PGArray
|
@@ -445,7 +445,7 @@ module Sequel
|
|
445
445
|
end
|
446
446
|
# Manually cast to integer using to_i, because adapter may not cast oid type
|
447
447
|
# correctly (e.g. swift)
|
448
|
-
parser_opts[:oid], rel_oid, array_oid = row.values_at(:oid, :typrelid, :typarray).map
|
448
|
+
parser_opts[:oid], rel_oid, array_oid = row.values_at(:oid, :typrelid, :typarray).map(&:to_i)
|
449
449
|
|
450
450
|
# Get column names and oids for each of the members of the composite type.
|
451
451
|
res = from(:pg_attribute).
|
@@ -123,7 +123,7 @@ SQL
|
|
123
123
|
|
124
124
|
Thread.new do
|
125
125
|
begin
|
126
|
-
listen(opts[:channel_name]||default_static_cache_update_name, {:loop=>true}.merge(opts)) do |_, _, oid|
|
126
|
+
listen(opts[:channel_name]||default_static_cache_update_name, {:loop=>true}.merge!(opts)) do |_, _, oid|
|
127
127
|
if model = oid_map[oid.to_i]
|
128
128
|
model.send(:load_cache)
|
129
129
|
end
|
@@ -73,7 +73,7 @@ module Sequel
|
|
73
73
|
<<END_MIG
|
74
74
|
Sequel.migration do
|
75
75
|
change do
|
76
|
-
#{ts.sort_by
|
76
|
+
#{ts.sort_by(&:to_s).map{|t| dump_table_foreign_keys(t)}.reject{|x| x == ''}.join("\n\n").gsub(/^/o, ' ')}
|
77
77
|
end
|
78
78
|
end
|
79
79
|
END_MIG
|
@@ -91,7 +91,7 @@ END_MIG
|
|
91
91
|
<<END_MIG
|
92
92
|
Sequel.migration do
|
93
93
|
change do
|
94
|
-
#{ts.sort_by
|
94
|
+
#{ts.sort_by(&:to_s).map{|t| dump_table_indexes(t, :add_index, options)}.reject{|x| x == ''}.join("\n\n").gsub(/^/o, ' ')}
|
95
95
|
end
|
96
96
|
end
|
97
97
|
END_MIG
|
@@ -207,7 +207,7 @@ END_MIG
|
|
207
207
|
def dump_add_fk_constraints(table, fks)
|
208
208
|
sfks = "alter_table(#{table.inspect}) do\n"
|
209
209
|
sfks << create_table_generator do
|
210
|
-
fks.sort_by{|fk| fk[:columns].map
|
210
|
+
fks.sort_by{|fk| fk[:columns].map(&:to_s)}.each do |fk|
|
211
211
|
foreign_key fk[:columns], fk
|
212
212
|
end
|
213
213
|
end.dump_constraints.gsub(/^foreign_key /, ' add_foreign_key ')
|
@@ -218,7 +218,7 @@ END_MIG
|
|
218
218
|
# string that would add the foreign keys if run in a migration.
|
219
219
|
def dump_table_foreign_keys(table, options=OPTS)
|
220
220
|
if supports_foreign_key_parsing?
|
221
|
-
fks = foreign_key_list(table, options).sort_by{|fk| fk[:columns].map
|
221
|
+
fks = foreign_key_list(table, options).sort_by{|fk| fk[:columns].map(&:to_s)}
|
222
222
|
end
|
223
223
|
|
224
224
|
if fks.nil? || fks.empty?
|
@@ -234,7 +234,7 @@ END_MIG
|
|
234
234
|
table = table.value.to_s if table.is_a?(SQL::Identifier)
|
235
235
|
raise(Error, "must provide table as a Symbol, String, or Sequel::SQL::Identifier") unless [String, Symbol].any?{|c| table.is_a?(c)}
|
236
236
|
s = schema(table).dup
|
237
|
-
pks = s.find_all{|x| x.last[:primary_key] == true}.map
|
237
|
+
pks = s.find_all{|x| x.last[:primary_key] == true}.map(&:first)
|
238
238
|
options = options.merge(:single_pk=>true) if pks.length == 1
|
239
239
|
m = method(:recreate_column)
|
240
240
|
im = method(:index_to_generator_opts)
|
@@ -319,7 +319,7 @@ END_MIG
|
|
319
319
|
options[:skipped_foreign_keys] = skipped_foreign_keys
|
320
320
|
tables
|
321
321
|
else
|
322
|
-
tables.sort_by
|
322
|
+
tables.sort_by(&:to_s)
|
323
323
|
end
|
324
324
|
end
|
325
325
|
|
@@ -351,7 +351,7 @@ END_MIG
|
|
351
351
|
end
|
352
352
|
|
353
353
|
# Add sorted tables from this loop to the final list
|
354
|
-
sorted_tables.concat(this_loop.sort_by
|
354
|
+
sorted_tables.concat(this_loop.sort_by(&:to_s))
|
355
355
|
|
356
356
|
# Remove tables that were handled this loop
|
357
357
|
this_loop.each{|t| table_fks.delete(t)}
|
@@ -417,7 +417,7 @@ END_MIG
|
|
417
417
|
if !name and c[:check].length == 1 and c[:check].first.is_a?(Hash)
|
418
418
|
"check #{c[:check].first.inspect[1...-1]}"
|
419
419
|
else
|
420
|
-
"#{name ? "constraint #{name.inspect}," : 'check'} #{c[:check].map
|
420
|
+
"#{name ? "constraint #{name.inspect}," : 'check'} #{c[:check].map(&:inspect).join(', ')}"
|
421
421
|
end
|
422
422
|
when :foreign_key
|
423
423
|
c.delete(:on_delete) if c[:on_delete] == :no_action
|