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,23 @@
1
+ ArJdbc::ConnectionMethods.module_eval do
2
+ def firebird_connection(config)
3
+ config[:adapter_spec] ||= ::ArJdbc::Firebird
4
+
5
+ return jndi_connection(config) if jndi_config?(config)
6
+
7
+ begin
8
+ require 'jdbc/firebird'
9
+ ::Jdbc::Firebird.load_driver(:require)
10
+ rescue LoadError # assuming driver.jar is on the class-path
11
+ end
12
+
13
+ config[:host] ||= 'localhost'
14
+ config[:port] ||= 3050
15
+ config[:url] ||= begin
16
+ "jdbc:firebirdsql://#{config[:host]}:#{config[:port]}/#{config[:database]}"
17
+ end
18
+ config[:driver] ||= ::Jdbc::Firebird.driver_name
19
+
20
+ jdbc_connection(config)
21
+ end
22
+ # alias_method :jdbcfirebird_connection, :firebird_connection
23
+ end
data/lib/arjdbc/h2.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'arjdbc'
2
+ require 'arjdbc/h2/adapter'
3
+ require 'arjdbc/h2/connection_methods'
@@ -0,0 +1,303 @@
1
+ ArJdbc.load_java_part :H2
2
+ require 'arjdbc/hsqldb/adapter'
3
+ require 'arel/visitors/h2'
4
+
5
+ module ArJdbc
6
+ module H2
7
+ include HSQLDB
8
+
9
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
10
+ def self.jdbc_connection_class
11
+ ::ActiveRecord::ConnectionAdapters::H2JdbcConnection
12
+ end
13
+
14
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
15
+ def self.column_selector
16
+ [ /\.h2\./i, lambda { |config, column| column.extend(Column) } ]
17
+ end
18
+
19
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn
20
+ module Column
21
+
22
+ private
23
+
24
+ def extract_limit(sql_type)
25
+ limit = super
26
+ case @sql_type = sql_type.downcase
27
+ # NOTE: JDBC driver f*cks sql_type up with limits (just like HSQLDB) :
28
+ when /^tinyint/i then @sql_type = 'tinyint'; limit = 1
29
+ when /^smallint|int2/i then @sql_type = 'smallint'; limit = 2
30
+ when /^bigint|int8/i then @sql_type = 'bigint'; limit = 8
31
+ when /^int|int4/i then @sql_type = 'int'; limit = 4
32
+ when /^double/i then @sql_type = 'double'; limit = 8
33
+ when /^real/i then @sql_type = 'real'; limit = 4
34
+ when /^date/i then @sql_type = 'date'; limit = nil
35
+ when /^timestamp/i then @sql_type = 'timestamp'; limit = nil
36
+ when /^time/i then @sql_type = 'time'; limit = nil
37
+ when /^boolean/i then @sql_type = 'boolean'; limit = nil
38
+ when /^binary|bytea/i; then @sql_type = 'binary'; limit = 2 * 1024 * 1024
39
+ when /blob|image|oid/i then @sql_type = 'blob'; limit = nil
40
+ when /clob|text/i then @sql_type = 'clob'; limit = nil
41
+ # NOTE: use lower-case due SchemaDumper not handling it's decimal/integer
42
+ # optimization case-insensitively due : column.type == :integer &&
43
+ # [/^numeric/, /^decimal/].any? { |e| e.match(column.sql_type) }
44
+ when /^decimal\(65535,32767\)/i
45
+ @sql_type = 'decimal'; nil
46
+ end
47
+ limit
48
+ end
49
+
50
+ def simplified_type(field_type)
51
+ case field_type
52
+ when /^bit|bool/i then :boolean
53
+ when /^signed|year/i then :integer
54
+ when /^real|double/i then :float
55
+ when /^varchar/i then :string
56
+ when /^longvarchar/i then :text
57
+ when /^binary|raw|bytea/i then :binary
58
+ when /varbinary/i then :binary # longvarbinary, varbinary
59
+ when /^blob|image|oid/i then :binary
60
+ else
61
+ super
62
+ end
63
+ end
64
+
65
+ # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
66
+ def default_value(value)
67
+ # H2 auto-generated key default value
68
+ return nil if value =~ /^\(NEXT VALUE FOR/i
69
+ # JDBC returns column default strings with actual single quotes around the value.
70
+ return $1 if value =~ /^'(.*)'$/
71
+ value
72
+ end
73
+
74
+ end
75
+
76
+ ADAPTER_NAME = 'H2'.freeze
77
+
78
+ # @override
79
+ def adapter_name
80
+ ADAPTER_NAME
81
+ end
82
+
83
+ # @deprecated no longer used. only here for backwards compatibility with 1.2
84
+ def h2_adapter
85
+ true
86
+ end
87
+
88
+ NATIVE_DATABASE_TYPES = {
89
+ # "integer GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY"
90
+ :primary_key => "bigint identity",
91
+ :boolean => { :name => "boolean" },
92
+ :tinyint => { :name => "tinyint", :limit => 1 },
93
+ :smallint => { :name => "smallint", :limit => 2 },
94
+ :bigint => { :name => "bigint", :limit => 8 },
95
+ :integer => { :name => "int", :limit => 4 },
96
+ :decimal => { :name => "decimal" }, # :limit => 2147483647
97
+ :numeric => { :name => "numeric" }, # :limit => 2147483647
98
+ :float => { :name => "float", :limit => 8 },
99
+ :double => { :name => "double", :limit => 8 },
100
+ :real => { :name => "real", :limit => 4 }, # :limit => 8
101
+ :date => { :name => "date" },
102
+ :time => { :name => "time" },
103
+ :timestamp => { :name => "timestamp" },
104
+ :datetime => { :name => "timestamp" },
105
+ :binary => { :name => "binary" },
106
+ :string => { :name => "varchar", :limit => 255 },
107
+ :char => { :name => "char" }, # :limit => 2147483647
108
+ :blob => { :name => "blob" },
109
+ :text => { :name => "clob" },
110
+ :clob => { :name => "clob" },
111
+ :uuid => { :name => "uuid" }, # :limit => 2147483647
112
+ :other => { :name => "other" }, # java.lang.Object
113
+ :array => { :name => "array" }, # java.lang.Object[]
114
+ # NOTE: would be great if AR allowed as to refactor as :
115
+ # t.column :string, :ignorecase => true
116
+ :varchar_casesensitive => { :name => 'varchar_casesensitive' },
117
+ :varchar_ignorecase => { :name => 'varchar_ignorecase' },
118
+ # :identity : { :name=>"identity", :limit => 19 }
119
+ # :result_set : { :name=>"result_set" }
120
+ }
121
+
122
+ # @override
123
+ def native_database_types
124
+ NATIVE_DATABASE_TYPES
125
+ end
126
+
127
+ # @override
128
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
129
+ case type.to_sym
130
+ when :integer
131
+ case limit
132
+ when 1; 'tinyint'
133
+ when 2; 'smallint'
134
+ when nil, 3, 4; 'int'
135
+ when 5..8; 'bigint'
136
+ else raise(ActiveRecordError, "No integer type has byte size #{limit}")
137
+ end
138
+ when :float
139
+ case limit
140
+ when 1..4; 'real'
141
+ when 5..8; 'double'
142
+ else raise(ActiveRecordError, "No float type has byte size #{limit}")
143
+ end
144
+ when :binary
145
+ if limit && limit < 2 * 1024 * 1024
146
+ 'binary'
147
+ else
148
+ 'blob'
149
+ end
150
+ else
151
+ super
152
+ end
153
+ end
154
+
155
+ # @override
156
+ def empty_insert_statement_value
157
+ "VALUES ()"
158
+ end
159
+
160
+ # @override
161
+ def tables
162
+ @connection.tables(nil, h2_schema)
163
+ end
164
+
165
+ # @override
166
+ def columns(table_name, name = nil)
167
+ @connection.columns_internal(table_name.to_s, nil, h2_schema)
168
+ end
169
+
170
+ # @override
171
+ def change_column(table_name, column_name, type, options = {})
172
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
173
+ change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
174
+ change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
175
+ end
176
+
177
+ def current_schema
178
+ execute('CALL SCHEMA()')[0].values[0]
179
+ end
180
+
181
+ # @override
182
+ def quote(value, column = nil)
183
+ case value
184
+ when String
185
+ if value.empty?
186
+ "''"
187
+ else
188
+ super
189
+ end
190
+ else
191
+ super
192
+ end
193
+ end
194
+
195
+ # @override
196
+ def supports_views?; true end
197
+
198
+ # EXPLAIN support :
199
+
200
+ # @override
201
+ def supports_explain?; true end
202
+
203
+ # @override
204
+ def explain(arel, binds = [])
205
+ sql = "EXPLAIN #{to_sql(arel, binds)}"
206
+ raw_result = exec_query_raw(sql, "EXPLAIN", binds)
207
+ raw_result[0].values.join("\n") # [ "SELECT \n ..." ].to_s
208
+ end
209
+
210
+ # @override
211
+ def structure_dump
212
+ execute('SCRIPT SIMPLE').map do |result|
213
+ # [ { 'script' => SQL }, { 'script' ... }, ... ]
214
+ case sql = result.first[1] # ['script']
215
+ when /CREATE USER IF NOT EXISTS SA/i then nil
216
+ else sql
217
+ end
218
+ end.compact.join("\n\n")
219
+ end
220
+
221
+ # @see #structure_dump
222
+ def structure_load(dump)
223
+ dump.each_line("\n\n") { |ddl| execute(ddl) }
224
+ end
225
+
226
+ def shutdown
227
+ execute 'SHUTDOWN COMPACT'
228
+ end
229
+
230
+ # @private
231
+ def recreate_database(name = nil, options = {})
232
+ drop_database(name)
233
+ create_database(name, options)
234
+ end
235
+
236
+ # @private
237
+ def create_database(name = nil, options = {}); end
238
+
239
+ # @private
240
+ def drop_database(name = nil)
241
+ execute('DROP ALL OBJECTS')
242
+ end
243
+
244
+ # @private
245
+ def database_path(base_only = false)
246
+ db_path = jdbc_connection(true).getSession.getDataHandler.getDatabasePath
247
+ return db_path if base_only
248
+ if File.exist?(mv_path = "#{db_path}.mv.db")
249
+ return mv_path
250
+ else
251
+ "#{db_path}.h2.db"
252
+ end
253
+ end
254
+
255
+ # @override
256
+ def jdbc_connection(unwrap = nil)
257
+ java_connection = raw_connection.connection
258
+ return java_connection unless unwrap
259
+ if java_connection.java_class.name == 'org.h2.jdbc.JdbcConnection'
260
+ return java_connection
261
+ end
262
+ connection_class = java.sql.Connection.java_class
263
+ if java_connection.wrapper_for?(connection_class)
264
+ java_connection.unwrap(connection_class) # java.sql.Wrapper.unwrap
265
+ elsif java_connection.respond_to?(:connection)
266
+ # e.g. org.apache.tomcat.jdbc.pool.PooledConnection
267
+ java_connection.connection # getConnection
268
+ else
269
+ java_connection
270
+ end
271
+ end
272
+
273
+ private
274
+
275
+ def change_column_null(table_name, column_name, null, default = nil)
276
+ if !null && !default.nil?
277
+ execute("UPDATE #{table_name} SET #{column_name}=#{quote(default)} WHERE #{column_name} IS NULL")
278
+ end
279
+ if null
280
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET NULL"
281
+ else
282
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET NOT NULL"
283
+ end
284
+ end
285
+
286
+ def h2_schema
287
+ @config[:schema] || ''
288
+ end
289
+
290
+ end
291
+ end
292
+
293
+ module ActiveRecord::ConnectionAdapters
294
+
295
+ class H2Adapter < JdbcAdapter
296
+ include ArJdbc::H2
297
+
298
+ def arel_visitor
299
+ Arel::Visitors::H2.new(self)
300
+ end
301
+ end
302
+
303
+ end
@@ -0,0 +1,27 @@
1
+ ArJdbc::ConnectionMethods.module_eval do
2
+ def h2_connection(config)
3
+ config[:adapter_spec] ||= ::ArJdbc::H2
4
+ config[:adapter_class] = ActiveRecord::ConnectionAdapters::H2Adapter unless config.key?(:adapter_class)
5
+
6
+ return jndi_connection(config) if jndi_config?(config)
7
+
8
+ begin
9
+ require 'jdbc/h2'
10
+ ::Jdbc::H2.load_driver(:require) if defined?(::Jdbc::H2.load_driver)
11
+ rescue LoadError # assuming driver.jar is on the class-path
12
+ end
13
+
14
+ config[:url] ||= begin
15
+ db = config[:database]
16
+ if db[0, 4] == 'mem:' || db[0, 5] == 'file:' || db[0, 5] == 'hsql:'
17
+ "jdbc:h2:#{db}"
18
+ else
19
+ "jdbc:h2:file:#{File.expand_path(db)}"
20
+ end
21
+ end
22
+ config[:driver] ||= defined?(::Jdbc::H2.driver_name) ? ::Jdbc::H2.driver_name : 'org.h2.Driver'
23
+
24
+ embedded_driver(config)
25
+ end
26
+ alias_method :jdbch2_connection, :h2_connection
27
+ end
@@ -0,0 +1,3 @@
1
+ require 'arjdbc'
2
+ require 'arjdbc/hsqldb/adapter'
3
+ require 'arjdbc/hsqldb/connection_methods'
@@ -0,0 +1,297 @@
1
+ ArJdbc.load_java_part :HSQLDB
2
+ require 'arjdbc/hsqldb/explain_support'
3
+ require 'arjdbc/hsqldb/schema_creation' # AR 4.x
4
+ require 'arel/visitors/hsqldb'
5
+
6
+ module ArJdbc
7
+ module HSQLDB
8
+ include ExplainSupport
9
+
10
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
11
+ def self.column_selector
12
+ [ /hsqldb/i, lambda { |config, column| column.extend(Column) } ]
13
+ end
14
+
15
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn
16
+ module Column
17
+
18
+ private
19
+
20
+ def extract_limit(sql_type)
21
+ limit = super
22
+ case @sql_type = sql_type.downcase
23
+ when /^tinyint/i then @sql_type = 'tinyint'; limit = 1
24
+ when /^smallint/i then @sql_type = 'smallint'; limit = 2
25
+ when /^bigint/i then @sql_type = 'bigint'; limit = 8
26
+ when /^double/i then @sql_type = 'double'; limit = 8
27
+ when /^real/i then @sql_type = 'real'; limit = 8
28
+ # NOTE: once again we get incorrect "limits" from HypesSQL's JDBC
29
+ # thus yet again we need to fix incorrectly detected limits :
30
+ when /^integer/i then @sql_type = 'integer'; limit = 4
31
+ when /^float/i then @sql_type = 'float'; limit = 8
32
+ when /^decimal/i then @sql_type = 'decimal';
33
+ when /^datetime/i then @sql_type = 'datetime'; limit = nil
34
+ when /^timestamp/i then @sql_type = 'timestamp'; limit = nil
35
+ when /^time/i then @sql_type = 'time'; limit = nil
36
+ when /^date/i then @sql_type = 'date'; limit = nil
37
+ else
38
+ # HSQLDB appears to return "LONGVARCHAR(0)" for :text columns,
39
+ # which for AR purposes should be interpreted as "no limit" :
40
+ limit = nil if sql_type =~ /\(0\)$/
41
+ end
42
+ limit
43
+ end
44
+
45
+ def simplified_type(field_type)
46
+ case field_type
47
+ when /^nvarchar/i then :string
48
+ when /^character/i then :string
49
+ when /^longvarchar/i then :text
50
+ when /int/i then :integer # TINYINT, SMALLINT, BIGINT, INT
51
+ when /real|double/i then :float
52
+ when /^bit/i then :boolean
53
+ when /binary/i then :binary # VARBINARY, LONGVARBINARY
54
+ else
55
+ super
56
+ end
57
+ end
58
+
59
+ # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
60
+ def default_value(value)
61
+ # JDBC returns column default strings with actual single quotes around the value.
62
+ return $1 if value =~ /^'(.*)'$/
63
+ value
64
+ end
65
+
66
+ end
67
+
68
+ ADAPTER_NAME = 'HSQLDB'.freeze
69
+
70
+ def adapter_name
71
+ ADAPTER_NAME
72
+ end
73
+
74
+ NATIVE_DATABASE_TYPES = {
75
+ :primary_key => "integer GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY",
76
+ :string => { :name => "varchar", :limit => 255 }, # :limit => 2147483647
77
+ :text => { :name => "clob" },
78
+ :binary => { :name => "blob" },
79
+ :boolean => { :name => "boolean" }, # :name => "tinyint", :limit => 1
80
+ :bit => { :name=>"bit" }, # stored as 0/1 on HSQLDB 2.2 (translates true/false)
81
+ :integer => { :name => "integer", :limit => 4 },
82
+ :decimal => { :name => "decimal" }, # :limit => 2147483647
83
+ :numeric => { :name => "numeric" }, # :limit => 2147483647
84
+ # NOTE: fix incorrectly detected limits :
85
+ :tinyint => { :name => "tinyint", :limit => 1 },
86
+ :smallint => { :name => "smallint", :limit => 2 },
87
+ :bigint => { :name => "bigint", :limit => 8 },
88
+ :float => { :name => "float" },
89
+ :double => { :name => "double", :limit => 8 },
90
+ :real => { :name => "real", :limit => 8 },
91
+ :date => { :name=>"date" },
92
+ :time => { :name=>"time" },
93
+ :timestamp => { :name=>"timestamp" },
94
+ :datetime => { :name=>"timestamp" },
95
+ :other => { :name=>"other" },
96
+ # NOTE: would be great if AR allowed as to refactor as :
97
+ # t.column :string, :ignorecase => true
98
+ :character => { :name => "character" },
99
+ :varchar_ignorecase => { :name => "varchar_ignorecase" },
100
+ }
101
+
102
+ # @override
103
+ def native_database_types
104
+ NATIVE_DATABASE_TYPES
105
+ end
106
+
107
+ # @override
108
+ def quote(value, column = nil)
109
+ return value.quoted_id if value.respond_to?(:quoted_id)
110
+ return value if sql_literal?(value)
111
+
112
+ case value
113
+ when String
114
+ column_type = column && column.type
115
+ if column_type == :binary
116
+ "X'#{value.unpack("H*")[0]}'"
117
+ elsif column_type == :integer ||
118
+ column.respond_to?(:primary) && column.primary && column.klass != String
119
+ value.to_i.to_s
120
+ else
121
+ "'#{quote_string(value)}'"
122
+ end
123
+ when Time
124
+ column_type = column && column.type
125
+ if column_type == :time
126
+ "'#{value.strftime("%H:%M:%S")}'"
127
+ #elsif column_type == :timestamp # || column_type == :datetime
128
+ #value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
129
+ #"'#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{sprintf("%06d", value.usec)}'"
130
+ else
131
+ super
132
+ end
133
+ else
134
+ super
135
+ end
136
+ end
137
+
138
+ # Quote date/time values for use in SQL input.
139
+ # Includes microseconds if the value is a Time responding to usec.
140
+ # @override
141
+ def quoted_date(value)
142
+ if value.acts_like?(:time) && value.respond_to?(:usec)
143
+ usec = sprintf("%06d", value.usec)
144
+ value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
145
+ "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}"
146
+ else
147
+ super
148
+ end
149
+ end if ::ActiveRecord::VERSION::MAJOR >= 3
150
+
151
+ # @override
152
+ def quote_column_name(name)
153
+ name = name.to_s
154
+ if name =~ /[-]/
155
+ %Q{"#{name.upcase}"}
156
+ else
157
+ name
158
+ end
159
+ end
160
+
161
+ # @override
162
+ def add_column(table_name, column_name, type, options = {})
163
+ add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
164
+ add_column_options!(add_column_sql, options)
165
+ execute(add_column_sql)
166
+ end unless const_defined? :SchemaCreation
167
+
168
+ # @override
169
+ def change_column(table_name, column_name, type, options = {})
170
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
171
+ end
172
+
173
+ def change_column_default(table_name, column_name, default) #:nodoc:
174
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT #{quote(default)}"
175
+ end
176
+
177
+ # @override
178
+ def rename_column(table_name, column_name, new_column_name) #:nodoc:
179
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} RENAME TO #{new_column_name}"
180
+ end
181
+
182
+ # @override
183
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
184
+ return super if defined?(::Jdbc::H2) || type.to_s != 'integer' || limit == nil
185
+ type
186
+ end
187
+
188
+ # @override
189
+ def rename_table(name, new_name)
190
+ execute "ALTER TABLE #{name} RENAME TO #{new_name}"
191
+ end
192
+
193
+ # @note AR API since 4.2
194
+ def truncate(table_name, name = nil)
195
+ execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
196
+ end
197
+
198
+ def last_insert_id
199
+ identity = select_value("CALL IDENTITY()")
200
+ Integer(identity.nil? ? 0 : identity)
201
+ end
202
+
203
+ # @private
204
+ def _execute(sql, name = nil)
205
+ result = super
206
+ self.class.insert?(sql) ? last_insert_id : result
207
+ end
208
+ private :_execute
209
+
210
+ # @note Only used with (non-AREL) ActiveRecord **2.3**.
211
+ # @see Arel::Visitors::HSQLDB#limit_offset
212
+ def add_limit_offset!(sql, options)
213
+ if sql =~ /^select/i
214
+ offset = options[:offset] || 0
215
+ if limit = options[:limit]
216
+ sql.replace "SELECT LIMIT #{offset} #{limit} #{sql[7..-1]}"
217
+ elsif offset > 0
218
+ sql.replace "SELECT LIMIT #{offset} 0 #{sql[7..-1]}"
219
+ end
220
+ end
221
+ end if ::ActiveRecord::VERSION::MAJOR < 3
222
+
223
+ # @override
224
+ def empty_insert_statement_value
225
+ # on HSQLDB only work with tables that have a default value for each
226
+ # and every column ... you'll need to avoid `Model.create!` on 4.0
227
+ 'DEFAULT VALUES'
228
+ end
229
+
230
+ # We filter out HSQLDB's system tables (named "SYSTEM.*").
231
+ # @override
232
+ def tables
233
+ @connection.tables.select { |row| row.to_s !~ /^system_/i }
234
+ end
235
+
236
+ # @override
237
+ def remove_index(table_name, options = {})
238
+ execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}"
239
+ end
240
+
241
+ # @override
242
+ def supports_views?; true end
243
+
244
+ # @override
245
+ def supports_foreign_keys?; true end
246
+
247
+ # @override
248
+ def structure_dump
249
+ execute('SCRIPT').map do |result|
250
+ # [ { 'command' => SQL }, { 'command' ... }, ... ]
251
+ case sql = result.first[1] # ['command']
252
+ when /CREATE USER SA PASSWORD DIGEST .*?/i then nil
253
+ when /CREATE SCHEMA PUBLIC AUTHORIZATION DBA/i then nil
254
+ when /GRANT DBA TO SA/i then nil
255
+ else sql
256
+ end
257
+ end.compact.join("\n\n")
258
+ end
259
+
260
+ # @see #structure_dump
261
+ def structure_load(dump)
262
+ dump.each_line("\n\n") { |ddl| execute(ddl) }
263
+ end
264
+
265
+ def shutdown
266
+ execute 'SHUTDOWN'
267
+ end
268
+
269
+ # @private
270
+ def recreate_database(name = nil, options = {})
271
+ drop_database(name)
272
+ create_database(name, options)
273
+ end
274
+
275
+ # @private
276
+ def create_database(name = nil, options = {}); end
277
+
278
+ # @private
279
+ def drop_database(name = nil)
280
+ execute('DROP SCHEMA PUBLIC CASCADE')
281
+ end
282
+
283
+ end
284
+ end
285
+
286
+ module ActiveRecord::ConnectionAdapters
287
+
288
+ class HsqldbAdapter < JdbcAdapter
289
+ include ArJdbc::HSQLDB
290
+
291
+ def arel_visitor # :nodoc:
292
+ Arel::Visitors::HSQLDB
293
+ end
294
+ end
295
+
296
+ end
297
+