static int process_file(const char *file, int *total) { Db *db; couchstore_error_t errcode; int count = 0; errcode = couchstore_open_db(file, COUCHSTORE_OPEN_FLAG_RDONLY, &db); if (errcode != COUCHSTORE_SUCCESS) { fprintf(stderr, "Failed to open \"%s\": %s\n", file, couchstore_strerror(errcode)); return -1; } else { fprintf(stderr, "Dumping \"%s\":\n", file); } switch (mode) { case DumpBySequence: if (dumpTree) { errcode = couchstore_walk_seq_tree(db, 0, COUCHSTORE_INCLUDE_CORRUPT_DOCS, visit_node, &count); } else { errcode = couchstore_changes_since(db, 0, COUCHSTORE_INCLUDE_CORRUPT_DOCS, foldprint, &count); } break; case DumpByID: if (dumpTree) { errcode = couchstore_walk_id_tree(db, NULL, COUCHSTORE_INCLUDE_CORRUPT_DOCS, visit_node, &count); } else if (oneKey) { DocInfo* info; errcode = couchstore_docinfo_by_id(db, dumpKey.buf, dumpKey.size, &info); if (errcode == COUCHSTORE_SUCCESS) { foldprint(db, info, &count); couchstore_free_docinfo(info); } } else { errcode = couchstore_all_docs(db, NULL, COUCHSTORE_INCLUDE_CORRUPT_DOCS, foldprint, &count); } break; case DumpLocals: errcode = couchstore_print_local_docs(db, &count); break; } (void)couchstore_close_db(db); if (errcode < 0) { fprintf(stderr, "Failed to dump database \"%s\": %s\n", file, couchstore_strerror(errcode)); return -1; } *total += count; return 0; }
static int process_file(const char *file, int *total) { Db *db; couchstore_error_t errcode; errcode = couchstore_open_db(file, COUCHSTORE_OPEN_FLAG_RDONLY, &db); if (errcode != COUCHSTORE_SUCCESS) { fprintf(stderr, "Failed to open \"%s\": %s\n", file, couchstore_strerror(errcode)); return -1; } int count = 0; switch (mode) { case DumpBySequence: if (dumpTree) { errcode = couchstore_walk_seq_tree(db, 0, COUCHSTORE_INCLUDE_CORRUPT_DOCS, visit_node, &count); } else { errcode = couchstore_changes_since(db, 0, COUCHSTORE_INCLUDE_CORRUPT_DOCS, foldprint, &count); } break; case DumpByID: if (dumpTree) { errcode = couchstore_walk_id_tree(db, NULL, COUCHSTORE_INCLUDE_CORRUPT_DOCS, visit_node, &count); } else { errcode = couchstore_all_docs(db, NULL, COUCHSTORE_INCLUDE_CORRUPT_DOCS, foldprint, &count); } break; } (void)couchstore_close_db(db); if (errcode < 0) { fprintf(stderr, "Failed to dump database \"%s\": %s\n", file, couchstore_strerror(errcode)); return -1; } *total += count; return 0; }
static int foldprint(Db *db, DocInfo *docinfo, void *ctx) { int *count = (int *) ctx; (*count)++; Doc *doc = NULL; uint64_t cas; uint32_t expiry, flags; if (mode == DumpBySequence) { printf("Doc seq: %"PRIu64"\n", docinfo->db_seq); printf(" id: "); printsb(&docinfo->id); } else { printf(" Doc ID: "); printsb(&docinfo->id); if (docinfo->db_seq > 0) { printf(" seq: %"PRIu64"\n", docinfo->db_seq); } } if (docinfo->bp == 0 && docinfo->deleted == 0) { printf(" ** This b-tree node is corrupt; raw node value follows:*\n"); printf(" raw: "); printsbhex(&docinfo->rev_meta, 1); return 0; } printf(" rev: %"PRIu64"\n", docinfo->rev_seq); printf(" content_meta: %d\n", docinfo->content_meta); if (docinfo->rev_meta.size == sizeof(CouchbaseRevMeta)) { const CouchbaseRevMeta* meta = (const CouchbaseRevMeta*)docinfo->rev_meta.buf; cas = decode_raw64(meta->cas); expiry = decode_raw32(meta->expiry); flags = decode_raw32(meta->flags); printf(" cas: %"PRIu64", expiry: %"PRIu32", flags: %"PRIu32"\n", cas, expiry, flags); } if (docinfo->deleted) { printf(" doc deleted\n"); } couchstore_error_t docerr = couchstore_open_doc_with_docinfo(db, docinfo, &doc, 0); if(docerr != COUCHSTORE_SUCCESS) { printf(" could not read document body: %s\n", couchstore_strerror(docerr)); } else if (doc && (docinfo->content_meta & COUCH_DOC_IS_COMPRESSED)) { size_t rlen; snappy_uncompressed_length(doc->data.buf, doc->data.size, &rlen); char *decbuf = (char *) malloc(rlen); size_t uncompr_len; snappy_uncompress(doc->data.buf, doc->data.size, decbuf, &uncompr_len); printf(" data: (snappy) %.*s\n", (int) uncompr_len, decbuf); free(decbuf); } else if(doc) { printf(" data: "); printsb(&doc->data); } couchstore_free_document(doc); return 0; }
static void print_os_err(Db *db) { char emsg[512]; couchstore_error_t ret; ret = couchstore_last_os_error(db, emsg, 512); if (ret == COUCHSTORE_SUCCESS) { fprintf(stderr, "OS Error: %s\n", emsg); } else { fprintf(stderr, "error: %s\n", couchstore_strerror(ret)); } }
static int process_file(const char *file, int iterate_headers) { Db *db; couchstore_error_t errcode; uint64_t btreesize = 0; const char* crc_strings[3] = {"warning crc is set to unknown", "CRC-32", "CRC-32C"}; errcode = couchstore_open_db(file, COUCHSTORE_OPEN_FLAG_RDONLY, &db); if (errcode != COUCHSTORE_SUCCESS) { fprintf(stderr, "Failed to open \"%s\": %s\n", file, couchstore_strerror(errcode)); return -1; } next_header: printf("DB Info (%s) - header at %"PRIu64"\n", file, db->header.position); printf(" file format version: %"PRIu64"\n", db->header.disk_version); printf(" update_seq: %"PRIu64"\n", db->header.update_seq); printf(" purge_seq: %"PRIu64"\n", db->header.purge_seq); if (db->file.crc_mode < 3) { printf(" crc: %s\n", crc_strings[db->file.crc_mode]); } else { printf(" crc: warning crc_mode is out of range %"PRIu32"\n", db->file.crc_mode); } print_db_info(db); if (db->header.by_id_root) { btreesize += db->header.by_id_root->subtreesize; } if (db->header.by_seq_root) { btreesize += db->header.by_seq_root->subtreesize; } printf(" B-tree size: %s\n", size_str(btreesize)); printf(" total disk size: %s\n", size_str(db->file.pos)); if (iterate_headers) { if (couchstore_rewind_db_header(db) == COUCHSTORE_SUCCESS) { printf("\n"); goto next_header; } } else { couchstore_close_file(db); couchstore_free_db(db); } return 0; }
static void exit_error(couchstore_error_t errcode) { fprintf(stderr, "Couchstore error: %s\n", couchstore_strerror(errcode)); exit(-1); }
int main(int argc, char** argv) { if(argc < 3) return usage(); couchstore_error_t errcode; CouchStoreIndex* index = NULL; // Process last arg first: the output filename const char* indexPath = argv[argc - 1]; errcode = couchstore_create_index(indexPath, &index); if (errcode) { fprintf(stderr, "Couldn't open database %s: %s\n", indexPath, couchstore_strerror(errcode)); goto cleanup; } couchstore_index_type indexType = COUCHSTORE_VIEW_PRIMARY_INDEX; const char* reduceName = NULL; couchstore_json_reducer reducer = COUCHSTORE_REDUCE_NONE; for (int i = 1; i < argc - 1; ++i) { const char* inputPath = argv[i]; if (strncmp(inputPath, "--reduce=", 9) == 0) { reduceName = inputPath + 9; if (strcmp(reduceName, "count") == 0) reducer = COUCHSTORE_REDUCE_COUNT; else if (strcmp(reduceName, "sum") == 0) reducer = COUCHSTORE_REDUCE_SUM; else if (strcmp(reduceName, "stats") == 0) reducer = COUCHSTORE_REDUCE_STATS; else { fprintf(stderr, "Unknown reduce function '%s'\n", reduceName); return usage(); } } else if (strcmp(inputPath, "--back") == 0) { indexType = COUCHSTORE_VIEW_BACK_INDEX; } else if (strcmp(inputPath, "--primary") == 0) { indexType = COUCHSTORE_VIEW_PRIMARY_INDEX; } else { if (indexType == COUCHSTORE_VIEW_PRIMARY_INDEX) { printf("Adding primary index %s to %s", inputPath, indexPath); if (reduceName) printf(", reducing by %s", reduceName); printf(" ...\n"); } else { if (reduceName) return usage(); printf("Adding back-index %s to %s...\n", inputPath, indexPath); } errcode = couchstore_index_add(inputPath, indexType, reducer, index); if (errcode < 0) { fprintf(stderr, "Error adding %s: %s\n", inputPath, couchstore_strerror(errcode)); goto cleanup; } indexType = COUCHSTORE_VIEW_PRIMARY_INDEX; reduceName = NULL; reducer = COUCHSTORE_REDUCE_NONE; } } printf("Done!"); cleanup: if (index) { couchstore_close_index(index); if (errcode < 0) { remove(indexPath); } } return errcode ? EXIT_FAILURE : EXIT_SUCCESS; }
void report_error(couchstore_error_t errcode, const char* file, int line) { fprintf(stderr, "Couchstore error `%s' at %s:%d\r\n", \ couchstore_strerror(errcode), file, line); }
static int foldprint(Db *db, DocInfo *docinfo, void *ctx) { int *count = (int *) ctx; Doc *doc = NULL; uint64_t cas; uint32_t expiry, flags; couchstore_error_t docerr; (*count)++; if (dumpJson) { printf("{\"seq\":%"PRIu64",\"id\":\"", docinfo->db_seq); printjquote(&docinfo->id); printf("\","); } else { if (mode == DumpBySequence) { printf("Doc seq: %"PRIu64"\n", docinfo->db_seq); printf(" id: "); printsb(&docinfo->id); } else { printf(" Doc ID: "); printsb(&docinfo->id); if (docinfo->db_seq > 0) { printf(" seq: %"PRIu64"\n", docinfo->db_seq); } } } if (docinfo->bp == 0 && docinfo->deleted == 0 && !dumpJson) { printf(" ** This b-tree node is corrupt; raw node value follows:*\n"); printf(" raw: "); printsbhex(&docinfo->rev_meta, 1); return 0; } if (dumpJson) { printf("\"rev\":%"PRIu64",\"content_meta\":%d,", docinfo->rev_seq, docinfo->content_meta); printf("\"physical_size\":%zu,", docinfo->size); } else { printf(" rev: %"PRIu64"\n", docinfo->rev_seq); printf(" content_meta: %d\n", docinfo->content_meta); printf(" size (on disk): %zu\n", docinfo->size); } if (docinfo->rev_meta.size >= sizeof(CouchbaseRevMeta)) { const CouchbaseRevMeta* meta = (const CouchbaseRevMeta*)docinfo->rev_meta.buf; cas = decode_raw64(meta->cas); expiry = decode_raw32(meta->expiry); flags = decode_raw32(meta->flags); if (dumpJson) { printf("\"cas\":\"%"PRIu64"\",\"expiry\":%"PRIu32",\"flags\":%"PRIu32",", cas, expiry, flags); } else { printf(" cas: %"PRIu64", expiry: %"PRIu32", flags: %"PRIu32"\n", cas, expiry, flags); } } if (docinfo->deleted) { if (dumpJson) { printf("\"deleted\":true,"); } else { printf(" doc deleted\n"); } } if (!noBody) { docerr = couchstore_open_doc_with_docinfo(db, docinfo, &doc, 0); if (docerr != COUCHSTORE_SUCCESS) { if (dumpJson) { printf("\"body\":null}\n"); } else { printf(" could not read document body: %s\n", couchstore_strerror(docerr)); } } else if (doc && (docinfo->content_meta & COUCH_DOC_IS_COMPRESSED)) { size_t rlen; snappy_uncompressed_length(doc->data.buf, doc->data.size, &rlen); char *decbuf = (char *) malloc(rlen); size_t uncompr_len; snappy_uncompress(doc->data.buf, doc->data.size, decbuf, &uncompr_len); sized_buf uncompr_body; uncompr_body.size = uncompr_len; uncompr_body.buf = decbuf; if (dumpJson) { printf("\"size\":%zu,", uncompr_body.size); printf("\"snappy\":true,\"body\":\""); if (dumpHex) { printsbhexraw(&uncompr_body); } else { printjquote(&uncompr_body); } printf("\"}\n"); } else { printf(" size: %zu\n", uncompr_body.size); printf(" data: (snappy) "); if (dumpHex) { printsbhexraw(&uncompr_body); printf("\n"); } else { printsb(&uncompr_body); } } } else if (doc) { if (dumpJson) { printf("\"size\":%zu,", doc->data.size); printf("\"body\":\""); printjquote(&doc->data); printf("\"}\n"); } else { printf(" size: %zu\n", doc->data.size); printf(" data: "); if (dumpHex) { printsbhexraw(&doc->data); printf("\n"); } else { printsb(&doc->data); } } } } else { if (dumpJson) { printf("\"body\":null}\n"); } else { printf("\n"); } } couchstore_free_document(doc); return 0; }