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

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 (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>