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

.column_selectorObject

See Also:

  • ActiveRecord::ConnectionAdapters::JdbcColumn#column_types


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

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

Instance Method Details

#adapter_nameObject



70
71
72
# File 'lib/arjdbc/hsqldb/adapter.rb', line 70

def adapter_name
  ADAPTER_NAME
end

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



162
163
164
165
166
# File 'lib/arjdbc/hsqldb/adapter.rb', line 162

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.



212
213
214
215
216
217
218
219
220
221
# File 'lib/arjdbc/hsqldb/adapter.rb', line 212

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



169
170
171
# File 'lib/arjdbc/hsqldb/adapter.rb', line 169

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:



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

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



224
225
226
227
228
# File 'lib/arjdbc/hsqldb/adapter.rb', line 224

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



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

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

#native_database_typesObject



103
104
105
# File 'lib/arjdbc/hsqldb/adapter.rb', line 103

def native_database_types
  NATIVE_DATABASE_TYPES
end

#quote(value, column = nil) ⇒ Object



108
109
110
111
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
# File 'lib/arjdbc/hsqldb/adapter.rb', line 108

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



152
153
154
155
156
157
158
159
# File 'lib/arjdbc/hsqldb/adapter.rb', line 152

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.



141
142
143
144
145
146
147
148
149
# File 'lib/arjdbc/hsqldb/adapter.rb', line 141

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



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

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



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

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



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

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



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

def shutdown
  execute 'SHUTDOWN'
end

#structure_dumpObject



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

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:



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

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

#supports_foreign_keys?Boolean

Returns:

  • (Boolean)


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

def supports_foreign_keys?; true end

#supports_views?Boolean

Returns:

  • (Boolean)


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

def supports_views?; true end

#tablesObject

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



232
233
234
# File 'lib/arjdbc/hsqldb/adapter.rb', line 232

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

#truncate(table_name, name = nil) ⇒ Object

Note:

AR API since 4.2



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

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



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

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