activerecord-jdbc-adapter-ficoh 1.3.21-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 (191) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/.travis.yml +462 -0
  4. data/.yardopts +4 -0
  5. data/Appraisals +36 -0
  6. data/CONTRIBUTING.md +49 -0
  7. data/Gemfile +68 -0
  8. data/History.md +1191 -0
  9. data/LICENSE.txt +25 -0
  10. data/README.md +277 -0
  11. data/RUNNING_TESTS.md +88 -0
  12. data/Rakefile +298 -0
  13. data/Rakefile.jdbc +20 -0
  14. data/activerecord-jdbc-adapter.gemspec +63 -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/oracle_adapter.rb +1 -0
  29. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
  30. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
  31. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
  32. data/lib/activerecord-jdbc-adapter.rb +1 -0
  33. data/lib/arel/visitors/compat.rb +64 -0
  34. data/lib/arel/visitors/db2.rb +137 -0
  35. data/lib/arel/visitors/derby.rb +112 -0
  36. data/lib/arel/visitors/firebird.rb +79 -0
  37. data/lib/arel/visitors/h2.rb +25 -0
  38. data/lib/arel/visitors/hsqldb.rb +32 -0
  39. data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
  40. data/lib/arel/visitors/sql_server.rb +225 -0
  41. data/lib/arel/visitors/sql_server/ng42.rb +293 -0
  42. data/lib/arjdbc.rb +22 -0
  43. data/lib/arjdbc/db2.rb +4 -0
  44. data/lib/arjdbc/db2/adapter.rb +802 -0
  45. data/lib/arjdbc/db2/as400.rb +137 -0
  46. data/lib/arjdbc/db2/column.rb +177 -0
  47. data/lib/arjdbc/db2/connection_methods.rb +45 -0
  48. data/lib/arjdbc/derby.rb +3 -0
  49. data/lib/arjdbc/derby/active_record_patch.rb +13 -0
  50. data/lib/arjdbc/derby/adapter.rb +567 -0
  51. data/lib/arjdbc/derby/connection_methods.rb +16 -0
  52. data/lib/arjdbc/derby/schema_creation.rb +15 -0
  53. data/lib/arjdbc/discover.rb +104 -0
  54. data/lib/arjdbc/firebird.rb +4 -0
  55. data/lib/arjdbc/firebird/adapter.rb +468 -0
  56. data/lib/arjdbc/firebird/connection_methods.rb +20 -0
  57. data/lib/arjdbc/h2.rb +3 -0
  58. data/lib/arjdbc/h2/adapter.rb +335 -0
  59. data/lib/arjdbc/h2/connection_methods.rb +22 -0
  60. data/lib/arjdbc/hsqldb.rb +3 -0
  61. data/lib/arjdbc/hsqldb/adapter.rb +304 -0
  62. data/lib/arjdbc/hsqldb/connection_methods.rb +23 -0
  63. data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
  64. data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
  65. data/lib/arjdbc/informix.rb +5 -0
  66. data/lib/arjdbc/informix/adapter.rb +160 -0
  67. data/lib/arjdbc/informix/connection_methods.rb +9 -0
  68. data/lib/arjdbc/jdbc.rb +62 -0
  69. data/lib/arjdbc/jdbc/adapter.rb +997 -0
  70. data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
  71. data/lib/arjdbc/jdbc/arel_support.rb +149 -0
  72. data/lib/arjdbc/jdbc/base_ext.rb +34 -0
  73. data/lib/arjdbc/jdbc/callbacks.rb +52 -0
  74. data/lib/arjdbc/jdbc/column.rb +83 -0
  75. data/lib/arjdbc/jdbc/connection.rb +26 -0
  76. data/lib/arjdbc/jdbc/connection_methods.rb +59 -0
  77. data/lib/arjdbc/jdbc/driver.rb +44 -0
  78. data/lib/arjdbc/jdbc/error.rb +75 -0
  79. data/lib/arjdbc/jdbc/extension.rb +69 -0
  80. data/lib/arjdbc/jdbc/java.rb +13 -0
  81. data/lib/arjdbc/jdbc/type_cast.rb +154 -0
  82. data/lib/arjdbc/jdbc/type_converter.rb +142 -0
  83. data/lib/arjdbc/mssql.rb +7 -0
  84. data/lib/arjdbc/mssql/adapter.rb +822 -0
  85. data/lib/arjdbc/mssql/column.rb +207 -0
  86. data/lib/arjdbc/mssql/connection_methods.rb +72 -0
  87. data/lib/arjdbc/mssql/explain_support.rb +99 -0
  88. data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
  89. data/lib/arjdbc/mssql/lock_methods.rb +77 -0
  90. data/lib/arjdbc/mssql/types.rb +343 -0
  91. data/lib/arjdbc/mssql/utils.rb +82 -0
  92. data/lib/arjdbc/mysql.rb +3 -0
  93. data/lib/arjdbc/mysql/adapter.rb +998 -0
  94. data/lib/arjdbc/mysql/bulk_change_table.rb +150 -0
  95. data/lib/arjdbc/mysql/column.rb +167 -0
  96. data/lib/arjdbc/mysql/connection_methods.rb +137 -0
  97. data/lib/arjdbc/mysql/explain_support.rb +82 -0
  98. data/lib/arjdbc/mysql/schema_creation.rb +58 -0
  99. data/lib/arjdbc/oracle.rb +4 -0
  100. data/lib/arjdbc/oracle/adapter.rb +968 -0
  101. data/lib/arjdbc/oracle/column.rb +136 -0
  102. data/lib/arjdbc/oracle/connection_methods.rb +21 -0
  103. data/lib/arjdbc/postgresql.rb +3 -0
  104. data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +21 -0
  105. data/lib/arjdbc/postgresql/adapter.rb +1498 -0
  106. data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
  107. data/lib/arjdbc/postgresql/base/oid.rb +412 -0
  108. data/lib/arjdbc/postgresql/base/pgconn.rb +8 -0
  109. data/lib/arjdbc/postgresql/base/schema_definitions.rb +132 -0
  110. data/lib/arjdbc/postgresql/column.rb +640 -0
  111. data/lib/arjdbc/postgresql/connection_methods.rb +44 -0
  112. data/lib/arjdbc/postgresql/explain_support.rb +53 -0
  113. data/lib/arjdbc/postgresql/oid/bytea.rb +3 -0
  114. data/lib/arjdbc/postgresql/oid_types.rb +265 -0
  115. data/lib/arjdbc/postgresql/schema_creation.rb +60 -0
  116. data/lib/arjdbc/railtie.rb +11 -0
  117. data/lib/arjdbc/sqlite3.rb +3 -0
  118. data/lib/arjdbc/sqlite3/adapter.rb +654 -0
  119. data/lib/arjdbc/sqlite3/connection_methods.rb +36 -0
  120. data/lib/arjdbc/sqlite3/explain_support.rb +29 -0
  121. data/lib/arjdbc/sybase.rb +2 -0
  122. data/lib/arjdbc/sybase/adapter.rb +47 -0
  123. data/lib/arjdbc/tasks.rb +13 -0
  124. data/lib/arjdbc/tasks/database_tasks.rb +66 -0
  125. data/lib/arjdbc/tasks/databases.rake +91 -0
  126. data/lib/arjdbc/tasks/databases3.rake +239 -0
  127. data/lib/arjdbc/tasks/databases4.rake +39 -0
  128. data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
  129. data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
  130. data/lib/arjdbc/tasks/h2_database_tasks.rb +31 -0
  131. data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
  132. data/lib/arjdbc/tasks/jdbc_database_tasks.rb +169 -0
  133. data/lib/arjdbc/tasks/mssql_database_tasks.rb +46 -0
  134. data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +297 -0
  135. data/lib/arjdbc/tasks/oracle_database_tasks.rb +65 -0
  136. data/lib/arjdbc/util/quoted_cache.rb +60 -0
  137. data/lib/arjdbc/util/serialized_attributes.rb +98 -0
  138. data/lib/arjdbc/util/table_copier.rb +108 -0
  139. data/lib/arjdbc/version.rb +8 -0
  140. data/lib/generators/jdbc/USAGE +9 -0
  141. data/lib/generators/jdbc/jdbc_generator.rb +17 -0
  142. data/pom.xml +285 -0
  143. data/rails_generators/jdbc_generator.rb +15 -0
  144. data/rails_generators/templates/config/initializers/jdbc.rb +10 -0
  145. data/rails_generators/templates/lib/tasks/jdbc.rake +11 -0
  146. data/rakelib/01-tomcat.rake +51 -0
  147. data/rakelib/02-test.rake +151 -0
  148. data/rakelib/bundler_ext.rb +11 -0
  149. data/rakelib/db.rake +58 -0
  150. data/rakelib/rails.rake +77 -0
  151. data/src/java/arjdbc/ArJdbcModule.java +288 -0
  152. data/src/java/arjdbc/db2/DB2Module.java +77 -0
  153. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +128 -0
  154. data/src/java/arjdbc/derby/DerbyModule.java +180 -0
  155. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +153 -0
  156. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +190 -0
  157. data/src/java/arjdbc/h2/H2Module.java +50 -0
  158. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +86 -0
  159. data/src/java/arjdbc/hsqldb/HSQLDBModule.java +74 -0
  160. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +76 -0
  161. data/src/java/arjdbc/jdbc/AdapterJavaService.java +43 -0
  162. data/src/java/arjdbc/jdbc/Callable.java +44 -0
  163. data/src/java/arjdbc/jdbc/ConnectionFactory.java +77 -0
  164. data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +156 -0
  165. data/src/java/arjdbc/jdbc/DriverConnectionFactory.java +63 -0
  166. data/src/java/arjdbc/jdbc/DriverWrapper.java +128 -0
  167. data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +32 -0
  168. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +4541 -0
  169. data/src/java/arjdbc/jdbc/SQLBlock.java +54 -0
  170. data/src/java/arjdbc/jdbc/WithResultSet.java +37 -0
  171. data/src/java/arjdbc/mssql/MSSQLModule.java +91 -0
  172. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +193 -0
  173. data/src/java/arjdbc/mysql/MySQLModule.java +140 -0
  174. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +456 -0
  175. data/src/java/arjdbc/oracle/OracleModule.java +81 -0
  176. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +477 -0
  177. data/src/java/arjdbc/postgresql/ByteaUtils.java +171 -0
  178. data/src/java/arjdbc/postgresql/DriverImplementation.java +78 -0
  179. data/src/java/arjdbc/postgresql/PGDriverImplementation.java +535 -0
  180. data/src/java/arjdbc/postgresql/PostgreSQLModule.java +189 -0
  181. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +489 -0
  182. data/src/java/arjdbc/sqlite3/SQLite3Module.java +93 -0
  183. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +405 -0
  184. data/src/java/arjdbc/util/CallResultSet.java +826 -0
  185. data/src/java/arjdbc/util/DateTimeUtils.java +517 -0
  186. data/src/java/arjdbc/util/NumberUtils.java +50 -0
  187. data/src/java/arjdbc/util/ObjectSupport.java +65 -0
  188. data/src/java/arjdbc/util/QuotingUtils.java +139 -0
  189. data/src/java/arjdbc/util/StringCache.java +60 -0
  190. data/src/java/arjdbc/util/StringHelper.java +155 -0
  191. metadata +288 -0
@@ -0,0 +1,20 @@
1
+ ArJdbc::ConnectionMethods.module_eval do
2
+ def firebird_connection(config)
3
+ config[:adapter_spec] ||= ::ArJdbc::Firebird
4
+ config[:adapter_class] = ActiveRecord::ConnectionAdapters::FirebirdAdapter unless config.key?(:adapter_class)
5
+
6
+ return jndi_connection(config) if jndi_config?(config)
7
+
8
+ config[:driver] ||= 'org.firebirdsql.jdbc.FBDriver'
9
+ ArJdbc.load_driver(:Firebird) unless config[:load_driver] == false
10
+
11
+ config[:host] ||= 'localhost'
12
+ config[:port] ||= 3050
13
+ config[:url] ||= begin
14
+ "jdbc:firebirdsql://#{config[:host]}:#{config[:port]}/#{config[:database]}"
15
+ end
16
+
17
+ jdbc_connection(config)
18
+ end
19
+ # alias_method :jdbcfirebird_connection, :firebird_connection
20
+ end
@@ -0,0 +1,3 @@
1
+ require 'arjdbc'
2
+ require 'arjdbc/h2/adapter'
3
+ require 'arjdbc/h2/connection_methods'
@@ -0,0 +1,335 @@
1
+ ArJdbc.load_java_part :H2
2
+ require 'arjdbc/hsqldb/adapter'
3
+
4
+ module ArJdbc
5
+ module H2
6
+ include HSQLDB
7
+
8
+ JdbcConnection = ::ActiveRecord::ConnectionAdapters::H2JdbcConnection
9
+
10
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
11
+ def self.jdbc_connection_class; JdbcConnection end
12
+
13
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
14
+ def self.column_selector
15
+ [ /\.h2\./i, lambda { |config, column| column.extend(ColumnMethods) } ]
16
+ end
17
+
18
+ # @since 1.4.0
19
+ # @private Internal - mostly due {#column_selector}.
20
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn
21
+ module ColumnMethods
22
+
23
+ private
24
+
25
+ def extract_limit(sql_type)
26
+ limit = super
27
+ case @sql_type = sql_type.downcase
28
+ # NOTE: JDBC driver f*cks sql_type up with limits (just like HSQLDB) :
29
+ when /^tinyint/i then @sql_type = 'tinyint'; limit = 1
30
+ when /^smallint|int2/i then @sql_type = 'smallint'; limit = 2
31
+ when /^bigint|int8/i then @sql_type = 'bigint'; limit = 8
32
+ when /^int|int4/i then @sql_type = 'int'; limit = 4
33
+ when /^double/i then @sql_type = 'double'; limit = 8
34
+ when /^real/i then @sql_type = 'real'; limit = 4
35
+ when /^date/i then @sql_type = 'date'; limit = nil
36
+ when /^timestamp/i then @sql_type = 'timestamp'; limit = nil
37
+ when /^time/i then @sql_type = 'time'; limit = nil
38
+ when /^boolean/i then @sql_type = 'boolean'; limit = nil
39
+ when /^binary|bytea/i; then @sql_type = 'binary'; limit = 2 * 1024 * 1024
40
+ when /blob|image|oid/i then @sql_type = 'blob'; limit = nil
41
+ when /clob|text/i then @sql_type = 'clob'; limit = nil
42
+ # NOTE: use lower-case due SchemaDumper not handling it's decimal/integer
43
+ # optimization case-insensitively due : column.type == :integer &&
44
+ # [/^numeric/, /^decimal/].any? { |e| e.match(column.sql_type) }
45
+ when /^decimal\(65535,32767\)/i
46
+ @sql_type = 'decimal'; nil
47
+ end
48
+ limit
49
+ end
50
+
51
+ def simplified_type(field_type)
52
+ case field_type
53
+ when /^bit|bool/i then :boolean
54
+ when /^signed|year/i then :integer
55
+ when /^real|double/i then :float
56
+ when /^varchar/i then :string
57
+ when /^longvarchar/i then :text
58
+ when /^binary|raw|bytea/i then :binary
59
+ when /varbinary/i then :binary # longvarbinary, varbinary
60
+ when /^blob|image|oid/i then :binary
61
+ else
62
+ super
63
+ end
64
+ end
65
+
66
+ # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
67
+ def default_value(value)
68
+ # H2 auto-generated key default value
69
+ return nil if value =~ /^\(NEXT VALUE FOR/i
70
+ # JDBC returns column default strings with actual single quotes around the value.
71
+ return $1 if value =~ /^'(.*)'$/
72
+ value
73
+ end
74
+
75
+ end
76
+
77
+ # H2's (JDBC) column class
78
+ # @since 1.4.0
79
+ class Column < ::ActiveRecord::ConnectionAdapters::JdbcColumn
80
+ include ColumnMethods
81
+ end
82
+
83
+ # @see ActiveRecord::ConnectionAdapters::Jdbc::ArelSupport
84
+ def self.arel_visitor_type(config = nil)
85
+ require 'arel/visitors/h2'; ::Arel::Visitors::H2
86
+ end
87
+
88
+ ADAPTER_NAME = 'H2'.freeze
89
+
90
+ # @override
91
+ def adapter_name
92
+ ADAPTER_NAME
93
+ end
94
+
95
+ NATIVE_DATABASE_TYPES = {
96
+ # "integer GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY"
97
+ :primary_key => "bigint identity",
98
+ :boolean => { :name => "boolean" },
99
+ :tinyint => { :name => "tinyint", :limit => 1 },
100
+ :smallint => { :name => "smallint", :limit => 2 },
101
+ :bigint => { :name => "bigint", :limit => 8 },
102
+ :integer => { :name => "int", :limit => 4 },
103
+ :decimal => { :name => "decimal" }, # :limit => 2147483647
104
+ :numeric => { :name => "numeric" }, # :limit => 2147483647
105
+ :float => { :name => "float", :limit => 8 },
106
+ :double => { :name => "double", :limit => 8 },
107
+ :real => { :name => "real", :limit => 4 }, # :limit => 8
108
+ :date => { :name => "date" },
109
+ :time => { :name => "time" },
110
+ :timestamp => { :name => "timestamp" },
111
+ :datetime => { :name => "timestamp" },
112
+ :binary => { :name => "binary" },
113
+ :string => { :name => "varchar", :limit => 255 },
114
+ :char => { :name => "char" }, # :limit => 2147483647
115
+ :blob => { :name => "blob" },
116
+ :text => { :name => "clob" },
117
+ :clob => { :name => "clob" },
118
+ :uuid => { :name => "uuid" }, # :limit => 2147483647
119
+ :other => { :name => "other" }, # java.lang.Object
120
+ :array => { :name => "array" }, # java.lang.Object[]
121
+ # NOTE: would be great if AR allowed as to refactor as :
122
+ # t.column :string, :ignorecase => true
123
+ :varchar_casesensitive => { :name => 'varchar_casesensitive' },
124
+ :varchar_ignorecase => { :name => 'varchar_ignorecase' },
125
+ # :identity : { :name=>"identity", :limit => 19 }
126
+ # :result_set : { :name=>"result_set" }
127
+ }
128
+
129
+ # @override
130
+ def native_database_types
131
+ NATIVE_DATABASE_TYPES
132
+ end
133
+
134
+ # @override
135
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
136
+ case type.to_sym
137
+ when :integer
138
+ case limit
139
+ when 1; 'tinyint'
140
+ when 2; 'smallint'
141
+ when nil, 3, 4; 'int'
142
+ when 5..8; 'bigint'
143
+ else raise(ActiveRecordError, "No integer type has byte size #{limit}")
144
+ end
145
+ when :float
146
+ case limit
147
+ when 1..4; 'real'
148
+ when 5..8; 'double'
149
+ else raise(ActiveRecordError, "No float type has byte size #{limit}")
150
+ end
151
+ when :binary
152
+ if limit && limit < 2 * 1024 * 1024
153
+ 'binary'
154
+ else
155
+ 'blob'
156
+ end
157
+ else
158
+ super
159
+ end
160
+ end
161
+
162
+ # @override
163
+ def empty_insert_statement_value
164
+ "VALUES ()"
165
+ end
166
+
167
+ # @override
168
+ def tables(schema = current_schema)
169
+ @connection.tables(nil, schema)
170
+ end
171
+
172
+ # @override
173
+ def columns(table_name, name = nil)
174
+ schema, table = extract_schema_and_table(table_name.to_s)
175
+ schema = current_schema if schema.nil?
176
+ @connection.columns_internal(table, nil, schema || '')
177
+ end
178
+
179
+ # @override
180
+ def change_column(table_name, column_name, type, options = {})
181
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
182
+ change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
183
+ change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
184
+ end
185
+
186
+ # @return [String] the current schema name
187
+ def current_schema
188
+ @current_schema ||= execute('CALL SCHEMA()', 'SCHEMA')[0].values[0] # PUBLIC (default)
189
+ end
190
+
191
+ # Change the (current) schema to be used for this connection.
192
+ def set_schema(schema = 'PUBLIC')
193
+ @current_schema = nil
194
+ execute "SET SCHEMA #{schema}", 'SCHEMA'
195
+ end
196
+ alias_method :current_schema=, :set_schema
197
+
198
+ def create_schema(schema)
199
+ execute "CREATE SCHEMA #{schema}", 'SCHEMA'
200
+ end
201
+
202
+ def drop_schema(schema)
203
+ @current_schema = nil if current_schema == schema
204
+ execute "DROP SCHEMA #{schema}", 'SCHEMA'
205
+ end
206
+
207
+ def configure_connection
208
+ # NOTE: just to support the config[:schema] setting
209
+ # it's likely better to append this to the JDBC URL :
210
+ # jdbc:h2:test;SCHEMA=MY_SCHEMA
211
+ if schema = config[:schema]
212
+ set_schema(schema) # if schema.uppercase != 'PUBLIC'
213
+ end
214
+ end
215
+
216
+ # @override
217
+ def quote(value, column = nil)
218
+ case value
219
+ when String
220
+ if value.empty?
221
+ "''"
222
+ else
223
+ super
224
+ end
225
+ else
226
+ super
227
+ end
228
+ end
229
+
230
+ # @override
231
+ def supports_views?; true end
232
+
233
+ # EXPLAIN support :
234
+
235
+ # @override
236
+ def supports_explain?; true end
237
+
238
+ # @override
239
+ def explain(arel, binds = [])
240
+ sql = "EXPLAIN #{to_sql(arel, binds)}"
241
+ raw_result = exec_query_raw(sql, "EXPLAIN", binds)
242
+ raw_result[0].values.join("\n") # [ "SELECT \n ..." ].to_s
243
+ end
244
+
245
+ # @override
246
+ def structure_dump
247
+ execute('SCRIPT SIMPLE').map do |result|
248
+ # [ { 'script' => SQL }, { 'script' ... }, ... ]
249
+ case sql = result.first[1] # ['script']
250
+ when /CREATE USER IF NOT EXISTS SA/i then nil
251
+ else sql
252
+ end
253
+ end.compact.join("\n\n")
254
+ end
255
+
256
+ # @see #structure_dump
257
+ def structure_load(dump)
258
+ dump.each_line("\n\n") { |ddl| execute(ddl) }
259
+ end
260
+
261
+ def shutdown
262
+ execute 'SHUTDOWN COMPACT'
263
+ end
264
+
265
+ # @private
266
+ def recreate_database(name = nil, options = {})
267
+ drop_database(name)
268
+ create_database(name, options)
269
+ end
270
+
271
+ # @private
272
+ def create_database(name = nil, options = {}); end
273
+
274
+ # @private
275
+ def drop_database(name = nil)
276
+ execute('DROP ALL OBJECTS')
277
+ end
278
+
279
+ # @private
280
+ def database_path(base_only = false)
281
+ db_path = jdbc_connection(true).getSession.getDataHandler.getDatabasePath
282
+ return db_path if base_only
283
+ if File.exist?(mv_path = "#{db_path}.mv.db")
284
+ return mv_path
285
+ else
286
+ "#{db_path}.h2.db"
287
+ end
288
+ end
289
+
290
+ # @override
291
+ def jdbc_connection(unwrap = nil)
292
+ java_connection = raw_connection.connection
293
+ return java_connection unless unwrap
294
+ if java_connection.java_class.name == 'org.h2.jdbc.JdbcConnection'
295
+ return java_connection
296
+ end
297
+ connection_class = java.sql.Connection.java_class
298
+ if java_connection.wrapper_for?(connection_class)
299
+ java_connection.unwrap(connection_class) # java.sql.Wrapper.unwrap
300
+ elsif java_connection.respond_to?(:connection)
301
+ # e.g. org.apache.tomcat.jdbc.pool.PooledConnection
302
+ java_connection.connection # getConnection
303
+ else
304
+ java_connection
305
+ end
306
+ end
307
+
308
+ private
309
+
310
+ def change_column_null(table_name, column_name, null, default = nil)
311
+ if !null && !default.nil?
312
+ execute("UPDATE #{table_name} SET #{column_name}=#{quote(default)} WHERE #{column_name} IS NULL")
313
+ end
314
+ if null
315
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET NULL"
316
+ else
317
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET NOT NULL"
318
+ end
319
+ end
320
+
321
+ def extract_schema_and_table(name)
322
+ result = name.scan(/[^".\s]+|"[^"]*"/)[0, 2]
323
+ result.each { |m| m.gsub!(/(^"|"$)/, '') }
324
+ result.unshift(nil) if result.size == 1 # schema == nil
325
+ result # [schema, table]
326
+ end
327
+
328
+ end
329
+ end
330
+
331
+ module ActiveRecord::ConnectionAdapters
332
+ class H2Adapter < JdbcAdapter
333
+ include ::ArJdbc::H2
334
+ end
335
+ end
@@ -0,0 +1,22 @@
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
+ ArJdbc.load_driver(:H2) unless config[:load_driver] == false
9
+ config[:driver] ||= 'org.h2.Driver'
10
+ config[:url] ||= begin
11
+ db = config[:database]
12
+ if db[0, 4] == 'mem:' || db[0, 5] == 'file:' || db[0, 5] == 'hsql:'
13
+ "jdbc:h2:#{db}"
14
+ else
15
+ "jdbc:h2:file:#{File.expand_path(db)}"
16
+ end
17
+ end
18
+
19
+ embedded_driver(config)
20
+ end
21
+ alias_method :jdbch2_connection, :h2_connection
22
+ end
@@ -0,0 +1,3 @@
1
+ require 'arjdbc'
2
+ require 'arjdbc/hsqldb/adapter'
3
+ require 'arjdbc/hsqldb/connection_methods'
@@ -0,0 +1,304 @@
1
+ ArJdbc.load_java_part :HSQLDB
2
+ require 'arjdbc/hsqldb/explain_support'
3
+ require 'arjdbc/hsqldb/schema_creation' # AR 4.x
4
+
5
+ module ArJdbc
6
+ module HSQLDB
7
+ include ExplainSupport
8
+
9
+ JdbcConnection = ::ActiveRecord::ConnectionAdapters::JdbcConnection
10
+
11
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
12
+ def self.column_selector
13
+ [ /hsqldb/i, lambda { |config, column| column.extend(ColumnMethods) } ]
14
+ end
15
+
16
+ # @since 1.4.0
17
+ # @private Internal - mostly due {#column_selector}.
18
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn
19
+ module ColumnMethods
20
+
21
+ private
22
+
23
+ def extract_limit(sql_type)
24
+ limit = super
25
+ case @sql_type = sql_type.downcase
26
+ when /^tinyint/i then @sql_type = 'tinyint'; limit = 1
27
+ when /^smallint/i then @sql_type = 'smallint'; limit = 2
28
+ when /^bigint/i then @sql_type = 'bigint'; limit = 8
29
+ when /^double/i then @sql_type = 'double'; limit = 8
30
+ when /^real/i then @sql_type = 'real'; limit = 8
31
+ # NOTE: once again we get incorrect "limits" from HypesSQL's JDBC
32
+ # thus yet again we need to fix incorrectly detected limits :
33
+ when /^integer/i then @sql_type = 'integer'; limit = 4
34
+ when /^float/i then @sql_type = 'float'; limit = 8
35
+ when /^decimal/i then @sql_type = 'decimal';
36
+ when /^datetime/i then @sql_type = 'datetime'; limit = nil
37
+ when /^timestamp/i then @sql_type = 'timestamp'; limit = nil
38
+ when /^time/i then @sql_type = 'time'; limit = nil
39
+ when /^date/i then @sql_type = 'date'; limit = nil
40
+ else
41
+ # HSQLDB appears to return "LONGVARCHAR(0)" for :text columns,
42
+ # which for AR purposes should be interpreted as "no limit" :
43
+ limit = nil if sql_type =~ /\(0\)$/
44
+ end
45
+ limit
46
+ end
47
+
48
+ def simplified_type(field_type)
49
+ case field_type
50
+ when /^nvarchar/i then :string
51
+ when /^character/i then :string
52
+ when /^longvarchar/i then :text
53
+ when /int/i then :integer # TINYINT, SMALLINT, BIGINT, INT
54
+ when /real|double/i then :float
55
+ when /^bit/i then :boolean
56
+ when /binary/i then :binary # VARBINARY, LONGVARBINARY
57
+ else
58
+ super
59
+ end
60
+ end
61
+
62
+ # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
63
+ def default_value(value)
64
+ # JDBC returns column default strings with actual single quotes around the value.
65
+ return $1 if value =~ /^'(.*)'$/
66
+ value
67
+ end
68
+
69
+ end
70
+
71
+ # HSQLDB's (JDBC) column class
72
+ # @since 1.4.0
73
+ class Column < ::ActiveRecord::ConnectionAdapters::JdbcColumn
74
+ include ColumnMethods
75
+ end
76
+
77
+ # @see ActiveRecord::ConnectionAdapters::Jdbc::ArelSupport
78
+ def self.arel_visitor_type(config = nil)
79
+ require 'arel/visitors/hsqldb'; ::Arel::Visitors::HSQLDB
80
+ end
81
+
82
+ ADAPTER_NAME = 'HSQLDB'.freeze
83
+
84
+ def adapter_name
85
+ ADAPTER_NAME
86
+ end
87
+
88
+ NATIVE_DATABASE_TYPES = {
89
+ :primary_key => "integer GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY",
90
+ :string => { :name => "varchar", :limit => 255 }, # :limit => 2147483647
91
+ :text => { :name => "clob" },
92
+ :binary => { :name => "blob" },
93
+ :boolean => { :name => "boolean" }, # :name => "tinyint", :limit => 1
94
+ :bit => { :name=>"bit" }, # stored as 0/1 on HSQLDB 2.2 (translates true/false)
95
+ :integer => { :name => "integer", :limit => 4 },
96
+ :decimal => { :name => "decimal" }, # :limit => 2147483647
97
+ :numeric => { :name => "numeric" }, # :limit => 2147483647
98
+ # NOTE: fix incorrectly detected limits :
99
+ :tinyint => { :name => "tinyint", :limit => 1 },
100
+ :smallint => { :name => "smallint", :limit => 2 },
101
+ :bigint => { :name => "bigint", :limit => 8 },
102
+ :float => { :name => "float" },
103
+ :double => { :name => "double", :limit => 8 },
104
+ :real => { :name => "real", :limit => 8 },
105
+ :date => { :name=>"date" },
106
+ :time => { :name=>"time" },
107
+ :timestamp => { :name=>"timestamp" },
108
+ :datetime => { :name=>"timestamp" },
109
+ :other => { :name=>"other" },
110
+ # NOTE: would be great if AR allowed as to refactor as :
111
+ # t.column :string, :ignorecase => true
112
+ :character => { :name => "character" },
113
+ :varchar_ignorecase => { :name => "varchar_ignorecase" },
114
+ }
115
+
116
+ # @override
117
+ def native_database_types
118
+ NATIVE_DATABASE_TYPES
119
+ end
120
+
121
+ # @override
122
+ def quote(value, column = nil)
123
+ return value.quoted_id if value.respond_to?(:quoted_id)
124
+ return value if sql_literal?(value)
125
+
126
+ case value
127
+ when String
128
+ column_type = column && column.type
129
+ if column_type == :binary
130
+ "X'#{value.unpack("H*")[0]}'"
131
+ elsif column_type == :integer ||
132
+ column.respond_to?(:primary) && column.primary && column.klass != String
133
+ value.to_i.to_s
134
+ else
135
+ "'#{quote_string(value)}'"
136
+ end
137
+ when Time
138
+ column_type = column && column.type
139
+ if column_type == :time
140
+ "'#{value.strftime("%H:%M:%S")}'"
141
+ #elsif column_type == :timestamp # || column_type == :datetime
142
+ #value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
143
+ #"'#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{sprintf("%06d", value.usec)}'"
144
+ else
145
+ super
146
+ end
147
+ else
148
+ super
149
+ end
150
+ end
151
+
152
+ # Quote date/time values for use in SQL input.
153
+ # Includes microseconds if the value is a Time responding to usec.
154
+ # @override
155
+ def quoted_date(value)
156
+ if value.acts_like?(:time) && value.respond_to?(:usec)
157
+ usec = sprintf("%06d", value.usec)
158
+ value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
159
+ "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}"
160
+ else
161
+ super
162
+ end
163
+ end if ::ActiveRecord::VERSION::MAJOR >= 3
164
+
165
+ # @override
166
+ def quote_column_name(name)
167
+ name = name.to_s
168
+ if name =~ /[-]/
169
+ %Q{"#{name.upcase}"}
170
+ else
171
+ name
172
+ end
173
+ end
174
+
175
+ # @override
176
+ def add_column(table_name, column_name, type, options = {})
177
+ 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])}"
178
+ add_column_options!(add_column_sql, options)
179
+ execute(add_column_sql)
180
+ end unless const_defined? :SchemaCreation
181
+
182
+ # @override
183
+ def change_column(table_name, column_name, type, options = {})
184
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
185
+ end
186
+
187
+ def change_column_default(table_name, column_name, default) #:nodoc:
188
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT #{quote(default)}"
189
+ end
190
+
191
+ # @override
192
+ def rename_column(table_name, column_name, new_column_name) #:nodoc:
193
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} RENAME TO #{new_column_name}"
194
+ end
195
+
196
+ # @override
197
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
198
+ return super if defined?(::Jdbc::H2) || type.to_s != 'integer' || limit == nil
199
+ type
200
+ end
201
+
202
+ # @override
203
+ def rename_table(name, new_name)
204
+ execute "ALTER TABLE #{name} RENAME TO #{new_name}"
205
+ end
206
+
207
+ # @note AR API since 4.2
208
+ def truncate(table_name, name = nil)
209
+ execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
210
+ end
211
+
212
+ def last_insert_id
213
+ identity = select_value("CALL IDENTITY()")
214
+ Integer(identity.nil? ? 0 : identity)
215
+ end
216
+
217
+ # @private
218
+ def _execute(sql, name = nil)
219
+ result = super
220
+ self.class.insert?(sql) ? last_insert_id : result
221
+ end
222
+ private :_execute
223
+
224
+ # @note Only used with (non-AREL) ActiveRecord **2.3**.
225
+ # @see Arel::Visitors::HSQLDB#limit_offset
226
+ def add_limit_offset!(sql, options)
227
+ if sql =~ /^select/i
228
+ offset = options[:offset] || 0
229
+ if limit = options[:limit]
230
+ sql.replace "SELECT LIMIT #{offset} #{limit} #{sql[7..-1]}"
231
+ elsif offset > 0
232
+ sql.replace "SELECT LIMIT #{offset} 0 #{sql[7..-1]}"
233
+ end
234
+ end
235
+ end if ::ActiveRecord::VERSION::MAJOR < 3
236
+
237
+ # @override
238
+ def empty_insert_statement_value
239
+ # on HSQLDB only work with tables that have a default value for each
240
+ # and every column ... you'll need to avoid `Model.create!` on 4.0
241
+ 'DEFAULT VALUES'
242
+ end
243
+
244
+ # We filter out HSQLDB's system tables (named "SYSTEM.*").
245
+ # @override
246
+ def tables
247
+ @connection.tables.select { |row| row.to_s !~ /^system_/i }
248
+ end
249
+
250
+ # @override
251
+ def remove_index!(table_name, index_name)
252
+ execute "DROP INDEX #{quote_column_name(index_name)}"
253
+ end
254
+
255
+ # @override
256
+ def supports_views?; true end
257
+
258
+ # @override
259
+ def supports_foreign_keys?; true end
260
+
261
+ # @override
262
+ def structure_dump
263
+ execute('SCRIPT').map do |result|
264
+ # [ { 'command' => SQL }, { 'command' ... }, ... ]
265
+ case sql = result.first[1] # ['command']
266
+ when /CREATE USER SA PASSWORD DIGEST .*?/i then nil
267
+ when /CREATE SCHEMA PUBLIC AUTHORIZATION DBA/i then nil
268
+ when /GRANT DBA TO SA/i then nil
269
+ else sql
270
+ end
271
+ end.compact.join("\n\n")
272
+ end
273
+
274
+ # @see #structure_dump
275
+ def structure_load(dump)
276
+ dump.each_line("\n\n") { |ddl| execute(ddl) }
277
+ end
278
+
279
+ def shutdown
280
+ execute 'SHUTDOWN'
281
+ end
282
+
283
+ # @private
284
+ def recreate_database(name = nil, options = {})
285
+ drop_database(name)
286
+ create_database(name, options)
287
+ end
288
+
289
+ # @private
290
+ def create_database(name = nil, options = {}); end
291
+
292
+ # @private
293
+ def drop_database(name = nil)
294
+ execute('DROP SCHEMA PUBLIC CASCADE')
295
+ end
296
+
297
+ end
298
+ end
299
+
300
+ module ActiveRecord::ConnectionAdapters
301
+ class HsqldbAdapter < JdbcAdapter
302
+ include ::ArJdbc::HSQLDB
303
+ end
304
+ end