public function select($cols = null, $where = true, $order = null, $limit = null)
    {
        if ($this->map) {
            $cols = $this->map->cols($cols);
            $where = $this->map->where($where);
            $order = $this->map->order($order);
        }
        if ($cols === null) {
            $cols = true;
        }
        if ($this->fake) {
            $result = $this->fake->select($cols, $where, $order, $limit);
            if ($this->map) {
                return new ArrFetcher($this->map->assoc($result));
            }
            return $result;
        }
        $pattern = 'SELECT ?cols FROM ?t WHERE ?w';
        $data = array($cols, $this->name, $where);
        if ($order !== null) {
            $pattern .= ' ORDER BY ?o';
            $data[] = $order;
        }
        if ($limit !== null) {
            if (is_array($limit)) {
                $offset = isset($limit[1]) ? $limit[1] : 0;
                $limit = $limit[0];
            } else {
                $offset = 0;
            }
            $pattern .= ' LIMIT ?i,?i';
            $data[] = $offset;
            $data[] = $limit;
        }
        $fetcher = $this->db->query($pattern, $data);
        if ($this->map) {
            $data = $fetcher->assoc();
            $data = $this->map->assoc($data);
            $fetcher = new ArrFetcher($data);
        }
        return $fetcher;
    }