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
data/lib/arjdbc/derby.rb
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
require 'arjdbc/jdbc/missing_functionality_helper'
|
|
2
|
+
|
|
3
|
+
module ::ArJdbc
|
|
4
|
+
module Derby
|
|
5
|
+
def self.column_selector
|
|
6
|
+
[/derby/i, lambda {|cfg,col| col.extend(::ArJdbc::Derby::Column)}]
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.monkey_rails
|
|
10
|
+
unless defined?(@already_monkeyd)
|
|
11
|
+
# Needed because Rails is broken wrt to quoting of
|
|
12
|
+
# some values. Most databases are nice about it,
|
|
13
|
+
# but not Derby. The real issue is that you can't
|
|
14
|
+
# compare a CHAR value to a NUMBER column.
|
|
15
|
+
::ActiveRecord::Associations::ClassMethods.module_eval do
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def select_limited_ids_list(options, join_dependency)
|
|
19
|
+
connection.select_all(
|
|
20
|
+
construct_finder_sql_for_association_limiting(options, join_dependency),
|
|
21
|
+
"#{name} Load IDs For Limited Eager Loading"
|
|
22
|
+
).collect { |row| connection.quote(row[primary_key], columns_hash[primary_key]) }.join(", ")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
@already_monkeyd = true
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.extended(adapter)
|
|
31
|
+
monkey_rails
|
|
32
|
+
adapter.configure_connection
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.included(*args)
|
|
36
|
+
monkey_rails
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def configure_connection
|
|
40
|
+
execute("SET ISOLATION = SERIALIZABLE") # This must be done or SELECT...FOR UPDATE won't work how we expect
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
module Column
|
|
44
|
+
def simplified_type(field_type)
|
|
45
|
+
case field_type
|
|
46
|
+
when /smallint/i then :boolean
|
|
47
|
+
when /real/i then :float
|
|
48
|
+
when /^timestamp/i then :datetime
|
|
49
|
+
else
|
|
50
|
+
super
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Post process default value from JDBC into a Rails-friendly format (columns{-internal})
|
|
55
|
+
def default_value(value)
|
|
56
|
+
# jdbc returns column default strings with actual single quotes around the value.
|
|
57
|
+
return $1 if value =~ /^'(.*)'$/
|
|
58
|
+
return nil if value == "GENERATED_BY_DEFAULT"
|
|
59
|
+
value
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def adapter_name #:nodoc:
|
|
64
|
+
'Derby'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.arel2_visitors(config)
|
|
68
|
+
require 'arel/visitors/derby'
|
|
69
|
+
{}.tap {|v| %w(derby jdbcderby).each {|a| v[a] = ::Arel::Visitors::Derby } }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
include ArJdbc::MissingFunctionalityHelper
|
|
73
|
+
|
|
74
|
+
def index_name_length
|
|
75
|
+
128
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Convert the specified column type to a SQL string.
|
|
79
|
+
# In Derby, the following cannot specify a limit:
|
|
80
|
+
# - integer
|
|
81
|
+
# - boolean (smallint)
|
|
82
|
+
# - datetime (timestamp)
|
|
83
|
+
# - date
|
|
84
|
+
def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
|
|
85
|
+
return super unless [:integer, :boolean, :timestamp, :datetime, :date].include? type
|
|
86
|
+
|
|
87
|
+
native = native_database_types[type.to_s.downcase.to_sym]
|
|
88
|
+
native.is_a?(Hash) ? native[:name] : native
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def modify_types(tp)
|
|
92
|
+
tp[:primary_key] = "int generated by default as identity NOT NULL PRIMARY KEY"
|
|
93
|
+
tp[:string][:limit] = 256
|
|
94
|
+
tp[:integer][:limit] = nil
|
|
95
|
+
tp[:boolean] = {:name => "smallint"}
|
|
96
|
+
tp[:datetime] = {:name => "timestamp", :limit => nil}
|
|
97
|
+
tp[:timestamp][:limit] = nil
|
|
98
|
+
tp[:date][:limit] = nil
|
|
99
|
+
tp
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Override default -- fix case where ActiveRecord passes :default => nil, :null => true
|
|
103
|
+
def add_column_options!(sql, options)
|
|
104
|
+
options.delete(:default) if options.has_key?(:default) && options[:default].nil?
|
|
105
|
+
sql << " DEFAULT #{quote(options.delete(:default))}" if options.has_key?(:default)
|
|
106
|
+
super
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def classes_for_table_name(table)
|
|
110
|
+
ActiveRecord::Base.send(:subclasses).select {|klass| klass.table_name == table}
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Set the sequence to the max value of the table's column.
|
|
114
|
+
def reset_sequence!(table, column, sequence = nil)
|
|
115
|
+
mpk = select_value("SELECT MAX(#{quote_column_name(column)}) FROM #{quote_table_name(table)}")
|
|
116
|
+
execute("ALTER TABLE #{quote_table_name(table)} ALTER COLUMN #{quote_column_name(column)} RESTART WITH #{mpk.to_i + 1}")
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def reset_pk_sequence!(table, pk = nil, sequence = nil)
|
|
120
|
+
klasses = classes_for_table_name(table)
|
|
121
|
+
klass = klasses.nil? ? nil : klasses.first
|
|
122
|
+
pk = klass.primary_key unless klass.nil?
|
|
123
|
+
if pk && klass.columns_hash[pk].type == :integer
|
|
124
|
+
reset_sequence!(klass.table_name, pk)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def remove_index(table_name, options) #:nodoc:
|
|
129
|
+
execute "DROP INDEX #{index_name(table_name, options)}"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def rename_table(name, new_name)
|
|
133
|
+
execute "RENAME TABLE #{quote_table_name(name)} TO #{quote_table_name(new_name)}"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
AUTO_INC_STMT2 = "SELECT AUTOINCREMENTSTART, AUTOINCREMENTINC, COLUMNNAME, REFERENCEID, COLUMNDEFAULT FROM SYS.SYSCOLUMNS WHERE REFERENCEID = (SELECT T.TABLEID FROM SYS.SYSTABLES T WHERE T.TABLENAME = '%s') AND COLUMNNAME = '%s'"
|
|
137
|
+
|
|
138
|
+
def add_quotes(name)
|
|
139
|
+
return name unless name
|
|
140
|
+
%Q{"#{name}"}
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def strip_quotes(str)
|
|
144
|
+
return str unless str
|
|
145
|
+
return str unless /^(["']).*\1$/ =~ str
|
|
146
|
+
str[1..-2]
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def expand_double_quotes(name)
|
|
150
|
+
return name unless name && name['"']
|
|
151
|
+
name.gsub(/"/,'""')
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def auto_increment_stmt(tname, cname)
|
|
155
|
+
stmt = AUTO_INC_STMT2 % [tname, strip_quotes(cname)]
|
|
156
|
+
data = execute(stmt).first
|
|
157
|
+
if data
|
|
158
|
+
start = data['autoincrementstart']
|
|
159
|
+
if start
|
|
160
|
+
coldef = ""
|
|
161
|
+
coldef << " GENERATED " << (data['columndefault'].nil? ? "ALWAYS" : "BY DEFAULT ")
|
|
162
|
+
coldef << "AS IDENTITY (START WITH "
|
|
163
|
+
coldef << start
|
|
164
|
+
coldef << ", INCREMENT BY "
|
|
165
|
+
coldef << data['autoincrementinc']
|
|
166
|
+
coldef << ")"
|
|
167
|
+
return coldef
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
""
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def add_column(table_name, column_name, type, options = {})
|
|
175
|
+
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])}"
|
|
176
|
+
add_column_options!(add_column_sql, options)
|
|
177
|
+
execute(add_column_sql)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def execute(sql, name = nil, binds = [])
|
|
181
|
+
sql = extract_sql(sql)
|
|
182
|
+
if sql =~ /\A\s*(UPDATE|INSERT)/i
|
|
183
|
+
i = sql =~ /\swhere\s/im
|
|
184
|
+
if i
|
|
185
|
+
sql[i..-1] = sql[i..-1].gsub(/!=\s*NULL/, 'IS NOT NULL').gsub(/=\sNULL/i, 'IS NULL')
|
|
186
|
+
end
|
|
187
|
+
else
|
|
188
|
+
sql.gsub!(/= NULL/i, 'IS NULL')
|
|
189
|
+
end
|
|
190
|
+
super
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
|
|
194
|
+
#
|
|
195
|
+
# Derby requires the ORDER BY columns in the select list for distinct queries, and
|
|
196
|
+
# requires that the ORDER BY include the distinct column.
|
|
197
|
+
#
|
|
198
|
+
# distinct("posts.id", "posts.created_at desc")
|
|
199
|
+
#
|
|
200
|
+
# Based on distinct method for PostgreSQL Adapter
|
|
201
|
+
def distinct(columns, order_by)
|
|
202
|
+
return "DISTINCT #{columns}" if order_by.blank?
|
|
203
|
+
|
|
204
|
+
# construct a clean list of column names from the ORDER BY clause, removing
|
|
205
|
+
# any asc/desc modifiers
|
|
206
|
+
order_columns = [order_by].flatten.map{|o| o.split(',').collect { |s| s.split.first } }.flatten.reject(&:blank?)
|
|
207
|
+
order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }
|
|
208
|
+
|
|
209
|
+
# return a DISTINCT clause that's distinct on the columns we want but includes
|
|
210
|
+
# all the required columns for the ORDER BY to work properly
|
|
211
|
+
sql = "DISTINCT #{columns}, #{order_columns * ', '}"
|
|
212
|
+
sql
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
SIZEABLE = %w(VARCHAR CLOB BLOB)
|
|
216
|
+
|
|
217
|
+
def structure_dump #:nodoc:
|
|
218
|
+
definition=""
|
|
219
|
+
rs = @connection.connection.meta_data.getTables(nil,nil,nil,["TABLE"].to_java(:string))
|
|
220
|
+
while rs.next
|
|
221
|
+
tname = rs.getString(3)
|
|
222
|
+
definition << "CREATE TABLE #{tname} (\n"
|
|
223
|
+
rs2 = @connection.connection.meta_data.getColumns(nil,nil,tname,nil)
|
|
224
|
+
first_col = true
|
|
225
|
+
while rs2.next
|
|
226
|
+
col_name = add_quotes(rs2.getString(4));
|
|
227
|
+
default = ""
|
|
228
|
+
d1 = rs2.getString(13)
|
|
229
|
+
if d1 =~ /^GENERATED_/
|
|
230
|
+
default = auto_increment_stmt(tname, col_name)
|
|
231
|
+
elsif d1
|
|
232
|
+
default = " DEFAULT #{d1}"
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
type = rs2.getString(6)
|
|
236
|
+
col_size = rs2.getString(7)
|
|
237
|
+
nulling = (rs2.getString(18) == 'NO' ? " NOT NULL" : "")
|
|
238
|
+
create_col_string = add_quotes(expand_double_quotes(strip_quotes(col_name))) +
|
|
239
|
+
" " +
|
|
240
|
+
type +
|
|
241
|
+
(SIZEABLE.include?(type) ? "(#{col_size})" : "") +
|
|
242
|
+
nulling +
|
|
243
|
+
default
|
|
244
|
+
if !first_col
|
|
245
|
+
create_col_string = ",\n #{create_col_string}"
|
|
246
|
+
else
|
|
247
|
+
create_col_string = " #{create_col_string}"
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
definition << create_col_string
|
|
251
|
+
|
|
252
|
+
first_col = false
|
|
253
|
+
end
|
|
254
|
+
definition << ");\n\n"
|
|
255
|
+
end
|
|
256
|
+
definition
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def remove_column(table_name, column_name)
|
|
260
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)} RESTRICT"
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
# Notes about changing in Derby:
|
|
264
|
+
# http://db.apache.org/derby/docs/10.2/ref/rrefsqlj81859.html#rrefsqlj81859__rrefsqlj37860)
|
|
265
|
+
#
|
|
266
|
+
# We support changing columns using the strategy outlined in:
|
|
267
|
+
# https://issues.apache.org/jira/browse/DERBY-1515
|
|
268
|
+
#
|
|
269
|
+
# This feature has not made it into a formal release and is not in Java 6. We will
|
|
270
|
+
# need to conditionally support this somehow (supposed to arrive for 10.3.0.0)
|
|
271
|
+
def change_column(table_name, column_name, type, options = {})
|
|
272
|
+
# null/not nulling is easy, handle that separately
|
|
273
|
+
if options.include?(:null)
|
|
274
|
+
# This seems to only work with 10.2 of Derby
|
|
275
|
+
if options.delete(:null) == false
|
|
276
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} NOT NULL"
|
|
277
|
+
else
|
|
278
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} NULL"
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# anything left to do?
|
|
283
|
+
unless options.empty?
|
|
284
|
+
begin
|
|
285
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DATA TYPE #{type_to_sql(type, options[:limit])}"
|
|
286
|
+
rescue
|
|
287
|
+
transaction do
|
|
288
|
+
temp_new_column_name = "#{column_name}_newtype"
|
|
289
|
+
# 1) ALTER TABLE t ADD COLUMN c1_newtype NEWTYPE;
|
|
290
|
+
add_column table_name, temp_new_column_name, type, options
|
|
291
|
+
# 2) UPDATE t SET c1_newtype = c1;
|
|
292
|
+
execute "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(temp_new_column_name)} = CAST(#{quote_column_name(column_name)} AS #{type_to_sql(type, options[:limit])})"
|
|
293
|
+
# 3) ALTER TABLE t DROP COLUMN c1;
|
|
294
|
+
remove_column table_name, column_name
|
|
295
|
+
# 4) ALTER TABLE t RENAME COLUMN c1_newtype to c1;
|
|
296
|
+
rename_column table_name, temp_new_column_name, column_name
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def rename_column(table_name, column_name, new_column_name) #:nodoc:
|
|
303
|
+
execute "RENAME COLUMN #{quote_table_name(table_name)}.#{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}"
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def primary_keys(table_name)
|
|
307
|
+
@connection.primary_keys table_name.to_s.upcase
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def columns(table_name, name=nil)
|
|
311
|
+
@connection.columns_internal(table_name.to_s, name, derby_schema)
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def tables
|
|
315
|
+
@connection.tables(nil, derby_schema)
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def recreate_database(db_name)
|
|
319
|
+
tables.each do |t|
|
|
320
|
+
drop_table t
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def quote_column_name(name) #:nodoc:
|
|
325
|
+
%Q{"#{name.to_s.upcase.gsub(/\"/, '""')}"}
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
def quoted_true
|
|
329
|
+
'1'
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def quoted_false
|
|
333
|
+
'0'
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def add_limit_offset!(sql, options) #:nodoc:
|
|
337
|
+
if options[:offset]
|
|
338
|
+
sql << " OFFSET #{options[:offset]} ROWS"
|
|
339
|
+
end
|
|
340
|
+
if options[:limit]
|
|
341
|
+
#ROWS/ROW and FIRST/NEXT mean the same
|
|
342
|
+
sql << " FETCH FIRST #{options[:limit]} ROWS ONLY"
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
private
|
|
347
|
+
# Derby appears to define schemas using the username
|
|
348
|
+
def derby_schema
|
|
349
|
+
if @config.has_key?(:schema)
|
|
350
|
+
config[:schema]
|
|
351
|
+
else
|
|
352
|
+
(@config[:username] && @config[:username].to_s) || ''
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
class Base
|
|
3
|
+
class << self
|
|
4
|
+
def derby_connection(config)
|
|
5
|
+
config[:url] ||= "jdbc:derby:#{config[:database]};create=true"
|
|
6
|
+
config[:driver] ||= "org.apache.derby.jdbc.EmbeddedDriver"
|
|
7
|
+
config[:adapter_spec] = ::ArJdbc::Derby
|
|
8
|
+
conn = embedded_driver(config)
|
|
9
|
+
md = conn.jdbc_connection.meta_data
|
|
10
|
+
if md.database_major_version < 10 || (md.database_major_version == 10 && md.database_minor_version < 5)
|
|
11
|
+
raise ::ActiveRecord::ConnectionFailed, "Derby adapter requires Derby 10.5 or later"
|
|
12
|
+
end
|
|
13
|
+
conn
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
alias_method :jdbcderby_connection, :derby_connection
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# arjdbc/discover.rb: Declare ArJdbc.extension modules in this file
|
|
2
|
+
# that loads a custom module and adapter.
|
|
3
|
+
|
|
4
|
+
module ::ArJdbc
|
|
5
|
+
# Adapters built-in to AR are required up-front so we can override
|
|
6
|
+
# the native ones
|
|
7
|
+
require 'arjdbc/mysql'
|
|
8
|
+
extension :MySQL do |name|
|
|
9
|
+
name =~ /mysql/i
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
require 'arjdbc/postgresql'
|
|
13
|
+
extension :PostgreSQL do |name|
|
|
14
|
+
name =~ /postgre/i
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
require 'arjdbc/sqlite3'
|
|
18
|
+
extension :SQLite3 do |name|
|
|
19
|
+
name =~ /sqlite/i
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Other adapters are lazy-loaded
|
|
23
|
+
extension :DB2 do |name, config|
|
|
24
|
+
if name =~ /(db2|as400)/i && config[:url] !~ /^jdbc:derby:net:/
|
|
25
|
+
require 'arjdbc/db2'
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
extension :Derby do |name|
|
|
31
|
+
if name =~ /derby/i
|
|
32
|
+
require 'arjdbc/derby'
|
|
33
|
+
true
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
extension :FireBird do |name|
|
|
38
|
+
if name =~ /firebird/i
|
|
39
|
+
require 'arjdbc/firebird'
|
|
40
|
+
true
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
extension :H2 do |name|
|
|
45
|
+
if name =~ /\.h2\./i
|
|
46
|
+
require 'arjdbc/h2'
|
|
47
|
+
true
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
extension :HSQLDB do |name|
|
|
52
|
+
if name =~ /hsqldb/i
|
|
53
|
+
require 'arjdbc/hsqldb'
|
|
54
|
+
true
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
extension :Informix do |name|
|
|
59
|
+
if name =~ /informix/i
|
|
60
|
+
require 'arjdbc/informix'
|
|
61
|
+
true
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
extension :Mimer do |name|
|
|
66
|
+
if name =~ /mimer/i
|
|
67
|
+
require 'arjdbc/mimer'
|
|
68
|
+
true
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
extension :MsSQL do |name|
|
|
73
|
+
if name =~ /sqlserver|tds|Microsoft SQL/i
|
|
74
|
+
require 'arjdbc/mssql'
|
|
75
|
+
true
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
extension :Oracle do |name|
|
|
80
|
+
if name =~ /oracle/i
|
|
81
|
+
require 'arjdbc/oracle'
|
|
82
|
+
true
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
extension :Sybase do |name|
|
|
87
|
+
if name =~ /sybase|tds/i
|
|
88
|
+
require 'arjdbc/sybase'
|
|
89
|
+
true
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|