activerecord-jdbc-adapter 1.2.9.1 → 1.3.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (231) hide show
  1. data/.travis.yml +3 -0
  2. data/Appraisals +12 -4
  3. data/Gemfile +3 -3
  4. data/Gemfile.lock +19 -19
  5. data/History.txt +90 -16
  6. data/LICENSE.txt +2 -1
  7. data/README.md +14 -1
  8. data/activerecord-jdbc-adapter.gemspec +2 -2
  9. data/gemfiles/rails23.gemfile +5 -5
  10. data/gemfiles/rails23.gemfile.lock +27 -27
  11. data/gemfiles/rails30.gemfile +3 -3
  12. data/gemfiles/rails30.gemfile.lock +8 -8
  13. data/gemfiles/rails31.gemfile +4 -4
  14. data/gemfiles/rails31.gemfile.lock +18 -18
  15. data/gemfiles/rails32.gemfile +4 -4
  16. data/gemfiles/rails32.gemfile.lock +17 -17
  17. data/gemfiles/rails40.gemfile +17 -0
  18. data/gemfiles/rails40.gemfile.lock +126 -0
  19. data/lib/activerecord-jdbc-adapter.rb +0 -7
  20. data/lib/arjdbc.rb +6 -5
  21. data/lib/arjdbc/db2.rb +1 -1
  22. data/lib/arjdbc/db2/adapter.rb +52 -29
  23. data/lib/arjdbc/db2/connection_methods.rb +13 -14
  24. data/lib/arjdbc/derby.rb +1 -1
  25. data/lib/arjdbc/derby/adapter.rb +29 -9
  26. data/lib/arjdbc/derby/connection_methods.rb +17 -20
  27. data/lib/arjdbc/firebird.rb +1 -1
  28. data/lib/arjdbc/h2.rb +2 -2
  29. data/lib/arjdbc/h2/adapter.rb +1 -1
  30. data/lib/arjdbc/h2/connection_methods.rb +12 -16
  31. data/lib/arjdbc/hsqldb.rb +1 -1
  32. data/lib/arjdbc/hsqldb/connection_methods.rb +13 -16
  33. data/lib/arjdbc/informix.rb +1 -1
  34. data/lib/arjdbc/informix/connection_methods.rb +8 -10
  35. data/lib/arjdbc/jdbc.rb +1 -1
  36. data/lib/arjdbc/jdbc/adapter.rb +125 -53
  37. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  38. data/lib/arjdbc/jdbc/base_ext.rb +34 -9
  39. data/lib/arjdbc/jdbc/column.rb +15 -2
  40. data/lib/arjdbc/jdbc/connection.rb +0 -2
  41. data/lib/arjdbc/jdbc/connection_methods.rb +10 -3
  42. data/lib/arjdbc/jdbc/driver.rb +2 -2
  43. data/lib/arjdbc/jdbc/extension.rb +35 -21
  44. data/lib/arjdbc/jdbc/java.rb +0 -2
  45. data/lib/arjdbc/jdbc/missing_functionality_helper.rb +35 -25
  46. data/lib/arjdbc/jdbc/railtie.rb +2 -9
  47. data/lib/arjdbc/mimer.rb +1 -1
  48. data/lib/arjdbc/mssql.rb +2 -2
  49. data/lib/arjdbc/mssql/adapter.rb +271 -92
  50. data/lib/arjdbc/mssql/connection_methods.rb +30 -32
  51. data/lib/arjdbc/mssql/explain_support.rb +107 -0
  52. data/lib/arjdbc/mssql/limit_helpers.rb +48 -18
  53. data/lib/arjdbc/mysql.rb +1 -1
  54. data/lib/arjdbc/mysql/adapter.rb +63 -14
  55. data/lib/arjdbc/mysql/connection_methods.rb +22 -24
  56. data/lib/arjdbc/mysql/explain_support.rb +2 -5
  57. data/lib/arjdbc/oracle.rb +1 -1
  58. data/lib/arjdbc/oracle/adapter.rb +78 -38
  59. data/lib/arjdbc/oracle/connection_methods.rb +9 -10
  60. data/lib/arjdbc/postgresql.rb +1 -1
  61. data/lib/arjdbc/postgresql/adapter.rb +964 -380
  62. data/lib/arjdbc/postgresql/column_cast.rb +136 -0
  63. data/lib/arjdbc/postgresql/connection_methods.rb +19 -21
  64. data/lib/arjdbc/postgresql/explain_support.rb +3 -6
  65. data/lib/arjdbc/railtie.rb +9 -0
  66. data/lib/arjdbc/sqlite3.rb +1 -1
  67. data/lib/arjdbc/sqlite3/adapter.rb +73 -26
  68. data/lib/arjdbc/sqlite3/connection_methods.rb +27 -28
  69. data/lib/arjdbc/sqlite3/explain_support.rb +2 -5
  70. data/lib/arjdbc/sybase.rb +1 -1
  71. data/lib/arjdbc/version.rb +5 -4
  72. data/pom.xml +8 -0
  73. data/rakelib/02-test.rake +57 -51
  74. data/rakelib/compile.rake +17 -5
  75. data/rakelib/rails.rake +42 -31
  76. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +4 -3
  77. data/src/java/arjdbc/derby/DerbyModule.java +98 -85
  78. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +70 -0
  79. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +0 -4
  80. data/src/java/arjdbc/jdbc/AdapterJavaService.java +26 -15
  81. data/src/java/arjdbc/jdbc/Callable.java +44 -0
  82. data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +10 -2
  83. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +1675 -834
  84. data/src/java/arjdbc/jdbc/SQLBlock.java +9 -3
  85. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +73 -36
  86. data/src/java/arjdbc/mysql/MySQLModule.java +11 -10
  87. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +86 -80
  88. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +27 -7
  89. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +214 -0
  90. data/src/java/arjdbc/postgresql/PostgresqlRubyJdbcConnection.java +25 -67
  91. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +52 -49
  92. data/src/java/arjdbc/util/QuotingUtils.java +6 -6
  93. data/test/abstract_db_create.rb +11 -11
  94. data/test/activerecord/connection_adapters/type_conversion_test.rb +18 -12
  95. data/test/db/db2.rb +1 -1
  96. data/test/{db2_binary_test.rb → db/db2/binary_test.rb} +0 -0
  97. data/test/db/db2/has_many_through_test.rb +6 -0
  98. data/test/{db2_reset_column_information_test.rb → db/db2/reset_column_information_test.rb} +1 -2
  99. data/test/{db2_serialize_test.rb → db/db2/serialize_test.rb} +0 -0
  100. data/test/{db2_simple_test.rb → db/db2/simple_test.rb} +1 -8
  101. data/test/db/db2/test_helper.rb +6 -0
  102. data/test/{db2_test.rb → db/db2/unit_test.rb} +1 -1
  103. data/test/db/derby.rb +1 -1
  104. data/test/{derby_binary_test.rb → db/derby/binary_test.rb} +0 -0
  105. data/test/{derby_migration_test.rb → db/derby/migration_test.rb} +0 -0
  106. data/test/{derby_reset_column_information_test.rb → db/derby/reset_column_information_test.rb} +0 -0
  107. data/test/{derby_row_locking_test.rb → db/derby/row_locking_test.rb} +1 -4
  108. data/test/db/derby/schema_dump_test.rb +5 -0
  109. data/test/{derby_serialize_test.rb → db/derby/serialize_test.rb} +0 -0
  110. data/test/{derby_simple_test.rb → db/derby/simple_test.rb} +23 -38
  111. data/test/db/derby/test_helper.rb +6 -0
  112. data/test/db/derby/unit_test.rb +32 -0
  113. data/test/db/derby/xml_column_test.rb +17 -0
  114. data/test/db/h2.rb +1 -1
  115. data/test/{h2_binary_test.rb → db/h2/binary_test.rb} +0 -0
  116. data/test/{h2_change_column_test.rb → db/h2/change_column_test.rb} +1 -0
  117. data/test/{h2_schema_dump_test.rb → db/h2/schema_dump_test.rb} +0 -0
  118. data/test/{h2_serialize_test.rb → db/h2/serialize_test.rb} +0 -0
  119. data/test/{h2_simple_test.rb → db/h2/simple_test.rb} +3 -1
  120. data/test/db/hsqldb.rb +1 -1
  121. data/test/{hsqldb_binary_test.rb → db/hsqldb/binary_test.rb} +0 -0
  122. data/test/{hsqldb_schema_dump_test.rb → db/hsqldb/schema_dump_test.rb} +0 -0
  123. data/test/{hsqldb_serialize_test.rb → db/hsqldb/serialize_test.rb} +0 -0
  124. data/test/{hsqldb_simple_test.rb → db/hsqldb/simple_test.rb} +3 -1
  125. data/test/db/informix.rb +1 -1
  126. data/test/db/jdbc.rb +3 -2
  127. data/test/db/jdbc_derby.rb +1 -1
  128. data/test/db/jdbc_h2.rb +1 -1
  129. data/test/db/jdbc_mysql.rb +1 -1
  130. data/test/db/jdbc_postgres.rb +1 -1
  131. data/test/db/jndi_config.rb +1 -2
  132. data/test/db/jndi_pooled_config.rb +2 -3
  133. data/test/db/mssql.rb +2 -2
  134. data/test/{mssql_binary_test.rb → db/mssql/binary_test.rb} +0 -0
  135. data/test/{mssql_db_create_test.rb → db/mssql/db_create_test.rb} +1 -1
  136. data/test/db/mssql/exec_proc_test.rb +46 -0
  137. data/test/{mssql_identity_insert_test.rb → db/mssql/identity_insert_test.rb} +0 -0
  138. data/test/db/mssql/ignore_system_views_test.rb +40 -0
  139. data/test/{mssql_limit_offset_test.rb → db/mssql/limit_offset_test.rb} +10 -1
  140. data/test/{mssql_multibyte_test.rb → db/mssql/multibyte_test.rb} +0 -0
  141. data/test/db/mssql/multiple_connections_test.rb +71 -0
  142. data/test/{mssql_reset_column_information_test.rb → db/mssql/reset_column_information_test.rb} +0 -0
  143. data/test/{mssql_row_locking_test.rb → db/mssql/row_locking_test.rb} +0 -0
  144. data/test/{mssql_serialize_test.rb → db/mssql/serialize_test.rb} +1 -1
  145. data/test/db/mssql/simple_test.rb +140 -0
  146. data/test/db/mssql/transaction_test.rb +6 -0
  147. data/test/db/mssql/types_test.rb +205 -0
  148. data/test/{mssql_test.rb → db/mssql/unit_test.rb} +2 -2
  149. data/test/db/mysql.rb +1 -2
  150. data/test/db/mysql/_rails_test_mysql.32.out +6768 -0
  151. data/test/{mysql_binary_test.rb → db/mysql/binary_test.rb} +0 -0
  152. data/test/db/mysql/connection_test.rb +51 -0
  153. data/test/{mysql_db_create_test.rb → db/mysql/db_create_test.rb} +0 -0
  154. data/test/{mysql_index_length_test.rb → db/mysql/index_length_test.rb} +0 -0
  155. data/test/{mysql_multibyte_test.rb → db/mysql/multibyte_test.rb} +0 -0
  156. data/test/{mysql_nonstandard_primary_key_test.rb → db/mysql/nonstandard_primary_key_test.rb} +0 -0
  157. data/test/{mysql_reset_column_information_test.rb → db/mysql/reset_column_information_test.rb} +0 -0
  158. data/test/{mysql_schema_dump_test.rb → db/mysql/schema_dump_test.rb} +9 -1
  159. data/test/{mysql_serialize_test.rb → db/mysql/serialize_test.rb} +0 -0
  160. data/test/{mysql_simple_test.rb → db/mysql/simple_test.rb} +16 -8
  161. data/test/db/mysql/transaction_test.rb +6 -0
  162. data/test/db/mysql/types_test.rb +30 -0
  163. data/test/{mysql_test.rb → db/mysql/unit_test.rb} +1 -1
  164. data/test/db/mysql_config.rb +1 -1
  165. data/test/db/oracle.rb +1 -1
  166. data/test/{oracle_binary_test.rb → db/oracle/binary_test.rb} +0 -0
  167. data/test/{oracle_limit_test.rb → db/oracle/limit_test.rb} +0 -0
  168. data/test/db/oracle/multibyte_test.rb +22 -0
  169. data/test/{oracle_reset_column_information_test.rb → db/oracle/reset_column_information_test.rb} +0 -0
  170. data/test/{oracle_serialize_test.rb → db/oracle/serialize_test.rb} +0 -0
  171. data/test/{oracle_simple_test.rb → db/oracle/simple_test.rb} +14 -19
  172. data/test/{oracle_specific_test.rb → db/oracle/specific_test.rb} +62 -16
  173. data/test/db/oracle/transaction_test.rb +31 -0
  174. data/test/db/oracle/unit_test.rb +31 -0
  175. data/test/db/postgres.rb +1 -1
  176. data/test/db/postgres/_rails_test_postgres.32.out +6777 -0
  177. data/test/db/postgres/a_custom_primary_key_test.rb +50 -0
  178. data/test/db/postgres/array_type_test.rb +101 -0
  179. data/test/{postgres_binary_test.rb → db/postgres/binary_test.rb} +0 -0
  180. data/test/db/postgres/connection_test.rb +55 -0
  181. data/test/db/postgres/data_types_test.rb +703 -0
  182. data/test/{postgres_db_create_test.rb → db/postgres/db_create_test.rb} +1 -1
  183. data/test/{postgres_drop_db_test.rb → db/postgres/db_drop_test.rb} +2 -0
  184. data/test/db/postgres/hstore_test.rb +200 -0
  185. data/test/db/postgres/information_schema_leak_test.rb +30 -0
  186. data/test/db/postgres/json_test.rb +86 -0
  187. data/test/db/postgres/ltree_test.rb +50 -0
  188. data/test/{postgres_mixed_case_test.rb → db/postgres/mixed_case_test.rb} +0 -0
  189. data/test/db/postgres/native_types_test.rb +128 -0
  190. data/test/{postgres_reserved_test.rb → db/postgres/reserved_test.rb} +0 -0
  191. data/test/{postgres_reset_column_information_test.rb → db/postgres/reset_column_information_test.rb} +0 -0
  192. data/test/{postgres_row_locking_test.rb → db/postgres/row_locking_test.rb} +0 -0
  193. data/test/{postgres_schema_dump_test.rb → db/postgres/schema_dump_test.rb} +4 -4
  194. data/test/db/postgres/schema_test.rb +113 -0
  195. data/test/{postgres_simple_test.rb → db/postgres/simple_test.rb} +48 -8
  196. data/test/{postgres_table_alias_length_test.rb → db/postgres/table_alias_length_test.rb} +2 -1
  197. data/test/db/postgres/transaction_test.rb +6 -0
  198. data/test/{postgres_test.rb → db/postgres/unit_test.rb} +3 -3
  199. data/test/db/sqlite3.rb +1 -1
  200. data/test/db/sqlite3/_rails_test_sqlite3.32.out +6502 -0
  201. data/test/db/sqlite3/has_many_though_test.rb +6 -0
  202. data/test/{sqlite3_reset_column_information_test.rb → db/sqlite3/reset_column_information_test.rb} +0 -0
  203. data/test/{sqlite3_schema_dump_test.rb → db/sqlite3/schema_dump_test.rb} +0 -0
  204. data/test/{sqlite3_serialize_test.rb → db/sqlite3/serialize_test.rb} +0 -0
  205. data/test/{sqlite3_simple_test.rb → db/sqlite3/simple_test.rb} +63 -63
  206. data/test/db/sqlite3/transaction_test.rb +32 -0
  207. data/test/{sqlite3_type_conversion_test.rb → db/sqlite3/type_conversion_test.rb} +0 -0
  208. data/test/has_many_through.rb +29 -64
  209. data/test/jdbc/oracle.rb +11 -0
  210. data/test/jndi_test.rb +16 -4
  211. data/test/models/auto_id.rb +1 -1
  212. data/test/models/rights_and_roles.rb +57 -0
  213. data/test/row_locking.rb +3 -0
  214. data/test/schema_dump.rb +24 -10
  215. data/test/simple.rb +359 -104
  216. data/test/test_helper.rb +4 -2
  217. data/test/transaction.rb +109 -0
  218. metadata +119 -86
  219. data/lib/arjdbc/jdbc/compatibility.rb +0 -51
  220. data/lib/arjdbc/jdbc/core_ext.rb +0 -24
  221. data/lib/arjdbc/jdbc/discover.rb +0 -18
  222. data/test/derby_schema_dump_test.rb +0 -9
  223. data/test/mssql_ignore_system_views_test.rb +0 -30
  224. data/test/mssql_legacy_types_test.rb +0 -58
  225. data/test/mssql_null_test.rb +0 -14
  226. data/test/mssql_simple_test.rb +0 -51
  227. data/test/postgres_information_schema_leak_test.rb +0 -28
  228. data/test/postgres_native_type_mapping_test.rb +0 -93
  229. data/test/postgres_nonseq_pkey_test.rb +0 -38
  230. data/test/postgres_schema_search_path_test.rb +0 -48
  231. data/test/postgres_type_conversion_test.rb +0 -33
@@ -25,13 +25,18 @@
25
25
  ***** END LICENSE BLOCK *****/
26
26
  package arjdbc.oracle;
27
27
 
28
+ import arjdbc.jdbc.RubyJdbcConnection;
29
+
28
30
  import java.sql.ResultSet;
29
31
  import java.sql.SQLException;
30
-
31
- import arjdbc.jdbc.RubyJdbcConnection;
32
+ import java.sql.DatabaseMetaData;
33
+ import java.util.ArrayList;
34
+ import java.util.List;
32
35
 
33
36
  import org.jruby.Ruby;
37
+ import org.jruby.RubyArray;
34
38
  import org.jruby.RubyClass;
39
+ import org.jruby.RubyString;
35
40
  import org.jruby.runtime.ObjectAllocator;
36
41
  import org.jruby.runtime.builtin.IRubyObject;
37
42
 
@@ -40,15 +45,15 @@ import org.jruby.runtime.builtin.IRubyObject;
40
45
  * @author nicksieger
41
46
  */
42
47
  public class OracleRubyJdbcConnection extends RubyJdbcConnection {
48
+
43
49
  protected OracleRubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
44
50
  super(runtime, metaClass);
45
51
  }
46
-
52
+
47
53
  public static RubyClass createOracleJdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) {
48
- RubyClass clazz = RubyJdbcConnection.getConnectionAdapters(runtime).defineClassUnder("OracleJdbcConnection",
49
- jdbcConnection, ORACLE_JDBCCONNECTION_ALLOCATOR);
54
+ final RubyClass clazz = RubyJdbcConnection.getConnectionAdapters(runtime).
55
+ defineClassUnder("OracleJdbcConnection", jdbcConnection, ORACLE_JDBCCONNECTION_ALLOCATOR);
50
56
  clazz.defineAnnotatedMethods(OracleRubyJdbcConnection.class);
51
-
52
57
  return clazz;
53
58
  }
54
59
 
@@ -76,5 +81,20 @@ public class OracleRubyJdbcConnection extends RubyJdbcConnection {
76
81
  final String type = resultSet.getString(TYPE_NAME);
77
82
  return formatTypeWithPrecisionAndScale(type, precision, scale);
78
83
  }
79
-
84
+
85
+ @Override
86
+ protected RubyArray mapTables(final Ruby runtime, final DatabaseMetaData metaData,
87
+ final String catalog, final String schemaPattern, final String tablePattern,
88
+ final ResultSet tablesSet) throws SQLException {
89
+ final List<IRubyObject> tables = new ArrayList<IRubyObject>(32);
90
+ while ( tablesSet.next() ) {
91
+ String name = tablesSet.getString(TABLES_TABLE_NAME);
92
+ name = caseConvertIdentifierForRails(metaData, name);
93
+ // Handle stupid Oracle 10g RecycleBin feature
94
+ if ( name.startsWith("bin$") ) continue;
95
+ tables.add(RubyString.newUnicodeString(runtime, name));
96
+ }
97
+ return runtime.newArray(tables);
98
+ }
99
+
80
100
  }
@@ -0,0 +1,214 @@
1
+ /*
2
+ **** BEGIN LICENSE BLOCK *****
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.sql.Array;
29
+ import java.sql.Connection;
30
+ import java.sql.DatabaseMetaData;
31
+ import java.sql.ResultSet;
32
+ import java.sql.SQLException;
33
+ import java.sql.Types;
34
+ import java.util.UUID;
35
+
36
+ import org.jruby.Ruby;
37
+ import org.jruby.RubyArray;
38
+ import org.jruby.RubyClass;
39
+ import org.jruby.RubyString;
40
+ import org.jruby.javasupport.JavaUtil;
41
+ import org.jruby.runtime.ObjectAllocator;
42
+ import org.jruby.runtime.builtin.IRubyObject;
43
+
44
+ import org.postgresql.util.PGInterval;
45
+ import org.postgresql.util.PGobject;
46
+
47
+ /**
48
+ *
49
+ * @author enebo
50
+ */
51
+ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection {
52
+
53
+ protected PostgreSQLRubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
54
+ super(runtime, metaClass);
55
+ }
56
+
57
+ public static RubyClass createPostgreSQLJdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) {
58
+ final RubyClass clazz = getConnectionAdapters(runtime).
59
+ defineClassUnder("PostgreSQLJdbcConnection", jdbcConnection, POSTGRESQL_JDBCCONNECTION_ALLOCATOR);
60
+ clazz.defineAnnotatedMethods(PostgreSQLRubyJdbcConnection.class);
61
+ getConnectionAdapters(runtime).setConstant("PostgresJdbcConnection", clazz); // backwards-compat
62
+ return clazz;
63
+ }
64
+
65
+ private static ObjectAllocator POSTGRESQL_JDBCCONNECTION_ALLOCATOR = new ObjectAllocator() {
66
+ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
67
+ return new PostgreSQLRubyJdbcConnection(runtime, klass);
68
+ }
69
+ };
70
+
71
+ @Override
72
+ protected String caseConvertIdentifierForJdbc(final DatabaseMetaData metaData, final String value)
73
+ throws SQLException {
74
+ if ( value != null ) {
75
+ if ( metaData.storesUpperCaseIdentifiers() ) {
76
+ return value.toUpperCase();
77
+ }
78
+ // for PostgreSQL we do not care about storesLowerCaseIdentifiers()
79
+ }
80
+ return value;
81
+ }
82
+
83
+ /**
84
+ * Override jdbcToRuby type conversions to handle infinite timestamps.
85
+ * Handing timestamp off to ruby as string so adapter can perform type
86
+ * conversion to timestamp
87
+ */
88
+ @Override
89
+ protected IRubyObject jdbcToRuby(final Ruby runtime,
90
+ final int column, final int type, final ResultSet resultSet)
91
+ throws SQLException {
92
+ switch ( type ) {
93
+ case Types.TIMESTAMP:
94
+ return stringToRuby(runtime, resultSet, column);
95
+ case Types.BIT:
96
+ // we do get BIT for 't' 'f' as well as BIT strings e.g. "0110" :
97
+ final String bits = resultSet.getString(column);
98
+ if ( bits == null ) return runtime.getNil();
99
+ if ( bits.length() > 1 ) {
100
+ return RubyString.newUnicodeString(runtime, bits);
101
+ }
102
+ return booleanToRuby(runtime, resultSet, column);
103
+ //case Types.JAVA_OBJECT: case Types.OTHER:
104
+ //return objectToRuby(runtime, resultSet, resultSet.getObject(column));
105
+ }
106
+ return super.jdbcToRuby(runtime, column, type, resultSet);
107
+ }
108
+
109
+ @Override
110
+ protected IRubyObject arrayToRuby(
111
+ final Ruby runtime, final ResultSet resultSet, final int column)
112
+ throws SQLException {
113
+ // NOTE: avoid `finally { array.free(); }` on PostgreSQL due :
114
+ // java.sql.SQLFeatureNotSupportedException:
115
+ // Method org.postgresql.jdbc4.Jdbc4Array.free() is not yet implemented.
116
+ final Array value = resultSet.getArray(column);
117
+
118
+ if ( value == null && resultSet.wasNull() ) return runtime.getNil();
119
+
120
+ final RubyArray array = runtime.newArray();
121
+
122
+ final ResultSet arrayResult = value.getResultSet(); // 1: index, 2: value
123
+ final int baseType = value.getBaseType();
124
+ while ( arrayResult.next() ) {
125
+ IRubyObject element = jdbcToRuby(runtime, 2, baseType, arrayResult);
126
+ array.append(element);
127
+ }
128
+ return array;
129
+ }
130
+
131
+ @Override
132
+ protected IRubyObject objectToRuby(
133
+ final Ruby runtime, final ResultSet resultSet, final int column)
134
+ throws SQLException {
135
+ final Object object = resultSet.getObject(column);
136
+
137
+ if ( object == null && resultSet.wasNull() ) return runtime.getNil();
138
+
139
+ final Class<?> objectClass = object.getClass();
140
+ if ( objectClass == UUID.class ) {
141
+ return runtime.newString( object.toString() );
142
+ }
143
+
144
+ if ( objectClass == PGInterval.class ) {
145
+ return runtime.newString( formatInterval(object) );
146
+ }
147
+
148
+ if ( object instanceof PGobject ) {
149
+ // PG 9.2 JSON type will be returned here as well
150
+ return runtime.newString( object.toString() );
151
+ }
152
+
153
+ return JavaUtil.convertJavaToRuby(runtime, object);
154
+ }
155
+
156
+ @Override
157
+ protected TableName extractTableName(
158
+ final Connection connection, String catalog, String schema,
159
+ final String tableName) throws IllegalArgumentException, SQLException {
160
+ // The postgres JDBC driver will default to searching every schema if no
161
+ // schema search path is given. Default to the 'public' schema instead:
162
+ if ( schema == null ) schema = "public";
163
+ return super.extractTableName(connection, catalog, schema, tableName);
164
+ }
165
+
166
+ // NOTE: do not use PG classes in the API so that loading is delayed !
167
+ private String formatInterval(final Object object) {
168
+ final PGInterval interval = (PGInterval) object;
169
+ if ( useRawIntervalType() ) return interval.getValue();
170
+
171
+ final StringBuilder str = new StringBuilder(32);
172
+
173
+ final int years = interval.getYears();
174
+ if ( years != 0 ) str.append(years).append(" years ");
175
+ final int months = interval.getMonths();
176
+ if ( months != 0 ) str.append(months).append(" months ");
177
+ final int days = interval.getDays();
178
+ if ( days != 0 ) str.append(days).append(" days ");
179
+ final int hours = interval.getHours();
180
+ final int mins = interval.getMinutes();
181
+ final int secs = (int) interval.getSeconds();
182
+ if ( hours != 0 || mins != 0 || secs != 0 ) { // xx:yy:zz if not all 00
183
+ if ( hours < 10 ) str.append('0');
184
+ str.append(hours).append(':');
185
+ if ( mins < 10 ) str.append('0');
186
+ str.append(mins).append(':');
187
+ if ( secs < 10 ) str.append('0');
188
+ str.append(secs);
189
+ }
190
+ else {
191
+ if ( str.length() > 1 ) str.deleteCharAt( str.length() - 1 ); // " " at the end
192
+ }
193
+
194
+ return str.toString();
195
+ }
196
+
197
+ // whether to use "raw" interval values off by default - due native adapter compatibilty :
198
+ // RAW values :
199
+ // - 2 years 0 mons 0 days 0 hours 3 mins 0.00 secs
200
+ // - -1 years 0 mons -2 days 0 hours 0 mins 0.00 secs
201
+ // Rails style :
202
+ // - 2 years 00:03:00
203
+ // - -1 years -2 days
204
+ private static boolean rawIntervalType = Boolean.getBoolean("arjdbc.postgresql.iterval.raw");
205
+
206
+ public static boolean useRawIntervalType() {
207
+ return rawIntervalType;
208
+ }
209
+
210
+ public static void setRawIntervalType(boolean rawInterval) {
211
+ PostgreSQLRubyJdbcConnection.rawIntervalType = rawInterval;
212
+ }
213
+
214
+ }
@@ -1,82 +1,40 @@
1
1
  /*
2
- **** BEGIN LICENSE BLOCK *****
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>
2
+ * The MIT License
6
3
  *
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:
4
+ * Copyright 2013 Karol Bucek.
14
5
  *
15
- * The above copyright notice and this permission notice shall be
16
- * included in all copies or substantial portions of the Software.
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:
17
12
  *
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 *****/
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
+ */
26
24
  package arjdbc.postgresql;
27
25
 
28
- import arjdbc.jdbc.RubyJdbcConnection;
29
-
30
- import java.sql.ResultSet;
31
- import java.sql.SQLException;
32
- import java.sql.Types;
33
-
34
26
  import org.jruby.Ruby;
35
27
  import org.jruby.RubyClass;
36
- import org.jruby.runtime.ObjectAllocator;
37
- import org.jruby.runtime.builtin.IRubyObject;
38
28
 
39
29
  /**
40
- *
41
- * @author enebo
30
+ * @see PostgreSQLRubyJdbcConnection
31
+ * @deprecated only for Java API backwards-compatibility
42
32
  */
43
- public class PostgresqlRubyJdbcConnection extends RubyJdbcConnection {
33
+ @Deprecated
34
+ public class PostgresqlRubyJdbcConnection extends PostgreSQLRubyJdbcConnection {
35
+
44
36
  protected PostgresqlRubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
45
37
  super(runtime, metaClass);
46
38
  }
47
-
48
- public static RubyClass createPostgresqlJdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) {
49
- RubyClass clazz = RubyJdbcConnection.getConnectionAdapters(runtime).defineClassUnder("PostgresJdbcConnection",
50
- jdbcConnection, POSTGRESQL_JDBCCONNECTION_ALLOCATOR);
51
- clazz.defineAnnotatedMethods(PostgresqlRubyJdbcConnection.class);
52
-
53
- return clazz;
54
- }
55
-
56
- /**
57
- * Override jdbcToRuby type conversions to handle infinite timestamps.
58
- * Handing timestamp off to ruby as string so adapter can perform type
59
- * conversion to timestamp
60
- */
61
- @Override
62
- protected IRubyObject jdbcToRuby(Ruby runtime, int column, int type,
63
- ResultSet resultSet)
64
- throws SQLException {
65
- if(type == Types.TIMESTAMP) {
66
- try {
67
- return stringToRuby(runtime, resultSet,
68
- resultSet.getString(column));
69
- } catch(java.io.IOException ioe) {
70
- SQLException ex = new SQLException(ioe.getMessage());
71
- throw (SQLException) ex.initCause(ioe);
72
- }
73
- }
74
- return super.jdbcToRuby(runtime, column, type, resultSet);
75
- }
76
-
77
- private static ObjectAllocator POSTGRESQL_JDBCCONNECTION_ALLOCATOR = new ObjectAllocator() {
78
- public IRubyObject allocate(Ruby runtime, RubyClass klass) {
79
- return new PostgresqlRubyJdbcConnection(runtime, klass);
80
- }
81
- };
39
+
82
40
  }
@@ -26,24 +26,28 @@
26
26
 
27
27
  package arjdbc.sqlite3;
28
28
 
29
- import java.io.ByteArrayInputStream;
29
+ import arjdbc.jdbc.Callable;
30
+ import arjdbc.jdbc.RubyJdbcConnection;
31
+
30
32
  import java.io.IOException;
31
33
  import java.sql.Connection;
32
34
  import java.sql.ResultSet;
33
35
  import java.sql.ResultSetMetaData;
34
36
  import java.sql.SQLException;
35
37
  import java.sql.Statement;
36
- import java.sql.Types;
37
-
38
- import arjdbc.jdbc.RubyJdbcConnection;
39
- import arjdbc.jdbc.SQLBlock;
38
+ import java.sql.DatabaseMetaData;
39
+ import java.util.ArrayList;
40
+ import java.util.List;
40
41
 
41
42
  import org.jruby.Ruby;
43
+ import org.jruby.RubyArray;
42
44
  import org.jruby.RubyClass;
45
+ import org.jruby.RubyString;
43
46
  import org.jruby.anno.JRubyMethod;
44
47
  import org.jruby.runtime.ObjectAllocator;
45
48
  import org.jruby.runtime.ThreadContext;
46
49
  import org.jruby.runtime.builtin.IRubyObject;
50
+ import org.jruby.util.ByteList;
47
51
 
48
52
  /**
49
53
  *
@@ -72,56 +76,55 @@ public class SQLite3RubyJdbcConnection extends RubyJdbcConnection {
72
76
  @JRubyMethod(name = "last_insert_row_id")
73
77
  public IRubyObject getLastInsertRowId(final ThreadContext context)
74
78
  throws SQLException {
75
- return (IRubyObject) withConnectionAndRetry(context, new SQLBlock() {
76
- public Object call(Connection c) throws SQLException {
77
- Statement stmt = null;
78
- try {
79
- stmt = c.createStatement();
80
- return unmarshal_id_result(context.getRuntime(),
81
- stmt.getGeneratedKeys());
82
- } catch (SQLException sqe) {
83
- if (context.getRuntime().isDebug()) {
84
- System.out.println("Error SQL:" + sqe.getMessage());
85
- }
86
- throw sqe;
87
- } finally {
88
- close(stmt);
89
- }
79
+ return withConnection(context, new Callable<IRubyObject>() {
80
+ public IRubyObject call(final Connection connection) throws SQLException {
81
+ Statement statement = null;
82
+ try {
83
+ statement = connection.createStatement();
84
+ return unmarshalIdResult(context.getRuntime(), statement);
90
85
  }
91
- });
86
+ catch (final SQLException e) {
87
+ debugMessage(context, "Failed to get generated keys: " + e.getMessage());
88
+ throw e;
89
+ }
90
+ finally { close(statement); }
91
+ }
92
+ });
92
93
  }
93
94
 
94
95
  @Override
95
- protected IRubyObject tables(ThreadContext context, String catalog, String schemaPattern, String tablePattern, String[] types) {
96
- return (IRubyObject) withConnectionAndRetry(context, tableLookupBlock(context.getRuntime(), catalog, schemaPattern, tablePattern, types, true));
96
+ protected IRubyObject jdbcToRuby(final Ruby runtime, final int column, int type, final ResultSet resultSet)
97
+ throws SQLException {
98
+ // This is rather gross, and only needed because the resultset metadata for SQLite tries to be overly
99
+ // clever, and returns a type for the column of the "current" row, so an integer value stored in a
100
+ // decimal column is returned as Types.INTEGER. Therefore, if the first row of a resultset was an
101
+ // integer value, all rows of that result set would get truncated.
102
+ if ( resultSet instanceof ResultSetMetaData ) {
103
+ type = ((ResultSetMetaData) resultSet).getColumnType(column);
104
+ }
105
+ return super.jdbcToRuby(runtime, column, type, resultSet);
106
+ }
107
+
108
+ @Override
109
+ protected IRubyObject streamToRuby(
110
+ final Ruby runtime, final ResultSet resultSet, final int column)
111
+ throws SQLException, IOException {
112
+ final byte[] bytes = resultSet.getBytes(column);
113
+ if ( resultSet.wasNull() ) return runtime.getNil();
114
+ return runtime.newString( new ByteList(bytes, false) );
97
115
  }
98
-
116
+
99
117
  @Override
100
- protected IRubyObject jdbcToRuby(Ruby runtime, int column, int type, ResultSet resultSet)
101
- throws SQLException {
102
- try {
103
- // This is rather gross, and only needed because the resultset metadata for SQLite tries to be overly
104
- // clever, and returns a type for the column of the "current" row, so an integer value stored in a
105
- // decimal column is returned as Types.INTEGER. Therefore, if the first row of a resultset was an
106
- // integer value, all rows of that result set would get truncated.
107
- if( resultSet instanceof ResultSetMetaData ) {
108
- type = ((ResultSetMetaData)resultSet).getColumnType(column);
109
- }
110
- switch (type) {
111
- case Types.BINARY:
112
- case Types.BLOB:
113
- case Types.LONGVARBINARY:
114
- case Types.VARBINARY:
115
- return streamToRuby(runtime, resultSet, new ByteArrayInputStream(resultSet.getBytes(column)));
116
- case Types.LONGVARCHAR:
117
- return runtime.is1_9() ?
118
- readerToRuby(runtime, resultSet, resultSet.getCharacterStream(column)) :
119
- streamToRuby(runtime, resultSet, new ByteArrayInputStream(resultSet.getBytes(column)));
120
- default:
121
- return super.jdbcToRuby(runtime, column, type, resultSet);
122
- }
123
- } catch (IOException ioe) {
124
- throw (SQLException) new SQLException(ioe.getMessage()).initCause(ioe);
118
+ protected RubyArray mapTables(final Ruby runtime, final DatabaseMetaData metaData,
119
+ final String catalog, final String schemaPattern, final String tablePattern,
120
+ final ResultSet tablesSet) throws SQLException {
121
+ final List<IRubyObject> tables = new ArrayList<IRubyObject>(32);
122
+ while ( tablesSet.next() ) {
123
+ String name = tablesSet.getString(TABLES_TABLE_NAME);
124
+ name = name.toLowerCase(); // simply lower-case for SQLite3
125
+ tables.add(RubyString.newUnicodeString(runtime, name));
125
126
  }
127
+ return runtime.newArray(tables);
126
128
  }
129
+
127
130
  }