/** * Check that once a schema has been generated, then it doesn't need any more updating */ function testFieldsDontRerequestChanges() { $db = DB::getConn(); DB::quiet(); // Table will have been initially created by the $extraDataObjects setting // Verify that it doesn't need to be recreated $db->beginSchemaUpdate(); $obj = new DataObjectSchemaGenerationTest_DO(); $obj->requireTable(); $needsUpdating = $db->doesSchemaNeedUpdating(); $db->cancelSchemaUpdate(); $this->assertFalse($needsUpdating); }
/** * Check that once a schema has been generated, then it doesn't need any more updating */ public function testFieldsDontRerequestChanges() { // These are MySQL specific :-S if (DB::getConn() instanceof MySQLDatabase) { $db = DB::getConn(); DB::quiet(); // Verify that it doesn't need to be recreated $db->beginSchemaUpdate(); $obj = new MySQLDatabaseTest_DO(); $obj->requireTable(); $needsUpdating = $db->doesSchemaNeedUpdating(); $db->cancelSchemaUpdate(); $this->assertFalse($needsUpdating); } }
/** * Check that updates to a dataobject's indexes are reflected in DDL */ public function testIndexesRerequestChanges() { $db = DB::getConn(); DB::quiet(); // Table will have been initially created by the $extraDataObjects setting // Update the SearchFields index here Config::inst()->update('DataObjectSchemaGenerationTest_IndexDO', 'indexes', array('SearchFields' => array('value' => 'Title'))); // Verify that the above index change triggered a schema update $db->beginSchemaUpdate(); $obj = new DataObjectSchemaGenerationTest_IndexDO(); $obj->requireTable(); $needsUpdating = $db->doesSchemaNeedUpdating(); $db->cancelSchemaUpdate(); $this->assertTrue($needsUpdating); }
/** * Check that once a schema has been generated, then it doesn't need any more updating */ public function testFieldsDontRerequestChanges() { // These are MySQL specific :-S if (DB::get_conn() instanceof MySQLDatabase) { $schema = DB::get_schema(); $test = $this; DB::quiet(); // Verify that it doesn't need to be recreated $schema->schemaUpdate(function () use($test, $schema) { $obj = new MySQLDatabaseTest_DO(); $obj->requireTable(); $needsUpdating = $schema->doesSchemaNeedUpdating(); $schema->cancelSchemaUpdate(); $test->assertFalse($needsUpdating); }); } }
/** * Check that updates to a dataobject's indexes are reflected in DDL */ public function testIndexesRerequestChanges() { $db = DB::getConn(); DB::quiet(); // Table will have been initially created by the $extraDataObjects setting // Update the SearchFields index here $oldIndexes = DataObjectSchemaGenerationTest_IndexDO::$indexes; DataObjectSchemaGenerationTest_IndexDO::$indexes['SearchFields']['value'] = '"Title"'; // Verify that the above index change triggered a schema update $db->beginSchemaUpdate(); $obj = new DataObjectSchemaGenerationTest_IndexDO(); $obj->requireTable(); $needsUpdating = $db->doesSchemaNeedUpdating(); $db->cancelSchemaUpdate(); $this->assertTrue($needsUpdating); // Restore old indexes DataObjectSchemaGenerationTest_IndexDO::$indexes = $oldIndexes; }
/** * Reset the testing database's schema. * @param $includeExtraDataObjects If true, the extraDataObjects tables will also be included */ function resetDBSchema($includeExtraDataObjects = false) { if (self::using_temp_db()) { // clear singletons, they're caching old extension info which is used in DatabaseAdmin->doBuild() global $_SINGLETONS; $_SINGLETONS = array(); $dataClasses = ClassInfo::subclassesFor('DataObject'); array_shift($dataClasses); $conn = DB::getConn(); $conn->beginSchemaUpdate(); DB::quiet(); foreach ($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness if (class_exists($dataClass)) { $SNG = singleton($dataClass); if (!$SNG instanceof TestOnly) { $SNG->requireTable(); } } } // If we have additional dataobjects which need schema, do so here: if ($includeExtraDataObjects && $this->extraDataObjects) { foreach ($this->extraDataObjects as $dataClass) { $SNG = singleton($dataClass); if (singleton($dataClass) instanceof DataObject) { $SNG->requireTable(); } } } $conn->endSchemaUpdate(); ClassInfo::reset_db_cache(); singleton('DataObject')->flushCache(); } }
/** * Updates the database schema, creating tables & fields as necessary. * * @param boolean $quiet Don't show messages * @param boolean $populate Populate the database, as well as setting up its schema */ public function doBuild($quiet = false, $populate = true, $testMode = false) { if ($quiet) { DB::quiet(); } else { $conn = DB::getConn(); // Assumes database class is like "MySQLDatabase" or "MSSQLDatabase" (suffixed with "Database") $dbType = substr(get_class($conn), 0, -8); $dbVersion = $conn->getVersion(); $databaseName = method_exists($conn, 'currentDatabase') ? $conn->currentDatabase() : ""; if (Director::is_cli()) { echo sprintf("\n\nBuilding database %s using %s %s\n\n", $databaseName, $dbType, $dbVersion); } else { echo sprintf("<h2>Building database %s using %s %s</h2>", $databaseName, $dbType, $dbVersion); } } // Set up the initial database if (!DB::isActive()) { if (!$quiet) { echo '<p><b>Creating database</b></p>'; } global $databaseConfig; $parameters = $databaseConfig ? $databaseConfig : $_REQUEST['db']; $connect = DB::getConnect($parameters); $username = $parameters['username']; $password = $parameters['password']; $database = $parameters['database']; if (!$database) { user_error("No database name given; please give a value for \$databaseConfig['database']", E_USER_ERROR); } DB::createDatabase($connect, $username, $password, $database); } // Build the database. Most of the hard work is handled by DataObject $dataClasses = ClassInfo::subclassesFor('DataObject'); array_shift($dataClasses); if (!$quiet) { if (Director::is_cli()) { echo "\nCREATING DATABASE TABLES\n\n"; } else { echo "\n<p><b>Creating database tables</b></p>\n\n"; } } $conn = DB::getConn(); $conn->beginSchemaUpdate(); foreach ($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness if (class_exists($dataClass)) { $SNG = singleton($dataClass); if ($testMode || !$SNG instanceof TestOnly) { if (!$quiet) { if (Director::is_cli()) { echo " * {$dataClass}\n"; } else { echo "<li>{$dataClass}</li>\n"; } } $SNG->requireTable(); } } } $conn->endSchemaUpdate(); ClassInfo::reset_db_cache(); if ($populate) { if (!$quiet) { if (Director::is_cli()) { echo "\nCREATING DATABASE RECORDS\n\n"; } else { echo "\n<p><b>Creating database records</b></p>\n\n"; } } foreach ($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness // Test_ indicates that it's the data class is part of testing system if (strpos($dataClass, 'Test_') === false && class_exists($dataClass)) { if (!$quiet) { if (Director::is_cli()) { echo " * {$dataClass}\n"; } else { echo "<li>{$dataClass}</li>\n"; } } singleton($dataClass)->requireDefaultRecords(); } } } touch(TEMP_FOLDER . '/database-last-generated-' . str_replace(array('\\', '/', ':'), '.', Director::baseFolder())); if (isset($_REQUEST['from_installer'])) { echo "OK"; } if (!$quiet) { echo Director::is_cli() ? "\n Database build completed!\n\n" : "<p>Database build completed!</p>"; } ClassInfo::reset_db_cache(); }
/** * Reset the testing database's schema. * @param $includeExtraDataObjects If true, the extraDataObjects tables will also be included */ public function resetDBSchema($includeExtraDataObjects = false) { if (self::using_temp_db()) { DataObject::reset(); // clear singletons, they're caching old extension info which is used in DatabaseAdmin->doBuild() Injector::inst()->unregisterAllObjects(); $dataClasses = ClassInfo::subclassesFor('DataObject'); array_shift($dataClasses); DB::quiet(); $schema = DB::get_schema(); $extraDataObjects = $includeExtraDataObjects ? $this->extraDataObjects : null; $schema->schemaUpdate(function () use($dataClasses, $extraDataObjects) { foreach ($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness if (class_exists($dataClass)) { $SNG = singleton($dataClass); if (!$SNG instanceof TestOnly) { $SNG->requireTable(); } } } // If we have additional dataobjects which need schema, do so here: if ($extraDataObjects) { foreach ($extraDataObjects as $dataClass) { $SNG = singleton($dataClass); if (singleton($dataClass) instanceof DataObject) { $SNG->requireTable(); } } } }); ClassInfo::reset_db_cache(); singleton('DataObject')->flushCache(); } }
/** * Updates the database schema, creating tables & fields as necessary. * * @param boolean $quiet Don't show messages * @param boolean $populate Populate the database, as well as setting up its schema */ public function doBuild($quiet = false, $populate = true, $testMode = false) { if ($quiet) { DB::quiet(); } else { $conn = DB::get_conn(); // Assumes database class is like "MySQLDatabase" or "MSSQLDatabase" (suffixed with "Database") $dbType = substr(get_class($conn), 0, -8); $dbVersion = $conn->getVersion(); $databaseName = method_exists($conn, 'currentDatabase') ? $conn->getSelectedDatabase() : ""; if (Director::is_cli()) { echo sprintf("\n\nBuilding database %s using %s %s\n\n", $databaseName, $dbType, $dbVersion); } else { echo sprintf("<h2>Building database %s using %s %s</h2>", $databaseName, $dbType, $dbVersion); } } // Set up the initial database if (!DB::is_active()) { if (!$quiet) { echo '<p><b>Creating database</b></p>'; } // Load parameters from existing configuration global $databaseConfig; if (empty($databaseConfig) && empty($_REQUEST['db'])) { user_error("No database configuration available", E_USER_ERROR); } $parameters = !empty($databaseConfig) ? $databaseConfig : $_REQUEST['db']; // Check database name is given if (empty($parameters['database'])) { user_error("No database name given; please give a value for \$databaseConfig['database']", E_USER_ERROR); } $database = $parameters['database']; // Establish connection and create database in two steps unset($parameters['database']); DB::connect($parameters); DB::create_database($database); } // Build the database. Most of the hard work is handled by DataObject $dataClasses = ClassInfo::subclassesFor('DataObject'); array_shift($dataClasses); if (!$quiet) { if (Director::is_cli()) { echo "\nCREATING DATABASE TABLES\n\n"; } else { echo "\n<p><b>Creating database tables</b></p>\n\n"; } } // Initiate schema update $dbSchema = DB::get_schema(); $dbSchema->schemaUpdate(function () use($dataClasses, $testMode, $quiet) { foreach ($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness if (!class_exists($dataClass)) { continue; } // Check if this class should be excluded as per testing conventions $SNG = singleton($dataClass); if (!$testMode && $SNG instanceof TestOnly) { continue; } // Log data if (!$quiet) { if (Director::is_cli()) { echo " * {$dataClass}\n"; } else { echo "<li>{$dataClass}</li>\n"; } } // Instruct the class to apply its schema to the database $SNG->requireTable(); } }); ClassInfo::reset_db_cache(); if ($populate) { if (!$quiet) { if (Director::is_cli()) { echo "\nCREATING DATABASE RECORDS\n\n"; } else { echo "\n<p><b>Creating database records</b></p>\n\n"; } } foreach ($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness // Test_ indicates that it's the data class is part of testing system if (strpos($dataClass, 'Test_') === false && class_exists($dataClass)) { if (!$quiet) { if (Director::is_cli()) { echo " * {$dataClass}\n"; } else { echo "<li>{$dataClass}</li>\n"; } } singleton($dataClass)->requireDefaultRecords(); } } } touch(TEMP_FOLDER . '/database-last-generated-' . str_replace(array('\\', '/', ':'), '.', Director::baseFolder())); if (isset($_REQUEST['from_installer'])) { echo "OK"; } if (!$quiet) { echo Director::is_cli() ? "\n Database build completed!\n\n" : "<p>Database build completed!</p>"; } ClassInfo::reset_db_cache(); }
/** * Updates the database schema, creating tables & fields as necessary. * * @param boolean $quiet Don't show messages * @param boolean $populate Populate the database, as well as setting up its schema */ function doBuild($quiet = false, $populate = true, $testMode = false) { if($quiet) { DB::quiet(); } else { echo "<h2>Building Database</h2>"; } // Set up the initial database if(!DB::isActive()) { if(!$quiet) { echo '<p><b>Creating database</b></p>'; } global $databaseConfig; $parameters = $databaseConfig ? $databaseConfig : $_REQUEST['db']; $connect = DB::getConnect($parameters); $username = $parameters['username']; $password = $parameters['password']; $database = $parameters['database']; if(!$database) { user_error("No database name given; please give a value for \$databaseConfig['database']", E_USER_ERROR); } DB::createDatabase($connect, $username, $password, $database); // ManifestBuilder::compileManifest(); } // Build the database. Most of the hard work is handled by DataObject $dataClasses = ClassInfo::subclassesFor('DataObject'); array_shift($dataClasses); if(!$quiet) { if(Director::is_cli()) echo "\nCREATING DATABASE TABLES\n\n"; else echo "\n<p><b>Creating database tables</b></p>\n\n"; } $conn = DB::getConn(); $conn->beginSchemaUpdate(); foreach($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness if(class_exists($dataClass)) { $SNG = singleton($dataClass); if($testMode || !($SNG instanceof TestOnly)) { if(!$quiet) { if(Director::is_cli()) echo " * $dataClass\n"; else echo "<li>$dataClass</li>\n"; } $SNG->requireTable(); } } } $conn->endSchemaUpdate(); if($populate) { if(!$quiet) { if(Director::is_cli()) echo "\nCREATING DATABASE RECORDS\n\n"; else echo "\n<p><b>Creating database records</b></p>\n\n"; } foreach($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness // Test_ indicates that it's the data class is part of testing system if(strpos($dataClass,'Test_') === false && class_exists($dataClass)) { if(!$quiet) { if(Director::is_cli()) echo " * $dataClass\n"; else echo "<li>$dataClass</li>\n"; } singleton($dataClass)->requireDefaultRecords(); } } } touch(TEMP_FOLDER . '/database-last-generated-' . str_replace(array('\\', '/', ':'), '.', Director::baseFolder())); if(isset($_REQUEST['from_installer'])) { echo "OK"; } }
/** * Updates the database schema, creating tables & fields as necessary. * * @param boolean $quiet Don't show messages * @param boolean $populate Populate the database, as well as setting up its schema */ function doBuild($quiet = false, $populate = true) { $conn = DB::getConn(); if ($quiet) { DB::quiet(); } else { echo "<h2>Building Database</h2>"; } // Set up the initial database if (!DB::isActive()) { if (!$quiet) { echo '<p><b>Creating database</b></p>'; } global $databaseConfig; $parameters = $databaseConfig ? $databaseConfig : $_REQUEST['db']; $connect = DB::getConnect($parameters); $username = $parameters['username']; $password = $parameters['password']; $database = $parameters['database']; DB::createDatabase($connect, $username, $password, $database); // ManifestBuilder::compileManifest(); } // Get all our classes // ManifestBuilder::compileManifest(); // ManifestBuilder::includeEverything(); // Build the database. Most of the hard work is handled by DataObject $dataClasses = ClassInfo::subclassesFor('DataObject'); array_shift($dataClasses); if (!$quiet) { echo '<p><b>Creating database tables</b></p>'; } $conn->beginSchemaUpdate(); foreach ($dataClasses as $dataClass) { // Test_ indicates that it's the data class is part of testing system if (strpos($dataClass, 'Test_') === false) { if (!$quiet) { echo "<li>{$dataClass}</li>"; } singleton($dataClass)->requireTable(); } } $conn->endSchemaUpdate(); ManifestBuilder::update_db_tables(); if ($populate) { if (!$quiet) { echo '<p><b>Creating database records</b></p>'; } foreach ($dataClasses as $dataClass) { // Test_ indicates that it's the data class is part of testing system if (strpos($dataClass, 'Test_') === false) { if (!$quiet) { echo "<li>{$dataClass}</li>"; } singleton($dataClass)->requireDefaultRecords(); } } } touch(TEMP_FOLDER . '/database-last-generated-' . str_replace(array('\\', '/', ':'), '.', Director::baseFolder())); if (isset($_REQUEST['from_installer'])) { echo "OK"; } }