Added a DB backend for the Git blob info.
This commit is contained in:
		
							
								
								
									
										52
									
								
								src/IDF/Migrations/11GitCache.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/IDF/Migrations/11GitCache.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| <?php | ||||
| /* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||
| /* | ||||
| # ***** BEGIN LICENSE BLOCK ***** | ||||
| # This file is part of InDefero, an open source project management application. | ||||
| # Copyright (C) 2008 Céondo Ltd and contributors. | ||||
| # | ||||
| # InDefero is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation; either version 2 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # InDefero is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program; if not, write to the Free Software | ||||
| # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | ||||
| # | ||||
| # ***** END LICENSE BLOCK ***** */ | ||||
|  | ||||
| /** | ||||
|  * Add the DB based Git cache. | ||||
|  */ | ||||
|  | ||||
| function IDF_Migrations_11GitCache_up($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->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(); | ||||
|     } | ||||
| } | ||||
| @@ -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. | ||||
|      * | ||||
|   | ||||
							
								
								
									
										133
									
								
								src/IDF/Scm/Cache/Git.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								src/IDF/Scm/Cache/Git.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| <?php | ||||
| /* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||
| /* | ||||
| # ***** BEGIN LICENSE BLOCK ***** | ||||
| # This file is part of InDefero, an open source project management application. | ||||
| # Copyright (C) 2008 Céondo Ltd and contributors. | ||||
| # | ||||
| # InDefero is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation; either version 2 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # InDefero is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program; if not, write to the Free Software | ||||
| # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | ||||
| # | ||||
| # ***** END LICENSE BLOCK ***** */ | ||||
|  | ||||
| /** | ||||
|  * This class implements the cache storage for the Git commits. | ||||
|  * | ||||
|  * The storage is simple. Each commit is linked to a project to drop | ||||
|  * the cache when the project is dropped. The key is the commit hash | ||||
|  * and the data is the date, author and one line title of information. | ||||
|  * | ||||
|  * A clean interface is available to bulk set/get a series of commit | ||||
|  * info with the minimum of SQL queries. The goal is to be fast. | ||||
|  */ | ||||
| class IDF_Scm_Cache_Git extends Pluf_Model | ||||
| { | ||||
|     public $_model = __CLASS__; | ||||
|  | ||||
|     /** | ||||
|      * The current project to limit the search to. | ||||
|      */ | ||||
|     public $_project = null; | ||||
|  | ||||
|     /** | ||||
|      * Store in the cache blob infos. | ||||
|      * | ||||
|      * The info is an array of stdClasses, with hash, date, title and | ||||
|      * author properties. | ||||
|      * | ||||
|      * @param array Blob infos | ||||
|      */ | ||||
|     public function store($infos) | ||||
|     { | ||||
|         foreach ($infos as $blob) { | ||||
|             $cache = new IDF_Scm_Cache_Git(); | ||||
|             $cache->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, | ||||
|                                   ), | ||||
|                             ); | ||||
|     } | ||||
| } | ||||
| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user