From 5c01063bbfbe0f22d6942a36568aee3d2279819f Mon Sep 17 00:00:00 2001 From: Florindo Date: Tue, 28 Mar 2017 16:01:14 +0200 Subject: [PATCH] new function ChangeField into the manager to change a column without drop the existing content, you must update the schema xml changing the field befor call this function --- core/xpdo/om/mysql/xpdomanager.class.php | 33 +++++++++++++++++++++++ core/xpdo/om/sqlite/xpdomanager.class.php | 8 ++++++ core/xpdo/om/sqlsrv/xpdomanager.class.php | 33 +++++++++++++++++++++++ core/xpdo/om/xpdomanager.class.php | 11 ++++++++ 4 files changed, 85 insertions(+) diff --git a/core/xpdo/om/mysql/xpdomanager.class.php b/core/xpdo/om/mysql/xpdomanager.class.php index fb2ba886ad0..266b541dcc4 100644 --- a/core/xpdo/om/mysql/xpdomanager.class.php +++ b/core/xpdo/om/mysql/xpdomanager.class.php @@ -375,6 +375,39 @@ public function alterField($class, $name, array $options = array()) { return $result; } + public function changeField($class, $oldName, $newName, array $options = array()) { + $result = false; + if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) { + $className = $this->xpdo->loadClass($class); + if ($className) { + $meta = $this->xpdo->getFieldMeta($className, true); + if (is_array($meta) && array_key_exists($newName, $meta)) { + $colDef = $this->getColumnDef($className, $newName, $meta[$newName]); + if (!empty($colDef)) { + $sql = "ALTER TABLE {$this->xpdo->getTableName($className)} CHANGE COLUMN {$oldName} {$colDef}"; + if (isset($options['first']) && !empty($options['first'])) { + $sql .= " FIRST"; + } elseif (isset($options['after']) && array_key_exists($options['after'], $meta)) { + $sql .= " AFTER {$this->xpdo->escape($options['after'])}"; + } + if ($this->xpdo->exec($sql) !== false) { + $result = true; + } else { + $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error altering field {$class}->{$newName}: " . print_r($this->xpdo->errorInfo(), true), '', __METHOD__, __FILE__, __LINE__); + } + } else { + $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error altering field {$class}->{$newName}: Could not get column definition"); + } + } else { + $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error altering field {$class}->{$newName}: No metadata defined"); + } + } + } else { + $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__); + } + return $result; + } + public function removeConstraint($class, $name, array $options = array()) { if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) { // TODO: Implement removeConstraint() method. diff --git a/core/xpdo/om/sqlite/xpdomanager.class.php b/core/xpdo/om/sqlite/xpdomanager.class.php index ecf013a416a..573fc5f3341 100644 --- a/core/xpdo/om/sqlite/xpdomanager.class.php +++ b/core/xpdo/om/sqlite/xpdomanager.class.php @@ -254,6 +254,14 @@ public function alterField($class, $name, array $options = array()) { return $result; } + public function changeField($class, $name, array $options = array()) { + $result = false; + if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) { + // TODO: Implement changeField() method somehow, no support in sqlite for altering existing columns + } + return $result; + } + public function removeConstraint($class, $name, array $options = array()) { $result = false; if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) { diff --git a/core/xpdo/om/sqlsrv/xpdomanager.class.php b/core/xpdo/om/sqlsrv/xpdomanager.class.php index a7181a40e8e..0895084f388 100644 --- a/core/xpdo/om/sqlsrv/xpdomanager.class.php +++ b/core/xpdo/om/sqlsrv/xpdomanager.class.php @@ -301,6 +301,39 @@ public function alterField($class, $name, array $options = array()) { return $result; } + public function changeField($class, $oldName, $newName, array $options = array()) { + $result = false; + if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) { + $className = $this->xpdo->loadClass($class); + if ($className) { + $meta = $this->xpdo->getFieldMeta($className, true); + if (is_array($meta) && array_key_exists($newName, $meta)) { + $colDef = $this->getColumnDef($className, $newName, $meta[$newName]); + if (!empty($colDef)) { + $sql = "ALTER TABLE {$this->xpdo->getTableName($className)} CHANGE COLUMN {$oldName} {$colDef}"; + if (isset($options['first']) && !empty($options['first'])) { + $sql .= " FIRST"; + } elseif (isset($options['after']) && array_key_exists($options['after'], $meta)) { + $sql .= " AFTER {$this->xpdo->escape($options['after'])}"; + } + if ($this->xpdo->exec($sql) !== false) { + $result = true; + } else { + $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error altering field {$class}->{$newName}: " . print_r($this->xpdo->errorInfo(), true), '', __METHOD__, __FILE__, __LINE__); + } + } else { + $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error altering field {$class}->{$newName}: Could not get column definition"); + } + } else { + $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error altering field {$class}->{$newName}: No metadata defined"); + } + } + } else { + $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__); + } + return $result; + } + public function removeConstraint($class, $name, array $options = array()) { $result = false; if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) { diff --git a/core/xpdo/om/xpdomanager.class.php b/core/xpdo/om/xpdomanager.class.php index 82787a0f4d4..e78b7b81874 100644 --- a/core/xpdo/om/xpdomanager.class.php +++ b/core/xpdo/om/xpdomanager.class.php @@ -132,6 +132,17 @@ abstract public function addField($class, $name, array $options = array()); */ abstract public function alterField($class, $name, array $options = array()); + /** + * Change an existing field of an object container, e.g. CHANGE COLUMN. + * + * @param string $class The object class to alter the field of. + * @param string $oldName The name of the old field you want change. + * @param string $newName The name of the new field you want set. + * @param array $options An array of options for the process for the new field. + * @return boolean True if the column is altered successfully, otherwise false. + */ + abstract public function changeField($class, $oldName, $newName, array $options = array()); + /** * Remove a field from an object container, e.g. DROP COLUMN. *