activerecord-jdbc-adapter-onsite 1.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/.gitignore +22 -0
- data/.travis.yml +14 -0
- data/Appraisals +16 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +45 -0
- data/History.txt +488 -0
- data/LICENSE.txt +21 -0
- data/README.rdoc +214 -0
- data/Rakefile +62 -0
- data/activerecord-jdbc-adapter.gemspec +23 -0
- data/bench/bench_attributes.rb +13 -0
- data/bench/bench_attributes_new.rb +14 -0
- data/bench/bench_create.rb +12 -0
- data/bench/bench_find_all.rb +12 -0
- data/bench/bench_find_all_mt.rb +25 -0
- data/bench/bench_model.rb +85 -0
- data/bench/bench_new.rb +12 -0
- data/bench/bench_new_valid.rb +12 -0
- data/bench/bench_valid.rb +13 -0
- data/gemfiles/rails23.gemfile +10 -0
- data/gemfiles/rails23.gemfile.lock +38 -0
- data/gemfiles/rails30.gemfile +9 -0
- data/gemfiles/rails30.gemfile.lock +33 -0
- data/gemfiles/rails31.gemfile +9 -0
- data/gemfiles/rails31.gemfile.lock +35 -0
- data/gemfiles/rails32.gemfile +9 -0
- data/gemfiles/rails32.gemfile.lock +35 -0
- 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/informix_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql2_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/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
- data/lib/activerecord-jdbc-adapter.rb +8 -0
- data/lib/arel/engines/sql/compilers/db2_compiler.rb +9 -0
- data/lib/arel/engines/sql/compilers/derby_compiler.rb +6 -0
- data/lib/arel/engines/sql/compilers/h2_compiler.rb +6 -0
- data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +15 -0
- data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +6 -0
- data/lib/arel/engines/sql/compilers/mssql_compiler.rb +46 -0
- data/lib/arel/visitors/compat.rb +13 -0
- data/lib/arel/visitors/db2.rb +17 -0
- data/lib/arel/visitors/derby.rb +32 -0
- data/lib/arel/visitors/firebird.rb +24 -0
- data/lib/arel/visitors/hsqldb.rb +26 -0
- data/lib/arel/visitors/sql_server.rb +46 -0
- data/lib/arjdbc.rb +24 -0
- data/lib/arjdbc/db2.rb +2 -0
- data/lib/arjdbc/db2/adapter.rb +541 -0
- data/lib/arjdbc/derby.rb +7 -0
- data/lib/arjdbc/derby/adapter.rb +358 -0
- data/lib/arjdbc/derby/connection_methods.rb +19 -0
- data/lib/arjdbc/discover.rb +92 -0
- data/lib/arjdbc/firebird.rb +2 -0
- data/lib/arjdbc/firebird/adapter.rb +140 -0
- data/lib/arjdbc/h2.rb +4 -0
- data/lib/arjdbc/h2/adapter.rb +54 -0
- data/lib/arjdbc/h2/connection_methods.rb +13 -0
- data/lib/arjdbc/hsqldb.rb +4 -0
- data/lib/arjdbc/hsqldb/adapter.rb +184 -0
- data/lib/arjdbc/hsqldb/connection_methods.rb +15 -0
- data/lib/arjdbc/informix.rb +3 -0
- data/lib/arjdbc/informix/adapter.rb +142 -0
- data/lib/arjdbc/informix/connection_methods.rb +11 -0
- data/lib/arjdbc/jdbc.rb +2 -0
- data/lib/arjdbc/jdbc/adapter.rb +356 -0
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/base_ext.rb +15 -0
- data/lib/arjdbc/jdbc/callbacks.rb +44 -0
- data/lib/arjdbc/jdbc/column.rb +47 -0
- data/lib/arjdbc/jdbc/compatibility.rb +51 -0
- data/lib/arjdbc/jdbc/connection.rb +134 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +16 -0
- data/lib/arjdbc/jdbc/core_ext.rb +24 -0
- data/lib/arjdbc/jdbc/discover.rb +18 -0
- data/lib/arjdbc/jdbc/driver.rb +35 -0
- data/lib/arjdbc/jdbc/extension.rb +47 -0
- data/lib/arjdbc/jdbc/java.rb +14 -0
- data/lib/arjdbc/jdbc/jdbc.rake +131 -0
- data/lib/arjdbc/jdbc/missing_functionality_helper.rb +88 -0
- data/lib/arjdbc/jdbc/quoted_primary_key.rb +28 -0
- data/lib/arjdbc/jdbc/railtie.rb +9 -0
- data/lib/arjdbc/jdbc/rake_tasks.rb +10 -0
- data/lib/arjdbc/jdbc/require_driver.rb +16 -0
- data/lib/arjdbc/jdbc/type_converter.rb +126 -0
- data/lib/arjdbc/mimer.rb +2 -0
- data/lib/arjdbc/mimer/adapter.rb +142 -0
- data/lib/arjdbc/mssql.rb +4 -0
- data/lib/arjdbc/mssql/adapter.rb +477 -0
- data/lib/arjdbc/mssql/connection_methods.rb +31 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +101 -0
- data/lib/arjdbc/mssql/lock_helpers.rb +72 -0
- data/lib/arjdbc/mssql/tsql_helper.rb +61 -0
- data/lib/arjdbc/mysql.rb +4 -0
- data/lib/arjdbc/mysql/adapter.rb +505 -0
- data/lib/arjdbc/mysql/connection_methods.rb +28 -0
- data/lib/arjdbc/oracle.rb +3 -0
- data/lib/arjdbc/oracle/adapter.rb +432 -0
- data/lib/arjdbc/oracle/connection_methods.rb +12 -0
- data/lib/arjdbc/postgresql.rb +4 -0
- data/lib/arjdbc/postgresql/adapter.rb +861 -0
- data/lib/arjdbc/postgresql/connection_methods.rb +23 -0
- data/lib/arjdbc/sqlite3.rb +4 -0
- data/lib/arjdbc/sqlite3/adapter.rb +389 -0
- data/lib/arjdbc/sqlite3/connection_methods.rb +35 -0
- data/lib/arjdbc/sybase.rb +2 -0
- data/lib/arjdbc/sybase/adapter.rb +46 -0
- data/lib/arjdbc/version.rb +8 -0
- data/lib/generators/jdbc/USAGE +10 -0
- data/lib/generators/jdbc/jdbc_generator.rb +9 -0
- data/lib/jdbc_adapter.rb +2 -0
- data/lib/jdbc_adapter/rake_tasks.rb +3 -0
- data/lib/jdbc_adapter/version.rb +3 -0
- data/lib/pg.rb +26 -0
- data/pom.xml +57 -0
- data/rails_generators/jdbc_generator.rb +15 -0
- data/rails_generators/templates/config/initializers/jdbc.rb +7 -0
- data/rails_generators/templates/lib/tasks/jdbc.rake +8 -0
- data/rakelib/bundler_ext.rb +11 -0
- data/rakelib/compile.rake +23 -0
- data/rakelib/db.rake +39 -0
- data/rakelib/rails.rake +41 -0
- data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +69 -0
- data/src/java/arjdbc/derby/DerbyModule.java +324 -0
- data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +70 -0
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +74 -0
- data/src/java/arjdbc/jdbc/AdapterJavaService.java +68 -0
- data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +36 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +1346 -0
- data/src/java/arjdbc/jdbc/SQLBlock.java +48 -0
- data/src/java/arjdbc/mssql/MssqlRubyJdbcConnection.java +127 -0
- data/src/java/arjdbc/mysql/MySQLModule.java +134 -0
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +161 -0
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +85 -0
- data/src/java/arjdbc/postgresql/PostgresqlRubyJdbcConnection.java +82 -0
- data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +126 -0
- data/test/abstract_db_create.rb +135 -0
- data/test/activerecord/connection_adapters/type_conversion_test.rb +31 -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/db/db2.rb +11 -0
- data/test/db/derby.rb +12 -0
- data/test/db/h2.rb +11 -0
- data/test/db/hsqldb.rb +13 -0
- data/test/db/informix.rb +11 -0
- data/test/db/jdbc.rb +12 -0
- data/test/db/jndi_config.rb +40 -0
- data/test/db/logger.rb +3 -0
- data/test/db/mssql.rb +9 -0
- data/test/db/mysql.rb +10 -0
- data/test/db/oracle.rb +34 -0
- data/test/db/postgres.rb +18 -0
- data/test/db/sqlite3.rb +11 -0
- data/test/db2_reset_column_information_test.rb +8 -0
- data/test/db2_simple_test.rb +66 -0
- data/test/derby_migration_test.rb +68 -0
- data/test/derby_multibyte_test.rb +12 -0
- data/test/derby_reset_column_information_test.rb +8 -0
- data/test/derby_row_locking_test.rb +9 -0
- data/test/derby_simple_test.rb +139 -0
- data/test/generic_jdbc_connection_test.rb +29 -0
- data/test/h2_change_column_test.rb +68 -0
- data/test/h2_simple_test.rb +41 -0
- data/test/has_many_through.rb +79 -0
- data/test/helper.rb +108 -0
- data/test/hsqldb_simple_test.rb +6 -0
- data/test/informix_simple_test.rb +48 -0
- data/test/jdbc_common.rb +28 -0
- data/test/jndi_callbacks_test.rb +36 -0
- data/test/jndi_test.rb +25 -0
- data/test/manualTestDatabase.rb +191 -0
- data/test/models/add_not_null_column_to_table.rb +9 -0
- data/test/models/auto_id.rb +15 -0
- data/test/models/custom_pk_name.rb +14 -0
- data/test/models/data_types.rb +30 -0
- data/test/models/entry.rb +40 -0
- data/test/models/mixed_case.rb +22 -0
- data/test/models/reserved_word.rb +15 -0
- data/test/models/string_id.rb +17 -0
- data/test/models/thing.rb +16 -0
- data/test/models/validates_uniqueness_of_string.rb +19 -0
- data/test/mssql_db_create_test.rb +26 -0
- data/test/mssql_identity_insert_test.rb +19 -0
- data/test/mssql_ignore_system_views_test.rb +27 -0
- data/test/mssql_legacy_types_test.rb +58 -0
- data/test/mssql_limit_offset_test.rb +136 -0
- data/test/mssql_multibyte_test.rb +18 -0
- data/test/mssql_null_test.rb +14 -0
- data/test/mssql_reset_column_information_test.rb +8 -0
- data/test/mssql_row_locking_sql_test.rb +159 -0
- data/test/mssql_row_locking_test.rb +9 -0
- data/test/mssql_simple_test.rb +55 -0
- data/test/mysql_db_create_test.rb +27 -0
- data/test/mysql_index_length_test.rb +58 -0
- data/test/mysql_info_test.rb +123 -0
- data/test/mysql_multibyte_test.rb +10 -0
- data/test/mysql_nonstandard_primary_key_test.rb +42 -0
- data/test/mysql_reset_column_information_test.rb +8 -0
- data/test/mysql_simple_test.rb +125 -0
- data/test/oracle_reset_column_information_test.rb +8 -0
- data/test/oracle_simple_test.rb +18 -0
- data/test/oracle_specific_test.rb +83 -0
- data/test/postgres_db_create_test.rb +32 -0
- data/test/postgres_drop_db_test.rb +16 -0
- data/test/postgres_information_schema_leak_test.rb +29 -0
- data/test/postgres_mixed_case_test.rb +29 -0
- data/test/postgres_native_type_mapping_test.rb +93 -0
- data/test/postgres_nonseq_pkey_test.rb +38 -0
- data/test/postgres_reserved_test.rb +22 -0
- data/test/postgres_reset_column_information_test.rb +8 -0
- data/test/postgres_schema_search_path_test.rb +48 -0
- data/test/postgres_simple_test.rb +168 -0
- data/test/postgres_table_alias_length_test.rb +15 -0
- data/test/postgres_type_conversion_test.rb +34 -0
- data/test/row_locking.rb +90 -0
- data/test/simple.rb +731 -0
- data/test/sqlite3_reset_column_information_test.rb +8 -0
- data/test/sqlite3_simple_test.rb +316 -0
- data/test/sybase_jtds_simple_test.rb +28 -0
- data/test/sybase_reset_column_information_test.rb +8 -0
- metadata +288 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
module ::ArJdbc
|
|
2
|
+
module FireBird
|
|
3
|
+
|
|
4
|
+
def self.extended(mod)
|
|
5
|
+
unless @lob_callback_added
|
|
6
|
+
ActiveRecord::Base.class_eval do
|
|
7
|
+
def after_save_with_firebird_blob
|
|
8
|
+
self.class.columns.select { |c| c.sql_type =~ /blob/i }.each do |c|
|
|
9
|
+
value = self[c.name]
|
|
10
|
+
if respond_to?(:unserializable_attribute?)
|
|
11
|
+
value = value.to_yaml if unserializable_attribute?(c.name, c)
|
|
12
|
+
else
|
|
13
|
+
value = value.to_yaml if value.is_a?(Hash)
|
|
14
|
+
end
|
|
15
|
+
next if value.nil?
|
|
16
|
+
connection.write_large_object(c.type == :binary, c.name, self.class.table_name, self.class.primary_key, quote_value(id), value)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
ActiveRecord::Base.after_save :after_save_with_firebird_blob
|
|
22
|
+
@lob_callback_added = true
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def adapter_name
|
|
27
|
+
'Firebird'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.arel2_visitors(config)
|
|
31
|
+
require 'arel/visitors/firebird'
|
|
32
|
+
{}.tap {|v| %w(firebird firebirdsql).each {|a| v[a] = ::Arel::Visitors::Firebird } }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def modify_types(tp)
|
|
36
|
+
tp[:primary_key] = 'INTEGER NOT NULL PRIMARY KEY'
|
|
37
|
+
tp[:string][:limit] = 252
|
|
38
|
+
tp[:integer][:limit] = nil
|
|
39
|
+
tp
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) # :nodoc:
|
|
43
|
+
execute(sql, name, binds)
|
|
44
|
+
id_value
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def add_limit_offset!(sql, options) # :nodoc:
|
|
48
|
+
if options[:limit]
|
|
49
|
+
limit_string = "FIRST #{options[:limit]}"
|
|
50
|
+
limit_string << " SKIP #{options[:offset]}" if options[:offset]
|
|
51
|
+
sql.sub!(/\A(\s*SELECT\s)/i, '\&' + limit_string + ' ')
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def prefetch_primary_key?(table_name = nil)
|
|
56
|
+
true
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def default_sequence_name(table_name, primary_key) # :nodoc:
|
|
60
|
+
"#{table_name}_seq"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def next_sequence_value(sequence_name)
|
|
64
|
+
select_one("SELECT GEN_ID(#{sequence_name}, 1 ) FROM RDB$DATABASE;")["gen_id"]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def create_table(name, options = {}) #:nodoc:
|
|
68
|
+
super(name, options)
|
|
69
|
+
execute "CREATE GENERATOR #{name}_seq"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def rename_table(name, new_name) #:nodoc:
|
|
73
|
+
execute "RENAME #{name} TO #{new_name}"
|
|
74
|
+
execute "UPDATE RDB$GENERATORS SET RDB$GENERATOR_NAME='#{new_name}_seq' WHERE RDB$GENERATOR_NAME='#{name}_seq'" rescue nil
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def drop_table(name, options = {}) #:nodoc:
|
|
78
|
+
super(name)
|
|
79
|
+
execute "DROP GENERATOR #{name}_seq" rescue nil
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def change_column(table_name, column_name, type, options = {}) #:nodoc:
|
|
83
|
+
execute "ALTER TABLE #{table_name} ALTER #{column_name} TYPE #{type_to_sql(type, options[:limit])}"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def rename_column(table_name, column_name, new_column_name)
|
|
87
|
+
execute "ALTER TABLE #{table_name} ALTER #{column_name} TO #{new_column_name}"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def remove_index(table_name, options) #:nodoc:
|
|
91
|
+
execute "DROP INDEX #{index_name(table_name, options)}"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def quote(value, column = nil) # :nodoc:
|
|
95
|
+
return value.quoted_id if value.respond_to?(:quoted_id)
|
|
96
|
+
|
|
97
|
+
# BLOBs are updated separately by an after_save trigger.
|
|
98
|
+
return value.nil? ? "NULL" : "'#{quote_string(value[0..1])}'" if column && [:binary, :text].include?(column.type)
|
|
99
|
+
|
|
100
|
+
if [Time, DateTime].include?(value.class)
|
|
101
|
+
"CAST('#{value.strftime("%Y-%m-%d %H:%M:%S")}' AS TIMESTAMP)"
|
|
102
|
+
else
|
|
103
|
+
if column && column.type == :primary_key
|
|
104
|
+
return value.to_s
|
|
105
|
+
end
|
|
106
|
+
super
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def quote_string(string) # :nodoc:
|
|
111
|
+
string.gsub(/'/, "''")
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def quote_column_name(column_name) # :nodoc:
|
|
115
|
+
%Q("#{ar_to_fb_case(column_name)}")
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def quoted_true # :nodoc:
|
|
119
|
+
quote(1)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def quoted_false # :nodoc:
|
|
123
|
+
quote(0)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
private
|
|
127
|
+
|
|
128
|
+
# Maps uppercase Firebird column names to lowercase for ActiveRecord;
|
|
129
|
+
# mixed-case columns retain their original case.
|
|
130
|
+
def fb_to_ar_case(column_name)
|
|
131
|
+
column_name =~ /[[:lower:]]/ ? column_name : column_name.to_s.downcase
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Maps lowercase ActiveRecord column names to uppercase for Fierbird;
|
|
135
|
+
# mixed-case columns retain their original case.
|
|
136
|
+
def ar_to_fb_case(column_name)
|
|
137
|
+
column_name =~ /[[:upper:]]/ ? column_name : column_name.to_s.upcase
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
data/lib/arjdbc/h2.rb
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'arjdbc/hsqldb/adapter'
|
|
2
|
+
|
|
3
|
+
module ArJdbc
|
|
4
|
+
module H2
|
|
5
|
+
include HSQLDB
|
|
6
|
+
|
|
7
|
+
def self.jdbc_connection_class
|
|
8
|
+
::ActiveRecord::ConnectionAdapters::H2JdbcConnection
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def adapter_name #:nodoc:
|
|
12
|
+
'H2'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.arel2_visitors(config)
|
|
16
|
+
v = HSQLDB.arel2_visitors(config)
|
|
17
|
+
v.merge({}.tap {|v| %w(h2 jdbch2).each {|a| v[a] = ::Arel::Visitors::HSQLDB } })
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def h2_adapter
|
|
21
|
+
true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def tables
|
|
25
|
+
@connection.tables(nil, h2_schema)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def columns(table_name, name=nil)
|
|
29
|
+
@connection.columns_internal(table_name.to_s, name, h2_schema)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def change_column(table_name, column_name, type, options = {}) #:nodoc:
|
|
33
|
+
execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
|
|
34
|
+
change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
|
|
35
|
+
change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
def change_column_null(table_name, column_name, null, default = nil)
|
|
40
|
+
if !null && !default.nil?
|
|
41
|
+
execute("UPDATE #{table_name} SET #{column_name}=#{quote(default)} WHERE #{column_name} IS NULL")
|
|
42
|
+
end
|
|
43
|
+
if null
|
|
44
|
+
execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET NULL"
|
|
45
|
+
else
|
|
46
|
+
execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET NOT NULL"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def h2_schema
|
|
51
|
+
@config[:schema] || ''
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
class Base
|
|
3
|
+
class << self
|
|
4
|
+
def h2_connection(config)
|
|
5
|
+
config[:url] ||= "jdbc:h2:#{config[:database]}"
|
|
6
|
+
config[:driver] ||= "org.h2.Driver"
|
|
7
|
+
config[:adapter_spec] = ::ArJdbc::H2
|
|
8
|
+
embedded_driver(config)
|
|
9
|
+
end
|
|
10
|
+
alias_method :jdbch2_connection, :h2_connection
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
module ::ArJdbc
|
|
2
|
+
module HSQLDB
|
|
3
|
+
def self.column_selector
|
|
4
|
+
[/hsqldb|\.h2\./i, lambda {|cfg,col| col.extend(::ArJdbc::HSQLDB::Column)}]
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
module Column
|
|
8
|
+
private
|
|
9
|
+
def simplified_type(field_type)
|
|
10
|
+
case field_type
|
|
11
|
+
when /longvarchar/i then :text
|
|
12
|
+
when /tinyint/i then :boolean
|
|
13
|
+
when /real/i then :float
|
|
14
|
+
else
|
|
15
|
+
super
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Override of ActiveRecord::ConnectionAdapters::Column
|
|
20
|
+
def extract_limit(sql_type)
|
|
21
|
+
# HSQLDB appears to return "LONGVARCHAR(0)" for :text columns, which
|
|
22
|
+
# for AR purposes should be interpreted as "no limit"
|
|
23
|
+
return nil if sql_type =~ /\(0\)/
|
|
24
|
+
super
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Post process default value from JDBC into a Rails-friendly format (columns{-internal})
|
|
28
|
+
def default_value(value)
|
|
29
|
+
# H2 auto-generated key default value
|
|
30
|
+
return nil if value =~ /^\(NEXT VALUE FOR/i
|
|
31
|
+
|
|
32
|
+
# jdbc returns column default strings with actual single quotes around the value.
|
|
33
|
+
return $1 if value =~ /^'(.*)'$/
|
|
34
|
+
|
|
35
|
+
value
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def adapter_name #:nodoc:
|
|
40
|
+
'Hsqldb'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.arel2_visitors(config)
|
|
44
|
+
require 'arel/visitors/hsqldb'
|
|
45
|
+
{}.tap {|v| %w(hsqldb jdbchsqldb).each {|a| v[a] = ::Arel::Visitors::HSQLDB } }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def modify_types(tp)
|
|
49
|
+
tp[:primary_key] = "INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY"
|
|
50
|
+
tp[:integer][:limit] = nil
|
|
51
|
+
tp[:boolean][:limit] = nil
|
|
52
|
+
# set text and float limits so we don't see odd scales tacked on
|
|
53
|
+
# in migrations
|
|
54
|
+
tp[:boolean] = { :name => "tinyint" }
|
|
55
|
+
tp[:text][:limit] = nil
|
|
56
|
+
tp[:float][:limit] = 17 if defined?(::Jdbc::H2)
|
|
57
|
+
tp[:string][:limit] = 255
|
|
58
|
+
tp[:datetime] = { :name => "DATETIME" }
|
|
59
|
+
tp[:timestamp] = { :name => "DATETIME" }
|
|
60
|
+
tp[:time] = { :name => "TIME" }
|
|
61
|
+
tp[:date] = { :name => "DATE" }
|
|
62
|
+
tp
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def quote(value, column = nil) # :nodoc:
|
|
66
|
+
return value.quoted_id if value.respond_to?(:quoted_id)
|
|
67
|
+
|
|
68
|
+
case value
|
|
69
|
+
when String
|
|
70
|
+
if respond_to?(:h2_adapter) && value.empty?
|
|
71
|
+
"''"
|
|
72
|
+
elsif column && column.type == :binary
|
|
73
|
+
"'#{value.unpack("H*")[0]}'"
|
|
74
|
+
elsif column && (column.type == :integer ||
|
|
75
|
+
column.respond_to?(:primary) && column.primary && column.klass != String)
|
|
76
|
+
value.to_i.to_s
|
|
77
|
+
else
|
|
78
|
+
"'#{quote_string(value)}'"
|
|
79
|
+
end
|
|
80
|
+
else
|
|
81
|
+
super
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def quote_column_name(name) #:nodoc:
|
|
86
|
+
name = name.to_s
|
|
87
|
+
if name =~ /[-]/
|
|
88
|
+
%Q{"#{name.upcase}"}
|
|
89
|
+
else
|
|
90
|
+
name
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def quote_string(str)
|
|
95
|
+
str.gsub(/'/, "''")
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def quoted_true
|
|
99
|
+
'1'
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def quoted_false
|
|
103
|
+
'0'
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def add_column(table_name, column_name, type, options = {})
|
|
107
|
+
add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
|
|
108
|
+
add_column_options!(add_column_sql, options)
|
|
109
|
+
execute(add_column_sql)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def change_column(table_name, column_name, type, options = {}) #:nodoc:
|
|
113
|
+
execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def change_column_default(table_name, column_name, default) #:nodoc:
|
|
117
|
+
execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT #{quote(default)}"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def rename_column(table_name, column_name, new_column_name) #:nodoc:
|
|
121
|
+
execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} RENAME TO #{new_column_name}"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Maps logical Rails types to MySQL-specific data types.
|
|
125
|
+
def type_to_sql(type, limit = nil, precision = nil, scale = nil)
|
|
126
|
+
return super if defined?(::Jdbc::H2) || type.to_s != 'integer' || limit == nil
|
|
127
|
+
|
|
128
|
+
type
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def rename_table(name, new_name)
|
|
132
|
+
execute "ALTER TABLE #{name} RENAME TO #{new_name}"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def last_insert_id
|
|
136
|
+
Integer(select_value("CALL IDENTITY()"))
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def _execute(sql, name = nil)
|
|
140
|
+
result = super
|
|
141
|
+
ActiveRecord::ConnectionAdapters::JdbcConnection::insert?(sql) ? last_insert_id : result
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def add_limit_offset!(sql, options) #:nodoc:
|
|
145
|
+
if sql =~ /^select/i
|
|
146
|
+
offset = options[:offset] || 0
|
|
147
|
+
bef = sql[7..-1]
|
|
148
|
+
if limit = options[:limit]
|
|
149
|
+
sql.replace "SELECT LIMIT #{offset} #{limit} #{bef}"
|
|
150
|
+
elsif offset > 0
|
|
151
|
+
sql.replace "SELECT LIMIT #{offset} 0 #{bef}"
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# override to filter out system tables that otherwise end
|
|
157
|
+
# up in db/schema.rb during migrations. JdbcConnection#tables
|
|
158
|
+
# now takes an optional block filter so we can screen out
|
|
159
|
+
# rows corresponding to system tables. HSQLDB names its
|
|
160
|
+
# system tables SYSTEM.*, but H2 seems to name them without
|
|
161
|
+
# any kind of convention
|
|
162
|
+
def tables
|
|
163
|
+
@connection.tables.select {|row| row.to_s !~ /^system_/i }
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def remove_index(table_name, options = {})
|
|
167
|
+
execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}"
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def recreate_database(name)
|
|
171
|
+
drop_database(name)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# do nothing since database gets created upon connection. However
|
|
175
|
+
# this method gets called by rails db rake tasks so now we're
|
|
176
|
+
# avoiding method_missing error
|
|
177
|
+
def create_database(name)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def drop_database(name)
|
|
181
|
+
execute("DROP ALL OBJECTS")
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
class Base
|
|
3
|
+
class << self
|
|
4
|
+
def hsqldb_connection(config)
|
|
5
|
+
require "arjdbc/hsqldb"
|
|
6
|
+
config[:url] ||= "jdbc:hsqldb:#{config[:database]}"
|
|
7
|
+
config[:driver] ||= "org.hsqldb.jdbcDriver"
|
|
8
|
+
config[:adapter_spec] = ::ArJdbc::HSQLDB
|
|
9
|
+
embedded_driver(config)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
alias_method :jdbchsqldb_connection, :hsqldb_connection
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
module ::ActiveRecord
|
|
2
|
+
class Base
|
|
3
|
+
after_save :write_lobs
|
|
4
|
+
|
|
5
|
+
private
|
|
6
|
+
def write_lobs
|
|
7
|
+
if connection.is_a?(ArJdbc::Informix)
|
|
8
|
+
self.class.columns.each do |c|
|
|
9
|
+
if [:text, :binary].include? c.type
|
|
10
|
+
value = self[c.name]
|
|
11
|
+
if respond_to?(:unserializable_attribute?)
|
|
12
|
+
value = value.to_yaml if unserializable_attribute?(c.name, c)
|
|
13
|
+
else
|
|
14
|
+
value = value.to_yaml if value.is_a?(Hash)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
unless value.nil? || (value == '')
|
|
18
|
+
connection.write_large_object(c.type == :binary,
|
|
19
|
+
c.name,
|
|
20
|
+
self.class.table_name,
|
|
21
|
+
self.class.primary_key,
|
|
22
|
+
quote_value(id),
|
|
23
|
+
value)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module ::ArJdbc
|
|
33
|
+
module Informix
|
|
34
|
+
def self.extended(base)
|
|
35
|
+
@@db_major_version = base.select_one("SELECT dbinfo('version', 'major') version FROM systables WHERE tabid = 1")['version'].to_i
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.column_selector
|
|
39
|
+
[ /informix/i,
|
|
40
|
+
lambda { |cfg, column| column.extend(::ArJdbc::Informix::Column) } ]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.jdbc_connection_class
|
|
44
|
+
::ActiveRecord::ConnectionAdapters::InformixJdbcConnection
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
module Column
|
|
48
|
+
private
|
|
49
|
+
# TODO: Test all Informix column types.
|
|
50
|
+
def simplified_type(field_type)
|
|
51
|
+
if field_type =~ /serial/i
|
|
52
|
+
:primary_key
|
|
53
|
+
else
|
|
54
|
+
super
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def modify_types(tp)
|
|
60
|
+
tp[:primary_key] = "SERIAL PRIMARY KEY"
|
|
61
|
+
tp[:string] = { :name => "VARCHAR", :limit => 255 }
|
|
62
|
+
tp[:integer] = { :name => "INTEGER" }
|
|
63
|
+
tp[:float] = { :name => "FLOAT" }
|
|
64
|
+
tp[:decimal] = { :name => "DECIMAL" }
|
|
65
|
+
tp[:datetime] = { :name => "DATETIME YEAR TO FRACTION(5)" }
|
|
66
|
+
tp[:timestamp] = { :name => "DATETIME YEAR TO FRACTION(5)" }
|
|
67
|
+
tp[:time] = { :name => "DATETIME HOUR TO FRACTION(5)" }
|
|
68
|
+
tp[:date] = { :name => "DATE" }
|
|
69
|
+
tp[:binary] = { :name => "BYTE" }
|
|
70
|
+
tp[:boolean] = { :name => "BOOLEAN" }
|
|
71
|
+
tp
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def prefetch_primary_key?(table_name = nil)
|
|
75
|
+
true
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def supports_migrations?
|
|
79
|
+
true
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def default_sequence_name(table, column)
|
|
83
|
+
"#{table}_seq"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def add_limit_offset!(sql, options)
|
|
87
|
+
if options[:limit]
|
|
88
|
+
limit = "FIRST #{options[:limit]}"
|
|
89
|
+
# SKIP available only in IDS >= 10
|
|
90
|
+
offset = (@@db_major_version >= 10 && options[:offset]?
|
|
91
|
+
"SKIP #{options[:offset]}" : "")
|
|
92
|
+
sql.sub!(/^select /i, "SELECT #{offset} #{limit} ")
|
|
93
|
+
end
|
|
94
|
+
sql
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def next_sequence_value(sequence_name)
|
|
98
|
+
select_one("SELECT #{sequence_name}.nextval id FROM systables WHERE tabid=1")['id']
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# TODO: Add some smart quoting for newlines in string and text fields.
|
|
102
|
+
def quote_string(string)
|
|
103
|
+
string.gsub(/\'/, "''")
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def quote(value, column = nil)
|
|
107
|
+
if column && [:binary, :text].include?(column.type)
|
|
108
|
+
# LOBs are updated separately by an after_save trigger.
|
|
109
|
+
"NULL"
|
|
110
|
+
elsif column && column.type == :date
|
|
111
|
+
"'#{value.mon}/#{value.day}/#{value.year}'"
|
|
112
|
+
else
|
|
113
|
+
super
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def create_table(name, options = {})
|
|
118
|
+
super(name, options)
|
|
119
|
+
execute("CREATE SEQUENCE #{name}_seq")
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def rename_table(name, new_name)
|
|
123
|
+
execute("RENAME TABLE #{name} TO #{new_name}")
|
|
124
|
+
execute("RENAME SEQUENCE #{name}_seq TO #{new_name}_seq")
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def drop_table(name)
|
|
128
|
+
super(name)
|
|
129
|
+
execute("DROP SEQUENCE #{name}_seq")
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def remove_index(table_name, options = {})
|
|
133
|
+
@connection.execute_update("DROP INDEX #{index_name(table_name, options)}")
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
private
|
|
137
|
+
def select(sql, *rest)
|
|
138
|
+
# Informix does not like "= NULL", "!= NULL", or "<> NULL".
|
|
139
|
+
execute(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL"), *rest)
|
|
140
|
+
end
|
|
141
|
+
end # module Informix
|
|
142
|
+
end # module ::ArJdbc
|