Version 1.1.5
ex_all.c

Demonstrate how to call every method in the API.

/*-
 * Copyright (c) 2008-2012 WiredTiger, Inc.
 *
 * This is free and unencumbered software released into the public domain.
 *
 * Anyone is free to copy, modify, publish, use, compile, sell, or
 * distribute this software, either in source code form or as a compiled
 * binary, for any purpose, commercial or non-commercial, and by any
 * means.
 *
 * In jurisdictions that recognize copyright laws, the author or authors
 * of this software dedicate any and all copyright interest in the
 * software to the public domain. We make this dedication for the benefit
 * of the public at large and to the detriment of our heirs and
 * successors. We intend this dedication to be an overt act of
 * relinquishment in perpetuity of all present and future rights to this
 * software under copyright law.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * ex_all.c
 *      Containing a call to every method in the WiredTiger API.
 *
 *      It doesn't do anything very useful, just demonstrates how to call each
 *      method.  This file is used to populate the API reference with code
 *      fragments.
 */

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

#include <wiredtiger.h>

int add_collator(WT_CONNECTION *conn);
int add_compressor(WT_CONNECTION *conn);
int add_cursor_type(WT_CONNECTION *conn);
int add_extractor(WT_CONNECTION *conn);
int connection_ops(WT_CONNECTION *conn);
int cursor_ops(WT_SESSION *session);
int cursor_search_near(WT_CURSOR *cursor);
int session_ops(WT_SESSION *session);

int
cursor_ops(WT_SESSION *session)
{
        WT_CURSOR *cursor, *other;
        int ret;

        other = NULL;

        ret = session->open_cursor(
            session, "table:mytable", NULL, NULL, &cursor);
        {
        const char *key;        /* Get the cursor's string key. */
        ret = cursor->get_key(cursor, &key);
        }

        {
        uint64_t recno;         /* Get the cursor's record number key. */
        ret = cursor->get_key(cursor, &recno);
        }

        {
        const char *value;      /* Get the cursor's string value. */
        ret = cursor->get_value(cursor, &value);
        }

        {
        WT_ITEM value;          /* Get the cursor's raw value. */
        ret = cursor->get_value(cursor, &value);
        }

        {
                                /* Set the cursor's string key. */
        const char *key = "another key";
        cursor->set_key(cursor, key);
        }

        {
        uint64_t recno = 37;    /* Set the cursor's record number key. */
        cursor->set_key(cursor, recno);
        }

        {
                                /* Set the cursor's string value. */
        const char *value = "another value";
        cursor->set_value(cursor, value);
        }
        {
        WT_ITEM value;          /* Set the cursor's raw value. */
        value.data = "another value";
        value.size = strlen("another value");
        cursor->set_value(cursor, &value);
        }

        ret = cursor->next(cursor);
        ret = cursor->prev(cursor);
        ret = cursor->reset(cursor);
        if (cursor->equals(cursor, other)) {
                /* Take some action. */
        }
        {
        const char *key = "some key";
        cursor->set_key(cursor, key);
        ret = cursor->search(cursor);
        }

        cursor_search_near(cursor);

        {
        /* Insert a new record. */
        const char *key = "some key";
        const char *value = "some value";
        cursor->set_key(cursor, key);
        cursor->set_value(cursor, value);
        ret = cursor->insert(cursor);
        }

        {
        /* Insert a new record or overwrite an existing record. */
        const char *key = "some key";
        const char *value = "some value";
        ret = session->open_cursor(
            session, "table:mytable", NULL, "overwrite", &cursor);
        cursor->set_key(cursor, key);
        cursor->set_value(cursor, value);
        ret = cursor->insert(cursor);
        }

        {
        /* Insert a new record and assign a record number. */
        uint64_t recno;
        const char *value = "some value";
        ret = session->open_cursor(
            session, "table:mytable", NULL, "append", &cursor);
        cursor->set_value(cursor, value);
        ret = cursor->insert(cursor);
        if (ret == 0)
                recno = cursor->get_key(cursor, &recno);
        }

        {
        const char *key = "some key";
        const char *value = "some value";
        cursor->set_key(cursor, key);
        cursor->set_value(cursor, value);
        ret = cursor->update(cursor);
        }

        {
        const char *key = "some key";
        cursor->set_key(cursor, key);
        ret = cursor->remove(cursor);
        }

        {
        const char *key = "some key";
        cursor->set_key(cursor, key);
        if ((ret = cursor->remove(cursor)) != 0) {
                fprintf(stderr,
                    "cursor.remove: %s\n", wiredtiger_strerror(ret));
                return (ret);
        }
        }

        ret = cursor->close(cursor);
        return (ret);
}

int
cursor_search_near(WT_CURSOR *cursor)
{
        int exact, ret;
        const char *key = "some key";

        cursor->set_key(cursor, key);
        ret = cursor->search_near(cursor, &exact);
        if (ret == 0) {
                if (exact == 0) {
                        /* an exact match */
                } else if (exact < 0) {
                        /* returned smaller key */
                } else if (exact > 0) {
                        /* returned larger key */
                }
        }
        /*
         * An example of a forward scan through the table, where all keys
         * greater than or equal to a specified prefix are included in the
         * scan.
         */
        cursor->set_key(cursor, key);
        ret = cursor->search_near(cursor, &exact);
        if (ret == 0 && exact >= 0) {
                /* include first key returned in the scan */
        }

        while ((ret = cursor->next(cursor)) == 0) {
                /* the rest of the scan */
        }
        /*
         * An example of a backward scan through the table, where all keys
         * less than a specified prefix are included in the scan.
         */
        cursor->set_key(cursor, key);
        ret = cursor->search_near(cursor, &exact);
        if (ret == 0 && exact < 0) {
                /* include first key returned in the scan */
        }

        while ((ret = cursor->prev(cursor)) == 0) {
                /* the rest of the scan */
        }
        return (ret);
}

int
session_ops(WT_SESSION *session)
{
        unsigned long mypid = 0;
        int ret;

        cursor_ops(session);

        ret = session->create(session, "table:mytable",
            "key_format=S,value_format=S");
        ret = session->checkpoint(session, NULL);
        ret = session->drop(session, "table:mytable", NULL);
        ret = session->dumpfile(session, "file:myfile", NULL);
        ret = session->msg_printf(session, "process pid %lu", mypid);
        ret = session->rename(session, "table:old", "table:new", NULL);
        ret = session->salvage(session, "table:mytable", NULL);
        ret = session->sync(session, "table:mytable", NULL);
        ret = session->truncate(session, "table:mytable", NULL, NULL, NULL);
        {
        WT_CURSOR *start, *stop;

        ret = session->open_cursor(
            session, "table:mytable", NULL, NULL, &start);
        start->set_key(start, "June01");
        ret = start->search(start);

        ret = session->open_cursor(
            session, "table:mytable", NULL, NULL, &stop);
        stop->set_key(stop, "June30");
        ret = stop->search(stop);

        ret = session->truncate(session, NULL, start, stop, NULL);
        }

        ret = session->upgrade(session, "table:mytable", NULL);
        ret = session->verify(session, "table:mytable", NULL);
        ret = session->begin_transaction(session, NULL);
        ret = session->commit_transaction(session, NULL);
        ret = session->rollback_transaction(session, NULL);
        ret = session->close(session, NULL);
        return (ret);
}

static int
my_cursor_size(WT_CURSOR_TYPE *ctype, const char *obj, size_t *sizep)
{
        (void)ctype;
        (void)obj;

        *sizep = sizeof (WT_CURSOR);
        return (0);
}
static int
my_init_cursor(WT_CURSOR_TYPE *ctype, WT_SESSION *session,
    const char *obj, WT_CURSOR *old_cursor, const char *config,
    WT_CURSOR *new_cursor)
{
        /* Unused parameters */
        (void)ctype;
        (void)session;
        (void)obj;
        (void)old_cursor;
        (void)config;
        (void)new_cursor;

        return (0);
}
int
add_cursor_type(WT_CONNECTION *conn)
{
        int ret;

        static WT_CURSOR_TYPE my_ctype = { my_cursor_size, my_init_cursor };
        ret = conn->add_cursor_type(conn, NULL, &my_ctype, NULL);
        return (ret);
}

/*
 * A simple example of the collator API: compare the keys as strings.
 */
static int
my_compare(WT_COLLATOR *collator, WT_SESSION *session,
    const WT_ITEM *value1, const WT_ITEM *value2, int *cmp)
{
        const char *p1, *p2;

        /* Unused parameters */
        (void)collator;
        (void)session;

        p1 = (const char *)value1->data;
        p2 = (const char *)value2->data;
        while (*p1 != '\0' && *p1 == *p2)
                p1++, p2++;

        *cmp = (int)*p2 - (int)*p1;
        return (0);
}
int
add_collator(WT_CONNECTION *conn)
{
        int ret;

        static WT_COLLATOR my_collator = { my_compare };
        ret = conn->add_collator(conn, "my_collator", &my_collator, NULL);
        return (ret);
}

/*
 * A simple compression example that passes data through unchanged.
 */
static int
my_compress(WT_COMPRESSOR *compressor, WT_SESSION *session,
    uint8_t *src, size_t src_len,
    uint8_t *dst, size_t dst_len,
    size_t *result_lenp, int *compression_failed)
{
        /* Unused parameters */
        (void)compressor;
        (void)session;

        *compression_failed = 0;
        if (dst_len < src_len) {
                *compression_failed = 1;
                return (0);
        }
        memcpy(dst, src, src_len);
        *result_lenp = src_len;
        return (0);
}
/*
 * A simple decompression example that passes data through unchanged.
 */
static int
my_decompress(WT_COMPRESSOR *compressor, WT_SESSION *session,
    uint8_t *src, size_t src_len,
    uint8_t *dst, size_t dst_len,
    size_t *result_lenp)
{
        /* Unused parameters */
        (void)compressor;
        (void)session;

        if (dst_len < src_len)
                return (ENOMEM);

        memcpy(dst, src, src_len);
        *result_lenp = src_len;
        return (0);
}
/*
 * A simple pre-size example that returns the source length.
 */
static int
my_pre_size(WT_COMPRESSOR *compressor, WT_SESSION *session,
    uint8_t *src, size_t src_len,
    size_t *result_lenp)
{
        /* Unused parameters */
        (void)compressor;
        (void)session;
        (void)src;

        *result_lenp = src_len;
        return (0);
}
int
add_compressor(WT_CONNECTION *conn)
{
        int ret;
        
        static WT_COMPRESSOR my_compressor = {
            my_compress, my_decompress, my_pre_size };
        ret = conn->add_compressor(conn, "my_compress", &my_compressor, NULL);
        return (ret);
}

static int
my_extract(WT_EXTRACTOR *extractor, WT_SESSION *session,
    const WT_ITEM *key, const WT_ITEM *value,
    WT_ITEM *result)
{
        /* Unused parameters */
        (void)extractor;
        (void)session;
        (void)key;

        *result = *value;
        return (0);
}
int
add_extractor(WT_CONNECTION *conn)
{
        int ret;

        static WT_EXTRACTOR my_extractor;
        my_extractor.extract = my_extract;
        ret = conn->add_extractor(conn, "my_extractor", &my_extractor, NULL);
        return (ret);
}

int
connection_ops(WT_CONNECTION *conn)
{
        int ret;

        ret = conn->load_extension(conn, "my_extension.dll", NULL);
        add_cursor_type(conn);
        add_collator(conn);
        add_extractor(conn);

        ret = conn->close(conn, NULL);
        printf("The database home is %s\n", conn->get_home(conn));
        if (conn->is_new(conn)) {
                /* First time initialization. */
        }
        {
        WT_SESSION *session;
        ret = conn->open_session(conn, NULL, NULL, &session);
        session_ops(session);
        }

        return (ret);
}

int main(void)
{
        int ret;

        {
        WT_CONNECTION *conn;
        const char *home = "WT_TEST";
        ret = wiredtiger_open(home, NULL, "create,transactional", &conn);
        }

        {
        size_t size;
        size = wiredtiger_struct_size("iSh", 42, "hello", -3);
        assert(size < 100);
        }

        {
        char buf[100];
        ret = wiredtiger_struct_pack(buf, sizeof (buf), "iSh", 42, "hello", -3);
        {
        int i;
        char *s;
        short h;
        ret = wiredtiger_struct_unpack(buf, sizeof (buf), "iSh", &i, &s, &h);
        }
        }

        printf("WiredTiger version %s\n", wiredtiger_version(NULL, NULL, NULL));
        {
        int major, minor, patch;
        (void)wiredtiger_version(&major, &minor, &patch);
        printf("WiredTiger version is %d, %d (patch %d)\n",
            major, minor, patch);
        }

        return (ret);
}