ActiveRecord-JDBC 0.0.1
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/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
|
+
|