con->select($sql); $res = []; while ($rs->fetch()) { $res[] = $rs->f(0); } return $res; } public function db_get_columns($table) { $sql = 'SHOW COLUMNS FROM ' . $this->con->escapeSystem($table); $rs = $this->con->select($sql); $res = []; while ($rs->fetch()) { $field = trim($rs->f('Field')); $type = trim($rs->f('Type')); $null = strtolower($rs->f('Null')) == 'yes'; $default = $rs->f('Default'); $len = null; if (preg_match('/^(.+?)\(([\d,]+)\)$/si', $type, $m)) { $type = $m[1]; $len = (integer) $m[2]; } // $default from db is a string and is NULL in schema so upgrade failed. if (strtoupper($default) == 'NULL') { $default = null; } elseif ($default != '' && !is_numeric($default)) { $default = "'" . $default . "'"; } $res[$field] = [ 'type' => $type, 'len' => $len, 'null' => $null, 'default' => $default ]; } return $res; } public function db_get_keys($table) { $sql = 'SHOW INDEX FROM ' . $this->con->escapeSystem($table); $rs = $this->con->select($sql); $t = []; $res = []; while ($rs->fetch()) { $key_name = $rs->f('Key_name'); $unique = $rs->f('Non_unique') == 0; $seq = $rs->f('Seq_in_index'); $col_name = $rs->f('Column_name'); if ($key_name == 'PRIMARY' || $unique) { $t[$key_name]['cols'][$seq] = $col_name; $t[$key_name]['unique'] = $unique; } } foreach ($t as $name => $idx) { ksort($idx['cols']); $res[] = [ 'name' => $name, 'primary' => $name == 'PRIMARY', 'unique' => $idx['unique'], 'cols' => array_values($idx['cols']) ]; } return $res; } public function db_get_indexes($table) { $sql = 'SHOW INDEX FROM ' . $this->con->escapeSystem($table); $rs = $this->con->select($sql); $t = []; $res = []; while ($rs->fetch()) { $key_name = $rs->f('Key_name'); $unique = $rs->f('Non_unique') == 0; $seq = $rs->f('Seq_in_index'); $col_name = $rs->f('Column_name'); $type = $rs->f('Index_type'); if ($key_name != 'PRIMARY' && !$unique) { $t[$key_name]['cols'][$seq] = $col_name; $t[$key_name]['type'] = $type; } } foreach ($t as $name => $idx) { ksort($idx['cols']); $res[] = [ 'name' => $name, 'type' => $idx['type'], 'cols' => $idx['cols'] ]; } return $res; } public function db_get_references($table) { $sql = 'SHOW CREATE TABLE ' . $this->con->escapeSystem($table); $rs = $this->con->select($sql); $s = $rs->f(1); $res = []; $n = preg_match_all('/^\s*CONSTRAINT\s+`(.+?)`\s+FOREIGN\s+KEY\s+\((.+?)\)\s+REFERENCES\s+`(.+?)`\s+\((.+?)\)(.*?)$/msi', $s, $match); if ($n > 0) { foreach ($match[1] as $i => $name) { # Columns transformation $t_cols = str_replace('`', '', $match[2][$i]); $t_cols = explode(',', $t_cols); $r_cols = str_replace('`', '', $match[4][$i]); $r_cols = explode(',', $r_cols); # ON UPDATE|DELETE $on = trim($match[5][$i], ', '); $on_delete = null; $on_update = null; if ($on != '') { if (preg_match('/ON DELETE (.+?)(?:\s+ON|$)/msi', $on, $m)) { $on_delete = strtolower(trim($m[1])); } if (preg_match('/ON UPDATE (.+?)(?:\s+ON|$)/msi', $on, $m)) { $on_update = strtolower(trim($m[1])); } } $res[] = [ 'name' => $name, 'c_cols' => $t_cols, 'p_table' => $match[3][$i], 'p_cols' => $r_cols, 'update' => $on_update, 'delete' => $on_delete ]; } } return $res; } public function db_create_table($name, $fields) { $a = []; foreach ($fields as $n => $f) { $type = $f['type']; $len = (integer) $f['len']; $default = $f['default']; $null = $f['null']; $type = $this->udt2dbt($type, $len, $default); $len = $len > 0 ? '(' . $len . ')' : ''; $null = $null ? 'NULL' : 'NOT NULL'; if ($default === null) { $default = 'DEFAULT NULL'; } elseif ($default !== false) { $default = 'DEFAULT ' . $default . ' '; } else { $default = ''; } $a[] = $this->con->escapeSystem($n) . ' ' . $type . $len . ' ' . $null . ' ' . $default; } $sql = 'CREATE TABLE ' . $this->con->escapeSystem($name) . " (\n" . implode(",\n", $a) . "\n) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin "; $this->con->execute($sql); } public function db_create_field($table, $name, $type, $len, $null, $default) { $type = $this->udt2dbt($type, $len, $default); $len = (integer) $len > 0 ? '(' . (integer) $len . ')' : ''; $null = $null ? 'NULL' : 'NOT NULL'; if ($default === null) { $default = 'DEFAULT NULL'; } elseif ($default !== false) { $default = 'DEFAULT ' . $default; } else { $default = ''; } $sql = 'ALTER TABLE ' . $this->con->escapeSystem($table) . ' ' . 'ADD COLUMN ' . $this->con->escapeSystem($name) . ' ' . $type . $len . ' ' . $null . ' ' . $default; $this->con->execute($sql); } public function db_create_primary($table, $name, $cols) { $c = []; foreach ($cols as $v) { $c[] = $this->con->escapeSystem($v); } $sql = 'ALTER TABLE ' . $this->con->escapeSystem($table) . ' ' . 'ADD CONSTRAINT PRIMARY KEY (' . implode(',', $c) . ') '; $this->con->execute($sql); } public function db_create_unique($table, $name, $cols) { $c = []; foreach ($cols as $v) { $c[] = $this->con->escapeSystem($v); } $sql = 'ALTER TABLE ' . $this->con->escapeSystem($table) . ' ' . 'ADD CONSTRAINT UNIQUE KEY ' . $this->con->escapeSystem($name) . ' ' . '(' . implode(',', $c) . ') '; $this->con->execute($sql); } public function db_create_index($table, $name, $type, $cols) { $c = []; foreach ($cols as $v) { $c[] = $this->con->escapeSystem($v); } $sql = 'ALTER TABLE ' . $this->con->escapeSystem($table) . ' ' . 'ADD INDEX ' . $this->con->escapeSystem($name) . ' USING ' . $type . ' ' . '(' . implode(',', $c) . ') '; $this->con->execute($sql); } public function db_create_reference($name, $c_table, $c_cols, $p_table, $p_cols, $update, $delete) { $c = []; $p = []; foreach ($c_cols as $v) { $c[] = $this->con->escapeSystem($v); } foreach ($p_cols as $v) { $p[] = $this->con->escapeSystem($v); } $sql = 'ALTER TABLE ' . $this->con->escapeSystem($c_table) . ' ' . 'ADD CONSTRAINT ' . $name . ' FOREIGN KEY ' . '(' . implode(',', $c) . ') ' . 'REFERENCES ' . $this->con->escapeSystem($p_table) . ' ' . '(' . implode(',', $p) . ') '; if ($update) { $sql .= 'ON UPDATE ' . $update . ' '; } if ($delete) { $sql .= 'ON DELETE ' . $delete . ' '; } $this->con->execute($sql); } public function db_alter_field($table, $name, $type, $len, $null, $default) { $type = $this->udt2dbt($type, $len, $default); $len = (integer) $len > 0 ? '(' . (integer) $len . ')' : ''; $null = $null ? 'NULL' : 'NOT NULL'; if ($default === null) { $default = 'DEFAULT NULL'; } elseif ($default !== false) { $default = 'DEFAULT ' . $default; } else { $default = ''; } $sql = 'ALTER TABLE ' . $this->con->escapeSystem($table) . ' ' . 'CHANGE COLUMN ' . $this->con->escapeSystem($name) . ' ' . $this->con->escapeSystem($name) . ' ' . $type . $len . ' ' . $null . ' ' . $default; $this->con->execute($sql); } public function db_alter_primary($table, $name, $newname, $cols) { $c = []; foreach ($cols as $v) { $c[] = $this->con->escapeSystem($v); } $sql = 'ALTER TABLE ' . $this->con->escapeSystem($table) . ' ' . 'DROP PRIMARY KEY, ADD PRIMARY KEY ' . '(' . implode(',', $c) . ') '; $this->con->execute($sql); } public function db_alter_unique($table, $name, $newname, $cols) { $c = []; foreach ($cols as $v) { $c[] = $this->con->escapeSystem($v); } $sql = 'ALTER TABLE ' . $this->con->escapeSystem($table) . ' ' . 'DROP INDEX ' . $this->con->escapeSystem($name) . ', ' . 'ADD UNIQUE ' . $this->con->escapeSystem($newname) . ' ' . '(' . implode(',', $c) . ') '; $this->con->execute($sql); } public function db_alter_index($table, $name, $newname, $type, $cols) { $c = []; foreach ($cols as $v) { $c[] = $this->con->escapeSystem($v); } $sql = 'ALTER TABLE ' . $this->con->escapeSystem($table) . ' ' . 'DROP INDEX ' . $this->con->escapeSystem($name) . ', ' . 'ADD INDEX ' . $this->con->escapeSystem($newname) . ' ' . 'USING ' . $type . ' ' . '(' . implode(',', $c) . ') '; $this->con->execute($sql); } public function db_alter_reference($name, $newname, $c_table, $c_cols, $p_table, $p_cols, $update, $delete) { $sql = 'ALTER TABLE ' . $this->con->escapeSystem($c_table) . ' ' . 'DROP FOREIGN KEY ' . $this->con->escapeSystem($name); $this->con->execute($sql); $this->createReference($newname, $c_table, $c_cols, $p_table, $p_cols, $update, $delete); } public function db_drop_unique($table, $name) { $sql = 'ALTER TABLE ' . $this->con->escapeSystem($table) . ' ' . 'DROP INDEX ' . $this->con->escapeSystem($name); $this->con->execute($sql); } } /** @cond ONCE */ } /** @endcond */