activerecord-jdbc-alt-adapter 50.3.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 (198) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/.travis.yml +100 -0
  4. data/.yardopts +4 -0
  5. data/CONTRIBUTING.md +50 -0
  6. data/Gemfile +92 -0
  7. data/History.md +1191 -0
  8. data/LICENSE.txt +26 -0
  9. data/README.md +240 -0
  10. data/RUNNING_TESTS.md +127 -0
  11. data/Rakefile +336 -0
  12. data/Rakefile.jdbc +20 -0
  13. data/activerecord-jdbc-adapter.gemspec +55 -0
  14. data/activerecord-jdbc-alt-adapter.gemspec +56 -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/postgresql_adapter.rb +1 -0
  29. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
  30. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
  31. data/lib/activerecord-jdbc-adapter.rb +1 -0
  32. data/lib/arel/visitors/compat.rb +60 -0
  33. data/lib/arel/visitors/db2.rb +137 -0
  34. data/lib/arel/visitors/derby.rb +112 -0
  35. data/lib/arel/visitors/firebird.rb +79 -0
  36. data/lib/arel/visitors/h2.rb +25 -0
  37. data/lib/arel/visitors/hsqldb.rb +32 -0
  38. data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
  39. data/lib/arel/visitors/sql_server.rb +225 -0
  40. data/lib/arel/visitors/sql_server/ng42.rb +294 -0
  41. data/lib/arel/visitors/sqlserver.rb +214 -0
  42. data/lib/arjdbc.rb +19 -0
  43. data/lib/arjdbc/abstract/connection_management.rb +35 -0
  44. data/lib/arjdbc/abstract/core.rb +74 -0
  45. data/lib/arjdbc/abstract/database_statements.rb +64 -0
  46. data/lib/arjdbc/abstract/statement_cache.rb +58 -0
  47. data/lib/arjdbc/abstract/transaction_support.rb +86 -0
  48. data/lib/arjdbc/db2.rb +4 -0
  49. data/lib/arjdbc/db2/adapter.rb +789 -0
  50. data/lib/arjdbc/db2/as400.rb +130 -0
  51. data/lib/arjdbc/db2/column.rb +167 -0
  52. data/lib/arjdbc/db2/connection_methods.rb +44 -0
  53. data/lib/arjdbc/derby.rb +3 -0
  54. data/lib/arjdbc/derby/active_record_patch.rb +13 -0
  55. data/lib/arjdbc/derby/adapter.rb +540 -0
  56. data/lib/arjdbc/derby/connection_methods.rb +20 -0
  57. data/lib/arjdbc/derby/schema_creation.rb +15 -0
  58. data/lib/arjdbc/discover.rb +104 -0
  59. data/lib/arjdbc/firebird.rb +4 -0
  60. data/lib/arjdbc/firebird/adapter.rb +434 -0
  61. data/lib/arjdbc/firebird/connection_methods.rb +23 -0
  62. data/lib/arjdbc/h2.rb +3 -0
  63. data/lib/arjdbc/h2/adapter.rb +303 -0
  64. data/lib/arjdbc/h2/connection_methods.rb +27 -0
  65. data/lib/arjdbc/hsqldb.rb +3 -0
  66. data/lib/arjdbc/hsqldb/adapter.rb +297 -0
  67. data/lib/arjdbc/hsqldb/connection_methods.rb +28 -0
  68. data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
  69. data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
  70. data/lib/arjdbc/informix.rb +5 -0
  71. data/lib/arjdbc/informix/adapter.rb +162 -0
  72. data/lib/arjdbc/informix/connection_methods.rb +9 -0
  73. data/lib/arjdbc/jdbc.rb +59 -0
  74. data/lib/arjdbc/jdbc/adapter.rb +475 -0
  75. data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
  76. data/lib/arjdbc/jdbc/base_ext.rb +15 -0
  77. data/lib/arjdbc/jdbc/callbacks.rb +53 -0
  78. data/lib/arjdbc/jdbc/column.rb +97 -0
  79. data/lib/arjdbc/jdbc/connection.rb +14 -0
  80. data/lib/arjdbc/jdbc/connection_methods.rb +37 -0
  81. data/lib/arjdbc/jdbc/error.rb +65 -0
  82. data/lib/arjdbc/jdbc/extension.rb +59 -0
  83. data/lib/arjdbc/jdbc/java.rb +13 -0
  84. data/lib/arjdbc/jdbc/railtie.rb +2 -0
  85. data/lib/arjdbc/jdbc/rake_tasks.rb +3 -0
  86. data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -0
  87. data/lib/arjdbc/jdbc/type_cast.rb +166 -0
  88. data/lib/arjdbc/jdbc/type_converter.rb +142 -0
  89. data/lib/arjdbc/mssql.rb +7 -0
  90. data/lib/arjdbc/mssql/adapter.rb +384 -0
  91. data/lib/arjdbc/mssql/column.rb +29 -0
  92. data/lib/arjdbc/mssql/connection_methods.rb +79 -0
  93. data/lib/arjdbc/mssql/database_statements.rb +134 -0
  94. data/lib/arjdbc/mssql/errors.rb +6 -0
  95. data/lib/arjdbc/mssql/explain_support.rb +129 -0
  96. data/lib/arjdbc/mssql/extensions.rb +36 -0
  97. data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
  98. data/lib/arjdbc/mssql/lock_methods.rb +77 -0
  99. data/lib/arjdbc/mssql/old_adapter.rb +804 -0
  100. data/lib/arjdbc/mssql/old_column.rb +200 -0
  101. data/lib/arjdbc/mssql/quoting.rb +101 -0
  102. data/lib/arjdbc/mssql/schema_creation.rb +31 -0
  103. data/lib/arjdbc/mssql/schema_definitions.rb +74 -0
  104. data/lib/arjdbc/mssql/schema_statements.rb +329 -0
  105. data/lib/arjdbc/mssql/transaction.rb +69 -0
  106. data/lib/arjdbc/mssql/types.rb +52 -0
  107. data/lib/arjdbc/mssql/types/binary_types.rb +33 -0
  108. data/lib/arjdbc/mssql/types/date_and_time_types.rb +134 -0
  109. data/lib/arjdbc/mssql/types/deprecated_types.rb +40 -0
  110. data/lib/arjdbc/mssql/types/numeric_types.rb +71 -0
  111. data/lib/arjdbc/mssql/types/string_types.rb +56 -0
  112. data/lib/arjdbc/mssql/utils.rb +66 -0
  113. data/lib/arjdbc/mysql.rb +3 -0
  114. data/lib/arjdbc/mysql/adapter.rb +140 -0
  115. data/lib/arjdbc/mysql/connection_methods.rb +166 -0
  116. data/lib/arjdbc/oracle/adapter.rb +863 -0
  117. data/lib/arjdbc/postgresql.rb +3 -0
  118. data/lib/arjdbc/postgresql/adapter.rb +687 -0
  119. data/lib/arjdbc/postgresql/base/array_decoder.rb +26 -0
  120. data/lib/arjdbc/postgresql/base/array_encoder.rb +25 -0
  121. data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
  122. data/lib/arjdbc/postgresql/base/pgconn.rb +11 -0
  123. data/lib/arjdbc/postgresql/column.rb +51 -0
  124. data/lib/arjdbc/postgresql/connection_methods.rb +67 -0
  125. data/lib/arjdbc/postgresql/name.rb +24 -0
  126. data/lib/arjdbc/postgresql/oid_types.rb +266 -0
  127. data/lib/arjdbc/railtie.rb +11 -0
  128. data/lib/arjdbc/sqlite3.rb +3 -0
  129. data/lib/arjdbc/sqlite3/adapter.rb +678 -0
  130. data/lib/arjdbc/sqlite3/connection_methods.rb +59 -0
  131. data/lib/arjdbc/sybase.rb +2 -0
  132. data/lib/arjdbc/sybase/adapter.rb +47 -0
  133. data/lib/arjdbc/tasks.rb +13 -0
  134. data/lib/arjdbc/tasks/database_tasks.rb +31 -0
  135. data/lib/arjdbc/tasks/databases.rake +48 -0
  136. data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
  137. data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
  138. data/lib/arjdbc/tasks/h2_database_tasks.rb +31 -0
  139. data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
  140. data/lib/arjdbc/tasks/jdbc_database_tasks.rb +169 -0
  141. data/lib/arjdbc/tasks/mssql_database_tasks.rb +46 -0
  142. data/lib/arjdbc/util/quoted_cache.rb +60 -0
  143. data/lib/arjdbc/util/serialized_attributes.rb +98 -0
  144. data/lib/arjdbc/util/table_copier.rb +110 -0
  145. data/lib/arjdbc/version.rb +3 -0
  146. data/lib/generators/jdbc/USAGE +9 -0
  147. data/lib/generators/jdbc/jdbc_generator.rb +17 -0
  148. data/lib/jdbc_adapter.rb +2 -0
  149. data/lib/jdbc_adapter/rake_tasks.rb +4 -0
  150. data/lib/jdbc_adapter/version.rb +4 -0
  151. data/pom.xml +114 -0
  152. data/rails_generators/jdbc_generator.rb +15 -0
  153. data/rails_generators/templates/config/initializers/jdbc.rb +10 -0
  154. data/rails_generators/templates/lib/tasks/jdbc.rake +11 -0
  155. data/rakelib/01-tomcat.rake +51 -0
  156. data/rakelib/02-test.rake +132 -0
  157. data/rakelib/bundler_ext.rb +11 -0
  158. data/rakelib/db.rake +75 -0
  159. data/rakelib/rails.rake +223 -0
  160. data/src/java/arjdbc/ArJdbcModule.java +276 -0
  161. data/src/java/arjdbc/db2/DB2Module.java +76 -0
  162. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +126 -0
  163. data/src/java/arjdbc/derby/DerbyModule.java +178 -0
  164. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +152 -0
  165. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +174 -0
  166. data/src/java/arjdbc/h2/H2Module.java +50 -0
  167. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +85 -0
  168. data/src/java/arjdbc/hsqldb/HSQLDBModule.java +73 -0
  169. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +75 -0
  170. data/src/java/arjdbc/jdbc/AdapterJavaService.java +43 -0
  171. data/src/java/arjdbc/jdbc/Callable.java +44 -0
  172. data/src/java/arjdbc/jdbc/ConnectionFactory.java +45 -0
  173. data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +156 -0
  174. data/src/java/arjdbc/jdbc/DriverConnectionFactory.java +63 -0
  175. data/src/java/arjdbc/jdbc/DriverWrapper.java +119 -0
  176. data/src/java/arjdbc/jdbc/JdbcResult.java +130 -0
  177. data/src/java/arjdbc/jdbc/RubyConnectionFactory.java +61 -0
  178. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +3979 -0
  179. data/src/java/arjdbc/mssql/MSSQLModule.java +90 -0
  180. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +508 -0
  181. data/src/java/arjdbc/mysql/MySQLModule.java +152 -0
  182. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +294 -0
  183. data/src/java/arjdbc/oracle/OracleModule.java +80 -0
  184. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +455 -0
  185. data/src/java/arjdbc/postgresql/ByteaUtils.java +157 -0
  186. data/src/java/arjdbc/postgresql/PgDateTimeUtils.java +52 -0
  187. data/src/java/arjdbc/postgresql/PostgreSQLModule.java +77 -0
  188. data/src/java/arjdbc/postgresql/PostgreSQLResult.java +192 -0
  189. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +948 -0
  190. data/src/java/arjdbc/sqlite3/SQLite3Module.java +73 -0
  191. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +525 -0
  192. data/src/java/arjdbc/util/CallResultSet.java +826 -0
  193. data/src/java/arjdbc/util/DateTimeUtils.java +699 -0
  194. data/src/java/arjdbc/util/ObjectSupport.java +65 -0
  195. data/src/java/arjdbc/util/QuotingUtils.java +137 -0
  196. data/src/java/arjdbc/util/StringCache.java +63 -0
  197. data/src/java/arjdbc/util/StringHelper.java +145 -0
  198. metadata +269 -0
@@ -0,0 +1,169 @@
1
+ module ArJdbc
2
+ module Tasks
3
+ # Sharing task related code between AR 3.x and 4.x
4
+ #
5
+ # @note this class needs to conform to the API available since AR 4.0
6
+ # mostly to be usable with ActiveRecord::Tasks::DatabaseTasks module
7
+ class JdbcDatabaseTasks
8
+
9
+ attr_reader :configuration
10
+ alias_method :config, :configuration
11
+
12
+ def initialize(configuration)
13
+ @configuration = configuration
14
+ end
15
+
16
+ delegate :connection, :establish_connection, :to => ActiveRecord::Base
17
+
18
+ def create
19
+ begin
20
+ establish_connection(config)
21
+ ActiveRecord::Base.connection
22
+ if defined? ActiveRecord::Tasks::DatabaseAlreadyExists
23
+ raise ActiveRecord::Tasks::DatabaseAlreadyExists # AR-4.x
24
+ end # silence on AR < 4.0
25
+ rescue #=> error # database does not exists :
26
+ url = config['url']
27
+ url = $1 if url && url =~ /^(.*(?<!\/)\/)(?=\w)/
28
+
29
+ establish_connection(config.merge('database' => nil, 'url' => url))
30
+
31
+ unless connection.respond_to?(:create_database)
32
+ raise "AR-JDBC adapter '#{adapter_with_spec}' does not support create_database"
33
+ end
34
+ connection.create_database(resolve_database(config), config)
35
+
36
+ establish_connection(config)
37
+ end
38
+ end
39
+
40
+ def drop
41
+ establish_connection(config)
42
+ unless ActiveRecord::Base.connection.respond_to?(:drop_database)
43
+ raise "AR-JDBC adapter '#{adapter_with_spec}' does not support drop_database"
44
+ end
45
+ connection.drop_database resolve_database(config)
46
+ end
47
+
48
+ def purge
49
+ establish_connection(config) # :test
50
+ unless ActiveRecord::Base.connection.respond_to?(:recreate_database)
51
+ raise "AR-JDBC adapter '#{adapter_with_spec}' does not support recreate_database (purge)"
52
+ end
53
+ db_name = ActiveRecord::Base.connection.database_name
54
+ ActiveRecord::Base.connection.recreate_database(db_name, config)
55
+ end
56
+
57
+ def charset
58
+ establish_connection(config)
59
+ if connection.respond_to?(:charset)
60
+ puts connection.charset
61
+ elsif connection.respond_to?(:encoding)
62
+ puts connection.encoding
63
+ else
64
+ raise "AR-JDBC adapter '#{adapter_with_spec}' does not support charset/encoding"
65
+ end
66
+ end
67
+
68
+ def collation
69
+ establish_connection(config)
70
+ if connection.respond_to?(:collation)
71
+ puts connection.collation
72
+ else
73
+ raise "AR-JDBC adapter '#{adapter_with_spec}' does not support collation"
74
+ end
75
+ end
76
+
77
+ def structure_dump(filename)
78
+ establish_connection(config)
79
+ if connection.respond_to?(:structure_dump)
80
+ File.open(filename, "w:utf-8") { |f| f << connection.structure_dump }
81
+ else
82
+ raise "AR-JDBC adapter '#{adapter_with_spec}' does not support structure_dump"
83
+ end
84
+ end
85
+
86
+ def structure_load(filename)
87
+ establish_connection(config)
88
+ if connection.respond_to?(:structure_load)
89
+ connection.structure_load IO.read(filename)
90
+ else
91
+ #IO.read(filename).split(/;\n*/m).each do |ddl|
92
+ # connection.execute(ddl)
93
+ #end
94
+ raise "AR-JDBC adapter '#{adapter_with_spec}' does not support structure_load"
95
+ end
96
+ end
97
+
98
+ protected
99
+
100
+ def expand_path(path)
101
+ require 'pathname'
102
+ path = Pathname.new path
103
+ return path.to_s if path.absolute?
104
+ rails_root ? File.join(rails_root, path) : File.expand_path(path)
105
+ end
106
+
107
+ def resolve_database(config, file_paths = false)
108
+ config['database'] || resolve_database_from_url(config['url'] || '', file_paths)
109
+ end
110
+
111
+ def resolve_database_from_url(url, file_paths = false)
112
+ ( config = config_from_url(url, file_paths) ) ? config['database'] : nil
113
+ end
114
+
115
+ private
116
+
117
+ def config_from_url(url, file_paths = false)
118
+ match = url.match %r{
119
+ ^ jdbc:
120
+ ( [\w]+ ): # $1 protocol
121
+ (?: ([\w]+) : )? # $2 (sub-protocol)
122
+ (?://)?
123
+ (?: ([\w\-]*) (?: [/:] ([\w\-]*) )? @ (?://)? )? # user[:password]@ or user[/password]@ ($3 $4)
124
+ ( [\w\.\-]+ )? # $5 host (or database if there's nothing left)
125
+ (?: : (\d+) )? # $6 port if any
126
+ (?: :? (/?[\w\-\./~]+) [\?;]? )? ([^/]*?) $
127
+ # $7 database part (ends with '?' or ';') and $8 query string - properties
128
+ }x
129
+
130
+ return nil unless match
131
+
132
+ config = {}
133
+ config['_protocol'] = match[1]
134
+ config['_sub_protocol'] = match[2] if match[2]
135
+ config['username'] = match[3] if match[3]
136
+ config['password'] = match[4] if match[4]
137
+ host = match[5]; port = match[6]
138
+ database = match[7]
139
+ if database.nil? && port.nil?
140
+ config['database'] = database = host
141
+ else
142
+ config['host'] = host if host
143
+ config['port'] = port if port
144
+ config['database'] = database
145
+ end
146
+ if database && ! file_paths && database[0...1] == '/'
147
+ config['database'] = database[1..-1]
148
+ end
149
+ if query_string = match[8]
150
+ properties = query_string.split('&').inject({}) do |memo, pair|
151
+ pair = pair.split("="); memo[ pair[0] ] = pair[1]; memo
152
+ end
153
+ config['properties'] = properties
154
+ end
155
+ config
156
+ end
157
+
158
+ def adapter_with_spec
159
+ adapter, spec = config['adapter'], config['adapter_spec']
160
+ spec ? "#{adapter} (#{spec})" : adapter
161
+ end
162
+
163
+ def rails_root
164
+ defined?(Rails.root) ? Rails.root : ( RAILS_ROOT )
165
+ end
166
+
167
+ end
168
+ end
169
+ end
@@ -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,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
@@ -0,0 +1,98 @@
1
+ module ArJdbc
2
+ module Util
3
+ # Gets included into `ActiveRecord::Base` to support sending LOB values
4
+ # in a separate update SQL statement for DB adapters that need this.
5
+ module SerializedAttributes
6
+
7
+ # protected
8
+
9
+ def update_lob_columns
10
+ klass = self.class
11
+ return unless type = klass.lob_type # e.g. /blob/i
12
+ connection = klass.connection
13
+ if connection.respond_to?(:update_lob_values?)
14
+ return false unless connection.update_lob_values?
15
+ end
16
+ klass.columns.each do |column|
17
+ next if column.sql_type !~ type
18
+ next if ( value = dump_column_value(column) ).nil?
19
+ if connection.respond_to?(:update_lob_value?)
20
+ next unless connection.update_lob_value?(value, column)
21
+ end
22
+ connection.update_lob_value(self, column, value)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def dump_column_value(column)
29
+ SerializedAttributes.dump_column_value(self, column)
30
+ end
31
+
32
+ if defined? ActiveRecord::Type::Serialized # ArJdbc::AR42
33
+
34
+ def self.dump_column_value(record, column)
35
+ value = record[ column.name.to_s ]
36
+ column.cast_type.type_cast_for_database(value)
37
+ end
38
+
39
+ else
40
+
41
+ def self.dump_column_value(record, column)
42
+ value = record[ name = column.name.to_s ]
43
+ if record.class.respond_to?(:serialized_attributes)
44
+ if coder = record.class.serialized_attributes[name]
45
+ value = coder.respond_to?(:dump) ? coder.dump(value) : value.to_yaml
46
+ end
47
+ else
48
+ if record.respond_to?(:unserializable_attribute?)
49
+ value = value.to_yaml if record.unserializable_attribute?(name, column)
50
+ else
51
+ value = value.to_yaml if value.is_a?(Hash)
52
+ end
53
+ end
54
+ value
55
+ end
56
+
57
+ end
58
+
59
+ def self.setup(lob_type = nil, after_save_alias = nil)
60
+ ActiveRecord::Base.send :include, self # include SerializedAttributes
61
+ ActiveRecord::Base.lob_type = lob_type unless lob_type.nil?
62
+ if after_save_alias
63
+ ActiveRecord::Base.class_eval do
64
+ alias_method after_save_alias, 'update_lob_columns'
65
+ end
66
+ ActiveRecord::Base.after_save after_save_alias
67
+ else
68
+ ActiveRecord::Base.after_save 'update_lob_columns'
69
+ end
70
+ end
71
+
72
+ def self.included(base)
73
+ base.extend ClassMethods
74
+ end
75
+
76
+ module ClassMethods
77
+
78
+ def lob_type
79
+ @lob_type ||= begin
80
+ if superclass.respond_to?(:lob_type)
81
+ superclass.lob_type
82
+ else
83
+ /blob|clob/i
84
+ end
85
+ end
86
+ end
87
+
88
+ def lob_type=(type)
89
+ @lob_type = type
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+ end
96
+ # @private only due backwards compatibility
97
+ SerializedAttributesHelper = Util::SerializedAttributes
98
+ end
@@ -0,0 +1,110 @@
1
+ module ArJdbc
2
+ module Util
3
+ module TableCopier
4
+
5
+ # taken from SQLite adapter, code loosely based on http://git.io/P7tFQA
6
+
7
+ # Performs changes for table by first copying (and preserving contents)
8
+ # into another (temporary) table, than alters and copies all data back.
9
+ def alter_table(table_name, options = {})
10
+ table_name = table_name.to_s.downcase
11
+ altered_table_name = "a#{table_name}"
12
+ caller = lambda { |definition| yield definition if block_given? }
13
+
14
+ transaction do
15
+ # A temporary table might improve performance here, but
16
+ # it doesn't seem to maintain indices across the whole move.
17
+ move_table(table_name, altered_table_name, options)
18
+ move_table(altered_table_name, table_name, &caller)
19
+ end
20
+ end
21
+
22
+ # Move a table into another while preserving all content.
23
+ # @see #copy_table
24
+ def move_table(from, to, options = {}, &block)
25
+ copy_table(from, to, options, &block)
26
+ drop_table(from)
27
+ end
28
+
29
+ # @see #copy_table_contents
30
+ # @see #copy_table_indexes
31
+ def copy_table(from, to, options = {})
32
+ from_primary_key = primary_key(from)
33
+ create_table(to, options.merge(:id => false)) do |definition|
34
+ @definition = definition
35
+ @definition.primary_key(from_primary_key) if from_primary_key.present?
36
+ columns(from).each do |column|
37
+ column_name = options[:rename] ?
38
+ (options[:rename][column.name] ||
39
+ options[:rename][column.name.to_sym] ||
40
+ column.name) : column.name
41
+
42
+ next if column_name == from_primary_key
43
+
44
+ @definition.column(column_name, column.type,
45
+ :limit => column.limit, :default => column.default,
46
+ :precision => column.precision, :scale => column.scale,
47
+ :null => column.null)
48
+ end
49
+ yield @definition if block_given?
50
+ end
51
+
52
+ copy_table_indexes(from, to, options[:rename] || {})
53
+ copy_table_contents(from, to,
54
+ @definition.columns.map {|column| column.name},
55
+ options[:rename] || {})
56
+ end
57
+
58
+ # Copies indexes for a given table.
59
+ def copy_table_indexes(from, to, rename = {})
60
+ indexes(from).each do |index|
61
+ name = index.name.downcase
62
+ if to == "a#{from}"
63
+ name = "t#{name}"
64
+ elsif from == "a#{to}"
65
+ name = name[1..-1]
66
+ end
67
+
68
+ to_column_names = columns(to).map(&:name)
69
+ columns = index.columns.map { |column| rename[column] || column }
70
+ columns = columns.select { |column| to_column_names.include?(column) }
71
+
72
+ unless columns.empty?
73
+ # index name can't be the same
74
+ opts = { :name => name.gsub(/(^|_)(#{from})_/, "\\1#{to}_"), :internal => true }
75
+ opts[:unique] = true if index.unique
76
+ add_index(to, columns, opts)
77
+ end
78
+ end
79
+ end
80
+
81
+ # Copies the content of a table into another.
82
+ def copy_table_contents(from, to, columns, rename = {})
83
+ column_mappings = Hash[ columns.map { |name| [name, name] } ]
84
+ rename.each { |a| column_mappings[a.last] = a.first }
85
+ from_columns = columns(from).collect {|col| col.name}
86
+ columns = columns.find_all{ |col| from_columns.include?(column_mappings[col]) }
87
+ quoted_columns = columns.map { |col| quote_column_name(col) } * ','
88
+
89
+ quoted_to = quote_table_name(to)
90
+
91
+ raw_column_mappings = Hash[ columns(from).map { |c| [c.name, c] } ]
92
+
93
+ execute("SELECT * FROM #{quote_table_name(from)}", 'Copy Table').each do |row|
94
+ sql = "INSERT INTO #{quoted_to} (#{quoted_columns}) VALUES ("
95
+
96
+ column_values = columns.map do |col|
97
+ quote(row[column_mappings[col]], raw_column_mappings[col])
98
+ end
99
+
100
+ sql << column_values * ', '
101
+ sql << ')'
102
+ exec_insert sql, 'Copy Table', []
103
+ end
104
+ end
105
+
106
+ end
107
+ end
108
+ # @private @deprecated backwards compatibility
109
+ MissingFunctionalityHelper = Util::TableCopier
110
+ end