/* * insert -- * Read and insert data. */ static int insert(WT_CURSOR *cursor, const char *name) { ULINE key, value; WT_DECL_RET; WT_SESSION *session; uint64_t insert_count; bool eof; session = cursor->session; memset(&key, 0, sizeof(key)); memset(&value, 0, sizeof(value)); /* Read key/value pairs and insert them into the file. */ for (insert_count = 0;;) { /* * Three modes: in row-store, we always read a key and use it, * in column-store, we might read it (a dump), we might read * and ignore it (a dump with "append" set), or not read it at * all (flat-text load). */ if (util_read_line(session, &key, true, &eof)) return (1); if (eof) break; if (!append) cursor->set_key(cursor, key.mem); if (util_read_line(session, &value, false, &eof)) return (1); cursor->set_value(cursor, value.mem); if ((ret = cursor->insert(cursor)) != 0) return ( util_err(session, ret, "%s: cursor.insert", name)); /* Report on progress every 100 inserts. */ if (verbose && ++insert_count % 100 == 0) { printf("\r\t%s: %" PRIu64, name, insert_count); fflush(stdout); } } if (verbose) printf("\r\t%s: %" PRIu64 "\n", name, insert_count); return (0); }
/* * json_skip -- * Skip over JSON input until one of the specified strings appears. * The tokenizer will be set to point to the beginning of * that string. */ static int json_skip(WT_SESSION *session, JSON_INPUT_STATE *ins, const char **matches) { const char *hit; const char **match; if (ins->kvraw != NULL) return (1); hit = NULL; while (!ins->ateof) { for (match = matches; *match != NULL; match++) if ((hit = strstr(ins->p, *match)) != NULL) goto out; if (util_read_line(&ins->line, 1, &ins->ateof)) { ins->toktype = -1; return (1); } ins->linenum++; ins->p = (const char *)ins->line.mem; } out: if (hit == NULL) return (1); /* Set to this token. */ ins->p = hit; ins->peeking = 0; ins->toktype = 0; (void)json_peek(session, ins); return (0); }
/* * json_peek -- * Set the input state to the next available token in the input * and return its token type, a code defined by __wt_json_token(). */ static int json_peek(WT_SESSION *session, JSON_INPUT_STATE *ins) { WT_DECL_RET; if (!ins->peeking) { while (!ins->ateof) { while (isspace(*ins->p)) ins->p++; if (*ins->p) break; if (ins->kvraw != NULL) { if (json_kvraw_append(ins, (char *)ins->line.mem + ins->kvrawstart, strlen(ins->line.mem) - ins->kvrawstart)) { ret = -1; goto err; } ins->kvrawstart = 0; } if (util_read_line(&ins->line, 1, &ins->ateof)) { ins->toktype = -1; ret = -1; goto err; } ins->linenum++; ins->p = (const char *)ins->line.mem; } if (ins->ateof) ins->toktype = 0; else if (__wt_json_token(session, ins->p, &ins->toktype, &ins->tokstart, &ins->toklen) != 0) ins->toktype = -1; ins->peeking = 1; } if (0) { err: if (ret == 0) ret = -1; } return (ret == 0 ? ins->toktype : -1); }
/* * load_json -- * Load from the JSON format produced by 'wt dump -j'. */ int util_load_json(WT_SESSION *session, const char *filename, uint32_t flags) { JSON_INPUT_STATE instate; WT_DECL_RET; memset(&instate, 0, sizeof(instate)); instate.session = session; if (util_read_line(&instate.line, 0, &instate.ateof)) return (1); instate.p = (const char *)instate.line.mem; instate.linenum = 1; instate.filename = filename; if ((ret = json_top_level(session, &instate, flags)) != 0) goto err; err: if (instate.line.mem != NULL) free(instate.line.mem); free(instate.kvraw); return (ret); }
/* * config_read -- * Read the config lines and do some basic validation. */ static int config_read(char ***listp, int *hexp) { ULINE l; WT_DECL_RET; int entry, eof, max_entry; const char *s; char **list, **tlist; list = NULL; memset(&l, 0, sizeof(l)); /* Header line #1: "WiredTiger Dump" and a WiredTiger version. */ if (util_read_line(&l, 0, &eof)) return (1); s = "WiredTiger Dump "; if (strncmp(l.mem, s, strlen(s)) != 0) return (format()); /* Header line #2: "Format={hex,print}". */ if (util_read_line(&l, 0, &eof)) return (1); if (strcmp(l.mem, "Format=print") == 0) *hexp = 0; else if (strcmp(l.mem, "Format=hex") == 0) *hexp = 1; else return (format()); /* Header line #3: "Header". */ if (util_read_line(&l, 0, &eof)) return (1); if (strcmp(l.mem, "Header") != 0) return (format()); /* Now, read in lines until we get to the end of the headers. */ for (entry = max_entry = 0, list = NULL;; ++entry) { if ((ret = util_read_line(&l, 0, &eof)) != 0) goto err; if (strcmp(l.mem, "Data") == 0) break; /* * Grow the array of header lines as necessary -- we need an * extra slot for NULL termination. */ if (entry + 1 >= max_entry) { if ((tlist = realloc(list, (size_t) (max_entry += 100) * sizeof(char *))) == NULL) { ret = util_err(errno, NULL); /* * List already freed by realloc, still use err * label for consistency. */ list = NULL; goto err; } list = tlist; } if ((list[entry] = strdup(l.mem)) == NULL) { ret = util_err(errno, NULL); goto err; } list[entry + 1] = NULL; } /* Headers are required, and they're supposed to be in pairs. */ if (list == NULL || entry % 2 != 0) { ret = format(); goto err; } *listp = list; return (0); err: if (list != NULL) { for (tlist = list; *tlist != NULL; ++tlist) free(*tlist); free(list); } return (ret); }