Skip to content
Snippets Groups Projects
class.orm.php 35.7 KiB
Newer Older
Jared Hancock's avatar
Jared Hancock committed
    // Returns meta data about the table used to build queries
    function inspectTable($table) {
    }
}

class MysqlExecutor {

    var $stmt;
    var $fields = array();

    var $sql;
    var $params;

    function __construct($sql, $params) {
        $this->sql = $sql;
        $this->params = $params;
    }

    function _prepare() {
        $this->execute();
        $this->_setup_output();
    }

    function execute() {
Jared Hancock's avatar
Jared Hancock committed
        if (!($this->stmt = db_prepare($this->sql)))
            throw new Exception('Unable to prepare query: '.db_error()
                .' '.$this->sql);
        if (count($this->params))
            $this->_bind($this->params);
        if (!$this->stmt->execute() || ! $this->stmt->store_result()) {
            throw new OrmException('Unable to execute query: ' . $this->stmt->error);
        }
        return true;
Jared Hancock's avatar
Jared Hancock committed
    }

    function _bind($params) {
        if (count($params) != $this->stmt->param_count)
            throw new Exception(__('Parameter count does not match query'));
Jared Hancock's avatar
Jared Hancock committed

        $types = '';
        $ps = array();
        foreach ($params as &$p) {
            if (is_int($p) || is_bool($p))
Jared Hancock's avatar
Jared Hancock committed
                $types .= 'i';
            elseif (is_float($p))
                $types .= 'd';
Jared Hancock's avatar
Jared Hancock committed
            elseif (is_string($p))
                $types .= 's';
            // TODO: Emit error if param is null
Jared Hancock's avatar
Jared Hancock committed
            $ps[] = &$p;
        }
Jared Hancock's avatar
Jared Hancock committed
        array_unshift($ps, $types);
        call_user_func_array(array($this->stmt,'bind_param'), $ps);
    }

    function _setup_output() {
        if (!($meta = $this->stmt->result_metadata()))
            throw new OrmException('Unable to fetch statment metadata: ', $this->stmt->error);
Jared Hancock's avatar
Jared Hancock committed
        while ($f = $meta->fetch_field())
            $this->fields[] = $f;
        $meta->free_result();
Jared Hancock's avatar
Jared Hancock committed
    }

    // Iterator interface
    function rewind() {
        if (!isset($this->stmt))
            $this->_prepare();
        $this->stmt->data_seek(0);
    }

    function next() {
        $status = $this->stmt->fetch();
        if ($status === false)
            throw new OrmException($this->stmt->error);
Jared Hancock's avatar
Jared Hancock committed
        elseif ($status === null) {
            $this->close();
            return false;
        }
        return true;
    }

    function getArray() {
        $output = array();
        $variables = array();

        if (!isset($this->stmt))
            $this->_prepare();

        foreach ($this->fields as $f)
            $variables[] = &$output[$f->name]; // pass by reference

        if (!call_user_func_array(array($this->stmt, 'bind_result'), $variables))
            throw new OrmException('Unable to bind result: ' . $this->stmt->error);

Jared Hancock's avatar
Jared Hancock committed
        if (!$this->next())
            return false;
        return $output;
    }

    function getRow() {
        $output = array();
        $variables = array();

        if (!isset($this->stmt))
            $this->_prepare();

        foreach ($this->fields as $f)
            $variables[] = &$output[]; // pass by reference

        if (!call_user_func_array(array($this->stmt, 'bind_result'), $variables))
            throw new OrmException('Unable to bind result: ' . $this->stmt->error);

        if (!$this->next())
            return false;
        return $output;
    }

    function getStruct() {
        $output = array();
        $variables = array();

        if (!isset($this->stmt))
            $this->_prepare();

        foreach ($this->fields as $f)
            $variables[] = &$output[$f->table][$f->name]; // pass by reference

        // TODO: Figure out what the table alias for the root model will be
        call_user_func_array(array($this->stmt, 'bind_result'), $variables);
        if (!$this->next())
            return false;
        return $output;
    }

Jared Hancock's avatar
Jared Hancock committed
    function close() {
        if (!$this->stmt)
            return;

        $this->stmt->close();
        $this->stmt = null;
    }

    function affected_rows() {
        return $this->stmt->affected_rows;
    }

    function insert_id() {
        return $this->stmt->insert_id;
    }

Jared Hancock's avatar
Jared Hancock committed
    function __toString() {
        return $this->sql;
    }
}
?>