bool indexInsert(size_t indexId, fstring key, llong recId) override {
		assert(started == m_status);
		assert(indexId < m_indices.size());
		WT_ITEM item;
		WT_SESSION* ses = m_session.ses;
		const Schema& schema = m_sconf.getIndexSchema(indexId);
		WT_CURSOR* cur = m_indices[indexId].insert;
		WtWritableIndex::setKeyVal(schema, cur, key, recId, &item, &m_wrtBuf);
		int err = cur->insert(cur);
		m_sizeDiff += sizeof(llong) + key.size();
		if (schema.m_isUnique) {
			if (WT_DUPLICATE_KEY == err) {
				return false;
			}
			if (err) {
				THROW_STD(invalid_argument
					, "ERROR: wiredtiger insert unique index: %s", ses->strerror(ses, err));
			}
		}
		else {
			if (WT_DUPLICATE_KEY == err) {
				assert(0); // assert in debug
				return true; // ignore in release
			}
			if (err) {
				THROW_STD(invalid_argument
					, "ERROR: wiredtiger insert multi index: %s", ses->strerror(ses, err));
			}
		}
		return true;
	}
示例#2
0
/*! [thread scan] */
void *
scan_thread(void *conn_arg)
{
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_SESSION *session;
	const char *key, *value;
	int ret;

	conn = conn_arg;
	ret = conn->open_session(conn, NULL, NULL, &session);
	ret = session->open_cursor(
	    session, "table:access", NULL, NULL, &cursor);

	/* Show all records. */
	while ((ret = cursor->next(cursor)) == 0) {
		ret = cursor->get_key(cursor, &key);
		ret = cursor->get_value(cursor, &value);

		printf("Got record: %s : %s\n", key, value);
	}
	if (ret != WT_NOTFOUND)
		fprintf(stderr,
		    "WT_CURSOR.next: %s\n", session->strerror(session, ret));

	return (NULL);
}
	explicit WtDbTransaction(WtWritableSegment* seg)
		: m_seg(seg), m_sconf(*seg->m_schema)
	{
		WT_CONNECTION* conn = seg->m_wtConn;
		int err = conn->open_session(conn, NULL, NULL, &m_session.ses);
		if (err) {
			THROW_STD(invalid_argument
				, "FATAL: wiredtiger open session(dir=%s) = %s"
				, conn->get_home(conn), wiredtiger_strerror(err)
				);
		}
		WT_SESSION* ses = m_session.ses;
		err = ses->open_cursor(ses, g_dataStoreUri, NULL, "overwrite=true", &m_store.cursor);
		if (err) {
			THROW_STD(invalid_argument
				, "ERROR: wiredtiger store open cursor: %s"
				, ses->strerror(ses, err));
		}
		m_indices.resize(seg->m_indices.size());
		for (size_t indexId = 0; indexId < m_indices.size(); ++indexId) {
			ReadableIndex* index = seg->m_indices[indexId].get();
			WtWritableIndex* wtIndex = dynamic_cast<WtWritableIndex*>(index);
			assert(NULL != wtIndex);
			const char* uri = wtIndex->getIndexUri().c_str();
			err = ses->open_cursor(ses, uri, NULL, "overwrite=false", &m_indices[indexId].insert.cursor);
			if (err) {
				THROW_STD(invalid_argument
					, "ERROR: wiredtiger open index cursor: %s"
					, ses->strerror(ses, err));
			}
			err = ses->open_cursor(ses, uri, NULL, "overwrite=true", &m_indices[indexId].overwrite.cursor);
			if (err) {
				THROW_STD(invalid_argument
					, "ERROR: wiredtiger open index cursor: %s"
					, ses->strerror(ses, err));
			}
		}
		m_sizeDiff = 0;
		m_wrtStore = dynamic_cast<WtWritableStore*>(seg->m_wrtStore.get());
		assert(nullptr != m_store);
		g_wtDbTxnLiveCnt++;
		g_wtDbTxnCreatedCnt++;
		if (getEnvBool("TerarkDB_TrackBuggyObjectLife")) {
			fprintf(stderr, "DEBUG: WtDbTransaction live count = %zd, created = %zd\n"
				, g_wtDbTxnLiveCnt.load(), g_wtDbTxnCreatedCnt.load());
		}
	}
	void do_rollback() override {
		resetCursors();
#if TERARK_WT_USE_TXN
		WT_SESSION* ses = m_session.ses;
		int err = ses->rollback_transaction(ses, NULL);
		if (err) {
			THROW_STD(invalid_argument
				, "ERROR: wiredtiger rollback_transaction: %s"
				, ses->strerror(ses, err));
		}
#endif
	}
	bool do_commit() override {
		resetCursors();
#if TERARK_WT_USE_TXN
		WT_SESSION* ses = m_session.ses;
		int err = ses->commit_transaction(ses, NULL);
		if (err) {
			m_strError = "wiredtiger commit_transaction: ";
			m_strError += ses->strerror(ses, err);
			assert(!"wiredtiger commit_transaction failed");
			return false;
		}
#endif
		m_wrtStore->estimateIncDataSize(m_sizeDiff);
		return true;
	}
	void do_startTransaction() override {
#if TERARK_WT_USE_TXN
		WT_SESSION* ses = m_session.ses;
		const char* txnConfig = getenv("TerarkDB_WiredtigerTransactionConfig");
		if (NULL == txnConfig) {
		// wiredtiger 2.8.0 is not binary compatible with 2.7.0
			txnConfig = "isolation=read-committed,sync=false";
		}
	//	fprintf(stderr, "INFO: %s: txnConfig=%s\n", BOOST_CURRENT_FUNCTION, txnConfig);
		int err = ses->begin_transaction(ses, txnConfig);
		if (err) {
			THROW_STD(invalid_argument
				, "ERROR: wiredtiger begin_transaction: %s"
				, ses->strerror(ses, err));
		}
#endif
		m_sizeDiff = 0;
	}
	void indexSearch(size_t indexId, fstring key, valvec<llong>* recIdvec) override {
		assert(started == m_status);
		assert(indexId < m_indices.size());
		WT_ITEM item;
		WT_SESSION* ses = m_session.ses;
		const Schema& schema = m_sconf.getIndexSchema(indexId);
		WT_CURSOR* cur = m_indices[indexId].insert;
		WtWritableIndex::setKeyVal(schema, cur, key, 0, &item, &m_wrtBuf);
		recIdvec->erase_all();
		if (schema.m_isUnique) {
			int err = cur->search(cur);
			BOOST_SCOPE_EXIT(cur) { cur->reset(cur); } BOOST_SCOPE_EXIT_END;
			if (WT_NOTFOUND == err) {
				return;
			}
			if (err) {
				THROW_STD(invalid_argument
					, "ERROR: wiredtiger search: %s", ses->strerror(ses, err));
			}
			llong recId = 0;
			cur->get_value(cur, &recId);
			recIdvec->push_back(recId);
		}
示例#8
0
static int
cursor_scope_ops(WT_CURSOR *cursor)
{
	struct {
		const char *key;
		const char *value;
		int (*apply)(WT_CURSOR *);
	} *op, ops[] = {
		{ "key1", "value1", cursor->insert, },
		{ "key1", "value2", cursor->update, },
		{ "key1", "value2", cursor->search, },
		{ "key1", "value2", cursor->remove, },
		{ NULL, NULL, NULL }
	};
	WT_SESSION *session;
	const char *key, *value;
	char keybuf[10], valuebuf[10];
	int ret;

	session = cursor->session;

	for (op = ops; op->key != NULL; op++) {
		key = value = NULL;

		/*! [cursor scope operation] */
		(void)snprintf(keybuf, sizeof(keybuf), "%s", op->key);
		cursor->set_key(cursor, keybuf);
		(void)snprintf(valuebuf, sizeof(valuebuf), "%s", op->value);
		cursor->set_value(cursor, valuebuf);

		/*
		 * The application must keep the key and value memory valid
		 * until the next operation that positions the cursor.
		 * Modifying either the key or value buffers is not permitted.
		 */

		/* Apply the operation (insert, update, search or remove). */
		if ((ret = op->apply(cursor)) != 0) {
			fprintf(stderr, "Error performing the operation: %s\n",
			    session->strerror(session, ret));
			return (ret);
		}

		/*
		 * Except for WT_CURSOR::insert, the cursor has been positioned
		 * and no longer references application memory, so application
		 * buffers can be safely overwritten.
		 */
		if (op->apply != cursor->insert) {
			strcpy(keybuf, "no key");
			strcpy(valuebuf, "no value");
		}

		/*
		 * Check that get_key/value behave as expected after the
		 * operation.
		 */
		if ((ret = cursor->get_key(cursor, &key)) != 0 ||
		    (op->apply != cursor->remove &&
		    (ret = cursor->get_value(cursor, &value)) != 0)) {
			fprintf(stderr, "Error in get_key/value: %s\n",
			     session->strerror(session, ret));
			return (ret);
		}

		/*
		 * Except for WT_CURSOR::insert (which does not position the
		 * cursor), the application now has pointers to memory owned
		 * by the cursor.  Modifying the memory referenced by either
		 * key or value is not permitted.
		 */

		/* Check that the cursor's key and value are what we expect. */
		if (op->apply != cursor->insert)
			if (key == keybuf ||
			    (op->apply != cursor->remove &&
			    value == valuebuf)) {
				fprintf(stderr,
				    "Cursor points at application memory!\n");
				return (EINVAL);
			}

		if (strcmp(key, op->key) != 0 ||
		    (op->apply != cursor->remove &&
		    strcmp(value, op->value) != 0)) {
			fprintf(stderr, "Unexpected key / value!\n");
			return (EINVAL);
		}
		/*! [cursor scope operation] */
	}

	return (0);
}