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