require 'mysql'
require 'criteria/sql'

module Criteria
  class MysqlTable < SQLTable
    attr_reader :_db

    def initialize(db, table, typemap = nil)
      super(table)
      @criterion_type = MysqlCriterion
      @_typemap       = typemap
      @_db            = db
    end #m:initialize


    def MysqlTable.create(db, table, *args)
      sql = super(table, *args)

      begin
        db.query(sql)
      rescue MysqlError => e
        raise unless e.message =~ /Table '#{table}' already exists/
      end

      tbl = MysqlTable.new(db, table)
      tbl._store_cols(args)
      return tbl
    end #m:MysqlTable.create


    def MysqlTable.drop(db, table)
      db.query(super(table.to_s))
    end #m:MysqlTable.drop


    def insert(h, *args)
      @_db.query(super)
    end #m:insert


    def MysqlTable.translate_item(item)
      case item
      when String; super(Mysql.quote(item))
      else super
      end
    end #m:MysqlTable.translate_item

    class << self; alias :get :new; end
  end #c:MysqlTable


  class MysqlCriterion < SQLCriterion
    def select(*args)
      return @_parent._db.query(super)
    end #m:select

    def select_parse(*args)
      return MysqlParsedRes.new(self._parent, args, select(*args))
    end #m:select_parse

    def delete(*args)
      return @_parent._db.query(super)
    end #m:delete

    def update(*args)
      return @_parent._db.query(super)
    end #m:update

    def _translate_fn(op)
      case op
      when :=~;   "RLIKE"
      when :"!~"; "NOT RLIKE"
      else super
      end
    end #m:_translate_fn
  end #c:MysqlCriterion


  class MysqlParsedRes
    attr_reader :res

    def initialize(tbl, cols, res)
      @tbl  = tbl
      @res  = res
      @cols = cols.select { |x| x if x.is_a? Symbol }
    end #m:initialize

    def each
      @res.each { |x| yield @tbl._parse_row(@cols, x) }
    end #m:each

    def to_a
      list = []
      self.each { |a| list << a }
      list
    end #m:to_a

    def num_rows
      @res.num_rows
    end #m:num_rows
  end #c:MysqlParsedRes
end

