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
|