module Sequel::JDBC::Derby::DatabaseMethods

def _table_exists?(ds)

so use a SELECT * FROM table there.
Derby optimizes away Sequel's default check of SELECT NULL FROM table,
def _table_exists?(ds)
  ds.first
end

def alter_table_sql(table, op)

Derby-specific syntax for renaming columns and changing a columns type/nullity.
def alter_table_sql(table, op)
  case op[:op]
  when :rename_column
    "RENAME COLUMN #{quote_schema_table(table)}.#{quote_identifier(op[:name])} TO #{quote_identifier(op[:new_name])}"
  when :set_column_type
    # Derby is very limited in changing a columns type, so adding a new column and then dropping the existing column is
    # the best approach, as mentioned in the Derby documentation.
    temp_name = :x_sequel_temp_column_x
    [alter_table_sql(table, op.merge(:op=>:add_column, :name=>temp_name)),
     from(table).update_sql(temp_name=>::Sequel::SQL::Cast.new(op[:name], op[:type])),
     alter_table_sql(table, op.merge(:op=>:drop_column)),
     alter_table_sql(table, op.merge(:op=>:rename_column, :name=>temp_name, :new_name=>op[:name]))]
  when :set_column_null
    "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} #{op[:null] ? 'NULL' : 'NOT NULL'}"
  else
    super
  end
end

def cast_type_literal(type)

elsewhere.
This does add a bunch of extra spaces at the end, but those will be trimmed
and char(254) appears to have the widest support (with char(255) failing).
Derby doesn't support casting integer to varchar, only integer to char,
def cast_type_literal(type)
  (type == String) ? 'CHAR(254)' : super
end

def column_definition_null_sql(sql, column)

Derby doesn't allow specifying NULL for columns, only NOT NULL.
def column_definition_null_sql(sql, column)
  sql << " NOT NULL" if column.fetch(:null, column[:allow_null]) == false
end

def create_table_sql(name, generator, options)

Temporary table creation on Derby use DECLARE instead of CREATE.
def create_table_sql(name, generator, options)
  if options[:temp]
    "DECLARE GLOBAL TEMPORARY TABLE #{quote_identifier(name)} (#{column_list_sql(generator)}) NOT LOGGED"
  else
    super
  end
end

def database_type

Derby uses the :derby database type.
def database_type
  :derby
end

def last_insert_id(conn, opts={})

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

def primary_key_index_re

Primary key indexes appear to be named sqlNNNN on Derby
def primary_key_index_re
  PRIMARY_KEY_INDEX_RE
end

def rename_table_sql(name, new_name)

Derby uses RENAME TABLE syntax to rename tables.
def rename_table_sql(name, new_name)
  "RENAME TABLE #{quote_schema_table(name)} TO #{quote_schema_table(new_name)}"
end

def serial_primary_key_options

Derby uses an IDENTITY sequence for autoincrementing columns.
def serial_primary_key_options
  {:primary_key => true, :type => :integer, :identity=>true, :start_with=>1}
end

def svn_version

The SVN version of the database.
def svn_version
  @svn_version ||= begin
    v = synchronize{|c| c.get_meta_data.get_database_product_version}
    v =~ /\((\d+)\)\z/
    $1.to_i
  end
end

def type_literal(column)

If an :identity option is present in the column, add the necessary IDENTITY SQL.
def type_literal(column)
  if column[:identity]
    sql = "#{super} GENERATED BY DEFAULT AS IDENTITY"
    if sw = column[:start_with]
      sql << " (START WITH #{sw.to_i}"
      sql << " INCREMENT BY #{column[:increment_by].to_i}" if column[:increment_by]
      sql << ")"
    end
    sql
  else
    super
  end
end