Location: PHPKode > projects > Movim > movim-0.5/system/Datajar/drivers/DatajarEngineMysql.php
<?php

/**
 * @file DatajarEngine.php
 *
 * @brief Implements a datajar driver for sqlite.
 *
 * Copyright © 2012 Guillaume Pasquet
 *
 * This file is part of Datajar.
 *
 * Datajar is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 *
 * Datajar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Datajar.  If not, see <http://www.gnu.org/licenses/>.
 */

class DatajarEngineMysql extends DatajarEngineBase
{
    protected $db;

    // Loading config and attempting to connect.
    public function __construct($conn = "")
    {
        $args = func_get_args();
        if($conn != "") {
            $this->init($conn);
        }
    }

    public function init($conn_string)
    {
        $conn = $this->parse_conn_string($conn_string);
        // OK, trying to open the file.
        $this->db = mysql_connect($conn['host'].':'.$conn['port'],
                                  $conn['username'], $conn['password']);
        if(!$this->db) {
            throw new DatajarException(sprintf("Couldn't connect to database server."));
        }

        if(!mysql_select_db($conn['database'], $this->db)) {
            throw new DatajarException(sprintf("Couldn't open database %s.", $database));
        }

        $this->errors();
    }

    public function __destruct()
    {
        //$this->close();
    }

    public function close()
    {
        if($this->db) {
            mysql_close($this->db);
            $this->db = NULL;
        }
    }

    public static function escape($data)
    {
        $escaped = mysql_real_escape_string($data);
        if($escaped === false) {
            return $data;
        } else {
            return $escaped;
        }
    }

    /**
     * Checks MySQL errors. Throws a DatajarException if there was an error
     * during the last query.
     */
    protected function errors()
    {
        $error = mysql_errno($this->db);
        if($error != 0) {
            throw new DatajarException(
                mysql_error($this->db),
                mysql_error($this->db),
                $error);
        }
    }

    /**
     * SQLite-specific routine with error check included.
     */
    protected function query($statement)
    {
        $ret = null;

        $this->log($statement);

        $res = mysql_query($statement, $this->db);
        $this->errors();

        $table = array();

        if(strtoupper(substr(trim($statement), 0, 6)) == "SELECT") {
            while($row = mysql_fetch_assoc($res))
            {
                $table[] = $row;
            }
            return $table;
        }

        return true;
    }

    protected function lastId()
    {
        return mysql_insert_id($this->db);
    }

    /**
     * Generates the creation statement.
     */
    protected function create_stmt(&$type)
    {
        $typename = $type['val']->gettype();
        $def = '`'.$type['name'] . '` ';
        switch($typename) {
        case 'DatajarTypeBigInt':
            $def.= 'BIGINT';
            break;
        case 'DatajarTypeBool':
            $def.= 'BOOLEAN';
            break;
        case 'DatajarTypeVarChar':
            $def.= 'VARCHAR('.$type['val']->length.')';
            break;
        case 'DatajarTypeDate':
            $def.= 'DATE';
            break;
        case 'DatajarTypeDateTime':
            $def.= 'DATETIME';
            break;
        case 'DatajarTypeDecimal':
            $def.= 'DECIMAL('.$type['val']->length.', '.$type['val']->decimal_places.')';
            break;
        case 'DatajarTypeFloat':
            $def.= 'DOUBLE';
            break;
        case 'DatajarTypeInt':
            $def.= 'INTEGER';
            break;
        case 'DatajarTypeText':
            $def.= 'TEXT';
            break;
        case 'DatajarTypeBlob':
            $def.= 'BLOB';
            break;
        case 'DatajarTypeForeignKey':
            $def.= 'INTEGER NOT NULL REFERENCES '.$type['val']->model.'('.$type['val']->field.')';
            break;
        }

        return $def;
    }

    public function create($object)
    {
        $this->require_datajar($object);

        $proto = $object->prototype();

        $stmt = "CREATE TABLE IF NOT EXISTS `".$this->obj_name($object)."`(".
            "`id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, ";
        foreach($proto as $prop) {
            $stmt .= $this->create_stmt($prop) . ", ";
        }

        // Stripping the extra ', ' and closing the statement.
        $stmt = substr($stmt, 0, -2) . ");";

        return $this->query($stmt);
    }

    public function save($object)
    {
        $this->require_datajar($object);

        $stmt = "";

        $props = $object->prototype();

        if(!$object->id) {
            $stmt = "INSERT INTO `" . $this->obj_name($object) . '`';

            $cols = "";
            $vals = "";
            foreach($props as $prop) {
                $cols.= '`'.$prop['name'] . '`, ';
                if(DatajarEngineBase::does_extend($prop['val'], "DatajarBase")) {
                    $vals.= "'" . $prop['val']->id . "', ";
                } else {
                    $vals.= "'" . mysql_real_escape_string ($prop['val']->getval()) . "', ";
                }
            }

            $stmt.= '(' . substr($cols, 0, -2) . ')';
            $stmt.= " VALUES(" . substr($vals, 0, -2) . ");";

            $this->query($stmt);
            $object->setid($this->lastId());
        } else {
            $stmt = "UPDATE `" . $this->obj_name($object) . "` SET ";

            $cols = "";
            $vals = "";
            foreach($props as $prop) {
                $stmt.= '`'.$prop['name'] . '`=';
                if(DatajarEngineBase::does_extend($prop['val'], "DatajarBase")) {
                    $stmt.= "'" . $prop['val']->id . "', ";
                } else {
                    $stmt.= "'" . mysql_real_escape_string ($prop['val']->getval()) . "', ";
                }
            }

            $stmt = substr($stmt, 0, -2) . " WHERE id='" . $object->id . "'";

            return $this->query($stmt);
        }
    }

    public function delete($object)
    {
        $this->require_datajar($object);

        // Does the object exist in the datajar?
        if($object->id) {
            $stmt = "DELETE FROM `" . $this->obj_name($object) . "` WHERE `id`='" . $object->id . "';";

            $result = $this->query($stmt);

            if($result) {
                $object->clearid();
            }

            return $result;
        }
    }

    public function drop($object)
    {
        $this->require_datajar($object);

        $stmt = 'DROP TABLE IF EXISTS `'.$this->obj_name($object).'`;';

        $result = $this->query($stmt);

        if($result) {
            $object->clearid();
        }

        return $result;
    }

    /**
     * Returns data relative to an object as an array.
     */
    public function load($object, array $cond)
    {
        $stmt = "SELECT * FROM `" . $this->obj_name($object) . '`';

        if(count($cond) > 0) {
            $stmt.= " WHERE ";

            foreach($cond as $col => $val) {
                $stmt.= "`$col`='$val' AND ";
            }

            // Stripping the extra " AND "
            $stmt = substr($stmt, 0, -5) . ';';
        }

        $this->log($stmt);

        $data = $this->query($stmt);

        if(count($data) < 1) {
            return false;
        }

        $data = $data[0];

        // Populating the object.
        $props = $object->prototype();

        $object->setid($data['id']);

        foreach($props as $prop) {
            if(isset($data[$prop['name']])) {
                $object->__set($prop['name'], $data[$prop['name']]);
            }
        }

        return true;
    }

    public function run($query)
    {
        return $this->select($query->get_object(),
                             $query->get_cond(),
                             $query->get_orderby(),
                             $query->get_desc(),
                             $query->get_limit());
    }

    /**
     * Loads a bunch of objects of a given type.
     */
    public function select($objecttype, array $where, $order = false,
                           $desc = false, array $limit = null)
    {
        $stmt = "SELECT * FROM `" . $objecttype . '`';

	if(is_array($where) && count($where) > 0) {
	    $stmt.=  ' WHERE ' . DatajarSQL::gen_where($where, "`", "'", array($this, 'escape'));
	}

        if($order) {
            $stmt .= " ORDER BY `" . $order . "`";
            if($desc) {
                $stmt .= " DESC";
            }
        }

        if(is_array($limit) && count($limit) == 2) {
            $stmt .= " LIMIT " . $limit[0] . ", " . $limit[1];
        }

        $this->log($stmt);

        $data = $this->query($stmt);

        if(count($data) < 1) {
            return false;
        }

        $objs = array();

        foreach($data as $row) {
            $object = new $objecttype();
            // Populating the object.
            $props = $object->prototype();

            $object->setid($row['id']);

            foreach($props as $prop) {
                if(isset($row[$prop['name']])) {
                    $object->__set($prop['name'], $row[$prop['name']]);
                }
            }

            $objs[] = $object;
        }

        return $objs;
    }

    function test_backend()
    {
        return function_exists('mysql_connect');
    }
}

?>
Return current item: Movim