Example #1
0
/*
 * load_dump --
 *	Load from the WiredTiger dump format.
 */
static int
load_dump(WT_SESSION *session)
{
    WT_CURSOR *cursor;
    WT_DECL_RET;
    int hex, tret;
    char **entry, **list, *p, **tlist, *uri, config[64];

    cursor = NULL;
    list = NULL;		/* -Wuninitialized */
    hex = 0;		/* -Wuninitialized */
    uri = NULL;

    /* Read the metadata file. */
    if ((ret = config_read(&list, &hex)) != 0)
        return (ret);

    /*
     * Search for a table name -- if we find one, then it's table dump,
     * otherwise, it's a single file dump.
     */
    for (entry = list; *entry != NULL; ++entry)
        if (WT_PREFIX_MATCH(*entry, "table:"))
            break;
    if (*entry == NULL) {
        /*
         * Single file dumps can only have two lines, the file name and
         * the configuration information.
         */
        if ((list[0] == NULL || list[1] == NULL || list[2] != NULL) ||
                (WT_PREFIX_MATCH(list[0], "file:") &&
                 WT_PREFIX_MATCH(list[0], "lsm:"))) {
            ret = format();
            goto err;
        }

        entry = list;
    }

    /*
     * Make sure the table key/value pair comes first, then we can just
     * run through the array in order.  (We already checked that we had
     * a multiple of 2 entries, so this is safe.)
     */
    if (entry != list) {
        p = list[0];
        list[0] = entry[0];
        entry[0] = p;
        p = list[1];
        list[1] = entry[1];
        entry[1] = p;
    }

    /* Update the config based on any command-line configuration. */
    if ((ret = config_update(session, list)) != 0)
        goto err;

    uri = list[0];
    for (entry = list; *entry != NULL; entry += 2)
        if ((ret = session->create(session, entry[0], entry[1])) != 0) {
            ret = util_err(ret, "%s: session.create", entry[0]);
            goto err;
        }

    /* Open the insert cursor. */
    (void)snprintf(config, sizeof(config),
                   "dump=%s%s%s",
                   hex ? "hex" : "print",
                   append ? ",append" : "", no_overwrite ? ",overwrite=false" : "");
    if ((ret = session->open_cursor(
                   session, uri, NULL, config, &cursor)) != 0) {
        ret = util_err(ret, "%s: session.open", uri);
        goto err;
    }

    /*
     * Check the append flag (it only applies to objects where the primary
     * key is a record number).
     */
    if (append && strcmp(cursor->key_format, "r") != 0) {
        fprintf(stderr,
                "%s: %s: -a option illegal unless the primary key is a "
                "record number\n",
                progname, uri);
        ret = 1;
    } else
        ret = insert(cursor, uri);

err:	/*
	 * Technically, we don't have to close the cursor because the session
	 * handle will do it for us, but I'd like to see the flush to disk and
	 * the close succeed, it's better to fail early when loading files.
	 */
    if (cursor != NULL && (tret = cursor->close(cursor)) != 0) {
        tret = util_err(tret, "%s: cursor.close", uri);
        if (ret == 0)
            ret = tret;
    }
    if (ret == 0)
        ret = util_flush(session, uri);

    for (tlist = list; *tlist != NULL; ++tlist)
        free(*tlist);
    free(list);

    return (ret == 0 ? 0 : 1);
}
Example #2
0
/*
 * load_dump --
 *	Load from the WiredTiger dump format.
 */
static int
load_dump(WT_SESSION *session)
{
	WT_CURSOR *cursor;
	WT_DECL_RET;
	int hex, tret;
	char **list, **tlist, *uri, config[64];

	cursor = NULL;
	list = NULL;		/* -Wuninitialized */
	hex = 0;		/* -Wuninitialized */
	uri = NULL;

	/* Read the metadata file. */
	if ((ret = config_read(&list, &hex)) != 0)
		return (ret);

	/* Reorder and check the list. */
	if ((ret = config_reorder(list)) != 0)
		goto err;

	/* Update the config based on any command-line configuration. */
	if ((ret = config_update(session, list)) != 0)
		goto err;

	uri = list[0];
	/* Create the items in the list. */
	if ((ret = config_exec(session, list)) != 0)
		goto err;

	/* Open the insert cursor. */
	(void)snprintf(config, sizeof(config),
	    "dump=%s%s%s",
	    hex ? "hex" : "print",
	    append ? ",append" : "", no_overwrite ? ",overwrite=false" : "");
	if ((ret = session->open_cursor(
	    session, uri, NULL, config, &cursor)) != 0) {
		ret = util_err(ret, "%s: session.open", uri);
		goto err;
	}

	/*
	 * Check the append flag (it only applies to objects where the primary
	 * key is a record number).
	 */
	if (append && strcmp(cursor->key_format, "r") != 0) {
		fprintf(stderr,
		    "%s: %s: -a option illegal unless the primary key is a "
		    "record number\n",
		    progname, uri);
		ret = 1;
	} else
		ret = insert(cursor, uri);

err:	/*
	 * Technically, we don't have to close the cursor because the session
	 * handle will do it for us, but I'd like to see the flush to disk and
	 * the close succeed, it's better to fail early when loading files.
	 */
	if (cursor != NULL && (tret = cursor->close(cursor)) != 0) {
		tret = util_err(tret, "%s: cursor.close", uri);
		if (ret == 0)
			ret = tret;
	}
	if (ret == 0)
		ret = util_flush(session, uri);

	for (tlist = list; *tlist != NULL; ++tlist)
		free(*tlist);
	free(list);

	return (ret == 0 ? 0 : 1);
}
/*
 * json_data --
 *	Parse the data portion of the JSON input, and insert all
 *	values.
 */
static int
json_data(WT_SESSION *session, JSON_INPUT_STATE *ins, CONFIG_LIST *clp,
    uint32_t flags)
{
	WT_CURSOR *cursor;
	WT_DECL_RET;
	char config[64], *endp, *uri;
	const char *keyformat;
	int isrec, nfield, nkeys, toktype, tret;
	size_t keystrlen;
	ssize_t gotnolen;
	uint64_t gotno, recno;

	cursor = NULL;
	uri = NULL;

	/* Reorder and check the list. */
	if ((ret = config_reorder(clp->list)) != 0)
		goto err;

	/* Update config based on command-line configuration. */
	if ((ret = config_update(session, clp->list)) != 0)
		goto err;

	/* Create the items collected. */
	if ((ret = config_exec(session, clp->list)) != 0)
		goto err;

	uri = clp->list[0];
	(void)snprintf(config, sizeof(config),
	    "dump=json%s%s",
	    LF_ISSET(LOAD_JSON_APPEND) ? ",append" : "",
	    LF_ISSET(LOAD_JSON_NO_OVERWRITE) ? ",overwrite=false" : "");
	if ((ret = session->open_cursor(
	    session, uri, NULL, config, &cursor)) != 0) {
		ret = util_err(ret, "%s: session.open", uri);
		goto err;
	}
	keyformat = cursor->key_format;
	isrec = (strcmp(keyformat, "r") == 0);
	for (nkeys = 0; *keyformat; keyformat++)
		if (!isdigit(*keyformat))
			nkeys++;

	recno = 0;
	while (json_peek(session, ins) == '{') {
		nfield = 0;
		JSON_EXPECT(session, ins, '{');
		if (ins->kvraw == NULL) {
			if ((ins->kvraw = (char *)malloc(1)) == NULL) {
				ret = util_err(errno, NULL);
				goto err;
			}
		}
		ins->kvraw[0] = '\0';
		ins->kvrawstart = JSON_INPUT_POS(ins);
		keystrlen = 0;
		while (json_peek(session, ins) == 's') {
			JSON_EXPECT(session, ins, 's');
			JSON_EXPECT(session, ins, ':');
			toktype = json_peek(session, ins);
			JSON_EXPECT(session, ins, toktype);
			if (isrec && nfield == 0) {
				/* Verify the dump has recnos in order. */
				recno++;
				gotno = __wt_strtouq(ins->tokstart, &endp, 0);
				gotnolen = (endp - ins->tokstart);
				if (recno != gotno ||
				    ins->toklen != (size_t)gotnolen) {
					ret = util_err(0,
					    "%s: recno out of order", uri);
					goto err;
				}
			}
			if (++nfield == nkeys) {
				size_t curpos = JSON_INPUT_POS(ins);
				if ((ret = json_kvraw_append(ins,
				    (char *)ins->line.mem + ins->kvrawstart,
				    curpos - ins->kvrawstart)) != 0)
					goto err;
				ins->kvrawstart = curpos;
				keystrlen = strlen(ins->kvraw);
			}
			if (json_peek(session, ins) != ',')
				break;
			JSON_EXPECT(session, ins, ',');
			if (json_peek(session, ins) != 's')
				goto err;
		}
		if (json_kvraw_append(ins, ins->line.mem, JSON_INPUT_POS(ins)))
			goto err;

		ins->kvraw[keystrlen] = '\0';
		if (!LF_ISSET(LOAD_JSON_APPEND))
			cursor->set_key(cursor, ins->kvraw);
		/* skip over inserted space and comma */
		cursor->set_value(cursor, &ins->kvraw[keystrlen+2]);
		if ((ret = cursor->insert(cursor)) != 0) {
			ret = util_err(ret, "%s: cursor.insert", uri);
			goto err;
		}

		JSON_EXPECT(session, ins, '}');
		if (json_peek(session, ins) != ',')
			break;
		JSON_EXPECT(session, ins, ',');
		if (json_peek(session, ins) != '{')
			goto err;
	}
	if (0) {
err:		if (ret == 0)
			ret = EINVAL;
	}
	/*
	 * Technically, we don't have to close the cursor because the session
	 * handle will do it for us, but I'd like to see the flush to disk and
	 * the close succeed, it's better to fail early when loading files.
	 */
	if (cursor != NULL && (tret = cursor->close(cursor)) != 0) {
		tret = util_err(tret, "%s: cursor.close", uri);
		if (ret == 0)
			ret = tret;
	}
	if (ret == 0)
		ret = util_flush(session, uri);
	return (ret);
}