!C99Shell v. 1.0 pre-release build #13!

Software: Apache. PHP/5.5.15 

uname -a: Windows NT SVR-DMZ 6.1 build 7600 (Windows Server 2008 R2 Enterprise Edition) i586 

SYSTEM 

Safe-mode: OFF (not secure)

C:\Intranet\C\xampp\php\PEAR\MDB\   drwxrwxrwx
Free 4.09 GB of 39.52 GB (10.36%)
Detected drives: [ a ] [ c ] [ d ] [ e ] [ f ]
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     Manager.php (102.93 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?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($codeNULLNULLNULLNULLNULLTRUE);
            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_UNSUPPORTEDNULLNULL"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_UNSUPPORTEDNULLNULL"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_numberintval($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_numberintval($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_numberdoubleval($field));
                                            break;
                                        case 
'decimal':
                                            
$result $this->database->setParamDecimal($prepared_query,
                                                
$field_number$field);
                                            break;
                                        default:
                                            
$result $this->raiseError(MDB_ERROR_MANAGERNULLNULL,
                                                
'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_UNSUPPORTEDNULLNULL,
                    
'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_MANAGERNULLNULL,
                    
'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_UNSUPPORTEDNULLNULL,
                
'sequences are not supported'));
        }
        if(!isset(
$sequence_name) || !strcmp($sequence_name'')) {
            return(
$this->raiseError(MDB_ERROR_INVALIDNULLNULL,
                
'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_UNSUPPORTEDNULLNULL,
                
'sequences are not supported'));
        }
        
$this->database->debug('Dropping sequence: '.$sequence_name);
        if(!isset(
$sequence_name) || !strcmp($sequence_name'')) {
            return(
$this->raiseError(MDB_ERROR_INVALIDNULLNULL,
                
'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_INVALIDNULLNULL,
                
'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$sequence0$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_MANAGERNULLNULL,
                            
'Could not rollback the partially created database alterations ('
                            
.$result->getMessage().' ('.$result->getUserinfo(),'))',
                            
'MDB_Error'TRUE);
                } else {
                    
$result $this->raiseError(MDB_ERROR_MANAGERNULLNULL,
                        
'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_MANAGERNULLNULL,
                        
'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_MANAGERNULLNULL,
                
'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_INVALIDNULLNULL,
                            
'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_INVALIDNULLNULL,
                                        
'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 == ' no length' "($previous_length)")."' to '".$field['type'].($length == ' 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_UNSUPPORTEDNULLNULL,
                                                
'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_INVALIDNULLNULL,
                                        
'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_INVALIDNULLNULL,
                                    
'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_INVALIDNULLNULL,
                                    
'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'");
                        }
                    }
                    foreach(
$previous_indexes as $index_previous_name => $index_previous) {
                        if(!isset(
$defined_indexes[$index_previous_name])) {
                            
$this->_addDefinitionChange($changes'INDEXES'$table_name, array('RemovedIndexes' => array($index_previous_name => $was_table_name)));
                            
$this->database->debug("Removed index '$index_name' from table '$table_name'");
                        }
                    }
                } else {
                    if(
strcmp($table_name$was_table_name)) {
                        return(
$this->raiseError(MDB_ERROR_INVALIDNULLNULL,
                            
'it was specified a previous table name ("'
                            
.$was_table_name.'") for table "'.$table_name.'" that does not exist',
                            
'MDB_Error'TRUE));
                    }
                    
$this->_addDefinitionChange($changes'TABLES'$table_name,array('Add' => 1));
                    
$this->database->debug("Added table '$table_name'");
                }
            }
            if(isset(
$previous_definition['TABLES']) && is_array($previous_definition['TABLES'])) {
                foreach (
$previous_definition['TABLES'] as $table_name => $table) {
                    if(!isset(
$defined_tables[$table_name])) {
                        
$this->_addDefinitionChange($changes'TABLES'$table_name, array('Remove' => 1));
                        
$this->database->debug("Removed table '$table_name'");
                    }
                }
            }
            if(isset(
$this->database_definition['SEQUENCES']) && is_array($this->database_definition['SEQUENCES'])) {
                foreach (
$this->database_definition['SEQUENCES'] as $sequence_name => $sequence) {
                    
$was_sequence_name $sequence['was'];
                    if(isset(
$previous_definition['SEQUENCES'][$sequence_name])
                        && isset(
$previous_definition['SEQUENCES'][$sequence_name]['was'])
                        && !
strcmp($previous_definition['SEQUENCES'][$sequence_name]['was'], $was_sequence_name)
                    ) {
                        
$was_sequence_name $sequence_name;
                    }
                    if(isset(
$previous_definition['SEQUENCES'][$was_sequence_name])) {
                        if(
strcmp($was_sequence_name$sequence_name)) {
                            
$this->_addDefinitionChange($changes'SEQUENCES'$was_sequence_name,array('name' => $sequence_name));
                            
$this->database->debug("Renamed sequence '$was_sequence_name' to '$sequence_name'");
                        }
                        if(isset(
$defined_sequences[$was_sequence_name])) {
                            return(
$this->raiseError(MDB_ERROR_INVALIDNULLNULL,
                                
'the sequence "'.$was_sequence_name.'" was specified as base'
                                
.' of more than of sequence of the database',
                                
'MDB_Error'TRUE));
                        }
                        
$defined_sequences[$was_sequence_name] = 1;
                        
$change = array();
                        if(
strcmp($sequence['start'], $previous_definition['SEQUENCES'][$was_sequence_name]['start'])) {
                            
$change['start'] = $this->database_definition['SEQUENCES'][$sequence_name]['start'];
                            
$this->database->debug("Changed sequence '$sequence_name' start from '".$previous_definition['SEQUENCES'][$was_sequence_name]['start']."' to '".$this->database_definition['SEQUENCES'][$sequence_name]['start']."'");
                        }
                        if(
strcmp($sequence['on']['table'], $previous_definition['SEQUENCES'][$was_sequence_name]['on']['table'])
                            || 
strcmp($sequence['on']['field'], $previous_definition['SEQUENCES'][$was_sequence_name]['on']['field'])
                        ) {
                            
$change['on'] = $sequence['on'];
                            
$this->database->debug("Changed sequence '$sequence_name' on table field from '".$previous_definition['SEQUENCES'][$was_sequence_name]['on']['table'].'.'.$previous_definition['SEQUENCES'][$was_sequence_name]['on']['field']."' to '".$this->database_definition['SEQUENCES'][$sequence_name]['on']['table'].'.'.$this->database_definition['SEQUENCES'][$sequence_name]['on']['field']."'");
                        }
                        if(
count($change)) {
                            
$this->_addDefinitionChange($changes'SEQUENCES'$was_sequence_name,array('Change' => array($sequence_name => array($change))));
                        }
                    } else {
                        if(
strcmp($sequence_name$was_sequence_name)) {
                            return(
$this->raiseError(MDB_ERROR_INVALIDNULLNULL,
                                
'it was specified a previous sequence name ("'.$was_sequence_name
                                
.'") for sequence "'.$sequence_name.'" that does not exist',
                                
'MDB_Error'TRUE));
                        }
                        
$this->_addDefinitionChange($changes'SEQUENCES'$sequence_name, array('Add' => 1));
                        
$this->database->debug("Added sequence '$sequence_name'");
                    }
                }
            }
            if(isset(
$previous_definition['SEQUENCES']) && is_array($previous_definition['SEQUENCES'])) {
                foreach (
$previous_definition['SEQUENCES'] as $sequence_name => $sequence) {
                    if(!isset(
$defined_sequences[$sequence_name])) {
                        
$this->_addDefinitionChange($changes'SEQUENCES'$sequence_name, array('Remove' => 1));
                        
$this->database->debug("Removed sequence '$sequence_name'");
                    }
                }
            }
        }
        return(
$changes);
    }

    
// }}}
    // {{{ _alterDatabase()

    /**
     * Execute the necessary actions to implement the requested changes
     * in a database structure.
     *
     * @param array $previous_definition an associative array that contains
     * the definition of the database structure before applying the requested
     * changes. The definition of this array may be built separately, but
     * usually it is built by the Parse method the Metabase parser class.
     * @param array $changes an associative array that contains the definition of
     * the changes that are meant to be applied to the database structure.
     * @return mixed MDB_OK on success, or a MDB error object
     * @access private
     */
    
function _alterDatabase($previous_definition$changes)
    {
        
$result '';
        if(isset(
$changes['TABLES']) && is_array($changes['TABLES'])) {
            foreach(
$changes['TABLES'] as $table_name => $table) {
                if(isset(
$table['Add']) || isset($table['Remove'])) {
                    continue;
                }
                
$result $this->database->alterTable($table_name$table1);
                if(
MDB::isError($result)) {
                    return(
$result);
                }
            }
        }
        if(isset(
$changes['SEQUENCES']) && is_array($changes['SEQUENCES'])) {
            if(!
$this->database->support('Sequences')) {
                return(
$this->raiseError(MDB_ERROR_UNSUPPORTEDNULLNULL,
                    
'sequences are not supported'));
            }
            foreach(
$changes['SEQUENCES'] as $sequence) {
                if(isset(
$sequence['Add'])
                    || isset(
$sequence['Remove'])
                    || isset(
$sequence['Change'])
                ) {
                    continue;
                }
                return(
$this->raiseError(MDB_ERROR_UNSUPPORTEDNULLNULL,
                    
'some sequences changes are not yet supported'));
            }
        }
        if(isset(
$changes['INDEXES']) && is_array($changes['INDEXES'])) {
            if(!
$this->database->support('Indexes')) {
                return(
$this->raiseError(MDB_ERROR_UNSUPPORTEDNULLNULL,
                    
'indexes are not supported'));
            }
            foreach(
$changes['INDEXES'] as $index) {
                
$table_changes count($index);
                if(isset(
$index['AddedIndexes'])) {
                    
$table_changes--;
                }
                if(isset(
$index['RemovedIndexes'])) {
                    
$table_changes--;
                }
                if(isset(
$index['ChangedIndexes'])) {
                    
$table_changes--;
                }
                if(
$table_changes) {
                    return(
$this->raiseError(MDB_ERROR_UNSUPPORTEDNULLNULL,
                        
'index alteration not yet supported'));
                }
            }
        }
        
        
$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);
        }
        
$error '';
        
$alterations 0;
        if(isset(
$changes['INDEXES']) && is_array($changes['INDEXES'])) {
            foreach(
$changes['INDEXES'] as $index_name => $index) {
                if(isset(
$index['RemovedIndexes']) && is_array($index['RemovedIndexes'])) {
                    foreach(
$index['RemovedIndexes'] as $index_remove_name => $index_remove) {
                        
$result $this->database->dropIndex($index_name,$index_remove_name);
                        if(
MDB::isError($result)) {
                            break;
                        }
                        
$alterations++;
                    }
                }
                if(!
MDB::isError($result)
                    && 
is_array($index['ChangedIndexes'])
                ) {
                    foreach(
$index['ChangedIndexes'] as $index_changed_name => $index_changed) {
                        
$was_name = (isset($indexes[$name]['name']) ? $indexes[$index_changed_name]['name'] : $index_changed_name);
                        
$result $this->database->dropIndex($index_name$was_name);
                        if(
MDB::isError($result)) {
                            break;
                        }
                        
$alterations++;
                    }
                }
                if(
MDB::isError($result)) {
                    break;
                }
            }
        }
        if(!
MDB::isError($result) && isset($changes['TABLES'])
            && 
is_array($changes['TABLES'])
        ) {
            foreach(
$changes['TABLES'] as $table_name => $table) {
                if(isset(
$table['Remove'])) {
                    
$result $this->_dropTable($table_name);
                    if(!
MDB::isError($result)) {
                        
$alterations++;
                    }
                } else {
                    if(!isset(
$table['Add'])) {
                        
$result $this->database->alterTable($table_name$changes['TABLES'][$table_name], 0);
                        if(!
MDB::isError($result)) {
                            
$alterations++;
                        }
                    }
                }
                if(
MDB::isError($result)) {
                    break;
                }
            }
            foreach(
$changes['TABLES'] as $table_name => $table) {
                if(isset(
$table['Add'])) {
                    
$result $this->_createTable($table_name$this->database_definition['TABLES'][$table_name]);
                    if(!
MDB::isError($result)) {
                        
$alterations++;
                    }
                }
                if(
MDB::isError($result)) {
                    break;
                }
            }
        }
        if(!
MDB::isError($result) && isset($changes['SEQUENCES']) && is_array($changes['SEQUENCES'])) {
            foreach(
$changes['SEQUENCES'] as $sequence_name => $sequence) {
                if(isset(
$sequence['Add'])) {
                    
$created_on_table 0;
                    if(isset(
$this->database_definition['SEQUENCES'][$sequence_name]['on'])) {
                        
$table $this->database_definition['SEQUENCES'][$sequence_name]['on']['table'];
                        if(isset(
$changes['TABLES'])
                            && isset(
$changes['TABLES'][$table_name])
                            && isset(
$changes['TABLES'][$table_name]['Add'])
                        ) {
                            
$created_on_table 1;
                        }
                    }
                    
                    
$result $this->_createSequence($sequence_name,
                        
$this->database_definition['SEQUENCES'][$sequence_name], $created_on_table);
                    if(!
MDB::isError($result)) {
                        
$alterations++;
                    }
                } else {
                    if(isset(
$sequence['Remove'])) {
                        if(!
strcmp($error $this->_dropSequence($sequence_name), '')) {
                            
$alterations++;
                        }
                    } else {
                        if(isset(
$sequence['Change'])) {
                            
$created_on_table 0;
                            if(isset(
$this->database_definition['SEQUENCES'][$sequence_name]['on'])) {
                                
$table $this->database_definition['SEQUENCES'][$sequence_name]['on']['table'];
                                if(isset(
$changes['TABLES'])
                                    && isset(
$changes['TABLES'][$table_name])
                                    && isset(
$changes['TABLES'][$table_name]['Add'])
                                ) {
                                    
$created_on_table 1;
                                }
                            }
                            if(!
MDB::isError($result $this->_dropSequence(
                                    
$this->database_definition['SEQUENCES'][$sequence_name]['was']), '')
                                && !
MDB::isError($result $this->_createSequence(
                                    
$sequence_name$this->database_definition['SEQUENCES'][$sequence_name], $created_on_table), '')
                            ) {
                                
$alterations++;
                            }
                        } else {
                            return(
$this->raiseError(MDB_ERROR_UNSUPPORTEDNULLNULL,
                                
'changing sequences is not yet supported'));
                        }
                    }
                }
                if(
MDB::isError($result)) {
                    break;
                }
            }
        }
        if(!
MDB::isError($result) && isset($changes['INDEXES']) && is_array($changes['INDEXES'])) {
            foreach(
$changes['INDEXES'] as $table_name => $indexes) {
                if(isset(
$indexes['ChangedIndexes'])) {
                    
$changedindexes $indexes['ChangedIndexes'];
                    foreach(
$changedindexes as $index_name => $index) {
                        
$result $this->database->createIndex($table_name$index_name,
                            
$this->database_definition['TABLES'][$table_name]['INDEXES'][$index_name]);
                        if(
MDB::isError($result)) {
                            break;
                        }
                        
$alterations++;
                    }
                }
                if(!
MDB::isError($result)
                    && isset(
$indexes['AddedIndexes'])
                ) {
                    
$addedindexes $indexes['AddedIndexes'];
                    foreach(
$addedindexes as $index_name => $index) {
                        
$result $this->database->createIndex($table_name$index_name,
                            
$this->database_definition['TABLES'][$table_name]['INDEXES'][$index_name]);
                        if(
MDB::isError($result)) {
                            break;
                        }
                        
$alterations++;
                    }
                }
                if(
MDB::isError($result)) {
                    break;
                }
            }
        }
        if(
$alterations && MDB::isError($result)) {
            if(
$support_transactions) {
                
$res $this->database->rollback();
                if(
MDB::isError($res))
                    
$result $this->raiseError(MDB_ERROR_MANAGERNULLNULL,
                        
'Could not rollback the partially created database alterations ('
                        
.$result->getMessage().' ('.$result->getUserinfo(),'))',
                        
'MDB_Error'TRUE);
            } else {
                
$result $this->raiseError(MDB_ERROR_MANAGERNULLNULL,
                    
'the requested database alterations were only partially implemented ('
                    
.$result->getMessage().' ('.$result->getUserinfo(),'))',
                    
'MDB_Error'TRUE);
            }
        }
        if(
$support_transactions) {
            
$result $this->database->autoCommit(TRUE);
            if(
MDB::isError($result)) {
                
$result $this->raiseError(MDB_ERROR_MANAGERNULLNULL,
                    
'Could not end transaction after successfully implemented the requested database alterations ('
                    
.$result->getMessage().' ('.$result->getUserinfo(),'))',
                    
'MDB_Error'TRUE);
            }
        }
        
$this->database->setDatabase($previous_database_name);
        return(
$result);
    }

    
// }}}
    // {{{ _escapeSpecialCharacters()

    /**
     * add escapecharacters to all special characters in a string
     *
     * @param string $string string that should be escaped
     * @return string escaped string
     * @access private
     */
    
function _escapeSpecialCharacters($string)
    {
        if(
gettype($string) != 'string') {
            
$string strval($string);
        }
        for(
$escaped ''$character 0;
            
$character strlen($string);
            
$character++)
        {
            switch(
$string[$character]) {
                case 
'\"':
                case 
'>':
                case 
'<':
                case 
'&':
                    
$code ord($string[$character]);
                    break;
                default:
                    
$code ord($string[$character]);
                    if(
$code 32 || $code>127) {
                        break;
                    }
                    
$escaped .= $string[$character];
                    continue 
2;
            }
            
$escaped .= "&#$code;";
        }
        return(
$escaped);
    }

    
// }}}
    // {{{ _dumpSequence()

    /**
     * dump the structure of a sequence
     *
     * @param string  $sequence_name
     * @param string  $eol
     * @return mixed string with xml seqeunce definition on success, or a MDB error object
     * @access private
     */
    
function _dumpSequence($sequence_name$eol$dump MDB_MANAGER_DUMP_ALL)
    {
        
$sequence_definition $this->database_definition['SEQUENCES'][$sequence_name];
        
$buffer "$eol <sequence>$eol  <name>$sequence_name</name>$eol";
        if(
$dump == MDB_MANAGER_DUMP_ALL || $dump == MDB_MANAGER_DUMP_CONTENT) {
            if(isset(
$sequence_definition['start'])) {
                
$start $sequence_definition['start'];
                
$buffer .= "  <start>$start</start>$eol";
            }
        }
        if(isset(
$sequence_definition['on'])) {
            
$buffer .= "  <on>$eol   <table>".$sequence_definition['on']['table']."</table>$eol   <field>".$sequence_definition['on']['field']."</field>$eol  </on>$eol";
        }
        
$buffer .= " </sequence>$eol";
        return(
$buffer);
    }

    
// }}}
    // {{{ parseDatabaseDefinitionFile()

    /**
     * Parse a database definition file by creating a Metabase schema format
     * parser object and passing the file contents as parser input data stream.
     *
     * @param string $input_file the path of the database schema file.
     * @param array $variables an associative array that the defines the text
     * string values that are meant to be used to replace the variables that are
     * used in the schema description.
     * @param bool $fail_on_invalid_names (optional) make function fail on invalid
     * names
     * @return mixed MDB_OK on success, or a MDB error object
     * @access public
     */
    
function parseDatabaseDefinitionFile($input_file$variables$fail_on_invalid_names 1)
    {
        
$parser =& new MDB_Parser($variables$fail_on_invalid_names);
        
$result $parser->setInputFile($input_file);
        if(
MDB::isError($result)) {
            return(
$result);
        };
        
$result $parser->parse();
        if(
MDB::isError($result)) {
            return(
$result);
        };
        if(
MDB::isError($parser->error)) {
            return(
$parser->error);
        }
        return(
$parser->database_definition);
    }

    
// }}}
    // {{{ _debugDatabaseChanges()

    /**
     * Dump the changes between two database definitions.
     *
     * @param array $changes an associative array that specifies the list
     * of database definitions changes as returned by the _compareDefinitions
     * manager class function.
     * @return mixed MDB_OK on success, or a MDB error object
     * @access private
     */
    
function _debugDatabaseChanges($changes)
    {
        if(isset(
$changes['TABLES'])) {
            foreach(
$changes['TABLES'] as $table_name => $table)
            {
                
$this->database->debug("$table_name:");
                if(isset(
$table['Add'])) {
                    
$this->database->debug("\tAdded table '$table_name'");
                } elseif(isset(
$table['Remove'])) {
                    
$this->database->debug("\tRemoved table '$table_name'");
                } else {
                    if(isset(
$table['name'])) {
                        
$this->database->debug("\tRenamed table '$table_name' to '".$table['name']."'");
                    }
                    if(isset(
$table['AddedFields'])) {
                        foreach(
$table['AddedFields'] as $field_name => $field) {
                            
$this->database->debug("\tAdded field '".$field_name."'");
                        }
                    }
                    if(isset(
$table['RemovedFields'])) {
                        foreach(
$table['RemovedFields'] as $field_name => $field) {
                            
$this->database->debug("\tRemoved field '".$field_name."'");
                        }
                    }
                    if(isset(
$table['RenamedFields'])) {
                        foreach(
$table['RenamedFields'] as $field_name => $field) {
                            
$this->database->debug("\tRenamed field '".$field_name."' to '".$field['name']."'");
                        }
                    }
                    if(isset(
$table['ChangedFields'])) {
                        foreach(
$table['ChangedFields'] as $field_name => $field) {
                            if(isset(
$field['type'])) {
                                
$this->database->debug(
                                    
"\tChanged field '$field_name' type to '".$field['type']."'");
                            }
                            if(isset(
$field['unsigned'])) {
                                
$this->database->debug(
                                    
"\tChanged field '$field_name' type to '".
                                    (
$field['unsigned'] ? '' 'not ')."unsigned'");
                            }
                            if(isset(
$field['length'])) {
                                
$this->database->debug(
                                    
"\tChanged field '$field_name' length to '".
                                    (
$field['length'] == 'no length' $field['length'])."'");
                            }
                            if(isset(
$field['ChangedDefault'])) {
                                
$this->database->debug(
                                    
"\tChanged field '$field_name' default to ".
                                    (isset(
$field['default']) ? "'".$field['default']."'" 'NULL'));
                            }
                            if(isset(
$field['ChangedNotNull'])) {
                                
$this->database->debug(
                                   
"\tChanged field '$field_name' notnull to ".(isset($field['notnull']) ? "'1'" '0'));
                            }
                        }
                    }
                }
            }
        }
        if(isset(
$changes['SEQUENCES'])) {
            foreach(
$changes['SEQUENCES'] as $sequence_name => $sequence)
            {
                
$this->database->debug("$sequence_name:");
                if(isset(
$sequence['Add'])) {
                    
$this->database->debug("\tAdded sequence '$sequence_name'");
                } elseif(isset(
$sequence['Remove'])) {
                    
$this->database->debug("\tRemoved sequence '$sequence_name'");
                } else {
                    if(isset(
$sequence['name'])) {
                        
$this->database->debug("\tRenamed sequence '$sequence_name' to '".$sequence['name']."'");
                    }
                    if(isset(
$sequence['Change'])) {
                        foreach(
$sequence['Change'] as $sequence_name => $sequence) {
                            if(isset(
$sequence['start'])) {
                                
$this->database->debug(
                                    
"\tChanged sequence '$sequence_name' start to '".$sequence['start']."'");
                            }
                        }
                    }
                }
            }
        }
        if(isset(
$changes['INDEXES'])) {
            foreach(
$changes['INDEXES'] as $table_name => $table)
            {
                
$this->database->debug("$table_name:");
                if(isset(
$table['AddedIndexes'])) {
                    foreach(
$table['AddedIndexes'] as $index_name => $index) {
                        
$this->database->debug("\tAdded index '".$index_name."' of table '$table_name'");
                    }
                }
                if(isset(
$table['RemovedIndexes'])) {
                    foreach(
$table['RemovedIndexes'] as $index_name => $index) {
                        
$this->database->debug("\tRemoved index '".$index_name."' of table '$table_name'");
                    }
                }
                if(isset(
$table['ChangedIndexes'])) {
                    foreach(
$table['ChangedIndexes'] as $index_name => $index) {
                        if(isset(
$index['name'])) {
                            
$this->database->debug(
                                
"\tRenamed index '".$index_name."' to '".$index['name']."' on table '$table_name'");
                        }
                        if(isset(
$index['ChangedUnique'])) {
                            
$this->database->debug(
                                
"\tChanged index '".$index_name."' unique to '".
                                isset(
$index['unique'])."' on table '$table_name'");
                        }
                        if(isset(
$index['ChangedFields'])) {
                            
$this->database->debug("\tChanged index '".$index_name."' on table '$table_name'");
                        }
                    }
                }
            }
        }
        return(
MDB_OK);
    }

    
// }}}
    // {{{ _dumpDatabaseContents()

    /**
     * Parse a database schema definition file and dump the respective structure
     * and contents.
     *
     * @param string $schema_file path of the database schema file.
     * @param mixed $setup_arguments an associative array that takes pairs of tag names and values
     * that define the setup arguments that are passed to the
     * MDB_Manager::connect function.
     * @param array $dump_arguments an associative array that takes pairs of tag names and values
     * that define dump options as defined for the MDB_Manager::DumpDatabase
     * function.
     * @param array $variables an associative array that the defines the text string values
     * that are meant to be used to replace the variables that are used in the
     * schema description as defined for the
     * MDB_Manager::parseDatabaseDefinitionFile function.
     * @return mixed MDB_OK on success, or a MDB error object
     * @access private
     */
    
function _dumpDatabaseContents($schema_file$setup_arguments$dump_arguments$variables)
    {
        
$database_definition $this->parseDatabaseDefinitionFile($schema_file,
            
$variables$this->options['fail_on_invalid_names']);
        if(
MDB::isError($database_definition)) {
            return(
$database_definition);
        }
        
        
$this->database_definition $database_definition;
        
        
$result $this->connect($setup_arguments);
        if(
MDB::isError($result)) {
            return(
$result);
        }
        
        return(
$this->dumpDatabase($dump_arguments));
    }

    
// }}}
    // {{{ getDefinitionFromDatabase()

    /**
     * Attempt to reverse engineer a schema structure from an existing MDB
     * This method can be used if no xml schema file exists yet.
     * The resulting xml schema file may need some manual adjustments.
     *
     * @return mixed MDB_OK or array with all ambiguities on success, or a MDB error object
     * @access public
     */
    
function getDefinitionFromDatabase()
    {
        
$database $this->database->database_name;
        if(
strlen($database) == 0) {
            return(
'it was not specified a valid database name');
        }
        
$this->database_definition = array(
            
'name' => $database,
            
'create' => 1,
            
'TABLES' => array()
        );
        
$tables $this->database->listTables();
        if(
MDB::isError($tables)) {
            return(
$tables);
        }
        for(
$table 0$table count($tables); $table++) {
            
$table_name $tables[$table];
            
$fields $this->database->listTableFields($table_name);
            if(
MDB::isError($fields)) {
                return(
$fields);
            }
            
$this->database_definition['TABLES'][$table_name] = array('FIELDS' => array());
            for(
$field 0$field count($fields); $field++)
            {
                
$field_name $fields[$field];
                
$definition $this->database->getTableFieldDefinition($table_name$field_name);
                if(
MDB::isError($definition)) {
                    return(
$definition);
                }
                
$this->database_definition['TABLES'][$table_name]['FIELDS'][$field_name] = $definition[0][0];
                
$field_choices count($definition[0]);
                if(
$field_choices 1) {
                    
$warning "There are $field_choices type choices in the table $table_name field $field_name (#1 is the default): ";
                    
$field_choice_cnt 1;
                    
$this->database_definition['TABLES'][$table_name]['FIELDS'][$field_name]['CHOICES'] = array();
                    foreach(
$definition[0] as $field_choice) {
                        
$this->database_definition['TABLES'][$table_name]['FIELDS'][$field_name]['CHOICES'][] = $field_choice;
                        
$warning .= 'choice #'.($field_choice_cnt).': '.serialize($field_choice);
                        
$field_choice_cnt++;
                    }
                    
$this->warnings[] = $warning;
                }
                if(isset(
$definition[1])) {
                    
$sequence $definition[1]['definition'];
                    
$sequence_name $definition[1]['name'];
                    
$this->database->debug('Implicitly defining sequence: '.$sequence_name);
                    if(!isset(
$this->database_definition['SEQUENCES'])) {
                        
$this->database_definition['SEQUENCES'] = array();
                    }
                    
$this->database_definition['SEQUENCES'][$sequence_name] = $sequence;
                }
                if(isset(
$definition[2])) {
                    
$index $definition[2]['definition'];
                    
$index_name $definition[2]['name'];
                    
$this->database->debug('Implicitly defining index: '.$index_name);
                    if(!isset(
$this->database_definition['TABLES'][$table_name]['INDEXES'])) {
                        
$this->database_definition['TABLES'][$table_name]['INDEXES'] = array();
                    }
                    
$this->database_definition['TABLES'][$table_name]['INDEXES'][$index_name] = $index;
                }
            }
            
$indexes $this->database->listTableIndexes($table_name);
            if(
MDB::isError($indexes)) {
                return(
$indexes);
            }
            if(
is_array($indexes) && count($indexes) > && !isset($this->database_definition['TABLES'][$table_name]['INDEXES'])) {
                
$this->database_definition['TABLES'][$table_name]['INDEXES'] = array();
            }
            for(
$index 0$index_cnt count($indexes); $index $index_cnt$index++)
            {
                
$index_name $indexes[$index];
                
$definition $this->database->getTableIndexDefinition($table_name$index_name);
                if(
MDB::isError($definition)) {
                    return(
$definition);
                }
               
$this->database_definition['TABLES'][$table_name]['INDEXES'][$index_name] = $definition;
            }
            
// ensure that all fields that have an index on them are set to not null
            
if(isset($this->database_definition['TABLES'][$table_name]['INDEXES'])
                && 
is_array($this->database_definition['TABLES'][$table_name]['INDEXES'])
                && 
count($this->database_definition['TABLES'][$table_name]['INDEXES']) > 0
            
) {
                foreach(
$this->database_definition['TABLES'][$table_name]['INDEXES'] as $index_check_null) {
                    foreach(
$index_check_null['FIELDS'] as $field_name_check_null => $field_check_null) {
                        
$this->database_definition['TABLES'][$table_name]['FIELDS'][$field_name_check_null]['notnull'] = 1;
                    }
                }
            }
            
// ensure that all fields that are set to not null also have a default value
            
if(is_array($this->database_definition['TABLES'][$table_name]['FIELDS'])
                && 
count($this->database_definition['TABLES'][$table_name]['FIELDS']) > 0
            
) {
                foreach(
$this->database_definition['TABLES'][$table_name]['FIELDS'] as $field_set_default_name => $field_set_default) {
                    if(isset(
$field_set_default['notnull']) && $field_set_default['notnull']
                        && !isset(
$field_set_default['default'])
                    ) {
                        if(isset(
$this->default_values[$field_set_default['type']])) {
                            
$this->database_definition['TABLES'][$table_name]['FIELDS'][$field_set_default_name]['default'] = $this->default_values[$field_set_default['type']];
                        } else {
                            
$this->database_definition['TABLES'][$table_name]['FIELDS'][$field_set_default_name]['default'] = 0;
                        }
                    }
                    if(isset(
$field_set_default['CHOICES']) && is_array($field_set_default['CHOICES'])) {
                        foreach(
$field_set_default['CHOICES'] as $field_choices_set_default_name => $field_choices_set_default) {
                            if(isset(
$field_choices_set_default['notnull'])
                                && 
$field_choices_set_default['notnull']
                                && !isset(
$field_choices_set_default['default'])
                            ) {
                                if(isset(
$this->default_values[$field_choices_set_default['type']])) {
                                    
$this->database_definition['TABLES'][$table_name]['FIELDS'][$field_set_default_name]['CHOICES']
                                        [
$field_choices_set_default_name]['default'] = $this->default_values[$field_choices_set_default['type']];
                                } else {
                                    
$this->database_definition['TABLES'][$table_name]['FIELDS'][$field_set_default_name]['CHOICES']
                                        [
$field_choices_set_default_name]['default'] = 0;
                                }
                            }
                        }
                    }
                }
            }
        }
        
$sequences $this->database->listSequences();
        if(
MDB::isError($sequences)) {
            return(
$sequences);
        }
        if(
is_array($sequences) && count($sequences) > && !isset($this->database_definition['SEQUENCES'])) {
            
$this->database_definition['SEQUENCES'] = array();
        }
        for(
$sequence 0$sequence count($sequences); $sequence++) {
            
$sequence_name $sequences[$sequence];
            
$definition $this->database->getSequenceDefinition($sequence_name);
            if(
MDB::isError($definition)) {
                return(
$definition);
            }
            
$this->database_definition['SEQUENCES'][$sequence_name] = $definition;
        }
        return(
MDB_OK);
    }

    
// }}}
    // {{{ dumpDatabase()

    /**
     * Dump a previously parsed database structure in the Metabase schema
     * XML based format suitable for the Metabase parser. This function
     * may optionally dump the database definition with initialization
     * commands that specify the data that is currently present in the tables.
     *
     * @param array $arguments an associative array that takes pairs of tag
     * names and values that define dump options.
     *                 array (
     *                     'Definition'    =>    Boolean
     *                         TRUE   :  dump currently parsed definition
     *                         default:  dump currently connected database
     *                     'Output_Mode'    =>    String
     *                         'file' :   dump into a file
     *                         default:   dump using a function
     *                     'Output'        =>    String
     *                         depending on the 'Output_Mode'
     *                                  name of the file
     *                                  name of the function
     *                     'EndOfLine'        =>    String
     *                         end of line delimiter that should be used
     *                         default: "\n"
     *                 );
     * @param integer $dump constant that determines what data to dump
     *                      MDB_MANAGER_DUMP_ALL       : the entire db
     *                      MDB_MANAGER_DUMP_STRUCTURE : only the structure of the db
     *                      MDB_MANAGER_DUMP_CONTENT   : only the content of the db
     * @return mixed MDB_OK on success, or a MDB error object
     * @access public
     */
    
function dumpDatabase($arguments$dump MDB_MANAGER_DUMP_ALL)
    {
        if(isset(
$arguments['Definition']) && $arguments['Definition']) {
            
$dump_definition TRUE;
        } else {
            if(!
$this->database) {
                return(
$this->raiseError(MDB_ERROR_NODBSELECTED,
                    
NULLNULL'please connect to a RDBMS first'));
            }
            
$error $this->getDefinitionFromDatabase();
            if(
MDB::isError($error)) {
                return(
$error);
            }
            
$dump_definition FALSE;
        }
        if(isset(
$arguments['Output'])) {
            if(isset(
$arguments['Output_Mode']) && $arguments['Output_Mode'] == 'file') {
                
$fp fopen($arguments['Output'], 'w');
                
$output FALSE;
            } elseif(
function_exists($arguments['Output'])) {
                
$output $arguments['Output'];
            } else {
                return(
$this->raiseError(MDB_ERROR_MANAGERNULLNULL,
                        
'no valid output function specified'));
            }
        } else {
            return(
$this->raiseError(MDB_ERROR_MANAGERNULLNULL,
                
'no output method specified'));
        }
        if(isset(
$arguments['EndOfLine'])) {
            
$eol $arguments['EndOfLine'];
        } else {
            
$eol "\n";
        }
        
        
$sequences = array();
        if(isset(
$this->database_definition['SEQUENCES'])
            && 
is_array($this->database_definition['SEQUENCES'])
        ) {
            foreach(
$this->database_definition['SEQUENCES'] as $sequence_name => $sequence) {
                if(isset(
$sequence['on'])) {
                    
$table $sequence['on']['table'];
                } else {
                    
$table '';
                }
                
$sequences[$table][] = $sequence_name;
            }
        }
        
$previous_database_name = (strcmp($this->database_definition['name'], '') ? $this->database->setDatabase($this->database_definition['name']) : '');
        
$buffer = ('<?xml version="1.0" encoding="ISO-8859-1" ?>'.$eol);
        
$buffer .= ("<database>$eol$eol <name>".$this->database_definition['name']."</name>$eol <create>".$this->database_definition['create']."</create>$eol");
        
        if(
$output) {
            
$output($buffer);
        } else {
            
fwrite($fp$buffer);
        }
        
$buffer '';
        if(isset(
$this->database_definition['TABLES']) && is_array($this->database_definition['TABLES'])) {
            foreach(
$this->database_definition['TABLES'] as $table_name => $table) {
                
$buffer = ("$eol <table>$eol$eol  <name>$table_name</name>$eol");
                if(
$dump == MDB_MANAGER_DUMP_ALL || $dump == MDB_MANAGER_DUMP_STRUCTURE) {
                    
$buffer .= ("$eol  <declaration>$eol");
                    if(isset(
$table['FIELDS']) && is_array($table['FIELDS'])) {
                        foreach(
$table['FIELDS'] as $field_name => $field) {
                            if(!isset(
$field['type'])) {
                                return(
$this->raiseError(MDB_ERROR_MANAGERNULLNULL,
                                    
'it was not specified the type of the field "'.$field_name.'" of the table "'.$table_name));
                            }
                            
$buffer .=("$eol   <field>$eol    <name>$field_name</name>$eol    <type>".$field['type']."</type>$eol");
                            if(
in_array($field_namearray_keys($this->invalid_names))) {
                                
$this->warnings[] = "invalid field name: $field_name. You will need to set the class var \$fail_on_invalid_names to FALSE or change the field name.";
                            }
                            switch(
$field['type']) {
                                case 
'integer':
                                    if(isset(
$field['unsigned'])) {
                                        
$buffer .=("    <unsigned>1</unsigned>$eol");
                                    }
                                    break;
                                case 
'text':
                                case 
'clob':
                                case 
'blob':
                                    if(isset(
$field['length'])) {
                                        
$buffer .=('    <length>'.$field['length']."</length>$eol");
                                    }
                                    break;
                                case 
'boolean':
                                case 
'date':
                                case 
'timestamp':
                                case 
'time':
                                case 
'float':
                                case 
'decimal':
                                    break;
                                default:
                                    return(
'type "'.$field['type'].'" is not yet supported');
                            }
                            if(isset(
$field['notnull'])) {
                                
$buffer .=("    <notnull>1</notnull>$eol");
                            }
                            if(isset(
$field['default'])) {
                                
$buffer .=('    <default>'.$this->_escapeSpecialCharacters($field['default'])."</default>$eol");
                            }
                            
$buffer .=("   </field>$eol");
                        }
                    }
                    if(isset(
$table['INDEXES']) && is_array($table['INDEXES'])) {
                        foreach(
$table['INDEXES'] as $index_name => $index) {
                            
$buffer .=("$eol   <index>$eol    <name>$index_name</name>$eol");
                            if(isset(
$index['unique'])) {
                                
$buffer .=("    <unique>1</unique>$eol");
                            }
                            foreach(
$index['FIELDS'] as $field_name => $field) {
                                
$buffer .=("    <field>$eol     <name>$field_name</name>$eol");
                                if(
is_array($field) && isset($field['sorting'])) { 
                                    
$buffer .=('     <sorting>'.$field['sorting']."</sorting>$eol");
                                }
                                
$buffer .=("    </field>$eol");
                            }
                            
$buffer .=("   </index>$eol");
                        }
                    }
                    
$buffer .= ("$eol  </declaration>$eol");
                }
                if(
$output) {
                    
$output($buffer);
                } else {
                    
fwrite($fp$buffer);
                }
                
$buffer '';
                if(
$dump == MDB_MANAGER_DUMP_ALL || $dump == MDB_MANAGER_DUMP_CONTENT) {
                    if(
$dump_definition) {
                        if(isset(
$table['initialization']) && is_array($table['initialization'])) {
                            
$buffer = ("$eol  <initialization>$eol");
                            foreach(
$table['initialization'] as $instruction_name => $instruction) {
                                switch(
$instruction['type']) {
                                    case 
'insert':
                                        
$buffer .= ("$eol   <insert>$eol");
                                        foreach(
$instruction['FIELDS'] as $field_name => $field) {
                                            
$buffer .= ("$eol    <field>$eol     <name>$field_name</name>$eol     <value>".$this->_escapeSpecialCharacters($field)."</value>$eol   </field>$eol");
                                        }
                                        
$buffer .= ("$eol   </insert>$eol");
                                        break;
                                }
                            }
                            
$buffer .= ("$eol  </initialization>$eol");
                        }
                    } else {
                        
$types = array();
                        foreach(
$table['FIELDS'] as $field) {
                            
$types[] = $field['type'];
                        }
                        
$query 'SELECT '.implode(',',array_keys($table['FIELDS']))." FROM $table_name";
                        
$result $this->database->queryAll($query$typesMDB_FETCHMODE_ASSOC);
                        if(
MDB::isError($result)) {
                            return(
$result);
                        }
                        
$rows count($result);
                        if(
$rows 0) {
                            
$buffer = ("$eol  <initialization>$eol");
                            if(
$output) {
                                
$output($buffer);
                            } else {
                                
fwrite($fp$buffer);
                            }
                            
                            for(
$row 0$row $rows$row++) {
                                
$buffer = ("$eol   <insert>$eol");
                                
$values $result[$row];
                                if(!
is_array($values)) {
                                    break;
                                } else {
                                    foreach(
$values as $field_name => $field) {
                                            
$buffer .= ("$eol   <field>$eol     <name>$field_name</name>$eol     <value>");
                                            
$buffer .= $this->_escapeSpecialCharacters($values[$field_name]);
                                            
$buffer .= ("</value>$eol   </field>$eol");
                                    }
                                }
                                
$buffer .= ("$eol   </insert>$eol");
                                if(
$output) {
                                    
$output($buffer);
                                } else {
                                    
fwrite($fp$buffer);
                                }
                                
$buffer '';
                            }
                            
$buffer = ("$eol  </initialization>$eol");
                            if(
$output) {
                                
$output($buffer);
                            } else {
                                
fwrite($fp$buffer);
                            }
                            
$buffer '';
                        }
                    }
                }
                
$buffer .= ("$eol </table>$eol");
                if(
$output) {
                    
$output($buffer);
                } else {
                    
fwrite($fp$buffer);
                }
                if(isset(
$sequences[$table_name])) {
                    for(
$sequence 0$j count($sequences[$table_name]);
                        
$sequence $j;
                        
$sequence++)
                    {
                        
$result $this->_dumpSequence($sequences[$table_name][$sequence], $eol$dump);
                        if(
MDB::isError($result)) {
                            return(
$result);
                        }
                        if(
$output) {
                            
$output($result);
                        } else {
                            
fwrite($fp$result);
                        }
                    }
                }
            }
        }
        if(isset(
$sequences[''])) {
            for(
$sequence 0;
                
$sequence count($sequences['']);
                
$sequence++)
            {
                
$result $this->_dumpSequence($sequences[''][$sequence], $eol$dump);
                if(
MDB::isError($result)) {
                    return(
$result);
                }
                if(
$output) {
                       
$output($result);
                   } else {
                       
fwrite($fp$result);
                }
            }
        }
        
        
$buffer = ("$eol</database>$eol");
        if(
$output) {
            
$output($buffer);
        } else {
            
fwrite($fp$buffer);
            
fclose($fp);
        }
        
        if(
strcmp($previous_database_name'')) {
            
$this->database->setDatabase($previous_database_name);
        }
        return(
MDB_OK);
    }

    
// }}}
    // {{{ updateDatabase()

    /**
     * Compare the correspondent files of two versions of a database schema
     * definition: the previously installed and the one that defines the schema
     * that is meant to update the database.
     * If the specified previous definition file does not exist, this function
     * will create the database from the definition specified in the current
     * schema file.
     * If both files exist, the function assumes that the database was previously
     * installed based on the previous schema file and will update it by just
     * applying the changes.
     * If this function succeeds, the contents of the current schema file are
     * copied to replace the previous schema file contents. Any subsequent schema
     * changes should only be done on the file specified by the $current_schema_file
     * to let this function make a consistent evaluation of the exact changes that
     * need to be applied.
     *
     * @param string $current_schema_file name of the updated database schema
     * definition file.
     * @param string $previous_schema_file name the previously installed database
     * schema definition file.
     * @param array $variables an associative array that is passed to the argument
     * of the same name to the parseDatabaseDefinitionFile function. (there third
     * param)
     * @return mixed MDB_OK on success, or a MDB error object
     * @access public
     */
    
function updateDatabase($current_schema_file$previous_schema_file FALSE$variables = array())
    {
        
$database_definition $this->parseDatabaseDefinitionFile($current_schema_file,
            
$variables$this->options['fail_on_invalid_names']);
        if(
MDB::isError($database_definition)) {
            return(
$database_definition);
        }
        
$this->database_definition $database_definition;
        
$copy 0;
/*
        $this->expectError(MDB_ERROR_UNSUPPORTED);
        $databases = $this->database->listDatabases();
        $this->popExpect();
        if((MDB::isError($databases) || (is_array($databases) && in_array($this->database_definition['name'], $databases)))
            && $previous_schema_file && file_exists($previous_schema_file))
        {
*/
        
if($previous_schema_file && file_exists($previous_schema_file)) {
            
$previous_definition $this->parseDatabaseDefinitionFile($previous_schema_file$variables0);
            if(
MDB::isError($previous_definition)) {
                return(
$previous_definition);
            }
            
$changes $this->_compareDefinitions($previous_definition);
            if(
MDB::isError($changes)) {
                return(
$changes);
            }
            if(isset(
$changes) && is_array($changes)) {
                
$result $this->_alterDatabase($previous_definition$changes);
                if(
MDB::isError($result)) {
                    return(
$result);
                }
                
$copy 1;
                if(
$this->options['debug']) {
                    
$result $this->_debugDatabaseChanges($changes);
                    if(
MDB::isError($result)) {
                        return(
$result);
                    }
                }
            }
        } else {
            
$result $this->_createDatabase();
            if(
MDB::isError($result)) {
                return(
$result);
            }
            
$copy 1;
        }
        if(
$copy && $previous_schema_file && !copy($current_schema_file$previous_schema_file)) {
            return(
$this->raiseError(MDB_ERROR_MANAGERNULLNULL,
                
'Could not copy the new database definition file to the current file'));
        }
        return(
MDB_OK);
    }

    
// }}}
}
?>

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0468 ]--