Conflicts: inc/MDB2/Driver/Function/pgsql.php inc/MDB2/Driver/Manager/mysql.php inc/MDB2/Driver/Reverse/pgsql.php inc/MDB2/Driver/mysql.php inc/lib_base.phpremotes/origin/stable
commit
96e185f150
@ -0,0 +1,381 @@ |
||||
<?xml version="1.0" encoding="ISO-8859-1" ?> |
||||
<database> |
||||
|
||||
<name>*dbname*</name> |
||||
<create>true</create> |
||||
<overwrite>false</overwrite> |
||||
|
||||
<charset>latin1</charset> |
||||
|
||||
<table> |
||||
|
||||
<name>*dbprefix*groups</name> |
||||
|
||||
<declaration> |
||||
|
||||
<field> |
||||
<name>group_id</name> |
||||
<type>integer</type> |
||||
<default>0</default> |
||||
<notnull>true</notnull> |
||||
<autoincrement>1</autoincrement> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>group_name</name> |
||||
<type>text</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>64</length> |
||||
</field> |
||||
|
||||
<index> |
||||
<name>group_name</name> |
||||
<unique>true</unique> |
||||
<field> |
||||
<name>group_name</name> |
||||
<sorting>ascending</sorting> |
||||
</field> |
||||
</index> |
||||
|
||||
</declaration> |
||||
|
||||
</table> |
||||
|
||||
<table> |
||||
|
||||
<name>*dbprefix*locks</name> |
||||
|
||||
<declaration> |
||||
|
||||
<field> |
||||
<name>token</name> |
||||
<type>text</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>255</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>path</name> |
||||
<type>text</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>200</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>created</name> |
||||
<type>integer</type> |
||||
<default>0</default> |
||||
<notnull>true</notnull> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>modified</name> |
||||
<type>integer</type> |
||||
<default>0</default> |
||||
<notnull>true</notnull> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>expires</name> |
||||
<type>integer</type> |
||||
<default>0</default> |
||||
<notnull>true</notnull> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>owner</name> |
||||
<type>text</type> |
||||
<default></default> |
||||
<notnull>false</notnull> |
||||
<length>200</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>recursive</name> |
||||
<type>integer</type> |
||||
<default>0</default> |
||||
<notnull>false</notnull> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>writelock</name> |
||||
<type>integer</type> |
||||
<default>0</default> |
||||
<notnull>false</notnull> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>exclusivelock</name> |
||||
<type>integer</type> |
||||
<default>0</default> |
||||
<notnull>true</notnull> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
<index> |
||||
<name>path_2</name> |
||||
<field> |
||||
<name>path</name> |
||||
<sorting>ascending</sorting> |
||||
</field> |
||||
</index> |
||||
|
||||
<index> |
||||
<name>path_3</name> |
||||
<field> |
||||
<name>path</name> |
||||
<sorting>ascending</sorting> |
||||
</field> |
||||
<field> |
||||
<name>token</name> |
||||
<sorting>ascending</sorting> |
||||
</field> |
||||
</index> |
||||
|
||||
<index> |
||||
<name>expires</name> |
||||
<field> |
||||
<name>expires</name> |
||||
<sorting>ascending</sorting> |
||||
</field> |
||||
</index> |
||||
|
||||
<index> |
||||
<name>locks_pKey</name> |
||||
<primary>true</primary> |
||||
<field> |
||||
<name>token</name> |
||||
<sorting>ascending</sorting> |
||||
</field> |
||||
</index> |
||||
|
||||
<index> |
||||
<name>token</name> |
||||
<unique>true</unique> |
||||
<field> |
||||
<name>token</name> |
||||
<sorting>ascending</sorting> |
||||
</field> |
||||
</index> |
||||
|
||||
</declaration> |
||||
|
||||
</table> |
||||
|
||||
<table> |
||||
|
||||
<name>*dbprefix*log</name> |
||||
|
||||
<declaration> |
||||
|
||||
<field> |
||||
<name>id</name> |
||||
<type>integer</type> |
||||
<default>0</default> |
||||
<notnull>true</notnull> |
||||
<autoincrement>1</autoincrement> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>timestamp</name> |
||||
<type>integer</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>user</name> |
||||
<type>text</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>250</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>type</name> |
||||
<type>integer</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>message</name> |
||||
<type>text</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>250</length> |
||||
</field> |
||||
|
||||
</declaration> |
||||
|
||||
</table> |
||||
|
||||
<table> |
||||
|
||||
<name>*dbprefix*properties</name> |
||||
|
||||
<declaration> |
||||
|
||||
<field> |
||||
<name>path</name> |
||||
<type>text</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>255</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>name</name> |
||||
<type>text</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>120</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>ns</name> |
||||
<type>text</type> |
||||
<default>DAV:</default> |
||||
<notnull>true</notnull> |
||||
<length>120</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>value</name> |
||||
<type>clob</type> |
||||
<notnull>false</notnull> |
||||
</field> |
||||
|
||||
<index> |
||||
<name>path</name> |
||||
<field> |
||||
<name>path</name> |
||||
<sorting>ascending</sorting> |
||||
</field> |
||||
</index> |
||||
|
||||
<index> |
||||
<name>properties_pKey</name> |
||||
<primary>true</primary> |
||||
<field> |
||||
<name>path</name> |
||||
<sorting>ascending</sorting> |
||||
</field> |
||||
<field> |
||||
<name>name</name> |
||||
<sorting>ascending</sorting> |
||||
</field> |
||||
<field> |
||||
<name>ns</name> |
||||
<sorting>ascending</sorting> |
||||
</field> |
||||
</index> |
||||
|
||||
</declaration> |
||||
|
||||
</table> |
||||
|
||||
<table> |
||||
|
||||
<name>*dbprefix*user_group</name> |
||||
|
||||
<declaration> |
||||
|
||||
<field> |
||||
<name>user_group_id</name> |
||||
<type>integer</type> |
||||
<default>0</default> |
||||
<notnull>true</notnull> |
||||
<autoincrement>1</autoincrement> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>user_id</name> |
||||
<type>integer</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>group_id</name> |
||||
<type>integer</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
</declaration> |
||||
|
||||
</table> |
||||
|
||||
<table> |
||||
|
||||
<name>*dbprefix*users</name> |
||||
|
||||
<declaration> |
||||
|
||||
<field> |
||||
<name>user_id</name> |
||||
<type>integer</type> |
||||
<default>0</default> |
||||
<notnull>true</notnull> |
||||
<autoincrement>1</autoincrement> |
||||
<length>4</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>user_name</name> |
||||
<type>text</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>64</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>user_name_clean</name> |
||||
<type>text</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>64</length> |
||||
</field> |
||||
|
||||
<field> |
||||
<name>user_password</name> |
||||
<type>text</type> |
||||
<default></default> |
||||
<notnull>true</notnull> |
||||
<length>340</length> |
||||
</field> |
||||
|
||||
<index> |
||||
<name>user_name</name> |
||||
<unique>true</unique> |
||||
<field> |
||||
<name>user_name</name> |
||||
<sorting>ascending</sorting> |
||||
</field> |
||||
<field> |
||||
<name>user_name_clean</name> |
||||
<sorting>ascending</sorting> |
||||
</field> |
||||
</index> |
||||
|
||||
</declaration> |
||||
|
||||
</table> |
||||
|
||||
</database> |
||||
@ -0,0 +1,11 @@ |
||||
<?php |
||||
$token=$_GET['token']; |
||||
|
||||
$file=sys_get_temp_dir().'/'.'remoteCloudFile'.$token; |
||||
if(file_exists($file) and is_readable($file) and is_writable($file)){ |
||||
readfile($file); |
||||
unlink($file); |
||||
}else{ |
||||
header("HTTP/1.0 404 Not Found"); |
||||
} |
||||
?> |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,819 @@ |
||||
<?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 |
||||
*/ |
||||
|
||||
|
||||
oc_require_once('XML/Parser.php'); |
||||
oc_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::XML_Parser('ISO-8859-1'); |
||||
|
||||
$this->variables = $variables; |
||||
$this->structure = $structure; |
||||
$this->val =new MDB2_Schema_Validate($fail_on_invalid_names, $valid_types, $force_defaults); |
||||
} |
||||
|
||||
function MDB2_Schema_Parser($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 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) |
||||
{ |
||||
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; |
||||
} |
||||
} |
||||
} |
||||
|
||||
?> |
||||
@ -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; |
||||
} |
||||
} |
||||
|
||||
?> |
||||
@ -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', |
||||
); |
||||
// }}} |
||||
?> |
||||
@ -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', |
||||
); |
||||
//}}} |
||||
|
||||
?> |
||||
@ -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', |
||||
); |
||||
// }}} |
||||
?> |
||||
@ -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', |
||||
); |
||||
// }}} |
||||
|
||||
?> |
||||
@ -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' |
||||
); |
||||
// }}} |
||||
?> |
||||
|
||||
@ -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 |
||||
|
||||
?> |
||||
@ -0,0 +1,6 @@ |
||||
<?php |
||||
|
||||
class MDB2_Schema_Tool_ParameterException extends Exception |
||||
{} |
||||
|
||||
?> |
||||
@ -0,0 +1,922 @@ |
||||
<?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; |
||||
} |
||||
|
||||
function MDB2_Schema_Validate($fail_on_invalid_names = true, $valid_types = array(), $force_defaults = true) |
||||
{ |
||||
$this->__construct($fail_on_invalid_names, $valid_types, $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; |
||||
} |
||||
} |
||||
|
||||
?> |
||||
@ -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 .= '&'; |
||||
break; |
||||
case '>': |
||||
$escaped .= '>'; |
||||
break; |
||||
case '<': |
||||
$escaped .= '<'; |
||||
break; |
||||
case '"': |
||||
$escaped .= '"'; |
||||
break; |
||||
case '\'': |
||||
$escaped .= '''; |
||||
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; |
||||
} |
||||
|
||||
// }}} |
||||
} |
||||
?> |
||||
@ -0,0 +1,353 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* ownCloud |
||||
* |
||||
* @author Frank Karlitschek |
||||
* @copyright 2010 Frank Karlitschek karlitschek@kde.org |
||||
* |
||||
* This library is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
* License as published by the Free Software Foundation; either |
||||
* version 3 of the License, or any later version. |
||||
* |
||||
* This library is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
class OC_FILESTORAGE_REMOTE extends OC_FILESTORAGE{ |
||||
private $url; |
||||
private $username; |
||||
private $password; |
||||
private $remote=false; |
||||
private $statCache; |
||||
private $statCacheDir=false; |
||||
private $changed=array(); |
||||
|
||||
private function cacheDir($dir){ |
||||
if($this->statCacheDir!=$dir or $this->statCacheDir===false){ |
||||
$this->statCache=$this->remote->getFiles($dir); |
||||
$keys=array_keys($this->statCache); |
||||
$this->statCacheDir=$dir; |
||||
} |
||||
} |
||||
|
||||
public function __construct($arguments){ |
||||
$this->url=$arguments['url']; |
||||
$this->username=$arguments['username']; |
||||
$this->password=$arguments['password']; |
||||
} |
||||
private function connect(){ |
||||
if($this->remote===false){ |
||||
$this->remote=OC_CONNECT::connect($this->url,$this->username,$this->password); |
||||
} |
||||
} |
||||
public function mkdir($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$return=$this->remote->newFile($parent,$name,'dir'); |
||||
if($return){ |
||||
$this->notifyObservers($path,OC_FILEACTION_CREATE); |
||||
} |
||||
return $return; |
||||
} |
||||
public function rmdir($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$return=$this->remote->delete($parent,$name); |
||||
if($return){ |
||||
$this->notifyObservers($path,OC_FILEACTION_DELETE); |
||||
} |
||||
return $return; |
||||
} |
||||
public function opendir($path){ |
||||
$this->connect(); |
||||
$this->cacheDir($path); |
||||
$dirs=array_keys($this->statCache); |
||||
$id=uniqid(); |
||||
global $FAKEDIRS; |
||||
$FAKEDIRS[$id]=$dirs; |
||||
if($return=opendir("fakedir://$id")){ |
||||
$this->notifyObservers($path,OC_FILEACTION_READ); |
||||
} |
||||
return $return; |
||||
} |
||||
public function is_dir($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$this->cacheDir($path); |
||||
if($path=='' or $path=='/'){ |
||||
return true; |
||||
} |
||||
if(!isset($this->statCache[$name])){ |
||||
return false; |
||||
} |
||||
return ($this->statCache[$name]['type'=='dir']); |
||||
} |
||||
public function is_file($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$this->cacheDir($parent); |
||||
if(!isset($this->statCache[$name])){ |
||||
return false; |
||||
} |
||||
return ($this->statCache[$name]['type'!='dir']); |
||||
} |
||||
public function stat($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$this->cacheDir($parent); |
||||
if(!isset($this->statCache[$name])){ |
||||
return $false; |
||||
} |
||||
return $this->statCache[$name]; |
||||
} |
||||
public function filetype($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$this->cacheDir($parent); |
||||
if(!isset($this->statCache[$name])){ |
||||
return false; |
||||
} |
||||
return $this->statCache[$name]['type']; |
||||
} |
||||
public function filesize($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$this->cacheDir($parent); |
||||
if(!isset($this->statCache[$name])){ |
||||
return $false; |
||||
} |
||||
return $this->statCache[$name]['size']; |
||||
} |
||||
public function is_readable($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$this->cacheDir($parent); |
||||
if(!isset($this->statCache[$name])){ |
||||
return false; |
||||
} |
||||
return $this->statCache[$name]['readable']; |
||||
} |
||||
public function is_writeable($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$this->cacheDir($parent); |
||||
if(!isset($this->statCache[$name])){ |
||||
return false; |
||||
} |
||||
return $this->statCache[$name]['writeable']; |
||||
} |
||||
public function file_exists($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$this->cacheDir($parent); |
||||
return isset($this->statCache[$name]); |
||||
} |
||||
public function readfile($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$file=$this->remote->getFile($parent,$name); |
||||
readfile($file); |
||||
unlink($file); |
||||
} |
||||
public function filectime($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$this->cacheDir($parent); |
||||
if(!isset($this->statCache[$name])){ |
||||
return false; |
||||
} |
||||
return $this->statCache[$name]['ctime']; |
||||
} |
||||
public function filemtime($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$this->cacheDir($parent); |
||||
if(!isset($this->statCache[$name])){ |
||||
return false; |
||||
} |
||||
return $this->statCache[$name]['mtime']; |
||||
} |
||||
public function fileatime($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$this->cacheDir($parent); |
||||
if(!isset($this->statCache[$name])){ |
||||
return false; |
||||
} |
||||
return $this->statCache[$name]['atime']; |
||||
} |
||||
public function file_get_contents($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$file=$this->remote->getFile($parent,$name); |
||||
file_get_contents($file); |
||||
unlink($file); |
||||
} |
||||
public function file_put_contents($path,$data){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$file=$this->remote->getFile($parent,$name); |
||||
$file=tempnam(sys_get_temp_dir(),'oc_'); |
||||
file_put_contents($file,$data); |
||||
if($return=$this->remote->sendTmpFile($file,$parent,$name)){ |
||||
$this->notifyObservers($path,OC_FILEACTION_WRITE); |
||||
} |
||||
} |
||||
public function unlink($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
if($return=$this->remote->delete($paren,$name)){ |
||||
$this->notifyObservers($path,OC_FILEACTION_DELETE); |
||||
} |
||||
return $return; |
||||
} |
||||
public function rename($path1,$path2){ |
||||
$this->connect(); |
||||
$parent1=dirname($path1); |
||||
$name1=substr($path1,strlen($parent1)+1); |
||||
$parent2=dirname($path2); |
||||
$name2=substr($path2,strlen($parent2)+1); |
||||
if($return=$this->remote->move($parent1,$name1,$parent2,$name2)){ |
||||
$this->notifyObservers($path1.'->'.$path2,OC_FILEACTION_RENAME); |
||||
} |
||||
return $return; |
||||
} |
||||
public function copy($path1,$path2){ |
||||
$this->connect(); |
||||
$parent1=dirname($path1); |
||||
$name1=substr($path1,strlen($parent1)+1); |
||||
$parent2=dirname($path2); |
||||
$name2=substr($path2,strlen($parent2)+1); |
||||
if($return=$this->copy->rename($parent1,$name1,$parent2,$name2)){ |
||||
$this->notifyObservers($path1.'->'.$path2,OC_FILEACTION_RENAME); |
||||
} |
||||
return $return; |
||||
} |
||||
public function fopen($path,$mode){ |
||||
$this->connect(); |
||||
$changed=false; |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
$file=$this->remote->getFile($parent,$name); |
||||
if($return=fopen($file,$mode)){ |
||||
switch($mode){ |
||||
case 'r': |
||||
$this->notifyObservers($path,OC_FILEACTION_READ); |
||||
break; |
||||
case 'r+': |
||||
case 'w+': |
||||
case 'x+': |
||||
case 'a+': |
||||
$this->notifyObservers($path,OC_FILEACTION_READ | OC_FILEACTION_WRITE); |
||||
$this->changed[]=array('dir'=>$parent,'file'=>$name,'tmp'=>$file); |
||||
break; |
||||
case 'w': |
||||
case 'x': |
||||
case 'a': |
||||
$this->notifyObservers($path,OC_FILEACTION_WRITE); |
||||
$this->changed[]=array('dir'=>$parent,'file'=>$name,'tmp'=>$file); |
||||
break; |
||||
} |
||||
} |
||||
return $return; |
||||
} |
||||
|
||||
public function getMimeType($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
if(substr($name,0,1)=='/'){ |
||||
$name=substr($name,1); |
||||
} |
||||
$this->cacheDir($parent); |
||||
if(!isset($this->statCache[$name])){ |
||||
return false; |
||||
} |
||||
return $this->statCache[$name]['mime']; |
||||
} |
||||
|
||||
public function toTmpFile($path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
if(substr($name,0,1)=='/'){ |
||||
$name=substr($name,1); |
||||
} |
||||
$filename=$this->remote->getFile($parent,$name); |
||||
if($filename){ |
||||
$this->notifyObservers($path,OC_FILEACTION_READ); |
||||
return $filename; |
||||
}else{ |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public function fromTmpFile($tmpFile,$path){ |
||||
$this->connect(); |
||||
$parent=dirname($path); |
||||
$name=substr($path,strlen($parent)+1); |
||||
if($this->remote->sendTmpFile($tmpFile,$parent,$name)){ |
||||
$this->notifyObservers($path,OC_FILEACTION_CREATE); |
||||
return true; |
||||
}else{ |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public function delTree($dir) { |
||||
$this->connect(); |
||||
$parent=dirname($dir); |
||||
$name=substr($dir,strlen($parent)+1); |
||||
$return=$this->remote->delete($parent,$name); |
||||
if($return=rmdir($dir)){ |
||||
$this->notifyObservers($dir,OC_FILEACTION_DELETE); |
||||
} |
||||
return $return; |
||||
} |
||||
|
||||
public function find($path){ |
||||
return $this->getTree($path); |
||||
} |
||||
|
||||
public function getTree($dir) { |
||||
$this->connect(); |
||||
if($return=$this->remote->getTree($dir)){ |
||||
$this->notifyObservers($dir,OC_FILEACTION_READ); |
||||
} |
||||
return $return; |
||||
} |
||||
|
||||
public function __destruct(){ |
||||
foreach($this->changed as $changed){ |
||||
$this->remote->sendTmpFile($changed['tmp'],$changed['dir'],$changed['file']); |
||||
} |
||||
} |
||||
} |
||||
|
||||
?> |
||||
Loading…
Reference in new issue