3 def self.column_selector
4 [/hsqldb|\.h2\./i, lambda {|cfg,col| col.extend(::ArJdbc::HSQLDB::Column)}]
9 def simplified_type(field_type)
11 when /longvarchar/i then :text
12 when /tinyint/i then :boolean
13 when /real/i then :float
14 when /decimal/i then :decimal
20 # Override of ActiveRecord::ConnectionAdapters::Column
21 def extract_limit(sql_type)
22 # HSQLDB appears to return "LONGVARCHAR(0)" for :text columns, which
23 # for AR purposes should be interpreted as "no limit"
24 return nil if sql_type =~ /\(0\)/
28 # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
29 def default_value(value)
30 # jdbc returns column default strings with actual single quotes around the value.
31 return $1 if value =~ /^'(.*)'$/
37 def adapter_name #:nodoc:
42 require 'arel/visitors/hsqldb'
43 {'hsqldb' => ::Arel::Visitors::HSQLDB, 'jdbchsqldb' => ::Arel::Visitors::HSQLDB}
47 tp[:primary_key] = "INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY"
48 tp[:integer][:limit] = nil
49 tp[:boolean][:limit] = nil
50 # set text and float limits so we don't see odd scales tacked on
52 tp[:boolean] = { :name => "tinyint" }
53 tp[:text][:limit] = nil
54 tp[:float][:limit] = 17 if defined?(::Jdbc::H2)
55 tp[:string][:limit] = 255
56 tp[:datetime] = { :name => "DATETIME" }
57 tp[:timestamp] = { :name => "DATETIME" }
58 tp[:time] = { :name => "TIME" }
59 tp[:date] = { :name => "DATE" }
63 def quote(value, column = nil) # :nodoc:
64 return value.quoted_id if value.respond_to?(:quoted_id)
68 if respond_to?(:h2_adapter) && value.empty?
70 elsif column && column.type == :binary
71 "'#{value.unpack("H*")}'"
72 elsif column && (column.type == :integer ||
73 column.respond_to?(:primary) && column.primary && column.klass != String)
76 "'#{quote_string(value)}'"
83 def quote_column_name(name) #:nodoc:
104 def add_column(table_name, column_name, type, options = {})
105 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])}"
106 add_column_options!(add_column_sql, options)
107 execute(add_column_sql)
110 def change_column(table_name, column_name, type, options = {}) #:nodoc:
111 execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
114 def change_column_default(table_name, column_name, default) #:nodoc:
115 execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT #{quote(default)}"
118 def rename_column(table_name, column_name, new_column_name) #:nodoc:
119 execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} RENAME TO #{new_column_name}"
122 # Maps logical Rails types to MySQL-specific data types.
123 def type_to_sql(type, limit = nil, precision = nil, scale = nil)
124 return super if defined?(::Jdbc::H2) || type.to_s != 'integer' || limit == nil
129 def rename_table(name, new_name)
130 execute "ALTER TABLE #{name} RENAME TO #{new_name}"
134 Integer(select_value("CALL IDENTITY()"))
137 def _execute(sql, name = nil)
139 ActiveRecord::ConnectionAdapters::JdbcConnection::insert?(sql) ? last_insert_id : result
142 def add_limit_offset!(sql, options) #:nodoc:
144 offset = options[:offset] || 0
146 if limit = options[:limit]
147 sql.replace "SELECT LIMIT #{offset} #{limit} #{bef}"
149 sql.replace "SELECT LIMIT #{offset} 0 #{bef}"
154 # override to filter out system tables that otherwise end
155 # up in db/schema.rb during migrations. JdbcConnection#tables
156 # now takes an optional block filter so we can screen out
157 # rows corresponding to system tables. HSQLDB names its
158 # system tables SYSTEM.*, but H2 seems to name them without
159 # any kind of convention
161 @connection.tables.select {|row| row.to_s !~ /^system_/i }
164 def remove_index(table_name, options = {})
165 execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}"
168 def recreate_database(name)
172 # do nothing since database gets created upon connection. However
173 # this method gets called by rails db rake tasks so now we're
174 # avoiding method_missing error
175 def create_database(name)
178 def drop_database(name)
179 execute("DROP ALL OBJECTS")