ActiveRecord-JDBC 0.2.1 → 0.2.2
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/lib/active_record/connection_adapters/jdbc_adapter.rb +45 -9
- data/lib/active_record/connection_adapters/jdbc_adapter_spec.rb +9 -1132
- data/lib/jdbc_adapter/jdbc_db2.rb +83 -0
- data/lib/jdbc_adapter/jdbc_derby.rb +113 -0
- data/lib/jdbc_adapter/jdbc_firebird.rb +103 -0
- data/lib/jdbc_adapter/jdbc_hsqldb.rb +104 -0
- data/lib/jdbc_adapter/jdbc_mimer.rb +122 -0
- data/lib/jdbc_adapter/jdbc_mssql.rb +208 -0
- data/lib/jdbc_adapter/jdbc_mysql.rb +119 -0
- data/lib/jdbc_adapter/jdbc_oracle.rb +237 -0
- data/lib/jdbc_adapter/jdbc_postgre.rb +173 -0
- data/test/db/hsqldb.rb +14 -0
- data/test/db/logger.rb +3 -0
- data/test/db/mysql.rb +20 -0
- data/test/hsqldb_simple_test.rb +9 -0
- data/test/manualTestDatabase.rb +5 -5
- data/test/minirunit/testHsqldb.rb +8 -6
- data/test/minirunit/testMysql.rb +1 -1
- data/test/models/entry.rb +22 -0
- data/test/mysql_simple_test.rb +15 -0
- data/test/simple.rb +65 -0
- metadata +21 -2
@@ -0,0 +1,173 @@
|
|
1
|
+
module JdbcSpec
|
2
|
+
module PostgreSQL
|
3
|
+
module Column
|
4
|
+
def type_cast(value)
|
5
|
+
return nil if value.nil? || value =~ /^\s*null\s*$/i
|
6
|
+
case type
|
7
|
+
when :string then value
|
8
|
+
when :integer then defined?(value.to_i) ? value.to_i : (value ? 1 : 0)
|
9
|
+
when :primary_key then defined?(value.to_i) ? value.to_i : (value ? 1 : 0)
|
10
|
+
when :float then value.to_f
|
11
|
+
when :datetime then cast_to_date_or_time(value)
|
12
|
+
when :timestamp then cast_to_time(value)
|
13
|
+
when :time then cast_to_time(value)
|
14
|
+
else value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
def cast_to_date_or_time(value)
|
18
|
+
return value if value.is_a? Date
|
19
|
+
return nil if value.blank?
|
20
|
+
guess_date_or_time (value.is_a? Time) ? value : cast_to_time(value)
|
21
|
+
end
|
22
|
+
|
23
|
+
def cast_to_time(value)
|
24
|
+
return value if value.is_a? Time
|
25
|
+
time_array = ParseDate.parsedate value
|
26
|
+
time_array[0] ||= 2000; time_array[1] ||= 1; time_array[2] ||= 1;
|
27
|
+
Time.send(Base.default_timezone, *time_array) rescue nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def guess_date_or_time(value)
|
31
|
+
(value.hour == 0 and value.min == 0 and value.sec == 0) ?
|
32
|
+
Date.new(value.year, value.month, value.day) : value
|
33
|
+
end
|
34
|
+
def default_value(value)
|
35
|
+
# Boolean types
|
36
|
+
return "t" if value =~ /true/i
|
37
|
+
return "f" if value =~ /false/i
|
38
|
+
|
39
|
+
# Char/String/Bytea type values
|
40
|
+
return $1 if value =~ /^'(.*)'::(bpchar|text|character varying|bytea)$/
|
41
|
+
|
42
|
+
# Numeric values
|
43
|
+
return value if value =~ /^-?[0-9]+(\.[0-9]*)?/
|
44
|
+
|
45
|
+
# Fixed dates / timestamp
|
46
|
+
return $1 if value =~ /^'(.+)'::(date|timestamp)/
|
47
|
+
|
48
|
+
# Anything else is blank, some user type, or some function
|
49
|
+
# and we can't know the value of that, so return nil.
|
50
|
+
return nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def modify_types(tp)
|
55
|
+
tp[:primary_key] = "serial primary key"
|
56
|
+
tp[:string][:limit] = 255
|
57
|
+
tp[:integer][:limit] = nil
|
58
|
+
tp[:boolean][:limit] = nil
|
59
|
+
tp
|
60
|
+
end
|
61
|
+
|
62
|
+
def default_sequence_name(table_name, pk = nil)
|
63
|
+
default_pk, default_seq = pk_and_sequence_for(table_name)
|
64
|
+
default_seq || "#{table_name}_#{pk || default_pk || 'id'}_seq"
|
65
|
+
end
|
66
|
+
|
67
|
+
# Find a table's primary key and sequence.
|
68
|
+
def pk_and_sequence_for(table)
|
69
|
+
# First try looking for a sequence with a dependency on the
|
70
|
+
# given table's primary key.
|
71
|
+
result = select(<<-end_sql, 'PK and serial sequence')[0]
|
72
|
+
SELECT attr.attname AS nm, name.nspname AS nsp, seq.relname AS rel
|
73
|
+
FROM pg_class seq,
|
74
|
+
pg_attribute attr,
|
75
|
+
pg_depend dep,
|
76
|
+
pg_namespace name,
|
77
|
+
pg_constraint cons
|
78
|
+
WHERE seq.oid = dep.objid
|
79
|
+
AND seq.relnamespace = name.oid
|
80
|
+
AND seq.relkind = 'S'
|
81
|
+
AND attr.attrelid = dep.refobjid
|
82
|
+
AND attr.attnum = dep.refobjsubid
|
83
|
+
AND attr.attrelid = cons.conrelid
|
84
|
+
AND attr.attnum = cons.conkey[1]
|
85
|
+
AND cons.contype = 'p'
|
86
|
+
AND dep.refobjid = '#{table}'::regclass
|
87
|
+
end_sql
|
88
|
+
|
89
|
+
if result.nil? or result.empty?
|
90
|
+
# If that fails, try parsing the primary key's default value.
|
91
|
+
# Support the 7.x and 8.0 nextval('foo'::text) as well as
|
92
|
+
# the 8.1+ nextval('foo'::regclass).
|
93
|
+
# TODO: assumes sequence is in same schema as table.
|
94
|
+
result = select(<<-end_sql, 'PK and custom sequence')[0]
|
95
|
+
SELECT attr.attname AS nm, name.nspname AS nsp, split_part(def.adsrc, '\\\'', 2) AS rel
|
96
|
+
FROM pg_class t
|
97
|
+
JOIN pg_namespace name ON (t.relnamespace = name.oid)
|
98
|
+
JOIN pg_attribute attr ON (t.oid = attrelid)
|
99
|
+
JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum)
|
100
|
+
JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1])
|
101
|
+
WHERE t.oid = '#{table}'::regclass
|
102
|
+
AND cons.contype = 'p'
|
103
|
+
AND def.adsrc ~* 'nextval'
|
104
|
+
end_sql
|
105
|
+
end
|
106
|
+
# check for existence of . in sequence name as in public.foo_sequence. if it does not exist, join the current namespace
|
107
|
+
result['rel']['.'] ? [result['nm'], result['rel']] : [result['nm'], "#{result['nsp']}.#{result['rel']}"]
|
108
|
+
rescue
|
109
|
+
nil
|
110
|
+
end
|
111
|
+
|
112
|
+
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
|
113
|
+
execute(sql, name)
|
114
|
+
table = sql.split(" ", 4)[2]
|
115
|
+
id_value || last_insert_id(table, sequence_name || default_sequence_name(table, pk))
|
116
|
+
end
|
117
|
+
|
118
|
+
def last_insert_id(table, sequence_name)
|
119
|
+
Integer(select_value("SELECT currval('#{sequence_name}')"))
|
120
|
+
end
|
121
|
+
|
122
|
+
def quote(value, column = nil)
|
123
|
+
if value.kind_of?(String) && column && column.type == :binary
|
124
|
+
"'#{escape_bytea(value)}'"
|
125
|
+
elsif column && column.type == :primary_key
|
126
|
+
return value.to_s
|
127
|
+
else
|
128
|
+
super
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def quote_column_name(name)
|
133
|
+
%("#{name}")
|
134
|
+
end
|
135
|
+
|
136
|
+
def rename_table(name, new_name)
|
137
|
+
execute "ALTER TABLE #{name} RENAME TO #{new_name}"
|
138
|
+
end
|
139
|
+
|
140
|
+
def add_column(table_name, column_name, type, options = {})
|
141
|
+
execute("ALTER TABLE #{table_name} ADD #{column_name} #{type_to_sql(type, options[:limit])}")
|
142
|
+
execute("ALTER TABLE #{table_name} ALTER #{column_name} SET NOT NULL") if options[:null] == false
|
143
|
+
change_column_default(table_name, column_name, options[:default]) unless options[:default].nil?
|
144
|
+
end
|
145
|
+
|
146
|
+
def change_column(table_name, column_name, type, options = {}) #:nodoc:
|
147
|
+
begin
|
148
|
+
execute "ALTER TABLE #{table_name} ALTER #{column_name} TYPE #{type_to_sql(type, options[:limit])}"
|
149
|
+
rescue ActiveRecord::StatementInvalid
|
150
|
+
# This is PG7, so we use a more arcane way of doing it.
|
151
|
+
begin_db_transaction
|
152
|
+
add_column(table_name, "#{column_name}_ar_tmp", type, options)
|
153
|
+
execute "UPDATE #{table_name} SET #{column_name}_ar_tmp = CAST(#{column_name} AS #{type_to_sql(type, options[:limit])})"
|
154
|
+
remove_column(table_name, column_name)
|
155
|
+
rename_column(table_name, "#{column_name}_ar_tmp", column_name)
|
156
|
+
commit_db_transaction
|
157
|
+
end
|
158
|
+
change_column_default(table_name, column_name, options[:default]) unless options[:default].nil?
|
159
|
+
end
|
160
|
+
|
161
|
+
def change_column_default(table_name, column_name, default) #:nodoc:
|
162
|
+
execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT '#{default}'"
|
163
|
+
end
|
164
|
+
|
165
|
+
def rename_column(table_name, column_name, new_column_name) #:nodoc:
|
166
|
+
execute "ALTER TABLE #{table_name} RENAME COLUMN #{column_name} TO #{new_column_name}"
|
167
|
+
end
|
168
|
+
|
169
|
+
def remove_index(table_name, options) #:nodoc:
|
170
|
+
execute "DROP INDEX #{index_name(table_name, options)}"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
data/test/db/hsqldb.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
config = {
|
2
|
+
:adapter => 'jdbc',
|
3
|
+
:username => 'sa',
|
4
|
+
:password => '',
|
5
|
+
:driver => 'org.hsqldb.jdbcDriver',
|
6
|
+
:url => 'jdbc:hsqldb:test.db'
|
7
|
+
}
|
8
|
+
|
9
|
+
ActiveRecord::Base.establish_connection(config)
|
10
|
+
|
11
|
+
at_exit {
|
12
|
+
# Clean up hsqldb when done
|
13
|
+
Dir['test.db*'].each {|f| File.delete(f)}
|
14
|
+
}
|
data/test/db/logger.rb
ADDED
data/test/db/mysql.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
config = {
|
2
|
+
:username => 'blog',
|
3
|
+
:password => ''
|
4
|
+
}
|
5
|
+
|
6
|
+
if RUBY_PLATFORM =~ /java/
|
7
|
+
config.update({
|
8
|
+
:adapter => 'jdbc',
|
9
|
+
:driver => 'com.mysql.jdbc.Driver',
|
10
|
+
:url => 'jdbc:mysql://localhost:3306/weblog_development',
|
11
|
+
})
|
12
|
+
else
|
13
|
+
config.update({
|
14
|
+
:adapter => 'mysql',
|
15
|
+
:database => 'weblog_development',
|
16
|
+
:host => 'localhost'
|
17
|
+
})
|
18
|
+
end
|
19
|
+
|
20
|
+
ActiveRecord::Base.establish_connection(config)
|
data/test/manualTestDatabase.rb
CHANGED
@@ -41,7 +41,7 @@ ActiveRecord::Schema.define do
|
|
41
41
|
change_column :author, :descr, :string, :limit => 100 if /db2|derby/ !~ ARGV[1]
|
42
42
|
change_column_default :author, :female, false if /db2|derby|mssql|firebird/ !~ ARGV[1]
|
43
43
|
remove_column :author, :died if /db2|derby/ !~ ARGV[1]
|
44
|
-
rename_column :author, :wakeup_time, :waking_time if /db2|derby/ !~ ARGV[1]
|
44
|
+
rename_column :author, :wakeup_time, :waking_time if /db2|derby|mimer/ !~ ARGV[1]
|
45
45
|
|
46
46
|
add_index :author, :name, :unique if /db2/ !~ ARGV[1]
|
47
47
|
add_index :author, [:age,:female], :name => :is_age_female if /db2/ !~ ARGV[1]
|
@@ -49,7 +49,7 @@ ActiveRecord::Schema.define do
|
|
49
49
|
remove_index :author, :name if /db2/ !~ ARGV[1]
|
50
50
|
remove_index :author, :name => :is_age_female if /db2/ !~ ARGV[1]
|
51
51
|
|
52
|
-
rename_table :author, :authors if /db2|firebird/ !~ ARGV[1]
|
52
|
+
rename_table :author, :authors if /db2|firebird|mimer/ !~ ARGV[1]
|
53
53
|
|
54
54
|
|
55
55
|
create_table :products, :force => true do |t|
|
@@ -73,7 +73,7 @@ ActiveRecord::Schema.define do
|
|
73
73
|
end
|
74
74
|
|
75
75
|
class Author < ActiveRecord::Base;
|
76
|
-
set_table_name "author" if /db2|firebird/ =~ ARGV[1]
|
76
|
+
set_table_name "author" if /db2|firebird|mimer/ =~ ARGV[1]
|
77
77
|
end
|
78
78
|
|
79
79
|
class Order < ActiveRecord::Base
|
@@ -152,7 +152,7 @@ end
|
|
152
152
|
$stderr.print '.'
|
153
153
|
Author.destroy_all
|
154
154
|
Author.create(:name => "Arne Svensson", :age => 30)
|
155
|
-
if /db2|derby/ !~ ARGV[1]
|
155
|
+
if /db2|derby|mimer/ !~ ARGV[1]
|
156
156
|
Author.create(:name => "Pelle Gogolsson", :age => 15, :waking_time => Time.now, :private_key => "afbafddsfgsdfg")
|
157
157
|
else
|
158
158
|
Author.create(:name => "Pelle Gogolsson", :age => 15, :wakeup_time => Time.now, :private_key => "afbafddsfgsdfg")
|
@@ -191,5 +191,5 @@ ActiveRecord::Schema.define do
|
|
191
191
|
drop_table :products
|
192
192
|
|
193
193
|
|
194
|
-
drop_table((/db2|firebird/=~ARGV[1]? :author : :authors ))
|
194
|
+
drop_table((/db2|firebird|mimer/=~ARGV[1]? :author : :authors ))
|
195
195
|
end
|
@@ -1,10 +1,5 @@
|
|
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
1
|
|
7
|
-
require '
|
2
|
+
require 'minirunit'
|
8
3
|
|
9
4
|
config = {
|
10
5
|
:adapter => 'jdbc',
|
@@ -13,10 +8,14 @@ config = {
|
|
13
8
|
:driver => 'org.hsqldb.jdbcDriver',
|
14
9
|
:url => 'jdbc:hsqldb:test.db'
|
15
10
|
}
|
11
|
+
RAILS_CONNECTION_ADAPTERS = ['abstract', 'jdbc']
|
16
12
|
|
17
13
|
require 'active_record'
|
18
14
|
|
19
15
|
ActiveRecord::Base.establish_connection(config)
|
16
|
+
require 'logger'
|
17
|
+
ActiveRecord::Base.logger = Logger.new($stdout)
|
18
|
+
ActiveRecord::Base.logger.level = Logger::DEBUG
|
20
19
|
|
21
20
|
class CreateEntries < ActiveRecord::Migration
|
22
21
|
def self.up
|
@@ -69,3 +68,6 @@ post.destroy
|
|
69
68
|
test_equal 0, Entry.count
|
70
69
|
|
71
70
|
CreateEntries.down
|
71
|
+
|
72
|
+
# Clean up hsqldb when done
|
73
|
+
Dir['test.db*'].each {|f| File.delete(f)}
|
data/test/minirunit/testMysql.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
if RUBY_PLATFORM =~ /java/
|
2
|
+
RAILS_CONNECTION_ADAPTERS = ['abstract', 'jdbc']
|
3
|
+
end
|
4
|
+
|
5
|
+
require 'active_record'
|
6
|
+
|
7
|
+
class CreateEntries < ActiveRecord::Migration
|
8
|
+
def self.up
|
9
|
+
create_table "entries", :force => true do |t|
|
10
|
+
t.column :title, :string, :limit => 100
|
11
|
+
t.column :updated_on, :datetime
|
12
|
+
t.column :content, :text
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.down
|
17
|
+
drop_table "entries"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Entry < ActiveRecord::Base
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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
|
+
|
8
|
+
require 'models/entry'
|
9
|
+
require 'db/mysql'
|
10
|
+
require 'simple'
|
11
|
+
require 'test/unit'
|
12
|
+
|
13
|
+
class MysqlSimpleTest < Test::Unit::TestCase
|
14
|
+
include SimpleTestMethods
|
15
|
+
end
|
data/test/simple.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
module MigrationSetup
|
2
|
+
def setup
|
3
|
+
CreateEntries.up
|
4
|
+
end
|
5
|
+
|
6
|
+
def teardown
|
7
|
+
CreateEntries.down
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module FixtureSetup
|
12
|
+
include MigrationSetup
|
13
|
+
def setup
|
14
|
+
super
|
15
|
+
@title = "First post!"
|
16
|
+
@content = "Hello from JRuby on Rails!"
|
17
|
+
@new_title = "First post updated title"
|
18
|
+
Entry.create :title => @title, :content => @content
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module SimpleTestMethods
|
23
|
+
include FixtureSetup
|
24
|
+
|
25
|
+
def test_entries_created
|
26
|
+
assert ActiveRecord::Base.connection.tables.include?('entries'), "entries not created"
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_entries_empty
|
30
|
+
Entry.delete_all
|
31
|
+
assert_equal 0, Entry.count
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_create_new_entry
|
35
|
+
Entry.delete_all
|
36
|
+
|
37
|
+
post = Entry.new
|
38
|
+
post.title = @title
|
39
|
+
post.content = @content
|
40
|
+
post.save
|
41
|
+
|
42
|
+
assert_equal 1, Entry.count
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_find_and_update_entry
|
46
|
+
post = Entry.find(:first)
|
47
|
+
assert_equal @title, post.title
|
48
|
+
assert_equal @content, post.content
|
49
|
+
|
50
|
+
post.title = @new_title
|
51
|
+
post.save
|
52
|
+
|
53
|
+
post = Entry.find(:first)
|
54
|
+
assert_equal @new_title, post.title
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_destroy_entry
|
58
|
+
prev_count = Entry.count
|
59
|
+
post = Entry.find(:first)
|
60
|
+
post.destroy
|
61
|
+
|
62
|
+
assert_equal prev_count - 1, Entry.count
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ActiveRecord-JDBC
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.2.
|
7
|
-
date: 2006-
|
6
|
+
version: 0.2.2
|
7
|
+
date: 2006-10-03 00:00:00 +02:00
|
8
8
|
summary: JDBC support for ActiveRecord. Only usable within JRuby
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -30,14 +30,29 @@ authors:
|
|
30
30
|
- JRuby-extras
|
31
31
|
files:
|
32
32
|
- lib/active_record
|
33
|
+
- lib/jdbc_adapter
|
33
34
|
- lib/jdbc_adapter.rb
|
34
35
|
- lib/active_record/connection_adapters
|
35
36
|
- lib/active_record/connection_adapters/jdbc_adapter_spec.rb
|
36
37
|
- lib/active_record/connection_adapters/jdbc_adapter.rb
|
38
|
+
- lib/jdbc_adapter/jdbc_postgre.rb
|
39
|
+
- lib/jdbc_adapter/jdbc_oracle.rb
|
40
|
+
- lib/jdbc_adapter/jdbc_mimer.rb
|
41
|
+
- lib/jdbc_adapter/jdbc_hsqldb.rb
|
42
|
+
- lib/jdbc_adapter/jdbc_firebird.rb
|
43
|
+
- lib/jdbc_adapter/jdbc_derby.rb
|
44
|
+
- lib/jdbc_adapter/jdbc_mysql.rb
|
45
|
+
- lib/jdbc_adapter/jdbc_db2.rb
|
46
|
+
- lib/jdbc_adapter/jdbc_mssql.rb
|
37
47
|
- test/activerecord
|
38
48
|
- test/minirunit
|
49
|
+
- test/models
|
39
50
|
- test/minirunit.rb
|
40
51
|
- test/manualTestDatabase.rb
|
52
|
+
- test/db
|
53
|
+
- test/hsqldb_simple_test.rb
|
54
|
+
- test/mysql_simple_test.rb
|
55
|
+
- test/simple.rb
|
41
56
|
- test/activerecord/connections
|
42
57
|
- test/activerecord/jtest.sh
|
43
58
|
- test/activerecord/jall.sh
|
@@ -48,6 +63,10 @@ files:
|
|
48
63
|
- test/minirunit/testConnect.rb
|
49
64
|
- test/minirunit/testRawSelect.rb
|
50
65
|
- test/minirunit/testLoadActiveRecord.rb
|
66
|
+
- test/models/entry.rb
|
67
|
+
- test/db/hsqldb.rb
|
68
|
+
- test/db/logger.rb
|
69
|
+
- test/db/mysql.rb
|
51
70
|
- LICENSE
|
52
71
|
- init.rb
|
53
72
|
- install.rb
|