Example #1
0
/*
 * __wt_open_cursor --
 *	Internal version of WT_SESSION::open_cursor.
 */
int
__wt_open_cursor(WT_SESSION_IMPL *session,
    const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp)
{
	WT_COLGROUP *colgroup;
	WT_DATA_SOURCE *dsrc;
	WT_DECL_RET;

	if (WT_PREFIX_MATCH(uri, "backup:"))
		ret = __wt_curbackup_open(session, uri, cfg, cursorp);
	else if (WT_PREFIX_MATCH(uri, "colgroup:")) {
		/*
		 * Column groups are a special case: open a cursor on the
		 * underlying data source.
		 */
		WT_RET(__wt_schema_get_colgroup(session, uri, NULL, &colgroup));
		ret = __wt_open_cursor(
		    session, colgroup->source, owner, cfg, cursorp);
	} else if (WT_PREFIX_MATCH(uri, "config:"))
		ret = __wt_curconfig_open(session, uri, cfg, cursorp);
	else if (WT_PREFIX_MATCH(uri, "file:"))
		ret = __wt_curfile_open(session, uri, owner, cfg, cursorp);
	else if (WT_PREFIX_MATCH(uri, "index:"))
		ret = __wt_curindex_open(session, uri, cfg, cursorp);
	else if (WT_PREFIX_MATCH(uri, "statistics:"))
		ret = __wt_curstat_open(session, uri, cfg, cursorp);
	else if (WT_PREFIX_MATCH(uri, "table:"))
		ret = __wt_curtable_open(session, uri, cfg, cursorp);
	else if ((ret = __wt_schema_get_source(session, uri, &dsrc)) == 0)
		ret = dsrc->open_cursor(dsrc, &session->iface,
		    uri, owner, cfg, cursorp);

	return (ret);
}
Example #2
0
/*
 * __drop_colgroup --
 *	WT_SESSION::drop for a colgroup.
 */
static int
__drop_colgroup(
    WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
{
	WT_COLGROUP *colgroup;
	WT_DECL_RET;
	WT_TABLE *table;

	/* If we can get the colgroup, detach it from the table. */
	if ((ret = __wt_schema_get_colgroup(
	    session, uri, &table, &colgroup)) == 0) {
		table->cg_complete = 0;
		WT_TRET(__wt_schema_drop(session, colgroup->source, cfg));
	}

	WT_TRET(__wt_metadata_remove(session, uri));
	return (ret);
}
Example #3
0
/*
 * __drop_colgroup --
 *	WT_SESSION::drop for a colgroup.
 */
static int
__drop_colgroup(
    WT_SESSION_IMPL *session, const char *uri, bool force, const char *cfg[])
{
	WT_COLGROUP *colgroup;
	WT_DECL_RET;
	WT_TABLE *table;

	WT_ASSERT(session, F_ISSET(session, WT_SESSION_LOCKED_TABLE_WRITE));

	/* If we can get the colgroup, detach it from the table. */
	if ((ret = __wt_schema_get_colgroup(
	    session, uri, force, &table, &colgroup)) == 0) {
		WT_TRET(__wt_schema_drop(session, colgroup->source, cfg));
		if (ret == 0)
			table->cg_complete = false;
	}

	WT_TRET(__wt_metadata_remove(session, uri));
	return (ret);
}
Example #4
0
/*
 * __wt_schema_worker --
 *	Get Btree handles for the object and cycle through calls to an
 *	underlying worker function with each handle.
 */
int
__wt_schema_worker(WT_SESSION_IMPL *session,
   const char *uri,
   int (*file_func)(WT_SESSION_IMPL *, const char *[]),
   int (*name_func)(WT_SESSION_IMPL *, const char *, bool *),
   const char *cfg[], uint32_t open_flags)
{
	WT_COLGROUP *colgroup;
	WT_DATA_SOURCE *dsrc;
	WT_DECL_RET;
	WT_INDEX *idx;
	WT_SESSION *wt_session;
	WT_TABLE *table;
	u_int i;
	bool skip;

	table = NULL;

	skip = false;
	if (name_func != NULL)
		WT_ERR(name_func(session, uri, &skip));

	/* If the callback said to skip this object, we're done. */
	if (skip)
		return (0);

	/* Get the btree handle(s) and call the underlying function. */
	if (WT_PREFIX_MATCH(uri, "file:")) {
		if (file_func != NULL)
			WT_ERR(__wt_exclusive_handle_operation(session,
			    uri, file_func, cfg, open_flags));
	} else if (WT_PREFIX_MATCH(uri, "colgroup:")) {
		WT_ERR(__wt_schema_get_colgroup(
		    session, uri, false, NULL, &colgroup));
		WT_ERR(__wt_schema_worker(session,
		    colgroup->source, file_func, name_func, cfg, open_flags));
	} else if (WT_PREFIX_MATCH(uri, "index:")) {
		idx = NULL;
		WT_ERR(__wt_schema_get_index(session, uri, false, false, &idx));
		WT_ERR(__wt_schema_worker(session, idx->source,
		    file_func, name_func, cfg, open_flags));
	} else if (WT_PREFIX_MATCH(uri, "lsm:")) {
		WT_ERR(__wt_lsm_tree_worker(session,
		    uri, file_func, name_func, cfg, open_flags));
	} else if (WT_PREFIX_MATCH(uri, "table:")) {
		/*
		 * Note: we would like to use open_flags here (e.g., to lock
		 * the table exclusive during schema-changing operations), but
		 * that is currently problematic because we get the table again
		 * in order to discover column groups and indexes.
		 */
		WT_ERR(__wt_schema_get_table_uri(
		    session, uri, false, 0, &table));

		/*
		 * We could make a recursive call for each colgroup or index
		 * URI, but since we have already opened the table, we can take
		 * a short cut and skip straight to the sources.  If we have a
		 * name function, it needs to know about the intermediate URIs.
		 */
		for (i = 0; i < WT_COLGROUPS(table); i++) {
			colgroup = table->cgroups[i];
			skip = false;
			if (name_func != NULL)
				WT_ERR(name_func(
				    session, colgroup->name, &skip));
			if (!skip)
				WT_ERR(__wt_schema_worker(
				    session, colgroup->source,
				    file_func, name_func, cfg, open_flags));
		}

		WT_ERR(__wt_schema_open_indices(session, table));
		for (i = 0; i < table->nindices; i++) {
			idx = table->indices[i];
			skip = false;
			if (name_func != NULL)
				WT_ERR(name_func(session, idx->name, &skip));
			if (!skip)
				WT_ERR(__wt_schema_worker(session, idx->source,
				    file_func, name_func, cfg, open_flags));
		}
	} else if ((dsrc = __wt_schema_get_source(session, uri)) != NULL) {
		wt_session = (WT_SESSION *)session;
		if (file_func == __wt_salvage && dsrc->salvage != NULL)
			WT_ERR(dsrc->salvage(
			    dsrc, wt_session, uri, (WT_CONFIG_ARG *)cfg));
		else if (file_func == __wt_verify && dsrc->verify != NULL)
			WT_ERR(dsrc->verify(
			    dsrc, wt_session, uri, (WT_CONFIG_ARG *)cfg));
		else if (file_func == __wt_checkpoint)
			;
		else if (file_func == __wt_checkpoint_get_handles)
			;
		else if (file_func == __wt_checkpoint_sync)
			;
		else
			WT_ERR(__wt_object_unsupported(session, uri));
	} else
		WT_ERR(__wt_bad_object_type(session, uri));

err:	if (table != NULL)
		WT_TRET(__wt_schema_release_table(session, table));
	return (ret);
}
Example #5
0
/*
 * __wt_schema_worker --
 *	Get Btree handles for the object and cycle through calls to an
 * underlying worker function with each handle.
 */
int
__wt_schema_worker(WT_SESSION_IMPL *session,
   const char *uri,
   int (*file_func)(WT_SESSION_IMPL *, const char *[]),
   int (*name_func)(WT_SESSION_IMPL *, const char *),
   const char *cfg[], uint32_t open_flags)
{
	WT_COLGROUP *colgroup;
	WT_DATA_SOURCE *dsrc;
	WT_DECL_RET;
	WT_INDEX *idx;
	WT_SESSION *wt_session;
	WT_TABLE *table;
	const char *tablename;
	u_int i;

	table = NULL;
	tablename = uri;

	if (name_func != NULL)
		WT_ERR(name_func(session, uri));

	/* Get the btree handle(s) and call the underlying function. */
	if (WT_PREFIX_MATCH(uri, "file:")) {
		if (file_func != NULL) {
			WT_ERR(__wt_session_get_btree_ckpt(
			    session, uri, cfg, open_flags));
			ret = file_func(session, cfg);
			WT_TRET(__wt_session_release_btree(session));
		}
	} else if (WT_PREFIX_MATCH(uri, "colgroup:")) {
		WT_ERR(__wt_schema_get_colgroup(session, uri, NULL, &colgroup));
		WT_ERR(__wt_schema_worker(session, colgroup->source,
		    file_func, name_func, cfg, open_flags));
	} else if (WT_PREFIX_SKIP(tablename, "index:")) {
		idx = NULL;
		WT_ERR(__wt_schema_get_index(session, uri, NULL, &idx));
		WT_ERR(__wt_schema_worker(session, idx->source,
		    file_func, name_func, cfg, open_flags));
	} else if (WT_PREFIX_MATCH(uri, "lsm:")) {
		WT_ERR(__wt_lsm_tree_worker(
		    session, uri, file_func, name_func, cfg, open_flags));
	} else if (WT_PREFIX_SKIP(tablename, "table:")) {
		WT_ERR(__wt_schema_get_table(session,
		    tablename, strlen(tablename), 0, &table));
		WT_ASSERT(session, session->dhandle == NULL);

		/*
		 * We could make a recursive call for each colgroup or index
		 * URI, but since we have already opened the table, we can take
		 * a short cut and skip straight to the sources.  If we have a
		 * name function, it needs to know about the intermediate URIs.
		 */
		for (i = 0; i < WT_COLGROUPS(table); i++) {
			colgroup = table->cgroups[i];
			if (name_func != NULL)
				WT_ERR(name_func(session, colgroup->name));
			WT_ERR(__wt_schema_worker(session, colgroup->source,
			    file_func, name_func, cfg, open_flags));
		}

		WT_ERR(__wt_schema_open_indices(session, table));
		for (i = 0; i < table->nindices; i++) {
			idx = table->indices[i];
			if (name_func != NULL)
				WT_ERR(name_func(session, idx->name));
			WT_ERR(__wt_schema_worker(session, idx->source,
			    file_func, name_func, cfg, open_flags));
		}
	} else if ((dsrc = __wt_schema_get_source(session, uri)) != NULL) {
		wt_session = (WT_SESSION *)session;
		if (file_func == __wt_compact && dsrc->compact != NULL)
			WT_ERR(dsrc->compact(
			    dsrc, wt_session, uri, (WT_CONFIG_ARG *)cfg));
		else if (file_func == __wt_salvage && dsrc->salvage != NULL)
			WT_ERR(dsrc->salvage(
			   dsrc, wt_session, uri, (WT_CONFIG_ARG *)cfg));
		else if (file_func == __wt_verify && dsrc->verify != NULL)
			WT_ERR(dsrc->verify(
			   dsrc, wt_session, uri, (WT_CONFIG_ARG *)cfg));
		else
			WT_ERR(__wt_object_unsupported(session, uri));
	} else
		WT_ERR(__wt_bad_object_type(session, uri));

err:	if (table != NULL)
		__wt_schema_release_table(session, table);
	return (ret);
}