Work to decouple the ManifestBuilder from the database, so that you can run manifest builder tests without an active database existing

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@61152 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sam Minnee 2008-08-20 04:47:48 +00:00
parent 29ccb18fac
commit c4b358e26e
4 changed files with 40 additions and 25 deletions

View File

@ -82,9 +82,18 @@ class ManifestBuilder {
$baseDir = dirname($_SERVER['SCRIPT_FILENAME']) . "/.."; $baseDir = dirname($_SERVER['SCRIPT_FILENAME']) . "/..";
$baseDir = ereg_replace("/[^/]+/\\.\\.", "", $baseDir); $baseDir = ereg_replace("/[^/]+/\\.\\.", "", $baseDir);
$baseDir = preg_replace("/\\\\/", "/", $baseDir); $baseDir = preg_replace("/\\\\/", "/", $baseDir);
$manifest = self::generate_php_file(self::get_manifest_info($baseDir)); $manifestInfo = self::get_manifest_info($baseDir);
// Connect to the database and get the database config
global $databaseConfig;
DB::connect($databaseConfig);
if(DB::isActive()) {
$tableList = DB::getConn()->tableList();
self::update_db_tables($tableList, $manifest['globals']['_ALL_CLASSES']);
}
$manifest = self::generate_php_file($manifestInfo);
if($fh = fopen(MANIFEST_FILE, "w")) { if($fh = fopen(MANIFEST_FILE, "w")) {
fwrite($fh, $manifest); fwrite($fh, $manifest);
fclose($fh); fclose($fh);
@ -112,8 +121,9 @@ class ManifestBuilder {
/** /**
* Return an array containing information for the manifest * Return an array containing information for the manifest
* @param $baseDir A
*/ */
static function get_manifest_info($baseDir) { static function get_manifest_info($baseDir, $tableList = null) {
// locate and include the exclude files // locate and include the exclude files
$topLevel = scandir($baseDir); $topLevel = scandir($baseDir);
foreach($topLevel as $file) { foreach($topLevel as $file) {
@ -156,7 +166,6 @@ class ManifestBuilder {
$_CLASS_MANIFEST = $classManifest; $_CLASS_MANIFEST = $classManifest;
// _config.php manifest // _config.php manifest
global $databaseConfig;
$topLevel = scandir($baseDir); $topLevel = scandir($baseDir);
foreach($topLevel as $filename) { foreach($topLevel as $filename) {
if($filename[0] == '.') continue; if($filename[0] == '.') continue;
@ -203,10 +212,8 @@ class ManifestBuilder {
$manifestInfo["globals"]["_TEMPLATE_MANIFEST"] = $templateManifest; $manifestInfo["globals"]["_TEMPLATE_MANIFEST"] = $templateManifest;
$manifestInfo["globals"]["_CSS_MANIFEST"] = $cssManifest; $manifestInfo["globals"]["_CSS_MANIFEST"] = $cssManifest;
DB::connect($databaseConfig);
// Database manifest // Database manifest
$allClasses = ManifestBuilder::allClasses($classManifest); $allClasses = ManifestBuilder::allClasses($classManifest, $tableList);
$manifestInfo["globals"]["_ALL_CLASSES"] = $allClasses; $manifestInfo["globals"]["_ALL_CLASSES"] = $allClasses;
@ -317,11 +324,14 @@ class ManifestBuilder {
* Include everything, so that actually *all* classes are available and * Include everything, so that actually *all* classes are available and
* build a map of classes and their subclasses and the information if * build a map of classes and their subclasses and the information if
* the class has a database table * the class has a database table
*
* @param $classManifest An array of all Sapphire classes; keys are class names and values are filenames
* @param $tables An array of the tables that exist in the database
* *
* @return array Returns an array that holds all class relevant * @return array Returns an array that holds all class relevant
* information. * information.
*/ */
private static function allClasses($classManifest) { private static function allClasses($classManifest, $tables = null) {
self::$classArray = array(); self::$classArray = array();
self::$extendsArray = array(); self::$extendsArray = array();
self::$implementsArray = array(); self::$implementsArray = array();
@ -333,8 +343,6 @@ class ManifestBuilder {
self::parse_file($file); self::parse_file($file);
} }
$tables = DB::isActive() ? DB::getConn()->tableList() : array();
$allClasses["parents"] = self::find_parents(); $allClasses["parents"] = self::find_parents();
$allClasses["children"] = self::find_children(); $allClasses["children"] = self::find_children();
$allClasses["implementors"] = self::$implementsArray; $allClasses["implementors"] = self::$implementsArray;
@ -526,19 +534,22 @@ class ManifestBuilder {
/** /**
* Updates the active table list in the class info in the manifest, but leaves everything else as-is. * Updates the active table list in the class info in the manifest, but leaves everything else as-is.
* Much quicker to run than compileManifest :-) * Much quicker to run than compileManifest :-)
*
* @param $tableList The list of tables to load into the manifest
* @param $allClassesArray The $_ALL_CLASSES array that should be updated
*/ */
static function update_db_tables() { static function update_db_tables($tableList, &$allClassesArray) {
global $_ALL_CLASSES; if(!isset($allClassesArray['exists'])) return;
$_ALL_CLASSES['hastable'] = array();
$allClassesArray['hastable'] = array();
$tables = DB::getConn()->tableList(); $tables = array();
foreach($tableList as $table) $tables[$table] = true;
// We need to iterate through the full class lists, because the table names come out in lowercase // We need to iterate through the full class lists, because the table names come out in lowercase
foreach($_ALL_CLASSES['exists'] as $class) { foreach($allClassesArray['exists'] as $class) {
if(isset($tables[strtolower($class)])) $_ALL_CLASSES['hastable'][$class] = $class; if(isset($tables[strtolower($class)])) $allClassesArray['hastable'][$class] = $class;
} }
self::write_manifest();
} }
/** /**

View File

@ -177,8 +177,10 @@ class DatabaseAdmin extends Controller {
} }
} }
$conn->endSchemaUpdate(); $conn->endSchemaUpdate();
ManifestBuilder::update_db_tables(); global $_ALL_CLASSES;
ManifestBuilder::update_db_tables(DB::getConn()->tableList(), $_ALL_CLASSES);
ManifestBuilder::write_manifest();
if($populate) { if($populate) {
if(!$quiet) { if(!$quiet) {

View File

@ -156,7 +156,9 @@ class MySQLDatabase extends Database {
*/ */
public function selectDatabase($dbname) { public function selectDatabase($dbname) {
$this->database = $dbname; $this->database = $dbname;
if($this->databaseExists($this->database)) mysql_select_db($this->database, $this->dbConn); if($this->databaseExists($this->database)) {
if(mysql_select_db($this->database, $this->dbConn)) $this->active = true;
}
$this->tableList = $this->fieldList = $this->indexList = null; $this->tableList = $this->fieldList = $this->indexList = null;
} }

View File

@ -6,7 +6,7 @@
class ManifestBuilderTest extends SapphireTest { class ManifestBuilderTest extends SapphireTest {
function testManifest() { function testManifest() {
$baseFolder = TEMP_FOLDER . '/manifest-test'; $baseFolder = TEMP_FOLDER . '/manifest-test';
$manifestInfo = ManifestBuilder::get_manifest_info($baseFolder); $manifestInfo = ManifestBuilder::get_manifest_info($baseFolder, DB::getConn()->tableList());
$this->assertEquals("$baseFolder/sapphire/MyClass.php", $manifestInfo['globals']['_CLASS_MANIFEST']['MyClass']); $this->assertEquals("$baseFolder/sapphire/MyClass.php", $manifestInfo['globals']['_CLASS_MANIFEST']['MyClass']);
$this->assertEquals("$baseFolder/sapphire/subdir/SubDirClass.php", $manifestInfo['globals']['_CLASS_MANIFEST']['SubDirClass']); $this->assertEquals("$baseFolder/sapphire/subdir/SubDirClass.php", $manifestInfo['globals']['_CLASS_MANIFEST']['SubDirClass']);
@ -33,7 +33,7 @@ class ManifestBuilderTest extends SapphireTest {
function testManifestIgnoresClassesInComments() { function testManifestIgnoresClassesInComments() {
$baseFolder = TEMP_FOLDER . '/manifest-test'; $baseFolder = TEMP_FOLDER . '/manifest-test';
$manifestInfo = ManifestBuilder::get_manifest_info($baseFolder); $manifestInfo = ManifestBuilder::get_manifest_info($baseFolder, DB::getConn()->tableList());
/* Our fixture defines the class MyClass_InComment inside a comment, so it shouldn't be included in the class manifest. */ /* Our fixture defines the class MyClass_InComment inside a comment, so it shouldn't be included in the class manifest. */
$this->assertNotContains('MyClass_InComment', array_keys($manifestInfo['globals']['_CLASS_MANIFEST'])); $this->assertNotContains('MyClass_InComment', array_keys($manifestInfo['globals']['_CLASS_MANIFEST']));
@ -50,7 +50,7 @@ class ManifestBuilderTest extends SapphireTest {
function testManifestIgnoresClassesInStrings() { function testManifestIgnoresClassesInStrings() {
$baseFolder = TEMP_FOLDER . '/manifest-test'; $baseFolder = TEMP_FOLDER . '/manifest-test';
$manifestInfo = ManifestBuilder::get_manifest_info($baseFolder); $manifestInfo = ManifestBuilder::get_manifest_info($baseFolder, DB::getConn()->tableList());
/* If a class defintion is listed in a single quote string, then it shouldn't be inlcuded. Here we have put a class definition for MyClass_InSingleQuoteString inside a single-quoted string */ /* If a class defintion is listed in a single quote string, then it shouldn't be inlcuded. Here we have put a class definition for MyClass_InSingleQuoteString inside a single-quoted string */
$this->assertNotContains('MyClass_InSingleQuoteString', array_keys($manifestInfo['globals']['_CLASS_MANIFEST'])); $this->assertNotContains('MyClass_InSingleQuoteString', array_keys($manifestInfo['globals']['_CLASS_MANIFEST']));