summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUrban Müller2008-11-27 16:00:12 +0000
committerUrban Müller2008-11-27 16:00:12 +0000
commit681f5a60ed975fef44f77a3ab1d96660562a6542 (patch)
tree12cdf976fad625b7023480c350c6c8b041a3b534
parent6df16a01b771cfae6f38e518fa6e8078703f7ad4 (diff)
downloaditools-681f5a60ed975fef44f77a3ab1d96660562a6542.tar.gz
itools-681f5a60ed975fef44f77a3ab1d96660562a6542.tar.bz2
itools-681f5a60ed975fef44f77a3ab1d96660562a6542.zip
schema cache
-rw-r--r--it_dbi.class66
1 files changed, 55 insertions, 11 deletions
diff --git a/it_dbi.class b/it_dbi.class
index 0a61fc8..3878759 100644
--- a/it_dbi.class
+++ b/it_dbi.class
@@ -108,11 +108,23 @@ function createclasses($p = array())
$p += $dbi->_p;
- for ($res = $dbi->query('SHOW TABLES', $p); $row = mysql_fetch_row($res);)
+ $dbid = "{$p['user']}@{$p['server']}:{$p['db']}";
+ $state = it_dbi::_state_get($dbid);
+
+ if (!$tables = $state['tables'])
+ {
+ for ($tables = array(), $res = $dbi->query('SHOW TABLES', $p); $row = mysql_fetch_row($res);)
+ $tables[] = $row[0];
+
+ $state['tables'] = $tables;
+ it_dbi::_state_put($dbid, $state);
+ }
+
+ foreach ($tables as $table)
{
# Either create class in autoloader or manually just below
- if (!class_exists($p['classprefix'] . $row[0]))
- it_dbi::createclass(array('table' => $row[0]) + $p);
+ if (!class_exists($p['classprefix'] . $table))
+ it_dbi::createclass(array('table' => $table) + $p);
}
}
@@ -128,13 +140,25 @@ function createclass($p)
# Make sure singleton exists
$dbi = $GLOBALS['it_dbi'] ? $GLOBALS['it_dbi'] : new it_dbi(array('table' => null) + $p);
+ $p += $dbi->_p; # FIXME: (has to be checked for side effects!)
$dbid = "{$p['user']}@{$p['server']}:{$p['db']}";
if (!isset($dbi->_tables[$dbid]))
{
+ $state = it_dbi::_state_get($dbid);
$dbi->_tables[$dbid] = array();
- for ($res = $dbi->query('SHOW TABLES', $p); $row = mysql_fetch_row($res);)
- $dbi->_tables[$dbid][$row[0]] = true;
+
+ if (!($tables = $state['tables']))
+ {
+ for ($tables = array(), $res = $dbi->query('SHOW TABLES', $p); $row = mysql_fetch_row($res);)
+ $tables[] = $row[0];
+
+ $state['tables'] = $tables;
+ it_dbi::_state_put($dbid, $state);
+ }
+
+ foreach ($tables as $table)
+ $dbi->_tables[$dbid][$table] = true;
}
if ($p['forcecreate'] || $dbi->_tables[$dbid][$p['table']]) # Do not generate classes for non-existant tables (can be overridden by forcecreate => true, used in tests/it_dbi.t)
@@ -172,8 +196,9 @@ function _connect($p = array())
{
$p += $this->_p;
$dbid = "{$p['user']}@{$p['server']}:{$p['db']}";
+ $state = it_dbi::_state_get($dbid);
- if ($p['reconnect'] || !($this->_link = $GLOBALS['it_dbi']->_state[$dbid]['link']))
+ if ($p['reconnect'] || !($this->_link = $state['link']))
{
# Force new link if same server/user was seen before (mysql ignores selected db)
if ($GLOBALS['it_dbi']->_connected["{$p['server']}/{$p['user']}"]++)
@@ -195,7 +220,8 @@ function _connect($p = array())
if (!(@mysql_select_db($p['db'], $this->_link)))
$this->_fatal("_connect(): can't select database \"{$p['db']}\"");
- $GLOBALS['it_dbi']->_state[$dbid]['link'] = $this->_link;
+ $state['link'] = $this->_link;
+ it_dbi::_state_put($dbid, $state);
}
}
@@ -654,8 +680,9 @@ function _get_field_info()
{
$result = array();
$dbid = "{$this->_p['user']}@{$this->_p['server']}:{$this->_p['db']}";
+ $state = it_dbi::_state_get($dbid);
- if (!($this->_fields = $GLOBALS['it_dbi']->_state[$dbid]['fields'][$this->_p['table']]))
+ if (!($this->_fields = $state['fields'][$this->_p['table']]))
{
debug("it_dbi(): no fields for {$dbid}.{$this->_p['table']}, calculating.", 5);
for ($res = $this->query('SHOW COLUMNS FROM ' . $this->_p['table']); $res && ($field = mysql_fetch_assoc($res)); )
@@ -664,11 +691,12 @@ function _get_field_info()
$this->_isint[$field['Field']] = $field['Type'] == "int(11)";
}
- $GLOBALS['it_dbi']->_state[$dbid]['fields'][$this->_p['table']] = $this->_fields;
- $GLOBALS['it_dbi']->_state[$dbid]['isint'][$this->_p['table']] = $this->_isint;
+ $state['fields'][$this->_p['table']] = $this->_fields;
+ $state['isint'][$this->_p['table']] = $this->_isint;
+ it_dbi::_state_put($dbid, $state);
}
else # Existing _fields, copy other info too
- $this->_isint = $GLOBALS['it_dbi']->_state[$dbid]['isint'][$this->_p['table']];
+ $this->_isint = $state['isint'][$this->_p['table']];
foreach((array)$this->_fields as $field)
{
@@ -684,6 +712,22 @@ function _get_field_info()
return $result;
}
+function _state_get($dbid)
+{
+ if (!($result = $GLOBALS['it_dbi']->_state[$dbid]))
+ $result = $GLOBALS['it_dbi']->_state[$dbid] = (array)it_cache::get("dbi:$dbid");
+
+ #var_dump("get", $dbid, $result);
+ return $result;
+}
+
+function _state_put($dbid, $state)
+{
+ #var_dump("put", $dbid, $state);
+ $GLOBALS['it_dbi']->_state[$dbid] = $state;
+ it_cache::put("dbi:$dbid", array('link' => null) + (array)$state); # link is not transferable
+}
+
#
# Implement PHP 5 Iterator interface to make foreach work
# Example: foreach (new T_User('firstname' => "foo") as $foouser) { ... }