module Swift
  module DB
    class Mysql < Adapter
      def initialize options = {}
        super options.update(driver: 'mysql')
      end

      def returning?
        false
      end
    end # Mysql

    class Postgres < Adapter
      def initialize options = {}
        super options.update(driver: 'postgresql')
      end

      def returning?
        true
      end

      def field_type attribute
        case attribute
          when Type::IO then 'bytea'
          else super
        end
      end
    end # Postgres

    class DB2 < Adapter
      def initialize options = {}
        super options.update(driver: 'db2')
      end

      def returning?
        false
      end

      def migrate!
        keys   =  scheme.header.keys
        fields =  scheme.header.map{|p| field_definition(p)}.join(', ')
        fields += ", primary key (#{keys.join(', ')})" unless keys.empty?

        sql = <<-SQL
          select count(*) as exists from syscat.tables
          where tabschema = CURRENT_SCEMA and tabname = '#{scheme.store.upcase}'
        SQL

        execute(sql) {|result| execute("drop table #{scheme.store}") if result[:exists] > 0 }
        execute("create table #{scheme.store} (#{fields})")
      end

      def field_type attribute
        case attribute
          when Type::String     then 'clob(2g)'
          when Type::Integer    then attribute.serial ? 'integer not null generated by default as identity' : 'integer'
          when Type::Boolean    then 'char(1)'
          when Type::Float      then 'real'
          when Type::BigDecimal then 'double'
          else super
        end
      end

      def prepare_create scheme
        prepare_cached(scheme, :create) do
          values = (['?'] * scheme.header.insertable.size).join(', ')
          sql    = "insert into #{scheme.store} (#{scheme.header.insertable.join(', ')}) values (#{values})"
          scheme.header.serial ? "select #{scheme.header.serial} from final table (#{sql})" : sql
        end
      end
    end # DB2
  end # DB
end # Swift
