module Sequel::JDBC::H2::DatabaseMethods

def alter_table_sql(table, op)

H2 needs to add a primary key column as a constraint
def alter_table_sql(table, op)
  case op[:op]
  when :add_column
    if (pk = op.delete(:primary_key)) || (ref = op.delete(:table))
      sqls = [super(table, op)]
      sqls << "ALTER TABLE #{quote_schema_table(table)} ADD PRIMARY KEY (#{quote_identifier(op[:name])})" if pk
      if ref
        op[:table] = ref
        sqls << "ALTER TABLE #{quote_schema_table(table)} ADD FOREIGN KEY (#{quote_identifier(op[:name])}) #{column_references_sql(op)}"
      end
      sqls
    else
      super(table, op)
    end
  when :rename_column
    "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} RENAME TO #{quote_identifier(op[:new_name])}"
  when :set_column_null
    "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} SET#{' NOT' unless op[:null]} NULL"
  when :set_column_type
    if sch = schema(table)
      if cs = sch.each{|k, v| break v if k == op[:name]; nil}
        cs = cs.dup
        cs[:default] = cs[:ruby_default]
        op = cs.merge!(op)
      end
    end
    sql = "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} #{type_literal(op)}"
    column_definition_order.each{|m| send(:"column_definition_#{m}_sql", sql, op)}
    sql
  else
    super(table, op)
  end
end

def commit_prepared_transaction(transaction_id)

identifier string.
Commit an existing prepared transaction with the given transaction
def commit_prepared_transaction(transaction_id)
  run("COMMIT TRANSACTION #{transaction_id}")
end

def commit_transaction(conn, opts={})

prepare the transaction for a two-phase commit.
If the :prepare option is given and we aren't in a savepoint,
def commit_transaction(conn, opts={})
  if (s = opts[:prepare]) && @transactions[conn][:savepoint_level] <= 1
    log_connection_execute(conn, "PREPARE COMMIT #{s}")
  else
    super
  end
end

def connection_pool_default_options

Default to a single connection for a memory database.
def connection_pool_default_options
  o = super
  uri == 'jdbc:h2:mem:' ? o.merge(:max_connections=>1) : o
end

def database_type

H2 uses the :h2 database type.
def database_type
  :h2
end

def last_insert_id(conn, opts={})

Use IDENTITY() to get the last inserted id.
def last_insert_id(conn, opts={})
  statement(conn) do |stmt|
    sql = 'SELECT IDENTITY();'
    rs = log_yield(sql){stmt.executeQuery(sql)}
    rs.next
    rs.getInt(1)
  end
end

def primary_key_index_re

def primary_key_index_re
  PRIMARY_KEY_INDEX_RE
end

def rollback_prepared_transaction(transaction_id)

identifier string.
Rollback an existing prepared transaction with the given transaction
def rollback_prepared_transaction(transaction_id)
  run("ROLLBACK TRANSACTION #{transaction_id}")
end

def schema_column_type(db_type)

Treat clob as string instead of blob
def schema_column_type(db_type)
  db_type == 'clob' ? :string : super
end

def serial_primary_key_options

H2 uses an IDENTITY type
def serial_primary_key_options
  {:primary_key => true, :type => :identity}
end

def supports_create_table_if_not_exists?

H2 supports CREATE TABLE IF NOT EXISTS syntax.
def supports_create_table_if_not_exists?
  true
end

def supports_prepared_transactions?

H2 supports prepared transactions
def supports_prepared_transactions?
  true
end

def supports_savepoints?

H2 supports savepoints
def supports_savepoints?
  true
end