summaryrefslogtreecommitdiff
path: root/shared
diff options
context:
space:
mode:
authorEudyptula <eitan@mosenkis.net>2009-07-06 16:08:33 -0400
committerEudyptula <eitan@mosenkis.net>2009-07-06 16:08:33 -0400
commit8142c45b618eaa99f3380c2e0714e95d87e14ee2 (patch)
treeec1461d218b966307dd0239dbf362888ed600b55 /shared
parentAdd javascript-based searching to package adding stage (diff)
downloadingenue-8142c45b618eaa99f3380c2e0714e95d87e14ee2.tar.gz
ingenue-8142c45b618eaa99f3380c2e0714e95d87e14ee2.tar.bz2
ingenue-8142c45b618eaa99f3380c2e0714e95d87e14ee2.zip
Stored all data from Packages files in the db to allow frontend/backend separation; created script to update db cache of available packages; renamed profiles -> gentoo_profiles for proper modularity
Diffstat (limited to 'shared')
-rw-r--r--shared/classes/0sql_row_obj.php38
-rw-r--r--shared/classes/configopt.php1
-rw-r--r--shared/classes/gentoo_package.php78
-rw-r--r--shared/classes/gentoo_profile.php137
-rw-r--r--shared/classes/profile.php114
-rw-r--r--shared/config.php2
-rw-r--r--shared/functions/get_pkgdirs.php18
7 files changed, 234 insertions, 154 deletions
diff --git a/shared/classes/0sql_row_obj.php b/shared/classes/0sql_row_obj.php
index 1db8703..62ef90f 100644
--- a/shared/classes/0sql_row_obj.php
+++ b/shared/classes/0sql_row_obj.php
@@ -1,5 +1,6 @@
<?php
// TODO
+// Improve caching to include anything constructed from the DB
// Fall back to multi key if single key didn't work (so unique key can be null)
// consider replacing the one sql_col class with a bunch of child classes for different types (will work well with defaults() when 5.3.0 comes out)
// make sure things really work with enum
@@ -25,14 +26,14 @@
abstract class sql_row_obj { // If the name of this class changes, it must be updated where is_subclass_of() is found
// PDO object to use for queries
protected static $pdo;
- // This line is the static cache so each class is only initialized once per page-load (maybe this should really be once per class edit, saved in a file somewhere...)
- private static $cache=array(), $table_cache=array();
+ // The static cache so each class is only initialized once per page-load (maybe this should really be once per class edit, saved in a file somewhere...)
+ private static $cache=array(), $table_cache=array(), $ref_cache=array();
// These are input by the source class (auto-filled by cache after init)
protected $table, $columns, $primary_key; // TODO $unique_keys
// These are loaded from the static cache
private $auto_increment, $num_key, $misc_key;
// These are run-time variables
- private $db_values=array(), $values, $ref_cache;
+ private $db_values=array(), $values;
// Sets the PDO object to use
public static function set_pdo_obj(&$obj) {
$obj->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
@@ -72,18 +73,9 @@ abstract class sql_row_obj { // If the name of this class changes, it must be up
}
}
private function init_constructors() {
- // Primary key is its own key now, we don't care if others are available
-/* // Sets the primary key as a constructor if it exists
- if (isset($this->primary_key)) {
- $pk=$this->columns[$this->primary_key];
- if ($this->columns[$this->primary_key]->is_numeric()) {
- $this->num_key=$this->primary_key;
- } else {
- $this->misc_key=$this->primary_key;
- }
- }*/
// Fills num and misc constructors with other unique columns
// TODO check where this is called and see if we really need this first check
+ // TODO fix this for multi-column keys - as of now, it's dangerous!
if (!isset($this->num_key) || !isset($this->misc_key)) {
foreach ($this->columns as $name => $col) {
if ($col->unique) {
@@ -474,9 +466,10 @@ abstract class sql_row_obj { // If the name of this class changes, it must be up
}
}
// Fetches objects for 'refers to' columns (column given by $name)
- function get($name) {
- if (isset($this->ref_cache[$name])) {
- return $this->ref_cache[$name];
+ function &get($name) {
+ // TODO in 5.3.0, this can be a static variable in each class instead of array[$class]
+ if (isset(self::$ref_cache[get_class($this)][$name][$this->__get($name)])) {
+ return self::$ref_cache[get_class($this)][$name][$this->__get($name)];
}
if (!isset($this->columns[$name])) {
throw new Exception('Tried to fetch object for `'.$name.'` column of '.get_class($this).' object, but that column does not exist.');
@@ -486,7 +479,8 @@ abstract class sql_row_obj { // If the name of this class changes, it must be up
throw new Exception('Tried to fetch object for `'.$name.'` column of '.get_class($this).' object, but that column does not refer to another table row.');
}
if (!$this->__isset($name)) {
- return null;
+ $null=null;
+ return $null;
}
list($reftable, $refcol)=explode('.', $col->refers_to, 2); // Should be refclass also
$obj=self::table_to_obj($reftable);
@@ -498,8 +492,8 @@ abstract class sql_row_obj { // If the name of this class changes, it must be up
return null;
} elseif ($r->rowCount() == 1) {
$obj->from_array($r->fetch());
- $this->ref_cache[$name]=$obj;
- return $this->ref_cache[$name];
+ self::$ref_cache[get_class($this)][$name][$this->__get($name)]=&$obj;
+ return $obj;
} else {
throw new Exception('Fetching '.$refclass.' object for `'.$name.'` column of `'.$this->table.'` table based on `'.$refcol.'`='.$col->sql_value($this->__get($name)).' and expected one row but got '.$r->rowCount().'.');
}
@@ -508,7 +502,8 @@ abstract class sql_row_obj { // If the name of this class changes, it must be up
// TODO this shouldn't have to instantiate every class, we need 5.3.0 so this can be fully static
public static function &table_to_obj($table) {
if (isset(self::$table_cache[$table])) {
- return new self::$table_cache[$table];
+ $obj=new self::$table_cache[$table]();
+ return $obj;
}
foreach (get_declared_classes() as $class) {
if (is_subclass_of($class, 'sql_row_obj')) {
@@ -519,7 +514,8 @@ abstract class sql_row_obj { // If the name of this class changes, it must be up
}
}
}
- return null;
+ $null=null;
+ return $null;
}
// Same as table_to_class, but returns the name of the class, not an instance
public static function table_to_class($table) {
diff --git a/shared/classes/configopt.php b/shared/classes/configopt.php
index 178d0bb..c157d22 100644
--- a/shared/classes/configopt.php
+++ b/shared/classes/configopt.php
@@ -5,6 +5,7 @@ class sql_configopt extends sql_row_obj {
'type' => 'CHAR',
'length' => 6,
'not_null' => true,
+ 'default' => '',
'refers_to' => 'configurations.id'
),
'name' => array (
diff --git a/shared/classes/gentoo_package.php b/shared/classes/gentoo_package.php
new file mode 100644
index 0000000..580312f
--- /dev/null
+++ b/shared/classes/gentoo_package.php
@@ -0,0 +1,78 @@
+<?php
+class sql_gentoo_package extends sql_row_obj {
+ protected $table='gentoo_packages', $primary_key=array('id'), $columns=array(
+ 'id' => array (
+ 'type' => 'INT',
+ 'length' => 10,
+ 'unsigned' => true,
+ 'not_null' => true,
+ 'auto_increment' => true
+ ),
+ 'profile' => array (
+ 'type' => 'TINYINT',
+ 'length' => 3,
+ 'unsigned' => true,
+ 'not_null' => true,
+ 'default' => 0,
+ 'refers_to' => 'gentoo_profiles.id'
+ ),
+ 'bcat' => array (
+ 'type' => 'VARCHAR',
+ 'length' => 255,
+ 'not_null' => true,
+ 'default' => ''
+ ),
+ 'lcat' => array (
+ 'type' => 'VARCHAR',
+ 'length' => 255,
+ 'not_null' => true,
+ 'default' => ''
+ ),
+ 'name' => array (
+ 'type' => 'VARCHAR',
+ 'length' => 255,
+ 'not_null' => true,
+ 'default' => ''
+ ),
+ 'version' => array (
+ 'type' => 'VARCHAR',
+ 'length' => 255,
+ 'not_null' => true,
+ 'default' => ''
+ ),
+ 'data' => array (
+ 'type' => 'TEXT',
+ 'not_null' => true
+ )
+
+ );
+ function &to_array($skip_masked=false) {
+ $r=array();
+ foreach (explode("\n", $this->data) as $line) {
+ if (!strlen($line)) continue;
+ list($name, $val)=explode(': ', $line, 2);
+ $name=strtolower($name);
+ $r[$name]=$val;
+ }
+ if (!$skip_masked) {
+ $r['masked']=$this->is_masked($r);
+ }
+ return $r;
+ }
+ function is_masked(&$array=null) {
+ if ($array === null) {
+ $array=$this->to_array(true);
+ }
+ $heads=$this->get_profile()->get_headers();
+ $accept=explode(' ', $heads['accept_keywords']);
+ foreach ($accept as $akwd) {
+ foreach (explode(' ', $array['keywords']) as $kwd) {
+ if ($akwd == $kwd) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+}
+?>
diff --git a/shared/classes/gentoo_profile.php b/shared/classes/gentoo_profile.php
new file mode 100644
index 0000000..b705a97
--- /dev/null
+++ b/shared/classes/gentoo_profile.php
@@ -0,0 +1,137 @@
+<?php
+class sql_gentoo_profile extends sql_row_obj {
+ protected $table='gentoo_profiles', $primary_key=array('id'), $columns=array(
+ 'id' => array (
+ 'type' => 'TINYINT',
+ 'length' => 3,
+ 'unsigned' => true,
+ 'not_null' => true,
+ 'auto_increment' => true
+ ),
+ 'pkgdir' => array (
+ 'type' => 'VARCHAR',
+ 'length' => 255,
+ 'not_null' => true,
+ 'default' => '',
+ 'unique' => true
+ ),
+ 'name' => array (
+ 'type' => 'VARCHAR',
+ 'length' => 255,
+ 'unique' => true
+ ),
+ 'order' => array (
+ 'type' => 'TINYINT',
+ 'length' => 4
+ ),
+ 'flags' => array (
+ 'type' => 'VARCHAR',
+ 'length' => 255,
+ 'not_null' => true,
+ 'default' => ''
+ ),
+ 'headers' => array (
+ 'type' => 'TEXT',
+ 'not_null' => true
+ )
+
+ );
+ private $headers_cache;
+ // Returns $this->headers as an array
+ public function &get_headers() {
+ if (isset($headers_cache)) return $headers_cache;
+ foreach (explode("\n", $this->headers) as $line) {
+ if (!$line) continue;
+ list($name, $val)=explode(': ', $line, 2);
+ $this->headers_cache[strtolower($name)]=$val;
+ }
+ return $this->headers_cache;
+ }
+ // Reads the data from the Packages file in $this->pkgdir
+ public function read_Packages($update_pkgs=false) {
+ global $conf;
+ $file=fopen($conf['pkgdir_root'].'/'.$this->pkgdir.'/Packages', 'r');
+ $this->headers='';
+ while (!feof($file)) {
+ $line=rtrim(fgets($file));
+ if (strlen($line) == 0) {
+ break;
+ } else {
+ list($name, $val)=array_merge(explode(': ', $line, 2), array(null));
+ if ($val !== null) {
+ $this->headers.="$name: $val\n";
+ }
+ }
+ }
+ $p=array();
+ $cur=null;
+ $this->write();
+ while (!feof($file)) {
+ $line=rtrim(fgets($file));
+ if (strlen($line) == 0) {
+ unset($cur);
+ continue;
+ }
+ list($name, $val)=array_merge(explode(': ', $line, 2), array(null));
+ if ($name == 'CPV') {
+ if (preg_match('#^([^/-]+)([^/]*)/(.+?)-([^-]+)((?:-r[0-9]+)?)$#', $val, $match)) {
+ list(, $bcat, $lcat, $name, $ver, $r)=$match;
+ $ver.=$r;
+ } else {
+ debug("Unsplittable atom: $val");
+ continue;
+ }
+ if (isset($p[$bcat][$lcat][$name][$ver])) {
+ debug("Duplicate package $bcat$lcat/$name-$ver");
+ }
+ $p[$bcat][$lcat][$name][$ver]='';
+ $cur=&$p[$bcat][$lcat][$name][$ver];
+ } elseif (isset($cur, $val)) {
+ $cur.="$name: $val\n";
+ }
+ }
+ unset($cur);
+ $u=0;
+ if ($update_pkgs) {
+ global $S;
+ $r=$S['pdo']->query('SELECT * FROM `gentoo_packages` WHERE `profile`='.$this->id);
+ while ($pkg=$r->fetch(PDO::FETCH_ASSOC)) {
+ $pkg=new sql_gentoo_package($pkg);
+ if (isset($p[$pkg->bcat][$pkg->lcat][$pkg->name][$pkg->version])) {
+ if ($pkg->data != $p[$pkg->bcat][$pkg->lcat][$pkg->name][$pkg->version]) {
+ $u++;
+ $pkg->data=$p[$pkg->bcat][$pkg->lcat][$pkg->name][$pkg->version];
+ $pkg->write();
+ }
+ unset($p[$pkg->bcat][$pkg->lcat][$pkg->name][$pkg->version]);
+ } else {
+ $pkg->delete();
+ }
+ }
+ }
+ $n=0;
+ foreach ($p as $bcat => $lcats) {
+ foreach ($lcats as $lcat => $pkgs) {
+ foreach ($pkgs as $pkg => $vers) {
+ foreach ($vers as $ver => $data) {
+ $n++;
+ $gp=new sql_gentoo_package(null, $this->id, $bcat, $lcat, $pkg, $ver, $data);
+ $gp->write();
+ }
+ }
+ }
+ }
+ return array($n, $u);
+ }
+ public function &get_packages() {
+ global $S;
+ $r=$S['pdo']->query('SELECT * FROM `gentoo_packages` WHERE `profile`='.$this->id);
+ $p=array();
+ while ($pkg=$r->fetch(PDO::FETCH_ASSOC)) {
+ $pkg=new sql_gentoo_package($pkg);
+ $p[$pkg->bcat][$pkg->lcat][$pkg->name][$pkg->version]=$pkg->to_array();
+ }
+ return $p;
+ }
+}
+?>
diff --git a/shared/classes/profile.php b/shared/classes/profile.php
deleted file mode 100644
index 77603e2..0000000
--- a/shared/classes/profile.php
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-class sql_profile extends sql_row_obj {
- protected $table='profiles', $primary_key=array('id'), $columns=array(
- 'id' => array (
- 'type' => 'TINYINT',
- 'length' => 3,
- 'unsigned' => true,
- 'not_null' => true,
- 'auto_increment' => true
- ),
- 'pkgdir' => array (
- 'type' => 'VARCHAR',
- 'length' => 255,
- 'not_null' => true,
- 'default' => '',
- 'unique' => true
- ),
- 'name' => array (
- 'type' => 'VARCHAR',
- 'length' => 255,
- 'unique' => true
- ),
- 'order' => array (
- 'type' => 'TINYINT',
- 'length' => 4
- ),
- 'flags' => array (
- 'type' => 'VARCHAR',
- 'length' => 255,
- 'not_null' => true,
- 'default' => ''
- )
-
- );
- public function get_headers($return_filehandle=false) {
- global $conf;
- $file=fopen($conf['pkgdir_root'].'/'.$this->pkgdir.'/Packages', 'r');
- $headers=array();
- while (!feof($file)) {
- $line=rtrim(fgets($file));
- if (strlen($line) == 0) {
- break;
- } else {
- list($name, $val)=array_merge(explode(': ', $line, 2), array(null));
- if ($val !== null) {
- $headers[strtolower($name)]=$val;
- }
- }
- }
- if ($return_filehandle) {
- return array(&$headers, &$file);
- } else {
- fclose($file);
- return $headers;
- }
- }
- public function &get_packages() {
- list($headers, $file)=$this->get_headers(true);
- $accept_keywords=explode(' ', $headers['accept_keywords']);
- $p=array();
- $cur=null;
- while (!feof($file)) {
- $line=rtrim(fgets($file));
- if (strlen($line) == 0) {
- unset($cur);
- continue;
- }
- list($name, $val)=array_merge(explode(': ', $line, 2), array(null));
- if ($name == 'CPV') {
- if (preg_match('#^([^/-]+)([^/]*)/(.+?)-([^-]+)((?:-r[0-9]+)?)$#', $val, $match)) {
- list(, $bcat, $lcat, $name, $ver, $r)=$match;
- $ver.=$r;
- } else {
- debug("Unsplittable atom: $val");
- continue;
- }
- if (isset($p[$bcat][$lcat][$name][$ver])) {
- debug("Duplicate package $bcat$lcat/$name-$ver");
- // We don't really care about having correct info
-/* global $conf;
- $tbz=$conf['pkgdir_root'].'/'.$this->pkgdir.'/'.(isset($p[$cat][$name][$ver]['path'])?$p[$cat][$name][$ver]['path']:"$cat/$name-$ver.tbz2");
- if (filesize($tbz) == $p[$cat][$name][$ver]['size']) {
- debug($this->pkgdir.": Duplicate package $cat/$name-$ver - current entry matches size, dropping new entry");
- continue;
- } else {
- debug($this->pkgdir.": Duplicate package $cat/$name-$ver - current entry invalid, using new entry");
- }*/
- }
- $p[$bcat][$lcat][$name][$ver]=array();
- $cur=&$p[$bcat][$lcat][$name][$ver];
- } elseif (isset($cur, $val)) {
- switch($name) {
- case 'KEYWORDS':
- $cur['keywords']=explode(' ', $val);
- $cur['masked']=!array_intersect($cur['keywords'], $accept_keywords);
- break;
- case 'DESC':
- $cur['description']=$val;
- break;
-/* case 'SIZE':
- $cur['size']=$val;
- break;
- case 'PATH':
- $cur['path']=$val;
- break;*/
- default:
- $cur[$name]=$val;
- }
- }
- }
- return $p;
- }
-}
-?>
diff --git a/shared/config.php b/shared/config.php
index c8f1179..ecf22fc 100644
--- a/shared/config.php
+++ b/shared/config.php
@@ -14,7 +14,7 @@ $conf['timezone']=10800; // Time difference in seconds between UTC and the defau
$conf['mod_rewrite']=true; // Use mod_rewrite for pretty URLs
$conf['emailfrom']='noreply@gentoo.org'; // Used as the From: field in emails
$conf['check_email_dns']=true; // Use DNS to check the domain of submitted emails for validity
-$conf['pkgdir_root']='/home/eitan/soc/tinderbox'; // The directory to recursively search for pkgdirs in
+$conf['pkgdir_root']='/home/eitan/soc/tinderbox'; // The directory to recursively search for pkgdirs in (Backend only)
$conf['emerge_default_opts']='-t -v -K --color=y --root-deps=rdeps'; // DON'T CHANGE UNLESS YOU KNOW WHAT YOU'RE DOING
$conf['portdir']='/usr/portage'; // The directory conatining the portage tree to use (/usr/portage unless you have a reason to think otherwise)
$conf['logview_max']=1000; // The maximum number of log entries shown on one page (1000 is a good start)
diff --git a/shared/functions/get_pkgdirs.php b/shared/functions/get_pkgdirs.php
deleted file mode 100644
index 1f39420..0000000
--- a/shared/functions/get_pkgdirs.php
+++ /dev/null
@@ -1,18 +0,0 @@
-<?php
-function get_pkgdirs($dir=null) {
- global $conf;
- if ($dir===null) {
- $dir=$conf['pkgdir_root'];
- }
- if (is_file($dir.'/Packages')) {
- // We assume that a dir with a Packages file will not contain other complete ppkgdirs
- return array(substr($dir, strlen($conf['pkgdir_root'])+1));
- } else {
- $return=array();
- foreach (glob ($dir.'/*', GLOB_ONLYDIR) as $subdir) {
- $return=array_merge($return, get_pkgdirs($subdir));
- }
- return $return;
- }
-}
-?>