ActiveRecord-JDBC 0.4 → 0.5
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 +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
|