Merge git://gitorious.org/~icewind/owncloud/icewinds-owncloud into merge

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.php
This commit is contained in:
Robin Appelman 2010-07-09 13:43:40 +02:00
commit 96e185f150
48 changed files with 8837 additions and 263 deletions

0
.gitignore vendored Normal file → Executable file
View file

0
config/.gitignore vendored Normal file → Executable file
View file

View file

@ -8,4 +8,5 @@ $CONFIG_DBHOST='localhost';
$CONFIG_DBNAME='owncloud-db-name';
$CONFIG_DBUSER='user-name';
$CONFIG_DBPASSWORD='password';
$CONFIG_DBTABLEPREFIX = 'oc_';
?>

0
css/small.php Normal file → Executable file
View file

381
db_structure.xml Executable file
View file

@ -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>

View file

@ -55,6 +55,9 @@ if($arguments['action']){
case 'getfiles':
echo json_encode(OC_FILES::getdirectorycontent($arguments['dir']));
break;
case 'gettree':
echo json_encode(OC_FILES::getTree($arguments['dir']));
break;
case 'find':
echo json_encode(OC_FILESYSTEM::find($arguments['path']));
break;
@ -72,6 +75,8 @@ if($arguments['action']){
echo 'false';
}
break;
case 'pull':
return OC_FILES::pull($arguments['source'],$arguments['token'],$arguments['dir'],$arguments['file']);
}
}

11
files/pull.php Normal file
View file

@ -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");
}
?>

View file

@ -150,6 +150,8 @@
*/
function fileinfo($path)
{
global $CONFIG_DBTABLEPREFIX;
// map URI path to filesystem path
$fspath =$path;
@ -183,7 +185,7 @@
$info["props"][] = $this->mkprop("getcontentlength", OC_FILESYSTEM::filesize($fspath));
}
// get additional properties from database
$query = "SELECT ns, name, value FROM properties WHERE path = '$path'";
$query = "SELECT ns, name, value FROM {$CONFIG_DBTABLEPREFIX}properties WHERE path = '$path'";
$res = OC_DB::select($query);
foreach($res as $row){
$info["props"][] = $this->mkprop($row["ns"], $row["name"], $row["value"]);
@ -389,6 +391,7 @@
*/
function DELETE($options)
{
global $CONFIG_DBTABLEPREFIX;
$path =$options["path"];
if (!OC_FILESYSTEM::file_exists($path)) {
return "404 Not found";
@ -402,13 +405,13 @@
}
}
if (OC_FILESYSTEM::is_dir($path)) {
$query = "DELETE FROM properties WHERE path LIKE '".$this->_slashify($options["path"])."%'";
$query = "DELETE FROM {$CONFIG_DBTABLEPREFIX}properties WHERE path LIKE '".$this->_slashify($options["path"])."%'";
OC_DB::query($query);
OC_FILESYSTEM::delTree($path);
} else {
OC_FILESYSTEM::unlink($path);
}
$query = "DELETE FROM properties WHERE path = '$options[path]'";
$query = "DELETE FROM {$CONFIG_DBTABLEPREFIX}properties WHERE path = '$options[path]'";
OC_DB::query($query);
return "204 No Content";
@ -435,6 +438,7 @@
function COPY($options, $del=false)
{
// TODO Property updates still broken (Litmus should detect this?)
global $CONFIG_DBTABLEPREFIX;
if (!empty($this->_SERVER["CONTENT_LENGTH"])) { // no body parsing yet
return "415 Unsupported media type";
@ -508,13 +512,13 @@
}
$destpath = $this->_unslashify($options["dest"]);
if (is_dir($source)) {
$query = "UPDATE properties
$query = "UPDATE {$CONFIG_DBTABLEPREFIX}properties
SET path = REPLACE(path, '".$options["path"]."', '".$destpath."')
WHERE path LIKE '".$this->_slashify($options["path"])."%'";
OC_DB::query($query);
}
$query = "UPDATE properties
$query = "UPDATE {$CONFIG_DBTABLEPREFIX}properties
SET path = '".$destpath."'
WHERE path = '".$options["path"]."'";
OC_DB::query($query);
@ -566,6 +570,7 @@
function PROPPATCH(&$options)
{
global $prefs, $tab;
global $CONFIG_DBTABLEPREFIX;
$msg = "";
$path = $options["path"];
@ -577,9 +582,9 @@
$options["props"][$key]['status'] = "403 Forbidden";
} else {
if (isset($prop["val"])) {
$query = "REPLACE INTO properties SET path = '$options[path]', name = '$prop[name]', ns= '$prop[ns]', value = '$prop[val]'";
$query = "REPLACE INTO {$CONFIG_DBTABLEPREFIX}properties SET path = '$options[path]', name = '$prop[name]', ns= '$prop[ns]', value = '$prop[val]'";
} else {
$query = "DELETE FROM properties WHERE path = '$options[path]' AND name = '$prop[name]' AND ns = '$prop[ns]'";
$query = "DELETE FROM {$CONFIG_DBTABLEPREFIX}properties WHERE path = '$options[path]' AND name = '$prop[name]' AND ns = '$prop[ns]'";
}
OC_DB::query($query);
}
@ -597,6 +602,8 @@
*/
function LOCK(&$options)
{
global $CONFIG_DBTABLEPREFIX;
// get absolute fs path to requested resource
$fspath = $options["path"];
// TODO recursive locks on directories not supported yet
@ -619,12 +626,12 @@
if (isset($options["update"])) { // Lock Update
$where = "WHERE path = '$options[path]' AND token = '$options[update]'";
$query = "SELECT owner, exclusivelock FROM locks $where";
$query = "SELECT owner, exclusivelock FROM {$CONFIG_DBTABLEPREFIX}locks $where";
$res = OC_DB::select($query);
if (is_array($res) and isset($res[0])) {
$row=$res[0];
$query = "UPDATE `locks` SET `expires` = '$options[timeout]', `modified` = ".time()." $where";
$query = "UPDATE `{$CONFIG_DBTABLEPREFIX}locks` SET `expires` = '$options[timeout]', `modified` = ".time()." $where";
OC_DB::query($query);
$options['owner'] = $row['owner'];
@ -634,14 +641,14 @@
return true;
} else {//check for indirect refresh
$query = "SELECT *
FROM locks
FROM {$CONFIG_DBTABLEPREFIX}locks
WHERE recursive = 1
";
$res = OC_DB::select($query);
foreach($res as $row){
if(strpos($options['path'],$row['path'])==0){//are we a child of a folder with an recursive lock
$where = "WHERE path = '$row[path]' AND token = '$options[update]'";
$query = "UPDATE `locks` SET `expires` = '$options[timeout]', `modified` = ".time()." $where";
$query = "UPDATE `{$CONFIG_DBTABLEPREFIX}locks` SET `expires` = '$options[timeout]', `modified` = ".time()." $where";
OC_DB::query($query);
$options['owner'] = $row['owner'];
$options['scope'] = $row["exclusivelock"] ? "exclusive" : "shared";
@ -652,7 +659,7 @@
}
}
$query = "INSERT INTO `locks`
$query = "INSERT INTO `{$CONFIG_DBTABLEPREFIX}locks`
SET `token` = '$options[locktoken]'
, `path` = '$options[path]'
, `created` = ".time()."
@ -677,7 +684,8 @@
*/
function UNLOCK(&$options)
{
$query = "DELETE FROM locks
global $CONFIG_DBTABLEPREFIX;
$query = "DELETE FROM {$CONFIG_DBTABLEPREFIX}locks
WHERE path = '$options[path]'
AND token = '$options[token]'";
OC_DB::query($query);
@ -693,9 +701,11 @@
*/
function checkLock($path)
{
global $CONFIG_DBTABLEPREFIX;
$result = false;
$query = "SELECT *
FROM locks
FROM {$CONFIG_DBTABLEPREFIX}locks
WHERE path = '$path'
";
$res = OC_DB::select($query);
@ -717,7 +727,7 @@
}else{
//check for recursive locks;
$query = "SELECT *
FROM locks
FROM {$CONFIG_DBTABLEPREFIX}locks
WHERE recursive = 1
";
$res = OC_DB::select($query);
@ -741,4 +751,4 @@
}
}
?>
?>

View file

@ -329,11 +329,10 @@ class MDB2
{
if (!MDB2::classExists($class_name)) {
$file_name = str_replace('_', DIRECTORY_SEPARATOR, $class_name).'.php';
// echo $file_name;
if ($debug) {
$include = oc_include_once($file_name);
} else {
$include = @oc_include_once($file_name);
$include = oc_include_once($file_name);
}
if (!$include) {
if (!MDB2::fileExists($file_name)) {
@ -958,8 +957,12 @@ class MDB2
function fileExists($file)
{
// safe_mode does notwork with is_readable()
global $SERVERROOT;
if (!@ini_get('safe_mode')) {
$dirs = explode(PATH_SEPARATOR, ini_get('include_path'));
$dirs[]=$SERVERROOT;
$dirs[]=$SERVERROOT. DIRECTORY_SEPARATOR .'inc';
// print_r($dirs);die();
foreach ($dirs as $dir) {
if (is_readable($dir . DIRECTORY_SEPARATOR . $file)) {
return true;
@ -1920,7 +1923,6 @@ class MDB2_Driver_Common extends PEAR
if (PEAR::isError($err)) {
return $err;
}
// load module in a specific version
if ($version) {
if (method_exists($class_name, 'getClassName')) {

View file

@ -44,7 +44,7 @@
//
// $Id: Common.php,v 1.139 2008/12/04 11:50:42 afz Exp $
require_once 'MDB2/LOB.php';
oc_require_once('MDB2/LOB.php');
/**
* @package MDB2

View file

@ -46,7 +46,7 @@
// $Id: mysql.php,v 1.65 2008/02/22 19:23:49 quipo Exp $
//
require_once 'MDB2/Driver/Datatype/Common.php';
oc_require_once('MDB2/Driver/Datatype/Common.php');
/**
* MDB2 MySQL driver

View file

@ -44,7 +44,7 @@
//
// $Id: pgsql.php,v 1.93 2008/08/28 20:32:57 afz Exp $
require_once 'MDB2/Driver/Datatype/Common.php';
oc_require_once('MDB2/Driver/Datatype/Common.php');
/**
* MDB2 PostGreSQL driver

View file

@ -46,7 +46,7 @@
// $Id: sqlite.php,v 1.67 2008/02/22 19:58:06 quipo Exp $
//
require_once 'MDB2/Driver/Datatype/Common.php';
oc_require_once('MDB2/Driver/Datatype/Common.php');
/**
* MDB2 SQLite driver

View file

@ -45,7 +45,7 @@
// $Id: mysql.php,v 1.12 2008/02/17 18:54:08 quipo Exp $
//
require_once 'MDB2/Driver/Function/Common.php';
oc_require_once('MDB2/Driver/Function/Common.php');
/**
* MDB2 MySQL driver for the function modules

View file

@ -44,7 +44,7 @@
//
// $Id: pgsql.php,v 1.11 2008/11/09 19:46:50 quipo Exp $
require_once 'MDB2/Driver/Function/Common.php';
oc_require_once('MDB2/Driver/Function/Common.php');
/**
* MDB2 MySQL driver for the function modules

View file

@ -45,7 +45,7 @@
// $Id: sqlite.php,v 1.10 2008/02/17 18:54:08 quipo Exp $
//
require_once 'MDB2/Driver/Function/Common.php';
oc_require_once('MDB2/Driver/Function/Common.php');
/**
* MDB2 SQLite driver for the function modules

View file

@ -45,7 +45,7 @@
// $Id: mysql.php,v 1.113 2008/11/23 20:30:29 quipo Exp $
//
require_once 'MDB2/Driver/Manager/Common.php';
oc_require_once('MDB2/Driver/Manager/Common.php');
/**
* MDB2 MySQL driver for the management modules

View file

@ -44,7 +44,7 @@
//
// $Id: pgsql.php,v 1.87 2008/11/29 14:09:59 afz Exp $
require_once 'MDB2/Driver/Manager/Common.php';
oc_require_once('MDB2/Driver/Manager/Common.php');
/**
* MDB2 MySQL driver for the management modules

View file

@ -46,7 +46,7 @@
// $Id: sqlite.php,v 1.76 2008/05/31 11:48:48 quipo Exp $
//
require_once 'MDB2/Driver/Manager/Common.php';
oc_require_once('MDB2/Driver/Manager/Common.php');
/**
* MDB2 SQLite driver for the management modules

View file

@ -45,7 +45,7 @@
// $Id: mysql.php,v 1.80 2008/03/26 21:15:37 quipo Exp $
//
require_once 'MDB2/Driver/Reverse/Common.php';
oc_require_once('MDB2/Driver/Reverse/Common.php');
/**
* MDB2 MySQL driver for the schema reverse engineering module

View file

@ -45,7 +45,7 @@
//
// $Id: pgsql.php,v 1.75 2008/08/22 16:36:20 quipo Exp $
require_once 'MDB2/Driver/Reverse/Common.php';
oc_require_once('MDB2/Driver/Reverse/Common.php');
/**
* MDB2 PostGreSQL driver for the schema reverse engineering module

View file

@ -46,7 +46,7 @@
// $Id: sqlite.php,v 1.80 2008/05/03 10:30:14 quipo Exp $
//
require_once 'MDB2/Driver/Reverse/Common.php';
oc_require_once('MDB2/Driver/Reverse/Common.php');
/**
* MDB2 SQlite driver for the schema reverse engineering module

View file

@ -1406,7 +1406,7 @@ class MDB2_Result_mysql extends MDB2_Result_Common
if ($object_class == 'stdClass') {
$row = (object) $row;
} else {
$row = &new $object_class($row);
$row = new $object_class($row);
}
}
++$this->rownum;

View file

@ -50,7 +50,7 @@
* @author Lukas Smith <smith@pooteeweet.org>
*/
require_once 'MDB2.php';
oc_require_once('MDB2.php');
/**
* MDB2_LOB: user land stream wrapper implementation for LOB support

2763
inc/MDB2/Schema.php Normal file

File diff suppressed because it is too large Load diff

819
inc/MDB2/Schema/Parser.php Normal file
View file

@ -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;
}
}
}
?>

624
inc/MDB2/Schema/Parser2.php Normal file
View file

@ -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;
}
}
?>

View file

@ -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',
);
// }}}
?>

View file

@ -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',
);
//}}}
?>

View file

@ -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',
);
// }}}
?>

View file

@ -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',
);
// }}}
?>

View file

@ -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'
);
// }}}
?>

560
inc/MDB2/Schema/Tool.php Normal file
View file

@ -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
?>

View file

@ -0,0 +1,6 @@
<?php
class MDB2_Schema_Tool_ParameterException extends Exception
{}
?>

View file

@ -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;
}
}
?>

581
inc/MDB2/Schema/Writer.php Normal file
View file

@ -0,0 +1,581 @@
<?php
/**
* PHP versions 4 and 5
*
* Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox,
* Stig. S. Bakken, Lukas Smith, Igor Feghali
* All rights reserved.
*
* MDB2_Schema enables users to maintain RDBMS independant schema files
* in XML that can be used to manipulate both data and database schemas
* This LICENSE is in the BSD license style.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,
* Lukas Smith, Igor Feghali nor the names of his contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Author: Lukas Smith <smith@pooteeweet.org>
* Author: Igor Feghali <ifeghali@php.net>
*
* @category Database
* @package MDB2_Schema
* @author Lukas Smith <smith@pooteeweet.org>
* @author Igor Feghali <ifeghali@php.net>
* @license BSD http://www.opensource.org/licenses/bsd-license.php
* @version CVS: $Id: Writer.php,v 1.40 2008/11/30 03:34:00 clockwerx Exp $
* @link http://pear.php.net/packages/MDB2_Schema
*/
/**
* Writes an XML schema file
*
* @category Database
* @package MDB2_Schema
* @author Lukas Smith <smith@pooteeweet.org>
* @license BSD http://www.opensource.org/licenses/bsd-license.php
* @link http://pear.php.net/packages/MDB2_Schema
*/
class MDB2_Schema_Writer
{
// {{{ properties
var $valid_types = array();
// }}}
// {{{ constructor
function __construct($valid_types = array())
{
$this->valid_types = $valid_types;
}
function MDB2_Schema_Writer($valid_types = array())
{
$this->__construct($valid_types);
}
// }}}
// {{{ raiseError()
/**
* This method is used to communicate an error and invoke error
* callbacks etc. Basically a wrapper for PEAR::raiseError
* without the message string.
*
* @param int|PEAR_Error $code integer error code or and PEAR_Error instance
* @param int $mode error mode, see PEAR_Error docs
* error level (E_USER_NOTICE etc). If error mode is
* PEAR_ERROR_CALLBACK, this is the callback function,
* either as a function name, or as an array of an
* object and method name. For other error modes this
* parameter is ignored.
* @param string $options Extra debug information. Defaults to the last
* query and native error code.
*
* @return object a PEAR error object
* @access public
* @see PEAR_Error
*/
function &raiseError($code = null, $mode = null, $options = null, $userinfo = null)
{
$error =& MDB2_Schema::raiseError($code, $mode, $options, $userinfo);
return $error;
}
// }}}
// {{{ _escapeSpecialChars()
/**
* add escapecharacters to all special characters in a string
*
* @param string $string string that should be escaped
*
* @return string escaped string
* @access protected
*/
function _escapeSpecialChars($string)
{
if (!is_string($string)) {
$string = strval($string);
}
$escaped = '';
for ($char = 0, $count = strlen($string); $char < $count; $char++) {
switch ($string[$char]) {
case '&':
$escaped .= '&amp;';
break;
case '>':
$escaped .= '&gt;';
break;
case '<':
$escaped .= '&lt;';
break;
case '"':
$escaped .= '&quot;';
break;
case '\'':
$escaped .= '&apos;';
break;
default:
$code = ord($string[$char]);
if ($code < 32 || $code > 127) {
$escaped .= "&#$code;";
} else {
$escaped .= $string[$char];
}
break;
}
}
return $escaped;
}
// }}}
// {{{ _dumpBoolean()
/**
* dump the structure of a sequence
*
* @param string $boolean boolean value or variable definition
*
* @return string with xml boolea definition
* @access private
*/
function _dumpBoolean($boolean)
{
if (is_string($boolean)) {
if ($boolean !== 'true' || $boolean !== 'false'
|| preg_match('/<variable>.*</variable>/', $boolean)
) {
return $boolean;
}
}
return $boolean ? 'true' : 'false';
}
// }}}
// {{{ dumpSequence()
/**
* dump the structure of a sequence
*
* @param string $sequence_definition sequence definition
* @param string $sequence_name sequence name
* @param string $eol end of line characters
* @param integer $dump determines what data to dump
* MDB2_SCHEMA_DUMP_ALL : the entire db
* MDB2_SCHEMA_DUMP_STRUCTURE : only the structure of the db
* MDB2_SCHEMA_DUMP_CONTENT : only the content of the db
*
* @return mixed string xml sequence definition on success, or a error object
* @access public
*/
function dumpSequence($sequence_definition, $sequence_name, $eol, $dump = MDB2_SCHEMA_DUMP_ALL)
{
$buffer = "$eol <sequence>$eol <name>$sequence_name</name>$eol";
if ($dump == MDB2_SCHEMA_DUMP_ALL || $dump == MDB2_SCHEMA_DUMP_CONTENT) {
if (!empty($sequence_definition['start'])) {
$start = $sequence_definition['start'];
$buffer .= " <start>$start</start>$eol";
}
}
if (!empty($sequence_definition['on'])) {
$buffer .= " <on>$eol";
$buffer .= " <table>".$sequence_definition['on']['table'];
$buffer .= "</table>$eol <field>".$sequence_definition['on']['field'];
$buffer .= "</field>$eol </on>$eol";
}
$buffer .= " </sequence>$eol";
return $buffer;
}
// }}}
// {{{ dumpDatabase()
/**
* Dump a previously parsed database structure in the Metabase schema
* XML based format suitable for the Metabase parser. This function
* may optionally dump the database definition with initialization
* commands that specify the data that is currently present in the tables.
*
* @param array $database_definition unknown
* @param array $arguments associative array that takes pairs of tag
* names and values that define dump options.
* array (
* 'output_mode' => String
* 'file' : dump into a file
* default: dump using a function
* 'output' => String
* depending on the 'Output_Mode'
* name of the file
* name of the function
* 'end_of_line' => String
* end of line delimiter that should be used
* default: "\n"
* );
* @param integer $dump determines what data to dump
* MDB2_SCHEMA_DUMP_ALL : the entire db
* MDB2_SCHEMA_DUMP_STRUCTURE : only the structure of the db
* MDB2_SCHEMA_DUMP_CONTENT : only the content of the db
*
* @return mixed MDB2_OK on success, or a error object
* @access public
*/
function dumpDatabase($database_definition, $arguments, $dump = MDB2_SCHEMA_DUMP_ALL)
{
if (!empty($arguments['output'])) {
if (!empty($arguments['output_mode']) && $arguments['output_mode'] == 'file') {
$fp = fopen($arguments['output'], 'w');
if ($fp === false) {
return $this->raiseError(MDB2_SCHEMA_ERROR_WRITER, null, null,
'it was not possible to open output file');
}
$output = false;
} elseif (is_callable($arguments['output'])) {
$output = $arguments['output'];
} else {
return $this->raiseError(MDB2_SCHEMA_ERROR_WRITER, null, null,
'no valid output function specified');
}
} else {
return $this->raiseError(MDB2_SCHEMA_ERROR_WRITER, null, null,
'no output method specified');
}
$eol = isset($arguments['end_of_line']) ? $arguments['end_of_line'] : "\n";
$sequences = array();
if (!empty($database_definition['sequences'])
&& is_array($database_definition['sequences'])
) {
foreach ($database_definition['sequences'] as $sequence_name => $sequence) {
$table = !empty($sequence['on']) ? $sequence['on']['table'] :'';
$sequences[$table][] = $sequence_name;
}
}
$buffer = '<?xml version="1.0" encoding="ISO-8859-1" ?>'.$eol;
$buffer .= "<database>$eol$eol <name>".$database_definition['name']."</name>";
$buffer .= "$eol <create>".$this->_dumpBoolean($database_definition['create'])."</create>";
$buffer .= "$eol <overwrite>".$this->_dumpBoolean($database_definition['overwrite'])."</overwrite>$eol";
$buffer .= "$eol <charset>".$database_definition['charset']."</charset>$eol";
if ($output) {
call_user_func($output, $buffer);
} else {
fwrite($fp, $buffer);
}
if (!empty($database_definition['tables']) && is_array($database_definition['tables'])) {
foreach ($database_definition['tables'] as $table_name => $table) {
$buffer = "$eol <table>$eol$eol <name>$table_name</name>$eol";
if ($dump == MDB2_SCHEMA_DUMP_ALL || $dump == MDB2_SCHEMA_DUMP_STRUCTURE) {
$buffer .= "$eol <declaration>$eol";
if (!empty($table['fields']) && is_array($table['fields'])) {
foreach ($table['fields'] as $field_name => $field) {
if (empty($field['type'])) {
return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE, null, null,
'it was not specified the type of the field "'.
$field_name.'" of the table "'.$table_name.'"');
}
if (!empty($this->valid_types) && !array_key_exists($field['type'], $this->valid_types)) {
return $this->raiseError(MDB2_SCHEMA_ERROR_UNSUPPORTED, null, null,
'type "'.$field['type'].'" is not yet supported');
}
$buffer .= "$eol <field>$eol <name>$field_name</name>$eol <type>";
$buffer .= $field['type']."</type>$eol";
if (!empty($field['fixed']) && $field['type'] === 'text') {
$buffer .= " <fixed>".$this->_dumpBoolean($field['fixed'])."</fixed>$eol";
}
if (array_key_exists('default', $field)
&& $field['type'] !== 'clob' && $field['type'] !== 'blob'
) {
$buffer .= ' <default>'.$this->_escapeSpecialChars($field['default'])."</default>$eol";
}
if (!empty($field['notnull'])) {
$buffer .= " <notnull>".$this->_dumpBoolean($field['notnull'])."</notnull>$eol";
} else {
$buffer .= " <notnull>false</notnull>$eol";
}
if (!empty($field['autoincrement'])) {
$buffer .= " <autoincrement>" . $field['autoincrement'] ."</autoincrement>$eol";
}
if (!empty($field['unsigned'])) {
$buffer .= " <unsigned>".$this->_dumpBoolean($field['unsigned'])."</unsigned>$eol";
}
if (!empty($field['length'])) {
$buffer .= ' <length>'.$field['length']."</length>$eol";
}
$buffer .= " </field>$eol";
}
}
if (!empty($table['indexes']) && is_array($table['indexes'])) {
foreach ($table['indexes'] as $index_name => $index) {
if (strtolower($index_name) === 'primary') {
$index_name = $table_name . '_pKey';
}
$buffer .= "$eol <index>$eol <name>$index_name</name>$eol";
if (!empty($index['unique'])) {
$buffer .= " <unique>".$this->_dumpBoolean($index['unique'])."</unique>$eol";
}
if (!empty($index['primary'])) {
$buffer .= " <primary>".$this->_dumpBoolean($index['primary'])."</primary>$eol";
}
foreach ($index['fields'] as $field_name => $field) {
$buffer .= " <field>$eol <name>$field_name</name>$eol";
if (!empty($field) && is_array($field)) {
$buffer .= ' <sorting>'.$field['sorting']."</sorting>$eol";
}
$buffer .= " </field>$eol";
}
$buffer .= " </index>$eol";
}
}
if (!empty($table['constraints']) && is_array($table['constraints'])) {
foreach ($table['constraints'] as $constraint_name => $constraint) {
$buffer .= "$eol <foreign>$eol <name>$constraint_name</name>$eol";
if (empty($constraint['fields']) || !is_array($constraint['fields'])) {
return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE, null, null,
'it was not specified a field for the foreign key "'.
$constraint_name.'" of the table "'.$table_name.'"');
}
if (!is_array($constraint['references']) || empty($constraint['references']['table'])) {
return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE, null, null,
'it was not specified the referenced table of the foreign key "'.
$constraint_name.'" of the table "'.$table_name.'"');
}
if (!empty($constraint['match'])) {
$buffer .= " <match>".$constraint['match']."</match>$eol";
}
if (!empty($constraint['ondelete'])) {
$buffer .= " <ondelete>".$constraint['ondelete']."</ondelete>$eol";
}
if (!empty($constraint['onupdate'])) {
$buffer .= " <onupdate>".$constraint['onupdate']."</onupdate>$eol";
}
if (!empty($constraint['deferrable'])) {
$buffer .= " <deferrable>".$constraint['deferrable']."</deferrable>$eol";
}
if (!empty($constraint['initiallydeferred'])) {
$buffer .= " <initiallydeferred>".$constraint['initiallydeferred']."</initiallydeferred>$eol";
}
foreach ($constraint['fields'] as $field_name => $field) {
$buffer .= " <field>$field_name</field>$eol";
}
$buffer .= " <references>$eol <table>".$constraint['references']['table']."</table>$eol";
foreach ($constraint['references']['fields'] as $field_name => $field) {
$buffer .= " <field>$field_name</field>$eol";
}
$buffer .= " </references>$eol";
$buffer .= " </foreign>$eol";
}
}
$buffer .= "$eol </declaration>$eol";
}
if ($output) {
call_user_func($output, $buffer);
} else {
fwrite($fp, $buffer);
}
$buffer = '';
if ($dump == MDB2_SCHEMA_DUMP_ALL || $dump == MDB2_SCHEMA_DUMP_CONTENT) {
if (!empty($table['initialization']) && is_array($table['initialization'])) {
$buffer = "$eol <initialization>$eol";
foreach ($table['initialization'] as $instruction) {
switch ($instruction['type']) {
case 'insert':
$buffer .= "$eol <insert>$eol";
foreach ($instruction['data']['field'] as $field) {
$field_name = $field['name'];
$buffer .= "$eol <field>$eol <name>$field_name</name>$eol";
$buffer .= $this->writeExpression($field['group'], 5, $arguments);
$buffer .= " </field>$eol";
}
$buffer .= "$eol </insert>$eol";
break;
case 'update':
$buffer .= "$eol <update>$eol";
foreach ($instruction['data']['field'] as $field) {
$field_name = $field['name'];
$buffer .= "$eol <field>$eol <name>$field_name</name>$eol";
$buffer .= $this->writeExpression($field['group'], 5, $arguments);
$buffer .= " </field>$eol";
}
if (!empty($instruction['data']['where'])
&& is_array($instruction['data']['where'])
) {
$buffer .= " <where>$eol";
$buffer .= $this->writeExpression($instruction['data']['where'], 5, $arguments);
$buffer .= " </where>$eol";
}
$buffer .= "$eol </update>$eol";
break;
case 'delete':
$buffer .= "$eol <delete>$eol$eol";
if (!empty($instruction['data']['where'])
&& is_array($instruction['data']['where'])
) {
$buffer .= " <where>$eol";
$buffer .= $this->writeExpression($instruction['data']['where'], 5, $arguments);
$buffer .= " </where>$eol";
}
$buffer .= "$eol </delete>$eol";
break;
}
}
$buffer .= "$eol </initialization>$eol";
}
}
$buffer .= "$eol </table>$eol";
if ($output) {
call_user_func($output, $buffer);
} else {
fwrite($fp, $buffer);
}
if (isset($sequences[$table_name])) {
foreach ($sequences[$table_name] as $sequence) {
$result = $this->dumpSequence($database_definition['sequences'][$sequence],
$sequence, $eol, $dump);
if (PEAR::isError($result)) {
return $result;
}
if ($output) {
call_user_func($output, $result);
} else {
fwrite($fp, $result);
}
}
}
}
}
if (isset($sequences[''])) {
foreach ($sequences[''] as $sequence) {
$result = $this->dumpSequence($database_definition['sequences'][$sequence],
$sequence, $eol, $dump);
if (PEAR::isError($result)) {
return $result;
}
if ($output) {
call_user_func($output, $result);
} else {
fwrite($fp, $result);
}
}
}
$buffer = "$eol</database>$eol";
if ($output) {
call_user_func($output, $buffer);
} else {
fwrite($fp, $buffer);
fclose($fp);
}
return MDB2_OK;
}
// }}}
// {{{ writeExpression()
/**
* Dumps the structure of an element. Elements can be value, column,
* function or expression.
*
* @param array $element multi dimensional array that represents the parsed element
* of a DML instruction.
* @param integer $offset base indentation width
* @param array $arguments associative array that takes pairs of tag
* names and values that define dump options.
*
* @return string
*
* @access public
* @see MDB2_Schema_Writer::dumpDatabase()
*/
function writeExpression($element, $offset = 0, $arguments = null)
{
$eol = isset($arguments['end_of_line']) ? $arguments['end_of_line'] : "\n";
$str = '';
$indent = str_repeat(' ', $offset);
$noffset = $offset + 1;
switch ($element['type']) {
case 'value':
$str .= "$indent<value>".$this->_escapeSpecialChars($element['data'])."</value>$eol";
break;
case 'column':
$str .= "$indent<column>".$this->_escapeSpecialChars($element['data'])."</column>$eol";
break;
case 'function':
$str .= "$indent<function>$eol$indent <name>".$this->_escapeSpecialChars($element['data']['name'])."</name>$eol";
if (!empty($element['data']['arguments'])
&& is_array($element['data']['arguments'])
) {
foreach ($element['data']['arguments'] as $v) {
$str .= $this->writeExpression($v, $noffset, $arguments);
}
}
$str .= "$indent</function>$eol";
break;
case 'expression':
$str .= "$indent<expression>$eol";
$str .= $this->writeExpression($element['data']['operants'][0], $noffset, $arguments);
$str .= "$indent <operator>".$element['data']['operator']."</operator>$eol";
$str .= $this->writeExpression($element['data']['operants'][1], $noffset, $arguments);
$str .= "$indent</expression>$eol";
break;
}
return $str;
}
// }}}
}
?>

View file

@ -36,7 +36,7 @@
/**
* uses PEAR's error handling
*/
require_once 'PEAR.php';
oc_require_once('PEAR.php');
/**
* resource could not be created
@ -376,13 +376,12 @@ class XML_Parser extends PEAR
/**
* check, if file is a remote file
*/
if (eregi('^(http|ftp)://', substr($file, 0, 10))) {
if (preg_match('[^(http|ftp)://]', substr($file, 0, 10))) {
if (!ini_get('allow_url_fopen')) {
return $this->raiseError('Remote files cannot be parsed, as safe mode is enabled.', XML_PARSER_ERROR_REMOTE);
}
}
$fp = @fopen($file, 'rb');
$fp = fopen($file, 'rb');
if (is_resource($fp)) {
$this->fp = $fp;
return $fp;
@ -564,7 +563,7 @@ class XML_Parser extends PEAR
function raiseError($msg = null, $ecode = 0)
{
$msg = !is_null($msg) ? $msg : $this->parser;
$err = &new XML_Parser_Error($msg, $ecode);
$err = new XML_Parser_Error($msg, $ecode);
return parent::raiseError($err);
}

View file

@ -81,7 +81,9 @@ oc_require_once('lib_config.php');
oc_require_once('lib_user.php');
oc_require_once('lib_ocs.php');
@oc_require_once('MDB2.php');
@oc_require_once('MDB2/Schema.php');
oc_require_once('lib_connect.php');
oc_require_once('lib_remotestorage.php');
if(!is_dir($CONFIG_DATADIRECTORY_ROOT)){
@ -312,6 +314,7 @@ class OC_UTIL {
*/
class OC_DB {
static private $DBConnection=false;
static private $schema=false;
static private $affected=0;
static private $result=false;
/**
@ -327,8 +330,11 @@ class OC_DB {
global $SERVERROOT;
if(!self::$DBConnection){
$options = array(
'debug' => 0,
'portability' => MDB2_PORTABILITY_ALL,
'log_line_break' => '<br>',
'idxname_format' => '%s',
'debug' => true,
'quote_identifier' => true,
);
if($CONFIG_DBTYPE=='sqlite'){
$dsn = array(
@ -344,14 +350,22 @@ class OC_DB {
'hostspec' => $CONFIG_DBHOST,
'database' => $CONFIG_DBNAME,
);
}elseif($CONFIG_DBTYPE=='pgsql'){
$dsn = array(
'phptype' => 'pgsql',
'username' => $CONFIG_DBUSER,
'password' => $CONFIG_DBPASSWORD,
'hostspec' => $CONFIG_DBHOST,
'database' => $CONFIG_DBNAME,
);
}
self::$DBConnection=MDB2::connect($dsn,$options);
if (@PEAR::isError(self::$DBConnection)) {
self::$DBConnection=&MDB2::factory($dsn,$options);
if (PEAR::isError(self::$DBConnection)) {
echo('<b>can not connect to database, using '.$CONFIG_DBTYPE.'. ('.self::$DBConnection->getUserInfo().')</center>');
die(self::$DBConnection->getMessage());
}
self::$DBConnection->setFetchMode(MDB2_FETCHMODE_ASSOC);
// self::$DBConnection->loadModule('Manager');
self::$schema=&MDB2_Schema::factory(self::$DBConnection);
}
}
@ -369,6 +383,8 @@ class OC_DB {
OC_DB::connect();
if($CONFIG_DBTYPE=='sqlite'){//fix differences between sql versions
$cmd=str_replace('`','',$cmd);
}elseif($CONFIG_DBTYPE=='pgsql'){
$cmd=str_replace('`','"',$cmd);
}
$result=self::$DBConnection->exec($cmd);
if (PEAR::isError($result)) {
@ -390,7 +406,19 @@ class OC_DB {
*/
static function select($cmd){
OC_DB::connect();
return self::$DBConnection->queryAll($cmd);
global $CONFIG_DBTYPE;
if($CONFIG_DBTYPE=='sqlite'){//fix differences between sql versions
$cmd=str_replace('`','',$cmd);
}elseif($CONFIG_DBTYPE=='pgsql'){
$cmd=str_replace('`','"',$cmd);
}
$result=self::$DBConnection->queryAll($cmd);
if (PEAR::isError($result)) {
$entry='DB Error: "'.$result->getMessage().'"<br />';
$entry.='Offending command was: '.$cmd.'<br />';
die($entry);
}
return $result;
}
/**
@ -425,12 +453,8 @@ class OC_DB {
* @return primarykey
*/
static function insertid() {
global $CONFIG_DBTYPE;
if($CONFIG_DBTYPE=='sqlite'){
return self::$DBConnection->lastInsertRowid();
}elseif($CONFIG_DBTYPE=='mysql'){
return(mysqli_insert_id(self::$DBConnection));
}
$id=self::$DBConnection->lastInsertID();
return $id;
}
/**
@ -505,7 +529,41 @@ class OC_DB {
OC_DB::connect();
return self::$DBConnection->escape($string);
}
static function getDBStructure($file){
OC_DB::connect();
$definition = self::$schema->getDefinitionFromDatabase();
$dump_options = array(
'output_mode' => 'file',
'output' => $file,
'end_of_line' => "\n"
);
self::$schema->dumpDatabase($definition, $dump_options, MDB2_SCHEMA_DUMP_STRUCTURE);
}
static function createDBFromStructure($file){
OC_DB::connect();
global $CONFIG_DBNAME;
global $CONFIG_DBTABLEPREFIX;
$content=file_get_contents($file);
$file2=tempnam(sys_get_temp_dir(),'oc_db_scheme_');
echo $content;
$content=str_replace('*dbname*',$CONFIG_DBNAME,$content);
$content=str_replace('*dbprefix*',$CONFIG_DBTABLEPREFIX,$content);
echo $content;
file_put_contents($file2,$content);
$definition=@self::$schema->parseDatabaseDefinitionFile($file2);
unlink($file2);
if($definition instanceof MDB2_Schema_Error){
die($definition->getMessage() . ': ' . $definition->getUserInfo());
}
$ret=@self::$schema->createDatabase($definition);
if($ret instanceof MDB2_Error) {
die ($ret->getMessage() . ': ' . $ret->getUserInfo());
}else{
return true;
}
}
}
@ -589,12 +647,12 @@ function oc_include_once($file){
global $CONFIG_HTTPFORCESSL;
global $CONFIG_DATEFORMAT;
global $CONFIG_INSTALLED;
if(is_file($file)){
return include_once($file);
}elseif(is_file($SERVERROOT.'/'.$file)){
if(is_file($SERVERROOT.'/'.$file)){
return include_once($SERVERROOT.'/'.$file);
}elseif(is_file($SERVERROOT.'/inc/'.$file)){
return include_once($SERVERROOT.'/inc/'.$file);
}elseif(is_file($file)){
return include_once($file);
}
}

View file

@ -25,6 +25,7 @@ class OC_CONFIG{
global $CONFIG_HTTPFORCESSL;
global $CONFIG_DATEFORMAT;
global $CONFIG_DBNAME;
global $CONFIG_DBTABLEPREFIX;
global $CONFIG_INSTALLED;
$allow=false;
if(!$CONFIG_INSTALLED){
@ -130,6 +131,7 @@ class OC_CONFIG{
global $WEBROOT;
global $CONFIG_DBHOST;
global $CONFIG_DBNAME;
global $CONFIG_DBTABLEPREFIX;
global $CONFIG_INSTALLED;
global $CONFIG_DBUSER;
global $CONFIG_DBPASSWORD;
@ -184,13 +186,17 @@ class OC_CONFIG{
//create/fill database
$CONFIG_DBTYPE=$dbtype;
$CONFIG_DBNAME=$_POST['dbname'];
if($dbtype=='mysql'){
if($dbtype!='sqlite'){
$CONFIG_DBTABLEPREFIX=$_POST['dbtableprefix'];
$CONFIG_DBHOST=$_POST['dbhost'];
$CONFIG_DBUSER=$_POST['dbuser'];
$CONFIG_DBPASSWORD=$_POST['dbpassword'];
}else{
$_POST['dbtableprefix']='';
$CONFIG_DBTABLEPREFIX='';
}
try{
if(isset($_POST['createdatabase']) and $CONFIG_DBTYPE=='mysql'){
if(isset($_POST['createdatabase']) and $CONFIG_DBTYPE!='sqlite'){
self::createdatabase($_POST['dbadminuser'],$_POST['dbadminpwd']);
}
}catch(Exception $e){
@ -209,7 +215,6 @@ class OC_CONFIG{
self::filldatabase();
}
}catch(Exception $e){
echo 'testin';
$error.='error while trying to fill the database<br/>';
}
if($CONFIG_DBTYPE=='sqlite'){
@ -241,7 +246,8 @@ class OC_CONFIG{
$config.='$CONFIG_DATEFORMAT=\''.$_POST['dateformat']."';\n";
$config.='$CONFIG_DBTYPE=\''.$dbtype."';\n";
$config.='$CONFIG_DBNAME=\''.$_POST['dbname']."';\n";
if($dbtype=='mysql'){
$config.='$CONFIG_DBTABLEPREFIX=\''.$_POST['dbtableprefix']."';\n";
if($dbtype!='sqlite'){
$config.='$CONFIG_DBHOST=\''.$_POST['dbhost']."';\n";
$config.='$CONFIG_DBUSER=\''.$_POST['dbuser']."';\n";
$config.='$CONFIG_DBPASSWORD=\''.$_POST['dbpassword']."';\n";
@ -267,169 +273,73 @@ class OC_CONFIG{
}
}
}
/**
* Fills the database with the initial tables
* Note: while the AUTO_INCREMENT function is not supported by SQLite
* the same effect can be achieved by accessing the SQLite pseudo-column
* "rowid"
*/
private static function filldatabase(){
global $CONFIG_DBTYPE;
if($CONFIG_DBTYPE=='sqlite'){
$query="CREATE TABLE 'locks' (
'token' VARCHAR(255) NOT NULL DEFAULT '',
'path' varchar(200) NOT NULL DEFAULT '',
'created' int(11) NOT NULL DEFAULT '0',
'modified' int(11) NOT NULL DEFAULT '0',
'expires' int(11) NOT NULL DEFAULT '0',
'owner' varchar(200) DEFAULT NULL,
'recursive' int(11) DEFAULT '0',
'writelock' int(11) DEFAULT '0',
'exclusivelock' int(11) NOT NULL DEFAULT '0',
PRIMARY KEY ('token'),
UNIQUE ('token')
);
CREATE TABLE 'log' (
`id` INTEGER ASC DEFAULT '' NOT NULL,
'timestamp' int(11) NOT NULL,
'user' varchar(250) NOT NULL,
'type' int(11) NOT NULL,
'message' varchar(250) NOT NULL,
PRIMARY KEY ('id')
);
CREATE TABLE 'properties' (
'path' varchar(255) NOT NULL DEFAULT '',
'name' varchar(120) NOT NULL DEFAULT '',
'ns' varchar(120) NOT NULL DEFAULT 'DAV:',
'value' text,
PRIMARY KEY ('path','name','ns')
);
CREATE TABLE 'users' (
'user_id' INTEGER ASC DEFAULT '',
'user_name' varchar(64) NOT NULL DEFAULT '',
'user_name_clean' varchar(64) NOT NULL DEFAULT '',
'user_password' varchar(40) NOT NULL DEFAULT '',
PRIMARY KEY ('user_id'),
UNIQUE ('user_name' ,'user_name_clean')
);
CREATE TABLE 'groups' (
'group_id' INTEGER ASC DEFAULT '',
'group_name' VARCHAR( 64 ) NOT NULL DEFAULT '',
PRIMARY KEY ('group_id'),
UNIQUE ('group_name')
);
CREATE TABLE 'user_group' (
'user_group_id' INTEGER ASC DEFAULT '',
'user_id' VARCHAR( 64 ) NOT NULL DEFAULT '',
'group_id' VARCHAR( 64 ) NOT NULL DEFAULT '',
PRIMARY KEY ('user_group_id')
)
";
}elseif($CONFIG_DBTYPE=='mysql'){
$query="CREATE TABLE IF NOT EXISTS `locks` (
`token` varchar(255) NOT NULL DEFAULT '',
`path` varchar(200) NOT NULL DEFAULT '',
`created` int(11) NOT NULL DEFAULT '0',
`modified` int(11) NOT NULL DEFAULT '0',
`expires` int(11) NOT NULL DEFAULT '0',
`owner` varchar(200) DEFAULT NULL,
`recursive` int(11) DEFAULT '0',
`writelock` int(11) DEFAULT '0',
`exclusivelock` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`token`),
UNIQUE KEY `token` (`token`),
KEY `path` (`path`),
KEY `path_2` (`path`),
KEY `path_3` (`path`,`token`),
KEY `expires` (`expires`)
);
CREATE TABLE IF NOT EXISTS `log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`timestamp` int(11) NOT NULL,
`user` varchar(250) NOT NULL,
`type` int(11) NOT NULL,
`message` varchar(250) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS `properties` (
`path` varchar(255) NOT NULL DEFAULT '',
`name` varchar(120) NOT NULL DEFAULT '',
`ns` varchar(120) NOT NULL DEFAULT 'DAV:',
`value` text,
PRIMARY KEY (`path`,`name`,`ns`),
KEY `path` (`path`)
);
CREATE TABLE IF NOT EXISTS `users` (
`user_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user_name` VARCHAR( 64 ) NOT NULL ,
`user_name_clean` VARCHAR( 64 ) NOT NULL ,
`user_password` VARCHAR( 340) NOT NULL ,
UNIQUE (
`user_name` ,
`user_name_clean`
)
);
CREATE TABLE IF NOT EXISTS `groups` (
`group_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`group_name` VARCHAR( 64 ) NOT NULL ,
UNIQUE (
`group_name`
)
);
CREATE TABLE IF NOT EXISTS `user_group` (
`user_group_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user_id` VARCHAR( 64 ) NOT NULL ,
`group_id` VARCHAR( 64 ) NOT NULL
)
";
/**
* Fills the database with the initial tables
* Note: while the AUTO_INCREMENT function is not supported by SQLite
* the same effect can be achieved by accessing the SQLite pseudo-column
* "rowid"
*/
private static function filldatabase(){
global $SERVERROOT;
OC_DB::createDBFromStructure($SERVERROOT.'/db_structure.xml');
}
/**
* Create the database and user
* @param string adminUser
* @param string adminPwd
*
*/
private static function createdatabase($adminUser,$adminPwd){
global $CONFIG_DBHOST;
global $CONFIG_DBNAME;
global $CONFIG_DBUSER;
global $CONFIG_DBPWD;
global $CONFIG_DBTYPE;
//we cant user OC_BD functions here because we need to connect as the administrative user.
if($CONFIG_DBTYPE=='mysql'){
$connection = @new mysqli($CONFIG_DBHOST, $adminUser, $adminPwd);
if (mysqli_connect_errno()) {
@ob_end_clean();
echo('<html><head></head><body bgcolor="#F0F0F0"><br /><br /><center><b>can not connect to database as administrative user.</center></body></html>');
exit();
}
$query="SELECT user FROM mysql.user WHERE user='{$_POST['dbuser']}';";
$result = @$connection->query($query);
if (!$result) {
$entry='DB Error: "'.$connection->error.'"<br />';
$entry.='Offending command was: '.$query.'<br />';
echo($entry);
}
if($result->num_rows==0){
$query="CREATE USER '{$_POST['dbuser']}' IDENTIFIED BY '{$_POST['dbpassword']}';";
}else{
$query='';
}
$query.="CREATE DATABASE IF NOT EXISTS `{$_POST['dbname']}`;";
$query.="GRANT ALL PRIVILEGES ON `{$_POST['dbname']}` . * TO '{$_POST['dbuser']}';";
$result = @$connection->multi_query($query);
if (!$result) {
$entry='DB Error: "'.$connection->error.'"<br />';
$entry.='Offending command was: '.$query.'<br />';
echo($entry);
}
$connection->close();
}elseif($CONFIG_DBTYPE=='pgsql'){
$connection = pg_connect("user='$adminUser' host='$CONFIG_DBHOST' password='$adminPwd'");
$query="CREATE USER {$_POST['dbuser']} WITH PASSWORD '{$_POST['dbpassword']}' CREATEDB;";
$result = pg_exec($connection, $query);
$query="select count(*) from pg_catalog.pg_database where datname = '{$_POST['dbname']}';";
$result = pg_exec($connection, $query);
if(pg_result($result,0,0)==0){
$query="CREATE DATABASE {$_POST['dbname']};";
$result = pg_exec($connection, $query);
$query="ALTER DATABASE {$_POST['dbname']} OWNER TO {$_POST['dbuser']};";
$result = pg_exec($connection, $query);
}
}
}
OC_DB::multiquery($query);
}
/**
* Create the database and user
* @param string adminUser
* @param string adminPwd
*
*/
private static function createdatabase($adminUser,$adminPwd){
global $CONFIG_DBHOST;
global $CONFIG_DBNAME;
global $CONFIG_DBUSER;
global $CONFIG_DBPWD;
//we cant user OC_BD functions here because we need to connect as the administrative user.
$connection = @new mysqli($CONFIG_DBHOST, $adminUser, $adminPwd);
if (mysqli_connect_errno()) {
@ob_end_clean();
echo('<html><head></head><body bgcolor="#F0F0F0"><br /><br /><center><b>can not connect to database as administrative user.</center></body></html>');
exit();
}
$query="CREATE USER '{$_POST['dbuser']}' IDENTIFIED BY '{$_POST['dbpassword']}';
CREATE DATABASE IF NOT EXISTS `{$_POST['dbname']}` ;
GRANT ALL PRIVILEGES ON `{$_POST['dbname']}` . * TO '{$_POST['dbuser']}';";
$result = @$connection->multi_query($query);
if (!$result) {
$entry='DB Error: "'.$connection->error.'"<br />';
$entry.='Offending command was: '.$query.'<br />';
echo($entry);
}
$connection->close();
}
}
?>

View file

@ -75,9 +75,11 @@ class OC_REMOTE_CLOUD{
curl_setopt($ch, CURLOPT_COOKIEFILE,$this->cookiefile);
curl_setopt($ch, CURLOPT_COOKIEJAR,$this->cookiefile);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$result=trim(curl_exec($ch));
$result=curl_exec($ch);
$result=trim($result);
$info=curl_getinfo($ch);
$httpCode=$info['http_code'];
curl_close($ch);
if($httpCode==200 or $httpCode==0){
return json_decode($result,$assoc);
}else{
@ -120,6 +122,70 @@ class OC_REMOTE_CLOUD{
$this->cookiefile=false;
}
/**
* create a new file or directory
* @param string $dir
* @param string $name
* @param string $type
*/
public function newFile($dir,$name,$type){
if(!$this->connected){
return false;
}
return $this->apiCall('new',array('dir'=>$dir,'name'=>$name,'type'=>$type),true);
}
/**
* deletes a file or directory
* @param string $dir
* @param string $file
*/
public function delete($dir,$name){
if(!$this->connected){
return false;
}
return $this->apiCall('delete',array('dir'=>$dir,'file'=>$name),true);
}
/**
* moves a file or directory
* @param string $sorceDir
* @param string $sorceFile
* @param string $targetDir
* @param string $targetFile
*/
public function move($sourceDir,$sourceFile,$targetDir,$targetFile){
if(!$this->connected){
return false;
}
return $this->apiCall('move',array('sourcedir'=>$sourceDir,'source'=>$sourceFile,'targetdir'=>$targetDir,'target'=>$targetFile),true);
}
/**
* copies a file or directory
* @param string $sorceDir
* @param string $sorceFile
* @param string $targetDir
* @param string $targetFile
*/
public function copy($sourceDir,$sourceFile,$targetDir,$targetFile){
if(!$this->connected){
return false;
}
return $this->apiCall('copy',array('sourcedir'=>$sourceDir,'source'=>$sourceFile,'targetdir'=>$targetDir,'target'=>$targetFile),true);
}
/**
* get a file tree
* @param string $dir
*/
public function getTree($dir){
if(!$this->connected){
return false;
}
return $this->apiCall('gettree',array('dir'=>$dir),true);
}
/**
* get the files inside a directory of the remote cloud
* @param string $dir
@ -130,6 +196,53 @@ class OC_REMOTE_CLOUD{
}
return $this->apiCall('getfiles',array('dir'=>$dir),true);
}
/**
* get a remove file and save it in a temporary file and return the path of the temporary file
* @param string $dir
* @param string $file
* @return string
*/
public function getFile($dir, $file){
if(!$this->connected){
return false;
}
$ch=curl_init();
if(!$this->cookiefile){
$this->cookiefile=sys_get_temp_dir().'/remoteCloudCookie'.uniqid();
}
$tmpfile=tempnam(sys_get_temp_dir(),'remoteCloudFile');
$fp=fopen($tmpfile,'w+');
$url=$this->path.="/files/api.php?action=get&dir=$dir&file=$file";
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_COOKIEFILE,$this->cookiefile);
curl_setopt($ch, CURLOPT_COOKIEJAR,$this->cookiefile);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_exec($ch);
fclose($fp);
curl_close($ch);
return $tmpfile;
}
public function sendFile($sourceDir,$sourceFile,$targetDir,$targetFile){
global $WEBROOT;
$source=$sourceDir.'/'.$sourceFile;
$tmp=OC_FILESYSTEM::toTmpFile($source);
return $this->sendTmpFile($tmp,$targetDir,$targetFile);
}
public function sendTmpFile($tmp,$targetDir,$targetFile){
$token=sha1(uniqid().$tmp);
global $WEBROOT;
$file=sys_get_temp_dir().'/'.'remoteCloudFile'.$token;
rename($tmp,$file);
if((isset($CONFIG_HTTPFORCESSL) and $CONFIG_HTTPFORCESSL) or isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') {
$url = "https://". $_SERVER['SERVER_NAME'] . $WEBROOT;
}else{
$url = "http://". $_SERVER['SERVER_NAME'] . $WEBROOT;
}
return $this->apiCall('pull',array('dir'=>$targetDir,'file'=>$targetFile,'token'=>$token,'source'=>$url),true);
}
}
function OC_CONNECT_TEST($path,$user,$password){
@ -146,6 +259,30 @@ function OC_CONNECT_TEST($path,$user,$password){
foreach($files as $file){
echo "{$file['type']} {$file['name']}: {$file['size']} bytes<br/>";
}
echo 'getting file "'.$file['name'].'"...';
$size=$file['size'];
$file=$remote->getFile('',$file['name']);
if(file_exists($file)){
$newSize=filesize($file);
if($size!=$newSize){
echo "fail<br/>Error: $newSize bytes received, $size expected.";
echo '<br/><br/>Recieved file:<br/>';
readfile($file);
unlink($file);
return;
}
OC_FILESYSTEM::fromTmpFile($file,'/remoteFile');
echo 'done<br/>';
echo 'sending file "burning_avatar.png"...';
$res=$remote->sendFile('','burning_avatar.png','','burning_avatar.png');
if($res){
echo 'done<br/>';
}else{
echo 'fail<br/>';
}
}else{
echo 'fail<br/>';
}
}else{
echo 'fail<br/>';
}

View file

@ -54,7 +54,7 @@ class OC_FILES {
$dirs=array();
$file=array();
$files=array();
if (OC_FILESYSTEM::is_dir($directory)) {
if(OC_FILESYSTEM::is_dir($directory)) {
if ($dh = OC_FILESYSTEM::opendir($directory)) {
while (($filename = readdir($dh)) !== false) {
if($filename<>'.' and $filename<>'..' and substr($filename,0,1)!='.'){
@ -136,7 +136,11 @@ class OC_FILES {
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
if($zip){
header('Content-Length: ' . filesize($filename));
}else{
header('Content-Length: ' . OC_FILESYSTEM::filesize($filename));
}
}elseif($zip or !OC_FILESYSTEM::file_exists($filename)){
header("HTTP/1.0 404 Not Found");
die('404 Not Found');
@ -242,6 +246,44 @@ class OC_FILES {
static function getMimeType($path){
return OC_FILESYSTEM::getMimeType($path);
}
/**
* get a file tree
*
* @param string path
* @return array
*/
static function getTree($path){
return OC_FILESYSTEM::getTree($path);
}
/**
* pull a file from a remote server
* @param string source
* @param string token
* @param string dir
* @param string file
* @return string guessed mime type
*/
static function pull($source,$token,$dir,$file){
$tmpfile=tempnam(sys_get_temp_dir(),'remoteCloudFile');
$fp=fopen($tmpfile,'w+');
$url=$source.="/files/pull.php?token=$token";
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_exec($ch);
fclose($fp);
$info=curl_getinfo($ch);
$httpCode=$info['http_code'];
curl_close($ch);
if($httpCode==200 or $httpCode==0){
OC_FILESYSTEM::fromTmpFile($tmpfile,$dir.'/'.$file);
return true;
}else{
return false;
}
}
}
function zipAddDir($dir,$zip,$internalDir=''){
@ -276,4 +318,46 @@ if(!function_exists('sys_get_temp_dir')) {
}
}
global $FAKEDIRS;
$FAKEDIRS=array();
class fakeDirStream{
private $name;
private $data;
private $index;
public function dir_opendir($path,$options){
global $FAKEDIRS;
$url=parse_url($path);
$this->name=substr($path,strlen('fakedir://'));
$this->index=0;
if(isset($FAKEDIRS[$this->name])){
$this->data=$FAKEDIRS[$this->name];
}else{
$this->data=array();
}
return true;
}
public function dir_readdir(){
if($this->index>=count($this->data)){
return false;
}
$filename=$this->data[$this->index];
$this->index++;
return $filename;
}
public function dir_closedir() {
$this->data=false;
$this->name='';
return true;
}
public function dir_rewinddir() {
$this->index=0;
return true;
}
}
stream_wrapper_register("fakedir", "fakeDirStream");
?>

View file

@ -62,7 +62,7 @@ class OC_FILESTORAGE{
public function filemtime($path){}
public function fileatime($path){}
public function file_get_contents($path){}
public function file_put_contents($path){}
public function file_put_contents($path,$data){}
public function unlink($path){}
public function rename($path1,$path2){}
public function copy($path1,$path2){}
@ -149,8 +149,8 @@ class OC_FILESTORAGE_LOCAL extends OC_FILESTORAGE{
}
return $return;
}
public function file_put_contents($path){
if($return=file_put_contents($this->datadir.$path)){
public function file_put_contents($path,$data){
if($return=file_put_contents($this->datadir.$path,$data)){
$this->notifyObservers($path,OC_FILEACTION_WRITE);
}
}

View file

@ -199,7 +199,7 @@ class OC_FILESYSTEM{
return $storage->file_get_contents(substr($path,strlen(self::getMountPoint($path))));
}
}
static public function file_put_contents($path){
static public function file_put_contents($path,$data){
if(self::canWrite($path) and $storage=self::getStorage($path)){
$this->notifyObservers($path,OC_FILEACTION_WRITE | OC_FILEACTION_CREATE);
return $storage->file_put_contents(substr($path,strlen(self::getMountPoint($path))));

View file

@ -48,7 +48,8 @@ class OC_LOG {
* @param message $message
*/
public static function event($user,$type,$message){
$result = OC_DB::query('insert into log (timestamp,user,type,message) values ("'.time().'","'.addslashes($user).'","'.addslashes($type).'","'.addslashes($message).'")');
global $CONFIG_DBTABLEPREFIX;
$result = OC_DB::query('INSERT INTO `' . $CONFIG_DBTABLEPREFIX . 'log` (`timestamp`,`user`,`type`,`message`) VALUES ('.time().',\''.addslashes($user).'\','.addslashes($type).',\''.addslashes($message).'\');');
}
@ -57,14 +58,15 @@ class OC_LOG {
*
*/
public static function show(){
global $CONFIG_DATEFORMAT;
global $CONFIG_DATEFORMAT;
global $CONFIG_DBTABLEPREFIX;
echo('<div class="center"><table cellpadding="6" cellspacing="0" border="0" class="log">');
if(OC_USER::ingroup($_SESSION['username_clean'],'admin')){
$result = OC_DB::select('select timestamp,user,type,message from log order by timestamp desc limit 20');
$result = OC_DB::select('select `timestamp`,`user`,`type`,`message` from '.$CONFIG_DBTABLEPREFIX.'log order by timestamp desc limit 20');
}else{
$user=$_SESSION['username_clean'];
$result = OC_DB::select('select timestamp,user,type,message from log where user=\''.$user.'\' order by timestamp desc limit 20');
$result = OC_DB::select('select `timestamp`,`user`,`type`,`message` from '.$CONFIG_DBTABLEPREFIX.'log where user=\''.$user.'\' order by timestamp desc limit 20');
}
foreach($result as $entry){
echo('<tr class="browserline">');

View file

@ -372,15 +372,16 @@ class OC_OCS {
* @return string xml/json
*/
private static function activityget($format,$page,$pagesize) {
global $CONFIG_DBTABLEPREFIX;
$user=OC_OCS::checkpassword();
$result = OC_DB::query('select count(*) as co from log');
$result = OC_DB::query("select count(*) as co from {$CONFIG_DBTABLEPREFIX}log");
$entry=$result->fetchRow();
$totalcount=$entry['co'];
OC_DB::free_result($result);
$result = OC_DB::select('select id,timestamp,user,type,message from log order by timestamp desc limit '.($page*$pagesize).','.$pagesize);
$result = OC_DB::select("select id,timestamp,user,type,message from {$CONFIG_DBTABLEPREFIX}log order by timestamp desc limit " . ($page*$pagesize) . ",$pagesize");
$itemscount=count($result);
$url='http://'.substr($_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'],0,-11).'';

353
inc/lib_remotestorage.php Normal file
View file

@ -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']);
}
}
}
?>

View file

@ -27,6 +27,14 @@ if(!$CONFIG_INSTALLED){
$_SESSION['username_clean']='';
}
//cache the userid's an groupid's
if(!isset($_SESSION['user_id_cache'])){
$_SESSION['user_id_cache']=array();
}
if(!isset($_SESSION['group_id_cache'])){
$_SESSION['group_id_cache']=array();
}
/**
* Class for usermanagement
*
@ -63,14 +71,15 @@ class OC_USER {
*
*/
public static function createuser($username,$password){
if(OC_USER::getuserid($username)!=0){
global $CONFIG_DBTABLEPREFIX;
if(OC_USER::getuserid($username,true)!=0){
return false;
}else{
$password=sha1($password);
$usernameclean=strtolower($username);
$password=sha1($password);
$username=OC_DB::escape($username);
$usernameclean=OC_DB::escape($usernameclean);
$query="INSERT INTO `users` (`user_id` ,`user_name` ,`user_name_clean` ,`user_password`) VALUES (NULL , '$username', '$usernameclean', '$password')";
$query="INSERT INTO `{$CONFIG_DBTABLEPREFIX}users` (`user_name` ,`user_name_clean` ,`user_password`) VALUES ('$username', '$usernameclean', '$password')";
$result=OC_DB::query($query);
return ($result)?true:false;
}
@ -82,11 +91,13 @@ class OC_USER {
*
*/
public static function login($username,$password){
global $CONFIG_DBTABLEPREFIX;
$password=sha1($password);
$usernameclean=strtolower($username);
$username=OC_DB::escape($username);
$usernameclean=OC_DB::escape($usernameclean);
$query="SELECT user_id FROM users WHERE user_name_clean = '$usernameclean' AND user_password = '$password' LIMIT 1";
$query = "SELECT user_id FROM {$CONFIG_DBTABLEPREFIX}users WHERE user_name_clean = '$usernameclean' AND user_password = '$password' LIMIT 1";
$result=OC_DB::select($query);
if(isset($result[0]) && isset($result[0]['user_id'])){
$_SESSION['user_id']=$result[0]['user_id'];
@ -124,9 +135,10 @@ class OC_USER {
*
*/
public static function creategroup($groupname){
if(OC_USER::getgroupid($groupname)==0){
global $CONFIG_DBTABLEPREFIX;
if(OC_USER::getgroupid($groupname,true)==0){
$groupname=OC_DB::escape($groupname);
$query="INSERT INTO `groups` (`group_id` ,`group_name`) VALUES (NULL , '$groupname')";
$query="INSERT INTO `{$CONFIG_DBTABLEPREFIX}groups` (`group_name`) VALUES ('$groupname')";
$result=OC_DB::query($query);
return ($result)?true:false;
}else{
@ -138,16 +150,20 @@ class OC_USER {
* get the id of a user
*
*/
public static function getuserid($username){
public static function getuserid($username,$nocache=false){
global $CONFIG_DBTABLEPREFIX;
$usernameclean=strtolower($username);
$username=OC_DB::escape($username);
if(!$nocache and isset($_SESSION['user_id_cache'][$usernameclean])){//try to use cached value to save an sql query
return $_SESSION['user_id_cache'][$usernameclean];
}
$usernameclean=OC_DB::escape($usernameclean);
$query="SELECT user_id FROM users WHERE user_name_clean = '$usernameclean'";
$query="SELECT user_id FROM {$CONFIG_DBTABLEPREFIX}users WHERE user_name_clean = '$usernameclean'";
$result=OC_DB::select($query);
if(!is_array($result)){
return 0;
}
if(isset($result[0]) && isset($result[0]['user_id'])){
$_SESSION['user_id_cache'][$usernameclean]=$result[0]['user_id'];
return $result[0]['user_id'];
}else{
return 0;
@ -158,14 +174,19 @@ class OC_USER {
* get the id of a group
*
*/
public static function getgroupid($groupname){
public static function getgroupid($groupname,$nocache=false){
global $CONFIG_DBTABLEPREFIX;
if(!$nocache and isset($_SESSION['group_id_cache'][$groupname])){//try to use cached value to save an sql query
return $_SESSION['group_id_cache'][$groupname];
}
$groupname=OC_DB::escape($groupname);
$query="SELECT group_id FROM groups WHERE group_name = '$groupname'";
$query="SELECT group_id FROM {$CONFIG_DBTABLEPREFIX}groups WHERE group_name = '$groupname'";
$result=OC_DB::select($query);
if(!is_array($result)){
return 0;
}
if(isset($result[0]) && isset($result[0]['group_id'])){
$_SESSION['group_id_cache'][$groupname]=$result[0]['group_id'];
return $result[0]['group_id'];
}else{
return 0;
@ -176,9 +197,13 @@ class OC_USER {
* get the name of a group
*
*/
public static function getgroupname($groupid){
public static function getgroupname($groupid,$nocache=false){
global $CONFIG_DBTABLEPREFIX;
if($nocache and $name=array_search($groupid,$_SESSION['group_id_cache'])){//try to use cached value to save an sql query
return $name;
}
$groupid=(integer)$groupid;
$query="SELECT group_name FROM groups WHERE group_id = '$groupid' LIMIT 1";
$query="SELECT group_name FROM {$CONFIG_DBTABLEPREFIX}groups WHERE group_id = '$groupid' LIMIT 1";
$result=OC_DB::select($query);
if(isset($result[0]) && isset($result[0]['group_name'])){
return $result[0]['group_name'];
@ -192,10 +217,12 @@ class OC_USER {
*
*/
public static function ingroup($username,$groupname){
global $CONFIG_DBTABLEPREFIX;
$userid=OC_USER::getuserid($username);
$groupid=OC_USER::getgroupid($groupname);
if($groupid>0 and $userid>0){
$query="SELECT user_group_id FROM user_group WHERE group_id = $groupid AND user_id = $userid LIMIT 1";
$query="SELECT * FROM {$CONFIG_DBTABLEPREFIX}user_group WHERE group_id = '$groupid' AND user_id = '$userid';";
$result=OC_DB::select($query);
if(isset($result[0]) && isset($result[0]['user_group_id'])){
return true;
@ -212,11 +239,13 @@ class OC_USER {
*
*/
public static function addtogroup($username,$groupname){
global $CONFIG_DBTABLEPREFIX;
if(!OC_USER::ingroup($username,$groupname)){
$userid=OC_USER::getuserid($username);
$groupid=OC_USER::getgroupid($groupname);
if($groupid!=0 and $userid!=0){
$query="INSERT INTO `user_group` (`user_group_id` ,`user_id` ,`group_id`) VALUES (NULL , '$userid', '$groupid');";
$query="INSERT INTO `{$CONFIG_DBTABLEPREFIX}user_group` (`user_id` ,`group_id`) VALUES ('$userid', '$groupid');";
$result=OC_DB::query($query);
if($result){
return true;
@ -240,8 +269,10 @@ class OC_USER {
*
*/
public static function getusergroups($username){
global $CONFIG_DBTABLEPREFIX;
$userid=OC_USER::getuserid($username);
$query="SELECT group_id FROM user_group WHERE user_id = '$userid'";
$query = "SELECT group_id FROM {$CONFIG_DBTABLEPREFIX}user_group WHERE user_id = '$userid'";
$result=OC_DB::select($query);
$groups=array();
if(is_array($result)){
@ -258,9 +289,11 @@ class OC_USER {
*
*/
public static function setpassword($username,$password){
global $CONFIG_DBTABLEPREFIX;
$password=sha1($password);
$userid=OC_USER::getuserid($username);
$query="UPDATE users SET user_password = '$password' WHERE user_id ='$userid'";
$query = "UPDATE {$CONFIG_DBTABLEPREFIX}users SET user_password = '$password' WHERE user_id ='$userid'";
$result=OC_DB::query($query);
if($result){
return true;
@ -274,11 +307,13 @@ class OC_USER {
*
*/
public static function checkpassword($username,$password){
global $CONFIG_DBTABLEPREFIX;
$password=sha1($password);
$usernameclean=strtolower($username);
$username=OC_DB::escape($username);
$usernameclean=OC_DB::escape($usernameclean);
$query="SELECT user_id FROM 'users' WHERE user_name_clean = '$usernameclean' AND user_password = '$password' LIMIT 1";
$query = "SELECT user_id FROM '{$CONFIG_DBTABLEPREFIX}users' WHERE user_name_clean = '$usernameclean' AND user_password = '$password' LIMIT 1";
$result=OC_DB::select($query);
if(isset($result[0]) && isset($result[0]['user_id']) && $result[0]['user_id']>0){
return true;

View file

@ -10,6 +10,7 @@ if(!$f) die('Error: Config file (config/config.php) is not writable for the webs
if(!isset($fillDB)) $fillDB=true;
if(!isset($CONFIG_DBHOST)) $CONFIG_DBHOST='localhost';
if(!isset($CONFIG_DBUSER)) $CONFIG_DBUSER='owncloud';
if(!isset($CONFIG_DBTABLEPREFIX)) $CONFIG_DBTABLEPREFIX='oc_';
$newuserpassword=OC_USER::generatepassword();
?>
<script type="text/javascript">
@ -27,7 +28,7 @@ function showBackupPath(){
function dbtypechange(){
var dropdown=action=document.getElementById('dbtype');
var type=dropdown.options[dropdown.selectedIndex].value;
var inputs=Array('dbhost','dbuser','dbpass','dbpass_retype','dbcreaterow','dbAdminPwd','dbAdminUser','dbname','dbfill');
var inputs=Array('dbhost','dbuser','dbpass','dbpass_retype','dbcreaterow','dbAdminPwd','dbAdminUser','dbname','dbfill','dbtableprefix');
var id,element;
if(type=='sqlite'){
for(i in inputs){
@ -37,7 +38,7 @@ function dbtypechange(){
element.style.display='none';
}
}
}else if(type=='mysql'){
}else if(type=='mysql' || type=='pgsql'){
for(i in inputs){
id=inputs[i];
element=document.getElementById(id);
@ -80,30 +81,43 @@ if($FIRSTRUN){?>
<select id='dbtype' name="dbtype" onchange='dbtypechange()'>
<?php
global $CONFIG_DBTYPE;
$dbtypes=array();
if($CONFIG_DBTYPE=='sqlite'){
if(is_callable('sqlite_open')){
$dbtypes[]='SQLite';
echo "<option value='sqlite'>SQLite</option>";
}
if(is_callable('mysql_connect')){
$dbtypes[]='MySQL';
echo "<option value='mysql'>MySQL</option>";
}
}else{
if(is_callable('pg_connect')){
echo "<option value='pgsql'>PostgreSQL</option>";
}
}elseif($CONFIG_DBTYPE=='mysql'){
if(is_callable('mysql_connect')){
$dbtypes[]='MySQL';
echo "<option value='mysql'>MySQL</option>";
}
if(is_callable('sqlite_open')){
$dbtypes[]='SQLite';
echo "<option value='sqlite'>SQLite</option>";
}
if(is_callable('pg_connect')){
echo "<option value='pgsql'>PostgreSQL</option>";
}
}elseif($CONFIG_DBTYPE=='pgsql'){
if(is_callable('pg_connect')){
echo "<option value='pgsql'>PostgreSQL</option>";
}
if(is_callable('mysql_connect')){
echo "<option value='mysql'>MySQL</option>";
}
if(is_callable('sqlite_open')){
echo "<option value='sqlite'>SQLite</option>";
}
}
foreach($dbtypes as $dbtype){
echo "<option value='".strtolower($dbtype)."'>$dbtype</option>";
}
?>
</select>
</td></tr>
<tr id='dbhost'><td>database host:</td><td><input type="text" name="dbhost" size="30" class="formstyle" value='<?php echo($CONFIG_DBHOST);?>'></input></td></tr>
<tr id='dbname'><td>database name:</td><td><input type="text" name="dbname" size="30" class="formstyle" value='<?php echo($CONFIG_DBNAME);?>'></input></td></tr>
<tr id='dbtableprefix'><td>database table prefix:</td><td><input type="text" name="dbtableprefix" size="30" class="formstyle" value='<?php echo($CONFIG_DBTABLEPREFIX);?>'></input></td></tr>
<tr id='dbuser'><td>database user:</td><td><input type="text" name="dbuser" size="30" class="formstyle" value='<?php echo($CONFIG_DBUSER);?>'></input></td></tr>
<tr id='dbpass'><td>database password:</td><td><input type="password" name="dbpassword" size="30" class="formstyle" value=''></input></td><td>(leave empty to keep current password)</td></tr>
<tr id='dbpass_retype'><td>retype database password:</td><td><input type="password" name="dbpassword2" size="30" class="formstyle" value=''></input></td></tr>