TOP-framework/framework/library/Database.php

503 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace top\library;
use top\library\database\Base;
use top\library\exception\DatabaseException;
/**
* 数据库操作类
* @author topnuomi 2018年11月21日
*/
class Database
{
/**
* 数据库连接
* @var Base
*/
private static $connection = null;
/**
* 当前类实例
* @var array
*/
private static $instance = [];
/**
* 数据库配置
* @var array
*/
private $config = [];
/**
* 当前操作的表
* @var string
*/
private $table = '';
/**
* 当前表的主键
* @var string
*/
private $pk = '';
/**
* 别名
* @var string
*/
private $alias = '';
/**
* 数据去重
* @var bool
*/
private $distinct = false;
/**
* 操作的字段
* @var array|string
*/
private $field = '';
/**
* 条件
* @var array
*/
private $where = [];
/**
* 排序
* @var string
*/
private $order = '';
/**
* 范围
* @var string
*/
private $limit = '';
/**
* 多表
* @var array
*/
private $join = [];
/**
* Database constructor.
* @param string $table
* @param string $pk
* @param string $prefix
* @throws DatabaseException
*/
private function __construct($table, $pk, $prefix)
{
// 获取配置
$this->config = config('db');
// 当前操作表名
$this->table = $this->getTableName($prefix, $table);
// 当前操作表主键
$this->pk = $pk;
if (!self::$connection) { // 保证只有一个数据库连接
// 设置数据库驱动
$driver = $this->config['driver'] ? $this->config['driver'] : 'MySQLi';
$class = '\\top\\library\\database\\driver\\' . $driver;
if (class_exists($class)) {
// 获取数据库驱动实例
self::$connection = $class::instance()->connect($this->config);
} else throw new DatabaseException('不存在的数据库驱动:' . $driver);
}
}
/**
* 获取表名
* @param string $prefix
* @param string $table
* @return string
*/
private function getTableName($prefix, $table)
{
// 无前缀
if ($prefix === false) {
$tableName = $table;
} elseif (!$prefix) {
$tableName = $this->config['prefix'] . $table;
} else {
$tableName = $prefix . $table;
}
return $tableName;
}
/**
* 指定表
* @param string $table
* @param string $pk
* @param string $prefix
* @return $this
*/
public static function table($table = '', $pk = '', $prefix = '')
{
$ident = $prefix . $table;
if (!isset(self::$instance[$ident])) {
self::$instance[$ident] = new self($table, $pk, $prefix);
}
return self::$instance[$ident];
}
/**
* 设置表别名
* @param string $name
* @return \top\library\Database
*/
public function alias($name)
{
$this->alias = $name;
return $this;
}
/**
* @param bool $flag
* @return \top\library\Database
*/
public function distinct($flag = true)
{
$this->distinct = $flag ? true : false;
return $this;
}
/**
* 设置操作字段
* @param array|string $field
* @return \top\library\Database
*/
public function field($field)
{
$this->field = $field;
return $this;
}
/**
* 设置条件
* @return \top\library\Database
*/
public function where()
{
$where = func_get_args();
if (!empty($where)) {
switch (count($where)) {
case 3:
$this->where[] = [
$where[0] => [
$where[1],
$where[2]
]
];
break;
case 2:
$this->where[] = [
$where[0] => $where[1]
];
break;
default:
$this->where[] = $where[0];
break;
}
}
return $this;
}
/**
* 设置排序
* @return \top\library\Database
*/
public function order()
{
$order = func_get_args();
if (!empty($order)) {
if (count($order) > 1) {
$this->order = $order[0] . ' ' . $order[1];
} else {
$this->order = $order[0];
}
}
return $this;
}
/**
* 设置记录范围
* @return \top\library\Database
*/
public function limit()
{
$limit = func_get_args();
if (!empty($limit)) {
if (count($limit) > 1) {
$this->limit = $limit[0] . ', ' . $limit[1];
} else {
$this->limit = $limit[0];
}
}
return $this;
}
/**
* 多表
*
* @param string $table
* @param string $on
* @param string $type
* @return \top\library\Database
*/
public function join($table, $on, $type = 'INNER')
{
$tableName = null;
if (is_array($table) && isset($table[0]) && isset($table[1])) {
$tableName = $table[0] . $table[1];
} else {
$tableName = $this->config['prefix'] . $table;
}
$this->join[] = [
$tableName,
$on,
$type
];
return $this;
}
/**
* 插入记录
*
* @param array $data
* @return int|boolean
*/
public function insert($data)
{
$result = self::$connection->insert($this->table, $data);
return $result;
}
/**
* 查询一条记录
* @param mixed $param
* @return mixed
*/
public function find($param = false)
{
(is_callable($param)) && $param($this);
if (!is_bool($param) && !is_callable($param)) {
$this->where = array_merge($this->where, [
[($this->alias ? $this->alias . '.' : '') . $this->getPk() => $param],
]);
}
$result = self::$connection->find(
$this->table,
$this->alias,
$this->distinct,
$this->field,
$this->join,
$this->where,
$this->order
);
$this->_reset();
return $result;
}
/**
* 查询所有记录
*
* @param mixed $param
* @return array|boolean
*/
public function select($param = false)
{
(is_callable($param)) && $param($this);
if (!is_bool($param) && !is_callable($param)) {
$this->where = array_merge($this->where, [
[($this->alias ? $this->alias . '.' : '') . $this->getPk() => $param],
]);
}
$result = self::$connection->select(
$this->table,
$this->alias,
$this->distinct,
$this->field,
$this->join,
$this->where,
$this->order,
$this->limit
);
$this->_reset();
foreach ($result as $k => $v)
$result[$k] = $v;
return $result;
}
/**
* 更新记录
*
* @param array $data
* @param mixed $param
* @return int|boolean
*/
public function update($data, $param = false)
{
(is_callable($param)) && $param($this);
if (!is_bool($param) && !is_callable($param)) {
$this->where = array_merge($this->where, [
[($this->alias ? $this->alias . '.' : '') . $this->getPk() => $param],
]);
}
$result = self::$connection->update(
$this->table,
$this->alias,
$this->join,
$this->where,
$this->order,
$this->limit,
$data
);
$this->_reset();
return $result;
}
/**
* 删除记录
*
* @param mixed $param
* @return int|boolean
*/
public function delete($param = false)
{
(is_callable($param)) && $param($this);
if (!is_bool($param) && !is_callable($param)) {
$this->where = array_merge($this->where, [
[($this->alias ? $this->alias . '.' : '') . $this->getPk() => $param],
]);
}
$result = self::$connection->delete(
$this->table,
$this->alias,
$this->join,
$this->where,
$this->order,
$this->limit
);
$this->_reset();
return $result;
}
/**
* 公共方法 sum、avg等等使用函数包裹字段的方法
*
* @param mixed $param
* @param string $type
* @return mixed
*/
public function common($param, $type)
{
(is_callable($param)) && $param($this);
if (empty($this->field) && $param && !is_callable($param)) {
$this->field = $param;
}
$result = self::$connection->common(
$this->table,
$this->alias,
$this->field,
$this->join,
$this->where,
$type
);
$this->_reset();
return $result;
}
/**
* 执行一条SQL
* @param string $query
* @param array $params
* @return bool|\PDOStatement
*/
public function query($query, $params = [])
{
return self::$connection->query($query, $params);
}
/**
* 开启事务
*/
public function begin()
{
self::$connection->begin();
}
/**
* 提交
*/
public function commit()
{
self::$connection->commit();
}
/**
* 回滚
*/
public function rollback()
{
self::$connection->rollback();
}
/**
* 返回PDO
* @return \PDO
*/
public function getPDO()
{
return self::$connection->getPDO();
}
/**
* 获取最后执行的SQL语句
*
* @return string
*/
public function sql()
{
return self::$connection->sql();
}
/**
* 重置查询条件
*/
private function _reset()
{
$this->distinct = false;
$this->field = '';
$this->join = [];
$this->where = [];
$this->order = '';
$this->limit = '';
}
/**
* 获取主键
*
* @return string
*/
private function getPk()
{
if (!$this->pk) {
$pk = self::$connection->getPk($this->table, $this->config['dbname']);
return ($pk) ? $pk : 'id';
}
return $this->pk;
}
private function __clone()
{
}
}