Module: ArJdbc::HSQLDB

Includes:
ExplainSupport
Included in:
ActiveRecord::ConnectionAdapters::HsqldbAdapter, H2
Defined in:
lib/arjdbc/hsqldb/adapter.rb,
lib/arjdbc/hsqldb/explain_support.rb,
lib/arjdbc/hsqldb/schema_creation.rb

Defined Under Namespace

Modules: Column, ExplainSupport

Constant Summary collapse

ADAPTER_NAME =
'HSQLDB'.freeze
NATIVE_DATABASE_TYPES =
{
  :primary_key => "integer GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY",
  :string => { :name => "varchar", :limit => 255 }, # :limit => 2147483647
  :text => { :name => "clob" },
  :binary => { :name => "blob" },
  :boolean => { :name => "boolean" }, # :name => "tinyint", :limit => 1
  :bit => { :name=>"bit" }, # stored as 0/1 on HSQLDB 2.2 (translates true/false)
  :integer => { :name => "integer", :limit => 4 },
  :decimal => { :name => "decimal" }, # :limit => 2147483647
  :numeric => { :name => "numeric" }, # :limit => 2147483647
  # NOTE: fix incorrectly detected limits :
  :tinyint => { :name => "tinyint", :limit => 1 },
  :smallint => { :name => "smallint", :limit => 2 },
  :bigint => { :name => "bigint", :limit => 8 },
  :float => { :name => "float" },
  :double => { :name => "double", :limit => 8 },
  :real => { :name => "real", :limit => 8 },
  :date => { :name=>"date" },
  :time => { :name=>"time" },
  :timestamp => { :name=>"timestamp" },
  :datetime => { :name=>"timestamp" },
  :other => { :name=>"other" },
  # NOTE: would be great if AR allowed as to refactor as :
  #   t.column :string, :ignorecase => true
  :character => { :name => "character" },
  :varchar_ignorecase => { :name => "varchar_ignorecase" },
}
SchemaCreation =
::ActiveRecord::ConnectionAdapters::AbstractAdapter::SchemaCreation

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ExplainSupport

#explain, #supports_explain?

Class Method Details

.arel_visitor_type(config = nil) ⇒ Object



68
69
70
# File 'lib/arjdbc/hsqldb/adapter.rb', line 68

def self.arel_visitor_type(config = nil)
  require 'arel/visitors/hsqldb'; ::Arel::Visitors::HSQLDB
end

.column_selectorObject

See Also:

  • ActiveRecord::ConnectionAdapters::JdbcColumn#column_types


10
11
12
# File 'lib/arjdbc/hsqldb/adapter.rb', line 10

def self.column_selector
  [ /hsqldb/i, lambda { |config, column| column.extend(Column) } ]
end

Instance Method Details

#adapter_nameObject



74
75
76
# File 'lib/arjdbc/hsqldb/adapter.rb', line 74

def adapter_name
  ADAPTER_NAME
end

#add_column(table_name, column_name, type, options = {}) ⇒ Object



166
167
168
169
170
# File 'lib/arjdbc/hsqldb/adapter.rb', line 166

def add_column(table_name, column_name, type, options = {})
  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])}"
  add_column_options!(add_column_sql, options)
  execute(add_column_sql)
end

#add_limit_offset!(sql, options) ⇒ Object

Note:

Only used with (non-AREL) ActiveRecord 2.3.

See Also:

  • Arel::Visitors::HSQLDB#limit_offset


216
217
218
219
220
221
222
223
224
225
# File 'lib/arjdbc/hsqldb/adapter.rb', line 216

def add_limit_offset!(sql, options)
  if sql =~ /^select/i
    offset = options[:offset] || 0
    if limit = options[:limit]
      sql.replace "SELECT LIMIT #{offset} #{limit} #{sql[7..-1]}"
    elsif offset > 0
      sql.replace "SELECT LIMIT #{offset} 0 #{sql[7..-1]}"
    end
  end
end

#change_column(table_name, column_name, type, options = {}) ⇒ Object



173
174
175
# File 'lib/arjdbc/hsqldb/adapter.rb', line 173

def change_column(table_name, column_name, type, options = {})
  execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
end

#change_column_default(table_name, column_name, default) ⇒ Object

:nodoc:



177
178
179
# File 'lib/arjdbc/hsqldb/adapter.rb', line 177

def change_column_default(table_name, column_name, default) #:nodoc:
  execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT #{quote(default)}"
end

#empty_insert_statement_valueObject



228
229
230
231
232
# File 'lib/arjdbc/hsqldb/adapter.rb', line 228

def empty_insert_statement_value
  # on HSQLDB only work with tables that have a default value for each
  # and every column ... you'll need to avoid `Model.create!` on 4.0
  'DEFAULT VALUES'
end

#last_insert_idObject



202
203
204
205
# File 'lib/arjdbc/hsqldb/adapter.rb', line 202

def last_insert_id
  identity = select_value("CALL IDENTITY()")
  Integer(identity.nil? ? 0 : identity)
end

#native_database_typesObject



107
108
109
# File 'lib/arjdbc/hsqldb/adapter.rb', line 107

def native_database_types
  NATIVE_DATABASE_TYPES
end

#quote(value, column = nil) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/arjdbc/hsqldb/adapter.rb', line 112

def quote(value, column = nil)
  return value.quoted_id if value.respond_to?(:quoted_id)
  return value if sql_literal?(value)

  case value
  when String
    column_type = column && column.type
    if column_type == :binary
      "X'#{value.unpack("H*")[0]}'"
    elsif column_type == :integer ||
        column.respond_to?(:primary) && column.primary && column.klass != String
      value.to_i.to_s
    else
      "'#{quote_string(value)}'"
    end
  when Time
    column_type = column && column.type
    if column_type == :time
      "'#{value.strftime("%H:%M:%S")}'"
    #elsif column_type == :timestamp # || column_type == :datetime
      #value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
      #"'#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{sprintf("%06d", value.usec)}'"
    else
      super
    end
  else
    super
  end
end

#quote_column_name(name) ⇒ Object



156
157
158
159
160
161
162
163
# File 'lib/arjdbc/hsqldb/adapter.rb', line 156

def quote_column_name(name)
  name = name.to_s
  if name =~ /[-]/
    %Q{"#{name.upcase}"}
  else
    name
  end
end

#quoted_date(value) ⇒ Object

Quote date/time values for use in SQL input. Includes microseconds if the value is a Time responding to usec.



145
146
147
148
149
150
151
152
153
# File 'lib/arjdbc/hsqldb/adapter.rb', line 145

def quoted_date(value)
  if value.acts_like?(:time) && value.respond_to?(:usec)
    usec = sprintf("%06d", value.usec)
    value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
    "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}"
  else
    super
  end
end

#remove_index(table_name, options = {}) ⇒ Object



241
242
243
# File 'lib/arjdbc/hsqldb/adapter.rb', line 241

def remove_index(table_name, options = {})
  execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}"
end

#rename_column(table_name, column_name, new_column_name) ⇒ Object



182
183
184
# File 'lib/arjdbc/hsqldb/adapter.rb', line 182

def rename_column(table_name, column_name, new_column_name) #:nodoc:
  execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} RENAME TO #{new_column_name}"
end

#rename_table(name, new_name) ⇒ Object



193
194
195
# File 'lib/arjdbc/hsqldb/adapter.rb', line 193

def rename_table(name, new_name)
  execute "ALTER TABLE #{name} RENAME TO #{new_name}"
end

#schema_creationObject



6
7
8
# File 'lib/arjdbc/hsqldb/schema_creation.rb', line 6

def schema_creation
  SchemaCreation.new self
end

#shutdownObject



266
267
268
# File 'lib/arjdbc/hsqldb/adapter.rb', line 266

def shutdown
  execute 'SHUTDOWN'
end

#structure_dumpObject



249
250
251
252
253
254
255
256
257
258
259
# File 'lib/arjdbc/hsqldb/adapter.rb', line 249

def structure_dump
  execute('SCRIPT').map do |result|
    # [ { 'command' => SQL }, { 'command' ... }, ... ]
    case sql = result.first[1] # ['command']
    when /CREATE USER SA PASSWORD DIGEST .*?/i then nil
    when /CREATE SCHEMA PUBLIC AUTHORIZATION DBA/i then nil
    when /GRANT DBA TO SA/i then nil
    else sql
    end
  end.compact.join("\n\n")
end

#structure_load(dump) ⇒ Object

See Also:



262
263
264
# File 'lib/arjdbc/hsqldb/adapter.rb', line 262

def structure_load(dump)
  dump.each_line("\n\n") { |ddl| execute(ddl) }
end

#supports_views?Boolean

Returns:

  • (Boolean)


246
# File 'lib/arjdbc/hsqldb/adapter.rb', line 246

def supports_views?; true end

#tablesObject

We filter out HSQLDB's system tables (named "SYSTEM.*").



236
237
238
# File 'lib/arjdbc/hsqldb/adapter.rb', line 236

def tables
  @connection.tables.select { |row| row.to_s !~ /^system_/i }
end

#truncate(table_name, name = nil) ⇒ Object

Note:

AR API since 4.2



198
199
200
# File 'lib/arjdbc/hsqldb/adapter.rb', line 198

def truncate(table_name, name = nil)
  execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
end

#type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object



187
188
189
190
# File 'lib/arjdbc/hsqldb/adapter.rb', line 187

def type_to_sql(type, limit = nil, precision = nil, scale = nil)
  return super if defined?(::Jdbc::H2) || type.to_s != 'integer' || limit == nil
  type
end