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.
Files changed (191) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/.travis.yml +462 -0
  4. data/.yardopts +4 -0
  5. data/Appraisals +36 -0
  6. data/CONTRIBUTING.md +49 -0
  7. data/Gemfile +68 -0
  8. data/History.md +1191 -0
  9. data/LICENSE.txt +25 -0
  10. data/README.md +277 -0
  11. data/RUNNING_TESTS.md +88 -0
  12. data/Rakefile +298 -0
  13. data/Rakefile.jdbc +20 -0
  14. data/activerecord-jdbc-adapter.gemspec +63 -0
  15. data/lib/active_record/connection_adapters/as400_adapter.rb +2 -0
  16. data/lib/active_record/connection_adapters/db2_adapter.rb +1 -0
  17. data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
  18. data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
  19. data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
  20. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
  21. data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
  22. data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
  23. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
  24. data/lib/active_record/connection_adapters/mariadb_adapter.rb +1 -0
  25. data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
  26. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
  27. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
  28. data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
  29. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
  30. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
  31. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
  32. data/lib/activerecord-jdbc-adapter.rb +1 -0
  33. data/lib/arel/visitors/compat.rb +64 -0
  34. data/lib/arel/visitors/db2.rb +137 -0
  35. data/lib/arel/visitors/derby.rb +112 -0
  36. data/lib/arel/visitors/firebird.rb +79 -0
  37. data/lib/arel/visitors/h2.rb +25 -0
  38. data/lib/arel/visitors/hsqldb.rb +32 -0
  39. data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
  40. data/lib/arel/visitors/sql_server.rb +225 -0
  41. data/lib/arel/visitors/sql_server/ng42.rb +293 -0
  42. data/lib/arjdbc.rb +22 -0
  43. data/lib/arjdbc/db2.rb +4 -0
  44. data/lib/arjdbc/db2/adapter.rb +802 -0
  45. data/lib/arjdbc/db2/as400.rb +137 -0
  46. data/lib/arjdbc/db2/column.rb +177 -0
  47. data/lib/arjdbc/db2/connection_methods.rb +45 -0
  48. data/lib/arjdbc/derby.rb +3 -0
  49. data/lib/arjdbc/derby/active_record_patch.rb +13 -0
  50. data/lib/arjdbc/derby/adapter.rb +567 -0
  51. data/lib/arjdbc/derby/connection_methods.rb +16 -0
  52. data/lib/arjdbc/derby/schema_creation.rb +15 -0
  53. data/lib/arjdbc/discover.rb +104 -0
  54. data/lib/arjdbc/firebird.rb +4 -0
  55. data/lib/arjdbc/firebird/adapter.rb +468 -0
  56. data/lib/arjdbc/firebird/connection_methods.rb +20 -0
  57. data/lib/arjdbc/h2.rb +3 -0
  58. data/lib/arjdbc/h2/adapter.rb +335 -0
  59. data/lib/arjdbc/h2/connection_methods.rb +22 -0
  60. data/lib/arjdbc/hsqldb.rb +3 -0
  61. data/lib/arjdbc/hsqldb/adapter.rb +304 -0
  62. data/lib/arjdbc/hsqldb/connection_methods.rb +23 -0
  63. data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
  64. data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
  65. data/lib/arjdbc/informix.rb +5 -0
  66. data/lib/arjdbc/informix/adapter.rb +160 -0
  67. data/lib/arjdbc/informix/connection_methods.rb +9 -0
  68. data/lib/arjdbc/jdbc.rb +62 -0
  69. data/lib/arjdbc/jdbc/adapter.rb +997 -0
  70. data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
  71. data/lib/arjdbc/jdbc/arel_support.rb +149 -0
  72. data/lib/arjdbc/jdbc/base_ext.rb +34 -0
  73. data/lib/arjdbc/jdbc/callbacks.rb +52 -0
  74. data/lib/arjdbc/jdbc/column.rb +83 -0
  75. data/lib/arjdbc/jdbc/connection.rb +26 -0
  76. data/lib/arjdbc/jdbc/connection_methods.rb +59 -0
  77. data/lib/arjdbc/jdbc/driver.rb +44 -0
  78. data/lib/arjdbc/jdbc/error.rb +75 -0
  79. data/lib/arjdbc/jdbc/extension.rb +69 -0
  80. data/lib/arjdbc/jdbc/java.rb +13 -0
  81. data/lib/arjdbc/jdbc/type_cast.rb +154 -0
  82. data/lib/arjdbc/jdbc/type_converter.rb +142 -0
  83. data/lib/arjdbc/mssql.rb +7 -0
  84. data/lib/arjdbc/mssql/adapter.rb +822 -0
  85. data/lib/arjdbc/mssql/column.rb +207 -0
  86. data/lib/arjdbc/mssql/connection_methods.rb +72 -0
  87. data/lib/arjdbc/mssql/explain_support.rb +99 -0
  88. data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
  89. data/lib/arjdbc/mssql/lock_methods.rb +77 -0
  90. data/lib/arjdbc/mssql/types.rb +343 -0
  91. data/lib/arjdbc/mssql/utils.rb +82 -0
  92. data/lib/arjdbc/mysql.rb +3 -0
  93. data/lib/arjdbc/mysql/adapter.rb +998 -0
  94. data/lib/arjdbc/mysql/bulk_change_table.rb +150 -0
  95. data/lib/arjdbc/mysql/column.rb +167 -0
  96. data/lib/arjdbc/mysql/connection_methods.rb +137 -0
  97. data/lib/arjdbc/mysql/explain_support.rb +82 -0
  98. data/lib/arjdbc/mysql/schema_creation.rb +58 -0
  99. data/lib/arjdbc/oracle.rb +4 -0
  100. data/lib/arjdbc/oracle/adapter.rb +968 -0
  101. data/lib/arjdbc/oracle/column.rb +136 -0
  102. data/lib/arjdbc/oracle/connection_methods.rb +21 -0
  103. data/lib/arjdbc/postgresql.rb +3 -0
  104. data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +21 -0
  105. data/lib/arjdbc/postgresql/adapter.rb +1498 -0
  106. data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
  107. data/lib/arjdbc/postgresql/base/oid.rb +412 -0
  108. data/lib/arjdbc/postgresql/base/pgconn.rb +8 -0
  109. data/lib/arjdbc/postgresql/base/schema_definitions.rb +132 -0
  110. data/lib/arjdbc/postgresql/column.rb +640 -0
  111. data/lib/arjdbc/postgresql/connection_methods.rb +44 -0
  112. data/lib/arjdbc/postgresql/explain_support.rb +53 -0
  113. data/lib/arjdbc/postgresql/oid/bytea.rb +3 -0
  114. data/lib/arjdbc/postgresql/oid_types.rb +265 -0
  115. data/lib/arjdbc/postgresql/schema_creation.rb +60 -0
  116. data/lib/arjdbc/railtie.rb +11 -0
  117. data/lib/arjdbc/sqlite3.rb +3 -0
  118. data/lib/arjdbc/sqlite3/adapter.rb +654 -0
  119. data/lib/arjdbc/sqlite3/connection_methods.rb +36 -0
  120. data/lib/arjdbc/sqlite3/explain_support.rb +29 -0
  121. data/lib/arjdbc/sybase.rb +2 -0
  122. data/lib/arjdbc/sybase/adapter.rb +47 -0
  123. data/lib/arjdbc/tasks.rb +13 -0
  124. data/lib/arjdbc/tasks/database_tasks.rb +66 -0
  125. data/lib/arjdbc/tasks/databases.rake +91 -0
  126. data/lib/arjdbc/tasks/databases3.rake +239 -0
  127. data/lib/arjdbc/tasks/databases4.rake +39 -0
  128. data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
  129. data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
  130. data/lib/arjdbc/tasks/h2_database_tasks.rb +31 -0
  131. data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
  132. data/lib/arjdbc/tasks/jdbc_database_tasks.rb +169 -0
  133. data/lib/arjdbc/tasks/mssql_database_tasks.rb +46 -0
  134. data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +297 -0
  135. data/lib/arjdbc/tasks/oracle_database_tasks.rb +65 -0
  136. data/lib/arjdbc/util/quoted_cache.rb +60 -0
  137. data/lib/arjdbc/util/serialized_attributes.rb +98 -0
  138. data/lib/arjdbc/util/table_copier.rb +108 -0
  139. data/lib/arjdbc/version.rb +8 -0
  140. data/lib/generators/jdbc/USAGE +9 -0
  141. data/lib/generators/jdbc/jdbc_generator.rb +17 -0
  142. data/pom.xml +285 -0
  143. data/rails_generators/jdbc_generator.rb +15 -0
  144. data/rails_generators/templates/config/initializers/jdbc.rb +10 -0
  145. data/rails_generators/templates/lib/tasks/jdbc.rake +11 -0
  146. data/rakelib/01-tomcat.rake +51 -0
  147. data/rakelib/02-test.rake +151 -0
  148. data/rakelib/bundler_ext.rb +11 -0
  149. data/rakelib/db.rake +58 -0
  150. data/rakelib/rails.rake +77 -0
  151. data/src/java/arjdbc/ArJdbcModule.java +288 -0
  152. data/src/java/arjdbc/db2/DB2Module.java +77 -0
  153. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +128 -0
  154. data/src/java/arjdbc/derby/DerbyModule.java +180 -0
  155. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +153 -0
  156. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +190 -0
  157. data/src/java/arjdbc/h2/H2Module.java +50 -0
  158. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +86 -0
  159. data/src/java/arjdbc/hsqldb/HSQLDBModule.java +74 -0
  160. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +76 -0
  161. data/src/java/arjdbc/jdbc/AdapterJavaService.java +43 -0
  162. data/src/java/arjdbc/jdbc/Callable.java +44 -0
  163. data/src/java/arjdbc/jdbc/ConnectionFactory.java +77 -0
  164. data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +156 -0
  165. data/src/java/arjdbc/jdbc/DriverConnectionFactory.java +63 -0
  166. data/src/java/arjdbc/jdbc/DriverWrapper.java +128 -0
  167. data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +32 -0
  168. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +4541 -0
  169. data/src/java/arjdbc/jdbc/SQLBlock.java +54 -0
  170. data/src/java/arjdbc/jdbc/WithResultSet.java +37 -0
  171. data/src/java/arjdbc/mssql/MSSQLModule.java +91 -0
  172. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +193 -0
  173. data/src/java/arjdbc/mysql/MySQLModule.java +140 -0
  174. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +456 -0
  175. data/src/java/arjdbc/oracle/OracleModule.java +81 -0
  176. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +477 -0
  177. data/src/java/arjdbc/postgresql/ByteaUtils.java +171 -0
  178. data/src/java/arjdbc/postgresql/DriverImplementation.java +78 -0
  179. data/src/java/arjdbc/postgresql/PGDriverImplementation.java +535 -0
  180. data/src/java/arjdbc/postgresql/PostgreSQLModule.java +189 -0
  181. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +489 -0
  182. data/src/java/arjdbc/sqlite3/SQLite3Module.java +93 -0
  183. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +405 -0
  184. data/src/java/arjdbc/util/CallResultSet.java +826 -0
  185. data/src/java/arjdbc/util/DateTimeUtils.java +517 -0
  186. data/src/java/arjdbc/util/NumberUtils.java +50 -0
  187. data/src/java/arjdbc/util/ObjectSupport.java +65 -0
  188. data/src/java/arjdbc/util/QuotingUtils.java +139 -0
  189. data/src/java/arjdbc/util/StringCache.java +60 -0
  190. data/src/java/arjdbc/util/StringHelper.java +155 -0
  191. 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