From 405dd794fe64ee9a6a87a96d57bf7065de1ee565 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Mon, 28 Apr 2014 23:55:47 +0200 Subject: [PATCH] New database system that uses PDO if present/Test script for doing database upgrades. --- include/dba_pdo.php | 340 ++++ include/dbstructure.php | 1429 +++++++++++++++++ library/dddbl2/config.inc.php | 83 + library/dddbl2/dddbl.php | 184 +++ .../handler/register_queue_handler.inc.php | 208 +++ .../handler/register_result_handler.inc.php | 102 ++ library/dddbl2/inc/DataObject.class.php | 195 +++ library/dddbl2/inc/DataObjectPool.class.php | 207 +++ library/dddbl2/inc/Queue.class.php | 138 ++ library/dddbl2/inc/Singleton.class.php | 44 + library/dddbl2/inc/database.func.php | 206 +++ .../inc/exceptions/QueryException.class.php | 94 ++ ...UnexpectedParameterTypeException.class.php | 26 + 13 files changed, 3256 insertions(+) create mode 100644 include/dba_pdo.php create mode 100644 include/dbstructure.php create mode 100644 library/dddbl2/config.inc.php create mode 100644 library/dddbl2/dddbl.php create mode 100644 library/dddbl2/handler/register_queue_handler.inc.php create mode 100644 library/dddbl2/handler/register_result_handler.inc.php create mode 100644 library/dddbl2/inc/DataObject.class.php create mode 100644 library/dddbl2/inc/DataObjectPool.class.php create mode 100644 library/dddbl2/inc/Queue.class.php create mode 100644 library/dddbl2/inc/Singleton.class.php create mode 100644 library/dddbl2/inc/database.func.php create mode 100644 library/dddbl2/inc/exceptions/QueryException.class.php create mode 100644 library/dddbl2/inc/exceptions/UnexpectedParameterTypeException.class.php diff --git a/include/dba_pdo.php b/include/dba_pdo.php new file mode 100644 index 0000000000..76937e7f95 --- /dev/null +++ b/include/dba_pdo.php @@ -0,0 +1,340 @@ +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 index 0000000000..1f3d361aea --- /dev/null +++ b/include/dbstructure.php @@ -0,0 +1,1429 @@ +$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 index 0000000000..4dcb98eaf9 --- /dev/null +++ b/library/dddbl2/config.inc.php @@ -0,0 +1,83 @@ +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 index 0000000000..5b5441fff6 --- /dev/null +++ b/library/dddbl2/dddbl.php @@ -0,0 +1,184 @@ +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 index 0000000000..1e9fb2362e --- /dev/null +++ b/library/dddbl2/handler/register_queue_handler.inc.php @@ -0,0 +1,208 @@ +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 index 0000000000..1ccae0c86b --- /dev/null +++ b/library/dddbl2/handler/register_result_handler.inc.php @@ -0,0 +1,102 @@ +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 index 0000000000..fa3618d093 --- /dev/null +++ b/library/dddbl2/inc/DataObject.class.php @@ -0,0 +1,195 @@ +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 index 0000000000..13b6e27bf5 --- /dev/null +++ b/library/dddbl2/inc/DataObjectPool.class.php @@ -0,0 +1,207 @@ + 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 index 0000000000..236bc61f8e --- /dev/null +++ b/library/dddbl2/inc/Queue.class.php @@ -0,0 +1,138 @@ +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 index 0000000000..fa75af8f58 --- /dev/null +++ b/library/dddbl2/inc/Singleton.class.php @@ -0,0 +1,44 @@ +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 index 0000000000..52c6250476 --- /dev/null +++ b/library/dddbl2/inc/exceptions/QueryException.class.php @@ -0,0 +1,94 @@ +errorInfo(); + + $strMessage = ''; + + if(!empty($arrErrorInfo) && !empty($arrErrorInfo[0]) && '00000' !== $arrErrorInfo[0]) + $strMessage = "\nError-Code: {$arrErrorInfo[0]}\nError-Message: {$arrErrorInfo[2]}\n"; + + return $strMessage; + + } + + /** + * + * @param $arrQueryDefinition - the complete query definition + * + * @return (string) a text version of the query definition + * + * create an text, which contains all information + * of the query definition + * + **/ + private function flattenQueryDefiniton($arrQueryDefinition) { + + $strMessage = "\nQuery-Definiton:\n"; + + foreach($arrQueryDefinition AS $strKeyword => $strContent) + $strMessage .= "$strKeyword: $strContent\n"; + + return $strMessage . "\n"; + + } + +} \ 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 index 0000000000..5a02dde5bc --- /dev/null +++ b/library/dddbl2/inc/exceptions/UnexpectedParameterTypeException.class.php @@ -0,0 +1,26 @@ +