sequel 3.10.0 → 3.11.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 +68 -0
- data/COPYING +1 -1
- data/README.rdoc +87 -27
- data/bin/sequel +2 -4
- data/doc/association_basics.rdoc +1383 -0
- data/doc/dataset_basics.rdoc +106 -0
- data/doc/opening_databases.rdoc +45 -16
- data/doc/querying.rdoc +210 -0
- data/doc/release_notes/3.11.0.txt +254 -0
- data/doc/virtual_rows.rdoc +217 -31
- data/lib/sequel/adapters/ado.rb +28 -12
- data/lib/sequel/adapters/ado/mssql.rb +33 -1
- data/lib/sequel/adapters/amalgalite.rb +13 -8
- data/lib/sequel/adapters/db2.rb +1 -2
- data/lib/sequel/adapters/dbi.rb +7 -4
- data/lib/sequel/adapters/do.rb +14 -15
- data/lib/sequel/adapters/do/postgres.rb +4 -5
- data/lib/sequel/adapters/do/sqlite.rb +9 -0
- data/lib/sequel/adapters/firebird.rb +5 -10
- data/lib/sequel/adapters/informix.rb +2 -4
- data/lib/sequel/adapters/jdbc.rb +111 -49
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +11 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +4 -7
- data/lib/sequel/adapters/jdbc/postgresql.rb +8 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +12 -0
- data/lib/sequel/adapters/mysql.rb +14 -5
- data/lib/sequel/adapters/odbc.rb +2 -4
- data/lib/sequel/adapters/odbc/mssql.rb +2 -4
- data/lib/sequel/adapters/openbase.rb +1 -2
- data/lib/sequel/adapters/oracle.rb +4 -8
- data/lib/sequel/adapters/postgres.rb +4 -11
- data/lib/sequel/adapters/shared/mssql.rb +22 -9
- data/lib/sequel/adapters/shared/mysql.rb +33 -30
- data/lib/sequel/adapters/shared/oracle.rb +0 -5
- data/lib/sequel/adapters/shared/postgres.rb +13 -11
- data/lib/sequel/adapters/shared/sqlite.rb +56 -10
- data/lib/sequel/adapters/sqlite.rb +16 -9
- data/lib/sequel/connection_pool.rb +6 -1
- data/lib/sequel/connection_pool/single.rb +1 -0
- data/lib/sequel/core.rb +6 -1
- data/lib/sequel/database.rb +52 -23
- data/lib/sequel/database/schema_generator.rb +6 -0
- data/lib/sequel/database/schema_methods.rb +5 -5
- data/lib/sequel/database/schema_sql.rb +1 -1
- data/lib/sequel/dataset.rb +4 -190
- data/lib/sequel/dataset/actions.rb +323 -1
- data/lib/sequel/dataset/features.rb +18 -2
- data/lib/sequel/dataset/graph.rb +7 -0
- data/lib/sequel/dataset/misc.rb +119 -0
- data/lib/sequel/dataset/mutation.rb +64 -0
- data/lib/sequel/dataset/prepared_statements.rb +6 -0
- data/lib/sequel/dataset/query.rb +272 -6
- data/lib/sequel/dataset/sql.rb +186 -394
- data/lib/sequel/model.rb +4 -2
- data/lib/sequel/model/associations.rb +31 -14
- data/lib/sequel/model/base.rb +32 -13
- data/lib/sequel/model/exceptions.rb +8 -4
- data/lib/sequel/model/plugins.rb +3 -13
- data/lib/sequel/plugins/active_model.rb +26 -7
- data/lib/sequel/plugins/instance_filters.rb +98 -0
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/optimistic_locking.rb +25 -9
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +26 -0
- data/spec/adapters/mysql_spec.rb +33 -4
- data/spec/adapters/postgres_spec.rb +24 -1
- data/spec/adapters/spec_helper.rb +6 -0
- data/spec/adapters/sqlite_spec.rb +28 -0
- data/spec/core/connection_pool_spec.rb +17 -5
- data/spec/core/database_spec.rb +101 -1
- data/spec/core/dataset_spec.rb +42 -4
- data/spec/core/schema_spec.rb +13 -0
- data/spec/extensions/active_model_spec.rb +34 -11
- data/spec/extensions/caching_spec.rb +2 -0
- data/spec/extensions/instance_filters_spec.rb +55 -0
- data/spec/extensions/spec_helper.rb +2 -0
- data/spec/integration/dataset_test.rb +12 -1
- data/spec/integration/model_test.rb +12 -0
- data/spec/integration/plugin_test.rb +61 -1
- data/spec/integration/schema_test.rb +14 -3
- data/spec/model/base_spec.rb +27 -0
- data/spec/model/plugins_spec.rb +0 -22
- data/spec/model/record_spec.rb +32 -1
- data/spec/model/spec_helper.rb +2 -0
- metadata +14 -3
- data/lib/sequel/dataset/convenience.rb +0 -326
data/lib/sequel/adapters/dbi.rb
CHANGED
@@ -26,6 +26,11 @@ module Sequel
|
|
26
26
|
when 'mssql'
|
27
27
|
Sequel.ts_require 'adapters/shared/mssql'
|
28
28
|
extend Sequel::MSSQL::DatabaseMethods
|
29
|
+
def self.dataset(*args)
|
30
|
+
ds = super
|
31
|
+
ds.extend Sequel::MSSQL::DatasetMethods
|
32
|
+
ds
|
33
|
+
end
|
29
34
|
end
|
30
35
|
end
|
31
36
|
|
@@ -63,17 +68,15 @@ module Sequel
|
|
63
68
|
end
|
64
69
|
|
65
70
|
def execute(sql, opts={})
|
66
|
-
log_info(sql)
|
67
71
|
synchronize(opts[:server]) do |conn|
|
68
|
-
r = conn.execute(sql)
|
72
|
+
r = log_yield(sql){conn.execute(sql)}
|
69
73
|
yield(r) if block_given?
|
70
74
|
r
|
71
75
|
end
|
72
76
|
end
|
73
77
|
|
74
78
|
def do(sql, opts={})
|
75
|
-
|
76
|
-
synchronize(opts[:server]){|conn| conn.do(sql)}
|
79
|
+
synchronize(opts[:server]){|conn| log_yield(sql){conn.do(sql)}}
|
77
80
|
end
|
78
81
|
alias_method :execute_dui, :do
|
79
82
|
|
data/lib/sequel/adapters/do.rb
CHANGED
@@ -66,11 +66,10 @@ module Sequel
|
|
66
66
|
# Otherwise, the return value is the insert id if opts[:type] is :insert,
|
67
67
|
# or the number of affected rows, otherwise.
|
68
68
|
def execute(sql, opts={})
|
69
|
-
log_info(sql)
|
70
69
|
synchronize(opts[:server]) do |conn|
|
71
70
|
begin
|
72
71
|
command = conn.create_command(sql)
|
73
|
-
res = block_given? ? command.execute_reader : command.execute_non_query
|
72
|
+
res = log_yield(sql){block_given? ? command.execute_reader : command.execute_non_query}
|
74
73
|
rescue ::DataObjects::Error => e
|
75
74
|
raise_error(e)
|
76
75
|
end
|
@@ -121,21 +120,23 @@ module Sequel
|
|
121
120
|
# substitute our own.
|
122
121
|
def begin_transaction(conn)
|
123
122
|
return super if supports_savepoints?
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
123
|
+
log_yield(TRANSACTION_BEGIN) do
|
124
|
+
t = ::DataObjects::Transaction.create_for_uri(uri)
|
125
|
+
t.instance_variable_get(:@connection).close
|
126
|
+
t.instance_variable_set(:@connection, conn)
|
127
|
+
t.begin
|
128
|
+
t
|
129
|
+
end
|
130
130
|
end
|
131
131
|
|
132
132
|
# DataObjects requires transactions be prepared before being
|
133
133
|
# committed, so we do that.
|
134
134
|
def commit_transaction(t)
|
135
135
|
return super if supports_savepoints?
|
136
|
-
|
137
|
-
|
138
|
-
|
136
|
+
log_yield(TRANSACTION_ROLLBACK) do
|
137
|
+
t.prepare
|
138
|
+
t.commit
|
139
|
+
end
|
139
140
|
end
|
140
141
|
|
141
142
|
# Method to call on a statement object to execute SQL that does
|
@@ -151,15 +152,13 @@ module Sequel
|
|
151
152
|
|
152
153
|
# Execute SQL on the connection by creating a command first
|
153
154
|
def log_connection_execute(conn, sql)
|
154
|
-
|
155
|
-
conn.create_command(sql).execute_non_query
|
155
|
+
log_yield(sql){conn.create_command(sql).execute_non_query}
|
156
156
|
end
|
157
157
|
|
158
158
|
# We use the transactions rollback method to rollback.
|
159
159
|
def rollback_transaction(t)
|
160
160
|
return super if supports_savepoints?
|
161
|
-
|
162
|
-
t.rollback
|
161
|
+
log_yield(TRANSACTION_COMMIT){t.rollback}
|
163
162
|
end
|
164
163
|
|
165
164
|
# Allow extending the given connection when it is first created.
|
@@ -19,13 +19,12 @@ module Sequel
|
|
19
19
|
begin
|
20
20
|
if block_given?
|
21
21
|
begin
|
22
|
-
reader = command.execute_reader
|
23
|
-
yield(reader)
|
22
|
+
yield(reader = @db.log_yield(sql){command.execute_reader})
|
24
23
|
ensure
|
25
24
|
reader.close if reader
|
26
25
|
end
|
27
26
|
else
|
28
|
-
command.execute_non_query
|
27
|
+
@db.log_yield(sql){command.execute_non_query}
|
29
28
|
end
|
30
29
|
rescue ::DataObjects::Error => e
|
31
30
|
raise_error(e)
|
@@ -64,9 +63,9 @@ module Sequel
|
|
64
63
|
# Run the INSERT sql on the database and return the primary key
|
65
64
|
# for the record.
|
66
65
|
def execute_insert(sql, opts={})
|
67
|
-
log_info(sql)
|
68
66
|
synchronize(opts[:server]) do |conn|
|
69
|
-
conn.create_command(sql)
|
67
|
+
com = conn.create_command(sql)
|
68
|
+
log_yield(sql){com.execute_non_query}
|
70
69
|
insert_result(conn, opts[:table], opts[:values])
|
71
70
|
end
|
72
71
|
end
|
@@ -20,6 +20,15 @@ module Sequel
|
|
20
20
|
o = super
|
21
21
|
uri == 'sqlite3::memory:' ? o.merge(:max_connections=>1) : o
|
22
22
|
end
|
23
|
+
|
24
|
+
# Execute the connection pragmas on the connection
|
25
|
+
def setup_connection(conn)
|
26
|
+
connection_pragmas.each do |s|
|
27
|
+
com = conn.create_command(s)
|
28
|
+
log_yield(s){com.execute_non_query}
|
29
|
+
end
|
30
|
+
super
|
31
|
+
end
|
23
32
|
end
|
24
33
|
|
25
34
|
# Dataset class for SQLite datasets accessed via DataObjects.
|
@@ -43,15 +43,13 @@ module Sequel
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def execute(sql, opts={})
|
46
|
-
log_info(sql)
|
47
46
|
begin
|
48
47
|
synchronize(opts[:server]) do |conn|
|
49
|
-
r = conn.execute(sql)
|
48
|
+
r = log_yield(sql){conn.execute(sql)}
|
50
49
|
yield(r) if block_given?
|
51
50
|
r
|
52
51
|
end
|
53
52
|
rescue => e
|
54
|
-
log_info(e.message)
|
55
53
|
raise_error(e, :classes=>[Fb::Error])
|
56
54
|
end
|
57
55
|
end
|
@@ -105,14 +103,12 @@ module Sequel
|
|
105
103
|
end
|
106
104
|
|
107
105
|
def begin_transaction(conn)
|
108
|
-
|
109
|
-
conn.transaction
|
106
|
+
log_yield(TRANSACTION_BEGIN){conn.transaction}
|
110
107
|
conn
|
111
108
|
end
|
112
109
|
|
113
110
|
def commit_transaction(conn)
|
114
|
-
|
115
|
-
conn.commit
|
111
|
+
log_yield(TRANSACTION_COMMIT){conn.commit}
|
116
112
|
end
|
117
113
|
|
118
114
|
def create_sequence_sql(name, opts={})
|
@@ -160,7 +156,7 @@ module Sequel
|
|
160
156
|
events = opts[:events] ? Array(opts[:events]) : [:insert, :update, :delete]
|
161
157
|
whence = opts[:after] ? 'AFTER' : 'BEFORE'
|
162
158
|
inactive = opts[:inactive] ? 'INACTIVE' : 'ACTIVE'
|
163
|
-
position = opts
|
159
|
+
position = opts.fetch(:position, 0)
|
164
160
|
sql = <<-end_sql
|
165
161
|
CREATE TRIGGER #{quote_identifier(name)} for #{quote_identifier(table)}
|
166
162
|
#{inactive} #{whence} #{events.map{|e| e.to_s.upcase}.join(' OR ')} position #{position}
|
@@ -187,8 +183,7 @@ module Sequel
|
|
187
183
|
end
|
188
184
|
|
189
185
|
def rollback_transaction(conn)
|
190
|
-
|
191
|
-
conn.rollback
|
186
|
+
log_yield(TRANSACTION_ROLLBACK){conn.rollback}
|
192
187
|
end
|
193
188
|
|
194
189
|
def type_literal_generic_string(column)
|
@@ -18,14 +18,12 @@ module Sequel
|
|
18
18
|
|
19
19
|
# Returns number of rows affected
|
20
20
|
def execute_dui(sql, opts={})
|
21
|
-
|
22
|
-
synchronize(opts[:server]){|c| c.immediate(sql)}
|
21
|
+
synchronize(opts[:server]){|c| log_yield(sql){c.immediate(sql)}}
|
23
22
|
end
|
24
23
|
alias_method :do, :execute_dui
|
25
24
|
|
26
25
|
def execute(sql, opts={})
|
27
|
-
|
28
|
-
synchronize(opts[:server]){|c| yield c.cursor(sql)}
|
26
|
+
synchronize(opts[:server]){|c| yield log_yield(sql){c.cursor(sql)}}
|
29
27
|
end
|
30
28
|
alias_method :query, :execute
|
31
29
|
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -3,24 +3,6 @@ Sequel.require 'adapters/utils/stored_procedures'
|
|
3
3
|
|
4
4
|
module Sequel
|
5
5
|
# Houses Sequel's JDBC support when running on JRuby.
|
6
|
-
# Support for individual database types is done using sub adapters.
|
7
|
-
# PostgreSQL, MySQL, SQLite, Oracle, and MSSQL all have relatively good support,
|
8
|
-
# close the the level supported by the native adapter.
|
9
|
-
# PostgreSQL, MySQL, SQLite can load necessary support using
|
10
|
-
# the jdbc-* gem, if it is installed, though they will work if you
|
11
|
-
# have the correct .jar in your CLASSPATH. Oracle and MSSQL should
|
12
|
-
# load the necessary support if you have the .jar in your CLASSPATH.
|
13
|
-
# For all other databases, the Java class should be loaded manually
|
14
|
-
# before calling Sequel.connect.
|
15
|
-
#
|
16
|
-
# Note that when using a JDBC adapter, the best way to use Sequel
|
17
|
-
# is via Sequel.connect, NOT Sequel.jdbc. Use the JDBC connection
|
18
|
-
# string when connecting, which will be in a different format than
|
19
|
-
# the native connection string. The connection string should start
|
20
|
-
# with 'jdbc:'. For PostgreSQL, use 'jdbc:postgresql:', and for
|
21
|
-
# SQLite you do not need 2 preceding slashes for the database name
|
22
|
-
# (use no preceding slashes for a relative path, and one preceding
|
23
|
-
# slash for an absolute path).
|
24
6
|
module JDBC
|
25
7
|
# Make it accesing the java.lang hierarchy more ruby friendly.
|
26
8
|
module JavaLang
|
@@ -31,6 +13,19 @@ module Sequel
|
|
31
13
|
module JavaSQL
|
32
14
|
include_package 'java.sql'
|
33
15
|
end
|
16
|
+
|
17
|
+
# Make it accesing the javax.naming hierarchy more ruby friendly.
|
18
|
+
module JavaxNaming
|
19
|
+
include_package 'javax.naming'
|
20
|
+
end
|
21
|
+
|
22
|
+
# Used to identify a jndi connection and to extract the jndi
|
23
|
+
# resource name.
|
24
|
+
JNDI_URI_REGEXP = /\Ajdbc:jndi:(.+)/
|
25
|
+
|
26
|
+
# The types to check for 0 scale to transform :decimal types
|
27
|
+
# to :integer.
|
28
|
+
DECIMAL_TYPE_RE = /number|numeric|decimal/io
|
34
29
|
|
35
30
|
# Contains procs keyed on sub adapter type that extend the
|
36
31
|
# given database object so it supports the correct database type.
|
@@ -62,6 +57,12 @@ module Sequel
|
|
62
57
|
db.extend(Sequel::JDBC::MSSQL::DatabaseMethods)
|
63
58
|
com.microsoft.sqlserver.jdbc.SQLServerDriver
|
64
59
|
end,
|
60
|
+
:jtds=>proc do |db|
|
61
|
+
Sequel.ts_require 'adapters/jdbc/mssql'
|
62
|
+
db.extend(Sequel::JDBC::MSSQL::DatabaseMethods)
|
63
|
+
JDBC.load_gem('jtds')
|
64
|
+
Java::net.sourceforge.jtds.jdbc.Driver
|
65
|
+
end,
|
65
66
|
:h2=>proc do |db|
|
66
67
|
Sequel.ts_require 'adapters/jdbc/h2'
|
67
68
|
db.extend(Sequel::JDBC::H2::DatabaseMethods)
|
@@ -93,6 +94,9 @@ module Sequel
|
|
93
94
|
# The type of database we are connecting to
|
94
95
|
attr_reader :database_type
|
95
96
|
|
97
|
+
# The Java database driver we are using
|
98
|
+
attr_reader :driver
|
99
|
+
|
96
100
|
# Whether to convert some Java types to ruby types when retrieving rows.
|
97
101
|
# True by default, can be set to false to roughly double performance when
|
98
102
|
# fetching rows.
|
@@ -104,11 +108,14 @@ module Sequel
|
|
104
108
|
# uri, since JDBC requires one.
|
105
109
|
def initialize(opts)
|
106
110
|
super
|
107
|
-
@convert_types = @opts.
|
111
|
+
@convert_types = typecast_value_boolean(@opts.fetch(:convert_types, true))
|
108
112
|
raise(Error, "No connection string specified") unless uri
|
109
|
-
|
110
|
-
|
111
|
-
|
113
|
+
|
114
|
+
resolved_uri = jndi? ? get_uri_from_jndi : uri
|
115
|
+
|
116
|
+
if match = /\Ajdbc:([^:]+)/.match(resolved_uri) and prok = DATABASE_SETUP[match[1].to_sym]
|
117
|
+
@driver = prok.call(self)
|
118
|
+
end
|
112
119
|
end
|
113
120
|
|
114
121
|
# Execute the given stored procedure with the give name. If a block is
|
@@ -124,14 +131,14 @@ module Sequel
|
|
124
131
|
|
125
132
|
begin
|
126
133
|
if block_given?
|
127
|
-
yield cps.executeQuery
|
134
|
+
yield log_yield(sql){cps.executeQuery}
|
128
135
|
else
|
129
136
|
case opts[:type]
|
130
137
|
when :insert
|
131
|
-
cps.executeUpdate
|
138
|
+
log_yield(sql){cps.executeUpdate}
|
132
139
|
last_insert_id(conn, opts)
|
133
140
|
else
|
134
|
-
cps.executeUpdate
|
141
|
+
log_yield(sql){cps.executeUpdate}
|
135
142
|
end
|
136
143
|
end
|
137
144
|
rescue NativeException, JavaSQL::SQLException => e
|
@@ -141,12 +148,29 @@ module Sequel
|
|
141
148
|
end
|
142
149
|
end
|
143
150
|
end
|
144
|
-
|
151
|
+
|
145
152
|
# Connect to the database using JavaSQL::DriverManager.getConnection.
|
146
153
|
def connect(server)
|
147
|
-
|
148
|
-
|
149
|
-
|
154
|
+
opts = server_opts(server)
|
155
|
+
conn = if jndi?
|
156
|
+
get_connection_from_jndi
|
157
|
+
else
|
158
|
+
args = [uri(opts)]
|
159
|
+
args.concat([opts[:user], opts[:password]]) if opts[:user] && opts[:password]
|
160
|
+
begin
|
161
|
+
JavaSQL::DriverManager.getConnection(*args)
|
162
|
+
rescue
|
163
|
+
# If the DriverManager can't get the connection - use the connect
|
164
|
+
# method of the driver. (This happens under Tomcat for instance)
|
165
|
+
props = java.util.Properties.new
|
166
|
+
if opts && opts[:user] && opts[:password]
|
167
|
+
props.setProperty("user", opts[:user])
|
168
|
+
props.setProperty("password", opts[:password])
|
169
|
+
end
|
170
|
+
driver.new.connect(args[0], props)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
setup_connection(conn)
|
150
174
|
end
|
151
175
|
|
152
176
|
# Return instances of JDBC::Dataset with the given opts.
|
@@ -159,21 +183,26 @@ module Sequel
|
|
159
183
|
def execute(sql, opts={}, &block)
|
160
184
|
return call_sproc(sql, opts, &block) if opts[:sproc]
|
161
185
|
return execute_prepared_statement(sql, opts, &block) if [Symbol, Dataset].any?{|c| sql.is_a?(c)}
|
162
|
-
log_info(sql)
|
163
186
|
synchronize(opts[:server]) do |conn|
|
164
187
|
stmt = conn.createStatement
|
165
188
|
begin
|
166
189
|
if block_given?
|
167
|
-
yield stmt.executeQuery(sql)
|
190
|
+
yield log_yield(sql){stmt.executeQuery(sql)}
|
168
191
|
else
|
169
192
|
case opts[:type]
|
170
193
|
when :ddl
|
171
|
-
stmt.execute(sql)
|
194
|
+
log_yield(sql){stmt.execute(sql)}
|
172
195
|
when :insert
|
173
|
-
|
196
|
+
log_yield(sql) do
|
197
|
+
if requires_return_generated_keys?
|
198
|
+
stmt.executeUpdate(sql, JavaSQL::Statement.RETURN_GENERATED_KEYS)
|
199
|
+
else
|
200
|
+
stmt.executeUpdate(sql)
|
201
|
+
end
|
202
|
+
end
|
174
203
|
last_insert_id(conn, opts.merge(:stmt=>stmt))
|
175
204
|
else
|
176
|
-
stmt.executeUpdate(sql)
|
205
|
+
log_yield(sql){stmt.executeUpdate(sql)}
|
177
206
|
end
|
178
207
|
end
|
179
208
|
rescue NativeException, JavaSQL::SQLException => e
|
@@ -235,9 +264,14 @@ module Sequel
|
|
235
264
|
ur = opts[:uri] || opts[:url] || opts[:database]
|
236
265
|
ur =~ /^\Ajdbc:/ ? ur : "jdbc:#{ur}"
|
237
266
|
end
|
267
|
+
|
268
|
+
# Whether or not JNDI is being used for this connection.
|
269
|
+
def jndi?
|
270
|
+
!!(uri =~ JNDI_URI_REGEXP)
|
271
|
+
end
|
238
272
|
|
239
273
|
private
|
240
|
-
|
274
|
+
|
241
275
|
# JDBC uses a statement object to execute SQL on the database
|
242
276
|
def begin_transaction(conn)
|
243
277
|
conn = conn.createStatement unless supports_savepoints?
|
@@ -269,29 +303,25 @@ module Sequel
|
|
269
303
|
if name and cps = conn.prepared_statements[name] and cps[0] == sql
|
270
304
|
cps = cps[1]
|
271
305
|
else
|
272
|
-
if cps
|
273
|
-
|
274
|
-
cps[1].close
|
275
|
-
end
|
276
|
-
log_info("Preparing#{" #{name}:" if name} #{sql}")
|
277
|
-
cps = conn.prepareStatement(sql)
|
306
|
+
log_yield("Closing #{name}"){cps[1].close} if cps
|
307
|
+
cps = log_yield("Preparing#{" #{name}:" if name} #{sql}"){conn.prepareStatement(sql)}
|
278
308
|
conn.prepared_statements[name] = [sql, cps] if name
|
279
309
|
end
|
280
310
|
i = 0
|
281
311
|
args.each{|arg| set_ps_arg(cps, arg, i+=1)}
|
282
|
-
|
312
|
+
msg = "Executing#{" #{name}" if name}"
|
283
313
|
begin
|
284
314
|
if block_given?
|
285
|
-
yield cps.executeQuery
|
315
|
+
yield log_yield(msg, args){cps.executeQuery}
|
286
316
|
else
|
287
317
|
case opts[:type]
|
288
318
|
when :ddl
|
289
|
-
cps.execute
|
319
|
+
log_yield(msg, args){cps.execute}
|
290
320
|
when :insert
|
291
|
-
cps.executeUpdate
|
321
|
+
log_yield(msg, args){cps.executeUpdate}
|
292
322
|
last_insert_id(conn, opts.merge(:prepared=>true))
|
293
323
|
else
|
294
|
-
cps.executeUpdate
|
324
|
+
log_yield(msg, args){cps.executeUpdate}
|
295
325
|
end
|
296
326
|
end
|
297
327
|
rescue NativeException, JavaSQL::SQLException => e
|
@@ -301,7 +331,21 @@ module Sequel
|
|
301
331
|
end
|
302
332
|
end
|
303
333
|
end
|
334
|
+
|
335
|
+
# Gets the JDBC connection uri from the JNDI resource.
|
336
|
+
def get_uri_from_jndi
|
337
|
+
conn = get_connection_from_jndi
|
338
|
+
conn.meta_data.url
|
339
|
+
ensure
|
340
|
+
conn.close if conn
|
341
|
+
end
|
304
342
|
|
343
|
+
# Gets the connection from JNDI.
|
344
|
+
def get_connection_from_jndi
|
345
|
+
jndi_name = JNDI_URI_REGEXP.match(uri)[1]
|
346
|
+
JavaxNaming::InitialContext.new.lookup(jndi_name).connection
|
347
|
+
end
|
348
|
+
|
305
349
|
# Support fractional seconds for Time objects used in bound variables
|
306
350
|
def java_sql_timestamp(time)
|
307
351
|
millis = time.to_i * 1000
|
@@ -319,7 +363,14 @@ module Sequel
|
|
319
363
|
|
320
364
|
# Yield the metadata for this database
|
321
365
|
def metadata(*args, &block)
|
322
|
-
synchronize
|
366
|
+
synchronize do |c|
|
367
|
+
result = c.getMetaData.send(*args)
|
368
|
+
begin
|
369
|
+
metadata_dataset.send(:process_result_set, result, &block)
|
370
|
+
ensure
|
371
|
+
result.close
|
372
|
+
end
|
373
|
+
end
|
323
374
|
end
|
324
375
|
|
325
376
|
# Treat SQLExceptions with a "Connection Error" SQLState as disconnects
|
@@ -388,7 +439,11 @@ module Sequel
|
|
388
439
|
pks << h[:column_name]
|
389
440
|
end
|
390
441
|
metadata(:getColumns, nil, schema, table, nil) do |h|
|
391
|
-
|
442
|
+
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]}
|
443
|
+
if s[:db_type] =~ DECIMAL_TYPE_RE && s[:scale] == 0
|
444
|
+
s[:type] = :integer
|
445
|
+
end
|
446
|
+
ts << [m.call(h[:column_name]), s]
|
392
447
|
end
|
393
448
|
ts
|
394
449
|
end
|
@@ -397,6 +452,13 @@ module Sequel
|
|
397
452
|
def transaction_statement_object(conn)
|
398
453
|
conn.createStatement
|
399
454
|
end
|
455
|
+
|
456
|
+
# This method determines whether or not to add
|
457
|
+
# Statement.RETURN_GENERATED_KEYS as an argument when inserting rows.
|
458
|
+
# Sub-adapters that require this should override this method.
|
459
|
+
def requires_return_generated_keys?
|
460
|
+
false
|
461
|
+
end
|
400
462
|
end
|
401
463
|
|
402
464
|
class Dataset < Sequel::Dataset
|
@@ -498,7 +560,7 @@ module Sequel
|
|
498
560
|
when Java::byte[]
|
499
561
|
Sequel::SQL::Blob.new(String.from_java_bytes(v))
|
500
562
|
when Java::JavaSQL::Blob
|
501
|
-
convert_type(v.getBytes(
|
563
|
+
convert_type(v.getBytes(1, v.length))
|
502
564
|
else
|
503
565
|
v
|
504
566
|
end
|