diff --git a/src/IDF/Migrations/11GitCache.php b/src/IDF/Migrations/11GitCache.php new file mode 100644 index 0000000..4fa1f31 --- /dev/null +++ b/src/IDF/Migrations/11GitCache.php @@ -0,0 +1,52 @@ +model = new $model(); + $schema->createTables(); + } +} + +function IDF_Migrations_11GitCache_down($params=null) +{ + $models = array( + 'IDF_Scm_Cache_Git', + ); + $db = Pluf::db(); + $schema = new Pluf_DB_Schema($db); + foreach ($models as $model) { + $schema->model = new $model(); + $schema->dropTables(); + } +} \ No newline at end of file diff --git a/src/IDF/Scm.php b/src/IDF/Scm.php index 55ee05b..faf7e57 100644 --- a/src/IDF/Scm.php +++ b/src/IDF/Scm.php @@ -55,6 +55,11 @@ class IDF_Scm */ public $repo = ''; + /** + * Corresponding project object. + */ + public $project = null; + /** * Cache storage. * @@ -64,6 +69,15 @@ class IDF_Scm */ protected $cache = array(); + /** + * Default constructor. + */ + public function __construct($repo, $project=null) + { + $this->repo = $repo; + $this->project = $project; + } + /** * Returns an instance of the correct scm backend object. * diff --git a/src/IDF/Scm/Cache/Git.php b/src/IDF/Scm/Cache/Git.php new file mode 100644 index 0000000..84a1a50 --- /dev/null +++ b/src/IDF/Scm/Cache/Git.php @@ -0,0 +1,133 @@ +project = $this->_project; + $cache->githash = $blob->hash; + $cache->content = $blob->date.chr(31).$blob->author.chr(31).$blob->title; + $sql = new Pluf_SQL('project=%s AND githash=%s', + array($this->_project->id, $blob->hash)); + if (0 == Pluf::factory(__CLASS__)->getCount(array('filter' => $sql->gen()))) { + $cache->create(); + } + } + } + + /** + * Get for the given hashes the corresponding date, title and + * author. + * + * It returns an hash indexed array with the info. If an hash is + * not in the db, the key is not set. + * + * Note that the hashes must always come from internal tools. + * + * @param array Hashes to get info + * @return array Blob infos + */ + public function retrieve($hashes) + { + $res = array(); + $db = $this->getDbConnection(); + $hashes = array_map(array($db, 'esc'), $hashes); + $sql = new Pluf_SQL('project=%s AND githash IN ('.implode(', ', $hashes).')', + array($this->_project->id)); + foreach (Pluf::factory(__CLASS__)->getList(array('filter' => $sql->gen())) as $blob) { + $tmp = split(chr(31), $blob->content, 3); + + $res[$blob->githash] = (object) array( + 'hash' => $blob->githash, + 'date' => $tmp[0], + 'title' => $tmp[2], + 'author' => $tmp[1], + ); + } + return $res; + } + + /** + * The storage is composed of 4 columns, id, project, hash and the + * raw data. + */ + function init() + { + $this->_a['table'] = 'idf_scm_cache_git'; + $this->_a['model'] = __CLASS__; + $this->_a['cols'] = array( + // It is mandatory to have an "id" column. + 'id' => + array( + 'type' => 'Pluf_DB_Field_Sequence', + 'blank' => true, + ), + 'project' => + array( + 'type' => 'Pluf_DB_Field_Foreignkey', + 'model' => 'IDF_Project', + 'blank' => false, + ), + 'githash' => + array( + 'type' => 'Pluf_DB_Field_Varchar', + 'blank' => false, + 'size' => 40, + 'index' => true, + ), + 'content' => + array( + 'type' => 'Pluf_DB_Field_Text', + 'blank' => false, + ), + ); + } +} \ No newline at end of file diff --git a/src/IDF/Scm/Git.php b/src/IDF/Scm/Git.php index 9e393f5..b89b44c 100644 --- a/src/IDF/Scm/Git.php +++ b/src/IDF/Scm/Git.php @@ -29,12 +29,6 @@ class IDF_Scm_Git extends IDF_Scm { public $mediumtree_fmt = 'commit %H%nAuthor: %an <%ae>%nTree: %T%nDate: %ai%n%n%s%n%n%b'; - - public function __construct($repo) - { - $this->repo = $repo; - } - /* ============================================== * * * * Common Methods Implemented By All The SCMs * @@ -190,7 +184,7 @@ class IDF_Scm_Git extends IDF_Scm public static function factory($project) { $rep = sprintf(Pluf::f('git_repositories'), $project->shortname); - return new IDF_Scm_Git($rep); + return new IDF_Scm_Git($rep, $project); } /** @@ -633,28 +627,9 @@ class IDF_Scm_Git extends IDF_Scm */ public function getCachedBlobInfo($hashes) { - $res = array(); - $cache = Pluf::f('tmp_folder').'/IDF_Scm_Git-'.md5($this->repo).'.cache.db'; - if (!file_exists($cache)) { - return $res; - } - $data = file_get_contents($cache); - if (false === $data) { - return $res; - } - $data = split(chr(30), $data); - foreach ($data as $rec) { - if (isset($hashes[substr($rec, 0, 40)])) { - //$tmp = split(chr(31), gzinflate(substr($rec, 40)), 3); - $tmp = split(chr(31), substr($rec, 40), 3); - $res[substr($rec, 0, 40)] = - (object) array('hash' => substr($rec, 0, 40), - 'date' => $tmp[0], - 'title' => $tmp[2], - 'author' => $tmp[1]); - } - } - return $res; + $cache = new IDF_Scm_Cache_Git(); + $cache->_project = $this->project; + return $cache->retrieve(array_keys($hashes)); } /** @@ -666,11 +641,50 @@ class IDF_Scm_Git extends IDF_Scm * @return bool Success */ public function cacheBlobInfo($info) + { + $cache = new IDF_Scm_Cache_Git(); + $cache->_project = $this->project; + return $cache->store($info); + } + + public function getFileCachedBlobInfo($hashes) + { + $res = array(); + $cache = Pluf::f('tmp_folder').'/IDF_Scm_Git-'.md5($this->repo).'.cache.db'; + if (!file_exists($cache)) { + return $res; + } + $data = file_get_contents($cache); + if (false === $data) { + return $res; + } + $data = split(chr(30), $data); + foreach ($data as $rec) { + if (isset($hashes[substr($rec, 0, 40)])) { + $tmp = split(chr(31), substr($rec, 40), 3); + $res[substr($rec, 0, 40)] = + (object) array('hash' => substr($rec, 0, 40), + 'date' => $tmp[0], + 'title' => $tmp[2], + 'author' => $tmp[1]); + } + } + return $res; + } + + /** + * File cache blob info. + * + * Given a series of blob info, cache them. + * + * @param array Blob info + * @return bool Success + */ + public function fileCacheBlobInfo($info) { // Prepare the data $data = array(); foreach ($info as $file) { - //$data[] = $file->hash.gzdeflate($file->date.chr(31).$file->author.chr(31).$file->title, 9); $data[] = $file->hash.$file->date.chr(31).$file->author.chr(31).$file->title; } $data = implode(chr(30), $data).chr(30);