// static int DbWrapper::copySecondary(DB_ENV *env, const std::string &oldcname, const std::string &newcname, const std::string &prefix, const std::string &dbname, bool duplicates) { int err; DbWrapper olddb(env, oldcname, prefix, dbname, DEFAULT_CONFIG); ContainerConfig config; config.setReadOnly(true); err = olddb.open(0, DB_BTREE, config); if (err) { // ignore ENOENT -- it's OK sometimes if (err == ENOENT) err = 0; return err; } config.setReadOnly(false); config.setPageSize(olddb.getPageSize()); DbWrapper newdb(env, newcname, prefix, dbname, config); if (duplicates) { err = newdb.getDb()->set_flags(newdb.getDb(), DB_DUP|DB_DUPSORT); if (err) throw XmlException(err); } err = newdb.open(0, DB_BTREE, DB_CREATE|DB_EXCL); if (err == 0) err = newdb.copy(olddb, DB_KEYFIRST); return err; }
// upgrade from 2.1 (version 4) to 2.2 (version 5) // Modify keys for both document secondary and content (if wholedoc storage) // secondary key: docId, nameId, type // content key: docId // for both: // 1. open old DB and create a new database // 2. for each record: // o unmarshal old format; marshal in new, and put into new DB static int upgrade22(const std::string &name, const std::string &tname, Manager &mgr) { int err = 0; SecondaryDatabase secondary(mgr.getDB_ENV(), name, document_name, DEFAULT_CONFIG); err = secondary.open(0, /*duplicates*/false, DEFAULT_CONFIG); ContainerConfig config; config.setPageSize(secondary.getPageSize()); SecondaryDatabase newSec(mgr.getDB_ENV(), tname, document_name, config); err = newSec.open(0, /*duplicates*/false, CREATE_CONFIG); // the key is: docId,nodeId,type DbXml::DbXmlDbt key; DbXml::DbXmlDbt data; Cursor curs(secondary, (Transaction*)0, DbXml::CURSOR_READ); int ret = 0; while ((err == 0) && (ret = curs.get(key, data, DB_NEXT)) == 0) { // decode key using pre-2.2 code DocID did; NameID nid; XmlValue::Type type; u_int32_t *p = (u_int32_t *)key.data; u_int32_t id1, id2; id1 = *p++; id2 = *p++; if (Manager::isBigendian()) { M_32_SWAP(id1); M_32_SWAP(id2); } did = id1; nid = id2; type = (XmlValue::Type) * ((unsigned char*)p); // encode using 2.2. code DbtOut newKey; MetaDatum::setKeyDbt(did, nid, type, newKey); err = newSec.put(0, &newKey, &data, 0); } curs.close(); secondary.close(0); newSec.close(0); if (err == 0) { DbWrapper content(mgr.getDB_ENV(), name, "content_", document_name, DEFAULT_CONFIG); err = content.open(0, DB_BTREE, DEFAULT_CONFIG); if (err != 0) { // ignore ENOENT if (err == ENOENT) err = 0; return err; } config.setPageSize(content.getPageSize()); DbWrapper newContent(mgr.getDB_ENV(), tname, "content_", document_name, config); err = newContent.open(0, DB_BTREE, CREATE_CONFIG); if (err != 0) return err; // the key is: docId DbXml::DbXmlDbt key; DbXml::DbXmlDbt data; Cursor curs1(content, (Transaction*)0, DbXml::CURSOR_READ); int ret = 0; while ((err == 0) && (ret = curs1.get(key, data, DB_NEXT)) == 0) { // decode/encode key, rewrite u_int32_t *p = (u_int32_t *)key.data; u_int32_t id1; id1 = *p; if (Manager::isBigendian()) M_32_SWAP(id1); DocID id(id1); DbtOut newKey; id.setDbtFromThis(newKey); err = newContent.put(0, &newKey, &data, 0); } curs1.close(); content.close(0); newContent.close(0); } return err; }