From b3c4efa3c5a95bffeeef4cfa2bbad6e74ad9828c Mon Sep 17 00:00:00 2001 From: Nick Sieger Date: Fri, 3 Apr 2009 02:13:13 +0800 Subject: [PATCH] JRUBY-3512: Treat LONGVARCHAR as a CLOB for Mssql Signed-off-by: Jean-Dominique Morani --- lib/jdbc_adapter/jdbc_mssql.rb | 4 ++ .../JdbcAdapterInternalService.java | 1 + .../jdbc_adapter/MssqlRubyJdbcConnection.java | 71 +++++++++++++++++++ .../PostgresRubyJdbcConnection.java | 28 ++++++-- src/java/jdbc_adapter/RubyJdbcConnection.java | 23 +++--- 5 files changed, 113 insertions(+), 14 deletions(-) create mode 100644 src/java/jdbc_adapter/MssqlRubyJdbcConnection.java diff --git a/lib/jdbc_adapter/jdbc_mssql.rb b/lib/jdbc_adapter/jdbc_mssql.rb index abc404a13..ffc2bc81d 100644 --- a/lib/jdbc_adapter/jdbc_mssql.rb +++ b/lib/jdbc_adapter/jdbc_mssql.rb @@ -31,6 +31,10 @@ def self.column_selector [/sqlserver|tds/i, lambda {|cfg,col| col.extend(::JdbcSpec::MsSQL::Column)}] end + def self.jdbc_connection_class + ::ActiveRecord::ConnectionAdapters::MssqlJdbcConnection + end + module Column attr_accessor :identity, :is_special diff --git a/src/java/jdbc_adapter/JdbcAdapterInternalService.java b/src/java/jdbc_adapter/JdbcAdapterInternalService.java index 99daef33e..2e73b82ea 100644 --- a/src/java/jdbc_adapter/JdbcAdapterInternalService.java +++ b/src/java/jdbc_adapter/JdbcAdapterInternalService.java @@ -41,6 +41,7 @@ public class JdbcAdapterInternalService implements BasicLibraryService { public boolean basicLoad(final Ruby runtime) throws IOException { RubyClass jdbcConnection = RubyJdbcConnection.createJdbcConnectionClass(runtime); PostgresRubyJdbcConnection.createPostgresJdbcConnectionClass(runtime, jdbcConnection); + MssqlRubyJdbcConnection.createMssqlJdbcConnectionClass(runtime, jdbcConnection); Sqlite3RubyJdbcConnection.createSqlite3JdbcConnectionClass(runtime, jdbcConnection); RubyModule jdbcSpec = runtime.getOrCreateModule("JdbcSpec"); diff --git a/src/java/jdbc_adapter/MssqlRubyJdbcConnection.java b/src/java/jdbc_adapter/MssqlRubyJdbcConnection.java new file mode 100644 index 000000000..d87a22e62 --- /dev/null +++ b/src/java/jdbc_adapter/MssqlRubyJdbcConnection.java @@ -0,0 +1,71 @@ +/* + **** BEGIN LICENSE BLOCK ***** + * Copyright (c) 2006-2009 Nick Sieger + * Copyright (c) 2006-2007 Ola Bini + * Copyright (c) 2008-2009 Thomas E Enebo + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ***** END LICENSE BLOCK *****/ +package jdbc_adapter; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.builtin.IRubyObject; + +/** + * + * @author nicksieger + */ +public class MssqlRubyJdbcConnection extends RubyJdbcConnection { + + protected MssqlRubyJdbcConnection(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + + public static RubyClass createMssqlJdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) { + RubyClass clazz = RubyJdbcConnection.getConnectionAdapters(runtime).defineClassUnder("MssqlJdbcConnection", + jdbcConnection, MSSQL_JDBCCONNECTION_ALLOCATOR); + clazz.defineAnnotatedMethods(MssqlRubyJdbcConnection.class); + + return clazz; + } + private static ObjectAllocator MSSQL_JDBCCONNECTION_ALLOCATOR = new ObjectAllocator() { + + public IRubyObject allocate(Ruby runtime, RubyClass klass) { + return new MssqlRubyJdbcConnection(runtime, klass); + } + }; + + /** + * Treat LONGVARCHAR as CLOB on Mssql for purposes of converting a JDBC value to Ruby. + */ + @Override + protected IRubyObject jdbcToRuby(Ruby runtime, int column, int type, ResultSet resultSet) + throws SQLException { + if (type == Types.LONGVARCHAR) { + type = Types.CLOB; + } + return super.jdbcToRuby(runtime, column, type, resultSet); + } +} diff --git a/src/java/jdbc_adapter/PostgresRubyJdbcConnection.java b/src/java/jdbc_adapter/PostgresRubyJdbcConnection.java index 9f9daf6d3..978fc7c21 100644 --- a/src/java/jdbc_adapter/PostgresRubyJdbcConnection.java +++ b/src/java/jdbc_adapter/PostgresRubyJdbcConnection.java @@ -1,8 +1,28 @@ /* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ - + **** BEGIN LICENSE BLOCK ***** + * Copyright (c) 2006-2009 Nick Sieger + * Copyright (c) 2006-2007 Ola Bini + * Copyright (c) 2008-2009 Thomas E Enebo + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ***** END LICENSE BLOCK *****/ package jdbc_adapter; import org.jruby.Ruby; diff --git a/src/java/jdbc_adapter/RubyJdbcConnection.java b/src/java/jdbc_adapter/RubyJdbcConnection.java index 48a617c3b..d7a99bfb1 100644 --- a/src/java/jdbc_adapter/RubyJdbcConnection.java +++ b/src/java/jdbc_adapter/RubyJdbcConnection.java @@ -618,7 +618,7 @@ private static String toStringOrNull(IRubyObject arg) { return arg.isNil() ? null : arg.toString(); } - private static IRubyObject floatToRuby(Ruby runtime, ResultSet resultSet, float floatValue) + protected IRubyObject floatToRuby(Ruby runtime, ResultSet resultSet, float floatValue) throws SQLException, IOException { if (floatValue == 0 && resultSet.wasNull()) return runtime.getNil(); @@ -718,18 +718,21 @@ private boolean isConnectionBroken(ThreadContext context, Connection c) { } } - private static IRubyObject integerToRuby(Ruby runtime, ResultSet resultSet, long longValue) + protected IRubyObject integerToRuby(Ruby runtime, ResultSet resultSet, long longValue) throws SQLException, IOException { if (longValue == 0 && resultSet.wasNull()) return runtime.getNil(); return runtime.newFixnum(longValue); } - private static IRubyObject jdbcToRuby(Ruby runtime, int column, int type, ResultSet resultSet) + protected IRubyObject jdbcToRuby(Ruby runtime, int column, int type, ResultSet resultSet) throws SQLException { try { switch (type) { - case Types.BINARY: case Types.BLOB: case Types.LONGVARBINARY: case Types.VARBINARY: + case Types.BINARY: + case Types.BLOB: + case Types.LONGVARBINARY: + case Types.VARBINARY: case Types.LONGVARCHAR: return streamToRuby(runtime, resultSet, resultSet.getBinaryStream(column)); case Types.CLOB: @@ -748,7 +751,7 @@ private static IRubyObject jdbcToRuby(Ruby runtime, int column, int type, Result } } - private static void populateFromResultSet(ThreadContext context, Ruby runtime, List results, + protected void populateFromResultSet(ThreadContext context, Ruby runtime, List results, ResultSet resultSet, ColumnData[] columns) throws SQLException { int columnCount = columns.length; @@ -763,7 +766,7 @@ private static void populateFromResultSet(ThreadContext context, Ruby runtime, L } - private static IRubyObject readerToRuby(Ruby runtime, ResultSet resultSet, Reader reader) + protected IRubyObject readerToRuby(Ruby runtime, ResultSet resultSet, Reader reader) throws SQLException, IOException { if (reader == null && resultSet.wasNull()) return runtime.getNil(); @@ -850,7 +853,7 @@ private static void setValuesOnPS(PreparedStatement ps, ThreadContext context, } } - private static IRubyObject streamToRuby(Ruby runtime, ResultSet resultSet, InputStream is) + protected IRubyObject streamToRuby(Ruby runtime, ResultSet resultSet, InputStream is) throws SQLException, IOException { if (is == null && resultSet.wasNull()) return runtime.getNil(); @@ -868,7 +871,7 @@ private static IRubyObject streamToRuby(Ruby runtime, ResultSet resultSet, Input return runtime.newString(str); } - private static IRubyObject stringToRuby(Ruby runtime, ResultSet resultSet, String string) + protected IRubyObject stringToRuby(Ruby runtime, ResultSet resultSet, String string) throws SQLException, IOException { if (string == null && resultSet.wasNull()) return runtime.getNil(); @@ -917,7 +920,7 @@ public Object call(Connection c) throws SQLException { }; } - private static IRubyObject timestampToRuby(Ruby runtime, ResultSet resultSet, Timestamp time) + protected IRubyObject timestampToRuby(Ruby runtime, ResultSet resultSet, Timestamp time) throws SQLException, IOException { if (time == null && resultSet.wasNull()) return runtime.getNil(); @@ -1031,7 +1034,7 @@ public static IRubyObject unmarshal_id_result(Ruby runtime, ResultSet rs) throws * * @param downCase should column names only be in lower case? */ - protected static IRubyObject unmarshalResult(ThreadContext context, DatabaseMetaData metadata, + protected IRubyObject unmarshalResult(ThreadContext context, DatabaseMetaData metadata, ResultSet resultSet, boolean downCase) throws SQLException { Ruby runtime = context.getRuntime(); List results = new ArrayList();