|
@@ -1,36 +1,56 @@
|
|
|
<?php namespace Dever;
|
|
|
+use Dever;
|
|
|
class Model
|
|
|
{
|
|
|
protected $method = '';
|
|
|
protected $store;
|
|
|
- protected $config = array();
|
|
|
- public function __construct($table, $app, $path)
|
|
|
+ protected $partition = false;
|
|
|
+ public $config = array();
|
|
|
+ public function __construct($table, $app, $store, $partition, $path)
|
|
|
{
|
|
|
- $store = 'default';
|
|
|
- if (strpos($table, '.')) {
|
|
|
- list($table, $this->method) = explode('.', $table);
|
|
|
+ $project = Project::load($app);
|
|
|
+ if ($table) {
|
|
|
+ $file = $path . DIRECTORY_SEPARATOR . $table . '.php';
|
|
|
+ $base = $project['path'] . $file;
|
|
|
+ if (is_file($base)) {
|
|
|
+ $this->config = include $base;
|
|
|
+ if (isset($this->config['partition']) && empty($partition)) {
|
|
|
+ $partition = $this->config['partition'];
|
|
|
+ }
|
|
|
+ $this->config['app'] = $app;
|
|
|
+ $this->config['table'] = DEVER_PROJECT . '_' . $app . '_' . $table;
|
|
|
+ $this->lang();
|
|
|
+ } else {
|
|
|
+ $this->config['table'] = $table;
|
|
|
+ $this->config['struct'] = false;
|
|
|
+ }
|
|
|
}
|
|
|
- if (strpos($table, ':')) {
|
|
|
- list($table, $store) = explode(':', $table);
|
|
|
+ if ($partition) {
|
|
|
+ $this->partition($partition);
|
|
|
}
|
|
|
- $project = Project::load($app);
|
|
|
- $file = $path . DIRECTORY_SEPARATOR . $table . '.php';
|
|
|
- $base = $project['path'] . $file;
|
|
|
- if (is_file($base)) {
|
|
|
- $this->config = include $base;
|
|
|
+ $this->store = Dever::store($store, $this->partition);
|
|
|
+ if (isset($file)) {
|
|
|
+ $this->init($file);
|
|
|
}
|
|
|
- $this->config['name'] = DEVER_PROJECT . '_' . $app . '_' . $table;
|
|
|
- $this->config['app'] = $app;
|
|
|
- if (isset($this->config['store'])) {
|
|
|
- $store = $this->config['store'];
|
|
|
+ }
|
|
|
+ private function partition($partition)
|
|
|
+ {
|
|
|
+ if (is_array($partition)) {
|
|
|
+ $this->partition = $partition;
|
|
|
+ } else {
|
|
|
+ $this->partition = Dever::config('setting')['database']['partition'] ?? false;
|
|
|
+ }
|
|
|
+ if ($this->partition['database']) {
|
|
|
+ foreach ($this->partition as $k => &$v) {
|
|
|
+ $t = Dever::session($k);
|
|
|
+ if (!$t) {
|
|
|
+ $e = '$v=' . $v . ';';
|
|
|
+ eval($e);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- $setting = Config::get('setting')['database'][$store];
|
|
|
- $class = 'Dever\\Store\\' . $setting['type'];
|
|
|
- $this->store = $class::getInstance($store, $setting);
|
|
|
- $this->load();
|
|
|
- $this->init($file);
|
|
|
}
|
|
|
- private function load()
|
|
|
+ private function lang()
|
|
|
{
|
|
|
if (isset($this->config['lang']) && isset($this->config['struct']) && $pack = Config::get('setting')['lang_pack']) {
|
|
|
foreach ($this->config['lang'] as $lang) {
|
|
@@ -47,6 +67,20 @@ class Model
|
|
|
private function init($file)
|
|
|
{
|
|
|
$data['struct'] = $data['index'] = 0;
|
|
|
+ if ($this->partition) {
|
|
|
+ if (isset($this->partition['table'])) {
|
|
|
+ $this->config['table'] .= '_' . $this->partition['table'];
|
|
|
+ $file = rtrim($file, '.php') . '_';
|
|
|
+ if (isset($this->partition['database'])) {
|
|
|
+ $file .= $this->partition['database'] . '_';
|
|
|
+ }
|
|
|
+ $file .= $this->partition['table'] . '.php';
|
|
|
+ }
|
|
|
+ if (isset($this->partition['field'])) {
|
|
|
+ $this->partition['field'] = Dever::$date::maketime($this->partition['field']);
|
|
|
+ $data['field'] = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
$file = Path::get($file);
|
|
|
if (is_file($file)) {
|
|
|
$data = include $file;
|
|
@@ -59,334 +93,159 @@ class Model
|
|
|
$data[$k] = $num;
|
|
|
file_put_contents($file, '<?php return ' . var_export($data, true) . ';');
|
|
|
}
|
|
|
+ } elseif ($k == 'field' && $v != $this->partition['field']) {
|
|
|
+ $this->store->partition($this->config, $this->partition['field']);
|
|
|
+ $data['field'] = $this->partition['field'];
|
|
|
+ file_put_contents($file, '<?php return ' . var_export($data, true) . ';');
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- public function select($param = array(), $set, $call = false)
|
|
|
+ public function select($param, $set = array())
|
|
|
{
|
|
|
- return $this->store->select($this->config['name'], $param, $set);
|
|
|
- if ($call) {
|
|
|
-
|
|
|
+ if (isset($set['num'])) {
|
|
|
+ $set['limit'] = Paginator::init($set['num'], $set['page'] ?? 1, function()use($param){return $this->count($param);});
|
|
|
}
|
|
|
- if ($data) {
|
|
|
- if (isset($set['reset'])) {
|
|
|
- $result = $this->reset($data, $set['reset'], $call);
|
|
|
- } else {
|
|
|
- if ($call) {
|
|
|
- foreach ($data as $row) {
|
|
|
- $result[] = $call($row);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ $result = $this->store->select($this->config['table'], $param, $set, $this->config['struct']);
|
|
|
+ if (isset($set['num']) && empty($set['page'])) {
|
|
|
+ $result = $result->fetchAll();
|
|
|
+ Paginator::status(empty($result));
|
|
|
}
|
|
|
return $result;
|
|
|
}
|
|
|
-
|
|
|
- public function find($where, $call = false)
|
|
|
- {
|
|
|
- return $this->db()->find($where, $call);
|
|
|
- }
|
|
|
-
|
|
|
- public function query($sql, $data = array(), $method = '')
|
|
|
+ public function count($param)
|
|
|
{
|
|
|
- return $this->db()->exe($sql, $data, $method);
|
|
|
+ return $this->store->count($this->config['table'], $param, $this->config['struct']);
|
|
|
}
|
|
|
-
|
|
|
- public function fetch($sql, $data = array(), $cache = false)
|
|
|
+ public function find($param, $set = array())
|
|
|
{
|
|
|
- return $this->fetchAll($sql, $data, false, $cache, 'fetch');
|
|
|
+ return $this->select($param, $set)->fetch();
|
|
|
}
|
|
|
-
|
|
|
- public function fetchAll($sql, $data = array(), $page = array(), $cache = false, $method = 'fetchAll')
|
|
|
+ public function insert($data)
|
|
|
{
|
|
|
- $this->setTable($sql);
|
|
|
-
|
|
|
- if (!$cache && !empty(Config::get('cache')->mysql)) {
|
|
|
- $cache = 'getSql_' . md5($sql . serialize($data));
|
|
|
- if ($page && $p = Input::get('page')) {
|
|
|
- $cache .= '_p' . $p;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if ($cache) {
|
|
|
- $result = $this->db()->cache($cache);
|
|
|
- if ($result) {
|
|
|
- return $result;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if ($page) {
|
|
|
- $result = $this->page($page, $sql, $data);
|
|
|
- } else {
|
|
|
- $result = $this->query($sql, $data)->$method();
|
|
|
+ if (empty($data['cdate'])) {
|
|
|
+ $data['cdate'] = DEVER_TIME;
|
|
|
}
|
|
|
-
|
|
|
- if ($cache) {
|
|
|
- $this->db()->cache($cache, $result);
|
|
|
- } else {
|
|
|
- $this->db()->log($this->sql, $data, $result);
|
|
|
- }
|
|
|
-
|
|
|
- return $result;
|
|
|
- }
|
|
|
-
|
|
|
- public function rowCount($sql, $data = array())
|
|
|
- {
|
|
|
- return $this->query($sql, $data)->rowcount();
|
|
|
- }
|
|
|
-
|
|
|
- public function row($sql, $data = array())
|
|
|
- {
|
|
|
- return $this->query($sql, $data)->rowcount();
|
|
|
+ return $this->store->insert($this->config['table'], $data, $this->config['struct']);
|
|
|
}
|
|
|
-
|
|
|
- public function lastId($sql, $data = array())
|
|
|
+ public function update($param, $data)
|
|
|
{
|
|
|
- return $this->query($sql, $data)->id();
|
|
|
+ return $this->store->update($this->config['table'], $param, $data, $this->config['struct']);
|
|
|
}
|
|
|
-
|
|
|
- public function page($config = array(), $sql = false, $data = array())
|
|
|
+ public function delete($param)
|
|
|
{
|
|
|
- return $this->db()->getPageBySql($config, $sql, $data, $this);
|
|
|
+ return $this->store->delete($this->config['table'], $param, $this->config['struct']);
|
|
|
}
|
|
|
-
|
|
|
- public function index($index)
|
|
|
- {
|
|
|
- return $this->db()->index($index);
|
|
|
- }
|
|
|
-
|
|
|
public function begin()
|
|
|
{
|
|
|
- return $this->db()->begin();
|
|
|
+ return $this->store->begin();
|
|
|
}
|
|
|
-
|
|
|
public function commit()
|
|
|
{
|
|
|
- return $this->db()->commit();
|
|
|
+ return $this->store->commit();
|
|
|
}
|
|
|
-
|
|
|
public function rollback()
|
|
|
{
|
|
|
- return $this->db()->rollback();
|
|
|
+ return $this->store->rollback();
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- * __call
|
|
|
- *
|
|
|
- * @return mixd
|
|
|
- */
|
|
|
- public function __call($method, $param)
|
|
|
+ public function query($sql, $bind = array(), $page = array())
|
|
|
{
|
|
|
- if (isset($param[0][0]) && is_array($param[0][0])) {
|
|
|
- $result = array();
|
|
|
- foreach ($param[0] as $k => $v) {
|
|
|
- $result[] = $this->$method($v);
|
|
|
- }
|
|
|
-
|
|
|
- return $result;
|
|
|
- }
|
|
|
-
|
|
|
- $call = false;
|
|
|
- if (isset($param[1])) {
|
|
|
- if (is_object($param[1])) {
|
|
|
- $call = $param[1];
|
|
|
- } elseif ($method == 'insert') {
|
|
|
- $param[0]['insert_value_num'] = $param[1];
|
|
|
- }
|
|
|
+ if (strpos($sql, '{table}')) {
|
|
|
+ $sql = str_replace('{table}', $this->config['table'], $sql);
|
|
|
}
|
|
|
-
|
|
|
- $param = $param ? $this->initParam($param[0], $method) : array();
|
|
|
-
|
|
|
- $key = $this->table . $method . md5(serialize($param));
|
|
|
- if (isset($param['clear']) && $param['clear'] && isset($this->data[$key])) {
|
|
|
- unset($this->data[$key]);
|
|
|
- }
|
|
|
-
|
|
|
- $this->compatible($key, $method, $param);
|
|
|
-
|
|
|
- if (!isset($this->data[$key])) {
|
|
|
- $this->request($method, $param);
|
|
|
- if (isset($this->config['request'][$method]['type']) && in_array($this->config['request'][$method]['type'], array('update', 'insert'))) {
|
|
|
- return $this->callData($method, $param, $call);
|
|
|
+ if (isset($page['num'])) {
|
|
|
+ if (strpos($sql, 'limit')) {
|
|
|
+ $temp = explode('limit', $sql);
|
|
|
+ $sql = $temp[0];
|
|
|
}
|
|
|
- $this->data[$key] = $this->callData($method, $param, $call);
|
|
|
+ $sql .= ' limit ' . Paginator::init($page['num'], $page['page'] ?? 1, function()use($sql, $bind){return $this->queryCount($sql, $bind);});
|
|
|
}
|
|
|
-
|
|
|
- return $this->data[$key];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- * getData
|
|
|
- *
|
|
|
- * @return mixd
|
|
|
- */
|
|
|
- private function callData($method, $param, $call = false)
|
|
|
- {
|
|
|
- $param = $this->search($method, $param);
|
|
|
- $handle = new Model\Handle($method, $this->config, $param, $call);
|
|
|
- return $handle->get();
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- * compatible
|
|
|
- *
|
|
|
- * @return mixd
|
|
|
- */
|
|
|
- protected function compatible($key, $method, $param)
|
|
|
- {
|
|
|
- if (Config::get('database')->compatible && isset($this->config['project'])) {
|
|
|
- $file = $this->config['project']['path'] . 'database/' . ucfirst(Config::get('database')->compatible) . '/' . ucfirst($this->config['name']) . '.php';
|
|
|
- if (is_file($file)) {
|
|
|
- $class = ucfirst($this->config['project']['name']) . '\\Database\\' . ucfirst(Config::get('database')->compatible) . '\\' . ucfirst($this->config['name']);
|
|
|
- if (class_exists($class) && method_exists($class, $method)) {
|
|
|
- $this->data[$key] = $class::$method($param);
|
|
|
- }
|
|
|
- }
|
|
|
+ $result = $this->store->query($sql, $bind);
|
|
|
+ if (isset($page['num']) && empty($page['page'])) {
|
|
|
+ $result = $result->fetchAll();
|
|
|
+ Paginator::status(empty($result));
|
|
|
}
|
|
|
+ return $result;
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- * request
|
|
|
- *
|
|
|
- * @return mixd
|
|
|
- */
|
|
|
- protected function request($method, $param)
|
|
|
+ public function queryCount($sql, $bind)
|
|
|
{
|
|
|
- if (!isset($this->config['struct'])) {
|
|
|
- $this->config['struct'] = array();
|
|
|
- }
|
|
|
- if (empty($this->config['request'][$method]) && isset($this->config['struct'])) {
|
|
|
- $search = '';
|
|
|
- if (isset($param['search_type'])) {
|
|
|
- $search = $param['search_type'];
|
|
|
- }
|
|
|
-
|
|
|
- $this->config['request'][$method] = Model\Request::get($this->table, $method, $this->config['struct'], $search);
|
|
|
-
|
|
|
- if ($method == 'list' && isset($this->config['manage']['list_type']) && $this->config['manage']['list_type']) {
|
|
|
- $this->config['request']['list']['page'][0] = 50000;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- if (isset($this->config['request'][$method]['type']) && isset($this->config['request'][$method]['option']) && $this->config['request'][$method]['type'] == 'all' && isset($this->config['request'][$method . '_option'])) {
|
|
|
-
|
|
|
- $this->config['request'][$method]['option'] = array_merge($this->config['request'][$method]['option'], $this->config['request'][$method . '_option']);
|
|
|
- }
|
|
|
+ $sql = mb_strtolower($sql);
|
|
|
+ if (strpos($sql, ' from ')) {
|
|
|
+ $temp = explode(' from ', $sql);
|
|
|
}
|
|
|
-
|
|
|
- if (isset($param['config']) && isset($this->config['request'][$method]['config']) && $this->config['request'][$method]['config']) {
|
|
|
- $this->config['request'][$method] = array_merge($this->config['request'][$method], $param['config']);
|
|
|
- unset($param['config']);
|
|
|
- unset($this->config['request'][$method]['config']);
|
|
|
- }
|
|
|
-
|
|
|
- if (in_array($method, array('all', 'state', 'total', 'list', 'find')) && isset($param['option'])) {
|
|
|
- foreach ($param['option'] as $k => $v) {
|
|
|
- $this->config['request'][$method]['option'][$k] = $v;
|
|
|
+ if (isset($temp[1])) {
|
|
|
+ if (strpos($temp[1], ' order ')) {
|
|
|
+ $temp = explode(' order ', $temp[1]);
|
|
|
+ $sql = $temp[0];
|
|
|
+ } else {
|
|
|
+ $sql = $temp[1];
|
|
|
}
|
|
|
- }
|
|
|
- if ($method == 'list') {
|
|
|
- $search = Dever::search_button();
|
|
|
- if ($search) {
|
|
|
- $this->config['request']['list']['group'] = $search[0];
|
|
|
- $this->config['request']['list']['col'] = $search[1];
|
|
|
+ if (strpos($sql, 'group')) {
|
|
|
+ $sql = 'SELECT count(1) as num FROM (SELECT count(1) FROM '.$sql.' ) a ';
|
|
|
+ } else {
|
|
|
+ $sql = 'SELECT count(1) as num FROM ' . $sql;
|
|
|
}
|
|
|
+ return $this->store->query($sql, $bind)->fetchColumn();
|
|
|
}
|
|
|
-
|
|
|
- if (isset($param['join'])) {
|
|
|
- $this->config['request'][$method]['join'] = $param['join'];
|
|
|
- if (isset($this->config['request'][$method]['option'])) {
|
|
|
- foreach ($this->config['request'][$method]['option'] as $k => $v) {
|
|
|
- if (is_string($v) && !strstr($v, 't_1') && !strstr($k, '-')) {
|
|
|
- $this->config['request'][$method]['option'][$k] = 'yes-t_1.' . $k;
|
|
|
- }
|
|
|
- if (is_array($v) && !strstr($v[0], 't_1')) {
|
|
|
- if (strstr($v[0], '-')) {
|
|
|
- $temp = explode('-', $v[0]);
|
|
|
- $this->config['request'][$method]['option'][$k][0] = 'yes-t_1.' . $temp[1];
|
|
|
- } else {
|
|
|
- $this->config['request'][$method]['option'][$k][0] = 'yes-t_1.' . $k;
|
|
|
+ }
|
|
|
+ public function __call($method, $data)
|
|
|
+ {
|
|
|
+ if (isset($this->config['request'][$method])) {
|
|
|
+ $method = $this->config['request'][$method];
|
|
|
+ $param = array();
|
|
|
+ if (isset($method['where'])) {
|
|
|
+ $temp = array();
|
|
|
+ foreach ($method['where'] as $k => $v) {
|
|
|
+ if ($k == 'or' || $k == 'and') {
|
|
|
+ foreach ($v as $k1 => $v1) {
|
|
|
+ $this->callCreate($data, $temp, $k1, $v1);
|
|
|
}
|
|
|
+ } else {
|
|
|
+ $this->callCreate($data, $temp, $k, $v);
|
|
|
}
|
|
|
}
|
|
|
+ $param[] = $temp;
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- if (DEVER_APP_NAME != 'manage') {
|
|
|
- $lang = Dever::langConfig();
|
|
|
- if (Dever::config('base')->lang && $lang && $lang != Dever::config('base')->lang && isset($this->config['manage']['lang']) && $this->config['manage']['lang']) {
|
|
|
- $col = array();
|
|
|
- foreach ($this->config['manage']['lang'] as $k => $v) {
|
|
|
- $col[] = $lang . '_' . $v . ' as `' . $v . '`';
|
|
|
+ if (isset($method['data'])) {
|
|
|
+ $temp = array();
|
|
|
+ foreach ($method['data'] as $k => $v) {
|
|
|
+ $this->callCreate($data, $temp, $k, $v);
|
|
|
}
|
|
|
- if (!isset($this->config['request'][$method]['col'])) {
|
|
|
- $this->config['request'][$method]['col'] = '*';
|
|
|
- }
|
|
|
- $this->config['request'][$method]['col'] .= ',' . implode(',', $col);
|
|
|
+ $param[] = $temp;
|
|
|
+ }
|
|
|
+ if (isset($method['set']) && isset($data[1])) {
|
|
|
+ $param[] = array_merge($method['set'], $data[1]);
|
|
|
}
|
|
|
+ $type = $method['type'];
|
|
|
+ return $this->$type(...$param);
|
|
|
}
|
|
|
+ return false;
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- * search
|
|
|
- *
|
|
|
- * @return mixd
|
|
|
- */
|
|
|
- protected function search($method, $param)
|
|
|
+ private function callCreate($data, &$param, $k, $v)
|
|
|
{
|
|
|
- if (isset($param['search_type']) && $param['search_type'] == 2) {
|
|
|
- $join = array();
|
|
|
- $i = 2;
|
|
|
- foreach ($param as $k => $v) {
|
|
|
- if (strpos($k, '-') !== false) {
|
|
|
- $k = str_replace(array('option_', 'where_'), '', $k);
|
|
|
- if (isset($this->config['struct'][$k]) && isset($this->config['struct'][$k]['sync'])) {
|
|
|
- $temp = explode('-', $k);
|
|
|
- $join[] = array
|
|
|
- (
|
|
|
- 'table' => $temp[0] . '/' . $temp[1],
|
|
|
- 'type' => 'left join',
|
|
|
- 'on' => $this->config['struct'][$k]['sync'],
|
|
|
- );
|
|
|
-
|
|
|
- $t = 't_' . $i . '.' . $temp[2];
|
|
|
- $this->config['request'][$method]['option'][$t] = $this->config['request'][$method]['option'][$k];
|
|
|
- $param['option_' . $t] = $param['option_' . $k];
|
|
|
- unset($this->config['request'][$method]['option'][$k]);
|
|
|
- unset($param['option_' . $k]);
|
|
|
- $i++;
|
|
|
- }
|
|
|
+ if (is_array($v)) {
|
|
|
+ if (empty($data[0][$k])) {
|
|
|
+ if (empty($v[2])) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ $data[0][$k] = $v[2];
|
|
|
}
|
|
|
- if ($join) {
|
|
|
- $this->config['request'][$method]['join'] = $join;
|
|
|
+ $i = $v[0];
|
|
|
+ $j = array($v[1], $data[0][$k]);
|
|
|
+ } else {
|
|
|
+ if (empty($data[0][$k])) {
|
|
|
+ $data[0][$k] = $v;
|
|
|
}
|
|
|
+ $i = $k;
|
|
|
+ $j = $data[0][$k];
|
|
|
}
|
|
|
-
|
|
|
- return $param;
|
|
|
+ $this->callCreateParam($param, $i, $j);
|
|
|
}
|
|
|
-
|
|
|
- protected function searchFulltext($k, $param)
|
|
|
+ private function callCreateParam(&$param, $i, $j)
|
|
|
{
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- * initParam
|
|
|
- *
|
|
|
- * @return mixd
|
|
|
- */
|
|
|
- private function initParam($param, $method)
|
|
|
- {
|
|
|
- if ($param && !is_array($param)) {
|
|
|
- if ($this->config['link']) {
|
|
|
- $param = array('id' => $param);
|
|
|
- } else {
|
|
|
- $param = array('where_id' => $param, 'option_id' => $param);
|
|
|
- }
|
|
|
+ if (isset($param[$i])) {
|
|
|
+ $i .= '#';
|
|
|
+ return $this->callCreateParam($param, $i, $j);
|
|
|
}
|
|
|
- return $param;
|
|
|
+ $param[$i] = $j;
|
|
|
}
|
|
|
-}
|
|
|
+}
|