Chinaunix首页 | 论坛 | 博客
  • 博客访问: 295456
  • 博文数量: 153
  • 博客积分: 3347
  • 博客等级: 中校
  • 技术积分: 1556
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-30 17:50
文章分类

全部博文(153)

文章存档

2013年(7)

2012年(21)

2011年(46)

2010年(16)

2009年(63)

我的朋友

分类:

2009-12-30 18:50:16

/**
* 数据访问层,仅处理MYSQL
* 包括
* by:李勇
* at:2009-01-19
*/

final class DalSplite{
    public function 
__construct(PDO $pdo){

    }
}

/**
* 指定库中的指定表的访问类
*
*/
final class DalTable{
    private 
$pdo;
    private 
$tableName;
    private 
$meta;
    private 
$primaryKey;

    
/**
     * 构造方法
     *
     * @param PDO $pdo
     * @param string $tableName
     */
    
public function __construct(PDO $pdo,$tableName){
        if(!
is_string($tableName)) return null;
        
$this->pdo=$pdo;
        
$this->tableName=$tableName;
        
$this->meta=false;
        
$this->primaryKey=false;
        return 
$this;
    }

    
/**
     * 获取本表的表结构(元数据),失败时返回0
     *
     * @return 0/array:<列名>=>array(列信息)
     */
    
private function getMeta(){
        if(
$this->meta!==false)return $this->meta;
        
$sql="DESCRIBE ".$this->tableName;
        
$table=$this->query($sql);

        if(!
$table or !count($table)){
            
$this->meta=0;
        }else{
            
$meta=array();
            foreach (
$table as $col) {
                
$meta[$col['Field']]=$col;
            }
            
$this->meta=$meta;
        }
        return 
$this->meta;
    }

    
/**
     * 获取本表的主键字段,无主键或组合主键时返回0
     *
     * @return 0/主键字段名
     */
    
private function getPrimaryKey(){
        if(
$this->primaryKey!==false)return $this->primaryKey;
        
$sql="SHOW INDEX FROM ".$this->tableName;
        
$table=$this->query($sql);

        if(!
$table or !count($table)){
            
$this->primaryKey=0;
        }else{
            
$pkvs=array();
            foreach (
$table as $row) {
                if(
$row['Key_name']=='PRIMARY')$pkvs[]=$row['Column_name'];
            }
            if(
count($pkvs)!=1){
                
$this->primaryKey=0;
            }else{
                
$this->primaryKey=$pkvs[0];
            }
        }
        return 
$this->primaryKey;
    }

    
/**
     * Enter description here...
     *
     * @param bool $distinct    是否消重
     * @param mixed $fields     请参考createFields
     * @param mixed $where      请参考createWhere
     * @param mixed $groupby    请参考createGroupby
     * @param mixed $having     请参考createHaving
     * @param mixed $orderby    请参考createOrderby
     * @param mixed $limit      请参考createLimit
     * @return mixed    单值/一维无键数组/一维有键数组/二维数组(一维无键,二维有键)
     */
    
private function _select($distinct,$fields=null,$where=null,$groupby=null,$having=null,$orderby=null,$limit=null){
        if(
is_object($fields))$fields=get_object_vars($fields);
        if(!
$where and !$groupby and !$having and !$orderby and !$limit and is_array($fields) and isset($fields['fields'])){
            if(isset(
$fields['where']))$where=$fields['where'];
            if(isset(
$fields['groupby']))$groupby=$fields['groupby'];
            if(isset(
$fields['having']))$having=$fields['having'];
            if(isset(
$fields['orderby']))$orderby=$fields['orderby'];
            if(isset(
$fields['limit']))$limit=$fields['limit'];
            
$fields=$fields['fields'];
            return 
$this->_select($distinct,$fields,$where,$groupby,$having,$orderby,$limit);
        }
        
$fields=$this->createFields($fields);
        
$where=$this->createWhere($where);
        
$groupby=$this->createGroupby($groupby);
        
$having=$this->createHaving($having);
        
$orderby=$this->createOrderby($orderby);
        
$limit=$this->createLimit($limit);

        
$sql='SELECT ';
        if(
$distinct)$sql.='DISTINCT ';
        
$sql.=$fields;

        
$sql.=" FROM ".$this->tableName." ";

        
$sql.=$where.$groupby.$having.$orderby.$limit;

        
$set=$this->query($sql);
        
$rows=count($set);
        if(
$rows)$cols=count($set[0]);
        else 
$cols=0;

        if(
$rows==and $cols==1){
            
$col=array();
            foreach (
$set[0] as $cell) {
                
$col[]=$cell;
            }
            return 
$col[0];
        }

        if(
$rows==1){
            return 
$set[0];
        }

        if(
$cols==1){
            
$col=array();
            foreach (
$set as $row) {
                
$col[]=$row[0];
            }
            return 
$col;
        }
        return 
$set;
    }

    
/**
     * 返回查询结果
     *      请参考_select
     */
    
public function select($fields=null,$where=null,$groupby=null,$having=null,$orderby=null,$limit=null){
        return 
$this->_select(false,$fields,$where,$groupby,$having,$orderby,$limit);
    }

    
/**
     * 返回消重后的查询结果
     *      请参考_select
     */
    
public function distinct($fields=null,$where=null,$groupby=null,$having=null,$orderby=null,$limit=null){
        return 
$this->_select(true,$fields,$where,$groupby,$having,$orderby,$limit);
    }

    
/**
     * 插入一条数据
     *
     * @param array[1] $row
     *      <列名>=><值>
     * @return int
     */
    
public function insert($row){
        if(!
$row)return false;
        if(
is_object($row))$row=get_object_vars($row);
        if(!
is_array($row))return false;

        
$meta=$this->getMeta();
        
$fields='';
        
$values='';
        foreach (
$row as $name=>$value){
            if(!
is_string($name))continue;
            if(!isset(
$meta[$name]))continue;
            if(
$fields)$fields.=' , ';
            
$fields.=$name;
            if(
$values)$value.=' , ';
            
$values.="'".mysql_escape_string($value)."'";
        }
        if(!
$fields or !$values)return false;
        
$sql="INSERT INTO ".$this->tableName.'('.$fields.') VALUES('.$values.')';
        
$count=$this->execute($sql);
        if(!
$count)return false;
        return 
$this->pdo->lastInsertId();
    }

    
/**
     * 删除表中的部分数据
     *
     * @param mixed $where
     *      请参考createWhere
     * @return int
     */
    
public function delete($where){
        
$where=trim($this->createWhere($where));
        if(!
$where)return false;
        
$sql="DELETE FROM ".$this->tableName." ".$where;
        return 
$this->execute($sql);
    }

    
/**
     * 删除表中全部数据
     *
     * @return int
     */
    
public function deleteAll(){
        
$sql="DELETE FROM ".$this->tableName;
        return 
$this->execute($sql);
    }

    
/**
     * 修改表中的部分数据
     *
     * @param array[1] $row
     *      <列名>=><值>
     * @param mixed $where
     *      请参考createWhere
     * @return int
     */
    
public function update($row,$where){
        if(!
$row)return false;
        if(
is_object($row))$row=get_object_vars($row);
        if(!
is_array($row))return false;

        
$meta=$this->getMeta();
        
$set='';
        foreach (
$row as $name=>$value){
            if(!
is_string($name))continue;
            if(!isset(
$meta[$name]))continue;
            if(
$set)$set.=' , ';
            
$set=$name."='".mysql_escape_string($value)."' ";
        }
        if(!
$set)return false;

        
$where=$this->createWhere($where);
        if(!
$where)return false;

        
$sql="UPDATE ".$this->tableName." SET ".$set." ".$where;
        return 
$this->execute($sql);
    }

    
/**
     * 生成字段列表
     *
     * @param mixed $fields
     *      null/''/0   所有字段
     *      string      直接使用
     *      object/array
     *          <列名|计算值>
     *          <列名|计算值>=><别名>
     * @return string
     */
    
private function createFields($fields=null){
        if(!
$fields)return '*';
        if(
is_string($fields)) return trim($fields);
        if(
is_object($fields))$fields=get_object_vars($fields);

        if(!
is_array($fields)) return '*';

        
$ret='';
        foreach(
$fields as $key=>$value){
            if(
is_int($key)){
                if(!
is_string($value))continue;
                if(
$ret)$ret.=' , ';
                
$ret.=$value;
                continue;
            }
            if(!
is_string($value))continue;
            if(
$ret)$ret.=' , ';
            
$ret.=$key.' AS '.$value;
        }
        return 
$ret;
    }

    
/**
     * 生成WHERE子句
     *
     * @param mixed $where
     *      参考createCondition
     * @return string
     */
    
private function createWhere($where){
        
$condition=$this->createCondition($where);
        if(!
$condition)return '';
        
$condition=trim($condition);
        if(
strpos(strtoupper($condition),'WHERE')===0)return $condition;
        return 
'WHERE '.$condition;
    }

    
/**
     * 生成HAVING子句
     *
     * @param mixed $having
     *      参考createCondition
     * @return string
     */
    
private function createHaving($having){
        
$condition=$this->createCondition($having);
        if(!
$condition)return '';
        
$condition=trim($condition);
        if(
strpos(strtoupper($condition),'HAVING')===0)return $condition;
        return 
'HAVING '.$condition;
    }

    
/**
     * 生成 GROUP BY 子句
     *
     * @param mixed $groupby
     *      参考createSort
     * @return string
     */
    
private function createGroupby($groupby){
        
$sort=$this->createSort($groupby);
        if(!
$sort)return '';
        
$sort=trim($sort);
        if(
strpos(strtoupper($sort),'GROUP')===0)return $sort;
        return 
'GROUP BY '.$sort;
    }

    
/**
     * 生成 ORDER BY 子句
     *
     * @param mixed $orderby
     *      参考createSort
     * @return string
     */
    
private function createOrderby($orderby=null){
        
$sort=$this->createSort($orderby);
        if(!
$sort)return '';
        
$sort=trim($sort);
        if(
strpos(strtoupper($sort),'ORDER')===0) return $sort;
        return 
'ORDER BY '.$sort;
    }

    
/**
     * 生成列排序子句,用于Order By与Group By中
     *
     * @param mixed $sort
     *      string  直接使用
     *      object/arrray
     *          <列名> ASC|asc|DESC|desc
     *          [<列名>|<列名>=>,...]
     * @return string
     */
    
private function createSort($sort=null){
        if(!
$sort)return '';
        if(
is_string($sort)) return trim($sort);

        if(
is_object($sort))$sort=get_object_vars($sort);
        if(!
is_array($sort)) return '';

        if(
count($sort)==and (strtoupper($sort[1])=='ASC' or strtoupper($sort[1])=='DESC')) return $sort[0].' '.strtoupper($sort[1]);

        
$meta=$this->getMeta();
        
$ret='';
        foreach (
$sort as $key=>$value) {
            if(
is_int($key)){
                if(!isset(
$meta[$value]))continue;
                if(
$ret)$ret.=' , ';
                
$ret.=$value;
                continue;
            }
            if(
strtoupper($value)=='ASC' or strtoupper($value)=='DESC'){
                if(!isset(
$meta[$key]))continue;
                if(
$ret)$ret.=' , ';
                
$ret.=$key.' '.strtoupper($value);
                continue;
            }
            continue;
        }
        return 
$ret;
    }

    
/**
     * 生成分页子句
     *
     * @param mixed $limit
     *      string  直接使用,其中可包含LIMIT
     *      int     只限制行数,不限制偏移
     *      object/array
     *          [limit/LIMIT/Limit=><行数>,Offset/offset/OFFSET=><偏移>]
     *          [<行数>,<偏移>]
     *          [<行数>]
     * @return string
     */
    
private function createLimit($limit=null){
        if(!
$limit)return '';
        if(
is_string($limit)){
            
$limit=trim($limit);
            if(
strpos(strtoupper($limit),'LIMIT')===0) return strtoupper($limit);
            return 
'LIMIT '.$limit;
        }
        if(
is_int($limit)) return 'LIMIT '.$limit;

        if(
is_object($limit))$limit=get_object_vars($limit);
        if(!
is_array($limit))return '';

        
$l=null;
        
$o=null;
        if(isset(
$limit['Limit']))$l=$limit['Limit'];
        if(isset(
$limit['limit']))$l=$limit['limit'];
        if(isset(
$limit['LIMIT']))$l=$limit['LIMIT'];
        if(isset(
$limit['Offset']))$o=$limit['Offset'];
        if(isset(
$limit['offset']))$o=$limit['offset'];
        if(isset(
$limit['OFFSET']))$o=$limit['OFFSET'];
        if(
$l){
            if(
$o){
                return 
'LIMIT '.$l.' OFFSET '.$o;
            }
            return 
'LIMIT '.$l;
        }
        if(
count($limit)==2){
            
$l=$limit[1];
            
$o=$limit[0];
            return 
'LIMIT '.$l.' OFFSET '.$o;
        }
        if(
count($limit)==1) return 'LIMIT '.$limit[0];
        return 
'';
    }

    
/**
     * 生成条件表达式,用于Where,Having子句中
     *
     * @param mixed $condition
     *      string  直接使用
     *      int     主键值
     *      object/array and组合
     *          PrimaryKey=>主键值
     *          列名=>列值(string/int)
     * @return string
     */
    
private function createCondition($condition=null){
        if(
is_null($condition)) return '';

        if(
is_string($condition)) return trim($condition);
        if(
is_int($condition)){
            if(
$this->getPrimaryKey())
                return 
$this->getPrimaryKey()."='".$condition."' ";
            return 
'';
        }

        if(
is_object($condition))$condition=get_object_vars($condition);
        if(!
is_array($condition))return '';

        if(isset(
$condition['PrimaryKey'])){
            if(
$this->getPrimaryKey())
                return 
$this->getPrimaryKey()."='".mysql_escape_string($condition['PrimaryKey'])."'";
            return 
'';
        }

        
$meta=$this->getMeta();
        
$ret='';
        foreach (
$condition as $key=>$value) {
            if(!
is_int($key)){
                if(!isset(
$meta[$key]))continue;
                if(!
is_int($value)&&!is_string($value))continue;
                if(
is_string($value))$value=trim($value);
                if(
$ret)$ret.=' and ';
                
$ret.=' '.$key."='".mysql_escape_string($value)."' ";
                continue;
            }
        }
        return 
$ret;
    }

    
/**
     * 执行SQL语句,并返回影响的行数
     *
     * @param string $sql
     * @return int
     */
    
public function execute($sql){
        if(!
is_string($sql)) return false;
        return 
$this->pdo->exec(trim($sql));
    }

    
/**
     * 查询并返回结果集
     *
     * @param string $sql
     * @return array[2]
     */
    
public function query($sql){
        if(!
is_string($sql)) return false;
        return 
$this->pdo->query(trim($sql));
    }
}



/**
* 本程序包的异常类
*
*/
class DalException extends Exception  {
    
//所有异常情况
    
const DE_PARAMETER_TYPE 1001;

    const 
DE_UNKNOWN=2000;

    
//所有异常情况的文字表达
    
static private $msgs=array(
        
self::DE_PARAMETER_TYPE => '参数类型错误:类:<%s>的方法:<%s>的第<%d>个参数的类型应该是<%s>类型,但现在是<%s>类型,值为:<%s>',
        
self::DE_UNKNOWN => '未知错误'
    
);

    public function 
__construct($code 0,$msg=null) {
        if(isset(
self::$msgs[$code])){
            if(
is_string($msg)){
                
$message=$msg;
            }else if(
is_array($msg)){
                
$message=vsprintf(self::$msgs[$code],$msg);
            }else{
                
$message=self::$msgs[$code];
            }
        }else{
            
$code=self::DE_UNKNOWN ;
            if(
is_string($msg)){
                
$message=$msg;
            }else{
                
$message='错误代码:'.$code;
            }
        }

        
parent::__construct($message$code);
    }
}
阅读(582) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~