Example #1
0
/*
 * dump_record --
 *	Dump a single record, advance cursor to next/prev, along
 *	with JSON formatting if needed.
 */
static int
dump_record(WT_CURSOR *cursor, const char *name, int reverse, int json)
{
	WT_DECL_RET;
	const char *infix, *key, *prefix, *suffix, *value;
	int once;

	once = 0;
	if (json) {
		prefix = "\n{\n";
		infix = ",\n";
		suffix = "\n}";
	} else {
		prefix = "";
		infix = "\n";
		suffix = "\n";
	}
	while ((ret =
	    (reverse ? cursor->prev(cursor) : cursor->next(cursor))) == 0) {
		if ((ret = cursor->get_key(cursor, &key)) != 0)
			return (util_cerr(name, "get_key", ret));
		if ((ret = cursor->get_value(cursor, &value)) != 0)
			return (util_cerr(name, "get_value", ret));
		if (printf("%s%s%s%s%s%s", (json && once) ? "," : "",
		    prefix, key, infix, value, suffix) < 0)
			return (util_err(EIO, NULL));
		once = 1;
	}
	if (json && once && printf("\n") < 0)
		return (util_err(EIO, NULL));
	return (ret == WT_NOTFOUND ? 0 :
	    util_cerr(name, (reverse ? "prev" : "next"), ret));
}
Example #2
0
/*
 * dump_table_config --
 *	Dump the config for a table.
 */
static int
dump_table_config(WT_SESSION *session, WT_CURSOR *cursor, const char *uri)
{
	WT_CURSOR *srch;
	WT_DECL_RET;
	int tret;
	const char *key, *name, *value;

	/* Get the table name. */
	if ((name = strchr(uri, ':')) == NULL) {
		fprintf(stderr, "%s: %s: corrupted uri\n", progname, uri);
		return (1);
	}
	++name;

	/*
	 * Dump out the config information: first, dump the uri entry itself
	 * (requires a lookup).
	 */
	cursor->set_key(cursor, uri);
	if ((ret = cursor->search(cursor)) != 0)
		return (util_cerr(cursor, "search", ret));
	if ((ret = cursor->get_key(cursor, &key)) != 0)
		return (util_cerr(cursor, "get_key", ret));
	if ((ret = cursor->get_value(cursor, &value)) != 0)
		return (util_cerr(cursor, "get_value", ret));
	if (print_config(session, key, value, NULL) != 0)
		return (1);

	/*
	 * The underlying table configuration function needs a second cursor:
	 * open one before calling it, it makes error handling hugely simpler.
	 */
	if ((ret =
	    session->open_cursor(session, NULL, cursor, NULL, &srch)) != 0)
		return (util_cerr(cursor, "open_cursor", ret));

	if ((ret = dump_table_config_type(
	    session, cursor, srch, name, "colgroup:")) == 0)
		ret = dump_table_config_type(
		    session, cursor, srch, name, "index:");

	if ((tret = srch->close(srch)) != 0) {
		tret = util_cerr(cursor, "close", tret);
		if (ret == 0)
			ret = tret;
	}

	return (ret);
}
Example #3
0
static inline int
dump_reverse(WT_CURSOR *cursor, const char *name)
{
	WT_DECL_RET;
	const char *key, *value;

	while ((ret = cursor->prev(cursor)) == 0) {
		if ((ret = cursor->get_key(cursor, &key)) != 0)
			return (util_cerr(name, "get_key", ret));
		if ((ret = cursor->get_value(cursor, &value)) != 0)
			return (util_cerr(name, "get_value", ret));
		if (printf("%s\n%s\n", key, value) < 0)
			return (util_err(EIO, NULL));
	}
	return (ret == WT_NOTFOUND ? 0 : util_cerr(name, "prev", ret));
}
Example #4
0
/*
 * dump_json_table_config --
 *	Dump the config for the uri.
 */
static int
dump_json_table_config(WT_SESSION *session, const char *uri)
{
	WT_CURSOR *cursor;
	WT_DECL_RET;
	int tret;
	char *value;

	/* Dump the config. */
	/* Open a metadata cursor. */
	if ((ret = session->open_cursor(
	    session, "metadata:create", NULL, NULL, &cursor)) != 0) {
		fprintf(stderr, "%s: %s: session.open_cursor: %s\n",
		    progname, "metadata:create",
		    session->strerror(session, ret));
		return (1);
	}

	/*
	 * Search for the object itself, to make sure it
	 * exists, and get its config string. This where we
	 * find out a table object doesn't exist, use a simple
	 * error message.
	 */
	cursor->set_key(cursor, uri);
	if ((ret = cursor->search(cursor)) == 0) {
		if ((ret = cursor->get_value(cursor, &value)) != 0)
			ret = util_cerr(cursor, "get_value", ret);
		else if (dump_json_table_begin(
		    session, cursor, uri, value) != 0)
			ret = 1;
	} else if (ret == WT_NOTFOUND)
		ret = util_err(
		    session, 0, "%s: No such object exists", uri);
	else
		ret = util_err(session, ret, "%s", uri);

	if ((tret = cursor->close(cursor)) != 0) {
		tret = util_cerr(cursor, "close", tret);
		if (ret == 0)
			ret = tret;
	}

	return (ret);
}
Example #5
0
/*
 * dump_record --
 *	Dump a single record, advance cursor to next/prev, along
 *	with JSON formatting if needed.
 */
static int
dump_record(WT_CURSOR *cursor, bool reverse, bool json)
{
	WT_DECL_RET;
	WT_SESSION *session;
	const char *infix, *key, *prefix, *suffix, *value;
	bool once;

	session = cursor->session;

	once = false;
	if (json) {
		prefix = "\n{\n";
		infix = ",\n";
		suffix = "\n}";
	} else {
		prefix = "";
		infix = "\n";
		suffix = "\n";
	}
	while ((ret =
	    (reverse ? cursor->prev(cursor) : cursor->next(cursor))) == 0) {
		if ((ret = cursor->get_key(cursor, &key)) != 0)
			return (util_cerr(cursor, "get_key", ret));
		if ((ret = cursor->get_value(cursor, &value)) != 0)
			return (util_cerr(cursor, "get_value", ret));
		if (printf("%s%s%s%s%s%s", json && once ? "," : "",
		    prefix, key, infix, value, suffix) < 0)
			return (util_err(session, EIO, NULL));
		once = true;
	}
	if (json && once && printf("\n") < 0)
		return (util_err(session, EIO, NULL));
	return (ret == WT_NOTFOUND ? 0 :
	    util_cerr(cursor, (reverse ? "prev" : "next"), ret));
}
Example #6
0
/*
 * dump_json_table_begin --
 *	Output the JSON syntax that starts a table, along with its config.
 */
static int
dump_json_table_begin(
    WT_SESSION *session, WT_CURSOR *cursor, const char *uri, const char *config)
{
	WT_DECL_RET;
	const char *name;
	char *jsonconfig, *stripped;

	jsonconfig = NULL;

	/* Get the table name. */
	if ((name = strchr(uri, ':')) == NULL) {
		fprintf(stderr, "%s: %s: corrupted uri\n", progname, uri);
		return (1);
	}
	++name;

	if ((ret = 
	    __wt_session_create_strip(session, config, NULL, &stripped)) != 0)
		return (util_err(ret, NULL));
	ret = dup_json_string(stripped, &jsonconfig);
	free(stripped);
	if (ret != 0)
		return (util_cerr(uri, "config dup", ret));
	if (printf("    \"%s\" : [\n        {\n", uri) < 0)
		goto eio;
	if (printf("            \"config\" : \"%s\",\n", jsonconfig) < 0)
		goto eio;

	if ((ret = dump_json_table_cg(
	    session, cursor, uri, name, "colgroup:", "colgroups")) == 0) {
		if (printf(",\n") < 0)
			goto eio;
		ret = dump_json_table_cg(
		    session, cursor, uri, name, "index:", "indices");
	}

	if (printf("\n        },\n        {\n            \"data\" : [") < 0)
		goto eio;

	if (0) {
eio:		ret = util_err(EIO, NULL);
	}

	free(jsonconfig);
	return (ret);
}
Example #7
0
/*
 * dump_config --
 *	Dump the config for the uri.
 */
static int
dump_config(WT_SESSION *session, const char *uri, WT_CURSOR *cursor, bool hex,
    bool json)
{
	WT_CURSOR *mcursor;
	WT_DECL_RET;
	int tret;

	/* Open a metadata cursor. */
	if ((ret = session->open_cursor(
	    session, "metadata:create", NULL, NULL, &mcursor)) != 0) {
		fprintf(stderr, "%s: %s: session.open_cursor: %s\n", progname,
		    "metadata:create", session->strerror(session, ret));
		return (1);
	}
	/*
	 * Search for the object itself, just to make sure it exists, we don't
	 * want to output a header if the user entered the wrong name. This is
	 * where we find out a table doesn't exist, use a simple error message.
	 */
	mcursor->set_key(mcursor, uri);
	if ((ret = mcursor->search(mcursor)) == 0) {
		if ((!json && dump_prefix(session, hex, json) != 0) ||
		    dump_table_config(session, mcursor, cursor,
		    uri, json) != 0 ||
		    dump_suffix(session, json) != 0)
			ret = 1;
	} else if (ret == WT_NOTFOUND)
		ret = util_err(session, 0, "%s: No such object exists", uri);
	else
		ret = util_err(session, ret, "%s", uri);

	if ((tret = mcursor->close(mcursor)) != 0) {
		tret = util_cerr(mcursor, "close", tret);
		if (ret == 0)
			ret = tret;
	}

	return (ret);
}
Example #8
0
/*
 * dump_config --
 *	Dump the config for the uri.
 */
static int
dump_config(WT_SESSION *session, const char *uri, int hex)
{
	WT_CURSOR *cursor;
	WT_DECL_RET;
	int tret;

	/* Open a metadata cursor. */
	if ((ret = session->open_cursor(
	    session, WT_METADATA_URI, NULL, NULL, &cursor)) != 0) {
		fprintf(stderr, "%s: %s: session.open_cursor: %s\n",
		    progname, WT_METADATA_URI, wiredtiger_strerror(ret));
		return (1);
	}
	/*
	 * Search for the object itself, just to make sure it exists, we don't
	 * want to output a header if the user entered the wrong name. This is
	 * where we find out a table doesn't exist, use a simple error message.
	 */
	cursor->set_key(cursor, uri);
	if ((ret = cursor->search(cursor)) == 0) {
		if (dump_prefix(hex) != 0 ||
		    dump_table_config(session, cursor, uri) != 0 ||
		    dump_suffix() != 0)
			ret = 1;
	} else if (ret == WT_NOTFOUND)
		ret = util_err(0, "%s: No such object exists", uri);
	else
		ret = util_err(ret, "%s", uri);

	if ((tret = cursor->close(cursor)) != 0) {
		tret = util_cerr(uri, "close", tret);
		if (ret == 0)
			ret = tret;
	}

	return (ret);
}
Example #9
0
int
util_write(WT_SESSION *session, int argc, char *argv[])
{
	WT_CURSOR *cursor;
	uint64_t recno;
	int append, ch, overwrite, rkey, ret;
	const char *uri;
	char config[100];

	append = overwrite = ret = 0;

	while ((ch = util_getopt(argc, argv, "ao")) != EOF)
		switch (ch) {
		case 'a':
			append = 1;
			break;
		case 'o':
			overwrite = 1;
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= util_optind;
	argv += util_optind;

	/*
	 * The remaining arguments are a uri followed by a list of values (if
	 * append is set), or key/value pairs (if append is not set).
	 */
	if (append) {
		if (argc < 2)
			return (usage());
	} else
		if (argc < 3 || ((argc - 1) % 2 != 0))
			return (usage());
	if ((uri =
	    util_name(*argv, "table", UTIL_FILE_OK | UTIL_TABLE_OK)) == NULL)
		return (1);

	/* Open the object. */
	(void)snprintf(config, sizeof(config), "%s,%s",
	    append ? "append=true" : "", overwrite ? "overwrite=true" : "");
	if ((ret = session->open_cursor(
	    session, uri, NULL, config, &cursor)) != 0)
		return (util_err(ret, "%s: session.open", uri));

	/*
	 * A simple search only makes sense if the key format is a string or a
	 * record number, and the value format is a single string.
	 */
	if (strcmp(cursor->key_format, "r") != 0 &&
	    strcmp(cursor->key_format, "S") != 0) {
		fprintf(stderr,
		    "%s: write command only possible when the key format is "
		    "a record number or string\n",
		    progname);
		return (1);
	}
	rkey = strcmp(cursor->key_format, "r") == 0 ? 1 : 0;
	if (strcmp(cursor->value_format, "S") != 0) {
		fprintf(stderr,
		    "%s: write command only possible when the value format is "
		    "a string\n",
		    progname);
		return (1);
	}

	/* Run through the values or key/value pairs. */
	while (*++argv != NULL) {
		if (!append) {
			if (rkey) {
				if (util_str2recno(*argv, &recno))
					return (1);
				cursor->set_key(cursor, recno);
			} else
				cursor->set_key(cursor, *argv);
			++argv;
		}
		cursor->set_value(cursor, *argv);

		if ((ret = cursor->insert(cursor)) != 0)
			return (util_cerr(uri, "search", ret));
	}
		
	return (0);
}
Example #10
0
/*
 * list_print --
 *	List the high-level objects in the database.
 */
static int
list_print(WT_SESSION *session, const char *name, int cflag, int vflag)
{
    WT_CURSOR *cursor;
    WT_DECL_RET;
    int found;
    const char *key, *value;

    /* Open the metadata file. */
    if ((ret = session->open_cursor(
                   session, WT_METADATA_URI, NULL, NULL, &cursor)) != 0) {
        /*
         * If there is no metadata (yet), this will return ENOENT.
         * Treat that the same as an empty metadata.
         */
        if (ret == ENOENT)
            return (0);

        fprintf(stderr, "%s: %s: session.open_cursor: %s\n",
                progname, WT_METADATA_URI, session->strerror(session, ret));
        return (1);
    }

    found = name == NULL;
    while ((ret = cursor->next(cursor)) == 0) {
        /* Get the key. */
        if ((ret = cursor->get_key(cursor, &key)) != 0)
            return (util_cerr(cursor, "get_key", ret));

        /*
         * If a name is specified, only show objects that match.
         */
        if (name != NULL) {
            if (!WT_PREFIX_MATCH(key, name))
                continue;
            found = 1;
        }

        /*
         * !!!
         * We don't normally say anything about the WiredTiger metadata
         * and lookaside tables, they're not application/user "objects"
         * in the database.  I'm making an exception for the checkpoint
         * and verbose options.
         */
        if (cflag || vflag ||
                (strcmp(key, WT_METADATA_URI) != 0 &&
                 strcmp(key, WT_LAS_URI) != 0))
            printf("%s\n", key);

        if (!cflag && !vflag)
            continue;

        if (cflag && (ret = list_print_checkpoint(session, key)) != 0)
            return (ret);
        if (vflag) {
            if ((ret = cursor->get_value(cursor, &value)) != 0)
                return (util_cerr(cursor, "get_value", ret));
            printf("%s\n", value);
        }
    }
    if (ret != WT_NOTFOUND)
        return (util_cerr(cursor, "next", ret));
    if (!found) {
        fprintf(stderr, "%s: %s: not found\n", progname, name);
        return (1);
    }

    return (0);
}
Example #11
0
int
util_read(WT_SESSION *session, int argc, char *argv[])
{
	WT_CURSOR *cursor;
	WT_DECL_RET;
	uint64_t recno;
	int ch;
	bool rkey, rval;
	char *uri, *value;

	uri = NULL;
	while ((ch = __wt_getopt(progname, argc, argv, "")) != EOF)
		switch (ch) {
		case '?':
		default:
			return (usage());
		}
	argc -= __wt_optind;
	argv += __wt_optind;

	/* The remaining arguments are a uri followed by a list of keys. */
	if (argc < 2)
		return (usage());
	if ((uri = util_uri(session, *argv, "table")) == NULL)
		return (1);

	/*
	 * Open the object; free allocated memory immediately to simplify
	 * future error handling.
	 */
	if ((ret =
	    session->open_cursor(session, uri, NULL, NULL, &cursor)) != 0)
		(void)util_err(session, ret, "%s: session.open_cursor", uri);
	free(uri);
	if (ret != 0)
		return (ret);

	/*
	 * A simple search only makes sense if the key format is a string or a
	 * record number, and the value format is a single string.
	 */
	if (strcmp(cursor->key_format, "r") != 0 &&
	    strcmp(cursor->key_format, "S") != 0) {
		fprintf(stderr,
		    "%s: read command only possible when the key format is "
		    "a record number or string\n",
		    progname);
		return (1);
	}
	rkey = strcmp(cursor->key_format, "r") == 0;
	if (strcmp(cursor->value_format, "S") != 0) {
		fprintf(stderr,
		    "%s: read command only possible when the value format is "
		    "a string\n",
		    progname);
		return (1);
	}

	/*
	 * Run through the keys, returning non-zero on error or if any requested
	 * key isn't found.
	 */
	for (rval = false; *++argv != NULL;) {
		if (rkey) {
			if (util_str2recno(session, *argv, &recno))
				return (1);
			cursor->set_key(cursor, recno);
		} else
			cursor->set_key(cursor, *argv);

		switch (ret = cursor->search(cursor)) {
		case 0:
			if ((ret = cursor->get_value(cursor, &value)) != 0)
				return (util_cerr(cursor, "get_value", ret));
			if (printf("%s\n", value) < 0)
				return (util_err(session, EIO, NULL));
			break;
		case WT_NOTFOUND:
			(void)util_err(session, 0, "%s: not found", *argv);
			rval = true;
			break;
		default:
			return (util_cerr(cursor, "search", ret));
		}
	}

	return (rval ? 1 : 0);
}
Example #12
0
/*
 * dump_table_config_complex --
 *	Dump the column groups or indices for a table.
 */
static int
dump_table_config_complex(WT_SESSION *session, WT_CURSOR *cursor,
    WT_CURSOR *srch, const char *name, const char *entry, bool json)
{
	WT_CONFIG_ITEM cval;
	WT_DECL_RET;
	bool multiple;
	const char *groupname, *key, *sep;
	size_t len;
	int exact;
	const char *v;
	char *p, *cfg[3] = {NULL, NULL, NULL};

	multiple = false;
	sep = "";

	if (json) {
		if (strcmp(entry, "colgroup:") == 0) {
			groupname = "colgroups";
			sep = ",";
		} else {
			groupname = "indices";
		}
		if (printf("            \"%s\" : [", groupname) < 0)
			return (util_err(session, EIO, NULL));
	}
	/*
	 * Search the file looking for column group and index key/value pairs:
	 * for each one, look up the related source information and append it
	 * to the base record, where the column group and index configuration
	 * overrides the source configuration.
	 */
	cursor->set_key(cursor, entry);
	if ((ret = cursor->search_near(cursor, &exact)) != 0) {
		if (ret == WT_NOTFOUND)
			return (0);
		return (util_cerr(cursor, "search_near", ret));
	}
	if (exact >= 0)
		goto match;
	while ((ret = cursor->next(cursor)) == 0) {
match:		if ((ret = cursor->get_key(cursor, &key)) != 0)
			return (util_cerr(cursor, "get_key", ret));

		/* Check if we've finished the list of entries. */
		if (!WT_PREFIX_MATCH(key, entry))
			break;

		/*
		 * Check for a table name match. This test will match "simple"
		 * table column-groups as well as the more complex ones, but
		 * the previous version of the test was wrong and we're only
		 * in this function in the case of complex tables.
		 */
		if (!WT_PREFIX_MATCH(key + strlen(entry), name))
			continue;

		/* Get the value. */
		if ((ret = cursor->get_value(cursor, &v)) != 0)
			return (util_cerr(cursor, "get_value", ret));
		if ((cfg[1] = strdup(v)) == NULL)
			return (util_err(session, errno, NULL));

		/* Crack it and get the underlying source. */
		if ((ret = __wt_config_getones(
		    (WT_SESSION_IMPL *)session, cfg[1], "source", &cval)) != 0)
			return (
			    util_err(session, ret, "%s: source entry", key));

		/* Nul-terminate the source entry. */
		len = cval.len + 10;
		if ((p = malloc(len)) == NULL)
			return (util_err(session, errno, NULL));
		(void)snprintf(p, len, "%.*s", (int)cval.len, cval.str);
		srch->set_key(srch, p);
		if ((ret = srch->search(srch)) != 0)
			ret = util_err(session, ret, "%s: %s", key, p);
		free(p);
		if (ret != 0)
			return (1);

		/* Get the source's value. */
		if ((ret = srch->get_value(srch, &v)) != 0)
			return (util_cerr(cursor, "get_value", ret));
		if ((cfg[0] = strdup(v)) == NULL)
			return (util_err(session, errno, NULL));

		if (json && printf("%s\n", multiple ? "," : "") < 0)
			return (util_err(session, EIO, NULL));
		/*
		 * The dumped configuration string is the original key plus the
		 * source's configuration, where the values of the original key
		 * override any source configurations of the same name.
		 */
		if (print_config(session, key, cfg, json, false) != 0)
			return (util_err(session, EIO, NULL));
		multiple = true;
	}
	if (json && printf("\n            ]%s\n", sep) < 0)
		return (util_err(session, EIO, NULL));
	free(cfg[0]);
	free(cfg[1]);

	if (ret == 0 || ret == WT_NOTFOUND)
		return (0);
	return (util_cerr(cursor, "next", ret));
}
Example #13
0
/*
 * dump_table_config --
 *	Dump the config for a table.
 */
static int
dump_table_config(
    WT_SESSION *session, WT_CURSOR *cursor, const char *uri, bool json)
{
	WT_CONFIG_ITEM cval;
	WT_CURSOR *srch;
	WT_DECL_RET;
	size_t len;
	int tret;
	bool complex_table;
	const char *name, *v;
	char *p, **cfg, *_cfg[4] = {NULL, NULL, NULL, NULL};

	p = NULL;
	cfg = &_cfg[3];

	/* Get the table name. */
	if ((name = strchr(uri, ':')) == NULL) {
		fprintf(stderr, "%s: %s: corrupted uri\n", progname, uri);
		return (1);
	}
	++name;

	/*
	 * Dump out the config information: first, dump the uri entry itself,
	 * it overrides all subsequent configurations.
	 */
	cursor->set_key(cursor, uri);
	if ((ret = cursor->search(cursor)) != 0)
		WT_ERR(util_cerr(cursor, "search", ret));
	if ((ret = cursor->get_value(cursor, &v)) != 0)
		WT_ERR(util_cerr(cursor, "get_value", ret));
	if ((*--cfg = strdup(v)) == NULL)
		WT_ERR(util_err(session, errno, NULL));

	/*
	 * Workaround for WiredTiger "simple" table handling. Simple tables
	 * have column-group entries, but they aren't listed in the metadata's
	 * table entry, and the name is different from other column-groups.
	 * Figure out if it's a simple table and in that case, retrieve the
	 * column-group's configuration value and the column-group's "source"
	 * entry, where the column-group entry overrides the source's.
	 */
	complex_table = false;
	if (WT_PREFIX_MATCH(uri, "table:")) {
		len = strlen("colgroup:") + strlen(name) + 1;
		if ((p = malloc(len)) == NULL)
			WT_ERR(util_err(session, errno, NULL));
		(void)snprintf(p, len, "colgroup:%s", name);
		cursor->set_key(cursor, p);
		if ((ret = cursor->search(cursor)) == 0) {
			if ((ret = cursor->get_value(cursor, &v)) != 0)
				WT_ERR(util_cerr(cursor, "get_value", ret));
			if ((*--cfg = strdup(v)) == NULL)
				WT_ERR(util_err(session, errno, NULL));
			if ((ret =__wt_config_getones(
			    (WT_SESSION_IMPL *)session,
			    *cfg, "source", &cval)) != 0)
				WT_ERR(util_err(
				    session, ret, "%s: source entry", p));
			free(p);
			len = cval.len + 10;
			if ((p = malloc(len)) == NULL)
				WT_ERR(util_err(session, errno, NULL));
			(void)snprintf(p, len, "%.*s", (int)cval.len, cval.str);
			cursor->set_key(cursor, p);
			if ((ret = cursor->search(cursor)) != 0)
				WT_ERR(util_cerr(cursor, "search", ret));
			if ((ret = cursor->get_value(cursor, &v)) != 0)
				WT_ERR(util_cerr(cursor, "get_value", ret));
			if ((*--cfg = strdup(v)) == NULL)
				WT_ERR(util_err(session, errno, NULL));
		} else
			complex_table = true;
	}

	WT_ERR(print_config(session, uri, cfg, json, true));

	if (complex_table) {
		/*
		 * The underlying table configuration function needs a second
		 * cursor: open one before calling it, it makes error handling
		 * hugely simpler.
		 */
		if ((ret = session->open_cursor(
		    session, "metadata:", NULL, NULL, &srch)) != 0)
			WT_ERR(util_cerr(cursor, "open_cursor", ret));

		if ((ret = dump_table_config_complex(
		    session, cursor, srch, name, "colgroup:", json)) == 0)
			ret = dump_table_config_complex(
			    session, cursor, srch, name, "index:", json);

		if ((tret = srch->close(srch)) != 0) {
			tret = util_cerr(cursor, "close", tret);
			if (ret == 0)
				ret = tret;
		}
	} else if (json && printf(
		    "            \"colgroups\" : [],\n"
		    "            \"indices\" : []\n") < 0)
		WT_ERR(util_cerr(cursor, NULL, EIO));

err:	free(p);
	free(_cfg[0]);
	free(_cfg[1]);
	free(_cfg[2]);
	return (ret);
}
Example #14
0
/*
 * dump_table_config_type --
 *	Dump the column groups or indices for a table.
 */
static int
dump_table_config_type(WT_SESSION *session,
    WT_CURSOR *cursor, WT_CURSOR *srch, const char *name, const char *entry)
{
	WT_CONFIG_ITEM cval;
	WT_DECL_RET;
	const char *key, *skip, *value, *value_source;
	int exact;
	char *p;

	/*
	 * Search the file looking for column group and index key/value pairs:
	 * for each one, look up the related source information and append it
	 * to the base record.
	 */
	cursor->set_key(cursor, entry);
	if ((ret = cursor->search_near(cursor, &exact)) != 0) {
		if (ret == WT_NOTFOUND)
			return (0);
		return (util_cerr(cursor, "search_near", ret));
	}
	if (exact >= 0)
		goto match;
	while ((ret = cursor->next(cursor)) == 0) {
match:		if ((ret = cursor->get_key(cursor, &key)) != 0)
			return (util_cerr(cursor, "get_key", ret));

		/* Check if we've finished the list of entries. */
		if (!WT_PREFIX_MATCH(key, entry))
			return (0);

		/* Check for a table name match. */
		skip = key + strlen(entry);
		if (strncmp(
		    skip, name, strlen(name)) != 0 || skip[strlen(name)] != ':')
			continue;

		/* Get the value. */
		if ((ret = cursor->get_value(cursor, &value)) != 0)
			return (util_cerr(cursor, "get_value", ret));

		/* Crack it and get the underlying source. */
		if ((ret = __wt_config_getones(
		    (WT_SESSION_IMPL *)session, value, "source", &cval)) != 0)
			return (
			    util_err(session, ret, "%s: source entry", key));

		/* Nul-terminate the source entry. */
		if ((p = malloc(cval.len + 10)) == NULL)
			return (util_err(session, errno, NULL));
		(void)strncpy(p, cval.str, cval.len);
		p[cval.len] = '\0';
		srch->set_key(srch, p);
		if ((ret = srch->search(srch)) != 0)
			ret = util_err(session, ret, "%s: %s", key, p);
		free(p);
		if (ret != 0)
			return (1);

		/* Get the source's value. */
		if ((ret = srch->get_value(srch, &value_source)) != 0)
			return (util_cerr(cursor, "get_value", ret));

		/*
		 * The dumped configuration string is the original key plus the
		 * source's configuration.
		 */
		if (print_config(session, key, value, value_source) != 0)
			return (util_err(session, EIO, NULL));
	}
	if (ret == 0 || ret == WT_NOTFOUND)
		return (0);
	return (util_cerr(cursor, "next", ret));
}
Example #15
0
/*
 * dump_json_table_cg --
 *	Dump the column groups or indices for a table.
 */
static int
dump_json_table_cg(WT_SESSION *session, WT_CURSOR *cursor,
    const char *name, const char *entry, const char *header)
{
	WT_DECL_RET;
	const char *key, *skip, *value;
	int exact, once;
	char *jsonconfig;
	static const char * const indent = "                ";

	once = 0;
	if (printf("            \"%s\" : [", header) < 0)
		return (util_err(session, EIO, NULL));

	/*
	 * For table dumps, we're done.
	 */
	if (cursor == NULL) {
		if (printf("]") < 0)
			return (util_err(session, EIO, NULL));
		else
			return (0);
	}

	/*
	 * Search the file looking for column group and index key/value pairs:
	 * for each one, look up the related source information and append it
	 * to the base record.
	 */
	cursor->set_key(cursor, entry);
	if ((ret = cursor->search_near(cursor, &exact)) != 0) {
		if (ret == WT_NOTFOUND)
			return (0);
		return (util_cerr(cursor, "search_near", ret));
	}
	if (exact >= 0)
		goto match;
	while ((ret = cursor->next(cursor)) == 0) {
match:		if ((ret = cursor->get_key(cursor, &key)) != 0)
			return (util_cerr(cursor, "get_key", ret));

		/* Check if we've finished the list of entries. */
		if (!WT_PREFIX_MATCH(key, entry))
			break;

		/* Check for a table name match. */
		skip = key + strlen(entry);
		if (strncmp(
		    skip, name, strlen(name)) != 0 || skip[strlen(name)] != ':')
			continue;

		/* Get the value. */
		if ((ret = cursor->get_value(cursor, &value)) != 0)
			return (util_cerr(cursor, "get_value", ret));

		if ((ret = dup_json_string(value, &jsonconfig)) != 0)
			return (util_cerr(cursor, "config dup", ret));
		ret = printf("%s\n"
		    "%s{\n"
		    "%s    \"uri\" : \"%s\",\n"
		    "%s    \"config\" : \"%s\"\n"
		    "%s}",
		    (once == 0 ? "" : ","),
		    indent, indent, key, indent, jsonconfig, indent);
		free(jsonconfig);
		if (ret < 0)
			return (util_err(session, EIO, NULL));

		once = 1;
	}
	if (printf("%s]", (once == 0 ? "" : "\n            ")) < 0)
		return (util_err(session, EIO, NULL));
	if (ret == 0 || ret == WT_NOTFOUND)
		return (0);
	return (util_cerr(cursor, "next", ret));
}
Example #16
0
/*
 * dump_config --
 *	Dump the config for the uri.
 */
static int
dump_config(WT_SESSION *session, const char *uri, int hex)
{
	WT_CURSOR *cursor;
	WT_DECL_RET;
	WT_EXTENSION_API *wtext;
	int tret;
	const char *value;

	/* Dump the config. */
	if (WT_PREFIX_MATCH(uri, "table:")) {
		/* Open a metadata cursor. */
		if ((ret = session->open_cursor(
		    session, "metadata:", NULL, NULL, &cursor)) != 0) {
			fprintf(stderr, "%s: %s: session.open_cursor: %s\n",
			    progname, "metadata:", wiredtiger_strerror(ret));
			return (1);
		}
		/*
		 * Search for the object itself, just to make sure it exists,
		 * we don't want to output a header if the user entered the
		 * wrong name.  This where we find out a table object doesn't
		 * exist, use a simple error message.
		 */
		cursor->set_key(cursor, uri);
		if ((ret = cursor->search(cursor)) == 0) {
			if (dump_prefix(hex) != 0 ||
			    dump_table_config(session, cursor, uri) != 0 ||
			    dump_suffix() != 0)
				ret = 1;
		} else if (ret == WT_NOTFOUND)
			ret = util_err(0, "%s: No such object exists", uri);
		else
			ret = util_err(ret, "%s", uri);

		if ((tret = cursor->close(cursor)) != 0) {
			tret = util_cerr(uri, "close", tret);
			if (ret == 0)
				ret = tret;
		}
	} else {
		/*
		 * We want to be able to dump the metadata file itself, but the
		 * configuration for that file lives in the turtle file.  Reach
		 * down into the library and ask for the file's configuration,
		 * that will work in all cases.
		 *
		 * This where we find out a file object doesn't exist, use a
		 * simple error message.
		 */
		wtext = session->
		    connection->get_extension_api(session->connection);
		if ((ret =
		    wtext->metadata_search(wtext, session, uri, &value)) == 0) {
			if (dump_prefix(hex) != 0 ||
			    print_config(session, uri, value, NULL) != 0 ||
			    dump_suffix() != 0)
				ret = 1;
		} else if (ret == WT_NOTFOUND)
			ret = util_err(0, "%s: No such object exists", uri);
		else
			ret = util_err(ret, "%s", uri);
	}

	return (ret);
}