diff --git a/src/IDF/Commit.php b/src/IDF/Commit.php index cf779f6..bfe2422 100644 --- a/src/IDF/Commit.php +++ b/src/IDF/Commit.php @@ -34,6 +34,7 @@ Pluf::loadFunction('Pluf_Template_dateAgo'); class IDF_Commit extends Pluf_Model { public $_model = __CLASS__; + public $extra = null; /**< Extra data as IDF_Gconf object */ function init() { @@ -127,6 +128,7 @@ class IDF_Commit extends Pluf_Model { IDF_Timeline::remove($this); IDF_Search::remove($this); + IDF_Gconf::dropForModel($this); } /** @@ -142,6 +144,10 @@ class IDF_Commit extends Pluf_Model array($project->id, $change->commit)); $r = Pluf::factory('IDF_Commit')->getList(array('filter'=>$sql->gen())); if ($r->count() > 0) { + $r[0]->extra = new IDF_Gconf(); + $r[0]->extra->serialize = true; + $r[0]->extra->setModel($r[0]); + $r[0]->extra->initCache(); return $r[0]; } if (!isset($change->full_message)) { @@ -157,6 +163,13 @@ class IDF_Commit extends Pluf_Model $commit->origauthor = self::toUTF8($change->author); $commit->creation_dtime = $change->date; $commit->create(); + $extra = $scm->getExtraProperties($change); + $commit->extra = new IDF_Gconf(); + $commit->extra->serialize = true; // As we can store arrays + $commit->extra->setModel($commit); + foreach ($extra as $key => $val) { + $commit->extra->setVal($key, $val); + } $commit->notify($project->getConf()); return $commit; } diff --git a/src/IDF/Gconf.php b/src/IDF/Gconf.php index ad09ef8..5f84008 100644 --- a/src/IDF/Gconf.php +++ b/src/IDF/Gconf.php @@ -35,6 +35,10 @@ class IDF_Gconf extends Pluf_Model public $dirty = array(); public $f = null; protected $_mod = null; + /** + * Do we (un)serialize the data when getting/setting them. + */ + public $serialize = false; function init() { @@ -97,7 +101,7 @@ class IDF_Gconf extends Pluf_Model $sql = new Pluf_SQL('model_class=%s AND model_id=%s', array($this->_mod->_model, $this->_mod->id)); foreach ($this->getList(array('filter' => $sql->gen())) as $val) { - $this->datacache[$val->vkey] = $val->vdesc; + $this->datacache[$val->vkey] = ($this->serialize) ? unserialize($val->vdesc) : $val->vdesc; $this->dirty[$val->vkey] = $val->id; } } @@ -112,11 +116,12 @@ class IDF_Gconf extends Pluf_Model and $value == $this->getVal($key)) { return; } + $svalue = ($this->serialize) ? serialize($value) : $value; if (isset($this->dirty[$key])) { // we get to check if deleted by other process + update $conf = new IDF_Gconf($this->dirty[$key]); if ($conf->id == $this->dirty[$key]) { - $conf->vdesc = $value; + $conf->vdesc = $svalue; $conf->update(); $this->datacache[$key] = $value; return; @@ -127,7 +132,7 @@ class IDF_Gconf extends Pluf_Model $conf->model_class = $this->_mod->_model; $conf->model_id = $this->_mod->id; $conf->vkey = $key; - $conf->vdesc = $value; + $conf->vdesc = $svalue; $conf->create(); $this->datacache[$key] = $value; $this->dirty[$key] = $conf->id; @@ -153,6 +158,32 @@ class IDF_Gconf extends Pluf_Model } } + /** + * Collection selection. + * + * Suppose you have 5 objects with associated meta data in the + * Gconf storage, if you load the data independently for each + * object, you end up with 5 SELECT queries. With 25 objects, 25 + * SELECT. You can select with one query all the data and merge in + * the code. It is faster. The collection selection get a + * model_class and a list of ids and returns an id indexed array + * of associative array data. This is for read only access as you + * do not get a series of Gconf objects. + */ + public static function collect($class, $ids) + { + $gconf = new IDF_Gconf(); + $stmpl = sprintf('model_class=%%s AND model_id IN (%s)', + implode(',' , $ids)); + $sql = new Pluf_SQL($stmpl, array($class)); + $out = array_fill_keys($ids, array()); + foreach ($gconf->getList(array('filter' => $sql->gen())) as $c) { + $out[$c->model_id][$c->vkey] = $c->vdesc; + } + + return $out; + } + /** * Drop the conf of a model. * diff --git a/src/IDF/Scm.php b/src/IDF/Scm.php index f474cd5..d9c4435 100644 --- a/src/IDF/Scm.php +++ b/src/IDF/Scm.php @@ -420,6 +420,21 @@ class IDF_Scm return null; } + /** + * Given a changelog parsed node, returns extra data. + * + * For example, if the node is a commit object from git, it will a + * stdClass object with the parents array. The extra value could + * then be the parent(s) commit(s). + * + * @param stdClass Commit object/Parse object + * @return array Extra properties + */ + public function getExtraProperties($obj) + { + return array(); + } + /** * Generate a zip archive at a given commit, wrapped in a HTTP response, suitable for pushing to client. * diff --git a/src/IDF/Scm/Git.php b/src/IDF/Scm/Git.php index 90954b8..e8ac2f6 100644 --- a/src/IDF/Scm/Git.php +++ b/src/IDF/Scm/Git.php @@ -116,6 +116,14 @@ class IDF_Scm_Git extends IDF_Scm return $this->_inObject($commit, 'branch'); } + /** + * Will find the parents if available. + */ + public function getExtraProperties($obj) + { + return (isset($obj->parents)) ? array('parents' => $obj->parents) : array(); + } + /** * @see IDF_Scm::getTags() **/ diff --git a/src/IDF/templates/idf/source/changelog.html b/src/IDF/templates/idf/source/changelog.html index 8c56074..9223651 100644 --- a/src/IDF/templates/idf/source/changelog.html +++ b/src/IDF/templates/idf/source/changelog.html @@ -12,8 +12,19 @@ {foreach $changes as $change} {aurl 'url', 'IDF_Views_Source::commit', array($project.shortname, $change.scm_id)}