sequel 3.37.0 → 3.38.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.
- data/CHANGELOG +56 -0
- data/README.rdoc +82 -58
- data/Rakefile +6 -5
- data/bin/sequel +1 -1
- data/doc/active_record.rdoc +67 -52
- data/doc/advanced_associations.rdoc +33 -48
- data/doc/association_basics.rdoc +41 -51
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +5 -5
- data/doc/dataset_filtering.rdoc +47 -43
- data/doc/mass_assignment.rdoc +1 -1
- data/doc/migration.rdoc +4 -5
- data/doc/model_hooks.rdoc +3 -3
- data/doc/object_model.rdoc +31 -25
- data/doc/opening_databases.rdoc +19 -5
- data/doc/prepared_statements.rdoc +2 -2
- data/doc/querying.rdoc +109 -52
- data/doc/reflection.rdoc +6 -6
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/schema_modification.rdoc +22 -13
- data/doc/sharding.rdoc +8 -9
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +47 -7
- data/doc/thread_safety.rdoc +1 -1
- data/doc/transactions.rdoc +1 -1
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +29 -43
- data/lib/sequel/adapters/do/postgres.rb +1 -4
- data/lib/sequel/adapters/jdbc.rb +14 -3
- data/lib/sequel/adapters/jdbc/db2.rb +9 -0
- data/lib/sequel/adapters/jdbc/derby.rb +41 -4
- data/lib/sequel/adapters/jdbc/jtds.rb +11 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +3 -6
- data/lib/sequel/adapters/mock.rb +10 -4
- data/lib/sequel/adapters/postgres.rb +1 -28
- data/lib/sequel/adapters/shared/mssql.rb +23 -13
- data/lib/sequel/adapters/shared/postgres.rb +46 -0
- data/lib/sequel/adapters/swift.rb +21 -13
- data/lib/sequel/adapters/swift/mysql.rb +1 -0
- data/lib/sequel/adapters/swift/postgres.rb +4 -5
- data/lib/sequel/adapters/swift/sqlite.rb +2 -1
- data/lib/sequel/adapters/tinytds.rb +14 -2
- data/lib/sequel/adapters/utils/pg_types.rb +5 -0
- data/lib/sequel/core.rb +29 -17
- data/lib/sequel/database/query.rb +1 -1
- data/lib/sequel/database/schema_generator.rb +3 -0
- data/lib/sequel/dataset/actions.rb +5 -6
- data/lib/sequel/dataset/query.rb +7 -7
- data/lib/sequel/dataset/sql.rb +5 -18
- data/lib/sequel/extensions/core_extensions.rb +8 -12
- data/lib/sequel/extensions/pg_array.rb +59 -33
- data/lib/sequel/extensions/pg_array_ops.rb +32 -4
- data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -1
- data/lib/sequel/extensions/pg_hstore.rb +32 -17
- data/lib/sequel/extensions/pg_hstore_ops.rb +32 -3
- data/lib/sequel/extensions/pg_inet.rb +1 -2
- data/lib/sequel/extensions/pg_interval.rb +0 -1
- data/lib/sequel/extensions/pg_json.rb +41 -23
- data/lib/sequel/extensions/pg_range.rb +36 -11
- data/lib/sequel/extensions/pg_range_ops.rb +32 -4
- data/lib/sequel/extensions/pg_row.rb +572 -0
- data/lib/sequel/extensions/pg_row_ops.rb +164 -0
- data/lib/sequel/extensions/query.rb +3 -3
- data/lib/sequel/extensions/schema_dumper.rb +7 -8
- data/lib/sequel/extensions/select_remove.rb +1 -1
- data/lib/sequel/model/base.rb +1 -0
- data/lib/sequel/no_core_ext.rb +1 -1
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/validation_helpers.rb +31 -0
- data/lib/sequel/sql.rb +64 -44
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +37 -12
- data/spec/adapters/mysql_spec.rb +39 -75
- data/spec/adapters/oracle_spec.rb +11 -11
- data/spec/adapters/postgres_spec.rb +414 -237
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +14 -14
- data/spec/core/database_spec.rb +6 -6
- data/spec/core/dataset_spec.rb +169 -205
- data/spec/core/expression_filters_spec.rb +182 -295
- data/spec/core/object_graph_spec.rb +6 -6
- data/spec/core/schema_spec.rb +14 -14
- data/spec/core/spec_helper.rb +1 -0
- data/spec/{extensions/core_extensions_spec.rb → core_extensions_spec.rb} +208 -14
- data/spec/extensions/columns_introspection_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +28 -36
- data/spec/extensions/many_through_many_spec.rb +4 -4
- data/spec/extensions/pg_array_ops_spec.rb +15 -7
- data/spec/extensions/pg_array_spec.rb +81 -48
- data/spec/extensions/pg_auto_parameterize_spec.rb +2 -2
- data/spec/extensions/pg_hstore_ops_spec.rb +13 -9
- data/spec/extensions/pg_hstore_spec.rb +66 -65
- data/spec/extensions/pg_inet_spec.rb +2 -4
- data/spec/extensions/pg_interval_spec.rb +2 -3
- data/spec/extensions/pg_json_spec.rb +20 -18
- data/spec/extensions/pg_range_ops_spec.rb +11 -4
- data/spec/extensions/pg_range_spec.rb +30 -7
- data/spec/extensions/pg_row_ops_spec.rb +48 -0
- data/spec/extensions/pg_row_plugin_spec.rb +45 -0
- data/spec/extensions/pg_row_spec.rb +323 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/query_literals_spec.rb +11 -11
- data/spec/extensions/query_spec.rb +3 -3
- data/spec/extensions/schema_dumper_spec.rb +20 -4
- data/spec/extensions/schema_spec.rb +18 -41
- data/spec/extensions/select_remove_spec.rb +4 -4
- data/spec/extensions/spec_helper.rb +4 -8
- data/spec/extensions/to_dot_spec.rb +5 -5
- data/spec/extensions/validation_class_methods_spec.rb +28 -16
- data/spec/integration/associations_test.rb +20 -20
- data/spec/integration/dataset_test.rb +98 -98
- data/spec/integration/eager_loader_test.rb +13 -27
- data/spec/integration/plugin_test.rb +5 -5
- data/spec/integration/prepared_statement_test.rb +22 -13
- data/spec/integration/schema_test.rb +28 -18
- data/spec/integration/spec_helper.rb +1 -1
- data/spec/integration/timezone_test.rb +2 -2
- data/spec/integration/type_test.rb +15 -6
- data/spec/model/association_reflection_spec.rb +1 -1
- data/spec/model/associations_spec.rb +4 -4
- data/spec/model/base_spec.rb +5 -5
- data/spec/model/eager_loading_spec.rb +15 -15
- data/spec/model/model_spec.rb +32 -32
- data/spec/model/record_spec.rb +16 -0
- data/spec/model/spec_helper.rb +2 -6
- data/spec/model/validations_spec.rb +1 -1
- metadata +16 -4
data/doc/testing.rdoc
CHANGED
|
@@ -12,16 +12,16 @@ Make sure you are using Sequel 3.29.0 or above when using these examples, as old
|
|
|
12
12
|
|
|
13
13
|
class Spec::Example::ExampleGroup
|
|
14
14
|
def execute(*args, &block)
|
|
15
|
-
|
|
16
|
-
Sequel::Model.db.transaction(:rollback=>:always){
|
|
17
|
-
|
|
15
|
+
result = nil
|
|
16
|
+
Sequel::Model.db.transaction(:rollback=>:always){result = super(*args, &block)}
|
|
17
|
+
result
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
=== RSpec 2
|
|
21
|
+
=== RSpec 2, <2.8
|
|
22
22
|
|
|
23
23
|
class RSpec::Core::ExampleGroup
|
|
24
|
-
# Setting an around filter globally doesn't appear to work in 2.
|
|
24
|
+
# Setting an around filter globally doesn't appear to work in <2.8,
|
|
25
25
|
# so set one up for each subclass.
|
|
26
26
|
def self.inherited(subclass)
|
|
27
27
|
super
|
|
@@ -31,21 +31,61 @@ Make sure you are using Sequel 3.29.0 or above when using these examples, as old
|
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
+
=== RSpec 2, >=2.8
|
|
35
|
+
|
|
36
|
+
# Global around filters should work
|
|
37
|
+
RSpec.configure do |c|
|
|
38
|
+
c.around(:each) do |example|
|
|
39
|
+
DB.transaction(:rollback=>:always){example.run}
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
34
43
|
=== Test::Unit
|
|
35
44
|
|
|
36
45
|
# Must use this class as the base class for your tests
|
|
37
46
|
class SequelTestCase < Test::Unit::TestCase
|
|
38
47
|
def run(*args, &block)
|
|
39
|
-
|
|
48
|
+
result = nil
|
|
49
|
+
Sequel::Model.db.transaction(:rollback=>:always){result = super}
|
|
50
|
+
result
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Or you could override the base implementation like this
|
|
55
|
+
class Test::Unit::TestCase
|
|
56
|
+
alias_method :_original_run, :run
|
|
57
|
+
|
|
58
|
+
def run(*args, &block)
|
|
59
|
+
result = nil
|
|
60
|
+
Sequel::Model.db.transaction(:rollback => :always) do
|
|
61
|
+
result = _original_run(*args, &block)
|
|
62
|
+
end
|
|
63
|
+
result
|
|
40
64
|
end
|
|
41
65
|
end
|
|
42
66
|
|
|
43
67
|
=== MiniTest::Unit
|
|
44
68
|
|
|
69
|
+
# Add a subclass
|
|
45
70
|
# Must use this class as the base class for your tests
|
|
46
71
|
class SequelTestCase < MiniTest::Unit::TestCase
|
|
47
72
|
def run(*args, &block)
|
|
48
|
-
|
|
73
|
+
result = nil
|
|
74
|
+
Sequel::Model.db.transaction(:rollback=>:always){result = super}
|
|
75
|
+
result
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Or you could override the base implementation like this
|
|
80
|
+
class MiniTest::Unit::TestCase
|
|
81
|
+
alias_method :_original_run, :run
|
|
82
|
+
|
|
83
|
+
def run(*args, &block)
|
|
84
|
+
result = nil
|
|
85
|
+
Sequel::Model.db.transaction(:rollback => :always) do
|
|
86
|
+
result = _original_run(*args, &block)
|
|
87
|
+
end
|
|
88
|
+
result
|
|
49
89
|
end
|
|
50
90
|
end
|
|
51
91
|
|
data/doc/thread_safety.rdoc
CHANGED
|
@@ -4,7 +4,7 @@ Most Sequel usage (and all common Sequel usage) is thread safe by default. Spec
|
|
|
4
4
|
|
|
5
5
|
== Connection Pool
|
|
6
6
|
|
|
7
|
-
In order to allow multiple threads to operate on the same database at the same time, Sequel uses a connection pool. The connection pool is designed so that a thread uses a connection for the minimum amount of time, returning the connection to the pool as soon as it is done using the connection. If a thread requests a connection and the pool
|
|
7
|
+
In order to allow multiple threads to operate on the same database at the same time, Sequel uses a connection pool. The connection pool is designed so that a thread uses a connection for the minimum amount of time, returning the connection to the pool as soon as it is done using the connection. If a thread requests a connection and the pool does not have an available connection, a new connection will be created. If the maximum number of connections in the pool has already been reached, the thread will block (actually busy-wait) until a connection is available or the the connection pool timeout has elapsed (in which case a PoolTimeout error will be raised).
|
|
8
8
|
|
|
9
9
|
== Exceptions
|
|
10
10
|
|
data/doc/transactions.rdoc
CHANGED
|
@@ -5,7 +5,7 @@ Sequel uses autocommit mode by default for all of its database adapters, so in g
|
|
|
5
5
|
* Dataset#import to insert many records at once
|
|
6
6
|
* Model#save
|
|
7
7
|
* Model#destroy
|
|
8
|
-
* Migrations
|
|
8
|
+
* Migrations if the database supports transactional schema
|
|
9
9
|
* A few model plugins
|
|
10
10
|
|
|
11
11
|
Everywhere else, it is up to use to use a database transaction if you want to.
|
data/doc/validations.rdoc
CHANGED
|
@@ -284,7 +284,7 @@ You can mix and match the two approaches. For example, if all albums should hav
|
|
|
284
284
|
|
|
285
285
|
+validates_unique+ also accepts a block to scope the uniqueness constraint. For example, if you want to ensure that all active albums have a unique name, but inactive albums can duplicate the name:
|
|
286
286
|
|
|
287
|
-
validates_unique(:name){|ds| ds.
|
|
287
|
+
validates_unique(:name){|ds| ds.where(:active)}
|
|
288
288
|
|
|
289
289
|
If you provide a block, it is called with the dataset to use for the uniqueness check, which you can then filter to scope the uniqueness validation to a subset of the model's dataset.
|
|
290
290
|
|
data/doc/virtual_rows.rdoc
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
= Virtual Row Blocks
|
|
2
2
|
|
|
3
|
-
Dataset methods
|
|
3
|
+
Dataset methods where, order, and select all take blocks that are referred to as
|
|
4
4
|
virtual row blocks. Many other dataset methods pass the blocks
|
|
5
5
|
they are given into one of those three methods, so there are actually
|
|
6
6
|
many Sequel::Dataset methods that take virtual row blocks.
|
|
@@ -11,7 +11,7 @@ Virtual Rows were created to work around the issue that some parts of
|
|
|
11
11
|
Sequel's standard DSL could not be used on ruby 1.9. For example, the
|
|
12
12
|
following Sequel code works on ruby 1.8, but not ruby 1.9:
|
|
13
13
|
|
|
14
|
-
dataset.
|
|
14
|
+
dataset.where(:a > :b[:c])
|
|
15
15
|
# WHERE a > b(c)
|
|
16
16
|
|
|
17
17
|
This code does not work on ruby 1.9 for two reasons. First, Symbol#>
|
|
@@ -20,30 +20,15 @@ does not override it to return an SQL inequality expression. Second, Symbol#[]
|
|
|
20
20
|
is already defined on ruby 1.9, so Sequel does not override it to return an
|
|
21
21
|
SQL function expression.
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
It's possible to use Sequel's DSL to represent such expressions, but it is a
|
|
24
|
+
little verbose:
|
|
25
25
|
|
|
26
|
-
dataset.
|
|
26
|
+
dataset.where(Sequel.expr(:a) > Sequel.function(:b, :c))
|
|
27
27
|
# WHERE a > b(c)
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
more concise:
|
|
29
|
+
The virtual row DSL makes such code more concise:
|
|
31
30
|
|
|
32
|
-
dataset.
|
|
33
|
-
|
|
34
|
-
Another use of virtual rows is when you turn off Sequel's core extensions off
|
|
35
|
-
using the SEQUEL_NO_CORE_EXTENSIONS constant or environment variable. With
|
|
36
|
-
the core extensions turned off, much of the standard Sequel DSL is not
|
|
37
|
-
available. For example, you are no longer able to do:
|
|
38
|
-
|
|
39
|
-
dataset.filter(:a & (:b | ~:c))
|
|
40
|
-
# WHERE a AND (b OR NOT c)
|
|
41
|
-
|
|
42
|
-
Because Symbol#&, Symbol#| and Symbol#~ are not defined when the core
|
|
43
|
-
extensions are turned off. However, virtual rows allow almost the same
|
|
44
|
-
syntax even without the core extensions:
|
|
45
|
-
|
|
46
|
-
dataset.filter{a & (b | ~c)}
|
|
31
|
+
dataset.where{a > b(c)}
|
|
47
32
|
|
|
48
33
|
== Regular Procs vs Instance Evaled Procs
|
|
49
34
|
|
|
@@ -54,11 +39,11 @@ evaluated in the context of an instance of Sequel::SQL::VirtualRow.
|
|
|
54
39
|
|
|
55
40
|
ds = DB[:items]
|
|
56
41
|
# Regular proc
|
|
57
|
-
ds.
|
|
42
|
+
ds.where{|o| o.column > 1}
|
|
58
43
|
# WHERE column > 1
|
|
59
44
|
|
|
60
45
|
# Instance-evaled proc
|
|
61
|
-
ds.
|
|
46
|
+
ds.where{column > 1}
|
|
62
47
|
# WHERE column > 1
|
|
63
48
|
|
|
64
49
|
If you aren't familiar with the difference between regular blocks and instance
|
|
@@ -75,21 +60,21 @@ inside the proc. If that doesn't make sense, maybe this example will help:
|
|
|
75
60
|
b = 32
|
|
76
61
|
|
|
77
62
|
# Regular proc
|
|
78
|
-
ds.
|
|
63
|
+
ds.where{|o| o.c > a - b}
|
|
79
64
|
# WHERE c > 10
|
|
80
65
|
|
|
81
66
|
# Instance-evaled proc
|
|
82
|
-
ds.
|
|
67
|
+
ds.where{c > a - b}
|
|
83
68
|
# WHERE c > (a - 32)
|
|
84
69
|
|
|
85
|
-
There are two related differences here. First is the usage of
|
|
86
|
-
and second is the difference between the the use of
|
|
87
|
-
you couldn't call c without an explicit receiver in the proc, unless the self of the
|
|
88
|
-
surrounding scope responded to it. For a
|
|
70
|
+
There are two related differences here. First is the usage of <tt>o.c</tt> vs +c+,
|
|
71
|
+
and second is the difference between the the use of +a+. In the regular proc,
|
|
72
|
+
you couldn't call +c+ without an explicit receiver in the proc, unless the self of the
|
|
73
|
+
surrounding scope responded to it. For +a+, note how ruby calls the method on
|
|
89
74
|
the receiver of the surrounding scope in the regular proc, which returns an integer,
|
|
90
|
-
and does the
|
|
91
|
-
proc, calling a without a receiver calls the a method on the VirtualRow instance.
|
|
92
|
-
For b
|
|
75
|
+
and does the subtraction before Sequel gets access to it. In the instance evaled
|
|
76
|
+
proc, calling +a+ without a receiver calls the a method on the VirtualRow instance.
|
|
77
|
+
For +b+, note that it operates the same in both cases, as it is a local variable.
|
|
93
78
|
|
|
94
79
|
Basically, the choice for whether to use a regular proc or an instance evaled proc is
|
|
95
80
|
completely up to you. The same things can be accomplished with both.
|
|
@@ -105,7 +90,7 @@ variable, you can call it with () to differentiate the method call from the
|
|
|
105
90
|
local variable access. This is mostly useful in instance_evaled procs:
|
|
106
91
|
|
|
107
92
|
b = 32
|
|
108
|
-
ds.
|
|
93
|
+
ds.where{b() > b}
|
|
109
94
|
# WHERE b > 32
|
|
110
95
|
|
|
111
96
|
== VirtualRow Methods
|
|
@@ -120,8 +105,8 @@ not qualified by any table. You get an SQL::Identifier if the method is called
|
|
|
120
105
|
without a block or arguments, and doesn't have a double underscore in the method
|
|
121
106
|
name:
|
|
122
107
|
|
|
123
|
-
ds.
|
|
124
|
-
ds.
|
|
108
|
+
ds.where{|o| o.column > 1}
|
|
109
|
+
ds.where{column > 1}
|
|
125
110
|
# WHERE column > 1
|
|
126
111
|
|
|
127
112
|
== SQL::QualifiedIdentifiers - Qualified columns
|
|
@@ -131,8 +116,8 @@ are qualified to a specific table. You get an SQL::QualifiedIdentifier if
|
|
|
131
116
|
the method is called without a block or arguments, and has a double underscore
|
|
132
117
|
in the method name:
|
|
133
118
|
|
|
134
|
-
ds.
|
|
135
|
-
ds.
|
|
119
|
+
ds.where{|o| o.table__column > 1}
|
|
120
|
+
ds.where{table__column > 1}
|
|
136
121
|
# WHERE table.column > 1
|
|
137
122
|
|
|
138
123
|
Using the double underscore for SQL::QualifiedIdentifiers was done to make
|
|
@@ -144,15 +129,15 @@ into a qualified column.
|
|
|
144
129
|
SQL::Functions can be thought of as function calls in SQL. You get a simple
|
|
145
130
|
function call if you call a method with arguments and without a block:
|
|
146
131
|
|
|
147
|
-
ds.
|
|
148
|
-
ds.
|
|
132
|
+
ds.where{|o| o.function(1) > 1}
|
|
133
|
+
ds.where{function(1) > 1}
|
|
149
134
|
# WHERE function(1) > 1
|
|
150
135
|
|
|
151
136
|
To call a SQL function with multiple arguments, just use those arguments in
|
|
152
137
|
your function call:
|
|
153
138
|
|
|
154
|
-
ds.
|
|
155
|
-
ds.
|
|
139
|
+
ds.where{|o| o.function(1, o.a) > 1}
|
|
140
|
+
ds.where{function(1, a) > 1}
|
|
156
141
|
# WHERE function(1, a) > 1
|
|
157
142
|
|
|
158
143
|
If the SQL function does not accept any arguments, you need to provide an empty
|
|
@@ -191,7 +176,8 @@ the method call:
|
|
|
191
176
|
SQL::WindowFunctions can be thought of as calls to SQL window functions. Not
|
|
192
177
|
all databases support them, but they are very helpful for certain types of
|
|
193
178
|
queries. To use them, you need to make :over the first argument of the method
|
|
194
|
-
call, with an optional hash as the second argument
|
|
179
|
+
call, with an optional hash as the second argument, and provide an empty block
|
|
180
|
+
to the method. Here are some examples of use:
|
|
195
181
|
|
|
196
182
|
ds.select{|o| o.rank(:over){}}
|
|
197
183
|
ds.select{rank(:over){}}
|
|
@@ -15,10 +15,7 @@ module Sequel
|
|
|
15
15
|
# Add the primary_keys and primary_key_sequences instance variables,
|
|
16
16
|
# so we can get the correct return values for inserted rows.
|
|
17
17
|
def self.extended(db)
|
|
18
|
-
db.
|
|
19
|
-
@primary_keys = {}
|
|
20
|
-
@primary_key_sequences = {}
|
|
21
|
-
end
|
|
18
|
+
db.send(:initialize_postgres_adapter)
|
|
22
19
|
end
|
|
23
20
|
|
|
24
21
|
private
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
|
@@ -66,7 +66,7 @@ module Sequel
|
|
|
66
66
|
end,
|
|
67
67
|
:jtds=>proc do |db|
|
|
68
68
|
Sequel.ts_require 'adapters/jdbc/jtds'
|
|
69
|
-
db.extend(Sequel::JDBC::
|
|
69
|
+
db.extend(Sequel::JDBC::JTDS::DatabaseMethods)
|
|
70
70
|
db.dataset_class = Sequel::JDBC::JTDS::Dataset
|
|
71
71
|
db.send(:set_mssql_unicode_strings)
|
|
72
72
|
JDBC.load_gem('jtds')
|
|
@@ -431,7 +431,8 @@ module Sequel
|
|
|
431
431
|
# Support fractional seconds for Time objects used in bound variables
|
|
432
432
|
def java_sql_timestamp(time)
|
|
433
433
|
ts = java.sql.Timestamp.new(time.to_i * 1000)
|
|
434
|
-
|
|
434
|
+
# Work around jruby 1.6 ruby 1.9 mode bug
|
|
435
|
+
ts.setNanos((RUBY_VERSION >= '1.9.0' && time.nsec != 0) ? time.nsec : time.usec * 1000)
|
|
435
436
|
ts
|
|
436
437
|
end
|
|
437
438
|
|
|
@@ -477,7 +478,7 @@ module Sequel
|
|
|
477
478
|
when TrueClass, FalseClass
|
|
478
479
|
cps.setBoolean(i, arg)
|
|
479
480
|
when NilClass
|
|
480
|
-
cps
|
|
481
|
+
set_ps_arg_nil(cps, i)
|
|
481
482
|
when DateTime
|
|
482
483
|
cps.setTimestamp(i, java_sql_datetime(arg))
|
|
483
484
|
when Date
|
|
@@ -492,6 +493,11 @@ module Sequel
|
|
|
492
493
|
cps.setObject(i, arg)
|
|
493
494
|
end
|
|
494
495
|
end
|
|
496
|
+
|
|
497
|
+
# Use setString with a nil value by default, but this doesn't work on all subadapters.
|
|
498
|
+
def set_ps_arg_nil(cps, i)
|
|
499
|
+
cps.setString(i, nil)
|
|
500
|
+
end
|
|
495
501
|
|
|
496
502
|
# Return the connection. Used to do configuration on the
|
|
497
503
|
# connection object before adding it to the connection pool.
|
|
@@ -636,6 +642,7 @@ module Sequel
|
|
|
636
642
|
JAVA_BUFFERED_READER = Java::JavaIo::BufferedReader
|
|
637
643
|
JAVA_BIG_DECIMAL = Java::JavaMath::BigDecimal
|
|
638
644
|
JAVA_BYTE_ARRAY = Java::byte[]
|
|
645
|
+
JAVA_UUID = Java::JavaUtil::UUID
|
|
639
646
|
|
|
640
647
|
# Handle type conversions for common Java types.
|
|
641
648
|
class TYPE_TRANSLATOR
|
|
@@ -656,6 +663,7 @@ module Sequel
|
|
|
656
663
|
end
|
|
657
664
|
lines
|
|
658
665
|
end
|
|
666
|
+
def uuid(v) v.to_string end
|
|
659
667
|
end
|
|
660
668
|
TYPE_TRANSLATOR_INSTANCE = tt = TYPE_TRANSLATOR.new
|
|
661
669
|
|
|
@@ -668,6 +676,7 @@ module Sequel
|
|
|
668
676
|
BYTE_ARRAY_METHOD = tt.method(:byte_array)
|
|
669
677
|
BLOB_METHOD = tt.method(:blob)
|
|
670
678
|
CLOB_METHOD = tt.method(:clob)
|
|
679
|
+
UUID_METHOD = tt.method(:uuid)
|
|
671
680
|
|
|
672
681
|
# Convert the given Java timestamp to an instance of Sequel.datetime_class.
|
|
673
682
|
def convert_type_timestamp(v)
|
|
@@ -695,6 +704,8 @@ module Sequel
|
|
|
695
704
|
BLOB_METHOD
|
|
696
705
|
when JAVA_SQL_CLOB
|
|
697
706
|
CLOB_METHOD
|
|
707
|
+
when JAVA_UUID
|
|
708
|
+
UUID_METHOD
|
|
698
709
|
else
|
|
699
710
|
false
|
|
700
711
|
end
|
|
@@ -114,6 +114,11 @@ module Sequel
|
|
|
114
114
|
end
|
|
115
115
|
end
|
|
116
116
|
|
|
117
|
+
# Handle nil values by using setNull with the correct parameter type.
|
|
118
|
+
def set_ps_arg_nil(cps, i)
|
|
119
|
+
cps.setNull(i, cps.getParameterMetaData.getParameterType(i))
|
|
120
|
+
end
|
|
121
|
+
|
|
117
122
|
# Derby uses RENAME TABLE syntax to rename tables.
|
|
118
123
|
def rename_table_sql(name, new_name)
|
|
119
124
|
"RENAME TABLE #{quote_schema_table(name)} TO #{quote_schema_table(new_name)}"
|
|
@@ -124,6 +129,11 @@ module Sequel
|
|
|
124
129
|
PRIMARY_KEY_INDEX_RE
|
|
125
130
|
end
|
|
126
131
|
|
|
132
|
+
# Treat clob as string instead of blob
|
|
133
|
+
def schema_column_type(db_type)
|
|
134
|
+
db_type.downcase == 'clob' ? :string : super
|
|
135
|
+
end
|
|
136
|
+
|
|
127
137
|
# If an :identity option is present in the column, add the necessary IDENTITY SQL.
|
|
128
138
|
def type_literal(column)
|
|
129
139
|
if column[:identity]
|
|
@@ -156,8 +166,10 @@ module Sequel
|
|
|
156
166
|
ROWS = " ROWS".freeze
|
|
157
167
|
FETCH_FIRST = " FETCH FIRST ".freeze
|
|
158
168
|
ROWS_ONLY = " ROWS ONLY".freeze
|
|
159
|
-
|
|
160
|
-
|
|
169
|
+
BOOL_TRUE_OLD = '(1 = 1)'.freeze
|
|
170
|
+
BOOL_FALSE_OLD = '(1 = 0)'.freeze
|
|
171
|
+
BOOL_TRUE = 'TRUE'.freeze
|
|
172
|
+
BOOL_FALSE = 'FALSE'.freeze
|
|
161
173
|
SELECT_CLAUSE_METHODS = clause_methods(:select, %w'select distinct columns from join where group having compounds order limit lock')
|
|
162
174
|
|
|
163
175
|
# Derby doesn't support an expression between CASE and WHEN,
|
|
@@ -226,6 +238,23 @@ module Sequel
|
|
|
226
238
|
|
|
227
239
|
private
|
|
228
240
|
|
|
241
|
+
JAVA_SQL_CLOB = Java::JavaSQL::Clob
|
|
242
|
+
|
|
243
|
+
class ::Sequel::JDBC::Dataset::TYPE_TRANSLATOR
|
|
244
|
+
def derby_clob(v) v.getSubString(1, v.length) end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
DERBY_CLOB_METHOD = TYPE_TRANSLATOR_INSTANCE.method(:derby_clob)
|
|
248
|
+
|
|
249
|
+
# Handle clobs on Derby as strings.
|
|
250
|
+
def convert_type_proc(v)
|
|
251
|
+
if v.is_a?(JAVA_SQL_CLOB)
|
|
252
|
+
DERBY_CLOB_METHOD
|
|
253
|
+
else
|
|
254
|
+
super
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
229
258
|
# Derby needs a hex string casted to BLOB for blobs.
|
|
230
259
|
def literal_blob_append(sql, v)
|
|
231
260
|
sql << BLOB_OPEN << v.unpack(HSTAR).first << BLOB_CLOSE
|
|
@@ -240,7 +269,11 @@ module Sequel
|
|
|
240
269
|
# Derby uses an expression yielding false for false values.
|
|
241
270
|
# Newer versions can use the FALSE literal, but the latest gem version cannot.
|
|
242
271
|
def literal_false
|
|
243
|
-
|
|
272
|
+
if db.svn_version >= 1040133
|
|
273
|
+
BOOL_FALSE
|
|
274
|
+
else
|
|
275
|
+
BOOL_FALSE_OLD
|
|
276
|
+
end
|
|
244
277
|
end
|
|
245
278
|
|
|
246
279
|
# Derby handles fractional seconds in timestamps, but not in times
|
|
@@ -251,7 +284,11 @@ module Sequel
|
|
|
251
284
|
# Derby uses an expression yielding true for true values.
|
|
252
285
|
# Newer versions can use the TRUE literal, but the latest gem version cannot.
|
|
253
286
|
def literal_true
|
|
254
|
-
|
|
287
|
+
if db.svn_version >= 1040133
|
|
288
|
+
BOOL_TRUE
|
|
289
|
+
else
|
|
290
|
+
BOOL_TRUE_OLD
|
|
291
|
+
end
|
|
255
292
|
end
|
|
256
293
|
|
|
257
294
|
# Derby doesn't support common table expressions.
|