activerecord-jdbc-alt-adapter 61.2.0-java → 70.0.0.rc1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +273 -0
  3. data/.gitignore +1 -0
  4. data/.travis.yml +3 -4
  5. data/Gemfile +8 -6
  6. data/README.md +2 -1
  7. data/Rakefile +1 -1
  8. data/activerecord-jdbc-adapter.gemspec +2 -2
  9. data/activerecord-jdbc-alt-adapter.gemspec +2 -2
  10. data/lib/arel/visitors/compat.rb +5 -33
  11. data/lib/arel/visitors/h2.rb +1 -13
  12. data/lib/arel/visitors/hsqldb.rb +1 -21
  13. data/lib/arel/visitors/sql_server.rb +2 -103
  14. data/lib/arjdbc/abstract/core.rb +8 -9
  15. data/lib/arjdbc/abstract/database_statements.rb +4 -4
  16. data/lib/arjdbc/discover.rb +0 -67
  17. data/lib/arjdbc/hsqldb/adapter.rb +2 -2
  18. data/lib/arjdbc/jdbc/adapter.rb +3 -3
  19. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  20. data/lib/arjdbc/jdbc/adapter_require.rb +3 -1
  21. data/lib/arjdbc/jdbc/column.rb +1 -26
  22. data/lib/arjdbc/jdbc/type_cast.rb +2 -2
  23. data/lib/arjdbc/jdbc.rb +0 -7
  24. data/lib/arjdbc/mssql/adapter.rb +134 -105
  25. data/lib/arjdbc/mssql/connection_methods.rb +0 -3
  26. data/lib/arjdbc/mssql/quoting.rb +26 -27
  27. data/lib/arjdbc/mssql/schema_creation.rb +1 -1
  28. data/lib/arjdbc/mssql/schema_definitions.rb +32 -17
  29. data/lib/arjdbc/mssql/schema_dumper.rb +13 -1
  30. data/lib/arjdbc/mssql/schema_statements.rb +61 -36
  31. data/lib/arjdbc/mssql/transaction.rb +2 -2
  32. data/lib/arjdbc/mssql/types/date_and_time_types.rb +6 -6
  33. data/lib/arjdbc/mssql/types/numeric_types.rb +2 -2
  34. data/lib/arjdbc/mssql.rb +1 -1
  35. data/lib/arjdbc/mysql/adapter.rb +2 -1
  36. data/lib/arjdbc/oracle/adapter.rb +4 -23
  37. data/lib/arjdbc/postgresql/adapter.rb +64 -1
  38. data/lib/arjdbc/postgresql/oid_types.rb +68 -47
  39. data/lib/arjdbc/sqlite3/adapter.rb +132 -88
  40. data/lib/arjdbc/tasks/database_tasks.rb +0 -12
  41. data/lib/arjdbc/util/serialized_attributes.rb +0 -22
  42. data/lib/arjdbc/util/table_copier.rb +2 -1
  43. data/lib/arjdbc/version.rb +1 -1
  44. data/rakelib/02-test.rake +3 -18
  45. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +17 -2
  46. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +33 -0
  47. metadata +8 -40
  48. data/lib/active_record/connection_adapters/as400_adapter.rb +0 -2
  49. data/lib/active_record/connection_adapters/db2_adapter.rb +0 -1
  50. data/lib/active_record/connection_adapters/derby_adapter.rb +0 -1
  51. data/lib/active_record/connection_adapters/informix_adapter.rb +0 -1
  52. data/lib/arel/visitors/db2.rb +0 -137
  53. data/lib/arel/visitors/derby.rb +0 -112
  54. data/lib/arel/visitors/firebird.rb +0 -79
  55. data/lib/arjdbc/db2/adapter.rb +0 -808
  56. data/lib/arjdbc/db2/as400.rb +0 -142
  57. data/lib/arjdbc/db2/column.rb +0 -131
  58. data/lib/arjdbc/db2/connection_methods.rb +0 -48
  59. data/lib/arjdbc/db2.rb +0 -4
  60. data/lib/arjdbc/derby/active_record_patch.rb +0 -13
  61. data/lib/arjdbc/derby/adapter.rb +0 -521
  62. data/lib/arjdbc/derby/connection_methods.rb +0 -20
  63. data/lib/arjdbc/derby/schema_creation.rb +0 -15
  64. data/lib/arjdbc/derby.rb +0 -3
  65. data/lib/arjdbc/firebird/adapter.rb +0 -413
  66. data/lib/arjdbc/firebird/connection_methods.rb +0 -23
  67. data/lib/arjdbc/firebird.rb +0 -4
  68. data/lib/arjdbc/informix/adapter.rb +0 -139
  69. data/lib/arjdbc/informix/connection_methods.rb +0 -9
  70. data/lib/arjdbc/sybase/adapter.rb +0 -47
  71. data/lib/arjdbc/sybase.rb +0 -2
  72. data/lib/arjdbc/tasks/db2_database_tasks.rb +0 -104
  73. data/lib/arjdbc/tasks/derby_database_tasks.rb +0 -95
  74. data/src/java/arjdbc/derby/DerbyModule.java +0 -178
  75. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +0 -152
  76. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +0 -174
  77. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +0 -75
@@ -1,104 +0,0 @@
1
- require 'arjdbc/tasks/jdbc_database_tasks'
2
-
3
- module ArJdbc
4
- module Tasks
5
- class DB2DatabaseTasks < JdbcDatabaseTasks
6
-
7
- def create
8
- raise "AR-JDBC adapter 'DB2' does not support create_database"
9
- end
10
-
11
- def purge
12
- establish_connection(config)
13
- connection.recreate_database
14
- end
15
-
16
- # NOTE: does not work correctly (on non AS400) due driver meta data issue
17
- #
18
- # also try db2move e.g. `db2move SAMPLE EXPORT -sn db2inst`
19
- # - where SAMPLE is the database name
20
- # - and -sn specified schema name
21
- #
22
-
23
- def structure_dump(filename)
24
- establish_connection(config)
25
- dump = File.open(filename, "w:utf-8")
26
-
27
- schema_name = connection.schema.upcase if connection.schema
28
- meta_data = connection.jdbc_connection.meta_data
29
- tables_rs = meta_data.getTables(nil, schema_name, nil, ["TABLE"].to_java(:String))
30
-
31
- have_scale = ArJdbc::DB2::HAVE_SCALE
32
- have_precision = ArJdbc::DB2::HAVE_LIMIT + ArJdbc::DB2::HAVE_LIMIT
33
-
34
- while tables_rs.next
35
- table_name = tables_rs.getString('TABLE_NAME')
36
- dump << "CREATE TABLE #{connection.quote_table_name(table_name)} (\n"
37
-
38
- cols_rs = meta_data.getColumns(nil, schema_name, table_name, nil)
39
- begin
40
- first_col = true
41
- while cols_rs.next
42
- column_name = cols_rs.getString(4)
43
- default = cols_rs.getString(13)
44
- default = default.empty? ? "" : " DEFAULT #{default}" if default
45
- type = cols_rs.getString(6)
46
- precision, scale = cols_rs.getString(7), cols_rs.getString(9)
47
- column_size = ""
48
- if scale && have_scale.include?(type)
49
- column_size = "(#{precision},#{scale})"
50
- elsif precision && have_precision.include?(type)
51
- column_size = "(#{precision})"
52
- end
53
- nulling = ( cols_rs.getString(18) == 'NO' ? " NOT NULL" : nil )
54
- autoinc = ( cols_rs.getString(23) == 'YES' ? " GENERATED ALWAYS AS IDENTITY" : nil )
55
-
56
- create_column = connection.quote_column_name(column_name)
57
- create_column << " #{type}"
58
- create_column << column_size
59
- create_column << nulling.to_s
60
- create_column << default.to_s
61
- create_column << autoinc.to_s
62
-
63
- create_column = first_col ? " #{create_column}" : ",\n #{create_column}"
64
- dump << create_column
65
-
66
- first_col = false
67
- end
68
- ensure
69
- cols_rs.close
70
- end
71
-
72
- dump << "\n);\n\n"
73
-
74
- pk_rs = meta_data.getPrimaryKeys(nil, schema_name, table_name)
75
- primary_keys = {}
76
- begin
77
- while pk_rs.next
78
- name = pk_rs.getString(6)
79
- primary_keys[name] ||= []
80
- primary_keys[name] << pk_rs.getString(4)
81
- end
82
- ensure
83
- pk_rs.close
84
- end
85
- primary_keys.each do |constraint_name, cols|
86
- dump << "ALTER TABLE #{connection.quote_table_name(table_name)}\n"
87
- dump << " ADD CONSTRAINT #{constraint_name}\n"
88
- dump << " PRIMARY KEY (#{cols.join(', ')});\n\n"
89
- end
90
- end
91
-
92
- dump.close
93
- end
94
-
95
- def structure_load(filename)
96
- establish_connection(config)
97
- IO.read(filename).split(/;\n*/m).each do |ddl|
98
- connection.execute ddl.sub(/;$/, '')
99
- end
100
- end
101
-
102
- end
103
- end
104
- end
@@ -1,95 +0,0 @@
1
- require 'arjdbc/tasks/jdbc_database_tasks'
2
-
3
- module ArJdbc
4
- module Tasks
5
- class DerbyDatabaseTasks < JdbcDatabaseTasks
6
-
7
- def create
8
- establish_connection(config)
9
- ActiveRecord::Base.connection
10
- end
11
-
12
- def drop
13
- db_dir = expand_path resolve_database(config, true)
14
- if File.exist?(db_dir)
15
- FileUtils.rm_r(db_dir)
16
- FileUtils.rmdir(db_dir) rescue nil
17
- end
18
- end
19
-
20
- SIZEABLE = %w( VARCHAR CLOB BLOB )
21
-
22
- def structure_dump(filename)
23
- establish_connection(config)
24
- dump = File.open(filename, "w:utf-8")
25
-
26
- meta_data = connection.jdbc_connection.meta_data
27
- tables_rs = meta_data.getTables(nil, nil, nil, ["TABLE"].to_java(:String))
28
-
29
- while tables_rs.next
30
- table_name = tables_rs.getString('TABLE_NAME') # getString(3)
31
- dump << "CREATE TABLE #{connection.quote_table_name(table_name)} (\n"
32
-
33
- columns_rs = meta_data.getColumns(nil, nil, table_name, nil)
34
- first_col = true
35
- while columns_rs.next
36
- column_name = columns_rs.getString(4)
37
- default = columns_rs.getString(13)
38
- if default =~ /^GENERATED_/
39
- default = column_auto_increment_def(table_name, column_name)
40
- elsif default
41
- default = " DEFAULT #{default}"
42
- end
43
- type = columns_rs.getString(6)
44
- column_size = columns_rs.getString(7)
45
- nulling = ( columns_rs.getString(18) == 'NO' ? " NOT NULL" : nil )
46
-
47
- create_column = connection.quote_column_name(column_name)
48
- create_column << " #{type}"
49
- create_column << ( SIZEABLE.include?(type) ? "(#{column_size})" : "" )
50
- create_column << nulling.to_s
51
- create_column << default.to_s
52
-
53
- create_column = first_col ? " #{create_column}" : ",\n #{create_column}"
54
- dump << create_column
55
-
56
- first_col = false
57
- end
58
- dump << "\n);\n\n"
59
- end
60
-
61
- dump.close
62
- end
63
-
64
- def structure_load(filename)
65
- establish_connection(config)
66
- IO.read(filename).split(/;\n*/m).each { |ddl| connection.execute(ddl) }
67
- end
68
-
69
- private
70
-
71
- AUTO_INCREMENT_SQL = '' <<
72
- "SELECT AUTOINCREMENTSTART, AUTOINCREMENTINC, COLUMNNAME, REFERENCEID, COLUMNDEFAULT " <<
73
- "FROM SYS.SYSCOLUMNS WHERE REFERENCEID = " <<
74
- "(SELECT T.TABLEID FROM SYS.SYSTABLES T WHERE T.TABLENAME = '%s') AND COLUMNNAME = '%s'"
75
-
76
- def column_auto_increment_def(table_name, column_name)
77
- sql = AUTO_INCREMENT_SQL % [ table_name, column_name ]
78
- if data = connection.execute(sql).first
79
- if start = data['autoincrementstart']
80
- ai_def = ' GENERATED '
81
- ai_def << ( data['columndefault'].nil? ? "ALWAYS" : "BY DEFAULT " )
82
- ai_def << "AS IDENTITY (START WITH "
83
- ai_def << start.to_s
84
- ai_def << ", INCREMENT BY "
85
- ai_def << data['autoincrementinc'].to_s
86
- ai_def << ")"
87
- return ai_def
88
- end
89
- end
90
- ''
91
- end
92
-
93
- end
94
- end
95
- end
@@ -1,178 +0,0 @@
1
- /***** BEGIN LICENSE BLOCK *****
2
- * Copyright (c) 2012-2013 Karol Bucek <self@kares.org>
3
- * Copyright (c) 2006-2011 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.derby;
27
-
28
- import static arjdbc.util.QuotingUtils.BYTES_0;
29
- import static arjdbc.util.QuotingUtils.BYTES_1;
30
- import static arjdbc.util.QuotingUtils.BYTES_SINGLE_Q_x2;
31
-
32
- import org.jruby.Ruby;
33
- import org.jruby.RubyModule;
34
- import org.jruby.RubyString;
35
- import org.jruby.anno.JRubyMethod;
36
- import org.jruby.runtime.ThreadContext;
37
- import org.jruby.runtime.builtin.IRubyObject;
38
- import org.jruby.util.ByteList;
39
-
40
- public class DerbyModule {
41
-
42
- public static RubyModule load(final RubyModule arJdbc) {
43
- RubyModule derby = arJdbc.defineModuleUnder("Derby");
44
- derby.defineAnnotatedMethods( DerbyModule.class );
45
- RubyModule column = derby.defineModuleUnder("Column");
46
- column.defineAnnotatedMethods(Column.class);
47
- return derby;
48
- }
49
-
50
- public static RubyModule load(final Ruby runtime) {
51
- return load( arjdbc.ArJdbcModule.get(runtime) );
52
- }
53
-
54
- public static class Column {
55
-
56
- @JRubyMethod(name = "type_cast", required = 1)
57
- public static IRubyObject type_cast(final ThreadContext context,
58
- final IRubyObject self, final IRubyObject value) {
59
-
60
- if ( value.isNil() ||
61
- ( (value instanceof RubyString) && value.toString().trim().equalsIgnoreCase("null") ) ) {
62
- return context.nil;
63
- }
64
-
65
- final String type = self.getInstanceVariables().getInstanceVariable("@type").toString();
66
-
67
- switch (type.charAt(0)) {
68
- case 's': //string
69
- return value;
70
- case 't': //text, timestamp, time
71
- if ( type.equals("time") ) {
72
- return self.getMetaClass().callMethod(context, "string_to_dummy_time", value);
73
- }
74
- if ( type.equals("timestamp") ) {
75
- return self.getMetaClass().callMethod(context, "string_to_time", value);
76
- }
77
- return value; // text
78
- case 'i': //integer
79
- case 'p': //primary key
80
- if ( value.respondsTo("to_i") ) {
81
- return value.callMethod(context, "to_i");
82
- }
83
- return context.getRuntime().newFixnum( value.isTrue() ? 1 : 0 );
84
- case 'd': //decimal, datetime, date
85
- if ( type.equals("datetime") ) {
86
- return self.getMetaClass().callMethod(context, "string_to_time", value);
87
- }
88
- if ( type.equals("date") ) {
89
- return self.getMetaClass().callMethod(context, "string_to_date", value);
90
- }
91
- return self.getMetaClass().callMethod(context, "value_to_decimal", value);
92
- case 'f': //float
93
- return value.callMethod(context, "to_f");
94
- case 'b': //binary, boolean
95
- return type.equals("binary") ?
96
- self.getMetaClass().callMethod(context, "binary_to_string", value) :
97
- self.getMetaClass().callMethod(context, "value_to_boolean", value) ;
98
- }
99
- return value;
100
- }
101
-
102
- }
103
-
104
- @JRubyMethod(name = "quote_binary", required = 1)
105
- public static IRubyObject quote_binary(final ThreadContext context,
106
- final IRubyObject self, final IRubyObject string) {
107
- final byte[] empty = ByteList.NULL_ARRAY; // ""
108
- return quoteStringHex(context.runtime, empty, string, empty);
109
- }
110
-
111
- private final static byte[] HEX = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
112
-
113
- private static RubyString quoteStringHex(final Ruby runtime,
114
- final byte[] before, final IRubyObject string, final byte[] after) {
115
-
116
- final ByteList input = ((RubyString) string).getByteList();
117
- final int size = input.getRealSize();
118
- final ByteList output = new ByteList( before.length + size * 2 + after.length );
119
- output.append( before );
120
-
121
- final byte[] inputBytes = input.unsafeBytes();
122
-
123
- int written = 0;
124
- for (int i = input.getBegin(); i < input.getBegin() + size; i++) {
125
- final byte b = inputBytes[i];
126
- byte h = HEX[ ( ((char) b) >> 4 ) % 16 ];
127
- byte l = HEX[ ( (char) b ) % 16 ];
128
- output.append(h).append(l);
129
- written += 2;
130
- if ( written >= 16334 ) { // max hex length = 16334
131
- output.append("'||X'".getBytes());
132
- written = 0;
133
- }
134
- }
135
-
136
- output.append( after );
137
- return RubyString.newString(runtime, output);
138
- }
139
-
140
- @JRubyMethod(name = "quote_string", required = 1)
141
- public static IRubyObject quote_string(final IRubyObject self, IRubyObject string) {
142
- if ( ! ( string instanceof RubyString ) ) {
143
- string = string.asString(); // e.g. Multibyte::Chars
144
- }
145
-
146
- ByteList bytes = ((RubyString) string).getByteList();
147
-
148
- boolean newBytes = false;
149
- for ( int i = 0; i < bytes.length(); i++ ) {
150
- switch ( bytes.get(i) ) {
151
- case '\'': break;
152
- default: continue;
153
- }
154
- // on first replacement allocate so we don't manip original
155
- if ( ! newBytes ) {
156
- bytes = new ByteList(bytes);
157
- newBytes = true;
158
- }
159
- bytes.replace(i, 1, BYTES_SINGLE_Q_x2);
160
- i += 1;
161
- }
162
-
163
- return newBytes ? RubyString.newString(self.getRuntime(), bytes) : string;
164
- }
165
-
166
- @JRubyMethod(name = "quoted_true", required = 0, frame = false)
167
- public static RubyString quoted_true(
168
- final ThreadContext context, final IRubyObject self) {
169
- return RubyString.newStringShared(context.runtime, BYTES_1);
170
- }
171
-
172
- @JRubyMethod(name = "quoted_false", required = 0, frame = false)
173
- public static RubyString quoted_false(
174
- final ThreadContext context, final IRubyObject self) {
175
- return RubyString.newStringShared(context.runtime, BYTES_0);
176
- }
177
-
178
- }
@@ -1,152 +0,0 @@
1
- /*
2
- * The MIT License
3
- *
4
- * Copyright 2013 Karol Bucek.
5
- *
6
- * Permission is hereby granted, free of charge, to any person obtaining a copy
7
- * of this software and associated documentation files (the "Software"), to deal
8
- * in the Software without restriction, including without limitation the rights
9
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- * copies of the Software, and to permit persons to whom the Software is
11
- * furnished to do so, subject to the following conditions:
12
- *
13
- * The above copyright notice and this permission notice shall be included in
14
- * all copies or substantial portions of the Software.
15
- *
16
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- * THE SOFTWARE.
23
- */
24
- package arjdbc.derby;
25
-
26
- import arjdbc.jdbc.Callable;
27
- import arjdbc.jdbc.DriverWrapper;
28
- import arjdbc.jdbc.RubyJdbcConnection;
29
-
30
- import java.sql.Connection;
31
- import java.sql.PreparedStatement;
32
- import java.sql.ResultSet;
33
- import java.sql.SQLException;
34
-
35
- import org.jruby.Ruby;
36
- import org.jruby.RubyBoolean;
37
- import org.jruby.RubyClass;
38
- import org.jruby.RubyString;
39
- import org.jruby.anno.JRubyMethod;
40
- import org.jruby.exceptions.RaiseException;
41
- import org.jruby.runtime.ObjectAllocator;
42
- import org.jruby.runtime.ThreadContext;
43
- import org.jruby.runtime.builtin.IRubyObject;
44
- import org.jruby.util.ByteList;
45
-
46
- /**
47
- * ArJdbc::DerbyJdbcConnection
48
- *
49
- * @author kares
50
- */
51
- public class DerbyRubyJdbcConnection extends RubyJdbcConnection {
52
- private static final long serialVersionUID = 4809475910953623325L;
53
-
54
- public DerbyRubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
55
- super(runtime, metaClass);
56
- }
57
-
58
- public static RubyClass createDerbyJdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) {
59
- final RubyClass clazz = getConnectionAdapters(runtime). // ActiveRecord::ConnectionAdapters
60
- defineClassUnder("DerbyJdbcConnection", jdbcConnection, ALLOCATOR);
61
- clazz.defineAnnotatedMethods(DerbyRubyJdbcConnection.class);
62
- return clazz;
63
- }
64
-
65
- public static RubyClass load(final Ruby runtime) {
66
- RubyClass jdbcConnection = getJdbcConnection(runtime);
67
- return createDerbyJdbcConnectionClass(runtime, jdbcConnection);
68
- }
69
-
70
- protected static ObjectAllocator ALLOCATOR = new ObjectAllocator() {
71
- public IRubyObject allocate(Ruby runtime, RubyClass klass) {
72
- return new DerbyRubyJdbcConnection(runtime, klass);
73
- }
74
- };
75
-
76
- @Override
77
- protected DriverWrapper newDriverWrapper(final ThreadContext context, final String driver) {
78
- DriverWrapper driverWrapper = super.newDriverWrapper(context, driver);
79
-
80
- final java.sql.Driver jdbcDriver = driverWrapper.getDriverInstance();
81
- if ( jdbcDriver.getClass().getName().startsWith("org.apache.derby.") ) {
82
- final int major = jdbcDriver.getMajorVersion();
83
- final int minor = jdbcDriver.getMinorVersion();
84
- if ( major < 10 || ( major == 10 && minor < 5 ) ) {
85
- final RubyClass errorClass = getConnectionNotEstablished(context.runtime);
86
- throw context.runtime.newRaiseException(errorClass,
87
- "adapter requires Derby >= 10.5 got: " + major + "." + minor + "");
88
- }
89
- if ( major == 10 && minor < 8 ) { // 10.8 ~ supports JDBC 4.1
90
- // config[:connection_alive_sql] ||= 'SELECT 1 FROM SYS.SYSSCHEMAS FETCH FIRST 1 ROWS ONLY'
91
- setConfigValueIfNotSet(context, "connection_alive_sql", // FROM clause mandatory
92
- context.runtime.newString("SELECT 1 FROM SYS.SYSSCHEMAS FETCH FIRST 1 ROWS ONLY"));
93
- }
94
- }
95
-
96
- return driverWrapper;
97
- }
98
-
99
- @JRubyMethod(name = "select?", required = 1, meta = true, frame = false)
100
- public static RubyBoolean select_p(final ThreadContext context,
101
- final IRubyObject self, final IRubyObject sql) {
102
- final RubyString sqlStr = sql.asString();
103
- if ( isValues(sqlStr) ) return context.runtime.getTrue();
104
- return arjdbc.jdbc.RubyJdbcConnection.select_p(context, self, sqlStr);
105
- }
106
-
107
- // Derby supports 'stand-alone' VALUES expressions
108
- private static final byte[] VALUES = new byte[]{ 'v','a','l','u','e','s' };
109
-
110
- private static boolean isValues(final RubyString sql) {
111
- final ByteList sqlBytes = sql.getByteList();
112
- return startsWithIgnoreCase(sqlBytes, VALUES);
113
- }
114
-
115
- @JRubyMethod(name = {"identity_val_local", "last_insert_id"})
116
- public IRubyObject identity_val_local(final ThreadContext context)
117
- throws SQLException {
118
- return withConnection(context, new Callable<IRubyObject>() {
119
- public IRubyObject call(final Connection connection) throws SQLException {
120
- PreparedStatement statement = null; ResultSet genKeys = null;
121
- try {
122
- statement = connection.prepareStatement("values IDENTITY_VAL_LOCAL()");
123
- genKeys = statement.executeQuery();
124
- return doMapGeneratedKeys(context.getRuntime(), genKeys, true);
125
- }
126
- catch (final SQLException e) {
127
- debugMessage(context.runtime, "failed to get generated keys: ", e);
128
- throw e;
129
- }
130
- finally { close(genKeys); close(statement); }
131
- }
132
- });
133
- }
134
-
135
- @Override
136
- protected boolean supportsGeneratedKeys(final Connection connection) throws SQLException {
137
- return true; // driver reports false from supportsGetGeneratedKeys()
138
- }
139
-
140
- @Override
141
- protected IRubyObject matchTables(final ThreadContext context,
142
- final Connection connection,
143
- final String catalog, String schemaPattern,
144
- final String tablePattern, final String[] types,
145
- final boolean checkExistsOnly) throws SQLException {
146
- if (schemaPattern != null && schemaPattern.equals("")) {
147
- schemaPattern = null; // Derby doesn't like empty-string schema name
148
- }
149
- return super.matchTables(context, connection, catalog, schemaPattern, tablePattern, types, checkExistsOnly);
150
- }
151
-
152
- }