ActiveRecord-JDBC 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/init.rb +8 -0
- data/install.rb +25 -0
- data/lib/active_record/connection_adapters/jdbc_adapter.rb +358 -0
- data/test/activerecord/connections/native_jdbc_mysql/connection.rb +25 -0
- data/test/activerecord/jall.sh +7 -0
- data/test/activerecord/jtest.sh +3 -0
- data/test/minirunit.rb +109 -0
- data/test/minirunit/testConnect.rb +14 -0
- data/test/minirunit/testHsqldb.rb +71 -0
- data/test/minirunit/testLoadActiveRecord.rb +3 -0
- data/test/minirunit/testMysql.rb +83 -0
- data/test/minirunit/testRawSelect.rb +24 -0
- metadata +63 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2006 Nick Sieger <nick@nicksieger.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/init.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
RAILS_CONNECTION_ADAPTERS << 'jdbc'
|
2
|
+
require 'active_record/connection_adapters/jdbc_adapter'
|
3
|
+
|
4
|
+
[:initialize_database, :initialize_framework_logging, :initialize_framework_settings].each do |cmd|
|
5
|
+
Rails::Initializer.run(cmd) do |config|
|
6
|
+
config.frameworks = [:active_record]
|
7
|
+
end
|
8
|
+
end
|
data/install.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
from_d=File.expand_path(File.join(File.dirname(__FILE__),'lib','active_record'))
|
5
|
+
to_d=File.expand_path(File.join(RAILS_ROOT,'lib','active_record'))
|
6
|
+
|
7
|
+
FileUtils.cp_r from_d, to_d
|
8
|
+
|
9
|
+
env_file = File.expand_path(File.join(RAILS_ROOT,"config","environment.rb"))
|
10
|
+
bck_file = File.expand_path(File.join(RAILS_ROOT,"config","~.environment.rb.before_jdbc"))
|
11
|
+
|
12
|
+
FileUtils.mv env_file,bck_file
|
13
|
+
|
14
|
+
File.open(bck_file,"r") {|inf|
|
15
|
+
File.open(env_file,"w") {|out|
|
16
|
+
inf.each_line do |ln|
|
17
|
+
if ln =~ /^Rails::Initializer\.run/
|
18
|
+
out.puts "# Added by ActiveRecord JDBC plugin"
|
19
|
+
out.puts "RAILS_CONNECTION_ADAPTERS = %w( jdbc mysql postgresql sqlite firebird sqlserver db2 oracle sybase openbase )"
|
20
|
+
out.puts
|
21
|
+
end
|
22
|
+
out.puts ln
|
23
|
+
end
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,358 @@
|
|
1
|
+
require 'active_record/connection_adapters/abstract_adapter'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
class Base
|
5
|
+
def self.jdbc_connection(config)
|
6
|
+
ConnectionAdapters::JdbcAdapter.new(ConnectionAdapters::JdbcConnection.new(config), logger, config)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module ConnectionAdapters
|
11
|
+
module Jdbc
|
12
|
+
require 'java'
|
13
|
+
include_class 'java.sql.DriverManager'
|
14
|
+
include_class 'java.sql.Statement'
|
15
|
+
include_class 'java.sql.Types'
|
16
|
+
end
|
17
|
+
|
18
|
+
# I want to use JDBC's DatabaseMetaData#getTypeInfo to choose the best native types to
|
19
|
+
# use for ActiveRecord's Adapter#native_database_types in a database-independent way,
|
20
|
+
# but apparently a database driver can return multiple types for a given
|
21
|
+
# java.sql.Types constant. So this type converter uses some heuristics to try to pick
|
22
|
+
# the best (most common) type to use. It's not great, it would be better to just
|
23
|
+
# delegate to each database's existin AR adapter's native_database_types method, but I
|
24
|
+
# wanted to try to do this in a way that didn't pull in all the other adapters as
|
25
|
+
# dependencies. Suggestions appreciated.
|
26
|
+
class JdbcTypeConverter
|
27
|
+
# The basic ActiveRecord types, mapped to an array of procs that are used to #select
|
28
|
+
# the best type. The procs are used as selectors in order until there is only one
|
29
|
+
# type left. If all the selectors are applied and there is still more than one
|
30
|
+
# type, an exception will be raised.
|
31
|
+
AR_TO_JDBC_TYPES = {
|
32
|
+
:string => [ proc {|r| Jdbc::Types::VARCHAR == r['data_type']},
|
33
|
+
proc {|r| r['type_name'] =~ /^varchar/i} ],
|
34
|
+
:text => [ proc {|r| [Jdbc::Types::LONGVARCHAR, Jdbc::Types::CLOB].include?(r['data_type'])},
|
35
|
+
proc {|r| r['type_name'] =~ /^(text|clob)/i} ],
|
36
|
+
:integer => [ proc {|r| Jdbc::Types::INTEGER == r['data_type']},
|
37
|
+
proc {|r| r['type_name'] =~ /^integer/i} ],
|
38
|
+
:float => [ proc {|r| [Jdbc::Types::FLOAT,Jdbc::Types::DOUBLE].include?(r['data_type'])},
|
39
|
+
proc {|r| r['type_name'] =~ /^float/i},
|
40
|
+
proc {|r| r['type_name'] =~ /^double$/i} ],
|
41
|
+
:datetime => [ proc {|r| Jdbc::Types::TIMESTAMP == r['data_type']},
|
42
|
+
proc {|r| r['type_name'] =~ /^datetime/i} ],
|
43
|
+
:timestamp => [ proc {|r| Jdbc::Types::TIMESTAMP == r['data_type']},
|
44
|
+
proc {|r| r['type_name'] =~ /^timestamp/i},
|
45
|
+
proc {|r| r['type_name'] =~ /^datetime/i} ],
|
46
|
+
:time => [ proc {|r| Jdbc::Types::TIME == r['data_type']} ],
|
47
|
+
:date => [ proc {|r| Jdbc::Types::DATE == r['data_type']} ],
|
48
|
+
:binary => [ proc {|r| Jdbc::Types::LONGVARBINARY == r['data_type']},
|
49
|
+
proc {|r| r['type_name'] =~ /^blob/i} ],
|
50
|
+
:boolean => [ proc {|r| Jdbc::Types::TINYINT == r['data_type']} ]
|
51
|
+
}
|
52
|
+
|
53
|
+
def initialize(types)
|
54
|
+
@types = types
|
55
|
+
end
|
56
|
+
|
57
|
+
def choose_best_types
|
58
|
+
type_map = {}
|
59
|
+
AR_TO_JDBC_TYPES.each_key do |k|
|
60
|
+
typerow = choose_type(k)
|
61
|
+
type_map[k] = { :name => typerow['type_name'] }
|
62
|
+
type_map[k][:limit] = typerow['precision'] if [:integer,:string].include?(k)
|
63
|
+
type_map[k][:limit] = 1 if k == :boolean
|
64
|
+
end
|
65
|
+
type_map
|
66
|
+
end
|
67
|
+
|
68
|
+
def choose_type(ar_type)
|
69
|
+
procs = AR_TO_JDBC_TYPES[ar_type]
|
70
|
+
types = @types
|
71
|
+
procs.each do |p|
|
72
|
+
new_types = types.select(&p)
|
73
|
+
return new_types.first if new_types.length == 1
|
74
|
+
types = new_types if new_types.length > 0
|
75
|
+
end
|
76
|
+
raise "unable to choose type from: #{types.collect{|t| t['type_name']}.inspect}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class JdbcDriver
|
81
|
+
def self.load(driver)
|
82
|
+
driver_class_const = (driver[0...1].capitalize + driver[1..driver.length]).gsub(/\./, '_')
|
83
|
+
unless Jdbc.const_defined?(driver_class_const)
|
84
|
+
Jdbc.module_eval do
|
85
|
+
include_class(driver) {|p,c| driver_class_const }
|
86
|
+
end
|
87
|
+
driver_class = Jdbc.const_get(driver_class_const.to_sym)
|
88
|
+
Jdbc::DriverManager.registerDriver(driver_class.new)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class JdbcConnection
|
94
|
+
def initialize(config)
|
95
|
+
config = config.symbolize_keys
|
96
|
+
driver = config[:driver].to_s
|
97
|
+
user = config[:username].to_s
|
98
|
+
pass = config[:password].to_s
|
99
|
+
url = config[:url].to_s
|
100
|
+
|
101
|
+
unless driver && url
|
102
|
+
raise ArgumentError, "jdbc adapter requires driver class and url"
|
103
|
+
end
|
104
|
+
|
105
|
+
JdbcDriver.load(driver)
|
106
|
+
@connection = Jdbc::DriverManager.getConnection(url, user, pass)
|
107
|
+
set_native_database_types
|
108
|
+
end
|
109
|
+
|
110
|
+
def set_native_database_types
|
111
|
+
types = unmarshal_result(@connection.getMetaData.getTypeInfo)
|
112
|
+
@native_types = JdbcTypeConverter.new(types).choose_best_types
|
113
|
+
end
|
114
|
+
|
115
|
+
def native_database_types
|
116
|
+
types = {
|
117
|
+
# TODO: this is copied from MySQL -- figure out how to
|
118
|
+
# generalize the primary key type
|
119
|
+
:primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY",
|
120
|
+
}
|
121
|
+
@native_types.each_pair {|k,v| types[k] = v.inject({}) {|memo,kv| memo.merge({kv.first => kv.last.dup})}}
|
122
|
+
types
|
123
|
+
end
|
124
|
+
|
125
|
+
def columns(table_name, name = nil)
|
126
|
+
metadata = @connection.getMetaData
|
127
|
+
results = metadata.getColumns(nil, nil, table_name, nil)
|
128
|
+
columns = []
|
129
|
+
unmarshal_result(results).each do |col|
|
130
|
+
columns << ActiveRecord::ConnectionAdapters::Column.new(col['column_name'], col['column_def'],
|
131
|
+
"#{col['type_name']}(#{col['column_size']})", col['is_nullable'] != 'NO')
|
132
|
+
end
|
133
|
+
columns
|
134
|
+
end
|
135
|
+
|
136
|
+
def tables
|
137
|
+
metadata = @connection.getMetaData
|
138
|
+
results = metadata.getTables(nil, nil, nil, nil)
|
139
|
+
unmarshal_result(results).collect {|t| t['table_name']}
|
140
|
+
end
|
141
|
+
|
142
|
+
def execute_insert(sql, pk)
|
143
|
+
stmt = @connection.createStatement
|
144
|
+
stmt.executeUpdate(sql, Jdbc::Statement::RETURN_GENERATED_KEYS)
|
145
|
+
row = unmarshal_result(stmt.getGeneratedKeys)
|
146
|
+
row.first && row.first.values.first
|
147
|
+
ensure
|
148
|
+
stmt.close
|
149
|
+
end
|
150
|
+
|
151
|
+
def execute_update(sql)
|
152
|
+
stmt = @connection.createStatement
|
153
|
+
stmt.executeUpdate(sql)
|
154
|
+
ensure
|
155
|
+
stmt.close
|
156
|
+
end
|
157
|
+
|
158
|
+
def execute_query(sql)
|
159
|
+
stmt = @connection.createStatement
|
160
|
+
unmarshal_result(stmt.executeQuery(sql))
|
161
|
+
ensure
|
162
|
+
stmt.close
|
163
|
+
end
|
164
|
+
|
165
|
+
def begin
|
166
|
+
@connection.setAutoCommit(false)
|
167
|
+
end
|
168
|
+
|
169
|
+
def commit
|
170
|
+
@connection.commit
|
171
|
+
ensure
|
172
|
+
@connection.setAutoCommit(true)
|
173
|
+
end
|
174
|
+
|
175
|
+
def rollback
|
176
|
+
@connection.rollback
|
177
|
+
ensure
|
178
|
+
@connection.setAutoCommit(true)
|
179
|
+
end
|
180
|
+
|
181
|
+
private
|
182
|
+
def unmarshal_result(resultset)
|
183
|
+
metadata = resultset.getMetaData
|
184
|
+
column_count = metadata.getColumnCount
|
185
|
+
column_names = ['']
|
186
|
+
column_types = ['']
|
187
|
+
column_scale = ['']
|
188
|
+
|
189
|
+
1.upto(column_count) do |i|
|
190
|
+
column_names << metadata.getColumnName(i)
|
191
|
+
column_types << metadata.getColumnType(i)
|
192
|
+
column_scale << metadata.getScale(i)
|
193
|
+
end
|
194
|
+
|
195
|
+
results = []
|
196
|
+
|
197
|
+
while resultset.next
|
198
|
+
row = {}
|
199
|
+
1.upto(column_count) do |i|
|
200
|
+
row[column_names[i].downcase] = convert_jdbc_type_to_ruby(i, column_types[i], column_scale[i], resultset)
|
201
|
+
end
|
202
|
+
results << row
|
203
|
+
end
|
204
|
+
|
205
|
+
results
|
206
|
+
end
|
207
|
+
|
208
|
+
def to_ruby_time(java_date)
|
209
|
+
if java_date
|
210
|
+
tm = java_date.getTime
|
211
|
+
Time.at(tm / 1000, (tm % 1000) * 1000)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def convert_jdbc_type_to_ruby(row, type, scale, resultset)
|
216
|
+
if scale != 0
|
217
|
+
decimal = resultset.getString(row)
|
218
|
+
decimal.to_f
|
219
|
+
else
|
220
|
+
case type
|
221
|
+
when Jdbc::Types::CHAR, Jdbc::Types::VARCHAR, Jdbc::Types::LONGVARCHAR
|
222
|
+
resultset.getString(row)
|
223
|
+
when Jdbc::Types::SMALLINT, Jdbc::Types::INTEGER, Jdbc::Types::NUMERIC, Jdbc::Types::BIGINT
|
224
|
+
resultset.getInt(row)
|
225
|
+
when Jdbc::Types::BIT, Jdbc::Types::BOOLEAN, Jdbc::Types::TINYINT
|
226
|
+
resultset.getBoolean(row)
|
227
|
+
when Jdbc::Types::TIMESTAMP
|
228
|
+
to_ruby_time(resultset.getTimestamp(row))
|
229
|
+
when Jdbc::Types::TIME
|
230
|
+
to_ruby_time(resultset.getTime(row))
|
231
|
+
when Jdbc::Types::DATE
|
232
|
+
to_ruby_time(resultset.getDate(row))
|
233
|
+
else
|
234
|
+
types = Jdbc::Types.constants
|
235
|
+
name = types.find {|t| Jdbc::Types.const_get(t.to_sym) == type}
|
236
|
+
raise "jdbc_adapter: type #{name} not supported yet"
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
class JdbcAdapter < AbstractAdapter
|
243
|
+
def initialize(connection, logger, config)
|
244
|
+
super(connection, logger)
|
245
|
+
@config = config
|
246
|
+
end
|
247
|
+
|
248
|
+
def adapter_name #:nodoc:
|
249
|
+
'JDBC'
|
250
|
+
end
|
251
|
+
|
252
|
+
def supports_migrations?
|
253
|
+
true
|
254
|
+
end
|
255
|
+
|
256
|
+
def native_database_types #:nodoc
|
257
|
+
@connection.native_database_types
|
258
|
+
end
|
259
|
+
|
260
|
+
def active?
|
261
|
+
true
|
262
|
+
end
|
263
|
+
|
264
|
+
def reconnect!
|
265
|
+
@connection.close rescue nil
|
266
|
+
@connection = JdbcConnection.new(@config)
|
267
|
+
end
|
268
|
+
|
269
|
+
def select_all(sql, name = nil)
|
270
|
+
select(sql, name)
|
271
|
+
end
|
272
|
+
|
273
|
+
def select_one(sql, name = nil)
|
274
|
+
select(sql, name).first
|
275
|
+
end
|
276
|
+
|
277
|
+
def execute(sql, name = nil)
|
278
|
+
log_no_bench(sql, name) do
|
279
|
+
if sql =~ /^select/i
|
280
|
+
@connection.execute_query(sql)
|
281
|
+
else
|
282
|
+
@connection.execute_update(sql)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
# Oracle doesn't support limit and offset. Fake it instead.
|
288
|
+
def add_limit_offset!(sql, options) #:nodoc:
|
289
|
+
if /oracle/ =~ @config[:driver]
|
290
|
+
offset = options[:offset] || 0
|
291
|
+
|
292
|
+
if limit = options[:limit]
|
293
|
+
sql.replace "select * from (select raw_sql_.*, rownum raw_rnum_ from (#{sql}) raw_sql_ where rownum <= #{offset+limit}) where raw_rnum_ > #{offset}"
|
294
|
+
elsif offset > 0
|
295
|
+
sql.replace "select * from (select raw_sql_.*, rownum raw_rnum_ from (#{sql}) raw_sql_) where raw_rnum_ > #{offset}"
|
296
|
+
end
|
297
|
+
else
|
298
|
+
super
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
alias :update :execute
|
303
|
+
alias :delete :execute
|
304
|
+
|
305
|
+
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
|
306
|
+
log_no_bench(sql, name) do
|
307
|
+
id = @connection.execute_insert(sql, pk)
|
308
|
+
id_value || id
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
def columns(table_name, name = nil)
|
313
|
+
@connection.columns(table_name)
|
314
|
+
end
|
315
|
+
|
316
|
+
def tables
|
317
|
+
@connection.tables
|
318
|
+
end
|
319
|
+
|
320
|
+
def begin_db_transaction
|
321
|
+
@connection.begin
|
322
|
+
end
|
323
|
+
|
324
|
+
def commit_db_transaction
|
325
|
+
@connection.commit
|
326
|
+
end
|
327
|
+
|
328
|
+
def rollback_db_transaction
|
329
|
+
@connection.rollback
|
330
|
+
end
|
331
|
+
|
332
|
+
private
|
333
|
+
def select(sql, name)
|
334
|
+
log_no_bench(sql, name) { @connection.execute_query(sql) }
|
335
|
+
end
|
336
|
+
|
337
|
+
def log_no_bench(sql, name)
|
338
|
+
if block_given?
|
339
|
+
if @logger and @logger.level <= Logger::INFO
|
340
|
+
result = yield
|
341
|
+
log_info(sql, name, 0)
|
342
|
+
result
|
343
|
+
else
|
344
|
+
yield
|
345
|
+
end
|
346
|
+
else
|
347
|
+
log_info(sql, name, 0)
|
348
|
+
nil
|
349
|
+
end
|
350
|
+
rescue Exception => e
|
351
|
+
# Log message and raise exception.
|
352
|
+
message = "#{e.class.name}: #{e.message}: #{sql}"
|
353
|
+
log_info(message, name, 0)
|
354
|
+
raise ActiveRecord::StatementInvalid, message
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
print "Using native JDBC (MySQL)\n"
|
2
|
+
require_dependency 'fixtures/course'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
RAILS_CONNECTION_ADAPTERS << 'jdbc'
|
6
|
+
require "active_record/connection_adapters/jdbc_adapter"
|
7
|
+
|
8
|
+
ActiveRecord::Base.logger = Logger.new("debug.log")
|
9
|
+
|
10
|
+
db1 = 'activerecord_unittest'
|
11
|
+
db2 = 'activerecord_unittest2'
|
12
|
+
|
13
|
+
ActiveRecord::Base.establish_connection(
|
14
|
+
:adapter => "jdbc",
|
15
|
+
:driver => "com.mysql.jdbc.Driver",
|
16
|
+
:url => "jdbc:mysql://localhost:3306/#{db1}",
|
17
|
+
:username => "rails"
|
18
|
+
)
|
19
|
+
|
20
|
+
Course.establish_connection(
|
21
|
+
:adapter => "jdbc",
|
22
|
+
:driver => "com.mysql.jdbc.Driver",
|
23
|
+
:url => "jdbc:mysql://localhost:3306/#{db2}",
|
24
|
+
:username => "rails"
|
25
|
+
)
|
data/test/minirunit.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
|
2
|
+
$silentTests = false
|
3
|
+
$testnum=0
|
4
|
+
$ntest=0
|
5
|
+
$failed = []
|
6
|
+
$curtestOK=true
|
7
|
+
|
8
|
+
module MiniRUnit
|
9
|
+
class Failure
|
10
|
+
def initialize(what, testnum, msg, where)
|
11
|
+
@what, @testnum, @msg, @where = what, testnum, msg, where
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
sprintf("FAILED %s %d %s-- %s\n", @what, @testnum, @msg, @where)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Error
|
20
|
+
def initialize(what, testnum, boom)
|
21
|
+
@what, @testnum, @boom = what, testnum, boom
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
sprintf("EXCEPTION raised %s %d -- \n\tException: %s\n\t%s",
|
26
|
+
@what, @testnum, @boom.to_s, @boom.backtrace.join("\n\t"))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def test_check(what)
|
33
|
+
printf "%s : ", what unless $silentTests
|
34
|
+
$what = what
|
35
|
+
$testnum = 0
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_ok(cond, msg="")
|
39
|
+
$testnum+=1
|
40
|
+
$ntest+=1
|
41
|
+
if cond
|
42
|
+
print "." unless $silentTests
|
43
|
+
else
|
44
|
+
where = caller.reject {|where| where =~ /minirunit/}[0]
|
45
|
+
$failed.push(MiniRUnit::Failure.new($what, $testnum, msg, where))
|
46
|
+
print "F" unless $silentTests
|
47
|
+
$curtestOK=false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_fail(msg="")
|
52
|
+
test_ok(false, msg)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_equal(a,b)
|
56
|
+
test_ok(a == b, "expected #{a.inspect}, found #{b.inspect}")
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_no_exception(&proc)
|
60
|
+
raised = false
|
61
|
+
begin
|
62
|
+
proc.call
|
63
|
+
rescue exception
|
64
|
+
raised = x
|
65
|
+
end
|
66
|
+
test_ok(!raised, "unexpected exception #{raised}")
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_exception(type=Exception, &proc)
|
70
|
+
raised = false
|
71
|
+
begin
|
72
|
+
proc.call
|
73
|
+
rescue type=>e
|
74
|
+
raised = true
|
75
|
+
end
|
76
|
+
test_ok(raised, "#{type} expected")
|
77
|
+
e
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_get_last_failed
|
81
|
+
if $failed.empty?
|
82
|
+
return nil
|
83
|
+
end
|
84
|
+
return $failed.last
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_print_report
|
88
|
+
puts
|
89
|
+
puts "-" * 80
|
90
|
+
$failed.each { |error| puts error }
|
91
|
+
puts "-" * 80
|
92
|
+
puts "Tests: #$ntest. (Ok: #{$ntest - $failed.size}; Failed: #{$failed.size})"
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_load(test)
|
96
|
+
begin
|
97
|
+
$curtestOK=true
|
98
|
+
load(test)
|
99
|
+
rescue Exception => boom
|
100
|
+
puts 'ERROR' unless $silentTests
|
101
|
+
$failed.push(MiniRUnit::Error.new($what, $testnum, boom))
|
102
|
+
else
|
103
|
+
if $curtestOK
|
104
|
+
puts 'OK' unless $silentTests
|
105
|
+
else
|
106
|
+
puts 'FAILED' unless $silentTests
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'test/minirunit'
|
2
|
+
RAILS_CONNECTION_ADAPTERS = ['abstract', 'jdbc']
|
3
|
+
require 'active_record'
|
4
|
+
|
5
|
+
connspec = ActiveRecord::Base.establish_connection(
|
6
|
+
:adapter => 'jdbc',
|
7
|
+
:driver => 'com.mysql.jdbc.Driver',
|
8
|
+
:url => 'jdbc:mysql://localhost:3306/test',
|
9
|
+
:username => 'rlsmgr',
|
10
|
+
:password => ''
|
11
|
+
)
|
12
|
+
|
13
|
+
puts "#{connspec}"
|
14
|
+
puts "#{ActiveRecord::Base.connection}"
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# To run this script, run the following in a mysql instance:
|
2
|
+
#
|
3
|
+
# drop database if exists weblog_development;
|
4
|
+
# create database weblog_development;
|
5
|
+
# grant all on weblog_development.* to blog@localhost;
|
6
|
+
|
7
|
+
require 'test/minirunit'
|
8
|
+
|
9
|
+
config = {
|
10
|
+
:adapter => 'jdbc',
|
11
|
+
:username => 'sa',
|
12
|
+
:password => '',
|
13
|
+
:driver => 'org.hsqldb.jdbcDriver',
|
14
|
+
:url => 'jdbc:hsqldb:test.db'
|
15
|
+
}
|
16
|
+
|
17
|
+
require 'active_record'
|
18
|
+
|
19
|
+
ActiveRecord::Base.establish_connection(config)
|
20
|
+
|
21
|
+
class CreateEntries < ActiveRecord::Migration
|
22
|
+
def self.up
|
23
|
+
create_table "entries", :force => true do |t|
|
24
|
+
t.column :title, :string, :limit => 100
|
25
|
+
t.column :updated_on, :datetime
|
26
|
+
t.column :content, :text
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.down
|
31
|
+
drop_table "entries"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
CreateEntries.up
|
36
|
+
|
37
|
+
test_ok ActiveRecord::Base.connection.tables.include?('entries')
|
38
|
+
|
39
|
+
class Entry < ActiveRecord::Base
|
40
|
+
end
|
41
|
+
|
42
|
+
Entry.delete_all
|
43
|
+
|
44
|
+
test_equal 0, Entry.count
|
45
|
+
|
46
|
+
TITLE = "First post!"
|
47
|
+
CONTENT = "Hello from JRuby on Rails!"
|
48
|
+
NEW_TITLE = "First post updated title"
|
49
|
+
|
50
|
+
post = Entry.new
|
51
|
+
post.title = TITLE
|
52
|
+
post.content = CONTENT
|
53
|
+
post.save
|
54
|
+
|
55
|
+
test_equal 1, Entry.count
|
56
|
+
|
57
|
+
post = Entry.find(:first)
|
58
|
+
test_equal TITLE, post.title
|
59
|
+
test_equal CONTENT, post.content
|
60
|
+
|
61
|
+
post.title = NEW_TITLE
|
62
|
+
post.save
|
63
|
+
|
64
|
+
post = Entry.find(:first)
|
65
|
+
test_equal NEW_TITLE, post.title
|
66
|
+
|
67
|
+
post.destroy
|
68
|
+
|
69
|
+
test_equal 0, Entry.count
|
70
|
+
|
71
|
+
CreateEntries.down
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# To run this script, run the following in a mysql instance:
|
2
|
+
#
|
3
|
+
# drop database if exists weblog_development;
|
4
|
+
# create database weblog_development;
|
5
|
+
# grant all on weblog_development.* to blog@localhost;
|
6
|
+
|
7
|
+
require 'test/minirunit'
|
8
|
+
|
9
|
+
config = {
|
10
|
+
:username => 'blog',
|
11
|
+
:password => ''
|
12
|
+
}
|
13
|
+
|
14
|
+
if RUBY_PLATFORM =~ /java/
|
15
|
+
RAILS_CONNECTION_ADAPTERS = ['abstract', 'jdbc']
|
16
|
+
config.update({
|
17
|
+
:adapter => 'jdbc',
|
18
|
+
:driver => 'com.mysql.jdbc.Driver',
|
19
|
+
:url => 'jdbc:mysql://localhost:3306/weblog_development',
|
20
|
+
})
|
21
|
+
else
|
22
|
+
config.update({
|
23
|
+
:adapter => 'mysql',
|
24
|
+
:database => 'weblog_development',
|
25
|
+
:host => 'localhost'
|
26
|
+
})
|
27
|
+
end
|
28
|
+
|
29
|
+
require 'active_record'
|
30
|
+
|
31
|
+
ActiveRecord::Base.establish_connection(config)
|
32
|
+
|
33
|
+
class CreateEntries < ActiveRecord::Migration
|
34
|
+
def self.up
|
35
|
+
create_table "entries", :force => true do |t|
|
36
|
+
t.column :title, :string, :limit => 100
|
37
|
+
t.column :updated_on, :datetime
|
38
|
+
t.column :content, :text
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.down
|
43
|
+
drop_table "entries"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
CreateEntries.up
|
48
|
+
|
49
|
+
test_ok ActiveRecord::Base.connection.tables.include?('entries')
|
50
|
+
|
51
|
+
class Entry < ActiveRecord::Base
|
52
|
+
end
|
53
|
+
|
54
|
+
Entry.delete_all
|
55
|
+
|
56
|
+
test_equal 0, Entry.count
|
57
|
+
|
58
|
+
TITLE = "First post!"
|
59
|
+
CONTENT = "Hello from JRuby on Rails!"
|
60
|
+
NEW_TITLE = "First post updated title"
|
61
|
+
|
62
|
+
post = Entry.new
|
63
|
+
post.title = TITLE
|
64
|
+
post.content = CONTENT
|
65
|
+
post.save
|
66
|
+
|
67
|
+
test_equal 1, Entry.count
|
68
|
+
|
69
|
+
post = Entry.find(:first)
|
70
|
+
test_equal TITLE, post.title
|
71
|
+
test_equal CONTENT, post.content
|
72
|
+
|
73
|
+
post.title = NEW_TITLE
|
74
|
+
post.save
|
75
|
+
|
76
|
+
post = Entry.find(:first)
|
77
|
+
test_equal NEW_TITLE, post.title
|
78
|
+
|
79
|
+
post.destroy
|
80
|
+
|
81
|
+
test_equal 0, Entry.count
|
82
|
+
|
83
|
+
CreateEntries.down
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
require 'test/minirunit'
|
3
|
+
RAILS_CONNECTION_ADAPTERS = ['abstract', 'jdbc']
|
4
|
+
require 'active_record'
|
5
|
+
|
6
|
+
connspec = ActiveRecord::Base.establish_connection(
|
7
|
+
:adapter => 'jdbc',
|
8
|
+
:driver => 'com.mysql.jdbc.Driver',
|
9
|
+
:url => 'jdbc:mysql://localhost:3306/weblog_development',
|
10
|
+
:username => 'blog',
|
11
|
+
:password => ''
|
12
|
+
)
|
13
|
+
|
14
|
+
connection = ActiveRecord::Base.connection
|
15
|
+
|
16
|
+
results = connection.execute "select * from entries"
|
17
|
+
|
18
|
+
test_equal results.length, 1
|
19
|
+
|
20
|
+
row = results.first
|
21
|
+
test_equal 'First post', row['title']
|
22
|
+
test_equal 'First post d00d!', row['content']
|
23
|
+
|
24
|
+
puts row.inspect
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: ActiveRecord-JDBC
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2006-08-07 00:00:00 +02:00
|
8
|
+
summary: JDBC support for ActiveRecord. Only usable within JRuby
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: ola@ologix.com
|
12
|
+
homepage: http://jruby-extras.rubyforge.org/
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: active_record/connection_adapters/jdbc_adapter
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
authors:
|
29
|
+
- JRuby-extras
|
30
|
+
files:
|
31
|
+
- lib/active_record
|
32
|
+
- lib/active_record/connection_adapters
|
33
|
+
- lib/active_record/connection_adapters/jdbc_adapter.rb
|
34
|
+
- test/activerecord
|
35
|
+
- test/minirunit
|
36
|
+
- test/minirunit.rb
|
37
|
+
- test/activerecord/connections
|
38
|
+
- test/activerecord/jall.sh
|
39
|
+
- test/activerecord/jtest.sh
|
40
|
+
- test/activerecord/connections/native_jdbc_mysql
|
41
|
+
- test/activerecord/connections/native_jdbc_mysql/connection.rb
|
42
|
+
- test/minirunit/testConnect.rb
|
43
|
+
- test/minirunit/testHsqldb.rb
|
44
|
+
- test/minirunit/testLoadActiveRecord.rb
|
45
|
+
- test/minirunit/testMysql.rb
|
46
|
+
- test/minirunit/testRawSelect.rb
|
47
|
+
- LICENSE
|
48
|
+
- init.rb
|
49
|
+
- install.rb
|
50
|
+
test_files: []
|
51
|
+
|
52
|
+
rdoc_options: []
|
53
|
+
|
54
|
+
extra_rdoc_files: []
|
55
|
+
|
56
|
+
executables: []
|
57
|
+
|
58
|
+
extensions: []
|
59
|
+
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
dependencies: []
|
63
|
+
|