123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514 |
- <?php
- /**
- * 简易数据库操作类
- *
- * @author Jinhui Zhu<jinhui.zhu@live.cn>2015-12-10 14:35
- *
- * usage:
- * $user = (new \Qii\Driver\Easy())->_initialize();
- * $user->setRules(new \Qii\Driver\Rules($rules));
- * $user->setPrivateKey(array());
- * $user->uid = 1;
- * $user->email = 'antsnet@163.com';
- * $user->nick = 'Jinhui Zhu';
- * $user->add_time = time();
- * $user->update_time = time();
- * 保存数据
- * $user->_save();
- * 检查指定数据是否存在,以privateKey为准
- * $user->_exist();
- * 删除指定数据,以privateKey为准
- * $user->_remove()
- * 更新数据,以privateKey为准
- * $user->_update();
- * if($user->isError())
- * {
- * //todo 如果执行操作有问题,错误详情 $user->getErrors()
- * }
- * else
- * {
- * //todo 对返回结果进行处理
- * }
- *
- * //获取所有
- * $user->_getRowsByEmail('antsnet@163.com');
- * $user->_getRowByFileds($this->_privateKey);
- * $user->_getRowsByFileds($this->_privateKey);
- * $user->getEmailByUid(1);
- * $user->_getAllByUid(1);
- */
- namespace Qii\Driver;
- \Qii\Autoloader\Import::requires(dirname(__FILE__) . DS . 'Response.php');
- class Easy
- {
- const VERSION = '1.2';
- /**
- * @var Fields $fields
- */
- private $fields = null;
- /**
- * 数据表主键
- * @var array $privateKeys
- */
- private $privateKeys = array();
- /**
- * 保存或更新的时候验证的规则
- * @var array $rules
- */
- private $easyRules = array();
- /**
- * @var string $databaseName 数据库名称
- * 如果没有指定数据库名称将使用当前连接的数据库
- */
- private $databaseName;
- /**
- * @var string $tableName 表名,
- * 如果要指定操作的数据库名需要将数据库名和表名合在一起,如:database.table
- */
- private $tableName = '';
- /**
- * @var book $isInstance 是否实例化对象了
- */
- private $isInstance = false;
- /**
- * @var array $_response 操作出错保存数据到此数组
- */
- private $_response;
- /**
- * @var bool 是否需要重置privateKeys
- */
- private $needResetPrivatekey = true;
-
- private $db;
- public function __construct()
- {
- $this->db = \Qii\Autoloader\Psr4::loadClass('Qii\Model')->db;
- $this->clean();
- return $this;
- }
- /**
- * 初始化数据库对象
- *
- */
- final public function _initialize()
- {
- $this->isInstance = true;
- $this->clean();
- return $this;
- }
- /**
- * 设置表字段
- *
- * @param array $fields
- * @return $this
- */
- final public function setFields(array $fields)
- {
- $this->fields = new Fields($fields);
- return $this;
- }
- /**
- * 设置主键
- *
- * @param array|string $privateKeys
- */
- final public function setPrivateKey(array $privateKeys)
- {
- if(count($privateKeys) == 0) return $this;
- $this->needResetPrivatekey = false;
- $this->privateKeys = $privateKeys;
- return $this;
- }
- /**
- * 重置主键,主要用于查询、更新、删除操作
- *
- * @param string | null $opt
- * @return array
- */
- final public function resetPrivateKey($opt = null)
- {
- if ($this->needResetPrivatekey && $opt) {
- $valid = $this->easyRules->getOperateValidFields($opt);
- if (!empty($valid)) $this->privateKeys = array_values($valid);
- }
- return $this->privateKeys;
- }
- /**
- * 设置规则
- * @param array $rules {_save:{}, _update:{}, _remove:{}}
- */
- final public function setRules(\Qii\Driver\Rules $rules)
- {
- $this->setFields($rules->getFields());
- $this->tableName = $rules->getTableName();
- $this->databaseName = $rules->getDatabase();
- if (!$this->privateKeys) $this->privateKeys = $rules->getPrivateKey();
- $this->easyRules = $rules;
- return $this;
- }
- /**
- * 设置表字段
- *
- * @param $name
- * @param $val
- * @return $this
- */
- public function __set($name, $val)
- {
- $this->fields->$name = $val;
- return $this;
- }
- /**
- * 批量设置字段的值
- * @param array $data
- * @return $this
- */
- public function setFieldsVal(array $data)
- {
- foreach ($data AS $name => $val) {
- $this->fields->$name = $val;
- }
- return $this;
- }
- /**
- * 获取当前使用的rules的字段
- *
- * @return mixed
- */
- public function getFields()
- {
- return $this->easyRules->getFields();
- }
- /**
- * 获取当前使用的fields的值
- *
- * @return mixed
- */
- public function getValues()
- {
- return $this->fields->getValues();
- }
- /**
- * 如果没有调用parent::__construct()方法就报错
- *
- */
- public function checkInstance()
- {
- if (!$this->isInstance) {
- $this->_response = Response::Fail('checkInstance', array('msg' => \Qii::i(1507, 'parent::__construct()'), 'code' => __LINE__));
- throw new \Qii\Exceptions\TableException(\Qii::i(1507, 'parent::__construct()'), __LINE__);
- }
- return $this;
- }
- /**
- * 重置Fields及相关条件
- *
- */
- final protected function clean()
- {
- $this->fields = null;
- $this->privateKeys = array();
- $this->easyRules = array();
- $this->tableName = '';
- $this->_response = new Response();
- return $this;
- }
- /**
- * 验证保存的数据
- *
- * @param $rules
- * @return bool
- */
- final protected function validateFields($rules)
- {
- if (empty($rules)) return true;
- $validateCls = _loadClass('Qii_Library_Validate');
- $result = $validateCls->verify($this->fields->getValues(), $rules, $this->easyRules->getInvalidMessage());
- if ($result === true) {
- return true;
- }
- $error = $validateCls->getErrors();
- $this->_response = Response::FailValidate('validate', array('_result' => $error['msg'], 'fields' => array('field' => $error['field'], 'message' => $error['msg'])));
- return false;
- }
- /**
- * 获取用户表
- */
- final public function getTableName()
- {
- if (!$this->tableName) throw new \Qii\Exceptions\Errors(\Qii::i(1510), true);
- return $this->databaseName ? $this->databaseName . '.' . $this->tableName : $this->tableName;
- }
- /**
- * 对指定字段执行指定方法 同时校验值的有效性
- *
- * @param String $func
- * @param String $field
- * @param String $val
- * @return Object
- */
- final public function func($func, $key, $val)
- {
- $rule = $this->getValidateField($key);
- //如果字段需要用到函数编码字符,如果没有通过验证就不将值放入fields中
- $validateCls = _loadClass('Qii\Library\Validate');
- $result = $validateCls->verify(array($key => $val), array($key => $rule), $this->easyRules->getInvalidMessage());
- if ($result === true) {
- $this->fields->$key = $func($val);
- return $this;
- }
- $error = $validateCls->getErrors();
- $this->_response = Response::FailValidate('validate', array('_result' => $error['msg'], 'fields' => array('field' => $error['field'], 'message' => $error['msg'])));
- return $this;
- }
- /**
- * 检查数据是否已经存在,并返回一行,只能根据主键查询
- *
- * @return array
- */
- final public function _exist()
- {
- $this->checkInstance();
- if (!$this->privateKeys) {
- $this->_response = Response::FAIL('privateKey', \Qii::i(1513));
- return $this->_response;
- }
- $where = array();
- foreach ($this->privateKeys AS $key) {
- $rule = $this->getValidateField($key);
- if (count($rule) > 0 && !$this->validateFields(array($key => $rule))) {
- return $this->_response;
- }
- if ($this->fields->isField($key)) $where[] = "`{$key}` = '" . $this->db->setQuote($this->fields->getField($key)) . "'";
- }
- $result = (array)$this->db->limit(1)->where(join(' AND ', $where))->select($this->getTableName());
- if ($this->db->isError()) {
- $this->_response = $this->db->getResponse();
- }
- return $this->_response = Response::Success('_exist', array('_result' => $result));
- }
- /**
- * 获取主键对应的值
- * @return array
- */
- final protected function getPrivateValue()
- {
- $data = array();
- foreach ($this->privateKeys AS $key) {
- $data[$key] = $this->fields->getField($key);
- }
- return $data;
- }
- /**
- * 保存数据
- *
- * @return string 如果是自动增长的行返回插入数据的id
- */
- final public function _save()
- {
- $this->checkInstance();
- if (!$this->validateFields($this->easyRules->getRulesByOperate('save'))) return $this->_response;
- $this->resetPrivateKey('save');
- if ($this->privateKeys && count($this->_exist()->getResult()) > 0) {
- $this->_response = Response::Exist('_save', array('_result' => \Qii::i(1511, join(',', $this->getPrivateValue()))));
- return $this->_response;
- }
- $result = $this->db->insertObject($this->getTableName(), $this->fields->getValues());
- if ($this->db->isError()) {
- return $this->db->getResponse();
- }
- return $this->_response = Response::Success('_save', array_merge($this->fields->getValueAsArray(), array('_result' => $result)));
- }
- /**
- * 更新数据
- *
- * @return int 更新数据影响的行数
- */
- final public function _update()
- {
- $this->checkInstance();
- if (!$this->validateFields($this->easyRules->getRulesByOperate('update'))) return $this->_response;
- $this->resetPrivateKey('update');
- if (count($this->_exist()) == 0) {
- return $this->_response = Response::NotExist('_update', \Qii::i(1512, join(',', $this->getPrivateValue())));
- }
- $result = $this->db->updateObject($this->getTableName(), $this->fields->getValues(), $this->privateKeys);
- if ($this->db->isError()) {
- return $this->_response = $this->db->getResponse();
- }
- return $this->_response = Response::Success('_update', array('_result' => $result));
- }
- /**
- * 删除数据
- * @return int 删除数据影响的行数
- */
- final public function _remove()
- {
- $this->checkInstance();
- if (!$this->validateFields($this->easyRules->getRulesByOperate('remove'))) return $this->_response;
- $this->resetPrivateKey('remove');
- if (count($this->_exist()) == 0) {
- return $this->_response = Response::NotExist('_remove', \Qii::i(1512, join(',', $this->getPrivateValue())));
- }
- $result = $this->db->deleteObject($this->getTableName(), $this->fields->getValues());
- if ($this->db->isError()) {
- return $this->_response = $this->db->getResponse();
- }
- return $this->_response = Response::Success('_remove', array('_result' => $result));
- }
- /**
- * 获取操作数据返回的错误
- */
- final public function getErrors()
- {
- if ($this->_response) {
- if (!$this->_response->isError()) return false;
- return $this->_response;
- }
- return $this->db->getError();
- }
- /**
- * 是否有错误
- */
- final public function isError()
- {
- if ($this->_response) {
- return $this->_response->isError();
- }
- return $this->db->isError();
- }
- /**
- * 获取response对象
- */
- final public function getResponse()
- {
- return $this->_response;
- }
- /**
- * 使用此方法用于查询某一条数据的某一个字段
- * @useage getXxxByXxx
- * getNameById:通过id获取name的值; getEmailById:通过id获取email;
- * _getRowById:返回所有字段; _getRowsById:通过id获取所有匹配的数据
- * 备注:以_开头的才会去走getRow, getRows方法去取所有字段,目前仅支持All, Row, Rows这几个方法
- * @param String $method [description]
- * @param Mix $args 请求的参数
- * @return Mix [description]
- */
- final public function __call($method, $args)
- {
- $this->checkInstance();
- $selectType = 'normal';
- if (substr($method, 0, 1) == '_') {
- $selectType = 'system';
- $method = substr($method, 1);
- }
- preg_match('/^(get)(.*)(By)(.*)/', $method, $matches);
- if ($matches && count($matches) == 5 && $matches[1] == 'get') {
- //大写字母匹配下划线,字段中统一用小写字母,在查询的时候使用驼峰结构
- //如:getEmailAddressByUserId 通过user_id查询email_address
- $field = strtolower(preg_replace('/(?<!^)([A-Z])/', '_$1', $matches[2]));
- if (isset($this->_relationMap[$field])) $field = $this->_relationMap[$field];
- $method = 'selectRow';
- if ($field == 'rows' && $selectType == 'system') $method = 'selectRows';
- if ($field == 'row' && $selectType == 'system') $method = 'selectRow';
- if (in_array($field, array('all', 'row', 'rows')) && $selectType == 'system') {
- $field = '*';
- }
- $value = $this->db->setQuote(array_shift($args));
- $name = strtolower(strtolower(preg_replace('/(?<!^)([A-Z])/', '_$1', $matches[4])));
- $whereArray = array();
- if ($selectType == 'system' && $name == 'fields') {
- foreach ($value AS $val) {
- $whereArray[$val] = $this->fields->isField($val) ? $this->fields->getField($val) : '';
- }
- } else {
- if (!$this->fields->isField($name)) $this->fields->$name = $value;
- $whereArray[$name] = $this->fields->getField($name);
- }
- foreach ($whereArray AS $key => $val) {
- $rule = $this->getValidateField($key);
- if (count($rule) > 0 && !$this->validateFields(array($key => $rule))) {
- return $this->_response;
- }
- }
- $result = $this->db->fields($field)->whereArray($whereArray)->$method($this->getTableName());
- if ($this->db->isError()) {
- return $this->_response = $this->db->getResponse();
- }
- return $this->_response = Response::Success($method, array('_result' => $result));
- }
- //exec{$method}
- preg_match('/^(exec)(.*)/', $method, $matches);
- if ($matches && count($matches) == 3) {
- $alias = lcfirst($matches[2]);
- if (method_exists($this->db, $alias)) {
- $result = $this->db->{$matches[2]}($this->getTableName(), $this->getFields());
- if ($this->db->isError()) {
- return $this->_response = $this->db->getResponse();
- }
- return $this->_response = Response::Success($matches[2], array('_result' => $result));
- }
- if ($this->db->getAlias($method) && method_exists($this->db, $this->db->getAlias($method))) {
- $this->db->whereArray($this->getFields());
- $result = $this->db->{$this->db->getAlias($method)}($this->getTableName());
- if ($this->db->isError()) {
- return $this->_response = $this->db->getResponse();
- }
- return $this->_response = Response::Success($this->db->getAlias($method), array('_result' => $result));
- }
- }
- //访问方法的别名
- if ($this->db->getAlias($method)) {
- if (method_exists($this->db, $this->db->getAlias($method))) {
- $result = call_user_func_array(array($this->db, $this->db->getAlias($method)), $args);
- if ($this->db->isError()) {
- return $this->_response = $this->db->getResponse();
- }
- return $this->_response = Response::Success($this->db->getAlias($method), array('_result' => $result));
- }
- $this->_response = Response::UndefinedMethod('__call', $this->db->getAlias($method));
- \Qii::setError(false, __LINE__, 1106, 'Model', 'Alias ' . $this->db->getAlias($method) . ' does not exist.', print_r($args, true));
- }
- $this->_response = Response::UndefinedMethod('__call', $method);
- \Qii::setError(false, __LINE__, 1106, 'Model', $method, print_r($args, true));
- }
- /**
- * 获取单个字段的验证规则
- * @param String $fieldName 字段名
- * @return Array
- */
- protected function getValidateField($fieldName)
- {
- return $this->easyRules->getRulesByField($fieldName);
- }
- }
|