sequel 3.28.0 → 3.29.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 +119 -3
- data/Rakefile +5 -3
- data/bin/sequel +1 -5
- data/doc/model_hooks.rdoc +9 -1
- data/doc/opening_databases.rdoc +49 -40
- data/doc/prepared_statements.rdoc +27 -6
- data/doc/release_notes/3.28.0.txt +2 -2
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +18 -9
- data/doc/transactions.rdoc +41 -1
- data/lib/sequel/adapters/ado.rb +28 -17
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/amalgalite.rb +11 -7
- data/lib/sequel/adapters/db2.rb +122 -70
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do.rb +5 -36
- data/lib/sequel/adapters/do/mysql.rb +0 -5
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/firebird.rb +3 -6
- data/lib/sequel/adapters/ibmdb.rb +24 -16
- data/lib/sequel/adapters/informix.rb +2 -4
- data/lib/sequel/adapters/jdbc.rb +47 -11
- data/lib/sequel/adapters/jdbc/as400.rb +5 -24
- data/lib/sequel/adapters/jdbc/db2.rb +0 -5
- data/lib/sequel/adapters/jdbc/derby.rb +217 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +0 -5
- data/lib/sequel/adapters/jdbc/h2.rb +10 -12
- data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
- data/lib/sequel/adapters/jdbc/informix.rb +0 -5
- data/lib/sequel/adapters/jdbc/jtds.rb +0 -5
- data/lib/sequel/adapters/jdbc/mysql.rb +0 -10
- data/lib/sequel/adapters/jdbc/oracle.rb +70 -3
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -11
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
- data/lib/sequel/adapters/jdbc/sqlserver.rb +0 -5
- data/lib/sequel/adapters/jdbc/transactions.rb +56 -7
- data/lib/sequel/adapters/mock.rb +315 -0
- data/lib/sequel/adapters/mysql.rb +64 -51
- data/lib/sequel/adapters/mysql2.rb +15 -9
- data/lib/sequel/adapters/odbc.rb +13 -6
- data/lib/sequel/adapters/odbc/db2.rb +0 -4
- data/lib/sequel/adapters/odbc/mssql.rb +0 -5
- data/lib/sequel/adapters/openbase.rb +2 -4
- data/lib/sequel/adapters/oracle.rb +333 -51
- data/lib/sequel/adapters/postgres.rb +80 -27
- data/lib/sequel/adapters/shared/access.rb +0 -6
- data/lib/sequel/adapters/shared/db2.rb +13 -15
- data/lib/sequel/adapters/shared/firebird.rb +6 -6
- data/lib/sequel/adapters/shared/mssql.rb +23 -18
- data/lib/sequel/adapters/shared/mysql.rb +6 -6
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +6 -0
- data/lib/sequel/adapters/shared/oracle.rb +185 -30
- data/lib/sequel/adapters/shared/postgres.rb +35 -18
- data/lib/sequel/adapters/shared/progress.rb +0 -6
- data/lib/sequel/adapters/shared/sqlite.rb +116 -37
- data/lib/sequel/adapters/sqlite.rb +16 -8
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/swift/mysql.rb +0 -5
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +6 -4
- data/lib/sequel/adapters/tinytds.rb +13 -10
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +8 -0
- data/lib/sequel/core.rb +40 -0
- data/lib/sequel/database/connecting.rb +1 -2
- data/lib/sequel/database/dataset.rb +3 -3
- data/lib/sequel/database/dataset_defaults.rb +58 -0
- data/lib/sequel/database/misc.rb +62 -2
- data/lib/sequel/database/query.rb +113 -49
- data/lib/sequel/database/schema_methods.rb +7 -2
- data/lib/sequel/dataset/actions.rb +37 -19
- data/lib/sequel/dataset/features.rb +24 -0
- data/lib/sequel/dataset/graph.rb +7 -6
- data/lib/sequel/dataset/misc.rb +11 -3
- data/lib/sequel/dataset/mutation.rb +2 -3
- data/lib/sequel/dataset/prepared_statements.rb +6 -4
- data/lib/sequel/dataset/query.rb +46 -15
- data/lib/sequel/dataset/sql.rb +28 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/model.rb +2 -1
- data/lib/sequel/model/associations.rb +115 -33
- data/lib/sequel/model/base.rb +91 -31
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +6 -10
- data/lib/sequel/plugins/prepared_statements.rb +12 -1
- data/lib/sequel/plugins/prepared_statements_associations.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +6 -1
- data/lib/sequel/plugins/sharding.rb +0 -5
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +1 -1
- data/lib/sequel/timezones.rb +42 -42
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +29 -29
- data/spec/adapters/mysql_spec.rb +86 -104
- data/spec/adapters/oracle_spec.rb +48 -76
- data/spec/adapters/postgres_spec.rb +98 -33
- data/spec/adapters/spec_helper.rb +0 -5
- data/spec/adapters/sqlite_spec.rb +24 -21
- data/spec/core/connection_pool_spec.rb +9 -15
- data/spec/core/core_sql_spec.rb +20 -31
- data/spec/core/database_spec.rb +491 -227
- data/spec/core/dataset_spec.rb +638 -1051
- data/spec/core/expression_filters_spec.rb +0 -1
- data/spec/core/mock_adapter_spec.rb +378 -0
- data/spec/core/object_graph_spec.rb +48 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +51 -114
- data/spec/core/spec_helper.rb +3 -90
- data/spec/extensions/class_table_inheritance_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/instance_hooks_spec.rb +71 -0
- data/spec/extensions/named_timezones_spec.rb +22 -2
- data/spec/extensions/nested_attributes_spec.rb +3 -0
- data/spec/extensions/schema_spec.rb +1 -1
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -0
- data/spec/extensions/serialization_spec.rb +5 -8
- data/spec/extensions/spec_helper.rb +4 -0
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/integration/associations_test.rb +123 -12
- data/spec/integration/dataset_test.rb +140 -47
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +179 -128
- data/spec/integration/prepared_statement_test.rb +92 -91
- data/spec/integration/schema_test.rb +42 -23
- data/spec/integration/spec_helper.rb +25 -31
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +161 -34
- data/spec/integration/type_test.rb +3 -3
- data/spec/model/association_reflection_spec.rb +83 -7
- data/spec/model/associations_spec.rb +393 -676
- data/spec/model/base_spec.rb +186 -116
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +343 -867
- data/spec/model/hooks_spec.rb +160 -79
- data/spec/model/model_spec.rb +118 -165
- data/spec/model/plugins_spec.rb +7 -13
- data/spec/model/record_spec.rb +138 -207
- data/spec/model/spec_helper.rb +10 -73
- metadata +14 -8
data/lib/sequel/adapters/dbi.rb
CHANGED
|
@@ -63,10 +63,6 @@ module Sequel
|
|
|
63
63
|
::DBI.connect(dbname, opts[:user], opts[:password])
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
def dataset(opts = nil)
|
|
67
|
-
DBI::Dataset.new(self, opts)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
66
|
def execute(sql, opts={})
|
|
71
67
|
synchronize(opts[:server]) do |conn|
|
|
72
68
|
r = log_yield(sql){conn.execute(sql)}
|
|
@@ -88,26 +84,30 @@ module Sequel
|
|
|
88
84
|
end
|
|
89
85
|
|
|
90
86
|
class Dataset < Sequel::Dataset
|
|
87
|
+
Database::DatasetClass = self
|
|
88
|
+
|
|
91
89
|
def fetch_rows(sql)
|
|
92
90
|
execute(sql) do |s|
|
|
93
91
|
begin
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
columns = cols = s.column_names.map{|c| output_identifier(c)}
|
|
93
|
+
if opts[:offset] && offset_returns_row_number_column?
|
|
94
|
+
rn = row_number_column
|
|
95
|
+
columns = columns.dup
|
|
96
|
+
columns.delete(rn)
|
|
97
|
+
end
|
|
98
|
+
@columns = columns
|
|
99
|
+
s.fetch do |r|
|
|
100
|
+
row = {}
|
|
101
|
+
cols.each{|c| row[c] = r.shift}
|
|
102
|
+
row.delete(rn) if rn
|
|
103
|
+
yield row
|
|
104
|
+
end
|
|
96
105
|
ensure
|
|
97
106
|
s.finish rescue nil
|
|
98
107
|
end
|
|
99
108
|
end
|
|
100
109
|
self
|
|
101
110
|
end
|
|
102
|
-
|
|
103
|
-
private
|
|
104
|
-
|
|
105
|
-
def hash_row(stmt, row)
|
|
106
|
-
@columns.inject({}) do |m, c|
|
|
107
|
-
m[c] = row.shift
|
|
108
|
-
m
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
111
|
end
|
|
112
112
|
end
|
|
113
113
|
end
|
data/lib/sequel/adapters/do.rb
CHANGED
|
@@ -17,16 +17,19 @@ module Sequel
|
|
|
17
17
|
Sequel.tsk_require 'do_postgres'
|
|
18
18
|
Sequel.ts_require 'adapters/do/postgres'
|
|
19
19
|
db.extend(Sequel::DataObjects::Postgres::DatabaseMethods)
|
|
20
|
+
db.dataset_class = Sequel::DataObjects::Postgres::Dataset
|
|
20
21
|
end,
|
|
21
22
|
:mysql=>proc do |db|
|
|
22
23
|
Sequel.tsk_require 'do_mysql'
|
|
23
24
|
Sequel.ts_require 'adapters/do/mysql'
|
|
24
25
|
db.extend(Sequel::DataObjects::MySQL::DatabaseMethods)
|
|
26
|
+
db.dataset_class = Sequel::DataObjects::MySQL::Dataset
|
|
25
27
|
end,
|
|
26
28
|
:sqlite3=>proc do |db|
|
|
27
29
|
Sequel.tsk_require 'do_sqlite3'
|
|
28
30
|
Sequel.ts_require 'adapters/do/sqlite'
|
|
29
31
|
db.extend(Sequel::DataObjects::SQLite::DatabaseMethods)
|
|
32
|
+
db.dataset_class = Sequel::DataObjects::SQLite::Dataset
|
|
30
33
|
end
|
|
31
34
|
}
|
|
32
35
|
|
|
@@ -57,11 +60,6 @@ module Sequel
|
|
|
57
60
|
setup_connection(::DataObjects::Connection.new(uri(server_opts(server))))
|
|
58
61
|
end
|
|
59
62
|
|
|
60
|
-
# Return a Sequel::DataObjects::Dataset object for this database.
|
|
61
|
-
def dataset(opts = nil)
|
|
62
|
-
DataObjects::Dataset.new(self, opts)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
63
|
# Execute the given SQL. If a block is given, the DataObjects::Reader
|
|
66
64
|
# created is yielded to it. A block should not be provided unless a
|
|
67
65
|
# a SELECT statement is being used (or something else that returns rows).
|
|
@@ -116,31 +114,6 @@ module Sequel
|
|
|
116
114
|
|
|
117
115
|
private
|
|
118
116
|
|
|
119
|
-
# DataObjects uses a special transaction object to keep track of
|
|
120
|
-
# transactions. Unfortunately, it tries to create a new connection
|
|
121
|
-
# to do a transaction. So we close the connection created and
|
|
122
|
-
# substitute our own.
|
|
123
|
-
def begin_transaction(conn, opts={})
|
|
124
|
-
return super if supports_savepoints?
|
|
125
|
-
log_yield(TRANSACTION_BEGIN) do
|
|
126
|
-
t = ::DataObjects::Transaction.create_for_uri(uri)
|
|
127
|
-
t.instance_variable_get(:@connection).close
|
|
128
|
-
t.instance_variable_set(:@connection, conn)
|
|
129
|
-
t.begin
|
|
130
|
-
t
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
# DataObjects requires transactions be prepared before being
|
|
135
|
-
# committed, so we do that.
|
|
136
|
-
def commit_transaction(t, opts={})
|
|
137
|
-
return super if supports_savepoints?
|
|
138
|
-
log_yield(TRANSACTION_ROLLBACK) do
|
|
139
|
-
t.prepare
|
|
140
|
-
t.commit
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
|
|
144
117
|
# Method to call on a statement object to execute SQL that does
|
|
145
118
|
# not return any rows.
|
|
146
119
|
def connection_execute_method
|
|
@@ -167,12 +140,6 @@ module Sequel
|
|
|
167
140
|
log_yield(sql){conn.create_command(sql).execute_non_query}
|
|
168
141
|
end
|
|
169
142
|
|
|
170
|
-
# We use the transactions rollback method to rollback.
|
|
171
|
-
def rollback_transaction(t, opts={})
|
|
172
|
-
return super if supports_savepoints?
|
|
173
|
-
log_yield(TRANSACTION_COMMIT){t.rollback}
|
|
174
|
-
end
|
|
175
|
-
|
|
176
143
|
# Allow extending the given connection when it is first created.
|
|
177
144
|
# By default, just returns the connection.
|
|
178
145
|
def setup_connection(conn)
|
|
@@ -182,6 +149,8 @@ module Sequel
|
|
|
182
149
|
|
|
183
150
|
# Dataset class for Sequel::DataObjects::Database objects.
|
|
184
151
|
class Dataset < Sequel::Dataset
|
|
152
|
+
Database::DatasetClass = self
|
|
153
|
+
|
|
185
154
|
# Execute the SQL on the database and yield the rows as hashes
|
|
186
155
|
# with symbol keys.
|
|
187
156
|
def fetch_rows(sql)
|
|
@@ -9,11 +9,6 @@ module Sequel
|
|
|
9
9
|
module DatabaseMethods
|
|
10
10
|
include Sequel::MySQL::DatabaseMethods
|
|
11
11
|
|
|
12
|
-
# Return instance of Sequel::DataObjects::MySQL::Dataset with the given opts.
|
|
13
|
-
def dataset(opts=nil)
|
|
14
|
-
Sequel::DataObjects::MySQL::Dataset.new(self, opts)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
12
|
private
|
|
18
13
|
|
|
19
14
|
# The database name for the given database. Need to parse it out
|
|
@@ -55,11 +55,6 @@ module Sequel
|
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
# Return instance of Sequel::DataObjects::Postgres::Dataset with the given opts.
|
|
59
|
-
def dataset(opts=nil)
|
|
60
|
-
Sequel::DataObjects::Postgres::Dataset.new(self, opts)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
58
|
# Run the INSERT sql on the database and return the primary key
|
|
64
59
|
# for the record.
|
|
65
60
|
def execute_insert(sql, opts={})
|
|
@@ -8,11 +8,6 @@ module Sequel
|
|
|
8
8
|
module DatabaseMethods
|
|
9
9
|
include Sequel::SQLite::DatabaseMethods
|
|
10
10
|
|
|
11
|
-
# Return Sequel::DataObjects::SQLite::Dataset object with the given opts.
|
|
12
|
-
def dataset(opts=nil)
|
|
13
|
-
Sequel::DataObjects::SQLite::Dataset.new(self, opts)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
11
|
private
|
|
17
12
|
|
|
18
13
|
# Default to a single connection for a memory database.
|
|
@@ -28,14 +28,10 @@ module Sequel
|
|
|
28
28
|
:password => opts[:password]).connect
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
def dataset(opts = nil)
|
|
32
|
-
Firebird::Dataset.new(self, opts)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
31
|
def execute(sql, opts={})
|
|
36
32
|
begin
|
|
37
33
|
synchronize(opts[:server]) do |conn|
|
|
38
|
-
if conn.transaction_started && !@transactions.
|
|
34
|
+
if conn.transaction_started && !@transactions.has_key?(conn)
|
|
39
35
|
conn.rollback
|
|
40
36
|
raise DatabaseDisconnectError, "transaction accidently left open, rolling back and disconnecting"
|
|
41
37
|
end
|
|
@@ -59,7 +55,6 @@ module Sequel
|
|
|
59
55
|
raise_error(e, :disconnect=>true)
|
|
60
56
|
end
|
|
61
57
|
end
|
|
62
|
-
conn
|
|
63
58
|
end
|
|
64
59
|
|
|
65
60
|
def commit_transaction(conn, opts={})
|
|
@@ -83,6 +78,8 @@ module Sequel
|
|
|
83
78
|
class Dataset < Sequel::Dataset
|
|
84
79
|
include Sequel::Firebird::DatasetMethods
|
|
85
80
|
|
|
81
|
+
Database::DatasetClass = self
|
|
82
|
+
|
|
86
83
|
# Yield all rows returned by executing the given SQL and converting
|
|
87
84
|
# the types.
|
|
88
85
|
def fetch_rows(sql)
|
|
@@ -23,8 +23,7 @@ module Sequel
|
|
|
23
23
|
:int => tt.method(:int),
|
|
24
24
|
:blob => ::Sequel::SQL::Blob.method(:new),
|
|
25
25
|
:time => ::Sequel.method(:string_to_time),
|
|
26
|
-
:date => ::Sequel.method(:string_to_date)
|
|
27
|
-
:timestamp => ::Sequel.method(:database_to_application_timestamp)
|
|
26
|
+
:date => ::Sequel.method(:string_to_date)
|
|
28
27
|
}
|
|
29
28
|
DB2_TYPES[:clob] = DB2_TYPES[:blob]
|
|
30
29
|
|
|
@@ -163,6 +162,15 @@ module Sequel
|
|
|
163
162
|
|
|
164
163
|
set_adapter_scheme :ibmdb
|
|
165
164
|
|
|
165
|
+
# Hash of connection procs for converting
|
|
166
|
+
attr_reader :conversion_procs
|
|
167
|
+
|
|
168
|
+
def initialize(opts={})
|
|
169
|
+
super
|
|
170
|
+
@conversion_procs = DB2_TYPES.dup
|
|
171
|
+
@conversion_procs[:timestamp] = method(:to_application_timestamp)
|
|
172
|
+
end
|
|
173
|
+
|
|
166
174
|
# REORG the related table whenever it is altered. This is not always
|
|
167
175
|
# required, but it is necessary for compatibilty with other Sequel
|
|
168
176
|
# code in many cases.
|
|
@@ -190,11 +198,6 @@ module Sequel
|
|
|
190
198
|
Connection.new(connection_string)
|
|
191
199
|
end
|
|
192
200
|
|
|
193
|
-
# Return a related IBMDB::Dataset instance with the given options.
|
|
194
|
-
def dataset(opts = nil)
|
|
195
|
-
IBMDB::Dataset.new(self, opts)
|
|
196
|
-
end
|
|
197
|
-
|
|
198
201
|
# Execute the given SQL on the database.
|
|
199
202
|
def execute(sql, opts={}, &block)
|
|
200
203
|
if sql.is_a?(Symbol)
|
|
@@ -250,7 +253,7 @@ module Sequel
|
|
|
250
253
|
if Sequel::IBMDB.convert_smallint_to_bool && db_type =~ /smallint/i
|
|
251
254
|
:boolean
|
|
252
255
|
else
|
|
253
|
-
|
|
256
|
+
super
|
|
254
257
|
end
|
|
255
258
|
end
|
|
256
259
|
|
|
@@ -293,15 +296,12 @@ module Sequel
|
|
|
293
296
|
# So starting a transaction just turns autocommit off.
|
|
294
297
|
def begin_transaction(conn, opts={})
|
|
295
298
|
log_yield(TRANSACTION_BEGIN){conn.autocommit = false}
|
|
296
|
-
conn
|
|
297
299
|
end
|
|
298
300
|
|
|
299
301
|
# This commits transaction in progress on the
|
|
300
302
|
# connection and sets autocommit back on.
|
|
301
303
|
def commit_transaction(conn, opts={})
|
|
302
|
-
log_yield(TRANSACTION_COMMIT){conn.commit}
|
|
303
|
-
ensure
|
|
304
|
-
conn.autocommit = true if conn
|
|
304
|
+
log_yield(TRANSACTION_COMMIT){conn.commit}
|
|
305
305
|
end
|
|
306
306
|
|
|
307
307
|
# Close the given connection.
|
|
@@ -332,18 +332,25 @@ module Sequel
|
|
|
332
332
|
end
|
|
333
333
|
end
|
|
334
334
|
|
|
335
|
+
# Set autocommit back on
|
|
336
|
+
def remove_transaction(conn, committed)
|
|
337
|
+
conn.autocommit = true
|
|
338
|
+
ensure
|
|
339
|
+
super
|
|
340
|
+
end
|
|
341
|
+
|
|
335
342
|
# This rolls back the transaction in progress on the
|
|
336
343
|
# connection and sets autocommit back on.
|
|
337
344
|
def rollback_transaction(conn, opts={})
|
|
338
|
-
log_yield(TRANSACTION_ROLLBACK){conn.rollback}
|
|
339
|
-
ensure
|
|
340
|
-
conn.autocommit = true if conn
|
|
345
|
+
log_yield(TRANSACTION_ROLLBACK){conn.rollback}
|
|
341
346
|
end
|
|
342
347
|
end
|
|
343
348
|
|
|
344
349
|
class Dataset < Sequel::Dataset
|
|
345
350
|
include Sequel::DB2::DatasetMethods
|
|
346
351
|
|
|
352
|
+
Database::DatasetClass = self
|
|
353
|
+
|
|
347
354
|
module CallableStatementMethods
|
|
348
355
|
# Extend given dataset with this module so subselects inside subselects in
|
|
349
356
|
# prepared statements work.
|
|
@@ -400,13 +407,14 @@ module Sequel
|
|
|
400
407
|
offset = @opts[:offset]
|
|
401
408
|
columns = []
|
|
402
409
|
convert = convert_smallint_to_bool
|
|
410
|
+
cps = db.conversion_procs
|
|
403
411
|
stmt.num_fields.times do |i|
|
|
404
412
|
k = stmt.field_name i
|
|
405
413
|
key = output_identifier(k)
|
|
406
414
|
type = stmt.field_type(k).downcase.to_sym
|
|
407
415
|
# decide if it is a smallint from precision
|
|
408
416
|
type = :boolean if type ==:int && convert && stmt.field_precision(k) < 8
|
|
409
|
-
columns << [key,
|
|
417
|
+
columns << [key, cps[type]]
|
|
410
418
|
end
|
|
411
419
|
cols = columns.map{|c| c.at(0)}
|
|
412
420
|
cols.delete(row_number_column) if offset
|
|
@@ -13,10 +13,6 @@ module Sequel
|
|
|
13
13
|
::Informix.connect(opts[:database], opts[:user], opts[:password])
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def dataset(opts = nil)
|
|
17
|
-
Sequel::Informix::Dataset.new(self, opts)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
16
|
# Returns number of rows affected
|
|
21
17
|
def execute_dui(sql, opts={})
|
|
22
18
|
synchronize(opts[:server]){|c| log_yield(sql){c.immediate(sql)}}
|
|
@@ -38,6 +34,8 @@ module Sequel
|
|
|
38
34
|
class Dataset < Sequel::Dataset
|
|
39
35
|
include DatasetMethods
|
|
40
36
|
|
|
37
|
+
Database::DatasetClass = self
|
|
38
|
+
|
|
41
39
|
def fetch_rows(sql)
|
|
42
40
|
execute(sql) do |cursor|
|
|
43
41
|
begin
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
|
@@ -32,35 +32,41 @@ module Sequel
|
|
|
32
32
|
DATABASE_SETUP = {:postgresql=>proc do |db|
|
|
33
33
|
Sequel.ts_require 'adapters/jdbc/postgresql'
|
|
34
34
|
db.extend(Sequel::JDBC::Postgres::DatabaseMethods)
|
|
35
|
+
db.dataset_class = Sequel::JDBC::Postgres::Dataset
|
|
35
36
|
JDBC.load_gem('postgres')
|
|
36
37
|
org.postgresql.Driver
|
|
37
38
|
end,
|
|
38
39
|
:mysql=>proc do |db|
|
|
39
40
|
Sequel.ts_require 'adapters/jdbc/mysql'
|
|
40
41
|
db.extend(Sequel::JDBC::MySQL::DatabaseMethods)
|
|
42
|
+
db.dataset_class = Sequel::JDBC::MySQL::Dataset
|
|
41
43
|
JDBC.load_gem('mysql')
|
|
42
44
|
com.mysql.jdbc.Driver
|
|
43
45
|
end,
|
|
44
46
|
:sqlite=>proc do |db|
|
|
45
47
|
Sequel.ts_require 'adapters/jdbc/sqlite'
|
|
46
48
|
db.extend(Sequel::JDBC::SQLite::DatabaseMethods)
|
|
49
|
+
db.dataset_class = Sequel::JDBC::SQLite::Dataset
|
|
47
50
|
JDBC.load_gem('sqlite3')
|
|
48
51
|
org.sqlite.JDBC
|
|
49
52
|
end,
|
|
50
53
|
:oracle=>proc do |db|
|
|
51
54
|
Sequel.ts_require 'adapters/jdbc/oracle'
|
|
52
55
|
db.extend(Sequel::JDBC::Oracle::DatabaseMethods)
|
|
56
|
+
db.dataset_class = Sequel::JDBC::Oracle::Dataset
|
|
53
57
|
Java::oracle.jdbc.driver.OracleDriver
|
|
54
58
|
end,
|
|
55
59
|
:sqlserver=>proc do |db|
|
|
56
60
|
Sequel.ts_require 'adapters/jdbc/sqlserver'
|
|
57
61
|
db.extend(Sequel::JDBC::SQLServer::DatabaseMethods)
|
|
62
|
+
db.dataset_class = Sequel::JDBC::SQLServer::Dataset
|
|
58
63
|
db.send(:set_mssql_unicode_strings)
|
|
59
64
|
com.microsoft.sqlserver.jdbc.SQLServerDriver
|
|
60
65
|
end,
|
|
61
66
|
:jtds=>proc do |db|
|
|
62
67
|
Sequel.ts_require 'adapters/jdbc/jtds'
|
|
63
68
|
db.extend(Sequel::JDBC::JTDS::DatabaseMethods)
|
|
69
|
+
db.dataset_class = Sequel::JDBC::JTDS::Dataset
|
|
64
70
|
db.send(:set_mssql_unicode_strings)
|
|
65
71
|
JDBC.load_gem('jtds')
|
|
66
72
|
Java::net.sourceforge.jtds.jdbc.Driver
|
|
@@ -68,27 +74,46 @@ module Sequel
|
|
|
68
74
|
:h2=>proc do |db|
|
|
69
75
|
Sequel.ts_require 'adapters/jdbc/h2'
|
|
70
76
|
db.extend(Sequel::JDBC::H2::DatabaseMethods)
|
|
77
|
+
db.dataset_class = Sequel::JDBC::H2::Dataset
|
|
71
78
|
JDBC.load_gem('h2')
|
|
72
79
|
org.h2.Driver
|
|
73
80
|
end,
|
|
81
|
+
:hsqldb=>proc do |db|
|
|
82
|
+
Sequel.ts_require 'adapters/jdbc/hsqldb'
|
|
83
|
+
db.extend(Sequel::JDBC::HSQLDB::DatabaseMethods)
|
|
84
|
+
db.dataset_class = Sequel::JDBC::HSQLDB::Dataset
|
|
85
|
+
# Current gem is 1.8.1.3, but Sequel supports 2.2.5
|
|
86
|
+
org.hsqldb.jdbcDriver
|
|
87
|
+
end,
|
|
88
|
+
:derby=>proc do |db|
|
|
89
|
+
Sequel.ts_require 'adapters/jdbc/derby'
|
|
90
|
+
db.extend(Sequel::JDBC::Derby::DatabaseMethods)
|
|
91
|
+
db.dataset_class = Sequel::JDBC::Derby::Dataset
|
|
92
|
+
JDBC.load_gem('derby')
|
|
93
|
+
org.apache.derby.jdbc.EmbeddedDriver
|
|
94
|
+
end,
|
|
74
95
|
:as400=>proc do |db|
|
|
75
96
|
Sequel.ts_require 'adapters/jdbc/as400'
|
|
76
97
|
db.extend(Sequel::JDBC::AS400::DatabaseMethods)
|
|
98
|
+
db.dataset_class = Sequel::JDBC::AS400::Dataset
|
|
77
99
|
com.ibm.as400.access.AS400JDBCDriver
|
|
78
100
|
end,
|
|
79
101
|
:"informix-sqli"=>proc do |db|
|
|
80
102
|
Sequel.ts_require 'adapters/jdbc/informix'
|
|
81
103
|
db.extend(Sequel::JDBC::Informix::DatabaseMethods)
|
|
104
|
+
db.dataset_class = Sequel::JDBC::Informix::Dataset
|
|
82
105
|
com.informix.jdbc.IfxDriver
|
|
83
106
|
end,
|
|
84
107
|
:db2=>proc do |db|
|
|
85
108
|
Sequel.ts_require 'adapters/jdbc/db2'
|
|
86
109
|
db.extend(Sequel::JDBC::DB2::DatabaseMethods)
|
|
110
|
+
db.dataset_class = Sequel::JDBC::DB2::Dataset
|
|
87
111
|
com.ibm.db2.jcc.DB2Driver
|
|
88
112
|
end,
|
|
89
113
|
:firebirdsql=>proc do |db|
|
|
90
114
|
Sequel.ts_require 'adapters/jdbc/firebird'
|
|
91
115
|
db.extend(Sequel::JDBC::Firebird::DatabaseMethods)
|
|
116
|
+
db.dataset_class = Sequel::JDBC::Firebird::Dataset
|
|
92
117
|
org.firebirdsql.jdbc.FBDriver
|
|
93
118
|
end
|
|
94
119
|
}
|
|
@@ -197,11 +222,6 @@ module Sequel
|
|
|
197
222
|
setup_connection(conn)
|
|
198
223
|
end
|
|
199
224
|
|
|
200
|
-
# Return instances of JDBC::Dataset with the given opts.
|
|
201
|
-
def dataset(opts = nil)
|
|
202
|
-
JDBC::Dataset.new(self, opts)
|
|
203
|
-
end
|
|
204
|
-
|
|
205
225
|
# Execute the given SQL. If a block is given, if should be a SELECT
|
|
206
226
|
# statement or something else that returns rows.
|
|
207
227
|
def execute(sql, opts={}, &block)
|
|
@@ -462,8 +482,8 @@ module Sequel
|
|
|
462
482
|
|
|
463
483
|
# Parse the table schema for the given table.
|
|
464
484
|
def schema_parse_table(table, opts={})
|
|
465
|
-
m = output_identifier_meth
|
|
466
|
-
im = input_identifier_meth
|
|
485
|
+
m = output_identifier_meth(opts[:dataset])
|
|
486
|
+
im = input_identifier_meth(opts[:dataset])
|
|
467
487
|
ds = dataset
|
|
468
488
|
schema, table = schema_and_table(table)
|
|
469
489
|
schema ||= opts[:schema]
|
|
@@ -471,11 +491,11 @@ module Sequel
|
|
|
471
491
|
table = im.call(table)
|
|
472
492
|
pks, ts = [], []
|
|
473
493
|
metadata(:getPrimaryKeys, nil, schema, table) do |h|
|
|
474
|
-
next if h
|
|
494
|
+
next if schema_parse_table_skip?(h, schema)
|
|
475
495
|
pks << h[:column_name]
|
|
476
496
|
end
|
|
477
497
|
metadata(:getColumns, nil, schema, table, nil) do |h|
|
|
478
|
-
next if h
|
|
498
|
+
next if schema_parse_table_skip?(h, schema)
|
|
479
499
|
s = {:type=>schema_column_type(h[:type_name]), :db_type=>h[:type_name], :default=>(h[:column_def] == '' ? nil : h[:column_def]), :allow_null=>(h[:nullable] != 0), :primary_key=>pks.include?(h[:column_name]), :column_size=>h[:column_size], :scale=>h[:decimal_digits]}
|
|
480
500
|
if s[:db_type] =~ DECIMAL_TYPE_RE && s[:scale] == 0
|
|
481
501
|
s[:type] = :integer
|
|
@@ -485,6 +505,12 @@ module Sequel
|
|
|
485
505
|
ts
|
|
486
506
|
end
|
|
487
507
|
|
|
508
|
+
# Whether schema_parse_table should skip the given row when
|
|
509
|
+
# parsing the schema.
|
|
510
|
+
def schema_parse_table_skip?(h, schema)
|
|
511
|
+
h[:table_schem] == 'INFORMATION_SCHEMA'
|
|
512
|
+
end
|
|
513
|
+
|
|
488
514
|
# Yield a new statement object, and ensure that it is closed before returning.
|
|
489
515
|
def statement(conn)
|
|
490
516
|
stmt = conn.createStatement
|
|
@@ -505,6 +531,8 @@ module Sequel
|
|
|
505
531
|
|
|
506
532
|
class Dataset < Sequel::Dataset
|
|
507
533
|
include StoredProcedures
|
|
534
|
+
|
|
535
|
+
Database::DatasetClass = self
|
|
508
536
|
|
|
509
537
|
# Use JDBC PreparedStatements instead of emulated ones. Statements
|
|
510
538
|
# created using #prepare are cached at the connection level to allow
|
|
@@ -590,7 +618,7 @@ module Sequel
|
|
|
590
618
|
def convert_type(v)
|
|
591
619
|
case v
|
|
592
620
|
when Java::JavaSQL::Timestamp
|
|
593
|
-
|
|
621
|
+
db.to_application_timestamp(v.to_string)
|
|
594
622
|
when Java::JavaSQL::Time
|
|
595
623
|
Sequel.string_to_time(v.to_string)
|
|
596
624
|
when Java::JavaSQL::Date
|
|
@@ -625,7 +653,12 @@ module Sequel
|
|
|
625
653
|
cols = []
|
|
626
654
|
i = 0
|
|
627
655
|
meta.getColumnCount.times{cols << [output_identifier(meta.getColumnLabel(i+=1)), i]}
|
|
628
|
-
|
|
656
|
+
columns = cols.map{|c| c.at(0)}
|
|
657
|
+
if opts[:offset] && offset_returns_row_number_column?
|
|
658
|
+
rn = row_number_column
|
|
659
|
+
columns.delete(rn)
|
|
660
|
+
end
|
|
661
|
+
@columns = columns
|
|
629
662
|
blk = result_set_object_getter
|
|
630
663
|
# get rows
|
|
631
664
|
while result.next
|
|
@@ -633,8 +666,11 @@ module Sequel
|
|
|
633
666
|
cols.each do |n, i|
|
|
634
667
|
row[n] = blk.call(result, n, i)
|
|
635
668
|
end
|
|
669
|
+
row.delete(rn) if rn
|
|
636
670
|
yield row
|
|
637
671
|
end
|
|
672
|
+
ensure
|
|
673
|
+
result.close
|
|
638
674
|
end
|
|
639
675
|
|
|
640
676
|
# Proc that takes the ResultSet and an integer field number and returns
|