/lib/php/MDB/Manager.php
PHP | 2148 lines | 1657 code | 85 blank | 406 comment | 439 complexity | bd1ebbc794ec7f9e153393dfd80db32c MD5 | raw file
Possible License(s): Apache-2.0, MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-2-Clause, GPL-2.0, LGPL-3.0
Large files files are truncated, but you can click here to view the full file
- <?php
- // +----------------------------------------------------------------------+
- // | PHP Version 4 |
- // +----------------------------------------------------------------------+
- // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, |
- // | Stig. S. Bakken, Lukas Smith |
- // | All rights reserved. |
- // +----------------------------------------------------------------------+
- // | MDB is a merge of PEAR DB and Metabases that provides a unified DB |
- // | API as well as database abstraction for PHP applications. |
- // | This LICENSE is in the BSD license style. |
- // | |
- // | Redistribution and use in source and binary forms, with or without |
- // | modification, are permitted provided that the following conditions |
- // | are met: |
- // | |
- // | Redistributions of source code must retain the above copyright |
- // | notice, this list of conditions and the following disclaimer. |
- // | |
- // | Redistributions in binary form must reproduce the above copyright |
- // | notice, this list of conditions and the following disclaimer in the |
- // | documentation and/or other materials provided with the distribution. |
- // | |
- // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
- // | Lukas Smith nor the names of his contributors may be used to endorse |
- // | or promote products derived from this software without specific prior|
- // | written permission. |
- // | |
- // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
- // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
- // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
- // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
- // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
- // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
- // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
- // | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
- // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
- // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
- // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
- // | POSSIBILITY OF SUCH DAMAGE. |
- // +----------------------------------------------------------------------+
- // | Author: Lukas Smith <smith@backendmedia.com> |
- // +----------------------------------------------------------------------+
- //
- // $Id: Manager.php,v 1.75.4.4 2004/03/10 14:42:59 lsmith Exp $
- //
- require_once('MDB/Parser.php');
- define('MDB_MANAGER_DUMP_ALL', 0);
- define('MDB_MANAGER_DUMP_STRUCTURE', 1);
- define('MDB_MANAGER_DUMP_CONTENT', 2);
- /**
- * The database manager is a class that provides a set of database
- * management services like installing, altering and dumping the data
- * structures of databases.
- *
- * @package MDB
- * @category Database
- * @author Lukas Smith <smith@backendmedia.com>
- */
- class MDB_Manager extends PEAR
- {
- // {{{ properties
- var $database;
- var $options = array(
- 'fail_on_invalid_names' => 1,
- 'debug' => 0
- );
- var $invalid_names = array(
- 'user' => array(),
- 'is' => array(),
- 'file' => array(
- 'oci' => array(),
- 'oracle' => array()
- ),
- 'notify' => array(
- 'pgsql' => array()
- ),
- 'restrict' => array(
- 'mysql' => array()
- ),
- 'password' => array(
- 'ibase' => array()
- )
- );
- var $default_values = array(
- 'integer' => 0,
- 'float' => 0,
- 'decimal' => 0,
- 'text' => '',
- 'timestamp' => '0001-01-01 00:00:00',
- 'date' => '0001-01-01',
- 'time' => '00:00:00'
- );
- var $warnings = array();
- var $database_definition = array(
- 'name' => '',
- 'create' => 0,
- 'TABLES' => array()
- );
- // }}}
- // {{{ raiseError()
- /**
- * This method is used to communicate an error and invoke error
- * callbacks etc. Basically a wrapper for PEAR::raiseError
- * without the message string.
- *
- * @param mixed $code integer error code, or a PEAR error object (all
- * other parameters are ignored if this parameter is an object
- * @param int $mode error mode, see PEAR_Error docs
- * @param mixed $options If error mode is PEAR_ERROR_TRIGGER, this is the
- * error level (E_USER_NOTICE etc). If error mode is
- * PEAR_ERROR_CALLBACK, this is the callback function, either as a
- * function name, or as an array of an object and method name. For
- * other error modes this parameter is ignored.
- * @param string $userinfo Extra debug information. Defaults to the last
- * query and native error code.
- * @param mixed $nativecode Native error code, integer or string depending
- * the backend.
- * @return object a PEAR error object
- * @access public
- * @see PEAR_Error
- */
- function &raiseError($code = MDB_MANAGER_ERROR, $mode = NULL, $options = NULL,
- $userinfo = NULL, $nativecode = NULL)
- {
- // The error is yet a MDB error object
- if(is_object($code)) {
- $err = PEAR::raiseError($code, NULL, NULL, NULL, NULL, NULL, TRUE);
- return($err);
- }
-
- $err = PEAR::raiseError(NULL, $code, $mode, $options, $userinfo,
- 'MDB_Error', TRUE);
- return($err);
- }
- // }}}
- // {{{ captureDebugOutput()
- /**
- * set a debug handler
- *
- * @param string $capture name of the function that should be used in
- * debug()
- * @access public
- * @see debug()
- */
- function captureDebugOutput($capture)
- {
- $this->options['debug'] = $capture;
- $this->database->captureDebugOutput(1);
- }
- // }}}
- // {{{ debugOutput()
- /**
- * output debug info
- *
- * @return string content of the debug_output class variable
- * @access public
- */
- function debugOutput()
- {
- return($this->database->debugOutput());
- }
- // }}}
- // {{{ resetWarnings()
- /**
- * reset the warning array
- *
- * @access public
- */
- function resetWarnings()
- {
- $this->warnings = array();
- }
- // }}}
- // {{{ getWarnings()
- /**
- * get all warnings in reverse order.
- * This means that the last warning is the first element in the array
- *
- * @return array with warnings
- * @access public
- * @see resetWarnings()
- */
- function getWarnings()
- {
- return array_reverse($this->warnings);
- }
- // }}}
- // {{{ setOption()
- /**
- * set the option for the db class
- *
- * @param string $option option name
- * @param mixed $value value for the option
- * @return mixed MDB_OK or MDB_Error
- * @access public
- */
- function setOption($option, $value)
- {
- if(isset($this->options[$option])) {
- $this->options[$option] = $value;
- return(MDB_OK);
- }
- return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, "unknown option $option"));
- }
- // }}}
- // {{{ getOption()
- /**
- * returns the value of an option
- *
- * @param string $option option name
- * @return mixed the option value or error object
- * @access public
- */
- function getOption($option)
- {
- if(isset($this->options[$option])) {
- return($this->options[$option]);
- }
- return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, "unknown option $option"));
- }
- // }}}
- // {{{ connect()
- /**
- * Create a new MDB connection object and connect to the specified
- * database
- *
- * @param mixed $dbinfo 'data source name', see the MDB::parseDSN
- * method for a description of the dsn format.
- * Can also be specified as an array of the
- * format returned by MDB::parseDSN.
- * Finally you can also pass an existing db
- * object to be used.
- * @param mixed $options An associative array of option names and
- * their values.
- * @return mixed MDB_OK on success, or a MDB error object
- * @access public
- * @see MDB::parseDSN
- */
- function &connect(&$dbinfo, $options = FALSE)
- {
- if(is_object($this->database) && !MDB::isError($this->database)) {
- $this->disconnect();
- }
- if(is_object($dbinfo)) {
- $this->database =& $dbinfo;
- } else {
- $this->database =& MDB::connect($dbinfo, $options);
- if(MDB::isError($this->database)) {
- return($this->database);
- }
- }
- if(is_array($options)) {
- $this->options = array_merge($options, $this->options);
- }
- return(MDB_OK);
- }
- // }}}
- // {{{ disconnect()
- /**
- * Log out and disconnect from the database.
- *
- * @access public
- */
- function disconnect()
- {
- if(is_object($this->database) && !MDB::isError($this->database)) {
- $this->database->disconnect();
- unset($this->database);
- }
- }
- // }}}
- // {{{ setDatabase()
- /**
- * Select a different database
- *
- * @param string $name name of the database that should be selected
- * @return string name of the database previously connected to
- * @access public
- */
- function setDatabase($name)
- {
- return($this->database->setDatabase($name));
- }
- // }}}
- // {{{ _createTable()
- /**
- * create a table and inititialize the table if data is available
- *
- * @param string $table_name name of the table to be created
- * @param array $table multi dimensional array that containts the
- * structure and optional data of the table
- * @param boolean $overwrite determine if the table/index should be
- overwritten if it already exists
- * @return mixed MDB_OK on success, or a MDB error object
- * @access private
- */
- function _createTable($table_name, $table, $overwrite = FALSE)
- {
- $this->expectError(MDB_ERROR_ALREADY_EXISTS);
- $result = $this->database->createTable($table_name, $table['FIELDS']);
- $this->popExpect();
- if(MDB::isError($result)) {
- if($result->getCode() === MDB_ERROR_ALREADY_EXISTS) {
- $this->warnings[] = 'Table already exists: '.$table_name;
- if($overwrite) {
- $this->database->debug('Overwritting Table');
- $result = $this->database->dropTable($table_name);
- if(MDB::isError($result)) {
- return($result);
- }
- $result = $this->database->createTable($table_name, $table['FIELDS']);
- if(MDB::isError($result)) {
- return($result);
- }
- } else {
- $result = MDB_OK;
- }
- } else {
- $this->database->debug('Create table error: '.$table_name);
- return($result);
- }
- }
- if(isset($table['initialization']) && is_array($table['initialization'])) {
- foreach($table['initialization'] as $instruction) {
- switch($instruction['type']) {
- case 'insert':
- $query_fields = $query_values = array();
- if(isset($instruction['FIELDS']) && is_array($instruction['FIELDS'])) {
- foreach($instruction['FIELDS'] as $field_name => $field) {
- $query_fields[] = $field_name;
- $query_values[] = '?';
- }
- $query_fields = implode(',',$query_fields);
- $query_values = implode(',',$query_values);
- $result = $prepared_query = $this->database->prepareQuery(
- "INSERT INTO $table_name ($query_fields) VALUES ($query_values)");
- }
- if(!MDB::isError($prepared_query)) {
- if(isset($instruction['FIELDS']) && is_array($instruction['FIELDS'])) {
- $lobs = array();
- $field_number = 0;
- foreach($instruction['FIELDS'] as $field_name => $field) {
- $field_number++;
- $query = $field_name;
- switch($table['FIELDS'][$field_name]['type']) {
- case 'integer':
- $result = $this->database->setParamInteger($prepared_query,
- $field_number, intval($field));
- break;
- case 'text':
- $result = $this->database->setParamText($prepared_query,
- $field_number, $field);
- break;
- case 'clob':
- $lob_definition = array(
- 'Database' => $this->database,
- 'Error' => '',
- 'Data' => $field
- );
- if(MDB::isError($result = $this->database->createLob($lob_definition)))
- {
- break;
- }
- $lob = count($lobs);
- $lobs[$lob] = $result;
- $result = $this->database->setParamClob($prepared_query,
- $field_number, $lobs[$lob], $field_name);
- break;
- case 'blob':
- $lob_definition = array(
- 'Database' => $this->database,
- 'Error' => '',
- 'Data' => $field
- );
- if(MDB::isError($result = $this->database->createLob($lob_definition))) {
- break;
- }
- $lob = count($lobs);
- $lobs[$lob] = $result;
- $result = $this->database->setParamBlob($prepared_query,
- $field_number, $lobs[$lob], $field_name);
- break;
- case 'boolean':
- $result = $this->database->setParamBoolean($prepared_query,
- $field_number, intval($field));
- break;
- case 'date':
- $result = $this->database->setParamDate($prepared_query,
- $field_number, $field);
- break;
- case 'timestamp':
- $result = $this->database->setParamTimestamp($prepared_query,
- $field_number, $field);
- break;
- case 'time':
- $result = $this->database->setParamTime($prepared_query,
- $field_number, $field);
- break;
- case 'float':
- $result = $this->database->setParamFloat($prepared_query,
- $field_number, doubleval($field));
- break;
- case 'decimal':
- $result = $this->database->setParamDecimal($prepared_query,
- $field_number, $field);
- break;
- default:
- $result = $this->raiseError(MDB_ERROR_MANAGER, NULL, NULL,
- 'type "'.$field['type'].'" is not yet supported');
- break;
- }
- if(MDB::isError($result)) {
- break;
- }
- }
- }
- if(!MDB::isError($result)) {
- $result = $this->database->executeQuery($prepared_query);
- }
- for($lob = 0; $lob < count($lobs); $lob++) {
- $this->database->destroyLOB($lobs[$lob]);
- }
- $this->database->freePreparedQuery($prepared_query);
- }
- break;
- }
- }
- };
- if(!MDB::isError($result) && isset($table['INDEXES']) && is_array($table['INDEXES'])) {
- if(!$this->database->support('Indexes')) {
- return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
- 'indexes are not supported'));
- }
- foreach($table['INDEXES'] as $index_name => $index) {
- $this->expectError(MDB_ERROR_ALREADY_EXISTS);
- $result = $this->database->createIndex($table_name, $index_name, $index);
- $this->popExpect();
- if(MDB::isError($result)) {
- if($result->getCode() === MDB_ERROR_ALREADY_EXISTS) {
- $this->warnings[] = 'Index already exists: '.$index_name;
- if($overwrite) {
- $this->database->debug('Overwritting Index');
- $result = $this->database->dropIndex($table_name, $index_name);
- if(MDB::isError($result)) {
- break;
- }
- $result = $this->database->createIndex($table_name, $index_name, $index);
- if(MDB::isError($result)) {
- break;
- }
- } else {
- $result = MDB_OK;
- }
- } else {
- $this->database->debug('Create index error: '.$table_name);
- break;
- }
- }
- }
- }
- if(MDB::isError($result)) {
- $result = $this->database->dropTable($table_name);
- if(MDB::isError($result)) {
- $result = $this->raiseError(MDB_ERROR_MANAGER, NULL, NULL,
- 'could not drop the table ('
- .$result->getMessage().' ('.$result->getUserinfo(),'))',
- 'MDB_Error', TRUE);
- }
- return($result);
- }
- return(MDB_OK);
- }
- // }}}
- // {{{ _dropTable()
- /**
- * drop a table
- *
- * @param string $table_name name of the table to be dropped
- * @return mixed MDB_OK on success, or a MDB error object
- * @access private
- */
- function _dropTable($table_name)
- {
- return($this->database->dropTable($table_name));
- }
- // }}}
- // {{{ _createSequence()
- /**
- * create a sequence
- *
- * @param string $sequence_name name of the sequence to be created
- * @param array $sequence multi dimensional array that containts the
- * structure and optional data of the table
- * @param string $created_on_table
- * @param boolean $overwrite determine if the sequence should be overwritten
- if it already exists
- * @return mixed MDB_OK on success, or a MDB error object
- * @access private
- */
- function _createSequence($sequence_name, $sequence, $created_on_table, $overwrite = FALSE)
- {
- if(!$this->database->support('Sequences')) {
- return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
- 'sequences are not supported'));
- }
- if(!isset($sequence_name) || !strcmp($sequence_name, '')) {
- return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
- 'no valid sequence name specified'));
- }
- $this->database->debug('Create sequence: '.$sequence_name);
- if(isset($sequence['start']) && $sequence['start'] != '') {
- $start = $sequence['start'];
- } else if(isset($sequence['on']) && !$created_on_table) {
- $table = $sequence['on']['table'];
- $field = $sequence['on']['field'];
- if($this->database->support('Summaryfunctions')) {
- $field = "MAX($field)";
- }
- $start = $this->database->queryOne("SELECT $field FROM $table");
- if(MDB::isError($start)) {
- return($start);
- }
- } else {
- $start = 1;
- }
-
- $this->expectError(MDB_ERROR_ALREADY_EXISTS);
- $result = $this->database->createSequence($sequence_name, $start);
- $this->popExpect();
- if(MDB::isError($result)) {
- if($result->getCode() === MDB_ERROR_ALREADY_EXISTS) {
- $this->warnings[] = 'Sequence already exists: '.$sequence_name;
- if($overwrite) {
- $this->database->debug('Overwritting Sequence');
- $result = $this->database->dropSequence($sequence_name);
- if(MDB::isError($result)) {
- return($result);
- }
- $result = $this->database->createSequence($sequence_name, $start);
- if(MDB::isError($result)) {
- return($result);
- }
- } else {
- return(MDB_OK);
- }
- } else {
- $this->database->debug('Create sequence error: '.$sequence_name);
- return($result);
- }
- }
- }
- // }}}
- // {{{ _dropSequence()
- /**
- * drop a table
- *
- * @param string $sequence_name name of the sequence to be dropped
- * @return mixed MDB_OK on success, or a MDB error object
- * @access private
- */
- function _dropSequence($sequence_name)
- {
- if(!$this->database->support('Sequences')) {
- return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
- 'sequences are not supported'));
- }
- $this->database->debug('Dropping sequence: '.$sequence_name);
- if(!isset($sequence_name) || !strcmp($sequence_name, '')) {
- return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
- 'no valid sequence name specified'));
- }
- return($this->database->dropSequence($sequence_name));
- }
- // }}}
- // {{{ _createDatabase()
- /**
- * Create a database space within which may be created database objects
- * like tables, indexes and sequences. The implementation of this function
- * is highly DBMS specific and may require special permissions to run
- * successfully. Consult the documentation or the DBMS drivers that you
- * use to be aware of eventual configuration requirements.
- *
- * @return mixed MDB_OK on success, or a MDB error object
- * @access private
- */
- function _createDatabase()
- {
- if(!isset($this->database_definition['name'])
- || !strcmp($this->database_definition['name'], '')
- ) {
- return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
- 'no valid database name specified'));
- }
- $create = (isset($this->database_definition['create']) && $this->database_definition['create']);
- $overwrite = (isset($this->database_definition['overwrite']) && $this->database_definition['overwrite']);
- if($create) {
- $this->database->debug('Create database: '.$this->database_definition['name']);
- $this->expectError(MDB_ERROR_ALREADY_EXISTS);
- $result = $this->database->createDatabase($this->database_definition['name']);
- $this->popExpect();
- if(MDB::isError($result)) {
- if($result->getCode() === MDB_ERROR_ALREADY_EXISTS) {
- $this->warnings[] = 'Database already exists: '.$this->database_definition['name'];
- if($overwrite) {
- $this->database->debug('Overwritting Database');
- $result = $this->database->dropDatabase($this->database_definition['name']);
- if(MDB::isError($result)) {
- return($result);
- }
- $result = $this->database->createDatabase($this->database_definition['name']);
- if(MDB::isError($result)) {
- return($result);
- }
- } else {
- $result = MDB_OK;
- }
- } else {
- $this->database->debug('Create database error.');
- return($result);
- }
- }
- }
- $previous_database_name = $this->database->setDatabase($this->database_definition['name']);
- if(($support_transactions = $this->database->support('Transactions'))
- && MDB::isError($result = $this->database->autoCommit(FALSE))
- ) {
- return($result);
- }
- $created_objects = 0;
- if(isset($this->database_definition['TABLES'])
- && is_array($this->database_definition['TABLES'])
- ) {
- foreach($this->database_definition['TABLES'] as $table_name => $table) {
- $result = $this->_createTable($table_name, $table, $overwrite);
- if(MDB::isError($result)) {
- break;
- }
- $created_objects++;
- }
- }
- if(!MDB::isError($result)
- && isset($this->database_definition['SEQUENCES'])
- && is_array($this->database_definition['SEQUENCES'])
- ) {
- foreach($this->database_definition['SEQUENCES'] as $sequence_name => $sequence) {
- $result = $this->_createSequence($sequence_name, $sequence, 0, $overwrite);
-
- if(MDB::isError($result)) {
- break;
- }
- $created_objects++;
- }
- }
-
- if(MDB::isError($result)) {
- if($created_objects) {
- if($support_transactions) {
- $res = $this->database->rollback();
- if(MDB::isError($res))
- $result = $this->raiseError(MDB_ERROR_MANAGER, NULL, NULL,
- 'Could not rollback the partially created database alterations ('
- .$result->getMessage().' ('.$result->getUserinfo(),'))',
- 'MDB_Error', TRUE);
- } else {
- $result = $this->raiseError(MDB_ERROR_MANAGER, NULL, NULL,
- 'the database was only partially created ('
- .$result->getMessage().' ('.$result->getUserinfo(),'))',
- 'MDB_Error', TRUE);
- }
- }
- } else {
- if($support_transactions) {
- $res = $this->database->autoCommit(TRUE);
- if(MDB::isError($res))
- $result = $this->raiseError(MDB_ERROR_MANAGER, NULL, NULL,
- 'Could not end transaction after successfully created the database ('
- .$res->getMessage().' ('.$res->getUserinfo(),'))',
- 'MDB_Error', TRUE);
- }
- }
-
- $this->database->setDatabase($previous_database_name);
-
- if(MDB::isError($result)
- && $create
- && MDB::isError($res = $this->database->dropDatabase($this->database_definition['name']))
- ) {
- return($this->raiseError(MDB_ERROR_MANAGER, NULL, NULL,
- 'Could not drop the created database after unsuccessful creation attempt ('
- .$res->getMessage().' ('.$res->getUserinfo(),'))',
- 'MDB_Error', TRUE));
- }
-
- if(MDB::isError($result)) {
- return($result);
- }
-
- return(MDB_OK);
- }
- // }}}
- // {{{ _addDefinitionChange()
- /**
- * add change to an array of multiple changes
- *
- * @param array &$changes
- * @param string $definition
- * @param string $item
- * @param array $change
- * @return mixed MDB_OK on success, or a MDB error object
- * @access private
- */
- function _addDefinitionChange(&$changes, $definition, $item, $change)
- {
- if(!isset($changes[$definition][$item])) {
- $changes[$definition][$item] = array();
- }
- foreach($change as $change_data_name => $change_data) {
- if(isset($change_data) && is_array($change_data)) {
- if(!isset($changes[$definition][$item][$change_data_name])) {
- $changes[$definition][$item][$change_data_name] = array();
- }
- foreach($change_data as $change_part_name => $change_part) {
- $changes[$definition][$item][$change_data_name][$change_part_name] = $change_part;
- }
- } else {
- $changes[$definition][$item][$change_data_name] = $change_data;
- }
- }
- return(MDB_OK);
- }
- // }}}
- // {{{ _compareDefinitions()
- /**
- * compare a previous definition with the currenlty parsed definition
- *
- * @param array multi dimensional array that contains the previous definition
- * @return mixed array of changes on success, or a MDB error object
- * @access private
- */
- function _compareDefinitions($previous_definition)
- {
- $defined_tables = $changes = array();
- if(isset($this->database_definition['TABLES']) && is_array($this->database_definition['TABLES'])) {
- foreach($this->database_definition['TABLES'] as $table_name => $table) {
- $was_table_name = $table['was'];
- if(isset($previous_definition['TABLES'][$table_name])
- && isset($previous_definition['TABLES'][$table_name]['was'])
- && !strcmp($previous_definition['TABLES'][$table_name]['was'], $was_table_name)
- ) {
- $was_table_name = $table_name;
- }
- if(isset($previous_definition['TABLES'][$was_table_name])) {
- if(strcmp($was_table_name, $table_name)) {
- $this->_addDefinitionChange($changes, 'TABLES', $was_table_name, array('name' => $table_name));
- $this->database->debug("Renamed table '$was_table_name' to '$table_name'");
- }
- if(isset($defined_tables[$was_table_name])) {
- return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
- 'the table "'.$was_table_name.'" was specified as base of more than of table of the database',
- 'MDB_Error', TRUE));
- }
- $defined_tables[$was_table_name] = 1;
-
- $previous_fields = $previous_definition['TABLES'][$was_table_name]['FIELDS'];
- $defined_fields = array();
- if(isset($table['FIELDS']) && is_array($table['FIELDS'])) {
- foreach($table['FIELDS'] as $field_name => $field) {
- $was_field_name = $field['was'];
- if(isset($previous_fields[$field_name])
- && isset($previous_fields[$field_name]['was'])
- && !strcmp($previous_fields[$field_name]['was'], $was_field_name)
- ) {
- $was_field_name = $field_name;
- }
- if(isset($previous_fields[$was_field_name])) {
- if(strcmp($was_field_name, $field_name)) {
- $query = $this->database->getFieldDeclaration($field_name, $field);
- if(MDB::isError($query)) {
- return($query);
- }
- $this->_addDefinitionChange($changes, 'TABLES', $was_table_name,
- array(
- 'RenamedFields' => array(
- $was_field_name => array(
- 'name' => $field_name,
- 'Declaration' => $query
- )
- )
- )
- );
- $this->database->debug("Renamed field '$was_field_name' to '$field_name' in table '$table_name'");
- }
- if(isset($defined_fields[$was_field_name])) {
- return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
- 'the field "'.$was_table_name.'" was specified as base of more than one field of table',
- 'MDB_Error', TRUE));
- }
- $defined_fields[$was_field_name] = 1;
- $change = array();
- if($field['type'] == $previous_fields[$was_field_name]['type']) {
- switch($field['type']) {
- case 'integer':
- $previous_unsigned = isset($previous_fields[$was_field_name]['unsigned']);
- $unsigned = isset($fields[$field_name]['unsigned']);
- if(strcmp($previous_unsigned, $unsigned)) {
- $change['unsigned'] = $unsigned;
- $this->database->debug("Changed field '$field_name' type from '".($previous_unsigned ? 'unsigned ' : '').$previous_fields[$was_field_name]['type']."' to '".($unsigned ? 'unsigned ' : '').$field['type']."' in table '$table_name'");
- }
- break;
- case 'text':
- case 'clob':
- case 'blob':
- $previous_length = (isset($previous_fields[$was_field_name]['length']) ? $previous_fields[$was_field_name]['length'] : 0);
- $length = (isset($field['length']) ? $field['length'] : 0);
- if(strcmp($previous_length, $length)) {
- $change['length'] = $length;
- $this->database->debug("Changed field '$field_name' length from '".$previous_fields[$was_field_name]['type'].($previous_length == 0 ? ' no length' : "($previous_length)")."' to '".$field['type'].($length == 0 ? ' no length' : "($length)")."' in table '$table_name'");
- }
- break;
- case 'date':
- case 'timestamp':
- case 'time':
- case 'boolean':
- case 'float':
- case 'decimal':
- break;
- default:
- return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL,
- 'type "'.$field['type'].'" is not yet supported',
- 'MDB_Error', TRUE));
- }
-
- $previous_notnull = isset($previous_fields[$was_field_name]['notnull']);
- $notnull = isset($field['notnull']);
- if($previous_notnull != $notnull) {
- $change['ChangedNotNull'] = 1;
- if($notnull) {
- $change['notnull'] = isset($field['notnull']);
- }
- $this->database->debug("Changed field '$field_name' notnull from $previous_notnull to $notnull in table '$table_name'");
- }
-
- $previous_default = isset($previous_fields[$was_field_name]['default']);
- $default = isset($field['default']);
- if(strcmp($previous_default, $default)) {
- $change['ChangedDefault'] = 1;
- if($default) {
- $change['default'] = $field['default'];
- }
- $this->database->debug("Changed field '$field_name' default from ".($previous_default ? "'".$previous_fields[$was_field_name]['default']."'" : 'NULL').' TO '.($default ? "'".$fields[$field_name]['default']."'" : 'NULL')." IN TABLE '$table_name'");
- } else {
- if($default
- && strcmp($previous_fields[$was_field_name]['default'], $field['default'])
- ) {
- $change['ChangedDefault'] = 1;
- $change['default'] = $field['default'];
- $this->database->debug("Changed field '$field_name' default from '".$previous_fields[$was_field_name]['default']."' to '".$fields[$field_name]['default']."' in table '$table_name'");
- }
- }
- } else {
- $change['type'] = $field['type'];
- $this->database->debug("Changed field '$field_name' type from '".$previous_fields[$was_field_name]['type']."' to '".$fields[$field_name]['type']."' in table '$table_name'");
- }
- if(count($change)) {
- $query = $this->database->getFieldDeclaration($field_name, $field);
- if(MDB::isError($query)) {
- return($query);
- }
- $change['Declaration'] = $query;
- $change['Definition'] = $field;
- $this->_addDefinitionChange($changes, 'TABLES', $was_table_name, array('ChangedFields' => array($field_name => $change)));
- }
- } else {
- if(strcmp($field_name, $was_field_name)) {
- return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
- 'it was specified a previous field name ("'
- .$was_field_name.'") for field "'.$field_name.'" of table "'
- .$table_name.'" that does not exist',
- 'MDB_Error', TRUE));
- }
- $query = $this->database->getFieldDeclaration($field_name, $field);
- if(MDB::isError($query)) {
- return($query);
- }
- $change['Declaration'] = $query;
- $this->_addDefinitionChange($changes, 'TABLES', $table_name, array('AddedFields' => array($field_name => $change)));
- $this->database->debug("Added field '$field_name' to table '$table_name'");
- }
- }
- }
- if(isset($previous_fields) && is_array($previous_fields)) {
- foreach ($previous_fields as $field_previous_name => $field_previous) {
- if(!isset($defined_fields[$field_previous_name])) {
- $this->_addDefinitionChange($changes, 'TABLES', $table_name, array('RemovedFields' => array($field_previous_name => array())));
- $this->database->debug("Removed field '$field_name' from table '$table_name'");
- }
- }
- }
- $indexes = array();
- if(isset($this->database_definition['TABLES'][$table_name]['INDEXES'])
- && is_array($this->database_definition['TABLES'][$table_name]['INDEXES'])
- ) {
- $indexes = $this->database_definition['TABLES'][$table_name]['INDEXES'];
- }
- $previous_indexes = array();
- if(isset($previous_definition['TABLES'][$was_table_name]['INDEXES'])
- && is_array($previous_definition['TABLES'][$was_table_name]['INDEXES'])
- ) {
- $previous_indexes = $previous_definition['TABLES'][$was_table_name]['INDEXES'];
- }
- $defined_indexes = array();
- foreach($indexes as $index_name => $index) {
- $was_index_name = $index['was'];
- if(isset($previous_indexes[$index_name])
- && isset($previous_indexes[$index_name]['was'])
- && !strcmp($previous_indexes[$index_name]['was'], $was_index_name)
- ) {
- $was_index_name = $index_name;
- }
- if(isset($previous_indexes[$was_index_name])) {
- $change = array();
-
- if(strcmp($was_index_name, $index_name)) {
- $change['name'] = $was_index_name;
- $this->database->debug("Changed index '$was_index_name' name to '$index_name' in table '$table_name'");
- }
- if(isset($defined_indexes[$was_index_name])) {
- return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
- 'the index "'.$was_index_name.'" was specified as base of'
- .' more than one index of table "'.$table_name.'"',
- 'MDB_Error', TRUE));
- }
- $defined_indexes[$was_index_name] = 1;
-
- $previous_unique = isset($previous_indexes[$was_index_name]['unique']);
- $unique = isset($index['unique']);
- if($previous_unique != $unique) {
- $change['ChangedUnique'] = 1;
- if($unique) {
- $change['unique'] = $unique;
- }
- $this->database->debug("Changed index '$index_name' unique from $previous_unique to $unique in table '$table_name'");
- }
- $defined_fields = array();
- $previous_fields = $previous_indexes[$was_index_name]['FIELDS'];
- if(isset($index['FIELDS']) && is_array($index['FIELDS'])) {
- foreach($index['FIELDS'] as $field_name => $field) {
- if(isset($previous_fields[$field_name])) {
- $defined_fields[$field_name] = 1;
- $sorting = (isset($field['sorting']) ? $field['sorting'] : '');
- $previous_sorting = (isset($previous_fields[$field_name]['sorting']) ? $previous_fields[$field_name]['sorting'] : '');
- if(strcmp($sorting, $previous_sorting)) {
- $this->database->debug("Changed index field '$field_name' sorting default from '$previous_sorting' to '$sorting' in table '$table_name'");
- $change['ChangedFields'] = 1;
- }
- } else {
- $change['ChangedFields'] = 1;
- $this->database->debug("Added field '$field_name' to index '$index_name' of table '$table_name'");
- }
- }
- }
- if(isset($previous_fields) && is_array($previous_fields)) {
- foreach($previous_fields as $field_name => $field) {
- if(!isset($defined_fields[$field_name])) {
- $change['ChangedFields'] = 1;
- $this->database->debug("Removed field '$field_name' from index '$index_name' of table '$table_name'");
- }
- }
- }
-
- if(count($change)) {
- $this->_addDefinitionChange($changes, 'INDEXES', $table_name,array('ChangedIndexes' => array($index_name => $change)));
- }
- } else {
- if(strcmp($index_name, $was_index_name)) {
- return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL,
- 'it was specified a previous index name ("'.$was_index_name
- .') for index "'.$index_name.'" of table "'.$table_name.'" that does not exist',
- 'MDB_Error', TRUE));
- }
- $this->_addDefinitionChange($changes, 'INDEXES', $table_name,array('AddedIndexes' => array($index_name => $indexes[$index_name])));
- $this->database->debug("Added index '$index_name' to table '$table_name'");
- }
- }
- …
Large files files are truncated, but you can click here to view the full file