activerecord-jdbc-adapter-ficoh 1.3.21-java
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.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/.travis.yml +462 -0
- data/.yardopts +4 -0
- data/Appraisals +36 -0
- data/CONTRIBUTING.md +49 -0
- data/Gemfile +68 -0
- data/History.md +1191 -0
- data/LICENSE.txt +25 -0
- data/README.md +277 -0
- data/RUNNING_TESTS.md +88 -0
- data/Rakefile +298 -0
- data/Rakefile.jdbc +20 -0
- data/activerecord-jdbc-adapter.gemspec +63 -0
- data/lib/active_record/connection_adapters/as400_adapter.rb +2 -0
- data/lib/active_record/connection_adapters/db2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/firebird_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/mariadb_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/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
- data/lib/activerecord-jdbc-adapter.rb +1 -0
- data/lib/arel/visitors/compat.rb +64 -0
- data/lib/arel/visitors/db2.rb +137 -0
- data/lib/arel/visitors/derby.rb +112 -0
- data/lib/arel/visitors/firebird.rb +79 -0
- data/lib/arel/visitors/h2.rb +25 -0
- data/lib/arel/visitors/hsqldb.rb +32 -0
- data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
- data/lib/arel/visitors/sql_server.rb +225 -0
- data/lib/arel/visitors/sql_server/ng42.rb +293 -0
- data/lib/arjdbc.rb +22 -0
- data/lib/arjdbc/db2.rb +4 -0
- data/lib/arjdbc/db2/adapter.rb +802 -0
- data/lib/arjdbc/db2/as400.rb +137 -0
- data/lib/arjdbc/db2/column.rb +177 -0
- data/lib/arjdbc/db2/connection_methods.rb +45 -0
- data/lib/arjdbc/derby.rb +3 -0
- data/lib/arjdbc/derby/active_record_patch.rb +13 -0
- data/lib/arjdbc/derby/adapter.rb +567 -0
- data/lib/arjdbc/derby/connection_methods.rb +16 -0
- data/lib/arjdbc/derby/schema_creation.rb +15 -0
- data/lib/arjdbc/discover.rb +104 -0
- data/lib/arjdbc/firebird.rb +4 -0
- data/lib/arjdbc/firebird/adapter.rb +468 -0
- data/lib/arjdbc/firebird/connection_methods.rb +20 -0
- data/lib/arjdbc/h2.rb +3 -0
- data/lib/arjdbc/h2/adapter.rb +335 -0
- data/lib/arjdbc/h2/connection_methods.rb +22 -0
- data/lib/arjdbc/hsqldb.rb +3 -0
- data/lib/arjdbc/hsqldb/adapter.rb +304 -0
- data/lib/arjdbc/hsqldb/connection_methods.rb +23 -0
- data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
- data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
- data/lib/arjdbc/informix.rb +5 -0
- data/lib/arjdbc/informix/adapter.rb +160 -0
- data/lib/arjdbc/informix/connection_methods.rb +9 -0
- data/lib/arjdbc/jdbc.rb +62 -0
- data/lib/arjdbc/jdbc/adapter.rb +997 -0
- data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
- data/lib/arjdbc/jdbc/arel_support.rb +149 -0
- data/lib/arjdbc/jdbc/base_ext.rb +34 -0
- data/lib/arjdbc/jdbc/callbacks.rb +52 -0
- data/lib/arjdbc/jdbc/column.rb +83 -0
- data/lib/arjdbc/jdbc/connection.rb +26 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +59 -0
- data/lib/arjdbc/jdbc/driver.rb +44 -0
- data/lib/arjdbc/jdbc/error.rb +75 -0
- data/lib/arjdbc/jdbc/extension.rb +69 -0
- data/lib/arjdbc/jdbc/java.rb +13 -0
- data/lib/arjdbc/jdbc/type_cast.rb +154 -0
- data/lib/arjdbc/jdbc/type_converter.rb +142 -0
- data/lib/arjdbc/mssql.rb +7 -0
- data/lib/arjdbc/mssql/adapter.rb +822 -0
- data/lib/arjdbc/mssql/column.rb +207 -0
- data/lib/arjdbc/mssql/connection_methods.rb +72 -0
- data/lib/arjdbc/mssql/explain_support.rb +99 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
- data/lib/arjdbc/mssql/lock_methods.rb +77 -0
- data/lib/arjdbc/mssql/types.rb +343 -0
- data/lib/arjdbc/mssql/utils.rb +82 -0
- data/lib/arjdbc/mysql.rb +3 -0
- data/lib/arjdbc/mysql/adapter.rb +998 -0
- data/lib/arjdbc/mysql/bulk_change_table.rb +150 -0
- data/lib/arjdbc/mysql/column.rb +167 -0
- data/lib/arjdbc/mysql/connection_methods.rb +137 -0
- data/lib/arjdbc/mysql/explain_support.rb +82 -0
- data/lib/arjdbc/mysql/schema_creation.rb +58 -0
- data/lib/arjdbc/oracle.rb +4 -0
- data/lib/arjdbc/oracle/adapter.rb +968 -0
- data/lib/arjdbc/oracle/column.rb +136 -0
- data/lib/arjdbc/oracle/connection_methods.rb +21 -0
- data/lib/arjdbc/postgresql.rb +3 -0
- data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +21 -0
- data/lib/arjdbc/postgresql/adapter.rb +1498 -0
- data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
- data/lib/arjdbc/postgresql/base/oid.rb +412 -0
- data/lib/arjdbc/postgresql/base/pgconn.rb +8 -0
- data/lib/arjdbc/postgresql/base/schema_definitions.rb +132 -0
- data/lib/arjdbc/postgresql/column.rb +640 -0
- data/lib/arjdbc/postgresql/connection_methods.rb +44 -0
- data/lib/arjdbc/postgresql/explain_support.rb +53 -0
- data/lib/arjdbc/postgresql/oid/bytea.rb +3 -0
- data/lib/arjdbc/postgresql/oid_types.rb +265 -0
- data/lib/arjdbc/postgresql/schema_creation.rb +60 -0
- data/lib/arjdbc/railtie.rb +11 -0
- data/lib/arjdbc/sqlite3.rb +3 -0
- data/lib/arjdbc/sqlite3/adapter.rb +654 -0
- data/lib/arjdbc/sqlite3/connection_methods.rb +36 -0
- data/lib/arjdbc/sqlite3/explain_support.rb +29 -0
- data/lib/arjdbc/sybase.rb +2 -0
- data/lib/arjdbc/sybase/adapter.rb +47 -0
- data/lib/arjdbc/tasks.rb +13 -0
- data/lib/arjdbc/tasks/database_tasks.rb +66 -0
- data/lib/arjdbc/tasks/databases.rake +91 -0
- data/lib/arjdbc/tasks/databases3.rake +239 -0
- data/lib/arjdbc/tasks/databases4.rake +39 -0
- data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
- data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
- data/lib/arjdbc/tasks/h2_database_tasks.rb +31 -0
- data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
- data/lib/arjdbc/tasks/jdbc_database_tasks.rb +169 -0
- data/lib/arjdbc/tasks/mssql_database_tasks.rb +46 -0
- data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +297 -0
- data/lib/arjdbc/tasks/oracle_database_tasks.rb +65 -0
- data/lib/arjdbc/util/quoted_cache.rb +60 -0
- data/lib/arjdbc/util/serialized_attributes.rb +98 -0
- data/lib/arjdbc/util/table_copier.rb +108 -0
- data/lib/arjdbc/version.rb +8 -0
- data/lib/generators/jdbc/USAGE +9 -0
- data/lib/generators/jdbc/jdbc_generator.rb +17 -0
- data/pom.xml +285 -0
- data/rails_generators/jdbc_generator.rb +15 -0
- data/rails_generators/templates/config/initializers/jdbc.rb +10 -0
- data/rails_generators/templates/lib/tasks/jdbc.rake +11 -0
- data/rakelib/01-tomcat.rake +51 -0
- data/rakelib/02-test.rake +151 -0
- data/rakelib/bundler_ext.rb +11 -0
- data/rakelib/db.rake +58 -0
- data/rakelib/rails.rake +77 -0
- data/src/java/arjdbc/ArJdbcModule.java +288 -0
- data/src/java/arjdbc/db2/DB2Module.java +77 -0
- data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +128 -0
- data/src/java/arjdbc/derby/DerbyModule.java +180 -0
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +153 -0
- data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +190 -0
- data/src/java/arjdbc/h2/H2Module.java +50 -0
- data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +86 -0
- data/src/java/arjdbc/hsqldb/HSQLDBModule.java +74 -0
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +76 -0
- data/src/java/arjdbc/jdbc/AdapterJavaService.java +43 -0
- data/src/java/arjdbc/jdbc/Callable.java +44 -0
- data/src/java/arjdbc/jdbc/ConnectionFactory.java +77 -0
- data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +156 -0
- data/src/java/arjdbc/jdbc/DriverConnectionFactory.java +63 -0
- data/src/java/arjdbc/jdbc/DriverWrapper.java +128 -0
- data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +32 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +4541 -0
- data/src/java/arjdbc/jdbc/SQLBlock.java +54 -0
- data/src/java/arjdbc/jdbc/WithResultSet.java +37 -0
- data/src/java/arjdbc/mssql/MSSQLModule.java +91 -0
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +193 -0
- data/src/java/arjdbc/mysql/MySQLModule.java +140 -0
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +456 -0
- data/src/java/arjdbc/oracle/OracleModule.java +81 -0
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +477 -0
- data/src/java/arjdbc/postgresql/ByteaUtils.java +171 -0
- data/src/java/arjdbc/postgresql/DriverImplementation.java +78 -0
- data/src/java/arjdbc/postgresql/PGDriverImplementation.java +535 -0
- data/src/java/arjdbc/postgresql/PostgreSQLModule.java +189 -0
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +489 -0
- data/src/java/arjdbc/sqlite3/SQLite3Module.java +93 -0
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +405 -0
- data/src/java/arjdbc/util/CallResultSet.java +826 -0
- data/src/java/arjdbc/util/DateTimeUtils.java +517 -0
- data/src/java/arjdbc/util/NumberUtils.java +50 -0
- data/src/java/arjdbc/util/ObjectSupport.java +65 -0
- data/src/java/arjdbc/util/QuotingUtils.java +139 -0
- data/src/java/arjdbc/util/StringCache.java +60 -0
- data/src/java/arjdbc/util/StringHelper.java +155 -0
- metadata +288 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'arjdbc/tasks/jdbc_database_tasks'
|
2
|
+
|
3
|
+
module ArJdbc
|
4
|
+
module Tasks
|
5
|
+
class MSSQLDatabaseTasks < JdbcDatabaseTasks
|
6
|
+
|
7
|
+
def purge
|
8
|
+
test = deep_dup(configuration)
|
9
|
+
test_database = resolve_database(test)
|
10
|
+
test['database'] = 'master'
|
11
|
+
establish_connection(test)
|
12
|
+
connection.recreate_database!(test_database)
|
13
|
+
end
|
14
|
+
|
15
|
+
def structure_dump(filename)
|
16
|
+
config = config_from_url_if_needed
|
17
|
+
`smoscript -s #{config['host']} -d #{config['database']} -u #{config['username']} -p #{config['password']} -f #{filename} -A -U`
|
18
|
+
end
|
19
|
+
|
20
|
+
def structure_load(filename)
|
21
|
+
config = config_from_url_if_needed
|
22
|
+
`sqlcmd -S #{config['host']} -d #{config['database']} -U #{config['username']} -P #{config['password']} -i #{filename}`
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def config_from_url_if_needed
|
28
|
+
config = self.config
|
29
|
+
if config['url'] && ! config.key?('database')
|
30
|
+
config = config_from_url(config['url'])
|
31
|
+
end
|
32
|
+
config
|
33
|
+
end
|
34
|
+
|
35
|
+
def deep_dup(hash)
|
36
|
+
dup = hash.dup
|
37
|
+
dup.each_pair do |k,v|
|
38
|
+
tv = dup[k]
|
39
|
+
dup[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? deep_dup(tv) : v
|
40
|
+
end
|
41
|
+
dup
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,297 @@
|
|
1
|
+
# NOTE: kindly copy-pasted from Raimonds Simanovskis's oracle-enhanced adapter :
|
2
|
+
# https://github.com/rsim/oracle-enhanced/blob/master/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb
|
3
|
+
|
4
|
+
module ActiveRecord #:nodoc:
|
5
|
+
module ConnectionAdapters #:nodoc:
|
6
|
+
module OracleEnhancedStructureDump #:nodoc:
|
7
|
+
|
8
|
+
# Statements separator used in structure dump to allow loading of structure dump also with SQL*Plus
|
9
|
+
STATEMENT_TOKEN = "\n\n/\n\n"
|
10
|
+
|
11
|
+
def structure_dump #:nodoc:
|
12
|
+
structure = select_values("SELECT sequence_name FROM user_sequences ORDER BY 1").map do |seq|
|
13
|
+
"CREATE SEQUENCE \"#{seq}\""
|
14
|
+
end
|
15
|
+
select_values("SELECT table_name FROM all_tables t
|
16
|
+
WHERE owner = SYS_CONTEXT('userenv', 'session_user') AND secondary = 'N'
|
17
|
+
AND NOT EXISTS (SELECT mv.mview_name FROM all_mviews mv WHERE mv.owner = t.owner AND mv.mview_name = t.table_name)
|
18
|
+
AND NOT EXISTS (SELECT mvl.log_table FROM all_mview_logs mvl WHERE mvl.log_owner = t.owner AND mvl.log_table = t.table_name)
|
19
|
+
ORDER BY 1").each do |table_name|
|
20
|
+
virtual_columns = virtual_columns_for(table_name)
|
21
|
+
ddl = "CREATE#{ ' GLOBAL TEMPORARY' if temporary_table?(table_name)} TABLE \"#{table_name}\" (\n"
|
22
|
+
cols = select_all(%Q{
|
23
|
+
SELECT column_name, data_type, data_length, char_used, char_length, data_precision, data_scale, data_default, nullable
|
24
|
+
FROM user_tab_columns
|
25
|
+
WHERE table_name = '#{table_name}'
|
26
|
+
ORDER BY column_id
|
27
|
+
}).map do |row|
|
28
|
+
if(v = virtual_columns.find {|col| col['column_name'] == row['column_name']})
|
29
|
+
structure_dump_virtual_column(row, v['data_default'])
|
30
|
+
else
|
31
|
+
structure_dump_column(row)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
ddl << cols.join(",\n ")
|
35
|
+
ddl << structure_dump_primary_key(table_name)
|
36
|
+
ddl << "\n)"
|
37
|
+
structure << ddl
|
38
|
+
structure << structure_dump_indexes(table_name)
|
39
|
+
structure << structure_dump_unique_keys(table_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
join_with_statement_token(structure) << structure_dump_fk_constraints
|
43
|
+
end
|
44
|
+
|
45
|
+
def structure_dump_column(column) #:nodoc:
|
46
|
+
col = "\"#{column['column_name']}\" #{column['data_type']}"
|
47
|
+
if column['data_type'] =='NUMBER' && ! column['data_precision'].blank?
|
48
|
+
col << "(#{column['data_precision'].to_i}"
|
49
|
+
col << ",#{column['data_scale'].to_i}" unless column['data_scale'].blank?
|
50
|
+
col << ')'
|
51
|
+
elsif column['data_type'].include?('CHAR')
|
52
|
+
length = column['char_used'] == 'C' ? column['char_length'].to_i : column['data_length'].to_i
|
53
|
+
col << "(#{length})"
|
54
|
+
end
|
55
|
+
col << " DEFAULT #{column['data_default']}" unless column['data_default'].blank?
|
56
|
+
col << ' NOT NULL' if column['nullable'] == 'N'
|
57
|
+
col
|
58
|
+
end
|
59
|
+
|
60
|
+
def structure_dump_virtual_column(column, data_default) #:nodoc:
|
61
|
+
data_default = data_default.gsub(/"/, '')
|
62
|
+
col = "\"#{column['column_name']}\" #{column['data_type']}"
|
63
|
+
if column['data_type'] =='NUMBER' && ! column['data_precision'].blank?
|
64
|
+
col << "(#{column['data_precision'].to_i}"
|
65
|
+
col << ",#{column['data_scale'].to_i}" unless column['data_scale'].blank?
|
66
|
+
col << ')'
|
67
|
+
elsif column['data_type'].include?('CHAR')
|
68
|
+
length = column['char_used'] == 'C' ? column['char_length'].to_i : column['data_length'].to_i
|
69
|
+
col << "(#{length})"
|
70
|
+
end
|
71
|
+
col << " GENERATED ALWAYS AS (#{data_default}) VIRTUAL"
|
72
|
+
end
|
73
|
+
|
74
|
+
def structure_dump_primary_key(table) #:nodoc:
|
75
|
+
opts = {:name => '', :cols => []}
|
76
|
+
pks = select_all(<<-SQL, "Primary Keys")
|
77
|
+
SELECT a.constraint_name, a.column_name, a.position
|
78
|
+
FROM user_cons_columns a
|
79
|
+
JOIN user_constraints c
|
80
|
+
ON a.constraint_name = c.constraint_name
|
81
|
+
WHERE c.table_name = '#{table.upcase}'
|
82
|
+
AND c.constraint_type = 'P'
|
83
|
+
AND c.owner = SYS_CONTEXT('userenv', 'session_user')
|
84
|
+
SQL
|
85
|
+
pks.each do |row|
|
86
|
+
opts[:name] = row['constraint_name']
|
87
|
+
opts[:cols][row['position']-1] = row['column_name']
|
88
|
+
end
|
89
|
+
opts[:cols].length > 0 ? ",\n CONSTRAINT #{opts[:name]} PRIMARY KEY (#{opts[:cols].join(',')})" : ''
|
90
|
+
end
|
91
|
+
|
92
|
+
def structure_dump_unique_keys(table) #:nodoc:
|
93
|
+
keys = {}
|
94
|
+
uks = select_all(<<-SQL, "Primary Keys")
|
95
|
+
SELECT a.constraint_name, a.column_name, a.position
|
96
|
+
FROM user_cons_columns a
|
97
|
+
JOIN user_constraints c
|
98
|
+
ON a.constraint_name = c.constraint_name
|
99
|
+
WHERE c.table_name = '#{table.upcase}'
|
100
|
+
AND c.constraint_type = 'U'
|
101
|
+
AND c.owner = SYS_CONTEXT('userenv', 'session_user')
|
102
|
+
SQL
|
103
|
+
uks.each do |uk|
|
104
|
+
keys[uk['constraint_name']] ||= []
|
105
|
+
keys[uk['constraint_name']][uk['position']-1] = uk['column_name']
|
106
|
+
end
|
107
|
+
keys.map do |k,v|
|
108
|
+
"ALTER TABLE #{table.upcase} ADD CONSTRAINT #{k} UNIQUE (#{v.join(',')})"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def structure_dump_indexes(table_name) #:nodoc:
|
113
|
+
indexes(table_name).map do |options|
|
114
|
+
column_names = options[:columns]
|
115
|
+
options = {:name => options[:name], :unique => options[:unique]}
|
116
|
+
index_name = index_name(table_name, :column => column_names)
|
117
|
+
if Hash === options # legacy support, since this param was a string
|
118
|
+
index_type = options[:unique] ? "UNIQUE" : ""
|
119
|
+
index_name = options[:name] || index_name
|
120
|
+
else
|
121
|
+
index_type = options
|
122
|
+
end
|
123
|
+
quoted_column_names = column_names.map { |e| quote_column_name_or_expression(e) }.join(", ")
|
124
|
+
"CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def structure_dump_fk_constraints #:nodoc:
|
129
|
+
fks = select_all("SELECT table_name FROM all_tables WHERE owner = SYS_CONTEXT('userenv', 'session_user') ORDER BY 1").map do |table|
|
130
|
+
if respond_to?(:foreign_keys) && (foreign_keys = foreign_keys(table["table_name"])).any?
|
131
|
+
foreign_keys.map do |fk|
|
132
|
+
sql = "ALTER TABLE #{quote_table_name(fk.from_table)} ADD CONSTRAINT #{quote_column_name(fk.options[:name])} "
|
133
|
+
sql << "#{foreign_key_definition(fk.to_table, fk.options)}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end.flatten.compact
|
137
|
+
join_with_statement_token(fks)
|
138
|
+
end
|
139
|
+
|
140
|
+
def dump_schema_information #:nodoc:
|
141
|
+
sm_table = ActiveRecord::Migrator.schema_migrations_table_name
|
142
|
+
migrated = select_values("SELECT version FROM #{sm_table} ORDER BY version")
|
143
|
+
join_with_statement_token(migrated.map{|v| "INSERT INTO #{sm_table} (version) VALUES ('#{v}')" })
|
144
|
+
end
|
145
|
+
|
146
|
+
# Extract all stored procedures, packages, synonyms and views.
|
147
|
+
def structure_dump_db_stored_code #:nodoc:
|
148
|
+
structure = []
|
149
|
+
select_all("SELECT DISTINCT name, type
|
150
|
+
FROM all_source
|
151
|
+
WHERE type IN ('PROCEDURE', 'PACKAGE', 'PACKAGE BODY', 'FUNCTION', 'TRIGGER', 'TYPE')
|
152
|
+
AND name NOT LIKE 'BIN$%'
|
153
|
+
AND owner = SYS_CONTEXT('userenv', 'session_user') ORDER BY type").each do |source|
|
154
|
+
ddl = "CREATE OR REPLACE \n"
|
155
|
+
select_all(%Q{
|
156
|
+
SELECT text
|
157
|
+
FROM all_source
|
158
|
+
WHERE name = '#{source['name']}'
|
159
|
+
AND type = '#{source['type']}'
|
160
|
+
AND owner = SYS_CONTEXT('userenv', 'session_user')
|
161
|
+
ORDER BY line
|
162
|
+
}).each do |row|
|
163
|
+
ddl << row['text']
|
164
|
+
end
|
165
|
+
ddl << ";" unless ddl.strip[-1,1] == ';'
|
166
|
+
structure << ddl
|
167
|
+
end
|
168
|
+
|
169
|
+
# export views
|
170
|
+
select_all("SELECT view_name, text FROM user_views").each do |view|
|
171
|
+
structure << "CREATE OR REPLACE VIEW #{view['view_name']} AS\n #{view['text']}"
|
172
|
+
end
|
173
|
+
|
174
|
+
# export synonyms
|
175
|
+
select_all("SELECT owner, synonym_name, table_name, table_owner
|
176
|
+
FROM all_synonyms
|
177
|
+
WHERE owner = SYS_CONTEXT('userenv', 'session_user') ").each do |synonym|
|
178
|
+
structure << "CREATE OR REPLACE #{synonym['owner'] == 'PUBLIC' ? 'PUBLIC' : '' } SYNONYM #{synonym['synonym_name']}"
|
179
|
+
structure << " FOR #{synonym['table_owner']}.#{synonym['table_name']}"
|
180
|
+
end
|
181
|
+
|
182
|
+
join_with_statement_token(structure)
|
183
|
+
end
|
184
|
+
|
185
|
+
def structure_drop #:nodoc:
|
186
|
+
statements = select_values("SELECT sequence_name FROM user_sequences ORDER BY 1").map do |seq|
|
187
|
+
"DROP SEQUENCE \"#{seq}\""
|
188
|
+
end
|
189
|
+
select_values("SELECT table_name from all_tables t
|
190
|
+
WHERE owner = SYS_CONTEXT('userenv', 'session_user') AND secondary = 'N'
|
191
|
+
AND NOT EXISTS (SELECT mv.mview_name FROM all_mviews mv WHERE mv.owner = t.owner AND mv.mview_name = t.table_name)
|
192
|
+
AND NOT EXISTS (SELECT mvl.log_table FROM all_mview_logs mvl WHERE mvl.log_owner = t.owner AND mvl.log_table = t.table_name)
|
193
|
+
ORDER BY 1").each do |table|
|
194
|
+
statements << "DROP TABLE \"#{table}\" CASCADE CONSTRAINTS"
|
195
|
+
end
|
196
|
+
join_with_statement_token(statements)
|
197
|
+
end
|
198
|
+
|
199
|
+
def temp_table_drop #:nodoc:
|
200
|
+
join_with_statement_token(select_values(
|
201
|
+
"SELECT table_name FROM all_tables
|
202
|
+
WHERE owner = SYS_CONTEXT('userenv', 'session_user') AND secondary = 'N' AND temporary = 'Y' ORDER BY 1").map do |table|
|
203
|
+
"DROP TABLE \"#{table}\" CASCADE CONSTRAINTS"
|
204
|
+
end)
|
205
|
+
end
|
206
|
+
|
207
|
+
def full_drop(preserve_tables=false) #:nodoc:
|
208
|
+
s = preserve_tables ? [] : [structure_drop]
|
209
|
+
s << temp_table_drop if preserve_tables
|
210
|
+
s << drop_sql_for_feature("view")
|
211
|
+
s << drop_sql_for_feature("materialized view")
|
212
|
+
s << drop_sql_for_feature("synonym")
|
213
|
+
s << drop_sql_for_feature("type")
|
214
|
+
s << drop_sql_for_object("package")
|
215
|
+
s << drop_sql_for_object("function")
|
216
|
+
s << drop_sql_for_object("procedure")
|
217
|
+
s.join
|
218
|
+
end
|
219
|
+
|
220
|
+
def add_column_options!(sql, options) #:nodoc:
|
221
|
+
type = options[:type] || ((column = options[:column]) && column.type)
|
222
|
+
type = type && type.to_sym
|
223
|
+
# handle case of defaults for CLOB columns, which would otherwise get "quoted" incorrectly
|
224
|
+
if options_include_default?(options)
|
225
|
+
if type == :text
|
226
|
+
sql << " DEFAULT #{quote(options[:default])}"
|
227
|
+
else
|
228
|
+
# from abstract adapter
|
229
|
+
sql << " DEFAULT #{quote(options[:default], options[:column])}"
|
230
|
+
end
|
231
|
+
end
|
232
|
+
# must explicitly add NULL or NOT NULL to allow change_column to work on migrations
|
233
|
+
if options[:null] == false
|
234
|
+
sql << " NOT NULL"
|
235
|
+
elsif options[:null] == true
|
236
|
+
sql << " NULL" unless type == :primary_key
|
237
|
+
end
|
238
|
+
# add AS expression for virtual columns
|
239
|
+
if options[:as].present?
|
240
|
+
sql << " AS (#{options[:as]})"
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def execute_structure_dump(string)
|
245
|
+
string.split(STATEMENT_TOKEN).each do |ddl|
|
246
|
+
ddl.chop! if ddl[-1,1] == ';'
|
247
|
+
execute(ddl) unless ddl.blank?
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
private
|
252
|
+
|
253
|
+
# virtual columns are an 11g feature. This returns [] if feature is not
|
254
|
+
# present or none are found.
|
255
|
+
# return [{'column_name' => 'FOOS', 'data_default' => '...'}, ...]
|
256
|
+
def virtual_columns_for(table)
|
257
|
+
begin
|
258
|
+
select_all <<-SQL
|
259
|
+
SELECT column_name, data_default
|
260
|
+
FROM user_tab_cols
|
261
|
+
WHERE virtual_column = 'YES'
|
262
|
+
AND table_name = '#{table.upcase}'
|
263
|
+
SQL
|
264
|
+
# feature not supported previous to 11g
|
265
|
+
rescue ActiveRecord::StatementInvalid => e
|
266
|
+
[]
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def drop_sql_for_feature(type)
|
271
|
+
short_type = type == 'materialized view' ? 'mview' : type
|
272
|
+
join_with_statement_token(
|
273
|
+
select_values("SELECT #{short_type}_name FROM user_#{short_type.tableize}").map do |name|
|
274
|
+
"DROP #{type.upcase} \"#{name}\""
|
275
|
+
end)
|
276
|
+
end
|
277
|
+
|
278
|
+
def drop_sql_for_object(type)
|
279
|
+
join_with_statement_token(
|
280
|
+
select_values("SELECT object_name FROM user_objects WHERE object_type = '#{type.upcase}'").map do |name|
|
281
|
+
"DROP #{type.upcase} \"#{name}\""
|
282
|
+
end)
|
283
|
+
end
|
284
|
+
|
285
|
+
def join_with_statement_token(array)
|
286
|
+
string = array.join(STATEMENT_TOKEN)
|
287
|
+
string << STATEMENT_TOKEN unless string.blank?
|
288
|
+
string
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
|
296
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhancedStructureDump
|
297
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'arjdbc/tasks/jdbc_database_tasks'
|
2
|
+
|
3
|
+
module ArJdbc
|
4
|
+
module Tasks
|
5
|
+
class OracleDatabaseTasks < JdbcDatabaseTasks
|
6
|
+
|
7
|
+
def create
|
8
|
+
print "Please provide the SYSTEM password for your oracle installation\n>"
|
9
|
+
system_password = $stdin.gets.strip
|
10
|
+
establish_connection(config.merge('username' => 'SYSTEM', 'password' => system_password))
|
11
|
+
unless ( config = self.config ).key?('username')
|
12
|
+
config = config_from_url(config['url']) if config['url']
|
13
|
+
end
|
14
|
+
begin
|
15
|
+
connection.execute "CREATE USER #{config['username']} IDENTIFIED BY #{config['password']}"
|
16
|
+
rescue => e
|
17
|
+
if e.message =~ /ORA-01920/ # user name conflicts with another user or role name
|
18
|
+
connection.execute "ALTER USER #{config['username']} IDENTIFIED BY #{config['password']}"
|
19
|
+
else
|
20
|
+
raise e
|
21
|
+
end
|
22
|
+
end
|
23
|
+
connection.execute "GRANT unlimited tablespace TO #{config['username']}"
|
24
|
+
connection.execute "GRANT create session TO #{config['username']}"
|
25
|
+
connection.execute "GRANT create table TO #{config['username']}"
|
26
|
+
connection.execute "GRANT create sequence TO #{config['username']}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def drop
|
30
|
+
self.class.load_enhanced_structure_dump
|
31
|
+
establish_connection(config)
|
32
|
+
connection.execute_structure_dump(connection.full_drop)
|
33
|
+
end
|
34
|
+
|
35
|
+
def purge
|
36
|
+
self.class.load_enhanced_structure_dump
|
37
|
+
establish_connection(:test)
|
38
|
+
connection.execute_structure_dump(connection.full_drop)
|
39
|
+
connection.execute("PURGE RECYCLEBIN") rescue nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def structure_dump(filename)
|
43
|
+
self.class.load_enhanced_structure_dump
|
44
|
+
establish_connection(config)
|
45
|
+
File.open(filename, "w:utf-8") { |f| f << connection.structure_dump }
|
46
|
+
end
|
47
|
+
|
48
|
+
def structure_load(filename)
|
49
|
+
self.class.load_enhanced_structure_dump
|
50
|
+
establish_connection(config)
|
51
|
+
connection.execute_structure_dump(File.read(filename))
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.load_enhanced_structure_dump
|
55
|
+
unless defined? ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter
|
56
|
+
ActiveRecord::ConnectionAdapters.module_eval do
|
57
|
+
const_set :OracleEnhancedAdapter, ActiveRecord::ConnectionAdapters::OracleAdapter
|
58
|
+
end
|
59
|
+
end
|
60
|
+
require 'arjdbc/tasks/oracle/enhanced_structure_dump'
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module ArJdbc
|
2
|
+
module Util
|
3
|
+
# Caches table and column name (quoted) outcomes.
|
4
|
+
# Uses {ThreadSafe::Cache} as a concurrent lock free (on JRuby) cache backend.
|
5
|
+
# The thread_safe gem is a dependency since ActiveSupport 4.0, when using
|
6
|
+
# ActiveRecord <= 3.2 one should add `gem 'thread_safe'` into the *Gemfile*
|
7
|
+
# as it is not forced (currently) as an explicit gem dependency.
|
8
|
+
#
|
9
|
+
# Caching can also be disabled by setting the *arjdbc.quoted_cache.disabled*
|
10
|
+
# system property = 'true'.
|
11
|
+
module QuotedCache
|
12
|
+
|
13
|
+
# @private
|
14
|
+
DISABLED = Java::JavaLang::Boolean.getBoolean('arjdbc.quoted_cache.disabled')
|
15
|
+
|
16
|
+
def self.included(base)
|
17
|
+
# the thread_safe gem is an ActiveSupport dependency (since 4.0) :
|
18
|
+
begin; require 'thread_safe'; rescue LoadError; end unless DISABLED
|
19
|
+
if ! DISABLED && defined? ThreadSafe::Cache
|
20
|
+
base.const_set :QUOTED_TABLE_NAMES, ThreadSafe::Cache.new
|
21
|
+
base.const_set :QUOTED_COLUMN_NAMES, ThreadSafe::Cache.new
|
22
|
+
else
|
23
|
+
base.const_set :QUOTED_TABLE_NAMES, nil
|
24
|
+
base.const_set :QUOTED_COLUMN_NAMES, nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Caches quoted table names, the cache is stored in the class'
|
29
|
+
# `QUOTED_TABLE_NAMES` constant.
|
30
|
+
# @return [String]
|
31
|
+
def quote_table_name(name, *args)
|
32
|
+
if cache = self.class::QUOTED_TABLE_NAMES
|
33
|
+
unless quoted = cache[name]
|
34
|
+
quoted = super
|
35
|
+
cache.put_if_absent name, quoted.freeze
|
36
|
+
end
|
37
|
+
quoted
|
38
|
+
else
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Caches quoted table names, the cache is stored in the class'
|
44
|
+
# `QUOTED_COLUMN_NAMES` constant.
|
45
|
+
# @return [String]
|
46
|
+
def quote_column_name(name, *args)
|
47
|
+
if cache = self.class::QUOTED_COLUMN_NAMES
|
48
|
+
unless quoted = cache[name]
|
49
|
+
quoted = super
|
50
|
+
cache.put_if_absent name, quoted.freeze
|
51
|
+
end
|
52
|
+
quoted
|
53
|
+
else
|
54
|
+
super
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|