示例#1
0
    void shouldReparentCollectionsOnModify()
    {
        // GIVEN
        auto data = Testlib::AkonadiFakeData();

        auto c1 = Akonadi::Collection(42);
        c1.setName(QStringLiteral("42"));
        data.createCollection(c1);

        auto c2 = Akonadi::Collection(43);
        c2.setName(QStringLiteral("43"));
        data.createCollection(c2);

        auto c3 = Akonadi::Collection(44);
        c3.setParentCollection(Akonadi::Collection(42));
        data.createCollection(c3);

        // WHEN
        c3.setParentCollection(Akonadi::Collection(43));
        data.modifyCollection(c3);

        // THEN
        QVERIFY(data.childCollections(c1.id()).isEmpty());
        QCOMPARE(data.childCollections(c2.id()).size(), 1);
        QCOMPARE(data.childCollections(c2.id()).at(0), c3);
    }
示例#2
0
    void shouldReparentItemsOnModify()
    {
        // GIVEN
        auto data = Testlib::AkonadiFakeData();
        QScopedPointer<Akonadi::MonitorInterface> monitor(data.createMonitor());
        QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemMoved);

        auto c1 = Akonadi::Collection(42);
        c1.setName(QStringLiteral("42"));
        data.createCollection(c1);

        auto c2 = Akonadi::Collection(43);
        c2.setName(QStringLiteral("43"));
        data.createCollection(c2);

        auto i1 = Akonadi::Item(42);
        i1.setPayloadFromData("42");
        i1.setParentCollection(Akonadi::Collection(42));
        data.createItem(i1);

        // WHEN
        i1.setPayloadFromData("42-bis");
        i1.setParentCollection(Akonadi::Collection(43));
        data.modifyItem(i1);

        // THEN
        QVERIFY(data.childItems(c1.id()).isEmpty());
        QCOMPARE(data.childItems(c2.id()).size(), 1);
        QCOMPARE(data.childItems(c2.id()).at(0), i1);

        QCOMPARE(spy.size(), 1);
        QCOMPARE(spy.takeFirst().at(0).value<Akonadi::Item>(), i1);
    }
示例#3
0
    void shouldNotLooseParentCollectionOnModifyCollection()
    {
        // GIVEN
        auto data = Testlib::AkonadiFakeData();

        auto root = Akonadi::Collection(42);
        root.setName(QStringLiteral("root"));
        data.createCollection(root);

        auto c1 = Akonadi::Collection(43);
        c1.setName(QStringLiteral("43"));
        c1.setParentCollection(Akonadi::Collection(root.id()));
        data.createCollection(c1);

        auto c2 = Akonadi::Collection(c1.id());
        c2.setName(QStringLiteral("43-bis"));

        // WHEN
        data.modifyCollection(c2);

        // THEN
        QCOMPARE(data.collections().size(), 2);
        QCOMPARE(data.collection(c1.id()), c2);
        QCOMPARE(data.collection(c1.id()).parentCollection().id(), root.id());
    }
示例#4
0
    void shouldRemoveCollections()
    {
        // GIVEN
        auto data = Testlib::AkonadiFakeData();
        QScopedPointer<Akonadi::MonitorInterface> monitor(data.createMonitor());
        QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionRemoved);

        auto c1 = Akonadi::Collection(42);
        c1.setName(QStringLiteral("42"));
        data.createCollection(c1);

        auto c2 = Akonadi::Collection(43);
        c2.setName(QStringLiteral("43"));
        c2.setParentCollection(Akonadi::Collection(42));
        data.createCollection(c2);

        auto c3 = Akonadi::Collection(44);
        c3.setName(QStringLiteral("44"));
        c3.setParentCollection(Akonadi::Collection(43));
        data.createCollection(c3);

        auto i1 = Akonadi::Item(42);
        i1.setPayloadFromData("42");
        i1.setParentCollection(Akonadi::Collection(43));
        data.createItem(i1);

        auto i2 = Akonadi::Item(43);
        i2.setPayloadFromData("43");
        i2.setParentCollection(Akonadi::Collection(44));
        data.createItem(i2);

        // WHEN
        data.removeCollection(c2);

        // THEN
        QCOMPARE(data.collections().size(), 1);
        QCOMPARE(data.collections().at(0), c1);

        QVERIFY(!data.collection(c2.id()).isValid());
        QVERIFY(!data.collection(c3.id()).isValid());

        QVERIFY(data.childCollections(c1.id()).isEmpty());
        QVERIFY(data.childCollections(c2.id()).isEmpty());
        QVERIFY(data.childCollections(c3.id()).isEmpty());

        QVERIFY(data.items().isEmpty());

        QVERIFY(!data.item(i1.id()).isValid());
        QVERIFY(!data.item(i2.id()).isValid());

        QVERIFY(data.childItems(c2.id()).isEmpty());
        QVERIFY(data.childItems(c3.id()).isEmpty());

        QCOMPARE(spy.size(), 2);
        QCOMPARE(spy.takeFirst().at(0).value<Akonadi::Collection>(), c3);
        QCOMPARE(spy.takeFirst().at(0).value<Akonadi::Collection>(), c2);
    }
示例#5
0
bool _testOplogEntryIsForCappedCollection(OperationContext* txn,
                                          const NamespaceString& nss,
                                          const CollectionOptions& options) {
    auto writerPool = SyncTail::makeWriterPool();
    MultiApplier::Operations operationsApplied;
    auto applyOperationFn = [&operationsApplied](MultiApplier::OperationPtrs* operationsToApply) {
        for (auto&& opPtr : *operationsToApply) {
            operationsApplied.push_back(*opPtr);
        }
    };
    createCollection(txn, nss, options);

    auto op = makeInsertDocumentOplogEntry({Timestamp(Seconds(1), 0), 1LL}, nss, BSON("a" << 1));
    ASSERT_FALSE(op.isForCappedCollection);

    auto lastOpTime =
        unittest::assertGet(multiApply(txn, writerPool.get(), {op}, applyOperationFn));
    ASSERT_EQUALS(op.getOpTime(), lastOpTime);

    ASSERT_EQUALS(1U, operationsApplied.size());
    const auto& opApplied = operationsApplied.front();
    ASSERT_EQUALS(op, opApplied);
    // "isForCappedCollection" is not parsed from raw oplog entry document.
    return opApplied.isForCappedCollection;
}
示例#6
0
    void shouldCreateCollections()
    {
        // GIVEN
        auto data = Testlib::AkonadiFakeData();
        QScopedPointer<Akonadi::MonitorInterface> monitor(data.createMonitor());
        QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionAdded);

        auto c1 = Akonadi::Collection(42);
        c1.setName(QStringLiteral("42"));
        auto c2 = Akonadi::Collection(43);
        c2.setName(QStringLiteral("43"));
        const auto colSet = QSet<Akonadi::Collection>() << c1 << c2;

        // WHEN
        data.createCollection(c1);
        data.createCollection(c2);

        // THEN
        QCOMPARE(data.collections().toList().toSet(), colSet);
        QCOMPARE(data.collection(c1.id()), c1);
        QCOMPARE(data.collection(c2.id()), c2);

        QCOMPARE(spy.size(), 2);
        QCOMPARE(spy.takeFirst().at(0).value<Akonadi::Collection>(), c1);
        QCOMPARE(spy.takeFirst().at(0).value<Akonadi::Collection>(), c2);
    }
示例#7
0
 Collection* Database::getOrCreateCollection(OperationContext* txn, StringData ns) {
     Collection* c = getCollection( ns );
     if ( !c ) {
         c = createCollection( txn, ns );
     }
     return c;
 }
示例#8
0
    void shouldNotLooseParentCollectionOnModifyItem()
    {
        // GIVEN
        auto data = Testlib::AkonadiFakeData();

        auto c1 = Akonadi::Collection(42);
        c1.setName(QStringLiteral("42"));
        data.createCollection(c1);

        auto i1 = Akonadi::Item(42);
        i1.setPayloadFromData("42");
        i1.setParentCollection(Akonadi::Collection(42));
        data.createItem(i1);

        auto i2 = Akonadi::Item(i1.id());
        i2.setPayloadFromData("42-bis");

        // WHEN
        data.modifyItem(i2);

        // THEN
        QCOMPARE(data.items().size(), 1);
        QCOMPARE(data.item(i1.id()), i2);
        QCOMPARE(data.item(i1.id()).parentCollection().id(), c1.id());
    }
示例#9
0
static void readCollectionContent(xmlNode *node) {
    Collection *col;
    xmlChar *col_uri;
	xmlNode *child_node; // structured xml annotation
	int i;

    // create Collection
    col_uri = getNodeURI(node);
    col = createCollection(DESTINATION, (char *)col_uri);
    xmlFree(col_uri);

    // add displayID, name, description
    readSBOLCompoundObject(col->base, node);

	// scan other xml nodes attached to this Collection for structured xml annotations
	// @TODO factor out this block of code.  This routine is generally used by each of the SBOL core objects
	// but it requires some custom knowledge of the calling object (in this case, Collection)
	child_node = node->children;
	while (child_node) {
		if (child_node->ns && !isSBOLNamespace(child_node->ns->href)) {
			// copy xml tree and save it in the SBOLDocument object as a structural annotation 
			xmlNode* node_copy = xmlDocCopyNode(child_node, col->doc->xml_doc, 1);
			node_copy = xmlAddChild(xmlDocGetRootElement(col->doc->xml_doc), node_copy);
			i = xmlReconciliateNs(col->doc->xml_doc, xmlDocGetRootElement(col->doc->xml_doc));
			insertPointerIntoArray(col->base->base->xml_annotations, node_copy);
		}
		child_node = child_node->next;
	}

}
示例#10
0
    void shouldModifyItems()
    {
        // GIVEN
        auto data = Testlib::AkonadiFakeData();
        QScopedPointer<Akonadi::MonitorInterface> monitor(data.createMonitor());
        QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged);
        QSignalSpy moveSpy(monitor.data(), &Akonadi::MonitorInterface::itemMoved);

        auto c1 = Akonadi::Collection(42);
        c1.setName(QStringLiteral("42"));
        data.createCollection(c1);

        auto i1 = Akonadi::Item(42);
        i1.setPayloadFromData("42");
        i1.setParentCollection(Akonadi::Collection(42));
        data.createItem(i1);

        auto i2 = Akonadi::Item(i1.id());
        i2.setPayloadFromData("42-bis");
        i2.setParentCollection(Akonadi::Collection(42));

        // WHEN
        data.modifyItem(i2);

        // THEN
        QCOMPARE(data.items().size(), 1);
        QCOMPARE(data.item(i1.id()), i2);

        QCOMPARE(spy.size(), 1);
        QCOMPARE(spy.takeFirst().at(0).value<Akonadi::Item>(), i2);

        QCOMPARE(moveSpy.size(), 0);
    }
示例#11
0
    void shouldRemoveTags()
    {
        // GIVEN
        auto data = Testlib::AkonadiFakeData();
        QScopedPointer<Akonadi::MonitorInterface> monitor(data.createMonitor());
        QSignalSpy tagSpy(monitor.data(), &Akonadi::MonitorInterface::tagRemoved);
        QSignalSpy itemSpy(monitor.data(), &Akonadi::MonitorInterface::itemChanged);

        auto c1 = Akonadi::Collection(42);
        data.createCollection(c1);

        auto t1 = Akonadi::Tag(42);
        t1.setName(QStringLiteral("42"));
        data.createTag(t1);

        auto t2 = Akonadi::Tag(43);
        t2.setName(QStringLiteral("43"));
        data.createTag(t2);

        auto i1 = Akonadi::Item(42);
        i1.setPayloadFromData("42");
        i1.setParentCollection(c1);
        i1.setTag(Akonadi::Tag(t1.id()));
        data.createItem(i1);

        auto i2 = Akonadi::Item(43);
        i2.setPayloadFromData("43");
        i2.setParentCollection(c1);
        i2.setTag(Akonadi::Tag(t2.id()));
        data.createItem(i2);

        const auto itemSet = QSet<Akonadi::Item>() << i1 << i2;

        // WHEN
        data.removeTag(t2);

        // THEN
        QCOMPARE(data.tags().size(), 1);
        QCOMPARE(data.tags().at(0), t1);

        QVERIFY(!data.tag(t2.id()).isValid());

        QCOMPARE(data.tagItems(t1.id()).size(), 1);
        QCOMPARE(data.tagItems(t1.id()).at(0), i1);
        QVERIFY(data.tagItems(t2.id()).isEmpty());

        QCOMPARE(data.items().toList().toSet(), itemSet);

        QVERIFY(data.item(i1.id()).isValid());
        QVERIFY(data.item(i2.id()).isValid());
        QVERIFY(!data.item(i2.id()).tags().contains(t2));

        QCOMPARE(tagSpy.size(), 1);
        QCOMPARE(tagSpy.takeFirst().at(0).value<Akonadi::Tag>(), t2);

        QCOMPARE(itemSpy.size(), 1);
        QCOMPARE(itemSpy.first().at(0).value<Akonadi::Item>(), i2);
        QVERIFY(!itemSpy.first().at(0).value<Akonadi::Item>().tags().contains(t2));
    }
示例#12
0
    void run() {
        string ns = "unittests.rollback_set_index_head";
        const ServiceContext::UniqueOperationContext opCtxPtr = cc().makeOperationContext();
        OperationContext& opCtx = *opCtxPtr;
        NamespaceString nss(ns);
        dropDatabase(&opCtx, nss);
        createCollection(&opCtx, nss);

        AutoGetDb autoDb(&opCtx, nss.db(), MODE_X);

        Collection* coll = autoDb.getDb()->getCollection(&opCtx, nss);
        IndexCatalog* catalog = coll->getIndexCatalog();

        string idxName = "a";
        BSONObj spec = BSON("ns" << ns << "key" << BSON("a" << 1) << "name" << idxName << "v"
                                 << static_cast<int>(kIndexVersion));

        {
            WriteUnitOfWork uow(&opCtx);
            ASSERT_OK(catalog->createIndexOnEmptyCollection(&opCtx, spec));
            uow.commit();
        }

        IndexDescriptor* indexDesc = catalog->findIndexByName(&opCtx, idxName);
        invariant(indexDesc);
        const IndexCatalogEntry* ice = catalog->getEntry(indexDesc);
        invariant(ice);
        HeadManager* headManager = ice->headManager();

        const RecordId oldHead = headManager->getHead(&opCtx);
        ASSERT_EQ(oldHead, ice->head(&opCtx));

        const RecordId dummyHead(123, 456);
        ASSERT_NE(oldHead, dummyHead);

        // END SETUP / START TEST

        {
            WriteUnitOfWork uow(&opCtx);

            headManager->setHead(&opCtx, dummyHead);

            ASSERT_EQ(ice->head(&opCtx), dummyHead);
            ASSERT_EQ(headManager->getHead(&opCtx), dummyHead);

            if (!rollback) {
                uow.commit();
            }
        }

        if (rollback) {
            ASSERT_EQ(ice->head(&opCtx), oldHead);
            ASSERT_EQ(headManager->getHead(&opCtx), oldHead);
        } else {
            ASSERT_EQ(ice->head(&opCtx), dummyHead);
            ASSERT_EQ(headManager->getHead(&opCtx), dummyHead);
        }
    }
示例#13
0
Status DeferredWriter::_makeCollection(OperationContext* opCtx) {
    BSONObjBuilder builder;
    builder.append("create", _nss.coll());
    builder.appendElements(_collectionOptions.toBSON());
    try {
        return createCollection(opCtx, _nss.db().toString(), builder.obj().getOwned());
    } catch (const DBException& exception) {
        return exception.toStatus();
    }
}
示例#14
0
Status createCollection(OperationContext* opCtx,
                        const std::string& dbName,
                        const BSONObj& cmdObj,
                        const BSONObj& idIndex) {
    return createCollection(opCtx,
                            Command::parseNsCollectionRequired(dbName, cmdObj),
                            cmdObj,
                            idIndex,
                            CollectionOptions::parseForCommand);
}
 RecordStoreV1Base* MMAPV1DatabaseCatalogEntry::_getIndexRecordStore( OperationContext* txn ) {
     NamespaceString nss( name(), "system.indexes" );
     RecordStoreV1Base* rs = _getRecordStore( txn, nss.ns() );
     if ( rs != NULL )
         return rs;
     CollectionOptions options;
     Status status = createCollection( txn, nss.ns(), options, true );
     massertStatusOK( status );
     rs = _getRecordStore( txn, nss.ns() );
     invariant( rs );
     return rs;
 }
/*!
 * This function uses our class's resolver to create a new collection but,
 * instead of loading the collection from a path, we instead load the given
 * serialized collection data.
 *
 * Other than that small detail, this function behaves identically to our
 * newCollection() function. See that function's documentation for more
 * information.
 *
 * \param n The name for the new collection.
 * \param p The path to the collection.
 * \param d The serialized collection data to load.
 */
void CSCollectionTypeResolver::unserializeCollection(const QString &n,
	const QString &p, const QByteArray &d)
{ /* SLOT */

	CSAbstractCollection *c = NULL;

	/*
	bool u = true;
	for(int j = 0; j < count(); ++j)
	{
		if(collectionAt(j)->getName() == name)
		{
			u = false;
			break;
		}
	}
	if(!u) continue;
	*/

	c = createCollection(n, p);

	if(c == NULL)
	{
#pragma message "TODO - Errors need to be handled here by emitting a signal"
		return;
	}

	// Connect the collection to our slots.

	QObject::connect(c, SIGNAL(jobStarted(const QString &, bool)),
		this, SLOT(doJobStarted(const QString &, bool)));
	QObject::connect(c, SIGNAL(progressLimitsUpdated(int, int)),
		this, SLOT(doProgressLimitsUpdated(int, int)));
	QObject::connect(c, SIGNAL(progressUpdated(int)),
		this, SLOT(doProgressUpdated(int)));
	QObject::connect(c, SIGNAL(jobFinished(const QString &)),
		this, SLOT(doJobFinished(const QString &)));

	/*
	 * The collection has been created, but we still need to load its data.
	 * Emit the signal indicating that the collection exists, but set it
	 * disabled (until it has been loaded).
	 */

	c->setEnabled(false);
	Q_EMIT(collectionCreated(c));

	// Try to load the collection from the path provided.

	c->unserialize(d);

}
示例#17
0
TEST_F(KVStorageEngineTest, RecreateIndexes) {
    repl::setGlobalReplicationCoordinator(
        new repl::ReplicationCoordinatorMock(getGlobalServiceContext(), repl::ReplSettings()));

    auto opCtx = cc().makeOperationContext();

    // Create two indexes for `db.coll1` in the catalog named `foo` and `bar`. Verify the indexes
    // appear as idents in the KVEngine.
    ASSERT_OK(createCollection(opCtx.get(), NamespaceString("db.coll1")).getStatus());
    ASSERT_OK(createIndex(opCtx.get(), NamespaceString("db.coll1"), "foo"));
    ASSERT_OK(createIndex(opCtx.get(), NamespaceString("db.coll1"), "bar"));
    auto kvIdents = getAllKVEngineIdents(opCtx.get());
    ASSERT_EQUALS(2, std::count_if(kvIdents.begin(), kvIdents.end(), [](const std::string& str) {
                      return str.find("index-") == 0;
                  }));

    // Use the `getIndexNameObjs` to find the `foo` index in the IndexCatalog.
    DatabaseCatalogEntry* dbce = _storageEngine->getDatabaseCatalogEntry(opCtx.get(), "db");
    CollectionCatalogEntry* cce = dbce->getCollectionCatalogEntry("db.coll1");
    auto swIndexNameObjs = getIndexNameObjs(
        opCtx.get(), dbce, cce, [](const std::string& indexName) { return indexName == "foo"; });
    ASSERT_OK(swIndexNameObjs.getStatus());
    auto& indexNameObjs = swIndexNameObjs.getValue();
    // There's one index that matched the name `foo`.
    ASSERT_EQUALS(static_cast<const unsigned long>(1), indexNameObjs.first.size());
    // Assert the parallel vectors have matching sizes.
    ASSERT_EQUALS(static_cast<const unsigned long>(1), indexNameObjs.second.size());
    // The index that matched should be named `foo`.
    ASSERT_EQUALS("foo", indexNameObjs.first[0]);
    ASSERT_EQUALS("db.coll1"_sd, indexNameObjs.second[0].getStringField("ns"));
    ASSERT_EQUALS("foo"_sd, indexNameObjs.second[0].getStringField("name"));
    ASSERT_EQUALS(2, indexNameObjs.second[0].getIntField("v"));
    ASSERT_EQUALS(1, indexNameObjs.second[0].getObjectField("key").getIntField("foo"));

    // Drop the `foo` index table. Count one remaining index ident according to the KVEngine.
    ASSERT_OK(dropIndexTable(opCtx.get(), NamespaceString("db.coll1"), "foo"));
    kvIdents = getAllKVEngineIdents(opCtx.get());
    ASSERT_EQUALS(1, std::count_if(kvIdents.begin(), kvIdents.end(), [](const std::string& str) {
                      return str.find("index-") == 0;
                  }));

    AutoGetCollection coll(opCtx.get(), NamespaceString("db.coll1"), LockMode::MODE_X);
    // Find the `foo` index in the catalog. Rebuild it. Count two indexes in the KVEngine.
    ASSERT_OK(rebuildIndexesOnCollection(opCtx.get(), dbce, cce, indexNameObjs));
    ASSERT_TRUE(cce->isIndexReady(opCtx.get(), "foo"));
    kvIdents = getAllKVEngineIdents(opCtx.get());
    ASSERT_EQUALS(2, std::count_if(kvIdents.begin(), kvIdents.end(), [](const std::string& str) {
                      return str.find("index-") == 0;
                  }));
}
示例#18
0
Collection* RollbackTest::_createCollection(OperationContext* opCtx,
                                            const NamespaceString& nss,
                                            const CollectionOptions& options) {
    Lock::DBLock dbLock(opCtx, nss.db(), MODE_X);
    mongo::WriteUnitOfWork wuow(opCtx);
    auto databaseHolder = DatabaseHolder::get(opCtx);
    auto db = databaseHolder->openDb(opCtx, nss.db());
    ASSERT_TRUE(db);
    db->dropCollection(opCtx, nss.ns()).transitional_ignore();
    auto coll = db->createCollection(opCtx, nss.ns(), options);
    ASSERT_TRUE(coll);
    wuow.commit();
    return coll;
}
示例#19
0
    void run() {
        string ns = "unittests.rollback_drop_index";
        const ServiceContext::UniqueOperationContext opCtxPtr = cc().makeOperationContext();
        OperationContext& opCtx = *opCtxPtr;
        NamespaceString nss(ns);
        dropDatabase(&opCtx, nss);
        createCollection(&opCtx, nss);

        AutoGetDb autoDb(&opCtx, nss.db(), MODE_X);

        Collection* coll = autoDb.getDb()->getCollection(&opCtx, nss);
        IndexCatalog* catalog = coll->getIndexCatalog();

        string idxName = "a";
        BSONObj spec = BSON("ns" << ns << "key" << BSON("a" << 1) << "name" << idxName << "v"
                                 << static_cast<int>(kIndexVersion));

        {
            WriteUnitOfWork uow(&opCtx);
            ASSERT_OK(catalog->createIndexOnEmptyCollection(&opCtx, spec));
            insertRecord(&opCtx, nss, BSON("a" << 1));
            insertRecord(&opCtx, nss, BSON("a" << 2));
            insertRecord(&opCtx, nss, BSON("a" << 3));
            uow.commit();
        }
        ASSERT(indexReady(&opCtx, nss, idxName));
        ASSERT_EQ(3u, getNumIndexEntries(&opCtx, nss, idxName));

        // END SETUP / START TEST

        {
            WriteUnitOfWork uow(&opCtx);

            dropIndex(&opCtx, nss, idxName);
            ASSERT(!indexExists(&opCtx, nss, idxName));

            if (!rollback) {
                uow.commit();
            }
        }
        if (rollback) {
            ASSERT(indexExists(&opCtx, nss, idxName));
            ASSERT(indexReady(&opCtx, nss, idxName));
            ASSERT_EQ(3u, getNumIndexEntries(&opCtx, nss, idxName));
        } else {
            ASSERT(!indexExists(&opCtx, nss, idxName));
        }
    }
示例#20
0
    bool DBClientWithCommands::setDbProfilingLevel(const string &dbname, ProfilingLevel level, BSONObj *info ) {
        BSONObj o;
        if ( info == 0 ) info = &o;

        if ( level ) {
            // Create system.profile collection.  If it already exists this does nothing.
            // TODO: move this into the db instead of here so that all
            //       drivers don't have to do this.
            string ns = dbname + ".system.profile";
            createCollection(ns.c_str(), 1024 * 1024, true, 0, info);
        }

        BSONObjBuilder b;
        b.append("profile", (int) level);
        return runCommand(dbname, b.done(), *info);
    }
示例#21
0
    RecordStoreV1Base* MMAP1DatabaseCatalogEntry::_getNamespaceRecordStore( OperationContext* txn,
                                                                            const StringData& whosAsking) {
        NamespaceString nss( _name, "system.namespaces" );
        if ( nss == whosAsking )
            return NULL;
        RecordStoreV1Base* rs = _getRecordStore( txn, nss.ns() );
        if ( rs != NULL )
            return rs;
        CollectionOptions options;
        Status status = createCollection( txn, nss.ns(), options, true );
        massertStatusOK( status );
        rs = _getRecordStore( txn, nss.ns() );
        invariant( rs );
        return rs;

    }
/*!
 * This function provides our class's main functionality - namely, taking an
 * input name and path and creating the appropriate type of collection object
 * to handle it. Note that this function should probably not be run in the
 * event dispatch thread; we load the collection from the path given, which can
 * take a nontrivial amount of time.
 *
 * Also note that we don't do any validity checking on the collection name; it
 * is assumed that the caller did that before calling this function.
 *
 * The returned collection will have this object as a parent, so deleting this
 * object will also delete any collections it created. The new collection will
 * also have the same thread affinity as this object.
 *
 * The new collection, instead of being returned directly, will be given to our
 * caller (and potentially others) via a signal emission once the collection is
 * loaded. This means that this operation can be done in a different thread
 * from our caller.
 *
 * \param n The name for the new collection.
 * \param p The path to the collection.
 * \param s Whether or not to remember the collection for next time.
 */
void CSCollectionTypeResolver::newCollection(const QString &n,
	const QString &p, bool s)
{ /* SLOT */

	CSAbstractCollection *c = NULL;

	// Create our new collection object.

	c = createCollection(n, p);

	// If we didn't create one, its type must be invalid.

	if(c == NULL)
	{
#pragma message "TODO - Errors need to be handled here by emitting a signal"
		return;
	}

	// Set our collection's save property.

	c->setSaveOnExit(s);

	// Connect the collection to our slots.

	QObject::connect(c, SIGNAL(jobStarted(const QString &, bool)),
		this, SLOT(doJobStarted(const QString &, bool)));
	QObject::connect(c, SIGNAL(progressLimitsUpdated(int, int)),
		this, SLOT(doProgressLimitsUpdated(int, int)));
	QObject::connect(c, SIGNAL(progressUpdated(int)),
		this, SLOT(doProgressUpdated(int)));
	QObject::connect(c, SIGNAL(jobFinished(const QString &)),
		this, SLOT(doJobFinished(const QString &)));

	/*
	 * The collection has been created, but we still need to load its data.
	 * Emit the signal indicating that the collection exists, but set it
	 * disabled (until it has been loaded).
	 */

	c->setEnabled(false);
	Q_EMIT(collectionCreated(c));

	// Try to load the collection from the path provided.

	c->loadCollectionFromPath(p);

}
示例#23
0
LibraryCollectionLayer::LibraryCollectionLayer( QWidget* parent ) :
    GestureWidget(parent) , m_page(0)
{
    setupUi(this);

    items.append(collectionItem0);
    items.append(collectionItem1);
    items.append(collectionItem2);
    items.append(collectionItem3);

    connect(collectionItem0,        SIGNAL(tap(int)),           this, SLOT(changeCollection(int)));
    connect(collectionItem1,        SIGNAL(tap(int)),           this, SLOT(changeCollection(int)));
    connect(collectionItem2,        SIGNAL(tap(int)),           this, SLOT(changeCollection(int)));
    connect(collectionItem3,        SIGNAL(tap(int)),           this, SLOT(changeCollection(int)));
    connect(VerticalPagerPopup,     SIGNAL(nextPageReq()),      this, SLOT(showNextPage()));
    connect(VerticalPagerPopup,     SIGNAL(previousPageReq()),  this, SLOT(showPreviousPage()));
    connect(addNewCollection,       SIGNAL(clicked()),          this, SIGNAL(createCollection()));
}
示例#24
0
    void shouldListChildItems()
    {
        // GIVEN
        auto data = Testlib::AkonadiFakeData();
        auto c1 = Akonadi::Collection(42);
        c1.setName(QStringLiteral("42"));
        data.createCollection(c1);

        auto i1 = Akonadi::Item(42);
        i1.setPayloadFromData("42");
        i1.setParentCollection(Akonadi::Collection(42));

        // WHEN
        data.createItem(i1);

        // THEN
        QCOMPARE(data.childItems(c1.id()).size(), 1);
        QCOMPARE(data.childItems(c1.id()).at(0), i1);
    }
示例#25
0
    void shouldListChildCollections()
    {
        // GIVEN
        auto data = Testlib::AkonadiFakeData();
        auto c1 = Akonadi::Collection(42);
        c1.setName(QStringLiteral("42"));
        auto c2 = Akonadi::Collection(43);
        c2.setName(QStringLiteral("43"));
        c2.setParentCollection(Akonadi::Collection(42));
        const auto colSet = QSet<Akonadi::Collection>() << c2;

        // WHEN
        data.createCollection(c1);
        data.createCollection(c2);

        // THEN
        QVERIFY(data.childCollections(c2.id()).isEmpty());
        QCOMPARE(data.childCollections(c1.id()).toList().toSet(), colSet);
    }
示例#26
0
int execInternalCommand(int commandCode, char* collection, char *id, char *value, int isObjt)
{
    //printf("commandCode: %d - value: %s\n", commandCode, value);
    int collectionCreated = 0;
    int addDocument = 0;
    switch(commandCode)
    {
        case CREATE_COLLECTION:
           collectionCreated = createCollection(value);
           (collectionCreated) ? printf("Collection created with successfully!\n") : printf("The collection already exists!\n");
           return 1;
        break;
        case ADD_DOCUMENT_IN_COLLECTION:
           if(isObjt == 1)
           {
               addDocument = addDocumentInCollection(collection, id, value);
               (addDocument) ? printf("Add Document with successfully!\n") : 0;
               return 1;
           }
           else
           {
               printf("the 'value' field does not contain a json object!\n");
               return 0;
           }
        break;
        case FIND:
            if(isObjt == 1)
            {
                find(collection, id, value);
                return 1;
            }
            else
            {
                printf("the 'value' field does not contain a json object!\n");
                return 0;
            }
        break;
    }
    return 0;
}
示例#27
0
Document* CreateValid11() {
	Document* doc = createDocument();
	// collection
	Collection *col = createCollection(doc, "http://example.com/collection1");
	setCollectionDisplayID(col, "Coll1");
	setCollectionName(col, "Collection1");
	setCollectionDescription(col, "A collection may contain multiple components");
	// components
	DNAComponent *dc1 = createDNAComponent(doc, "http://example.com/dc1");
	DNAComponent *dc2 = createDNAComponent(doc, "http://example.com/dc2");
	setDNAComponentDisplayID(dc1, "DC1");
	setDNAComponentDisplayID(dc2, "DC2");
	setDNAComponentName(dc1, "DnaComponent1");
	setDNAComponentName(dc2, "DnaComponent2");
	addDNAComponentToCollection(col, dc1);
	addDNAComponentToCollection(col, dc2);
	// sequence
	DNASequence *ds1 = createDNASequence(doc, "http://example.com/ds1");
	setDNASequenceNucleotides(ds1, "tccctatcagtgat");
	setDNAComponentSequence(dc1, ds1);
	return doc;
}
示例#28
0
TEST_F(KVStorageEngineTest, ReconcileIdentsTest) {
    auto opCtx = cc().makeOperationContext();

    // Add a collection, `db.coll1` to both the KVCatalog and KVEngine. The returned value is the
    // `ident` name given to the collection.
    auto swIdentName = createCollection(opCtx.get(), NamespaceString("db.coll1"));
    ASSERT_OK(swIdentName);
    // Create a table in the KVEngine not reflected in the KVCatalog. This should be dropped when
    // reconciling.
    ASSERT_OK(createCollTable(opCtx.get(), NamespaceString("db.coll2")));
    ASSERT_OK(reconcile(opCtx.get()).getStatus());
    auto identsVec = getAllKVEngineIdents(opCtx.get());
    auto idents = std::set<std::string>(identsVec.begin(), identsVec.end());
    // There are two idents. `_mdb_catalog` and the ident for `db.coll1`.
    ASSERT_EQUALS(static_cast<const unsigned long>(2), idents.size());
    ASSERT_TRUE(idents.find(swIdentName.getValue()) != idents.end());
    ASSERT_TRUE(idents.find("_mdb_catalog") != idents.end());

    // Create a catalog entry for the `_id` index. Drop the created the table.
    ASSERT_OK(createIndex(opCtx.get(), NamespaceString("db.coll1"), "_id"));
    ASSERT_OK(dropIndexTable(opCtx.get(), NamespaceString("db.coll1"), "_id"));
    // The reconcile response should include this index as needing to be rebuilt.
    auto reconcileStatus = reconcile(opCtx.get());
    ASSERT_OK(reconcileStatus.getStatus());
    ASSERT_EQUALS(static_cast<const unsigned long>(1), reconcileStatus.getValue().size());
    StorageEngine::CollectionIndexNamePair& toRebuild = reconcileStatus.getValue()[0];
    ASSERT_EQUALS("db.coll1", toRebuild.first);
    ASSERT_EQUALS("_id", toRebuild.second);

    // Now drop the `db.coll1` table, while leaving the KVCatalog entry.
    ASSERT_OK(dropIdent(opCtx.get(), swIdentName.getValue()));
    ASSERT_EQUALS(static_cast<const unsigned long>(1), getAllKVEngineIdents(opCtx.get()).size());

    // Reconciling this should result in an error.
    reconcileStatus = reconcile(opCtx.get());
    ASSERT_NOT_OK(reconcileStatus.getStatus());
    ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, reconcileStatus.getStatus());
}
示例#29
0
    void shouldModifyCollections()
    {
        // GIVEN
        auto data = Testlib::AkonadiFakeData();
        QScopedPointer<Akonadi::MonitorInterface> monitor(data.createMonitor());
        QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged);

        auto c1 = Akonadi::Collection(42);
        c1.setName(QStringLiteral("42"));
        data.createCollection(c1);

        auto c2 = Akonadi::Collection(c1.id());
        c2.setName(QStringLiteral("42-bis"));

        // WHEN
        data.modifyCollection(c2);

        // THEN
        QCOMPARE(data.collections().size(), 1);
        QCOMPARE(data.collection(c1.id()), c2);

        QCOMPARE(spy.size(), 1);
        QCOMPARE(spy.takeFirst().at(0).value<Akonadi::Collection>(), c2);
    }
示例#30
0
Status createCollectionForApplyOps(OperationContext* opCtx,
                                   const std::string& dbName,
                                   const BSONElement& ui,
                                   const BSONObj& cmdObj,
                                   const BSONObj& idIndex) {
    invariant(opCtx->lockState()->isDbLockedForMode(dbName, MODE_X));
    auto db = dbHolder().get(opCtx, dbName);
    const NamespaceString newCollName(Command::parseNsCollectionRequired(dbName, cmdObj));
    auto newCmd = cmdObj;

    // If a UUID is given, see if we need to rename a collection out of the way, and whether the
    // collection already exists under a different name. If so, rename it into place. As this is
    // done during replay of the oplog, the operations do not need to be atomic, just idempotent.
    // We need to do the renaming part in a separate transaction, as we cannot transactionally
    // create a database on MMAPv1, which could result in createCollection failing if the database
    // does not yet exist.
    if (ui.ok()) {
        // Return an optional, indicating whether we need to early return (if the collection already
        // exists, or in case of an error).
        using Result = boost::optional<Status>;
        auto result =
            writeConflictRetry(opCtx, "createCollectionForApplyOps", newCollName.ns(), [&] {
                WriteUnitOfWork wunit(opCtx);
                // Options need the field to be named "uuid", so parse/recreate.
                auto uuid = uassertStatusOK(UUID::parse(ui));
                uassert(ErrorCodes::InvalidUUID,
                        "Invalid UUID in applyOps create command: " + uuid.toString(),
                        uuid.isRFC4122v4());

                auto& catalog = UUIDCatalog::get(opCtx);
                auto currentName = catalog.lookupNSSByUUID(uuid);
                OpObserver* opObserver = getGlobalServiceContext()->getOpObserver();
                if (currentName == newCollName)
                    return Result(Status::OK());

                // In the case of oplog replay, a future command may have created or renamed a
                // collection with that same name. In that case, renaming this future collection to
                // a random temporary name is correct: once all entries are replayed no temporary
                // names will remain.  On MMAPv1 the rename can result in index names that are too
                // long. However this should only happen for initial sync and "resync collection"
                // for rollback, so we can let the error propagate resulting in an abort and restart
                // of the initial sync or result in rollback to fassert, requiring a resync of that
                // node.
                const bool stayTemp = true;
                if (auto futureColl = db ? db->getCollection(opCtx, newCollName) : nullptr) {
                    auto tmpNameResult = db->makeUniqueCollectionNamespace(opCtx, "tmp%%%%%");
                    if (!tmpNameResult.isOK()) {
                        return Result(Status(tmpNameResult.getStatus().code(),
                                             str::stream() << "Cannot generate temporary "
                                                              "collection namespace for applyOps "
                                                              "create command: collection: "
                                                           << newCollName.ns()
                                                           << ". error: "
                                                           << tmpNameResult.getStatus().reason()));
                    }
                    const auto& tmpName = tmpNameResult.getValue();
                    Status status =
                        db->renameCollection(opCtx, newCollName.ns(), tmpName.ns(), stayTemp);
                    if (!status.isOK())
                        return Result(status);
                    opObserver->onRenameCollection(opCtx,
                                                   newCollName,
                                                   tmpName,
                                                   futureColl->uuid(),
                                                   /*dropTarget*/ false,
                                                   /*dropTargetUUID*/ {},
                                                   stayTemp);
                }

                // If the collection with the requested UUID already exists, but with a different
                // name, just rename it to 'newCollName'.
                if (catalog.lookupCollectionByUUID(uuid)) {
                    Status status =
                        db->renameCollection(opCtx, currentName.ns(), newCollName.ns(), stayTemp);
                    if (!status.isOK())
                        return Result(status);
                    opObserver->onRenameCollection(opCtx,
                                                   currentName,
                                                   newCollName,
                                                   uuid,
                                                   /*dropTarget*/ false,
                                                   /*dropTargetUUID*/ {},
                                                   stayTemp);

                    wunit.commit();
                    return Result(Status::OK());
                }

                // A new collection with the specific UUID must be created, so add the UUID to the
                // creation options. Regular user collection creation commands cannot do this.
                auto uuidObj = uuid.toBSON();
                newCmd = cmdObj.addField(uuidObj.firstElement());
                wunit.commit();

                return Result(boost::none);
            });

        if (result) {
            return *result;
        }
    }

    return createCollection(
        opCtx, newCollName, newCmd, idIndex, CollectionOptions::parseForStorage);
}