]> git.mxchange.org Git - friendica.git/commitdiff
New database system that uses PDO if present/Test script for doing database upgrades.
authorMichael Vogel <icarus@dabo.de>
Mon, 28 Apr 2014 21:55:47 +0000 (23:55 +0200)
committerMichael Vogel <icarus@dabo.de>
Mon, 28 Apr 2014 21:55:47 +0000 (23:55 +0200)
13 files changed:
include/dba_pdo.php [new file with mode: 0644]
include/dbstructure.php [new file with mode: 0644]
library/dddbl2/config.inc.php [new file with mode: 0644]
library/dddbl2/dddbl.php [new file with mode: 0644]
library/dddbl2/handler/register_queue_handler.inc.php [new file with mode: 0644]
library/dddbl2/handler/register_result_handler.inc.php [new file with mode: 0644]
library/dddbl2/inc/DataObject.class.php [new file with mode: 0644]
library/dddbl2/inc/DataObjectPool.class.php [new file with mode: 0644]
library/dddbl2/inc/Queue.class.php [new file with mode: 0644]
library/dddbl2/inc/Singleton.class.php [new file with mode: 0644]
library/dddbl2/inc/database.func.php [new file with mode: 0644]
library/dddbl2/inc/exceptions/QueryException.class.php [new file with mode: 0644]
library/dddbl2/inc/exceptions/UnexpectedParameterTypeException.class.php [new file with mode: 0644]

diff --git a/include/dba_pdo.php b/include/dba_pdo.php
new file mode 100644 (file)
index 0000000..76937e7
--- /dev/null
@@ -0,0 +1,340 @@
+<?php
+
+require_once('include/datetime.php');
+
+$objDDDBLResultHandler = new \DDDBL\DataObjectPool('Result-Handler');
+
+/**
+  * create handler, which returns just the PDOStatement object
+  * this allows usage of the cursor to scroll through
+  * big result-sets
+  *
+  **/
+$cloPDOStatementResultHandler = function(\DDDBL\Queue $objQueue) {
+
+  $objPDO = $objQueue->getState()->get('PDOStatement');
+  $objQueue->getState()->update(array('result' => $objPDO));
+  
+  # delete handler which closes the PDOStatement-cursor
+  # this will be done manual if using this handler
+  $objQueue->deleteHandler(QUEUE_CLOSE_CURSOR_POSITION);
+
+};
+
+$objDDDBLResultHandler->add('PDOStatement', array('HANDLER' => $cloPDOStatementResultHandler));
+
+/**
+ *
+ * MySQL database class
+ *
+ * For debugging, insert 'dbg(1);' anywhere in the program flow.
+ * dbg(0); will turn it off. Logging is performed at LOGGER_DATA level.
+ * When logging, all binary info is converted to text and html entities are escaped so that 
+ * the debugging stream is safe to view within both terminals and web pages.
+ *
+ */
+if(! class_exists('dba')) { 
+class dba {
+
+       private $debug = 0;
+       private $db;
+       private $result;
+       public  $connected = false;
+       public  $error = false;
+
+       function __construct($server,$user,$pass,$db,$install = false) {
+               global $a;
+    
+    # work around, to store the database - configuration in DDDBL
+    $objDataObjectPool = new \DDDBL\DataObjectPool('Database-Definition');
+    $objDataObjectPool->add('DEFAULT', array('CONNECTION' => "mysql:host=$server;dbname=$db",
+                                             'USER'       => $user,
+                                             'PASS'       => $pass,
+                                             'DEFAULT'    => true));
+
+               $stamp1 = microtime(true);
+
+               $server = trim($server);
+               $user = trim($user);
+               $pass = trim($pass);
+               $db = trim($db);
+
+               if (!(strlen($server) && strlen($user))){
+                       $this->connected = false;
+                       $this->db = null;
+                       return;
+               }
+
+               if($install) {
+                       if(strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1')) {
+                               if(! dns_get_record($server, DNS_A + DNS_CNAME + DNS_PTR)) {
+                                       $this->error = sprintf( t('Cannot locate DNS info for database server \'%s\''), $server);
+                                       $this->connected = false;
+                                       $this->db = null;
+                                       return;
+                               }
+                       }
+               }
+
+    # etablish connection to database and store PDO object
+    \DDDBL\connect();
+    $this->db = \DDDBL\getDB();
+    
+    if(\DDDBL\isConnected()) {
+      $this->connected = true;
+    }
+  
+               if(! $this->connected) {
+                       $this->db = null;
+                       if(! $install)
+                               system_unavailable();
+               }
+
+               $a->save_timestamp($stamp1, "network");
+       }
+
+       public function getdb() {
+               return $this->db;
+       }
+
+       public function q($sql, $onlyquery = false) {
+               global $a;
+    
+    $strHandler = (true === $onlyquery) ? 'PDOStatement' : 'MULTI';
+    
+    $strQueryAlias = md5($sql);
+    $strSQLType    = strtoupper(strstr($sql, ' ', true));
+    
+    $objPreparedQueryPool = new \DDDBL\DataObjectPool('Query-Definition');
+    
+    # check if query do not exists till now, if so create its definition
+    if(!$objPreparedQueryPool->exists($strQueryAlias))
+      $objPreparedQueryPool->add($strQueryAlias, array('QUERY'   => $sql,
+                                                       'HANDLER' => $strHandler));
+
+               if((! $this->db) || (! $this->connected))
+                       return false;
+
+               $this->error = '';
+
+               $stamp1 = microtime(true);
+
+    try {
+      $r = \DDDBL\get($strQueryAlias);
+      
+      # bad workaround to emulate the bizzare behavior of mysql_query
+      if(in_array($strSQLType, array('INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP', 'SET')))
+        $result = true;
+        
+    } catch (\Exception $objException) {
+      $result = false;
+      $intErrorCode = $objPreparedQueryPool->get($strQueryAlias)->get('PDOStatement')->errorCode();
+    }
+
+               $stamp2 = microtime(true);
+               $duration = (float)($stamp2-$stamp1);
+
+               $a->save_timestamp($stamp1, "database");
+
+               if(x($a->config,'system') && x($a->config['system'],'db_log')) {
+                       if (($duration > $a->config["system"]["db_loglimit"])) {
+                               $duration = round($duration, 3);
+                               $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+                               @file_put_contents($a->config["system"]["db_log"], datetime_convert()."\t".$duration."\t".
+                                               basename($backtrace[1]["file"])."\t".
+                                               $backtrace[1]["line"]."\t".$backtrace[2]["function"]."\t".
+                                               substr($sql, 0, 2000)."\n", FILE_APPEND);
+                       }
+               }
+
+               if($intErrorCode)
+      $this->error = $intErrorCode;
+
+               if(strlen($this->error)) {
+                       logger('dba: ' . $this->error);
+               }
+
+               if($this->debug) {
+
+                       $mesg = '';
+
+                       if($result === false)
+                               $mesg = 'false';
+                       elseif($result === true)
+                               $mesg = 'true';
+                       else {
+        # this needs fixing, but is a bug itself
+                               #$mesg = mysql_num_rows($result) . ' results' . EOL; 
+                       }
+
+                       $str =  'SQL = ' . printable($sql) . EOL . 'SQL returned ' . $mesg
+                               . (($this->error) ? ' error: ' . $this->error : '')
+                               . EOL;
+
+                       logger('dba: ' . $str );
+               }
+
+               /**
+                * If dbfail.out exists, we will write any failed calls directly to it,
+                * regardless of any logging that may or may nor be in effect.
+                * These usually indicate SQL syntax errors that need to be resolved.
+                */
+
+               if($result === false) {
+                       logger('dba: ' . printable($sql) . ' returned false.' . "\n" . $this->error);
+                       if(file_exists('dbfail.out'))
+                               file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n" . $this->error . "\n", FILE_APPEND);
+               }
+
+               if(($result === true) || ($result === false))
+                       return $result;
+
+               if ($onlyquery) {
+                       $this->result = $result;
+                       return true;
+               }
+    
+               //$a->save_timestamp($stamp1, "database");
+
+               if($this->debug)
+                       logger('dba: ' . printable(print_r($r, true)));
+               return($r);
+       }
+
+       public function qfetch() {
+  
+               if (!$this->result)
+      return false;
+      
+    return $this->result->fetch();
+
+       }
+  
+       public function qclose() {
+               if ($this->result)
+      $this->result->closeCursor();
+       }
+
+       public function dbg($dbg) {
+               $this->debug = $dbg;
+       }
+
+       public function escape($str) {
+               if($this->db && $this->connected) {
+      $strQuoted = $this->db->quote($str);
+      # this workaround is needed, because quote creates "'" and the beginning and the end
+      # of the string, which is correct. but until now the queries set this delimiter manually,
+      # so we must remove them from here and wait until everything uses prepared statements
+      return mb_substr($strQuoted, 1, mb_strlen($strQuoted) - 2); 
+               }
+       }
+
+       function __destruct() {
+               if ($this->db) 
+                 \DDDBL\disconnect();
+       }
+}}
+
+if(! function_exists('printable')) {
+function printable($s) {
+       $s = preg_replace("~([\x01-\x08\x0E-\x0F\x10-\x1F\x7F-\xFF])~",".", $s);
+       $s = str_replace("\x00",'.',$s);
+       if(x($_SERVER,'SERVER_NAME'))
+               $s = escape_tags($s);
+       return $s;
+}}
+
+// Procedural functions
+if(! function_exists('dbg')) { 
+function dbg($state) {
+       global $db;
+       if($db)
+       $db->dbg($state);
+}}
+
+if(! function_exists('dbesc')) { 
+function dbesc($str) {
+       global $db;
+       if($db && $db->connected)
+               return($db->escape($str));
+       else
+               return(str_replace("'","\\'",$str));
+}}
+
+
+
+// Function: q($sql,$args);
+// Description: execute SQL query with printf style args.
+// Example: $r = q("SELECT * FROM `%s` WHERE `uid` = %d",
+//                   'user', 1);
+
+if(! function_exists('q')) { 
+function q($sql) {
+
+       global $db;
+       $args = func_get_args();
+       unset($args[0]);
+
+       if($db && $db->connected) {
+               $stmt = @vsprintf($sql,$args); // Disabled warnings
+               //logger("dba: q: $stmt", LOGGER_ALL);
+               if($stmt === false)
+                       logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true), LOGGER_DEBUG);
+               return $db->q($stmt);
+       }
+
+       /**
+        *
+        * This will happen occasionally trying to store the 
+        * session data after abnormal program termination 
+        *
+        */
+       logger('dba: no database: ' . print_r($args,true));
+       return false; 
+
+}}
+
+/**
+ *
+ * Raw db query, no arguments
+ *
+ */
+
+if(! function_exists('dbq')) { 
+function dbq($sql) {
+
+       global $db;
+       if($db && $db->connected)
+               $ret = $db->q($sql);
+       else
+               $ret = false;
+       return $ret;
+}}
+
+
+// Caller is responsible for ensuring that any integer arguments to 
+// dbesc_array are actually integers and not malformed strings containing
+// SQL injection vectors. All integer array elements should be specifically 
+// cast to int to avoid trouble. 
+
+
+if(! function_exists('dbesc_array_cb')) {
+function dbesc_array_cb(&$item, $key) {
+       if(is_string($item))
+               $item = dbesc($item);
+}}
+
+
+if(! function_exists('dbesc_array')) {
+function dbesc_array(&$arr) {
+       if(is_array($arr) && count($arr)) {
+               array_walk($arr,'dbesc_array_cb');
+       }
+}}
+
+if(! function_exists('dba_timer')) {
+function dba_timer() {
+  return microtime(true);
+}}
+
diff --git a/include/dbstructure.php b/include/dbstructure.php
new file mode 100644 (file)
index 0000000..1f3d361
--- /dev/null
@@ -0,0 +1,1429 @@
+<?php
+
+require_once("boot.php");
+
+function dbstructure_run(&$argv, &$argc) {
+       global $a, $db;
+
+       if(is_null($a)){
+               $a = new App;
+       }
+
+       if(is_null($db)) {
+               @include(".htconfig.php");
+               require_once("include/dba.php");
+               $db = new dba($db_host, $db_user, $db_pass, $db_data);
+                       unset($db_host, $db_user, $db_pass, $db_data);
+       }
+
+       load_config('config');
+       load_config('system');
+
+       update_structure($a);
+}
+
+if (array_search(__file__,get_included_files())===0){
+       dbstructure_run($argv,$argc);
+       killme();
+}
+
+function table_structure($table) {
+       $structures = q("DESCRIBE `%s`", $table);
+
+       $indexes = q("SHOW INDEX FROM `%s`", $table);
+
+       $fielddata = array();
+       $indexdata = array();
+
+       if (is_array($indexes))
+               foreach ($indexes AS $index) {
+                       if ($index["Index_type"] == "FULLTEXT")
+                               continue;
+
+                       $column = $index["Column_name"];
+                       if ($index["Sub_part"] != "")
+                               $column .= "(".$index["Sub_part"].")";
+
+                       $indexdata[$index["Key_name"]][] = $column;
+               }
+
+       if (is_array($structures)) {
+               foreach($structures AS $field) {
+                       $fielddata[$field["Field"]]["type"] = $field["Type"];
+                       if ($field["Null"] == "NO")
+                               $fielddata[$field["Field"]]["not null"] = true;
+
+                       if ($field["Default"] != "")
+                               $fielddata[$field["Field"]]["default"] = $field["Default"];
+
+                       if ($field["Extra"] != "")
+                               $fielddata[$field["Field"]]["extra"] = $field["Extra"];
+
+                       if ($field["Key"] == "PRI")
+                               $fielddata[$field["Field"]]["primary"] = true;
+               }
+       }
+
+       return(array("fields"=>$fielddata, "indexes"=>$indexdata));
+}
+
+function print_structure($db) {
+       foreach ($db AS $name => $structure) {
+               echo "\t".'$db["'.$name."\"] = array(\n";
+
+               echo "\t\t\t".'"fields" => array('."\n";
+               foreach ($structure["fields"] AS $fieldname => $parameters) {
+                       echo "\t\t\t\t\t".'"'.$fieldname.'" => array(';
+
+                       $data = "";
+                       foreach ($parameters AS $name => $value) {
+                               if ($data != "")
+                                       $data .= ", ";
+                               $data .= '"'.$name.'" => "'.$value.'"';
+                       }
+
+                       echo $data."),\n";
+               }
+               echo "\t\t\t\t\t),\n";
+               echo "\t\t\t".'"indexes" => array('."\n";
+               foreach ($structure["indexes"] AS $indexname => $fieldnames) {
+                       echo "\t\t\t\t\t".'"'.$indexname.'" => array("'.implode($fieldnames, '","').'"'."),\n";
+               }
+               echo "\t\t\t\t\t)\n";
+               echo "\t\t\t);\n";
+       }
+}
+
+function update_structure($a) {
+
+       // Get the current structure
+       $db = array();
+
+       $tables = q("show tables");
+
+       foreach ($tables AS $table) {
+               $table = current($table);
+
+               $db[$table] = table_structure($table);
+       }
+
+       // Get the definition
+       $definition = db_definition();
+
+       // Compare it
+       foreach ($definition AS $name => $structure) {
+               if (!isset($db[$name]))
+                       db_create_table($name, $structure["fields"]);
+               else {
+                       // Compare the field structure field by field
+                       foreach ($structure["fields"] AS $fieldname => $parameters) {
+                               if (!isset($db[$name]["fields"][$fieldname]))
+                                       db_add_table_field($name, $fieldname, $parameters);
+                               else {
+                                       // Compare the field definition
+                                       $current_field_definition = implode($db[$name]["fields"][$fieldname]);
+                                       $new_field_definition = implode($parameters);
+                                       if ($current_field_definition != $new_field_definition)
+                                               db_modify_table_field($name, $fieldname, $parameters);
+                               }
+                       }
+               }
+
+               // Drop the index if it isn't present in the definition
+               if (isset($db[$name]))
+                       foreach ($db[$name]["indexes"] AS $indexname => $fieldnames)
+                               if (!isset($structure["indexes"][$indexname]))
+                                       db_drop_index($name, $indexname);
+
+               // Create the index
+               foreach ($structure["indexes"] AS $indexname => $fieldnames)
+                       if (!isset($db[$name]["indexes"][$indexname]))
+                               db_create_index($name, $indexname, $fieldnames);
+       }
+}
+
+function db_field_command($parameters) {
+       $fieldstruct = $parameters["type"];
+
+       if ($parameters["not null"])
+               $fieldstruct .= " NOT NULL";
+
+       if ($parameters["default"] != "")
+               $fieldstruct .= " DEFAULT '".$parameters["default"]."'";
+
+       if ($parameters["extra"] != "")
+               $fieldstruct .= " ".$parameters["extra"];
+
+       if ($parameters["primary"] != "")
+               $fieldstruct .= " PRIMARY KEY";
+
+       return($fieldstruct);
+}
+
+function db_create_table($name, $fields) {
+       $sql = "";
+       foreach($fields AS $fieldname => $field) {
+               if ($sql != "")
+                       $sql .= ",\n";
+
+               $sql .= "`".dbesc($fieldname)."` ".db_field_command($field);
+       }
+
+       $sql = sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n", dbesc($name)).$sql."\n) DEFAULT CHARSET=utf8";
+       echo $sql.";\n";
+       //$ret = q($sql);
+}
+
+function db_add_table_field($name, $fieldname, $parameters) {
+       $sql = sprintf("ALTER TABLE `%s` ADD `%s` %s", dbesc($name), dbesc($fieldname), db_field_command($parameters));
+       echo $sql.";\n";
+       //$ret = q($sql);
+}
+
+function db_modify_table_field($name, $fieldname, $parameters) {
+       $sql = sprintf("ALTER TABLE `%s` MODIFY `%s` %s", dbesc($name), dbesc($fieldname), db_field_command($parameters));
+       echo $sql.";\n";
+       //$ret = q($sql);
+}
+
+function db_drop_index($name, $indexname) {
+       $sql = sprintf("DROP INDEX `%s` ON `%s`", dbesc($indexname), dbesc($name));
+       echo $sql.";\n";
+       //$ret = q($sql);
+}
+
+function db_create_index($name, $indexname, $fieldnames) {
+
+       if ($indexname == "PRIMARY")
+               return;
+
+       $names = "";
+       foreach ($fieldnames AS $fieldname) {
+               if ($names != "")
+                       $names .= ",";
+
+               if (preg_match('|(.+)\((\d+)\)|', $fieldname, $matches))
+                       $names .= "`".dbesc($matches[1])."`(".intval($matches[2]).")";
+               else
+                       $names .= "`".dbesc($fieldname)."`";
+       }
+
+       $sql = sprintf("CREATE INDEX `%s` ON `%s`(%s)", dbesc($indexname), dbesc($name), $names);
+       echo $sql."\n";
+       //$ret = q($sql);
+}
+
+function db_definition() {
+
+       $db = array();
+
+       $db["addon"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "name" => array("type" => "char(255)", "not null" => "1"),
+                                       "version" => array("type" => "char(255)", "not null" => "1"),
+                                       "installed" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "hidden" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "timestamp" => array("type" => "bigint(20)", "not null" => "1", "default" => "0"),
+                                       "plugin_admin" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["attach"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "hash" => array("type" => "char(64)", "not null" => "1"),
+                                       "filename" => array("type" => "char(255)", "not null" => "1"),
+                                       "filetype" => array("type" => "char(64)", "not null" => "1"),
+                                       "filesize" => array("type" => "int(11)", "not null" => "1"),
+                                       "data" => array("type" => "longblob", "not null" => "1"),
+                                       "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "allow_cid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "allow_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "deny_cid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "deny_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["auth_codes"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "varchar(40)", "not null" => "1", "primary" => "1"),
+                                       "client_id" => array("type" => "varchar(20)", "not null" => "1"),
+                                       "redirect_uri" => array("type" => "varchar(200)", "not null" => "1"),
+                                       "expires" => array("type" => "int(11)", "not null" => "1"),
+                                       "scope" => array("type" => "varchar(250)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["cache"] = array(
+                       "fields" => array(
+                                       "k" => array("type" => "char(255)", "not null" => "1", "primary" => "1"),
+                                       "v" => array("type" => "text", "not null" => "1"),
+                                       "updated" => array("type" => "datetime", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("k"),
+                                       "updated" => array("updated"),
+                                       )
+                       );
+       $db["challenge"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "challenge" => array("type" => "char(255)", "not null" => "1"),
+                                       "dfrn-id" => array("type" => "char(255)", "not null" => "1"),
+                                       "expire" => array("type" => "int(11)", "not null" => "1"),
+                                       "type" => array("type" => "char(255)", "not null" => "1"),
+                                       "last_update" => array("type" => "char(255)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["clients"] = array(
+                       "fields" => array(
+                                       "client_id" => array("type" => "varchar(20)", "not null" => "1", "primary" => "1"),
+                                       "pw" => array("type" => "varchar(20)", "not null" => "1"),
+                                       "redirect_uri" => array("type" => "varchar(200)", "not null" => "1"),
+                                       "name" => array("type" => "varchar(128)"),
+                                       "icon" => array("type" => "varchar(255)"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("client_id"),
+                                       )
+                       );
+       $db["config"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "cat" => array("type" => "char(255)", "not null" => "1"),
+                                       "k" => array("type" => "char(255)", "not null" => "1"),
+                                       "v" => array("type" => "text", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "access" => array("cat","k"),
+                                       )
+                       );
+       $db["contact"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "self" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "remote_self" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "rel" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "duplex" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "network" => array("type" => "char(255)", "not null" => "1"),
+                                       "name" => array("type" => "char(255)", "not null" => "1"),
+                                       "nick" => array("type" => "char(255)", "not null" => "1"),
+                                       "attag" => array("type" => "char(255)", "not null" => "1"),
+                                       "photo" => array("type" => "text", "not null" => "1"),
+                                       "thumb" => array("type" => "text", "not null" => "1"),
+                                       "micro" => array("type" => "text", "not null" => "1"),
+                                       "site-pubkey" => array("type" => "text", "not null" => "1"),
+                                       "issued-id" => array("type" => "char(255)", "not null" => "1"),
+                                       "dfrn-id" => array("type" => "char(255)", "not null" => "1"),
+                                       "url" => array("type" => "char(255)", "not null" => "1"),
+                                       "nurl" => array("type" => "char(255)", "not null" => "1"),
+                                       "addr" => array("type" => "char(255)", "not null" => "1"),
+                                       "alias" => array("type" => "char(255)", "not null" => "1"),
+                                       "pubkey" => array("type" => "text", "not null" => "1"),
+                                       "prvkey" => array("type" => "text", "not null" => "1"),
+                                       "batch" => array("type" => "char(255)", "not null" => "1"),
+                                       "request" => array("type" => "text", "not null" => "1"),
+                                       "notify" => array("type" => "text", "not null" => "1"),
+                                       "poll" => array("type" => "text", "not null" => "1"),
+                                       "confirm" => array("type" => "text", "not null" => "1"),
+                                       "poco" => array("type" => "text", "not null" => "1"),
+                                       "aes_allow" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "ret-aes" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "usehub" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "subhub" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "hub-verify" => array("type" => "char(255)", "not null" => "1"),
+                                       "last-update" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "success_update" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "name-date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "uri-date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "avatar-date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "term-date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "priority" => array("type" => "tinyint(3)", "not null" => "1"),
+                                       "blocked" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
+                                       "readonly" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "writable" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "forum" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "prv" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "hidden" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "archive" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "pending" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
+                                       "rating" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "reason" => array("type" => "text", "not null" => "1"),
+                                       "closeness" => array("type" => "tinyint(2)", "not null" => "1", "default" => "99"),
+                                       "info" => array("type" => "mediumtext", "not null" => "1"),
+                                       "profile-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
+                                       "bdyear" => array("type" => "char(4)", "not null" => "1"),
+                                       "bd" => array("type" => "date", "not null" => "1"),
+                                       "notify_new_posts" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "fetch_further_information" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid" => array("uid"),
+                                       )
+                       );
+       $db["conv"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "guid" => array("type" => "char(64)", "not null" => "1"),
+                                       "recips" => array("type" => "mediumtext", "not null" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "creator" => array("type" => "char(255)", "not null" => "1"),
+                                       "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "updated" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "subject" => array("type" => "mediumtext", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid" => array("uid"),
+                                       )
+                       );
+       $db["dav_addressbookobjects"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "addressbook_id" => array("type" => "int(11) unsigned", "not null" => "1"),
+                                       "contact" => array("type" => "int(11)"),
+                                       "carddata" => array("type" => "mediumtext"),
+                                       "uri" => array("type" => "varchar(100)"),
+                                       "lastmodified" => array("type" => "timestamp"),
+                                       "needs_rebuild" => array("type" => "tinyint(4)", "not null" => "1", "default" => "0"),
+                                       "manually_deleted" => array("type" => "tinyint(4)", "not null" => "1", "default" => "0"),
+                                       "etag" => array("type" => "varchar(15)", "not null" => "1"),
+                                       "size" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "namespace" => array("addressbook_id","contact"),
+                                       "contact" => array("contact"),
+                                       )
+                       );
+       $db["dav_addressbooks"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "namespace" => array("type" => "mediumint(9)", "not null" => "1"),
+                                       "namespace_id" => array("type" => "int(11) unsigned", "not null" => "1"),
+                                       "displayname" => array("type" => "varchar(200)", "not null" => "1"),
+                                       "description" => array("type" => "varchar(500)"),
+                                       "needs_rebuild" => array("type" => "tinyint(4)", "not null" => "1", "default" => "1"),
+                                       "uri" => array("type" => "varchar(50)", "not null" => "1"),
+                                       "ctag" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["dav_cal_virtual_object_cache"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "bigint(20) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "calendar_id" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "date" => array("type" => "timestamp", "not null" => "1", "default" => "CURRENT_TIMESTAMP"),
+                                       "data_uri" => array("type" => "char(80)", "not null" => "1"),
+                                       "data_summary" => array("type" => "varchar(1000)", "not null" => "1"),
+                                       "data_location" => array("type" => "varchar(1000)", "not null" => "1"),
+                                       "data_start" => array("type" => "timestamp", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "data_end" => array("type" => "timestamp", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "data_allday" => array("type" => "tinyint(4)", "not null" => "1"),
+                                       "data_type" => array("type" => "varchar(20)", "not null" => "1"),
+                                       "calendardata" => array("type" => "text", "not null" => "1"),
+                                       "size" => array("type" => "int(11)", "not null" => "1"),
+                                       "etag" => array("type" => "varchar(15)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "data_uri" => array("data_uri"),
+                                       "ref_type" => array("calendar_id","data_end"),
+                                       )
+                       );
+       $db["dav_cal_virtual_object_sync"] = array(
+                       "fields" => array(
+                                       "calendar_id" => array("type" => "int(10) unsigned", "not null" => "1", "primary" => "1"),
+                                       "date" => array("type" => "timestamp", "not null" => "1", "default" => "CURRENT_TIMESTAMP"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("calendar_id"),
+                                       )
+                       );
+       $db["dav_caldav_log"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "mediumint(9)", "not null" => "1"),
+                                       "ip" => array("type" => "varchar(15)", "not null" => "1"),
+                                       "user_agent" => array("type" => "varchar(100)", "not null" => "1"),
+                                       "date" => array("type" => "timestamp", "not null" => "1", "default" => "CURRENT_TIMESTAMP"),
+                                       "method" => array("type" => "varchar(10)", "not null" => "1"),
+                                       "url" => array("type" => "varchar(100)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "mitglied" => array("uid"),
+                                       )
+                       );
+       $db["dav_calendarobjects"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "calendar_id" => array("type" => "int(11)", "not null" => "1"),
+                                       "calendardata" => array("type" => "text"),
+                                       "uri" => array("type" => "varchar(200)", "not null" => "1"),
+                                       "lastmodified" => array("type" => "timestamp"),
+                                       "componentType" => array("type" => "enum('VEVENT','VTODO')", "not null" => "1", "default" => "VEVENT"),
+                                       "firstOccurence" => array("type" => "timestamp", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "lastOccurence" => array("type" => "timestamp", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "etag" => array("type" => "varchar(15)", "not null" => "1"),
+                                       "size" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uri" => array("uri"),
+                                       "calendar_id" => array("calendar_id"),
+                                       )
+                       );
+       $db["dav_calendars"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "namespace" => array("type" => "mediumint(9)", "not null" => "1"),
+                                       "namespace_id" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "calendarorder" => array("type" => "int(11)", "not null" => "1", "default" => "1"),
+                                       "calendarcolor" => array("type" => "char(6)", "not null" => "1", "default" => "5858FF"),
+                                       "displayname" => array("type" => "varchar(200)", "not null" => "1"),
+                                       "timezone" => array("type" => "text", "not null" => "1"),
+                                       "description" => array("type" => "varchar(500)", "not null" => "1"),
+                                       "uri" => array("type" => "varchar(50)", "not null" => "1"),
+                                       "has_vevent" => array("type" => "tinyint(4)", "not null" => "1", "default" => "1"),
+                                       "has_vtodo" => array("type" => "tinyint(4)", "not null" => "1", "default" => "1"),
+                                       "ctag" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "namespace" => array("namespace","namespace_id","uri"),
+                                       "uri" => array("uri"),
+                                       )
+                       );
+       $db["dav_jqcalendar"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "ical_recurr_uri" => array("type" => "varchar(100)"),
+                                       "calendar_id" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "calendarobject_id" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "Summary" => array("type" => "varchar(100)", "not null" => "1"),
+                                       "StartTime" => array("type" => "timestamp"),
+                                       "EndTime" => array("type" => "timestamp"),
+                                       "IsEditable" => array("type" => "tinyint(3) unsigned", "not null" => "1"),
+                                       "IsAllDayEvent" => array("type" => "tinyint(4)", "not null" => "1"),
+                                       "IsRecurring" => array("type" => "tinyint(4)", "not null" => "1"),
+                                       "Color" => array("type" => "char(6)"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "calendarByStart" => array("calendar_id","StartTime"),
+                                       "calendarobject_id" => array("calendarobject_id","ical_recurr_uri"),
+                                       )
+                       );
+       $db["dav_notifications"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "ical_recurr_uri" => array("type" => "varchar(100)"),
+                                       "calendar_id" => array("type" => "int(11)", "not null" => "1"),
+                                       "calendarobject_id" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "action" => array("type" => "enum('email','display')", "not null" => "1", "default" => "email"),
+                                       "alert_date" => array("type" => "timestamp", "not null" => "1", "default" => "CURRENT_TIMESTAMP"),
+                                       "notified" => array("type" => "tinyint(4)", "not null" => "1", "default" => "0"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "notified" => array("notified","alert_date"),
+                                       "calendar_id" => array("calendar_id","calendarobject_id"),
+                                       )
+                       );
+       $db["deliverq"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "cmd" => array("type" => "char(32)", "not null" => "1"),
+                                       "item" => array("type" => "int(11)", "not null" => "1"),
+                                       "contact" => array("type" => "int(11)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["dsprphotoq"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "msg" => array("type" => "mediumtext", "not null" => "1"),
+                                       "attempt" => array("type" => "tinyint(4)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["event"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "cid" => array("type" => "int(11)", "not null" => "1"),
+                                       "uri" => array("type" => "char(255)", "not null" => "1"),
+                                       "created" => array("type" => "datetime", "not null" => "1"),
+                                       "edited" => array("type" => "datetime", "not null" => "1"),
+                                       "start" => array("type" => "datetime", "not null" => "1"),
+                                       "finish" => array("type" => "datetime", "not null" => "1"),
+                                       "summary" => array("type" => "text", "not null" => "1"),
+                                       "desc" => array("type" => "text", "not null" => "1"),
+                                       "location" => array("type" => "text", "not null" => "1"),
+                                       "type" => array("type" => "char(255)", "not null" => "1"),
+                                       "nofinish" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "adjust" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
+                                       "ignore" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
+                                       "allow_cid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "allow_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "deny_cid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "deny_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid" => array("uid"),
+                                       )
+                       );
+       $db["fcontact"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "url" => array("type" => "char(255)", "not null" => "1"),
+                                       "name" => array("type" => "char(255)", "not null" => "1"),
+                                       "photo" => array("type" => "char(255)", "not null" => "1"),
+                                       "request" => array("type" => "char(255)", "not null" => "1"),
+                                       "nick" => array("type" => "char(255)", "not null" => "1"),
+                                       "addr" => array("type" => "char(255)", "not null" => "1"),
+                                       "batch" => array("type" => "char(255)", "not null" => "1"),
+                                       "notify" => array("type" => "char(255)", "not null" => "1"),
+                                       "poll" => array("type" => "char(255)", "not null" => "1"),
+                                       "confirm" => array("type" => "char(255)", "not null" => "1"),
+                                       "priority" => array("type" => "tinyint(1)", "not null" => "1"),
+                                       "network" => array("type" => "char(32)", "not null" => "1"),
+                                       "alias" => array("type" => "char(255)", "not null" => "1"),
+                                       "pubkey" => array("type" => "text", "not null" => "1"),
+                                       "updated" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "addr" => array("addr"),
+                                       )
+                       );
+       $db["ffinder"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "cid" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "fid" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["fserver"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "server" => array("type" => "char(255)", "not null" => "1"),
+                                       "posturl" => array("type" => "char(255)", "not null" => "1"),
+                                       "key" => array("type" => "text", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "server" => array("server"),
+                                       )
+                       );
+       $db["fsuggest"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "cid" => array("type" => "int(11)", "not null" => "1"),
+                                       "name" => array("type" => "char(255)", "not null" => "1"),
+                                       "url" => array("type" => "char(255)", "not null" => "1"),
+                                       "request" => array("type" => "char(255)", "not null" => "1"),
+                                       "photo" => array("type" => "char(255)", "not null" => "1"),
+                                       "note" => array("type" => "text", "not null" => "1"),
+                                       "created" => array("type" => "datetime", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["gcign"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "gcid" => array("type" => "int(11)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid" => array("uid"),
+                                       "gcid" => array("gcid"),
+                                       )
+                       );
+       $db["gcontact"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "name" => array("type" => "char(255)", "not null" => "1"),
+                                       "url" => array("type" => "char(255)", "not null" => "1"),
+                                       "nurl" => array("type" => "char(255)", "not null" => "1"),
+                                       "photo" => array("type" => "char(255)", "not null" => "1"),
+                                       "connect" => array("type" => "char(255)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "nurl" => array("nurl"),
+                                       )
+                       );
+       $db["glink"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "cid" => array("type" => "int(11)", "not null" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "gcid" => array("type" => "int(11)", "not null" => "1"),
+                                       "zcid" => array("type" => "int(11)", "not null" => "1"),
+                                       "updated" => array("type" => "datetime", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "cid_uid_gcid_zcid" => array("cid","uid","gcid","zcid"),
+                                       "gcid" => array("gcid"),
+                                       "zcid" => array("zcid"),
+                                       )
+                       );
+       $db["group"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "visible" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "deleted" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "name" => array("type" => "char(255)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid" => array("uid"),
+                                       )
+                       );
+       $db["group_member"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "gid" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "contact-id" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid_gid_contactid" => array("uid","gid","contact-id"),
+                                       )
+                       );
+       $db["guid"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "guid" => array("type" => "char(64)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "guid" => array("guid"),
+                                       )
+                       );
+       $db["hook"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "hook" => array("type" => "char(255)", "not null" => "1"),
+                                       "file" => array("type" => "char(255)", "not null" => "1"),
+                                       "function" => array("type" => "char(255)", "not null" => "1"),
+                                       "priority" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "hook_file_function" => array("hook","file","function"),
+                                       )
+                       );
+       $db["intro"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "fid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
+                                       "contact-id" => array("type" => "int(11)", "not null" => "1"),
+                                       "knowyou" => array("type" => "tinyint(1)", "not null" => "1"),
+                                       "duplex" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "note" => array("type" => "text", "not null" => "1"),
+                                       "hash" => array("type" => "char(255)", "not null" => "1"),
+                                       "datetime" => array("type" => "datetime", "not null" => "1"),
+                                       "blocked" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
+                                       "ignore" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["item"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "guid" => array("type" => "char(64)", "not null" => "1"),
+                                       "uri" => array("type" => "char(255)", "not null" => "1"),
+                                       "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
+                                       "contact-id" => array("type" => "int(11)", "not null" => "1"),
+                                       "type" => array("type" => "char(255)", "not null" => "1"),
+                                       "wall" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "gravity" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "parent" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
+                                       "parent-uri" => array("type" => "char(255)", "not null" => "1"),
+                                       "extid" => array("type" => "char(255)", "not null" => "1"),
+                                       "thr-parent" => array("type" => "char(255)", "not null" => "1"),
+                                       "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "commented" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "received" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "changed" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "owner-name" => array("type" => "char(255)", "not null" => "1"),
+                                       "owner-link" => array("type" => "char(255)", "not null" => "1"),
+                                       "owner-avatar" => array("type" => "char(255)", "not null" => "1"),
+                                       "author-name" => array("type" => "char(255)", "not null" => "1"),
+                                       "author-link" => array("type" => "char(255)", "not null" => "1"),
+                                       "author-avatar" => array("type" => "char(255)", "not null" => "1"),
+                                       "title" => array("type" => "char(255)", "not null" => "1"),
+                                       "body" => array("type" => "mediumtext", "not null" => "1"),
+                                       "app" => array("type" => "char(255)", "not null" => "1"),
+                                       "verb" => array("type" => "char(255)", "not null" => "1"),
+                                       "object-type" => array("type" => "char(255)", "not null" => "1"),
+                                       "object" => array("type" => "text", "not null" => "1"),
+                                       "target-type" => array("type" => "char(255)", "not null" => "1"),
+                                       "target" => array("type" => "text", "not null" => "1"),
+                                       "postopts" => array("type" => "text", "not null" => "1"),
+                                       "plink" => array("type" => "char(255)", "not null" => "1"),
+                                       "resource-id" => array("type" => "char(255)", "not null" => "1"),
+                                       "event-id" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "tag" => array("type" => "mediumtext", "not null" => "1"),
+                                       "attach" => array("type" => "mediumtext", "not null" => "1"),
+                                       "inform" => array("type" => "mediumtext", "not null" => "1"),
+                                       "file" => array("type" => "mediumtext", "not null" => "1"),
+                                       "location" => array("type" => "char(255)", "not null" => "1"),
+                                       "coord" => array("type" => "char(255)", "not null" => "1"),
+                                       "allow_cid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "allow_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "deny_cid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "deny_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "private" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "pubmail" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "moderated" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "visible" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "spam" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "starred" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "bookmark" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "unseen" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
+                                       "deleted" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "origin" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "forum_mode" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "last-child" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "1"),
+                                       "mention" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "network" => array("type" => "char(32)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "guid" => array("guid"),
+                                       "uri" => array("uri"),
+                                       "parent" => array("parent"),
+                                       "parent-uri" => array("parent-uri"),
+                                       "extid" => array("extid"),
+                                       "uid_id" => array("uid","id"),
+                                       "uid_created" => array("uid","created"),
+                                       "uid_unseen" => array("uid","unseen"),
+                                       "uid_network_received" => array("uid","network","received"),
+                                       "uid_received" => array("uid","received"),
+                                       "uid_network_commented" => array("uid","network","commented"),
+                                       "uid_commented" => array("uid","commented"),
+                                       "uid_title" => array("uid","title"),
+                                       "uid_thrparent" => array("uid","thr-parent"),
+                                       "uid_parenturi" => array("uid","parent-uri"),
+                                       "uid_contactid_created" => array("uid","contact-id","created"),
+                                       "wall_body" => array("wall","body(6)"),
+                                       "uid_visible_moderated_created" => array("uid","visible","moderated","created"),
+                                       "uid_uri" => array("uid","uri"),
+                                       "uid_wall_created" => array("uid","wall","created"),
+                                       "resource-id" => array("resource-id"),
+                                       "uid_type" => array("uid","type"),
+                                       "uid_starred" => array("uid","starred"),
+                                       "contactid_allowcid_allowpid_denycid_denygid" => array("contact-id","allow_cid(10)","allow_gid(10)","deny_cid(10)","deny_gid(10)"),
+                                       "uid_wall_parent_created" => array("uid","wall","parent","created"),
+                                       "uid_type_changed" => array("uid","type","changed"),
+                                       "contactid_verb" => array("contact-id","verb"),
+                                       "deleted_changed" => array("deleted","changed"),
+                                       "uid_wall_changed" => array("uid","wall","changed"),
+                                       "uid_eventid" => array("uid","event-id"),
+                                       "uid_authorlink" => array("uid","author-link"),
+                                       "uid_ownerlink" => array("uid","owner-link"),
+                                       )
+                       );
+       $db["item_id"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "iid" => array("type" => "int(11)", "not null" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "sid" => array("type" => "char(255)", "not null" => "1"),
+                                       "service" => array("type" => "char(255)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid" => array("uid"),
+                                       "sid" => array("sid"),
+                                       "service" => array("service"),
+                                       "iid" => array("iid"),
+                                       )
+                       );
+       $db["locks"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "name" => array("type" => "char(128)", "not null" => "1"),
+                                       "locked" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["mail"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "guid" => array("type" => "char(64)", "not null" => "1"),
+                                       "from-name" => array("type" => "char(255)", "not null" => "1"),
+                                       "from-photo" => array("type" => "char(255)", "not null" => "1"),
+                                       "from-url" => array("type" => "char(255)", "not null" => "1"),
+                                       "contact-id" => array("type" => "char(255)", "not null" => "1"),
+                                       "convid" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "title" => array("type" => "char(255)", "not null" => "1"),
+                                       "body" => array("type" => "mediumtext", "not null" => "1"),
+                                       "seen" => array("type" => "tinyint(1)", "not null" => "1"),
+                                       "reply" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "replied" => array("type" => "tinyint(1)", "not null" => "1"),
+                                       "unknown" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "uri" => array("type" => "char(255)", "not null" => "1"),
+                                       "parent-uri" => array("type" => "char(255)", "not null" => "1"),
+                                       "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid" => array("uid"),
+                                       "guid" => array("guid"),
+                                       "convid" => array("convid"),
+                                       "reply" => array("reply"),
+                                       "uri" => array("uri"),
+                                       "parent-uri" => array("parent-uri"),
+                                       )
+                       );
+       $db["mailacct"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "server" => array("type" => "char(255)", "not null" => "1"),
+                                       "port" => array("type" => "int(11)", "not null" => "1"),
+                                       "ssltype" => array("type" => "char(16)", "not null" => "1"),
+                                       "mailbox" => array("type" => "char(255)", "not null" => "1"),
+                                       "user" => array("type" => "char(255)", "not null" => "1"),
+                                       "pass" => array("type" => "text", "not null" => "1"),
+                                       "reply_to" => array("type" => "char(255)", "not null" => "1"),
+                                       "action" => array("type" => "int(11)", "not null" => "1"),
+                                       "movetofolder" => array("type" => "char(255)", "not null" => "1"),
+                                       "pubmail" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "last_check" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["manage"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "mid" => array("type" => "int(11)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid_mid" => array("uid","mid"),
+                                       )
+                       );
+       $db["notify"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "hash" => array("type" => "char(64)", "not null" => "1"),
+                                       "type" => array("type" => "int(11)", "not null" => "1"),
+                                       "name" => array("type" => "char(255)", "not null" => "1"),
+                                       "url" => array("type" => "char(255)", "not null" => "1"),
+                                       "photo" => array("type" => "char(255)", "not null" => "1"),
+                                       "date" => array("type" => "datetime", "not null" => "1"),
+                                       "msg" => array("type" => "mediumtext", "not null" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "link" => array("type" => "char(255)", "not null" => "1"),
+                                       "parent" => array("type" => "int(11)", "not null" => "1"),
+                                       "seen" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "verb" => array("type" => "char(255)", "not null" => "1"),
+                                       "otype" => array("type" => "char(16)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid" => array("uid"),
+                                       )
+                       );
+       $db["notify-threads"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "notify-id" => array("type" => "int(11)", "not null" => "1"),
+                                       "master-parent-item" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
+                                       "parent-item" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
+                                       "receiver-uid" => array("type" => "int(11)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "master-parent-item" => array("master-parent-item"),
+                                       "receiver-uid" => array("receiver-uid"),
+                                       )
+                       );
+       $db["pconfig"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
+                                       "cat" => array("type" => "char(255)", "not null" => "1"),
+                                       "k" => array("type" => "char(255)", "not null" => "1"),
+                                       "v" => array("type" => "mediumtext", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "access" => array("uid","cat","k"),
+                                       )
+                       );
+       $db["photo"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "contact-id" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "guid" => array("type" => "char(64)", "not null" => "1"),
+                                       "resource-id" => array("type" => "char(255)", "not null" => "1"),
+                                       "created" => array("type" => "datetime", "not null" => "1"),
+                                       "edited" => array("type" => "datetime", "not null" => "1"),
+                                       "title" => array("type" => "char(255)", "not null" => "1"),
+                                       "desc" => array("type" => "text", "not null" => "1"),
+                                       "album" => array("type" => "char(255)", "not null" => "1"),
+                                       "filename" => array("type" => "char(255)", "not null" => "1"),
+                                       "type" => array("type" => "char(128)", "not null" => "1", "default" => "image/jpeg"),
+                                       "height" => array("type" => "smallint(6)", "not null" => "1"),
+                                       "width" => array("type" => "smallint(6)", "not null" => "1"),
+                                       "datasize" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
+                                       "data" => array("type" => "mediumblob", "not null" => "1"),
+                                       "scale" => array("type" => "tinyint(3)", "not null" => "1"),
+                                       "profile" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "allow_cid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "allow_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "deny_cid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "deny_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid" => array("uid"),
+                                       "resource-id" => array("resource-id"),
+                                       "guid" => array("guid"),
+                                       )
+                       );
+       $db["poll"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "q0" => array("type" => "mediumtext", "not null" => "1"),
+                                       "q1" => array("type" => "mediumtext", "not null" => "1"),
+                                       "q2" => array("type" => "mediumtext", "not null" => "1"),
+                                       "q3" => array("type" => "mediumtext", "not null" => "1"),
+                                       "q4" => array("type" => "mediumtext", "not null" => "1"),
+                                       "q5" => array("type" => "mediumtext", "not null" => "1"),
+                                       "q6" => array("type" => "mediumtext", "not null" => "1"),
+                                       "q7" => array("type" => "mediumtext", "not null" => "1"),
+                                       "q8" => array("type" => "mediumtext", "not null" => "1"),
+                                       "q9" => array("type" => "mediumtext", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid" => array("uid"),
+                                       )
+                       );
+       $db["poll_result"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "poll_id" => array("type" => "int(11)", "not null" => "1"),
+                                       "choice" => array("type" => "int(11)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "poll_id" => array("poll_id"),
+                                       "choice" => array("choice"),
+                                       )
+                       );
+       $db["profile"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "profile-name" => array("type" => "char(255)", "not null" => "1"),
+                                       "is-default" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "hide-friends" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "name" => array("type" => "char(255)", "not null" => "1"),
+                                       "pdesc" => array("type" => "char(255)", "not null" => "1"),
+                                       "dob" => array("type" => "char(32)", "not null" => "1", "default" => "0000-00-00"),
+                                       "address" => array("type" => "char(255)", "not null" => "1"),
+                                       "locality" => array("type" => "char(255)", "not null" => "1"),
+                                       "region" => array("type" => "char(255)", "not null" => "1"),
+                                       "postal-code" => array("type" => "char(32)", "not null" => "1"),
+                                       "country-name" => array("type" => "char(255)", "not null" => "1"),
+                                       "hometown" => array("type" => "char(255)", "not null" => "1"),
+                                       "gender" => array("type" => "char(32)", "not null" => "1"),
+                                       "marital" => array("type" => "char(255)", "not null" => "1"),
+                                       "showwith" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "with" => array("type" => "text", "not null" => "1"),
+                                       "howlong" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "sexual" => array("type" => "char(255)", "not null" => "1"),
+                                       "politic" => array("type" => "char(255)", "not null" => "1"),
+                                       "religion" => array("type" => "char(255)", "not null" => "1"),
+                                       "pub_keywords" => array("type" => "text", "not null" => "1"),
+                                       "prv_keywords" => array("type" => "text", "not null" => "1"),
+                                       "likes" => array("type" => "text", "not null" => "1"),
+                                       "dislikes" => array("type" => "text", "not null" => "1"),
+                                       "about" => array("type" => "text", "not null" => "1"),
+                                       "summary" => array("type" => "char(255)", "not null" => "1"),
+                                       "music" => array("type" => "text", "not null" => "1"),
+                                       "book" => array("type" => "text", "not null" => "1"),
+                                       "tv" => array("type" => "text", "not null" => "1"),
+                                       "film" => array("type" => "text", "not null" => "1"),
+                                       "interest" => array("type" => "text", "not null" => "1"),
+                                       "romance" => array("type" => "text", "not null" => "1"),
+                                       "work" => array("type" => "text", "not null" => "1"),
+                                       "education" => array("type" => "text", "not null" => "1"),
+                                       "contact" => array("type" => "text", "not null" => "1"),
+                                       "homepage" => array("type" => "char(255)", "not null" => "1"),
+                                       "photo" => array("type" => "char(255)", "not null" => "1"),
+                                       "thumb" => array("type" => "char(255)", "not null" => "1"),
+                                       "publish" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "net-publish" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "hometown" => array("hometown"),
+                                       )
+                       );
+       $db["profile_check"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "cid" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "dfrn_id" => array("type" => "char(255)", "not null" => "1"),
+                                       "sec" => array("type" => "char(255)", "not null" => "1"),
+                                       "expire" => array("type" => "int(11)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["push_subscriber"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "callback_url" => array("type" => "char(255)", "not null" => "1"),
+                                       "topic" => array("type" => "char(255)", "not null" => "1"),
+                                       "nickname" => array("type" => "char(255)", "not null" => "1"),
+                                       "push" => array("type" => "int(11)", "not null" => "1"),
+                                       "last_update" => array("type" => "datetime", "not null" => "1"),
+                                       "secret" => array("type" => "char(255)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["queue"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "cid" => array("type" => "int(11)", "not null" => "1"),
+                                       "network" => array("type" => "char(32)", "not null" => "1"),
+                                       "created" => array("type" => "datetime", "not null" => "1"),
+                                       "last" => array("type" => "datetime", "not null" => "1"),
+                                       "content" => array("type" => "mediumtext", "not null" => "1"),
+                                       "batch" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "cid" => array("cid"),
+                                       "created" => array("created"),
+                                       "last" => array("last"),
+                                       "network" => array("network"),
+                                       "batch" => array("batch"),
+                                       )
+                       );
+       $db["register"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "hash" => array("type" => "char(255)", "not null" => "1"),
+                                       "created" => array("type" => "datetime", "not null" => "1"),
+                                       "uid" => array("type" => "int(11) unsigned", "not null" => "1"),
+                                       "password" => array("type" => "char(255)", "not null" => "1"),
+                                       "language" => array("type" => "char(16)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["retriever_item"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "item-uri" => array("type" => "varchar(800)", "not null" => "1"),
+                                       "item-uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
+                                       "contact-id" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
+                                       "resource" => array("type" => "int(11)", "not null" => "1"),
+                                       "parent" => array("type" => "int(11)", "not null" => "1"),
+                                       "finished" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "resource" => array("resource"),
+                                       "all" => array("item-uri(767)","item-uid","contact-id"),
+                                       )
+                       );
+       $db["retriever_resource"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "type" => array("type" => "char(255)", "not null" => "1"),
+                                       "binary" => array("type" => "int(1)", "not null" => "1", "default" => "0"),
+                                       "url" => array("type" => "varchar(800)", "not null" => "1"),
+                                       "created" => array("type" => "timestamp", "not null" => "1", "default" => "CURRENT_TIMESTAMP"),
+                                       "completed" => array("type" => "timestamp"),
+                                       "last-try" => array("type" => "timestamp"),
+                                       "num-tries" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
+                                       "data" => array("type" => "mediumtext", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["retriever_rule"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "contact-id" => array("type" => "int(11)", "not null" => "1"),
+                                       "data" => array("type" => "mediumtext", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid" => array("uid"),
+                                       "contact-id" => array("contact-id"),
+                                       )
+                       );
+       $db["search"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "term" => array("type" => "char(255)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid" => array("uid"),
+                                       "term" => array("term"),
+                                       )
+                       );
+       $db["session"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "bigint(20) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "sid" => array("type" => "char(255)", "not null" => "1"),
+                                       "data" => array("type" => "text", "not null" => "1"),
+                                       "expire" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "sid" => array("sid"),
+                                       "expire" => array("expire"),
+                                       )
+                       );
+       $db["sign"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "iid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
+                                       "retract_iid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
+                                       "signed_text" => array("type" => "mediumtext", "not null" => "1"),
+                                       "signature" => array("type" => "text", "not null" => "1"),
+                                       "signer" => array("type" => "char(255)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "iid" => array("iid"),
+                                       "retract_iid" => array("retract_iid"),
+                                       )
+                       );
+       $db["spam"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       "spam" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
+                                       "ham" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
+                                       "term" => array("type" => "char(255)", "not null" => "1"),
+                                       "date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "uid" => array("uid"),
+                                       "spam" => array("spam"),
+                                       "ham" => array("ham"),
+                                       "term" => array("term"),
+                                       )
+                       );
+       $db["term"] = array(
+                       "fields" => array(
+                                       "tid" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "oid" => array("type" => "int(10) unsigned", "not null" => "1"),
+                                       "otype" => array("type" => "tinyint(3) unsigned", "not null" => "1"),
+                                       "type" => array("type" => "tinyint(3) unsigned", "not null" => "1"),
+                                       "term" => array("type" => "char(255)", "not null" => "1"),
+                                       "url" => array("type" => "char(255)", "not null" => "1"),
+                                       "aid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
+                                       "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("tid"),
+                                       "oid_otype_type_term" => array("oid","otype","type","term"),
+                                       "uid_term_tid" => array("uid","term","tid"),
+                                       "type_term" => array("type","term"),
+                                       "uid_otype_type_term_tid" => array("uid","otype","type","term","tid"),
+                                       "otype_type_term_tid" => array("otype","type","term","tid"),
+                                       )
+                       );
+       $db["thread"] = array(
+                       "fields" => array(
+                                       "iid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "primary" => "1"),
+                                       "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
+                                       "contact-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
+                                       "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "commented" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "received" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "changed" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "wall" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "private" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "pubmail" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "moderated" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "visible" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "spam" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "starred" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "bookmark" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "unseen" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
+                                       "deleted" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "origin" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "forum_mode" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "mention" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "network" => array("type" => "char(32)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("iid"),
+                                       "created" => array("created"),
+                                       "commented" => array("commented"),
+                                       "uid_network_commented" => array("uid","network","commented"),
+                                       "uid_network_created" => array("uid","network","created"),
+                                       "uid_contactid_commented" => array("uid","contact-id","commented"),
+                                       "uid_contactid_created" => array("uid","contact-id","created"),
+                                       "wall_private_received" => array("wall","private","received"),
+                                       "uid_created" => array("uid","created"),
+                                       "uid_commented" => array("uid","commented"),
+                                       )
+                       );
+       $db["tokens"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "varchar(40)", "not null" => "1", "primary" => "1"),
+                                       "secret" => array("type" => "varchar(40)", "not null" => "1"),
+                                       "client_id" => array("type" => "varchar(20)", "not null" => "1"),
+                                       "expires" => array("type" => "int(11)", "not null" => "1"),
+                                       "scope" => array("type" => "varchar(200)", "not null" => "1"),
+                                       "uid" => array("type" => "int(11)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       )
+                       );
+       $db["unique_contacts"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "url" => array("type" => "char(255)", "not null" => "1"),
+                                       "nick" => array("type" => "char(255)", "not null" => "1"),
+                                       "name" => array("type" => "char(255)", "not null" => "1"),
+                                       "avatar" => array("type" => "char(255)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "url" => array("url"),
+                                       )
+                       );
+       $db["user"] = array(
+                       "fields" => array(
+                                       "uid" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "guid" => array("type" => "char(64)", "not null" => "1"),
+                                       "username" => array("type" => "char(255)", "not null" => "1"),
+                                       "password" => array("type" => "char(255)", "not null" => "1"),
+                                       "nickname" => array("type" => "char(255)", "not null" => "1"),
+                                       "email" => array("type" => "char(255)", "not null" => "1"),
+                                       "openid" => array("type" => "char(255)", "not null" => "1"),
+                                       "timezone" => array("type" => "char(128)", "not null" => "1"),
+                                       "language" => array("type" => "char(32)", "not null" => "1", "default" => "en"),
+                                       "register_date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "login_date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "default-location" => array("type" => "char(255)", "not null" => "1"),
+                                       "allow_location" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "theme" => array("type" => "char(255)", "not null" => "1"),
+                                       "pubkey" => array("type" => "text", "not null" => "1"),
+                                       "prvkey" => array("type" => "text", "not null" => "1"),
+                                       "spubkey" => array("type" => "text", "not null" => "1"),
+                                       "sprvkey" => array("type" => "text", "not null" => "1"),
+                                       "verified" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
+                                       "blocked" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
+                                       "blockwall" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
+                                       "hidewall" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
+                                       "blocktags" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
+                                       "unkmail" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "cntunkmail" => array("type" => "int(11)", "not null" => "1", "default" => "10"),
+                                       "notify-flags" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "65535"),
+                                       "page-flags" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
+                                       "prvnets" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "pwdreset" => array("type" => "char(255)", "not null" => "1"),
+                                       "maxreq" => array("type" => "int(11)", "not null" => "1", "default" => "10"),
+                                       "expire" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
+                                       "account_removed" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "account_expired" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "account_expires_on" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "expire_notification_sent" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       "service_class" => array("type" => "char(32)", "not null" => "1"),
+                                       "def_gid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
+                                       "allow_cid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "allow_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "deny_cid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "deny_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "openidserver" => array("type" => "text", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("uid"),
+                                       "nickname" => array("nickname"),
+                                       )
+                       );
+       $db["userd"] = array(
+                       "fields" => array(
+                                       "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
+                                       "username" => array("type" => "char(255)", "not null" => "1"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("id"),
+                                       "username" => array("username"),
+                                       )
+                       );
+
+       return($db);
+}
diff --git a/library/dddbl2/config.inc.php b/library/dddbl2/config.inc.php
new file mode 100644 (file)
index 0000000..4dcb98e
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+
+namespace DDDBL;
+
+require_once __DIR__ . '/inc/DataObjectPool.class.php';
+require_once __DIR__ . '/inc/DataObject.class.php';
+require_once __DIR__ . '/inc/Singleton.class.php';
+require_once __DIR__ . '/inc/Queue.class.php';
+
+require_once __DIR__ . '/inc/exceptions/UnexpectedParameterTypeException.class.php';
+require_once __DIR__ . '/inc/exceptions/QueryException.class.php';
+
+require_once __DIR__ . '/inc/database.func.php';
+
+# position of handler, which gets the active database-connection into the queue
+define('QUEUE_GET_DB_CONNECTION_POSITION', 10);
+define('QUEUE_GET_QUERY_POSITION',         20);
+define('QUEUE_BIND_DATA_TYPE_POSITION',    30);
+define('QUEUE_PREPARE_QUERY_POSITION',     40);
+define('QUEUE_EXECUTE_QUERY_POSITION',     50);
+define('QUEUE_FORMAT_RESULT_POSITION',     60);
+define('QUEUE_CLOSE_CURSOR_POSITION',      70);
+
+###############################################
+### set validator for "Database-Definition" ###
+###############################################
+
+$objDBDefinitionValidator = function ($arrValues) {
+
+  foreach(array('CONNECTION', 'USER', 'PASS') AS $strDefinitionField)
+    if(!isset($arrValues[$strDefinitionField]) || !is_string($arrValues[$strDefinitionField]))
+      return false;
+
+  if(isset($arrValues['PDO']) && !is_a($arrValues['PDO'], '\PDO'))
+    return false;
+
+  return true;
+
+};
+
+$objDataObjectPool = new DataObjectPool('Database-Definition');
+$objDataObjectPool->setValidator($objDBDefinitionValidator);
+
+############################################
+### set validator for "Query-Definition" ###
+############################################
+
+$objQueryDefinitionValidator = function ($arrValues) {
+
+  if(!isset($arrValues['QUERY']) || !is_string($arrValues['QUERY']))
+    return false;
+
+  if(isset($arrValues['HANDLER']) && !is_string($arrValues['HANDLER']))
+    return false;
+
+  return true;
+
+};
+
+$objDataObjectPool = new DataObjectPool('Query-Definition');
+$objDataObjectPool->setValidator($objQueryDefinitionValidator);
+
+##########################################
+### set validator for "Result-Handler" ###
+##########################################
+
+$objResultHandlerValidator = function ($arrValues) {
+
+  if(!isset($arrValues['HANDLER']) || !is_callable($arrValues['HANDLER']))
+    return false;
+
+  return true;
+};
+
+$objDataObjectPool = new DataObjectPool('Result-Handler');
+$objDataObjectPool->setValidator($objResultHandlerValidator);
+
+#########################################
+### register queue and result handler ###
+#########################################
+
+require_once __DIR__ . '/handler/register_queue_handler.inc.php';
+require_once __DIR__ . '/handler/register_result_handler.inc.php';
diff --git a/library/dddbl2/dddbl.php b/library/dddbl2/dddbl.php
new file mode 100644 (file)
index 0000000..5b5441f
--- /dev/null
@@ -0,0 +1,184 @@
+<?php
+
+namespace DDDBL;
+
+require_once __DIR__ . '/config.inc.php';
+
+/**
+  * @throws \Exception                       - if no parameter are given
+  * @throws UnexpectedParameterTypeException - if first parameter is not a string
+  *
+  * @returns (mixed) - the result of the query-definition execution
+  *
+  * expect a list of parameter with at least one value. the
+  * list is handled over to the queue, which will executed
+  * with them
+  *
+  * in the end a result of the execution of the query-definition
+  * through the stored handler is returned
+  *
+  **/
+function get() {
+
+  $arrParameter = func_get_args();
+  
+  if(empty($arrParameter))
+    throw new \Exception ("no parameter given for execution");
+  
+  if(!is_string($arrParameter[0]))
+    throw new UnexpectedParameterTypeException('string', $arrParameter[0]);
+
+  # get instance of queue and work with a copy of it
+  $objQueue = Singleton::getInstance('\DDDBL\Queue');
+  $objQueue = $objQueue->getClone();
+  
+  return $objQueue->execute($arrParameter);
+
+}
+
+/**
+  * @param $strFile - the file with the query definitions to store
+  *
+  * store all query-definitions from the given file
+  *
+  **/
+function storeQueryFileContent($strFile) {
+
+  storeDefinitionsFromFileInGroup($strFile, 'Query-Definition');
+
+}
+
+/**
+  * @param $strDir   - the dir with query-definitions files
+  * @param $strMatch - a rule files in the dir have to match
+  *
+  * iterate through all files in the given dir. if a file matches
+  * the rule in $strMatch, the definitions in the file will be stored
+  * as query-definitions. all files are match in default.
+  *
+  **/
+function loadQueryDefinitionsInDir($strDir, $strMatch = '*') {
+
+  walkDirForCallback($strDir, '\DDDBL\storeQueryFileContent', $strMatch);
+
+}
+
+/**
+  * @param $strFile - the file with the database definitions to store
+  *
+  * store all database definition from the given file
+  *
+  **/
+function storeDBFileContent($strFile) {
+
+  $cloAdditionalHandler = function ($objDataObjectPool, $arrDefinition) {
+    if(!empty($arrDefinition['DEFAULT'])  && true == (boolean) $arrDefinition['DEFAULT'])
+      $objDataObjectPool->add('DEFAULT', $arrDefinition);
+  };
+
+  storeDefinitionsFromFileInGroup($strFile, 'Database-Definition', $cloAdditionalHandler);
+
+}
+
+/**
+  * @param $strDir   - the dir with query-definitions files
+  * @param $strMatch - a rule files in the dir have to match
+  *
+  * iterate through all files in the given dir. if a file matches
+  * the rule in $strMatch, the definitions in the file will be stored
+  * as database-definitions. all files are matched in default.
+  *
+  **/
+function loadDBDefinitionsInDir($strDir, $strMatch = '*') {
+
+  walkDirForCallback($strDir, '\DDDBL\loadDBDefinitionsInDir', $strMatch);
+
+}
+
+/**
+  * @param $strPath          - the path to the dir to handle
+  * @param $strCallback      - the callback to call when a matching file is found
+  * @param $strFilenameMatch - the rule to filename has to match
+  *
+  * @throws UnexpectedParameterTypeException - if the given path or filematch-rule is not a string
+  * @throws UnexpectedParameterTypeException - if the given callback is not a callable
+  * @throws \Exception - if given path is not a directory
+  * @throws \Exception - if the directory is not readable
+  *
+  * reads all files of the given directory (just directory, not recursive)
+  * and checks, if the filename matches against the given rule. if
+  * a match is found the given callback is called with the full
+  * path to the file
+  *
+  **/
+function walkDirForCallback($strPath, $strCallback, $strFilenameMatch) {
+
+  if(!is_string($strPath))
+    throw new UnexpectedParameterTypeException('string', $strPath);
+  
+  if(!is_callable($strCallback))
+    throw new UnexpectedParameterTypeException('callable', $strCallback);
+    
+  if(!is_string($strFilenameMatch))
+    throw new UnexpectedParameterTypeException('string', $strFilenameMatch);
+  
+  if(!is_dir($strPath))
+    throw new \Exception ('given path is not an directory: ' . $strPath);
+  
+  $resDirHandle = opendir($strPath);
+  
+  if(!is_resource($resDirHandle))
+    throw new \Exception ('could not read directory: ' . $strPath);
+  
+  while($strFile = readdir($resDirHandle))
+    if(is_file($strPath.$strFile) && fnmatch($strFilenameMatch, $strFile)) 
+      call_user_func_array($strCallback, array($strPath.$strFile));
+  
+  closedir($resDirHandle);
+  
+}
+
+/**
+  * @param $strFile  - the file with definitions
+  * @param $strGroup - the group the definitions should be stored in
+  *
+  * @throws UnexpectedParameterTypeException - if the given file is not a string
+  * @throws UnexpectedParameterTypeException - if the given optional handler is not a callable
+  * @throws \Exception - if the given file is not a file or do not exists
+  * @throws \Exception - if the given file is not readable
+  *
+  * generic function to store all definitions in a given file
+  * in the specified group.
+  *
+  * if an additional handler is given, it is called AFTER the storage of the
+  * definition. when called it will get the reference to the DataObjectPool and the 
+  * found definition as parameter.
+  *
+  **/
+function storeDefinitionsFromFileInGroup($strFile, $strGroup, $cloAdditionalHandler = null) {
+
+  if(!is_string($strGroup))
+    throw new UnexpectedParameterTypeException('string', $strGroup);
+    
+  if(!is_null($cloAdditionalHandler) && !is_callable($cloAdditionalHandler))
+    throw new UnexpectedParameterTypeException('callable', $cloAdditionalHandler);
+
+  if(!is_file($strFile) || !file_exists($strFile))
+    throw new \Exception ("given file is not a file or doesn't exists: $strFile");
+
+  if(!is_readable($strFile))
+    throw new \Exception ("given file is not readable: $strFile");
+
+  $arrDefinitions = parse_ini_file($strFile, true);
+  
+  $objDataObjectPool = new DataObjectPool($strGroup);
+  
+  foreach($arrDefinitions AS $strDefinitionAlias => $arrDefinition) {
+    $objDataObjectPool->add($strDefinitionAlias, $arrDefinition);
+    
+    if(!is_null($cloAdditionalHandler))
+      $cloAdditionalHandler($objDataObjectPool, $arrDefinition);
+
+  }
+
+}
diff --git a/library/dddbl2/handler/register_queue_handler.inc.php b/library/dddbl2/handler/register_queue_handler.inc.php
new file mode 100644 (file)
index 0000000..1e9fb23
--- /dev/null
@@ -0,0 +1,208 @@
+<?php
+
+namespace DDDBL;
+
+$objQueue = Singleton::getInstance('\DDDBL\Queue');
+
+#############################
+### db-connection handler ###
+#############################
+
+# get (or first establish) connection to database
+# and store the DataObject of the connection in the Queue-State
+
+$cloStoreDBConnection = function(\DDDBL\Queue $objQueue, array $arrParameter) {
+
+  if(!isConnected())
+    connect();
+  
+  $objQueue->getState()->update(array('DB' => getDBDataObject()));
+
+};
+
+$objQueue->addHandler(QUEUE_GET_DB_CONNECTION_POSITION, $cloStoreDBConnection);
+
+###############################
+### query-definition-loader ###
+###############################
+
+# get the DataObject of the query and store it in the queue
+
+$cloGetQuery = function(\DDDBL\Queue $objQueue, array $arrParameter) {
+
+  $objDataObjectPool = new DataObjectPool('Query-Definition');
+
+  # get the first entry of the parameter-list; this is the query-alias
+  $strAlias = array_shift($arrParameter);
+
+  if(empty($strAlias) || !is_string($strAlias))
+    throw new \Exception('no query-alias defined!');
+
+  if(!$objDataObjectPool->exists($strAlias))
+    throw new \Exception("given query alias is unknown: $strAlias");
+  
+  $objQueue->getState()->update(array('QUERY' => $objDataObjectPool->get($strAlias)));
+
+};
+
+$objQueue->addHandler(QUEUE_GET_QUERY_POSITION, $cloGetQuery);
+
+#################################
+### set BIND-DATA-TYPE option ###
+#################################
+
+# check if the query has a BIND-DATA-TYPE config.
+# if not check if there is one given for the database-connection.
+# if yes, store it as setting for the query, otherwise
+# set false for this option
+
+$cloSetBindDataTypeConfig = function(\DDDBL\Queue $objQueue, array $arrParameter) {
+
+  $objDB    = $objQueue->getState()->get('DB');
+  $objQuery = $objQueue->getState()->get('QUERY');
+
+  # skip this step, if the query itselfs has its own
+  if($objQuery->exists('BIND-DATA-TYPE')) {
+    $objQuery->update(array('BIND-DATA-TYPE' => (bool) $objQuery->get('BIND-DATA-TYPE'))); #bugfix for php-bug #38409
+    return;
+  }
+
+  # set type to false, if no config is available, otherwise use the given config
+  if(!$objDB->exists('BIND-DATA-TYPE'))
+    $objQuery->update(array('BIND-DATA-TYPE' => false));
+  else
+    $objQuery->update(array('BIND-DATA-TYPE' => (bool) $objDB->get('BIND-DATA-TYPE')));
+
+};
+
+$objQueue->addHandler(QUEUE_BIND_DATA_TYPE_POSITION, $cloSetBindDataTypeConfig);
+
+#####################
+### prepare query ###
+#####################
+
+# get the stored query and prepare() it for the given database-connection
+# store the resulting PDOStatement
+
+$cloPrepareQuery = function(\DDDBL\Queue $objQueue, array $arrParameter) {
+
+  # if query is not prepared yet, do this now
+  if(!$objQueue->getState()->get('QUERY')->exists('PDOStatement')) {
+    $objPDO = $objQueue->getState()->get('DB')->get('PDO');
+    $objPDO = $objPDO->prepare($objQueue->getState()->get('QUERY')->get('QUERY'));
+    $objQueue->getState()->get('QUERY')->update(array('PDOStatement' => $objPDO));
+  }
+
+  # copy reference of prepared statement into queue for execution
+  $objQueue->getState()->update(array('PDOStatement' => $objQueue->getState()->get('QUERY')->get('PDOStatement')));
+
+};
+
+$objQueue->addHandler(QUEUE_PREPARE_QUERY_POSITION, $cloPrepareQuery);
+
+#########################
+### execute the query ###
+#########################
+
+# handler, which maps the data-type of a variable to the PDO-constants
+
+$cloMapDataType = function($mixedParameter) {
+
+  $arrDataTypeMap = array('NULL'    => \PDO::PARAM_NULL,
+                          'boolean' => \PDO::PARAM_BOOL,
+                          'integer' => \PDO::PARAM_INT,
+                          'string'  => \PDO::PARAM_STR);
+
+  $strDataType = gettype($mixedParameter);
+
+  if(!isset($arrDataTypeMap[$strDataType]))
+    throw new \Exception ("could not bind parameters data type - type is not supported by PDO: $strDataType");
+
+  return $arrDataTypeMap[$strDataType];
+
+};
+
+# bind the given parameter to the prepared statement,
+# then set the fetch mode and execute the query
+
+$cloQueryExcecute = function(\DDDBL\Queue $objQueue, array $arrParameter) use ($cloMapDataType) {
+
+  $objPDO = $objQueue->getState()->get('PDOStatement');
+
+  # remove the alias from the parameter list
+  array_shift($arrParameter);
+
+  $objQuery = $objQueue->getState()->get('QUERY');
+
+  if(true === $objQuery->get('BIND-DATA-TYPE')) {
+
+    foreach($arrParameter AS $intIndex => $mixedParameter)
+      $objPDO->bindValue($intIndex + 1, $mixedParameter, $cloMapDataType($mixedParameter));
+      
+  } else {
+
+    foreach($arrParameter AS $intIndex => $mixedParameter)
+      $objPDO->bindValue($intIndex + 1, $mixedParameter);
+    
+  }
+  
+  $objPDO->setFetchMode(\PDO::FETCH_ASSOC);
+
+  # execute the query. if execution fails, throw an exception
+  if(!$objPDO->execute())
+    throw new QueryException($objPDO, $objQuery->getAll());
+
+};
+
+$objQueue->addHandler(QUEUE_EXECUTE_QUERY_POSITION, $cloQueryExcecute);
+
+###############################
+### format the query result ###
+###############################
+
+# if a result-handler for the query is configured, call it
+
+$cloFormatQueryResult = function(\DDDBL\Queue $objQueue, array $arrParameter) {
+
+  $objQuery = $objQueue->getState()->get('QUERY');
+
+  if(!$objQuery->exists('HANDLER'))
+    return ;
+
+  # get the handler and its config
+  $strHandlerConfig = $objQuery->get('HANDLER');
+  $arrHandlerConfig = preg_split('/\s+/', $strHandlerConfig);
+  $strHandler       = array_shift($arrHandlerConfig);
+
+  # remove handler-name from config
+  $strHandlerConfig = trim(str_replace($strHandler, '', $strHandlerConfig));
+  
+  $objDataObjectPool = new DataObjectPool('Result-Handler');
+
+  if(!$objDataObjectPool->exists($strHandler))
+    throw new \Exception ("unknown result-handler: $strHandler");
+
+  $objHandler = $objDataObjectPool->get($strHandler);
+  $cloHandler = $objHandler->get('HANDLER');
+
+  $cloHandler($objQueue, $strHandlerConfig);
+
+};
+
+$objQueue->addHandler(QUEUE_FORMAT_RESULT_POSITION, $cloFormatQueryResult);
+
+####################
+### close cursor ###
+####################
+
+# closing the cursor of the PDOStatement. this will free
+# the result and enable the connection to execute the next query
+
+$cloCloseCursor = function(\DDDBL\Queue $objQueue, array $arrParameter) {
+
+  $objQueryResult = $objQueue->getState()->get('PDOStatement');
+  $objQueryResult->closeCursor();
+
+};
+
+$objQueue->addHandler(QUEUE_CLOSE_CURSOR_POSITION, $cloCloseCursor);
diff --git a/library/dddbl2/handler/register_result_handler.inc.php b/library/dddbl2/handler/register_result_handler.inc.php
new file mode 100644 (file)
index 0000000..1ccae0c
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+
+namespace DDDBL;
+
+$objDataObjectPool = new DataObjectPool('Result-Handler');
+
+#################################
+### handler for: SINGLE_VALUE ###
+#################################
+
+$cloSingleValueHandler = function(\DDDBL\Queue $objQueue) {
+
+  $arrResult = $objQueue->getState()->get('PDOStatement')->fetch();
+  $objQueue->getState()->update(array('result' => (empty($arrResult)) ? null : reset($arrResult)));
+
+};
+
+$objDataObjectPool->add('SINGLE_VALUE', array('HANDLER' => $cloSingleValueHandler));
+
+###########################
+### handler for: SINGLE ###
+###########################
+
+$cloSingleHandler = function(\DDDBL\Queue $objQueue) {
+
+  $arrResult = $objQueue->getState()->get('PDOStatement')->fetch();
+  $objQueue->getState()->update(array('result' => (empty($arrResult)) ? null : $arrResult));
+
+};
+
+$objDataObjectPool->add('SINGLE', array('HANDLER' => $cloSingleHandler));
+
+##########################
+### handler for: MULTI ###
+##########################
+
+$cloMultiHandler = function(\DDDBL\Queue $objQueue) {
+
+  $arrResult = $objQueue->getState()->get('PDOStatement')->fetchAll();
+  $objQueue->getState()->update(array('result' => (empty($arrResult)) ? array() : $arrResult));
+
+};
+
+$objDataObjectPool->add('MULTI', array('HANDLER' => $cloMultiHandler));
+
+#########################
+### handler for: LIST ###
+#########################
+
+$cloListHandler = function(\DDDBL\Queue $objQueue) {
+
+  $objResultCursor = $objQueue->getState()->get('PDOStatement');
+
+  $arrResult = array();
+  
+  while($arrRow = $objResultCursor->fetch())
+    array_push($arrResult, current($arrRow));
+
+  $objQueue->getState()->update(array('result' => $arrResult));
+
+};
+
+$objDataObjectPool->add('LIST', array('HANDLER' => $cloListHandler));
+
+#############################
+### handler for: GROUP_BY ###
+#############################
+
+$cloGroupedByHandler = function(\DDDBL\Queue $objQueue, $strGroupColumn) {
+
+  $objResultCursor = $objQueue->getState()->get('PDOStatement');
+
+  $arrResult = array();
+  
+  while($arrRow = $objResultCursor->fetch()) {
+    
+    if(!isset($arrRow[$strGroupColumn]))
+      throw new \Exception ("could not group result by non-existing column: $strGroupColumn");
+    
+    $arrResult[$arrRow[$strGroupColumn]][] = $arrRow;
+
+  }
+
+  $objQueue->getState()->update(array('result' => $arrResult));
+
+};
+
+$objDataObjectPool->add('GROUP_BY', array('HANDLER' => $cloGroupedByHandler));
+
+#############################
+### handler for: NOT_NULL ###
+#############################
+
+$cloNotNullHandler = function(\DDDBL\Queue $objQueue) {
+
+  $arrResult = $objQueue->getState()->get('PDOStatement')->fetch();
+
+  $objQueue->getState()->update(array('result' => (empty($arrResult)) ? false : true));
+
+};
+
+$objDataObjectPool->add('NOT_NULL', array('HANDLER' => $cloNotNullHandler));
diff --git a/library/dddbl2/inc/DataObject.class.php b/library/dddbl2/inc/DataObject.class.php
new file mode 100644 (file)
index 0000000..fa3618d
--- /dev/null
@@ -0,0 +1,195 @@
+<?php
+
+namespace DDDBL;
+
+/**
+  * a DataObject is a generic object
+  * to store data under given keys.
+  * 
+  * it allows getting, adding, updating and deleting
+  * data.
+  * 
+  * a validation callback can be provided
+  * to ensure, that the stored data
+  * validate correctly.
+  *
+  **/
+class DataObject {
+
+  /**
+    * list of stored data 
+    **/
+  private $arrData = array();
+  
+  /**
+    * callback to validate all stored data
+    **/
+  private $cloValidator = null;
+  
+  /**
+    * @param $cloValidator - optional validator callback to validate stored data
+    * @param $arrData      - optional list of data to store in object
+    *
+    * @throws UnexpectedParameterTypeException - if validator callback is not a callable
+    *
+    * initiates the data-object and stores the validator callback. if no
+    * callback is given, a default callback is stored, which validates against
+    * everything.
+    * 
+    * if optional data are given, they are passed to DataObject::add(), to be stored
+    * immediatley
+    *
+    **/
+  public function __construct($cloValidator = null, array $arrData = array()) {
+  
+    if(!is_null($cloValidator) && !is_callable($cloValidator))
+      throw new UnexpectedParameterTypeException('callable', $cloValidator);
+    
+    $this->cloValidator = (!is_null($cloValidator)) ? $cloValidator : function() {return true; };
+    
+    if(!empty($arrData))
+      $this->add($arrData);
+  
+  }
+  
+  /**
+    * @param $arrData - list of data to store in object
+    * 
+    * @throws \Exception - if a key is already in use
+    * @throws \Exception - if the final data-set do not validate
+    *
+    * add the list of data to the existing ones. the given data
+    * must have the following format:
+    * array([key] => data
+    *       [key] => data, [..])
+    *
+    * if a key in the given data is already used in stored
+    * data the addition is aborted and an exception is
+    * thrown.
+    *
+    * the stored data are only modified on success
+    *
+    **/
+  public function add(array $arrData) {
+  
+    $arrMergedData = array_merge($this->arrData, $arrData);
+    
+    foreach($arrData AS $strKey => $mixData)
+      if(array_key_exists($strKey, $this->arrData))
+        throw new \Exception("could not store data, key is already in use: $strKey");
+    
+    $cloValidator = $this->cloValidator;
+    
+    if(!$cloValidator($arrMergedData))
+      throw new \Exception("given data do not validate");
+    
+    $this->arrData = $arrMergedData;
+  
+  }
+  
+  /**
+    * @param $arrData - list of data to update
+    * 
+    * @throws \Exception - if the final data-set do not validate
+    * 
+    * update the stored data with the given data-set. for
+    * the structure of $arrData have a look at DataObject:add()
+    *
+    * existing keys are overwritten with new values. new
+    * keys are added to the data-set.
+    * 
+    * if validation of final set fails, an exception is
+    * thrown. no data are modified on failure.
+    *
+    **/
+  public function update(array $arrData) {
+  
+    $arrMergedData = array_merge($this->arrData, $arrData);
+    
+    $cloValidator = $this->cloValidator;
+    
+    if(!$cloValidator($arrMergedData))
+      throw new \Exception("given data do not validate");
+    
+    $this->arrData = $arrMergedData;
+  
+  }
+  
+  /**
+    * @param $strKey - the key of the value to delete
+    * 
+    * @throws UnexpectedParameterTypeException - if given key is not a string
+    *
+    * delete the value stored under the given key.
+    * if given key do not exists, nothing is done!
+    *
+    **/
+  public function delete($strKey) {
+  
+    if(!is_string($strKey))
+      throw new UnexpectedParameterTypeException('string', $strKey);
+    
+    if($this->exists($strKey))
+      unset($this->arrData[$strKey]);
+  
+  }
+  
+  /**
+    * @param $strKey - the key to check
+    *
+    * @throws UnexpectedParameterTypeException - if given key is not a string
+    *
+    * @return (boolean) true, if key exists
+    * @return (boolean) false, if key do not exists
+    *
+    * check if the given key exists
+    *
+    **/
+  public function exists($strKey) {
+  
+    if(!is_string($strKey))
+      throw new UnexpectedParameterTypeException('string', $strKey);
+    
+    if(!array_key_exists($strKey, $this->arrData))
+      return false;
+    
+    return true;
+  
+  }
+  
+  /**
+    * @param $strKey - the key to get the value from
+    * 
+    * @throws UnexpectedParameterTypeException - if given key is not a string
+    * @throws \Exception - if given key is unknown
+    *
+    * @return (mixed) the value stored under the given key
+    *
+    * return the value stored under the given key
+    *
+    **/
+  public function get($strKey) {
+  
+    if(!is_string($strKey))
+      throw new UnexpectedParameterTypeException('string', $strKey);
+    
+    if(!$this->exists($strKey))
+      throw new \Exception("unknown key: $strKey");
+    
+    return $this->arrData[$strKey];
+  
+  }
+  
+  /**
+    * return all stored data in the structure of:
+    * array([key] => data
+    *       [key] => data, [..])
+    *
+    **/
+  public function getAll() {
+    
+    return $this->arrData;
+    
+  }
+  
+}
\ No newline at end of file
diff --git a/library/dddbl2/inc/DataObjectPool.class.php b/library/dddbl2/inc/DataObjectPool.class.php
new file mode 100644 (file)
index 0000000..13b6e27
--- /dev/null
@@ -0,0 +1,207 @@
+<?php
+
+namespace DDDBL;
+
+/**
+  * The DataObjectPool is a class to  manage
+  * the DataObjects for different types.
+  *
+  * DataObjects are stored within groups. Every group
+  * has a validatator, with is applyed to
+  * every DataObject stored in the group.
+  * If no validatator is set, no validation will
+  * be done.
+  *
+  * A DataObject is referenced by an identifier,
+  * which is uniqiue within a group.
+  *
+  * when creating a DataObjectPool instance,
+  * the wanted group is set. All following
+  * operations are done at this group.
+  *
+  **/
+class DataObjectPool {
+
+  /**
+    * the actual group to operate on
+    *
+    **/
+  private $strGroup = null;
+  
+  /**
+    * list of validators for each group. structure:
+    * array([group] => validator-callback,
+    *       [group-n] => validator-callback-n, [..])
+    *
+    **/
+  static private $arrValidatorList = array();
+  
+  /**
+    * list of DataObjects. stored in the following structure:
+    * array([group][uniqueue-identifier] => DataObject-reference, 
+    *       [group-n][uniqueue-identifier-n] => DataObject-reference-n, [..])
+    *
+    **/
+  static private $arrDataObjects = array(); 
+
+  /**
+    * @param $strGroup - the group of DataObjects to operate on
+    *
+    * @throws UnexpectedParameterTypeException - if given group is not a string
+    *
+    * create an instance of DataObjectPool and store the group
+    * to operate on
+    *
+    **/
+  public function __construct($strGroup) {
+  
+    if(!is_string($strGroup))
+      throw new UnexpectedParameterTypeException('string', $strGroup);
+    
+    $this->strGroup = $strGroup;
+    
+    if(!array_key_exists($this->strGroup, self::$arrValidatorList))
+      self::$arrValidatorList[$this->strGroup] = null;
+    
+    if(!array_key_exists($this->strGroup, self::$arrDataObjects))
+      self::$arrDataObjects[$this->strGroup] = array();
+
+  }
+  
+  /**
+    * @param $cloValidator - the validator to set for the group
+    *
+    * @throws UnexpectedParameterTypeException - if given validator is not a callable
+    *
+    * set the validator for the active group. this validator
+    * is given to each newly created DataObject.
+    * if it is changed, the existing DataObjects are
+    * *NOT* revalidated.
+    *
+    **/
+  public function setValidator($cloValidator) {
+  
+    if(!is_callable($cloValidator))
+      throw new UnexpectedParameterTypeException('string', $cloValidator);
+    
+    self::$arrValidatorList[$this->strGroup] = $cloValidator;
+    
+  }
+  
+  /**
+    * @param $strIdentifier - the unique identifier of the DataObject
+    * @param $arrData       - the data to store in the DataObject
+    *
+    * @see DataObject:add()
+    *
+    * @throws UnexpectedParameterTypeException - if identifier is not a string
+    * @throws \Exception                       - if given identifier is not unique
+    *
+    * @returns (DataObject) - reference to the created DataObject-instance
+    *
+    * create a new DataObject and store it in the pool. The given
+    * identifier is the key to retrieve the DataObject from the pool.
+    * The given data are stored within the DataObject.
+    *
+    * After creation and storage of the DataObject, a reference
+    * to the object is returned
+    *
+    **/
+  public function add($strIdentifier, array $arrData) {
+  
+    if(!is_string($strIdentifier))
+      throw new UnexpectedParameterTypeException('string', $strIdentifier);
+    
+    if($this->exists($strIdentifier))
+      throw new \Exception ("identifier already in use: $strIdentifier");
+    
+    $objDataObject = new DataObject(self::$arrValidatorList[$this->strGroup], $arrData);
+    
+    self::$arrDataObjects[$this->strGroup][$strIdentifier] = $objDataObject;
+    
+    return $objDataObject;
+  
+  }
+  
+  /**
+    * @param $strIdentifier - the identifier of the object to delete
+    *
+    * @throws UnexpectedParameterTypeException - if given identifier is not a string
+    * @throws \Exception                       - if the given identifier is not known
+    *
+    * delete the stored DataObject from the DataObjectPool
+    *
+    **/
+  public function delete($strIdentifier) {
+    
+    if(!is_string($strIdentifier))
+      throw new UnexpectedParameterTypeException('string', $strIdentifier);
+    
+    if(!$this->exists($strIdentifier))
+      throw new \Exception ("DataObject not found, identifier unknown: $strIdentifier");
+    
+    unset(self::$arrDataObjects[$this->strGroup][$strIdentifier]);
+  
+  }
+  
+  /**
+    * @param $strIdentifier - the identifier to check
+    *
+    * @throws UnexpectedParameterTypeException - if given identifier is not a string
+    *
+    * @returns (boolean) true, if the identifier exists
+    * @returns (boolean) false, if the identifier do not exists
+    *
+    **/
+  public function exists($strIdentifier) {
+  
+    if(!is_string($strIdentifier))
+      throw new UnexpectedParameterTypeException('string', $strIdentifier);
+      
+    if(!isset(self::$arrDataObjects[$this->strGroup][$strIdentifier]))
+      return false;
+    
+    return true;
+  
+  }
+  
+  /**
+    * @param $strIdentifier - the identifier of the DataObject to retrieve
+    *
+    * @throws UnexpectedParameterTypeException - if given identifier is not a string
+    * @throws \Exception                       - if given identifier is unknown
+    *
+    * @returns (DataObject) - reference to the DataObject
+    *
+    * returns a reference to the DataObject stored under the identifer
+    *
+    **/
+  public function get($strIdentifier) {
+  
+    if(!is_string($strIdentifier))
+      throw new UnexpectedParameterTypeException('string', $strIdentifier);
+    
+    if(!$this->exists($strIdentifier))
+      throw new \Exception ("DataObject not found, identifier unknown: $strIdentifier");
+      
+    return self::$arrDataObjects[$this->strGroup][$strIdentifier];
+    
+  }
+  
+  /**
+    * @returns (array) - list of all DataObjects of the active group
+    *
+    * returns an array of all stored DataObjects of the active group
+    * with the following structure:
+    *
+    * array([identifier] => DataObject-reference, 
+    *       [identifier-n] => DataObject-reference-n, [..])
+    *
+    **/
+  public function getAll() {
+  
+    return self::$arrDataObjects[$this->strGroup];
+  
+  }
+
+}
diff --git a/library/dddbl2/inc/Queue.class.php b/library/dddbl2/inc/Queue.class.php
new file mode 100644 (file)
index 0000000..236bc61
--- /dev/null
@@ -0,0 +1,138 @@
+<?php
+
+namespace DDDBL;
+
+/**
+  * this class implements a queue of handler, which
+  * are called in a specified order.
+  *
+  * this allows the combiniation of different steps,
+  * like database-connection management, query execution
+  * and result parsing in a simple list of actions.
+  *
+  * Queue::getClone() returns a clone of the queue,
+  * which allows modifications of the queue by
+  * the executed handler.
+  * in this way different problems, like substituions,
+  * test-cases, statistics and much more can be solved,
+  * without destroying the configured order for other queries.
+  *
+  **/
+class Queue {
+
+  /**
+    * the sorted (!) queue of handler to execute
+    *
+    **/
+  private $arrHandlerQueue = array();
+  
+  /**
+    * @see \DDDBL\DataObject
+    * 
+    * an DataObject, which is used to store the states of the queue
+    *
+    **/
+  private $objState   = null;
+
+  /**
+    * @param $intPosition - the position to store the handler at
+    * @param $cloHandler  - the handler to store in the queue
+    *
+    * @throws UnexpectedParameterTypeException - if the first parameter is not an integer
+    * @throws UnexpectedParameterTypeException - if the second parameter is not a callable
+    * @throws \Exception                       - if there is already a handler stored under the given position
+    *
+    * store the given handler under the given position in the queue.
+    * if the position is already in use an expection is thrown.
+    *
+    **/
+  public function addHandler($intPosition, $cloHandler) {
+  
+    if(!is_int($intPosition))
+      throw new UnexpectedParameterTypeException('integer', $intPosition);
+    
+    if(!is_callable($cloHandler))
+      throw new UnexpectedParameterTypeException('callable', $cloHandler);
+    
+    if(!empty($this->arrHandlerQueue[$intPosition]))
+      throw new \Exception("there is already a handler stored for position: $intPosition");
+    
+    $this->arrHandlerQueue[$intPosition] = $cloHandler;
+    
+    ksort($this->arrHandlerQueue);
+  
+  }
+  
+  /**
+    * @param $intPosition - the position the handler for deletion is stored under
+    *
+    * @throws UnexpectedParameterTypeException - if the parameter is not an integer
+    *
+    * delete the handler stored under the given position
+    *
+    **/
+  public function deleteHandler($intPosition) {
+  
+    if(!is_int($intPosition))
+      throw new UnexpectedParameterTypeException('integer', $intPosition);
+    
+    if(array_key_exists($intPosition, $this->arrHandlerQueue))
+      unset($this->arrHandlerQueue[$intPosition]);
+  
+  }
+  
+  /**
+    * @returns (\DDDBL\Queue) - a clone of the queue-instance
+    *
+    * return a clone of the acutal queue
+    *
+    **/
+  public function getClone() {
+  
+    return clone $this;
+  
+  }
+  
+  /**
+    * @param $arrParameter - the parameter to use when executing the queue-handler
+    *
+    * @returns (mixed) the state of "result"
+    *
+    * execute all handler in the queue, in the given
+    * order from low to high. after execution return the
+    * state "result".
+    *
+    * handler which generates an output
+    * are expected to store the result in this state
+    *
+    **/
+  public function execute(array $arrParameter) {
+  
+    $this->getState()->add(array('result' => null));
+    
+    foreach($this->arrHandlerQueue AS $cloHandler)
+      $cloHandler($this, $arrParameter);
+    
+    return $this->getState()->get('result');
+  
+  }
+  
+  /**
+    * @returns (DataObject) - the DataObject which handles the states of the queue
+    *
+    * returns a reference to the DataObject, which
+    * stores all states of the queue.
+    *
+    * if no object exists till now, a new one is created
+    *
+    **/
+  public function getState() {
+  
+    if(!is_object($this->objState))
+      $this->objState = new DataObject();
+  
+    return $this->objState;
+  
+  }
+  
+}
\ No newline at end of file
diff --git a/library/dddbl2/inc/Singleton.class.php b/library/dddbl2/inc/Singleton.class.php
new file mode 100644 (file)
index 0000000..fa75af8
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+
+namespace DDDBL;
+
+/**
+  * simple implementation of generic singleton
+  * for all classes, which allows additional instances
+  * if needed
+  *
+  **/
+  
+class Singleton {
+
+  /**
+    * @param $strClass - the class we want an instance from
+    *
+    * @throws UnexpectedParameterTypeException - if given parameter is not a string
+    * @throws \Exception                       - if given class do not exists
+    *
+    * @return (object) - an instance of the given classname
+    *
+    * get a reference to the instance of the given class.
+    * if instance do not exists, create one. after creation
+    * always return reference to this reference
+    *
+    **/
+  static function getInstance($strClass) {
+  
+    if(!is_string($strClass))
+      throw new UnexpectedParameterTypeException('string', $strClass);
+    
+    if(!class_exists($strClass))
+      throw new \Exception ("class do not exists: $strClass");
+    
+    static $arrObjectList = array();
+    
+    if(!isset($arrObjectList[$strClass]))
+      $arrObjectList[$strClass] = new $strClass();
+    
+    return $arrObjectList[$strClass];
+  
+  }
+
+}
\ No newline at end of file
diff --git a/library/dddbl2/inc/database.func.php b/library/dddbl2/inc/database.func.php
new file mode 100644 (file)
index 0000000..6cba667
--- /dev/null
@@ -0,0 +1,206 @@
+<?php
+
+namespace DDDBL;
+
+/**
+  * @returns (PDO) - reference to PDO object
+  * @returns (boolean) false, if there is no connection to the database
+  *
+  * if there is a connection to the database,
+  * the PDO object is returned otherwise false
+  *
+  **/
+function getDB() {
+
+  if(!isConnected())
+    return false;
+  
+  $objDB = getDBDataObject();
+  
+  return $objDB->get('PDO');
+
+}
+
+/**
+  * @returns (boolean) true, if connection exists or is established
+  * @returns (boolean) false, if connection could not be established
+  *
+  * if no connection to the database exists, establishe one.
+  *
+  **/
+function connect() {
+
+  if(isConnected())
+    return true;
+
+  $objDB = getDBDataObject();
+
+  try {
+    $objPDO = new \PDO($objDB->get('CONNECTION'),
+                       $objDB->get('USER'),
+                       $objDB->get('PASS'));
+  } catch (\Exception $objException) {
+    return false;
+  }
+
+  $objDB->update(array('PDO' => $objPDO));
+
+  return true;
+
+}
+
+/**
+  * disconnect from the database
+  *
+  **/
+function disconnect() {
+
+  $objDB = getDBDataObject();
+  
+  $objPDO = $objDB->get('PDO');
+  $objPDO = null;
+  
+  $objDB->delete('PDO');
+
+}
+
+/**
+  * check if a connection to the database is established
+  *
+  **/
+function isConnected() {
+
+  $objDB = getDBDataObject();
+  
+  if(!$objDB->exists('PDO'))
+    return false;
+  
+  return true;
+
+}
+
+/**
+  * @returns (boolean) true, if transaction started
+  * @returns (boolean) false, if transaction could not be started
+  * @returns (boolean) false, if no connection to database exists
+  *
+  * start a transaction
+  *
+  **/
+function startTransaction() {
+
+  return mapMethod('beginTransaction');
+
+}
+
+/**
+  * @returns (boolean) true, if there is an active transaction
+  * @returns (boolean) false, if there is no active transaction
+  * @returns (boolean) false, if no connection to database exists
+  *
+  * check if there is an active transaction
+  *
+  **/
+function inTransaction() {
+
+  return mapMethod('inTransaction');
+
+}
+
+/**
+  * @returns (boolean) true, if rollback was successfull
+  * @returns (boolean) false, if rollback was not successfull
+  * @returns (boolean) false, if no connection to database exists
+  *
+  * perform a rollback of the active transaction
+  *
+  **/
+function rollback() {
+
+  return mapMethod('rollback');
+
+}
+
+/**
+  * @returns (boolean) true, if commit was successfull
+  * @returns (boolean) false, if commit was not successfull
+  * @returns (boolean) false, if no connection to database exists
+  *
+  * commit the active transaction
+  *
+  **/
+function commit() {
+
+  return mapMethod('commit');
+
+}
+
+/**
+  * @returns (array) - list of error-information
+  *
+  * get information about an error
+  *
+  **/
+function getErrorInfo() {
+
+  return mapMethod('errorInfo');
+
+}
+
+/**
+  * change the active database-connection. all db-functions
+  * are performed at the new connection.
+  *
+  * ATTENTION: the old connection is *not* closed!
+  *
+  **/
+function changeDB($strIdentifier) {
+
+  $objDataObjectPool = new DataObjectPool('Database-Definition');
+  
+  $objNewDB = $objDataObjectPool->get($strIdentifier);
+  
+  $objDataObjectPool->delete('DEFAULT');
+  $objDataObjectPool->add('DEFAULT', $objNewDB->getAll());
+
+}
+
+
+/**
+  * @returns (DataObject) - reference to the DataObject of default connection
+  *
+  * returns the DataObject of the default connection.
+  *
+  **/
+function getDBDataObject() {
+
+  $objDataObjectPool = new DataObjectPool('Database-Definition');
+  return $objDataObjectPool->get('DEFAULT');
+
+}
+
+/**
+  * @throws UnexpectedParameterTypeException - if the given parameter is not a string
+  *
+  * @returns (boolean) false, if no connection is established
+  *
+  * check if a connection to the database is established. if so,
+  * the given parameter is used, as method to call at the 
+  * PDO object. the result of the call is returned
+  *
+  **/
+function mapMethod($strMethod) {
+
+  if(!is_string($strMethod))
+    throw new UnexpectedParameterTypeException('string', $strMethod);
+
+  if(!isConnected())
+    return false;
+    
+  $objDB = getDBDataObject();
+  
+  $objPDO = $objDB->get('PDO');
+  
+  return $objPDO->$strMethod();
+
+}
\ No newline at end of file
diff --git a/library/dddbl2/inc/exceptions/QueryException.class.php b/library/dddbl2/inc/exceptions/QueryException.class.php
new file mode 100644 (file)
index 0000000..52c6250
--- /dev/null
@@ -0,0 +1,94 @@
+<?php\r
+\r
+namespace DDDBL;\r
+\r
+/**\r
+  *\r
+  * create an exception with relevant information, if a query fails\r
+  *\r
+  **/\r
+\r
+class QueryException extends \Exception {\r
+\r
+  /**\r
+    *\r
+    * @param $objPDO             - the PDO object which caused the error when executed\r
+    * @param $arrQueryDefinition - the complete query definition\r
+    * \r
+    * create an error message which contains all relevant informations\r
+    * and print them as exception\r
+    *\r
+    **/\r
+    public function __construct(\PDOStatement $objPDO, $arrQueryDefinition) {\r
+        \r
+        $strMessage = self::createErrorMessage($objPDO, $arrQueryDefinition);\r
+        \r
+        parent::__construct($strMessage);\r
+        \r
+    }\r
+\r
+  /**\r
+    *\r
+    * @param $objPDO             - the PDO object related with the error\r
+    * @param $arrQueryDefinition - the complete query definition\r
+    * \r
+    * @return (string) the complete exception message\r
+    * \r
+    * build and return the exception message out of the given error info\r
+    * and query definition\r
+    *\r
+    **/\r
+    private function createErrorMessage($objPDO, $arrQueryDefinition) {\r
+      \r
+      $strMessage  = self::flattenQueryErrorInfo($objPDO);\r
+      $strMessage .= self::flattenQueryDefiniton($arrQueryDefinition);\r
+      \r
+      return $strMessage;\r
+      \r
+    }\r
+\r
+  /**\r
+    *\r
+    * @param $objPDO - PDO object to get error information from\r
+    * \r
+    * @return (string) a flatten error info from the query object\r
+    * \r
+    * build and return a flatten error-info \r
+    * from the driver specific error message\r
+    *\r
+    **/\r
+    private function flattenQueryErrorInfo($objPDO) {\r
+    \r
+      $arrErrorInfo = $objPDO->errorInfo();\r
+      \r
+      $strMessage = '';\r
+      \r
+      if(!empty($arrErrorInfo) && !empty($arrErrorInfo[0]) && '00000' !== $arrErrorInfo[0])\r
+        $strMessage = "\nError-Code: {$arrErrorInfo[0]}\nError-Message: {$arrErrorInfo[2]}\n";\r
+      \r
+      return $strMessage;\r
+    \r
+    }\r
+\r
+  /**\r
+    *\r
+    * @param $arrQueryDefinition - the complete query definition\r
+    * \r
+    * @return (string) a text version of the query definition\r
+    * \r
+    * create an text, which contains all information \r
+    * of the query definition\r
+    *\r
+    **/\r
+    private function flattenQueryDefiniton($arrQueryDefinition) {\r
+      \r
+      $strMessage = "\nQuery-Definiton:\n";\r
+      \r
+      foreach($arrQueryDefinition AS $strKeyword => $strContent)\r
+        $strMessage .= "$strKeyword: $strContent\n";\r
+      \r
+      return $strMessage . "\n";\r
+      \r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/library/dddbl2/inc/exceptions/UnexpectedParameterTypeException.class.php b/library/dddbl2/inc/exceptions/UnexpectedParameterTypeException.class.php
new file mode 100644 (file)
index 0000000..5a02dde
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+namespace DDDBL;
+
+/**
+  * exception if the given parameter
+  * has an unexpected data-type
+  *
+  **/
+class UnexpectedParameterTypeException extends \Exception {
+
+  /**
+    * @param $strExpected - the expected datatype
+    * @param $mixedValue  - the given parameter
+    *
+    * determines the datatype of the given parameter and
+    * creates and stores the exception message
+    *
+    **/
+  public function __construct($strExpected, $mixedValue) {
+
+    parent::__construct("value of type $strExpected expected, but got: " . gettype($mixedValue));
+
+  }
+
+}
\ No newline at end of file