Exemplo n.º 1
0
// 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;
}
Exemplo n.º 2
0
// 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;
}