ActiveRecord-JDBC 0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +12 -0
- data/Manifest.txt +13 -0
- data/Rakefile +18 -10
- data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/jdbc_adapter.rb +124 -56
- data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
- data/lib/jdbc_adapter/jdbc_db2.rb +21 -0
- data/lib/jdbc_adapter/jdbc_derby.rb +22 -101
- data/lib/jdbc_adapter/jdbc_firebird.rb +5 -1
- data/lib/jdbc_adapter/jdbc_hsqldb.rb +23 -1
- data/lib/jdbc_adapter/jdbc_mimer.rb +4 -2
- data/lib/jdbc_adapter/jdbc_mssql.rb +149 -67
- data/lib/jdbc_adapter/jdbc_mysql.rb +22 -2
- data/lib/jdbc_adapter/jdbc_oracle.rb +80 -15
- data/lib/jdbc_adapter/jdbc_postgre.rb +132 -4
- data/lib/jdbc_adapter_internal.jar +0 -0
- data/src/java/JDBCDerbySpec.java +323 -0
- data/src/java/JDBCMySQLSpec.java +83 -0
- data/src/java/JdbcAdapterInternalService.java +802 -0
- data/test/activerecord/connection_adapters/type_conversion_test.rb +1 -0
- data/test/db/derby.rb +2 -5
- data/test/db/h2.rb +2 -5
- data/test/db/hsqldb.rb +2 -6
- data/test/db/jdbc.rb +9 -0
- data/test/db/mysql.rb +4 -15
- data/test/db/postgres.rb +2 -3
- data/test/generic_jdbc_connection_test.rb +9 -0
- data/test/jdbc_adapter/jdbc_db2_test.rb +21 -0
- data/test/simple.rb +6 -8
- metadata +15 -2
data/History.txt
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
== 0.5
|
2
|
+
|
3
|
+
- Release coincides with JRuby 1.0.1 release
|
4
|
+
- It is no longer necessary to specify :driver and :url configuration parameters for the mysql,
|
5
|
+
postgresql, oracle, derby, hsqldb, and h2 adapters. The previous configuration is still
|
6
|
+
valid and compatible, but for new applications, this makes it possible to use the exact same
|
7
|
+
database.yml configuration as Rails applications running under native Ruby.
|
8
|
+
- JDBC drivers can now be dynamically loaded by Ruby code, without being on the classpath prior to
|
9
|
+
launching JRuby. Simply use "require 'jdbc-driver.jar'" in JRuby code to add it to the runtime
|
10
|
+
classpath.
|
11
|
+
- Updates to HSQL, MS SQLServer, Postgres, Oracle and Derby adapters
|
12
|
+
|
1
13
|
== 0.4
|
2
14
|
|
3
15
|
- Release coincides with JRuby 1.0 release
|
data/Manifest.txt
CHANGED
@@ -3,8 +3,15 @@ Manifest.txt
|
|
3
3
|
README.txt
|
4
4
|
Rakefile
|
5
5
|
LICENSE
|
6
|
+
lib/active_record/connection_adapters/derby_adapter.rb
|
7
|
+
lib/active_record/connection_adapters/h2_adapter.rb
|
8
|
+
lib/active_record/connection_adapters/hsqldb_adapter.rb
|
6
9
|
lib/active_record/connection_adapters/jdbc_adapter.rb
|
7
10
|
lib/active_record/connection_adapters/jdbc_adapter_spec.rb
|
11
|
+
lib/active_record/connection_adapters/jndi_adapter.rb
|
12
|
+
lib/active_record/connection_adapters/mysql_adapter.rb
|
13
|
+
lib/active_record/connection_adapters/oracle_adapter.rb
|
14
|
+
lib/active_record/connection_adapters/postgresql_adapter.rb
|
8
15
|
lib/jdbc_adapter/jdbc_db2.rb
|
9
16
|
lib/jdbc_adapter/jdbc_derby.rb
|
10
17
|
lib/jdbc_adapter/jdbc_firebird.rb
|
@@ -22,14 +29,17 @@ test/activerecord/connections/native_jdbc_mysql/connection.rb
|
|
22
29
|
test/db/derby.rb
|
23
30
|
test/db/h2.rb
|
24
31
|
test/db/hsqldb.rb
|
32
|
+
test/db/jdbc.rb
|
25
33
|
test/db/jndi_config.rb
|
26
34
|
test/db/logger.rb
|
27
35
|
test/db/mysql.rb
|
28
36
|
test/db/postgres.rb
|
29
37
|
test/derby_multibyte_test.rb
|
30
38
|
test/derby_simple_test.rb
|
39
|
+
test/generic_jdbc_connection_test.rb
|
31
40
|
test/h2_simple_test.rb
|
32
41
|
test/hsqldb_simple_test.rb
|
42
|
+
test/jdbc_adapter/jdbc_db2_test.rb
|
33
43
|
test/jdbc_common.rb
|
34
44
|
test/jndi_test.rb
|
35
45
|
test/manualTestDatabase.rb
|
@@ -47,3 +57,6 @@ test/mysql_simple_test.rb
|
|
47
57
|
test/postgres_simple_test.rb
|
48
58
|
test/simple.rb
|
49
59
|
lib/tasks/jdbc_databases.rake
|
60
|
+
src/java/JdbcAdapterInternalService.java
|
61
|
+
src/java/JDBCDerbySpec.java
|
62
|
+
src/java/JDBCMySQLSpec.java
|
data/Rakefile
CHANGED
@@ -40,7 +40,7 @@ end
|
|
40
40
|
desc "Run AR-JDBC tests"
|
41
41
|
if RUBY_PLATFORM =~ /java/
|
42
42
|
# TODO: add more databases into the standard tests here.
|
43
|
-
task :test => [:test_mysql, :test_derby, :test_hsqldb]
|
43
|
+
task :test => [:test_mysql, :test_jdbc, :test_derby, :test_hsqldb]
|
44
44
|
else
|
45
45
|
task :test => [:test_mysql]
|
46
46
|
end
|
@@ -50,6 +50,11 @@ Rake::TestTask.new(:test_mysql) do |t|
|
|
50
50
|
t.libs << 'test'
|
51
51
|
end
|
52
52
|
|
53
|
+
Rake::TestTask.new(:test_jdbc) do |t|
|
54
|
+
t.test_files = FileList['test/generic_jdbc_connection_test.rb']
|
55
|
+
t.libs << 'test'
|
56
|
+
end
|
57
|
+
|
53
58
|
Rake::TestTask.new(:test_hsqldb) do |t|
|
54
59
|
t.test_files = FileList['test/hsqldb_simple_test.rb']
|
55
60
|
t.libs << 'test'
|
@@ -73,18 +78,19 @@ Rake::TestTask.new(:test_jndi) do |t|
|
|
73
78
|
t.libs << 'test'
|
74
79
|
end
|
75
80
|
|
76
|
-
|
77
|
-
|
78
|
-
|
81
|
+
MANIFEST = FileList["History.txt", "Manifest.txt", "README.txt",
|
82
|
+
"Rakefile", "LICENSE", "lib/**/*.rb", "lib/jdbc_adapter_internal.jar", "test/**/*.rb", "lib/**/*.rake",
|
83
|
+
"src/**/*.java"]
|
79
84
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
+
file "Manifest.txt" => :manifest
|
86
|
+
task :manifest do
|
87
|
+
File.open("Manifest.txt", "w") {|f| MANIFEST.each {|n| f << "#{n}\n"} }
|
88
|
+
end
|
89
|
+
Rake::Task['manifest'].invoke # Always regen manifest, so Hoe has up-to-date list of files
|
85
90
|
|
91
|
+
begin
|
86
92
|
require 'hoe'
|
87
|
-
Hoe.new("ActiveRecord-JDBC", "0.
|
93
|
+
Hoe.new("ActiveRecord-JDBC", "0.5") do |p|
|
88
94
|
p.rubyforge_name = "jruby-extras"
|
89
95
|
p.url = "http://jruby-extras.rubyforge.org/ActiveRecord-JDBC"
|
90
96
|
p.author = "Nick Sieger, Ola Bini and JRuby contributors"
|
@@ -95,4 +101,6 @@ begin
|
|
95
101
|
end.spec.dependencies.delete_if { |dep| dep.name == "hoe" }
|
96
102
|
rescue LoadError
|
97
103
|
puts "You really need Hoe installed to be able to package this gem"
|
104
|
+
rescue => e
|
105
|
+
puts "ignoring error while loading hoe: #{e.to_s}"
|
98
106
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'active_record/connection_adapters/jdbc_adapter'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'active_record/connection_adapters/jdbc_adapter'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'active_record/connection_adapters/jdbc_adapter'
|
@@ -5,11 +5,55 @@ require 'jdbc_adapter_internal'
|
|
5
5
|
require 'bigdecimal'
|
6
6
|
|
7
7
|
module ActiveRecord
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
module ConnectionAdapters # :nodoc:
|
9
|
+
module SchemaStatements
|
10
|
+
# The original implementation of this had a bug, which modifies native_database_types.
|
11
|
+
# This version allows us to cache that value.
|
12
|
+
def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
|
13
|
+
native = native_database_types[type]
|
14
|
+
column_type_sql = native.is_a?(Hash) ? native[:name] : native
|
15
|
+
if type == :decimal # ignore limit, use precison and scale
|
16
|
+
precision ||= native[:precision]
|
17
|
+
scale ||= native[:scale]
|
18
|
+
if precision
|
19
|
+
if scale
|
20
|
+
column_type_sql += "(#{precision},#{scale})"
|
21
|
+
else
|
22
|
+
column_type_sql += "(#{precision})"
|
23
|
+
end
|
24
|
+
else
|
25
|
+
raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale if specified" if scale
|
26
|
+
end
|
27
|
+
column_type_sql
|
28
|
+
else
|
29
|
+
limit ||= native[:limit]
|
30
|
+
column_type_sql += "(#{limit})" if limit
|
31
|
+
column_type_sql
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
module JdbcSpec
|
39
|
+
module ActiveRecordExtensions
|
40
|
+
def jdbc_connection(config)
|
41
|
+
connection = ::ActiveRecord::ConnectionAdapters::JdbcConnection.new(config)
|
42
|
+
::ActiveRecord::ConnectionAdapters::JdbcAdapter.new(connection, logger, config)
|
43
|
+
end
|
44
|
+
alias jndi_connection jdbc_connection
|
45
|
+
|
46
|
+
def embedded_driver(config)
|
47
|
+
config[:username] ||= "sa"
|
48
|
+
config[:password] ||= ""
|
49
|
+
jdbc_connection(config)
|
12
50
|
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
module ActiveRecord
|
55
|
+
class Base
|
56
|
+
extend JdbcSpec::ActiveRecordExtensions
|
13
57
|
|
14
58
|
alias :attributes_with_quotes_pre_oracle :attributes_with_quotes
|
15
59
|
def attributes_with_quotes(include_primary_key = true) #:nodoc:
|
@@ -29,6 +73,7 @@ module ActiveRecord
|
|
29
73
|
end
|
30
74
|
|
31
75
|
module Jdbc
|
76
|
+
Mutex = java.lang.Object.new
|
32
77
|
DriverManager = java.sql.DriverManager
|
33
78
|
Statement = java.sql.Statement
|
34
79
|
Types = java.sql.Types
|
@@ -105,7 +150,8 @@ module ActiveRecord
|
|
105
150
|
lambda {|r| r['type_name'] =~ /^time$/i},
|
106
151
|
lambda {|r| r['type_name'] =~ /^date/i}],
|
107
152
|
:date => [ lambda {|r| Jdbc::Types::DATE == r['data_type'].to_i},
|
108
|
-
lambda {|r| r['type_name'] =~ /^date$/i}
|
153
|
+
lambda {|r| r['type_name'] =~ /^date$/i},
|
154
|
+
lambda {|r| r['type_name'] =~ /^date/i}],
|
109
155
|
:binary => [ lambda {|r| [Jdbc::Types::LONGVARBINARY,Jdbc::Types::BINARY,Jdbc::Types::BLOB].include?(r['data_type'].to_i)},
|
110
156
|
lambda {|r| r['type_name'] =~ /^blob/i},
|
111
157
|
lambda {|r| r['type_name'] =~ /sub_type 0$/i}, # For FireBird
|
@@ -147,35 +193,43 @@ module ActiveRecord
|
|
147
193
|
end
|
148
194
|
|
149
195
|
class JdbcDriver
|
150
|
-
def
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
196
|
+
def initialize(name)
|
197
|
+
@name = name
|
198
|
+
end
|
199
|
+
|
200
|
+
def driver_class
|
201
|
+
@driver_class ||= begin
|
202
|
+
driver_class_const = (@name[0...1].capitalize + @name[1..@name.length]).gsub(/\./, '_')
|
203
|
+
Jdbc::Mutex.synchronized do
|
204
|
+
unless Jdbc.const_defined?(driver_class_const)
|
205
|
+
driver_class_name = @name
|
206
|
+
Jdbc.module_eval do
|
207
|
+
include_class(driver_class_name) { driver_class_const }
|
208
|
+
end
|
209
|
+
end
|
155
210
|
end
|
156
|
-
Jdbc
|
211
|
+
Jdbc.const_get(driver_class_const)
|
157
212
|
end
|
158
213
|
end
|
214
|
+
|
215
|
+
def load
|
216
|
+
Jdbc::DriverManager.registerDriver(create)
|
217
|
+
end
|
218
|
+
|
219
|
+
def create
|
220
|
+
driver_class.new
|
221
|
+
end
|
159
222
|
end
|
160
223
|
|
161
224
|
class JdbcColumn < Column
|
162
225
|
attr_writer :limit, :precision
|
163
226
|
|
164
|
-
COLUMN_TYPES = {
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
/derby/i => lambda {|cfg,col| col.extend(JdbcSpec::Derby::Column)},
|
171
|
-
/db2/i => lambda {|cfg,col|
|
172
|
-
if cfg[:url] =~ /^jdbc:derby:net:/
|
173
|
-
col.extend(JdbcSpec::Derby::Column)
|
174
|
-
else
|
175
|
-
col.extend(JdbcSpec::DB2::Column)
|
176
|
-
end }
|
177
|
-
}
|
178
|
-
|
227
|
+
COLUMN_TYPES = ::JdbcSpec.constants.map{|c|
|
228
|
+
::JdbcSpec.const_get c }.select{ |c|
|
229
|
+
c.respond_to? :column_selector }.map{|c|
|
230
|
+
c.column_selector }.inject({}) { |h,val|
|
231
|
+
h[val[0]] = val[1]; h }
|
232
|
+
|
179
233
|
def initialize(config, name, default, *args)
|
180
234
|
ds = config[:driver].to_s
|
181
235
|
for reg, func in COLUMN_TYPES
|
@@ -210,6 +264,10 @@ module ActiveRecord
|
|
210
264
|
rescue Exception => e
|
211
265
|
raise "The driver encountered an error: #{e}"
|
212
266
|
end
|
267
|
+
|
268
|
+
def reconnect!
|
269
|
+
self.adapter.reconnect!
|
270
|
+
end
|
213
271
|
|
214
272
|
def adapter=(adapt)
|
215
273
|
@adapter = adapt
|
@@ -226,7 +284,9 @@ module ActiveRecord
|
|
226
284
|
# one index, one row per column in the index), so a simple block-based
|
227
285
|
# filter like that used for tables doesn't really work here. Callers
|
228
286
|
# should filter the return from this method instead.
|
229
|
-
|
287
|
+
#
|
288
|
+
# TODO: fix to use reconnect correctly
|
289
|
+
def indexes(table_name, name = nil, schema_name = nil)
|
230
290
|
metadata = @connection.getMetaData
|
231
291
|
unless String === table_name
|
232
292
|
table_name = table_name.to_s
|
@@ -235,12 +295,14 @@ module ActiveRecord
|
|
235
295
|
end
|
236
296
|
table_name.upcase! if metadata.storesUpperCaseIdentifiers
|
237
297
|
table_name.downcase! if metadata.storesLowerCaseIdentifiers
|
238
|
-
resultset = metadata.getIndexInfo(nil,
|
298
|
+
resultset = metadata.getIndexInfo(nil, schema_name, table_name, false, false)
|
239
299
|
primary_keys = primary_keys(table_name)
|
240
300
|
indexes = []
|
241
301
|
current_index = nil
|
242
302
|
while resultset.next
|
243
|
-
index_name = resultset.get_string(Jdbc::IndexMetaData::INDEX_NAME)
|
303
|
+
index_name = resultset.get_string(Jdbc::IndexMetaData::INDEX_NAME)
|
304
|
+
next unless index_name
|
305
|
+
index_name.downcase!
|
244
306
|
column_name = resultset.get_string(Jdbc::IndexMetaData::COLUMN_NAME).downcase
|
245
307
|
|
246
308
|
next if primary_keys.include? column_name
|
@@ -298,30 +360,30 @@ module ActiveRecord
|
|
298
360
|
@config[:url] = url
|
299
361
|
end
|
300
362
|
|
301
|
-
JdbcDriver.
|
302
|
-
|
363
|
+
jdbc_driver = JdbcDriver.new(driver)
|
364
|
+
jdbc_driver.load
|
365
|
+
connection = begin
|
366
|
+
Jdbc::DriverManager.getConnection(url, user, pass)
|
367
|
+
rescue
|
368
|
+
# bypass DriverManager to get around problem with dynamically loaded jdbc drivers
|
369
|
+
props = java.util.Properties.new
|
370
|
+
props.setProperty("user", user)
|
371
|
+
props.setProperty("password", pass)
|
372
|
+
jdbc_driver.create.connect(url, props)
|
373
|
+
end
|
374
|
+
set_connection connection
|
303
375
|
end
|
304
376
|
|
305
377
|
end
|
306
378
|
|
307
379
|
class JdbcAdapter < AbstractAdapter
|
308
|
-
|
309
|
-
/oracle/i => lambda{|cfg,adapt| adapt.extend(JdbcSpec::Oracle)},
|
310
|
-
/mimer/i => lambda{|cfg,adapt| adapt.extend(JdbcSpec::Mimer)},
|
311
|
-
/postgre/i => lambda{|cfg,adapt| adapt.extend(JdbcSpec::PostgreSQL)},
|
312
|
-
/mysql/i => lambda{|cfg,adapt| adapt.extend(JdbcSpec::MySQL)},
|
313
|
-
/sqlserver|tds/i => lambda{|cfg,adapt| adapt.extend(JdbcSpec::MsSQL)},
|
314
|
-
/hsqldb|\.h2\./i => lambda{|cfg,adapt| adapt.extend(JdbcSpec::HSQLDB)},
|
315
|
-
/derby/i => lambda{|cfg,adapt| adapt.extend(JdbcSpec::Derby)},
|
316
|
-
/db2/i => lambda{|cfg,adapt|
|
317
|
-
if cfg[:url] =~ /^jdbc:derby:net:/
|
318
|
-
adapt.extend(JdbcSpec::Derby)
|
319
|
-
else
|
320
|
-
adapt.extend(JdbcSpec::DB2)
|
321
|
-
end},
|
322
|
-
/firebird/i => lambda{|cfg,adapt| adapt.extend(JdbcSpec::FireBird)}
|
380
|
+
attr_reader :config
|
323
381
|
|
324
|
-
|
382
|
+
ADAPTER_TYPES = ::JdbcSpec.constants.map{|c|
|
383
|
+
::JdbcSpec.const_get c }.select{ |c|
|
384
|
+
c.respond_to? :adapter_selector }.map{|c|
|
385
|
+
c.adapter_selector }.inject({}) { |h,val|
|
386
|
+
h[val[0]] = val[1]; h }
|
325
387
|
|
326
388
|
def initialize(connection, logger, config)
|
327
389
|
super(connection, logger)
|
@@ -393,6 +455,8 @@ module ActiveRecord
|
|
393
455
|
def reconnect!
|
394
456
|
@connection.close rescue nil
|
395
457
|
@connection = JdbcConnection.new(@config)
|
458
|
+
@connection.adapter = self
|
459
|
+
@connection
|
396
460
|
end
|
397
461
|
|
398
462
|
def select_all(sql, name = nil)
|
@@ -404,25 +468,25 @@ module ActiveRecord
|
|
404
468
|
end
|
405
469
|
|
406
470
|
def execute(sql, name = nil)
|
407
|
-
|
471
|
+
log_no_bench(sql, name) do
|
472
|
+
_execute(sql,name)
|
473
|
+
end
|
408
474
|
end
|
409
475
|
|
410
476
|
# we need to do it this way, to allow Rails stupid tests to always work
|
411
477
|
# even if we define a new execute method. Instead of mixing in a new
|
412
478
|
# execute, an _execute should be mixed in.
|
413
479
|
def _execute(sql, name = nil)
|
414
|
-
|
415
|
-
|
416
|
-
when /^insert/i:
|
480
|
+
case sql.strip
|
481
|
+
when /\Ainsert/i:
|
417
482
|
@connection.execute_insert(sql)
|
418
|
-
|
483
|
+
when /\A\(?\s*(select|show)/i:
|
419
484
|
@connection.execute_query(sql)
|
420
|
-
|
421
|
-
|
422
|
-
end
|
485
|
+
else
|
486
|
+
@connection.execute_update(sql)
|
423
487
|
end
|
424
488
|
end
|
425
|
-
|
489
|
+
|
426
490
|
def update(sql, name = nil) #:nodoc:
|
427
491
|
execute(sql, name)
|
428
492
|
end
|
@@ -455,6 +519,10 @@ module ActiveRecord
|
|
455
519
|
def rollback_db_transaction
|
456
520
|
@connection.rollback
|
457
521
|
end
|
522
|
+
|
523
|
+
def write_large_object(*args)
|
524
|
+
@connection.write_large_object(*args)
|
525
|
+
end
|
458
526
|
|
459
527
|
private
|
460
528
|
def select(sql, name=nil)
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'active_record/connection_adapters/jdbc_adapter'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'active_record/connection_adapters/jdbc_adapter'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'active_record/connection_adapters/jdbc_adapter'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'active_record/connection_adapters/jdbc_adapter'
|
@@ -1,5 +1,23 @@
|
|
1
1
|
module JdbcSpec
|
2
2
|
module DB2
|
3
|
+
def self.column_selector
|
4
|
+
[/db2/i, lambda {|cfg,col|
|
5
|
+
if cfg[:url] =~ /^jdbc:derby:net:/
|
6
|
+
col.extend(::JdbcSpec::Derby::Column)
|
7
|
+
else
|
8
|
+
col.extend(::JdbcSpec::DB2::Column)
|
9
|
+
end }]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.adapter_selector
|
13
|
+
[/db2/i, lambda {|cfg,adapt|
|
14
|
+
if cfg[:url] =~ /^jdbc:derby:net:/
|
15
|
+
adapt.extend(::JdbcSpec::Derby)
|
16
|
+
else
|
17
|
+
adapt.extend(::JdbcSpec::DB2)
|
18
|
+
end }]
|
19
|
+
end
|
20
|
+
|
3
21
|
module Column
|
4
22
|
def type_cast(value)
|
5
23
|
return nil if value.nil? || value =~ /^\s*null\s*$/i
|
@@ -57,6 +75,9 @@ module JdbcSpec
|
|
57
75
|
if column && column.type == :primary_key
|
58
76
|
return value.to_s
|
59
77
|
end
|
78
|
+
if column && column.type == :decimal && value
|
79
|
+
return value.to_s
|
80
|
+
end
|
60
81
|
case value
|
61
82
|
when String
|
62
83
|
if column && column.type == :binary
|
@@ -1,7 +1,23 @@
|
|
1
1
|
require 'jdbc_adapter/missing_functionality_helper'
|
2
2
|
|
3
|
-
module JdbcSpec
|
3
|
+
module ::JdbcSpec
|
4
|
+
module ActiveRecordExtensions
|
5
|
+
def derby_connection(config)
|
6
|
+
config[:url] ||= "jdbc:derby:#{config[:database]};create=true"
|
7
|
+
config[:driver] ||= "org.apache.derby.jdbc.EmbeddedDriver"
|
8
|
+
embedded_driver(config)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
4
12
|
module Derby
|
13
|
+
def self.column_selector
|
14
|
+
[/derby/i, lambda {|cfg,col| col.extend(::JdbcSpec::Derby::Column)}]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.adapter_selector
|
18
|
+
[/derby/i, lambda {|cfg,adapt| adapt.extend(::JdbcSpec::Derby)}]
|
19
|
+
end
|
20
|
+
|
5
21
|
def self.monkey_rails
|
6
22
|
unless @already_monkeyd
|
7
23
|
# Needed because Rails is broken wrt to quoting of
|
@@ -32,23 +48,8 @@ module JdbcSpec
|
|
32
48
|
end
|
33
49
|
|
34
50
|
module Column
|
35
|
-
def
|
36
|
-
|
37
|
-
case type
|
38
|
-
when :string then value
|
39
|
-
when :text then value
|
40
|
-
when :integer then defined?(value.to_i) ? value.to_i : (value ? 1 : 0)
|
41
|
-
when :primary_key then defined?(value.to_i) ? value.to_i : (value ? 1 : 0)
|
42
|
-
when :decimal then self.class.value_to_decimal(value)
|
43
|
-
when :float then value.to_f
|
44
|
-
when :datetime then cast_to_date_or_time(value)
|
45
|
-
when :date then self.class.string_to_date(value)
|
46
|
-
when :timestamp then cast_to_time(value)
|
47
|
-
when :binary then value.scan(/[0-9A-Fa-f]{2}/).collect {|v| v.to_i(16)}.pack("C*")
|
48
|
-
when :time then cast_to_time(value)
|
49
|
-
when :boolean then self.class.value_to_boolean(value)
|
50
|
-
else value
|
51
|
-
end
|
51
|
+
def value_to_binary(value)
|
52
|
+
value.scan(/[0-9A-Fa-f]{2}/).collect {|v| v.to_i(16)}.pack("C*")
|
52
53
|
end
|
53
54
|
|
54
55
|
def cast_to_date_or_time(value)
|
@@ -85,22 +86,6 @@ module JdbcSpec
|
|
85
86
|
tp[:boolean] = {:name => "smallint"}
|
86
87
|
tp
|
87
88
|
end
|
88
|
-
|
89
|
-
def add_limit_offset!(sql, options) # :nodoc:
|
90
|
-
@limit = options[:limit]
|
91
|
-
@offset = options[:offset]
|
92
|
-
end
|
93
|
-
|
94
|
-
def select_all(sql, name = nil)
|
95
|
-
execute(sql, name)
|
96
|
-
end
|
97
|
-
|
98
|
-
def select_one(sql, name = nil)
|
99
|
-
@limit ||= 1
|
100
|
-
execute(sql, name).first
|
101
|
-
ensure
|
102
|
-
@limit = nil
|
103
|
-
end
|
104
89
|
|
105
90
|
def classes_for_table_name(table)
|
106
91
|
ActiveRecord::Base.send(:subclasses).select {|klass| klass.table_name == table}
|
@@ -121,29 +106,6 @@ module JdbcSpec
|
|
121
106
|
end
|
122
107
|
end
|
123
108
|
|
124
|
-
def _execute(sql, name = nil)
|
125
|
-
log_no_bench(sql, name) do
|
126
|
-
case sql.strip
|
127
|
-
when /^insert/i:
|
128
|
-
@connection.execute_insert(sql)
|
129
|
-
when /^\(?\s*(select|show)/i:
|
130
|
-
@offset ||= 0
|
131
|
-
if !@limit || @limit == -1
|
132
|
-
range = @offset..-1
|
133
|
-
max = 0
|
134
|
-
else
|
135
|
-
range = @offset...(@offset+@limit)
|
136
|
-
max = @offset+@limit+1
|
137
|
-
end
|
138
|
-
@connection.execute_query(sql,max)[range] || []
|
139
|
-
else
|
140
|
-
@connection.execute_update(sql)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
ensure
|
144
|
-
@limit = @offset = nil
|
145
|
-
end
|
146
|
-
|
147
109
|
def primary_key(table_name) #:nodoc:
|
148
110
|
primary_keys(table_name).first
|
149
111
|
end
|
@@ -372,51 +334,8 @@ module JdbcSpec
|
|
372
334
|
drop_table t
|
373
335
|
end
|
374
336
|
end
|
375
|
-
|
376
|
-
def quote(value, column = nil) # :nodoc:
|
377
|
-
return value.to_s if column && column.type == :primary_key
|
378
|
-
|
379
|
-
case value
|
380
|
-
when String
|
381
|
-
if column
|
382
|
-
case column.type
|
383
|
-
when :binary
|
384
|
-
"CAST(x'#{quote_string(value).unpack("C*").collect {|v| v.to_s(16)}.join}' AS BLOB)"
|
385
|
-
when :text
|
386
|
-
"CAST('#{quote_string(value)}' AS CLOB)"
|
387
|
-
when :string
|
388
|
-
"'#{quote_string(value)}'"
|
389
|
-
else
|
390
|
-
vi = value.to_i
|
391
|
-
if vi.to_s == value
|
392
|
-
value
|
393
|
-
else
|
394
|
-
super
|
395
|
-
end
|
396
|
-
end
|
397
|
-
else
|
398
|
-
super
|
399
|
-
end
|
400
|
-
when Float, Fixnum, Bignum
|
401
|
-
if column
|
402
|
-
case column.type
|
403
|
-
when :string
|
404
|
-
"'#{quote_string(value.to_s)}'"
|
405
|
-
else
|
406
|
-
super
|
407
|
-
end
|
408
|
-
else
|
409
|
-
super
|
410
|
-
end
|
411
|
-
else super
|
412
|
-
end
|
413
|
-
end
|
414
337
|
|
415
|
-
|
416
|
-
s.gsub(/'/, "''") # ' (for ruby-mode)
|
417
|
-
end
|
418
|
-
|
419
|
-
# For DDL it appears you can quote "" column names, but in queries (like insert it errors out?)
|
338
|
+
# For DDL it appears you can quote "" column names, but in queries (like insert it errors out?)
|
420
339
|
def quote_column_name(name) #:nodoc:
|
421
340
|
if /^references$/i =~ name
|
422
341
|
%Q{"#{name.upcase}"}
|
@@ -424,6 +343,8 @@ module JdbcSpec
|
|
424
343
|
%Q{"#{name}"}
|
425
344
|
elsif name =~ /\s/
|
426
345
|
%Q{"#{name.upcase}"}
|
346
|
+
elsif name =~ /^[_\d]/
|
347
|
+
%Q{"#{name.upcase}"}
|
427
348
|
else
|
428
349
|
name
|
429
350
|
end
|