activerecord-jdbc-adapter 0.6 → 0.7
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.
- data/History.txt +46 -27
- data/Manifest.txt +7 -4
- data/Rakefile +6 -5
- data/lib/active_record/connection_adapters/jdbc_adapter.rb +93 -108
- data/lib/jdbc_adapter/jdbc_adapter_internal.jar +0 -0
- data/lib/jdbc_adapter/jdbc_derby.rb +1 -0
- data/lib/jdbc_adapter/jdbc_hsqldb.rb +1 -1
- data/lib/jdbc_adapter/jdbc_mysql.rb +55 -13
- data/lib/jdbc_adapter/version.rb +1 -1
- data/src/java/jdbc_adapter/JdbcAdapterInternalService.java +1113 -0
- data/src/java/jdbc_adapter/JdbcConnectionFactory.java +36 -0
- data/src/java/{JDBCDerbySpec.java → jdbc_adapter/JdbcDerbySpec.java} +95 -91
- data/src/java/{JDBCMySQLSpec.java → jdbc_adapter/JdbcMySQLSpec.java} +24 -27
- data/src/java/jdbc_adapter/SQLBlock.java +18 -0
- data/test/has_many_through.rb +72 -0
- data/test/jdbc_common.rb +1 -0
- data/test/mysql_simple_test.rb +4 -0
- data/test/simple.rb +36 -1
- metadata +9 -6
- data/lib/jdbc_adapter_internal.jar +0 -0
- data/src/java/JdbcAdapterInternalService.java +0 -953
| @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            /***** BEGIN LICENSE BLOCK *****
         | 
| 2 | 
            +
             * Copyright (c) 2006-2007 Nick Sieger <nick@nicksieger.com>
         | 
| 3 | 
            +
             * Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
         | 
| 4 | 
            +
             * 
         | 
| 5 | 
            +
             * Permission is hereby granted, free of charge, to any person obtaining
         | 
| 6 | 
            +
             * a copy of this software and associated documentation files (the
         | 
| 7 | 
            +
             * "Software"), to deal in the Software without restriction, including
         | 
| 8 | 
            +
             * without limitation the rights to use, copy, modify, merge, publish,
         | 
| 9 | 
            +
             * distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 10 | 
            +
             * permit persons to whom the Software is furnished to do so, subject to
         | 
| 11 | 
            +
             * the following conditions:
         | 
| 12 | 
            +
             * 
         | 
| 13 | 
            +
             * The above copyright notice and this permission notice shall be
         | 
| 14 | 
            +
             * included in all copies or substantial portions of the Software.
         | 
| 15 | 
            +
             * 
         | 
| 16 | 
            +
             * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 17 | 
            +
             * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 18 | 
            +
             * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 19 | 
            +
             * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 20 | 
            +
             * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 21 | 
            +
             * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 22 | 
            +
             * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
| 23 | 
            +
             ***** END LICENSE BLOCK *****/
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            package jdbc_adapter;
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            import java.sql.Connection;
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            /**
         | 
| 30 | 
            +
             * Interface to be implemented in Ruby for retrieving a new connection
         | 
| 31 | 
            +
             *  
         | 
| 32 | 
            +
             * @author nicksieger
         | 
| 33 | 
            +
             */
         | 
| 34 | 
            +
            public interface JdbcConnectionFactory {
         | 
| 35 | 
            +
                Connection newConnection();
         | 
| 36 | 
            +
            }
         | 
| @@ -1,31 +1,29 @@ | |
| 1 1 | 
             
            /***** BEGIN LICENSE BLOCK *****
         | 
| 2 | 
            -
             *  | 
| 3 | 
            -
             *
         | 
| 4 | 
            -
             * The contents of this file are subject to the Common Public
         | 
| 5 | 
            -
             * License Version 1.0 (the "License"); you may not use this file
         | 
| 6 | 
            -
             * except in compliance with the License. You may obtain a copy of
         | 
| 7 | 
            -
             * the License at http://www.eclipse.org/legal/cpl-v10.html
         | 
| 8 | 
            -
             *
         | 
| 9 | 
            -
             * Software distributed under the License is distributed on an "AS
         | 
| 10 | 
            -
             * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
         | 
| 11 | 
            -
             * implied. See the License for the specific language governing
         | 
| 12 | 
            -
             * rights and limitations under the License.
         | 
| 13 | 
            -
             *
         | 
| 14 | 
            -
             * Copyright (C) 2007 Ola Bini <ola.bini@gmail.com>
         | 
| 2 | 
            +
             * Copyright (c) 2006-2007 Nick Sieger <nick@nicksieger.com>
         | 
| 3 | 
            +
             * Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
         | 
| 15 4 | 
             
             * 
         | 
| 16 | 
            -
             *  | 
| 17 | 
            -
             *  | 
| 18 | 
            -
             *  | 
| 19 | 
            -
             *  | 
| 20 | 
            -
             *  | 
| 21 | 
            -
             *  | 
| 22 | 
            -
             *  | 
| 23 | 
            -
             *  | 
| 24 | 
            -
             *  | 
| 25 | 
            -
             *  | 
| 26 | 
            -
             *  | 
| 5 | 
            +
             * Permission is hereby granted, free of charge, to any person obtaining
         | 
| 6 | 
            +
             * a copy of this software and associated documentation files (the
         | 
| 7 | 
            +
             * "Software"), to deal in the Software without restriction, including
         | 
| 8 | 
            +
             * without limitation the rights to use, copy, modify, merge, publish,
         | 
| 9 | 
            +
             * distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 10 | 
            +
             * permit persons to whom the Software is furnished to do so, subject to
         | 
| 11 | 
            +
             * the following conditions:
         | 
| 12 | 
            +
             * 
         | 
| 13 | 
            +
             * The above copyright notice and this permission notice shall be
         | 
| 14 | 
            +
             * included in all copies or substantial portions of the Software.
         | 
| 15 | 
            +
             * 
         | 
| 16 | 
            +
             * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 17 | 
            +
             * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 18 | 
            +
             * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 19 | 
            +
             * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 20 | 
            +
             * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 21 | 
            +
             * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 22 | 
            +
             * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
| 27 23 | 
             
             ***** END LICENSE BLOCK *****/
         | 
| 28 24 |  | 
| 25 | 
            +
            package jdbc_adapter;
         | 
| 26 | 
            +
             | 
| 29 27 | 
             
            import org.jruby.Ruby;
         | 
| 30 28 | 
             
            import org.jruby.RubyModule;
         | 
| 31 29 | 
             
            import org.jruby.RubyString;
         | 
| @@ -40,17 +38,18 @@ import org.jruby.RubyNumeric; | |
| 40 38 | 
             
            import org.jruby.runtime.Arity;
         | 
| 41 39 | 
             
            import org.jruby.runtime.CallbackFactory;
         | 
| 42 40 | 
             
            import org.jruby.runtime.MethodIndex;
         | 
| 43 | 
            -
            import org.jruby.runtime.ThreadContext;
         | 
| 44 41 | 
             
            import org.jruby.runtime.builtin.IRubyObject;
         | 
| 45 42 |  | 
| 46 43 | 
             
            import org.jruby.util.ByteList;
         | 
| 47 44 |  | 
| 48 45 | 
             
            import java.sql.SQLException;
         | 
| 46 | 
            +
            import org.jruby.RubyObjectAdapter;
         | 
| 49 47 |  | 
| 50 | 
            -
            public class  | 
| 51 | 
            -
                 | 
| 48 | 
            +
            public class JdbcDerbySpec {
         | 
| 49 | 
            +
                private static RubyObjectAdapter rubyApi;
         | 
| 50 | 
            +
                public static void load(Ruby runtime, RubyModule jdbcSpec, RubyObjectAdapter adapter) {
         | 
| 52 51 | 
             
                    RubyModule derby = jdbcSpec.defineModuleUnder("Derby");
         | 
| 53 | 
            -
                    CallbackFactory cf = runtime.callbackFactory( | 
| 52 | 
            +
                    CallbackFactory cf = runtime.callbackFactory(JdbcDerbySpec.class);
         | 
| 54 53 | 
             
                    derby.defineFastMethod("quote_string",cf.getFastSingletonMethod("quote_string",IRubyObject.class));
         | 
| 55 54 | 
             
                    derby.defineFastMethod("quote",cf.getFastOptSingletonMethod("quote"));
         | 
| 56 55 | 
             
                    derby.defineFastMethod("_execute",cf.getFastOptSingletonMethod("_execute"));
         | 
| @@ -59,6 +58,7 @@ public class JDBCDerbySpec { | |
| 59 58 | 
             
                    derby.defineFastMethod("select_one",cf.getFastOptSingletonMethod("select_one"));
         | 
| 60 59 | 
             
                    RubyModule col = derby.defineModuleUnder("Column");
         | 
| 61 60 | 
             
                    col.defineFastMethod("type_cast",cf.getFastSingletonMethod("type_cast", IRubyObject.class));
         | 
| 61 | 
            +
                    rubyApi = adapter;
         | 
| 62 62 | 
             
                }
         | 
| 63 63 |  | 
| 64 64 | 
             
                /*
         | 
| @@ -67,11 +67,11 @@ public class JDBCDerbySpec { | |
| 67 67 | 
             
                public static IRubyObject type_cast(IRubyObject recv, IRubyObject value) {
         | 
| 68 68 | 
             
                    Ruby runtime = recv.getRuntime();
         | 
| 69 69 |  | 
| 70 | 
            -
                    if(value.isNil() || ((value instanceof RubyString) && value.toString().trim().equalsIgnoreCase("null"))) {
         | 
| 70 | 
            +
                    if (value.isNil() || ((value instanceof RubyString) && value.toString().trim().equalsIgnoreCase("null"))) {
         | 
| 71 71 | 
             
                        return runtime.getNil();
         | 
| 72 72 | 
             
                    }
         | 
| 73 73 |  | 
| 74 | 
            -
                    String type =  | 
| 74 | 
            +
                    String type = rubyApi.getInstanceVariable(recv,"@type").toString();
         | 
| 75 75 |  | 
| 76 76 | 
             
                    switch(type.charAt(0)) {
         | 
| 77 77 | 
             
                    case 's': //string
         | 
| @@ -80,30 +80,30 @@ public class JDBCDerbySpec { | |
| 80 80 | 
             
                        if(type.equals("text")) {
         | 
| 81 81 | 
             
                            return value;
         | 
| 82 82 | 
             
                        } else {
         | 
| 83 | 
            -
                            return  | 
| 83 | 
            +
                            return rubyApi.callMethod(recv, "cast_to_time", value);
         | 
| 84 84 | 
             
                        }
         | 
| 85 85 | 
             
                    case 'i': //integer
         | 
| 86 86 | 
             
                    case 'p': //primary key
         | 
| 87 | 
            -
                        if(value.respondsTo("to_i")) {
         | 
| 88 | 
            -
                            return  | 
| 87 | 
            +
                        if (value.respondsTo("to_i")) {
         | 
| 88 | 
            +
                            return rubyApi.callMethod(value, "to_i");
         | 
| 89 89 | 
             
                        } else {
         | 
| 90 | 
            -
                            return runtime.newFixnum( | 
| 90 | 
            +
                            return runtime.newFixnum(value.isTrue() ? 1 : 0 );
         | 
| 91 91 | 
             
                        }
         | 
| 92 92 | 
             
                    case 'd': //decimal, datetime, date
         | 
| 93 93 | 
             
                        if(type.equals("datetime")) {
         | 
| 94 | 
            -
                            return  | 
| 94 | 
            +
                            return rubyApi.callMethod(recv, "cast_to_date_or_time", value);
         | 
| 95 95 | 
             
                        } else if(type.equals("date")) {
         | 
| 96 | 
            -
                            return  | 
| 96 | 
            +
                            return rubyApi.callMethod(recv.getMetaClass(), "string_to_date", value);
         | 
| 97 97 | 
             
                        } else {
         | 
| 98 | 
            -
                            return  | 
| 98 | 
            +
                            return rubyApi.callMethod(recv.getMetaClass(), "value_to_decimal", value);
         | 
| 99 99 | 
             
                        }
         | 
| 100 100 | 
             
                    case 'f': //float
         | 
| 101 | 
            -
                        return  | 
| 101 | 
            +
                        return rubyApi.callMethod(value,"to_f");
         | 
| 102 102 | 
             
                    case 'b': //binary, boolean
         | 
| 103 | 
            -
                        if(type.equals("binary")) {
         | 
| 104 | 
            -
                            return  | 
| 103 | 
            +
                        if (type.equals("binary")) {
         | 
| 104 | 
            +
                            return rubyApi.callMethod(recv, "value_to_binary", value);
         | 
| 105 105 | 
             
                        } else {
         | 
| 106 | 
            -
                            return  | 
| 106 | 
            +
                            return rubyApi.callMethod(recv.getMetaClass(), "value_to_boolean", value);
         | 
| 107 107 | 
             
                        }
         | 
| 108 108 | 
             
                    }
         | 
| 109 109 | 
             
                    return value;
         | 
| @@ -113,26 +113,26 @@ public class JDBCDerbySpec { | |
| 113 113 | 
             
                    Ruby runtime = recv.getRuntime();
         | 
| 114 114 | 
             
                    Arity.checkArgumentCount(runtime, args, 1, 2);
         | 
| 115 115 | 
             
                    IRubyObject value = args[0];
         | 
| 116 | 
            -
                    if(args.length > 1) {
         | 
| 116 | 
            +
                    if (args.length > 1) {
         | 
| 117 117 | 
             
                        IRubyObject col = args[1];
         | 
| 118 | 
            -
                        IRubyObject type =  | 
| 119 | 
            -
                        if(value instanceof RubyString) {
         | 
| 120 | 
            -
                            if(type == runtime.newSymbol("string")) {
         | 
| 118 | 
            +
                        IRubyObject type = rubyApi.callMethod(col, "type");
         | 
| 119 | 
            +
                        if (value instanceof RubyString) {
         | 
| 120 | 
            +
                            if (type == runtime.newSymbol("string")) {
         | 
| 121 121 | 
             
                                return quote_string_with_surround(runtime, "'", (RubyString)value, "'");
         | 
| 122 | 
            -
                            } else if(type == runtime.newSymbol("text")) {
         | 
| 122 | 
            +
                            } else if (type == runtime.newSymbol("text")) {
         | 
| 123 123 | 
             
                                return quote_string_with_surround(runtime, "CAST('", (RubyString)value, "' AS CLOB)");
         | 
| 124 | 
            -
                            } else if(type == runtime.newSymbol("binary")) {
         | 
| 124 | 
            +
                            } else if (type == runtime.newSymbol("binary")) {
         | 
| 125 125 | 
             
                                return hexquote_string_with_surround(runtime, "CAST('", (RubyString)value, "' AS BLOB)");
         | 
| 126 126 | 
             
                            } else {
         | 
| 127 127 | 
             
                                // column type :integer or other numeric or date version
         | 
| 128 | 
            -
                                if(only_digits((RubyString)value)) {
         | 
| 128 | 
            +
                                if (only_digits((RubyString)value)) {
         | 
| 129 129 | 
             
                                    return value;
         | 
| 130 130 | 
             
                                } else {
         | 
| 131 131 | 
             
                                    return super_quote(recv, runtime, value, col);
         | 
| 132 132 | 
             
                                }
         | 
| 133 133 | 
             
                            }
         | 
| 134 | 
            -
                        } else if((value instanceof RubyFloat) || (value instanceof RubyFixnum) || (value instanceof RubyBignum)) {
         | 
| 135 | 
            -
                            if(type == runtime.newSymbol("string")) {
         | 
| 134 | 
            +
                        } else if ((value instanceof RubyFloat) || (value instanceof RubyFixnum) || (value instanceof RubyBignum)) {
         | 
| 135 | 
            +
                            if (type == runtime.newSymbol("string")) {
         | 
| 136 136 | 
             
                                return quote_string_with_surround(runtime, "'", RubyString.objAsString(value), "'");
         | 
| 137 137 | 
             
                            }
         | 
| 138 138 | 
             
                        }
         | 
| @@ -143,39 +143,40 @@ public class JDBCDerbySpec { | |
| 143 143 | 
             
                private final static ByteList NULL = new ByteList("NULL".getBytes());
         | 
| 144 144 |  | 
| 145 145 | 
             
                public static IRubyObject super_quote(IRubyObject recv, Ruby runtime, IRubyObject value, IRubyObject col) {
         | 
| 146 | 
            -
                    if(value.respondsTo("quoted_id")) {
         | 
| 147 | 
            -
                        return  | 
| 146 | 
            +
                    if (value.respondsTo("quoted_id")) {
         | 
| 147 | 
            +
                        return rubyApi.callMethod(value, "quoted_id");
         | 
| 148 148 | 
             
                    }
         | 
| 149 149 |  | 
| 150 | 
            -
                    IRubyObject type = (col.isNil()) ? col :  | 
| 151 | 
            -
                     | 
| 152 | 
            -
             | 
| 150 | 
            +
                    IRubyObject type = (col.isNil()) ? col : rubyApi.callMethod(col, "type");
         | 
| 151 | 
            +
                    RubyModule multibyteChars = (RubyModule) 
         | 
| 152 | 
            +
                            ((RubyModule) ((RubyModule) runtime.getModule("ActiveSupport")).getConstant("Multibyte")).getConstantAt("Chars");
         | 
| 153 | 
            +
                    if (value instanceof RubyString || rubyApi.isKindOf(value, multibyteChars)) {
         | 
| 153 154 | 
             
                        RubyString svalue = RubyString.objAsString(value);
         | 
| 154 | 
            -
                        if(type == runtime.newSymbol("binary") && col.getType().respondsTo("string_to_binary")) {
         | 
| 155 | 
            -
                            return quote_string_with_surround(runtime, "'", (RubyString)( | 
| 156 | 
            -
                        } else if(type == runtime.newSymbol("integer") || type == runtime.newSymbol("float")) {
         | 
| 155 | 
            +
                        if (type == runtime.newSymbol("binary") && col.getType().respondsTo("string_to_binary")) {
         | 
| 156 | 
            +
                            return quote_string_with_surround(runtime, "'", (RubyString)(rubyApi.callMethod(col.getType(), "string_to_binary", svalue)), "'"); 
         | 
| 157 | 
            +
                        } else if (type == runtime.newSymbol("integer") || type == runtime.newSymbol("float")) {
         | 
| 157 158 | 
             
                            return RubyString.objAsString(((type == runtime.newSymbol("integer")) ? 
         | 
| 158 | 
            -
                                                            | 
| 159 | 
            -
                                                            | 
| 159 | 
            +
                                                           rubyApi.callMethod(svalue, "to_i") : 
         | 
| 160 | 
            +
                                                           rubyApi.callMethod(svalue, "to_f")));
         | 
| 160 161 | 
             
                        } else {
         | 
| 161 162 | 
             
                            return quote_string_with_surround(runtime, "'", svalue, "'"); 
         | 
| 162 163 | 
             
                        }
         | 
| 163 | 
            -
                    } else if(value.isNil()) {
         | 
| 164 | 
            +
                    } else if (value.isNil()) {
         | 
| 164 165 | 
             
                        return runtime.newStringShared(NULL);
         | 
| 165 | 
            -
                    } else if(value instanceof RubyBoolean) {
         | 
| 166 | 
            +
                    } else if (value instanceof RubyBoolean) {
         | 
| 166 167 | 
             
                        return (value.isTrue() ? 
         | 
| 167 | 
            -
                                (type == runtime.newSymbol(":integer")) ? runtime.newString("1") :  | 
| 168 | 
            -
                                (type == runtime.newSymbol(":integer")) ? runtime.newString("0") :  | 
| 168 | 
            +
                                (type == runtime.newSymbol(":integer")) ? runtime.newString("1") : rubyApi.callMethod(recv, "quoted_true") :
         | 
| 169 | 
            +
                                (type == runtime.newSymbol(":integer")) ? runtime.newString("0") : rubyApi.callMethod(recv, "quoted_false"));
         | 
| 169 170 | 
             
                    } else if((value instanceof RubyFloat) || (value instanceof RubyFixnum) || (value instanceof RubyBignum)) {
         | 
| 170 171 | 
             
                        return RubyString.objAsString(value);
         | 
| 171 172 | 
             
                    } else if(value instanceof RubyBigDecimal) {
         | 
| 172 | 
            -
                        return  | 
| 173 | 
            -
                    } else if( | 
| 173 | 
            +
                        return rubyApi.callMethod(value, "to_s", runtime.newString("F"));
         | 
| 174 | 
            +
                    } else if (rubyApi.isKindOf(value, runtime.getModule("Date"))) {
         | 
| 174 175 | 
             
                        return quote_string_with_surround(runtime, "'", RubyString.objAsString(value), "'"); 
         | 
| 175 | 
            -
                    } else if( | 
| 176 | 
            -
                        return quote_string_with_surround(runtime, "'", (RubyString)( | 
| 176 | 
            +
                    } else if (rubyApi.isKindOf(value, runtime.getModule("Time")) || rubyApi.isKindOf(value, runtime.getModule("DateTime"))) {
         | 
| 177 | 
            +
                        return quote_string_with_surround(runtime, "'", (RubyString)(rubyApi.callMethod(recv, "quoted_date", value)), "'"); 
         | 
| 177 178 | 
             
                    } else {
         | 
| 178 | 
            -
                        return quote_string_with_surround(runtime, "'", (RubyString)( | 
| 179 | 
            +
                        return quote_string_with_surround(runtime, "'", (RubyString)(rubyApi.callMethod(value, "to_yaml")), "'");
         | 
| 179 180 | 
             
                    }
         | 
| 180 181 | 
             
                }
         | 
| 181 182 |  | 
| @@ -259,55 +260,58 @@ public class JDBCDerbySpec { | |
| 259 260 | 
             
                }
         | 
| 260 261 |  | 
| 261 262 | 
             
                public static IRubyObject select_all(IRubyObject recv, IRubyObject[] args) {
         | 
| 262 | 
            -
                    return  | 
| 263 | 
            +
                    return rubyApi.callMethod(recv, "execute", args);
         | 
| 263 264 | 
             
                }
         | 
| 264 265 |  | 
| 265 266 | 
             
                public static IRubyObject select_one(IRubyObject recv, IRubyObject[] args) {
         | 
| 266 | 
            -
                    IRubyObject limit =  | 
| 267 | 
            -
                    if(limit == null || limit.isNil()) {
         | 
| 268 | 
            -
                         | 
| 267 | 
            +
                    IRubyObject limit = rubyApi.getInstanceVariable(recv, "@limit");
         | 
| 268 | 
            +
                    if (limit == null || limit.isNil()) {
         | 
| 269 | 
            +
                        rubyApi.setInstanceVariable(recv, "@limit", recv.getRuntime().newFixnum(1));
         | 
| 269 270 | 
             
                    }
         | 
| 270 271 | 
             
                    try {
         | 
| 271 | 
            -
                         | 
| 272 | 
            +
                        IRubyObject result = rubyApi.callMethod(recv, "execute", args);
         | 
| 273 | 
            +
                        return rubyApi.callMethod(result, "first");
         | 
| 272 274 | 
             
                    } finally {
         | 
| 273 | 
            -
                         | 
| 275 | 
            +
                        rubyApi.setInstanceVariable(recv, "@limit", recv.getRuntime().getNil());
         | 
| 274 276 | 
             
                    }
         | 
| 275 277 | 
             
                }
         | 
| 276 278 |  | 
| 277 279 | 
             
                public static IRubyObject add_limit_offset(IRubyObject recv, IRubyObject sql, IRubyObject options) {
         | 
| 278 | 
            -
                     | 
| 279 | 
            -
                     | 
| 280 | 
            +
                    IRubyObject limit = rubyApi.callMethod(options, "[]", recv.getRuntime().newSymbol("limit"));
         | 
| 281 | 
            +
                    rubyApi.setInstanceVariable(recv, "@limit",limit);
         | 
| 282 | 
            +
                    IRubyObject offset = rubyApi.callMethod(options, "[]", recv.getRuntime().newSymbol("offset"));
         | 
| 283 | 
            +
                    return rubyApi.setInstanceVariable(recv, "@offset",offset);
         | 
| 280 284 | 
             
                }
         | 
| 281 285 |  | 
| 282 286 | 
             
                public static IRubyObject _execute(IRubyObject recv, IRubyObject[] args) throws SQLException, java.io.IOException {
         | 
| 283 287 | 
             
                    Ruby runtime = recv.getRuntime();
         | 
| 284 288 | 
             
                    try {
         | 
| 285 | 
            -
                        IRubyObject conn =  | 
| 289 | 
            +
                        IRubyObject conn = rubyApi.getInstanceVariable(recv, "@connection");
         | 
| 286 290 | 
             
                        String sql = args[0].toString().trim().toLowerCase();
         | 
| 287 | 
            -
                        if(sql.charAt(0) == '(') {
         | 
| 291 | 
            +
                        if (sql.charAt(0) == '(') {
         | 
| 288 292 | 
             
                            sql = sql.substring(1).trim();
         | 
| 289 293 | 
             
                        }
         | 
| 290 | 
            -
                        if(sql.startsWith("insert")) {
         | 
| 294 | 
            +
                        if (sql.startsWith("insert")) {
         | 
| 291 295 | 
             
                            return JdbcAdapterInternalService.execute_insert(conn, args[0]);
         | 
| 292 | 
            -
                        } else if(sql.startsWith("select") || sql.startsWith("show")) {
         | 
| 293 | 
            -
                            IRubyObject offset =  | 
| 296 | 
            +
                        } else if (sql.startsWith("select") || sql.startsWith("show")) {
         | 
| 297 | 
            +
                            IRubyObject offset = rubyApi.getInstanceVariable(recv, "@offset");
         | 
| 294 298 | 
             
                            if(offset == null || offset.isNil()) {
         | 
| 295 299 | 
             
                                offset = RubyFixnum.zero(runtime);
         | 
| 296 300 | 
             
                            }
         | 
| 297 | 
            -
                            IRubyObject limit =  | 
| 301 | 
            +
                            IRubyObject limit = rubyApi.getInstanceVariable(recv, "@limit");
         | 
| 298 302 | 
             
                            IRubyObject range;
         | 
| 299 303 | 
             
                            IRubyObject max;
         | 
| 300 | 
            -
                            if(limit == null || limit.isNil() || RubyNumeric.fix2int(limit) == -1) {
         | 
| 304 | 
            +
                            if (limit == null || limit.isNil() || RubyNumeric.fix2int(limit) == -1) {
         | 
| 301 305 | 
             
                                range = RubyRange.newRange(runtime, offset, runtime.newFixnum(-1), false);
         | 
| 302 306 | 
             
                                max = RubyFixnum.zero(runtime);
         | 
| 303 307 | 
             
                            } else {
         | 
| 304 | 
            -
                                IRubyObject v1 =  | 
| 308 | 
            +
                                IRubyObject v1 = rubyApi.callMethod(offset, "+", limit);
         | 
| 305 309 | 
             
                                range = RubyRange.newRange(runtime, offset, v1, true);
         | 
| 306 | 
            -
                                max =  | 
| 310 | 
            +
                                max = rubyApi.callMethod(v1, "+", RubyFixnum.one(runtime));
         | 
| 307 311 | 
             
                            }
         | 
| 308 | 
            -
                            IRubyObject  | 
| 309 | 
            -
             | 
| 310 | 
            -
                            if(ret.isNil()) {
         | 
| 312 | 
            +
                            IRubyObject result = JdbcAdapterInternalService.execute_query(conn, new IRubyObject[]{args[0], max});
         | 
| 313 | 
            +
                            IRubyObject ret = rubyApi.callMethod(result, "[]", range);
         | 
| 314 | 
            +
                            if (ret.isNil()) {
         | 
| 311 315 | 
             
                                return runtime.newArray();
         | 
| 312 316 | 
             
                            } else {
         | 
| 313 317 | 
             
                                return ret;
         | 
| @@ -316,8 +320,8 @@ public class JDBCDerbySpec { | |
| 316 320 | 
             
                            return JdbcAdapterInternalService.execute_update(conn, args[0]);
         | 
| 317 321 | 
             
                        }
         | 
| 318 322 | 
             
                    } finally {
         | 
| 319 | 
            -
                         | 
| 320 | 
            -
                         | 
| 323 | 
            +
                        rubyApi.setInstanceVariable(recv, "@limit", runtime.getNil());
         | 
| 324 | 
            +
                        rubyApi.setInstanceVariable(recv, "@offset", runtime.getNil());
         | 
| 321 325 | 
             
                    }
         | 
| 322 326 | 
             
                }
         | 
| 323 327 | 
             
            }
         | 
| @@ -1,45 +1,42 @@ | |
| 1 1 | 
             
            /***** BEGIN LICENSE BLOCK *****
         | 
| 2 | 
            -
             *  | 
| 3 | 
            -
             *
         | 
| 4 | 
            -
             * The contents of this file are subject to the Common Public
         | 
| 5 | 
            -
             * License Version 1.0 (the "License"); you may not use this file
         | 
| 6 | 
            -
             * except in compliance with the License. You may obtain a copy of
         | 
| 7 | 
            -
             * the License at http://www.eclipse.org/legal/cpl-v10.html
         | 
| 8 | 
            -
             *
         | 
| 9 | 
            -
             * Software distributed under the License is distributed on an "AS
         | 
| 10 | 
            -
             * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
         | 
| 11 | 
            -
             * implied. See the License for the specific language governing
         | 
| 12 | 
            -
             * rights and limitations under the License.
         | 
| 13 | 
            -
             *
         | 
| 14 | 
            -
             * Copyright (C) 2007 Ola Bini <ola.bini@gmail.com>
         | 
| 2 | 
            +
             * Copyright (c) 2006-2007 Nick Sieger <nick@nicksieger.com>
         | 
| 3 | 
            +
             * Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
         | 
| 15 4 | 
             
             * 
         | 
| 16 | 
            -
             *  | 
| 17 | 
            -
             *  | 
| 18 | 
            -
             *  | 
| 19 | 
            -
             *  | 
| 20 | 
            -
             *  | 
| 21 | 
            -
             *  | 
| 22 | 
            -
             *  | 
| 23 | 
            -
             *  | 
| 24 | 
            -
             *  | 
| 25 | 
            -
             *  | 
| 26 | 
            -
             *  | 
| 5 | 
            +
             * Permission is hereby granted, free of charge, to any person obtaining
         | 
| 6 | 
            +
             * a copy of this software and associated documentation files (the
         | 
| 7 | 
            +
             * "Software"), to deal in the Software without restriction, including
         | 
| 8 | 
            +
             * without limitation the rights to use, copy, modify, merge, publish,
         | 
| 9 | 
            +
             * distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 10 | 
            +
             * permit persons to whom the Software is furnished to do so, subject to
         | 
| 11 | 
            +
             * the following conditions:
         | 
| 12 | 
            +
             * 
         | 
| 13 | 
            +
             * The above copyright notice and this permission notice shall be
         | 
| 14 | 
            +
             * included in all copies or substantial portions of the Software.
         | 
| 15 | 
            +
             * 
         | 
| 16 | 
            +
             * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 17 | 
            +
             * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 18 | 
            +
             * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 19 | 
            +
             * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 20 | 
            +
             * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 21 | 
            +
             * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 22 | 
            +
             * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
| 27 23 | 
             
             ***** END LICENSE BLOCK *****/
         | 
| 28 24 |  | 
| 25 | 
            +
            package jdbc_adapter;
         | 
| 26 | 
            +
             | 
| 29 27 | 
             
            import org.jruby.Ruby;
         | 
| 30 28 | 
             
            import org.jruby.RubyModule;
         | 
| 31 29 | 
             
            import org.jruby.RubyString;
         | 
| 32 30 |  | 
| 33 31 | 
             
            import org.jruby.runtime.CallbackFactory;
         | 
| 34 | 
            -
            import org.jruby.runtime.ThreadContext;
         | 
| 35 32 | 
             
            import org.jruby.runtime.builtin.IRubyObject;
         | 
| 36 33 |  | 
| 37 34 | 
             
            import org.jruby.util.ByteList;
         | 
| 38 35 |  | 
| 39 | 
            -
            public class  | 
| 36 | 
            +
            public class JdbcMySQLSpec {
         | 
| 40 37 | 
             
                public static void load(Ruby runtime, RubyModule jdbcSpec) {
         | 
| 41 38 | 
             
                    RubyModule mysql = jdbcSpec.defineModuleUnder("MySQL");
         | 
| 42 | 
            -
                    CallbackFactory cf = runtime.callbackFactory( | 
| 39 | 
            +
                    CallbackFactory cf = runtime.callbackFactory(JdbcMySQLSpec.class);
         | 
| 43 40 | 
             
                    mysql.defineFastMethod("quote_string",cf.getFastSingletonMethod("quote_string",IRubyObject.class));
         | 
| 44 41 | 
             
                }
         | 
| 45 42 |  | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            /*
         | 
| 2 | 
            +
             * To change this template, choose Tools | Templates
         | 
| 3 | 
            +
             * and open the template in the editor.
         | 
| 4 | 
            +
             */
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            package jdbc_adapter;
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            import java.sql.Connection;
         | 
| 9 | 
            +
            import java.sql.SQLException;
         | 
| 10 | 
            +
            import org.jruby.runtime.builtin.IRubyObject;
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            /**
         | 
| 13 | 
            +
             *
         | 
| 14 | 
            +
             * @author nicksieger
         | 
| 15 | 
            +
             */
         | 
| 16 | 
            +
            public interface SQLBlock {
         | 
| 17 | 
            +
                IRubyObject call(Connection c) throws SQLException;
         | 
| 18 | 
            +
            }
         | 
| @@ -0,0 +1,72 @@ | |
| 1 | 
            +
            class CreateRbac < ActiveRecord::Migration
         | 
| 2 | 
            +
              def self.up
         | 
| 3 | 
            +
                create_table :role_assignments do |t| 
         | 
| 4 | 
            +
                  t.column :role_id, :integer
         | 
| 5 | 
            +
                  t.column :user_id, :integer
         | 
| 6 | 
            +
                end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                create_table :roles do |t| 
         | 
| 9 | 
            +
                  t.column :name, :string
         | 
| 10 | 
            +
                  t.column :description, :string
         | 
| 11 | 
            +
                end 
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                create_table :permission_groups do |t|
         | 
| 14 | 
            +
                  t.column :right_id, :integer
         | 
| 15 | 
            +
                  t.column :role_id, :integer
         | 
| 16 | 
            +
                end 
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                create_table :rights do |t| 
         | 
| 19 | 
            +
                  t.column :name, :string
         | 
| 20 | 
            +
                  t.column :controller_name, :string
         | 
| 21 | 
            +
                  t.column :actions, :string
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              def self.down
         | 
| 26 | 
            +
                drop_table :role_assignments
         | 
| 27 | 
            +
                drop_table :roles
         | 
| 28 | 
            +
                drop_table :permission_groups
         | 
| 29 | 
            +
                drop_table :rights
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            class Right < ActiveRecord::Base
         | 
| 34 | 
            +
              has_many :permission_groups, :dependent => :destroy
         | 
| 35 | 
            +
              has_many :roles, :through => :permission_groups
         | 
| 36 | 
            +
            end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            class Role < ActiveRecord::Base
         | 
| 39 | 
            +
              has_many :permission_groups, :dependent => :destroy
         | 
| 40 | 
            +
              has_many :rights, :through => :permission_groups
         | 
| 41 | 
            +
              has_many :role_assignments, :dependent => :destroy
         | 
| 42 | 
            +
            end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            class PermissionGroup < ActiveRecord::Base
         | 
| 45 | 
            +
              belongs_to :right
         | 
| 46 | 
            +
              belongs_to :role
         | 
| 47 | 
            +
            end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            class RoleAssignment < ActiveRecord::Base
         | 
| 50 | 
            +
              belongs_to :user
         | 
| 51 | 
            +
              belongs_to :role
         | 
| 52 | 
            +
            end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            module HasManyThroughMethods
         | 
| 55 | 
            +
              def setup
         | 
| 56 | 
            +
                CreateRbac.up
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              def teardown
         | 
| 60 | 
            +
                CreateRbac.down
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              def test_has_many_through
         | 
| 64 | 
            +
                role_rights   = Right.create( {:name => "Administrator - Full Access To Roles", :actions => "*", :controller_name => "Admin::RolesController"} )
         | 
| 65 | 
            +
                right_rights  = Right.create( {:name => "Administrator - Full Access To Rights", :actions => "*", :controller_name => "Admin::RightsController"} )
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                admin_role    = Role.create( {:name => "Administrator", :description => "System defined super user - access to right and role management."} )
         | 
| 68 | 
            +
                admin_role.rights << role_rights
         | 
| 69 | 
            +
                admin_role.rights << right_rights
         | 
| 70 | 
            +
                admin_role.save
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
            end
         |