Index: database_manager.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/ddl/database_manager.php,v retrieving revision 1.12 diff -u -r1.12 database_manager.php --- database_manager.php 13 Jul 2008 20:27:14 -0000 1.12 +++ database_manager.php 24 Jul 2008 07:45:46 -0000 @@ -906,6 +906,69 @@ $this->execute_sql_arr($sqlarr); } + + /** + * Reads the install.xml files for Moodle core and modules and returns an array of + * xmldb_structure object with xmldb_table from these files. + * @return xmldb_structure schema from install.xml files + */ + public static function get_install_xml_schema() { + global $CFG; + $schema = new xmldb_structure('export'); + $schema->setVersion($CFG->version); + $dbdirs = get_db_directories(); + foreach ($dbdirs as $dbdir) { + $xmldb_file = new xmldb_file($dbdir.'/install.xml'); + if (!($xmldb_file->fileExists() && $xmldb_file->loadXMLStructure())) { + continue; + } + $structure = $xmldb_file->getStructure(); + $tables = $structure->getTables(); + foreach($tables as $table) { + $table->setPrevious(null); + $table->setNext(null); + $schema->addTable($table); + } + } + return $schema; + } + + /** + * Checks the database schema against a schema specified by an xmldb_structure object + * @return array keyed by table name with array of difference messages as values + */ + public function check_database_schema(xmldb_structure $schema) { + $errors = array(); + $dbtables = $this->mdb->get_tables(); + $tables = $schema->getTables(); + //TODO: localize strings + // check for required tables and we ignore other tables from the + // database since this can be a shared with other applications + foreach($tables as $table) { + $tablename = $table->getName(); + if(empty($dbtables[$tablename])) { + $errors[$tablename][] = 'Table is missing.'; + continue; + } + // if table is found, then + $dbfields = $this->mdb->get_columns($tablename, false); + // a) check for required fields + $fields = $table->getFields(); + foreach($fields as $field) { + $fieldname = $field->getName(); + if(empty($dbfields[$fieldname])) { + $errors[$tablename][] = 'Field ' . $fieldname . ' is missing.'; + } + unset($dbfields[$fieldname]); + } + // b) check for extra fields (which indicates a hack and we don't + // support them for now) + foreach($dbfields as $fieldname=>$info) { + $errors[$tablename][] = 'Field ' . $fieldname . ' is unexpected.'; + } + } + return $errors; + } }