summaryrefslogtreecommitdiffstats
path: root/3rdparty/MDB2/Schema
diff options
context:
space:
mode:
authorFrank Karlitschek <karlitschek@kde.org>2011-08-07 17:36:49 +0200
committerFrank Karlitschek <karlitschek@kde.org>2011-08-07 17:36:49 +0200
commitf5a030f4ae5298c2b3325a27e8d05153f0488ea0 (patch)
tree3317cc1a238a0caaabb23a8c9a26451106f24ec1 /3rdparty/MDB2/Schema
parent51caa624bb0874fff878a00fb2883e58ad60cde3 (diff)
downloadnextcloud-server-f5a030f4ae5298c2b3325a27e8d05153f0488ea0.tar.gz
nextcloud-server-f5a030f4ae5298c2b3325a27e8d05153f0488ea0.zip
remove the ownCloud 3D support and add lot's of usefull 3rd party libraries instead.
Diffstat (limited to '3rdparty/MDB2/Schema')
-rw-r--r--3rdparty/MDB2/Schema/Parser.php812
-rw-r--r--3rdparty/MDB2/Schema/Parser2.php624
-rw-r--r--3rdparty/MDB2/Schema/Reserved/ibase.php436
-rw-r--r--3rdparty/MDB2/Schema/Reserved/mssql.php258
-rw-r--r--3rdparty/MDB2/Schema/Reserved/mysql.php284
-rw-r--r--3rdparty/MDB2/Schema/Reserved/oci8.php171
-rw-r--r--3rdparty/MDB2/Schema/Reserved/pgsql.php147
-rw-r--r--3rdparty/MDB2/Schema/Tool.php560
-rw-r--r--3rdparty/MDB2/Schema/Tool/ParameterException.php6
-rw-r--r--3rdparty/MDB2/Schema/Validate.php917
-rw-r--r--3rdparty/MDB2/Schema/Writer.php581
11 files changed, 4796 insertions, 0 deletions
diff --git a/3rdparty/MDB2/Schema/Parser.php b/3rdparty/MDB2/Schema/Parser.php
new file mode 100644
index 00000000000..b740ef55fa8
--- /dev/null
+++ b/3rdparty/MDB2/Schema/Parser.php
@@ -0,0 +1,812 @@
+<?php
+/**
+ * PHP versions 4 and 5
+ *
+ * Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox,
+ * Stig. S. Bakken, Lukas Smith, Igor Feghali
+ * All rights reserved.
+ *
+ * MDB2_Schema enables users to maintain RDBMS independant schema files
+ * in XML that can be used to manipulate both data and database schemas
+ * 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, Igor Feghali 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: Christian Dickmann <dickmann@php.net>
+ * Author: Igor Feghali <ifeghali@php.net>
+ *
+ * $Id: Parser.php,v 1.68 2008/11/30 03:34:00 clockwerx Exp $
+ *
+ * @category Database
+ * @package MDB2_Schema
+ * @author Christian Dickmann <dickmann@php.net>
+ * @author Igor Feghali <ifeghali@php.net>
+ * @license BSD http://www.opensource.org/licenses/bsd-license.php
+ * @version CVS: $Id: Parser.php,v 1.68 2008/11/30 03:34:00 clockwerx Exp $
+ * @link http://pear.php.net/packages/MDB2_Schema
+ */
+
+
+require_once('XML/Parser.php');
+require_once('MDB2/Schema/Validate.php');
+
+/**
+ * Parses an XML schema file
+ *
+ * @category Database
+ * @package MDB2_Schema
+ * @author Christian Dickmann <dickmann@php.net>
+ * @license BSD http://www.opensource.org/licenses/bsd-license.php
+ * @link http://pear.php.net/packages/MDB2_Schema
+ */
+class MDB2_Schema_Parser extends XML_Parser
+{
+ var $database_definition = array();
+
+ var $elements = array();
+
+ var $element = '';
+
+ var $count = 0;
+
+ var $table = array();
+
+ var $table_name = '';
+
+ var $field = array();
+
+ var $field_name = '';
+
+ var $init = array();
+
+ var $init_function = array();
+
+ var $init_expression = array();
+
+ var $init_field = array();
+
+ var $index = array();
+
+ var $index_name = '';
+
+ var $constraint = array();
+
+ var $constraint_name = '';
+
+ var $var_mode = false;
+
+ var $variables = array();
+
+ var $sequence = array();
+
+ var $sequence_name = '';
+
+ var $error;
+
+ var $structure = false;
+
+ var $val;
+
+ function __construct($variables, $fail_on_invalid_names = true,
+ $structure = false, $valid_types = array(),
+ $force_defaults = true)
+ {
+ // force ISO-8859-1 due to different defaults for PHP4 and PHP5
+ // todo: this probably needs to be investigated some more andcleaned up
+ parent::__construct('ISO-8859-1');
+
+ $this->variables = $variables;
+ $this->structure = $structure;
+ $this->val =new MDB2_Schema_Validate($fail_on_invalid_names, $valid_types, $force_defaults);
+ }
+
+ function startHandler($xp, $element, $attribs)
+ {
+ if (strtolower($element) == 'variable') {
+ $this->var_mode = true;
+ return;
+ }
+
+ $this->elements[$this->count++] = strtolower($element);
+
+ $this->element = implode('-', $this->elements);
+
+ switch ($this->element) {
+ /* Initialization */
+ case 'database-table-initialization':
+ $this->table['initialization'] = array();
+ break;
+
+ /* Insert */
+ /* insert: field+ */
+ case 'database-table-initialization-insert':
+ $this->init = array('type' => 'insert', 'data' => array('field' => array()));
+ break;
+ /* insert-select: field+, table, where? */
+ case 'database-table-initialization-insert-select':
+ $this->init['data']['table'] = '';
+ break;
+
+ /* Update */
+ /* update: field+, where? */
+ case 'database-table-initialization-update':
+ $this->init = array('type' => 'update', 'data' => array('field' => array()));
+ break;
+
+ /* Delete */
+ /* delete: where */
+ case 'database-table-initialization-delete':
+ $this->init = array('type' => 'delete', 'data' => array('where' => array()));
+ break;
+
+ /* Insert and Update */
+ case 'database-table-initialization-insert-field':
+ case 'database-table-initialization-insert-select-field':
+ case 'database-table-initialization-update-field':
+ $this->init_field = array('name' => '', 'group' => array());
+ break;
+ case 'database-table-initialization-insert-field-value':
+ case 'database-table-initialization-insert-select-field-value':
+ case 'database-table-initialization-update-field-value':
+ /* if value tag is empty cdataHandler is not called so we must force value element creation here */
+ $this->init_field['group'] = array('type' => 'value', 'data' => '');
+ break;
+ case 'database-table-initialization-insert-field-null':
+ case 'database-table-initialization-insert-select-field-null':
+ case 'database-table-initialization-update-field-null':
+ $this->init_field['group'] = array('type' => 'null');
+ break;
+ case 'database-table-initialization-insert-field-function':
+ case 'database-table-initialization-insert-select-field-function':
+ case 'database-table-initialization-update-field-function':
+ $this->init_function = array('name' => '');
+ break;
+ case 'database-table-initialization-insert-field-expression':
+ case 'database-table-initialization-insert-select-field-expression':
+ case 'database-table-initialization-update-field-expression':
+ $this->init_expression = array();
+ break;
+
+ /* All */
+ case 'database-table-initialization-insert-select-where':
+ case 'database-table-initialization-update-where':
+ case 'database-table-initialization-delete-where':
+ $this->init['data']['where'] = array('type' => '', 'data' => array());
+ break;
+ case 'database-table-initialization-insert-select-where-expression':
+ case 'database-table-initialization-update-where-expression':
+ case 'database-table-initialization-delete-where-expression':
+ $this->init_expression = array();
+ break;
+
+ /* One level simulation of expression-function recursion */
+ case 'database-table-initialization-insert-field-expression-function':
+ case 'database-table-initialization-insert-select-field-expression-function':
+ case 'database-table-initialization-insert-select-where-expression-function':
+ case 'database-table-initialization-update-field-expression-function':
+ case 'database-table-initialization-update-where-expression-function':
+ case 'database-table-initialization-delete-where-expression-function':
+ $this->init_function = array('name' => '');
+ break;
+
+ /* One level simulation of function-expression recursion */
+ case 'database-table-initialization-insert-field-function-expression':
+ case 'database-table-initialization-insert-select-field-function-expression':
+ case 'database-table-initialization-insert-select-where-function-expression':
+ case 'database-table-initialization-update-field-function-expression':
+ case 'database-table-initialization-update-where-function-expression':
+ case 'database-table-initialization-delete-where-function-expression':
+ $this->init_expression = array();
+ break;
+
+ /* Definition */
+ case 'database':
+ $this->database_definition = array(
+ 'name' => '',
+ 'create' => '',
+ 'overwrite' => '',
+ 'charset' => '',
+ 'description' => '',
+ 'comments' => '',
+ 'tables' => array(),
+ 'sequences' => array()
+ );
+ break;
+ case 'database-table':
+ $this->table_name = '';
+
+ $this->table = array(
+ 'was' => '',
+ 'description' => '',
+ 'comments' => '',
+ 'fields' => array(),
+ 'indexes' => array(),
+ 'constraints' => array(),
+ 'initialization' => array()
+ );
+ break;
+ case 'database-table-declaration-field':
+ case 'database-table-declaration-foreign-field':
+ case 'database-table-declaration-foreign-references-field':
+ $this->field_name = '';
+
+ $this->field = array();
+ break;
+ case 'database-table-declaration-index-field':
+ $this->field_name = '';
+
+ $this->field = array('sorting' => '', 'length' => '');
+ break;
+ /* force field attributes to be initialized when the tag is empty in the XML */
+ case 'database-table-declaration-field-was':
+ $this->field['was'] = '';
+ break;
+ case 'database-table-declaration-field-type':
+ $this->field['type'] = '';
+ break;
+ case 'database-table-declaration-field-fixed':
+ $this->field['fixed'] = '';
+ break;
+ case 'database-table-declaration-field-default':
+ $this->field['default'] = '';
+ break;
+ case 'database-table-declaration-field-notnull':
+ $this->field['notnull'] = '';
+ break;
+ case 'database-table-declaration-field-autoincrement':
+ $this->field['autoincrement'] = '';
+ break;
+ case 'database-table-declaration-field-unsigned':
+ $this->field['unsigned'] = '';
+ break;
+ case 'database-table-declaration-field-length':
+ $this->field['length'] = '';
+ break;
+ case 'database-table-declaration-field-description':
+ $this->field['description'] = '';
+ break;
+ case 'database-table-declaration-field-comments':
+ $this->field['comments'] = '';
+ break;
+ case 'database-table-declaration-index':
+ $this->index_name = '';
+
+ $this->index = array(
+ 'was' => '',
+ 'unique' =>'',
+ 'primary' => '',
+ 'fields' => array()
+ );
+ break;
+ case 'database-table-declaration-foreign':
+ $this->constraint_name = '';
+
+ $this->constraint = array(
+ 'was' => '',
+ 'match' => '',
+ 'ondelete' => '',
+ 'onupdate' => '',
+ 'deferrable' => '',
+ 'initiallydeferred' => '',
+ 'foreign' => true,
+ 'fields' => array(),
+ 'references' => array('table' => '', 'fields' => array())
+ );
+ break;
+ case 'database-sequence':
+ $this->sequence_name = '';
+
+ $this->sequence = array(
+ 'was' => '',
+ 'start' => '',
+ 'description' => '',
+ 'comments' => '',
+ 'on' => array('table' => '', 'field' => '')
+ );
+ break;
+ }
+ }
+
+ function endHandler($xp, $element)
+ {
+ if (strtolower($element) == 'variable') {
+ $this->var_mode = false;
+ return;
+ }
+
+ switch ($this->element) {
+ /* Initialization */
+
+ /* Insert */
+ case 'database-table-initialization-insert-select':
+ $this->init['data'] = array('select' => $this->init['data']);
+ break;
+
+ /* Insert and Delete */
+ case 'database-table-initialization-insert-field':
+ case 'database-table-initialization-insert-select-field':
+ case 'database-table-initialization-update-field':
+ $result = $this->val->validateDataField($this->table['fields'], $this->init['data']['field'], $this->init_field);
+ if (PEAR::isError($result)) {
+ $this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
+ } else {
+ $this->init['data']['field'][] = $this->init_field;
+ }
+ break;
+ case 'database-table-initialization-insert-field-function':
+ case 'database-table-initialization-insert-select-field-function':
+ case 'database-table-initialization-update-field-function':
+ $this->init_field['group'] = array('type' => 'function', 'data' => $this->init_function);
+ break;
+ case 'database-table-initialization-insert-field-expression':
+ case 'database-table-initialization-insert-select-field-expression':
+ case 'database-table-initialization-update-field-expression':
+ $this->init_field['group'] = array('type' => 'expression', 'data' => $this->init_expression);
+ break;
+
+ /* All */
+ case 'database-table-initialization-insert-select-where-expression':
+ case 'database-table-initialization-update-where-expression':
+ case 'database-table-initialization-delete-where-expression':
+ $this->init['data']['where']['type'] = 'expression';
+ $this->init['data']['where']['data'] = $this->init_expression;
+ break;
+ case 'database-table-initialization-insert':
+ case 'database-table-initialization-delete':
+ case 'database-table-initialization-update':
+ $this->table['initialization'][] = $this->init;
+ break;
+
+ /* One level simulation of expression-function recursion */
+ case 'database-table-initialization-insert-field-expression-function':
+ case 'database-table-initialization-insert-select-field-expression-function':
+ case 'database-table-initialization-insert-select-where-expression-function':
+ case 'database-table-initialization-update-field-expression-function':
+ case 'database-table-initialization-update-where-expression-function':
+ case 'database-table-initialization-delete-where-expression-function':
+ $this->init_expression['operants'][] = array('type' => 'function', 'data' => $this->init_function);
+ break;
+
+ /* One level simulation of function-expression recursion */
+ case 'database-table-initialization-insert-field-function-expression':
+ case 'database-table-initialization-insert-select-field-function-expression':
+ case 'database-table-initialization-insert-select-where-function-expression':
+ case 'database-table-initialization-update-field-function-expression':
+ case 'database-table-initialization-update-where-function-expression':
+ case 'database-table-initialization-delete-where-function-expression':
+ $this->init_function['arguments'][] = array('type' => 'expression', 'data' => $this->init_expression);
+ break;
+
+ /* Table definition */
+ case 'database-table':
+ $result = $this->val->validateTable($this->database_definition['tables'], $this->table, $this->table_name);
+ if (PEAR::isError($result)) {
+ $this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
+ } else {
+ $this->database_definition['tables'][$this->table_name] = $this->table;
+ }
+ break;
+ case 'database-table-name':
+ if (isset($this->structure['tables'][$this->table_name])) {
+ $this->table = $this->structure['tables'][$this->table_name];
+ }
+ break;
+
+ /* Field declaration */
+ case 'database-table-declaration-field':
+ $result = $this->val->validateField($this->table['fields'], $this->field, $this->field_name);
+ if (PEAR::isError($result)) {
+ $this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
+ } else {
+ $this->table['fields'][$this->field_name] = $this->field;
+ }
+ break;
+
+ /* Index declaration */
+ case 'database-table-declaration-index':
+ $result = $this->val->validateIndex($this->table['indexes'], $this->index, $this->index_name);
+ if (PEAR::isError($result)) {
+ $this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
+ } else {
+ $this->table['indexes'][$this->index_name] = $this->index;
+ }
+ break;
+ case 'database-table-declaration-index-field':
+ $result = $this->val->validateIndexField($this->index['fields'], $this->field, $this->field_name);
+ if (PEAR::isError($result)) {
+ $this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
+ } else {
+ $this->index['fields'][$this->field_name] = $this->field;
+ }
+ break;
+
+ /* Foreign Key declaration */
+ case 'database-table-declaration-foreign':
+ $result = $this->val->validateConstraint($this->table['constraints'], $this->constraint, $this->constraint_name);
+ if (PEAR::isError($result)) {
+ $this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
+ } else {
+ $this->table['constraints'][$this->constraint_name] = $this->constraint;
+ }
+ break;
+ case 'database-table-declaration-foreign-field':
+ $result = $this->val->validateConstraintField($this->constraint['fields'], $this->field_name);
+ if (PEAR::isError($result)) {
+ $this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
+ } else {
+ $this->constraint['fields'][$this->field_name] = '';
+ }
+ break;
+ case 'database-table-declaration-foreign-references-field':
+ $result = $this->val->validateConstraintReferencedField($this->constraint['references']['fields'], $this->field_name);
+ if (PEAR::isError($result)) {
+ $this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
+ } else {
+ $this->constraint['references']['fields'][$this->field_name] = '';
+ }
+ break;
+
+ /* Sequence declaration */
+ case 'database-sequence':
+ $result = $this->val->validateSequence($this->database_definition['sequences'], $this->sequence, $this->sequence_name);
+ if (PEAR::isError($result)) {
+ $this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
+ } else {
+ $this->database_definition['sequences'][$this->sequence_name] = $this->sequence;
+ }
+ break;
+
+ /* End of File */
+ case 'database':
+ $result = $this->val->validateDatabase($this->database_definition);
+ if (PEAR::isError($result)) {
+ $this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
+ }
+ break;
+ }
+
+ unset($this->elements[--$this->count]);
+ $this->element = implode('-', $this->elements);
+ }
+
+ function raiseError($msg = null, $xmlecode = 0, $xp = null, $ecode = MDB2_SCHEMA_ERROR_PARSE,$a=null,$b=null,$c=null)
+ {
+ if (is_null($this->error)) {
+ $error = '';
+ if (is_resource($msg)) {
+ $error .= 'Parser error: '.xml_error_string(xml_get_error_code($msg));
+ $xp = $msg;
+ } else {
+ $error .= 'Parser error: '.$msg;
+ if (!is_resource($xp)) {
+ $xp = $this->parser;
+ }
+ }
+
+ if ($error_string = xml_error_string($xmlecode)) {
+ $error .= ' - '.$error_string;
+ }
+
+ if (is_resource($xp)) {
+ $byte = @xml_get_current_byte_index($xp);
+ $line = @xml_get_current_line_number($xp);
+ $column = @xml_get_current_column_number($xp);
+ $error .= " - Byte: $byte; Line: $line; Col: $column";
+ }
+
+ $error .= "\n";
+
+ $this->error =& MDB2_Schema::raiseError($ecode, null, null, $error);
+ }
+ return $this->error;
+ }
+
+ function cdataHandler($xp, $data)
+ {
+ if ($this->var_mode == true) {
+ if (!isset($this->variables[$data])) {
+ $this->raiseError('variable "'.$data.'" not found', null, $xp);
+ return;
+ }
+ $data = $this->variables[$data];
+ }
+
+ switch ($this->element) {
+ /* Initialization */
+
+ /* Insert */
+ case 'database-table-initialization-insert-select-table':
+ $this->init['data']['table'] = $data;
+ break;
+
+ /* Insert and Update */
+ case 'database-table-initialization-insert-field-name':
+ case 'database-table-initialization-insert-select-field-name':
+ case 'database-table-initialization-update-field-name':
+ $this->init_field['name'] .= $data;
+ break;
+ case 'database-table-initialization-insert-field-value':
+ case 'database-table-initialization-insert-select-field-value':
+ case 'database-table-initialization-update-field-value':
+ $this->init_field['group']['data'] .= $data;
+ break;
+ case 'database-table-initialization-insert-field-function-name':
+ case 'database-table-initialization-insert-select-field-function-name':
+ case 'database-table-initialization-update-field-function-name':
+ $this->init_function['name'] .= $data;
+ break;
+ case 'database-table-initialization-insert-field-function-value':
+ case 'database-table-initialization-insert-select-field-function-value':
+ case 'database-table-initialization-update-field-function-value':
+ $this->init_function['arguments'][] = array('type' => 'value', 'data' => $data);
+ break;
+ case 'database-table-initialization-insert-field-function-column':
+ case 'database-table-initialization-insert-select-field-function-column':
+ case 'database-table-initialization-update-field-function-column':
+ $this->init_function['arguments'][] = array('type' => 'column', 'data' => $data);
+ break;
+ case 'database-table-initialization-insert-field-column':
+ case 'database-table-initialization-insert-select-field-column':
+ case 'database-table-initialization-update-field-column':
+ $this->init_field['group'] = array('type' => 'column', 'data' => $data);
+ break;
+
+ /* All */
+ case 'database-table-initialization-insert-field-expression-operator':
+ case 'database-table-initialization-insert-select-field-expression-operator':
+ case 'database-table-initialization-insert-select-where-expression-operator':
+ case 'database-table-initialization-update-field-expression-operator':
+ case 'database-table-initialization-update-where-expression-operator':
+ case 'database-table-initialization-delete-where-expression-operator':
+ $this->init_expression['operator'] = $data;
+ break;
+ case 'database-table-initialization-insert-field-expression-value':
+ case 'database-table-initialization-insert-select-field-expression-value':
+ case 'database-table-initialization-insert-select-where-expression-value':
+ case 'database-table-initialization-update-field-expression-value':
+ case 'database-table-initialization-update-where-expression-value':
+ case 'database-table-initialization-delete-where-expression-value':
+ $this->init_expression['operants'][] = array('type' => 'value', 'data' => $data);
+ break;
+ case 'database-table-initialization-insert-field-expression-column':
+ case 'database-table-initialization-insert-select-field-expression-column':
+ case 'database-table-initialization-insert-select-where-expression-column':
+ case 'database-table-initialization-update-field-expression-column':
+ case 'database-table-initialization-update-where-expression-column':
+ case 'database-table-initialization-delete-where-expression-column':
+ $this->init_expression['operants'][] = array('type' => 'column', 'data' => $data);
+ break;
+
+ case 'database-table-initialization-insert-field-function-function':
+ case 'database-table-initialization-insert-field-function-expression':
+ case 'database-table-initialization-insert-field-expression-expression':
+ case 'database-table-initialization-update-field-function-function':
+ case 'database-table-initialization-update-field-function-expression':
+ case 'database-table-initialization-update-field-expression-expression':
+ case 'database-table-initialization-update-where-expression-expression':
+ case 'database-table-initialization-delete-where-expression-expression':
+ /* Recursion to be implemented yet */
+ break;
+
+ /* One level simulation of expression-function recursion */
+ case 'database-table-initialization-insert-field-expression-function-name':
+ case 'database-table-initialization-insert-select-field-expression-function-name':
+ case 'database-table-initialization-insert-select-where-expression-function-name':
+ case 'database-table-initialization-update-field-expression-function-name':
+ case 'database-table-initialization-update-where-expression-function-name':
+ case 'database-table-initialization-delete-where-expression-function-name':
+ $this->init_function['name'] .= $data;
+ break;
+ case 'database-table-initialization-insert-field-expression-function-value':
+ case 'database-table-initialization-insert-select-field-expression-function-value':
+ case 'database-table-initialization-insert-select-where-expression-function-value':
+ case 'database-table-initialization-update-field-expression-function-value':
+ case 'database-table-initialization-update-where-expression-function-value':
+ case 'database-table-initialization-delete-where-expression-function-value':
+ $this->init_function['arguments'][] = array('type' => 'value', 'data' => $data);
+ break;
+ case 'database-table-initialization-insert-field-expression-function-column':
+ case 'database-table-initialization-insert-select-field-expression-function-column':
+ case 'database-table-initialization-insert-select-where-expression-function-column':
+ case 'database-table-initialization-update-field-expression-function-column':
+ case 'database-table-initialization-update-where-expression-function-column':
+ case 'database-table-initialization-delete-where-expression-function-column':
+ $this->init_function['arguments'][] = array('type' => 'column', 'data' => $data);
+ break;
+
+ /* One level simulation of function-expression recursion */
+ case 'database-table-initialization-insert-field-function-expression-operator':
+ case 'database-table-initialization-insert-select-field-function-expression-operator':
+ case 'database-table-initialization-update-field-function-expression-operator':
+ $this->init_expression['operator'] = $data;
+ break;
+ case 'database-table-initialization-insert-field-function-expression-value':
+ case 'database-table-initialization-insert-select-field-function-expression-value':
+ case 'database-table-initialization-update-field-function-expression-value':
+ $this->init_expression['operants'][] = array('type' => 'value', 'data' => $data);
+ break;
+ case 'database-table-initialization-insert-field-function-expression-column':
+ case 'database-table-initialization-insert-select-field-function-expression-column':
+ case 'database-table-initialization-update-field-function-expression-column':
+ $this->init_expression['operants'][] = array('type' => 'column', 'data' => $data);
+ break;
+
+ /* Database */
+ case 'database-name':
+ $this->database_definition['name'] .= $data;
+ break;
+ case 'database-create':
+ $this->database_definition['create'] .= $data;
+ break;
+ case 'database-overwrite':
+ $this->database_definition['overwrite'] .= $data;
+ break;
+ case 'database-charset':
+ $this->database_definition['charset'] .= $data;
+ break;
+ case 'database-description':
+ $this->database_definition['description'] .= $data;
+ break;
+ case 'database-comments':
+ $this->database_definition['comments'] .= $data;
+ break;
+
+ /* Table declaration */
+ case 'database-table-name':
+ $this->table_name .= $data;
+ break;
+ case 'database-table-was':
+ $this->table['was'] .= $data;
+ break;
+ case 'database-table-description':
+ $this->table['description'] .= $data;
+ break;
+ case 'database-table-comments':
+ $this->table['comments'] .= $data;
+ break;
+
+ /* Field declaration */
+ case 'database-table-declaration-field-name':
+ $this->field_name .= $data;
+ break;
+ case 'database-table-declaration-field-was':
+ $this->field['was'] .= $data;
+ break;
+ case 'database-table-declaration-field-type':
+ $this->field['type'] .= $data;
+ break;
+ case 'database-table-declaration-field-fixed':
+ $this->field['fixed'] .= $data;
+ break;
+ case 'database-table-declaration-field-default':
+ $this->field['default'] .= $data;
+ break;
+ case 'database-table-declaration-field-notnull':
+ $this->field['notnull'] .= $data;
+ break;
+ case 'database-table-declaration-field-autoincrement':
+ $this->field['autoincrement'] .= $data;
+ break;
+ case 'database-table-declaration-field-unsigned':
+ $this->field['unsigned'] .= $data;
+ break;
+ case 'database-table-declaration-field-length':
+ $this->field['length'] .= $data;
+ break;
+ case 'database-table-declaration-field-description':
+ $this->field['description'] .= $data;
+ break;
+ case 'database-table-declaration-field-comments':
+ $this->field['comments'] .= $data;
+ break;
+
+ /* Index declaration */
+ case 'database-table-declaration-index-name':
+ $this->index_name .= $data;
+ break;
+ case 'database-table-declaration-index-was':
+ $this->index['was'] .= $data;
+ break;
+ case 'database-table-declaration-index-unique':
+ $this->index['unique'] .= $data;
+ break;
+ case 'database-table-declaration-index-primary':
+ $this->index['primary'] .= $data;
+ break;
+ case 'database-table-declaration-index-field-name':
+ $this->field_name .= $data;
+ break;
+ case 'database-table-declaration-index-field-sorting':
+ $this->field['sorting'] .= $data;
+ break;
+ /* Add by Leoncx */
+ case 'database-table-declaration-index-field-length':
+ $this->field['length'] .= $data;
+ break;
+
+ /* Foreign Key declaration */
+ case 'database-table-declaration-foreign-name':
+ $this->constraint_name .= $data;
+ break;
+ case 'database-table-declaration-foreign-was':
+ $this->constraint['was'] .= $data;
+ break;
+ case 'database-table-declaration-foreign-match':
+ $this->constraint['match'] .= $data;
+ break;
+ case 'database-table-declaration-foreign-ondelete':
+ $this->constraint['ondelete'] .= $data;
+ break;
+ case 'database-table-declaration-foreign-onupdate':
+ $this->constraint['onupdate'] .= $data;
+ break;
+ case 'database-table-declaration-foreign-deferrable':
+ $this->constraint['deferrable'] .= $data;
+ break;
+ case 'database-table-declaration-foreign-initiallydeferred':
+ $this->constraint['initiallydeferred'] .= $data;
+ break;
+ case 'database-table-declaration-foreign-field':
+ $this->field_name .= $data;
+ break;
+ case 'database-table-declaration-foreign-references-table':
+ $this->constraint['references']['table'] .= $data;
+ break;
+ case 'database-table-declaration-foreign-references-field':
+ $this->field_name .= $data;
+ break;
+
+ /* Sequence declaration */
+ case 'database-sequence-name':
+ $this->sequence_name .= $data;
+ break;
+ case 'database-sequence-was':
+ $this->sequence['was'] .= $data;
+ break;
+ case 'database-sequence-start':
+ $this->sequence['start'] .= $data;
+ break;
+ case 'database-sequence-description':
+ $this->sequence['description'] .= $data;
+ break;
+ case 'database-sequence-comments':
+ $this->sequence['comments'] .= $data;
+ break;
+ case 'database-sequence-on-table':
+ $this->sequence['on']['table'] .= $data;
+ break;
+ case 'database-sequence-on-field':
+ $this->sequence['on']['field'] .= $data;
+ break;
+ }
+ }
+}
+
+?>
diff --git a/3rdparty/MDB2/Schema/Parser2.php b/3rdparty/MDB2/Schema/Parser2.php
new file mode 100644
index 00000000000..01318473fdd
--- /dev/null
+++ b/3rdparty/MDB2/Schema/Parser2.php
@@ -0,0 +1,624 @@
+<?php
+/**
+ * PHP versions 4 and 5
+ *
+ * Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox,
+ * Stig. S. Bakken, Lukas Smith, Igor Feghali
+ * All rights reserved.
+ *
+ * MDB2_Schema enables users to maintain RDBMS independant schema files
+ * in XML that can be used to manipulate both data and database schemas
+ * 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, Igor Feghali 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: Igor Feghali <ifeghali@php.net>
+ *
+ * @category Database
+ * @package MDB2_Schema
+ * @author Igor Feghali <ifeghali@php.net>
+ * @license BSD http://www.opensource.org/licenses/bsd-license.php
+ * @version CVS: $Id: Parser2.php,v 1.12 2008/11/30 03:34:00 clockwerx Exp $
+ * @link http://pear.php.net/packages/MDB2_Schema
+ */
+
+require_once 'XML/Unserializer.php';
+require_once 'MDB2/Schema/Validate.php';
+
+/**
+ * Parses an XML schema file
+ *
+ * @category Database
+ * @package MDB2_Schema
+ * @author Lukas Smith <smith@pooteeweet.org>
+ * @author Igor Feghali <ifeghali@php.net>
+ * @license BSD http://www.opensource.org/licenses/bsd-license.php
+ * @link http://pear.php.net/packages/MDB2_Schema
+ */
+class MDB2_Schema_Parser2 extends XML_Unserializer
+{
+ var $database_definition = array();
+
+ var $database_loaded = array();
+
+ var $variables = array();
+
+ var $error;
+
+ var $structure = false;
+
+ var $val;
+
+ var $options = array();
+
+ var $table = array();
+
+ var $table_name = '';
+
+ var $field = array();
+
+ var $field_name = '';
+
+ var $index = array();
+
+ var $index_name = '';
+
+ var $constraint = array();
+
+ var $constraint_name = '';
+
+ var $sequence = array();
+
+ var $sequence_name = '';
+
+ var $init = array();
+
+ function __construct($variables, $fail_on_invalid_names = true, $structure = false, $valid_types = array(), $force_defaults = true)
+ {
+ // force ISO-8859-1 due to different defaults for PHP4 and PHP5
+ // todo: this probably needs to be investigated some more and cleaned up
+ $this->options['encoding'] = 'ISO-8859-1';
+
+ $this->options['XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE'] = true;
+ $this->options['XML_UNSERIALIZER_OPTION_ATTRIBUTES_ARRAYKEY'] = false;
+
+ $this->options['forceEnum'] = array('table', 'field', 'index', 'foreign', 'insert', 'update', 'delete', 'sequence');
+
+ /*
+ * todo: find a way to force the following items not to be parsed as arrays
+ * as it cause problems in functions with multiple arguments
+ */
+ //$this->options['forceNEnum'] = array('value', 'column');
+ $this->variables = $variables;
+ $this->structure = $structure;
+
+ $this->val =& new MDB2_Schema_Validate($fail_on_invalid_names, $valid_types, $force_defaults);
+ parent::XML_Unserializer($this->options);
+ }
+
+ function MDB2_Schema_Parser2($variables, $fail_on_invalid_names = true, $structure = false, $valid_types = array(), $force_defaults = true)
+ {
+ $this->__construct($variables, $fail_on_invalid_names, $structure, $valid_types, $force_defaults);
+ }
+
+ function parse()
+ {
+ $result = $this->unserialize($this->filename, true);
+
+ if (PEAR::isError($result)) {
+ return $result;
+ } else {
+ $this->database_loaded = $this->getUnserializedData();
+ return $this->fixDatabaseKeys($this->database_loaded);
+ }
+ }
+
+ function setInputFile($filename)
+ {
+ $this->filename = $filename;
+ return MDB2_OK;
+ }
+
+ function renameKey(&$arr, $oKey, $nKey)
+ {
+ $arr[$nKey] = &$arr[$oKey];
+ unset($arr[$oKey]);
+ }
+
+ function fixDatabaseKeys($database)
+ {
+ $this->database_definition = array(
+ 'name' => '',
+ 'create' => '',
+ 'overwrite' => '',
+ 'charset' => '',
+ 'description' => '',
+ 'comments' => '',
+ 'tables' => array(),
+ 'sequences' => array()
+ );
+
+ if (!empty($database['name'])) {
+ $this->database_definition['name'] = $database['name'];
+ }
+ if (!empty($database['create'])) {
+ $this->database_definition['create'] = $database['create'];
+ }
+ if (!empty($database['overwrite'])) {
+ $this->database_definition['overwrite'] = $database['overwrite'];
+ }
+ if (!empty($database['charset'])) {
+ $this->database_definition['charset'] = $database['charset'];
+ }
+ if (!empty($database['description'])) {
+ $this->database_definition['description'] = $database['description'];
+ }
+ if (!empty($database['comments'])) {
+ $this->database_definition['comments'] = $database['comments'];
+ }
+
+ if (!empty($database['table']) && is_array($database['table'])) {
+ foreach ($database['table'] as $table) {
+ $this->fixTableKeys($table);
+ }
+ }
+
+ if (!empty($database['sequence']) && is_array($database['sequence'])) {
+ foreach ($database['sequence'] as $sequence) {
+ $this->fixSequenceKeys($sequence);
+ }
+ }
+
+ $result = $this->val->validateDatabase($this->database_definition);
+ if (PEAR::isError($result)) {
+ return $this->raiseError($result->getUserinfo());
+ }
+
+ return MDB2_OK;
+ }
+
+ function fixTableKeys($table)
+ {
+ $this->table = array(
+ 'was' => '',
+ 'description' => '',
+ 'comments' => '',
+ 'fields' => array(),
+ 'indexes' => array(),
+ 'constraints' => array(),
+ 'initialization' => array()
+ );
+
+ if (!empty($table['name'])) {
+ $this->table_name = $table['name'];
+ } else {
+ $this->table_name = '';
+ }
+ if (!empty($table['was'])) {
+ $this->table['was'] = $table['was'];
+ }
+ if (!empty($table['description'])) {
+ $this->table['description'] = $table['description'];
+ }
+ if (!empty($table['comments'])) {
+ $this->table['comments'] = $table['comments'];
+ }
+
+ if (!empty($table['declaration']) && is_array($table['declaration'])) {
+ if (!empty($table['declaration']['field']) && is_array($table['declaration']['field'])) {
+ foreach ($table['declaration']['field'] as $field) {
+ $this->fixTableFieldKeys($field);
+ }
+ }
+
+ if (!empty($table['declaration']['index']) && is_array($table['declaration']['index'])) {
+ foreach ($table['declaration']['index'] as $index) {
+ $this->fixTableIndexKeys($index);
+ }
+ }
+
+ if (!empty($table['declaration']['foreign']) && is_array($table['declaration']['foreign'])) {
+ foreach ($table['declaration']['foreign'] as $constraint) {
+ $this->fixTableConstraintKeys($constraint);
+ }
+ }
+ }
+
+ if (!empty($table['initialization']) && is_array($table['initialization'])) {
+ if (!empty($table['initialization']['insert']) && is_array($table['initialization']['insert'])) {
+ foreach ($table['initialization']['insert'] as $init) {
+ $this->fixTableInitializationKeys($init, 'insert');
+ }
+ }
+ if (!empty($table['initialization']['update']) && is_array($table['initialization']['update'])) {
+ foreach ($table['initialization']['update'] as $init) {
+ $this->fixTableInitializationKeys($init, 'update');
+ }
+ }
+ if (!empty($table['initialization']['delete']) && is_array($table['initialization']['delete'])) {
+ foreach ($table['initialization']['delete'] as $init) {
+ $this->fixTableInitializationKeys($init, 'delete');
+ }
+ }
+ }
+
+ $result = $this->val->validateTable($this->database_definition['tables'], $this->table, $this->table_name);
+ if (PEAR::isError($result)) {
+ return $this->raiseError($result->getUserinfo());
+ } else {
+ $this->database_definition['tables'][$this->table_name] = $this->table;
+ }
+
+ return MDB2_OK;
+ }
+
+ function fixTableFieldKeys($field)
+ {
+ $this->field = array();
+ if (!empty($field['name'])) {
+ $this->field_name = $field['name'];
+ } else {
+ $this->field_name = '';
+ }
+ if (!empty($field['was'])) {
+ $this->field['was'] = $field['was'];
+ }
+ if (!empty($field['type'])) {
+ $this->field['type'] = $field['type'];
+ }
+ if (!empty($field['fixed'])) {
+ $this->field['fixed'] = $field['fixed'];
+ }
+ if (isset($field['default'])) {
+ $this->field['default'] = $field['default'];
+ }
+ if (!empty($field['notnull'])) {
+ $this->field['notnull'] = $field['notnull'];
+ }
+ if (!empty($field['autoincrement'])) {
+ $this->field['autoincrement'] = $field['autoincrement'];
+ }
+ if (!empty($field['unsigned'])) {
+ $this->field['unsigned'] = $field['unsigned'];
+ }
+ if (!empty($field['length'])) {
+ $this->field['length'] = $field['length'];
+ }
+ if (!empty($field['description'])) {
+ $this->field['description'] = $field['description'];
+ }
+ if (!empty($field['comments'])) {
+ $this->field['comments'] = $field['comments'];
+ }
+
+ $result = $this->val->validateField($this->table['fields'], $this->field, $this->field_name);
+ if (PEAR::isError($result)) {
+ return $this->raiseError($result->getUserinfo());
+ } else {
+ $this->table['fields'][$this->field_name] = $this->field;
+ }
+
+ return MDB2_OK;
+ }
+
+ function fixTableIndexKeys($index)
+ {
+ $this->index = array(
+ 'was' => '',
+ 'unique' =>'',
+ 'primary' => '',
+ 'fields' => array()
+ );
+
+ if (!empty($index['name'])) {
+ $this->index_name = $index['name'];
+ } else {
+ $this->index_name = '';
+ }
+ if (!empty($index['was'])) {
+ $this->index['was'] = $index['was'];
+ }
+ if (!empty($index['unique'])) {
+ $this->index['unique'] = $index['unique'];
+ }
+ if (!empty($index['primary'])) {
+ $this->index['primary'] = $index['primary'];
+ }
+ if (!empty($index['field'])) {
+ foreach ($index['field'] as $field) {
+ if (!empty($field['name'])) {
+ $this->field_name = $field['name'];
+ } else {
+ $this->field_name = '';
+ }
+ $this->field = array(
+ 'sorting' => '',
+ 'length' => ''
+ );
+
+ if (!empty($field['sorting'])) {
+ $this->field['sorting'] = $field['sorting'];
+ }
+ if (!empty($field['length'])) {
+ $this->field['length'] = $field['length'];
+ }
+
+ $result = $this->val->validateIndexField($this->index['fields'], $this->field, $this->field_name);
+ if (PEAR::isError($result)) {
+ return $this->raiseError($result->getUserinfo());
+ }
+
+ $this->index['fields'][$this->field_name] = $this->field;
+ }
+ }
+
+ $result = $this->val->validateIndex($this->table['indexes'], $this->index, $this->index_name);
+ if (PEAR::isError($result)) {
+ return $this->raiseError($result->getUserinfo());
+ } else {
+ $this->table['indexes'][$this->index_name] = $this->index;
+ }
+
+ return MDB2_OK;
+ }
+
+ function fixTableConstraintKeys($constraint)
+ {
+ $this->constraint = array(
+ 'was' => '',
+ 'match' => '',
+ 'ondelete' => '',
+ 'onupdate' => '',
+ 'deferrable' => '',
+ 'initiallydeferred' => '',
+ 'foreign' => true,
+ 'fields' => array(),
+ 'references' => array('table' => '', 'fields' => array())
+ );
+
+ if (!empty($constraint['name'])) {
+ $this->constraint_name = $constraint['name'];
+ } else {
+ $this->constraint_name = '';
+ }
+ if (!empty($constraint['was'])) {
+ $this->constraint['was'] = $constraint['was'];
+ }
+ if (!empty($constraint['match'])) {
+ $this->constraint['match'] = $constraint['match'];
+ }
+ if (!empty($constraint['ondelete'])) {
+ $this->constraint['ondelete'] = $constraint['ondelete'];
+ }
+ if (!empty($constraint['onupdate'])) {
+ $this->constraint['onupdate'] = $constraint['onupdate'];
+ }
+ if (!empty($constraint['deferrable'])) {
+ $this->constraint['deferrable'] = $constraint['deferrable'];
+ }
+ if (!empty($constraint['initiallydeferred'])) {
+ $this->constraint['initiallydeferred'] = $constraint['initiallydeferred'];
+ }
+ if (!empty($constraint['field']) && is_array($constraint['field'])) {
+ foreach ($constraint['field'] as $field) {
+ $result = $this->val->validateConstraintField($this->constraint['fields'], $field);
+ if (PEAR::isError($result)) {
+ return $this->raiseError($result->getUserinfo());
+ }
+
+ $this->constraint['fields'][$field] = '';
+ }
+ }
+
+ if (!empty($constraint['references']) && is_array($constraint['references'])) {
+ /**
+ * As we forced 'table' to be enumerated
+ * we have to fix it on the foreign-references-table context
+ */
+ if (!empty($constraint['references']['table']) && is_array($constraint['references']['table'])) {
+ $this->constraint['references']['table'] = $constraint['references']['table'][0];
+ }
+
+ if (!empty($constraint['references']['field']) && is_array($constraint['references']['field'])) {
+ foreach ($constraint['references']['field'] as $field) {
+ $result = $this->val->validateConstraintReferencedField($this->constraint['references']['fields'], $field);
+ if (PEAR::isError($result)) {
+ return $this->raiseError($result->getUserinfo());
+ }
+
+ $this->constraint['references']['fields'][$field] = '';
+ }
+ }
+ }
+
+ $result = $this->val->validateConstraint($this->table['constraints'], $this->constraint, $this->constraint_name);
+ if (PEAR::isError($result)) {
+ return $this->raiseError($result->getUserinfo());
+ } else {
+ $this->table['constraints'][$this->constraint_name] = $this->constraint;
+ }
+
+ return MDB2_OK;
+ }
+
+ function fixTableInitializationKeys($element, $type = '')
+ {
+ if (!empty($element['select']) && is_array($element['select'])) {
+ $this->fixTableInitializationDataKeys($element['select']);
+ $this->init = array( 'select' => $this->init );
+ } else {
+ $this->fixTableInitializationDataKeys($element);
+ }
+
+ $this->table['initialization'][] = array( 'type' => $type, 'data' => $this->init );
+ }
+
+ function fixTableInitializationDataKeys($element)
+ {
+ $this->init = array();
+ if (!empty($element['field']) && is_array($element['field'])) {
+ foreach ($element['field'] as $field) {
+ $name = $field['name'];
+ unset($field['name']);
+
+ $this->setExpression($field);
+ $this->init['field'][] = array( 'name' => $name, 'group' => $field );
+ }
+ }
+ /**
+ * As we forced 'table' to be enumerated
+ * we have to fix it on the insert-select context
+ */
+ if (!empty($element['table']) && is_array($element['table'])) {
+ $this->init['table'] = $element['table'][0];
+ }
+ if (!empty($element['where']) && is_array($element['where'])) {
+ $this->init['where'] = $element['where'];
+ $this->setExpression($this->init['where']);
+ }
+ }
+
+ function setExpression(&$arr)
+ {
+ $element = each($arr);
+
+ $arr = array( 'type' => $element['key'] );
+
+ $element = $element['value'];
+
+ switch ($arr['type']) {
+ case 'null':
+ break;
+ case 'value':
+ case 'column':
+ $arr['data'] = $element;
+ break;
+ case 'function':
+ if (!empty($element)
+ && is_array($element)
+ ) {
+ $arr['data'] = array( 'name' => $element['name'] );
+ unset($element['name']);
+
+ foreach ($element as $type => $value) {
+ if (!empty($value)) {
+ if (is_array($value)) {
+ foreach ($value as $argument) {
+ $argument = array( $type => $argument );
+ $this->setExpression($argument);
+ $arr['data']['arguments'][] = $argument;
+ }
+ } else {
+ $arr['data']['arguments'][] = array( 'type' => $type, 'data' => $value );
+ }
+ }
+ }
+ }
+ break;
+ case 'expression':
+ $arr['data'] = array( 'operants' => array(), 'operator' => $element['operator'] );
+ unset($element['operator']);
+
+ foreach ($element as $k => $v) {
+ $argument = array( $k => $v );
+ $this->setExpression($argument);
+ $arr['data']['operants'][] = $argument;
+ }
+ break;
+ }
+ }
+
+ function fixSequenceKeys($sequence)
+ {
+ $this->sequence = array(
+ 'was' => '',
+ 'start' => '',
+ 'description' => '',
+ 'comments' => '',
+ 'on' => array('table' => '', 'field' => '')
+ );
+
+ if (!empty($sequence['name'])) {
+ $this->sequence_name = $sequence['name'];
+ } else {
+ $this->sequence_name = '';
+ }
+ if (!empty($sequence['was'])) {
+ $this->sequence['was'] = $sequence['was'];
+ }
+ if (!empty($sequence['start'])) {
+ $this->sequence['start'] = $sequence['start'];
+ }
+ if (!empty($sequence['description'])) {
+ $this->sequence['description'] = $sequence['description'];
+ }
+ if (!empty($sequence['comments'])) {
+ $this->sequence['comments'] = $sequence['comments'];
+ }
+ if (!empty($sequence['on']) && is_array($sequence['on'])) {
+ /**
+ * As we forced 'table' to be enumerated
+ * we have to fix it on the sequence-on-table context
+ */
+ if (!empty($sequence['on']['table']) && is_array($sequence['on']['table'])) {
+ $this->sequence['on']['table'] = $sequence['on']['table'][0];
+ }
+
+ /**
+ * As we forced 'field' to be enumerated
+ * we have to fix it on the sequence-on-field context
+ */
+ if (!empty($sequence['on']['field']) && is_array($sequence['on']['field'])) {
+ $this->sequence['on']['field'] = $sequence['on']['field'][0];
+ }
+ }
+
+ $result = $this->val->validateSequence($this->database_definition['sequences'], $this->sequence, $this->sequence_name);
+ if (PEAR::isError($result)) {
+ return $this->raiseError($result->getUserinfo());
+ } else {
+ $this->database_definition['sequences'][$this->sequence_name] = $this->sequence;
+ }
+
+ return MDB2_OK;
+ }
+
+ function &raiseError($msg = null, $ecode = MDB2_SCHEMA_ERROR_PARSE)
+ {
+ if (is_null($this->error)) {
+ $error = 'Parser error: '.$msg."\n";
+
+ $this->error =& MDB2_Schema::raiseError($ecode, null, null, $error);
+ }
+ return $this->error;
+ }
+}
+
+?>
diff --git a/3rdparty/MDB2/Schema/Reserved/ibase.php b/3rdparty/MDB2/Schema/Reserved/ibase.php
new file mode 100644
index 00000000000..b208abc83a3
--- /dev/null
+++ b/3rdparty/MDB2/Schema/Reserved/ibase.php
@@ -0,0 +1,436 @@
+<?php
+// {{{ Disclaimer, Licence, copyrights
+// +----------------------------------------------------------------------+
+// | PHP versions 4 and 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
+// | Stig. S. Bakken, Lukas Smith |
+// | All rights reserved. |
+// +----------------------------------------------------------------------+
+// | MDB2 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: Lorenzo Alberton <l.alberton@quipo.it> |
+// +----------------------------------------------------------------------+
+//
+// }}}
+// {{{ $GLOBALS['_MDB2_Schema_Reserved']['ibase']
+/**
+ * Has a list of reserved words of Interbase/Firebird
+ *
+ * @package MDB2_Schema
+ * @category Database
+ * @access protected
+ * @author Lorenzo Alberton <l.alberton@quipo.it>
+ */
+$GLOBALS['_MDB2_Schema_Reserved']['ibase'] = array(
+ 'ABS',
+ 'ABSOLUTE',
+ 'ACTION',
+ 'ACTIVE',
+ 'ADD',
+ 'ADMIN',
+ 'AFTER',
+ 'ALL',
+ 'ALLOCATE',
+ 'ALTER',
+ 'AND',
+ 'ANY',
+ 'ARE',
+ 'AS',
+ 'ASC',
+ 'ASCENDING',
+ 'ASSERTION',
+ 'AT',
+ 'AUTHORIZATION',
+ 'AUTO',
+ 'AUTODDL',
+ 'AVG',
+ 'BACKUP',
+ 'BASE_NAME',
+ 'BASED',
+ 'BASENAME',
+ 'BEFORE',
+ 'BEGIN',
+ 'BETWEEN',
+ 'BIGINT',
+ 'BIT',
+ 'BIT_LENGTH',
+ 'BLOB',
+ 'BLOCK',
+ 'BLOBEDIT',
+ 'BOOLEAN',
+ 'BOTH',
+ 'BOTH',
+ 'BREAK',
+ 'BUFFER',
+ 'BY',
+ 'CACHE',
+ 'CASCADE',
+ 'CASCADED',
+ 'CASE',
+ 'CASE',
+ 'CAST',
+ 'CATALOG',
+ 'CHAR',
+ 'CHAR_LENGTH',
+ 'CHARACTER',
+ 'CHARACTER_LENGTH',
+ 'CHECK',
+ 'CHECK_POINT_LEN',
+ 'CHECK_POINT_LENGTH',
+ 'CLOSE',
+ 'COALESCE',
+ 'COLLATE',
+ 'COLLATION',
+ 'COLUMN',
+ 'COMMENT',
+ 'COMMIT',
+ 'COMMITTED',
+ 'COMPILETIME',
+ 'COMPUTED',
+ 'CONDITIONAL',
+ 'CONNECT',
+ 'CONNECTION',
+ 'CONSTRAINT',
+ 'CONSTRAINTS',
+ 'CONTAINING',
+ 'CONTINUE',
+ 'CONVERT',
+ 'CORRESPONDING',
+ 'COUNT',
+ 'CREATE',
+ 'CROSS',
+ 'CSTRING',
+ 'CURRENT',
+ 'CURRENT_CONNECTION',
+ 'CURRENT_DATE',
+ 'CURRENT_ROLE',
+ 'CURRENT_TIME',
+ 'CURRENT_TIMESTAMP',
+ 'CURRENT_TRANSACTION',
+ 'CURRENT_USER',
+ 'DATABASE',
+ 'DATE',
+ 'DAY',
+ 'DB_KEY',
+ 'DEALLOCATE',
+ 'DEBUG',
+ 'DEC',
+ 'DECIMAL',
+ 'DECLARE',
+ 'DEFAULT',
+ 'DEFERRABLE',
+ 'DEFERRED',
+ 'DELETE',
+ 'DELETING',
+ 'DESC',
+ 'DESCENDING',
+ 'DESCRIBE',
+ 'DESCRIPTOR',
+ 'DIAGNOSTICS',
+ 'DIFFERENCE',
+ 'DISCONNECT',
+ 'DISPLAY',
+ 'DISTINCT',
+ 'DO',
+ 'DOMAIN',
+ 'DOUBLE',
+ 'DROP',
+ 'ECHO',
+ 'EDIT',
+ 'ELSE',
+ 'END',
+ 'END-EXEC',
+ 'ENTRY_POINT',
+ 'ESCAPE',
+ 'EVENT',
+ 'EXCEPT',
+ 'EXCEPTION',
+ 'EXEC',
+ 'EXECUTE',
+ 'EXISTS',
+ 'EXIT',
+ 'EXTERN',
+ 'EXTERNAL',
+ 'EXTRACT',
+ 'FALSE',
+ 'FETCH',
+ 'FILE',
+ 'FILTER',
+ 'FIRST',
+ 'FLOAT',
+ 'FOR',
+ 'FOREIGN',
+ 'FOUND',
+ 'FREE_IT',
+ 'FROM',
+ 'FULL',
+ 'FUNCTION',
+ 'GDSCODE',
+ 'GEN_ID',
+ 'GENERATOR',
+ 'GET',
+ 'GLOBAL',
+ 'GO',
+ 'GOTO',
+ 'GRANT',
+ 'GROUP',
+ 'GROUP_COMMIT_WAIT',
+ 'GROUP_COMMIT_WAIT_TIME',
+ 'HAVING',
+ 'HELP',
+ 'HOUR',
+ 'IDENTITY',
+ 'IF',
+ 'IIF',
+ 'IMMEDIATE',
+ 'IN',
+ 'INACTIVE',
+ 'INDEX',
+ 'INDICATOR',
+ 'INIT',
+ 'INITIALLY',
+ 'INNER',
+ 'INPUT',
+ 'INPUT_TYPE',
+ 'INSENSITIVE',
+ 'INSERT',
+ 'INSERTING',
+ 'INT',
+ 'INTEGER',
+ 'INTERSECT',
+ 'INTERVAL',
+ 'INTO',
+ 'IS',
+ 'ISOLATION',
+ 'ISQL',
+ 'JOIN',
+ 'KEY',
+ 'LANGUAGE',
+ 'LAST',
+ 'LC_MESSAGES',
+ 'LC_TYPE',
+ 'LEADING',
+ 'LEADING',
+ 'LEADING',
+ 'LEAVE',
+ 'LEFT',
+ 'LENGTH',
+ 'LEV',
+ 'LEVEL',
+ 'LIKE',
+ 'LOCAL',
+ 'LOCK',
+ 'LOG_BUF_SIZE',
+ 'LOG_BUFFER_SIZE',
+ 'LOGFILE',
+ 'LONG',
+ 'LOWER',
+ 'MANUAL',
+ 'MATCH',
+ 'MAX',
+ 'MAX_SEGMENT',
+ 'MAXIMUM',
+ 'MAXIMUM_SEGMENT',
+ 'MERGE',
+ 'MESSAGE',
+ 'MIN',
+ 'MINIMUM',
+ 'MINUTE',
+ 'MODULE',
+ 'MODULE_NAME',
+ 'MONTH',
+ 'NAMES',
+ 'NATIONAL',
+ 'NATURAL',
+ 'NCHAR',
+ 'NEXT',
+ 'NO',
+ 'NOAUTO',
+ 'NOT',
+ 'NULL',
+ 'NULLIF',
+ 'NULLS',
+ 'NUM_LOG_BUFFERS',
+ 'NUM_LOG_BUFS',
+ 'NUMERIC',
+ 'OCTET_LENGTH',
+ 'OF',
+ 'ON',
+ 'ONLY',
+ 'OPEN',
+ 'OPTION',
+ 'OR',
+ 'ORDER',
+ 'OUTER',
+ 'OUTPUT',
+ 'OUTPUT_TYPE',
+ 'OVERFLOW',
+ 'OVERLAPS',
+ 'PAD',
+ 'PAGE',
+ 'PAGE_SIZE',
+ 'PAGELENGTH',
+ 'PAGES',
+ 'PARAMETER',
+ 'PARTIAL',
+ 'PASSWORD',
+ 'PERCENT',
+ 'PLAN',
+ 'POSITION',
+ 'POST_EVENT',
+ 'PRECISION',
+ 'PREPARE',
+ 'PRESERVE',
+ 'PRIMARY',
+ 'PRIOR',
+ 'PRIVILEGES',
+ 'PROCEDURE',
+ 'PUBLIC',
+ 'QUIT',
+ 'RAW_PARTITIONS',
+ 'RDB$DB_KEY',
+ 'READ',
+ 'REAL',
+ 'RECORD_VERSION',
+ 'RECREATE',
+ 'RECREATE ROW_COUNT',
+ 'REFERENCES',
+ 'RELATIVE',
+ 'RELEASE',
+ 'RESERV',
+ 'RESERVING',
+ 'RESTART',
+ 'RESTRICT',
+ 'RETAIN',
+ 'RETURN',
+ 'RETURNING',
+ 'RETURNING_VALUES',
+ 'RETURNS',
+ 'REVOKE',
+ 'RIGHT',
+ 'ROLE',
+ 'ROLLBACK',
+ 'ROW_COUNT',
+ 'ROWS',
+ 'RUNTIME',
+ 'SAVEPOINT',
+ 'SCALAR_ARRAY',
+ 'SCHEMA',
+ 'SCROLL',
+ 'SECOND',
+ 'SECTION',
+ 'SELECT',
+ 'SEQUENCE',
+ 'SESSION',
+ 'SESSION_USER',
+ 'SET',
+ 'SHADOW',
+ 'SHARED',
+ 'SHELL',
+ 'SHOW',
+ 'SINGULAR',
+ 'SIZE',
+ 'SKIP',
+ 'SMALLINT',
+ 'SNAPSHOT',
+ 'SOME',
+ 'SORT',
+ 'SPACE',
+ 'SQL',
+ 'SQLCODE',
+ 'SQLERROR',
+ 'SQLSTATE',
+ 'SQLWARNING',
+ 'STABILITY',
+ 'STARTING',
+ 'STARTS',
+ 'STATEMENT',
+ 'STATIC',
+ 'STATISTICS',
+ 'SUB_TYPE',
+ 'SUBSTRING',
+ 'SUM',
+ 'SUSPEND',
+ 'SYSTEM_USER',
+ 'TABLE',
+ 'TEMPORARY',
+ 'TERMINATOR',
+ 'THEN',
+ 'TIES',
+ 'TIME',
+ 'TIMESTAMP',
+ 'TIMEZONE_HOUR',
+ 'TIMEZONE_MINUTE',
+ 'TO',
+ 'TRAILING',
+ 'TRANSACTION',
+ 'TRANSLATE',
+ 'TRANSLATION',
+ 'TRIGGER',
+ 'TRIM',
+ 'TRUE',
+ 'TYPE',
+ 'UNCOMMITTED',
+ 'UNION',
+ 'UNIQUE',
+ 'UNKNOWN',
+ 'UPDATE',
+ 'UPDATING',
+ 'UPPER',
+ 'USAGE',
+ 'USER',
+ 'USING',
+ 'VALUE',
+ 'VALUES',
+ 'VARCHAR',
+ 'VARIABLE',
+ 'VARYING',
+ 'VERSION',
+ 'VIEW',
+ 'WAIT',
+ 'WEEKDAY',
+ 'WHEN',
+ 'WHENEVER',
+ 'WHERE',
+ 'WHILE',
+ 'WITH',
+ 'WORK',
+ 'WRITE',
+ 'YEAR',
+ 'YEARDAY',
+ 'ZONE',
+);
+// }}}
+?> \ No newline at end of file
diff --git a/3rdparty/MDB2/Schema/Reserved/mssql.php b/3rdparty/MDB2/Schema/Reserved/mssql.php
new file mode 100644
index 00000000000..74ac6885780
--- /dev/null
+++ b/3rdparty/MDB2/Schema/Reserved/mssql.php
@@ -0,0 +1,258 @@
+<?php
+// {{{ Disclaimer, Licence, copyrights
+// +----------------------------------------------------------------------+
+// | PHP versions 4 and 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
+// | Stig. S. Bakken, Lukas Smith |
+// | All rights reserved. |
+// +----------------------------------------------------------------------+
+// | MDB2 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: David Coallier <davidc@php.net> |
+// +----------------------------------------------------------------------+
+// }}}
+// {{{ $GLOBALS['_MDB2_Schema_Reserved']['mssql']
+/**
+ * Has a list of all the reserved words for mssql.
+ *
+ * @package MDB2_Schema
+ * @category Database
+ * @access protected
+ * @author David Coallier <davidc@php.net>
+ */
+$GLOBALS['_MDB2_Schema_Reserved']['mssql'] = array(
+ 'ADD',
+ 'CURRENT_TIMESTAMP',
+ 'GROUP',
+ 'OPENQUERY',
+ 'SERIALIZABLE',
+ 'ALL',
+ 'CURRENT_USER',
+ 'HAVING',
+ 'OPENROWSET',
+ 'SESSION_USER',
+ 'ALTER',
+ 'CURSOR',
+ 'HOLDLOCK',
+ 'OPTION',
+ 'SET',
+ 'AND',
+ 'DATABASE',
+ 'IDENTITY',
+ 'OR',
+ 'SETUSER',
+ 'ANY',
+ 'DBCC',
+ 'IDENTITYCOL',
+ 'ORDER',
+ 'SHUTDOWN',
+ 'AS',
+ 'DEALLOCATE',
+ 'IDENTITY_INSERT',
+ 'OUTER',
+ 'SOME',
+ 'ASC',
+ 'DECLARE',
+ 'IF',
+ 'OVER',
+ 'STATISTICS',
+ 'AUTHORIZATION',
+ 'DEFAULT',
+ 'IN',
+ 'PERCENT',
+ 'SUM',
+ 'AVG',
+ 'DELETE',
+ 'INDEX',
+ 'PERM',
+ 'SYSTEM_USER',
+ 'BACKUP',
+ 'DENY',
+ 'INNER',
+ 'PERMANENT',
+ 'TABLE',
+ 'BEGIN',
+ 'DESC',
+ 'INSERT',
+ 'PIPE',
+ 'TAPE',
+ 'BETWEEN',
+ 'DISK',
+ 'INTERSECT',
+ 'PLAN',
+ 'TEMP',
+ 'BREAK',
+ 'DISTINCT',
+ 'INTO',
+ 'PRECISION',
+ 'TEMPORARY',
+ 'BROWSE',
+ 'DISTRIBUTED',
+ 'IS',
+ 'PREPARE',
+ 'TEXTSIZE',
+ 'BULK',
+ 'DOUBLE',
+ 'ISOLATION',
+ 'PRIMARY',
+ 'THEN',
+ 'BY',
+ 'DROP',
+ 'JOIN',
+ 'PRINT',
+ 'TO',
+ 'CASCADE',
+ 'DUMMY',
+ 'KEY',
+ 'PRIVILEGES',
+ 'TOP',
+ 'CASE',
+ 'DUMP',
+ 'KILL',
+ 'PROC',
+ 'TRAN',
+ 'CHECK',
+ 'ELSE',
+ 'LEFT',
+ 'PROCEDURE',
+ 'TRANSACTION',
+ 'CHECKPOINT',
+ 'END',
+ 'LEVEL',
+ 'PROCESSEXIT',
+ 'TRIGGER',
+ 'CLOSE',
+ 'ERRLVL',
+ 'LIKE',
+ 'PUBLIC',
+ 'TRUNCATE',
+ 'CLUSTERED',
+ 'ERROREXIT',
+ 'LINENO',
+ 'RAISERROR',
+ 'TSEQUAL',
+ 'COALESCE',
+ 'ESCAPE',
+ 'LOAD',
+ 'READ',
+ 'UNCOMMITTED',
+ 'COLUMN',
+ 'EXCEPT',
+ 'MAX',
+ 'READTEXT',
+ 'UNION',
+ 'COMMIT',
+ 'EXEC',
+ 'MIN',
+ 'RECONFIGURE',
+ 'UNIQUE',
+ 'COMMITTED',
+ 'EXECUTE',
+ 'MIRROREXIT',
+ 'REFERENCES',
+ 'UPDATE',
+ 'COMPUTE',
+ 'EXISTS',
+ 'NATIONAL',
+ 'REPEATABLE',
+ 'UPDATETEXT',
+ 'CONFIRM',
+ 'EXIT',
+ 'NOCHECK',
+ 'REPLICATION',
+ 'USE',
+ 'CONSTRAINT',
+ 'FETCH',
+ 'NONCLUSTERED',
+ 'RESTORE',
+ 'USER',
+ 'CONTAINS',
+ 'FILE',
+ 'NOT',
+ 'RESTRICT',
+ 'VALUES',
+ 'CONTAINSTABLE',
+ 'FILLFACTOR',
+ 'NULL',
+ 'RETURN',
+ 'VARYING',
+ 'CONTINUE',
+ 'FLOPPY',
+ 'NULLIF',
+ 'REVOKE',
+ 'VIEW',
+ 'CONTROLROW',
+ 'FOR',
+ 'OF',
+ 'RIGHT',
+ 'WAITFOR',
+ 'CONVERT',
+ 'FOREIGN',
+ 'OFF',
+ 'ROLLBACK',
+ 'WHEN',
+ 'COUNT',
+ 'FREETEXT',
+ 'OFFSETS',
+ 'ROWCOUNT',
+ 'WHERE',
+ 'CREATE',
+ 'FREETEXTTABLE',
+ 'ON',
+ 'ROWGUIDCOL',
+ 'WHILE',
+ 'CROSS',
+ 'FROM',
+ 'ONCE',
+ 'RULE',
+ 'WITH',
+ 'CURRENT',
+ 'FULL',
+ 'ONLY',
+ 'SAVE',
+ 'WORK',
+ 'CURRENT_DATE',
+ 'GOTO',
+ 'OPEN',
+ 'SCHEMA',
+ 'WRITETEXT',
+ 'CURRENT_TIME',
+ 'GRANT',
+ 'OPENDATASOURCE',
+ 'SELECT',
+);
+//}}}
+
+?>
diff --git a/3rdparty/MDB2/Schema/Reserved/mysql.php b/3rdparty/MDB2/Schema/Reserved/mysql.php
new file mode 100644
index 00000000000..4f0575e0bb1
--- /dev/null
+++ b/3rdparty/MDB2/Schema/Reserved/mysql.php
@@ -0,0 +1,284 @@
+<?php
+// {{{ Disclaimer, Licence, copyrights
+// +----------------------------------------------------------------------+
+// | PHP versions 4 and 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
+// | Stig. S. Bakken, Lukas Smith |
+// | All rights reserved. |
+// +----------------------------------------------------------------------+
+// | MDB2 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: David Coallier <davidc@php.net> |
+// +----------------------------------------------------------------------+
+//
+// $Id: mysql.php,v 1.3 2006/03/01 12:16:40 lsmith Exp $
+// }}}
+// {{{ $GLOBALS['_MDB2_Schema_Reserved']['mysql']
+/**
+ * Has a list of reserved words of mysql
+ *
+ * @package MDB2_Schema
+ * @category Database
+ * @access protected
+ * @author David Coalier <davidc@php.net>
+ */
+$GLOBALS['_MDB2_Schema_Reserved']['mysql'] = array(
+ 'ADD',
+ 'ALL',
+ 'ALTER',
+ 'ANALYZE',
+ 'AND',
+ 'AS',
+ 'ASC',
+ 'ASENSITIVE',
+ 'BEFORE',
+ 'BETWEEN',
+ 'BIGINT',
+ 'BINARY',
+ 'BLOB',
+ 'BOTH',
+ 'BY',
+ 'CALL',
+ 'CASCADE',
+ 'CASE',
+ 'CHANGE',
+ 'CHAR',
+ 'CHARACTER',
+ 'CHECK',
+ 'COLLATE',
+ 'COLUMN',
+ 'CONDITION',
+ 'CONNECTION',
+ 'CONSTRAINT',
+ 'CONTINUE',
+ 'CONVERT',
+ 'CREATE',
+ 'CROSS',
+ 'CURRENT_DATE',
+ 'CURRENT_TIME',
+ 'CURRENT_TIMESTAMP',
+ 'CURRENT_USER',
+ 'CURSOR',
+ 'DATABASE',
+ 'DATABASES',
+ 'DAY_HOUR',
+ 'DAY_MICROSECOND',
+ 'DAY_MINUTE',
+ 'DAY_SECOND',
+ 'DEC',
+ 'DECIMAL',
+ 'DECLARE',
+ 'DEFAULT',
+ 'DELAYED',
+ 'DELETE',
+ 'DESC',
+ 'DESCRIBE',
+ 'DETERMINISTIC',
+ 'DISTINCT',
+ 'DISTINCTROW',
+ 'DIV',
+ 'DOUBLE',
+ 'DROP',
+ 'DUAL',
+ 'EACH',
+ 'ELSE',
+ 'ELSEIF',
+ 'ENCLOSED',
+ 'ESCAPED',
+ 'EXISTS',
+ 'EXIT',
+ 'EXPLAIN',
+ 'FALSE',
+ 'FETCH',
+ 'FLOAT',
+ 'FLOAT4',
+ 'FLOAT8',
+ 'FOR',
+ 'FORCE',
+ 'FOREIGN',
+ 'FROM',
+ 'FULLTEXT',
+ 'GOTO',
+ 'GRANT',
+ 'GROUP',
+ 'HAVING',
+ 'HIGH_PRIORITY',
+ 'HOUR_MICROSECOND',
+ 'HOUR_MINUTE',
+ 'HOUR_SECOND',
+ 'IF',
+ 'IGNORE',
+ 'IN',
+ 'INDEX',
+ 'INFILE',
+ 'INNER',
+ 'INOUT',
+ 'INSENSITIVE',
+ 'INSERT',
+ 'INT',
+ 'INT1',
+ 'INT2',
+ 'INT3',
+ 'INT4',
+ 'INT8',
+ 'INTEGER',
+ 'INTERVAL',
+ 'INTO',
+ 'IS',
+ 'ITERATE',
+ 'JOIN',
+ 'KEY',
+ 'KEYS',
+ 'KILL',
+ 'LABEL',
+ 'LEADING',
+ 'LEAVE',
+ 'LEFT',
+ 'LIKE',
+ 'LIMIT',
+ 'LINES',
+ 'LOAD',
+ 'LOCALTIME',
+ 'LOCALTIMESTAMP',
+ 'LOCK',
+ 'LONG',
+ 'LONGBLOB',
+ 'LONGTEXT',
+ 'LOOP',
+ 'LOW_PRIORITY',
+ 'MATCH',
+ 'MEDIUMBLOB',
+ 'MEDIUMINT',
+ 'MEDIUMTEXT',
+ 'MIDDLEINT',
+ 'MINUTE_MICROSECOND',
+ 'MINUTE_SECOND',
+ 'MOD',
+ 'MODIFIES',
+ 'NATURAL',
+ 'NOT',
+ 'NO_WRITE_TO_BINLOG',
+ 'NULL',
+ 'NUMERIC',
+ 'ON',
+ 'OPTIMIZE',
+ 'OPTION',
+ 'OPTIONALLY',
+ 'OR',
+ 'ORDER',
+ 'OUT',
+ 'OUTER',
+ 'OUTFILE',
+ 'PRECISION',
+ 'PRIMARY',
+ 'PROCEDURE',
+ 'PURGE',
+ 'RAID0',
+ 'READ',
+ 'READS',
+ 'REAL',
+ 'REFERENCES',
+ 'REGEXP',
+ 'RELEASE',
+ 'RENAME',
+ 'REPEAT',
+ 'REPLACE',
+ 'REQUIRE',
+ 'RESTRICT',
+ 'RETURN',
+ 'REVOKE',
+ 'RIGHT',
+ 'RLIKE',
+ 'SCHEMA',
+ 'SCHEMAS',
+ 'SECOND_MICROSECOND',
+ 'SELECT',
+ 'SENSITIVE',
+ 'SEPARATOR',
+ 'SET',
+ 'SHOW',
+ 'SMALLINT',
+ 'SONAME',
+ 'SPATIAL',
+ 'SPECIFIC',
+ 'SQL',
+ 'SQLEXCEPTION',
+ 'SQLSTATE',
+ 'SQLWARNING',
+ 'SQL_BIG_RESULT',
+ 'SQL_CALC_FOUND_ROWS',
+ 'SQL_SMALL_RESULT',
+ 'SSL',
+ 'STARTING',
+ 'STRAIGHT_JOIN',
+ 'TABLE',
+ 'TERMINATED',
+ 'THEN',
+ 'TINYBLOB',
+ 'TINYINT',
+ 'TINYTEXT',
+ 'TO',
+ 'TRAILING',
+ 'TRIGGER',
+ 'TRUE',
+ 'UNDO',
+ 'UNION',
+ 'UNIQUE',
+ 'UNLOCK',
+ 'UNSIGNED',
+ 'UPDATE',
+ 'USAGE',
+ 'USE',
+ 'USING',
+ 'UTC_DATE',
+ 'UTC_TIME',
+ 'UTC_TIMESTAMP',
+ 'VALUES',
+ 'VARBINARY',
+ 'VARCHAR',
+ 'VARCHARACTER',
+ 'VARYING',
+ 'WHEN',
+ 'WHERE',
+ 'WHILE',
+ 'WITH',
+ 'WRITE',
+ 'X509',
+ 'XOR',
+ 'YEAR_MONTH',
+ 'ZEROFILL',
+ );
+ // }}}
+?>
diff --git a/3rdparty/MDB2/Schema/Reserved/oci8.php b/3rdparty/MDB2/Schema/Reserved/oci8.php
new file mode 100644
index 00000000000..57fe12ddcab
--- /dev/null
+++ b/3rdparty/MDB2/Schema/Reserved/oci8.php
@@ -0,0 +1,171 @@
+<?php
+// {{{ Disclaimer, Licence, copyrights
+// +----------------------------------------------------------------------+
+// | PHP versions 4 and 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
+// | Stig. S. Bakken, Lukas Smith |
+// | All rights reserved. |
+// +----------------------------------------------------------------------+
+// | MDB2 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: David Coallier <davidc@php.net> |
+// +----------------------------------------------------------------------+
+// }}}
+// {{{ $GLOBALS['_MDB2_Schema_Reserved']['oci8']
+/**
+ * Has a list of all the reserved words for oracle.
+ *
+ * @package MDB2_Schema
+ * @category Database
+ * @access protected
+ * @author David Coallier <davidc@php.net>
+ */
+$GLOBALS['_MDB2_Schema_Reserved']['oci8'] = array(
+ 'ACCESS',
+ 'ELSE',
+ 'MODIFY',
+ 'START',
+ 'ADD',
+ 'EXCLUSIVE',
+ 'NOAUDIT',
+ 'SELECT',
+ 'ALL',
+ 'EXISTS',
+ 'NOCOMPRESS',
+ 'SESSION',
+ 'ALTER',
+ 'FILE',
+ 'NOT',
+ 'SET',
+ 'AND',
+ 'FLOAT',
+ 'NOTFOUND ',
+ 'SHARE',
+ 'ANY',
+ 'FOR',
+ 'NOWAIT',
+ 'SIZE',
+ 'ARRAYLEN',
+ 'FROM',
+ 'NULL',
+ 'SMALLINT',
+ 'AS',
+ 'GRANT',
+ 'NUMBER',
+ 'SQLBUF',
+ 'ASC',
+ 'GROUP',
+ 'OF',
+ 'SUCCESSFUL',
+ 'AUDIT',
+ 'HAVING',
+ 'OFFLINE ',
+ 'SYNONYM',
+ 'BETWEEN',
+ 'IDENTIFIED',
+ 'ON',
+ 'SYSDATE',
+ 'BY',
+ 'IMMEDIATE',
+ 'ONLINE',
+ 'TABLE',
+ 'CHAR',
+ 'IN',
+ 'OPTION',
+ 'THEN',
+ 'CHECK',
+ 'INCREMENT',
+ 'OR',
+ 'TO',
+ 'CLUSTER',
+ 'INDEX',
+ 'ORDER',
+ 'TRIGGER',
+ 'COLUMN',
+ 'INITIAL',
+ 'PCTFREE',
+ 'UID',
+ 'COMMENT',
+ 'INSERT',
+ 'PRIOR',
+ 'UNION',
+ 'COMPRESS',
+ 'INTEGER',
+ 'PRIVILEGES',
+ 'UNIQUE',
+ 'CONNECT',
+ 'INTERSECT',
+ 'PUBLIC',
+ 'UPDATE',
+ 'CREATE',
+ 'INTO',
+ 'RAW',
+ 'USER',
+ 'CURRENT',
+ 'IS',
+ 'RENAME',
+ 'VALIDATE',
+ 'DATE',
+ 'LEVEL',
+ 'RESOURCE',
+ 'VALUES',
+ 'DECIMAL',
+ 'LIKE',
+ 'REVOKE',
+ 'VARCHAR',
+ 'DEFAULT',
+ 'LOCK',
+ 'ROW',
+ 'VARCHAR2',
+ 'DELETE',
+ 'LONG',
+ 'ROWID',
+ 'VIEW',
+ 'DESC',
+ 'MAXEXTENTS',
+ 'ROWLABEL',
+ 'WHENEVER',
+ 'DISTINCT',
+ 'MINUS',
+ 'ROWNUM',
+ 'WHERE',
+ 'DROP',
+ 'MODE',
+ 'ROWS',
+ 'WITH',
+);
+// }}}
+
+?>
diff --git a/3rdparty/MDB2/Schema/Reserved/pgsql.php b/3rdparty/MDB2/Schema/Reserved/pgsql.php
new file mode 100644
index 00000000000..d358e9c12f0
--- /dev/null
+++ b/3rdparty/MDB2/Schema/Reserved/pgsql.php
@@ -0,0 +1,147 @@
+<?php
+// {{{ Disclaimer, Licence, copyrights
+// +----------------------------------------------------------------------+
+// | PHP versions 4 and 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
+// | Stig. S. Bakken, Lukas Smith |
+// | All rights reserved. |
+// +----------------------------------------------------------------------+
+// | MDB2 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: Marcelo Santos Araujo <msaraujo@php.net> |
+// +----------------------------------------------------------------------+
+//
+// }}}
+// {{{ $GLOBALS['_MDB2_Schema_Reserved']['pgsql']
+/**
+ * Has a list of reserved words of pgsql
+ *
+ * @package MDB2_Schema
+ * @category Database
+ * @access protected
+ * @author Marcelo Santos Araujo <msaraujo@php.net>
+ */
+$GLOBALS['_MDB2_Schema_Reserved']['pgsql'] = array(
+ 'ALL',
+ 'ANALYSE',
+ 'ANALYZE',
+ 'AND',
+ 'ANY',
+ 'AS',
+ 'ASC',
+ 'AUTHORIZATION',
+ 'BETWEEN',
+ 'BINARY',
+ 'BOTH',
+ 'CASE',
+ 'CAST',
+ 'CHECK',
+ 'COLLATE',
+ 'COLUMN',
+ 'CONSTRAINT',
+ 'CREATE',
+ 'CURRENT_DATE',
+ 'CURRENT_TIME',
+ 'CURRENT_TIMESTAMP',
+ 'CURRENT_USER',
+ 'DEFAULT',
+ 'DEFERRABLE',
+ 'DESC',
+ 'DISTINCT',
+ 'DO',
+ 'ELSE',
+ 'END',
+ 'EXCEPT',
+ 'FALSE',
+ 'FOR',
+ 'FOREIGN',
+ 'FREEZE',
+ 'FROM',
+ 'FULL',
+ 'GRANT',
+ 'GROUP',
+ 'HAVING',
+ 'ILIKE',
+ 'IN',
+ 'INITIALLY',
+ 'INNER',
+ 'INTERSECT',
+ 'INTO',
+ 'IS',
+ 'ISNULL',
+ 'JOIN',
+ 'LEADING',
+ 'LEFT',
+ 'LIKE',
+ 'LIMIT',
+ 'LOCALTIME',
+ 'LOCALTIMESTAMP',
+ 'NATURAL',
+ 'NEW',
+ 'NOT',
+ 'NOTNULL',
+ 'NULL',
+ 'OFF',
+ 'OFFSET',
+ 'OLD',
+ 'ON',
+ 'ONLY',
+ 'OR',
+ 'ORDER',
+ 'OUTER',
+ 'OVERLAPS',
+ 'PLACING',
+ 'PRIMARY',
+ 'REFERENCES',
+ 'SELECT',
+ 'SESSION_USER',
+ 'SIMILAR',
+ 'SOME',
+ 'TABLE',
+ 'THEN',
+ 'TO',
+ 'TRAILING',
+ 'TRUE',
+ 'UNION',
+ 'UNIQUE',
+ 'USER',
+ 'USING',
+ 'VERBOSE',
+ 'WHEN',
+ 'WHERE'
+);
+// }}}
+?>
+
diff --git a/3rdparty/MDB2/Schema/Tool.php b/3rdparty/MDB2/Schema/Tool.php
new file mode 100644
index 00000000000..9689a0f6d73
--- /dev/null
+++ b/3rdparty/MDB2/Schema/Tool.php
@@ -0,0 +1,560 @@
+<?php
+/**
+ * PHP versions 4 and 5
+ *
+ * Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox,
+ * Stig. S. Bakken, Lukas Smith, Igor Feghali
+ * All rights reserved.
+ *
+ * MDB2_Schema enables users to maintain RDBMS independant schema files
+ * in XML that can be used to manipulate both data and database schemas
+ * 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, Igor Feghali 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: Christian Weiske <cweiske@php.net>
+ * $Id: Tool.php,v 1.6 2008/12/13 00:26:07 clockwerx Exp $
+ *
+ * @category Database
+ * @package MDB2_Schema
+ * @author Christian Weiske <cweiske@php.net>
+ * @license BSD http://www.opensource.org/licenses/bsd-license.php
+ * @version CVS: $Id: Tool.php,v 1.6 2008/12/13 00:26:07 clockwerx Exp $
+ * @link http://pear.php.net/packages/MDB2_Schema
+ */
+
+require_once 'MDB2/Schema.php';
+require_once 'MDB2/Schema/Tool/ParameterException.php';
+
+/**
+* Command line tool to work with database schemas
+*
+* Functionality:
+* - dump a database schema to stdout
+* - import schema into database
+* - create a diff between two schemas
+* - apply diff to database
+*
+ * @category Database
+ * @package MDB2_Schema
+ * @author Christian Weiske <cweiske@php.net>
+ * @license BSD http://www.opensource.org/licenses/bsd-license.php
+ * @link http://pear.php.net/packages/MDB2_Schema
+ */
+class MDB2_Schema_Tool
+{
+ /**
+ * Run the schema tool
+ *
+ * @param array $args Array of command line arguments
+ */
+ public function __construct($args)
+ {
+ $strAction = $this->getAction($args);
+ try {
+ $this->{'do' . ucfirst($strAction)}($args);
+ } catch (MDB2_Schema_Tool_ParameterException $e) {
+ $this->{'doHelp' . ucfirst($strAction)}($e->getMessage());
+ }
+ }//public function __construct($args)
+
+
+
+ /**
+ * Runs the tool with command line arguments
+ *
+ * @return void
+ */
+ public static function run()
+ {
+ $args = $GLOBALS['argv'];
+ array_shift($args);
+
+ try {
+ $tool = new MDB2_Schema_Tool($args);
+ } catch (Exception $e) {
+ self::toStdErr($e->getMessage() . "\n");
+ }
+ }//public static function run()
+
+
+
+ /**
+ * Reads the first parameter from the argument array and
+ * returns the action.
+ *
+ * @param array &$args Command line parameters
+ *
+ * @return string Action to execute
+ */
+ protected function getAction(&$args)
+ {
+ if (count($args) == 0) {
+ return 'help';
+ }
+ $arg = array_shift($args);
+ switch ($arg) {
+ case 'h':
+ case 'help':
+ case '-h':
+ case '--help':
+ return 'help';
+ case 'd':
+ case 'dump':
+ case '-d':
+ case '--dump':
+ return 'dump';
+ case 'l':
+ case 'load':
+ case '-l':
+ case '--load':
+ return 'load';
+ case 'i':
+ case 'diff':
+ case '-i':
+ case '--diff':
+ return 'diff';
+ case 'a':
+ case 'apply':
+ case '-a':
+ case '--apply':
+ return 'apply';
+ case 'n':
+ case 'init':
+ case '-i':
+ case '--init':
+ return 'init';
+ default:
+ throw new MDB2_Schema_Tool_ParameterException("Unknown mode \"$arg\"");
+ }
+ }//protected function getAction(&$args)
+
+
+
+ /**
+ * Writes the message to stderr
+ *
+ * @param string $msg Message to print
+ *
+ * @return void
+ */
+ protected static function toStdErr($msg)
+ {
+ file_put_contents('php://stderr', $msg);
+ }//protected static function toStdErr($msg)
+
+
+
+ /**
+ * Displays generic help to stdout
+ *
+ * @return void
+ */
+ protected function doHelp()
+ {
+ self::toStdErr(<<<EOH
+Usage: mdb2_schematool mode parameters
+
+Works with database schemas
+
+mode: (- and -- are optional)
+ h, help Show this help screen
+ d, dump Dump a schema to stdout
+ l, load Load a schema into database
+ i, diff Create a diff between two schemas and dump it to stdout
+ a, apply Apply a diff to a database
+ n, init Initialize a database with data
+
+EOH
+ );
+ }//protected function doHelp()
+
+
+
+ /**
+ * Displays the help screen for "dump" command
+ *
+ * @return void
+ */
+ protected function doHelpDump()
+ {
+ self::toStdErr( <<<EOH
+Usage: mdb2_schematool dump [all|data|schema] [-p] DSN
+
+Dumps a database schema to stdout
+
+If dump type is not specified, defaults to "schema".
+
+DSN: Data source name in the form of
+ driver://user:password@host/database
+
+User and password may be omitted.
+Using -p reads password from stdin which is more secure than passing it in the parameter.
+
+EOH
+ );
+ }//protected function doHelpDump()
+
+
+
+ /**
+ * Displays the help screen for "init" command
+ *
+ * @return void
+ */
+ protected function doHelpInit()
+ {
+ self::toStdErr( <<<EOH
+Usage: mdb2_schematool init source [-p] destination
+
+Initializes a database with data
+ (Inserts data on a previous created database at destination)
+
+source should be a schema file containing data,
+destination should be a DSN
+
+DSN: Data source name in the form of
+ driver://user:password@host/database
+
+User and password may be omitted.
+Using -p reads password from stdin which is more secure than passing it in the parameter.
+
+EOH
+ );
+ }//protected function doHelpInit()
+
+
+
+ /**
+ * Displays the help screen for "load" command
+ *
+ * @return void
+ */
+ protected function doHelpLoad()
+ {
+ self::toStdErr( <<<EOH
+Usage: mdb2_schematool load [-p] source [-p] destination
+
+Loads a database schema from source to destination
+ (Creates the database schema at destination)
+
+source can be a DSN or a schema file,
+destination should be a DSN
+
+DSN: Data source name in the form of
+ driver://user:password@host/database
+
+User and password may be omitted.
+Using -p reads password from stdin which is more secure than passing it in the parameter.
+
+EOH
+ );
+ }//protected function doHelpLoad()
+
+
+
+ /**
+ * Returns an array of options for MDB2_Schema constructor
+ *
+ * @return array Options for MDB2_Schema constructor
+ */
+ protected function getSchemaOptions()
+ {
+ $options = array(
+ 'log_line_break' => '<br>',
+ 'idxname_format' => '%s',
+ 'debug' => true,
+ 'quote_identifier' => true,
+ 'force_defaults' => false,
+ 'portability' => true,
+ 'use_transactions' => false,
+ );
+ return $options;
+ }//protected function getSchemaOptions()
+
+
+
+ /**
+ * Checks if the passed parameter is a PEAR_Error object
+ * and throws an exception in that case.
+ *
+ * @param mixed $object Some variable to check
+ * @param string $location Where the error occured
+ *
+ * @return void
+ */
+ protected function throwExceptionOnError($object, $location = '')
+ {
+ if (PEAR::isError($object)) {
+ //FIXME: exception class
+ //debug_print_backtrace();
+ throw new Exception('Error ' . $location
+ . "\n" . $object->getMessage()
+ . "\n" . $object->getUserInfo()
+ );
+ }
+ }//protected function throwExceptionOnError($object, $location = '')
+
+
+
+ /**
+ * Loads a file or a dsn from the arguments
+ *
+ * @param array &$args Array of arguments to the program
+ *
+ * @return array Array of ('file'|'dsn', $value)
+ */
+ protected function getFileOrDsn(&$args)
+ {
+ if (count($args) == 0) {
+ throw new MDB2_Schema_Tool_ParameterException('File or DSN expected');
+ }
+
+ $arg = array_shift($args);
+ if ($arg == '-p') {
+ $bAskPassword = true;
+ $arg = array_shift($args);
+ } else {
+ $bAskPassword = false;
+ }
+
+ if (strpos($arg, '://') === false) {
+ if (file_exists($arg)) {
+ //File
+ return array('file', $arg);
+ } else {
+ throw new Exception('Schema file does not exist');
+ }
+ }
+
+ //read password if necessary
+ if ($bAskPassword) {
+ $password = $this->readPasswordFromStdin($arg);
+ $arg = self::setPasswordIntoDsn($arg, $password);
+ self::toStdErr($arg);
+ }
+ return array('dsn', $arg);
+ }//protected function getFileOrDsn(&$args)
+
+
+
+ /**
+ * Takes a DSN data source name and integrates the given
+ * password into it.
+ *
+ * @param string $dsn Data source name
+ * @param string $password Password
+ *
+ * @return string DSN with password
+ */
+ protected function setPasswordIntoDsn($dsn, $password)
+ {
+ //simple try to integrate password
+ if (strpos($dsn, '@') === false) {
+ //no @ -> no user and no password
+ return str_replace('://', '://:' . $password . '@', $dsn);
+ } else if (preg_match('|://[^:]+@|', $dsn)) {
+ //user only, no password
+ return str_replace('@', ':' . $password . '@', $dsn);
+ } else if (strpos($dsn, ':@') !== false) {
+ //abstract version
+ return str_replace(':@', ':' . $password . '@', $dsn);
+ }
+
+ return $dsn;
+ }//protected function setPasswordIntoDsn($dsn, $password)
+
+
+
+ /**
+ * Reads a password from stdin
+ *
+ * @param string $dsn DSN name to put into the message
+ *
+ * @return string Password
+ */
+ protected function readPasswordFromStdin($dsn)
+ {
+ $stdin = fopen('php://stdin', 'r');
+ self::toStdErr('Please insert password for ' . $dsn . "\n");
+ $password = '';
+ $breakme = false;
+ while (false !== ($char = fgetc($stdin))) {
+ if (ord($char) == 10 || $char == "\n" || $char == "\r") {
+ break;
+ }
+ $password .= $char;
+ }
+ fclose($stdin);
+
+ return trim($password);
+ }//protected function readPasswordFromStdin()
+
+
+
+ /**
+ * Creates a database schema dump and sends it to stdout
+ *
+ * @param array $args Command line arguments
+ *
+ * @return void
+ */
+ protected function doDump($args)
+ {
+ $dump_what = MDB2_SCHEMA_DUMP_STRUCTURE;
+ $arg = '';
+ if (count($args)) {
+ $arg = $args[0];
+ }
+
+ switch (strtolower($arg)) {
+ case 'all':
+ $dump_what = MDB2_SCHEMA_DUMP_ALL;
+ array_shift($args);
+ break;
+ case 'data':
+ $dump_what = MDB2_SCHEMA_DUMP_CONTENT;
+ array_shift($args);
+ break;
+ case 'schema':
+ array_shift($args);
+ }
+
+ list($type, $dsn) = $this->getFileOrDsn($args);
+ if ($type == 'file') {
+ throw new MDB2_Schema_Tool_ParameterException(
+ 'Dumping a schema file as a schema file does not make much sense'
+ );
+ }
+
+ $schema = MDB2_Schema::factory($dsn, $this->getSchemaOptions());
+ $this->throwExceptionOnError($schema);
+
+ $definition = $schema->getDefinitionFromDatabase();
+ $this->throwExceptionOnError($definition);
+
+
+ $dump_options = array(
+ 'output_mode' => 'file',
+ 'output' => 'php://stdout',
+ 'end_of_line' => "\r\n"
+ );
+ $op = $schema->dumpDatabase(
+ $definition, $dump_options, $dump_what
+ );
+ $this->throwExceptionOnError($op);
+
+ $schema->disconnect();
+ }//protected function doDump($args)
+
+
+
+ /**
+ * Loads a database schema
+ *
+ * @param array $args Command line arguments
+ *
+ * @return void
+ */
+ protected function doLoad($args)
+ {
+ list($typeSource, $dsnSource) = $this->getFileOrDsn($args);
+ list($typeDest, $dsnDest) = $this->getFileOrDsn($args);
+
+ if ($typeDest == 'file') {
+ throw new MDB2_Schema_Tool_ParameterException(
+ 'A schema can only be loaded into a database, not a file'
+ );
+ }
+
+
+ $schemaDest = MDB2_Schema::factory($dsnDest, $this->getSchemaOptions());
+ $this->throwExceptionOnError($schemaDest);
+
+ //load definition
+ if ($typeSource == 'file') {
+ $definition = $schemaDest->parseDatabaseDefinitionFile($dsnSource);
+ $where = 'loading schema file';
+ } else {
+ $schemaSource = MDB2_Schema::factory($dsnSource, $this->getSchemaOptions());
+ $this->throwExceptionOnError($schemaSource, 'connecting to source database');
+
+ $definition = $schemaSource->getDefinitionFromDatabase();
+ $where = 'loading definition from database';
+ }
+ $this->throwExceptionOnError($definition, $where);
+
+
+ //create destination database from definition
+ $simulate = false;
+ $op = $schemaDest->createDatabase($definition, array(), $simulate);
+ $this->throwExceptionOnError($op, 'creating the database');
+ }//protected function doLoad($args)
+
+
+
+ /**
+ * Initializes a database with data
+ *
+ * @param array $args Command line arguments
+ *
+ * @return void
+ */
+ protected function doInit($args)
+ {
+ list($typeSource, $dsnSource) = $this->getFileOrDsn($args);
+ list($typeDest, $dsnDest) = $this->getFileOrDsn($args);
+
+ if ($typeSource != 'file') {
+ throw new MDB2_Schema_Tool_ParameterException(
+ 'Data must come from a source file'
+ );
+ }
+
+ if ($typeDest != 'dsn') {
+ throw new MDB2_Schema_Tool_ParameterException(
+ 'A schema can only be loaded into a database, not a file'
+ );
+ }
+
+ $schemaDest = MDB2_Schema::factory($dsnDest, $this->getSchemaOptions());
+ $this->throwExceptionOnError($schemaDest, 'connecting to destination database');
+
+ $definition = $schemaDest->getDefinitionFromDatabase();
+ $this->throwExceptionOnError($definition, 'loading definition from database');
+
+ $op = $schemaDest->writeInitialization($dsnSource, $definition);
+ $this->throwExceptionOnError($op, 'initializing database');
+ }//protected function doInit($args)
+
+
+}//class MDB2_Schema_Tool
+
+?>
diff --git a/3rdparty/MDB2/Schema/Tool/ParameterException.php b/3rdparty/MDB2/Schema/Tool/ParameterException.php
new file mode 100644
index 00000000000..fab1e03e250
--- /dev/null
+++ b/3rdparty/MDB2/Schema/Tool/ParameterException.php
@@ -0,0 +1,6 @@
+<?php
+
+class MDB2_Schema_Tool_ParameterException extends Exception
+{}
+
+?> \ No newline at end of file
diff --git a/3rdparty/MDB2/Schema/Validate.php b/3rdparty/MDB2/Schema/Validate.php
new file mode 100644
index 00000000000..217cf51b959
--- /dev/null
+++ b/3rdparty/MDB2/Schema/Validate.php
@@ -0,0 +1,917 @@
+<?php
+/**
+ * PHP versions 4 and 5
+ *
+ * Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox,
+ * Stig. S. Bakken, Lukas Smith, Igor Feghali
+ * All rights reserved.
+ *
+ * MDB2_Schema enables users to maintain RDBMS independant schema files
+ * in XML that can be used to manipulate both data and database schemas
+ * 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, Igor Feghali 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: Christian Dickmann <dickmann@php.net>
+ * Author: Igor Feghali <ifeghali@php.net>
+ *
+ * @category Database
+ * @package MDB2_Schema
+ * @author Christian Dickmann <dickmann@php.net>
+ * @author Igor Feghali <ifeghali@php.net>
+ * @license BSD http://www.opensource.org/licenses/bsd-license.php
+ * @version CVS: $Id: Validate.php,v 1.42 2008/11/30 03:34:00 clockwerx Exp $
+ * @link http://pear.php.net/packages/MDB2_Schema
+ */
+
+/**
+ * Validates an XML schema file
+ *
+ * @category Database
+ * @package MDB2_Schema
+ * @author Igor Feghali <ifeghali@php.net>
+ * @license BSD http://www.opensource.org/licenses/bsd-license.php
+ * @link http://pear.php.net/packages/MDB2_Schema
+ */
+class MDB2_Schema_Validate
+{
+ // {{{ properties
+
+ var $fail_on_invalid_names = true;
+
+ var $valid_types = array();
+
+ var $force_defaults = true;
+
+ // }}}
+ // {{{ constructor
+
+ function __construct($fail_on_invalid_names = true, $valid_types = array(), $force_defaults = true)
+ {
+ if (empty($GLOBALS['_MDB2_Schema_Reserved'])) {
+ $GLOBALS['_MDB2_Schema_Reserved'] = array();
+ }
+
+ if (is_array($fail_on_invalid_names)) {
+ $this->fail_on_invalid_names = array_intersect($fail_on_invalid_names,
+ array_keys($GLOBALS['_MDB2_Schema_Reserved']));
+ } elseif ($fail_on_invalid_names === true) {
+ $this->fail_on_invalid_names = array_keys($GLOBALS['_MDB2_Schema_Reserved']);
+ } else {
+ $this->fail_on_invalid_names = array();
+ }
+ $this->valid_types = $valid_types;
+ $this->force_defaults = $force_defaults;
+ }
+
+ // }}}
+ // {{{ raiseError()
+
+ function &raiseError($ecode, $msg = null)
+ {
+ $error =& MDB2_Schema::raiseError($ecode, null, null, $msg);
+ return $error;
+ }
+
+ // }}}
+ // {{{ isBoolean()
+
+ /**
+ * Verifies if a given value can be considered boolean. If yes, set value
+ * to true or false according to its actual contents and return true. If
+ * not, keep its contents untouched and return false.
+ *
+ * @param mixed &$value value to be checked
+ *
+ * @return bool
+ *
+ * @access public
+ * @static
+ */
+ function isBoolean(&$value)
+ {
+ if (is_bool($value)) {
+ return true;
+ }
+
+ if ($value === 0 || $value === 1 || $value === '') {
+ $value = (bool)$value;
+ return true;
+ }
+
+ if (!is_string($value)) {
+ return false;
+ }
+
+ switch ($value) {
+ case '0':
+ case 'N':
+ case 'n':
+ case 'no':
+ case 'false':
+ $value = false;
+ break;
+ case '1':
+ case 'Y':
+ case 'y':
+ case 'yes':
+ case 'true':
+ $value = true;
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ // }}}
+ // {{{ validateTable()
+
+ /* Definition */
+ /**
+ * Checks whether the definition of a parsed table is valid. Modify table
+ * definition when necessary.
+ *
+ * @param array $tables multi dimensional array that contains the
+ * tables of current database.
+ * @param array &$table multi dimensional array that contains the
+ * structure and optional data of the table.
+ * @param string $table_name name of the parsed table
+ *
+ * @return bool|error object
+ *
+ * @access public
+ */
+ function validateTable($tables, &$table, $table_name)
+ {
+ /* Have we got a name? */
+ if (!$table_name) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'a table has to have a name');
+ }
+
+ /* Table name duplicated? */
+ if (is_array($tables) && isset($tables[$table_name])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'table "'.$table_name.'" already exists');
+ }
+
+ /* Table name reserved? */
+ if (is_array($this->fail_on_invalid_names)) {
+ $name = strtoupper($table_name);
+ foreach ($this->fail_on_invalid_names as $rdbms) {
+ if (in_array($name, $GLOBALS['_MDB2_Schema_Reserved'][$rdbms])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'table name "'.$table_name.'" is a reserved word in: '.$rdbms);
+ }
+ }
+ }
+
+ /* Was */
+ if (empty($table['was'])) {
+ $table['was'] = $table_name;
+ }
+
+ /* Have we got fields? */
+ if (empty($table['fields']) || !is_array($table['fields'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'tables need one or more fields');
+ }
+
+ /* Autoincrement */
+ $autoinc = $primary = false;
+ foreach ($table['fields'] as $field_name => $field) {
+ if (!empty($field['autoincrement'])) {
+ if ($autoinc) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'there was already an autoincrement field in "'.$table_name.'" before "'.$field_name.'"');
+ }
+ $autoinc = $field_name;
+ }
+ }
+
+ /*
+ * Checking Indexes
+ * this have to be done here otherwise we can't
+ * guarantee that all table fields were already
+ * defined in the moment we are parsing indexes
+ */
+ if (!empty($table['indexes']) && is_array($table['indexes'])) {
+ foreach ($table['indexes'] as $name => $index) {
+ $skip_index = false;
+ if (!empty($index['primary'])) {
+ /*
+ * Lets see if we should skip this index since there is
+ * already an auto increment on this field this implying
+ * a primary key index.
+ */
+ if (count($index['fields']) == '1'
+ && $autoinc
+ && array_key_exists($autoinc, $index['fields'])) {
+ $skip_index = true;
+ } elseif ($autoinc || $primary) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'there was already an primary index or autoincrement field in "'.$table_name.'" before "'.$name.'"');
+ } else {
+ $primary = true;
+ }
+ }
+
+ if (!$skip_index && is_array($index['fields'])) {
+ foreach ($index['fields'] as $field_name => $field) {
+ if (!isset($table['fields'][$field_name])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'index field "'.$field_name.'" does not exist');
+ }
+ if (!empty($index['primary'])
+ && !$table['fields'][$field_name]['notnull']
+ ) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'all primary key fields must be defined notnull in "'.$table_name.'"');
+ }
+ }
+ } else {
+ unset($table['indexes'][$name]);
+ }
+ }
+ }
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ validateField()
+
+ /**
+ * Checks whether the definition of a parsed field is valid. Modify field
+ * definition when necessary.
+ *
+ * @param array $fields multi dimensional array that contains the
+ * fields of current table.
+ * @param array &$field multi dimensional array that contains the
+ * structure of the parsed field.
+ * @param string $field_name name of the parsed field
+ *
+ * @return bool|error object
+ *
+ * @access public
+ */
+ function validateField($fields, &$field, $field_name)
+ {
+ /* Have we got a name? */
+ if (!$field_name) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'field name missing');
+ }
+
+ /* Field name duplicated? */
+ if (is_array($fields) && isset($fields[$field_name])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'field "'.$field_name.'" already exists');
+ }
+
+ /* Field name reserverd? */
+ if (is_array($this->fail_on_invalid_names)) {
+ $name = strtoupper($field_name);
+ foreach ($this->fail_on_invalid_names as $rdbms) {
+ if (in_array($name, $GLOBALS['_MDB2_Schema_Reserved'][$rdbms])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'field name "'.$field_name.'" is a reserved word in: '.$rdbms);
+ }
+ }
+ }
+
+ /* Type check */
+ if (empty($field['type'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'no field type specified');
+ }
+ if (!empty($this->valid_types) && !array_key_exists($field['type'], $this->valid_types)) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'no valid field type ("'.$field['type'].'") specified');
+ }
+
+ /* Unsigned */
+ if (array_key_exists('unsigned', $field) && !$this->isBoolean($field['unsigned'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'unsigned has to be a boolean value');
+ }
+
+ /* Fixed */
+ if (array_key_exists('fixed', $field) && !$this->isBoolean($field['fixed'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'fixed has to be a boolean value');
+ }
+
+ /* Length */
+ if (array_key_exists('length', $field) && $field['length'] <= 0) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'length has to be an integer greater 0');
+ }
+
+ // if it's a DECIMAL datatype, check if a 'scale' value is provided:
+ // <length>8,4</length> should be translated to DECIMAL(8,4)
+ if (is_float($this->valid_types[$field['type']])
+ && !empty($field['length'])
+ && strpos($field['length'], ',') !== false
+ ) {
+ list($field['length'], $field['scale']) = explode(',', $field['length']);
+ }
+
+ /* Was */
+ if (empty($field['was'])) {
+ $field['was'] = $field_name;
+ }
+
+ /* Notnull */
+ if (empty($field['notnull'])) {
+ $field['notnull'] = false;
+ }
+ if (!$this->isBoolean($field['notnull'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'field "notnull" has to be a boolean value');
+ }
+
+ /* Default */
+ if ($this->force_defaults
+ && !array_key_exists('default', $field)
+ && $field['type'] != 'clob' && $field['type'] != 'blob'
+ ) {
+ $field['default'] = $this->valid_types[$field['type']];
+ }
+ if (array_key_exists('default', $field)) {
+ if ($field['type'] == 'clob' || $field['type'] == 'blob') {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ '"'.$field['type'].'"-fields are not allowed to have a default value');
+ }
+ if ($field['default'] === '' && !$field['notnull']) {
+ $field['default'] = null;
+ }
+ }
+ if (isset($field['default'])
+ && PEAR::isError($result = $this->validateDataFieldValue($field, $field['default'], $field_name))
+ ) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'default value of "'.$field_name.'" is incorrect: '.$result->getUserinfo());
+ }
+
+ /* Autoincrement */
+ if (!empty($field['autoincrement'])) {
+ if (!$field['notnull']) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'all autoincrement fields must be defined notnull');
+ }
+
+ if (empty($field['default'])) {
+ $field['default'] = '0';
+ } elseif ($field['default'] !== '0' && $field['default'] !== 0) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'all autoincrement fields must be defined default "0"');
+ }
+ }
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ validateIndex()
+
+ /**
+ * Checks whether a parsed index is valid. Modify index definition when
+ * necessary.
+ *
+ * @param array $table_indexes multi dimensional array that contains the
+ * indexes of current table.
+ * @param array &$index multi dimensional array that contains the
+ * structure of the parsed index.
+ * @param string $index_name name of the parsed index
+ *
+ * @return bool|error object
+ *
+ * @access public
+ */
+ function validateIndex($table_indexes, &$index, $index_name)
+ {
+ if (!$index_name) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'an index has to have a name');
+ }
+ if (is_array($table_indexes) && isset($table_indexes[$index_name])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'index "'.$index_name.'" already exists');
+ }
+ if (array_key_exists('unique', $index) && !$this->isBoolean($index['unique'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'field "unique" has to be a boolean value');
+ }
+ if (array_key_exists('primary', $index) && !$this->isBoolean($index['primary'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'field "primary" has to be a boolean value');
+ }
+
+ /* Have we got fields? */
+ if (empty($index['fields']) || !is_array($index['fields'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'indexes need one or more fields');
+ }
+
+ if (empty($index['was'])) {
+ $index['was'] = $index_name;
+ }
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ validateIndexField()
+
+ /**
+ * Checks whether a parsed index-field is valid. Modify its definition when
+ * necessary.
+ *
+ * @param array $index_fields multi dimensional array that contains the
+ * fields of current index.
+ * @param array &$field multi dimensional array that contains the
+ * structure of the parsed index-field.
+ * @param string $field_name name of the parsed index-field
+ *
+ * @return bool|error object
+ *
+ * @access public
+ */
+ function validateIndexField($index_fields, &$field, $field_name)
+ {
+ if (is_array($index_fields) && isset($index_fields[$field_name])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'index field "'.$field_name.'" already exists');
+ }
+ if (!$field_name) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'the index-field-name is required');
+ }
+ if (empty($field['sorting'])) {
+ $field['sorting'] = 'ascending';
+ } elseif ($field['sorting'] !== 'ascending' && $field['sorting'] !== 'descending') {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'sorting type unknown');
+ }
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ validateConstraint()
+
+ /**
+ * Checks whether a parsed foreign key is valid. Modify its definition when
+ * necessary.
+ *
+ * @param array $table_constraints multi dimensional array that contains the
+ * constraints of current table.
+ * @param array &$constraint multi dimensional array that contains the
+ * structure of the parsed foreign key.
+ * @param string $constraint_name name of the parsed foreign key
+ *
+ * @return bool|error object
+ *
+ * @access public
+ */
+ function validateConstraint($table_constraints, &$constraint, $constraint_name)
+ {
+ if (!$constraint_name) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'a foreign key has to have a name');
+ }
+ if (is_array($table_constraints) && isset($table_constraints[$constraint_name])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'foreign key "'.$constraint_name.'" already exists');
+ }
+
+ /* Have we got fields? */
+ if (empty($constraint['fields']) || !is_array($constraint['fields'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'foreign key "'.$constraint_name.'" need one or more fields');
+ }
+
+ /* Have we got referenced fields? */
+ if (empty($constraint['references']) || !is_array($constraint['references'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'foreign key "'.$constraint_name.'" need to reference one or more fields');
+ }
+
+ /* Have we got referenced table? */
+ if (empty($constraint['references']['table'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'foreign key "'.$constraint_name.'" need to reference a table');
+ }
+
+ if (empty($constraint['was'])) {
+ $constraint['was'] = $constraint_name;
+ }
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ validateConstraintField()
+
+ /**
+ * Checks whether a foreign-field is valid.
+ *
+ * @param array $constraint_fields multi dimensional array that contains the
+ * fields of current foreign key.
+ * @param string $field_name name of the parsed foreign-field
+ *
+ * @return bool|error object
+ *
+ * @access public
+ */
+ function validateConstraintField($constraint_fields, $field_name)
+ {
+ if (!$field_name) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'empty value for foreign-field');
+ }
+ if (is_array($constraint_fields) && isset($constraint_fields[$field_name])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'foreign field "'.$field_name.'" already exists');
+ }
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ validateConstraintReferencedField()
+
+ /**
+ * Checks whether a foreign-referenced field is valid.
+ *
+ * @param array $referenced_fields multi dimensional array that contains the
+ * fields of current foreign key.
+ * @param string $field_name name of the parsed foreign-field
+ *
+ * @return bool|error object
+ *
+ * @access public
+ */
+ function validateConstraintReferencedField($referenced_fields, $field_name)
+ {
+ if (!$field_name) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'empty value for referenced foreign-field');
+ }
+ if (is_array($referenced_fields) && isset($referenced_fields[$field_name])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'foreign field "'.$field_name.'" already referenced');
+ }
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ validateSequence()
+
+ /**
+ * Checks whether the definition of a parsed sequence is valid. Modify
+ * sequence definition when necessary.
+ *
+ * @param array $sequences multi dimensional array that contains the
+ * sequences of current database.
+ * @param array &$sequence multi dimensional array that contains the
+ * structure of the parsed sequence.
+ * @param string $sequence_name name of the parsed sequence
+ *
+ * @return bool|error object
+ *
+ * @access public
+ */
+ function validateSequence($sequences, &$sequence, $sequence_name)
+ {
+ if (!$sequence_name) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'a sequence has to have a name');
+ }
+
+ if (is_array($sequences) && isset($sequences[$sequence_name])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'sequence "'.$sequence_name.'" already exists');
+ }
+
+ if (is_array($this->fail_on_invalid_names)) {
+ $name = strtoupper($sequence_name);
+ foreach ($this->fail_on_invalid_names as $rdbms) {
+ if (in_array($name, $GLOBALS['_MDB2_Schema_Reserved'][$rdbms])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'sequence name "'.$sequence_name.'" is a reserved word in: '.$rdbms);
+ }
+ }
+ }
+
+ if (empty($sequence['was'])) {
+ $sequence['was'] = $sequence_name;
+ }
+
+ if (!empty($sequence['on'])
+ && (empty($sequence['on']['table']) || empty($sequence['on']['field']))
+ ) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'sequence "'.$sequence_name.'" on a table was not properly defined');
+ }
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ validateDatabase()
+
+ /**
+ * Checks whether a parsed database is valid. Modify its structure and
+ * data when necessary.
+ *
+ * @param array &$database multi dimensional array that contains the
+ * structure and optional data of the database.
+ *
+ * @return bool|error object
+ *
+ * @access public
+ */
+ function validateDatabase(&$database)
+ {
+ /* Have we got a name? */
+ if (!is_array($database) || !isset($database['name']) || !$database['name']) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'a database has to have a name');
+ }
+
+ /* Database name reserved? */
+ if (is_array($this->fail_on_invalid_names)) {
+ $name = strtoupper($database['name']);
+ foreach ($this->fail_on_invalid_names as $rdbms) {
+ if (in_array($name, $GLOBALS['_MDB2_Schema_Reserved'][$rdbms])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'database name "'.$database['name'].'" is a reserved word in: '.$rdbms);
+ }
+ }
+ }
+
+ /* Create */
+ if (isset($database['create'])
+ && !$this->isBoolean($database['create'])
+ ) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'field "create" has to be a boolean value');
+ }
+
+ /* Overwrite */
+ if (isset($database['overwrite'])
+ && $database['overwrite'] !== ''
+ && !$this->isBoolean($database['overwrite'])
+ ) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'field "overwrite" has to be a boolean value');
+ }
+
+ /*
+ * This have to be done here otherwise we can't guarantee that all
+ * tables were already defined in the moment we are parsing constraints
+ */
+ if (isset($database['tables'])) {
+ foreach ($database['tables'] as $table_name => $table) {
+ if (!empty($table['constraints'])) {
+ foreach ($table['constraints'] as $constraint_name => $constraint) {
+ $referenced_table_name = $constraint['references']['table'];
+
+ if (!isset($database['tables'][$referenced_table_name])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'referenced table "'.$referenced_table_name.'" of foreign key "'.$constraint_name.'" of table "'.$table_name.'" does not exist');
+ }
+
+ if (empty($constraint['references']['fields'])) {
+ $referenced_table = $database['tables'][$referenced_table_name];
+
+ $primary = false;
+
+ if (!empty($referenced_table['indexes'])) {
+ foreach ($referenced_table['indexes'] as $index_name => $index) {
+ if (array_key_exists('primary', $index)
+ && $index['primary']
+ ) {
+ $primary = array();
+ foreach ($index['fields'] as $field_name => $field) {
+ $primary[$field_name] = '';
+ }
+ break;
+ }
+ }
+ }
+
+ if (!$primary) {
+ foreach ($referenced_table['fields'] as $field_name => $field) {
+ if (array_key_exists('autoincrement', $field)
+ && $field['autoincrement']
+ ) {
+ $primary = array( $field_name => '' );
+ break;
+ }
+ }
+ }
+
+ if (!$primary) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'referenced table "'.$referenced_table_name.'" has no primary key and no referenced field was specified for foreign key "'.$constraint_name.'" of table "'.$table_name.'"');
+ }
+
+ $constraint['references']['fields'] = $primary;
+ }
+
+ /* the same number of referencing and referenced fields ? */
+ if (count($constraint['fields']) != count($constraint['references']['fields'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'The number of fields in the referenced key must match those of the foreign key "'.$constraint_name.'"');
+ }
+
+ $database['tables'][$table_name]['constraints'][$constraint_name]['references']['fields'] = $constraint['references']['fields'];
+ }
+ }
+ }
+ }
+
+ /*
+ * This have to be done here otherwise we can't guarantee that all
+ * tables were already defined in the moment we are parsing sequences
+ */
+ if (isset($database['sequences'])) {
+ foreach ($database['sequences'] as $seq_name => $seq) {
+ if (!empty($seq['on'])
+ && empty($database['tables'][$seq['on']['table']]['fields'][$seq['on']['field']])
+ ) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'sequence "'.$seq_name.'" was assigned on unexisting field/table');
+ }
+ }
+ }
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ validateDataField()
+
+ /* Data Manipulation */
+ /**
+ * Checks whether a parsed DML-field is valid. Modify its structure when
+ * necessary. This is called when validating INSERT and
+ * UPDATE.
+ *
+ * @param array $table_fields multi dimensional array that contains the
+ * definition for current table's fields.
+ * @param array $instruction_fields multi dimensional array that contains the
+ * parsed fields of the current DML instruction.
+ * @param string &$field array that contains the parsed instruction field
+ *
+ * @return bool|error object
+ *
+ * @access public
+ */
+ function validateDataField($table_fields, $instruction_fields, &$field)
+ {
+ if (!$field['name']) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'field-name has to be specified');
+ }
+
+ if (is_array($instruction_fields) && isset($instruction_fields[$field['name']])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'field "'.$field['name'].'" already initialized');
+ }
+
+ if (is_array($table_fields) && !isset($table_fields[$field['name']])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ '"'.$field['name'].'" is not defined');
+ }
+
+ if (!isset($field['group']['type'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ '"'.$field['name'].'" has no initial value');
+ }
+
+ if (isset($field['group']['data'])
+ && $field['group']['type'] == 'value'
+ && $field['group']['data'] !== ''
+ && PEAR::isError($result = $this->validateDataFieldValue($table_fields[$field['name']], $field['group']['data'], $field['name']))
+ ) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ 'value of "'.$field['name'].'" is incorrect: '.$result->getUserinfo());
+ }
+
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ validateDataFieldValue()
+
+ /**
+ * Checks whether a given value is compatible with a table field. This is
+ * done when parsing a field for a INSERT or UPDATE instruction.
+ *
+ * @param array $field_def multi dimensional array that contains the
+ * definition for current table's fields.
+ * @param string &$field_value value to fill the parsed field
+ * @param string $field_name name of the parsed field
+ *
+ * @return bool|error object
+ *
+ * @access public
+ * @see MDB2_Schema_Validate::validateInsertField()
+ */
+ function validateDataFieldValue($field_def, &$field_value, $field_name)
+ {
+ switch ($field_def['type']) {
+ case 'text':
+ case 'clob':
+ if (!empty($field_def['length']) && strlen($field_value) > $field_def['length']) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ '"'.$field_value.'" is larger than "'.$field_def['length'].'"');
+ }
+ break;
+ case 'blob':
+ $field_value = pack('H*', $field_value);
+ if (!empty($field_def['length']) && strlen($field_value) > $field_def['length']) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ '"'.$field_value.'" is larger than "'.$field_def['type'].'"');
+ }
+ break;
+ case 'integer':
+ if ($field_value != ((int)$field_value)) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ '"'.$field_value.'" is not of type "'.$field_def['type'].'"');
+ }
+ //$field_value = (int)$field_value;
+ if (!empty($field_def['unsigned']) && $field_def['unsigned'] && $field_value < 0) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ '"'.$field_value.'" signed instead of unsigned');
+ }
+ break;
+ case 'boolean':
+ if (!$this->isBoolean($field_value)) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ '"'.$field_value.'" is not of type "'.$field_def['type'].'"');
+ }
+ break;
+ case 'date':
+ if (!preg_match('/([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})/', $field_value)
+ && $field_value !== 'CURRENT_DATE'
+ ) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ '"'.$field_value.'" is not of type "'.$field_def['type'].'"');
+ }
+ break;
+ case 'timestamp':
+ if (!preg_match('/([0-9]{4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/', $field_value)
+ && strcasecmp($field_value, 'now()') != 0
+ && $field_value !== 'CURRENT_TIMESTAMP'
+ ) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ '"'.$field_value.'" is not of type "'.$field_def['type'].'"');
+ }
+ break;
+ case 'time':
+ if (!preg_match("/([0-9]{2}):([0-9]{2}):([0-9]{2})/", $field_value)
+ && $field_value !== 'CURRENT_TIME'
+ ) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ '"'.$field_value.'" is not of type "'.$field_def['type'].'"');
+ }
+ break;
+ case 'float':
+ case 'double':
+ if ($field_value != (double)$field_value) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE,
+ '"'.$field_value.'" is not of type "'.$field_def['type'].'"');
+ }
+ //$field_value = (double)$field_value;
+ break;
+ }
+ return MDB2_OK;
+ }
+}
+
+?>
diff --git a/3rdparty/MDB2/Schema/Writer.php b/3rdparty/MDB2/Schema/Writer.php
new file mode 100644
index 00000000000..5ae4918dc1d
--- /dev/null
+++ b/3rdparty/MDB2/Schema/Writer.php
@@ -0,0 +1,581 @@
+<?php
+/**
+ * PHP versions 4 and 5
+ *
+ * Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox,
+ * Stig. S. Bakken, Lukas Smith, Igor Feghali
+ * All rights reserved.
+ *
+ * MDB2_Schema enables users to maintain RDBMS independant schema files
+ * in XML that can be used to manipulate both data and database schemas
+ * 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, Igor Feghali 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@pooteeweet.org>
+ * Author: Igor Feghali <ifeghali@php.net>
+ *
+ * @category Database
+ * @package MDB2_Schema
+ * @author Lukas Smith <smith@pooteeweet.org>
+ * @author Igor Feghali <ifeghali@php.net>
+ * @license BSD http://www.opensource.org/licenses/bsd-license.php
+ * @version CVS: $Id: Writer.php,v 1.40 2008/11/30 03:34:00 clockwerx Exp $
+ * @link http://pear.php.net/packages/MDB2_Schema
+ */
+
+/**
+ * Writes an XML schema file
+ *
+ * @category Database
+ * @package MDB2_Schema
+ * @author Lukas Smith <smith@pooteeweet.org>
+ * @license BSD http://www.opensource.org/licenses/bsd-license.php
+ * @link http://pear.php.net/packages/MDB2_Schema
+ */
+class MDB2_Schema_Writer
+{
+ // {{{ properties
+
+ var $valid_types = array();
+
+ // }}}
+ // {{{ constructor
+
+ function __construct($valid_types = array())
+ {
+ $this->valid_types = $valid_types;
+ }
+
+ function MDB2_Schema_Writer($valid_types = array())
+ {
+ $this->__construct($valid_types);
+ }
+
+ // }}}
+ // {{{ 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 int|PEAR_Error $code integer error code or and PEAR_Error instance
+ * @param int $mode error mode, see PEAR_Error docs
+ * 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 $options Extra debug information. Defaults to the last
+ * query and native error code.
+ *
+ * @return object a PEAR error object
+ * @access public
+ * @see PEAR_Error
+ */
+ function &raiseError($code = null, $mode = null, $options = null, $userinfo = null)
+ {
+ $error =& MDB2_Schema::raiseError($code, $mode, $options, $userinfo);
+ return $error;
+ }
+
+ // }}}
+ // {{{ _escapeSpecialChars()
+
+ /**
+ * add escapecharacters to all special characters in a string
+ *
+ * @param string $string string that should be escaped
+ *
+ * @return string escaped string
+ * @access protected
+ */
+ function _escapeSpecialChars($string)
+ {
+ if (!is_string($string)) {
+ $string = strval($string);
+ }
+
+ $escaped = '';
+ for ($char = 0, $count = strlen($string); $char < $count; $char++) {
+ switch ($string[$char]) {
+ case '&':
+ $escaped .= '&amp;';
+ break;
+ case '>':
+ $escaped .= '&gt;';
+ break;
+ case '<':
+ $escaped .= '&lt;';
+ break;
+ case '"':
+ $escaped .= '&quot;';
+ break;
+ case '\'':
+ $escaped .= '&apos;';
+ break;
+ default:
+ $code = ord($string[$char]);
+ if ($code < 32 || $code > 127) {
+ $escaped .= "&#$code;";
+ } else {
+ $escaped .= $string[$char];
+ }
+ break;
+ }
+ }
+ return $escaped;
+ }
+
+ // }}}
+ // {{{ _dumpBoolean()
+
+ /**
+ * dump the structure of a sequence
+ *
+ * @param string $boolean boolean value or variable definition
+ *
+ * @return string with xml boolea definition
+ * @access private
+ */
+ function _dumpBoolean($boolean)
+ {
+ if (is_string($boolean)) {
+ if ($boolean !== 'true' || $boolean !== 'false'
+ || preg_match('/<variable>.*</variable>/', $boolean)
+ ) {
+ return $boolean;
+ }
+ }
+ return $boolean ? 'true' : 'false';
+ }
+
+ // }}}
+ // {{{ dumpSequence()
+
+ /**
+ * dump the structure of a sequence
+ *
+ * @param string $sequence_definition sequence definition
+ * @param string $sequence_name sequence name
+ * @param string $eol end of line characters
+ * @param integer $dump determines what data to dump
+ * MDB2_SCHEMA_DUMP_ALL : the entire db
+ * MDB2_SCHEMA_DUMP_STRUCTURE : only the structure of the db
+ * MDB2_SCHEMA_DUMP_CONTENT : only the content of the db
+ *
+ * @return mixed string xml sequence definition on success, or a error object
+ * @access public
+ */
+ function dumpSequence($sequence_definition, $sequence_name, $eol, $dump = MDB2_SCHEMA_DUMP_ALL)
+ {
+ $buffer = "$eol <sequence>$eol <name>$sequence_name</name>$eol";
+ if ($dump == MDB2_SCHEMA_DUMP_ALL || $dump == MDB2_SCHEMA_DUMP_CONTENT) {
+ if (!empty($sequence_definition['start'])) {
+ $start = $sequence_definition['start'];
+ $buffer .= " <start>$start</start>$eol";
+ }
+ }
+
+ if (!empty($sequence_definition['on'])) {
+ $buffer .= " <on>$eol";
+ $buffer .= " <table>".$sequence_definition['on']['table'];
+ $buffer .= "</table>$eol <field>".$sequence_definition['on']['field'];
+ $buffer .= "</field>$eol </on>$eol";
+ }
+ $buffer .= " </sequence>$eol";
+
+ return $buffer;
+ }
+
+ // }}}
+ // {{{ 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 $database_definition unknown
+ * @param array $arguments associative array that takes pairs of tag
+ * names and values that define dump options.
+ * array (
+ * '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
+ * 'end_of_line' => String
+ * end of line delimiter that should be used
+ * default: "\n"
+ * );
+ * @param integer $dump determines what data to dump
+ * MDB2_SCHEMA_DUMP_ALL : the entire db
+ * MDB2_SCHEMA_DUMP_STRUCTURE : only the structure of the db
+ * MDB2_SCHEMA_DUMP_CONTENT : only the content of the db
+ *
+ * @return mixed MDB2_OK on success, or a error object
+ * @access public
+ */
+ function dumpDatabase($database_definition, $arguments, $dump = MDB2_SCHEMA_DUMP_ALL)
+ {
+ if (!empty($arguments['output'])) {
+ if (!empty($arguments['output_mode']) && $arguments['output_mode'] == 'file') {
+ $fp = fopen($arguments['output'], 'w');
+ if ($fp === false) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_WRITER, null, null,
+ 'it was not possible to open output file');
+ }
+
+ $output = false;
+ } elseif (is_callable($arguments['output'])) {
+ $output = $arguments['output'];
+ } else {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_WRITER, null, null,
+ 'no valid output function specified');
+ }
+ } else {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_WRITER, null, null,
+ 'no output method specified');
+ }
+
+ $eol = isset($arguments['end_of_line']) ? $arguments['end_of_line'] : "\n";
+
+ $sequences = array();
+ if (!empty($database_definition['sequences'])
+ && is_array($database_definition['sequences'])
+ ) {
+ foreach ($database_definition['sequences'] as $sequence_name => $sequence) {
+ $table = !empty($sequence['on']) ? $sequence['on']['table'] :'';
+
+ $sequences[$table][] = $sequence_name;
+ }
+ }
+
+ $buffer = '<?xml version="1.0" encoding="ISO-8859-1" ?>'.$eol;
+ $buffer .= "<database>$eol$eol <name>".$database_definition['name']."</name>";
+ $buffer .= "$eol <create>".$this->_dumpBoolean($database_definition['create'])."</create>";
+ $buffer .= "$eol <overwrite>".$this->_dumpBoolean($database_definition['overwrite'])."</overwrite>$eol";
+ $buffer .= "$eol <charset>".$database_definition['charset']."</charset>$eol";
+
+ if ($output) {
+ call_user_func($output, $buffer);
+ } else {
+ fwrite($fp, $buffer);
+ }
+
+ if (!empty($database_definition['tables']) && is_array($database_definition['tables'])) {
+ foreach ($database_definition['tables'] as $table_name => $table) {
+ $buffer = "$eol <table>$eol$eol <name>$table_name</name>$eol";
+ if ($dump == MDB2_SCHEMA_DUMP_ALL || $dump == MDB2_SCHEMA_DUMP_STRUCTURE) {
+ $buffer .= "$eol <declaration>$eol";
+ if (!empty($table['fields']) && is_array($table['fields'])) {
+ foreach ($table['fields'] as $field_name => $field) {
+ if (empty($field['type'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE, null, null,
+ 'it was not specified the type of the field "'.
+ $field_name.'" of the table "'.$table_name.'"');
+ }
+ if (!empty($this->valid_types) && !array_key_exists($field['type'], $this->valid_types)) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_UNSUPPORTED, null, null,
+ 'type "'.$field['type'].'" is not yet supported');
+ }
+ $buffer .= "$eol <field>$eol <name>$field_name</name>$eol <type>";
+ $buffer .= $field['type']."</type>$eol";
+ if (!empty($field['fixed']) && $field['type'] === 'text') {
+ $buffer .= " <fixed>".$this->_dumpBoolean($field['fixed'])."</fixed>$eol";
+ }
+ if (array_key_exists('default', $field)
+ && $field['type'] !== 'clob' && $field['type'] !== 'blob'
+ ) {
+ $buffer .= ' <default>'.$this->_escapeSpecialChars($field['default'])."</default>$eol";
+ }
+ if (!empty($field['notnull'])) {
+ $buffer .= " <notnull>".$this->_dumpBoolean($field['notnull'])."</notnull>$eol";
+ } else {
+ $buffer .= " <notnull>false</notnull>$eol";
+ }
+ if (!empty($field['autoincrement'])) {
+ $buffer .= " <autoincrement>" . $field['autoincrement'] ."</autoincrement>$eol";
+ }
+ if (!empty($field['unsigned'])) {
+ $buffer .= " <unsigned>".$this->_dumpBoolean($field['unsigned'])."</unsigned>$eol";
+ }
+ if (!empty($field['length'])) {
+ $buffer .= ' <length>'.$field['length']."</length>$eol";
+ }
+ $buffer .= " </field>$eol";
+ }
+ }
+
+ if (!empty($table['indexes']) && is_array($table['indexes'])) {
+ foreach ($table['indexes'] as $index_name => $index) {
+ if (strtolower($index_name) === 'primary') {
+ $index_name = $table_name . '_pKey';
+ }
+ $buffer .= "$eol <index>$eol <name>$index_name</name>$eol";
+ if (!empty($index['unique'])) {
+ $buffer .= " <unique>".$this->_dumpBoolean($index['unique'])."</unique>$eol";
+ }
+
+ if (!empty($index['primary'])) {
+ $buffer .= " <primary>".$this->_dumpBoolean($index['primary'])."</primary>$eol";
+ }
+
+ foreach ($index['fields'] as $field_name => $field) {
+ $buffer .= " <field>$eol <name>$field_name</name>$eol";
+ if (!empty($field) && is_array($field)) {
+ $buffer .= ' <sorting>'.$field['sorting']."</sorting>$eol";
+ }
+ $buffer .= " </field>$eol";
+ }
+ $buffer .= " </index>$eol";
+ }
+ }
+
+ if (!empty($table['constraints']) && is_array($table['constraints'])) {
+ foreach ($table['constraints'] as $constraint_name => $constraint) {
+ $buffer .= "$eol <foreign>$eol <name>$constraint_name</name>$eol";
+ if (empty($constraint['fields']) || !is_array($constraint['fields'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE, null, null,
+ 'it was not specified a field for the foreign key "'.
+ $constraint_name.'" of the table "'.$table_name.'"');
+ }
+ if (!is_array($constraint['references']) || empty($constraint['references']['table'])) {
+ return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE, null, null,
+ 'it was not specified the referenced table of the foreign key "'.
+ $constraint_name.'" of the table "'.$table_name.'"');
+ }
+ if (!empty($constraint['match'])) {
+ $buffer .= " <match>".$constraint['match']."</match>$eol";
+ }
+ if (!empty($constraint['ondelete'])) {
+ $buffer .= " <ondelete>".$constraint['ondelete']."</ondelete>$eol";
+ }
+ if (!empty($constraint['onupdate'])) {
+ $buffer .= " <onupdate>".$constraint['onupdate']."</onupdate>$eol";
+ }
+ if (!empty($constraint['deferrable'])) {
+ $buffer .= " <deferrable>".$constraint['deferrable']."</deferrable>$eol";
+ }
+ if (!empty($constraint['initiallydeferred'])) {
+ $buffer .= " <initiallydeferred>".$constraint['initiallydeferred']."</initiallydeferred>$eol";
+ }
+ foreach ($constraint['fields'] as $field_name => $field) {
+ $buffer .= " <field>$field_name</field>$eol";
+ }
+ $buffer .= " <references>$eol <table>".$constraint['references']['table']."</table>$eol";
+ foreach ($constraint['references']['fields'] as $field_name => $field) {
+ $buffer .= " <field>$field_name</field>$eol";
+ }
+ $buffer .= " </references>$eol";
+
+ $buffer .= " </foreign>$eol";
+ }
+ }
+
+ $buffer .= "$eol </declaration>$eol";
+ }
+
+ if ($output) {
+ call_user_func($output, $buffer);
+ } else {
+ fwrite($fp, $buffer);
+ }
+
+ $buffer = '';
+ if ($dump == MDB2_SCHEMA_DUMP_ALL || $dump == MDB2_SCHEMA_DUMP_CONTENT) {
+ if (!empty($table['initialization']) && is_array($table['initialization'])) {
+ $buffer = "$eol <initialization>$eol";
+ foreach ($table['initialization'] as $instruction) {
+ switch ($instruction['type']) {
+ case 'insert':
+ $buffer .= "$eol <insert>$eol";
+ foreach ($instruction['data']['field'] as $field) {
+ $field_name = $field['name'];
+
+ $buffer .= "$eol <field>$eol <name>$field_name</name>$eol";
+ $buffer .= $this->writeExpression($field['group'], 5, $arguments);
+ $buffer .= " </field>$eol";
+ }
+ $buffer .= "$eol </insert>$eol";
+ break;
+ case 'update':
+ $buffer .= "$eol <update>$eol";
+ foreach ($instruction['data']['field'] as $field) {
+ $field_name = $field['name'];
+
+ $buffer .= "$eol <field>$eol <name>$field_name</name>$eol";
+ $buffer .= $this->writeExpression($field['group'], 5, $arguments);
+ $buffer .= " </field>$eol";
+ }
+
+ if (!empty($instruction['data']['where'])
+ && is_array($instruction['data']['where'])
+ ) {
+ $buffer .= " <where>$eol";
+ $buffer .= $this->writeExpression($instruction['data']['where'], 5, $arguments);
+ $buffer .= " </where>$eol";
+ }
+
+ $buffer .= "$eol </update>$eol";
+ break;
+ case 'delete':
+ $buffer .= "$eol <delete>$eol$eol";
+ if (!empty($instruction['data']['where'])
+ && is_array($instruction['data']['where'])
+ ) {
+ $buffer .= " <where>$eol";
+ $buffer .= $this->writeExpression($instruction['data']['where'], 5, $arguments);
+ $buffer .= " </where>$eol";
+ }
+ $buffer .= "$eol </delete>$eol";
+ break;
+ }
+ }
+ $buffer .= "$eol </initialization>$eol";
+ }
+ }
+ $buffer .= "$eol </table>$eol";
+ if ($output) {
+ call_user_func($output, $buffer);
+ } else {
+ fwrite($fp, $buffer);
+ }
+
+ if (isset($sequences[$table_name])) {
+ foreach ($sequences[$table_name] as $sequence) {
+ $result = $this->dumpSequence($database_definition['sequences'][$sequence],
+ $sequence, $eol, $dump);
+ if (PEAR::isError($result)) {
+ return $result;
+ }
+
+ if ($output) {
+ call_user_func($output, $result);
+ } else {
+ fwrite($fp, $result);
+ }
+ }
+ }
+ }
+ }
+
+ if (isset($sequences[''])) {
+ foreach ($sequences[''] as $sequence) {
+ $result = $this->dumpSequence($database_definition['sequences'][$sequence],
+ $sequence, $eol, $dump);
+ if (PEAR::isError($result)) {
+ return $result;
+ }
+
+ if ($output) {
+ call_user_func($output, $result);
+ } else {
+ fwrite($fp, $result);
+ }
+ }
+ }
+
+ $buffer = "$eol</database>$eol";
+ if ($output) {
+ call_user_func($output, $buffer);
+ } else {
+ fwrite($fp, $buffer);
+ fclose($fp);
+ }
+
+ return MDB2_OK;
+ }
+
+ // }}}
+ // {{{ writeExpression()
+
+ /**
+ * Dumps the structure of an element. Elements can be value, column,
+ * function or expression.
+ *
+ * @param array $element multi dimensional array that represents the parsed element
+ * of a DML instruction.
+ * @param integer $offset base indentation width
+ * @param array $arguments associative array that takes pairs of tag
+ * names and values that define dump options.
+ *
+ * @return string
+ *
+ * @access public
+ * @see MDB2_Schema_Writer::dumpDatabase()
+ */
+ function writeExpression($element, $offset = 0, $arguments = null)
+ {
+ $eol = isset($arguments['end_of_line']) ? $arguments['end_of_line'] : "\n";
+ $str = '';
+
+ $indent = str_repeat(' ', $offset);
+ $noffset = $offset + 1;
+
+ switch ($element['type']) {
+ case 'value':
+ $str .= "$indent<value>".$this->_escapeSpecialChars($element['data'])."</value>$eol";
+ break;
+ case 'column':
+ $str .= "$indent<column>".$this->_escapeSpecialChars($element['data'])."</column>$eol";
+ break;
+ case 'function':
+ $str .= "$indent<function>$eol$indent <name>".$this->_escapeSpecialChars($element['data']['name'])."</name>$eol";
+
+ if (!empty($element['data']['arguments'])
+ && is_array($element['data']['arguments'])
+ ) {
+ foreach ($element['data']['arguments'] as $v) {
+ $str .= $this->writeExpression($v, $noffset, $arguments);
+ }
+ }
+
+ $str .= "$indent</function>$eol";
+ break;
+ case 'expression':
+ $str .= "$indent<expression>$eol";
+ $str .= $this->writeExpression($element['data']['operants'][0], $noffset, $arguments);
+ $str .= "$indent <operator>".$element['data']['operator']."</operator>$eol";
+ $str .= $this->writeExpression($element['data']['operants'][1], $noffset, $arguments);
+ $str .= "$indent</expression>$eol";
+ break;
+ }
+ return $str;
+ }
+
+ // }}}
+}
+?>