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