DB\SQL\Mapper::select PHP 메소드

select() 공개 메소드

Build query string and execute
public select ( $fields, $filter = NULL, array $options = NULL, $ttl ) : static[]
$fields string
$filter string|array
$options array array
$ttl int|array
리턴 static[]
    function select($fields, $filter = NULL, array $options = NULL, $ttl = 0)
    {
        if (!$options) {
            $options = [];
        }
        $options += ['group' => NULL, 'order' => NULL, 'limit' => 0, 'offset' => 0];
        $db = $this->db;
        $sql = 'SELECT ' . $fields . ' FROM ' . $this->table;
        $args = [];
        if (is_array($filter)) {
            $args = isset($filter[1]) && is_array($filter[1]) ? $filter[1] : array_slice($filter, 1, NULL, TRUE);
            $args = is_array($args) ? $args : [1 => $args];
            list($filter) = $filter;
        }
        if ($filter) {
            $sql .= ' WHERE ' . $filter;
        }
        if ($options['group']) {
            $sql .= ' GROUP BY ' . implode(',', array_map(function ($str) use($db) {
                return preg_replace_callback('/\\b(\\w+)\\h*(HAVING.+|$)/i', function ($parts) use($db) {
                    return $db->quotekey($parts[1]) . (isset($parts[2]) ? ' ' . $parts[2] : '');
                }, $str);
            }, explode(',', $options['group'])));
        }
        if ($options['order']) {
            $sql .= ' ORDER BY ' . implode(',', array_map(function ($str) use($db) {
                return preg_match('/^(\\w+)(?:\\h+(ASC|DESC))?\\h*(?:,|$)/i', $str, $parts) ? $db->quotekey($parts[1]) . (isset($parts[2]) ? ' ' . $parts[2] : '') : $str;
            }, explode(',', $options['order'])));
        }
        if (preg_match('/mssql|sqlsrv|odbc/', $this->engine) && ($options['limit'] || $options['offset'])) {
            $pkeys = [];
            foreach ($this->fields as $key => $field) {
                if ($field['pkey']) {
                    $pkeys[] = $key;
                }
            }
            $ofs = $options['offset'] ? (int) $options['offset'] : 0;
            $lmt = $options['limit'] ? (int) $options['limit'] : 0;
            if (strncmp($db->version(), '11', 2) >= 0) {
                // SQL Server 2012
                if (!$options['order']) {
                    $sql .= ' ORDER BY ' . $db->quotekey($pkeys[0]);
                }
                $sql .= ' OFFSET ' . $ofs . ' ROWS';
                if ($lmt) {
                    $sql .= ' FETCH NEXT ' . $lmt . ' ROWS ONLY';
                }
            } else {
                // SQL Server 2008
                $sql = str_replace('SELECT', 'SELECT ' . ($lmt > 0 ? 'TOP ' . ($ofs + $lmt) : '') . ' ROW_NUMBER() ' . 'OVER (ORDER BY ' . $db->quotekey($pkeys[0]) . ') AS rnum,', $sql);
                $sql = 'SELECT * FROM (' . $sql . ') x WHERE rnum > ' . $ofs;
            }
        } else {
            if ($options['limit']) {
                $sql .= ' LIMIT ' . (int) $options['limit'];
            }
            if ($options['offset']) {
                $sql .= ' OFFSET ' . (int) $options['offset'];
            }
        }
        $result = $this->db->exec($sql, $args, $ttl);
        $out = [];
        foreach ($result as &$row) {
            foreach ($row as $field => &$val) {
                if (array_key_exists($field, $this->fields)) {
                    if (!is_null($val) || !$this->fields[$field]['nullable']) {
                        $val = $this->db->value($this->fields[$field]['pdo_type'], $val);
                    }
                } elseif (array_key_exists($field, $this->adhoc)) {
                    $this->adhoc[$field]['value'] = $val;
                }
                unset($val);
            }
            $out[] = $this->factory($row);
            unset($row);
        }
        return $out;
    }