activerecord-jdbc-adapter 1.3.0.beta1 → 1.3.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (161) hide show
  1. data/.gitignore +12 -11
  2. data/.travis.yml +36 -7
  3. data/Appraisals +3 -3
  4. data/Gemfile +1 -1
  5. data/Gemfile.lock +13 -6
  6. data/History.txt +64 -0
  7. data/README.md +8 -1
  8. data/Rakefile +3 -1
  9. data/gemfiles/rails23.gemfile +1 -1
  10. data/gemfiles/rails23.gemfile.lock +6 -5
  11. data/gemfiles/rails30.gemfile +1 -1
  12. data/gemfiles/rails30.gemfile.lock +7 -6
  13. data/gemfiles/rails31.gemfile +1 -1
  14. data/gemfiles/rails31.gemfile.lock +6 -5
  15. data/gemfiles/rails32.gemfile +1 -1
  16. data/gemfiles/rails32.gemfile.lock +6 -5
  17. data/gemfiles/rails40.gemfile +2 -4
  18. data/gemfiles/rails40.gemfile.lock +37 -51
  19. data/lib/active_record/connection_adapters/as400_adapter.rb +2 -0
  20. data/lib/active_record/connection_adapters/db2_adapter.rb +1 -1
  21. data/lib/arel/visitors/db2.rb +5 -1
  22. data/lib/arel/visitors/hsqldb.rb +1 -0
  23. data/lib/arel/visitors/sql_server.rb +55 -13
  24. data/lib/arjdbc/db2/adapter.rb +197 -227
  25. data/lib/arjdbc/db2/as400.rb +124 -0
  26. data/lib/arjdbc/db2/connection_methods.rb +20 -1
  27. data/lib/arjdbc/derby/adapter.rb +17 -85
  28. data/lib/arjdbc/derby/connection_methods.rb +2 -1
  29. data/lib/arjdbc/discover.rb +55 -47
  30. data/lib/arjdbc/h2/adapter.rb +52 -18
  31. data/lib/arjdbc/h2/connection_methods.rb +10 -2
  32. data/lib/arjdbc/hsqldb/adapter.rb +33 -9
  33. data/lib/arjdbc/hsqldb/connection_methods.rb +10 -2
  34. data/lib/arjdbc/informix.rb +2 -1
  35. data/lib/arjdbc/jdbc.rb +5 -1
  36. data/lib/arjdbc/jdbc/adapter.rb +167 -89
  37. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  38. data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
  39. data/lib/arjdbc/jdbc/base_ext.rb +25 -3
  40. data/lib/arjdbc/jdbc/callbacks.rb +9 -8
  41. data/lib/arjdbc/jdbc/column.rb +8 -20
  42. data/lib/arjdbc/jdbc/connection.rb +69 -80
  43. data/lib/arjdbc/jdbc/extension.rb +6 -8
  44. data/lib/arjdbc/jdbc/jdbc.rake +3 -141
  45. data/lib/arjdbc/jdbc/rake_tasks.rb +3 -10
  46. data/lib/arjdbc/mssql/adapter.rb +108 -34
  47. data/lib/arjdbc/mssql/connection_methods.rb +3 -1
  48. data/lib/arjdbc/mssql/limit_helpers.rb +3 -2
  49. data/lib/arjdbc/mssql/lock_helpers.rb +5 -1
  50. data/lib/arjdbc/mysql/adapter.rb +127 -70
  51. data/lib/arjdbc/mysql/connection_methods.rb +5 -2
  52. data/lib/arjdbc/oracle/adapter.rb +124 -94
  53. data/lib/arjdbc/oracle/connection_methods.rb +2 -1
  54. data/lib/arjdbc/postgresql/adapter.rb +99 -67
  55. data/lib/arjdbc/postgresql/column_cast.rb +3 -5
  56. data/lib/arjdbc/postgresql/connection_methods.rb +6 -6
  57. data/lib/arjdbc/railtie.rb +3 -1
  58. data/lib/arjdbc/sqlite3/adapter.rb +60 -43
  59. data/lib/arjdbc/sqlite3/connection_methods.rb +9 -9
  60. data/lib/arjdbc/sybase.rb +1 -1
  61. data/lib/arjdbc/tasks.rb +13 -0
  62. data/lib/arjdbc/tasks/database_tasks.rb +50 -0
  63. data/lib/arjdbc/tasks/databases.rake +89 -0
  64. data/lib/arjdbc/tasks/databases3.rake +203 -0
  65. data/lib/arjdbc/tasks/databases4.rake +39 -0
  66. data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
  67. data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
  68. data/lib/arjdbc/tasks/h2_database_tasks.rb +29 -0
  69. data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
  70. data/lib/arjdbc/tasks/jdbc_database_tasks.rb +122 -0
  71. data/lib/arjdbc/tasks/mssql_database_tasks.rb +36 -0
  72. data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +297 -0
  73. data/lib/arjdbc/tasks/oracle_database_tasks.rb +62 -0
  74. data/lib/arjdbc/version.rb +1 -1
  75. data/pom.xml +11 -12
  76. data/rails_generators/jdbc_generator.rb +1 -1
  77. data/rails_generators/templates/config/initializers/jdbc.rb +8 -5
  78. data/rails_generators/templates/lib/tasks/jdbc.rake +7 -4
  79. data/rakelib/02-test.rake +42 -15
  80. data/rakelib/compile.rake +29 -2
  81. data/rakelib/db.rake +2 -1
  82. data/rakelib/rails.rake +23 -6
  83. data/src/java/arjdbc/ArJdbcModule.java +175 -0
  84. data/src/java/arjdbc/db2/DB2Module.java +2 -1
  85. data/src/java/arjdbc/derby/DerbyModule.java +5 -24
  86. data/src/java/arjdbc/hsqldb/HSQLDBModule.java +3 -2
  87. data/src/java/arjdbc/jdbc/AdapterJavaService.java +3 -46
  88. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +1001 -259
  89. data/src/java/arjdbc/mssql/MSSQLModule.java +2 -1
  90. data/src/java/arjdbc/mysql/MySQLModule.java +4 -3
  91. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +12 -7
  92. data/src/java/arjdbc/oracle/OracleModule.java +2 -1
  93. data/src/java/arjdbc/sqlite3/SQLite3Module.java +2 -1
  94. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +12 -0
  95. data/test/db/db2.rb +14 -7
  96. data/test/db/db2/rake_test.rb +82 -0
  97. data/test/db/db2/rake_test_data.sql +35 -0
  98. data/test/db/db2/simple_test.rb +20 -0
  99. data/test/db/db2/unit_test.rb +3 -1
  100. data/test/db/derby.rb +7 -5
  101. data/test/db/derby/rake_test.rb +96 -0
  102. data/test/db/derby/simple_test.rb +10 -2
  103. data/test/db/h2.rb +6 -8
  104. data/test/db/h2/identity_column_test.rb +35 -0
  105. data/test/db/h2/offset_test.rb +49 -0
  106. data/test/db/h2/rake_test.rb +98 -0
  107. data/test/db/h2/schema_dump_test.rb +5 -1
  108. data/test/db/hsqldb.rb +6 -10
  109. data/test/db/hsqldb/rake_test.rb +101 -0
  110. data/test/db/hsqldb/schema_dump_test.rb +5 -1
  111. data/test/db/hsqldb/simple_test.rb +8 -0
  112. data/test/db/jndi_config.rb +1 -3
  113. data/test/db/jndi_pooled_config.rb +1 -3
  114. data/test/db/mssql/limit_offset_test.rb +23 -14
  115. data/test/db/mssql/rake_test.rb +143 -0
  116. data/test/db/mysql/_rails_test_mysql.32.out +1069 -1252
  117. data/test/db/mysql/nonstandard_primary_key_test.rb +21 -24
  118. data/test/db/mysql/rake_test.rb +97 -0
  119. data/test/db/mysql/schema_dump_test.rb +11 -11
  120. data/test/db/mysql/simple_test.rb +52 -3
  121. data/test/db/mysql/statement_escaping_test.rb +46 -0
  122. data/test/db/oracle/rake_test.rb +100 -0
  123. data/test/db/oracle/simple_test.rb +48 -0
  124. data/test/db/postgres/_rails_test_postgres.32.out +998 -1370
  125. data/test/db/postgres/active_schema_unit_test.rb +68 -0
  126. data/test/db/postgres/connection_test.rb +10 -2
  127. data/test/db/postgres/data_types_test.rb +2 -2
  128. data/test/db/postgres/ltree_test.rb +6 -5
  129. data/test/db/postgres/native_types_test.rb +1 -5
  130. data/test/db/postgres/rake_test.rb +117 -0
  131. data/test/db/postgres/schema_dump_test.rb +9 -2
  132. data/test/db/postgres/schema_test.rb +4 -2
  133. data/test/db/postgres/simple_test.rb +57 -16
  134. data/test/db/sqlite3.rb +3 -10
  135. data/test/db/sqlite3/_rails_test_sqlite3.32.out +1070 -1298
  136. data/test/db/sqlite3/rake_test.rb +71 -0
  137. data/test/db/sqlite3/simple_test.rb +9 -9
  138. data/test/has_many_through.rb +4 -1
  139. data/test/jdbc/db2.rb +14 -1
  140. data/test/jdbc_column_test.rb +23 -0
  141. data/test/{generic_jdbc_connection_test.rb → jdbc_connection_test.rb} +22 -17
  142. data/test/jndi_callbacks_test.rb +26 -28
  143. data/test/jndi_test.rb +7 -16
  144. data/test/models/data_types.rb +2 -1
  145. data/test/models/thing.rb +1 -0
  146. data/test/rails/mysql.rb +13 -0
  147. data/test/rails/sqlite3/version.rb +6 -0
  148. data/test/rails_stub.rb +31 -0
  149. data/test/rake_test_support.rb +298 -0
  150. data/test/serialize.rb +2 -4
  151. data/test/{helper.rb → shared_helper.rb} +0 -0
  152. data/test/simple.rb +167 -93
  153. data/test/test_helper.rb +52 -16
  154. metadata +388 -354
  155. data/lib/pg.rb +0 -26
  156. data/test/abstract_db_create.rb +0 -139
  157. data/test/activerecord/connection_adapters/type_conversion_test.rb +0 -36
  158. data/test/db/mssql/db_create_test.rb +0 -29
  159. data/test/db/mysql/db_create_test.rb +0 -33
  160. data/test/db/postgres/db_create_test.rb +0 -44
  161. data/test/db/postgres/db_drop_test.rb +0 -17
@@ -0,0 +1,36 @@
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 = test['database']
10
+ test['database'] = 'master'
11
+ establish_connection(test)
12
+ connection.recreate_database!(test_database)
13
+ end
14
+
15
+ def structure_dump(filename)
16
+ `smoscript -s #{config['host']} -d #{config['database']} -u #{config['username']} -p #{config['password']} -f #{filename} -A -U`
17
+ end
18
+
19
+ def structure_load(filename)
20
+ `sqlcmd -S #{config['host']} -d #{config['database']} -U #{config['username']} -P #{config['password']} -i #{filename}`
21
+ end
22
+
23
+ private
24
+
25
+ def deep_dup(hash)
26
+ dup = hash.dup
27
+ dup.each_pair do |k,v|
28
+ tv = dup[k]
29
+ dup[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? deep_dup(tv) : v
30
+ end
31
+ dup
32
+ end
33
+
34
+ end
35
+ end
36
+ 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' and !column['data_precision'].nil?
48
+ col << "(#{column['data_precision'].to_i}"
49
+ col << ",#{column['data_scale'].to_i}" if !column['data_scale'].nil?
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']}" if !column['data_default'].nil?
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' and !column['data_precision'].nil?
64
+ col << "(#{column['data_precision'].to_i}"
65
+ col << ",#{column['data_scale'].to_i}" if !column['data_scale'].nil?
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
+ lines = 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
+ }).map 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] == ';'
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,62 @@
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
+ begin
12
+ connection.execute "CREATE USER #{config['username']} IDENTIFIED BY #{config['password']}"
13
+ rescue => e
14
+ if e.message =~ /ORA-01920/ # user name conflicts with another user or role name
15
+ connection.execute "ALTER USER #{config['username']} IDENTIFIED BY #{config['password']}"
16
+ else
17
+ raise e
18
+ end
19
+ end
20
+ connection.execute "GRANT unlimited tablespace TO #{config['username']}"
21
+ connection.execute "GRANT create session TO #{config['username']}"
22
+ connection.execute "GRANT create table TO #{config['username']}"
23
+ connection.execute "GRANT create sequence TO #{config['username']}"
24
+ end
25
+
26
+ def drop
27
+ self.class.load_enhanced_structure_dump
28
+ establish_connection(config)
29
+ connection.execute_structure_dump(connection.full_drop)
30
+ end
31
+
32
+ def purge
33
+ self.class.load_enhanced_structure_dump
34
+ establish_connection(:test)
35
+ connection.execute_structure_dump(connection.full_drop)
36
+ connection.execute("PURGE RECYCLEBIN") rescue nil
37
+ end
38
+
39
+ def structure_dump(filename)
40
+ self.class.load_enhanced_structure_dump
41
+ establish_connection(config)
42
+ File.open(filename, "w:utf-8") { |f| f << connection.structure_dump }
43
+ end
44
+
45
+ def structure_load(filename)
46
+ self.class.load_enhanced_structure_dump
47
+ establish_connection(config)
48
+ connection.execute_structure_dump(File.read(filename))
49
+ end
50
+
51
+ def self.load_enhanced_structure_dump
52
+ unless defined? ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter
53
+ ActiveRecord::ConnectionAdapters.module_eval do
54
+ const_set :OracleEnhancedAdapter, ActiveRecord::ConnectionAdapters::OracleAdapter
55
+ end
56
+ end
57
+ require 'arjdbc/tasks/oracle/enhanced_structure_dump'
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -1,5 +1,5 @@
1
1
  module ArJdbc
2
- VERSION = "1.3.0.beta1"
2
+ VERSION = "1.3.0.beta2"
3
3
  module Version # :nodoc:
4
4
  VERSION = ArJdbc::VERSION # :nodoc: 1.2.x compatibility
5
5
  end
data/pom.xml CHANGED
@@ -1,26 +1,25 @@
1
1
  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2
2
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3
3
  <modelVersion>4.0.0</modelVersion>
4
- <groupId>org.jruby.activerecord-jdbc</groupId>
4
+ <groupId>org.jruby.rails</groupId>
5
5
  <artifactId>activerecord-jdbc</artifactId>
6
6
  <packaging>jar</packaging>
7
- <version>1.0.0</version>
7
+ <version>IDE-SNAPSHOT</version>
8
8
  <name>activerecord-jdbc</name>
9
9
  <description>
10
- This POM for activerecord-jdbc is just for bootstrapping IDEs. You
11
- can't use it to build the project at the moment.
10
+ This POM for ActiveRecord-JDBC is just for bootstrapping IDEs.
12
11
  </description>
13
- <url>http://activerecord-jdbc.kenai.com/</url>
12
+ <url>http://github.com/jruby/activerecord-jdbc-adapter/wiki</url>
14
13
 
15
14
  <issueManagement>
16
- <system>JIRA</system>
17
- <url>http://kenai.com/jira/browse/ACTIVERECORD_JDBC</url>
15
+ <system>GitHub</system>
16
+ <url>http://github.com/jruby/activerecord-jdbc-adapter/issues</url>
18
17
  </issueManagement>
19
18
 
20
19
  <scm>
21
- <connection>scm:git:git://github.com/nicksieger/activerecord-jdbc-adapter.git</connection>
22
- <developerConnection>scm:git:git@github.com:nicksieger/activerecord-jdbc-adapter.git</developerConnection>
23
- <url>http://github.com/nicksieger/activerecord-jdbc-adapter</url>
20
+ <connection>scm:git:git://github.com/jruby/activerecord-jdbc-adapter.git</connection>
21
+ <developerConnection>scm:git:git@github.com:jruby/activerecord-jdbc-adapter.git</developerConnection>
22
+ <url>https://github.com/jruby/activerecord-jdbc-adapter</url>
24
23
  </scm>
25
24
 
26
25
  <licenses>
@@ -55,8 +54,8 @@
55
54
  <groupId>org.apache.maven.plugins</groupId>
56
55
  <artifactId>maven-compiler-plugin</artifactId>
57
56
  <configuration>
58
- <source>1.5</source>
59
- <target>1.5</target>
57
+ <source>1.6</source>
58
+ <target>1.6</target>
60
59
  </configuration>
61
60
  </plugin>
62
61
  </plugins>