activerecord-jdbc-adapter-ficoh 1.3.21-java
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.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/.travis.yml +462 -0
- data/.yardopts +4 -0
- data/Appraisals +36 -0
- data/CONTRIBUTING.md +49 -0
- data/Gemfile +68 -0
- data/History.md +1191 -0
- data/LICENSE.txt +25 -0
- data/README.md +277 -0
- data/RUNNING_TESTS.md +88 -0
- data/Rakefile +298 -0
- data/Rakefile.jdbc +20 -0
- data/activerecord-jdbc-adapter.gemspec +63 -0
- data/lib/active_record/connection_adapters/as400_adapter.rb +2 -0
- data/lib/active_record/connection_adapters/db2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mariadb_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
- data/lib/activerecord-jdbc-adapter.rb +1 -0
- data/lib/arel/visitors/compat.rb +64 -0
- data/lib/arel/visitors/db2.rb +137 -0
- data/lib/arel/visitors/derby.rb +112 -0
- data/lib/arel/visitors/firebird.rb +79 -0
- data/lib/arel/visitors/h2.rb +25 -0
- data/lib/arel/visitors/hsqldb.rb +32 -0
- data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
- data/lib/arel/visitors/sql_server.rb +225 -0
- data/lib/arel/visitors/sql_server/ng42.rb +293 -0
- data/lib/arjdbc.rb +22 -0
- data/lib/arjdbc/db2.rb +4 -0
- data/lib/arjdbc/db2/adapter.rb +802 -0
- data/lib/arjdbc/db2/as400.rb +137 -0
- data/lib/arjdbc/db2/column.rb +177 -0
- data/lib/arjdbc/db2/connection_methods.rb +45 -0
- data/lib/arjdbc/derby.rb +3 -0
- data/lib/arjdbc/derby/active_record_patch.rb +13 -0
- data/lib/arjdbc/derby/adapter.rb +567 -0
- data/lib/arjdbc/derby/connection_methods.rb +16 -0
- data/lib/arjdbc/derby/schema_creation.rb +15 -0
- data/lib/arjdbc/discover.rb +104 -0
- data/lib/arjdbc/firebird.rb +4 -0
- data/lib/arjdbc/firebird/adapter.rb +468 -0
- data/lib/arjdbc/firebird/connection_methods.rb +20 -0
- data/lib/arjdbc/h2.rb +3 -0
- data/lib/arjdbc/h2/adapter.rb +335 -0
- data/lib/arjdbc/h2/connection_methods.rb +22 -0
- data/lib/arjdbc/hsqldb.rb +3 -0
- data/lib/arjdbc/hsqldb/adapter.rb +304 -0
- data/lib/arjdbc/hsqldb/connection_methods.rb +23 -0
- data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
- data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
- data/lib/arjdbc/informix.rb +5 -0
- data/lib/arjdbc/informix/adapter.rb +160 -0
- data/lib/arjdbc/informix/connection_methods.rb +9 -0
- data/lib/arjdbc/jdbc.rb +62 -0
- data/lib/arjdbc/jdbc/adapter.rb +997 -0
- data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
- data/lib/arjdbc/jdbc/arel_support.rb +149 -0
- data/lib/arjdbc/jdbc/base_ext.rb +34 -0
- data/lib/arjdbc/jdbc/callbacks.rb +52 -0
- data/lib/arjdbc/jdbc/column.rb +83 -0
- data/lib/arjdbc/jdbc/connection.rb +26 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +59 -0
- data/lib/arjdbc/jdbc/driver.rb +44 -0
- data/lib/arjdbc/jdbc/error.rb +75 -0
- data/lib/arjdbc/jdbc/extension.rb +69 -0
- data/lib/arjdbc/jdbc/java.rb +13 -0
- data/lib/arjdbc/jdbc/type_cast.rb +154 -0
- data/lib/arjdbc/jdbc/type_converter.rb +142 -0
- data/lib/arjdbc/mssql.rb +7 -0
- data/lib/arjdbc/mssql/adapter.rb +822 -0
- data/lib/arjdbc/mssql/column.rb +207 -0
- data/lib/arjdbc/mssql/connection_methods.rb +72 -0
- data/lib/arjdbc/mssql/explain_support.rb +99 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
- data/lib/arjdbc/mssql/lock_methods.rb +77 -0
- data/lib/arjdbc/mssql/types.rb +343 -0
- data/lib/arjdbc/mssql/utils.rb +82 -0
- data/lib/arjdbc/mysql.rb +3 -0
- data/lib/arjdbc/mysql/adapter.rb +998 -0
- data/lib/arjdbc/mysql/bulk_change_table.rb +150 -0
- data/lib/arjdbc/mysql/column.rb +167 -0
- data/lib/arjdbc/mysql/connection_methods.rb +137 -0
- data/lib/arjdbc/mysql/explain_support.rb +82 -0
- data/lib/arjdbc/mysql/schema_creation.rb +58 -0
- data/lib/arjdbc/oracle.rb +4 -0
- data/lib/arjdbc/oracle/adapter.rb +968 -0
- data/lib/arjdbc/oracle/column.rb +136 -0
- data/lib/arjdbc/oracle/connection_methods.rb +21 -0
- data/lib/arjdbc/postgresql.rb +3 -0
- data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +21 -0
- data/lib/arjdbc/postgresql/adapter.rb +1498 -0
- data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
- data/lib/arjdbc/postgresql/base/oid.rb +412 -0
- data/lib/arjdbc/postgresql/base/pgconn.rb +8 -0
- data/lib/arjdbc/postgresql/base/schema_definitions.rb +132 -0
- data/lib/arjdbc/postgresql/column.rb +640 -0
- data/lib/arjdbc/postgresql/connection_methods.rb +44 -0
- data/lib/arjdbc/postgresql/explain_support.rb +53 -0
- data/lib/arjdbc/postgresql/oid/bytea.rb +3 -0
- data/lib/arjdbc/postgresql/oid_types.rb +265 -0
- data/lib/arjdbc/postgresql/schema_creation.rb +60 -0
- data/lib/arjdbc/railtie.rb +11 -0
- data/lib/arjdbc/sqlite3.rb +3 -0
- data/lib/arjdbc/sqlite3/adapter.rb +654 -0
- data/lib/arjdbc/sqlite3/connection_methods.rb +36 -0
- data/lib/arjdbc/sqlite3/explain_support.rb +29 -0
- data/lib/arjdbc/sybase.rb +2 -0
- data/lib/arjdbc/sybase/adapter.rb +47 -0
- data/lib/arjdbc/tasks.rb +13 -0
- data/lib/arjdbc/tasks/database_tasks.rb +66 -0
- data/lib/arjdbc/tasks/databases.rake +91 -0
- data/lib/arjdbc/tasks/databases3.rake +239 -0
- data/lib/arjdbc/tasks/databases4.rake +39 -0
- data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
- data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
- data/lib/arjdbc/tasks/h2_database_tasks.rb +31 -0
- data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
- data/lib/arjdbc/tasks/jdbc_database_tasks.rb +169 -0
- data/lib/arjdbc/tasks/mssql_database_tasks.rb +46 -0
- data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +297 -0
- data/lib/arjdbc/tasks/oracle_database_tasks.rb +65 -0
- data/lib/arjdbc/util/quoted_cache.rb +60 -0
- data/lib/arjdbc/util/serialized_attributes.rb +98 -0
- data/lib/arjdbc/util/table_copier.rb +108 -0
- data/lib/arjdbc/version.rb +8 -0
- data/lib/generators/jdbc/USAGE +9 -0
- data/lib/generators/jdbc/jdbc_generator.rb +17 -0
- data/pom.xml +285 -0
- data/rails_generators/jdbc_generator.rb +15 -0
- data/rails_generators/templates/config/initializers/jdbc.rb +10 -0
- data/rails_generators/templates/lib/tasks/jdbc.rake +11 -0
- data/rakelib/01-tomcat.rake +51 -0
- data/rakelib/02-test.rake +151 -0
- data/rakelib/bundler_ext.rb +11 -0
- data/rakelib/db.rake +58 -0
- data/rakelib/rails.rake +77 -0
- data/src/java/arjdbc/ArJdbcModule.java +288 -0
- data/src/java/arjdbc/db2/DB2Module.java +77 -0
- data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +128 -0
- data/src/java/arjdbc/derby/DerbyModule.java +180 -0
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +153 -0
- data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +190 -0
- data/src/java/arjdbc/h2/H2Module.java +50 -0
- data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +86 -0
- data/src/java/arjdbc/hsqldb/HSQLDBModule.java +74 -0
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +76 -0
- data/src/java/arjdbc/jdbc/AdapterJavaService.java +43 -0
- data/src/java/arjdbc/jdbc/Callable.java +44 -0
- data/src/java/arjdbc/jdbc/ConnectionFactory.java +77 -0
- data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +156 -0
- data/src/java/arjdbc/jdbc/DriverConnectionFactory.java +63 -0
- data/src/java/arjdbc/jdbc/DriverWrapper.java +128 -0
- data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +32 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +4541 -0
- data/src/java/arjdbc/jdbc/SQLBlock.java +54 -0
- data/src/java/arjdbc/jdbc/WithResultSet.java +37 -0
- data/src/java/arjdbc/mssql/MSSQLModule.java +91 -0
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +193 -0
- data/src/java/arjdbc/mysql/MySQLModule.java +140 -0
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +456 -0
- data/src/java/arjdbc/oracle/OracleModule.java +81 -0
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +477 -0
- data/src/java/arjdbc/postgresql/ByteaUtils.java +171 -0
- data/src/java/arjdbc/postgresql/DriverImplementation.java +78 -0
- data/src/java/arjdbc/postgresql/PGDriverImplementation.java +535 -0
- data/src/java/arjdbc/postgresql/PostgreSQLModule.java +189 -0
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +489 -0
- data/src/java/arjdbc/sqlite3/SQLite3Module.java +93 -0
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +405 -0
- data/src/java/arjdbc/util/CallResultSet.java +826 -0
- data/src/java/arjdbc/util/DateTimeUtils.java +517 -0
- data/src/java/arjdbc/util/NumberUtils.java +50 -0
- data/src/java/arjdbc/util/ObjectSupport.java +65 -0
- data/src/java/arjdbc/util/QuotingUtils.java +139 -0
- data/src/java/arjdbc/util/StringCache.java +60 -0
- data/src/java/arjdbc/util/StringHelper.java +155 -0
- metadata +288 -0
@@ -0,0 +1,189 @@
|
|
1
|
+
/*
|
2
|
+
* The MIT License
|
3
|
+
*
|
4
|
+
* Copyright 2014 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.postgresql;
|
25
|
+
|
26
|
+
import java.sql.ResultSet;
|
27
|
+
import java.sql.SQLException;
|
28
|
+
|
29
|
+
import org.jruby.Ruby;
|
30
|
+
import org.jruby.RubyModule;
|
31
|
+
import org.jruby.RubyString;
|
32
|
+
import org.jruby.anno.JRubyMethod;
|
33
|
+
import org.jruby.exceptions.RaiseException;
|
34
|
+
import org.jruby.runtime.ThreadContext;
|
35
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
36
|
+
import org.jruby.util.ByteList;
|
37
|
+
|
38
|
+
import arjdbc.jdbc.WithResultSet;
|
39
|
+
import static arjdbc.jdbc.RubyJdbcConnection.debugMessage;
|
40
|
+
import static arjdbc.jdbc.RubyJdbcConnection.executeImpl;
|
41
|
+
import static arjdbc.jdbc.RubyJdbcConnection.executeQueryImpl;
|
42
|
+
import static arjdbc.util.QuotingUtils.quoteCharAndDecorateWith;
|
43
|
+
import static arjdbc.util.QuotingUtils.quoteCharWith;
|
44
|
+
|
45
|
+
/**
|
46
|
+
* ArJdbc::PostgreSQL
|
47
|
+
*
|
48
|
+
* @author kares
|
49
|
+
*/
|
50
|
+
@org.jruby.anno.JRubyModule(name = "ArJdbc::PostgreSQL")
|
51
|
+
public class PostgreSQLModule {
|
52
|
+
|
53
|
+
public static RubyModule load(final RubyModule arJdbc) {
|
54
|
+
RubyModule postgreSQL = arJdbc.defineModuleUnder("PostgreSQL");
|
55
|
+
postgreSQL.defineAnnotatedMethods( PostgreSQLModule.class );
|
56
|
+
return postgreSQL;
|
57
|
+
}
|
58
|
+
|
59
|
+
public static RubyModule load(final Ruby runtime) {
|
60
|
+
return load( arjdbc.ArJdbcModule.get(runtime) );
|
61
|
+
}
|
62
|
+
|
63
|
+
@JRubyMethod(name = "quote_column_name", required = 1, frame = false)
|
64
|
+
public static IRubyObject quote_column_name(
|
65
|
+
final ThreadContext context,
|
66
|
+
final IRubyObject self,
|
67
|
+
final IRubyObject string) { // %("#{name.to_s.gsub("\"", "\"\"")}")
|
68
|
+
return quoteCharAndDecorateWith(context, string.asString(), '"', '"', (byte) '"', (byte) '"');
|
69
|
+
}
|
70
|
+
|
71
|
+
private static final ByteList BYTES_BACKSLASH = new ByteList(new byte[] { '\\' }, false);
|
72
|
+
private static final ByteList BYTES_ANDAND = new ByteList(new byte[] { '\\', '&', '\\', '&' }, false);
|
73
|
+
|
74
|
+
@JRubyMethod(name = "quote_string", required = 1, frame = false)
|
75
|
+
public static IRubyObject quote_string(
|
76
|
+
final ThreadContext context,
|
77
|
+
final IRubyObject self,
|
78
|
+
final IRubyObject string) {
|
79
|
+
final RubyString str = string.asString();
|
80
|
+
// quoted = string.gsub("'", "''")
|
81
|
+
RubyString quoted = quoteCharWith(context, str, '\'', '\'');
|
82
|
+
|
83
|
+
if ( ! standard_conforming_strings(context, self) ) { // minor branch
|
84
|
+
// quoted.gsub!(/\\/, '\&\&')
|
85
|
+
return quoted.callMethod(context, "gsub", new IRubyObject[] {
|
86
|
+
context.runtime.newString(BYTES_BACKSLASH),
|
87
|
+
context.runtime.newString(BYTES_ANDAND)
|
88
|
+
});
|
89
|
+
}
|
90
|
+
return quoted;
|
91
|
+
}
|
92
|
+
|
93
|
+
@JRubyMethod(name = "standard_conforming_strings?")
|
94
|
+
public static IRubyObject standard_conforming_strings_p(final ThreadContext context, final IRubyObject self) {
|
95
|
+
return context.runtime.newBoolean( standard_conforming_strings(context, self) );
|
96
|
+
}
|
97
|
+
|
98
|
+
private static boolean standard_conforming_strings(final ThreadContext context, final IRubyObject self) {
|
99
|
+
IRubyObject standard_conforming_strings =
|
100
|
+
self.getInstanceVariables().getInstanceVariable("@standard_conforming_strings");
|
101
|
+
|
102
|
+
if ( standard_conforming_strings == null ) {
|
103
|
+
synchronized (self) {
|
104
|
+
standard_conforming_strings = context.nil; // unsupported
|
105
|
+
|
106
|
+
final IRubyObject client_min_messages = self.callMethod(context, "client_min_messages");
|
107
|
+
final Ruby runtime = context.runtime;
|
108
|
+
try {
|
109
|
+
self.callMethod(context, "client_min_messages=", runtime.newString("panic"));
|
110
|
+
// NOTE: we no longer log this query as before ... with :
|
111
|
+
// select_one('SHOW standard_conforming_strings', 'SCHEMA')['standard_conforming_strings']
|
112
|
+
standard_conforming_strings = executeQueryImpl(context, self,
|
113
|
+
"SHOW standard_conforming_strings", 1, false, new WithResultSet<IRubyObject>() {
|
114
|
+
public IRubyObject call(final ResultSet resultSet) throws SQLException {
|
115
|
+
if ( resultSet != null && resultSet.next() ) {
|
116
|
+
final String result = resultSet.getString(1);
|
117
|
+
return runtime.newBoolean( "on".equals(result) );
|
118
|
+
}
|
119
|
+
return context.nil;
|
120
|
+
}
|
121
|
+
});
|
122
|
+
}
|
123
|
+
catch (SQLException e) { // unsupported
|
124
|
+
debugMessage(context.runtime, "standard conforming strings not supported: ", e);
|
125
|
+
}
|
126
|
+
catch (RaiseException e) { // unsupported
|
127
|
+
debugMessage(context.runtime, "standard conforming strings raised: ", e);
|
128
|
+
}
|
129
|
+
finally {
|
130
|
+
self.callMethod(context, "client_min_messages=", client_min_messages);
|
131
|
+
}
|
132
|
+
|
133
|
+
self.getInstanceVariables().setInstanceVariable("@standard_conforming_strings", standard_conforming_strings);
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
return standard_conforming_strings.isTrue();
|
138
|
+
}
|
139
|
+
|
140
|
+
@JRubyMethod(name = "standard_conforming_strings=")
|
141
|
+
public static IRubyObject set_standard_conforming_strings(final ThreadContext context, final IRubyObject self,
|
142
|
+
final IRubyObject enable) {
|
143
|
+
//
|
144
|
+
// client_min_messages = self.client_min_messages
|
145
|
+
// begin
|
146
|
+
// self.client_min_messages = 'panic'
|
147
|
+
// value = enable ? "on" : "off"
|
148
|
+
// execute("SET standard_conforming_strings = #{value}", 'SCHEMA')
|
149
|
+
// @standard_conforming_strings = ( value == "on" )
|
150
|
+
// rescue
|
151
|
+
// @standard_conforming_strings = :unsupported
|
152
|
+
// ensure
|
153
|
+
// self.client_min_messages = client_min_messages
|
154
|
+
// end
|
155
|
+
//
|
156
|
+
IRubyObject standard_conforming_strings = context.nil; // unsupported
|
157
|
+
final IRubyObject client_min_messages = self.callMethod(context, "client_min_messages");
|
158
|
+
|
159
|
+
try {
|
160
|
+
final Ruby runtime = context.runtime;
|
161
|
+
self.callMethod(context, "client_min_messages=", runtime.newString("panic"));
|
162
|
+
|
163
|
+
final String value;
|
164
|
+
if ( enable.isNil() || enable == runtime.getFalse() ) value = "off";
|
165
|
+
else value = "on";
|
166
|
+
// NOTE: we no longer log this query as before ... with :
|
167
|
+
// execute("SET standard_conforming_strings = #{value}", 'SCHEMA')
|
168
|
+
executeImpl(context, self, "SET standard_conforming_strings = " + value);
|
169
|
+
|
170
|
+
standard_conforming_strings = runtime.newBoolean( value == (Object) "on" );
|
171
|
+
}
|
172
|
+
catch (RaiseException e) {
|
173
|
+
// unsupported
|
174
|
+
}
|
175
|
+
finally {
|
176
|
+
self.callMethod(context, "client_min_messages=", client_min_messages);
|
177
|
+
}
|
178
|
+
|
179
|
+
return self.getInstanceVariables().setInstanceVariable("@standard_conforming_strings", standard_conforming_strings);
|
180
|
+
}
|
181
|
+
|
182
|
+
@JRubyMethod(name = "unescape_bytea", meta = true)
|
183
|
+
public static RubyString unescape_bytea(final ThreadContext context, final IRubyObject self, final IRubyObject escaped) {
|
184
|
+
final ByteList bytes = ((RubyString) escaped).getByteList();
|
185
|
+
final byte[] rawBytes = ByteaUtils.toBytes(bytes.unsafeBytes(), bytes.getBegin(), bytes.getRealSize());
|
186
|
+
return RubyString.newString(context.runtime, new ByteList(rawBytes, false));
|
187
|
+
}
|
188
|
+
|
189
|
+
}
|
@@ -0,0 +1,489 @@
|
|
1
|
+
/***** BEGIN LICENSE BLOCK *****
|
2
|
+
* Copyright (c) 2012-2015 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
|
+
* Copyright (c) 2008-2009 Thomas E Enebo <enebo@acm.org>
|
6
|
+
*
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
8
|
+
* a copy of this software and associated documentation files (the
|
9
|
+
* "Software"), to deal in the Software without restriction, including
|
10
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
11
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
12
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
13
|
+
* the following conditions:
|
14
|
+
*
|
15
|
+
* The above copyright notice and this permission notice shall be
|
16
|
+
* included in all copies or substantial portions of the Software.
|
17
|
+
*
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
20
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
22
|
+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
23
|
+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
24
|
+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
25
|
+
***** END LICENSE BLOCK *****/
|
26
|
+
package arjdbc.postgresql;
|
27
|
+
|
28
|
+
import java.io.ByteArrayInputStream;
|
29
|
+
import java.io.InputStream;
|
30
|
+
import java.lang.reflect.InvocationTargetException;
|
31
|
+
import java.sql.Array;
|
32
|
+
import java.sql.Connection;
|
33
|
+
import java.sql.PreparedStatement;
|
34
|
+
import java.sql.ResultSet;
|
35
|
+
import java.sql.SQLException;
|
36
|
+
import java.sql.Statement;
|
37
|
+
import java.sql.Types;
|
38
|
+
|
39
|
+
import org.jruby.Ruby;
|
40
|
+
import org.jruby.RubyArray;
|
41
|
+
import org.jruby.RubyBoolean;
|
42
|
+
import org.jruby.RubyClass;
|
43
|
+
import org.jruby.RubyFixnum;
|
44
|
+
import org.jruby.RubyFloat;
|
45
|
+
import org.jruby.RubyIO;
|
46
|
+
import org.jruby.RubyString;
|
47
|
+
import org.jruby.anno.JRubyMethod;
|
48
|
+
import org.jruby.runtime.ObjectAllocator;
|
49
|
+
import org.jruby.runtime.ThreadContext;
|
50
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
51
|
+
import org.jruby.util.ByteList;
|
52
|
+
import org.jruby.util.SafePropertyAccessor;
|
53
|
+
|
54
|
+
import arjdbc.jdbc.DriverWrapper;
|
55
|
+
import arjdbc.util.DateTimeUtils;
|
56
|
+
|
57
|
+
/**
|
58
|
+
*
|
59
|
+
* @author enebo
|
60
|
+
*/
|
61
|
+
@org.jruby.anno.JRubyClass(name = "ActiveRecord::ConnectionAdapters::PostgreSQLJdbcConnection")
|
62
|
+
public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection {
|
63
|
+
private static final long serialVersionUID = 7235537759545717760L;
|
64
|
+
|
65
|
+
public PostgreSQLRubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
|
66
|
+
super(runtime, metaClass);
|
67
|
+
}
|
68
|
+
|
69
|
+
public static RubyClass createPostgreSQLJdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) {
|
70
|
+
final RubyClass clazz = getConnectionAdapters(runtime).
|
71
|
+
defineClassUnder("PostgreSQLJdbcConnection", jdbcConnection, ALLOCATOR);
|
72
|
+
clazz.defineAnnotatedMethods(PostgreSQLRubyJdbcConnection.class);
|
73
|
+
return clazz;
|
74
|
+
}
|
75
|
+
|
76
|
+
public static RubyClass load(final Ruby runtime) {
|
77
|
+
RubyClass jdbcConnection = getJdbcConnection(runtime);
|
78
|
+
return createPostgreSQLJdbcConnectionClass(runtime, jdbcConnection);
|
79
|
+
}
|
80
|
+
|
81
|
+
protected static ObjectAllocator ALLOCATOR = new ObjectAllocator() {
|
82
|
+
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
|
83
|
+
return new PostgreSQLRubyJdbcConnection(runtime, klass);
|
84
|
+
}
|
85
|
+
};
|
86
|
+
|
87
|
+
@Override
|
88
|
+
protected DriverWrapper newDriverWrapper(final ThreadContext context, final String driver) {
|
89
|
+
DriverWrapper driverWrapper = super.newDriverWrapper(context, driver);
|
90
|
+
|
91
|
+
final java.sql.Driver jdbcDriver = driverWrapper.getDriverInstance();
|
92
|
+
if ( jdbcDriver.getClass().getName().startsWith("org.postgresql.") ) {
|
93
|
+
try { // public static String getVersion()
|
94
|
+
final String version = (String) // "PostgreSQL 9.2 JDBC4 (build 1002)"
|
95
|
+
jdbcDriver.getClass().getMethod("getVersion").invoke(null);
|
96
|
+
if ( version != null && version.indexOf("JDBC3") >= 0 ) {
|
97
|
+
// config[:connection_alive_sql] ||= 'SELECT 1'
|
98
|
+
setConfigValueIfNotSet(context, "connection_alive_sql", context.runtime.newString("SELECT 1"));
|
99
|
+
}
|
100
|
+
}
|
101
|
+
catch (NoSuchMethodException e) { }
|
102
|
+
catch (SecurityException e) { }
|
103
|
+
catch (IllegalAccessException e) { }
|
104
|
+
catch (InvocationTargetException e) { }
|
105
|
+
}
|
106
|
+
|
107
|
+
return driverWrapper;
|
108
|
+
}
|
109
|
+
|
110
|
+
protected final IRubyObject beginTransaction(final ThreadContext context, final Connection connection,
|
111
|
+
final IRubyObject isolation) throws SQLException {
|
112
|
+
// NOTE: only reversed order - just to ~ match how Rails does it :
|
113
|
+
/* if ( connection.getAutoCommit() ) */ connection.setAutoCommit(false);
|
114
|
+
if ( isolation != null ) {
|
115
|
+
setTransactionIsolation(context, connection, isolation);
|
116
|
+
}
|
117
|
+
return context.nil;
|
118
|
+
}
|
119
|
+
|
120
|
+
final DriverImplementation driverImplementation = new PGDriverImplementation(); // currently no other supported
|
121
|
+
|
122
|
+
DriverImplementation driverImplementation() { return driverImplementation; }
|
123
|
+
|
124
|
+
// enables testing if the bug is fixed (please run our test-suite)
|
125
|
+
// using `rake test_postgresql JRUBY_OPTS="-J-Darjdbc.postgresql.generated_keys=true"`
|
126
|
+
protected static final boolean generatedKeys;
|
127
|
+
static {
|
128
|
+
String genKeys = SafePropertyAccessor.getProperty("arjdbc.postgresql.generated_keys");
|
129
|
+
if ( genKeys == null ) { // @deprecated system property name :
|
130
|
+
genKeys = SafePropertyAccessor.getProperty("arjdbc.postgresql.generated.keys");
|
131
|
+
}
|
132
|
+
generatedKeys = Boolean.parseBoolean(genKeys);
|
133
|
+
}
|
134
|
+
|
135
|
+
@Override
|
136
|
+
protected IRubyObject mapGeneratedKeys(
|
137
|
+
final Ruby runtime, final Connection connection,
|
138
|
+
final Statement statement, final Boolean singleResult)
|
139
|
+
throws SQLException {
|
140
|
+
// NOTE: PostgreSQL driver supports generated keys but does not work
|
141
|
+
// correctly for all cases e.g. for tables whene no keys are generated
|
142
|
+
// during an INSERT getGeneratedKeys return all inserted rows instead
|
143
|
+
// of an empty result set ... thus disabled until issue is resolved !
|
144
|
+
if ( ! generatedKeys ) return null; // not supported
|
145
|
+
// NOTE: generated-keys is implemented by the Postgre's JDBC driver by
|
146
|
+
// adding a "RETURNING" suffix after the executeUpdate passed query ...
|
147
|
+
return super.mapGeneratedKeys(runtime, connection, statement, singleResult);
|
148
|
+
}
|
149
|
+
|
150
|
+
// storesMixedCaseIdentifiers() return false;
|
151
|
+
// storesLowerCaseIdentifiers() return true;
|
152
|
+
// storesUpperCaseIdentifiers() return false;
|
153
|
+
|
154
|
+
@Override
|
155
|
+
protected final String caseConvertIdentifierForRails(final Connection connection, final String value)
|
156
|
+
throws SQLException {
|
157
|
+
return value;
|
158
|
+
}
|
159
|
+
|
160
|
+
@Override
|
161
|
+
protected final String caseConvertIdentifierForJdbc(final Connection connection, final String value)
|
162
|
+
throws SQLException {
|
163
|
+
return value;
|
164
|
+
}
|
165
|
+
|
166
|
+
@Override
|
167
|
+
protected final Connection newConnection() throws SQLException {
|
168
|
+
return driverImplementation().newConnection( getConnectionFactory().newConnection() );
|
169
|
+
}
|
170
|
+
|
171
|
+
@Override // due statement.setNull(index, Types.BLOB) not working :
|
172
|
+
// org.postgresql.util.PSQLException: ERROR: column "sample_binary" is of type bytea but expression is of type oid
|
173
|
+
protected void setBlobParameter(final ThreadContext context,
|
174
|
+
final Connection connection, final PreparedStatement statement,
|
175
|
+
final int index, final Object value,
|
176
|
+
final IRubyObject column, final int type) throws SQLException {
|
177
|
+
if ( value instanceof IRubyObject ) {
|
178
|
+
setBlobParameter(context, connection, statement, index, (IRubyObject) value, column, type);
|
179
|
+
}
|
180
|
+
else {
|
181
|
+
if ( value == null ) statement.setNull(index, Types.BINARY);
|
182
|
+
else {
|
183
|
+
statement.setBinaryStream(index, (InputStream) value);
|
184
|
+
}
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
@Override // due statement.setNull(index, Types.BLOB) not working :
|
189
|
+
// org.postgresql.util.PSQLException: ERROR: column "sample_binary" is of type bytea but expression is of type oid
|
190
|
+
protected void setBlobParameter(final ThreadContext context,
|
191
|
+
final Connection connection, final PreparedStatement statement,
|
192
|
+
final int index, final IRubyObject value,
|
193
|
+
final IRubyObject column, final int type) throws SQLException {
|
194
|
+
if ( value.isNil() ) {
|
195
|
+
statement.setNull(index, Types.BINARY);
|
196
|
+
}
|
197
|
+
else {
|
198
|
+
if ( value instanceof RubyIO ) { // IO/File
|
199
|
+
statement.setBinaryStream(index, ((RubyIO) value).getInStream());
|
200
|
+
}
|
201
|
+
else { // should be a RubyString
|
202
|
+
final ByteList blob = value.asString().getByteList();
|
203
|
+
statement.setBinaryStream(index,
|
204
|
+
new ByteArrayInputStream(blob.unsafeBytes(), blob.getBegin(), blob.getRealSize()),
|
205
|
+
blob.getRealSize() // length
|
206
|
+
);
|
207
|
+
}
|
208
|
+
}
|
209
|
+
}
|
210
|
+
|
211
|
+
@Override // to handle infinity timestamp values
|
212
|
+
protected void setTimestampParameter(final ThreadContext context,
|
213
|
+
final Connection connection, final PreparedStatement statement,
|
214
|
+
final int index, IRubyObject value,
|
215
|
+
final IRubyObject column, final int type) throws SQLException {
|
216
|
+
|
217
|
+
if ( ! driverImplementation().setTimestampParameter(context, connection, statement, index, value, column, type) ) {
|
218
|
+
super.setTimestampParameter(context, connection, statement, index, value, column, type);
|
219
|
+
}
|
220
|
+
}
|
221
|
+
|
222
|
+
@Override
|
223
|
+
protected void setStringParameter(final ThreadContext context,
|
224
|
+
final Connection connection, final PreparedStatement statement,
|
225
|
+
final int index, final IRubyObject value,
|
226
|
+
final IRubyObject column, final int type) throws SQLException {
|
227
|
+
|
228
|
+
if ( ! driverImplementation().setStringParameter(context, connection, statement, index, value, column, type) ) {
|
229
|
+
super.setStringParameter(context, connection, statement, index, value, column, type);
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
static int oid(final ThreadContext context, final IRubyObject column) {
|
234
|
+
// our column convention :
|
235
|
+
IRubyObject oid = column.getInstanceVariables().getInstanceVariable("@oid");
|
236
|
+
if ( oid == null || oid.isNil() ) { // only for user instantiated Column
|
237
|
+
throw new IllegalStateException("missing @oid for column: " + column.inspect());
|
238
|
+
}
|
239
|
+
return RubyFixnum.fix2int(oid);
|
240
|
+
}
|
241
|
+
|
242
|
+
@Override
|
243
|
+
protected void setObjectParameter(final ThreadContext context,
|
244
|
+
final Connection connection, final PreparedStatement statement,
|
245
|
+
final int index, Object value,
|
246
|
+
final IRubyObject column, final int type) throws SQLException {
|
247
|
+
|
248
|
+
if ( ! driverImplementation().setObjectParameter(context, connection, statement, index, value, column, type) ) {
|
249
|
+
super.setObjectParameter(context, connection, statement, index, value, column, type);
|
250
|
+
}
|
251
|
+
}
|
252
|
+
|
253
|
+
@Override
|
254
|
+
protected String resolveArrayBaseTypeName(final ThreadContext context,
|
255
|
+
final Object value, final IRubyObject column, final int type) {
|
256
|
+
String sqlType = column.callMethod(context, "sql_type").toString();
|
257
|
+
if ( sqlType.startsWith("character varying") ) return "text";
|
258
|
+
final int index = sqlType.indexOf('('); // e.g. "character varying(255)"
|
259
|
+
if ( index > 0 ) sqlType = sqlType.substring(0, index);
|
260
|
+
return sqlType;
|
261
|
+
}
|
262
|
+
|
263
|
+
//private static final int HSTORE_TYPE = 100000 + 1111;
|
264
|
+
|
265
|
+
@Override
|
266
|
+
protected int jdbcTypeFor(final ThreadContext context, final Ruby runtime,
|
267
|
+
final IRubyObject column, final Object value) throws SQLException {
|
268
|
+
// NOTE: likely wrong but native adapters handles this thus we should
|
269
|
+
// too - used from #table_exists? `binds << [ nil, schema ] if schema`
|
270
|
+
if ( column == null || column.isNil() ) return Types.VARCHAR; // assume type == :string
|
271
|
+
final int type = super.jdbcTypeFor(context, runtime, column, value);
|
272
|
+
/*
|
273
|
+
if ( type == Types.OTHER ) {
|
274
|
+
final IRubyObject columnType = column.callMethod(context, "type");
|
275
|
+
if ( "hstore" == (Object) columnType.asJavaString() ) {
|
276
|
+
return HSTORE_TYPE;
|
277
|
+
}
|
278
|
+
} */
|
279
|
+
return type;
|
280
|
+
}
|
281
|
+
|
282
|
+
/**
|
283
|
+
* Override jdbcToRuby type conversions to handle infinite timestamps.
|
284
|
+
* Handing timestamp off to ruby as string so adapter can perform type
|
285
|
+
* conversion to timestamp
|
286
|
+
*/
|
287
|
+
@Override
|
288
|
+
protected IRubyObject jdbcToRuby(
|
289
|
+
final ThreadContext context, final Ruby runtime,
|
290
|
+
final int column, final int type, final ResultSet resultSet)
|
291
|
+
throws SQLException {
|
292
|
+
switch ( type ) {
|
293
|
+
case Types.BIT:
|
294
|
+
// we do get BIT for 't' 'f' as well as BIT strings e.g. "0110" :
|
295
|
+
final String bits = resultSet.getString(column);
|
296
|
+
if ( bits == null ) return context.nil;
|
297
|
+
if ( bits.length() > 1 ) {
|
298
|
+
return RubyString.newUnicodeString(runtime, bits);
|
299
|
+
}
|
300
|
+
return booleanToRuby(context, runtime, resultSet, column);
|
301
|
+
//case Types.JAVA_OBJECT: case Types.OTHER:
|
302
|
+
//return objectToRuby(runtime, resultSet, resultSet.getObject(column));
|
303
|
+
}
|
304
|
+
return super.jdbcToRuby(context, runtime, column, type, resultSet);
|
305
|
+
}
|
306
|
+
|
307
|
+
@Override
|
308
|
+
protected boolean useByteStrings() { return true; }
|
309
|
+
|
310
|
+
@Override
|
311
|
+
protected IRubyObject dateToRuby(final ThreadContext context,
|
312
|
+
final Ruby runtime, final ResultSet resultSet, final int column)
|
313
|
+
throws SQLException {
|
314
|
+
|
315
|
+
if ( rawDateTime != null && rawDateTime.booleanValue() ) {
|
316
|
+
final byte[] value = resultSet.getBytes(column);
|
317
|
+
if ( value == null ) {
|
318
|
+
if ( resultSet.wasNull() ) return context.nil;
|
319
|
+
return RubyString.newEmptyString(runtime); // ""
|
320
|
+
}
|
321
|
+
return RubyString.newString(runtime, new ByteList(value, false));
|
322
|
+
}
|
323
|
+
|
324
|
+
final String value = resultSet.getString(column);
|
325
|
+
if ( value == null ) return context.nil;
|
326
|
+
|
327
|
+
return DateTimeUtils.parseDate(context, value);
|
328
|
+
}
|
329
|
+
|
330
|
+
@Override
|
331
|
+
protected IRubyObject timeToRuby(final ThreadContext context,
|
332
|
+
final Ruby runtime, final ResultSet resultSet, final int column)
|
333
|
+
throws SQLException {
|
334
|
+
return timestampToRuby(context, runtime, resultSet, column);
|
335
|
+
}
|
336
|
+
|
337
|
+
@Override
|
338
|
+
protected IRubyObject timestampToRuby(final ThreadContext context,
|
339
|
+
final Ruby runtime, final ResultSet resultSet, final int column)
|
340
|
+
throws SQLException {
|
341
|
+
|
342
|
+
if ( rawDateTime != null && rawDateTime.booleanValue() ) {
|
343
|
+
final byte[] value = resultSet.getBytes(column);
|
344
|
+
if ( value == null ) {
|
345
|
+
if ( resultSet.wasNull() ) return context.nil;
|
346
|
+
return RubyString.newEmptyString(runtime); // ""
|
347
|
+
}
|
348
|
+
return RubyString.newString(runtime, new ByteList(value, false));
|
349
|
+
}
|
350
|
+
|
351
|
+
// NOTE: using Timestamp we would loose information such as BC :
|
352
|
+
// Timestamp: '0001-12-31 22:59:59.0' String: '0001-12-31 22:59:59 BC'
|
353
|
+
|
354
|
+
final String value = resultSet.getString(column);
|
355
|
+
if ( value == null ) return context.nil;
|
356
|
+
|
357
|
+
// string_to_time
|
358
|
+
final int len = value.length();
|
359
|
+
if ( (len == 8 || len == 9) && value.charAt(len - 1) == 'y' ) {
|
360
|
+
if ( value.charAt(0) == '-' ) { // 'infinity' / '-infinity'
|
361
|
+
return RubyFloat.newFloat(context.runtime, -RubyFloat.INFINITY);
|
362
|
+
}
|
363
|
+
return RubyFloat.newFloat(context.runtime, RubyFloat.INFINITY);
|
364
|
+
}
|
365
|
+
return DateTimeUtils.parseDateTime(context, value);
|
366
|
+
/*
|
367
|
+
final IRubyObject adapter = callMethod(context, "adapter"); // self.adapter
|
368
|
+
if ( usesType(runtime) ) {
|
369
|
+
return typeCastFromDatabase(context, adapter, runtime.newSymbol("timestamp"), strValue);
|
370
|
+
}
|
371
|
+
|
372
|
+
if ( adapter.isNil() ) return strValue; // NOTE: we warn on init_connection
|
373
|
+
return adapter.callMethod(context, "_string_to_timestamp", strValue);
|
374
|
+
*/
|
375
|
+
}
|
376
|
+
|
377
|
+
@Override
|
378
|
+
protected IRubyObject arrayToRuby(final ThreadContext context,
|
379
|
+
final Ruby runtime, final ResultSet resultSet, final int column)
|
380
|
+
throws SQLException {
|
381
|
+
if ( rawArrayType == Boolean.TRUE ) { // pre AR 4.0 compatibility
|
382
|
+
return stringToRuby(context, runtime, resultSet, column);
|
383
|
+
}
|
384
|
+
// NOTE: avoid `finally { array.free(); }` on PostgreSQL due :
|
385
|
+
// java.sql.SQLFeatureNotSupportedException:
|
386
|
+
// Method org.postgresql.jdbc4.Jdbc4Array.free() is not yet implemented.
|
387
|
+
final Array value = resultSet.getArray(column);
|
388
|
+
|
389
|
+
if ( value == null /* || resultSet.wasNull() */ ) return context.nil;
|
390
|
+
|
391
|
+
final RubyArray array = RubyArray.newArray(runtime);
|
392
|
+
|
393
|
+
final ResultSet arrayResult = value.getResultSet(); // 1: index, 2: value
|
394
|
+
final int baseType = value.getBaseType();
|
395
|
+
while ( arrayResult.next() ) {
|
396
|
+
array.append( jdbcToRuby(context, runtime, 2, baseType, arrayResult) );
|
397
|
+
}
|
398
|
+
return array;
|
399
|
+
}
|
400
|
+
|
401
|
+
@Override
|
402
|
+
protected final IRubyObject objectToRuby(final ThreadContext context,
|
403
|
+
final Ruby runtime, final ResultSet resultSet, final int column)
|
404
|
+
throws SQLException {
|
405
|
+
return driverImplementation().objectToRuby(context, resultSet, column);
|
406
|
+
}
|
407
|
+
|
408
|
+
@Override
|
409
|
+
protected TableName extractTableName(
|
410
|
+
final Connection connection, String catalog, String schema,
|
411
|
+
final String tableName) throws IllegalArgumentException, SQLException {
|
412
|
+
// The postgres JDBC driver will default to searching every schema if no
|
413
|
+
// schema search path is given. Default to the 'public' schema instead:
|
414
|
+
if ( schema == null ) schema = "public";
|
415
|
+
return super.extractTableName(connection, catalog, schema, tableName);
|
416
|
+
}
|
417
|
+
|
418
|
+
static Boolean rawArrayType;
|
419
|
+
static {
|
420
|
+
final String arrayRaw = SafePropertyAccessor.getProperty("arjdbc.postgresql.array.raw");
|
421
|
+
if ( arrayRaw != null ) rawArrayType = Boolean.parseBoolean(arrayRaw);
|
422
|
+
}
|
423
|
+
|
424
|
+
@JRubyMethod(name = "raw_array_type?", meta = true)
|
425
|
+
public static IRubyObject useRawArrayType(final ThreadContext context, final IRubyObject self) {
|
426
|
+
if ( rawArrayType == null ) return context.nil;
|
427
|
+
return context.runtime.newBoolean(rawArrayType);
|
428
|
+
}
|
429
|
+
|
430
|
+
@JRubyMethod(name = "raw_array_type=", meta = true)
|
431
|
+
public static IRubyObject setRawArrayType(final IRubyObject self, final IRubyObject value) {
|
432
|
+
if ( value instanceof RubyBoolean ) {
|
433
|
+
rawArrayType = ((RubyBoolean) value).isTrue() ? Boolean.TRUE : Boolean.FALSE;
|
434
|
+
}
|
435
|
+
else {
|
436
|
+
rawArrayType = value.isNil() ? null : Boolean.TRUE;
|
437
|
+
}
|
438
|
+
return value;
|
439
|
+
}
|
440
|
+
|
441
|
+
static Boolean rawHstoreType;
|
442
|
+
static {
|
443
|
+
final String hstoreRaw = SafePropertyAccessor.getProperty("arjdbc.postgresql.hstore.raw");
|
444
|
+
if ( hstoreRaw != null ) rawHstoreType = Boolean.parseBoolean(hstoreRaw);
|
445
|
+
}
|
446
|
+
|
447
|
+
@JRubyMethod(name = "raw_hstore_type?", meta = true)
|
448
|
+
public static IRubyObject useRawHstoreType(final ThreadContext context, final IRubyObject self) {
|
449
|
+
if ( rawHstoreType == null ) return context.nil;
|
450
|
+
return context.runtime.newBoolean(rawHstoreType);
|
451
|
+
}
|
452
|
+
|
453
|
+
@JRubyMethod(name = "raw_hstore_type=", meta = true)
|
454
|
+
public static IRubyObject setRawHstoreType(final IRubyObject self, final IRubyObject value) {
|
455
|
+
if ( value instanceof RubyBoolean ) {
|
456
|
+
rawHstoreType = ((RubyBoolean) value).isTrue() ? Boolean.TRUE : Boolean.FALSE;
|
457
|
+
}
|
458
|
+
else {
|
459
|
+
rawHstoreType = value.isNil() ? null : Boolean.TRUE;
|
460
|
+
}
|
461
|
+
return value;
|
462
|
+
}
|
463
|
+
|
464
|
+
// whether to use "raw" interval values off by default - due native adapter compatibilty :
|
465
|
+
// RAW values :
|
466
|
+
// - 2 years 0 mons 0 days 0 hours 3 mins 0.00 secs
|
467
|
+
// - -1 years 0 mons -2 days 0 hours 0 mins 0.00 secs
|
468
|
+
// Rails style :
|
469
|
+
// - 2 years 00:03:00
|
470
|
+
// - -1 years -2 days
|
471
|
+
static boolean rawIntervalType = Boolean.getBoolean("arjdbc.postgresql.iterval.raw");
|
472
|
+
|
473
|
+
@JRubyMethod(name = "raw_interval_type?", meta = true)
|
474
|
+
public static IRubyObject useRawIntervalType(final ThreadContext context, final IRubyObject self) {
|
475
|
+
return context.runtime.newBoolean(rawIntervalType);
|
476
|
+
}
|
477
|
+
|
478
|
+
@JRubyMethod(name = "raw_interval_type=", meta = true)
|
479
|
+
public static IRubyObject setRawIntervalType(final IRubyObject self, final IRubyObject value) {
|
480
|
+
if ( value instanceof RubyBoolean ) {
|
481
|
+
rawIntervalType = ((RubyBoolean) value).isTrue();
|
482
|
+
}
|
483
|
+
else {
|
484
|
+
rawIntervalType = ! value.isNil();
|
485
|
+
}
|
486
|
+
return value;
|
487
|
+
}
|
488
|
+
|
489
|
+
}
|