Source for file Parser.php
Documentation is available at Parser.php
// +----------------------------------------------------------------------+
// | PHP versions 4 and 5 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1998-2004 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 |
// | 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: Christian Dickmann <dickmann@php.net> |
// +----------------------------------------------------------------------+
// $Id: Parser.php,v 1.25 2006/01/04 20:10:35 lsmith Exp $
require_once 'XML/Parser.php';
* Parses an XML schema file
* @author Christian Dickmann <dickmann@php.net>
function __construct($variables, $fail_on_invalid_names = true , $structure = false )
function MDB2_Schema_Parser($variables, $fail_on_invalid_names = true , $structure = false )
$this->__construct($variables, $fail_on_invalid_names, $structure);
case 'database-table-initialization-insert':
$this->init = array ('type' => 'insert');
case 'database-table-initialization-insert-field':
case 'database-table-declaration-field':
case 'database-table-declaration-field-default':
$this->field['default'] = '';
case 'database-table-declaration-index':
case 'database-sequence':
case 'database-table-declaration-index-field':
case 'database-table-initialization-insert-field':
$this->raiseError('field-name has to be specified', null , $xp);
case 'database-table-initialization-insert':
$this->table['initialization'][] = $this->init;
$this->raiseError('tables need names', null , $xp);
$autoinc = $primary = false;
$this->raiseError('tables need one or more fields', null , $xp);
foreach ($this->table['fields'] as $field_name => $field) {
$this->raiseError('there was already an autoincrement field in "'. $this->table_name. '" before "'. $field_name. '"', null , $xp);
$autoinc = $primary = true;
if (!$this->table['fields'][$field_name]['notnull']) {
$this->raiseError('all autoincrement fields must be defined notnull in "'. $this->table_name. '"', null , $xp);
$this->table['fields'][$field_name]['default'] = '0';
} elseif ($field['default'] !== '0' && $field['default'] !== 0 ) {
$this->raiseError('all autoincrement fields must be defined default "0" in "'. $this->table_name. '"', null , $xp);
foreach ($this->table['indexes'] as $name => $index) {
* Lets see if we should skip this index since there is
* already a auto increment on this field this implying
if ($autoinc && count($index['fields']) == '1') {
$this->raiseError('there was already an primary index or autoincrement field in "'. $this->table_name. '" before "'. $name. '"', null , $xp);
foreach ($index['fields'] as $field_name => $field) {
if (!isset ($this->table['fields'][$field_name])) {
$this->raiseError('index field "'. $field_name. '" does not exist', null , $xp);
if (!$this->table['fields'][$field_name]['notnull']) {
$this->raiseError('all primary key fields must be defined notnull in "'. $this->table_name. '"', null , $xp);
unset ($this->table['indexes'][$name]);
case 'database-table-declaration-field':
switch ($this->field['type']) {
$this->raiseError('unsigned has to be a boolean value', null , $xp);
$this->raiseError('length has to be an integer greater 0', null , $xp);
$this->raiseError('no valid field type ("'. $this->field['type']. '") specified', null , $xp);
$this->field['notnull'] = false;
$this->raiseError('field "notnull" has to be a boolean value', null , $xp);
&& $this->field['type'] != 'clob' && $this->field['type'] != 'blob'
$this->field['default'] = '';
$this->raiseError('field "unsigned" has to be a boolean value', null , $xp);
if ($this->field['type'] == 'clob' || $this->field['type'] == 'blob') {
'"-fields are not allowed to have a default value', null , $xp);
if ($this->field['default'] === '') {
if (!$this->field['notnull']) {
$this->field['default'] = null;
case 'database-table-declaration-index':
$this->raiseError('an index needs a name', null , $xp);
$this->raiseError('field "unique" has to be a boolean value', null , $xp);
$this->raiseError('field "primary" has to be a boolean value', null , $xp);
case 'database-table-declaration-index-field':
$this->raiseError('the index-field-name is required', null , $xp);
&& $this->field['sorting'] !== 'ascending' && $this->field['sorting'] !== 'descending') {
$this->raiseError('sorting type unknown', null , $xp);
$this->field['sorting'] = 'ascending';
case 'database-table-name':
/* Sequence declaration */
case 'database-sequence':
$this->raiseError('a sequence has to have a name', null , $xp);
if ((!isset ($this->seq['on']['table']) || !$this->seq['on']['table'])
|| (!isset ($this->seq['on']['field']) || !$this->seq['on']['field'])
'" was not properly defined', null , $xp);
$this->raiseError('field "create" has to be a boolean value', null , $xp);
$this->raiseError('field "overwrite" has to be a boolean value', null , $xp);
$this->raiseError('database needs a name', null , $xp);
&& !isset ($this->database_definition['tables'][$seq['on']['table']]['fields'][$seq['on']['field']])
'" was assigned on unexisting field/table', null , $xp);
if (PEAR ::isError ($this->error)) {
if (!isset ($this->table['fields'][$field_name])) {
return $this->raiseError('"'. $field_name. '" is not defined', null , $xp);
$field_def = $this->table['fields'][$field_name];
switch ($field_def['type']) {
return $this->raiseError('"'. $field_value. '" is not of type "'.
$field_def['type']. '"', null , $xp);
if (!preg_match('/^([0-9a-f]{2})*$/i', $field_value)) {
return $this->raiseError('"'.$field_value.'" is not of type "'.
$field_def['type'].'"', null, $xp);
$field_value = pack('H*', $field_value);
return $this->raiseError('"'. $field_value. '" is not of type "'.
$field_def['type']. '"', null , $xp);
if ($field_value != ((int) $field_value)) {
return $this->raiseError('"'. $field_value. '" is not of type "'.
$field_def['type']. '"', null , $xp);
$field_value = (int) $field_value;
if (array_key_exists('unsigned', $field_def) && $field_def['unsigned'] && $field_value < 0 ) {
return $this->raiseError('"'. $field_value. '" is not of type "'.
$field_def['type']. '"', null , $xp);
return $this->raiseError('"'. $field_value. '" is not of type "'.
$field_def['type']. '"', null , $xp);
if (!preg_match('/([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})/', $field_value)) {
return $this->raiseError('"'. $field_value. '" is not of type "'.
$field_def['type']. '"', null , $xp);
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)) {
return $this->raiseError('"'. $field_value. '" is not of type "'.
$field_def['type']. '"', null , $xp);
if (!preg_match("/([0-9]{2}):([0-9]{2}):([0-9]{2})/", $field_value)) {
return $this->raiseError('"'. $field_value. '" is not of type "'.
$field_def['type']. '"', null , $xp);
if ($field_value != (double) $field_value) {
return $this->raiseError('"'. $field_value. '" is not of type "'.
$field_def['type']. '"', null , $xp);
$field_value = (double) $field_value;
function &raiseError($msg = null , $ecode = 0 , $xp = null )
$error .= 'Parser error: '. $msg;
$error .= ' - '. $error_string;
$error .= " - Byte: $byte; Line: $line; Col: $column";
if ($value === 0 || $value === 1 ) {
$this->raiseError('variable "'. $data. '" not found', null , $xp);
case 'database-table-initialization-insert-field-name':
case 'database-table-initialization-insert-field-value':
case 'database-overwrite':
case 'database-table-name':
case 'database-table-was':
$this->table['was'] .= $data;
$this->table['was'] = $data;
case 'database-table-declaration-field-name':
case 'database-table-declaration-field-type':
$this->field['type'] .= $data;
$this->field['type'] = $data;
case 'database-table-declaration-field-was':
$this->field['was'] .= $data;
$this->field['was'] = $data;
case 'database-table-declaration-field-notnull':
$this->field['notnull'] .= $data;
$this->field['notnull'] = $data;
case 'database-table-declaration-field-unsigned':
$this->field['unsigned'] .= $data;
$this->field['unsigned'] = $data;
case 'database-table-declaration-field-autoincrement':
$this->field['autoincrement'] .= $data;
$this->field['autoincrement'] = $data;
case 'database-table-declaration-field-default':
$this->field['default'] .= $data;
$this->field['default'] = $data;
case 'database-table-declaration-field-length':
$this->field['length'] .= $data;
$this->field['length'] = $data;
case 'database-table-declaration-index-name':
case 'database-table-declaration-index-primary':
$this->index['primary'] .= $data;
$this->index['primary'] = $data;
case 'database-table-declaration-index-unique':
$this->index['unique'] .= $data;
$this->index['unique'] = $data;
case 'database-table-declaration-index-was':
$this->index['was'] .= $data;
$this->index['was'] = $data;
case 'database-table-declaration-index-field-name':
case 'database-table-declaration-index-field-sorting':
$this->field['sorting'] .= $data;
$this->field['sorting'] = $data;
case 'database-table-declaration-index-field-length':
$this->field['length'] .= $data;
$this->field['length'] = $data;
/* Sequence declaration */
case 'database-sequence-name':
case 'database-sequence-was':
$this->seq['was'] .= $data;
$this->seq['was'] = $data;
case 'database-sequence-start':
$this->seq['start'] .= $data;
$this->seq['start'] = $data;
case 'database-sequence-on-table':
if (isset ($this->seq['on']['table'])) {
$this->seq['on']['table'] .= $data;
$this->seq['on']['table'] = $data;
case 'database-sequence-on-field':
if (isset ($this->seq['on']['field'])) {
$this->seq['on']['field'] .= $data;
$this->seq['on']['field'] = $data;
Documentation generated on Mon, 11 Mar 2019 14:32:55 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|