mirror of
https://github.com/processwire/processwire.git
synced 2025-08-11 09:14:58 +02:00
Several additions to $database API var: Add option to $database->getColumns() method to get the column type as used in a CREATE TABLE statement. Add $database->renameColumns() and $database->renameColumn() methods that enable you to rename columns without having to know the column type (something that MySQL versions prior to 8.x require). Add a $getNumberOnly argument to $database->getVersion() method to return the version number without vendor suffix. Add a $database->getServerType() method that returns the MySQL server type: MariaDB, MySQL, Percona, etc.
This commit is contained in:
@@ -1003,6 +1003,7 @@ class WireDatabasePDO extends Wire implements WireDatabase {
|
|||||||
* - Omit or false (bool) to just get column names.
|
* - Omit or false (bool) to just get column names.
|
||||||
* - True (bool) or 1 (int) to get a verbose array of information for each column, indexed by column name.
|
* - True (bool) or 1 (int) to get a verbose array of information for each column, indexed by column name.
|
||||||
* - 2 (int) to get raw MySQL column information, indexed by column name (added 3.0.182).
|
* - 2 (int) to get raw MySQL column information, indexed by column name (added 3.0.182).
|
||||||
|
* - 3 (int) to get column types as used in a CREATE TABLE statement (added 3.0.185).
|
||||||
* - Column name (string) to get verbose array only for only that column (added 3.0.182).
|
* - Column name (string) to get verbose array only for only that column (added 3.0.182).
|
||||||
* @return array
|
* @return array
|
||||||
* @since 3.0.180
|
* @since 3.0.180
|
||||||
@@ -1010,9 +1011,20 @@ class WireDatabasePDO extends Wire implements WireDatabase {
|
|||||||
*/
|
*/
|
||||||
public function getColumns($table, $verbose = false) {
|
public function getColumns($table, $verbose = false) {
|
||||||
$columns = array();
|
$columns = array();
|
||||||
|
$table = $this->escapeTable($table);
|
||||||
|
if($verbose === 3) {
|
||||||
|
$query = $this->query("SHOW CREATE TABLE $table");
|
||||||
|
if(!$query->rowCount()) return array();
|
||||||
|
$row = $query->fetch(\PDO::FETCH_NUM);
|
||||||
|
$query->closeCursor();
|
||||||
|
if(!preg_match_all('/`([_a-z0-9]+)`\s+([a-z][^\r\n]+)/i', $row[1], $matches)) return array();
|
||||||
|
foreach($matches[1] as $key => $name) {
|
||||||
|
$columns[$name] = trim(rtrim($matches[2][$key], ','));
|
||||||
|
}
|
||||||
|
return $columns;
|
||||||
|
}
|
||||||
$getColumn = $verbose && is_string($verbose) ? $verbose : '';
|
$getColumn = $verbose && is_string($verbose) ? $verbose : '';
|
||||||
if(strpos($table, '.')) list($table, $getColumn) = explode('.', $table, 2);
|
if(strpos($table, '.')) list($table, $getColumn) = explode('.', $table, 2);
|
||||||
$table = $this->escapeTable($table);
|
|
||||||
$sql = "SHOW COLUMNS FROM $table " . ($getColumn ? 'WHERE Field=:column' : '');
|
$sql = "SHOW COLUMNS FROM $table " . ($getColumn ? 'WHERE Field=:column' : '');
|
||||||
$query = $this->prepare($sql);
|
$query = $this->prepare($sql);
|
||||||
if($getColumn) $query->bindValue(':column', $getColumn);
|
if($getColumn) $query->bindValue(':column', $getColumn);
|
||||||
@@ -1238,6 +1250,63 @@ class WireDatabasePDO extends Wire implements WireDatabase {
|
|||||||
return $exists;
|
return $exists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rename table columns without changing type
|
||||||
|
*
|
||||||
|
* @param string $table
|
||||||
|
* @param array $columns Associative array with one or more of `[ 'old_name' => 'new_name' ]`
|
||||||
|
* @return int Number of columns renamed
|
||||||
|
* @since 3.0.185
|
||||||
|
* @throws \PDOException|WireException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function renameColumns($table, array $columns) {
|
||||||
|
|
||||||
|
$qty = 0;
|
||||||
|
|
||||||
|
if(version_compare($this->getVersion(true), '8.0.0', '>=')) {
|
||||||
|
$mysql8 = $this->getServerType() === 'MySQL';
|
||||||
|
} else {
|
||||||
|
$mysql8 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $this->escapeTable($table);
|
||||||
|
$colTypes = $mysql8 ? array() : $this->getColumns($table, 3);
|
||||||
|
|
||||||
|
foreach($columns as $oldName => $newName) {
|
||||||
|
$oldName = $this->escapeCol($oldName);
|
||||||
|
$newName = $this->escapeCol($newName);
|
||||||
|
if(empty($oldName) || empty($newName)) continue;
|
||||||
|
if($mysql8) {
|
||||||
|
$sql = "ALTER TABLE `$table` RENAME COLUMN `$oldName` TO `$newName`";
|
||||||
|
} else if(isset($colTypes[$oldName])) {
|
||||||
|
$colType = $colTypes[$oldName];
|
||||||
|
$sql = "ALTER TABLE `$table` CHANGE `$oldName` `$newName` $colType";
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if($this->exec($sql)) $qty++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $qty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rename a table column without changing type
|
||||||
|
*
|
||||||
|
* @param string $table
|
||||||
|
* @param string $oldName
|
||||||
|
* @param string $newName
|
||||||
|
* @return bool
|
||||||
|
* @throws \PDOException|WireException
|
||||||
|
* @since 3.0.185
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function renameColumn($table, $oldName, $newName) {
|
||||||
|
$columns = array($oldName => $newName);
|
||||||
|
return $this->renameColumns($table, $columns) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the given string a database comparison operator?
|
* Is the given string a database comparison operator?
|
||||||
*
|
*
|
||||||
@@ -1502,7 +1571,7 @@ class WireDatabasePDO extends Wire implements WireDatabase {
|
|||||||
* @param string $name Name of MySQL variable you want to retrieve
|
* @param string $name Name of MySQL variable you want to retrieve
|
||||||
* @param bool $cache Allow use of cached values? (default=true)
|
* @param bool $cache Allow use of cached values? (default=true)
|
||||||
* @param bool $sub Allow substitution of MyISAM variable names to InnoDB equivalents when InnoDB is engine? (default=true)
|
* @param bool $sub Allow substitution of MyISAM variable names to InnoDB equivalents when InnoDB is engine? (default=true)
|
||||||
* @return string|int
|
* @return string|null
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function getVariable($name, $cache = true, $sub = true) {
|
public function getVariable($name, $cache = true, $sub = true) {
|
||||||
@@ -1512,8 +1581,12 @@ class WireDatabasePDO extends Wire implements WireDatabase {
|
|||||||
$query->bindValue(':name', $name);
|
$query->bindValue(':name', $name);
|
||||||
$query->execute();
|
$query->execute();
|
||||||
/** @noinspection PhpUnusedLocalVariableInspection */
|
/** @noinspection PhpUnusedLocalVariableInspection */
|
||||||
list($varName, $value) = $query->fetch(\PDO::FETCH_NUM);
|
if($query->rowCount()) {
|
||||||
|
list(,$value) = $query->fetch(\PDO::FETCH_NUM);
|
||||||
$this->variableCache[$name] = $value;
|
$this->variableCache[$name] = $value;
|
||||||
|
} else {
|
||||||
|
$value = null;
|
||||||
|
}
|
||||||
$query->closeCursor();
|
$query->closeCursor();
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
@@ -1527,11 +1600,36 @@ class WireDatabasePDO extends Wire implements WireDatabase {
|
|||||||
* - 10.1.34-MariaDB
|
* - 10.1.34-MariaDB
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
* @param bool $getNumberOnly Get only version number, exclude any vendor specific suffixes? (default=false) 3.0.185+
|
||||||
* @since 3.0.166
|
* @since 3.0.166
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function getVersion() {
|
public function getVersion($getNumberOnly = false) {
|
||||||
return $this->getVariable('version', true, false);
|
$version = $this->getVariable('version', true, false);
|
||||||
|
if($getNumberOnly && preg_match('/^([\d.]+)/', $version, $matches)) $version = $matches[1];
|
||||||
|
return $version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get server type, one of MySQL, MariDB, Percona, etc.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.0.185
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function getServerType() {
|
||||||
|
$serverType = '';
|
||||||
|
$serverTypes = array('MariaDB', 'Percona', 'OurDelta', 'Drizzle', 'MySQL');
|
||||||
|
foreach(array('version', 'version_comment') as $name) {
|
||||||
|
$value = $this->getVariable($name);
|
||||||
|
if($value === null) continue;
|
||||||
|
foreach($serverTypes as $type) {
|
||||||
|
if(stripos($value, $type) !== false) $serverType = $type;
|
||||||
|
if($serverType) break;
|
||||||
|
}
|
||||||
|
if($serverType) break;
|
||||||
|
}
|
||||||
|
return $serverType ? $serverType : 'MySQL';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user