* made rebuildFileMap method public, added caching and checkFileMap method

This commit is contained in:
Stig Bakken 2002-07-07 20:48:54 +00:00
parent 8619108154
commit 81e5b17f91
2 changed files with 202 additions and 44 deletions

View file

@ -29,7 +29,9 @@ TODO:
require_once "System.php";
require_once "PEAR.php";
define("PEAR_REGISTRY_ERROR_LOCK", -2);
define('PEAR_REGISTRY_ERROR_LOCK', -2);
define('PEAR_REGISTRY_ERROR_FORMAT', -3);
define('PEAR_REGISTRY_ERROR_FILE', -4);
/**
* Administration class used to maintain the installed package database.
@ -63,6 +65,20 @@ class PEAR_Registry extends PEAR
*/
var $lock_mode = 0; // XXX UNUSED
/** Cache of package information. Structure:
* array(
* 'package' => array('id' => ... ),
* ... )
* @var array
*/
var $pkginfo_cache = array();
/** Cache of file map. Structure:
* array( '/path/to/file' => 'package', ... )
* @var array
*/
var $filemap_cache = array();
// }}}
// {{{ constructor
@ -78,11 +94,12 @@ class PEAR_Registry extends PEAR
{
parent::PEAR();
$ds = DIRECTORY_SEPARATOR;
$this->install_dir = $pear_install_dir;
$this->statedir = $pear_install_dir.$ds.'.registry';
$this->filemap = $pear_install_dir.$ds.'.filemap';
$this->lockfile = $pear_install_dir.$ds.'.lock';
if (!file_exists($this->filemap)) {
$this->_rebuildFileMap();
$this->rebuildFileMap();
}
}
@ -164,9 +181,9 @@ class PEAR_Registry extends PEAR
}
// }}}
// {{{ _rebuildFileMap()
// {{{ rebuildFileMap()
function _rebuildFileMap()
function rebuildFileMap()
{
$packages = $this->listPackages();
$files = array();
@ -194,11 +211,32 @@ class PEAR_Registry extends PEAR
if (!$fp) {
return false;
}
$this->filemap_cache = $files;
fwrite($fp, serialize($files));
fclose($fp);
return true;
}
// }}}
// {{{ readFileMap()
function readFileMap()
{
$fp = @fopen($this->filemap, 'r');
if (!$fp) {
return $this->raiseError('PEAR_Registry: could not open filemap', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg);
}
$fsize = filesize($this->filemap);
$data = fread($fp, $fsize);
fclose($fp);
$tmp = unserialize($data);
if (!$tmp && $fsize > 7) {
return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data);
}
$this->filemap = $tmp;
return true;
}
// }}}
// {{{ _lock()
@ -216,7 +254,7 @@ class PEAR_Registry extends PEAR
*/
function _lock($mode = LOCK_EX)
{
if(!strstr(php_uname(), 'Windows 95/98')) {
if (!strstr(php_uname(), 'Windows 95/98')) {
if ($mode != LOCK_UN && is_resource($this->lock_fp)) {
// XXX does not check type of lock (LOCK_SH/LOCK_EX)
return true;
@ -389,7 +427,7 @@ class PEAR_Registry extends PEAR
}
$file = $this->_packageFileName($package);
$ret = @unlink($file);
$this->_rebuildFileMap();
$this->rebuildFileMap();
$this->_unlock();
return $ret;
}
@ -406,9 +444,6 @@ class PEAR_Registry extends PEAR
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
if (!file_exists($this->filemap)) {
$this->_rebuildFileMap();
}
$fp = $this->_openPackageFile($package, 'w');
if ($fp === null) {
$this->_unlock();
@ -422,13 +457,61 @@ class PEAR_Registry extends PEAR
}
$this->_closePackageFile($fp);
if (isset($info['filelist'])) {
$this->_rebuildFileMap();
$this->rebuildFileMap();
}
$this->_unlock();
return true;
}
// }}}
// {{{ checkFileMap()
/**
* Test whether a file belongs to a package.
*
* @param string $path file path, absolute or relative to the pear
* install dir
*
* @return string which package the file belongs to, or an empty
* string if the file does not belong to an installed package
*
* @access public
*/
function checkFileMap($path)
{
if (is_array($path)) {
static $notempty;
if (empty($notempty)) {
$notempty = create_function('$a','return !empty($a);');
}
$pkgs = array();
foreach ($path as $name => $attrs) {
if (isset($attrs['baseinstalldir'])) {
$name = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name;
}
$pkgs[$name] = $this->checkFileMap($name);
}
return array_filter($pkgs, $notempty);
}
if (empty($this->filemap_cache) && PEAR::isError($this->readFileMap())) {
return $err;
}
if (isset($this->filemap_cache[$path])) {
return $this->filemap_cache[$path];
}
$l = strlen($this->install_dir);
if (substr($path, 0, $l) == $this->install_dir) {
$path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l));
}
if (isset($this->filemap_cache[$path])) {
return $this->filemap_cache[$path];
}
return '';
}
// }}}
// {{{ rebuildDepsFile()
/**
Experimental dependencies database handling functions (not yet in production)
@ -601,6 +684,8 @@ class PEAR_Registry extends PEAR
}
return $this->_depWriteDepDB($data);
}
// }}}
}
?>

View file

@ -8,24 +8,72 @@ include dirname(__FILE__)."/../PEAR/Registry.php";
PEAR::setErrorHandling(PEAR_ERROR_DIE, "%s\n");
cleanall();
$files1 = array(
"pkg1-1.php" => array(
"role" => "php",
),
"pkg1-2.php" => array(
"role" => "php",
"baseinstalldir" => "pkg1",
),
);
$files2 = array(
"pkg2-1.php" => array(
"role" => "php",
),
"pkg2-2.php" => array(
"role" => "php",
"baseinstalldir" => "pkg2",
),
);
$files3 = array(
"pkg3-1.php" => array(
"role" => "php",
),
"pkg3-2.php" => array(
"role" => "php",
"baseinstalldir" => "pkg3",
),
);
$files3_new = array(
"pkg3-3.php" => array(
"role" => "php",
"baseinstalldir" => "pkg3",
),
"pkg3-4.php" => array(
"role" => "php",
),
);
print "creating registry object\n";
$reg = new PEAR_Registry;
$reg->statedir = getcwd();
dumpall($reg);
$reg->addPackage("pkg1", array("name" => "pkg1", "version" => "1.0"));
$reg->addPackage("pkg1", array("name" => "pkg1", "version" => "1.0", "filelist" => $files1));
dumpall($reg);
$reg->addPackage("pkg2", array("name" => "pkg2", "version" => "2.0"));
$reg->addPackage("pkg3", array("name" => "pkg3", "version" => "3.0"));
$reg->addPackage("pkg2", array("name" => "pkg2", "version" => "2.0", "filelist" => $files2));
$reg->addPackage("pkg3", array("name" => "pkg3", "version" => "3.0", "filelist" => $files3));
dumpall($reg);
$reg->updatePackage("pkg2", array("version" => "2.1"));
dumpall($reg);
var_dump($reg->deletePackage("pkg2"));
dumpall($reg);
var_dump($reg->deletePackage("pkg2"));
dumpall($reg);
$reg->updatePackage("pkg3", array("version" => "3.1b1", "status" => "beta"));
dumpall($reg);
print_r($reg->checkFilemap(array_merge($files3, $files2)));
$reg->updatePackage("pkg3", array("filelist" => $files3_new));
dumpall($reg);
print "tests done\n";
cleanall();
@ -34,28 +82,44 @@ cleanall();
function cleanall()
{
$dp = opendir(".");
while ($ent = readdir($dp)) {
if (substr($ent, -4) == ".reg") {
unlink($ent);
}
}
$dp = opendir(".");
while ($ent = readdir($dp)) {
if (substr($ent, -4) == ".reg") {
unlink($ent);
}
}
}
function dumpall(&$reg)
{
print "dumping registry...\n";
$info = $reg->packageInfo();
foreach ($info as $pkg) {
print $pkg["name"] . ":";
unset($pkg["name"]);
foreach ($pkg as $k => $v) {
if ($k == '_lastmodified') continue;
print " $k=\"$v\"";
}
print "\n";
}
print "dump done\n";
print "dumping registry...\n";
$info = $reg->packageInfo();
foreach ($info as $pkg) {
print $pkg["name"] . ":";
unset($pkg["name"]);
foreach ($pkg as $k => $v) {
if ($k == '_lastmodified') continue;
if (is_array($v) && $k == 'filelist') {
print " $k=array(";
$i = 0;
foreach ($v as $k2 => $v2) {
if ($i++ > 0) print ",";
print "{$k2}[";
$j = 0;
foreach ($v2 as $k3 => $v3) {
if ($j++ > 0) print ",";
print "$k3=$v3";
}
print "]";
}
print ")";
} else {
print " $k=\"$v\"";
}
}
print "\n";
}
print "dump done\n";
}
?>
@ -64,30 +128,39 @@ creating registry object
dumping registry...
dump done
dumping registry...
pkg1: version="1.0"
pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
dump done
dumping registry...
pkg1: version="1.0"
pkg2: version="2.0"
pkg3: version="3.0"
pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
pkg2: version="2.0" filelist=array(pkg2-1.php[role=php],pkg2-2.php[role=php,baseinstalldir=pkg2])
pkg3: version="3.0" filelist=array(pkg3-1.php[role=php],pkg3-2.php[role=php,baseinstalldir=pkg3])
dump done
dumping registry...
pkg1: version="1.0"
pkg2: version="2.1"
pkg3: version="3.0"
pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
pkg2: version="2.1" filelist=array(pkg2-1.php[role=php],pkg2-2.php[role=php,baseinstalldir=pkg2])
pkg3: version="3.0" filelist=array(pkg3-1.php[role=php],pkg3-2.php[role=php,baseinstalldir=pkg3])
dump done
bool(true)
dumping registry...
pkg1: version="1.0"
pkg3: version="3.0"
pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
pkg3: version="3.0" filelist=array(pkg3-1.php[role=php],pkg3-2.php[role=php,baseinstalldir=pkg3])
dump done
bool(false)
dumping registry...
pkg1: version="1.0"
pkg3: version="3.0"
pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
pkg3: version="3.0" filelist=array(pkg3-1.php[role=php],pkg3-2.php[role=php,baseinstalldir=pkg3])
dump done
dumping registry...
pkg1: version="1.0"
pkg3: version="3.1b1" status="beta"
pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
pkg3: version="3.1b1" filelist=array(pkg3-1.php[role=php],pkg3-2.php[role=php,baseinstalldir=pkg3]) status="beta"
dump done
Array
(
[pkg3-1.php] => pkg3
[pkg3/pkg3-2.php] => pkg3
)
dumping registry...
pkg1: version="1.0" filelist=array(pkg1-1.php[role=php],pkg1-2.php[role=php,baseinstalldir=pkg1])
pkg3: version="3.1b1" filelist=array(pkg3-3.php[role=php,baseinstalldir=pkg3],pkg3-4.php[role=php]) status="beta"
dump done
tests done