activerecord-jdbc-adapter 1.2.5 → 1.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +5 -1
  3. data/Appraisals +5 -5
  4. data/Gemfile +9 -1
  5. data/Gemfile.lock +44 -10
  6. data/History.txt +126 -2
  7. data/README.md +246 -0
  8. data/Rakefile +34 -25
  9. data/activerecord-jdbc-adapter.gemspec +1 -1
  10. data/gemfiles/rails23.gemfile +5 -3
  11. data/gemfiles/rails23.gemfile.lock +26 -18
  12. data/gemfiles/rails30.gemfile +4 -2
  13. data/gemfiles/rails30.gemfile.lock +16 -8
  14. data/gemfiles/rails31.gemfile +4 -2
  15. data/gemfiles/rails31.gemfile.lock +16 -9
  16. data/gemfiles/rails32.gemfile +4 -2
  17. data/gemfiles/rails32.gemfile.lock +15 -8
  18. data/lib/active_record/connection_adapters/db2_adapter.rb +1 -0
  19. data/lib/arel/visitors/sql_server.rb +3 -0
  20. data/lib/arjdbc.rb +3 -5
  21. data/lib/arjdbc/db2.rb +1 -0
  22. data/lib/arjdbc/db2/adapter.rb +302 -196
  23. data/lib/arjdbc/db2/connection_methods.rb +18 -0
  24. data/lib/arjdbc/derby/active_record_patch.rb +12 -0
  25. data/lib/arjdbc/derby/adapter.rb +180 -158
  26. data/lib/arjdbc/derby/connection_methods.rb +5 -1
  27. data/lib/arjdbc/firebird/adapter.rb +27 -19
  28. data/lib/arjdbc/h2/adapter.rb +162 -7
  29. data/lib/arjdbc/h2/connection_methods.rb +5 -1
  30. data/lib/arjdbc/hsqldb.rb +1 -1
  31. data/lib/arjdbc/hsqldb/adapter.rb +96 -61
  32. data/lib/arjdbc/hsqldb/connection_methods.rb +5 -1
  33. data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
  34. data/lib/arjdbc/informix/adapter.rb +56 -55
  35. data/lib/arjdbc/jdbc/adapter.rb +173 -86
  36. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  37. data/lib/arjdbc/jdbc/column.rb +28 -23
  38. data/lib/arjdbc/jdbc/connection.rb +10 -6
  39. data/lib/arjdbc/jdbc/driver.rb +13 -5
  40. data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +21 -0
  41. data/lib/arjdbc/mssql.rb +1 -1
  42. data/lib/arjdbc/mssql/adapter.rb +51 -53
  43. data/lib/arjdbc/mssql/connection_methods.rb +8 -1
  44. data/lib/arjdbc/mysql.rb +1 -1
  45. data/lib/arjdbc/mysql/adapter.rb +186 -150
  46. data/lib/arjdbc/mysql/connection_methods.rb +9 -9
  47. data/lib/arjdbc/mysql/explain_support.rb +85 -0
  48. data/lib/arjdbc/oracle.rb +1 -1
  49. data/lib/arjdbc/oracle/adapter.rb +232 -125
  50. data/lib/arjdbc/oracle/connection_methods.rb +2 -2
  51. data/lib/arjdbc/postgresql.rb +1 -1
  52. data/lib/arjdbc/postgresql/adapter.rb +134 -86
  53. data/lib/arjdbc/postgresql/connection_methods.rb +6 -4
  54. data/lib/arjdbc/postgresql/explain_support.rb +55 -0
  55. data/lib/arjdbc/sqlite3.rb +1 -1
  56. data/lib/arjdbc/sqlite3/adapter.rb +176 -108
  57. data/lib/arjdbc/sqlite3/connection_methods.rb +5 -5
  58. data/lib/arjdbc/sqlite3/explain_support.rb +32 -0
  59. data/lib/arjdbc/sybase/adapter.rb +7 -6
  60. data/lib/arjdbc/version.rb +1 -1
  61. data/pom.xml +1 -1
  62. data/rakelib/02-test.rake +9 -11
  63. data/rakelib/rails.rake +18 -10
  64. data/src/java/arjdbc/db2/DB2Module.java +70 -0
  65. data/src/java/arjdbc/derby/DerbyModule.java +24 -5
  66. data/src/java/arjdbc/hsqldb/HSQLDBModule.java +66 -0
  67. data/src/java/arjdbc/jdbc/AdapterJavaService.java +14 -7
  68. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +111 -89
  69. data/src/java/arjdbc/mysql/MySQLModule.java +79 -70
  70. data/src/java/arjdbc/oracle/OracleModule.java +74 -0
  71. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +5 -10
  72. data/src/java/arjdbc/sqlite3/SQLite3Module.java +77 -0
  73. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +127 -0
  74. data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +25 -111
  75. data/src/java/arjdbc/util/QuotingUtils.java +104 -0
  76. data/test/abstract_db_create.rb +6 -6
  77. data/test/activerecord/connection_adapters/type_conversion_test.rb +2 -2
  78. data/test/assets/flowers.jpg +0 -0
  79. data/test/binary.rb +67 -0
  80. data/test/db/db2.rb +30 -7
  81. data/test/db/jdbc.rb +4 -2
  82. data/test/db/oracle.rb +18 -27
  83. data/test/db2_binary_test.rb +6 -0
  84. data/test/db2_serialize_test.rb +6 -0
  85. data/test/db2_simple_test.rb +20 -25
  86. data/test/db2_test.rb +71 -0
  87. data/test/derby_binary_test.rb +6 -0
  88. data/test/derby_migration_test.rb +42 -35
  89. data/test/derby_reset_column_information_test.rb +1 -0
  90. data/test/derby_row_locking_test.rb +17 -0
  91. data/test/derby_schema_dump_test.rb +9 -0
  92. data/test/derby_serialize_test.rb +6 -0
  93. data/test/derby_simple_test.rb +59 -17
  94. data/test/generic_jdbc_connection_test.rb +112 -5
  95. data/test/h2_binary_test.rb +6 -0
  96. data/test/h2_change_column_test.rb +1 -1
  97. data/test/h2_schema_dump_test.rb +25 -0
  98. data/test/h2_serialize_test.rb +6 -0
  99. data/test/h2_simple_test.rb +23 -9
  100. data/test/has_many_through.rb +18 -4
  101. data/test/hsqldb_binary_test.rb +6 -0
  102. data/test/hsqldb_schema_dump_test.rb +15 -0
  103. data/test/hsqldb_serialize_test.rb +6 -0
  104. data/test/hsqldb_simple_test.rb +1 -0
  105. data/test/informix_simple_test.rb +1 -1
  106. data/test/jdbc/db2.rb +23 -0
  107. data/test/jdbc/oracle.rb +23 -0
  108. data/test/jdbc_common.rb +3 -110
  109. data/test/jndi_callbacks_test.rb +0 -2
  110. data/test/jndi_test.rb +2 -0
  111. data/test/models/binary.rb +18 -0
  112. data/test/models/custom_pk_name.rb +1 -0
  113. data/test/models/data_types.rb +11 -2
  114. data/test/models/entry.rb +1 -1
  115. data/test/models/string_id.rb +2 -2
  116. data/test/models/thing.rb +1 -1
  117. data/test/models/topic.rb +32 -0
  118. data/test/mssql_legacy_types_test.rb +1 -1
  119. data/test/mssql_limit_offset_test.rb +13 -3
  120. data/test/mssql_serialize_test.rb +6 -0
  121. data/test/mysql_binary_test.rb +6 -0
  122. data/test/mysql_schema_dump_test.rb +220 -0
  123. data/test/mysql_serialize_test.rb +6 -0
  124. data/test/mysql_simple_test.rb +22 -2
  125. data/test/mysql_test.rb +93 -0
  126. data/test/oracle_binary_test.rb +6 -0
  127. data/test/oracle_limit_test.rb +2 -1
  128. data/test/oracle_serialize_test.rb +6 -0
  129. data/test/oracle_simple_test.rb +61 -0
  130. data/test/oracle_specific_test.rb +77 -26
  131. data/test/postgres_binary_test.rb +6 -0
  132. data/test/postgres_native_type_mapping_test.rb +12 -11
  133. data/test/postgres_nonseq_pkey_test.rb +1 -0
  134. data/test/postgres_reserved_test.rb +1 -0
  135. data/test/postgres_reset_column_information_test.rb +1 -0
  136. data/test/postgres_row_locking_test.rb +21 -0
  137. data/test/postgres_schema_dump_test.rb +88 -0
  138. data/test/postgres_schema_search_path_test.rb +1 -0
  139. data/test/postgres_simple_test.rb +62 -89
  140. data/test/postgres_table_alias_length_test.rb +1 -0
  141. data/test/postgres_test.rb +31 -0
  142. data/test/postgres_type_conversion_test.rb +16 -16
  143. data/test/row_locking.rb +69 -64
  144. data/test/schema_dump.rb +168 -0
  145. data/test/serialize.rb +277 -0
  146. data/test/simple.rb +326 -122
  147. data/test/sqlite3_serialize_test.rb +6 -0
  148. data/test/sqlite3_simple_test.rb +51 -84
  149. data/test/sqlite3_type_conversion_test.rb +101 -0
  150. data/test/test_helper.rb +224 -0
  151. metadata +325 -366
  152. data/README.rdoc +0 -214
  153. data/test/db/logger.rb +0 -3
  154. data/test/derby_multibyte_test.rb +0 -11
  155. data/test/mysql_info_test.rb +0 -123
@@ -2,7 +2,11 @@ module ActiveRecord
2
2
  class Base
3
3
  class << self
4
4
  def derby_connection(config)
5
- require 'active_record/connection_adapters/jdbcderby_adapter'
5
+ begin
6
+ require 'jdbc/derby'
7
+ ::Jdbc::Derby.load_driver(:require) if defined?(::Jdbc::Derby.load_driver)
8
+ rescue LoadError # assuming driver.jar is on the class-path
9
+ end
6
10
 
7
11
  config[:url] ||= "jdbc:derby:#{config[:database]};create=true"
8
12
  config[:driver] ||= defined?(::Jdbc::Derby.driver_name) ? ::Jdbc::Derby.driver_name : 'org.apache.derby.jdbc.EmbeddedDriver'
@@ -1,25 +1,29 @@
1
- module ::ArJdbc
1
+ require 'arjdbc/jdbc/serialized_attributes_helper'
2
+
3
+ module ArJdbc
2
4
  module FireBird
3
5
 
6
+ @@_lob_callback_added = nil
7
+
4
8
  def self.extended(mod)
5
- unless @lob_callback_added
9
+ unless @@_lob_callback_added
6
10
  ActiveRecord::Base.class_eval do
7
11
  def after_save_with_firebird_blob
8
- self.class.columns.select { |c| c.sql_type =~ /blob/i }.each do |c|
9
- value = self[c.name]
10
- if respond_to?(:unserializable_attribute?)
11
- value = value.to_yaml if unserializable_attribute?(c.name, c)
12
- else
13
- value = value.to_yaml if value.is_a?(Hash)
14
- end
12
+ self.class.columns.select { |c| c.sql_type =~ /blob/i }.each do |column|
13
+ value = ::ArJdbc::SerializedAttributesHelper.dump_column_value(self, column)
15
14
  next if value.nil?
16
- connection.write_large_object(c.type == :binary, c.name, self.class.table_name, self.class.primary_key, quote_value(id), value)
15
+
16
+ connection.write_large_object(
17
+ column.type == :binary, column.name,
18
+ self.class.table_name, self.class.primary_key,
19
+ quote_value(id), value
20
+ )
17
21
  end
18
22
  end
19
23
  end
20
24
 
21
25
  ActiveRecord::Base.after_save :after_save_with_firebird_blob
22
- @lob_callback_added = true
26
+ @@_lob_callback_added = true
23
27
  end
24
28
  end
25
29
 
@@ -29,14 +33,18 @@ module ::ArJdbc
29
33
 
30
34
  def self.arel2_visitors(config)
31
35
  require 'arel/visitors/firebird'
32
- {}.tap {|v| %w(firebird firebirdsql).each {|a| v[a] = ::Arel::Visitors::Firebird } }
33
- end
34
-
35
- def modify_types(tp)
36
- tp[:primary_key] = 'INTEGER NOT NULL PRIMARY KEY'
37
- tp[:string][:limit] = 252
38
- tp[:integer][:limit] = nil
39
- tp
36
+ {
37
+ 'firebird' => ::Arel::Visitors::Firebird,
38
+ 'firebirdsql' => ::Arel::Visitors::Firebird
39
+ }
40
+ end
41
+
42
+ def modify_types(types)
43
+ super(types)
44
+ types[:primary_key] = 'INTEGER NOT NULL PRIMARY KEY'
45
+ types[:string][:limit] = 252
46
+ types[:integer][:limit] = nil
47
+ types
40
48
  end
41
49
 
42
50
  def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) # :nodoc:
@@ -8,24 +8,150 @@ module ArJdbc
8
8
  ::ActiveRecord::ConnectionAdapters::H2JdbcConnection
9
9
  end
10
10
 
11
- def adapter_name #:nodoc:
12
- 'H2'
11
+ def self.column_selector
12
+ [ /\.h2\./i, lambda { |cfg, column| column.extend(::ArJdbc::H2::Column) } ]
13
+ end
14
+
15
+ module Column
16
+
17
+ private
18
+
19
+ def extract_limit(sql_type)
20
+ limit = super
21
+ case @sql_type = sql_type.downcase
22
+ # NOTE: JDBC driver f*cks sql_type up with limits (just like HSQLDB) :
23
+ when /^tinyint/i then @sql_type = 'tinyint'; limit = 1
24
+ when /^smallint|int2/i then @sql_type = 'smallint'; limit = 2
25
+ when /^bigint|int8/i then @sql_type = 'bigint'; limit = 8
26
+ when /^int|int4/i then @sql_type = 'int'; limit = 4
27
+ when /^double/i then @sql_type = 'double'; limit = 8
28
+ when /^real/i then @sql_type = 'real'; limit = 4
29
+ when /^date/i then @sql_type = 'date'; limit = nil
30
+ when /^timestamp/i then @sql_type = 'timestamp'; limit = nil
31
+ when /^time/i then @sql_type = 'time'; limit = nil
32
+ when /^boolean/i then @sql_type = 'boolean'; limit = nil
33
+ when /^binary|bytea/i; then @sql_type = 'binary'; limit = 2 * 1024 * 1024
34
+ when /blob|image|oid/i then @sql_type = 'blob'; limit = nil
35
+ when /clob|text/i then @sql_type = 'clob'; limit = nil
36
+ # NOTE: use lower-case due SchemaDumper not handling it's decimal/integer
37
+ # optimization case-insensitively due : column.type == :integer &&
38
+ # [/^numeric/, /^decimal/].any? { |e| e.match(column.sql_type) }
39
+ when /^decimal\(65535,32767\)/i
40
+ @sql_type = 'decimal'; nil
41
+ end
42
+ limit
43
+ end
44
+
45
+ def simplified_type(field_type)
46
+ case field_type
47
+ when /^bit|bool/i then :boolean
48
+ when /^signed|year/i then :integer
49
+ when /^real|double/i then :float
50
+ when /^varchar/i then :string
51
+ when /^binary|raw|bytea/i then :binary
52
+ when /^blob|image|oid/i then :binary
53
+ else
54
+ super
55
+ end
56
+ end
57
+
58
+ # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
59
+ def default_value(value)
60
+ # H2 auto-generated key default value
61
+ return nil if value =~ /^\(NEXT VALUE FOR/i
62
+ # JDBC returns column default strings with actual single quotes around the value.
63
+ return $1 if value =~ /^'(.*)'$/
64
+ value
65
+ end
66
+
67
+ end
68
+
69
+ ADAPTER_NAME = 'H2' # :nodoc:
70
+
71
+ def adapter_name # :nodoc:
72
+ ADAPTER_NAME
13
73
  end
14
74
 
15
75
  def self.arel2_visitors(config)
16
- v = HSQLDB.arel2_visitors(config)
17
- v.merge({}.tap {|v| %w(h2 jdbch2).each {|a| v[a] = ::Arel::Visitors::HSQLDB } })
76
+ visitors = HSQLDB.arel2_visitors(config)
77
+ visitors.merge({
78
+ 'h2' => ::Arel::Visitors::HSQLDB,
79
+ 'jdbch2' => ::Arel::Visitors::HSQLDB,
80
+ })
18
81
  end
19
-
20
- def h2_adapter
82
+
83
+ # #deprecated
84
+ def h2_adapter # :nodoc:
21
85
  true
22
86
  end
23
87
 
88
+ NATIVE_DATABASE_TYPES = {
89
+ :primary_key => "integer GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY",
90
+ :boolean => { :name => "boolean" },
91
+ :tinyint => { :name => "tinyint", :limit => 1 },
92
+ :smallint => { :name => "smallint", :limit => 2 },
93
+ :bigint => { :name => "bigint", :limit => 8 },
94
+ :integer => { :name => "int", :limit => 4 },
95
+ :decimal => { :name => "decimal" },
96
+ :float => { :name => "float", :limit => 8 },
97
+ :double => { :name => "double", :limit => 8 },
98
+ :real => { :name => "real", :limit => 4 },
99
+ :date => { :name => "date" },
100
+ :time => { :name => "time" },
101
+ :timestamp => { :name => "timestamp" },
102
+ :binary => { :name => "binary" },
103
+ :string => { :name => "varchar", :limit => 255 },
104
+ :char => { :name => "char" },
105
+ :blob => { :name => "blob" },
106
+ :text => { :name => "clob" },
107
+ :clob => { :name => "clob" },
108
+ :uuid => { :name => "uuid" },
109
+ :other => { :name => "other" }, # java.lang.Object
110
+ :array => { :name => "array" }, # java.lang.Object[]
111
+ :varchar_casesensitive => { :name => 'VARCHAR_CASESENSITIVE' },
112
+ :varchar_ignorecase => { :name => 'VARCHAR_IGNORECASE' },
113
+ }
114
+
115
+ def native_database_types
116
+ NATIVE_DATABASE_TYPES.dup
117
+ end
118
+
119
+ def modify_types(types)
120
+ types
121
+ end
122
+
123
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
124
+ case type.to_sym
125
+ when :integer
126
+ case limit
127
+ when 1; 'tinyint'
128
+ when 2; 'smallint'
129
+ when nil, 3, 4; 'int'
130
+ when 5..8; 'bigint'
131
+ else raise(ActiveRecordError, "No integer type has byte size #{limit}")
132
+ end
133
+ when :float
134
+ case limit
135
+ when 1..4; 'real'
136
+ when 5..8; 'double'
137
+ else raise(ActiveRecordError, "No float type has byte size #{limit}")
138
+ end
139
+ when :binary
140
+ if limit && limit < 2 * 1024 * 1024
141
+ 'binary'
142
+ else
143
+ 'blob'
144
+ end
145
+ else
146
+ super
147
+ end
148
+ end
149
+
24
150
  def tables
25
151
  @connection.tables(nil, h2_schema)
26
152
  end
27
153
 
28
- def columns(table_name, name=nil)
154
+ def columns(table_name, name = nil)
29
155
  @connection.columns_internal(table_name.to_s, name, h2_schema)
30
156
  end
31
157
 
@@ -35,7 +161,35 @@ module ArJdbc
35
161
  change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
36
162
  end
37
163
 
164
+ def current_schema
165
+ execute('CALL SCHEMA()')[0].values[0]
166
+ end
167
+
168
+ def quote(value, column = nil) # :nodoc:
169
+ case value
170
+ when String
171
+ if value.empty?
172
+ "''"
173
+ else
174
+ super
175
+ end
176
+ else
177
+ super
178
+ end
179
+ end
180
+
181
+ # EXPLAIN support :
182
+
183
+ def supports_explain?; true; end
184
+
185
+ def explain(arel, binds = [])
186
+ sql = "EXPLAIN #{to_sql(arel, binds)}"
187
+ raw_result = execute(sql, "EXPLAIN", binds)
188
+ raw_result[0].values.join("\n") # [ "SELECT \n ..." ].to_s
189
+ end
190
+
38
191
  private
192
+
39
193
  def change_column_null(table_name, column_name, null, default = nil)
40
194
  if !null && !default.nil?
41
195
  execute("UPDATE #{table_name} SET #{column_name}=#{quote(default)} WHERE #{column_name} IS NULL")
@@ -50,5 +204,6 @@ module ArJdbc
50
204
  def h2_schema
51
205
  @config[:schema] || ''
52
206
  end
207
+
53
208
  end
54
209
  end
@@ -2,7 +2,11 @@ module ActiveRecord
2
2
  class Base
3
3
  class << self
4
4
  def h2_connection(config)
5
- require 'active_record/connection_adapters/jdbch2_adapter'
5
+ begin
6
+ require 'jdbc/h2'
7
+ ::Jdbc::H2.load_driver(:require) if defined?(::Jdbc::H2.load_driver)
8
+ rescue LoadError # assuming driver.jar is on the class-path
9
+ end
6
10
 
7
11
  config[:url] ||= "jdbc:h2:#{config[:database]}"
8
12
  config[:driver] ||= defined?(::Jdbc::H2.driver_name) ? ::Jdbc::H2.driver_name : 'org.h2.Driver'
@@ -1,3 +1,3 @@
1
1
  require 'arjdbc/jdbc'
2
- require 'arjdbc/hsqldb/connection_methods'
3
2
  require 'arjdbc/hsqldb/adapter'
3
+ require 'arjdbc/hsqldb/connection_methods'
@@ -1,65 +1,105 @@
1
- module ::ArJdbc
1
+ require 'arjdbc/hsqldb/explain_support'
2
+
3
+ module ArJdbc
2
4
  module HSQLDB
5
+ include ExplainSupport
6
+
3
7
  def self.column_selector
4
- [/hsqldb|\.h2\./i, lambda {|cfg,col| col.extend(::ArJdbc::HSQLDB::Column)}]
8
+ [ /hsqldb/i, lambda { |cfg, column| column.extend(::ArJdbc::HSQLDB::Column) } ]
5
9
  end
6
10
 
7
11
  module Column
12
+
8
13
  private
14
+
15
+ def extract_limit(sql_type)
16
+ limit = super
17
+ case @sql_type = sql_type.downcase
18
+ when /^tinyint/i then @sql_type = 'tinyint'; limit = 1
19
+ when /^smallint/i then @sql_type = 'smallint'; limit = 2
20
+ when /^bigint/i then @sql_type = 'bigint'; limit = 8
21
+ when /^double/i then @sql_type = 'double'; limit = 8
22
+ when /^real/i then @sql_type = 'real'; limit = 8
23
+ # NOTE: once again we get incorrect "limits" from HypesSQL's JDBC
24
+ # thus yet again we need to fix incorrectly detected limits :
25
+ when /^integer/i then @sql_type = 'integer'; limit = 4
26
+ when /^float/i then @sql_type = 'float'; limit = 8
27
+ when /^decimal/i then @sql_type = 'decimal';
28
+ when /^datetime/i then @sql_type = 'datetime'; limit = nil
29
+ when /^timestamp/i then @sql_type = 'timestamp'; limit = nil
30
+ when /^time/i then @sql_type = 'time'; limit = nil
31
+ when /^date/i then @sql_type = 'date'; limit = nil
32
+ else
33
+ # HSQLDB appears to return "LONGVARCHAR(0)" for :text columns,
34
+ # which for AR purposes should be interpreted as "no limit" :
35
+ limit = nil if sql_type =~ /\(0\)$/
36
+ end
37
+ limit
38
+ end
39
+
9
40
  def simplified_type(field_type)
10
41
  case field_type
11
42
  when /longvarchar/i then :text
12
- when /tinyint/i then :boolean
13
- when /real/i then :float
43
+ when /int/i then :integer # TINYINT, SMALLINT, BIGINT, INT
44
+ when /real|double/i then :float
45
+ when /bit/i then :boolean
46
+ when /binary/i then :binary # VARBINARY, LONGVARBINARY
14
47
  else
15
48
  super
16
49
  end
17
50
  end
18
-
19
- # Override of ActiveRecord::ConnectionAdapters::Column
20
- def extract_limit(sql_type)
21
- # HSQLDB appears to return "LONGVARCHAR(0)" for :text columns, which
22
- # for AR purposes should be interpreted as "no limit"
23
- return nil if sql_type =~ /\(0\)/
24
- super
25
- end
26
-
51
+
27
52
  # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
28
53
  def default_value(value)
29
- # H2 auto-generated key default value
30
- return nil if value =~ /^\(NEXT VALUE FOR/i
31
-
32
- # jdbc returns column default strings with actual single quotes around the value.
54
+ # JDBC returns column default strings with actual single quotes around the value.
33
55
  return $1 if value =~ /^'(.*)'$/
34
-
35
56
  value
36
57
  end
58
+
37
59
  end
38
60
 
39
- def adapter_name #:nodoc:
40
- 'Hsqldb'
61
+ ADAPTER_NAME = 'HSQLDB' # :nodoc:
62
+
63
+ def adapter_name # :nodoc:
64
+ ADAPTER_NAME
41
65
  end
42
66
 
43
67
  def self.arel2_visitors(config)
44
68
  require 'arel/visitors/hsqldb'
45
- {}.tap {|v| %w(hsqldb jdbchsqldb).each {|a| v[a] = ::Arel::Visitors::HSQLDB } }
46
- end
47
-
48
- def modify_types(tp)
49
- tp[:primary_key] = "INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY"
50
- tp[:integer][:limit] = nil
51
- tp[:boolean][:limit] = nil
52
- # set text and float limits so we don't see odd scales tacked on
53
- # in migrations
54
- tp[:boolean] = { :name => "tinyint" }
55
- tp[:text][:limit] = nil
56
- tp[:float][:limit] = 17 if defined?(::Jdbc::H2)
57
- tp[:string][:limit] = 255
58
- tp[:datetime] = { :name => "DATETIME" }
59
- tp[:timestamp] = { :name => "DATETIME" }
60
- tp[:time] = { :name => "TIME" }
61
- tp[:date] = { :name => "DATE" }
62
- tp
69
+ {
70
+ 'hsqldb' => ::Arel::Visitors::HSQLDB,
71
+ 'jdbchsqldb' => ::Arel::Visitors::HSQLDB,
72
+ }
73
+ end
74
+
75
+ NATIVE_DATABASE_TYPES = {
76
+ :primary_key => "integer GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY",
77
+ :string => { :name => "varchar", :limit => 255 },
78
+ :text => { :name => "clob" },
79
+ :binary => { :name => "blob" },
80
+ :boolean => { :name => "boolean" },
81
+ :integer => { :name => "integer", :limit => 4 },
82
+ :float => { :name => "float", :limit => 8 },
83
+ # NOTE: fix incorrectly detected limits :
84
+ :tinyint => { :name => "tinyint", :limit => 1 },
85
+ :smallint => { :name => "smallint", :limit => 2 },
86
+ :bigint => { :name => "bigint", :limit => 8 },
87
+ :double => { :name => "double", :limit => 8 },
88
+ :real => { :name => "real", :limit => 8 },
89
+ }
90
+
91
+ def native_database_types
92
+ super.merge NATIVE_DATABASE_TYPES
93
+ end
94
+
95
+ def modify_types(types)
96
+ super(types)
97
+ types[:primary_key] = NATIVE_DATABASE_TYPES[:primary_key]
98
+ types[:string] = NATIVE_DATABASE_TYPES[:string].dup
99
+ #types[:integer][:limit] = nil
100
+ #types[:boolean][:limit] = nil
101
+ types[:text][:limit] = nil
102
+ types
63
103
  end
64
104
 
65
105
  def quote(value, column = nil) # :nodoc:
@@ -67,22 +107,27 @@ module ::ArJdbc
67
107
 
68
108
  case value
69
109
  when String
70
- if respond_to?(:h2_adapter) && value.empty?
71
- "''"
72
- elsif column && column.type == :binary
110
+ column_type = column && column.type
111
+ if column_type == :binary
73
112
  "X'#{value.unpack("H*")[0]}'"
74
- elsif column && (column.type == :integer ||
75
- column.respond_to?(:primary) && column.primary && column.klass != String)
113
+ elsif column_type == :integer ||
114
+ column.respond_to?(:primary) && column.primary && column.klass != String
76
115
  value.to_i.to_s
77
116
  else
78
117
  "'#{quote_string(value)}'"
79
118
  end
119
+ when Time
120
+ if column && column.type == :time
121
+ "'#{value.strftime("%H:%M:%S")}'"
122
+ else
123
+ super
124
+ end
80
125
  else
81
126
  super
82
127
  end
83
128
  end
84
129
 
85
- def quote_column_name(name) #:nodoc:
130
+ def quote_column_name(name) # :nodoc:
86
131
  name = name.to_s
87
132
  if name =~ /[-]/
88
133
  %Q{"#{name.upcase}"}
@@ -91,18 +136,6 @@ module ::ArJdbc
91
136
  end
92
137
  end
93
138
 
94
- def quote_string(str)
95
- str.gsub(/'/, "''")
96
- end
97
-
98
- def quoted_true
99
- '1'
100
- end
101
-
102
- def quoted_false
103
- '0'
104
- end
105
-
106
139
  def add_column(table_name, column_name, type, options = {})
107
140
  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])}"
108
141
  add_column_options!(add_column_sql, options)
@@ -139,8 +172,9 @@ module ::ArJdbc
139
172
 
140
173
  def _execute(sql, name = nil)
141
174
  result = super
142
- ActiveRecord::ConnectionAdapters::JdbcConnection::insert?(sql) ? last_insert_id : result
175
+ self.class.insert?(sql) ? last_insert_id : result
143
176
  end
177
+ private :_execute
144
178
 
145
179
  def add_limit_offset!(sql, options) #:nodoc:
146
180
  if sql =~ /^select/i
@@ -154,14 +188,14 @@ module ::ArJdbc
154
188
  end
155
189
  end
156
190
 
157
- # override to filter out system tables that otherwise end
158
- # up in db/schema.rb during migrations. JdbcConnection#tables
191
+ # filter out system tables (that otherwise end up in db/schema.rb)
192
+ # JdbcConnection#tables
159
193
  # now takes an optional block filter so we can screen out
160
194
  # rows corresponding to system tables. HSQLDB names its
161
195
  # system tables SYSTEM.*, but H2 seems to name them without
162
196
  # any kind of convention
163
197
  def tables
164
- @connection.tables.select {|row| row.to_s !~ /^system_/i }
198
+ @connection.tables.select { |row| row.to_s !~ /^system_/i }
165
199
  end
166
200
 
167
201
  def remove_index(table_name, options = {})
@@ -180,6 +214,7 @@ module ::ArJdbc
180
214
 
181
215
  def drop_database(name)
182
216
  execute("DROP ALL OBJECTS")
183
- end
217
+ end
218
+
184
219
  end
185
220
  end