/**
* 数据访问层,仅处理MYSQL
* 包括
* by:李勇
* at:2009-01-19
*/final classDalSplite{
public function__construct(PDO $pdo){
}
}/**
* 指定库中的指定表的访问类
*
*/final classDalTable{
private$pdo;
private$tableName;
private$meta;
private$primaryKey;/**
* 构造方法
*
* @param PDO $pdo
* @param string $tableName
*/public function__construct(PDO $pdo,$tableName){
if(!is_string($tableName)) returnnull;$this->pdo=$pdo;$this->tableName=$tableName;$this->meta=false;$this->primaryKey=false;
return$this;
}/**
* 获取本表的表结构(元数据),失败时返回0
*
* @return 0/array:=>array(列信息)
*/private functiongetMeta(){
if($this->meta!==false)return$this->meta;$sql="DESCRIBE ".$this->tableName;$table=$this->query($sql);
if(!$tableor !count($table)){$this->meta=0;
}else{$meta=array();
foreach ($tableas$col) {$meta[$col['Field']]=$col;
}$this->meta=$meta;
}
return$this->meta;
}/**
* 获取本表的主键字段,无主键或组合主键时返回0
*
* @return 0/主键字段名
*/private functiongetPrimaryKey(){
if($this->primaryKey!==false)return$this->primaryKey;$sql="SHOW INDEX FROM ".$this->tableName;$table=$this->query($sql);
if(!$tableor !count($table)){$this->primaryKey=0;
}else{$pkvs=array();
foreach ($tableas$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(!$whereand !$groupbyand !$havingand !$orderbyand !$limitandis_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==1and$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 ($setas$row) {$col[]=$row[0];
}
return$col;
}
return$set;
}/**
* 返回查询结果
* 请参考_select
*/public functionselect($fields=null,$where=null,$groupby=null,$having=null,$orderby=null,$limit=null){
return$this->_select(false,$fields,$where,$groupby,$having,$orderby,$limit);
}/**
* 返回消重后的查询结果
* 请参考_select
*/public functiondistinct($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 functioninsert($row){
if(!$row)returnfalse;
if(is_object($row))$row=get_object_vars($row);
if(!is_array($row))returnfalse;$meta=$this->getMeta();$fields='';$values='';
foreach ($rowas$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(!$fieldsor !$values)returnfalse;$sql="INSERT INTO ".$this->tableName.'('.$fields.') VALUES('.$values.')';$count=$this->execute($sql);
if(!$count)returnfalse;
return$this->pdo->lastInsertId();
}/**
* 删除表中的部分数据
*
* @param mixed $where
* 请参考createWhere
* @return int
*/public functiondelete($where){$where=trim($this->createWhere($where));
if(!$where)returnfalse;$sql="DELETE FROM ".$this->tableName." ".$where;
return$this->execute($sql);
}/**
* 删除表中全部数据
*
* @return int
*/public functiondeleteAll(){$sql="DELETE FROM ".$this->tableName;
return$this->execute($sql);
}/**
* 修改表中的部分数据
*
* @param array[1] $row
* =>
* @param mixed $where
* 请参考createWhere
* @return int
*/public functionupdate($row,$where){
if(!$row)returnfalse;
if(is_object($row))$row=get_object_vars($row);
if(!is_array($row))returnfalse;$meta=$this->getMeta();$set='';
foreach ($rowas$name=>$value){
if(!is_string($name))continue;
if(!isset($meta[$name]))continue;
if($set)$set.=' , ';$set=$name."='".mysql_escape_string($value)."' ";
}
if(!$set)returnfalse;$where=$this->createWhere($where);
if(!$where)returnfalse;$sql="UPDATE ".$this->tableName." SET ".$set." ".$where;
return$this->execute($sql);
}/**
* 生成字段列表
*
* @param mixed $fields
* null/''/0 所有字段
* string 直接使用
* object/array
*
* =>
* @return string
*/private functioncreateFields($fields=null){
if(!$fields)return'*';
if(is_string($fields)) returntrim($fields);
if(is_object($fields))$fields=get_object_vars($fields);
if(!is_array($fields)) return'*';$ret='';
foreach($fieldsas$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 functioncreateWhere($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 functioncreateHaving($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 functioncreateGroupby($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 functioncreateOrderby($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 functioncreateSort($sort=null){
if(!$sort)return'';
if(is_string($sort)) returntrim($sort);
if(is_object($sort))$sort=get_object_vars($sort);
if(!is_array($sort)) return'';
if(count($sort)==2and (strtoupper($sort[1])=='ASC'orstrtoupper($sort[1])=='DESC')) return$sort[0].' '.strtoupper($sort[1]);$meta=$this->getMeta();$ret='';
foreach ($sortas$key=>$value) {
if(is_int($key)){
if(!isset($meta[$value]))continue;
if($ret)$ret.=' , ';$ret.=$value;
continue;
}
if(strtoupper($value)=='ASC'orstrtoupper($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 functioncreateLimit($limit=null){
if(!$limit)return'';
if(is_string($limit)){$limit=trim($limit);
if(strpos(strtoupper($limit),'LIMIT')===0) returnstrtoupper($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 functioncreateCondition($condition=null){
if(is_null($condition)) return'';
if(is_string($condition)) returntrim($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 ($conditionas$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 functionexecute($sql){
if(!is_string($sql)) returnfalse;
return$this->pdo->exec(trim($sql));
}/**
* 查询并返回结果集
*
* @param string $sql
* @return array[2]
*/public functionquery($sql){
if(!is_string($sql)) returnfalse;
return$this->pdo->query(trim($sql));
}
}/**
* 本程序包的异常类
*
*/classDalExceptionextendsException{//所有异常情况constDE_PARAMETER_TYPE=1001;
constDE_UNKNOWN=2000;//所有异常情况的文字表达static private$msgs=array(self::DE_PARAMETER_TYPE=>'参数类型错误:类:的方法:的第个参数的类型应该是类型,但现在是类型,值为:',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);
}
}