1/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2#ifndef COUCHSTORE_COUCH_DB_H
3#define COUCHSTORE_COUCH_DB_H
4
5#include "couch_common.h"
6
7#include <libcouchstore/error.h>
8#include <libcouchstore/file_ops.h>
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14    /*///////////////////  OPENING/CLOSING DATABASES: */
15
16    /*
17     * Flags to pass as the flags parameter to couchstore_open_db
18     */
19    typedef uint64_t couchstore_open_flags;
20
21    /**
22     * Create a new empty .couch file if file doesn't exist.
23     */
24    const uint64_t COUCHSTORE_OPEN_FLAG_CREATE = 1;
25
26    /**
27     * Open the database in read only mode
28     */
29    const uint64_t COUCHSTORE_OPEN_FLAG_RDONLY = 2;
30
31    /**
32     * Require the database to use the legacy CRC.
33     * This forces the disk_version flag to be 11 and is only valid for new
34     * files and existing version 11 files. When excluded the correct CRC is
35     * automatically chosen for existing files. When excluded the latest
36     * file version is always used for new files.
37     */
38    const uint64_t COUCHSTORE_OPEN_WITH_LEGACY_CRC = 4;
39
40    /**
41     * Open the database file without using an IO buffer
42     *
43     * This prevents the FileOps that are used in from being
44     * wrapped by the buffered file operations. This will
45     * *usually* result in performance degradation and is
46     * primarily intended for testing purposes.
47     */
48    const uint64_t COUCHSTORE_OPEN_FLAG_UNBUFFERED = 8;
49
50    /**
51     * Customize IO buffer configurations.
52     *
53     * This specifies the capacity of a read buffer and its count.
54     * The first 4 bits are for the capacity; that will be calculated as:
55     *     1KB * 1 << (N-1)
56     * And the next 4 bits are for the count:
57     *     8 * 1 << (N-1)
58     * Note that all zeros represent the default setting.
59     */
60    const uint64_t COUCHSTORE_OPEN_WITH_CUSTOM_BUFFER = 0xff00;
61
62    /**
63     * Customize B+tree node size.
64     *
65     * This specifies the size of B+tree node.
66     * The first 4 bits represents the size of key-pointer
67     * (i.e., intermediate) nodes in KB, and the next 4 bits denotes
68     * the size of key-value (i.e., leaf) nodes in KB.
69     * Note that all zeros represent the default setting,
70     * 1279 (0x4ff) bytes.
71     */
72    const uint64_t COUCHSTORE_OPEN_WITH_CUSTOM_NODESIZE = 0xff0000;
73
74    /**
75     * Enable periodic sync().
76     *
77     * Automatically perform a sync() call after every N bytes written.
78     *
79     * When writing large amounts of data (e.g during compaction), read
80     * latency can be adversely affected if a single sync() is made at the
81     * end of writing all the data, as the IO subsystem has a large amount
82     * of outstanding writes to flush to disk. By issuing periodic syncs
83     * the affect on read latency can be signifcantly reduced.
84     *
85     * Encoded as a power-of-2 KB value, ranging from 1KB .. 1TB (5 bits):
86     *     1KB * << (N-1)
87     *
88     * A value of N=0 specifies that automatic fsync is disabled.
89     */
90    const uint64_t COUCHSTORE_OPEN_WITH_PERIODIC_SYNC = 0x1f000000;
91
92    /**
93     * Enable tracing and verification.
94     *
95     * Flags to turn on tracing and perform other validations to
96     * help detect corruption.
97     *
98     * The operations performed on a couchstore file can be traced using
99     * the phoshpor tracing library.
100     * Checks to validate data that was written was passed on correctly to
101     * OS. If needed, the internal iobuffer can be used in a protected mode
102     * and trigger a fault if accessed by other threads.
103     *
104     * TRACING          - 0x20000000 Enable tracing
105     * WRITE_VALIDATION - 0x40000000 validation of data writes
106     * MPROTECT         - 0x60000000 mprotect of internal iobuffer
107     */
108    const uint64_t COUCHSTORE_OPEN_WITH_TRACING = 0x20000000;
109    const uint64_t COUCHSTORE_OPEN_WITH_WRITE_VALIDATION = 0x40000000;
110    const uint64_t COUCHSTORE_OPEN_WITH_MPROTECT = 0x800000000;
111
112    /**
113     * Encode a periodic sync specified in bytes to the correct
114     * couchstore_open_flags encoding.
115     * @param fsync period in bytes
116     * @return encoded open_flags value, ranging from 1KB to 1TB. Rounded down
117     *         to nearest power-of-2.
118     */
119    LIBCOUCHSTORE_API
120    couchstore_open_flags couchstore_encode_periodic_sync_flags(uint64_t bytes);
121
122    /**
123     * Open a database.
124     *
125     * The database should be closed with couchstore_close_db().
126     *
127     * @param filename The name of the file containing the database
128     * @param flags Additional flags for how the database should
129     *              be opened. See couchstore_open_flags_* for the
130     *              available flags.
131     * @param db Pointer to where you want the handle to the database to be
132     *           stored.
133     * @return COUCHSTORE_SUCCESS for success
134     */
135    LIBCOUCHSTORE_API
136    couchstore_error_t couchstore_open_db(const char *filename,
137                                          couchstore_open_flags flags,
138                                          Db **db);
139
140    /**
141     * Open a database, with custom I/O callbacks.
142     *
143     * The database should be closed with couchstore_close_db().
144     *
145     * @param filename The name of the file containing the database
146     * @param flags Additional flags for how the database should
147     *              be opened. See couchstore_open_flags_* for the
148     *              available flags.
149     * @param ops Pointer to the implementation of FileOpsInterface
150     *            you want the library to use.
151     * @param db Pointer to where you want the handle to the database to be
152     *           stored.
153     * @return COUCHSTORE_SUCCESS for success
154     */
155    LIBCOUCHSTORE_API
156    couchstore_error_t couchstore_open_db_ex(const char *filename,
157                                             couchstore_open_flags flags,
158                                             FileOpsInterface* ops,
159                                             Db **db);
160
161    /**
162     * Release all resources held by the database handle after the file
163     * has been closed.
164     *
165     * This should be called *after* couchstore_close_file(db).
166     *
167     * @param db Pointer to the database handle to free.
168     * @return COUCHSTORE_SUCCESS upon success
169     */
170    LIBCOUCHSTORE_API
171    couchstore_error_t couchstore_free_db(Db* db);
172
173
174    /**
175     * Close the file handle associated with this database handle.
176     *
177     * This does not free the resources held by the database handle. These
178     * resources should be released by subsequently calling
179     * couchstore_free_db(db).
180     *
181     * @param db Pointer to the database handle to drop the file from.
182     * @return COUCHSTORE_SUCCESS upon success
183     */
184    LIBCOUCHSTORE_API
185    couchstore_error_t couchstore_close_file(Db* db);
186
187    /**
188     * Rewind a db handle to the next-oldest header still present in the file.
189     * If there is no next-oldest header, the db handle will be *closed*, and
190     * COUCHSTORE_DB_NO_LONGER_VALID will be returned.
191     *
192     * @param db The database handle to rewind
193     * @return COUCHSTORE_SUCCESS upon success, COUCHSTORE_DB_NO_LONGER_VALID if
194     * no next-oldest header was found.
195     */
196    LIBCOUCHSTORE_API
197    couchstore_error_t couchstore_rewind_db_header(Db *db);
198
199    /**
200     * Get the default FileOpsInterface object
201     */
202    LIBCOUCHSTORE_API
203    FileOpsInterface* couchstore_get_default_file_ops(void);
204
205    /**
206     * Get information about the database.
207     *
208     * @param db Pointer to the database handle.
209     * @param info Pointer to where you want the info to be stored.
210     * @return COUCHSTORE_SUCCESS upon success
211     */
212    LIBCOUCHSTORE_API
213    couchstore_error_t couchstore_db_info(Db *db, DbInfo* info);
214
215
216    /**
217     * Returns the filename of the database, as given when it was opened.
218     *
219     * @param db Pointer to the database handle.
220     * @return Pointer to filename (path). This is an exact copy of the filename given to
221     *         couchstore_open_db.
222     */
223    LIBCOUCHSTORE_API
224    const char* couchstore_get_db_filename(Db *db);
225
226#ifdef __cplusplus
227    /**
228     * Return file handle statistics of the database's underlying file handle.
229     *
230     * @return A non-null pointer to a FileStats instance if the
231     *         database's file ops support file statistics, otherwise
232     *         returns nullptr.
233     */
234    LIBCOUCHSTORE_API
235    FileOpsInterface::FHStats* couchstore_get_db_filestats(Db* db);
236#endif
237
238    /**
239     * Get the position in the file of the mostly recently written
240     * database header.
241     */
242    LIBCOUCHSTORE_API
243    uint64_t couchstore_get_header_position(Db *db);
244
245
246    /*////////////////////  WRITING DOCUMENTS: */
247
248    /*
249     * Options used by couchstore_save_document() and
250     * couchstore_save_documents():
251     */
252    typedef uint64_t couchstore_save_options;
253    enum {
254        /**
255         * Snappy compress document data if the high bit of the
256         * content_meta field of the DocInfo is set. This is NOT the
257         * default, and if this is not set the data field of the Doc will
258         * be written to disk as-is, regardless of the content_meta flags.
259         */
260        COMPRESS_DOC_BODIES = 1,
261        /**
262         * Store the DocInfo's passed in db_seq as is.
263         *
264         * Couchstore will *not* assign it a new sequence number, but store the
265         * sequence number as given. The update_seq for the DB will be set to
266         * at least this sequence.
267         * */
268        COUCHSTORE_SEQUENCE_AS_IS = 2
269    };
270
271    /**
272     * Save document pointed to by doc and docinfo to db.
273     *
274     * When saving documents you should only set the id, rev_meta,
275     * rev_seq, deleted, and content_meta fields on the DocInfo.
276     *
277     * To delete a docuemnt, set doc to NULL.
278     *
279     * On return, the db_seq field of the DocInfo will be filled in with the
280     * document's (or deletion's) sequence number.
281     *
282     * @param db database to save the document in
283     * @param doc the document to save
284     * @param info document info
285     * @param options see descrtiption of COMPRESS_DOC_BODIES below
286     * @return COUCHSTORE_SUCCESS upon success
287     */
288    LIBCOUCHSTORE_API
289    couchstore_error_t couchstore_save_document(Db *db,
290                                                const Doc *doc,
291                                                DocInfo *info,
292                                                couchstore_save_options options);
293
294    /**
295     * Save array of docs to db
296     *
297     * To delete documents, set docs to NULL: the docs referenced by
298     * the docinfos will be deleted. To intermix deletes and inserts
299     * in a bulk update, pass docinfos with the deleted flag set.
300     *
301     * On return, the db_seq fields of the DocInfos will be filled in with the
302     * documents' (or deletions') sequence numbers.
303     *
304     * @param db the database to save documents in
305     * @param docs an array of document pointers
306     * @param infos an array of docinfo pointers
307     * @param numDocs the number documents to save
308     * @param options see descrtiption of COMPRESS_DOC_BODIES below
309     * @return COUCHSTORE_SUCCESS upon success
310     */
311    LIBCOUCHSTORE_API
312    couchstore_error_t couchstore_save_documents(Db *db,
313                                                 Doc* const docs[],
314                                                 DocInfo *infos[],
315                                                 unsigned numDocs,
316                                                 couchstore_save_options options);
317    /**
318     * Commit all pending changes and flush buffers to persistent storage.
319     *
320     * @param db database to perform the commit on
321     * @return COUCHSTORE_SUCCESS on success
322     */
323    LIBCOUCHSTORE_API
324    couchstore_error_t couchstore_commit(Db *db);
325
326
327    /*////////////////////  RETRIEVING DOCUMENTS: */
328
329    /**
330     * Retrieve the document info for a given key.
331     *
332     * The info should be freed with couchstore_free_docinfo().
333     *
334     * @param id the document identifier
335     * @param idlen the number of bytes in the identifier
336     * @param pInfo where to store the result
337     * @return COUCHSTORE_SUCCESS on success.
338     */
339    LIBCOUCHSTORE_API
340    couchstore_error_t couchstore_docinfo_by_id(Db *db,
341                                                const void *id,
342                                                size_t idlen,
343                                                DocInfo **pInfo);
344
345    /**
346     * Retrieve the document info for a given sequence number.
347     *
348     * To look up multiple sequences, it's more efficient to call couchstore_docinfos_by_sequence.
349     *
350     * @param sequence the document sequence number
351     * @param pInfo where to store the result. Must be freed with couchstore_free_docinfo().
352     * @return COUCHSTORE_SUCCESS on success.
353     */
354    LIBCOUCHSTORE_API
355    couchstore_error_t couchstore_docinfo_by_sequence(Db *db,
356                                                      uint64_t sequence,
357                                                      DocInfo **pInfo);
358
359    /** Options flags for open_doc and open_doc_with_docinfo */
360    typedef uint64_t couchstore_open_options;
361    enum {
362        /* Snappy decompress document data if the high bit of the content_meta field
363         * of the DocInfo is set.
364         * This is NOT the default, and if this is not set the data field of the Doc
365         * will be read from disk as-is, regardless of the content_meta flags. */
366        DECOMPRESS_DOC_BODIES = 1
367    };
368
369    /**
370     * Retrieve a doc from the db.
371     *
372     * The document should be freed with couchstore_free_document()
373     *
374     * On a successful return, doc.id.buf will point to the id you passed in,
375     * so don't free or overwrite the id buffer before freeing the document!
376     *
377     * @param db database to load document from
378     * @param id the identifier to load
379     * @param idlen the number of bytes in the id
380     * @param pDoc Where to store the result
381     * @param options See DECOMPRESS_DOC_BODIES
382     * @return COUCHSTORE_SUCCESS if found
383     */
384    LIBCOUCHSTORE_API
385    couchstore_error_t couchstore_open_document(Db *db,
386                                                const void *id,
387                                                size_t idlen,
388                                                Doc **pDoc,
389                                                couchstore_open_options options);
390
391    /**
392     * Retrieve a doc from the db, using a DocInfo.
393     * The DocInfo must have been filled in with valid values by an API call such
394     * as couchstore_docinfo_by_id().
395     *
396     * Do not free the docinfo before freeing the doc, with couchstore_free_document().
397     *
398     * @param db database to load document from
399     * @param docinfo a valid DocInfo, as filled in by couchstore_docinfo_by_id()
400     * @param pDoc Where to store the result
401     * @param options See DECOMPRESS_DOC_BODIES
402     * @return COUCHSTORE_SUCCESS if found
403     */
404    LIBCOUCHSTORE_API
405    couchstore_error_t couchstore_open_doc_with_docinfo(Db *db,
406                                                        const DocInfo *docinfo,
407                                                        Doc **pDoc,
408                                                        couchstore_open_options options);
409
410    /**
411     * Free all allocated resources from a document returned from
412     * couchstore_open_document().
413     *
414     * @param doc the document to free. May be NULL.
415     */
416    LIBCOUCHSTORE_API
417    void couchstore_free_document(Doc *doc);
418
419
420    /**
421     * Allocates a new DocInfo structure on the heap, plus optionally its id and rev_meta.
422     * If the id or rev_meta are given, their values will be copied into the allocated memory
423     * and the corresponding fields in the returned DocInfo will point there. Otherwise the
424     * DocInfo's id and/or rev_meta fields will be empty/null.
425     * @param id the document ID to copy into the DocInfo, or NULL to leave its ID NULL.
426     * @param rev_meta the revision metadata to copy into the DocInfo, or NULL to leave its
427     *          rev_meta NULL.
428     * @return the allocated DocInfo, or NULL on an allocation failure. Must be freed by
429     *          calling couchstore_free_docinfo.
430     */
431    LIBCOUCHSTORE_API
432    DocInfo* couchstore_alloc_docinfo(const sized_buf *id,
433                                      const sized_buf *rev_meta);
434
435
436    /**
437     * Free all allocated resources from a docinfo structure returned by
438     * couchstore_docinfo_by_id() or passed to a couchstore_changes_callback_fn.
439     *
440     * @param docinfo the document info to free. May be NULL.
441     */
442    LIBCOUCHSTORE_API
443    void couchstore_free_docinfo(DocInfo *docinfo);
444
445
446    /*////////////////////  ITERATING DOCUMENTS: */
447
448    /**
449     * The callback function used by couchstore_changes_since(), couchstore_docinfos_by_id()
450     * and couchstore_docinfos_by_sequence() to iterate through the documents.
451     *
452     * The docinfo structure is automatically freed if the callback
453     * returns 0. A positive return value will preserve the DocInfo
454     * for future use (should be freed with free_docinfo by the
455     * caller). A negative return value will cancel the iteration and
456     * pass the error value back to the caller.
457     *
458     * @param db the database being traversed
459     * @param docinfo the current document
460     * @param ctx user context
461     * @return 1 to preserve the DocInfo, 0 or negative error value to free it (see above).
462     */
463    typedef int (*couchstore_changes_callback_fn)(Db *db,
464                                                  DocInfo *docinfo,
465                                                  void *ctx);
466
467    /** Options flags for document iteration */
468    typedef uint64_t couchstore_docinfos_options;
469    enum {
470        /* If set, the sequences/ids lists are interpreted as pairs of range endpoints,
471         * and all documents within those ranges will be iterated over.
472         */
473        RANGES = 1,
474        /**
475         * Send only deleted items.
476         */
477        COUCHSTORE_DELETES_ONLY = 2,
478        /**
479         * Send only non-deleted items.
480         */
481        COUCHSTORE_NO_DELETES = 4,
482        /**
483         * If set, corrupted B+tree nodes or documents will be tolerated
484         * to collect as much data as possible.
485         */
486        COUCHSTORE_TOLERATE_CORRUPTION = 8
487    };
488
489    /**
490     * Iterate through the changes since sequence number `since`.
491     *
492     * @param db the database to iterate through
493     * @param since the sequence number to start iterating from
494     * @param options COUCHSTORE_DELETES_ONLY and COUCHSTORE_NO_DELETES are supported
495     * @param callback the callback function used to iterate over all changes
496     * @param ctx client context (passed to the callback)
497     * @return COUCHSTORE_SUCCESS upon success
498     */
499    LIBCOUCHSTORE_API
500    couchstore_error_t couchstore_changes_since(Db *db,
501                                                uint64_t since,
502                                                couchstore_docinfos_options options,
503                                                couchstore_changes_callback_fn callback,
504                                                void *ctx);
505
506    /**
507     * Iterate through all documents in order by key.
508     *
509     * @param db the database to iterate through
510     * @param startKeyPtr  The key to start at, or NULL to start from the beginning
511     * @param options COUCHSTORE_DELETES_ONLY and COUCHSTORE_NO_DELETES are supported
512     * @param callback the callback function used to iterate over all documents
513     * @param ctx client context (passed to the callback)
514     * @return COUCHSTORE_SUCCESS upon success
515     */
516    LIBCOUCHSTORE_API
517    couchstore_error_t couchstore_all_docs(Db *db,
518                                           const sized_buf* startKeyPtr,
519                                           couchstore_docinfos_options options,
520                                           couchstore_changes_callback_fn callback,
521                                           void *ctx);
522
523    /**
524     * Iterate over the document infos of a set of sequence numbers.
525     *
526     * The DocInfos will be presented to the callback in order of ascending sequence
527     * number, *not* in the order in which they appear in the sequence[] array.
528     *
529     * If the RANGES option flag is set, the sequences array is interpreted as
530     * alternating begin/end points of ranges, and all DocInfos within those ranges
531     * are iterated over. (If there is an odd number of sequences, the iteration will
532     * stop at the last sequence.)
533     *
534     * The callback will not be invoked for nonexistent sequence numbers.
535     *
536     * @param sequence array of document sequence numbers. Need not be sorted but must not contain
537     *          duplicates.
538     * @param numDocs number of documents to look up (size of sequence[] array)
539     * @param options Set the RANGES bit for range mode (see above)
540     * @param callback the callback function used to iterate over document infos
541     * @param ctx client context (passed to the callback)
542     * @return COUCHSTORE_SUCCESS on success.
543     */
544    LIBCOUCHSTORE_API
545    couchstore_error_t couchstore_docinfos_by_sequence(Db *db,
546                                                       const uint64_t sequence[],
547                                                       unsigned numDocs,
548                                                       couchstore_docinfos_options options,
549                                                       couchstore_changes_callback_fn callback,
550                                                       void *ctx);
551
552    /**
553     * Iterate over the document infos of a set of ids.
554     *
555     * The DocInfos will be presented to the callback in order of ascending document id,
556     * *not* in the order in which they appear in the ids[] array.
557     *
558     * If the RANGES option flag is set, the ids array is interpreted as alternating
559     * begin/end points of ranges, and all DocInfos with IDs within those ranges
560     * are iterated over. (If there is an odd number of IDs, the iteration will
561     * stop at the last ID.)
562     *
563     * The callback will not be invoked for nonexistent ids.
564     *
565     * @param ids array of document ids. Need not be sorted but must not contain
566     *          duplicates.
567     * @param numDocs number of documents to look up (size of ids[] array)
568     * @param options Set the RANGES bit for range mode (see above)
569     * @param callback the callback function used to iterate over document infos
570     * @param ctx client context (passed to the callback)
571     * @return COUCHSTORE_SUCCESS on success.
572     */
573    LIBCOUCHSTORE_API
574    couchstore_error_t couchstore_docinfos_by_id(Db *db,
575                                                 const sized_buf ids[],
576                                                 unsigned numDocs,
577                                                 couchstore_docinfos_options options,
578                                                 couchstore_changes_callback_fn callback,
579                                                 void *ctx);
580
581    /*////////////////////  ITERATING TREES: */
582
583    /**
584     * The callback function used by couchstore_walk_id_tree() and couchstore_walk_seq_tree()
585     * to iterate through the B-tree.
586     *
587     * This function is called both for documents and tree nodes. reduce_value will be non-NULL
588     * for a node; doc_info will be non-NULL for a document.
589     *
590     * The docinfo structure is automatically freed if the callback
591     * returns 0. A positive return value will preserve the DocInfo
592     * for future use (should be freed with free_docinfo by the
593     * caller). A negative return value will cancel the iteration and
594     * pass the error value back to the caller.
595     *
596     * @param db the database being traversed
597     * @param depth the current depth in the tree (the root node is 0, and documents are one level
598     *          deeper than their leaf nodes)
599     * @param doc_info the current document, or NULL if this is a tree node
600     * @param subtree_size the on-disk size of this tree node and its children, or 0 for a document
601     * @param reduce_value the reduce data of this node, or NULL for a document
602     * @param ctx user context
603     * @return 1 to preserve the DocInfo, 0 to free it, or a negative error code to abort iteration.
604     */
605    typedef int (*couchstore_walk_tree_callback_fn)(Db *db,
606                                                    int depth,
607                                                    const DocInfo* doc_info,
608                                                    uint64_t subtree_size,
609                                                    const sized_buf* reduce_value,
610                                                    void *ctx);
611
612    /**
613     * Iterate through the by-ID B-tree, including interior and leaf nodes as well as documents.
614     *
615     * The iteration is depth-first, in order by document ID. The callback is invoked on a tree
616     * node before its children. The first call is for the root node.
617     *
618     * This is only useful for tools that want to examine the B-tree structure or reduced values,
619     * such as couch_dbdump. It's unlikely that applications will need to use it.
620     *
621     * @param db the database to iterate through
622     * @param startDocID  The key to start at, or NULL to start from the beginning
623     * @param options COUCHSTORE_DELETES_ONLY and COUCHSTORE_NO_DELETES are supported
624     * @param callback the callback function used to iterate over all documents
625     * @param ctx client context (passed to the callback)
626     * @return COUCHSTORE_SUCCESS upon success
627     */
628    LIBCOUCHSTORE_API
629    couchstore_error_t couchstore_walk_id_tree(Db *db,
630                                               const sized_buf* startDocID,
631                                               couchstore_docinfos_options options,
632                                               couchstore_walk_tree_callback_fn callback,
633                                               void *ctx);
634
635    /**
636     * Iterate through the by-sequence B-tree, including interior and leaf nodes as well as documents.
637     *
638     * The iteration is depth-first, in order by sequence. The callback is invoked on a tree
639     * node before its children. The first call is for the root node.
640     *
641     * This is only useful for tools that want to examine the B-tree structure or reduced values,
642     * such as couch_dbdump. It's unlikely that applications will need to use it.
643     *
644     * @param db the database to iterate through
645     * @param startSequence the sequence number to start from
646     * @param options COUCHSTORE_DELETES_ONLY and COUCHSTORE_NO_DELETES are supported
647     * @param callback the callback function used to iterate over all documents
648     * @param ctx client context (passed to the callback)
649     * @return COUCHSTORE_SUCCESS upon success
650     */
651    LIBCOUCHSTORE_API
652    couchstore_error_t couchstore_walk_seq_tree(Db *db,
653                                                uint64_t startSequence,
654                                                couchstore_docinfos_options options,
655                                                couchstore_walk_tree_callback_fn callback,
656                                                void *ctx);
657
658    /*////////////////////  LOCAL DOCUMENTS: */
659
660    /**
661     * Get a local doc from the db.
662     *
663     * The document should be freed with couchstore_free_local_document().
664     *
665     * @param db database to load document from
666     * @param id the identifier to load (must begin with "_local/")
667     * @param idlen the number of bytes in the id
668     * @param lDoc Where to store the result
669     * @return COUCHSTORE_SUCCESS if found
670     */
671    LIBCOUCHSTORE_API
672    couchstore_error_t couchstore_open_local_document(Db *db,
673                                                      const void *id,
674                                                      size_t idlen,
675                                                      LocalDoc **lDoc);
676
677    /**
678     * Save a local doc to the db. Its identifier must begin with "_local/".
679     * To delete an existing doc, set the deleted flag on the LocalDoc
680     * struct. The json buffer will be ignored for a deletion.
681     *
682     * @param db the database to store the document in
683     * @param lDoc the document to store
684     * @return COUCHSTORE_SUCCESS on success
685     */
686    LIBCOUCHSTORE_API
687    couchstore_error_t couchstore_save_local_document(Db *db, LocalDoc *lDoc);
688
689    /*
690     * Free all allocated resources from a LocalDoc obtained from
691     * couchstore_open_local_document().
692     *
693     * @param lDoc document to free
694     */
695    LIBCOUCHSTORE_API
696    void couchstore_free_local_document(LocalDoc *lDoc);
697
698
699    /*////////////////////  UTILITIES: */
700
701    /**
702     * Compact a database. This creates a new DB file with the same data as the
703     * source db, omitting data that is no longer needed.
704     * Will use default couch_file_ops to create and write the target db.
705     *
706     * @param source the source database
707     * @param target_filename the filename of the new database to create.
708     * @return COUCHSTORE_SUCCESS on success
709     */
710    LIBCOUCHSTORE_API
711    couchstore_error_t couchstore_compact_db(Db* source, const char* target_filename);
712
713
714    /*
715     * Flags to pass as the flags parameter to couchstore_compact_db_ex
716     */
717    typedef uint64_t couchstore_compact_flags;
718    enum {
719        /**
720         * Do not copy the tombstones of deleted items into compacted file.
721         */
722        COUCHSTORE_COMPACT_FLAG_DROP_DELETES = 1,
723
724        /**
725         * Upgrade the database whilst compacting.
726         * The only supported upgrade is from version 11 to 12 which
727         * changes the CRC function used.
728         */
729        COUCHSTORE_COMPACT_FLAG_UPGRADE_DB = 2,
730
731        /**
732         * Open the target database file without using an IO buffer
733         *
734         * This prevents the FileOps that are used in from being
735         * wrapped by the buffered file operations. This will
736         * *usually* result in performance degradation and is
737         * primarily intended for testing purposes.
738         */
739        COUCHSTORE_COMPACT_FLAG_UNBUFFERED = 4,
740
741        /**
742         * This flag internally turns on 'error toleration' mode,
743         * so as to migrate as many KV pairs as possible to the new
744         * file, without aborting the task in the middle of compaction.
745         */
746        COUCHSTORE_COMPACT_RECOVERY_MODE = 8,
747
748        /**
749         * Currently unused flag bits.
750         */
751        COUCHSTORE_COMPACT_UNUSED = 0xfffff0,
752
753        /**
754         * Enable periodic sync().
755         *
756         * Automatically perform a sync() call after every N bytes written.
757         * Same encoding as COUCHSTORE_OPEN_WITH_PERIODIC_SYNC - see
758         * couchstore_open_flags for details.
759         */
760        COUCHSTORE_COMPACT_WITH_PERIODIC_SYNC = 0x1f000000,
761    };
762
763    /**
764     * A compactor hook will be given each DocInfo, and can either keep or drop the item
765     * based on its contents.
766     *
767     * It can also return a couchstore error code, which will abort the compaction.
768     *
769     * If a compactor hook is set, COUCHSTORE_COMPACT_FLAG_DROP_DELETES will *not* drop deletes,
770     * but will bump the purge counter. The hook is responsible for dropping deletes.
771     *
772     * The couchstore_docinfo_hook is for editing the docinfo of the item if the rev_meta
773     * section in docinfo is not found to already contain extended metadata.
774     */
775    enum {
776        COUCHSTORE_COMPACT_KEEP_ITEM = 0,
777        COUCHSTORE_COMPACT_DROP_ITEM = 1,
778        // The compact hook might need to see the full body to determine
779        // if it should keep or drop the body. By default the body is
780        // _not_ being read (as we expect that "keep" would be the common
781        // path).
782        COUCHSTORE_COMPACT_NEED_BODY = 2
783    };
784
785    typedef int (*couchstore_compact_hook)(Db* target,
786                                           DocInfo *docinfo,
787                                           sized_buf item, // is {nullptr, 0}
788                                           void *ctx);
789
790    typedef int (*couchstore_docinfo_hook)(DocInfo **docinfo,
791                                           const sized_buf *item);
792
793    /**
794     * Set purge sequence number. This allows the compactor hook to set the highest
795     * purged sequence number into the header once compaction is complete
796     *
797     * @param target any database whose's purge_seq needs to be set
798     * @param purge_seq the sequence number to set into the header's purge_seq.
799     * @return COUCHSTORE_SUCCESS on success
800     */
801    LIBCOUCHSTORE_API
802    couchstore_error_t couchstore_set_purge_seq(Db* target, uint64_t purge_seq);
803
804    /**
805     * Compact a database. This creates a new DB file with the same data as the
806     * source db, omitting data that is no longer needed.
807     * Will use specified couch_file_ops to create and write the target db.
808     *
809     * @param source the source database
810     * @param target_filename the filename of the new database to create.
811     * @param flags flags that change compaction behavior
812     * @param hook time_purge_hook callback
813     * @param dhook get_extmeta_hook callback
814     * @param hook_ctx compaction_ctx struct
815     * @param ops Pointer to the FileOpsInterface implementation
816     *            you want the library to use.
817     * @return COUCHSTORE_SUCCESS on success
818     */
819    LIBCOUCHSTORE_API
820    couchstore_error_t couchstore_compact_db_ex(Db* source, const char* target_filename, uint64_t flags,
821                                                couchstore_compact_hook hook,
822                                                couchstore_docinfo_hook dhook, void* hook_ctx,
823                                                FileOpsInterface* ops);
824
825
826    /*////////////////////  MISC: */
827
828    /**
829     * Convert an error code from couchstore to a textual description. The
830     * text is a constant within the library so you should not try to modify
831     * or free the pointer.
832     *
833     * @param errcode The error code to look up
834     * @return a textual description of the error
835     */
836    LIBCOUCHSTORE_API
837    const char *couchstore_strerror(couchstore_error_t errcode);
838
839    /**
840     * Prints a description of the last OS-level errors that Couchstore
841     * encountered on this thread into buf.
842     *
843     * @param buf The buffer to store the message in
844     * @param size The size of the buffer.
845     */
846    LIBCOUCHSTORE_API
847    couchstore_error_t couchstore_last_os_error(const Db *db,
848                                                 char* buf,
849                                                 size_t size);
850    /**
851     * Prints a description of the last internal error that Couchstore
852     * encountered on this thread into buf.
853     *
854     * @param buf The buffer to store the message in
855     * @param size The size of the buffer.
856     */
857    LIBCOUCHSTORE_API
858    couchstore_error_t couchstore_last_internal_error(const Db *db,
859                                                 char* buf,
860                                                 size_t size);
861
862     /**
863      * Counts the number of changes between two sequence numbers, inclusive.
864      *
865      * @param db The db to count changes in
866      * @param min_seq The minimum sequence to count
867      * @param max_seq The maximum sequence to count
868      * @param count Pointer to uint64_t to store count in
869      * @return COUCHSTORE_SUCCESS on success
870      */
871     LIBCOUCHSTORE_API
872     couchstore_error_t couchstore_changes_count(Db* db,
873                                                 uint64_t min_seq,
874                                                 uint64_t max_seq,
875                                                 uint64_t *count);
876
877#ifdef __cplusplus
878}
879#endif
880#endif
881