/* * Load a database and adapt to the description if needed */ CDatabase* CDbManager::loadDatabase(TDatabaseId id, const string& description, CLog* log) { CHECK_DB_MGR_INIT(loadDatabase, false); nlinfo("CDbManager::loadDatabase(): load/setup database '%d'", id); CDatabase* db = getDatabase(id); // database not loaded yet? if (db == NULL) { // create a memory image db = createDatabase(id, log); if (db == NULL) { log->displayNL("failed to create database '%d'", id); return NULL; } // if can't load database if (!db->loadState()) { nlinfo("CDbManager::loadDatabase(): database '%d' doesn't exist, create new", id); // create a new database with the new description if (!db->createFromScratch(description)) { log->displayNL("failed to create database '%d' from scratch", id); return NULL; } return db; } } CDatabase* adapted = db->adapt(description); if (adapted == NULL) { log->displayNL("failed to adapt database '%s' to new description", db->getName().c_str()); return NULL; } // database changed? if (db != adapted) { // replace old on with new one _DatabaseMap[id] = adapted; // and delete old delete db; } return adapted; }
/* * Adapt database to new description * \param description is the latest xml description of the database * \returns true is adaptation succeded */ CDatabase* CDatabase::adapt(const string& description) { PDS_DEBUG("adapt()"); if (!initialised()) { PDS_WARNING("adapt(): failed, database not initialised"); return NULL; } // get 'From' HashKey CHashKey hash1 = _Description.getHashKey(); // get 'Into' HashKey CHashKey hash2 = getSHA1((const uint8*)(description.c_str()), (uint32)description.size()); // same hash, ok go on if (hash1 == hash2) return this; // build a clean reference if needed if (!isReferenceUpToDate()) { if (!buildReference()) { PDS_WARNING("adapt(): failed to buildReference()"); return false; } } // backup old reference if (!_Reference.save(_Reference.getPath()+"ref")) { PDS_WARNING("adapt(): failed to backup reference index"); } // create a new destination database CDatabase* into = new CDatabase(_State.Id); if (!into->createFromScratch(description)) { PDS_WARNING("adapt(): failed to create new reference"); delete into; return NULL; } CDatabaseAdapter adapter; if (!adapter.build(this, into)) { PDS_WARNING("adapt(): failed to build() adapter"); delete into; return NULL; } if (!adapter.buildContent()) { PDS_WARNING("adapt(): adapter failed to buildContent()"); delete into; return NULL; } // rebuild volatile data // that is all non persistant data that can be found from persistant data if (!into->rebuildVolatileData()) { PDS_WARNING("adapt(): failed to rebuildVolatileData()"); delete into; return NULL; } // init timestamps as database is ready to run into->initTimestamps(); return into; }