Esempio n. 1
0
/*
 * util_str2recno --
 *	Convert a string to a record number.
 */
int
util_str2recno(WT_SESSION *session, const char *p, uint64_t *recnop)
{
	uint64_t recno;
	char *endptr;

	/*
	 * strtouq takes lots of things like hex values, signs and so on and so
	 * forth -- none of them are OK with us.  Check the string starts with
	 * digit, that turns off the special processing.
	 */
	if (!isdigit(p[0]))
		goto format;

	errno = 0;
	recno = __wt_strtouq(p, &endptr, 0);
	if (recno == ULLONG_MAX && errno == ERANGE)
		return (
		    util_err(session, ERANGE, "%s: invalid record number", p));

	if (endptr[0] != '\0')
format:		return (
		    util_err(session, EINVAL, "%s: invalid record number", p));

	*recnop = recno;
	return (0);
}
Esempio n. 2
0
/*
 * 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);
}