Fixed up the documentation, prettied up the code to Campware coding conventions.

This commit is contained in:
paul 2006-09-01 09:25:13 +00:00
parent d522ccead7
commit 3a90898e3b

View file

@ -31,22 +31,27 @@ class M2tree{
* Database object container * Database object container
*/ */
var $dbc; var $dbc;
/** /**
* Configuration tree * Configuration tree
*/ */
var $config; var $config;
/** /**
* Tree table name * Tree table name
*/ */
var $treeTable; var $treeTable;
/** /**
* Structure table name * Structure table name
*/ */
var $structTable; var $structTable;
/** /**
* Root node name * Root node name
*/ */
var $rootNodeName; var $rootNodeName;
/** /**
* Constructor * Constructor
* *
@ -61,63 +66,81 @@ class M2tree{
$this->treeTable = $config['tblNamePrefix'].'tree'; $this->treeTable = $config['tblNamePrefix'].'tree';
$this->structTable = $config['tblNamePrefix'].'struct'; $this->structTable = $config['tblNamePrefix'].'struct';
$this->rootNodeName = $config['RootNode']; $this->rootNodeName = $config['RootNode'];
} } // constructor
/* ======================================================= public methods */ /* ======================================================= public methods */
/** /**
* Add new object of specified type to the tree under specified parent * Add new object of specified type to the tree under specified parent
* node * node
* *
* @param name string, mnemonic name for new object * @param string $name, mnemonic name for new object
* @param type string, type of new object * @param string $type, type of new object
* @param parid int, optional, parent id * @param int $parid, optional, parent id
* @return int/err - new id of inserted object or PEAR::error * @return int/err - new id of inserted object or PEAR::error
*/ */
function addObj($name, $type, $parid = NULL) function addObj($name, $type, $parid = NULL)
{ {
if($name=='' || $type=='') return $this->dbc->raiseError( if ( ($name == '') || ($type == '') ) {
"M2tree::addObj: Wrong name or type", ALIBERR_MTREE return $this->dbc->raiseError("M2tree::addObj: Wrong name or type", ALIBERR_MTREE);
); }
if(is_null($parid)) $parid = $this->getRootNode(); if (is_null($parid)) {
$parid = $this->getRootNode();
}
// changing name if the same is in the dest. folder: // changing name if the same is in the dest. folder:
for( ; for( ;
$xid = $this->getObjId($name, $parid), $xid = $this->getObjId($name, $parid),
!is_null($xid) && !$this->dbc->isError($xid); !is_null($xid) && !$this->dbc->isError($xid);
$name .= "_" $name .= "_"
); );
if($this->dbc->isError($xid)) return $xid; if ($this->dbc->isError($xid)) {
return $xid;
}
// insert new object record: // insert new object record:
$this->dbc->query("BEGIN"); $this->dbc->query("BEGIN");
$oid = $this->dbc->nextId("{$this->treeTable}_id_seq"); $oid = $this->dbc->nextId("{$this->treeTable}_id_seq");
if($this->dbc->isError($oid)) return $this->_dbRollback($oid); if ($this->dbc->isError($oid)) {
return $this->_dbRollback($oid);
}
$r = $this->dbc->query(" $r = $this->dbc->query("
INSERT INTO {$this->treeTable} (id, name, type) INSERT INTO {$this->treeTable} (id, name, type)
VALUES ($oid, '$name', '$type') VALUES ($oid, '$name', '$type')
"); ");
if($this->dbc->isError($r)) return $this->_dbRollback($r); if ($this->dbc->isError($r)) {
return $this->_dbRollback($r);
}
$dataArr = array(); $dataArr = array();
// build data ($dataArr) for INSERT of structure records: // build data ($dataArr) for INSERT of structure records:
for ($p=$parid, $l=1; !is_null($p); $p=$this->getParent($p), $l++) { for ($p=$parid, $l=1; !is_null($p); $p=$this->getParent($p), $l++) {
$rid = $this->dbc->nextId("{$this->structTable}_id_seq"); $rid = $this->dbc->nextId("{$this->structTable}_id_seq");
if($this->dbc->isError($rid)) return $this->_dbRollback($rid); if ($this->dbc->isError($rid)) {
return $this->_dbRollback($rid);
}
$dataArr[] = array($rid, $oid, $p, $l); $dataArr[] = array($rid, $oid, $p, $l);
} }
// build and prepare INSERT command automatically: // build and prepare INSERT command automatically:
$pr = $this->dbc->autoPrepare($this->structTable, $pr = $this->dbc->autoPrepare($this->structTable,
array('rid', 'objid', 'parid', 'level'), DB_AUTOQUERY_INSERT); array('rid', 'objid', 'parid', 'level'), DB_AUTOQUERY_INSERT);
if($this->dbc->isError($pr)) return $this->_dbRollback($pr); if ($this->dbc->isError($pr)) {
return $this->_dbRollback($pr);
}
// execute INSERT command for $dataArr: // execute INSERT command for $dataArr:
$r = $this->dbc->executeMultiple($pr, $dataArr); $r = $this->dbc->executeMultiple($pr, $dataArr);
if($this->dbc->isError($r)) return $this->_dbRollback($r); if ($this->dbc->isError($r)) {
$r = $this->dbc->query("COMMIT"); return $this->_dbRollback($r);
if(PEAR::isError($r)) return $this->_dbRollback($r);
return $oid;
} }
$r = $this->dbc->query("COMMIT");
if (PEAR::isError($r)) {
return $this->_dbRollback($r);
}
return $oid;
} // fn addObj
/** /**
* Remove specified object * Remove specified object
* *
* @param oid int, object id to remove * @param int $oid, object id to remove
* @return boolean/err - TRUE or PEAR::error * @return boolean/err - TRUE or PEAR::error
*/ */
function removeObj($oid) function removeObj($oid)
@ -128,16 +151,22 @@ class M2tree{
); );
} }
$dir = $this->getDir($oid); $dir = $this->getDir($oid);
if($this->dbc->isError($dir)) return $dir; if ($this->dbc->isError($dir)) {
return $dir;
}
foreach ($dir as $k => $ch){ foreach ($dir as $k => $ch){
$r = $this->removeObj($ch['id']); $r = $this->removeObj($ch['id']);
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
} }
$r = $this->dbc->query(" $r = $this->dbc->query("
DELETE FROM {$this->treeTable} DELETE FROM {$this->treeTable}
WHERE id=$oid WHERE id=$oid
"); ");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
/* done by automatic reference trigger: /* done by automatic reference trigger:
$r = $this->dbc->query(" $r = $this->dbc->query("
DELETE FROM {$this->structTable} DELETE FROM {$this->structTable}
@ -146,7 +175,7 @@ class M2tree{
if($this->dbc->isError($r)) return $r; if($this->dbc->isError($r)) return $r;
*/ */
return TRUE; return TRUE;
} } // fn removeObj
/** /**
@ -165,32 +194,51 @@ class M2tree{
"M2tree::copyObj: Can't copy into itself" "M2tree::copyObj: Can't copy into itself"
); );
} }
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
// get name: // get name:
$name = $this->getObjName($oid); $name = $this->getObjName($oid);
if($this->dbc->isError($name)) return $name; if ($this->dbc->isError($name)) {
return $name;
}
// get parent id: // get parent id:
$parid = $this->getParent($oid); $parid = $this->getParent($oid);
if($this->dbc->isError($parid)) return $parid; if ($this->dbc->isError($parid)) {
if($parid == $newParid) $name .= "_copy"; return $parid;
}
if ($parid == $newParid) {
$name .= "_copy";
}
// get type: // get type:
$type = $this->getObjType($oid); $type = $this->getObjType($oid);
if($this->dbc->isError($type)) return $type; if ($this->dbc->isError($type)) {
return $type;
}
// look for children: // look for children:
$dir = $this->getDir($oid, $flds='id'); $dir = $this->getDir($oid, $flds='id');
if($this->dbc->isError($dir)) return $dir; if ($this->dbc->isError($dir)) {
return $dir;
}
// insert aktual object: // insert aktual object:
$nid = $this->addObj($name, $type, $newParid); $nid = $this->addObj($name, $type, $newParid);
if($this->dbc->isError($nid)) return $nid; if ($this->dbc->isError($nid)) {
return $nid;
}
// if no children: // if no children:
if(is_null($dir)) return $nid; if (is_null($dir)) {
return $nid;
}
// optionally insert children recursively: // optionally insert children recursively:
foreach ($dir as $k => $item){ foreach ($dir as $k => $item){
$r = $this->copyObj($item['id'], $nid); $r = $this->copyObj($item['id'], $nid);
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
} }
return $nid; return $nid;
} } // fn copyObj
/** /**
* Move subtree to another node without removing/adding * Move subtree to another node without removing/adding
@ -210,72 +258,96 @@ class M2tree{
"M2tree::moveObj: Can't move into itself" "M2tree::moveObj: Can't move into itself"
); );
} }
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
// get name: // get name:
$name0 = $name = $this->getObjName($oid); $name0 = $name = $this->getObjName($oid);
if($this->dbc->isError($name)) return $name; if ($this->dbc->isError($name)) {
return $name;
}
$this->dbc->query("BEGIN"); $this->dbc->query("BEGIN");
// cut it from source: // cut it from source:
$r = $this->_cutSubtree($oid); $r = $this->_cutSubtree($oid);
if($this->dbc->isError($r)) return $this->_dbRollback($r); if ($this->dbc->isError($r)) {
return $this->_dbRollback($r);
}
// changing name if the same is in the dest. folder: // changing name if the same is in the dest. folder:
for( ; for( ;
$xid = $this->getObjId($name, $newParid), $xid = $this->getObjId($name, $newParid),
!is_null($xid) && !$this->dbc->isError($xid); !is_null($xid) && !$this->dbc->isError($xid);
$name .= "_" $name .= "_"
); );
if($this->dbc->isError($xid)) return $this->_dbRollback($xid); if ($this->dbc->isError($xid)) {
return $this->_dbRollback($xid);
}
if ($name != $name0){ if ($name != $name0){
$r = $this->renameObj($oid, $name); $r = $this->renameObj($oid, $name);
if($this->dbc->isError($r)) return $this->_dbRollback($r); if ($this->dbc->isError($r)) {
return $this->_dbRollback($r);
}
} }
// paste it to dest.: // paste it to dest.:
$r = $this->_pasteSubtree($oid, $newParid); $r = $this->_pasteSubtree($oid, $newParid);
if($this->dbc->isError($r)) return $this->_dbRollback($r); if ($this->dbc->isError($r)) {
$r = $this->dbc->query("COMMIT"); return $this->_dbRollback($r);
if(PEAR::isError($r)) return $this->_dbRollback($r);
return TRUE;
} }
$r = $this->dbc->query("COMMIT");
if (PEAR::isError($r)) {
return $this->_dbRollback($r);
}
return TRUE;
} //fn moveObj
/** /**
* Rename of specified object * Rename of specified object
* *
* @param oid int, object id to rename * @param int $oid, object id to rename
* @param newName string, new name * @param string $newName, new name
* @return boolean/err - True or PEAR::error * @return boolean/err - True or PEAR::error
*/ */
function renameObj($oid, $newName) function renameObj($oid, $newName)
{ {
// get parent id: // get parent id:
$parid = $this->getParent($oid); $parid = $this->getParent($oid);
if($this->dbc->isError($parid)) return $parid; if ($this->dbc->isError($parid)) {
return $parid;
}
// changing name if the same is in the folder: // changing name if the same is in the folder:
for( ; for( ;
$xid = $this->getObjId($newName, $parid), $xid = $this->getObjId($newName, $parid),
!is_null($xid) && !$this->dbc->isError($xid); !is_null($xid) && !$this->dbc->isError($xid);
$newName .= "_" $newName .= "_"
); );
if($this->dbc->isError($xid)) return $xid; if ($this->dbc->isError($xid)) {
return $xid;
}
$r = $this->dbc->query(" $r = $this->dbc->query("
UPDATE {$this->treeTable} UPDATE {$this->treeTable}
SET name='$newName' SET name='$newName'
WHERE id=$oid WHERE id=$oid
"); ");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return TRUE; return $r;
} }
return TRUE;
} // fn renameObj
/* --------------------------------------------------------- info methods */ /* --------------------------------------------------------- info methods */
/** /**
* Search for child id by name in sibling set * Search for child id by name in sibling set
* *
* @param name string, searched name * @param string $name, searched name
* @param parId int, optional, parent id (default is root node) * @param int $parId, optional, parent id (default is root node)
* @return int/null/err - child id (if found) or null or PEAR::error * @return int/null/err - child id (if found) or null or PEAR::error
*/ */
function getObjId($name, $parId=NULL) function getObjId($name, $parId = null)
{ {
if($name=='' && is_null($parId)) $name = $this->rootNodeName; if ( ($name == '') && is_null($parId)) {
$name = $this->rootNodeName;
}
$parcond = (is_null($parId) ? "parid is null" : $parcond = (is_null($parId) ? "parid is null" :
"parid='$parId' AND level=1"); "parid='$parId' AND level=1");
$r = $this->dbc->getOne(" $r = $this->dbc->getOne("
@ -283,15 +355,18 @@ class M2tree{
LEFT JOIN {$this->structTable} s ON id=objid LEFT JOIN {$this->structTable} s ON id=objid
WHERE name='$name' AND $parcond" WHERE name='$name' AND $parcond"
); );
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r; return $r;
} }
return $r;
} // fn getObjId
/** /**
* Get one value for object by id (default: get name) * Get one value for object by id (default: get name)
* *
* @param oid int * @param int $oid
* @param fld string, optional, requested field (default: name) * @param string $fld, optional, requested field (default: name)
* @return string/err * @return string/err
*/ */
function getObjName($oid, $fld='name') function getObjName($oid, $fld='name')
@ -301,23 +376,25 @@ class M2tree{
WHERE id=$oid WHERE id=$oid
"); ");
return $r; return $r;
} } // fn getObjName
/** /**
* Get object type by id * Get object type by id.
* *
* @param oid int * @param int $oid
* @return string/err * @return string/err
*/ */
function getObjType($oid) function getObjType($oid)
{ {
return $this->getObjName($oid, 'type'); return $this->getObjName($oid, 'type');
} } // fn getObjType
/** /**
* Get parent id * Get parent id
* *
* @param oid int * @param int $oid
* @return int/err * @return int/err
*/ */
function getParent($oid) function getParent($oid)
@ -327,14 +404,15 @@ class M2tree{
WHERE objid=$oid AND level=1 WHERE objid=$oid AND level=1
"); ");
return $r; return $r;
} } // fn getParent
/** /**
* Get array of nodes in object's path from root node * Get array of nodes in object's path from root node
* *
* @param oid int * @param int $oid
* @param flds string, optional * @param string $flds, optional
* @param withSelf boolean - flag for include specified object to the path * @param boolean $withSelf - flag for include specified object to the path
* @return array/err * @return array/err
*/ */
function getPath($oid, $flds='id', $withSelf=TRUE) function getPath($oid, $flds='id', $withSelf=TRUE)
@ -356,14 +434,15 @@ class M2tree{
array_push($path, $r); array_push($path, $r);
} }
return $path; return $path;
} } // fn getPath
/** /**
* Get array of childnodes * Get array of childnodes
* *
* @param oid int * @param int $oid
* @param flds string, optional, comma separated list of requested fields * @param string $flds, optional, comma separated list of requested fields
* @param order string, optional, fieldname for order by clause * @param string $order, optional, fieldname for order by clause
* @return array/err * @return array/err
*/ */
function getDir($oid, $flds='id', $order='name') function getDir($oid, $flds='id', $order='name')
@ -376,38 +455,44 @@ class M2tree{
ORDER BY $order ORDER BY $order
"); ");
return $r; return $r;
} } // fn getDir
/** /**
* Get level of object relatively to specified root * Get level of object relatively to specified root
* *
* @param oid int, object id * @param int $oid, object id
* @param flds string, list of field names for select * @param string $flds, list of field names for select
* (optional - default: 'level') * (optional - default: 'level')
* @param rootId int, root for relative levels * @param int $rootId, root for relative levels
* (optional - default: NULL - use root of whole tree) * (optional - default: NULL - use root of whole tree)
* @return hash-array with field name/value pairs * @return hash-array with field name/value pairs
*/ */
function getObjLevel($oid, $flds='level', $rootId=NULL) function getObjLevel($oid, $flds='level', $rootId=NULL)
{ {
if(is_null($rootId)) $rootId = $this->getRootNode(); if (is_null($rootId)) {
$rootId = $this->getRootNode();
}
$re = $this->dbc->getRow(" $re = $this->dbc->getRow("
SELECT $flds SELECT $flds
FROM {$this->treeTable} FROM {$this->treeTable}
LEFT JOIN {$this->structTable} s ON id=objid AND parid=$rootId LEFT JOIN {$this->structTable} s ON id=objid AND parid=$rootId
WHERE id=$oid WHERE id=$oid
"); ");
if($this->dbc->isError($re)) return $re; if ($this->dbc->isError($re)) {
$re['level'] = intval($re['level']);
return $re; return $re;
} }
$re['level'] = intval($re['level']);
return $re;
} // fn getObjLevel
/** /**
* Get subtree of specified node * Get subtree of specified node
* *
* @param oid int, optional, default: root node * @param int $oid, optional, default: root node
* @param withRoot boolean, optional, include/exclude specified node * @param boolean $withRoot, optional, include/exclude specified node
* @param rootId int, root for relative levels, optional * @param int $rootId, root for relative levels, optional
* @return array/err * @return array/err
*/ */
function getSubTree($oid=NULL, $withRoot=FALSE, $rootId=NULL) function getSubTree($oid=NULL, $withRoot=FALSE, $rootId=NULL)
@ -417,43 +502,60 @@ class M2tree{
$r = array(); $r = array();
if($withRoot){ if($withRoot){
$r[] = $re = $this->getObjLevel($oid, 'id, name, level', $rootId); $r[] = $re = $this->getObjLevel($oid, 'id, name, level', $rootId);
}else $re=NULL; } else {
if($this->dbc->isError($re)) return $re; $re=NULL;
}
if ($this->dbc->isError($re)) {
return $re;
}
$dirarr = $this->getDir($oid, 'id, level'); $dirarr = $this->getDir($oid, 'id, level');
if($this->dbc->isError($dirarr)) return $dirarr; if ($this->dbc->isError($dirarr)) {
foreach($dirarr as $k=>$snod) return $dirarr;
{ }
foreach ($dirarr as $k => $snod) {
$re = $this->getObjLevel($snod['id'], 'id, name, level', $rootId); $re = $this->getObjLevel($snod['id'], 'id, name, level', $rootId);
if($this->dbc->isError($re)) return $re; if($this->dbc->isError($re)) {
return $re;
}
# $re['level'] = intval($re['level'])+1; # $re['level'] = intval($re['level'])+1;
$r[] = $re; $r[] = $re;
$r = array_merge($r, $r = array_merge($r,
$this->getSubTree($snod['id'], FALSE, $rootId)); $this->getSubTree($snod['id'], FALSE, $rootId));
} }
return $r; return $r;
} } // fn getSubTree
/** /**
* Returns true if first object if child of second one * Returns true if first object if child of second one
* *
* @param oid int, object id of tested object * @param int $oid, object id of tested object
* @param parid int, object id of parent * @param int $parid, object id of parent
* @param indirect boolean, test indirect or only direct relation * @param boolean $indirect, test indirect or only direct relation
* @return boolean * @return boolean
*/ */
function isChildOf($oid, $parid, $indirect=FALSE) function isChildOf($oid, $parid, $indirect=FALSE)
{ {
if (!$indirect){ if (!$indirect){
$paridD = $this->getParent($oid); $paridD = $this->getParent($oid);
if($this->dbc->isError($paridD)) return $paridD; if ($this->dbc->isError($paridD)) {
return $paridD;
}
return ($paridD == $parid); return ($paridD == $parid);
} }
$path = $this->getPath($oid, 'id', FALSE); $path = $this->getPath($oid, 'id', FALSE);
if($this->dbc->isError($path)) return $path; if ($this->dbc->isError($path)) {
$res = FALSE; return $path;
foreach($path as $k=>$item){ if($item['id'] == $parid) $res = TRUE; }
return $res;
} }
$res = FALSE;
foreach ($path as $k=>$item) {
if ($item['id'] == $parid) {
$res = TRUE;
}
}
return $res;
} // fn isChildOf
/** /**
* Get id of root node * Get id of root node
@ -463,7 +565,8 @@ class M2tree{
function getRootNode() function getRootNode()
{ {
return $this->getObjId($this->rootNodeName); return $this->getObjId($this->rootNodeName);
} } // fn getRootNode
/** /**
* Get all objects in the tree as array of hashes * Get all objects in the tree as array of hashes
@ -475,7 +578,8 @@ class M2tree{
return $this->dbc->getAll( return $this->dbc->getAll(
"SELECT * FROM {$this->treeTable}" "SELECT * FROM {$this->treeTable}"
); );
} } // fn getAllObjects
/* ------------------------ info methods related to application structure */ /* ------------------------ info methods related to application structure */
/* (this part should be redefined in extended class to allow /* (this part should be redefined in extended class to allow
@ -486,13 +590,14 @@ class M2tree{
/** /**
* Get child types allowed by application definition * Get child types allowed by application definition
* *
* @param type string * @param string $type
* @return array * @return array
*/ */
function getAllowedChildTypes($type) function getAllowedChildTypes($type)
{ {
return $this->config['objtypes'][$type]; return $this->config['objtypes'][$type];
} } // fn getAllowedChildTypes
/* ==================================================== "private" methods */ /* ==================================================== "private" methods */
@ -500,13 +605,15 @@ class M2tree{
* Cut subtree of specified object from tree. * Cut subtree of specified object from tree.
* Preserve subtree structure. * Preserve subtree structure.
* *
* @param oid int, object id * @param int $oid, object id
* @return boolean * @return boolean
*/ */
function _cutSubtree($oid) function _cutSubtree($oid)
{ {
$lvl = $this->getObjLevel($oid); $lvl = $this->getObjLevel($oid);
if($this->dbc->isError($lvl)) return $lvl; if ($this->dbc->isError($lvl)) {
return $lvl;
}
$lvl = $lvl['level']; $lvl = $lvl['level'];
// release downside structure // release downside structure
$r = $this->dbc->query(" $r = $this->dbc->query("
@ -519,15 +626,18 @@ class M2tree{
AND s2.parid=1 AND s3.level>(s2.level-$lvl) AND s2.parid=1 AND s3.level>(s2.level-$lvl)
) )
"); ");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return TRUE; return $r;
} }
return TRUE;
} // fn _cutSubtree
/** /**
* Paste subtree previously cut by _cutSubtree method into main tree * Paste subtree previously cut by _cutSubtree method into main tree
* *
* @param oid int, object id * @param int $oid, object id
* @param newParid int, destination object id * @param int $newParid, destination object id
* @return boolean * @return boolean
*/ */
function _pasteSubtree($oid, $newParid) function _pasteSubtree($oid, $newParid)
@ -538,46 +648,55 @@ class M2tree{
$l = intval($o['level'])+1; $l = intval($o['level'])+1;
for ($p = $newParid; !is_null($p); $p=$this->getParent($p), $l++){ for ($p = $newParid; !is_null($p); $p=$this->getParent($p), $l++){
$rid = $this->dbc->nextId("{$this->structTable}_id_seq"); $rid = $this->dbc->nextId("{$this->structTable}_id_seq");
if($this->dbc->isError($rid)) return $rid; if ($this->dbc->isError($rid)) {
return $rid;
}
$dataArr[] = array($rid, $o['id'], $p, $l); $dataArr[] = array($rid, $o['id'], $p, $l);
} }
} }
// build and prepare INSERT command automatically: // build and prepare INSERT command automatically:
$pr = $this->dbc->autoPrepare($this->structTable, $pr = $this->dbc->autoPrepare($this->structTable,
array('rid', 'objid', 'parid', 'level'), DB_AUTOQUERY_INSERT); array('rid', 'objid', 'parid', 'level'), DB_AUTOQUERY_INSERT);
if($this->dbc->isError($pr)) return $pr; if ($this->dbc->isError($pr)) {
return $pr;
}
// execute INSERT command for $dataArr: // execute INSERT command for $dataArr:
$r = $this->dbc->executeMultiple($pr, $dataArr); $r = $this->dbc->executeMultiple($pr, $dataArr);
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return TRUE; return $r;
} }
return TRUE;
} // _pasteSubtree
/** /**
* Do SQL rollback and return PEAR::error * Do SQL rollback and return PEAR::error
* *
* @param r object/string, error object or error message * @param object/string $r, error object or error message
* @return err * @return err
*/ */
function _dbRollback($r) function _dbRollback($r)
{ {
$this->dbc->query("ROLLBACK"); $this->dbc->query("ROLLBACK");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
elseif(is_string($r)){ return $r;
} elseif(is_string($r)) {
$msg = basename(__FILE__)."::".get_class($this).": $r"; $msg = basename(__FILE__)."::".get_class($this).": $r";
} else { } else {
$msg = basename(__FILE__)."::".get_class($this).": unknown error"; $msg = basename(__FILE__)."::".get_class($this).": unknown error";
} }
return $this->dbc->raiseError($msg, ALIBERR_MTREE, PEAR_ERROR_RETURN); return $this->dbc->raiseError($msg, ALIBERR_MTREE, PEAR_ERROR_RETURN);
} } // fn _dbRollback
/* ==================================================== auxiliary methods */ /* ==================================================== auxiliary methods */
/** /**
* Human readable dump of subtree - for debug * Human readable dump of subtree - for debug
* *
* @param oid int, start object id * @param int $oid, start object id
* @param indstr string, indentation string * @param string $indstr, indentation string
* @param ind string, aktual indentation * @param string $ind, aktual indentation
* @return string * @return string
*/ */
function dumpTree($oid=NULL, $indstr=' ', $ind='', function dumpTree($oid=NULL, $indstr=' ', $ind='',
@ -585,23 +704,28 @@ class M2tree{
{ {
$r=''; $r='';
foreach($st = $this->getSubTree($oid, $withRoot) as $o){ foreach($st = $this->getSubTree($oid, $withRoot) as $o){
if($this->dbc->isError($st)) return $st; if ($this->dbc->isError($st)) {
return $st;
}
$r .= $ind.str_repeat($indstr, $o['level']). $r .= $ind.str_repeat($indstr, $o['level']).
preg_replace(array('|\{name\}|', '|\{id\}|'), preg_replace(array('|\{name\}|', '|\{id\}|'),
array($o['name'], $o['id']), $format). array($o['name'], $o['id']), $format).
"\n"; "\n";
} }
return $r; return $r;
} } // fn dumpTree
/** /**
* Create tables + initialize root node * Create tables + initialize root node
* * @return err/void
*/ */
function install() function install()
{ {
$r = $this->dbc->query("BEGIN"); $r = $this->dbc->query("BEGIN");
if(PEAR::isError($r)) return $r; if (PEAR::isError($r)) {
return $r;
}
$r = $this->dbc->query("CREATE TABLE {$this->treeTable} ( $r = $this->dbc->query("CREATE TABLE {$this->treeTable} (
id int not null PRIMARY KEY, id int not null PRIMARY KEY,
name varchar(255) not null default'', name varchar(255) not null default'',
@ -609,15 +733,23 @@ class M2tree{
type varchar(255) not null default'', type varchar(255) not null default'',
param varchar(255) param varchar(255)
)"); )");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
$r = $this->dbc->createSequence("{$this->treeTable}_id_seq"); $r = $this->dbc->createSequence("{$this->treeTable}_id_seq");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
$r = $this->dbc->query("CREATE UNIQUE INDEX {$this->treeTable}_id_idx $r = $this->dbc->query("CREATE UNIQUE INDEX {$this->treeTable}_id_idx
ON {$this->treeTable} (id)"); ON {$this->treeTable} (id)");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
$r = $this->dbc->query("CREATE INDEX {$this->treeTable}_name_idx $r = $this->dbc->query("CREATE INDEX {$this->treeTable}_name_idx
ON {$this->treeTable} (name)"); ON {$this->treeTable} (name)");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
$r = $this->dbc->query("CREATE TABLE {$this->structTable} ( $r = $this->dbc->query("CREATE TABLE {$this->structTable} (
rid int not null PRIMARY KEY, rid int not null PRIMARY KEY,
@ -625,48 +757,71 @@ class M2tree{
parid int not null REFERENCES {$this->treeTable} ON DELETE CASCADE, parid int not null REFERENCES {$this->treeTable} ON DELETE CASCADE,
level int level int
)"); )");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
$r = $this->dbc->createSequence("{$this->structTable}_id_seq"); $r = $this->dbc->createSequence("{$this->structTable}_id_seq");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
$r = $this->dbc->query("CREATE UNIQUE INDEX {$this->structTable}_rid_idx $r = $this->dbc->query("CREATE UNIQUE INDEX {$this->structTable}_rid_idx
ON {$this->structTable} (rid)"); ON {$this->structTable} (rid)");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
$r = $this->dbc->query("CREATE INDEX {$this->structTable}_objid_idx $r = $this->dbc->query("CREATE INDEX {$this->structTable}_objid_idx
ON {$this->structTable} (objid)"); ON {$this->structTable} (objid)");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
$r = $this->dbc->query("CREATE INDEX {$this->structTable}_parid_idx $r = $this->dbc->query("CREATE INDEX {$this->structTable}_parid_idx
ON {$this->structTable} (parid)"); ON {$this->structTable} (parid)");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
$r = $this->dbc->query("CREATE INDEX {$this->structTable}_level_idx $r = $this->dbc->query("CREATE INDEX {$this->structTable}_level_idx
ON {$this->structTable} (level)"); ON {$this->structTable} (level)");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
$r = $this->dbc->query(" $r = $this->dbc->query("
CREATE UNIQUE INDEX {$this->structTable}_objid_level_idx CREATE UNIQUE INDEX {$this->structTable}_objid_level_idx
ON {$this->structTable} (objid, level) ON {$this->structTable} (objid, level)
"); ");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
$r = $this->dbc->query(" $r = $this->dbc->query("
CREATE UNIQUE INDEX {$this->structTable}_objid_parid_idx CREATE UNIQUE INDEX {$this->structTable}_objid_parid_idx
ON {$this->structTable} (objid, parid) ON {$this->structTable} (objid, parid)
"); ");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
return $r;
}
$oid = $this->dbc->nextId("{$this->treeTable}_id_seq"); $oid = $this->dbc->nextId("{$this->treeTable}_id_seq");
if($this->dbc->isError($oid)) return $oid; if ($this->dbc->isError($oid)) {
return $oid;
}
$r = $this->dbc->query(" $r = $this->dbc->query("
INSERT INTO {$this->treeTable} INSERT INTO {$this->treeTable}
(id, name, type) (id, name, type)
VALUES VALUES
($oid, '{$this->rootNodeName}', 'RootNode') ($oid, '{$this->rootNodeName}', 'RootNode')
"); ");
if($this->dbc->isError($r)) return $r; if ($this->dbc->isError($r)) {
$r = $this->dbc->query("COMMIT"); return $r;
if(PEAR::isError($r)) return $r;
} }
$r = $this->dbc->query("COMMIT");
if (PEAR::isError($r)) {
return $r;
}
} // fn install
/** /**
* Drop all tables and sequencies * Drop all tables and sequences.
* * @return void
*/ */
function uninstall() function uninstall()
{ {
@ -674,31 +829,40 @@ class M2tree{
$this->dbc->dropSequence("{$this->structTable}_id_seq"); $this->dbc->dropSequence("{$this->structTable}_id_seq");
$this->dbc->query("DROP TABLE {$this->treeTable}"); $this->dbc->query("DROP TABLE {$this->treeTable}");
$this->dbc->dropSequence("{$this->treeTable}_id_seq"); $this->dbc->dropSequence("{$this->treeTable}_id_seq");
} } // fn uninstall
/** /**
* Uninstall and install * Uninstall and install.
* * @return void
*/ */
function reinstall() function reinstall()
{ {
$this->uninstall(); $this->uninstall();
$this->install(); $this->install();
} } // fn reinstall
/** /**
* Clean up tree - delete all except root node * Clean up tree - delete all except the root node.
* * @return err/void
*/ */
function reset() function reset()
{ {
$rid = $this->getRootNode(); $rid = $this->getRootNode();
if($this->dbc->isError($rid)) return $rid; if ($this->dbc->isError($rid)) {
$r = $this->dbc->query("DELETE FROM {$this->structTable}"); return $rid;
if($this->dbc->isError($r)) return $r;
$r = $this->dbc->query("DELETE FROM {$this->treeTable} WHERE id<>$rid");
if($this->dbc->isError($r)) return $r;
} }
$r = $this->dbc->query("DELETE FROM {$this->structTable}");
if ($this->dbc->isError($r)) {
return $r;
}
$r = $this->dbc->query("DELETE FROM {$this->treeTable} WHERE id<>$rid");
if ($this->dbc->isError($r)) {
return $r;
}
} // fn reset
/** /**
* Insert test data to the tree. * Insert test data to the tree.
@ -712,7 +876,8 @@ class M2tree{
$mt = &new M2treeTest($this->dbc, $this->config); $mt = &new M2treeTest($this->dbc, $this->config);
$r = $mt->_test(); $r = $mt->_test();
return $r; return $r;
} } // fn test
/** /**
* Insert test data to the tree. * Insert test data to the tree.
@ -734,6 +899,7 @@ class M2tree{
$o['s2c'] = $this->addObj('Section c', 'Section', $o['i2']); $o['s2c'] = $this->addObj('Section c', 'Section', $o['i2']);
$o['pb'] = $this->addObj('Publication B', 'Publication', $o['root']); $o['pb'] = $this->addObj('Publication B', 'Publication', $o['root']);
$this->tdata['tree'] = $o; $this->tdata['tree'] = $o;
} } // fn testData
}
} // class M2Tree
?> ?>