activerecord-jdbc-alt-adapter 60.1.0-java → 61.0.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.nvimlog +0 -0
- data/.travis.yml +11 -11
- data/Gemfile +1 -1
- data/README.md +21 -17
- data/activerecord-jdbc-adapter.gemspec +2 -2
- data/activerecord-jdbc-alt-adapter.gemspec +5 -5
- data/lib/arel/visitors/postgresql_jdbc.rb +1 -1
- data/lib/arel/visitors/sqlserver.rb +16 -0
- data/lib/arjdbc/abstract/core.rb +1 -0
- data/lib/arjdbc/abstract/database_statements.rb +4 -0
- data/lib/arjdbc/abstract/transaction_support.rb +20 -7
- data/lib/arjdbc/mssql.rb +1 -1
- data/lib/arjdbc/mssql/adapter.rb +3 -1
- data/lib/arjdbc/mssql/column.rb +14 -0
- data/lib/arjdbc/mssql/database_limits.rb +7 -0
- data/lib/arjdbc/mssql/extensions/attribute_methods.rb +1 -1
- data/lib/arjdbc/mssql/schema_creation.rb +2 -2
- data/lib/arjdbc/mssql/schema_statements.rb +29 -1
- data/lib/arjdbc/mysql/adapter.rb +14 -5
- data/lib/arjdbc/mysql/connection_methods.rb +5 -1
- data/lib/arjdbc/postgresql/adapter.rb +85 -73
- data/lib/arjdbc/postgresql/column.rb +1 -1
- data/lib/arjdbc/postgresql/oid_types.rb +4 -3
- data/lib/arjdbc/sqlite3/adapter.rb +95 -58
- data/lib/arjdbc/sqlite3/connection_methods.rb +11 -1
- data/lib/arjdbc/tasks/databases.rake +15 -10
- data/lib/arjdbc/tasks/mssql_database_tasks.rb +88 -31
- data/lib/arjdbc/version.rb +3 -1
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +106 -68
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +81 -22
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +3 -4
- metadata +10 -8
@@ -35,7 +35,17 @@ ArJdbc::ConnectionMethods.module_eval do
|
|
35
35
|
# * http://sqlite.org/c3ref/open.html
|
36
36
|
# * http://sqlite.org/c3ref/c_open_autoproxy.html
|
37
37
|
# => 0x01 = readonly, 0x40 = uri (default in JDBC)
|
38
|
-
config[:properties][:open_mode] =
|
38
|
+
config[:properties][:open_mode] = ::SQLite3::Constants::Open::READONLY | ::SQLite3::Constants::Open::URI
|
39
|
+
end
|
40
|
+
|
41
|
+
if config[:flags]
|
42
|
+
config[:properties][:open_mode] ||= 0
|
43
|
+
config[:properties][:open_mode] |= config[:flags]
|
44
|
+
|
45
|
+
# JDBC driver has an extra flag for it
|
46
|
+
if config[:flags] & ::SQLite3::Constants::Open::SHAREDCACHE != 0
|
47
|
+
config[:properties][:shared_cache] = true
|
48
|
+
end
|
39
49
|
end
|
40
50
|
|
41
51
|
timeout = config[:timeout]
|
@@ -5,15 +5,17 @@ module ActiveRecord::Tasks
|
|
5
5
|
DatabaseTasks.module_eval do
|
6
6
|
|
7
7
|
# @override patched to adapt jdbc configuration
|
8
|
-
def each_current_configuration(environment,
|
8
|
+
def each_current_configuration(environment, name = nil)
|
9
9
|
environments = [environment]
|
10
10
|
environments << 'test' if environment == 'development'
|
11
11
|
|
12
12
|
environments.each do |env|
|
13
13
|
ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
|
14
|
-
next if
|
14
|
+
next if name && name != db_config.name
|
15
15
|
|
16
|
-
|
16
|
+
if db_config.database
|
17
|
+
yield adapt_jdbc_config(db_config), db_config.name, env
|
18
|
+
end
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|
@@ -21,21 +23,24 @@ module ActiveRecord::Tasks
|
|
21
23
|
# @override patched to adapt jdbc configuration
|
22
24
|
def each_local_configuration
|
23
25
|
ActiveRecord::Base.configurations.configs_for.each do |db_config|
|
24
|
-
next unless db_config.
|
26
|
+
next unless db_config.database
|
25
27
|
|
26
|
-
if local_database?(db_config
|
27
|
-
yield adapt_jdbc_config(db_config
|
28
|
+
if local_database?(db_config)
|
29
|
+
yield adapt_jdbc_config(db_config)
|
28
30
|
else
|
29
|
-
$stderr.puts "This task only modifies local databases. #{db_config.
|
31
|
+
$stderr.puts "This task only modifies local databases. #{db_config.database} is on a remote host."
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
34
36
|
private
|
35
37
|
|
36
|
-
def adapt_jdbc_config(
|
37
|
-
|
38
|
-
|
38
|
+
def adapt_jdbc_config(db_config)
|
39
|
+
if db_config.adapter.start_with? 'jdbc'
|
40
|
+
config = db_config.configuration_hash.merge(adapter: db_config.adapter.sub(/^jdbc/, ''))
|
41
|
+
db_config = ActiveRecord::DatabaseConfigurations::HashConfig.new(db_config.env_name, db_config.name, config)
|
42
|
+
end
|
43
|
+
db_config
|
39
44
|
end
|
40
45
|
|
41
46
|
end
|
@@ -1,18 +1,29 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'active_record/tasks/database_tasks'
|
4
4
|
|
5
5
|
module ArJdbc
|
6
|
-
module Tasks
|
7
|
-
class MSSQLDatabaseTasks
|
6
|
+
module Tasks # :nodoc:
|
7
|
+
class MSSQLDatabaseTasks # :nodoc:
|
8
|
+
delegate :connection, to: ActiveRecord::Base
|
9
|
+
delegate :establish_connection, to: ActiveRecord::Base
|
8
10
|
delegate :clear_active_connections!, to: ActiveRecord::Base
|
9
11
|
|
12
|
+
def self.using_database_configurations?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(db_config)
|
17
|
+
@db_config = db_config
|
18
|
+
@configuration_hash = db_config.configuration_hash
|
19
|
+
end
|
20
|
+
|
10
21
|
def create
|
11
22
|
establish_master_connection
|
12
|
-
connection.create_database(
|
13
|
-
establish_connection
|
14
|
-
rescue ActiveRecord::StatementInvalid =>
|
15
|
-
case
|
23
|
+
connection.create_database(db_config.database, creation_options)
|
24
|
+
establish_connection(db_config)
|
25
|
+
rescue ActiveRecord::StatementInvalid => e
|
26
|
+
case e.message
|
16
27
|
when /database .* already exists/i
|
17
28
|
raise ActiveRecord::Tasks::DatabaseAlreadyExists
|
18
29
|
else
|
@@ -22,7 +33,15 @@ module ArJdbc
|
|
22
33
|
|
23
34
|
def drop
|
24
35
|
establish_master_connection
|
25
|
-
connection.drop_database
|
36
|
+
connection.drop_database(db_config.database)
|
37
|
+
end
|
38
|
+
|
39
|
+
def charset
|
40
|
+
connection.charset
|
41
|
+
end
|
42
|
+
|
43
|
+
def collation
|
44
|
+
connection.collation
|
26
45
|
end
|
27
46
|
|
28
47
|
def purge
|
@@ -31,40 +50,78 @@ module ArJdbc
|
|
31
50
|
create
|
32
51
|
end
|
33
52
|
|
53
|
+
def structure_dump(filename, _extra_flags)
|
54
|
+
args = prepare_command_options
|
55
|
+
|
56
|
+
args.concat(["-f #{filename}"])
|
34
57
|
|
35
|
-
|
36
|
-
config = config_from_url_if_needed
|
37
|
-
`smoscript -s #{config['host']} -d #{config['database']} -u #{config['username']} -p #{config['password']} -f #{filename} -A -U`
|
58
|
+
run_cmd('mssql-scripter', args, 'dumping')
|
38
59
|
end
|
39
60
|
|
40
|
-
def structure_load(filename)
|
41
|
-
|
42
|
-
|
61
|
+
def structure_load(filename, _extra_flags)
|
62
|
+
args = prepare_command_options
|
63
|
+
|
64
|
+
args.concat(["-i #{filename}"])
|
65
|
+
|
66
|
+
run_cmd('mssql-cli', args, 'loading')
|
43
67
|
end
|
44
68
|
|
45
69
|
private
|
46
70
|
|
71
|
+
attr_reader :db_config, :configuration_hash
|
72
|
+
|
73
|
+
def creation_options
|
74
|
+
{}.tap do |options|
|
75
|
+
options[:collation] = configuration_hash[:collation] if configuration_hash.include?(:collation)
|
76
|
+
|
77
|
+
# azure creation options
|
78
|
+
options[:azure_maxsize] = configuration_hash[:azure_maxsize] if configuration_hash.include?(:azure_maxsize)
|
79
|
+
options[:azure_edition] = configuration_hash[:azure_edition] if configuration_hash.include?(:azure_edition)
|
80
|
+
|
81
|
+
if configuration_hash.include?(:azure_service_objective)
|
82
|
+
options[:azure_service_objective] = configuration_hash[:azure_service_objective]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
47
87
|
def establish_master_connection
|
48
|
-
establish_connection
|
88
|
+
establish_connection(configuration_hash.merge(database: 'master'))
|
49
89
|
end
|
50
90
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
91
|
+
def prepare_command_options
|
92
|
+
{
|
93
|
+
server: '-S',
|
94
|
+
database: '-d',
|
95
|
+
username: '-U',
|
96
|
+
password: '-P'
|
97
|
+
}.map { |option, arg| "#{arg} #{config_for_cli[option]}" }
|
57
98
|
end
|
58
99
|
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
100
|
+
def config_for_cli
|
101
|
+
{}.tap do |options|
|
102
|
+
if configuration_hash[:host].present? && configuration_hash[:port].present?
|
103
|
+
options[:server] = "#{configuration_hash[:host]},#{configuration_hash[:port]}"
|
104
|
+
elsif configuration_hash[:host].present?
|
105
|
+
options[:server] = configuration_hash[:host]
|
106
|
+
end
|
107
|
+
|
108
|
+
options[:database] = configuration_hash[:database] if configuration_hash[:database].present?
|
109
|
+
options[:username] = configuration_hash[:username] if configuration_hash[:username].present?
|
110
|
+
options[:password] = configuration_hash[:password] if configuration_hash[:password].present?
|
64
111
|
end
|
65
|
-
dup
|
66
112
|
end
|
67
113
|
|
114
|
+
def run_cmd(cmd, args, action)
|
115
|
+
fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
|
116
|
+
end
|
117
|
+
|
118
|
+
def run_cmd_error(cmd, args, action)
|
119
|
+
msg = +"failed to execute:\n"
|
120
|
+
msg << "#{cmd} #{args.join(' ')}\n\n"
|
121
|
+
msg << "Failed #{action} structure, please check the output above for any errors"
|
122
|
+
msg << " and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
|
123
|
+
msg
|
124
|
+
end
|
68
125
|
end
|
69
126
|
|
70
127
|
module DatabaseTasksMSSQL
|
@@ -74,8 +131,8 @@ module ArJdbc
|
|
74
131
|
|
75
132
|
def check_protected_environments!
|
76
133
|
super
|
77
|
-
rescue ActiveRecord::JDBCError =>
|
78
|
-
case
|
134
|
+
rescue ActiveRecord::JDBCError => e
|
135
|
+
case e.message
|
79
136
|
when /cannot open database .* requested by the login/i
|
80
137
|
else
|
81
138
|
raise
|
@@ -85,6 +142,6 @@ module ArJdbc
|
|
85
142
|
end
|
86
143
|
end
|
87
144
|
|
88
|
-
ActiveRecord::Tasks::DatabaseTasks.send
|
145
|
+
ActiveRecord::Tasks::DatabaseTasks.send(:include, DatabaseTasksMSSQL)
|
89
146
|
end
|
90
147
|
end
|
data/lib/arjdbc/version.rb
CHANGED
@@ -86,6 +86,7 @@ import org.jruby.anno.JRubyMethod;
|
|
86
86
|
import org.jruby.exceptions.RaiseException;
|
87
87
|
import org.jruby.ext.bigdecimal.RubyBigDecimal;
|
88
88
|
import org.jruby.ext.date.RubyDate;
|
89
|
+
import org.jruby.ext.date.RubyDateTime;
|
89
90
|
import org.jruby.javasupport.JavaEmbedUtils;
|
90
91
|
import org.jruby.javasupport.JavaUtil;
|
91
92
|
import org.jruby.runtime.Block;
|
@@ -124,6 +125,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
124
125
|
private IRubyObject config;
|
125
126
|
private IRubyObject adapter; // the AbstractAdapter instance we belong to
|
126
127
|
private volatile boolean connected = true;
|
128
|
+
private RubyClass attributeClass;
|
127
129
|
|
128
130
|
private boolean lazy = false; // final once set on initialize
|
129
131
|
private boolean jndi; // final once set on initialize
|
@@ -132,6 +134,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
132
134
|
|
133
135
|
protected RubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
|
134
136
|
super(runtime, metaClass);
|
137
|
+
attributeClass = runtime.getModule("ActiveModel").getClass("Attribute");
|
135
138
|
}
|
136
139
|
|
137
140
|
private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
|
@@ -359,7 +362,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
359
362
|
if ( ! connection.getAutoCommit() ) {
|
360
363
|
try {
|
361
364
|
connection.commit();
|
362
|
-
resetSavepoints(context); // if any
|
365
|
+
resetSavepoints(context, connection); // if any
|
363
366
|
return context.runtime.newBoolean(true);
|
364
367
|
}
|
365
368
|
finally {
|
@@ -380,7 +383,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
380
383
|
if ( ! connection.getAutoCommit() ) {
|
381
384
|
try {
|
382
385
|
connection.rollback();
|
383
|
-
resetSavepoints(context); // if any
|
386
|
+
resetSavepoints(context, connection); // if any
|
384
387
|
return context.tru;
|
385
388
|
} finally {
|
386
389
|
connection.setAutoCommit(true);
|
@@ -516,7 +519,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
516
519
|
return null;
|
517
520
|
}
|
518
521
|
|
519
|
-
protected boolean resetSavepoints(final ThreadContext context) {
|
522
|
+
protected boolean resetSavepoints(final ThreadContext context, final Connection connection) throws SQLException {
|
520
523
|
if ( hasInternalVariable("savepoints") ) {
|
521
524
|
removeInternalVariable("savepoints");
|
522
525
|
return true;
|
@@ -610,11 +613,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
610
613
|
return convertJavaToRuby( connection.unwrap(Connection.class) );
|
611
614
|
}
|
612
615
|
}
|
613
|
-
catch (AbstractMethodError e) {
|
614
|
-
debugStackTrace(context, e);
|
615
|
-
warn(context, "driver/pool connection does not support unwrapping: " + e);
|
616
|
-
}
|
617
|
-
catch (SQLException e) {
|
616
|
+
catch (AbstractMethodError | SQLException e) {
|
618
617
|
debugStackTrace(context, e);
|
619
618
|
warn(context, "driver/pool connection does not support unwrapping: " + e);
|
620
619
|
}
|
@@ -860,27 +859,25 @@ public class RubyJdbcConnection extends RubyObject {
|
|
860
859
|
*/
|
861
860
|
@JRubyMethod(name = "execute_insert_pk", required = 2)
|
862
861
|
public IRubyObject execute_insert_pk(final ThreadContext context, final IRubyObject sql, final IRubyObject pk) {
|
863
|
-
return withConnection(context,
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
try {
|
868
|
-
|
869
|
-
statement = createStatement(context, connection);
|
862
|
+
return withConnection(context, connection -> {
|
863
|
+
Statement statement = null;
|
864
|
+
final String query = sqlString(sql);
|
865
|
+
try {
|
870
866
|
|
871
|
-
|
872
|
-
statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
|
873
|
-
} else {
|
874
|
-
statement.executeUpdate(query, createStatementPk(pk));
|
875
|
-
}
|
867
|
+
statement = createStatement(context, connection);
|
876
868
|
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
} finally {
|
882
|
-
close(statement);
|
869
|
+
if (pk == context.nil || pk == context.fals || !supportsGeneratedKeys(connection)) {
|
870
|
+
statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
|
871
|
+
} else {
|
872
|
+
statement.executeUpdate(query, createStatementPk(pk));
|
883
873
|
}
|
874
|
+
|
875
|
+
return mapGeneratedKeys(context, connection, statement);
|
876
|
+
} catch (final SQLException e) {
|
877
|
+
debugErrorSQL(context, query);
|
878
|
+
throw e;
|
879
|
+
} finally {
|
880
|
+
close(statement);
|
884
881
|
}
|
885
882
|
});
|
886
883
|
}
|
@@ -903,26 +900,24 @@ public class RubyJdbcConnection extends RubyObject {
|
|
903
900
|
@JRubyMethod(name = "execute_insert_pk", required = 3)
|
904
901
|
public IRubyObject execute_insert_pk(final ThreadContext context, final IRubyObject sql, final IRubyObject binds,
|
905
902
|
final IRubyObject pk) {
|
906
|
-
return withConnection(context,
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
statement = connection.prepareStatement(query, createStatementPk(pk));
|
915
|
-
}
|
916
|
-
|
917
|
-
setStatementParameters(context, connection, statement, (RubyArray) binds);
|
918
|
-
statement.executeUpdate();
|
919
|
-
return mapGeneratedKeys(context, connection, statement);
|
920
|
-
} catch (final SQLException e) {
|
921
|
-
debugErrorSQL(context, query);
|
922
|
-
throw e;
|
923
|
-
} finally {
|
924
|
-
close(statement);
|
903
|
+
return withConnection(context, connection -> {
|
904
|
+
PreparedStatement statement = null;
|
905
|
+
final String query = sqlString(sql);
|
906
|
+
try {
|
907
|
+
if (pk == context.nil || pk == context.fals || !supportsGeneratedKeys(connection)) {
|
908
|
+
statement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
|
909
|
+
} else {
|
910
|
+
statement = connection.prepareStatement(query, createStatementPk(pk));
|
925
911
|
}
|
912
|
+
|
913
|
+
setStatementParameters(context, connection, statement, (RubyArray) binds);
|
914
|
+
statement.executeUpdate();
|
915
|
+
return mapGeneratedKeys(context, connection, statement);
|
916
|
+
} catch (final SQLException e) {
|
917
|
+
debugErrorSQL(context, query);
|
918
|
+
throw e;
|
919
|
+
} finally {
|
920
|
+
close(statement);
|
926
921
|
}
|
927
922
|
});
|
928
923
|
}
|
@@ -1012,12 +1007,12 @@ public class RubyJdbcConnection extends RubyObject {
|
|
1012
1007
|
binds = null;
|
1013
1008
|
} else { // (sql, binds)
|
1014
1009
|
maxRows = 0;
|
1015
|
-
binds = (RubyArray) TypeConverter.checkArrayType(args[1]);
|
1010
|
+
binds = (RubyArray) TypeConverter.checkArrayType(context, args[1]);
|
1016
1011
|
}
|
1017
1012
|
break;
|
1018
1013
|
case 3: // (sql, max_rows, binds)
|
1019
1014
|
maxRows = RubyNumeric.fix2int(args[1]);
|
1020
|
-
binds = (RubyArray) TypeConverter.checkArrayType(args[2]);
|
1015
|
+
binds = (RubyArray) TypeConverter.checkArrayType(context, args[2]);
|
1021
1016
|
break;
|
1022
1017
|
default: // (sql) 1-arg
|
1023
1018
|
maxRows = 0;
|
@@ -1106,6 +1101,28 @@ public class RubyJdbcConnection extends RubyObject {
|
|
1106
1101
|
});
|
1107
1102
|
}
|
1108
1103
|
|
1104
|
+
@JRubyMethod(required = 1)
|
1105
|
+
public IRubyObject get_first_value(final ThreadContext context, final IRubyObject sql) {
|
1106
|
+
return withConnection(context, connection -> {
|
1107
|
+
Statement statement = null;
|
1108
|
+
final String query = sqlString(sql);
|
1109
|
+
try {
|
1110
|
+
statement = createStatement(context, connection);
|
1111
|
+
statement.execute(query);
|
1112
|
+
ResultSet rs = statement.getResultSet();
|
1113
|
+
if (rs == null || !rs.next()) return context.nil;
|
1114
|
+
|
1115
|
+
return jdbcToRuby(context, context.getRuntime(), 1, rs.getMetaData().getColumnType(1), rs);
|
1116
|
+
|
1117
|
+
} catch (final SQLException e) {
|
1118
|
+
debugErrorSQL(context, query);
|
1119
|
+
throw e;
|
1120
|
+
} finally {
|
1121
|
+
close(statement);
|
1122
|
+
}
|
1123
|
+
});
|
1124
|
+
}
|
1125
|
+
|
1109
1126
|
/**
|
1110
1127
|
* Prepares a query, returns a wrapped PreparedStatement. This takes care of exception wrapping
|
1111
1128
|
* @param context which context this method is executing on.
|
@@ -2402,9 +2419,16 @@ public class RubyJdbcConnection extends RubyObject {
|
|
2402
2419
|
final Connection connection, final PreparedStatement statement,
|
2403
2420
|
final int index, IRubyObject attribute) throws SQLException {
|
2404
2421
|
|
2405
|
-
|
2406
|
-
final int type
|
2407
|
-
|
2422
|
+
final IRubyObject value;
|
2423
|
+
final int type;
|
2424
|
+
|
2425
|
+
if (attributeClass.isInstance(attribute)) {
|
2426
|
+
type = jdbcTypeForAttribute(context, attribute);
|
2427
|
+
value = valueForDatabase(context, attribute);
|
2428
|
+
} else {
|
2429
|
+
type = jdbcTypeForPrimitiveAttribute(context, attribute);
|
2430
|
+
value = attribute;
|
2431
|
+
}
|
2408
2432
|
|
2409
2433
|
// All the set methods were calling this first so save a method call in the nil case
|
2410
2434
|
if ( value == context.nil ) {
|
@@ -2520,6 +2544,34 @@ public class RubyJdbcConnection extends RubyObject {
|
|
2520
2544
|
return Types.OTHER; // -1 as well as 0 are used in Types
|
2521
2545
|
}
|
2522
2546
|
|
2547
|
+
protected String internedTypeForPrimitive(final ThreadContext context, final IRubyObject value) throws SQLException {
|
2548
|
+
if (value instanceof RubyString) {
|
2549
|
+
return "string";
|
2550
|
+
}
|
2551
|
+
if (value instanceof RubyInteger) {
|
2552
|
+
return "integer";
|
2553
|
+
}
|
2554
|
+
if (value instanceof RubyNumeric) {
|
2555
|
+
return "float";
|
2556
|
+
}
|
2557
|
+
if (value instanceof RubyTime || value instanceof RubyDateTime) {
|
2558
|
+
return "timestamp";
|
2559
|
+
}
|
2560
|
+
if (value instanceof RubyDate) {
|
2561
|
+
return "date";
|
2562
|
+
}
|
2563
|
+
if (value instanceof RubyBoolean) {
|
2564
|
+
return "boolean";
|
2565
|
+
}
|
2566
|
+
return "string";
|
2567
|
+
}
|
2568
|
+
|
2569
|
+
protected Integer jdbcTypeForPrimitiveAttribute(final ThreadContext context,
|
2570
|
+
final IRubyObject attribute) throws SQLException {
|
2571
|
+
final String internedType = internedTypeForPrimitive(context, attribute);
|
2572
|
+
return jdbcTypeFor(internedType);
|
2573
|
+
}
|
2574
|
+
|
2523
2575
|
protected Integer jdbcTypeFor(final String type) {
|
2524
2576
|
return JDBC_TYPE_FOR.get(type);
|
2525
2577
|
}
|
@@ -2531,7 +2583,9 @@ public class RubyJdbcConnection extends RubyObject {
|
|
2531
2583
|
}
|
2532
2584
|
|
2533
2585
|
protected static IRubyObject attributeSQLType(final ThreadContext context, final IRubyObject attribute) {
|
2534
|
-
|
2586
|
+
final IRubyObject type = attributeType(context, attribute);
|
2587
|
+
if (type != null) return type.callMethod(context, "type");
|
2588
|
+
return context.nil;
|
2535
2589
|
}
|
2536
2590
|
|
2537
2591
|
private final CachingCallSite value_site = new FunctionalCachingCallSite("value"); // AR::Attribute#value
|
@@ -2546,23 +2600,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
2546
2600
|
|
2547
2601
|
final IRubyObject value = value_site.call(context, attribute, attribute);
|
2548
2602
|
|
2549
|
-
|
2550
|
-
return "integer";
|
2551
|
-
}
|
2552
|
-
|
2553
|
-
if (value instanceof RubyNumeric) {
|
2554
|
-
return "float";
|
2555
|
-
}
|
2556
|
-
|
2557
|
-
if (value instanceof RubyTime) {
|
2558
|
-
return "timestamp";
|
2559
|
-
}
|
2560
|
-
|
2561
|
-
if (value instanceof RubyBoolean) {
|
2562
|
-
return "boolean";
|
2563
|
-
}
|
2564
|
-
|
2565
|
-
return "string";
|
2603
|
+
return internedTypeForPrimitive(context, value);
|
2566
2604
|
}
|
2567
2605
|
|
2568
2606
|
// to be overriden in child class for database specific types
|