activerecord-jdbc-adapter 52.1-java → 52.2-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +34 -15
- data/Gemfile +1 -2
- data/README.md +10 -3
- data/lib/arjdbc/abstract/core.rb +12 -2
- data/lib/arjdbc/abstract/database_statements.rb +1 -1
- data/lib/arjdbc/abstract/statement_cache.rb +4 -4
- data/lib/arjdbc/db2/adapter.rb +68 -60
- data/lib/arjdbc/db2/as400.rb +12 -0
- data/lib/arjdbc/db2/column.rb +3 -0
- data/lib/arjdbc/db2/connection_methods.rb +4 -0
- data/lib/arjdbc/jdbc.rb +3 -0
- data/lib/arjdbc/jdbc/adapter.rb +0 -6
- data/lib/arjdbc/jdbc/column.rb +4 -2
- data/lib/arjdbc/mysql/adapter.rb +8 -0
- data/lib/arjdbc/postgresql/adapter.rb +5 -72
- data/lib/arjdbc/postgresql/oid_types.rb +82 -14
- data/lib/arjdbc/version.rb +1 -1
- data/rakelib/rails.rake +4 -3
- data/src/java/arjdbc/ArJdbcModule.java +5 -15
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +2 -2
- data/src/java/arjdbc/jdbc/ConnectionFactory.java +0 -87
- data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +0 -1
- data/src/java/arjdbc/jdbc/RubyConnectionFactory.java +61 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +46 -18
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +2 -2
- data/src/java/arjdbc/postgresql/PgDateTimeUtils.java +52 -0
- data/src/java/arjdbc/postgresql/PostgreSQLResult.java +90 -17
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +68 -49
- data/src/java/arjdbc/util/DateTimeUtils.java +119 -0
- data/src/java/arjdbc/util/PG.java +8 -0
- data/src/java/arjdbc/util/QuotingUtils.java +6 -7
- metadata +6 -4
- data/src/java/arjdbc/postgresql/PgResultSetMetaDataWrapper.java +0 -23
data/lib/arjdbc/mysql/adapter.rb
CHANGED
@@ -32,7 +32,15 @@ module ActiveRecord
|
|
32
32
|
include ArJdbc::MySQL
|
33
33
|
|
34
34
|
def initialize(connection, logger, connection_parameters, config)
|
35
|
+
# workaround to skip version check on JNDI to be lazy, dummy version is high enough for Rails 5.0 - 6.0
|
36
|
+
is_jndi = ::ActiveRecord::ConnectionAdapters::JdbcConnection.jndi_config?(config)
|
37
|
+
@version = '8.1.5' if is_jndi
|
38
|
+
|
35
39
|
super
|
40
|
+
|
41
|
+
# set to nil to have it lazy-load the real value when required
|
42
|
+
@version = nil if is_jndi
|
43
|
+
|
36
44
|
@prepared_statements = false unless config.key?(:prepared_statements)
|
37
45
|
# configure_connection taken care of at ArJdbc::Abstract::Core
|
38
46
|
end
|
@@ -531,77 +531,6 @@ module ArJdbc
|
|
531
531
|
execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
|
532
532
|
end
|
533
533
|
|
534
|
-
# Returns an array of indexes for the given table.
|
535
|
-
def indexes(table_name)
|
536
|
-
|
537
|
-
# FIXME: AR version => table = Utils.extract_schema_qualified_name(table_name.to_s)
|
538
|
-
schema, table = extract_schema_and_table(table_name.to_s)
|
539
|
-
|
540
|
-
result = query(<<-SQL, 'SCHEMA')
|
541
|
-
SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid,
|
542
|
-
pg_catalog.obj_description(i.oid, 'pg_class') AS comment
|
543
|
-
FROM pg_class t
|
544
|
-
INNER JOIN pg_index d ON t.oid = d.indrelid
|
545
|
-
INNER JOIN pg_class i ON d.indexrelid = i.oid
|
546
|
-
LEFT JOIN pg_namespace n ON n.oid = i.relnamespace
|
547
|
-
WHERE i.relkind = 'i'
|
548
|
-
AND d.indisprimary = 'f'
|
549
|
-
AND t.relname = '#{table}'
|
550
|
-
AND n.nspname = #{schema ? "'#{schema}'" : 'ANY (current_schemas(false))'}
|
551
|
-
ORDER BY i.relname
|
552
|
-
SQL
|
553
|
-
|
554
|
-
result.map do |row|
|
555
|
-
index_name = row[0]
|
556
|
-
# FIXME: These values [1,2] are returned in a different format than AR expects, maybe we could update it on the Java side to be more accurate
|
557
|
-
unique = row[1].is_a?(String) ? row[1] == 't' : row[1] # JDBC gets us a boolean
|
558
|
-
indkey = row[2].is_a?(Java::OrgPostgresqlUtil::PGobject) ? row[2].value : row[2]
|
559
|
-
indkey = indkey.split(" ").map(&:to_i)
|
560
|
-
inddef = row[3]
|
561
|
-
oid = row[4]
|
562
|
-
comment = row[5]
|
563
|
-
|
564
|
-
using, expressions, where = inddef.scan(/ USING (\w+?) \((.+?)\)(?: WHERE (.+))?\z/m).flatten
|
565
|
-
|
566
|
-
orders = {}
|
567
|
-
opclasses = {}
|
568
|
-
|
569
|
-
if indkey.include?(0)
|
570
|
-
columns = expressions
|
571
|
-
else
|
572
|
-
columns = Hash[query(<<-SQL.strip_heredoc, "SCHEMA")].values_at(*indkey).compact
|
573
|
-
SELECT a.attnum, a.attname
|
574
|
-
FROM pg_attribute a
|
575
|
-
WHERE a.attrelid = #{oid}
|
576
|
-
AND a.attnum IN (#{indkey.join(",")})
|
577
|
-
SQL
|
578
|
-
|
579
|
-
# add info on sort order (only desc order is explicitly specified, asc is the default)
|
580
|
-
# and non-default opclasses
|
581
|
-
expressions.scan(/(?<column>\w+)\s?(?<opclass>\w+_ops)?\s?(?<desc>DESC)?\s?(?<nulls>NULLS (?:FIRST|LAST))?/).each do |column, opclass, desc, nulls|
|
582
|
-
opclasses[column] = opclass.to_sym if opclass
|
583
|
-
if nulls
|
584
|
-
orders[column] = [desc, nulls].compact.join(' ')
|
585
|
-
elsif desc
|
586
|
-
orders[column] = :desc
|
587
|
-
end
|
588
|
-
end
|
589
|
-
end
|
590
|
-
|
591
|
-
IndexDefinition.new(
|
592
|
-
table_name,
|
593
|
-
index_name,
|
594
|
-
unique,
|
595
|
-
columns,
|
596
|
-
orders: orders,
|
597
|
-
opclasses: opclasses,
|
598
|
-
where: where,
|
599
|
-
using: using.to_sym,
|
600
|
-
comment: comment.presence
|
601
|
-
)
|
602
|
-
end
|
603
|
-
end
|
604
|
-
|
605
534
|
# @private
|
606
535
|
def column_name_for_operation(operation, node)
|
607
536
|
case operation
|
@@ -690,6 +619,10 @@ module ArJdbc
|
|
690
619
|
@local_tz ||= execute('SHOW TIME ZONE', 'SCHEMA').first["TimeZone"]
|
691
620
|
end
|
692
621
|
|
622
|
+
def bind_params_length
|
623
|
+
32767
|
624
|
+
end
|
625
|
+
|
693
626
|
end
|
694
627
|
end
|
695
628
|
|
@@ -766,7 +699,7 @@ module ActiveRecord::ConnectionAdapters
|
|
766
699
|
|
767
700
|
# Prepared statements aren't schema aware so we need to make sure we
|
768
701
|
# store different PreparedStatement objects for different schemas
|
769
|
-
def
|
702
|
+
def sql_key(sql)
|
770
703
|
"#{schema_search_path}-#{sql}"
|
771
704
|
end
|
772
705
|
|
@@ -9,6 +9,61 @@ module ArJdbc
|
|
9
9
|
# @private
|
10
10
|
OID = ::ActiveRecord::ConnectionAdapters::PostgreSQL::OID
|
11
11
|
|
12
|
+
# this version makes sure to register the types by name as well
|
13
|
+
# we still need to version with OID since it's used from SchemaStatements as well
|
14
|
+
class ArjdbcTypeMapInitializer < OID::TypeMapInitializer
|
15
|
+
private
|
16
|
+
|
17
|
+
def name_with_ns(row)
|
18
|
+
if row['in_ns']
|
19
|
+
row['typname']
|
20
|
+
else
|
21
|
+
%Q("#{row['nspname']}"."#{row['typname']}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def register_enum_type(row)
|
26
|
+
super
|
27
|
+
register name_with_ns(row), OID::Enum.new
|
28
|
+
end
|
29
|
+
|
30
|
+
def register_array_type(row)
|
31
|
+
super
|
32
|
+
register_with_subtype(name_with_ns(row), row['typelem'].to_i) do |subtype|
|
33
|
+
OID::Array.new(subtype, row['typdelim'])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def register_range_type(row)
|
38
|
+
super
|
39
|
+
name = name_with_ns(row)
|
40
|
+
register_with_subtype(name, row['rngsubtype'].to_i) do |subtype|
|
41
|
+
OID::Range.new(subtype, name.to_sym)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def register_domain_type(row)
|
46
|
+
if base_type = @store.lookup(row['typbasetype'].to_i)
|
47
|
+
register row['oid'], base_type
|
48
|
+
register name_with_ns(row), base_type
|
49
|
+
else
|
50
|
+
warn "unknown base type (OID: #{row['typbasetype']}) for domain #{row['typname']}."
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def register_composite_type(row)
|
55
|
+
if subtype = @store.lookup(row['typelem'].to_i)
|
56
|
+
register row['oid'], OID::Vector.new(row['typdelim'], subtype)
|
57
|
+
register name_with_ns(row), OID::Vector.new(row['typdelim'], subtype)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def assert_valid_registration(oid, oid_type)
|
62
|
+
ret = super
|
63
|
+
ret == 0 ? oid : ret
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
12
67
|
# @private
|
13
68
|
module OIDTypes
|
14
69
|
|
@@ -33,15 +88,9 @@ module ArJdbc
|
|
33
88
|
@extensions ||= super
|
34
89
|
end
|
35
90
|
|
36
|
-
# @override
|
37
|
-
def lookup_cast_type(sql_type)
|
38
|
-
oid = execute("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA")
|
39
|
-
super oid.first['oid'].to_i
|
40
|
-
end
|
41
|
-
|
42
91
|
def get_oid_type(oid, fmod, column_name, sql_type = '') # :nodoc:
|
43
92
|
if !type_map.key?(oid)
|
44
|
-
load_additional_types(
|
93
|
+
load_additional_types(type_map, oid)
|
45
94
|
end
|
46
95
|
|
47
96
|
type_map.fetch(oid, fmod, sql_type) {
|
@@ -132,27 +181,46 @@ module ArJdbc
|
|
132
181
|
end
|
133
182
|
end
|
134
183
|
|
135
|
-
load_additional_types
|
184
|
+
load_additional_types(m)
|
185
|
+
|
186
|
+
# pgjdbc returns these if the column is auto-incrmenting
|
187
|
+
m.alias_type 'serial', 'int4'
|
188
|
+
m.alias_type 'bigserial', 'int8'
|
136
189
|
end
|
137
190
|
|
138
|
-
def load_additional_types(
|
139
|
-
initializer =
|
191
|
+
def load_additional_types(type_map, oid = nil) # :nodoc:
|
192
|
+
initializer = ArjdbcTypeMapInitializer.new(type_map)
|
140
193
|
|
141
194
|
if supports_ranges?
|
142
195
|
query = <<-SQL
|
143
|
-
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
|
196
|
+
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype,
|
197
|
+
ns.nspname, ns.nspname = ANY(current_schemas(true)) in_ns
|
144
198
|
FROM pg_type as t
|
145
199
|
LEFT JOIN pg_range as r ON oid = rngtypid
|
200
|
+
JOIN pg_namespace AS ns ON t.typnamespace = ns.oid
|
146
201
|
SQL
|
147
202
|
else
|
148
203
|
query = <<-SQL
|
149
|
-
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype
|
204
|
+
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype,
|
205
|
+
ns.nspname, ns.nspname = ANY(current_schemas(true)) in_ns
|
150
206
|
FROM pg_type as t
|
207
|
+
JOIN pg_namespace AS ns ON t.typnamespace = ns.oid
|
151
208
|
SQL
|
152
209
|
end
|
153
210
|
|
154
|
-
if
|
155
|
-
|
211
|
+
if oid
|
212
|
+
if oid.is_a? Numeric || oid.match(/^\d+$/)
|
213
|
+
# numeric OID
|
214
|
+
query += "WHERE t.oid::integer = %s" % oid
|
215
|
+
|
216
|
+
elsif m = oid.match(/"?(\w+)"?\."?(\w+)"?/)
|
217
|
+
# namespace and type name
|
218
|
+
query += "WHERE ns.nspname = '%s' AND t.typname = '%s'" % [m[1], m[2]]
|
219
|
+
|
220
|
+
else
|
221
|
+
# only type name
|
222
|
+
query += "WHERE t.typname = '%s' AND ns.nspname = ANY(current_schemas(true))" % oid
|
223
|
+
end
|
156
224
|
else
|
157
225
|
query += initializer.query_conditions_for_initial_load
|
158
226
|
end
|
data/lib/arjdbc/version.rb
CHANGED
data/rakelib/rails.rake
CHANGED
@@ -9,14 +9,15 @@ namespace :rails do
|
|
9
9
|
if ENV['RAILS']
|
10
10
|
ar_path = File.join(ENV['RAILS'], 'activerecord')
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
unless ar_path && File.exist?(ar_path)
|
14
|
-
ar_path = `bundle info --path activerecord`.chomp
|
14
|
+
ar_path = `bundle info --path activerecord`.lines.last.chomp
|
15
15
|
end
|
16
16
|
|
17
17
|
unless File.exist? ar_test_dir = File.join(ar_path, 'test')
|
18
18
|
raise "can not directly load Rails tests;" +
|
19
|
-
" try setting a local repository path e.g. export RAILS=`pwd`/../rails"
|
19
|
+
" try setting a local repository path e.g. export RAILS=`pwd`/../rails;" +
|
20
|
+
" failed guess: #{ar_path}"
|
20
21
|
end
|
21
22
|
|
22
23
|
driver = "jdbc-#{ENV['DRIVER'] ? ENV['DRIVER'].downcase : (adapter =~ /postgres/i ? 'postgres' : adapter)}"
|
@@ -29,7 +29,6 @@ import java.util.HashMap;
|
|
29
29
|
import java.util.Map;
|
30
30
|
import java.util.WeakHashMap;
|
31
31
|
|
32
|
-
import org.jruby.NativeException;
|
33
32
|
import org.jruby.Ruby;
|
34
33
|
import org.jruby.RubyArray;
|
35
34
|
import org.jruby.RubyClass;
|
@@ -148,13 +147,7 @@ public class ArJdbcModule {
|
|
148
147
|
}
|
149
148
|
}
|
150
149
|
catch (ClassNotFoundException e) { /* ignored */ }
|
151
|
-
catch (NoSuchMethodException e) {
|
152
|
-
throw newNativeException(runtime, e);
|
153
|
-
}
|
154
|
-
catch (IllegalAccessException e) {
|
155
|
-
throw newNativeException(runtime, e);
|
156
|
-
}
|
157
|
-
catch (InvocationTargetException e) {
|
150
|
+
catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
158
151
|
throw newNativeException(runtime, e);
|
159
152
|
}
|
160
153
|
|
@@ -263,18 +256,15 @@ public class ArJdbcModule {
|
|
263
256
|
try {
|
264
257
|
return klass.getMethod(name, argType).invoke(null, arg);
|
265
258
|
}
|
266
|
-
catch (IllegalAccessException e) {
|
267
|
-
throw newNativeException(runtime, e);
|
268
|
-
}
|
269
|
-
catch (InvocationTargetException e) {
|
259
|
+
catch (IllegalAccessException | InvocationTargetException e) {
|
270
260
|
throw newNativeException(runtime, e);
|
271
261
|
}
|
272
262
|
}
|
273
263
|
|
274
264
|
private static RaiseException newNativeException(final Ruby runtime, final Throwable cause) {
|
275
|
-
|
276
|
-
|
277
|
-
return
|
265
|
+
final RaiseException error = runtime.newRuntimeError(cause.toString());
|
266
|
+
error.initCause(cause);
|
267
|
+
return error;
|
278
268
|
}
|
279
269
|
|
280
270
|
@JRubyMethod(meta = true)
|
@@ -83,8 +83,8 @@ public class DerbyRubyJdbcConnection extends RubyJdbcConnection {
|
|
83
83
|
final int minor = jdbcDriver.getMinorVersion();
|
84
84
|
if ( major < 10 || ( major == 10 && minor < 5 ) ) {
|
85
85
|
final RubyClass errorClass = getConnectionNotEstablished(context.runtime);
|
86
|
-
throw
|
87
|
-
"adapter requires Derby >= 10.5 got: " + major + "." + minor + ""
|
86
|
+
throw context.runtime.newRaiseException(errorClass,
|
87
|
+
"adapter requires Derby >= 10.5 got: " + major + "." + minor + "");
|
88
88
|
}
|
89
89
|
if ( major == 10 && minor < 8 ) { // 10.8 ~ supports JDBC 4.1
|
90
90
|
// config[:connection_alive_sql] ||= 'SELECT 1 FROM SYS.SYSSCHEMAS FETCH FIRST 1 ROWS ONLY'
|
@@ -27,12 +27,6 @@ package arjdbc.jdbc;
|
|
27
27
|
|
28
28
|
import java.sql.Connection;
|
29
29
|
import java.sql.SQLException;
|
30
|
-
import javax.sql.DataSource;
|
31
|
-
|
32
|
-
import org.jruby.RubyObject;
|
33
|
-
import org.jruby.RubyString;
|
34
|
-
import org.jruby.runtime.ThreadContext;
|
35
|
-
import org.jruby.runtime.builtin.IRubyObject;
|
36
30
|
|
37
31
|
/**
|
38
32
|
* Interface to be implemented in Ruby for retrieving a new connection.
|
@@ -49,84 +43,3 @@ public interface ConnectionFactory {
|
|
49
43
|
Connection newConnection() throws SQLException;
|
50
44
|
|
51
45
|
}
|
52
|
-
|
53
|
-
class DataSourceConnectionFactoryImpl implements ConnectionFactory {
|
54
|
-
|
55
|
-
private final DataSource dataSource;
|
56
|
-
final String username, password; // optional
|
57
|
-
|
58
|
-
public DataSourceConnectionFactoryImpl(final DataSource dataSource) {
|
59
|
-
this.dataSource = dataSource;
|
60
|
-
this.username = null; this.password = null;
|
61
|
-
}
|
62
|
-
|
63
|
-
public DataSourceConnectionFactoryImpl(final DataSource dataSource,
|
64
|
-
final String username, final String password) {
|
65
|
-
this.dataSource = dataSource;
|
66
|
-
this.username = username; this.password = password;
|
67
|
-
}
|
68
|
-
|
69
|
-
@Override
|
70
|
-
public Connection newConnection() throws SQLException {
|
71
|
-
if ( username != null ) {
|
72
|
-
dataSource.getConnection(username, password);
|
73
|
-
}
|
74
|
-
return dataSource.getConnection();
|
75
|
-
}
|
76
|
-
|
77
|
-
DataSource getDataSource() { return dataSource; } /* for tests */
|
78
|
-
|
79
|
-
}
|
80
|
-
|
81
|
-
class DriverConnectionFactoryImpl implements ConnectionFactory {
|
82
|
-
|
83
|
-
private final DriverWrapper driverWrapper;
|
84
|
-
final String url;
|
85
|
-
final String username, password; // null allowed
|
86
|
-
|
87
|
-
public DriverConnectionFactoryImpl(final DriverWrapper driver, final String url) {
|
88
|
-
this.driverWrapper = driver; this.url = url;
|
89
|
-
this.username = null; this.password = null;
|
90
|
-
}
|
91
|
-
|
92
|
-
public DriverConnectionFactoryImpl(final DriverWrapper driver, final String url,
|
93
|
-
final String username, final String password) {
|
94
|
-
this.driverWrapper = driver; this.url = url;
|
95
|
-
this.username = username; this.password = password;
|
96
|
-
}
|
97
|
-
|
98
|
-
@Override
|
99
|
-
public Connection newConnection() throws SQLException {
|
100
|
-
return driverWrapper.connect(url, username, password);
|
101
|
-
}
|
102
|
-
|
103
|
-
DriverWrapper getDriverWrapper() { return driverWrapper; } /* for tests */
|
104
|
-
|
105
|
-
}
|
106
|
-
|
107
|
-
// @legacy ActiveRecord::ConnectionAdapters::JdbcDriver
|
108
|
-
class RubyConnectionFactoryImpl implements ConnectionFactory {
|
109
|
-
|
110
|
-
private final IRubyObject driver;
|
111
|
-
final RubyString url;
|
112
|
-
final IRubyObject username, password; // null allowed
|
113
|
-
|
114
|
-
private final RubyObject contextProvider;
|
115
|
-
|
116
|
-
public RubyConnectionFactoryImpl(final IRubyObject driver, final RubyString url,
|
117
|
-
final IRubyObject username, final IRubyObject password) {
|
118
|
-
this.driver = driver; this.url = url;
|
119
|
-
this.username = username; this.password = password;
|
120
|
-
contextProvider = (RubyObject) driver;
|
121
|
-
}
|
122
|
-
|
123
|
-
@Override
|
124
|
-
public Connection newConnection() throws SQLException {
|
125
|
-
final ThreadContext context = contextProvider.getRuntime().getCurrentContext();
|
126
|
-
final IRubyObject connection = driver.callMethod(context, "connection", new IRubyObject[] { url, username, password });
|
127
|
-
return (Connection) connection.toJava(Connection.class);
|
128
|
-
}
|
129
|
-
|
130
|
-
IRubyObject getDriver() { return driver; } /* for tests */
|
131
|
-
|
132
|
-
}
|
@@ -68,7 +68,6 @@ final class DataSourceConnectionFactory implements ConnectionFactory {
|
|
68
68
|
|
69
69
|
@Override
|
70
70
|
public Connection newConnection() throws SQLException {
|
71
|
-
DataSource dataSource = this.dataSource;
|
72
71
|
// in case DS failed previously look it up again from JNDI :
|
73
72
|
if (dataSource == null) {
|
74
73
|
lookupDataSource();
|
@@ -0,0 +1,61 @@
|
|
1
|
+
/***** BEGIN LICENSE BLOCK *****
|
2
|
+
* Copyright (c) 2012-2014 Karol Bucek <self@kares.org>
|
3
|
+
* Copyright (c) 2006-2010 Nick Sieger <nick@nicksieger.com>
|
4
|
+
* Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
|
5
|
+
*
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
* a copy of this software and associated documentation files (the
|
8
|
+
* "Software"), to deal in the Software without restriction, including
|
9
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
* the following conditions:
|
13
|
+
*
|
14
|
+
* The above copyright notice and this permission notice shall be
|
15
|
+
* included in all copies or substantial portions of the Software.
|
16
|
+
*
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
***** END LICENSE BLOCK *****/
|
25
|
+
|
26
|
+
package arjdbc.jdbc;
|
27
|
+
|
28
|
+
import java.sql.Connection;
|
29
|
+
import java.sql.SQLException;
|
30
|
+
|
31
|
+
import org.jruby.RubyObject;
|
32
|
+
import org.jruby.RubyString;
|
33
|
+
import org.jruby.runtime.ThreadContext;
|
34
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
35
|
+
|
36
|
+
// @legacy ActiveRecord::ConnectionAdapters::JdbcDriver
|
37
|
+
class RubyConnectionFactory implements ConnectionFactory {
|
38
|
+
|
39
|
+
private final IRubyObject driver;
|
40
|
+
final RubyString url;
|
41
|
+
final IRubyObject username, password; // null allowed
|
42
|
+
|
43
|
+
private final RubyObject contextProvider;
|
44
|
+
|
45
|
+
public RubyConnectionFactory(final IRubyObject driver, final RubyString url,
|
46
|
+
final IRubyObject username, final IRubyObject password) {
|
47
|
+
this.driver = driver; this.url = url;
|
48
|
+
this.username = username; this.password = password;
|
49
|
+
contextProvider = (RubyObject) driver;
|
50
|
+
}
|
51
|
+
|
52
|
+
@Override
|
53
|
+
public Connection newConnection() throws SQLException {
|
54
|
+
final ThreadContext context = contextProvider.getRuntime().getCurrentContext();
|
55
|
+
final IRubyObject connection = driver.callMethod(context, "connection", new IRubyObject[] { url, username, password });
|
56
|
+
return (Connection) connection.toJava(Connection.class);
|
57
|
+
}
|
58
|
+
|
59
|
+
IRubyObject getDriver() { return driver; } /* for tests */
|
60
|
+
|
61
|
+
}
|