<?php
namespace framework\src\db;
use framework\cao as cao;
final class mysql extends cao {
static private $_id = NULL;
static private $_resource = array();
static private $_new = NULL;
static private function _register(){
if(self::$_new === NULL){
$db = parent::db();
self::$_new = $db['class'][__CLASS__]['register'];
}
return self::$_new;
}
static private function _error($message = '', $alert = false, $register_backtrace ){
$sort = count(self::$_resource[self::$_id]['runtime'])-1 self::$_resource[self::$_id]['error'][$sort][] = array(
'location' => parent::_location_( $register_backtrace ),
'message' => $message
);
self::$_resource[self::$_id]['last_error'] = $message;
if( !empty($alert) ){
parent::_error_message_(
$message,
$register_backtrace
);
}
}
static private function _cache_dir($folder_name, $register_backtrace){
if( empty(self::$_resource[self::$_id]['config']['cache_folder_name']) ||
!is_string(self::$_resource[self::$_id]['config']['cache_folder_name'])
){
self::_error(parent::language('db_cache_folder_name_illegal'), true, $register_backtrace);
}
$directory = CACHE_PATH.DIRECTORY_SEPARATOR.
self::$_resource[self::$_id]['config']['cache_folder_name'].DIRECTORY_SEPARATOR.
self::$_resource[self::$_id]['config']['type'].DIRECTORY_SEPARATOR.
$folder_name.DIRECTORY_SEPARATOR;
return $directory;
}
static private function _cache_mkdir($folder_name, $register_backtrace){
$directory = self::_cache_dir($folder_name, $register_backtrace);
self::_mkdir(
$directory,
true,
parent::language('db_cache_dir_mkdir', $directory),
$register_backtrace
);
return $directory;
}
static private function _mkdir($directory, $is_alert = false, $error_message = '', $register_backtrace = array()){
clearstatcache(true, $directory);
if( !is_dir($directory) || !is_writable($directory) ){
if( CACHE_PATH == '' || !mkdir($directory, 0777, true) ){
if( empty($is_alert) ){
return false;
}else{
self::_error($error_message, true, $register_backtrace);
}
}
}
return true;
}
static private function _file_unserialize($path_file){
clearstatcache(true, $path_file);
if( !is_file($path_file) || !is_writable($path_file) ){
return false;
}
$contents = unserialize(file_get_contents($path_file));
if( $contents === false ){
return false }else{
return $contents;
}
}
static private function _connect( $config, $register_backtrace ){
if( !empty(self::$_resource[self::$_id]['register']) ){
self::_close($register_backtrace);
}
self::$_resource[self::$_id]['id'] = self::$_id;
self::$_resource[self::$_id]['config'] = $config;
self::_lock_check_validity('database', $register_backtrace);
if( empty($config['base']) ){
self::_error(parent::language('db_base_exists'), true, $register_backtrace);
}
if( empty($config['charset']) ){
self::_error(parent::language('db_charset_exists'), true, $register_backtrace);
}
$sort = count(self::$_resource[self::$_id]['runtime'])-1;
self::$_resource[self::$_id]['register'] = mysqli_connect(
( empty($config['persistent'])? $config['host'] : 'p:'.$config['host'] ), $config['user'],
$config['pass'],
'',
$config['port']
);
if( empty(self::$_resource[self::$_id]['register']) ){
self::_error( parent::language('db_connect', cmd(array(mysqli_connect_errno()), 'str charset'), cmd(array(mysqli_connect_error()), 'str charset') ), true, $register_backtrace );
}else{
if( !empty($config['base_no_exists_create']) ){
if( !mysqli_query(self::$_resource[self::$_id]['register'], 'CREATE DATABASE IF NOT EXISTS `'.$config['base'].'`;') ){
self::_error( parent::language('db_create_base', $config['base'], mysqli_error(self::$_resource[self::$_id]['register']) ), true, $register_backtrace );
}
}
if( !mysqli_select_db( self::$_resource[self::$_id]['register'], $config['base']) ){
self::_error(parent::language('db_base_select', mysqli_error(self::$_resource[self::$_id]['register']) ), true, $register_backtrace);
}
if( !mysqli_set_charset(self::$_resource[self::$_id]['register'], $config['charset']) ){
self::_error( parent::language('db_charset_set', $config['charset'], mysqli_error(self::$_resource[self::$_id]['register']) ), true, $register_backtrace );
}
if( !isset(self::$_resource[self::$_id]['frequency']) ){
self::$_resource[self::$_id]['frequency'] = 0;
}
self::$_resource[self::$_id]['frequency'] ++;
self::$_resource[self::$_id]['location'] = parent::_location_( $register_backtrace );
parent::destruct('db:'.__CLASS__, function(){
call_user_func_array(array(__CLASS__, 'destruct'), array());
});
}
}
static private function _close(){
self::_work_rollback();
self::_lock_close();
if( !empty(self::$_resource[self::$_id]['register']) ){
mysqli_close( self::$_resource[self::$_id]['register'] );
self::$_resource[self::$_id]['register'] = null;
}
}
static private function _link($register_backtrace){
if( !isset( self::$_id ) || !isset( self::$_resource[self::$_id]['register'] ) ){
self::_config_(
(isset( self::$_id )? self::$_id : ''),
(isset( self::$_resource[self::$_id]['config'] )? self::$_resource[self::$_id]['config'] : parent::config('db')),
null,
$register_backtrace
);
}
return self::$_resource[self::$_id]['register'];
}
static private function _method_log( $log = array() ){
if( empty($log) ){
if(empty(self::$_resource[self::$_id]['method_log'])){
self::$_resource[self::$_id]['method_log'] = array();
}
}else{
self::$_resource[self::$_id]['runtime'][$log['sort']] += $log['runtime'];
if( !empty(self::$_resource[self::$_id]['config']['method_log']) ){
self::$_resource[self::$_id]['method_log'][] = $log;
}
}
}
static private function _query_log( $log = array() ){
if( empty($log) ){
if( empty(self::$_resource[self::$_id]['query_log']) ){
self::$_resource[self::$_id]['query_log'] = array();
}
}else{
if( !empty(self::$_resource[self::$_id]['config']['query_log']) ){
self::$_resource[self::$_id]['query_log'][] = $log;
}
}
}
static private function _query($sql, $type = false, $alert = false, $register_backtrace){
self::_lock_check_validity('database', $register_backtrace);
$microtime = microtime(true);
$resource = mysqli_query(self::_link($register_backtrace), $sql);
if( !$resource ){
self::_error($sql.' - SQL语句执行出错 - '.mysqli_error(self::_link($register_backtrace)), $alert, $register_backtrace);
$return_data = null
}else{
if( is_bool($resource) ){
if( mysqli_affected_rows( self::_link($register_backtrace) ) > 0 ){
$state = mysqli_insert_id( self::_link($register_backtrace) ) if( empty($state) ){
$return_data = true }else{
$return_data = $state }
}else{
$return_data = false }
}else{
$return_data = array() if( empty($type) ){
while( $assoc = mysqli_fetch_assoc($resource) ){
$return_data[] = $assoc }
mysqli_free_result($resource) }else{
while( $object = mysqli_fetch_object($resource) ){
$return_data[] = $object }
mysqli_free_result($resource) }
}
}
self::_query_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'sql' => $sql,
'location' => parent::_location_( $register_backtrace ),
'action' => (is_array($return_data)? (empty($type)? 'query array' : 'query object') : 'query affected'),
'resource' => (empty($return_data)? false : true),
'error' => (empty(self::$_resource[self::$_id]['last_error'])? '' : self::$_resource[self::$_id]['last_error']),
'runtime' => (microtime(true)-$microtime)
));
return $return_data;
}
static protected function _config_($identify, $config, $coverage = false, $register_backtrace = array()){
self::$_id = $identify;
self::$_resource[self::$_id]['runtime'][] = 0 self::$_resource[self::$_id]['query'] = array() if( empty(self::$_resource[$identify]['register']) || !empty($coverage) ){
call_user_func_array( array(__CLASS__, '_connect'), array($config, $register_backtrace ) );
}
self::_method_log() self::_query_log()
return self::_register();
}
static public function destruct(){
if( !empty(self::$_resource) && is_array(self::$_resource) ){
foreach(self::$_resource as $identify => $value){
self::$_id = $identify;
self::_close();
}
}
}
static public function resource(){
return self::$_resource;
}
static public function info(){
return self::$_resource[self::$_id];
}
static public function close(){
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
if( !empty(self::$_resource[self::$_id]['register']) ){
self::_close($register_backtrace);
}
}
static public function query(){
$microtime = microtime(true);
$func_get_args = parent::_args_( func_get_args() );
$sql = isset( $func_get_args['string'][0] )? $func_get_args['string'][0] : '';
$type = isset( $func_get_args['boolean'][0] )? $func_get_args['boolean'][0] : false;
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
$return_data = self::_query($sql, $type, true, $register_backtrace);
if(!empty($closure)){
$closure_return_data = call_user_func_array($closure, array($return_data, self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1 'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ) 'runtime' => (microtime(true)-$microtime) 'args' => array($sql, $type),
'sql' => null,
));
if( isset($closure_return_data) ){
return $closure_return_data }else{
return $return_data;
}
}
static public function call(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$method_name = isset( $func_get_args['string'][0] )? $func_get_args['string'][0] : '';
$method_tags = isset( $func_get_args['array'][0] )? $func_get_args['array'][0] : array();
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
if( empty($method_name) ){
self::_error(parent::language('db_call_method_empty'), true, $register_backtrace);
}
$method_name = trim(strtolower($method_name));
$methods = array('joinon','where','having','data','orderby','groupby','table','limit');
if( !in_array($method_name, $methods) ){
self::_error(parent::language('db_call_method_illegal', $method_name), true, $register_backtrace);
}
call_user_func_array(array(__CLASS__, $method_name ), $method_tags);
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => array($method_name, $method_tags),
'sql' => null,
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function clear(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$method_name = isset( $func_get_args['string'][0] )? $func_get_args['string'][0] : '';
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
if( !empty($func_get_args['string']) ){
foreach($func_get_args['string'] as $key => $value){
if( isset(self::$_resource[self::$_id]['query'][$value]) ){
unset(self::$_resource[self::$_id]['query'][$value]) }
}
}else{
self::$_resource[self::$_id]['query'] = array() }
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $func_get_args['string'],
'sql' => null,
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function base(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$base_name = isset( $func_get_args['string'][0] )? $func_get_args['string'][0] : '';
$create = isset( $func_get_args['boolean'][0] )? $func_get_args['boolean'][0] : false;
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
if( $base_name != '' && !empty($create) ){
self::_query('CREATE DATABASE IF NOT EXISTS `'.$base_name.'`;', null, true, $register_backtrace);
}
if( $base_name == '' ){
self::_error(parent::language('db_base_exists'), true, $register_backtrace);
}
if( !mysqli_select_db( self::_link($register_backtrace), $base_name) ){
self::_error(parent::language('db_base_select', mysqli_error(self::_link($register_backtrace)) ), true, $register_backtrace);
}
self::$_resource[self::$_id]['config']['base'] = $base_name;
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $base_name,
'sql' => null,
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function charset(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$charset = isset( $func_get_args['string'][0] )? $func_get_args['string'][0] : '';
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
if( $charset == '' ){
self::_error(parent::language('db_charset_exists'), true, $register_backtrace);
}
if( !mysqli_set_charset(self::_link($register_backtrace), $charset) ){
self::_error( parent::language('db_charset_set', $charset, mysqli_error(self::_link($register_backtrace)) ), true, $register_backtrace );
}
self::$_resource[self::$_id]['config']['charset'] = $charset;
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $charset,
'sql' => null,
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function prefix(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$prefix = isset( $func_get_args['string'][0] )? $func_get_args['string'][0] : '';
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
self::$_resource[self::$_id]['config']['prefix'] = $prefix;
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $prefix,
'sql' => null,
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function table(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
if( empty(self::$_resource[self::$_id]['query']['base']) ){
self::$_resource[self::$_id]['query']['base'] = array();
}
if( empty(self::$_resource[self::$_id]['query']['base'][self::$_resource[self::$_id]['config']['base']]) ){
self::$_resource[self::$_id]['query']['base'][self::$_resource[self::$_id]['config']['base']] = array();
}
if( empty(self::$_resource[self::$_id]['query']['table']) ){
self::$_resource[self::$_id]['query']['table'] = '';
}else{
self::$_resource[self::$_id]['query']['table'] .= ',';
}
if( !empty($func_get_args['string']) ){
foreach($func_get_args['string'] as $value){
$table_array = preg_split('/\s+/', trim(str_ireplace(' as ', ' ', $value)));
if( empty($table_array[0]) ){
continue;
}
if( !in_array(self::$_resource[self::$_id]['config']['prefix'].$table_array[0], self::$_resource[self::$_id]['query']['base'][self::$_resource[self::$_id]['config']['base']] ) ){
self::$_resource[self::$_id]['query']['base'][self::$_resource[self::$_id]['config']['base']][] = self::$_resource[self::$_id]['config']['prefix'].$table_array[0];
}
if( empty($table_array[1]) ){
self::$_resource[self::$_id]['query']['table'] .=
'`'.self::$_resource[self::$_id]['config']['base'].'`.'.'`'.self::$_resource[self::$_id]['config']['prefix'].$table_array[0].'`,';
}else{
self::$_resource[self::$_id]['query']['table'] .=
'`'.self::$_resource[self::$_id]['config']['base'].'`.'.'`'.self::$_resource[self::$_id]['config']['prefix'].$table_array[0].'` AS '.$table_array[1].',';
}
}
}
if( self::$_resource[self::$_id]['query']['table'] != '' ){
self::$_resource[self::$_id]['query']['table'] = substr(self::$_resource[self::$_id]['query']['table'], 0, -1);
}
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $func_get_args['string'],
'sql' => self::$_resource[self::$_id]['query']['table'],
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function from(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
self::$_resource[self::$_id]['query']['from'] = isset( $func_get_args['string'][0] )? $func_get_args['string'][0] : '';
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1 'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $func_get_args['args'],
'sql' => self::$_resource[self::$_id]['query']['from'],
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function joinon(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
if( empty(self::$_resource[self::$_id]['query']['base']) ){
self::$_resource[self::$_id]['query']['base'] = array();
}
if( empty(self::$_resource[self::$_id]['query']['joinon']) ){
self::$_resource[self::$_id]['query']['joinon'] = '';
}
if( !empty($func_get_args['array']) ){
foreach($func_get_args['array'] as $value){
if( !isset($value['base']) ){
$value['base'] = self::$_resource[self::$_id]['config']['base'] }
if( empty(self::$_resource[self::$_id]['query']['base'][$value['base']]) ){
self::$_resource[self::$_id]['query']['base'][$value['base']] = array();
}
if( empty($value['table']) ){
continue }
$table_array = preg_split('/\s+/', trim(str_ireplace(' as ', ' ', $value['table'])));
if( empty($table_array[0]) ){
continue;
}
if( empty($value['type']) ){
$value['type'] = 'INNER' }else{
$value['type']=strtoupper($value['type']) }
if( empty($value['on']) ){
$value['on'] = '';
}
if( !isset($value['prefix']) ){
$value['prefix'] = self::$_resource[self::$_id]['config']['prefix'] }
if( !in_array($value['prefix'].$table_array[0], self::$_resource[self::$_id]['query']['base'][$value['base']]) ){
self::$_resource[self::$_id]['query']['base'][$value['base']][] = $value['prefix'].$table_array[0];
}
if( empty($table_array[1]) ){
self::$_resource[self::$_id]['query']['joinon'] .= ' '.$value['type'].' JOIN `'.$value['base'].'`.`'.$value['prefix'].$table_array[0].'` ON '.$value['on'];
}else{
self::$_resource[self::$_id]['query']['joinon'] .= ' '.$value['type'].' JOIN `'.$value['base'].'`.`'.$value['prefix'].$table_array[0].'` AS '.$table_array[1].' ON '.$value['on'];
}
}
self::$_resource[self::$_id]['query']['joinon'] = trim(self::$_resource[self::$_id]['query']['joinon']);
}
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $func_get_args['array'],
'sql' => self::$_resource[self::$_id]['query']['joinon'],
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static private function _where_having($args){
$data = array(
'hyphen' => 'AND' 'sql' => ' );
$i = 1;
foreach($args as $value){
if( empty($value[0]) ){
continue }else{
$value[0] = trim($value[0]);
}
if( !isset($value[1]) ){
$value[1] = '';
}
if( !is_integer($value[1]) && !is_float($value[1]) ){
if( empty($value[2]) ){
$value[1] = parent::cmd(array($value[1]), 'str addslashes') }
}
preg_match('/^\[([\w\s]+)\][\s+]?(.*)/i', $value[0], $match);
if( $i == 1 ){
if( !empty($match) ){
$data['hyphen'] = strtoupper($match[1]);
$value[0] = $match[2];
}
}else{
if( empty($match) ){
$value[0] = 'AND '.$value[0];
}else{
$value[0] = strtoupper(trim($match[1])).' '.$match[2];
}
}
$value[0] = preg_replace(array(
'/\[\s{0,}\+\s{0,}\]/i',
'/\[\s{0,}\-\s{0,}\]/i',
'/\[\s{0,}\]/i',
), array('[+]', '[-]', '[]'), $value[0]);
if( mb_strpos($value[0], '[+]') !== false ){
$value[1] = '\''.$value[1].'\'';
$data['sql'] .= ' '.str_replace('[+]', $value[1], $value[0]);
}else
if( mb_strpos($value[0], '[-]') !== false ){
$data['sql'] .= ' '.str_replace('[-]', $value[1], $value[0]);
}else
if( mb_strpos($value[0], '[]') !== false ){
if( !is_integer($value[1]) && !is_float($value[1]) ){
$value[1] = '\''.$value[1].'\'';
}
$data['sql'] .= ' '.str_replace('[]', $value[1], $value[0]);
}else{
$data['sql'] .= ' '.$value[0];
}
$i++;
}
return $data;
}
static public function where(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
if( !empty($func_get_args['array']) ){
$data = self::_where_having($func_get_args['array']);
}
if( empty($data['sql']) ){
if( empty(self::$_resource[self::$_id]['query']['where']) ){
self::$_resource[self::$_id]['query']['where'] = '';
}
}else{
if( empty(self::$_resource[self::$_id]['query']['where']) ){
self::$_resource[self::$_id]['query']['where'] = 'WHERE ( '.trim($data['sql']).' )';
}else{
self::$_resource[self::$_id]['query']['where'] .= ' '.$data['hyphen'].' ( '.trim($data['sql']).' )';
}
}
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $func_get_args['array'],
'sql' => self::$_resource[self::$_id]['query']['where'],
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function having(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
if( !empty($func_get_args['array']) ){
$data = self::_where_having($func_get_args['array']);
}
if( empty($data['sql']) ){
if( empty(self::$_resource[self::$_id]['query']['having']) ){
self::$_resource[self::$_id]['query']['having'] = '';
}
}else{
if( empty(self::$_resource[self::$_id]['query']['having']) ){
self::$_resource[self::$_id]['query']['having'] = 'HAVING ( '.trim($data['sql']).' )';
}else{
self::$_resource[self::$_id]['query']['having'] .= ' '.$data['hyphen'].' ( '.trim($data['sql']).' )';
}
}
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $func_get_args['array'],
'sql' => self::$_resource[self::$_id]['query']['having'],
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function groupby(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
$groupby = '' if( !empty($func_get_args['string']) ){
foreach($func_get_args['string'] as $value){
$groupby .= $value.',';
}
if( $groupby != '' ){
$groupby = trim(substr($groupby, 0, -1)) }
}
if( empty(self::$_resource[self::$_id]['query']['groupby']) ){
if( $groupby != '' ){
self::$_resource[self::$_id]['query']['groupby'] = 'GROUP BY '.$groupby;
}else{
self::$_resource[self::$_id]['query']['groupby'] = '';
}
}else{
self::$_resource[self::$_id]['query']['groupby'] .= ','.$groupby;
}
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $func_get_args['string'],
'sql' => self::$_resource[self::$_id]['query']['groupby'],
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function orderby(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
$orderby = '';
if( !empty($func_get_args['string']) ){
foreach($func_get_args['string'] as $value){
$value = trim($value);
if( $value == ''){
continue }
$value = preg_replace(array('/asc$/i', '/desc$/i'), array('ASC', 'DESC'), $value);
$orderby .= $value.',';
}
}
if( !empty($func_get_args['array']) ){
foreach($func_get_args['array'] as $value){
if( empty($value[0]) || !is_string($value[0]) ){
continue;
}
$value[0] = trim($value[0]);
if( $value[0] == ''){
continue;
}
if( empty($value[1]) ){
$value[1] = 'ASC';
}else{
$value[1] = 'DESC';
}
$orderby .= $value[0].' '.$value[1].',';
}
}
if( $orderby != '' ){
$orderby = substr($orderby, 0, -1);
}
if( empty(self::$_resource[self::$_id]['query']['orderby']) ){
if( $orderby != '' ){
self::$_resource[self::$_id]['query']['orderby'] = 'ORDER BY '.$orderby;
}else{
self::$_resource[self::$_id]['query']['orderby'] = '';
}
}else{
self::$_resource[self::$_id]['query']['orderby'] .= ','.$orderby;
}
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => array($func_get_args['string'], $func_get_args['array']),
'sql' => self::$_resource[self::$_id]['query']['orderby'],
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function limit(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
self::$_resource[self::$_id]['query']['limit'] = '';
if( !empty($func_get_args['identify']) ){
$i = 0 foreach($func_get_args['identify'] as $value){
if( is_string($value) ){
$value = trim($value);
}
if( $value === '' || !is_numeric($value) ){
continue;
}
if( $i < 2 ){
if( $i == 0 ){
self::$_resource[self::$_id]['query']['limit'] .= $value;
}else{
self::$_resource[self::$_id]['query']['limit'] .= ','.$value;
}
$i++;
}
if( $i == 2 ){
break }
}
}
if( self::$_resource[self::$_id]['query']['limit'] != '' ){
self::$_resource[self::$_id]['query']['limit'] = 'LIMIT '.self::$_resource[self::$_id]['query']['limit'];
}
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $func_get_args['identify'],
'sql' => self::$_resource[self::$_id]['query']['limit'],
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function batch(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
self::$_resource[self::$_id]['query']['batch'] = true;
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => NULL,
'sql' => NULL,
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function data(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
$temp_data = array();
if( !empty($func_get_args['array']) ){
foreach($func_get_args['array'] as $value){
if( !isset($value[0]) || (!is_numeric($value[0]) && !is_string($value[0])) ){
continue }
if( !isset($value[1]) ){
$value[1] = '';
}
if( !is_numeric($value[1]) && !is_string($value[1]) ){
continue }
if( !is_integer($value[1]) && !is_float($value[1]) ){
if( empty($value[2]) ){
$value[1] = parent::cmd(array($value[1]), 'str addslashes') }
}
$value[0] = preg_replace(array(
'/\=\s{0,}\[\s{0,}\+\s{0,}\]/i',
'/\=\s{0,}\[\s{0,}\-\s{0,}\]/i',
'/\=\s{0,}\[\s{0,}\]/i',
), array('=[+]', '=[-]', '=[]'), $value[0]);
if( mb_strpos($value[0], '=[+]') !== false ){
$value[0] = trim(str_replace('=[+]', '', $value[0])) $value[0] = parent::cmd(array($value[0]), 'str addslashes') $temp_data[$value[0]] = '\''.$value[1].'\'';
}else
if( mb_strpos($value[0], '=[-]') !== false ){
$value[0] = trim(str_replace('=[-]', '', $value[0])) $value[0] = parent::cmd(array($value[0]), 'str addslashes') $temp_data[$value[0]] = $value[1];
}else
if( mb_strpos($value[0], '=[]') !== false ){
$value[0] = trim(str_replace('=[]', '', $value[0])) $value[0] = parent::cmd(array($value[0]), 'str addslashes') if( !is_integer($value[1]) && !is_float($value[1]) ){
$value[1] = '\''.$value[1].'\'';
}
$temp_data[$value[0]] = $value[1];
}else{
$exp_arr = explode('=', $value[0], 2);
$exp_arr[0] = trim(str_replace('=[]', '', $exp_arr[0])) $exp_arr[1] = isset($exp_arr[1])? $exp_arr[1] : '\'\'' $temp_data[$exp_arr[0]] = $exp_arr[1];
}
}
}
$method_log_sql = NULL;
if( !empty($temp_data) ){
if( empty(self::$_resource[self::$_id]['query']['batch']) ){
if( empty(self::$_resource[self::$_id]['query']['data']) ){
self::$_resource[self::$_id]['query']['data'] = array();
}
self::$_resource[self::$_id]['query']['data'] = array_merge(self::$_resource[self::$_id]['query']['data'], $temp_data);
$method_log_sql = self::$_resource[self::$_id]['query']['data'];
}else{
if( empty(self::$_resource[self::$_id]['query']['batch_data']) ){
self::$_resource[self::$_id]['query']['batch_data'] = array();
}
self::$_resource[self::$_id]['query']['batch_data'][] = $temp_data;
$method_log_sql = self::$_resource[self::$_id]['query']['batch_data'];
}
}
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $func_get_args['array'],
'sql' => $method_log_sql,
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function all(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
self::$_resource[self::$_id]['query']['all'] = true;
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => NULL,
'sql' => NULL,
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static public function find(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$type = isset( $func_get_args['boolean'][0] )? $func_get_args['boolean'][0] : false;
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
$select = '';
if( !empty($func_get_args['string']) ){
foreach($func_get_args['string'] as $value){
$value = trim(trim($value),',');
if( $value == ''){
continue }
$select .= $value.',';
}
}
if( !empty($func_get_args['array']) ){
$select_array = array();
foreach($func_get_args['array'] as $value){
$select_array = array_merge($select_array, $value);
}
if( !empty($select_array) ){
$select_array = array_unique($select_array);
foreach($select_array as $value){
$value = trim(trim($value),',');
if( $value == ''){
continue }
$select .= $value.',';
}
}
}
if( $select != '' ){
$select = substr($select, 0, -1);
}else{
$select = '*';
}
if( empty(self::$_resource[self::$_id]['query']['from']) ){
if( !isset(self::$_resource[self::$_id]['query']['table']) ){
self::$_resource[self::$_id]['query']['table'] = '';
}
$from = ' FROM '.self::$_resource[self::$_id]['query']['table'];
}else{
$from = ' FROM '.self::$_resource[self::$_id]['query']['from'];
}
$joinon = empty(self::$_resource[self::$_id]['query']['joinon'])?'':' '.self::$_resource[self::$_id]['query']['joinon'];
$where = empty(self::$_resource[self::$_id]['query']['where'])?'':' '.self::$_resource[self::$_id]['query']['where'];
$groupby = empty(self::$_resource[self::$_id]['query']['groupby'])?'':' '.self::$_resource[self::$_id]['query']['groupby'];
$having = empty(self::$_resource[self::$_id]['query']['having'])?'':' '.self::$_resource[self::$_id]['query']['having'];
$orderby = empty(self::$_resource[self::$_id]['query']['orderby'])?'':' '.self::$_resource[self::$_id]['query']['orderby'];
$limit = empty(self::$_resource[self::$_id]['query']['limit'])?' LIMIT 0,1':' '.self::$_resource[self::$_id]['query']['limit'];
self::$_resource[self::$_id]['query']['find'] = 'SELECT '.$select.$from.$joinon.$where.$groupby.$having.$orderby.$limit;
self::$_resource[self::$_id]['query']['sql'] = self::$_resource[self::$_id]['query']['find'].';' $sql = self::$_resource[self::$_id]['query']['sql']
self::_lock_check_validity('select', $register_backtrace);
if(!empty($closure)){
$closure_data = call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => array($select, $type),
'sql' => self::$_resource[self::$_id]['query']['find'],
));
if( isset($closure_data) ){
return $closure_data }else{
$return_data = self::_query($sql, $type, true, $register_backtrace) if( isset($return_data[0]) ){
return $return_data[0] }else{
return array();
}
}
}
static public function select(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$type = isset( $func_get_args['boolean'][0] )? $func_get_args['boolean'][0] : false;
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
$select = '';
if( !empty($func_get_args['string']) ){
foreach($func_get_args['string'] as $value){
$value = trim(trim($value),',');
if( $value == ''){
continue }
$select .= $value.',';
}
}
if( !empty($func_get_args['array']) ){
$select_array = array();
foreach($func_get_args['array'] as $value){
$select_array = array_merge($select_array, $value);
}
if( !empty($select_array) ){
$select_array = array_unique($select_array);
foreach($select_array as $value){
$value = trim(trim($value),',');
if( $value == ''){
continue }
$select .= $value.',';
}
}
}
if( $select != '' ){
$select = substr($select, 0, -1);
}else{
$select = '*';
}
if( empty(self::$_resource[self::$_id]['query']['from']) ){
if( !isset(self::$_resource[self::$_id]['query']['table']) ){
self::$_resource[self::$_id]['query']['table'] = '';
}
$from = ' FROM '.self::$_resource[self::$_id]['query']['table'];
}else{
$from = ' FROM '.self::$_resource[self::$_id]['query']['from'];
}
$joinon = empty(self::$_resource[self::$_id]['query']['joinon'])?'':' '.self::$_resource[self::$_id]['query']['joinon'];
$where = empty(self::$_resource[self::$_id]['query']['where'])?'':' '.self::$_resource[self::$_id]['query']['where'];
$groupby = empty(self::$_resource[self::$_id]['query']['groupby'])?'':' '.self::$_resource[self::$_id]['query']['groupby'];
$having = empty(self::$_resource[self::$_id]['query']['having'])?'':' '.self::$_resource[self::$_id]['query']['having'];
$orderby = empty(self::$_resource[self::$_id]['query']['orderby'])?'':' '.self::$_resource[self::$_id]['query']['orderby'];
$limit = empty(self::$_resource[self::$_id]['query']['limit'])?'':' '.self::$_resource[self::$_id]['query']['limit'];
self::$_resource[self::$_id]['query']['select'] = 'SELECT '.$select.$from.$joinon.$where.$groupby.$having.$orderby.$limit;
self::$_resource[self::$_id]['query']['sql'] = self::$_resource[self::$_id]['query']['select'].';' $sql = self::$_resource[self::$_id]['query']['sql']
self::_lock_check_validity('select', $register_backtrace);
if(!empty($closure)){
$closure_data = call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => array($select, $type),
'sql' => self::$_resource[self::$_id]['query']['select'],
));
if( isset($closure_data) ){
return $closure_data }else{
return self::_query($sql, $type, true, $register_backtrace) }
}
static private function _insert_update($args){
if( empty($args) || !is_array($args)){
return false;
}
$temp_data = array();
foreach($args as $key => $value){
if( !isset($key) || (!is_numeric($key) && !is_string($key)) ){
continue }
if( !is_numeric($value) && !is_string($value) ){
continue }
if( isset($value) && !is_integer($value) && !is_float($value) && $value != '' ){
$value = '\''.parent::cmd(array($value), 'str addslashes').'\'' }else
if( !isset($value) || $value === '' ){
$value = '\'\'';
}
$key = parent::cmd(array($key), 'str addslashes') $temp_data[$key] = $value;
}
if( !empty($temp_data) ){
if( empty(self::$_resource[self::$_id]['query']['batch']) ){
if( empty(self::$_resource[self::$_id]['query']['data']) ){
self::$_resource[self::$_id]['query']['data'] = array();
}
self::$_resource[self::$_id]['query']['data'] = array_merge(self::$_resource[self::$_id]['query']['data'], $temp_data);
}else{
if( empty(self::$_resource[self::$_id]['query']['batch_data']) ){
self::$_resource[self::$_id]['query']['batch_data'] = array();
}
self::$_resource[self::$_id]['query']['batch_data'][] = $temp_data;
}
}
}
static public function insert(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
if( !empty($func_get_args['array']) ){
foreach($func_get_args['array'] as $args){
if( empty(self::$_resource[self::$_id]['query']['batch']) ){
self::_insert_update($args);
}else
if( is_array($args) ){
foreach($args as $args_value){
self::_insert_update($args_value);
}
}
}
}
if( empty(self::$_resource[self::$_id]['query']['batch']) ){
$data_key = '';
$data_value = '';
if( !empty(self::$_resource[self::$_id]['query']['data']) ){
foreach(self::$_resource[self::$_id]['query']['data'] as $key => $value){
$data_key .= '`'.$key.'`,';
$data_value .= $value.',';
}
$data_key = substr($data_key, 0, -1);
$data_value = substr($data_value, 0, -1);
}
self::$_resource[self::$_id]['query']['keys'] = '( '.$data_key.' )';
self::$_resource[self::$_id]['query']['values'] = '( '.$data_value.' )';
self::$_resource[self::$_id]['query']['keys_values'] = '( '.$data_key.' ) VALUES ( '.$data_value.' )';
}else{
$keys_string = '';
$values_string = '';
if( !empty(self::$_resource[self::$_id]['query']['batch_data']) ){
$keys_array = array();
$values_array = array();
foreach(self::$_resource[self::$_id]['query']['batch_data'] as $batch_args){
if( empty($batch_args) || !is_array($batch_args) ){
continue;
}
$temp_value = '';
if( empty($keys_array) ){
foreach($batch_args as $key => $value){
if( !isset($keys_array[$key]) ){
$keys_string .= '`'.$key.'`,';
$temp_value .= $value.',';
$keys_array[$key] = $key;
}
}
}else{
if( count($batch_args) != count($keys_array) ){
self::$_resource[self::$_id]['query']['batch_error'] = true;
break;
}
foreach($keys_array as $keys_key => $keys_value){
if( !isset($batch_args[$keys_key]) ){
self::$_resource[self::$_id]['query']['batch_error'] = true;
break;
}else{
$temp_value .= $batch_args[$keys_key].',';
}
}
}
if( $temp_value != ''){
$values_array[] = '( '.substr($temp_value, 0, -1).' )';
}
}
if( $keys_string != '' ) $keys_string = substr($keys_string, 0, -1);
if( !empty($values_array) ){
$values_string = implode(",", $values_array);
}
}
self::$_resource[self::$_id]['query']['keys'] = '( '.$keys_string.' )';
self::$_resource[self::$_id]['query']['values'] = $values_string;
self::$_resource[self::$_id]['query']['keys_values'] = '( '.$keys_string.' ) VALUES '.$values_string;
}
if( empty(self::$_resource[self::$_id]['query']['from']) ){
if( !isset(self::$_resource[self::$_id]['query']['table']) ){
self::$_resource[self::$_id]['query']['table'] = '';
}
$from = ' '.self::$_resource[self::$_id]['query']['table'];
}else{
$from = ' '.self::$_resource[self::$_id]['query']['from'];
}
self::$_resource[self::$_id]['query']['insert'] = 'INSERT INTO'.$from.' '.self::$_resource[self::$_id]['query']['keys_values'];
self::$_resource[self::$_id]['query']['sql'] = self::$_resource[self::$_id]['query']['insert'].';' $sql = self::$_resource[self::$_id]['query']['sql']
self::_lock_check_validity('insert', $register_backtrace);
if(!empty($closure)){
$closure_data = call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $args,
'sql' => self::$_resource[self::$_id]['query']['insert'],
));
if(isset($closure_data)){
return $closure_data }else{
if( !empty(self::$_resource[self::$_id]['query']['batch_error']) ){
self::_error(__FUNCTION__.'() 的 batch() 操作有错误,请检查插入的键值参数!', true, $register_backtrace);
}
return self::_query($sql, NULL, true, $register_backtrace) }
}
static public function update(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
$args = array();
if( !empty($func_get_args['array']) ){
foreach($func_get_args['array'] as $value){
$args = array_merge($args, $value);
}
}
if( !empty($args) ){
self::_insert_update($args);
}
self::$_resource[self::$_id]['query']['set'] = '';
if( !empty(self::$_resource[self::$_id]['query']['data']) ){
foreach(self::$_resource[self::$_id]['query']['data'] as $key => $value){
self::$_resource[self::$_id]['query']['set'] .= '`'.$key.'`='.$value.',';
}
self::$_resource[self::$_id]['query']['set'] = substr(self::$_resource[self::$_id]['query']['set'], 0, -1);
}
$set = self::$_resource[self::$_id]['query']['set'] == ''? '':' SET '.self::$_resource[self::$_id]['query']['set'];
if( empty(self::$_resource[self::$_id]['query']['from']) ){
if( !isset(self::$_resource[self::$_id]['query']['table']) ){
self::$_resource[self::$_id]['query']['table'] = '';
}
$from = ' '.self::$_resource[self::$_id]['query']['table'];
}else{
$from = ' '.self::$_resource[self::$_id]['query']['from'];
}
$where = empty(self::$_resource[self::$_id]['query']['where'])?'':' '.self::$_resource[self::$_id]['query']['where'];
$orderby = empty(self::$_resource[self::$_id]['query']['orderby'])?'':' '.self::$_resource[self::$_id]['query']['orderby'];
$limit = empty(self::$_resource[self::$_id]['query']['limit'])?'':' '.self::$_resource[self::$_id]['query']['limit'];
self::$_resource[self::$_id]['query']['update'] = 'UPDATE'.$from.$set.$where.$orderby.$limit;
self::$_resource[self::$_id]['query']['sql'] = self::$_resource[self::$_id]['query']['update'].';' $sql = self::$_resource[self::$_id]['query']['sql']
self::_lock_check_validity('update', $register_backtrace);
if(!empty($closure)){
$closure_data = call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => $args,
'sql' => self::$_resource[self::$_id]['query']['update'],
));
if(isset($closure_data)){
return $closure_data }else{
if( empty(self::$_resource[self::$_id]['query']['all']) && empty($where) ){
self::_error(__FUNCTION__.'() 的 where() 条件为空 ,无法执行该语句!可以使用 all() 将操作该表字段的所有记录,请慎重使用!但 all()在有 where() 条件 的情况下无效!', true, $register_backtrace);
}
return self::_query($sql, NULL, true, $register_backtrace) }
}
static public function delete(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
if( empty(self::$_resource[self::$_id]['query']['from']) ){
if( !isset(self::$_resource[self::$_id]['query']['table']) ){
self::$_resource[self::$_id]['query']['table'] = '';
}
$from = ' '.self::$_resource[self::$_id]['query']['table'];
}else{
$from = ' '.self::$_resource[self::$_id]['query']['from'];
}
$where = empty(self::$_resource[self::$_id]['query']['where'])?'':' '.self::$_resource[self::$_id]['query']['where'];
$orderby = empty(self::$_resource[self::$_id]['query']['orderby'])?'':' '.self::$_resource[self::$_id]['query']['orderby'];
$limit = empty(self::$_resource[self::$_id]['query']['limit'])?'':' '.self::$_resource[self::$_id]['query']['limit'];
self::$_resource[self::$_id]['query']['delete'] = 'DELETE FROM'.$from.$where.$orderby.$limit;
self::$_resource[self::$_id]['query']['sql'] = self::$_resource[self::$_id]['query']['delete'].';' $sql = self::$_resource[self::$_id]['query']['sql']
self::_lock_check_validity('delete', $register_backtrace);
if(!empty($closure)){
$closure_data = call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => NULL,
'sql' => self::$_resource[self::$_id]['query']['delete'],
));
if(isset($closure_data)){
return $closure_data }else{
if( empty(self::$_resource[self::$_id]['query']['all']) && empty($where) ){
self::_error(__FUNCTION__.'() 的 where() 条件为空 ,无法执行该语句!可以使用 all() 将操作该表字段的所有记录,请慎重使用!但 all()在有 where() 条件 的情况下无效!', true, $register_backtrace);
}
return self::_query($sql, NULL, true, $register_backtrace) }
}
static public function session(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$data = isset($func_get_args['args'][0])? $func_get_args['args'][0] : NULL;
$exists = isset($func_get_args['args'][1])? $func_get_args['args'][1] : NULL;
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
if( empty($data) || !is_array($data) ){
if(!is_string($data) && !is_numeric($data)){
$data = '';
}else{
$data = (string)$data;
}
$return_data = self::_session_start($data, $exists, $register_backtrace);
}else{
$return_data = self::_session_update($data, $register_backtrace);
}
if(!empty($closure)){
$closure_return_data = call_user_func_array($closure, array($return_data, self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1 'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ) 'runtime' => (microtime(true)-$microtime) 'args' => empty($data)? null : $data,
'sql' => null,
));
if( isset($closure_return_data) ){
return $closure_return_data }else{
return $return_data;
}
}
static private function _session_start($session_id, $exists, $register_backtrace){
if( empty(self::$_resource[self::$_id]['config']['session']['table']['name']) ||
!is_string(self::$_resource[self::$_id]['config']['session']['table']['name']) ){
self::_error(parent::language('db_session_table_illegal'), true, $register_backtrace);
}
if( empty(self::$_resource[self::$_id]['config']['session']['table']['field']) ||
!is_array(self::$_resource[self::$_id]['config']['session']['table']['field'])){
self::_error(parent::language('db_session_table_field_illegal'), true, $register_backtrace);
}
$table_name = self::$_resource[self::$_id]['config']['session']['table']['name'];
if( isset(self::$_resource[self::$_id]['config']['prefix']) &&
is_string(self::$_resource[self::$_id]['config']['prefix']) ){
$table_name = self::$_resource[self::$_id]['config']['prefix'].$table_name;
}
if( empty($exists) ){
$sql = "select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='".self::$_resource[self::$_id]['config']['base']."' and TABLE_NAME='".$table_name."';";
$is_exist = self::_query($sql, false, true, $register_backtrace);
if( empty($is_exist) ){
if( empty(self::$_resource[self::$_id]['config']['session']['found']) ){
self::_error(parent::language('db_session_table_exists', self::$_resource[self::$_id]['config']['base'], $table_name), true, $register_backtrace);
}else{
self::_session_create($table_name, $register_backtrace);
}
}
}
$field_list = self::_session_field($register_backtrace);
if($session_id == ''){
$session_id = self::_session_closure('id', 'string', array('db_session_id_define', 'db_session_id_illegal'), $register_backtrace);
$exists = false;
}
if( $exists === NULL ){
self::clear() self::table(self::$_resource[self::$_id]['config']['session']['table']['name']);
self::where(array($field_list['id']."=[]", $session_id));
$sql_find = self::find($field_list['id'], function($info){
return $info['query']['sql'];
});
$exists = (bool)self::_query($sql_find, false, true, $register_backtrace);
}
if( empty($exists) ){
$session_id = self::_session_closure('id', 'string', array('db_session_id_define', 'db_session_id_illegal'), $register_backtrace);
$expire_time = self::_session_closure('expire_time', 'int', array('db_session_expire_time_define', 'db_session_expire_time_illegal'), $register_backtrace);
$field_data = array();
$field_data[$field_list['id']] = $session_id;
$field_data[$field_list['lock']] = 0;
$field_data[$field_list['found_time']] = time();
$field_data[$field_list['now_time']] = time();
$field_data[$field_list['expire_time']] = $expire_time;
self::clear() self::table(self::$_resource[self::$_id]['config']['session']['table']['name']);
self::where(array($field_list['id']."=[]", $session_id));
$sql_insert = self::insert($field_data, function($info){
return $info['query']['insert'];
});
$update_data = array();
$update_data[$field_list['now_time']] = time();
$update_data[$field_list['expire_time']] = $expire_time;
self::clear() $sql_update = self::update($update_data, function($info){
return $info['query']['set'];
});
$bool = self::_query($sql_insert.' ON DUPLICATE KEY UPDATE '.$sql_update, false, true, $register_backtrace);
if( empty($bool) ){
return false;
}
}
$lock_timeout_time = empty(self::$_resource[self::$_id]['config']['session']['lock_timeout_time'])?
0 : self::$_resource[self::$_id]['config']['session']['lock_timeout_time'];
$lock_expire_time = empty(self::$_resource[self::$_id]['config']['session']['lock_expire_time'])?
0 : self::$_resource[self::$_id]['config']['session']['lock_expire_time'];
$count_number = 0 $total_s = 0 while(true){
$count_number ++;
$expire_time = self::_session_closure('expire_time', 'int', array('db_session_expire_time_define', 'db_session_expire_time_illegal'), $register_backtrace);
self::clear() self::table(self::$_resource[self::$_id]['config']['session']['table']['name']);
self::where(array($field_list['id']."=[]", $session_id), array('[and] '.$field_list['lock'].'=0') );
self::where(
array('[or] '.$field_list['id']."=[]", $session_id),
array('[and] '.$field_list['lock'].'=1'),
array('[and] '.$field_list['now_time'].'<[]', time() ), array('[and] ('.time().'-'.$field_list['now_time'].')>'.$lock_expire_time)
);
$sql_update = self::update(array(
$field_list['lock'] => 1,
$field_list['now_time'] => time(),
$field_list['expire_time'] => $expire_time
),function($info){
return $info['query']['sql'];
});
$lock_bool = (bool)self::_query($sql_update, false, true, $register_backtrace);
if( empty($lock_bool) ){
if($count_number == 1){
self::clear() self::table(self::$_resource[self::$_id]['config']['session']['table']['name']);
self::where(array($field_list['id']."=[]", $session_id));
$sql_find = self::find($field_list['id'], function($info){
return $info['query']['sql'];
});
$find = (bool)self::_query($sql_find, false, true, $register_backtrace);
if( empty($find) ){
return false;
}
}
if( $total_s >= $lock_timeout_time ){
return false;
}
sleep(1) $total_s ++;
}else{
break;
}
}
self::clear() self::table(self::$_resource[self::$_id]['config']['session']['table']['name']);
self::where(array($field_list['id']."=[]", $session_id));
$sql_find = self::find(function($info){
return $info['query']['sql'];
});
$session_data = self::_query($sql_find, false, true, $register_backtrace);
if( empty($session_data[0]) ){
self::_error(parent::language('db_session_start'), true, $register_backtrace);
}
if( !empty($field_list['json']) ){
foreach($field_list['json'] as $json_field){
$session_data[0][$json_field] = $session_data[0][$json_field] == ''?
NULL : parent::cmd(array($session_data[0][$json_field]), 'json decode');
if($session_data[0][$json_field] !== NULL &&
!is_array($session_data[0][$json_field]) ){
$session_data[0][$json_field] = NULL;
}
}
}
if( !empty($field_list['serialize']) ){
foreach($field_list['serialize'] as $serialize_field){
$session_data[0][$serialize_field] = $session_data[0][$serialize_field] == ''?
NULL : unserialize($session_data[0][$serialize_field]);
if($session_data[0][$serialize_field] !== NULL &&
$session_data[0][$serialize_field] === false){
$session_data[0][$serialize_field] = NULL;
}
}
}
$destruct_update_id = 'db.session.update:'.$session_id;
$db_id = self::$_id;
$field_lock = $field_list['lock'];
parent::destruct($destruct_update_id, array( self::$_resource[self::$_id]['config'] ), function($db_config) use ($db_id, $field_lock){
$_SESSION[$field_lock] = 0;
db($db_id, $db_config)->session($_SESSION);
});
if( empty(self::$_resource[self::$_id]['config']['session']['clear']) ){
return $session_data[0];
}
$destruct_clear_id = 'db.session.clear:'.$session_id;
$args = array(self::$_resource[self::$_id]['config'], self::$_resource[self::$_id]['config']['session']['table']['name'], $field_list['expire_time']);
$db_id = self::$_id;
parent::destruct($destruct_clear_id, $args, function($db_config, $table_name, $expire_time) use ($db_id){
db($db_id, $db_config)
->table($table_name)
->where(array($expire_time."<[]", time()))
->delete();
});
return $session_data[0];
}
static private function _session_update($data, $register_backtrace){
$field_list = self::_session_field($register_backtrace);
if( empty($data[$field_list['id']]) || !is_string($data[$field_list['id']]) ){
self::_error(parent::language('db_session_update_id_illegal'), true, $register_backtrace);
}
$black_list = parent::cmd(array(
parent::cmd(array($field_list), 'arr indexedvalue'),
array($field_list['id'], $field_list['found_time']),
true
), 'arr blacklist');
$session_data = parent::cmd(array($data, $black_list), 'arr whitelist');
$session_data[$field_list['expire_time']] = self::_session_closure('expire_time', 'int', array('db_session_expire_time_define', 'db_session_expire_time_illegal'), $register_backtrace);
$session_data[$field_list['now_time']] = time();
if( !empty($field_list['json']) ){
foreach($field_list['json'] as $json_field){
$session_data[$json_field] = empty($session_data[$json_field])?
'' : parent::cmd(array($session_data[$json_field]), 'json encode');
}
}
if( !empty($field_list['serialize']) ){
foreach($field_list['serialize'] as $serialize_field){
$session_data[$serialize_field] = empty($session_data[$serialize_field])?
'' : serialize($session_data[$serialize_field]);
}
}
self::clear() self::table(self::$_resource[self::$_id]['config']['session']['table']['name']);
self::where(array($field_list['id']."=[]", $data[$field_list['id']] ));
$bool = self::_query(self::update($session_data, function($info){
return $info['query']['sql'];
}), false, true, $register_backtrace);
return $bool;
}
static private function _session_closure($field, $data_type, $language_name, $register_backtrace){
if( empty(self::$_resource[self::$_id]['config']['session'][$field]) || gettype(self::$_resource[self::$_id]['config']['session'][$field]) != 'object' || get_class(self::$_resource[self::$_id]['config']['session'][$field]) != 'Closure' ){
self::_error(parent::language($language_name[0]), true, $register_backtrace);
}
$data = call_user_func_array(self::$_resource[self::$_id]['config']['session'][$field], array());
if($data_type == 'string'){
if( !is_string($data) || trim($data) == ''){
self::_error(parent::language($language_name[1]), true, $register_backtrace);
}
}else
if($data_type == 'int'){
if( !is_int($data) ){
self::_error(parent::language($language_name[1]), true, $register_backtrace);
}
}
return $data;
}
static private function _session_field($register_backtrace){
$field_list = array(
'id' => NULL,
'unique' => NULL,
'lock' => NULL,
'found_time' => NULL,
'now_time' => NULL,
'expire_time' => NULL,
'json' => array(),
'serialize' => array(),
'var' => array(),
'state' => array()
);
foreach(self::$_resource[self::$_id]['config']['session']['table']['field'] as $field => $field_type){
if( !is_string($field_type) ){
continue;
}
$field_type = trim(strtolower($field_type));
if( $field_type == ''){
continue;
}
if( $field_type == 'id' ){
$field_list['id'] = $field;
}else
if( $field_type == 'lock' ){
$field_list['lock'] = $field;
}else
if( $field_type == 'found_time' ){
$field_list['found_time'] = $field;
}else
if( $field_type == 'now_time' ){
$field_list['now_time'] = $field;
}else
if( $field_type == 'expire_time' ){
$field_list['expire_time'] = $field;
}else
if( $field_type == 'unique' ){
$field_list['unique'][] = $field;
}else
if( $field_type == 'json' ){
$field_list['json'][] = $field;
}else
if( $field_type == 'serialize' ){
$field_list['serialize'][] = $field;
}else
if( $field_type == 'var' ){
$field_list['var'][] = $field;
}else
if( $field_type == 'state' ){
$field_list['state'][] = $field;
}
}
if( empty($field_list['id']) ){
self::_error(parent::language('db_session_table_field_type', 'id'), true, $register_backtrace) }else
if( empty($field_list['lock']) ){
self::_error(parent::language('db_session_table_field_type', 'lock'), true, $register_backtrace) }else
if( empty($field_list['found_time']) ){
self::_error(parent::language('db_session_table_field_type', 'found_time'), true, $register_backtrace) }else
if( empty($field_list['now_time']) ){
self::_error(parent::language('db_session_table_field_type', 'now_time'), true, $register_backtrace) }else
if( empty($field_list['expire_time']) ){
self::_error(parent::language('db_session_table_field_type', 'expire_time'), true, $register_backtrace) }
return $field_list;
}
static private function _session_create($table_name, $register_backtrace){
$field_list = self::_session_field($register_backtrace);
$id = '' $lock = '' $found_time = '' $expire_time ='' $now_time = ''
$var = '' $text = '' $state = ''
$primary_key = '' $unique_key = '' $index_key = ''
$id = "\t`".$field_list['id']."` varchar(150) NOT NULL DEFAULT '' COMMENT '唯一ID、主键'";
$primary_key = ",\r\n\tPRIMARY KEY (`".$field_list['id']."`)";
$unique_key = ",\r\n\tUNIQUE KEY `".$field_list['id']."` (`".$field_list['id']."`)";
$lock = ",\r\n\t`".$field_list['lock']."` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '会话锁,同个会话将排队执行'";
$index_key.=",\r\n\tKEY `".$field_list['lock']."` (`".$field_list['lock']."`)";
$found_time = ",\r\n\t`".$field_list['found_time']."` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间'";
$index_key.=",\r\n\tKEY `".$field_list['found_time']."` (`".$field_list['found_time']."`)";
$now_time = ",\r\n\t`".$field_list['now_time']."` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '当前时间'";
$index_key.=",\r\n\tKEY `".$field_list['now_time']."` (`".$field_list['now_time']."`)";
$expire_time = ",\r\n\t`".$field_list['expire_time']."` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '失效时间'";
$index_key .= ",\r\n\tKEY `".$field_list['expire_time']."` (`".$field_list['expire_time']."`)";
if( !empty($field_list['state']) ){
foreach($field_list['state'] as $state_field){
$state .= ",\r\n\t`".$state_field."` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '状态数据'";
$index_key .= ",\r\n\tKEY `".$state_field."` (`".$state_field."`)";
}
}
if( !empty($field_list['unique']) ){
foreach($field_list['unique'] as $unique_field){
$var .= ",\r\n\t`".$unique_field."` varchar(200) DEFAULT NULL COMMENT '唯一变量数据'";
$unique_key .= ",\r\n\tUNIQUE KEY `".$unique_field."` (`".$unique_field."`) USING BTREE";
}
}
if( !empty($field_list['var']) ){
foreach($field_list['var'] as $var_field){
$var .= ",\r\n\t`".$var_field."` varchar(200) NOT NULL DEFAULT '' COMMENT '变量数据'";
$index_key .= ",\r\n\tKEY `".$var_field."` (`".$var_field."`)";
}
}
if( !empty($field_list['json']) ){
foreach($field_list['json'] as $json_field){
$text .= ",\r\n\t`".$json_field."` text NOT NULL COMMENT 'json数据'";
}
}
if( !empty($field_list['serialize']) ){
foreach($field_list['serialize'] as $serialize_field){
$text .= ",\r\n\t`".$serialize_field."` text NOT NULL COMMENT 'serialize数据'";
}
}
$sql = "CREATE TABLE `".$table_name."` (\r\n";
$sql .= $id . $lock . $found_time . $now_time . $expire_time . $state . $var . $text . $primary_key . $unique_key . $index_key;
$sql .= "\r\n) ENGINE=".self::$_resource[self::$_id]['config']['session']['table']['engine']." DEFAULT CHARSET=".self::$_resource[self::$_id]['config']['charset']." COMMENT='".self::$_resource[self::$_id]['config']['session']['table']['comment']."';";
if( !empty(self::$_resource[self::$_id]['config']['session']['found_log_file']) ){
$directory = self::_cache_mkdir('session', $register_backtrace);
$file_path = $directory.parent::cmd(array(22), 'random autoincrement').'.sql';
file_put_contents($file_path, $sql, LOCK_EX);
}
self::_query($sql, false, true, $register_backtrace);
}
static public function lock(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
$args = array(
'database' => false 'select' => false 'insert' => false 'update' => false 'delete' => fals );
$close = false;
if( !empty($func_get_args['string'][0]) ){
$str_array = str_split(strtolower($func_get_args['string'][0]));
$args['database'] = in_array('b', $str_array);
$args['select'] = in_array('s', $str_array);
$args['insert'] = in_array('i', $str_array);
$args['update'] = in_array('u', $str_array);
$args['delete'] = in_array('d', $str_array);
$close = in_array('c', $str_array);
}
if( $close ){
self::_lock_close($register_backtrace);
}else{
self::_lock_start($args, $register_backtrace);
}
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => (empty($close)? $args : 'close'),
'sql' => NULL,
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static private function _lock_file($register_backtrace){
$directory = self::_cache_mkdir('lock', $register_backtrace);
if( empty(self::$_resource[self::$_id]['config']['lock_file_name_md5']) ){
$path_file = $directory.self::$_resource[self::$_id]['config']['host'].'('.self::$_resource[self::$_id]['config']['port'].').serialize';
}else{
$path_file = $directory.
md5(self::$_resource[self::$_id]['config']['host'].':'.self::$_resource[self::$_id]['config']['port']).
md5(self::$_resource[self::$_id]['config']['port'].':'.self::$_resource[self::$_id]['config']['host']).
'.serialize';
}
return $path_file;
}
static private function _lock_start($type, $register_backtrace){
$path_file = self::_lock_file($register_backtrace);
self::_lock_check_exist( $path_file, $register_backtrace );
if( empty(self::$_resource[self::$_id]['lock']) ){
self::$_resource[self::$_id]['lock'] = parent::cmd(array(22), 'random autoincrement');
}
$content = array(
'key' => self::$_resource[self::$_id]['lock'],
'type' => $type,
'value' => (empty(self::$_resource[self::$_id]['query']['base'])? array() : self::$_resource[self::$_id]['query']['base']),
);
if( empty($content['value'][self::$_resource[self::$_id]['config']['base']]) ){
$content['value'][self::$_resource[self::$_id]['config']['base']] = array();
}
/*$contents = "<?php\r\n\treturn '".parent::cmd(array(serialize($content)), 'str addslashes')."';\r\n?>";*/
if( !file_put_contents($path_file, serialize($content), LOCK_EX) ){
self::_error(parent::language('db_lock_start', $path_file), true, $register_backtrace);
}
}
static private function _lock_check_exist( $path_file = '', $register_backtrace){
if( empty(self::$_resource[self::$_id]['config']['lock_time']) ){
self::$_resource[self::$_id]['config']['lock_time'] = 0;
}
$lock_contents = array();
$lock_contents = self::_file_unserialize($path_file);
if( (isset($lock_contents['key']) && !isset(self::$_resource[self::$_id]['lock']) ) ||
(isset($lock_contents['key']) && isset(self::$_resource[self::$_id]['lock']) && $lock_contents['key'] != self::$_resource[self::$_id]['lock']) ){
if( (time() - filemtime( $path_file )) > self::$_resource[self::$_id]['config']['lock_time'] ){
if( !empty(self::$_resource[self::$_id]['config']['lock_unlink']) ){
unlink($path_file) }
$alert = empty(self::$_resource[self::$_id]['config']['lock_alert'])? false : true;
self::_error(parent::language('db_lock_timeout', $path_file), $alert, $register_backtrace);
}else{
usleep ( 500000 ) }
if( isset($lock_contents) ){
unset($lock_contents);
}
return self::_lock_check_exist( $path_file, $register_backtrace ) }
return;
}
static private function _lock_check_validity($type, $register_backtrace){
if( $type != 'database' ){
if( empty(self::$_resource[self::$_id]['query']['base']) ){
return false;
}
}
$path_file = self::_lock_file($register_backtrace);
if( empty(self::$_resource[self::$_id]['config']['lock_time']) ){
self::$_resource[self::$_id]['config']['lock_time'] = 0;
}
while(true){
$lock_contents = array();
$lock_contents = self::_file_unserialize($path_file);
if( empty($lock_contents) ||
empty($lock_contents['key']) ||
empty($lock_contents['value']) ||
empty($lock_contents['type'][$type]) ){
break;
}
if( !empty(self::$_resource[self::$_id]['lock']) && self::$_resource[self::$_id]['lock'] == $lock_contents['key'] ){
break;
}
$in = false;
if( $type == 'database' ){
if( isset($lock_contents['value'][self::$_resource[self::$_id]['config']['base']]) ){
$in = true;
}else
if( !empty(self::$_resource[self::$_id]['query']['base']) ){
foreach(self::$_resource[self::$_id]['query']['base'] as $base_name => $table_list){
if( isset($lock_contents['value'][$base_name]) ){
$in = true;
break 1 }
}
}
}else{
foreach(self::$_resource[self::$_id]['query']['base'] as $base_name => $table_list){
if( empty($lock_contents['value'][$base_name]) ){
continue }
foreach($table_list as $table){
if( in_array($table, $lock_contents['value'][$base_name]) ){
$in = true;
break 2 }
}
}
}
if( $in ){
if( (time() - filemtime( $path_file )) > self::$_resource[self::$_id]['config']['lock_time'] ){
if( !empty(self::$_resource[self::$_id]['config']['lock_unlink']) ){
unlink($path_file) }
$alert = empty(self::$_resource[self::$_id]['config']['lock_alert'])? false : true;
self::_error(parent::language('db_lock_timeout', $path_file), $alert, $register_backtrace);
}else{
usleep ( 500000 ) }
}else{
break;
}
}
static private function _lock_close( $register_backtrace = array() ){
if( !empty(self::$_resource[self::$_id]['lock']) ){
$path_file = self::_lock_file($register_backtrace);
$lock_contents = array();
$lock_contents = self::_file_unserialize($path_file);
if( is_file($path_file) ){
if( isset($lock_contents['key']) && $lock_contents['key'] == self::$_resource[self::$_id]['lock'] ){
unlink($path_file) }
}
self::$_resource[self::$_id]['lock'] = NULL;
}
}
static public function work(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
self::_work_start( $register_backtrace );
if( !empty($func_get_args['string'][0]) ){
$str_array = str_split(strtolower($func_get_args['string'][0]));
if(in_array('b', $str_array)) self::_work_backups( $register_backtrace );
if(in_array('f', $str_array)) self::_work_freeze( $register_backtrace );
if(in_array('r', $str_array)) self::_work_rollback( $register_backtrace );
if(in_array('c', $str_array)) self::_work_close( $register_backtrace );
}
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => (isset($func_get_args['string'][0])? $func_get_args['string'][0] : $func_get_args['array']),
'sql' => NULL,
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static private function _work_start( $register_backtrace ){
if( !empty(self::$_resource[self::$_id]['work']) ){
return true }
$directory = self::_cache_mkdir('work', $register_backtrace);
self::$_resource[self::$_id]['work'] = $directory.parent::cmd(array(22), 'random autoincrement').'.sql';
$content = "-- \r\n";
$content .= "-- 备份日期:".date("Y-m-d H:i:s",time())."\r\n";
$content .= "-- 执行信息:本次操作,是对".self::$_resource[self::$_id]['config']['base']."数据库的数据备份 \r\n";
$content .= "-- \r\n\r\n\r\n\r\n\r\n";
file_put_contents(self::$_resource[self::$_id]['work'], $content, FILE_APPEND | LOCK_EX) }
static private function _work_backups( $register_backtrace ){
if( empty(self::$_resource[self::$_id]['query']['table']) ){
self::_error(parent::language('db_work_table_exists'), true, $register_backtrace);
}
$where = empty(self::$_resource[self::$_id]['query']['where'])? '' : ' '.self::$_resource[self::$_id]['query']['where'];
$limit = 1000 $already_limit = 0 $i = TRUE while($i){
$select_sql = 'SELECT * FROM '.self::$_resource[self::$_id]['query']['table'].$where.' LIMIT '.$already_limit.','.$limit;
$select = self::_query($select_sql, NULL, true, $register_backtrace);
if( empty($select) ) {
$i = FALSE;
}else{
if( empty($already_limit) ){
$content = "\r\nDELETE FROM ".self::$_resource[self::$_id]['query']['table'].$where.";\r\n";
}else{
$content = '' }
$already_limit = $already_limit + $limit
foreach($select as $find){
$data_key = '';
$data_value = '';
foreach($find as $field_key => $field_value){
$data_key .= '`'.$field_key.'`,';
if( $field_value === NULL ){
$data_value .= 'NULL,';
}else
if( $field_value == '' ){
$data_value .= '\'\',';
}else{
$field_value = str_replace(array( "\r", "\n"), array( "\\r", "\\n"), $field_value) $data_value .= '\''.parent::cmd(array($field_value), 'str addslashes').'\',' }
}
$data_key = substr($data_key, 0, -1);
$data_value = substr($data_value, 0, -1);
$content .= "INSERT INTO ".self::$_resource[self::$_id]['query']['table']." ( ".$data_key." ) values ( ".$data_value." );\r\n";
}
file_put_contents(self::$_resource[self::$_id]['work'], $content, FILE_APPEND | LOCK_EX);
}
}
}
static private function _work_freeze( $register_backtrace ){
if( empty(self::$_resource[self::$_id]['query']['table']) ){
self::_error(parent::language('db_work_table_exists'), true, $register_backtrace);
}
$where = empty(self::$_resource[self::$_id]['query']['where'])? '' : ' '.self::$_resource[self::$_id]['query']['where'];
$content = "\r\nDELETE FROM ".self::$_resource[self::$_id]['query']['table'].$where.";\r\n";
file_put_contents(self::$_resource[self::$_id]['work'], $content, FILE_APPEND | LOCK_EX);
}
static private function _work_rollback( $register_backtrace = array() ){
if( !empty(self::$_resource[self::$_id]['work']) && is_file(self::$_resource[self::$_id]['work']) ){
$log = self::import( self::$_resource[self::$_id]['work'], true);
self::_work_close($register_backtrace) if( !empty(self::$_resource[self::$_id]['config']['work_rollback_log_file']) ){
self::_work_rollback_log_file($log, $register_backtrace);
}
}
}
static private function _work_rollback_log_file( $log, $register_backtrace ){
$directory = self::_cache_mkdir('work', $register_backtrace);
$file = 'work_rollback_'.date('Ymd').'.log' $path = $directory.DIRECTORY_SEPARATOR.$file;
$br = "\r\n" $tab = "\t" $file_string = '--'.$br $file_string .= '执行链接:'.parent::http().$br;
if( is_array($log) ){
if( isset($log['start_time']) ){
$file_string .= '开始时间:'.$log['start_time'].$br;
}
if( isset($log['host']) ){
$file_string .= '主机:'.$log['host'].$br;
}
if( isset($log['port']) ){
$file_string .= '端口:'.$log['port'].$br;
}
if( isset($log['user']) ){
$file_string .= '用户:'.$log['user'].$br;
}
if( isset($log['base']) ){
$file_string .= '数据库:'.$log['base'].$br;
}
if( isset($log['error_count']) ){
$file_string .= '执行错误次数:'.$log['error_count'].$br;
}
if( isset($log['run_count']) ){
$file_string .= '执行总次数:'.$log['run_count'].$br;
}
if( isset($log['end_time']) ){
$file_string .= '最后时间:'.$log['end_time'].$br;
}
if( isset($log['runtime']) ){
$file_string .= '执行时间:'.$log['runtime'].$br;
}
if( !empty($log['error']) ){
$file_string .= '错误信息:'.print_r($log['error'], true).$br;
}
}
$file_string .= '--'.$br
file_put_contents($path, $file_string, FILE_APPEND | LOCK_EX);
}
static private function _work_close( $register_backtrace = array() ){
if( !empty(self::$_resource[self::$_id]['work']) ){
if( is_file(self::$_resource[self::$_id]['work']) ){
unlink(self::$_resource[self::$_id]['work']) }
self::$_resource[self::$_id]['work'] = NULL;
}
}
static public function import(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$sql = isset( $func_get_args['string'][0] )? $func_get_args['string'][0] : '';
$is_file = isset( $func_get_args['boolean'][0] )? $func_get_args['boolean'][0] : false;
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
$return_data = array() $return_data['start_time'] = date('Y-m-d H:i:s',time()) $return_data['host'] = self::$_resource[self::$_id]['config']['host'] $return_data['port'] = self::$_resource[self::$_id]['config']['port'] $return_data['user'] = self::$_resource[self::$_id]['config']['user'] $return_data['base'] = self::$_resource[self::$_id]['config']['base']
if( empty($is_file) ){
if( empty($sql) ){
self::_error(parent::language('db_import_data_empty'), true, $register_backtrace);
}
self::_import_string($sql, $return_data, $register_backtrace);
}else{
if( empty($sql) || !is_string($sql) ){
self::_error(parent::language('db_import_file_illegal'), true, $register_backtrace);
}
if( !is_file($sql) ){
self::_error(parent::language('db_import_file_exists'), true, $register_backtrace);
}
self::_import_file($sql, $return_data, $register_backtrace);
}
$return_data['end_time'] = date('Y-m-d H:i:s',time()) $return_data['runtime'] = microtime(true)-$microtime
if(!empty($closure)){
$closure_return_data = call_user_func_array($closure, array($return_data, self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1 'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ) 'runtime' => (microtime(true)-$microtime) 'args' => null,
'sql' => null,
));
if( isset($closure_return_data) ){
return $closure_return_data }else{
return $return_data;
}
}
static private function _import_string($sql, &$return_data, $register_backtrace){
$sql_contents = preg_split('/\r\n/i', $sql);
$return_data['error_count'] = 0 $return_data['run_count'] = 0 $sql_temp = '' foreach($sql_contents as $key => $line){
$line = trim($line);
if ( substr($line, 0, 2) == '--' || $line == '' ){
continue;
}
$sql_temp .= $line;
if( substr($line, -1, 1) == ';' ){
$int = self::_query($sql_temp, null, false, $register_backtrace);
if( $int === null ){
$return_data['error_count'] += 1 $return_data['error'][] = 'Error [ '.self::$_resource[self::$_id]['last_error'].' ] - '.$sql_temp }
$return_data['run_count'] ++;
$sql_temp = '';
}
}
}
static private function _import_file($sql, &$return_data, $register_backtrace){
$resource = fopen($sql, 'rb');
if( empty($resource) ){
self::_error(parent::language('db_import_file_exists'), true, $register_backtrace);
}
$return_data['error_count'] = 0 $return_data['run_count'] = 0 $sql_temp = ''
while( !feof($resource) ){
$line = trim(fgets($resource));
if ( substr($line, 0, 2) == '--' || $line == '' ){
continue;
}
$sql_temp .= $line;
if( substr($line, -1, 1) == ';' ){
$int = self::_query($sql_temp, null, false, $register_backtrace);
if( $int === null ){
$return_data['error_count'] += 1 $return_data['error'][] = 'Error [ '.self::$_resource[self::$_id]['last_error'].' ] - '.$sql_temp }
$return_data['run_count'] ++;
$sql_temp = '';
}
}
fclose($resource);
}
static public function export(){
$microtime = microtime(true) $func_get_args = parent::_args_( func_get_args() );
$path = isset( $func_get_args['string'][0] )? $func_get_args['string'][0] : '';
$type = isset( $func_get_args['string'][1] )? $func_get_args['string'][1] : '';
$table = isset( $func_get_args['array'][0] )? $func_get_args['array'][0] : array();
$closure = isset( $func_get_args['closure'][0] )? $func_get_args['closure'][0] : NULL;
$register_backtrace = array('class'=>array(__CLASS__, __FUNCTION__), 'function' => __FUNCTION__);
if( empty($path) ){
self::_error(parent::language('db_export_path_empty'), true, $register_backtrace);
}
if( empty($type) ){
self::_error(parent::language('db_export_type_empty'), true, $register_backtrace);
}
$str_array = str_split(strtolower($type));
$type = in_array('s', $str_array)? 's' : '';
$type .= in_array('d', $str_array)? 'd' : '';
if( empty($type) ){
self::_error(parent::language('db_export_type_illegal', implode($str_array) ), true, $register_backtrace);
}
$directory = dirname($path);
self::_mkdir(
$directory,
true,
parent::language('db_export_path_mkdir', $directory ),
$register_backtrace
);
$content = "-- \r\n";
$content .= "-- 备份日期:".date("Y-m-d H:i:s", time())."\r\n";
$content .= "-- 版权所有:".FRAMEWORK_VERSION."\r\n";
$content .= "-- 执行信息:本次操作,是对".self::$_resource[self::$_id]['config']['base']."数据库的数据备份\r\n";
$content .= "-- \r\n\r\n\r\n\r\n\r\n";
file_put_contents($path, $content, LOCK_EX);
$version = mysqli_get_server_info( self::_link($register_backtrace) ) if( version_compare($version, '5.1', '>=') ){
$view_list = self::_query('SHOW TABLE STATUS WHERE COMMENT=\'VIEW\';', null, true, $register_backtrace);
}
if( !empty($view_list) ){
$view_list = parent::cmd(array($view_list, 'Name'), 'arr indexedvalue');
}else{
$view_list = array();
}
$table_list = self::_query('SHOW TABLES;', null, true, $register_backtrace);
if( !empty($table_list) ){
$table_list = parent::cmd(array($table_list), array($view_list, true), 'arr indexedvalue blacklist');
}
if( !empty($table) ){
$table_list = parent::cmd(array($table_list, $table, true), 'arr whitelist');
$view_list = parent::cmd(array($view_list, $table, true), 'arr whitelist');
}
if( empty($table_list) && empty($view_list) ){
$content = "\r\n";
$content .= "-- \r\n";
$content .= "-- ".self::$_resource[self::$_id]['config']['base']." 数据库中,表为空!视图亦为空!\r\n";
$content .= "-- \r\n";
$content .= "\r\n\r\n\r\n\r\n\r\n";
$content .= "-- \r\n";
$content .= "-- 执行完成!\r\n";
$content .= "-- 完成日期:".date("Y-m-d H:i:s",time())."\r\n";
$content .= "-- 存储路径: ".$path."\r\n";
$content .= "-- 耗费时间:".(microtime(true)-$microtime)." 秒 \r\n";
$content .= "-- \r\n\r\n\r\n";
file_put_contents($path, $content, FILE_APPEND | LOCK_EX);
}else{
if( in_array($type, array('s', 'sd', 'ds')) ){
$content = "-- \r\n";
$content .= "-- 取消外键约束 (Mysql中如果表和表之间建立的外键约束,则无法删除表及修改表结构。)\r\n";
$content .= "-- \r\n";
$content .= "SET FOREIGN_KEY_CHECKS=0;\r\n\r\n\r\n\r\n\r\n";
file_put_contents($path, $content, FILE_APPEND | LOCK_EX);
if( !empty($table_list) ){
self::_export_table_structure($path, $table_list, $register_backtrace);
}
if( !empty($view_list) ){
self::_export_view_structure($path, $view_list, $register_backtrace);
}
}
if( in_array($type, array('d', 'sd', 'ds')) && !empty($table_list) ){
self::_export_table_data($path, $table_list, $register_backtrace);
}
$content = "\r\n\r\n\r\n\r\n\r\n";
$content .= "-- \r\n";
$content .= "-- 执行完成!\r\n";
$content .= "-- 完成日期:".date("Y-m-d H:i:s",time())."\r\n";
$content .= "-- 存储路径: ".$path."\r\n";
$content .= "-- 耗费时间:".(microtime(true)-$microtime)." 秒 \r\n";
$content .= "-- \r\n\r\n\r\n";
file_put_contents($path, $content, FILE_APPEND | LOCK_EX);
}
if(!empty($closure)){
call_user_func_array($closure, array(self::$_resource[self::$_id]));
}
self::_method_log(array(
'sort' => count(self::$_resource[self::$_id]['runtime'])-1,
'function' => __FUNCTION__,
'location' => parent::_location_( $register_backtrace ),
'runtime' => microtime(true)-$microtime,
'args' => array($path, $type, $table),
'sql' => NULL,
));
return parent::_response_(self::_register(), $closure, array(self::$_resource[self::$_id]) );
}
static private function _export_table_structure($path, $table_list, $register_backtrace){
foreach($table_list as $value){
$table_show = self::_query('SHOW CREATE TABLE `'.$value.'`;', null, true, $register_backtrace);
$content = "-- \r\n";
$content .= "-- 备份表的结构 `".$value."`\r\n";
$content .= "-- \r\n";
$content .= "DROP TABLE IF EXISTS `".$value."`;\r\n";
$content = $content.parent::cmd(array($table_show[0]['Create Table']), 'html decode').";\r\n\r\n";
file_put_contents($path, $content, FILE_APPEND | LOCK_EX) }
}
static private function _export_view_structure($path, $view_list, $register_backtrace){
foreach($view_list as $value){
$view_show = self::_query('SHOW CREATE VIEW `'.$value.'`;', null, true, $register_backtrace);
$content = "\r\n\r\n\r\n";
$content .= "-- \r\n";
$content .= "-- 备份视图的结构 `".$value."`\r\n";
$content .= "-- \r\n";
$content .= "DROP VIEW IF EXISTS `".$value."`;\r\n";
$content = $content.parent::cmd(array($view_show[0]['Create View']), 'html decode').";\r\n\r\n";
file_put_contents($path, $content, FILE_APPEND | LOCK_EX) }
}
static private function _export_table_data($path, $table_list, $register_backtrace){
foreach($table_list as $value){
$limit = 1000 $already_limit = 0 $i = TRUE while($i){
$select_sql = 'SELECT * FROM `'.self::$_resource[self::$_id]['config']['base'].'`.`'.$value.'` LIMIT '.$already_limit.','.$limit;
$select = self::_query($select_sql, NULL, true, $register_backtrace);
if( empty($select) ) {
$i = FALSE;
}else{
if( empty($already_limit) ){
$content = "-- \r\n";
$content .= "-- 备份表的数据 `".$value."`\r\n";
$content .= "-- \r\n";
file_put_contents($path, $content, FILE_APPEND | LOCK_EX) }
$already_limit = $already_limit + $limit
$table_field = self::_query('DESC `'.$value.'`;', null, true, $register_backtrace);
if( !empty($table_field) ){
$table_field = parent::cmd(array($table_field, 'Field'), 'arr indexedvalue');
}else{
$table_field = array();
}
$table_field_string = 'INSERT INTO `'.$value.'` (';
foreach($table_field as $field){
$table_field_string .= '`'.$field.'`, ';
}
$table_field_string = substr($table_field_string, 0, -2) $table_field_string .= ") VALUES ";
$string = '' foreach($select as $data){
$string .= "\r\n (";
foreach($data as $value_string){
if( $value_string === NULL ){
$string .= 'NULL, ';
}else
if( $value_string == '' ){
$string .= '\'\', ';
}else{
$value_string = str_replace(array( "\r", "\n"), array( "\\r", "\\n"), $value_string) $value_string = parent::cmd(array($value_string), 'str addslashes');
$string .= '\''.$value_string.'\', ';
}
}
$string = substr($string, 0, -2) $string .= '), ';
}
$table_field_string .= substr($string, 0, -2) $table_field_string .= ";\r\n\r\n";
file_put_contents($path, $table_field_string, FILE_APPEND | LOCK_EX);
}
}
}
?>