activerecord-jdbc-adapter 51.8-java → 52.0-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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -2
  3. data/.travis.yml +26 -51
  4. data/README.md +9 -11
  5. data/Rakefile +19 -74
  6. data/activerecord-jdbc-adapter.gemspec +2 -2
  7. data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
  8. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
  9. data/lib/arjdbc/abstract/core.rb +2 -12
  10. data/lib/arjdbc/abstract/database_statements.rb +24 -10
  11. data/lib/arjdbc/abstract/statement_cache.rb +4 -4
  12. data/lib/arjdbc/db2/adapter.rb +52 -2
  13. data/lib/arjdbc/jdbc.rb +4 -0
  14. data/lib/arjdbc/jdbc/column.rb +11 -5
  15. data/lib/arjdbc/jdbc/connection_methods.rb +9 -2
  16. data/lib/arjdbc/jdbc/jdbc.rake +4 -0
  17. data/lib/arjdbc/mssql.rb +7 -0
  18. data/lib/arjdbc/mssql/adapter.rb +804 -0
  19. data/lib/arjdbc/mssql/column.rb +200 -0
  20. data/lib/arjdbc/mssql/connection_methods.rb +79 -0
  21. data/lib/arjdbc/mssql/explain_support.rb +99 -0
  22. data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
  23. data/lib/arjdbc/mssql/lock_methods.rb +77 -0
  24. data/lib/arjdbc/mssql/types.rb +343 -0
  25. data/lib/arjdbc/mssql/utils.rb +82 -0
  26. data/lib/arjdbc/mysql/adapter.rb +22 -14
  27. data/lib/arjdbc/mysql/connection_methods.rb +9 -18
  28. data/lib/arjdbc/postgresql/adapter.rb +102 -75
  29. data/lib/arjdbc/postgresql/column.rb +3 -6
  30. data/lib/arjdbc/postgresql/connection_methods.rb +3 -12
  31. data/lib/arjdbc/postgresql/oid_types.rb +12 -86
  32. data/lib/arjdbc/sqlite3/adapter.rb +88 -92
  33. data/lib/arjdbc/sqlite3/connection_methods.rb +0 -1
  34. data/lib/arjdbc/tasks/database_tasks.rb +36 -16
  35. data/lib/arjdbc/tasks/databases.rake +75 -32
  36. data/lib/arjdbc/tasks/databases3.rake +215 -0
  37. data/lib/arjdbc/tasks/databases4.rake +39 -0
  38. data/lib/arjdbc/version.rb +1 -1
  39. data/rakelib/01-tomcat.rake +2 -2
  40. data/rakelib/02-test.rake +3 -0
  41. data/rakelib/compile.rake +70 -0
  42. data/rakelib/db.rake +7 -21
  43. data/rakelib/rails.rake +4 -5
  44. data/src/java/arjdbc/ArJdbcModule.java +15 -5
  45. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +2 -2
  46. data/src/java/arjdbc/jdbc/ConnectionFactory.java +87 -0
  47. data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +1 -0
  48. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +29 -113
  49. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +14 -310
  50. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +2 -2
  51. data/src/java/arjdbc/postgresql/PgResultSetMetaDataWrapper.java +23 -0
  52. data/src/java/arjdbc/postgresql/PostgreSQLResult.java +13 -21
  53. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +50 -44
  54. data/src/java/arjdbc/util/DateTimeUtils.java +5 -141
  55. data/src/java/arjdbc/util/QuotingUtils.java +7 -6
  56. metadata +26 -11
  57. data/src/java/arjdbc/jdbc/RubyConnectionFactory.java +0 -61
  58. data/src/java/arjdbc/postgresql/PgDateTimeUtils.java +0 -52
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  ArJdbc::ConnectionMethods.module_eval do
3
3
  def sqlite3_connection(config)
4
- config = config.deep_dup
5
4
  config[:adapter_spec] ||= ::ArJdbc::SQLite3
6
5
  config[:adapter_class] = ActiveRecord::ConnectionAdapters::SQLite3Adapter unless config.key?(:adapter_class)
7
6
 
@@ -1,32 +1,52 @@
1
1
  module ArJdbc
2
2
  module Tasks
3
3
 
4
- def self.register_tasks(pattern, task)
5
- ActiveRecord::Tasks::DatabaseTasks.register_task(pattern, task)
6
- end
4
+ if defined? ActiveRecord::Tasks::DatabaseTasks # AR-4.x
5
+
6
+ def self.register_tasks(pattern, task)
7
+ ActiveRecord::Tasks::DatabaseTasks.register_task(pattern, task)
8
+ end
9
+
10
+ # support adapter: mariadb (as if it were mysql)
11
+ register_tasks(/mariadb/, ActiveRecord::Tasks::MySQLDatabaseTasks)
12
+
13
+ else
7
14
 
8
- # support adapter: mariadb (as if it were mysql)
9
- register_tasks(/mariadb/, ActiveRecord::Tasks::MySQLDatabaseTasks)
15
+ @@tasks = {}
16
+
17
+ def self.register_tasks(pattern, task)
18
+ @@tasks[pattern] = task
19
+ end
20
+
21
+ def self.tasks_instance(config)
22
+ adapter = config['adapter']
23
+ key = @@tasks.keys.detect { |pattern| adapter[pattern] }
24
+ ( @@tasks[key] || JdbcDatabaseTasks ).new(config)
25
+ end
26
+
27
+ end
10
28
 
11
29
  require 'arjdbc/tasks/jdbc_database_tasks'
12
- #require 'arjdbc/tasks/db2_database_tasks'
13
- #require 'arjdbc/tasks/derby_database_tasks'
14
- #require 'arjdbc/tasks/h2_database_tasks'
15
- #require 'arjdbc/tasks/hsqldb_database_tasks'
16
- #require 'arjdbc/tasks/mssql_database_tasks'
30
+ require 'arjdbc/tasks/db2_database_tasks'
31
+ require 'arjdbc/tasks/derby_database_tasks'
32
+ require 'arjdbc/tasks/h2_database_tasks'
33
+ require 'arjdbc/tasks/hsqldb_database_tasks'
34
+ require 'arjdbc/tasks/mssql_database_tasks'
17
35
 
18
36
  # re-invent built-in (but deprecated on 4.0) tasks :
19
- #register_tasks(/sqlserver/, MSSQLDatabaseTasks)
20
- #register_tasks(/mssql/, MSSQLDatabaseTasks) # (built-in) alias
37
+ register_tasks(/sqlserver/, MSSQLDatabaseTasks)
38
+ register_tasks(/mssql/, MSSQLDatabaseTasks) # (built-in) alias
21
39
  # tasks for custom (JDBC) adapters :
22
- #register_tasks(/db2/, DB2DatabaseTasks)
23
- #register_tasks(/derby/, DerbyDatabaseTasks)
24
- #register_tasks(/h2/, H2DatabaseTasks)
25
- #register_tasks(/hsqldb/, HSQLDBDatabaseTasks)
40
+ register_tasks(/db2/, DB2DatabaseTasks)
41
+ register_tasks(/derby/, DerbyDatabaseTasks)
42
+ register_tasks(/h2/, H2DatabaseTasks)
43
+ register_tasks(/hsqldb/, HSQLDBDatabaseTasks)
26
44
  # (default) generic JDBC task :
27
45
  register_tasks(/^jdbc$/, JdbcDatabaseTasks)
28
46
 
29
47
  # NOTE: no need to register "built-in" adapters such as MySQL
48
+ # - on 4.0 these are registered and will be instantiated
49
+ # - while on 2.3/3.x we keep the AR built-in task behavior
30
50
 
31
51
  end
32
52
  end
@@ -1,48 +1,91 @@
1
- require 'arjdbc/tasks/database_tasks'
1
+ raise "ArJdbc needs rake 0.9.x or newer" unless Rake.const_defined?(:VERSION)
2
2
 
3
- module ActiveRecord::Tasks
3
+ Rake::DSL.module_eval do
4
4
 
5
- DatabaseTasks.module_eval do
5
+ def redefine_task(*args, &block)
6
+ if Hash === args.first
7
+ task_name = args.first.keys[0]
8
+ old_prereqs = false # leave as specified
9
+ else
10
+ task_name = args.first; old_prereqs = []
11
+ # args[0] = { task_name => old_prereqs }
12
+ end
6
13
 
7
- # @override patched to adapt jdbc configuration
8
- def each_current_configuration(environment)
9
- environments = [environment]
10
- environments << 'test' if environment == 'development'
14
+ full_name = Rake::Task.scope_name(Rake.application.current_scope, task_name)
11
15
 
12
- configurations = ActiveRecord::Base.configurations.values_at(*environments)
13
- configurations.compact.each do |config|
14
- yield adapt_jdbc_config(config) unless config['database'].blank?
15
- end
16
+ if old_task = Rake.application.lookup(task_name)
17
+ old_comment = old_task.full_comment
18
+ old_prereqs = old_task.prerequisites.dup if old_prereqs
19
+ old_actions = old_task.actions.dup
20
+ old_actions.shift # remove the main 'action' block - we're redefining it
21
+ # old_task.clear_prerequisites if old_prereqs
22
+ # old_task.clear_actions
23
+ # remove the (old) task instance from the application :
24
+ Rake.application.send(:instance_variable_get, :@tasks)[full_name.to_s] = nil
25
+ else
26
+ # raise "could not find rake task with (full) name '#{full_name}'"
16
27
  end
17
28
 
18
- # @override patched to adapt jdbc configuration
19
- def each_local_configuration
20
- ActiveRecord::Base.configurations.each_value do |config|
21
- next unless config['database']
29
+ new_task = task(*args, &block)
30
+ new_task.comment = old_comment if old_comment
31
+ new_task.actions.concat(old_actions) if old_actions
32
+ new_task.prerequisites.concat(old_prereqs) if old_prereqs
33
+ new_task
34
+ end
22
35
 
23
- if local_database?(config)
24
- yield adapt_jdbc_config(config)
25
- else
26
- $stderr.puts "This task only modifies local databases. #{config['database']} is on a remote host."
27
- end
28
- end
29
- end
36
+ end
30
37
 
31
- private
38
+ namespace :db do
32
39
 
33
- def adapt_jdbc_config(config)
34
- return config unless config['adapter']
35
- config.merge 'adapter' => config['adapter'].sub(/^jdbc/, '')
36
- end
40
+ def rails_env
41
+ defined?(Rails.env) ? Rails.env : ( RAILS_ENV || 'development' )
42
+ end
37
43
 
44
+ if defined? adapt_jdbc_config
45
+ ArJdbc.warn "double loading #{__FILE__} please delete lib/tasks/jdbc.rake if present!"
38
46
  end
39
47
 
40
- MySQLDatabaseTasks.class_eval do
48
+ def adapt_jdbc_config(config)
49
+ return config unless config['adapter']
50
+ config.merge 'adapter' => config['adapter'].sub(/^jdbc/, '')
51
+ end
41
52
 
42
- def error_class
43
- ActiveRecord::JDBCError
53
+ if defined? ActiveRecord::Tasks::DatabaseTasks # 4.0
54
+
55
+ def current_config(options = {})
56
+ ActiveRecord::Tasks::DatabaseTasks.current_config(options)
44
57
  end
45
58
 
46
- end if const_defined?(:MySQLDatabaseTasks)
59
+ else # 3.x / 2.3
60
+
61
+ def current_config(options = {}) # not on 2.3
62
+ options = { :env => rails_env }.merge! options
63
+ if options[:config]
64
+ @current_config = options[:config]
65
+ else
66
+ @current_config ||= ENV['DATABASE_URL'] ?
67
+ database_url_config : ActiveRecord::Base.configurations[options[:env]]
68
+ end
69
+ end
70
+
71
+ def database_url_config(url = ENV['DATABASE_URL'])
72
+ # NOTE: ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver
73
+ # since AR 4.0 that is handled by DatabaseTasks - only care about 2.3/3.x :
74
+ unless defined? ActiveRecord::Base::ConnectionSpecification::Resolver
75
+ raise "DATABASE_URL not supported on ActiveRecord #{ActiveRecord::VERSION::STRING}"
76
+ end
77
+ resolver = ActiveRecord::Base::ConnectionSpecification::Resolver.new(url, {})
78
+ resolver.spec.config.stringify_keys
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+
85
+ require 'arjdbc/tasks/database_tasks'
47
86
 
48
- end
87
+ if defined? ActiveRecord::Tasks::DatabaseTasks # 4.0
88
+ load File.expand_path('databases4.rake', File.dirname(__FILE__))
89
+ else # 3.x / 2.3
90
+ load File.expand_path('databases3.rake', File.dirname(__FILE__))
91
+ end
@@ -0,0 +1,215 @@
1
+ module ArJdbc
2
+ module Tasks
3
+ class << self
4
+
5
+ # API similar to ActiveRecord::Tasks::DatabaseTasks on AR 4.0
6
+
7
+ def create(config)
8
+ tasks_instance(config).create
9
+ end
10
+
11
+ def drop(config)
12
+ tasks_instance(config).drop
13
+ end
14
+
15
+ def purge(config)
16
+ tasks_instance(config).purge
17
+ end
18
+
19
+ def charset(config)
20
+ tasks_instance(config).charset
21
+ end
22
+
23
+ def collation(config)
24
+ tasks_instance(config).collation
25
+ end
26
+
27
+ def structure_dump(config, filename)
28
+ tasks_instance(config).structure_dump(filename)
29
+ end
30
+
31
+ def structure_load(config, filename)
32
+ tasks_instance(config).structure_load(filename)
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+
39
+ namespace :db do
40
+
41
+ class << self
42
+ alias_method :_rails_create_database, :create_database
43
+ alias_method :_rails_drop_database, :drop_database
44
+ end
45
+
46
+ def create_database(config)
47
+ case config['adapter']
48
+ when /mysql2/
49
+ unless defined? Mysql2::Error
50
+ # NOTE: fake it for create_database(config)
51
+ Object.const_set :Mysql2, Module.new
52
+ Mysql2.const_set :Error, ActiveRecord::JDBCError
53
+ ActiveRecord::JDBCError.class_eval do
54
+ def error; self end # Mysql2::Error#error
55
+ end
56
+ end
57
+ _rails_create_database adapt_jdbc_config(config)
58
+ when /mysql/
59
+ unless defined? Mysql::Error
60
+ # NOTE: fake it for create_database(config)
61
+ Object.const_set :Mysql, Module.new
62
+ Mysql.const_set :Error, ActiveRecord::JDBCError
63
+ ActiveRecord::JDBCError.class_eval do
64
+ def error; self end # Mysql::Error#error
65
+ end
66
+ end
67
+ _rails_create_database adapt_jdbc_config(config)
68
+ when /postgresql|sqlite/
69
+ _rails_create_database adapt_jdbc_config(config)
70
+ else
71
+ ArJdbc::Tasks.create(config)
72
+ end
73
+ end
74
+
75
+ def drop_database(config)
76
+ case config['adapter']
77
+ when /mysql|postgresql|sqlite/
78
+ _rails_drop_database adapt_jdbc_config(config)
79
+ else
80
+ ArJdbc::Tasks.drop(config)
81
+ end
82
+ end
83
+
84
+ redefine_task :charset do # available on 2.3
85
+ ArJdbc::Tasks.charset ActiveRecord::Base.configurations[rails_env]
86
+ end
87
+
88
+ redefine_task :collation do # available on 2.3
89
+ ArJdbc::Tasks.collation ActiveRecord::Base.configurations[rails_env]
90
+ end
91
+
92
+ namespace :structure do
93
+
94
+ redefine_task :dump do
95
+ config = ActiveRecord::Base.configurations[rails_env] # current_config
96
+ filename = structure_sql
97
+
98
+ case config['adapter']
99
+ when /mysql/
100
+ ActiveRecord::Base.establish_connection(config)
101
+ File.open(filename, 'w:utf-8') { |f| f << ActiveRecord::Base.connection.structure_dump }
102
+ when /postgresql/
103
+ ActiveRecord::Base.establish_connection(config)
104
+
105
+ ENV['PGHOST'] = config['host'] if config['host']
106
+ ENV['PGPORT'] = config['port'].to_s if config['port']
107
+ ENV['PGPASSWORD'] = config['password'].to_s if config['password']
108
+ ENV['PGUSER'] = config['username'].to_s if config['username']
109
+
110
+ require 'shellwords'
111
+ search_path = config['schema_search_path']
112
+ unless search_path.blank?
113
+ search_path = search_path.split(",").map{ |part| "--schema=#{Shellwords.escape(part.strip)}" }.join(" ")
114
+ end
115
+ sh "pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(config['database'])}"
116
+
117
+ File.open(filename, 'a') { |f| f << "SET search_path TO #{ActiveRecord::Base.connection.schema_search_path};\n\n" }
118
+ when /sqlite/
119
+ dbfile = config['database']
120
+ sh "sqlite3 #{dbfile} .schema > #{filename}"
121
+ else
122
+ ActiveRecord::Base.establish_connection(config)
123
+ ArJdbc::Tasks.structure_dump(config, filename)
124
+ end
125
+
126
+ if ActiveRecord::Base.connection.supports_migrations?
127
+ File.open(filename, 'a') { |f| f << ActiveRecord::Base.connection.dump_schema_information }
128
+ end
129
+
130
+ end
131
+
132
+ redefine_task :load do
133
+ config = current_config
134
+ filename = structure_sql
135
+
136
+ case config['adapter']
137
+ when /mysql/
138
+ ActiveRecord::Base.establish_connection(config)
139
+ ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0')
140
+ IO.read(filename).split("\n\n").each do |table|
141
+ ActiveRecord::Base.connection.execute(table)
142
+ end
143
+ when /postgresql/
144
+ ENV['PGHOST'] = config['host'] if config['host']
145
+ ENV['PGPORT'] = config['port'].to_s if config['port']
146
+ ENV['PGPASSWORD'] = config['password'].to_s if config['password']
147
+ ENV['PGUSER'] = config['username'].to_s if config['username']
148
+
149
+ `psql -f "#{filename}" #{config['database']}`
150
+ when /sqlite/
151
+ dbfile = config['database']
152
+ `sqlite3 #{dbfile} < "#{filename}"`
153
+ else
154
+ ArJdbc::Tasks.structure_load(config, filename)
155
+ end
156
+ end
157
+
158
+ def structure_sql
159
+ ENV['DB_STRUCTURE'] ||= begin
160
+ root = defined?(Rails.root) ? Rails.root : ( RAILS_ROOT rescue nil )
161
+ if ActiveRecord::VERSION::STRING > '3.2'
162
+ root ? File.join(root, "db", "structure.sql") : File.join("db", "structure.sql")
163
+ else
164
+ root ? File.join(root, "db/#{rails_env}_structure.sql") : "db/#{rails_env}_structure.sql"
165
+ end
166
+ end
167
+ end
168
+
169
+ end
170
+
171
+ namespace :test do
172
+
173
+ # desc "Recreate the test database from an existent structure.sql file"
174
+ redefine_task :load_structure => 'db:test:purge' do # not on 2.3
175
+ begin
176
+ current_config(:config => ActiveRecord::Base.configurations['test'])
177
+ Rake::Task["db:structure:load"].invoke
178
+ ensure
179
+ current_config(:config => nil)
180
+ end
181
+ end
182
+
183
+ # desc "Recreate the test database from a fresh structure.sql file"
184
+ redefine_task :clone_structure => [ "db:structure:dump", "db:test:load_structure" ]
185
+ # same as on 3.2 - but this task gets changed on 2.3 by depending on :load_structure
186
+
187
+ # desc "Empty the test database"
188
+ redefine_task :purge do
189
+ config = ActiveRecord::Base.configurations['test']
190
+ case config['adapter']
191
+ when /mysql/
192
+ ActiveRecord::Base.establish_connection(:test)
193
+ options = mysql_creation_options(config) rescue config
194
+ ActiveRecord::Base.connection.recreate_database(config['database'], options)
195
+ when /postgresql/
196
+ ActiveRecord::Base.clear_active_connections!
197
+ # drop_database(config) :
198
+ ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
199
+ ActiveRecord::Base.connection.drop_database config['database']
200
+ # create_database(config) :
201
+ encoding = config[:encoding] || ENV['CHARSET'] || 'utf8'
202
+ ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => encoding))
203
+ when /sqlite/
204
+ dbfile = config['database']
205
+ File.delete(dbfile) if File.exist?(dbfile)
206
+ else
207
+ ArJdbc::Tasks.purge(config)
208
+ end
209
+ end
210
+ # only does (:purge => :environment) on AR < 3.2
211
+ task :purge => :load_config if Rake::Task.task_defined?(:load_config)
212
+
213
+ end
214
+
215
+ end
@@ -0,0 +1,39 @@
1
+ module ActiveRecord::Tasks
2
+
3
+ DatabaseTasks.module_eval do
4
+
5
+ # patched to adapt jdbc configuration
6
+ def each_current_configuration(environment)
7
+ environments = [environment]
8
+ environments << 'test' if environment == 'development'
9
+
10
+ configurations = ActiveRecord::Base.configurations.values_at(*environments)
11
+ configurations.compact.each do |config|
12
+ yield adapt_jdbc_config(config) unless config['database'].blank?
13
+ end
14
+ end
15
+
16
+ # patched to adapt jdbc configuration
17
+ def each_local_configuration
18
+ ActiveRecord::Base.configurations.each_value do |config|
19
+ next unless config['database']
20
+
21
+ if local_database?(config)
22
+ yield adapt_jdbc_config(config)
23
+ else
24
+ $stderr.puts "This task only modifies local databases. #{config['database']} is on a remote host."
25
+ end
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ MySQLDatabaseTasks.class_eval do
32
+
33
+ def error_class
34
+ ActiveRecord::JDBCError
35
+ end
36
+
37
+ end
38
+
39
+ end