test
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

270 lines
9.9 KiB

<?php
defined('IN_IA') or exit('Access Denied');
class WeliamDb {
/**
* 生成表差异SQL
* @param $table
* @return array
*/
static function table_upgrade($table) {
$sqlarr = [];
if (!empty($table['table'])) {
$oldtable = self::get_table_schema($table['table']);
if (empty($oldtable)) {
//创建表
$sqlarr[] = self::create_table($table);
} else {
//对比字段
foreach ($table['fields'] as $fk => $field) {
if (empty($oldtable['fields'][$fk])) {
//字段不存在,增加字段
$sqlarr[] = ($field['increment'] == 1) ? self::table_field_edit($table['table'], $field, 1, $table['indexes']['PRIMARY']) : self::table_field_edit($table['table'], $field, 1);
} elseif (array_diff_assoc($table['fields'][$fk], $oldtable['fields'][$fk]) || array_diff_assoc($oldtable['fields'][$fk], $table['fields'][$fk])) {
//字段有变化,修改字段
$sqlarr[] = self::table_field_edit($table['table'], $field, 2);
}
}
//对比索引
foreach ($table['indexes'] as $idx => $index) {
if ($idx == 'PRIMARY') {
continue;
}
if (empty($oldtable['indexes'][$idx])) {
//索引不存在,增加索引
$sqlarr[] = self::table_index_edit($table['table'], $index, 1);
} elseif (array_diff_assoc($table['indexes'][$idx], $oldtable['indexes'][$idx]) || array_diff_assoc($oldtable['indexes'][$idx]['fields'], $table['indexes'][$idx]['fields']) || array_diff_assoc($table['indexes'][$idx]['fields'], $oldtable['indexes'][$idx]['fields'])) {
//索引有变化,删除索引,新建索引
$sqlarr[] = self::table_index_edit($table['table'], $index, 2);
$sqlarr[] = self::table_index_edit($table['table'], $index, 1);
}
}
//多余索引,需要删除
foreach ($oldtable['indexes'] as $oidx => $oindex) {
if (empty($table['indexes'][$oidx])) {
$sqlarr[] = self::table_index_edit($table['table'], $oindex, 2);
}
}
//对比存储引擎
if ($table['engine'] != $oldtable['engine']) {
$sqlarr[] = "ALTER TABLE " . self::tablename($table['table']) . " ENGINE=" . $table['engine'] . ", ROW_FORMAT=DEFAULT;";
}
}
}
return $sqlarr;
}
/**
* 根据条件查找表名
* @param $table
* @param string $tablepre
* @param bool $haspre
* @return array
*/
static function get_tables_name($table, $tablepre = 'ims_', $haspre = false) {
$tablenames = pdo_fetchall("SHOW TABLES LIKE :tablename", array(":tablename" => "%" . $table . "%"));
if (!empty($tablenames)) {
$tables = [];
foreach ($tablenames as $item) {
$table = end($item);
$tables[] = $haspre ? $table : substr($table, strlen($tablepre));
}
return $tables;
}
return [];
}
/**
* 根据表名生成数据库插入语句
* @param $tablename
* @param $uniacid
* @param $start
* @param $size
* @return array|bool
*/
static function get_table_insert_sql($tablename, $uniacid, $start, $size) {
$data = '';
$tmp = '';
$sql = "SELECT * FROM {$tablename} WHERE `uniacid` = {$uniacid} LIMIT {$start}, {$size}";
$result = pdo_fetchall($sql);
if (!empty($result)) {
foreach ($result as $row) {
$tmp .= '(';
foreach ($row as $k => $v) {
$value = str_replace(array('\\', "\0", "\n", "\r", "'", '"', "\x1a"), array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), $v);
$tmp .= "'" . $value . "',";
}
$tmp = rtrim($tmp, ',');
$tmp .= "),\n";
}
$tmp = rtrim($tmp, ",\n");
$data .= "INSERT INTO {$tablename} VALUES \n{$tmp};\n";
$datas = array(
'data' => $data,
'result' => $result,
);
return $datas;
} else {
return false;
}
}
/**
* 根据表名返回表的数据
* @param string $tablename
* @return array
*/
static function get_table_schema($tablename = '') {
$result = self::pdo()->fetch("SHOW TABLE STATUS LIKE '" . trim(self::tablename($tablename), "`") . "'");
if (empty($result) || empty($result['Create_time'])) {
return array();
}
$ret["table"] = $tablename;
$ret["tablename"] = $result["Name"];
$ret["charset"] = $result["Collation"];
$ret["engine"] = $result["Engine"];
$ret["increment"] = $result["Auto_increment"];
$result = self::pdo()->fetchall("SHOW FULL COLUMNS FROM " . self::tablename($tablename));
foreach ($result as $value) {
$temp = array();
$type = explode(" ", $value["Type"], 2);
$temp["name"] = $value["Field"];
$pieces = explode("(", $type[0], 2);
$temp["type"] = $pieces[0];
$temp["length"] = rtrim($pieces[1], ")");
$temp["null"] = !($value["Null"] == "NO");
$temp["signed"] = empty($type[1]);
$temp["increment"] = $value["Extra"] == "auto_increment";
if (!empty($value['Comment'])) {
$temp["comment"] = $value["Comment"];
}
if ($value["Default"] != NULL) {
$temp["default"] = $value["Default"];
}
$ret["fields"][$value["Field"]] = $temp;
}
$result = self::pdo()->fetchall("SHOW INDEX FROM " . self::tablename($tablename));
foreach ($result as $value) {
$ret["indexes"][$value["Key_name"]]["name"] = $value["Key_name"];
$ret["indexes"][$value["Key_name"]]["type"] = $value["Key_name"] == "PRIMARY" ? "primary" : ($value["Non_unique"] == 0 ? "unique" : "index");
$ret["indexes"][$value["Key_name"]]["fields"][] = $value["Column_name"];
}
return $ret;
}
/**
* 返回完整表名
* @param $table
* @return string
*/
private static function tablename($table) {
return self::pdo()->tablename($table);
}
/**
* 数据库操作类
* @return DB|SlaveDb
*/
private static function pdo() {
return pdo();
}
/**
* 生成创建表的SQL
* @param $schema
* @return string
*/
private static function create_table($schema) {
if (empty($schema)) {
return '';
}
$sql = "CREATE TABLE IF NOT EXISTS " . self::tablename($schema['table']) . " (";
//生成表的字段
foreach ($schema['fields'] as $field) {
$sql .= self::create_table_field($field);
$sql .= ",";
}
//生成表的索引
foreach ($schema['indexes'] as $index) {
$sql .= self::create_table_index($index);
$sql .= ",";
}
$sql = rtrim($sql, ",");
$charset = substr($schema['charset'], 0, stripos($schema['charset'], "_"));
$sql .= ") ENGINE={$schema['engine']} DEFAULT CHARSET={$charset};";
return $sql;
}
/**
* 生成操作字段的SQL段
* @param $field
* @return string
*/
private static function create_table_field($field) {
if (empty($field)) {
return "";
}
$sql = "";
$sql .= " `{$field['name']}` {$field['type']}";
$sql .= !empty($field['length']) ? "({$field['length']})" : "";
$sql .= !empty($field['signed']) ? "" : " UNSIGNED";
$sql .= !empty($field['null']) ? (array_key_exists("default", $field) ? "" : " DEFAULT NULL") : " NOT NULL";
$sql .= array_key_exists("default", $field) ? " DEFAULT '{$field['default']}'" : "";
$sql .= !empty($field['increment']) ? " AUTO_INCREMENT" : "";
$sql .= !empty($field['comment']) ? " COMMENT '{$field['comment']}'" : "";
return $sql;
}
/**
* 生成操作索引的SQL段
* @param $index
* @param string $type
* @return string
*/
private static function create_table_index($index, $type = 'ADD') {
if (empty($index)) {
return "";
}
$sql = "";
$sql .= $index['type'] == 'primary' ? "PRIMARY KEY" : "KEY `{$index['name']}`";
if ($type == 'ADD') {
$sql .= " (`" . implode("`,`", $index['fields']) . "`)";
}
return $sql;
}
/**
* 生成操作字段的SQL
* @param string $tablename
* @param $field
* @param int $type
* @return string
*/
private static function table_field_edit($tablename = '', $field, $type = 1, $idx_field = []) {
$sqlstr = ($type == 1) ? " ADD " : " MODIFY COLUMN ";
$sql = "ALTER TABLE " . self::tablename($tablename) . $sqlstr . self::create_table_field($field);
//特殊情况,增加主键字段时
if ($type == 1 && $field['increment'] == 1) {
$sql .= ", ADD " . self::create_table_index($idx_field, 'ADD');
}
$sql .= ";";
return $sql;
}
/**
* 生成操作索引的SQL
* @param string $tablename
* @param $field
* @param int $type
* @return string
*/
private static function table_index_edit($tablename = '', $field, $type = 1) {
$sqlstr = ($type == 1) ? " ADD " : " DROP ";
$sql = "ALTER TABLE " . self::tablename($tablename) . $sqlstr . self::create_table_index($field, trim($sqlstr)) . ";";
return $sql;
}
}