[置顶] orm 用多了,忽然发觉SQL不会写了... 整个基本的功能重新学习SQL,改自fleaphp

来源:互联网 发布:linux lvm配置文件 编辑:程序博客网 时间:2024/06/06 00:33
<?php/** * 数据库封装对象,对Mysql的一个操作封装 * */class CoreDB {/** * 数据库操作实用工具对象 * * @var CoreDbUtils */protected $_dbUtils = NULL;/** * 链接资源标志 *  * @var resource */protected $_link_identifier = NULL ;protected $_dsn = null;    /**     * 执行的查询计数     *     * @var int     */    protected $querycount = 0;        /**     * 最后一次数据库操作的错误信息     *     * @var mixed     */    public $lasterr = null;    /**     * 最后一次数据库操作的错误代码     *     * @var mixed     */    public $lasterrcode = null;        /**     * 最近一次插入操作或者 lastInsertId() 操作返回的插入 ID     *     * @var mixed     */    protected $_lastInsertId = null;    /**     * 指示数据库是否支持事务     *     * @var boolean     */    protected $_has_transaction = false;            /**     * 指示数据库是否支持事务中的 SAVEPOINT 功能     *     * @var boolean     */    protected $_has_savepoint = false;        /**     * 指示事务启动次数     *     * @var int     */    protected $_trans_count = 0;    /**     * 指示事务执行期间是否发生了错误     *     * @var boolean     */    protected $_has_failed_query = false;    /**     * SAVEPOINT 堆栈     *     * @var array     */    protected $_savepoint_stack = array();    /** * 数据库程序版本号 */private $_version = NULL;function __construct(array $dsn,$doParse=true){$this->_dsn = $doParse ? self::parseDSN($dsn) : $dsn;}/**     * 连接数据库     *      * @return bool     * @throw SqlQueryException     */function connect(){if (is_resource($this->_link_identifier)) return;$host = $this->_dsn['host'] . ( empty($this->_dsn['port']) ? '' : ":{$this->_dsn['port']}" );if (!empty($this->_dsn['options'])) {$this->_link_identifier = @mysql_connect($host, $dsn['login'], $dsn['password'], false, $this->_dsn['options']);} else {$this->_link_identifier = @mysql_connect($host,$this->_dsn['login'] ,$this->_dsn['password']);}//$this->_log_($this->_link_identifier);if (!$this->_link_identifier){$this->lasterr = mysql_error();$this->lasterrcode = mysql_errno();throw new SqlQueryException("connect('{$host}','{$this->_dsn['login']}') failed!", $this->lasterr, $this->lasterrcode);}if (!empty($this->_dsn['database'])) {$this->selectDb($this->_dsn['database']);}$this->_version = $this->getOne('SELECT VERSION()');if ($this->_version >= '5.0') {            $this->_has_transaction = true;        }// 设置字符集if (!empty($this->_dsn['charset'])) {$this->execute("SET NAMES '{$this->_dsn['charset']}'");}return true;}/**     * 关闭数据库连接     */function close(){if($this->_link_identifier){mysql_close($this->_link_identifier);}$this->_link_identifier = NULL ;        $this->_lastInsertId = null;        $this->_trans_count = 0;}/**     * 选择要操作的数据库     *     * @param string $database     *     * @return boolean     */function selectDb($database){if (!mysql_select_db($database, $this->_link_identifier)) {$this->lasterr = mysql_error($this->_link_identifier);$this->lasterrcode = mysql_errno($this->_link_identifier);throw new SqlQueryException("SELECT DATABASE: '{$database}' FAILED!", $this->lasterr,$this->lasterrcode);}return true;}/**     * 启动事务     */    function startTrans()    {    if ($this->_has_transaction){        if ($this->_trans_count == 0) {            $this->execute('START TRANSACTION');            $this->_has_failed_query = false;        }        $this->_trans_count++;            if ($this->_trans_count > 1 && $this->_has_savepoint) {            $savepoint = 'savepoint_' . $this->_trans_count;            $this->execute("SAVEPOINT {$savepoint}");            array_push($this->_savepoint_stack, $savepoint);        }    }    }    /**     * 完成事务,根据查询是否出错决定是提交事务还是回滚事务     *     * 如果 $commitOnNoErrors 参数为 true,当事务中所有查询都成功完成时,则提交事务,否则回滚事务     * 如果 $commitOnNoErrors 参数为 false,则强制回滚事务     *     * @param $commitOnNoErrors 指示在没有错误时是否提交事务     */    function completeTrans($commitOnNoErrors = true)    {    if ($this->_has_transaction && $this->_trans_count > 0){    $this->_trans_count--;    if ($this->_trans_count > 0 && $this->_has_savepoint) {    $savepoint = array_pop($this->_savepoint_stack);    if ($this->_has_failed_query || $commitOnNoErrors == false) {    $this->execute("ROLLBACK TO SAVEPOINT {$savepoint}");    }    } else {    if ($this->_has_failed_query == false && $commitOnNoErrors) {    $this->execute('COMMIT');    } else {    $this->execute('ROLLBACK');    }    }    }    }    /**     * 强制指示在调用 completeTrans() 时回滚事务     */    function failTrans()    {        $this->_has_failed_query = true;    }    /**     * 返回事务是否失败的状态     */    function hasFailedTrans()    {        return $this->_has_failed_query;    }        /**     * 执行一个查询,返回一个 resource 或者 boolean 值     *     * @param string $sql     * @param array $inputarr     * @param boolean $throw 指示查询出错时是否抛出异常     *     * @return resource|boolean     */function execute($sql, $inputarr = null, $throw = true){if (is_array($inputarr)) {$sql = $this->bind($sql, $inputarr);}$this->_log_($sql);$this->querycount++;$result = mysql_query($sql, $this->_link_identifier);if ($result !== false) {return $result;}$this->lasterr = mysql_error($this->_link_identifier);$this->lasterrcode = mysql_errno($this->_link_identifier);if ($throw) {throw new SqlQueryException($sql, $this->lasterr, $this->lasterrcode);}return false;}/**     * 返回最近一次数据库操作受到影响的记录数     *     * @return int     */function lastQueryAffectedRows(){return mysql_affected_rows($this->_link_identifier);}/**     * 获取最后一次 nextId 操作获得的值     *     * @return int     */function lastInsertId(){return mysql_insert_id($this->_link_identifier);}/**     * 执行一个查询,返回查询结果记录集     *     * @param string|resource $sql     *     * @return array     */    function getAll($sql)    {        $res = is_resource($sql) ? $sql : $this->execute($sql);        $rowset = array();        while ($row = mysql_fetch_assoc($res)) {            $rowset[] = $row;        }        mysql_free_result($res);        return $rowset;    }    /**     * 执行查询,返回第一条记录的第一个字段     *     * @param string|resource $sql     *     * @return mixed     */    function getOne($sql)    {        $res = is_resource($sql) ? $sql : $this->execute($sql);                $row = mysql_fetch_row($res);        mysql_free_result($res);        return isset($row[0]) ? $row[0] : null;    }        /**     * 执行查询,返回第一条记录     *     * @param string|resource $sql     *     * @return mixed     */    function getRow($sql)    {        $res = is_resource($sql) ? $sql : $this->execute($sql);                $row = mysql_fetch_assoc($res);        mysql_free_result($res);        return $row;    }    /**     * 执行查询,返回结果集的指定列     *     * @param string|resource $sql     * @param int $col 要返回的列,0 为第一列     *     * @return mixed     */    function getCol($sql, $col = 0)    {        $res = is_resource($sql) ? $sql : $this->execute($sql);        $data = array();        while ($row = mysql_fetch_row($res)) {            $data[] = $row[$col];        }        mysql_free_result($res);        return $data;    }            /**     * 从记录集中返回一行数据     *     * @param resouce $res     *     * @return array     */function fetchRow($res){return mysql_fetch_row($res);}/**     * 从记录集中返回一行数据,字段名作为键名     *     * @param resouce $res     *     * @return array     */function fetchAssoc($res){return mysql_fetch_assoc($res);}/**     * 释放查询句柄     *     * @param resource $res     *     * @return boolean     */function freeRes($res){return mysql_free_result($res);}/**     * 转义字符串     *     * @param string $value     *     * @return mixed     */function qstr($value){if (is_int($value) || is_float($value)) { return $value; }if (is_bool($value)) { return $value ? 1 : 0; }if (is_null($value)) { return 'NULL'; }return "'" . mysql_real_escape_string($value, $this->_link_identifier) . "'";}    /**     * 执行一个查询,返回分组后的查询结果记录集     *     * $groupBy 参数如果为字符串或整数,表示结果集根据 $groupBy 参数指定的字段进行分组。     * 如果 $groupBy 参数为 true,则表示根据每行记录的第一个字段进行分组。     *     * @param string|resource $sql     * @param string $groupBy     *     * @return array     */    function getAllGroupBy($sql, & $groupBy)    {    $res = is_resource($sql) ? $sql : $this->execute($sql);        $data = array();        $row = mysql_fetch_assoc($res);        if ($row != false) {            if (empty($groupBy)) {                $groupBy = key($row);            }            do {                $rkv = $row[$groupBy];                unset($row[$groupBy]);                $data[$rkv][] = $row;            } while ($row = mysql_fetch_assoc($res));        }        mysql_free_result($res);        return $data;    }            /**     * 分析 DSN 数组,返回包含 DSN 连接信息的数组,失败返回 false     *     * @param array $dsn     *     * @return array     */    static function parseDSN(array $dsn)    {    if (empty($dsn)) return NULL;            $dsn['host'] = isset($dsn['host']) ? $dsn['host'] : '';        $dsn['port'] = isset($dsn['port']) ? $dsn['port'] : '';        $dsn['login'] = isset($dsn['login']) ? $dsn['login'] : '';        $dsn['password'] = isset($dsn['password']) ? $dsn['password'] : '';        $dsn['database'] = isset($dsn['database']) ? $dsn['database'] : '';        $dsn['charset'] = isset($dsn['charset']) ? $dsn['charset'] : 'utf8';        $dsn['options'] = isset($dsn['options']) ? $dsn['options'] : '';        $dsn['prefix'] = isset($dsn['prefix']) ? $dsn['prefix'] : '';        $dsn['schema'] = isset($dsn['schema']) ? $dsn['schema'] : '';                $dsnid = "mysql://{$dsn['login']}:{$dsn['password']}@{$dsn['host']}_{$dsn['prefix']}/{$dsn['database']}/{$dsn['schema']}/{$dsn['options']}";        $dsn['id'] = $dsnid;        return $dsn;    }    /**     * 返回数据库访问对象实例     *     * 必须提供 $dsn 参数     *     * DSN 是 Database Source Name 的缩写,可以理解为数据源名字。     * DSN 是一个数组,包含了连接数据库需要的各种信息,例如主机、用户名、密码等。     *     * DSN 的正确写法:     *     * example:     * <code>     * $dsn = array(     *      'host'     => 'localhost',     *      'login'    => 'username',     *      'password' => 'password',     *      'database' => 'test_db',     *      'charset'  => 'utf8',     * );     *     * $dbo = CoreDB::instance($dsn);     * </code>     *     * @param array $dsn     *     * @return CoreDB     */    static function instance(array $dsn)    {        $dsn = self::parseDSN($dsn);                $dsnid = "core-db/[{$dsn['id']}]";        if (App::isRegistered($dsnid)) return App::registry($dsnid);                return App::register(new self($dsn,false),$dsnid);    }    /**     * 返回 数据库操作工具对象     *      * @return CoreDbUtils     */    function getDbUtils(){    if (!$this->_dbUtils){        $this->_dbUtils = new CoreDbUtils($this);    }    return $this->_dbUtils;    }        private function _log_($statement)    {        App::$_logWriter_->append($statement,'sql','debug');    }}/** * InvalidDSNException 异常指示没有提供有效的 DSN 设置 * */class InvalidDSNException extends Exception{public $dsn;    /**     * 构造函数     *     * @param array $dsn     */    function __construct(array $dsn)    {    unset($dsn['password']);    $this->dsn = $dsn;         parent::__construct('无效的数据源名称“Data-Source-Name (DSN)”.');    }}/** * SqlQueryException 异常指示一个 SQL 语句执行错误 *  */class SqlQueryException extends Exception{    public $sql;        public $error;        public $errno;    /**     * 构造函数     *     * @param string $sql sql语句     * @param string $error 错误文本     * @param int $errno 错误号     */    function __construct($sql, $error ,$errno)    {    $this->sql = $sql;    $this->error = $error;    $this->errno = $errno;        $msg = sprintf('SQL: "%s"\nError: "%s"\nErrno: "%s"', $sql, $error ,$errno);        parent::__construct($msg);    }}require_once 'dbutils.php';
 
<?php/** * CoreDb 工具 * */final class CoreDbUtils {/** * @var CoreDb */private $_dbo = NULL;function __construct(CoreDb $dbo){$this->_dbo = $dbo;}/** *  C CHAR 或 VARCHAR 类型字段 *  X TEXT 或 CLOB 类型字段 *  B 二进制数据(BLOB) *  N 数值或者浮点数 *  D 日期 *  T TimeStamp *  L 逻辑布尔值 *  I 整数 *  R 自动增量或计数器 */private static $typeMap = array(            'BIT'           => 'I',            'TINYINT'       => 'I',            'BOOL'          => 'L',            'BOOLEAN'       => 'L',            'SMALLINT'      => 'I',            'MEDIUMINT'     => 'I',            'INT'           => 'I',            'INTEGER'       => 'I',            'BIGINT'        => 'I',            'FLOAT'         => 'N',            'DOUBLE'        => 'N',            'DOUBLEPRECISION' => 'N',            'FLOAT'         => 'N',            'DECIMAL'       => 'N',            'DEC'           => 'N',            'DATE'          => 'D',            'DATETIME'      => 'T',            'TIMESTAMP'     => 'T',            'TIME'          => 'T',            'YEAR'          => 'I',            'CHAR'          => 'C',            'NCHAR'         => 'C',            'VARCHAR'       => 'C',            'NVARCHAR'      => 'C',            'BINARY'        => 'B',            'VARBINARY'     => 'B',            'TINYBLOB'      => 'X',            'TINYTEXT'      => 'X',            'BLOB'          => 'X',            'TEXT'          => 'X',            'MEDIUMBLOB'    => 'X',            'MEDIUMTEXT'    => 'X',            'LONGBLOB'      => 'X',            'LONGTEXT'      => 'X',            'ENUM'          => 'C',            'SET'           => 'C',);/**     * 按照指定的类型,返回值     *     * @param mixed $value     * @param string $type     *     * @return mixed     */    static function setValueByType($value, $type)    {        /**         *  C CHAR 或 VARCHAR 类型字段         *  X TEXT 或 CLOB 类型字段         *  B 二进制数据(BLOB)         *  N 数值或者浮点数         *  D 日期         *  T TimeStamp         *  L 逻辑布尔值         *  I 整数         *  R 自动增量或计数器         */        switch (strtoupper($type)) {        case 'I':            return (int)$value;        case 'N':            return (float)$value;        case 'L':            return (bool)$value;        default:            return $value;        }    }    /**     * 返回指定表(或者视图)的元数据     *     * 部分代码参考 ADOdb 实现。     *     * 每个字段包含下列属性:     *     * name:            字段名     * scale:           小数位数     * type:            字段类型     * simpleType:      简单字段类型(与数据库无关)     * maxLength:       最大长度     * notNull:         是否不允许保存 NULL 值     * primaryKey:      是否是主键     * autoIncrement:   是否是自动增量字段     * binary:          是否是二进制数据     * unsigned:        是否是无符号数值     * hasDefault:      是否有默认值     * defaultValue:    默认值     *     * @param string $table     *     * @return array     */function metaColumns($table){$rs = $this->_dbo->execute(sprintf('SHOW FULL COLUMNS FROM %s', $table));if (!$rs) { return false; }$retarr = array();while (($row = $this->_dbo->fetchAssoc($rs))) {$field = array();$field['name'] = $row['Field'];$type = $row['Type'];$field['scale'] = null;$queryArray = false;if (preg_match('/^(.+)\((\d+),(\d+)/', $type, $queryArray)) {$field['type'] = $queryArray[1];$field['maxLength'] = is_numeric($queryArray[2]) ? $queryArray[2] : -1;$field['scale'] = is_numeric($queryArray[3]) ? $queryArray[3] : -1;} elseif (preg_match('/^(.+)\((\d+)/', $type, $queryArray)) {$field['type'] = $queryArray[1];$field['maxLength'] = is_numeric($queryArray[2]) ? $queryArray[2] : -1;} elseif (preg_match('/^(enum)\((.*)\)$/i', $type, $queryArray)) {$field['type'] = $queryArray[1];$arr = explode(",",$queryArray[2]);$field['enums'] = $arr;$zlen = max(array_map("strlen",$arr)) - 2; // PHP >= 4.0.6$field['maxLength'] = ($zlen > 0) ? $zlen : 1;} else {$field['type'] = $type;$field['maxLength'] = -1;}$field['simpleType'] = self::$typeMap[strtoupper($field['type'])];// if ($field['simpleType'] == 'C' && $field['maxLength'] > 250) {// $field['simpleType'] = 'X';// }$field['notNull'] = ($row['Null'] != 'YES');$field['primaryKey'] = ($row['Key'] == 'PRI');$field['autoIncrement'] = (strpos($row['Extra'], 'auto_increment') !== false);if ($field['autoIncrement']) { $field['simpleType'] = 'R'; }$field['binary'] = (strpos($type,'blob') !== false);$field['unsigned'] = (strpos($type,'unsigned') !== false);if ($field['type'] == 'tinyint' && $field['maxLength'] == 1) {$field['simpleType'] = 'L';}if (!$field['binary']) {$d = $row['Default'];if ($d != '' && $d != 'NULL') {$field['hasDefault'] = true;$field['defaultValue'] = self::setValueByType($d, $field['simpleType']);} else {$field['hasDefault'] = false;}}$field['description'] = isset($row['Comment']) ? $row['Comment'] : '';$retarr[strtoupper($field['name'])] = $field;}$this->_dbo->freeRes($rs);return $retarr;}/**     * 获得所有数据表的名称     *     * @param string $pattern     * @param string $schema     *     * @return array     */function metaTables($pattern = null, $schema = null){$sql = 'SHOW TABLES';if (!empty($schema)) {$sql .= " FROM {$schema}";}if (!empty($pattern)) {$sql .= ' LIKE ' . $this->_dbo->qstr($schema);}$res = $this->_dbo->execute($sql, null, false);$tables = array();while (($row = $this->_dbo->fetchRow($res))) {$tables[] = reset($row);}$this->_dbo->freeRes($res);return $tables;}    /**     * 为数据表产生下一个序列值     *     * @param string $seqName     * @param string $startValue     *     * @return int     */    function nextId($seqName = 'coredb_seq', $startValue = 1)    {        $getNextIdSql = sprintf('UPDATE %s SET id = LAST_INSERT_ID(id + 1)', $seqName);        $result = $this->_dbo->execute($getNextIdSql, null, false);        if (!$result) {            if (!$this->createSeq($seqName, $startValue)) { return false; }            $result = $this->_dbo->execute($getNextIdSql);            if (!$result) { return false; }        }        return $this->_dbo->lastInsertId();    }    /**     * 创建一个新的序列,成功返回 true,失败返回 false     *     * @param string $seqName     * @param int $startValue     *     * @return boolean     */    function createSeq($seqName = 'coredb_seq', $startValue = 1)    {        if ($this->_dbo->execute(sprintf('CREATE TABLE %s (id INT NOT NULL)', $seqName))) {            return $this->_dbo->execute(sprintf('INSERT INTO %s VALUES (%s)', $seqName, $startValue - 1));        } else {            return false;        }    }    /**     * 删除一个序列     *     * @param string $seqName     */    function dropSeq($seqName = 'coredb_seq')    {        return $this->_dbo->execute(sprintf('DROP TABLE %s', $seqName));    }    /**     * 执行一个查询,返回查询结果记录集、指定字段的值集合以及以该字段值分组后的记录集     *     * @param string|resource $sql     * @param string $field     * @param array $fieldValues     * @param array $reference     *     * @return array     */    function getAllWithFieldRefs($sql, $field, & $fieldValues, & $reference)    {        $res = is_resource($sql) ? $sql : $this->_dbo->execute($sql);        $fieldValues = array();        $reference = array();        $offset = 0;        $data = array();        while ($row = $this->_dbo->fetchAssoc($res)) {            $fieldValue = $row[$field];            unset($row[$field]);            $data[$offset] = $row;            $fieldValues[$offset] = $fieldValue;            $reference[$fieldValue] =& $data[$offset];            $offset++;        }        $this->_dbo->freeRes($res);        return $data;    }    /**     * 执行一个查询,并将数据按照指定字段分组后与 $assocRowset 记录集组装在一起     *     * @param string|resource $sql     * @param array $assocRowset     * @param string $mappingName     * @param boolean $oneToOne     * @param string $refKeyName     * @param mixed $limit     */    function assemble($sql, & $assocRowset, $mappingName, $oneToOne, $refKeyName, $limit = null)    {        if (is_resource($sql)) {            $res = $sql;        } else {            if (!is_null($limit)) {                if (is_array($limit)) {                    list($length, $offset) = $limit;                } else {                    $length = $limit;                    $offset = 0;                }                $res = $this->_dbo->selectLimit($sql, $length, $offset);            } else {                $res = $this->_dbo->execute($sql);            }        }        if ($oneToOne) {            // 一对一组装数据            while ($row = $this->_dbo->fetchAssoc($res)) {                $rkv = $row[$refKeyName];                unset($row[$refKeyName]);                $assocRowset[$rkv][$mappingName] = $row;            }        } else {            // 一对多组装数据            while ($row = $this->_dbo->fetchAssoc($res)) {                $rkv = $row[$refKeyName];                unset($row[$refKeyName]);                $assocRowset[$rkv][$mappingName][] = $row;            }        }        $this->_dbo->freeRes($res);    }}/** * SqlHelper 类提供了各种生成 SQL 语句的辅助方法 * */final class CoreDbSqlHelper {/** * 分析查询条件 * * @param CoreDb $dbo * @param mixed $conditions * * @return string */static function parseConditions(CoreDb $dbo, $conditions){// 对于 NULL,直接返回 NULL        if (is_null($conditions)) { return null; } // 如果是字符串,则假定为自定义条件        if (is_string($conditions)) {            return $conditions;        }        // 如果不是数组,说明提供的查询条件有误        if (!is_array($conditions)) {            return null;        } $where = ''; $expr = '';  /**         * 不过何种条件形式,一律为  字段名 => (值, 操作, 连接运算符, 值是否是SQL命令) 的形式         */ foreach ($conditions as $field => $cond) {  $expr = 'AND';             if (!is_string($field)) { continue; } if (!is_array($cond)) {                // 字段名 => 值            $cond = array($cond);            }            reset($cond);            // 第一个元素是值 if (!isset($cond[1])) { $cond[1] = '='; }            if (!isset($cond[2])) { $cond[2] = $expr; }            if (!isset($cond[3])) { $cond[3] = false; }            list($value, $op, $expr, $isCommand) = $cond;             if (is_array($value)){ $value = '(' . implode(',',array_map(array($dbo, 'qstr'),$value)) . ')' ; $op = 'IN'; $isCommand = true; }  if (!$isCommand) {$value = $dbo->qstr($value);}$where .= "{$field} {$op} {$value} {$expr} "; }         $where = substr($where, 0, - (strlen($expr) + 2));                return $where;}/** * 返回 limit sql字串 * * @param int|array $limit * @return string */static function getLimitSql($limit){if (is_null($limit)) return '';if (is_array($limit)) {            list($length, $offset) = $limit;        } else {            $length = $limit;            $offset = null;        }        if (!is_null($offset)) {$sql = " LIMIT " . (int)$offset;if (!is_null($length)) {$sql .= ', ' . (int)$length;} else {$sql .= ', 4294967294';}} elseif (!is_null($length)) {$sql = " LIMIT " . (int)$length;}return $sql;}/**     * 返回数据库可以接受的日期格式     *     * @param int $timestamp     * @return string     */    static function dbTimeStamp($timestamp)    {        return date('Y-m-d H:i:s', $timestamp);    }/**     * 将数据表名字转换为完全限定名     *     * @param string $tableName     * @param string $schema     *     * @return string     */static function qtable($tableName, $schema = null){return $schema != '' ? "`{$schema}`.`{$tableName}`" : "`{$tableName}`";}/**     * 将字段名转换为完全限定名,避免因为字段名和数据库关键词相同导致的错误     *     * @param string $fieldName     * @param string $tableName     * @param string $schema     *     * @return string     */static function qfield($fieldName, $tableName = null, $schema = null){$fieldName = ($fieldName == '*') ? '*' : "`{$fieldName}`";return $tableName != '' ? self::qtable($tableName, $schema) . '.' . $fieldName : $fieldName;}    /**     * 一次性将多个字段名转换为完全限定名     *     * @param string|array $fields     * @param string $tableName     * @param string $schema     * @param boolean $returnArray     *     * @return string     */    static function qfields($fields, $tableName = null, $schema = null, $returnArray = false)    {        if (!is_array($fields)) {            $fields = explode(',', $fields);            $fields = array_map('trim', $fields);        }        $return = array();        foreach ($fields as $fieldName) {            $return[] = self::qfield($fieldName, $tableName, $schema);        }        return $returnArray ? $return : implode(', ', $return);    }/**     * 根据 SQL 语句和提供的参数数组,生成最终的 SQL 语句     *     * @param CoreDb $dbo     * @param string $sql     * @param array $inputarr     *     * @return string     */    static function bind(CoreDb $dbo, $sql, & $inputarr)    {        $arr = explode('?', $sql);        $sql = array_shift($arr);        foreach ($inputarr as $value) {            if (isset($arr[0])) {                $sql .= $dbo->qstr($value) . array_shift($arr);            }        }        return $sql;    }    /**     * 根据包含记录内容的数组返回一条有效的 SQL 插入记录语句     *     * @param array $row     * @param string $table 要插入的数据表     * @param string $schema     *     * @return string     */    static function getInsertSQL(& $row, $table, $schema = null)    {        list($holders, $values) = self::getPlaceholder($row);        $holders = implode(',', $holders);        $fields = self::qfields(array_keys($values));        $table = self::qtable($table, $schema);        $sql = "INSERT INTO {$table} ({$fields}) VALUES ({$holders})";        return $sql;    }    /**     * 根据包含记录内容的数组返回一条有效的 SQL 更新记录语句     *     * @param CoreDb $dbo     * @param array $row     * @param array $pk 表主键字段     * @param string $table 要插入的数据表     * @param string $schema     *     * @return string     */    static function getUpdateSQL(CoreDb $dbo, & $row, $pk, $table, $schema = null)    {        $pkv = $row[$pk];        unset($row[$pk]);        list($pairs, $values) = self::getPlaceholderPair($dbo,$row);        $row[$pk] = $pkv;        $pairs = implode(',', $pairs);        $table = self::qtable($table, $schema);        $pk = self::qfield($pk);        $sql = "UPDATE {$table} SET {$pairs} WHERE {$pk} = " . $dbo->qstr($pkv);        return $sql;    }    /**     * 根据参数占位符样式,返回包含参数占位符及有效数据的数组     *     * @param array $inputarr     * @param array $fields     *     * @return array     */    static function getPlaceholder(& $inputarr, $fields = null)    {        $holders = array();        $values = array();        if (is_array($fields)) {            $fields = array_change_key_case(array_flip($fields), CASE_LOWER);            foreach (array_keys($inputarr) as $key) {                if (!isset($fields[strtolower($key)])) { continue; }                $holders[] = '?';                $values[$key] =& $inputarr[$key];            }        } else {            foreach (array_keys($inputarr) as $key) {                $holders[] = '?';                $values[$key] =& $inputarr[$key];            }        }        return array($holders, $values);    }        /**     * 根据驱动的参数占位符样式,返回包含参数及占位符字符串对、有效数据的数组     *     * @param CoreDb $dbo     * @param array $inputarr     * @param array $fields     *     * @return array     */    static function getPlaceholderPair(CoreDb $dbo, & $inputarr, $fields = null)    {        $pairs = array();        $values = array();        if (is_array($fields)) {            $fields = array_change_key_case(array_flip($fields), CASE_LOWER);            foreach (array_keys($inputarr) as $key) {                if (!isset($fields[strtolower($key)])) { continue; }                $qkey = $this->qfield($key);                $pairs[] = "{$qkey}=?";                $values[$key] =& $inputarr[$key];            }        } else {            foreach (array_keys($inputarr) as $key) {                $qkey = $this->qfield($key);                $pairs[] = "{$qkey}=?";                $values[$key] =& $inputarr[$key];            }        }        return array($pairs, $values);    }}

 代码例子:

 

$dbo = CoreDB::instance(App::ini('_dsn/default'));$dbo->connect();////$sqlCond = SqlHelper::parseConditions(array(//'name' => 'asfdfds',//'id' => array(array(123),'IN','OR'),//'role.name' => array('%ha%','Like')//),$dbo);$row = array('name' => 'asfdfds','id' => 112.5 );$sqlCond = CoreDbSqlHelper::getInsertSQL($row,'users');$sqlCond = CoreDbSqlHelper::bind($dbo,$sqlCond,$row);dump($dbo->getCol('show tables'),$sqlCond);dump($dbo->getDbUtils()->metaTables(),'metaTables');
0 0
原创粉丝点击