[dev] datatree: getObject for nonexistent objects
Karsten Fourmont
fourmont at gmx.de
Sun Jan 21 03:37:17 PST 2007
Hi,
I just realized that calling DataTree:getObject is extremly costly for
nonexistent objects (with sql backend). If you do this:
$o = $_datatree->getObject("unknown_fake_object");
you'll end up with this sql query being executed:
SELECT [*] FROM horde_datatree c WHERE c.group_uid = 'syncml'
which means that the complete datatree is loaded! Futile as the object
is not there no matter how much you load. (see end of post for detailed
horde.log)
The reason for that as far as I could figure it out:
_buildLoadQuery calls _buildParentIds in line 193 of sql.php:
$parent_where = $this->_buildParentIds($root, $loadTree, 'c.');
_buildParentIds' SQL query does not find anything and so returns '' in
line 267.
Then _buildLoadQuery goes on like this in line 194:
if (!empty($parent_where) && !is_a($parent_where, 'PEAR_Error')) {
$where = sprintf('%s AND (%s)', $where, $parent_where);
}
so the where part is not included and the query ends up being "get all".
I'm not an expert on the delicate internals of the datatree but imho
_buildLoadQuery should do like this:
if (!empty($parent_where) && !is_a($parent_where, 'PEAR_Error')) {
$where = sprintf('%s AND (%s)', $where, $parent_where);
} else {
return $parent_where;
}
both invocations of _buildLoadQuery explicitly check for empty as well
as PEAR_Error returns so all should be fine.
With this change in place the result if getObject is the same ("not
found") but the complete datatree is not loaded.
The query
SQL Query by DataTree_sql::_buildParentIds(): SELECT datatree_id,
datatree_parents FROM horde_datatree WHERE datatree_name = ? AND
group_uid = ? ORDER BY datatree_id [on line 266 of
"/home/httpd/html/horde/framework/DataTree/DataTree/sql.php"]
is still executed twice though.
Would some DataTree-expert review and commit this patch? Thanks!
Index: DataTree/DataTree/sql.php
===================================================================
RCS file: /repository/framework/DataTree/DataTree/sql.php,v
retrieving revision 1.224
diff -u -r1.224 sql.php
--- DataTree/DataTree/sql.php 4 Jan 2007 08:01:58 -0000 1.224
+++ DataTree/DataTree/sql.php 21 Jan 2007 11:42:12 -0000
@@ -193,6 +193,8 @@
$parent_where = $this->_buildParentIds($root, $loadTree,
'c.');
if (!empty($parent_where) && !is_a($parent_where,
'PEAR_Error')) {
$where = sprintf('%s AND (%s)', $where, $parent_where);
+ } else {
+ return $parent_where;
}
}
if (!is_null($sortby_name)) {
--
1) here's the complete log of the unnecessary load for reference:
SQL Query by DataTree_sql::_buildParentIds(): SELECT datatree_id,
datatree_parents FROM horde_datatree WHERE datatree_name = ? AND
group_uid = ? ORDER BY datatree_id [on line 264 of DataTree/sql.php"]
SQL Query by DataTree_sql::_load(): SELECT c.datatree_id,
c.datatree_name, c.datatree_parents, c.datatree_order FROM
horde_datatree c WHERE c.group_uid = 'syncml' [on line 133 of
"DataTree/sql.php"]
SQL Query by DataTree_sql::_buildParentIds(): SELECT datatree_id,
datatree_parents FROM horde_datatree WHERE datatree_name = ? AND
group_uid = ? ORDER BY datatree_id [on line 264 of "DataTree/sql.php"]
SQL Query by DataTree_sql::_load(): SELECT c.datatree_id,
c.datatree_name, c.datatree_parents, c.datatree_order FROM
horde_datatree c WHERE c.group_uid = 'syncml' [on line 133 of
"DataTree/sql.php"]
More information about the dev
mailing list