/* * 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); }
/* * 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); }