diff options
author | Eliot Horowitz <eliot@10gen.com> | 2014-11-04 15:46:40 -0500 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2014-11-05 11:21:19 -0500 |
commit | 5ca2daf551a2c631a5f573cb054406f5d49fbef5 (patch) | |
tree | b0a23d34ffdb376bac0b79ed17b5619cfc0d9b47 /src/third_party/wiredtiger/examples | |
parent | 017704acdfc7517efadb3fab167bba06c025c01a (diff) | |
download | mongo-5ca2daf551a2c631a5f573cb054406f5d49fbef5.tar.gz |
SERVER-15953: add wiredtiger to third_party
Diffstat (limited to 'src/third_party/wiredtiger/examples')
30 files changed, 7520 insertions, 0 deletions
diff --git a/src/third_party/wiredtiger/examples/c/Makefile.am b/src/third_party/wiredtiger/examples/c/Makefile.am new file mode 100644 index 00000000000..adf87c3cc5d --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/Makefile.am @@ -0,0 +1,32 @@ +LDADD = $(top_builddir)/libwiredtiger.la +AM_CPPFLAGS = -I$(top_srcdir)/src/include + +noinst_PROGRAMS = \ + ex_access \ + ex_all \ + ex_async \ + ex_call_center \ + ex_config \ + ex_config_parse \ + ex_cursor \ + ex_data_source \ + ex_extending \ + ex_file \ + ex_hello \ + ex_log \ + ex_pack \ + ex_process \ + ex_schema \ + ex_scope \ + ex_stat \ + ex_thread + +# The examples can be run with no arguments as simple smoke tests +TESTS = $(noinst_PROGRAMS) + +AM_TESTS_ENVIRONMENT = WIREDTIGER_HOME=`mktemp -d WT_HOME.XXXX` ; export WIREDTIGER_HOME ; rm -rf $$WIREDTIGER_HOME ; mkdir $$WIREDTIGER_HOME ; +# automake 1.11 compatibility +TESTS_ENVIRONMENT = $(AM_TESTS_ENVIRONMENT) + +clean-local: + rm -rf WT_HOME* *.core WiredTiger* *.wt diff --git a/src/third_party/wiredtiger/examples/c/ex_access.c b/src/third_party/wiredtiger/examples/c/ex_access.c new file mode 100644 index 00000000000..522db567d71 --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_access.c @@ -0,0 +1,98 @@ +/*- + * Public Domain 2008-2014 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_access.c + * demonstrates how to create and access a simple table. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +static const char *home; + +int +main(void) +{ + /*! [access example connection] */ + WT_CONNECTION *conn; + WT_CURSOR *cursor; + WT_SESSION *session; + const char *key, *value; + int ret; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + /* Open a connection to the database, creating it if necessary. */ + if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0 || + (ret = conn->open_session(conn, NULL, NULL, &session)) != 0) { + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + return (ret); + } + /*! [access example connection] */ + + /*! [access example table create] */ + ret = session->create(session, + "table:access", "key_format=S,value_format=S"); + /*! [access example table create] */ + + /*! [access example cursor open] */ + ret = session->open_cursor(session, + "table:access", NULL, NULL, &cursor); + /*! [access example cursor open] */ + + /*! [access example cursor insert] */ + cursor->set_key(cursor, "key1"); /* Insert a record. */ + cursor->set_value(cursor, "value1"); + ret = cursor->insert(cursor); + /*! [access example cursor insert] */ + + /*! [access example cursor list] */ + ret = cursor->reset(cursor); /* Restart the scan. */ + while ((ret = cursor->next(cursor)) == 0) { + ret = cursor->get_key(cursor, &key); + ret = cursor->get_value(cursor, &value); + + printf("Got record: %s : %s\n", key, value); + } + /*! [access example cursor list] */ + + /*! [access example close] */ + ret = conn->close(conn, NULL); + /*! [access example close] */ + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_all.c b/src/third_party/wiredtiger/examples/c/ex_all.c new file mode 100644 index 00000000000..1339e90eb2c --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_all.c @@ -0,0 +1,1125 @@ +/*- + * Public Domain 2008-2014 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 <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifndef _WIN32 +#include <unistd.h> +#else +#include "windows_shim.h" +#endif +#include <sys/stat.h> + +#include <wiredtiger.h> + +int add_collator(WT_CONNECTION *conn); +int add_extractor(WT_CONNECTION *conn); +int backup(WT_SESSION *session); +int checkpoint_ops(WT_SESSION *session); +int connection_ops(WT_CONNECTION *conn); +int cursor_ops(WT_SESSION *session); +int cursor_search_near(WT_CURSOR *cursor); +int cursor_statistics(WT_SESSION *session); +int pack_ops(WT_SESSION *session); +int session_ops(WT_SESSION *session); +int transaction_ops(WT_CONNECTION *conn, WT_SESSION *session); + +static const char * const progname = "ex_all"; +static const char *home; + +int +cursor_ops(WT_SESSION *session) +{ + WT_CURSOR *cursor; + int ret; + + /*! [Open a cursor] */ + ret = session->open_cursor( + session, "table:mytable", NULL, NULL, &cursor); + /*! [Open a cursor] */ + + /*! [Open a cursor on the metadata] */ + ret = session->open_cursor( + session, "metadata:", NULL, NULL, &cursor); + /*! [Open a cursor on the metadata] */ + + { + WT_CURSOR *duplicate; + const char *key = "some key"; + /*! [Duplicate a cursor] */ + ret = session->open_cursor( + session, "table:mytable", NULL, NULL, &cursor); + cursor->set_key(cursor, key); + ret = cursor->search(cursor); + + /* Duplicate the cursor. */ + ret = session->open_cursor(session, NULL, cursor, NULL, &duplicate); + /*! [Duplicate a cursor] */ + } + + { + WT_CURSOR *overwrite_cursor; + const char *key = "some key", *value = "some value"; + /*! [Reconfigure a cursor] */ + ret = session->open_cursor( + session, "table:mytable", NULL, NULL, &cursor); + cursor->set_key(cursor, key); + + /* Reconfigure the cursor to overwrite the record. */ + ret = session->open_cursor( + session, NULL, cursor, "overwrite", &overwrite_cursor); + ret = cursor->close(cursor); + + overwrite_cursor->set_value(overwrite_cursor, value); + ret = overwrite_cursor->insert(cursor); + /*! [Reconfigure a cursor] */ + } + + { + /*! [boolean configuration string example] */ + ret = session->open_cursor(session, "table:mytable", NULL, + "overwrite", &cursor); + ret = session->open_cursor(session, "table:mytable", NULL, + "overwrite=true", &cursor); + ret = session->open_cursor(session, "table:mytable", NULL, + "overwrite=1", &cursor); + /*! [boolean configuration string example] */ + } + + { + /*! [open a named checkpoint] */ + ret = session->open_cursor(session, + "table:mytable", NULL, "checkpoint=midnight", &cursor); + /*! [open a named checkpoint] */ + } + + { + /*! [open the default checkpoint] */ + ret = session->open_cursor(session, + "table:mytable", NULL, "checkpoint=WiredTigerCheckpoint", &cursor); + /*! [open the default checkpoint] */ + } + + { + /*! [Get the cursor's string key] */ + const char *key; /* Get the cursor's string key. */ + ret = cursor->get_key(cursor, &key); + /*! [Get the cursor's string key] */ + } + + { + /*! [Set the cursor's string key] */ + /* Set the cursor's string key. */ + const char *key = "another key"; + cursor->set_key(cursor, key); + /*! [Set the cursor's string key] */ + } + + { + /*! [Get the cursor's record number key] */ + uint64_t recno; /* Get the cursor's record number key. */ + ret = cursor->get_key(cursor, &recno); + /*! [Get the cursor's record number key] */ + } + + { + /*! [Set the cursor's record number key] */ + uint64_t recno = 37; /* Set the cursor's record number key. */ + cursor->set_key(cursor, recno); + /*! [Set the cursor's record number key] */ + } + + { + /*! [Get the cursor's composite key] */ + /* Get the cursor's "SiH" format composite key. */ + const char *first; + int32_t second; + uint16_t third; + ret = cursor->get_key(cursor, &first, &second, &third); + /*! [Get the cursor's composite key] */ + } + + { + /*! [Set the cursor's composite key] */ + /* Set the cursor's "SiH" format composite key. */ + cursor->set_key(cursor, "first", (int32_t)5, (uint16_t)7); + /*! [Set the cursor's composite key] */ + } + + { + /*! [Get the cursor's string value] */ + const char *value; /* Get the cursor's string value. */ + ret = cursor->get_value(cursor, &value); + /*! [Get the cursor's string value] */ + } + + { + /*! [Set the cursor's string value] */ + /* Set the cursor's string value. */ + const char *value = "another value"; + cursor->set_value(cursor, value); + /*! [Set the cursor's string value] */ + } + + { + /*! [Get the cursor's raw value] */ + WT_ITEM value; /* Get the cursor's raw value. */ + ret = cursor->get_value(cursor, &value); + /*! [Get the cursor's raw value] */ + } + + { + /*! [Set the cursor's raw value] */ + WT_ITEM value; /* Set the cursor's raw value. */ + value.data = "another value"; + value.size = strlen("another value"); + cursor->set_value(cursor, &value); + /*! [Set the cursor's raw value] */ + } + + /*! [Return the next record] */ + ret = cursor->next(cursor); + /*! [Return the next record] */ + + /*! [Return the previous record] */ + ret = cursor->prev(cursor); + /*! [Return the previous record] */ + + /*! [Reset the cursor] */ + ret = cursor->reset(cursor); + /*! [Reset the cursor] */ + + { + WT_CURSOR *other = NULL; + /*! [Cursor comparison] */ + int compare; + ret = cursor->compare(cursor, other, &compare); + if (compare == 0) { + /* Cursors reference the same key */ + } else if (compare < 0) { + /* Cursor key less than other key */ + } else if (compare > 0) { + /* Cursor key greater than other key */ + } + /*! [Cursor comparison] */ + } + + { + /*! [Search for an exact match] */ + const char *key = "some key"; + cursor->set_key(cursor, key); + ret = cursor->search(cursor); + /*! [Search for an exact match] */ + } + + ret = cursor_search_near(cursor); + + { + /*! [Insert a new record or overwrite an existing record] */ + /* Insert a new record or overwrite an existing record. */ + const char *key = "some key", *value = "some value"; + ret = session->open_cursor( + session, "table:mytable", NULL, NULL, &cursor); + cursor->set_key(cursor, key); + cursor->set_value(cursor, value); + ret = cursor->insert(cursor); + /*! [Insert a new record or overwrite an existing record] */ + } + + { + /*! [Insert a new record and fail if the record exists] */ + /* Insert a new record and fail if the record exists. */ + const char *key = "some key", *value = "some value"; + ret = session->open_cursor( + session, "table:mytable", NULL, "overwrite=false", &cursor); + cursor->set_key(cursor, key); + cursor->set_value(cursor, value); + ret = cursor->insert(cursor); + /*! [Insert a new record and fail if the record exists] */ + } + + { + /*! [Insert a new record and assign a record number] */ + /* 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) + ret = cursor->get_key(cursor, &recno); + /*! [Insert a new record and assign a record number] */ + } + + { + /*! [Update an existing record or insert a new record] */ + const char *key = "some key", *value = "some value"; + ret = session->open_cursor( + session, "table:mytable", NULL, NULL, &cursor); + cursor->set_key(cursor, key); + cursor->set_value(cursor, value); + ret = cursor->update(cursor); + /*! [Update an existing record or insert a new record] */ + } + + { + /*! [Update an existing record and fail if DNE] */ + const char *key = "some key", *value = "some value"; + ret = session->open_cursor( + session, "table:mytable", NULL, "overwrite=false", &cursor); + cursor->set_key(cursor, key); + cursor->set_value(cursor, value); + ret = cursor->update(cursor); + /*! [Update an existing record and fail if DNE] */ + } + + { + /*! [Remove a record] */ + const char *key = "some key"; + ret = session->open_cursor( + session, "table:mytable", NULL, NULL, &cursor); + cursor->set_key(cursor, key); + ret = cursor->remove(cursor); + /*! [Remove a record] */ + } + + { + /*! [Remove a record and fail if DNE] */ + const char *key = "some key"; + ret = session->open_cursor( + session, "table:mytable", NULL, "overwrite=false", &cursor); + cursor->set_key(cursor, key); + ret = cursor->remove(cursor); + /*! [Remove a record and fail if DNE] */ + } + + { + /*! [Display an error] */ + const char *key = "non-existent key"; + cursor->set_key(cursor, key); + if ((ret = cursor->remove(cursor)) != 0) { + fprintf(stderr, + "cursor.remove: %s\n", wiredtiger_strerror(ret)); + return (ret); + } + /*! [Display an error] */ + } + + /*! [Close the cursor] */ + ret = cursor->close(cursor); + /*! [Close the cursor] */ + + return (ret); +} + +int +cursor_search_near(WT_CURSOR *cursor) +{ + int exact, ret; + const char *key = "some key"; + + /*! [Search for an exact or adjacent match] */ + 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 */ + } + } + /*! [Search for an exact or adjacent match] */ + + /*! [Forward scan greater than or equal] */ + 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 */ + } + /*! [Forward scan greater than or equal] */ + + /*! [Backward scan less than] */ + 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 */ + } + /*! [Backward scan less than] */ + + return (ret); +} + +int +checkpoint_ops(WT_SESSION *session) +{ + int ret; + + /*! [Checkpoint examples] */ + /* Checkpoint the database. */ + ret = session->checkpoint(session, NULL); + + /* Checkpoint of the database, creating a named snapshot. */ + ret = session->checkpoint(session, "name=June01"); + + /* + * Checkpoint a list of objects. + * JSON parsing requires quoting the list of target URIs. + */ + ret = session-> + checkpoint(session, "target=(\"table:table1\",\"table:table2\")"); + + /* + * Checkpoint a list of objects, creating a named snapshot. + * JSON parsing requires quoting the list of target URIs. + */ + ret = session-> + checkpoint(session, "target=(\"table:mytable\"),name=midnight"); + + /* Checkpoint the database, discarding all previous snapshots. */ + ret = session->checkpoint(session, "drop=(from=all)"); + + /* Checkpoint the database, discarding the "midnight" snapshot. */ + ret = session->checkpoint(session, "drop=(midnight)"); + + /* + * Checkpoint the database, discarding all snapshots after and + * including "noon". + */ + ret = session->checkpoint(session, "drop=(from=noon)"); + + /* + * Checkpoint the database, discarding all snapshots before and + * including "midnight". + */ + ret = session->checkpoint(session, "drop=(to=midnight)"); + + /* + * Create a checkpoint of a table, creating the "July01" snapshot and + * discarding the "May01" and "June01" snapshots. + * JSON parsing requires quoting the list of target URIs. + */ + ret = session->checkpoint(session, + "target=(\"table:mytable\"),name=July01,drop=(May01,June01)"); + /*! [Checkpoint examples] */ + + /*! [JSON quoting example] */ + /* + * Checkpoint a list of objects. + * JSON parsing requires quoting the list of target URIs. + */ + ret = session-> + checkpoint(session, "target=(\"table:table1\",\"table:table2\")"); + /*! [JSON quoting example] */ + + return (ret); +} + +int +cursor_statistics(WT_SESSION *session) +{ + WT_CURSOR *cursor; + int ret; + + /*! [Statistics cursor database] */ + ret = session->open_cursor( + session, "statistics:", NULL, NULL, &cursor); + /*! [Statistics cursor database] */ + + /*! [Statistics cursor table] */ + ret = session->open_cursor( + session, "statistics:table:mytable", NULL, NULL, &cursor); + /*! [Statistics cursor table] */ + + /*! [Statistics cursor table fast] */ + ret = session->open_cursor(session, + "statistics:table:mytable", NULL, "statistics=(fast)", &cursor); + /*! [Statistics cursor table fast] */ + + /*! [Statistics clear configuration] */ + ret = session->open_cursor(session, + "statistics:", NULL, "statistics=(fast,clear)", &cursor); + /*! [Statistics clear configuration] */ + + /*! [Statistics cursor clear configuration] */ + ret = session->open_cursor(session, + "statistics:table:mytable", + NULL, "statistics=(all,clear)", &cursor); + /*! [Statistics cursor clear configuration] */ + + return (ret); +} + +int +session_ops(WT_SESSION *session) +{ + int ret; + + /*! [Reconfigure a session] */ + ret = session->reconfigure(session, "isolation=snapshot"); + /*! [Reconfigure a session] */ + + /*! [Create a table] */ + ret = session->create(session, + "table:mytable", "key_format=S,value_format=S"); + /*! [Create a table] */ + ret = session->drop(session, "table:mytable", NULL); + + /*! [Create a column-store table] */ + ret = session->create(session, + "table:mytable", "key_format=r,value_format=S"); + /*! [Create a column-store table] */ + ret = session->drop(session, "table:mytable", NULL); + + /*! [Create a table with columns] */ + /* + * Create a table with columns: keys are record numbers, values are + * (string, signed 32-bit integer, unsigned 16-bit integer). + */ + ret = session->create(session, "table:mytable", + "key_format=r,value_format=SiH," + "columns=(id,department,salary,year-started)"); + /*! [Create a table with columns] */ + ret = session->drop(session, "table:mytable", NULL); + + /* + * This example code gets run, and the compression libraries might not + * be loaded, causing the create to fail. The documentation requires + * the code snippets, use #ifdef's to avoid running it. + */ +#ifdef MIGHT_NOT_RUN + /*! [Create a bzip2 compressed table] */ + ret = session->create(session, + "table:mytable", + "block_compressor=bzip2,key_format=S,value_format=S"); + /*! [Create a bzip2 compressed table] */ + ret = session->drop(session, "table:mytable", NULL); + + /*! [Create a snappy compressed table] */ + ret = session->create(session, + "table:mytable", + "block_compressor=snappy,key_format=S,value_format=S"); + /*! [Create a snappy compressed table] */ + ret = session->drop(session, "table:mytable", NULL); + + /*! [Create a zlib compressed table] */ + ret = session->create(session, + "table:mytable", + "block_compressor=zlib,key_format=S,value_format=S"); + /*! [Create a zlib compressed table] */ + ret = session->drop(session, "table:mytable", NULL); +#endif + + /*! [Configure checksums to uncompressed] */ + ret = session->create(session, "table:mytable", + "key_format=S,value_format=S,checksum=uncompressed"); + /*! [Configure checksums to uncompressed] */ + ret = session->drop(session, "table:mytable", NULL); + + /*! [Configure dictionary compression on] */ + ret = session->create(session, "table:mytable", + "key_format=S,value_format=S,dictionary=1000"); + /*! [Configure dictionary compression on] */ + ret = session->drop(session, "table:mytable", NULL); + + /*! [Configure key prefix compression on] */ + ret = session->create(session, "table:mytable", + "key_format=S,value_format=S,prefix_compression=true"); + /*! [Configure key prefix compression on] */ + ret = session->drop(session, "table:mytable", NULL); + +#ifdef MIGHT_NOT_RUN + /* Requires sync_file_range */ + /*! [os_cache_dirty_max configuration] */ + ret = session->create( + session, "table:mytable", "os_cache_dirty_max=500MB"); + /*! [os_cache_dirty_max configuration] */ + ret = session->drop(session, "table:mytable", NULL); + + /* Requires posix_fadvise */ + /*! [os_cache_max configuration] */ + ret = session->create(session, "table:mytable", "os_cache_max=1GB"); + /*! [os_cache_max configuration] */ + ret = session->drop(session, "table:mytable", NULL); +#endif + /*! [Configure block_allocation] */ + ret = session->create(session, "table:mytable", + "key_format=S,value_format=S,block_allocation=first"); + /*! [Configure block_allocation] */ + ret = session->drop(session, "table:mytable", NULL); + + /*! [Create a cache-resident object] */ + ret = session->create(session, + "table:mytable", "key_format=r,value_format=S,cache_resident=true"); + /*! [Create a cache-resident object] */ + ret = session->drop(session, "table:mytable", NULL); + + { + /* Create a table for the session operations. */ + ret = session->create( + session, "table:mytable", "key_format=S,value_format=S"); + + /*! [Compact a table] */ + ret = session->compact(session, "table:mytable", NULL); + /*! [Compact a table] */ + + /*! [Rename a table] */ + ret = session->rename(session, "table:old", "table:new", NULL); + /*! [Rename a table] */ + + /*! [Salvage a table] */ + ret = session->salvage(session, "table:mytable", NULL); + /*! [Salvage a table] */ + + /*! [Truncate a table] */ + ret = session->truncate(session, "table:mytable", NULL, NULL, NULL); + /*! [Truncate a table] */ + + { + /* + * Insert a pair of keys so we can truncate a range. + */ + WT_CURSOR *cursor; + ret = session->open_cursor( + session, "table:mytable", NULL, NULL, &cursor); + cursor->set_key(cursor, "June01"); + cursor->set_value(cursor, "value"); + ret = cursor->update(cursor); + cursor->set_key(cursor, "June30"); + cursor->set_value(cursor, "value"); + ret = cursor->update(cursor); + ret = cursor->close(cursor); + + { + /*! [Truncate a range] */ + 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); + /*! [Truncate a range] */ + } + } + + /*! [Upgrade a table] */ + ret = session->upgrade(session, "table:mytable", NULL); + /*! [Upgrade a table] */ + + /*! [Verify a table] */ + ret = session->verify(session, "table:mytable", NULL); + /*! [Verify a table] */ + + /*! [Drop a table] */ + ret = session->drop(session, "table:mytable", NULL); + /*! [Drop a table] */ + } + + /*! [Close a session] */ + ret = session->close(session, NULL); + /*! [Close a session] */ + + return (ret); +} + +int +transaction_ops(WT_CONNECTION *conn, WT_SESSION *session) +{ + WT_CURSOR *cursor; + int ret; + + /*! [transaction commit/rollback] */ + /* + * Cursors may be opened before or after the transaction begins, and in + * either case, subsequent operations are included in the transaction. + * Opening cursors before the transaction begins allows applications to + * cache cursors and use them for multiple operations. + */ + ret = + session->open_cursor(session, "table:mytable", NULL, NULL, &cursor); + ret = session->begin_transaction(session, NULL); + + cursor->set_key(cursor, "key"); + cursor->set_value(cursor, "value"); + switch (ret = cursor->update(cursor)) { + case 0: /* Update success */ + ret = session->commit_transaction(session, NULL); + /* + * If commit_transaction succeeds, cursors remain positioned; if + * commit_transaction fails, the transaction was rolled-back and + * and all cursors are reset. + */ + break; + case WT_ROLLBACK: /* Update conflict */ + default: /* Other error */ + ret = session->rollback_transaction(session, NULL); + /* The rollback_transaction call resets all cursors. */ + break; + } + + /* + * Cursors remain open and may be used for multiple transactions. + */ + /*! [transaction commit/rollback] */ + ret = cursor->close(cursor); + + /*! [transaction isolation] */ + /* A single transaction configured for snapshot isolation. */ + ret = + session->open_cursor(session, "table:mytable", NULL, NULL, &cursor); + ret = session->begin_transaction(session, "isolation=snapshot"); + cursor->set_key(cursor, "some-key"); + cursor->set_value(cursor, "some-value"); + ret = cursor->update(cursor); + ret = session->commit_transaction(session, NULL); + /*! [transaction isolation] */ + + /*! [session isolation configuration] */ + /* Open a session configured for read-uncommitted isolation. */ + ret = conn->open_session( + conn, NULL, "isolation=read_uncommitted", &session); + /*! [session isolation configuration] */ + + /*! [session isolation re-configuration] */ + /* Re-configure a session for snapshot isolation. */ + ret = session->reconfigure(session, "isolation=snapshot"); + /*! [session isolation re-configuration] */ + + { + /*! [transaction pinned range] */ + /* Check the transaction ID range pinned by the session handle. */ + uint64_t range; + + ret = session->transaction_pinned_range(session, &range); + /*! [transaction pinned range] */ + } + + return (ret); +} + +/*! [Implement WT_COLLATOR] */ +/* + * 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); +} +/*! [Implement WT_COLLATOR] */ + +int +add_collator(WT_CONNECTION *conn) +{ + int ret; + + /*! [WT_COLLATOR register] */ + static WT_COLLATOR my_collator = { my_compare, NULL, NULL }; + ret = conn->add_collator(conn, "my_collator", &my_collator, NULL); + /*! [WT_COLLATOR register] */ + + return (ret); +} + +/*! [WT_EXTRACTOR] */ +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->data = value->data; + result->size = value->size; + return (0); +} +/*! [WT_EXTRACTOR] */ + +int +add_extractor(WT_CONNECTION *conn) +{ + int ret; + + /*! [WT_EXTRACTOR register] */ + static WT_EXTRACTOR my_extractor = {my_extract}; + + ret = conn->add_extractor(conn, "my_extractor", &my_extractor, NULL); + /*! [WT_EXTRACTOR register] */ + + return (ret); +} + +int +connection_ops(WT_CONNECTION *conn) +{ + int ret; + +#ifdef MIGHT_NOT_RUN + /*! [Load an extension] */ + ret = conn->load_extension(conn, "my_extension.dll", NULL); + + ret = conn->load_extension(conn, + "datasource/libdatasource.so", + "config=[device=/dev/sd1,alignment=64]"); + /*! [Load an extension] */ +#endif + + ret = add_collator(conn); + ret = add_extractor(conn); + + /*! [Reconfigure a connection] */ + ret = conn->reconfigure(conn, "eviction_target=75"); + /*! [Reconfigure a connection] */ + + /*! [Get the database home directory] */ + printf("The database home is %s\n", conn->get_home(conn)); + /*! [Get the database home directory] */ + + /*! [Check if the database is newly created] */ + if (conn->is_new(conn)) { + /* First time initialization. */ + } + /*! [Check if the database is newly created] */ + + { + /*! [Open a session] */ + WT_SESSION *session; + ret = conn->open_session(conn, NULL, NULL, &session); + /*! [Open a session] */ + + ret = session_ops(session); + } + + /*! [Configure method configuration] */ + /* + * Applications opening a cursor for the data-source object "my_data" + * have an additional configuration option "entries", which is an + * integer type, defaults to 5, and must be an integer between 1 and 10. + */ + ret = conn->configure_method(conn, + "session.open_cursor", + "my_data:", "entries=5", "int", "min=1,max=10"); + + /* + * Applications opening a cursor for the data-source object "my_data" + * have an additional configuration option "devices", which is a list + * of strings. + */ + ret = conn->configure_method(conn, + "session.open_cursor", "my_data:", "devices", "list", NULL); + /*! [Configure method configuration] */ + + /*! [Close a connection] */ + ret = conn->close(conn, NULL); + /*! [Close a connection] */ + + return (ret); +} + +int +pack_ops(WT_SESSION *session) +{ + int ret; + + { + /*! [Get the packed size] */ + size_t size; + ret = wiredtiger_struct_size(session, &size, "iSh", 42, "hello", -3); + /*! [Get the packed size] */ + assert(size < 100); + } + + { + /*! [Pack fields into a buffer] */ + char buf[100]; + ret = wiredtiger_struct_pack( + session, buf, sizeof(buf), "iSh", 42, "hello", -3); + /*! [Pack fields into a buffer] */ + + { + /*! [Unpack fields from a buffer] */ + int i; + char *s; + short h; + ret = wiredtiger_struct_unpack( + session, buf, sizeof(buf), "iSh", &i, &s, &h); + /*! [Unpack fields from a buffer] */ + } + } + + return (ret); +} + +int +backup(WT_SESSION *session) +{ + char buf[1024]; + + /*! [backup]*/ + WT_CURSOR *cursor; + const char *filename; + int ret; + + /* Create the backup directory. */ + ret = mkdir("/path/database.backup", 077); + + /* Open the backup data source. */ + ret = session->open_cursor(session, "backup:", NULL, NULL, &cursor); + + /* Copy the list of files. */ + while ( + (ret = cursor->next(cursor)) == 0 && + (ret = cursor->get_key(cursor, &filename)) == 0) { + (void)snprintf(buf, sizeof(buf), + "cp /path/database/%s /path/database.backup/%s", + filename, filename); + ret = system(buf); + } + if (ret == WT_NOTFOUND) + ret = 0; + if (ret != 0) + fprintf(stderr, "%s: cursor next(backup:) failed: %s\n", + progname, wiredtiger_strerror(ret)); + + ret = cursor->close(cursor); + /*! [backup]*/ + + /*! [backup of a checkpoint]*/ + ret = session->checkpoint(session, "drop=(from=June01),name=June01"); + /*! [backup of a checkpoint]*/ + + return (ret); +} + +int +main(void) +{ + WT_CONNECTION *conn; + int ret; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + /*! [Open a connection] */ + ret = wiredtiger_open(home, NULL, "create,cache_size=500M", &conn); + /*! [Open a connection] */ + + if (ret == 0) + ret = connection_ops(conn); + /* + * The connection has been closed. + */ + +#ifdef MIGHT_NOT_RUN + /* + * This example code gets run, and the compression libraries might not + * be installed, causing the open to fail. The documentation requires + * the code snippets, use #ifdef's to avoid running it. + */ + /*! [Configure bzip2 extension] */ + ret = wiredtiger_open(home, NULL, + "create," + "extensions=[/usr/local/lib/libwiredtiger_bzip2.so]", &conn); + /*! [Configure bzip2 extension] */ + if (ret == 0) + (void)conn->close(conn, NULL); + + /*! [Configure snappy extension] */ + ret = wiredtiger_open(home, NULL, + "create," + "extensions=[/usr/local/lib/libwiredtiger_snappy.so]", &conn); + /*! [Configure snappy extension] */ + if (ret == 0) + (void)conn->close(conn, NULL); + + /*! [Configure zlib extension] */ + ret = wiredtiger_open(home, NULL, + "create," + "extensions=[/usr/local/lib/libwiredtiger_zlib.so]", &conn); + /*! [Configure zlib extension] */ + if (ret == 0) + (void)conn->close(conn, NULL); + + /* + * This example code gets run, and direct I/O might not be available, + * causing the open to fail. The documentation requires code snippets, + * use #ifdef's to avoid running it. + */ + /* Might Not Run: direct I/O may not be available. */ + /*! [Configure direct_io for data files] */ + ret = wiredtiger_open(home, NULL, "create,direct_io=[data]", &conn); + /*! [Configure direct_io for data files] */ + if (ret == 0) + (void)conn->close(conn, NULL); +#endif + + /*! [Configure file_extend] */ + ret = wiredtiger_open( + home, NULL, "create,file_extend=(data=16MB)", &conn); + /*! [Configure file_extend] */ + if (ret == 0) + (void)conn->close(conn, NULL); + + /*! [Eviction configuration] */ + /* + * Configure eviction to begin at 90% full, and run until the cache + * is only 75% dirty. + */ + ret = wiredtiger_open(home, NULL, + "create,eviction_trigger=90,eviction_dirty_target=75", &conn); + /*! [Eviction configuration] */ + if (ret == 0) + (void)conn->close(conn, NULL); + + /*! [Eviction worker configuration] */ + /* Configure up to four eviction threads */ + ret = wiredtiger_open(home, NULL, + "create,eviction_trigger=90,eviction=(threads_max=4)", &conn); + /*! [Eviction worker configuration] */ + if (ret == 0) + (void)conn->close(conn, NULL); + + /*! [Statistics configuration] */ + ret = wiredtiger_open(home, NULL, "create,statistics=(all)", &conn); + /*! [Statistics configuration] */ + if (ret == 0) + (void)conn->close(conn, NULL); + + /*! [Statistics logging] */ + ret = wiredtiger_open( + home, NULL, "create,statistics_log=(wait=30)", &conn); + /*! [Statistics logging] */ + if (ret == 0) + (void)conn->close(conn, NULL); + + /*! [Statistics logging with a table] */ + ret = wiredtiger_open(home, NULL, + "create, statistics_log=(" + "sources=(\"lsm:table1\",\"lsm:table2\"), wait=5)", + &conn); + /*! [Statistics logging with a table] */ + if (ret == 0) + (void)conn->close(conn, NULL); + + /*! [Statistics logging with all tables] */ + ret = wiredtiger_open(home, NULL, + "create, statistics_log=(sources=(\"lsm:\"), wait=5)", + &conn); + /*! [Statistics logging with all tables] */ + if (ret == 0) + (void)conn->close(conn, NULL); + +#ifdef MIGHT_NOT_RUN + /* + * This example code gets run, and a non-existent log file path might + * cause the open to fail. The documentation requires code snippets, + * use #ifdef's to avoid running it. + */ + /*! [Statistics logging with path] */ + ret = wiredtiger_open(home, NULL, + "create," + "statistics_log=(wait=120,path=/log/log.%m.%d.%y)", &conn); + /*! [Statistics logging with path] */ + if (ret == 0) + (void)conn->close(conn, NULL); + + /* + * Don't run this code, because memory checkers get very upset when we + * leak memory. + */ + (void)wiredtiger_open(home, NULL, "create", &conn); + /*! [Connection close leaking memory] */ + ret = conn->close(conn, "leak_memory=true"); + /*! [Connection close leaking memory] */ +#endif + + /*! [Get the WiredTiger library version #1] */ + printf("WiredTiger version %s\n", wiredtiger_version(NULL, NULL, NULL)); + /*! [Get the WiredTiger library version #1] */ + + { + /*! [Get the WiredTiger library version #2] */ + int major_v, minor_v, patch; + (void)wiredtiger_version(&major_v, &minor_v, &patch); + printf("WiredTiger version is %d, %d (patch %d)\n", + major_v, minor_v, patch); + /*! [Get the WiredTiger library version #2] */ + } + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_async.c b/src/third_party/wiredtiger/examples/c/ex_async.c new file mode 100644 index 00000000000..0c8f83e4aac --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_async.c @@ -0,0 +1,223 @@ +/*- + * Public Domain 2008-2014 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_async.c + * demonstrates how to use the asynchronous API. + */ +#include <errno.h> +#include <inttypes.h> +#include <stdio.h> +#include <string.h> +#ifndef _WIN32 +#include <unistd.h> +#else +#include "windows_shim.h" +#endif + +#include <wiredtiger.h> + +#if defined(_lint) +#define ATOMIC_ADD(v, val) ((v) += (val), (v)) +#elif defined(_WIN32) +#define ATOMIC_ADD(v, val) (_InterlockedExchangeAdd(&(v), val) + val) +#else +#define ATOMIC_ADD(v, val) __sync_add_and_fetch(&(v), val) +#endif + +static const char * const home = NULL; +static int global_error = 0; + +/*! [async example callback implementation] */ +typedef struct { + WT_ASYNC_CALLBACK iface; + uint32_t num_keys; +} ASYNC_KEYS; + +static int +async_callback(WT_ASYNC_CALLBACK *cb, + WT_ASYNC_OP *op, int wiredtiger_error, uint32_t flags) +{ + ASYNC_KEYS *asynckey = (ASYNC_KEYS *)cb; + WT_ASYNC_OPTYPE type; + WT_ITEM k, v; + const char *key, *value; + uint64_t id; + int ret; + + (void)flags; /* Unused */ + + ret = 0; + + /*! [async get type] */ + /* Retrieve the operation's WT_ASYNC_OPTYPE type. */ + type = op->get_type(op); + /*! [async get type] */ + + /*! [async get identifier] */ + /* Retrieve the operation's 64-bit identifier. */ + id = op->get_id(op); + /*! [async get identifier] */ + + /* Check for a WiredTiger error. */ + if (wiredtiger_error != 0) { + fprintf(stderr, + "ID %" PRIu64 " error %d: %s\n", + id, wiredtiger_error, + wiredtiger_strerror(wiredtiger_error)); + global_error = wiredtiger_error; + return (1); + } + + /* If doing a search, retrieve the key/value pair. */ + if (type == WT_AOP_SEARCH) { + /*! [async get the operation's string key] */ + ret = op->get_key(op, &k); + key = k.data; + /*! [async get the operation's string key] */ + /*! [async get the operation's string value] */ + ret = op->get_value(op, &v); + value = v.data; + /*! [async get the operation's string value] */ + ATOMIC_ADD(asynckey->num_keys, 1); + printf("Id %" PRIu64 " got record: %s : %s\n", id, key, value); + } + return (ret); +} +/*! [async example callback implementation] */ + +static ASYNC_KEYS ex_asynckeys = { {async_callback}, 0 }; + +#define MAX_KEYS 15 + +int +main(void) +{ + WT_ASYNC_OP *op; + WT_CONNECTION *conn; + WT_SESSION *session; + int i, ret; + char k[MAX_KEYS][16], v[MAX_KEYS][16]; + + /*! [async example connection] */ + ret = wiredtiger_open(home, NULL, + "create,cache_size=100MB," + "async=(enabled=true,ops_max=20,threads=2)", &conn); + /*! [async example connection] */ + + /*! [async example table create] */ + ret = conn->open_session(conn, NULL, NULL, &session); + ret = session->create( + session, "table:async", "key_format=S,value_format=S"); + /*! [async example table create] */ + + /* Insert a set of keys asynchronously. */ + for (i = 0; i < MAX_KEYS; i++) { + /*! [async handle allocation] */ + while ((ret = conn->async_new_op(conn, + "table:async", NULL, &ex_asynckeys.iface, &op)) != 0) { + /* + * If we used up all the handles, pause and retry to + * give the workers a chance to catch up. + */ + fprintf(stderr, + "asynchronous operation handle not available\n"); + if (ret == EBUSY) + sleep(1); + else + return (ret); + } + /*! [async handle allocation] */ + + /*! [async insert] */ + /* + * Set the operation's string key and value, and then do + * an asynchronous insert. + */ + /*! [async set the operation's string key] */ + snprintf(k[i], sizeof(k), "key%d", i); + op->set_key(op, k[i]); + /*! [async set the operation's string key] */ + + /*! [async set the operation's string value] */ + snprintf(v[i], sizeof(v), "value%d", i); + op->set_value(op, v[i]); + /*! [async set the operation's string value] */ + + ret = op->insert(op); + /*! [async insert] */ + } + + /*! [async flush] */ + /* Wait for all outstanding operations to complete. */ + ret = conn->async_flush(conn); + /*! [async flush] */ + + /*! [async compaction] */ + /* + * Compact a table asynchronously, limiting the run-time to 5 minutes. + */ + ret = conn->async_new_op( + conn, "table:async", "timeout=300", &ex_asynckeys.iface, &op); + ret = op->compact(op); + /*! [async compaction] */ + + /* Search for the keys we just inserted, asynchronously. */ + for (i = 0; i < MAX_KEYS; i++) { + while ((ret = conn->async_new_op(conn, + "table:async", NULL, &ex_asynckeys.iface, &op)) != 0) { + /* + * If we used up all the handles, pause and retry to + * give the workers a chance to catch up. + */ + fprintf(stderr, + "asynchronous operation handle not available\n"); + if (ret == EBUSY) + sleep(1); + else + return (ret); + } + + /*! [async search] */ + /* + * Set the operation's string key and value, and then do + * an asynchronous search. + */ + snprintf(k[i], sizeof(k), "key%d", i); + op->set_key(op, k[i]); + ret = op->search(op); + /*! [async search] */ + } + + /* + * Connection close automatically does an async_flush so it will wait + * for all queued search operations to complete. + */ + ret = conn->close(conn, NULL); + + printf("Searched for %d keys\n", ex_asynckeys.num_keys); + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_call_center.c b/src/third_party/wiredtiger/examples/c/ex_call_center.c new file mode 100644 index 00000000000..14ab8f37f56 --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_call_center.c @@ -0,0 +1,248 @@ +/*- + * Public Domain 2008-2014 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_call_center.c + * This is an example application that demonstrates how to map a + * moderately complex SQL application into WiredTiger. + */ + +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +static const char *home; + +/*! [call-center decl] */ +/* + * In SQL, the tables are described as follows: + * + * CREATE TABLE Customers(id INTEGER PRIMARY KEY, + * name VARCHAR(30), address VARCHAR(50), phone VARCHAR(15)) + * CREATE INDEX CustomersPhone ON Customers(phone) + * + * CREATE TABLE Calls(id INTEGER PRIMARY KEY, call_date DATE, + * cust_id INTEGER, emp_id INTEGER, call_type VARCHAR(12), + * notes VARCHAR(25)) + * CREATE INDEX CallsCustDate ON Calls(cust_id, call_date) + * + * In this example, both tables will use record numbers for their IDs, which + * will be the key. The C structs for the records are as follows. + */ + +/* Customer records. */ +typedef struct { + uint64_t id; + const char *name; + const char *address; + const char *phone; +} CUSTOMER; + +/* Call records. */ +typedef struct { + uint64_t id; + uint64_t call_date; + uint64_t cust_id; + uint64_t emp_id; + const char *call_type; + const char *notes; +} CALL; +/*! [call-center decl] */ + +int +main(void) +{ + int count, exact, ret; + WT_CONNECTION *conn; + WT_SESSION *session; + WT_CURSOR *cursor; + CUSTOMER cust, *custp, cust_sample[] = { + { 0, "Professor Oak", "LeafGreen Avenue", "123-456-7890" }, + { 0, "Lorelei", "Sevii Islands", "098-765-4321" }, + { 0, NULL, NULL, NULL } + }; + CALL call, *callp, call_sample[] = { + { 0, 32, 1, 2, "billing", "unavailable" }, + { 0, 33, 1, 2, "billing", "available" }, + { 0, 34, 1, 2, "reminder", "unavailable" }, + { 0, 35, 1, 2, "reminder", "available" }, + { 0, 0, 0, 0, NULL, NULL } + }; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0) { + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + return (1); + } + /* Note: further error checking omitted for clarity. */ + + /*! [call-center work] */ + ret = conn->open_session(conn, NULL, NULL, &session); + + /* + * Create the customers table, give names and types to the columns. + * The columns will be stored in two groups: "main" and "address", + * created below. + */ + ret = session->create(session, "table:customers", + "key_format=r," + "value_format=SSS," + "columns=(id,name,address,phone)," + "colgroups=(main,address)"); + + /* Create the main column group with value columns except address. */ + ret = session->create(session, + "colgroup:customers:main", "columns=(name,phone)"); + + /* Create the address column group with just the address. */ + ret = session->create(session, + "colgroup:customers:address", "columns=(address)"); + + /* Create an index on the customer table by phone number. */ + ret = session->create(session, + "index:customers:phone", "columns=(phone)"); + + /* Populate the customers table with some data. */ + ret = session->open_cursor( + session, "table:customers", NULL, "append", &cursor); + for (custp = cust_sample; custp->name != NULL; custp++) { + cursor->set_value(cursor, + custp->name, custp->address, custp->phone); + ret = cursor->insert(cursor); + } + ret = cursor->close(cursor); + + /* + * Create the calls table, give names and types to the columns. All the + * columns will be stored together, so no column groups are declared. + */ + ret = session->create(session, "table:calls", + "key_format=r," + "value_format=qrrSS," + "columns=(id,call_date,cust_id,emp_id,call_type,notes)"); + + /* + * Create an index on the calls table with a composite key of cust_id + * and call_date. + */ + ret = session->create(session, "index:calls:cust_date", + "columns=(cust_id,call_date)"); + + /* Populate the calls table with some data. */ + ret = session->open_cursor( + session, "table:calls", NULL, "append", &cursor); + for (callp = call_sample; callp->call_type != NULL; callp++) { + cursor->set_value(cursor, callp->call_date, callp->cust_id, + callp->emp_id, callp->call_type, callp->notes); + ret = cursor->insert(cursor); + } + ret = cursor->close(cursor); + + /* + * First query: a call arrives. In SQL: + * + * SELECT id, name FROM Customers WHERE phone=? + * + * Use the cust_phone index, lookup by phone number to fill the + * customer record. The cursor will have a key format of "S" for a + * string because the cust_phone index has a single column ("phone"), + * which is of type "S". + * + * Specify the columns we want: the customer ID and the name. This + * means the cursor's value format will be "rS". + */ + ret = session->open_cursor(session, + "index:customers:phone(id,name)", NULL, NULL, &cursor); + cursor->set_key(cursor, "123-456-7890"); + ret = cursor->search(cursor); + if (ret == 0) { + ret = cursor->get_value(cursor, &cust.id, &cust.name); + printf("Read customer record for %s (ID %" PRIu64 ")\n", + cust.name, cust.id); + } + ret = cursor->close(cursor); + + /* + * Next query: get the recent order history. In SQL: + * + * SELECT * FROM Calls WHERE cust_id=? ORDER BY call_date DESC LIMIT 3 + * + * Use the call_cust_date index to find the matching calls. Since it is + * is in increasing order by date for a given customer, we want to start + * with the last record for the customer and work backwards. + * + * Specify a subset of columns to be returned. (Note that if these were + * all covered by the index, the primary would not have to be accessed.) + * Stop after getting 3 records. + */ + ret = session->open_cursor(session, + "index:calls:cust_date(cust_id,call_type,notes)", + NULL, NULL, &cursor); + + /* + * The keys in the index are (cust_id,call_date) -- we want the largest + * call date for a given cust_id. Search for (cust_id+1,0), then work + * backwards. + */ + cust.id = 1; + cursor->set_key(cursor, cust.id + 1, 0); + ret = cursor->search_near(cursor, &exact); + + /* + * If the table is empty, search_near will return WT_NOTFOUND, else the + * cursor will be positioned on a matching key if one exists, or an + * adjacent key if one does not. If the positioned key is equal to or + * larger than the search key, go back one. + */ + if (ret == 0 && exact >= 0) + ret = cursor->prev(cursor); + for (count = 0; ret == 0 && count < 3; ++count) { + ret = cursor->get_value(cursor, + &call.cust_id, &call.call_type, &call.notes); + if (call.cust_id != cust.id) + break; + printf("Call record: customer %" PRIu64 " (%s: %s)\n", + call.cust_id, call.call_type, call.notes); + ret = cursor->prev(cursor); + } + /*! [call-center work] */ + + ret = conn->close(conn, NULL); + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_config.c b/src/third_party/wiredtiger/examples/c/ex_config.c new file mode 100644 index 00000000000..cb8ab02b393 --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_config.c @@ -0,0 +1,90 @@ +/*- + * Public Domain 2008-2014 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_config.c + * This is an example demonstrating how to configure various database and + * table properties. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +static const char *home; + +int +main(void) +{ + int ret; + WT_CONNECTION *conn; + WT_SESSION *session; + WT_CURSOR *cursor; + const char *key, *value; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + /*! [configure cache size] */ + if ((ret = wiredtiger_open(home, NULL, + "create,cache_size=500M", &conn)) != 0) + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + /*! [configure cache size] */ + + /*! [create a table] */ + ret = conn->open_session(conn, NULL, NULL, &session); + + ret = session->create(session, + "table:access", "key_format=S,value_format=S"); + /*! [create a table] */ + + /*! [transaction] */ + ret = session->begin_transaction(session, "priority=100,name=mytxn"); + + ret = session->open_cursor(session, "config:", NULL, NULL, &cursor); + + while ((ret = cursor->next(cursor)) == 0) { + ret = cursor->get_key(cursor, &key); + ret = cursor->get_value(cursor, &value); + printf("configuration value: %s = %s\n", key, value); + } + + ret = session->commit_transaction(session, NULL); + /*! [transaction] */ + + ret = conn->close(conn, NULL); + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_config_parse.c b/src/third_party/wiredtiger/examples/c/ex_config_parse.c new file mode 100644 index 00000000000..543c53f508c --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_config_parse.c @@ -0,0 +1,165 @@ +/*- + * Public Domain 2008-2014 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_config_parse.c + * This is an example demonstrating how to parse WiredTiger compatible + * configuration strings. + */ + +#include <stdio.h> +#include <string.h> + +#include <wiredtiger.h> + +int +main(void) +{ + int ret; + + /*! [Create a configuration parser] */ + WT_CONFIG_ITEM k, v; + WT_CONFIG_PARSER *parser; + const char *config_string = + "path=/dev/loop,page_size=1024,log=(archive=true,file_max=20MB)"; + + if ((ret = wiredtiger_config_parser_open( + NULL, config_string, strlen(config_string), &parser)) != 0) { + fprintf(stderr, "Error creating configuration parser: %s\n", + wiredtiger_strerror(ret)); + return (ret); + } + if ((ret = parser->close(parser)) != 0) { + fprintf(stderr, "Error closing configuration parser: %s\n", + wiredtiger_strerror(ret)); + return (ret); + } + /*! [Create a configuration parser] */ + + if ((ret = wiredtiger_config_parser_open( + NULL, config_string, strlen(config_string), &parser)) != 0) { + fprintf(stderr, "Error creating configuration parser: %s\n", + wiredtiger_strerror(ret)); + return (ret); + } + + { + /*! [get] */ + int64_t my_page_size; + /* + * Retrieve the value of the integer configuration string "page_size". + */ + if ((ret = parser->get(parser, "page_size", &v)) != 0) { + fprintf(stderr, + "page_size configuration: %s", wiredtiger_strerror(ret)); + return (ret); + } + my_page_size = v.val; + /*! [get] */ + + ret = parser->close(parser); + + (void)my_page_size; + } + + { + if ((ret = wiredtiger_config_parser_open( + NULL, config_string, strlen(config_string), &parser)) != 0) { + fprintf(stderr, "Error creating configuration parser: %s\n", + wiredtiger_strerror(ret)); + return (ret); + } + /*! [next] */ + /* + * Retrieve and print the values of the configuration strings. + */ + while ((ret = parser->next(parser, &k, &v)) == 0) { + printf("%.*s:", (int)k.len, k.str); + if (v.type == WT_CONFIG_ITEM_NUM) + printf("%d\n", (int)v.val); + else + printf("%.*s\n", (int)v.len, v.str); + } + /*! [next] */ + ret = parser->close(parser); + } + + if ((ret = wiredtiger_config_parser_open( + NULL, config_string, strlen(config_string), &parser)) != 0) { + fprintf(stderr, "Error creating configuration parser: %s\n", + wiredtiger_strerror(ret)); + return (ret); + } + + /*! [nested get] */ + /* + * Retrieve the value of the nested log file_max configuration string + * using dot shorthand. Utilize the configuration parsing automatic + * conversion of value strings into an integer. + */ + v.type = WT_CONFIG_ITEM_NUM; + if ((ret = parser->get(parser, "log.file_max", &v)) != 0) { + fprintf(stderr, + "log.file_max configuration: %s", wiredtiger_strerror(ret)); + return (ret); + } + printf("log file max: %d\n", (int)v.val); + /*! [nested get] */ + ret = parser->close(parser); + + if ((ret = wiredtiger_config_parser_open( + NULL, config_string, strlen(config_string), &parser)) != 0) { + fprintf(stderr, "Error creating configuration parser: %s\n", + wiredtiger_strerror(ret)); + return (ret); + } + /*! [nested traverse] */ + { + WT_CONFIG_PARSER *sub_parser; + while ((ret = parser->next(parser, &k, &v)) == 0) { + if (v.type == WT_CONFIG_ITEM_STRUCT) { + printf("Found nested configuration: %.*s\n", + (int)k.len, k.str); + if ((ret = wiredtiger_config_parser_open( + NULL, v.str, v.len, &sub_parser)) != 0) { + fprintf(stderr, + "Error creating nested configuration " + "parser: %s\n", + wiredtiger_strerror(ret)); + ret = parser->close(parser); + return (ret); + } + while ((ret = sub_parser->next( + sub_parser, &k, &v)) == 0) + printf("\t%.*s\n", (int)k.len, k.str); + ret = sub_parser->close(sub_parser); + } + } + /*! [nested traverse] */ + ret = parser->close(parser); + } + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_cursor.c b/src/third_party/wiredtiger/examples/c/ex_cursor.c new file mode 100644 index 00000000000..e8f9b7fa9e8 --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_cursor.c @@ -0,0 +1,227 @@ +/*- + * Public Domain 2008-2014 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_cursor.c + * This is an example demonstrating some cursor types and operations. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +int cursor_reset(WT_CURSOR *cursor); +int cursor_forward_scan(WT_CURSOR *cursor); +int cursor_reverse_scan(WT_CURSOR *cursor); +int cursor_search(WT_CURSOR *cursor); +int cursor_search_near(WT_CURSOR *cursor); +int cursor_insert(WT_CURSOR *cursor); +int cursor_update(WT_CURSOR *cursor); +int cursor_remove(WT_CURSOR *cursor); + +static const char *home; + +/*! [cursor next] */ +int +cursor_forward_scan(WT_CURSOR *cursor) +{ + const char *key, *value; + int ret; + + while ((ret = cursor->next(cursor)) == 0) { + ret = cursor->get_key(cursor, &key); + ret = cursor->get_value(cursor, &value); + } + return (ret); +} +/*! [cursor next] */ + +/*! [cursor prev] */ +int +cursor_reverse_scan(WT_CURSOR *cursor) +{ + const char *key, *value; + int ret; + + while ((ret = cursor->prev(cursor)) == 0) { + ret = cursor->get_key(cursor, &key); + ret = cursor->get_value(cursor, &value); + } + return (ret); +} +/*! [cursor prev] */ + +/*! [cursor reset] */ +int +cursor_reset(WT_CURSOR *cursor) +{ + return (cursor->reset(cursor)); +} +/*! [cursor reset] */ + +/*! [cursor search] */ +int +cursor_search(WT_CURSOR *cursor) +{ + const char *value; + int ret; + + cursor->set_key(cursor, "foo"); + + if ((ret = cursor->search(cursor)) != 0) + ret = cursor->get_value(cursor, &value); + + return (ret); +} +/*! [cursor search] */ + +/*! [cursor search near] */ +int +cursor_search_near(WT_CURSOR *cursor) +{ + const char *key, *value; + int exact, ret; + + cursor->set_key(cursor, "foo"); + + if ((ret = cursor->search_near(cursor, &exact)) == 0) { + switch (exact) { + case -1: /* Returned key smaller than search key */ + ret = cursor->get_key(cursor, &key); + break; + case 0: /* Exact match found */ + break; + case 1: /* Returned key larger than search key */ + ret = cursor->get_key(cursor, &key); + break; + } + + ret = cursor->get_value(cursor, &value); + } + + return (ret); +} +/*! [cursor search near] */ + +/*! [cursor insert] */ +int +cursor_insert(WT_CURSOR *cursor) +{ + cursor->set_key(cursor, "foo"); + cursor->set_value(cursor, "bar"); + + return (cursor->insert(cursor)); +} +/*! [cursor insert] */ + +/*! [cursor update] */ +int +cursor_update(WT_CURSOR *cursor) +{ + cursor->set_key(cursor, "foo"); + cursor->set_value(cursor, "newbar"); + + return (cursor->update(cursor)); +} +/*! [cursor update] */ + +/*! [cursor remove] */ +int +cursor_remove(WT_CURSOR *cursor) +{ + cursor->set_key(cursor, "foo"); + return (cursor->remove(cursor)); +} +/*! [cursor remove] */ + +int +main(void) +{ + WT_CONNECTION *conn; + WT_CURSOR *cursor; + WT_SESSION *session; + int ret; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + /* Open a connection to the database, creating it if necessary. */ + if ((ret = wiredtiger_open( + home, NULL, "create,statistics=(fast)", &conn)) != 0) + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + + /* Open a session for the current thread's work. */ + if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) + fprintf(stderr, "Error opening a session on %s: %s\n", + home, wiredtiger_strerror(ret)); + + ret = session->create(session, "table:world", + "key_format=r,value_format=5sii," + "columns=(id,country,population,area)"); + + /*! [open cursor #1] */ + ret = session->open_cursor(session, "table:world", NULL, NULL, &cursor); + /*! [open cursor #1] */ + + /*! [open cursor #2] */ + ret = session->open_cursor(session, + "table:world(country,population)", NULL, NULL, &cursor); + /*! [open cursor #2] */ + + /*! [open cursor #3] */ + ret = session->open_cursor(session, "statistics:", NULL, NULL, &cursor); + /*! [open cursor #3] */ + + /* Create a simple string table to illustrate basic operations. */ + ret = session->create(session, "table:map", + "key_format=S,value_format=S"); + ret = session->open_cursor(session, "table:map", NULL, NULL, &cursor); + ret = cursor_insert(cursor); + ret = cursor_reset(cursor); + ret = cursor_forward_scan(cursor); + ret = cursor_reset(cursor); + ret = cursor_reverse_scan(cursor); + ret = cursor_search_near(cursor); + ret = cursor_update(cursor); + ret = cursor_remove(cursor); + ret = cursor->close(cursor); + + /* Note: closing the connection implicitly closes open session(s). */ + if ((ret = conn->close(conn, NULL)) != 0) + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_data_source.c b/src/third_party/wiredtiger/examples/c/ex_data_source.c new file mode 100644 index 00000000000..b6fc143a586 --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_data_source.c @@ -0,0 +1,661 @@ +/*- + * Public Domain 2008-2014 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_data_source.c + * demonstrates how to create and access a data source + */ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wiredtiger.h> + +/*! [WT_EXTENSION_API declaration] */ +#include <wiredtiger_ext.h> + +static WT_EXTENSION_API *wt_api; + +static void +my_data_source_init(WT_CONNECTION *connection) +{ + wt_api = connection->get_extension_api(connection); +} +/*! [WT_EXTENSION_API declaration] */ + +/*! [WT_DATA_SOURCE create] */ +static int +my_create(WT_DATA_SOURCE *dsrc, WT_SESSION *session, + const char *uri, WT_CONFIG_ARG *config) +/*! [WT_DATA_SOURCE create] */ +{ + /* Unused parameters */ + (void)dsrc; + (void)uri; + (void)config; + + { + const char *msg = "string"; + /*! [WT_EXTENSION_API err_printf] */ + (void)wt_api->err_printf( + wt_api, session, "extension error message: %s", msg); + /*! [WT_EXTENSION_API err_printf] */ + } + + { + const char *msg = "string"; + /*! [WT_EXTENSION_API msg_printf] */ + (void)wt_api->msg_printf(wt_api, session, "extension message: %s", msg); + /*! [WT_EXTENSION_API msg_printf] */ + } + + { + int ret = 0; + /*! [WT_EXTENSION_API strerror] */ + (void)wt_api->err_printf(wt_api, + session, "WiredTiger error return: %s", wt_api->strerror(ret)); + /*! [WT_EXTENSION_API strerror] */ + } + + { + /*! [WT_EXTENSION_API scr_alloc] */ + void *buffer; + if ((buffer = wt_api->scr_alloc(wt_api, session, 512)) == NULL) { + (void)wt_api->err_printf(wt_api, session, + "buffer allocation: %s", wiredtiger_strerror(ENOMEM)); + return (ENOMEM); + } + /*! [WT_EXTENSION_API scr_alloc] */ + + /*! [WT_EXTENSION_API scr_free] */ + wt_api->scr_free(wt_api, session, buffer); + /*! [WT_EXTENSION_API scr_free] */ + } + + return (0); +} + +/*! [WT_DATA_SOURCE compact] */ +static int +my_compact(WT_DATA_SOURCE *dsrc, WT_SESSION *session, + const char *uri, WT_CONFIG_ARG *config) +/*! [WT_DATA_SOURCE compact] */ +{ + /* Unused parameters */ + (void)dsrc; + (void)session; + (void)uri; + (void)config; + + return (0); +} + +/*! [WT_DATA_SOURCE drop] */ +static int +my_drop(WT_DATA_SOURCE *dsrc, WT_SESSION *session, + const char *uri, WT_CONFIG_ARG *config) +/*! [WT_DATA_SOURCE drop] */ +{ + /* Unused parameters */ + (void)dsrc; + (void)session; + (void)uri; + (void)config; + + return (0); +} + +static int +data_source_cursor(void) +{ + return (0); +} + +static const char * +data_source_error(int v) +{ + return (v == 0 ? "one" : "two"); +} + +static int +data_source_notify( + WT_TXN_NOTIFY *handler, WT_SESSION *session, uint64_t txnid, int committed) +{ + /* Unused parameters */ + (void)handler; + (void)session; + (void)txnid; + (void)committed; + + return (0); +} + +static int my_cursor_next(WT_CURSOR *wtcursor) + { (void)wtcursor; return (0); } +static int my_cursor_prev(WT_CURSOR *wtcursor) + { (void)wtcursor; return (0); } +static int my_cursor_reset(WT_CURSOR *wtcursor) + { (void)wtcursor; return (0); } +static int my_cursor_search(WT_CURSOR *wtcursor) + { (void)wtcursor; return (0); } +static int my_cursor_search_near(WT_CURSOR *wtcursor, int *exactp) + { (void)wtcursor; (void)exactp; return (0); } +static int my_cursor_insert(WT_CURSOR *wtcursor) +{ + WT_SESSION *session = NULL; + int ret; + + /* Unused parameters */ + (void)wtcursor; + + { + int is_snapshot_isolation, isolation_level; + /*! [WT_EXTENSION transaction isolation level] */ + isolation_level = wt_api->transaction_isolation_level(wt_api, session); + if (isolation_level == WT_TXN_ISO_SNAPSHOT) + is_snapshot_isolation = 1; + else + is_snapshot_isolation = 0; + /*! [WT_EXTENSION transaction isolation level] */ + (void)is_snapshot_isolation; + } + + { + /*! [WT_EXTENSION transaction ID] */ + uint64_t transaction_id; + + transaction_id = wt_api->transaction_id(wt_api, session); + /*! [WT_EXTENSION transaction ID] */ + (void)transaction_id; + } + + { + /*! [WT_EXTENSION transaction oldest] */ + uint64_t transaction_oldest; + + transaction_oldest = wt_api->transaction_oldest(wt_api); + /*! [WT_EXTENSION transaction oldest] */ + (void)transaction_oldest; + } + + { + /*! [WT_EXTENSION transaction notify] */ + WT_TXN_NOTIFY handler; + handler.notify = data_source_notify; + ret = wt_api->transaction_notify(wt_api, session, &handler); + /*! [WT_EXTENSION transaction notify] */ + } + + { + uint64_t transaction_id = 1; + int is_visible; + /*! [WT_EXTENSION transaction visible] */ + is_visible = + wt_api->transaction_visible(wt_api, session, transaction_id); + /*! [WT_EXTENSION transaction visible] */ + (void)is_visible; + } + + { + const char *key1 = NULL, *key2 = NULL; + uint32_t key1_len = 0, key2_len = 0; + WT_COLLATOR *collator = NULL; + /*! [WT_EXTENSION collate] */ + WT_ITEM first, second; + int cmp; + + first.data = key1; + first.size = key1_len; + second.data = key2; + second.size = key2_len; + + ret = wt_api->collate(wt_api, session, collator, &first, &second, &cmp); + if (cmp == 0) + printf("key1 collates identically to key2\n"); + else if (cmp < 0) + printf("key1 collates less than key2\n"); + else + printf("key1 collates greater than key2\n"); + /*! [WT_EXTENSION collate] */ + } + + return (ret); +} + +static int my_cursor_update(WT_CURSOR *wtcursor) + { (void)wtcursor; return (0); } +static int my_cursor_remove(WT_CURSOR *wtcursor) + { (void)wtcursor; return (0); } +static int my_cursor_close(WT_CURSOR *wtcursor) + { (void)wtcursor; return (0); } + +/*! [WT_DATA_SOURCE open_cursor] */ +typedef struct __my_cursor { + WT_CURSOR wtcursor; /* WiredTiger cursor, must come first */ + + /* + * Local cursor information: for example, we might want to have a + * reference to the extension functions. + */ + WT_EXTENSION_API *wtext; /* Extension functions */ +} MY_CURSOR; + +static int +my_open_cursor(WT_DATA_SOURCE *dsrc, WT_SESSION *session, + const char *uri, WT_CONFIG_ARG *config, WT_CURSOR **new_cursor) +{ + MY_CURSOR *cursor; + + /* Allocate and initialize a WiredTiger cursor. */ + if ((cursor = calloc(1, sizeof(*cursor))) == NULL) + return (errno); + + cursor->wtcursor.next = my_cursor_next; + cursor->wtcursor.prev = my_cursor_prev; + cursor->wtcursor.reset = my_cursor_reset; + cursor->wtcursor.search = my_cursor_search; + cursor->wtcursor.search_near = my_cursor_search_near; + cursor->wtcursor.insert = my_cursor_insert; + cursor->wtcursor.update = my_cursor_update; + cursor->wtcursor.remove = my_cursor_remove; + cursor->wtcursor.close = my_cursor_close; + + /* + * Configure local cursor information. + */ + + /* Return combined cursor to WiredTiger. */ + *new_cursor = (WT_CURSOR *)cursor; + +/*! [WT_DATA_SOURCE open_cursor] */ + { + int ret = 0; + (void)dsrc; /* Unused parameters */ + (void)session; + (void)uri; + (void)new_cursor; + + { + /*! [WT_EXTENSION_CONFIG boolean] */ + WT_CONFIG_ITEM v; + int my_data_source_overwrite; + + /* + * Retrieve the value of the boolean type configuration string + * "overwrite". + */ + if ((ret = wt_api->config_get( + wt_api, session, config, "overwrite", &v)) != 0) { + (void)wt_api->err_printf(wt_api, session, + "overwrite configuration: %s", wiredtiger_strerror(ret)); + return (ret); + } + my_data_source_overwrite = v.val != 0; + /*! [WT_EXTENSION_CONFIG boolean] */ + + (void)my_data_source_overwrite; + } + + { + /*! [WT_EXTENSION_CONFIG integer] */ + WT_CONFIG_ITEM v; + int64_t my_data_source_page_size; + + /* + * Retrieve the value of the integer type configuration string + * "page_size". + */ + if ((ret = wt_api->config_get( + wt_api, session, config, "page_size", &v)) != 0) { + (void)wt_api->err_printf(wt_api, session, + "page_size configuration: %s", wiredtiger_strerror(ret)); + return (ret); + } + my_data_source_page_size = v.val; + /*! [WT_EXTENSION_CONFIG integer] */ + + (void)my_data_source_page_size; + } + + { + /*! [WT_EXTENSION config_get] */ + WT_CONFIG_ITEM v; + const char *my_data_source_key; + + /* + * Retrieve the value of the string type configuration string + * "key_format". + */ + if ((ret = wt_api->config_get( + wt_api, session, config, "key_format", &v)) != 0) { + (void)wt_api->err_printf(wt_api, session, + "key_format configuration: %s", wiredtiger_strerror(ret)); + return (ret); + } + + /* + * Values returned from WT_EXTENSION_API::config in the str field are + * not nul-terminated; the associated length must be used instead. + */ + if (v.len == 1 && v.str[0] == 'r') + my_data_source_key = "recno"; + else + my_data_source_key = "bytestring"; + /*! [WT_EXTENSION config_get] */ + + (void)my_data_source_key; + } + + { + /*! [WT_EXTENSION collator config] */ + WT_COLLATOR *collator; + int collator_owned; + /* + * Configure the appropriate collator. + */ + if ((ret = wt_api->collator_config( + wt_api, session, config, &collator, &collator_owned)) != 0) { + (void)wt_api->err_printf(wt_api, session, + "collator configuration: %s", wiredtiger_strerror(ret)); + return (ret); + } + /*! [WT_EXTENSION collator config] */ + } + + /*! [WT_DATA_SOURCE error message] */ + /* + * If an underlying function fails, log the error and then return an + * error within WiredTiger's name space. + */ + if ((ret = data_source_cursor()) != 0) { + (void)wt_api->err_printf(wt_api, + session, "my_open_cursor: %s", data_source_error(ret)); + return (WT_ERROR); + } + /*! [WT_DATA_SOURCE error message] */ + + { + /*! [WT_EXTENSION metadata insert] */ + /* + * Insert a new WiredTiger metadata record. + */ + const char *key = "datasource_uri"; + const char *value = "data source uri's record"; + + if ((ret = wt_api->metadata_insert(wt_api, session, key, value)) != 0) { + (void)wt_api->err_printf(wt_api, session, + "%s: metadata insert: %s", key, wiredtiger_strerror(ret)); + return (ret); + } + /*! [WT_EXTENSION metadata insert] */ + } + + { + /*! [WT_EXTENSION metadata remove] */ + /* + * Remove a WiredTiger metadata record. + */ + const char *key = "datasource_uri"; + + if ((ret = wt_api->metadata_remove(wt_api, session, key)) != 0) { + (void)wt_api->err_printf(wt_api, session, + "%s: metadata remove: %s", key, wiredtiger_strerror(ret)); + return (ret); + } + /*! [WT_EXTENSION metadata remove] */ + } + + { + /*! [WT_EXTENSION metadata search] */ + /* + * Insert a new WiredTiger metadata record. + */ + const char *key = "datasource_uri"; + const char *value; + + if ((ret = + wt_api->metadata_search(wt_api, session, key, &value)) != 0) { + (void)wt_api->err_printf(wt_api, session, + "%s: metadata search: %s", key, wiredtiger_strerror(ret)); + return (ret); + } + printf("metadata: %s has a value of %s\n", key, value); + /*! [WT_EXTENSION metadata search] */ + } + + { + /*! [WT_EXTENSION metadata update] */ + /* + * Update a WiredTiger metadata record (insert it if it does not yet + * exist, update it if it does). + */ + const char *key = "datasource_uri"; + const char *value = "data source uri's record"; + + if ((ret = wt_api->metadata_update(wt_api, session, key, value)) != 0) { + (void)wt_api->err_printf(wt_api, session, + "%s: metadata update: %s", key, wiredtiger_strerror(ret)); + return (ret); + } + /*! [WT_EXTENSION metadata update] */ + } + + } + return (0); +} + +/*! [WT_DATA_SOURCE rename] */ +static int +my_rename(WT_DATA_SOURCE *dsrc, WT_SESSION *session, + const char *uri, const char *newname, WT_CONFIG_ARG *config) +/*! [WT_DATA_SOURCE rename] */ +{ + /* Unused parameters */ + (void)dsrc; + (void)session; + (void)uri; + (void)newname; + (void)config; + + return (0); +} + +/*! [WT_DATA_SOURCE salvage] */ +static int +my_salvage(WT_DATA_SOURCE *dsrc, WT_SESSION *session, + const char *uri, WT_CONFIG_ARG *config) +/*! [WT_DATA_SOURCE salvage] */ +{ + /* Unused parameters */ + (void)dsrc; + (void)session; + (void)uri; + (void)config; + + return (0); +} + +/*! [WT_DATA_SOURCE truncate] */ +static int +my_truncate(WT_DATA_SOURCE *dsrc, WT_SESSION *session, + const char *uri, WT_CONFIG_ARG *config) +/*! [WT_DATA_SOURCE truncate] */ +{ + /* Unused parameters */ + (void)dsrc; + (void)session; + (void)uri; + (void)config; + + return (0); +} + +/*! [WT_DATA_SOURCE range truncate] */ +static int +my_range_truncate(WT_DATA_SOURCE *dsrc, WT_SESSION *session, + WT_CURSOR *start, WT_CURSOR *stop) +/*! [WT_DATA_SOURCE range truncate] */ +{ + /* Unused parameters */ + (void)dsrc; + (void)session; + (void)start; + (void)stop; + + return (0); +} + +/*! [WT_DATA_SOURCE verify] */ +static int +my_verify(WT_DATA_SOURCE *dsrc, WT_SESSION *session, + const char *uri, WT_CONFIG_ARG *config) +/*! [WT_DATA_SOURCE verify] */ +{ + /* Unused parameters */ + (void)dsrc; + (void)session; + (void)uri; + (void)config; + + return (0); +} + +/*! [WT_DATA_SOURCE checkpoint] */ +static int +my_checkpoint(WT_DATA_SOURCE *dsrc, WT_SESSION *session, WT_CONFIG_ARG *config) +/*! [WT_DATA_SOURCE checkpoint] */ +{ + /* Unused parameters */ + (void)dsrc; + (void)session; + (void)config; + + return (0); +} + +/*! [WT_DATA_SOURCE terminate] */ +static int +my_terminate(WT_DATA_SOURCE *dsrc, WT_SESSION *session) +/*! [WT_DATA_SOURCE terminate] */ +{ + /* Unused parameters */ + (void)dsrc; + (void)session; + + return (0); +} + +int +main(void) +{ + WT_CONNECTION *conn; + WT_SESSION *session; + int ret; + + ret = wiredtiger_open(NULL, NULL, "create", &conn); + ret = conn->open_session(conn, NULL, NULL, &session); + + my_data_source_init(conn); + + { + /*! [WT_DATA_SOURCE register] */ + static WT_DATA_SOURCE my_dsrc = { + my_create, + my_compact, + my_drop, + my_open_cursor, + my_rename, + my_salvage, + my_truncate, + my_range_truncate, + my_verify, + my_checkpoint, + my_terminate + }; + ret = conn->add_data_source(conn, "dsrc:", &my_dsrc, NULL); + /*! [WT_DATA_SOURCE register] */ + } + + /*! [WT_DATA_SOURCE configure boolean] */ + /* my_boolean defaults to true. */ + ret = conn->configure_method(conn, + "session.open_cursor", NULL, "my_boolean=true", "boolean", NULL); + /*! [WT_DATA_SOURCE configure boolean] */ + + /*! [WT_DATA_SOURCE configure integer] */ + /* my_integer defaults to 5. */ + ret = conn->configure_method(conn, + "session.open_cursor", NULL, "my_integer=5", "int", NULL); + /*! [WT_DATA_SOURCE configure integer] */ + + /*! [WT_DATA_SOURCE configure string] */ + /* my_string defaults to "name". */ + ret = conn->configure_method(conn, + "session.open_cursor", NULL, "my_string=name", "string", NULL); + /*! [WT_DATA_SOURCE configure string] */ + + /*! [WT_DATA_SOURCE configure list] */ + /* my_list defaults to "first" and "second". */ + ret = conn->configure_method(conn, + "session.open_cursor", + NULL, "my_list=[first, second]", "list", NULL); + /*! [WT_DATA_SOURCE configure list] */ + + /*! [WT_DATA_SOURCE configure integer with checking] */ + /* + * Limit the number of devices to between 1 and 30; the default is 5. + */ + ret = conn->configure_method(conn, + "session.open_cursor", NULL, "devices=5", "int", "min=1, max=30"); + /*! [WT_DATA_SOURCE configure integer with checking] */ + + /*! [WT_DATA_SOURCE configure string with checking] */ + /* + * Limit the target string to one of /device, /home or /target; default + * to /home. + */ + ret = conn->configure_method(conn, + "session.open_cursor", NULL, "target=/home", "string", + "choices=[/device, /home, /target]"); + /*! [WT_DATA_SOURCE configure string with checking] */ + + /*! [WT_DATA_SOURCE configure list with checking] */ + /* + * Limit the paths list to one or more of /device, /home, /mnt or + * /target; default to /mnt. + */ + ret = conn->configure_method(conn, + "session.open_cursor", NULL, "paths=[/mnt]", "list", + "choices=[/device, /home, /mnt, /target]"); + /*! [WT_DATA_SOURCE configure list with checking] */ + + /*! [WT_EXTENSION_API default_session] */ + (void)wt_api->msg_printf(wt_api, NULL, "configuration complete"); + /*! [WT_EXTENSION_API default_session] */ + + (void)conn->close(conn, NULL); + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_extending.c b/src/third_party/wiredtiger/examples/c/ex_extending.c new file mode 100644 index 00000000000..f043dd5b383 --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_extending.c @@ -0,0 +1,132 @@ +/*- + * Public Domain 2008-2014 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_extending.c + * This is an example demonstrating ways to extend WiredTiger with + * extractors, collators and loadable modules. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +#ifdef _WIN32 +#define strcasecmp stricmp +#endif + +static const char *home; + +/*! [case insensitive comparator] */ +/* A simple case insensitive comparator. */ +static int +__compare_nocase(WT_COLLATOR *collator, WT_SESSION *session, + const WT_ITEM *v1, const WT_ITEM *v2, int *cmp) +{ + const char *s1 = (const char *)v1->data; + const char *s2 = (const char *)v2->data; + + (void)session; /* unused */ + (void)collator; /* unused */ + + *cmp = strcasecmp(s1, s2); + return (0); +} + +static WT_COLLATOR nocasecoll = { __compare_nocase, NULL, NULL }; +/*! [case insensitive comparator] */ + +/*! [n character comparator] */ +/* + * Comparator that only compares the first N prefix characters of the string. + * This has associated data, so we need to extend WT_COLLATOR. + */ +typedef struct { + WT_COLLATOR iface; + uint32_t maxlen; +} PREFIX_COLLATOR; + +static int +__compare_prefixes(WT_COLLATOR *collator, WT_SESSION *session, + const WT_ITEM *v1, const WT_ITEM *v2, int *cmp) +{ + PREFIX_COLLATOR *pcoll = (PREFIX_COLLATOR *)collator; + const char *s1 = (const char *)v1->data; + const char *s2 = (const char *)v2->data; + + (void)session; /* unused */ + + *cmp = strncmp(s1, s2, pcoll->maxlen); + return (0); +} + +static PREFIX_COLLATOR pcoll10 = { {__compare_prefixes, NULL, NULL}, 10 }; +/*! [n character comparator] */ + +int +main(void) +{ + int ret; + WT_CONNECTION *conn; + WT_SESSION *session; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + /* Open a connection to the database, creating it if necessary. */ + if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0) + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + + /*! [add collator nocase] */ + ret = conn->add_collator(conn, "nocase", &nocasecoll, NULL); + /*! [add collator nocase] */ + /*! [add collator prefix10] */ + ret = conn->add_collator(conn, "prefix10", &pcoll10.iface, NULL); + + /* Open a session for the current thread's work. */ + if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) + fprintf(stderr, "Error opening a session on %s: %s\n", + home, wiredtiger_strerror(ret)); + + /* XXX Do some work... */ + + /* Note: closing the connection implicitly closes open session(s). */ + if ((ret = conn->close(conn, NULL)) != 0) + /*! [add collator prefix10] */ + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_file.c b/src/third_party/wiredtiger/examples/c/ex_file.c new file mode 100644 index 00000000000..4170d1b099d --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_file.c @@ -0,0 +1,72 @@ +/*- + * Public Domain 2008-2014 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_file.c + * This is an example demonstrating how to configure an individual file. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +static const char *home; + +int +main(void) +{ + WT_CONNECTION *conn; + WT_SESSION *session; + int ret; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0 || + (ret = conn->open_session(conn, NULL, NULL, &session)) != 0) { + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + return (ret); + } + /* Note: further error checking omitted for clarity. */ + + /*! [file create] */ + ret = session->create(session, "file:example", + "key_format=u," + "internal_page_max=32KB,internal_item_max=1KB," + "leaf_page_max=1MB,leaf_item_max=32KB"); + /*! [file create] */ + + return (conn->close(conn, NULL) == 0 ? ret : EXIT_FAILURE); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_hello.c b/src/third_party/wiredtiger/examples/c/ex_hello.c new file mode 100644 index 00000000000..c94c1072f61 --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_hello.c @@ -0,0 +1,75 @@ +/*- + * Public Domain 2008-2014 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_hello.c + * This is an example demonstrating how to create and connect to a + * database. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +static const char *home; + +int +main(void) +{ + WT_CONNECTION *conn; + WT_SESSION *session; + int ret; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + /* Open a connection to the database, creating it if necessary. */ + if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0) + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + + /* Open a session for the current thread's work. */ + if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) + fprintf(stderr, "Error opening a session on %s: %s\n", + home, wiredtiger_strerror(ret)); + + /* Do some work... */ + + /* Note: closing the connection implicitly closes open session(s). */ + if ((ret = conn->close(conn, NULL)) != 0) + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_log.c b/src/third_party/wiredtiger/examples/c/ex_log.c new file mode 100644 index 00000000000..8ac7d079da1 --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_log.c @@ -0,0 +1,344 @@ +/*- + * Public Domain 2008-2014 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_log.c + * demonstrates how to logging and log cursors. + */ +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifndef _WIN32 +#include <unistd.h> +#else +/* snprintf is not supported on <= VS2013 */ +#define snprintf _snprintf +#endif + +#include <wiredtiger.h> + +static const char *home1 = "WT_HOME_LOG_1"; +static const char *home2 = "WT_HOME_LOG_2"; + +static const char * const uri = "table:logtest"; + +#define CONN_CONFIG "create,cache_size=100MB,log=(archive=false,enabled=true)" +#define MAX_KEYS 10 + +static int +setup_copy(WT_CONNECTION **wt_connp, WT_SESSION **sessionp) +{ + int ret; + + if ((ret = wiredtiger_open(home2, NULL, + CONN_CONFIG, wt_connp)) != 0) { + fprintf(stderr, "Error connecting to %s: %s\n", + home1, wiredtiger_strerror(ret)); + return (ret); + } + + ret = (*wt_connp)->open_session(*wt_connp, NULL, NULL, sessionp); + ret = (*sessionp)->create(*sessionp, uri, + "key_format=S,value_format=S"); + return (ret); +} + +static int +compare_tables(WT_SESSION *session, WT_SESSION *sess_copy) +{ + WT_CURSOR *cursor, *curs_copy; + int ret; + const char *key, *key_copy, *value, *value_copy; + + ret = session->open_cursor(session, uri, NULL, NULL, &cursor); + ret = sess_copy->open_cursor(sess_copy, uri, NULL, NULL, &curs_copy); + + while ((ret = cursor->next(cursor)) == 0) { + ret = curs_copy->next(curs_copy); + ret = cursor->get_key(cursor, &key); + ret = cursor->get_value(cursor, &value); + ret = curs_copy->get_key(curs_copy, &key_copy); + ret = curs_copy->get_value(curs_copy, &value_copy); + if (strcmp(key, key_copy) != 0 || + strcmp(value, value_copy) != 0) { + fprintf(stderr, + "Mismatched: key %s, key_copy %s " + "value %s value_copy %s\n", + key, key_copy, value, value_copy); + return (1); + } + } + if (ret != WT_NOTFOUND) + fprintf(stderr, + "WT_CURSOR.next: %s\n", wiredtiger_strerror(ret)); + ret = cursor->close(cursor); + + ret = curs_copy->next(curs_copy); + if (ret != WT_NOTFOUND) + fprintf(stderr, + "copy: WT_CURSOR.next: %s\n", wiredtiger_strerror(ret)); + ret = curs_copy->close(curs_copy); + + return (ret); +} + +/*! [log cursor walk] */ +static void +print_record(WT_LSN *lsn, uint32_t opcount, + uint32_t rectype, uint32_t optype, uint64_t txnid, uint32_t fileid, + WT_ITEM *key, WT_ITEM *value) +{ + printf( + "LSN [%" PRIu32 "][%" PRIu64 "].%" PRIu32 + ": record type %" PRIu32 " optype %" PRIu32 + " txnid %" PRIu64 " fileid %" PRIu32, + lsn->file, (uint64_t)lsn->offset, opcount, + rectype, optype, txnid, fileid); + printf(" key size %zu value size %zu\n", key->size, value->size); + if (rectype == WT_LOGREC_MESSAGE) + printf("Application Record: %s\n", (char *)value->data); +} + +/* + * simple_walk_log -- + * A simple walk of the log. + */ +static int +simple_walk_log(WT_SESSION *session) +{ + WT_CURSOR *cursor; + WT_LSN lsn; + WT_ITEM logrec_key, logrec_value; + uint64_t txnid; + uint32_t fileid, opcount, optype, rectype; + int ret; + + /*! [log cursor open] */ + ret = session->open_cursor(session, "log:", NULL, NULL, &cursor); + /*! [log cursor open] */ + + while ((ret = cursor->next(cursor)) == 0) { + /*! [log cursor get_key] */ + ret = cursor->get_key(cursor, &lsn.file, &lsn.offset, &opcount); + /*! [log cursor get_key] */ + /*! [log cursor get_value] */ + ret = cursor->get_value(cursor, &txnid, + &rectype, &optype, &fileid, &logrec_key, &logrec_value); + /*! [log cursor get_value] */ + + print_record(&lsn, opcount, + rectype, optype, txnid, fileid, &logrec_key, &logrec_value); + } + if (ret == WT_NOTFOUND) + ret = 0; + ret = cursor->close(cursor); + return (ret); +} +/*! [log cursor walk] */ + +static int +walk_log(WT_SESSION *session) +{ + WT_CONNECTION *wt_conn2; + WT_CURSOR *cursor, *cursor2; + WT_LSN lsn, lsnsave; + WT_ITEM logrec_key, logrec_value; + WT_SESSION *session2; + uint64_t txnid; + uint32_t fileid, opcount, optype, rectype; + int first, i, in_txn, ret; + + ret = setup_copy(&wt_conn2, &session2); + ret = session->open_cursor(session, "log:", NULL, NULL, &cursor); + ret = session2->open_cursor(session2, uri, NULL, "raw=true", &cursor2); + i = 0; + in_txn = 0; + txnid = 0; + memset(&lsnsave, 0, sizeof(lsnsave)); + while ((ret = cursor->next(cursor)) == 0) { + ret = cursor->get_key(cursor, &lsn.file, &lsn.offset, &opcount); + /* + * Save one of the LSNs we get back to search for it + * later. Pick a later one because we want to walk from + * that LSN to the end (where the multi-step transaction + * was performed). Just choose the record that is MAX_KEYS. + */ + if (++i == MAX_KEYS) + lsnsave = lsn; + ret = cursor->get_value(cursor, &txnid, &rectype, + &optype, &fileid, &logrec_key, &logrec_value); + + print_record(&lsn, opcount, + rectype, optype, txnid, fileid, &logrec_key, &logrec_value); + + /* + * If we are in a transaction and this is a new one, end + * the previous one. + */ + if (in_txn && opcount == 0) { + ret = session2->commit_transaction(session2, NULL); + in_txn = 0; + } + + /* + * If the operation is a put, replay it here on the backup + * connection. Note, we cheat by looking only for fileid 1 + * in this example. The metadata is fileid 0. + */ + if (fileid == 1 && rectype == WT_LOGREC_COMMIT && + optype == WT_LOGOP_ROW_PUT) { + if (!in_txn) { + ret = session2->begin_transaction(session2, + NULL); + in_txn = 1; + } + cursor2->set_key(cursor2, &logrec_key); + cursor2->set_value(cursor2, &logrec_value); + ret = cursor2->insert(cursor2); + } + } + if (in_txn) + ret = session2->commit_transaction(session2, NULL); + + ret = cursor2->close(cursor2); + /* + * Compare the tables after replay. They should be identical. + */ + if (compare_tables(session, session2)) + printf("compare failed\n"); + ret = session2->close(session2, NULL); + ret = wt_conn2->close(wt_conn2, NULL); + + ret = cursor->reset(cursor); + /*! [log cursor set_key] */ + cursor->set_key(cursor, lsnsave.file, lsnsave.offset, 0); + /*! [log cursor set_key] */ + /*! [log cursor search] */ + ret = cursor->search(cursor); + /*! [log cursor search] */ + printf("Reset to saved...\n"); + /* + * Walk all records starting with this key. + */ + first = 1; + while ((ret = cursor->get_key(cursor, + &lsn.file, &lsn.offset, &opcount)) == 0) { + if (first) { + first = 0; + if (lsnsave.file != lsn.file || + lsnsave.offset != lsn.offset) { + fprintf(stderr, + "search returned the wrong LSN\n"); + exit (1); + } + } + ret = cursor->get_value(cursor, &txnid, &rectype, + &optype, &fileid, &logrec_key, &logrec_value); + + print_record(&lsn, opcount, + rectype, optype, txnid, fileid, &logrec_key, &logrec_value); + + ret = cursor->next(cursor); + if (ret != 0) + break; + } + ret = cursor->close(cursor); + return (ret); +} + +int +main(void) +{ + WT_CONNECTION *wt_conn; + WT_CURSOR *cursor; + WT_SESSION *session; + int i, record_count, ret; + char cmd_buf[256], k[16], v[16]; + + snprintf(cmd_buf, sizeof(cmd_buf), "rm -rf %s %s && mkdir %s %s", + home1, home2, home1, home2); + if ((ret = system(cmd_buf)) != 0) { + fprintf(stderr, "%s: failed ret %d\n", cmd_buf, ret); + return (ret); + } + if ((ret = wiredtiger_open(home1, NULL, + CONN_CONFIG, &wt_conn)) != 0) { + fprintf(stderr, "Error connecting to %s: %s\n", + home1, wiredtiger_strerror(ret)); + return (ret); + } + + ret = wt_conn->open_session(wt_conn, NULL, NULL, &session); + ret = session->create(session, uri, "key_format=S,value_format=S"); + + ret = session->open_cursor(session, uri, NULL, NULL, &cursor); + /* + * Perform some operations with individual auto-commit transactions. + */ + for (record_count = 0, i = 0; i < MAX_KEYS; i++, record_count++) { + snprintf(k, sizeof(k), "key%d", i); + snprintf(v, sizeof(v), "value%d", i); + cursor->set_key(cursor, k); + cursor->set_value(cursor, v); + ret = cursor->insert(cursor); + } + ret = session->begin_transaction(session, NULL); + /* + * Perform some operations within a single transaction. + */ + for (i = MAX_KEYS; i < MAX_KEYS+5; i++, record_count++) { + snprintf(k, sizeof(k), "key%d", i); + snprintf(v, sizeof(v), "value%d", i); + cursor->set_key(cursor, k); + cursor->set_value(cursor, v); + ret = cursor->insert(cursor); + } + ret = session->commit_transaction(session, NULL); + ret = cursor->close(cursor); + + /*! [log cursor printf] */ + ret = session->log_printf(session, "Wrote %d records", record_count); + /*! [log cursor printf] */ + + /* + * Close and reopen the connection so that the log ends up with + * a variety of records such as file sync and checkpoint. We + * have archiving turned off. + */ + ret = wt_conn->close(wt_conn, NULL); + if ((ret = wiredtiger_open(home1, NULL, + CONN_CONFIG, &wt_conn)) != 0) { + fprintf(stderr, "Error connecting to %s: %s\n", + home1, wiredtiger_strerror(ret)); + return (ret); + } + + ret = wt_conn->open_session(wt_conn, NULL, NULL, &session); + ret = simple_walk_log(session); + ret = walk_log(session); + ret = wt_conn->close(wt_conn, NULL); + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_pack.c b/src/third_party/wiredtiger/examples/c/ex_pack.c new file mode 100644 index 00000000000..29d645f6cfc --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_pack.c @@ -0,0 +1,85 @@ +/*- + * Public Domain 2008-2014 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_pack.c + * This is an example demonstrating basic packing and unpacking of fields. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +static const char *home; + +int +main(void) +{ + WT_CONNECTION *conn; + WT_SESSION *session; + char buf[50]; + size_t size; + int i, j, k, ret; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + /* Open a connection to the database, creating it if necessary. */ + if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0) + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + + /* Open a session for the current thread's work. */ + if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) + fprintf(stderr, "Error opening a session on %s: %s\n", + home, wiredtiger_strerror(ret)); + + /*! [packing] */ + ret = wiredtiger_struct_size(session, &size, "iii", 42, 1000, -9); + if (size > sizeof(buf)) { + /* Allocate a bigger buffer. */ + } + + ret = wiredtiger_struct_pack(session, buf, size, "iii", 42, 1000, -9); + + ret = wiredtiger_struct_unpack(session, buf, size, "iii", &i, &j, &k); + /*! [packing] */ + + /* Note: closing the connection implicitly closes open session(s). */ + if ((ret = conn->close(conn, NULL)) != 0) + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_process.c b/src/third_party/wiredtiger/examples/c/ex_process.c new file mode 100644 index 00000000000..a25d9084965 --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_process.c @@ -0,0 +1,78 @@ +/*- + * Public Domain 2008-2014 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_process.c + * This is an example demonstrating how to connect to a database from + * multiple processes. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +static const char *home; + +int +main(void) +{ + int ret; + WT_CONNECTION *conn; + WT_SESSION *session; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + /*! [processes] */ + /* Open a connection to the database, creating it if necessary. */ + if ((ret = + wiredtiger_open(home, NULL, "create,multiprocess", &conn)) != 0) + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + + /* Open a session for the current thread's work. */ + if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) + fprintf(stderr, "Error opening a session on %s: %s\n", + home, wiredtiger_strerror(ret)); + + /* XXX Do some work... */ + + /* Note: closing the connection implicitly closes open session(s). */ + if ((ret = conn->close(conn, NULL)) != 0) + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + /*! [processes] */ + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_schema.c b/src/third_party/wiredtiger/examples/c/ex_schema.c new file mode 100644 index 00000000000..bc2f3b6c2d9 --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_schema.c @@ -0,0 +1,309 @@ +/*- + * Public Domain 2008-2014 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_schema.c + * This is an example application demonstrating how to create and access + * tables using a schema. + */ + +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +static const char *home; + +/*! [schema declaration] */ +/* The C struct for the data we are storing in a WiredTiger table. */ +typedef struct { + char country[5]; + uint16_t year; + uint64_t population; +} POP_RECORD; + +static POP_RECORD pop_data[] = { + { "AU", 1900, 4000000 }, + { "AU", 2000, 19053186 }, + { "CAN", 1900, 5500000 }, + { "CAN", 2000, 31099561 }, + { "UK", 1900, 369000000 }, + { "UK", 2000, 59522468 }, + { "USA", 1900, 76212168 }, + { "USA", 2000, 301279593 }, + { "", 0, 0 } +}; +/*! [schema declaration] */ + +int +main(void) +{ + POP_RECORD *p; + WT_CONNECTION *conn; + WT_CURSOR *cursor; + WT_SESSION *session; + const char *country; + uint64_t recno, population; + uint16_t year; + int ret; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0) { + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + return (ret); + } + /* Note: error checking omitted for clarity. */ + + ret = conn->open_session(conn, NULL, NULL, &session); + + /*! [Create a table with column groups] */ + /* + * Create the population table. + * Keys are record numbers, the format for values is (5-byte string, + * uint16_t, uint64_t). + * See ::wiredtiger_struct_pack for details of the format strings. + */ + ret = session->create(session, "table:poptable", + "key_format=r," + "value_format=5sHQ," + "columns=(id,country,year,population)," + "colgroups=(main,population)"); + + /* + * Create two column groups: a primary column group with the country + * code, year and population (named "main"), and a population column + * group with the population by itself (named "population"). + */ + ret = session->create(session, + "colgroup:poptable:main", "columns=(country,year,population)"); + ret = session->create(session, + "colgroup:poptable:population", "columns=(population)"); + /*! [Create a table with column groups] */ + + /*! [Create an index] */ + /* Create an index with a simple key. */ + ret = session->create(session, + "index:poptable:country", "columns=(country)"); + /*! [Create an index] */ + + /*! [Create an index with a composite key] */ + /* Create an index with a composite key (country,year). */ + ret = session->create(session, + "index:poptable:country_plus_year", "columns=(country,year)"); + /*! [Create an index with a composite key] */ + + /* Insert the records into the table. */ + ret = session->open_cursor( + session, "table:poptable", NULL, "append", &cursor); + for (p = pop_data; p->year != 0; p++) { + cursor->set_value(cursor, p->country, p->year, p->population); + ret = cursor->insert(cursor); + } + ret = cursor->close(cursor); + + /* List the records in the table. */ + ret = session->open_cursor(session, + "table:poptable", NULL, NULL, &cursor); + while ((ret = cursor->next(cursor)) == 0) { + ret = cursor->get_key(cursor, &recno); + ret = cursor->get_value(cursor, &country, &year, &population); + printf("ID %" PRIu64, recno); + printf(": country %s, year %u, population %" PRIu64 "\n", + country, year, population); + } + ret = cursor->close(cursor); + + /*! [List the records in the table using raw mode.] */ + /* List the records in the table using raw mode. */ + ret = session->open_cursor(session, + "table:poptable", NULL, "raw", &cursor); + while ((ret = cursor->next(cursor)) == 0) { + WT_ITEM key, value; + + ret = cursor->get_key(cursor, &key); + ret = wiredtiger_struct_unpack(session, + key.data, key.size, "r", &recno); + printf("ID %" PRIu64, recno); + + ret = cursor->get_value(cursor, &value); + ret = wiredtiger_struct_unpack(session, + value.data, value.size, + "5sHQ", &country, &year, &population); + printf(": country %s, year %u, population %" PRIu64 "\n", + country, year, population); + } + /*! [List the records in the table using raw mode.] */ + ret = cursor->close(cursor); + + /*! [Read population from the primary column group] */ + /* + * Open a cursor on the main column group, and return the information + * for a particular country. + */ + ret = session->open_cursor( + session, "colgroup:poptable:main", NULL, NULL, &cursor); + cursor->set_key(cursor, 2); + if ((ret = cursor->search(cursor)) == 0) { + ret = cursor->get_value(cursor, &country, &year, &population); + printf("ID 2: country %s, year %u, population %" PRIu64 "\n", + country, year, population); + } + /*! [Read population from the primary column group] */ + ret = cursor->close(cursor); + + /*! [Read population from the standalone column group] */ + /* + * Open a cursor on the population column group, and return the + * population of a particular country. + */ + ret = session->open_cursor(session, + "colgroup:poptable:population", NULL, NULL, &cursor); + cursor->set_key(cursor, 2); + if ((ret = cursor->search(cursor)) == 0) { + ret = cursor->get_value(cursor, &population); + printf("ID 2: population %" PRIu64 "\n", population); + } + /*! [Read population from the standalone column group] */ + ret = cursor->close(cursor); + + /*! [Search in a simple index] */ + /* Search in a simple index. */ + ret = session->open_cursor(session, + "index:poptable:country", NULL, NULL, &cursor); + cursor->set_key(cursor, "AU\0\0\0"); + ret = cursor->search(cursor); + ret = cursor->get_value(cursor, &country, &year, &population); + printf("AU: country %s, year %u, population %" PRIu64 "\n", + country, (unsigned int)year, population); + /*! [Search in a simple index] */ + ret = cursor->close(cursor); + + /*! [Search in a composite index] */ + /* Search in a composite index. */ + ret = session->open_cursor(session, + "index:poptable:country_plus_year", NULL, NULL, &cursor); + cursor->set_key(cursor, "USA\0\0", (uint16_t)1900); + ret = cursor->search(cursor); + ret = cursor->get_value(cursor, &country, &year, &population); + printf("US 1900: country %s, year %u, population %" PRIu64 "\n", + country, (unsigned int)year, population); + /*! [Search in a composite index] */ + ret = cursor->close(cursor); + + /*! [Return a subset of values from the table] */ + /* + * Use a projection to return just the table's country and year + * columns. + */ + ret = session->open_cursor(session, + "table:poptable(country,year)", NULL, NULL, &cursor); + while ((ret = cursor->next(cursor)) == 0) { + ret = cursor->get_value(cursor, &country, &year); + printf("country %s, year %u\n", country, year); + } + /*! [Return a subset of values from the table] */ + ret = cursor->close(cursor); + + /*! [Return a subset of values from the table using raw mode] */ + /* + * Use a projection to return just the table's country and year + * columns, using raw mode. + */ + ret = session->open_cursor(session, + "table:poptable(country,year)", NULL, "raw", &cursor); + while ((ret = cursor->next(cursor)) == 0) { + WT_ITEM value; + + ret = cursor->get_value(cursor, &value); + ret = wiredtiger_struct_unpack( + session, value.data, value.size, "5sH", &country, &year); + printf("country %s, year %u\n", country, year); + } + /*! [Return a subset of values from the table using raw mode] */ + ret = cursor->close(cursor); + + /*! [Return the table's record number key using an index] */ + /* + * Use a projection to return just the table's record number key + * from an index. + */ + ret = session->open_cursor(session, + "index:poptable:country_plus_year(id)", NULL, NULL, &cursor); + while ((ret = cursor->next(cursor)) == 0) { + ret = cursor->get_key(cursor, &country, &year); + ret = cursor->get_value(cursor, &recno); + printf("row ID %" PRIu64 ": country %s, year %u\n", + recno, country, year); + } + /*! [Return the table's record number key using an index] */ + ret = cursor->close(cursor); + + /*! [Return a subset of the value columns from an index] */ + /* + * Use a projection to return just the population column from an + * index. + */ + ret = session->open_cursor(session, + "index:poptable:country_plus_year(population)", + NULL, NULL, &cursor); + while ((ret = cursor->next(cursor)) == 0) { + ret = cursor->get_key(cursor, &country, &year); + ret = cursor->get_value(cursor, &population); + printf("population %" PRIu64 ": country %s, year %u\n", + population, country, year); + } + /*! [Return a subset of the value columns from an index] */ + ret = cursor->close(cursor); + + /*! [Access only the index] */ + /* + * Use a projection to avoid accessing any other column groups when + * using an index: supply an empty list of value columns. + */ + ret = session->open_cursor(session, + "index:poptable:country_plus_year()", NULL, NULL, &cursor); + while ((ret = cursor->next(cursor)) == 0) { + ret = cursor->get_key(cursor, &country, &year); + printf("country %s, year %u\n", country, year); + } + /*! [Access only the index] */ + ret = cursor->close(cursor); + + ret = conn->close(conn, NULL); + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_scope.c b/src/third_party/wiredtiger/examples/c/ex_scope.c new file mode 100644 index 00000000000..334745f7e37 --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_scope.c @@ -0,0 +1,174 @@ +/*- + * Public Domain 2008-2014 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_scope.c + * demonstrates the scope of buffers holding cursor keys and values. + */ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +#ifdef _WIN32 +/* snprintf is not supported on <= VS2013 */ +#define snprintf _snprintf +#endif + +static const char *home; + +static int +cursor_scope_ops(WT_CURSOR *cursor) +{ + struct { + const char *key; + const char *value; + int (*apply)(WT_CURSOR *); + } *op, ops[] = { + { "key1", "value1", cursor->insert, }, + { "key1", "value2", cursor->update, }, + { "key1", "value2", cursor->search, }, + { "key1", "value2", cursor->remove, }, + { NULL, NULL, NULL } + }; + const char *key, *value; + char keybuf[10], valuebuf[10]; + int ret; + + for (op = ops; op->key != NULL; op++) { + key = value = NULL; + + /*! [cursor scope operation] */ + (void)snprintf(keybuf, sizeof(keybuf), "%s", op->key); + cursor->set_key(cursor, keybuf); + (void)snprintf(valuebuf, sizeof(valuebuf), "%s", op->value); + cursor->set_value(cursor, valuebuf); + + /* + * The application must keep the key and value memory valid + * until the next operation that positions the cursor. + * Modifying either the key or value buffers is not permitted. + */ + + /* Apply the operation (insert, update, search or remove). */ + if ((ret = op->apply(cursor)) != 0) { + fprintf(stderr, "Error performing the operation: %s\n", + wiredtiger_strerror(ret)); + return (ret); + } + + /* + * Except for WT_CURSOR::insert, the cursor has been positioned + * and no longer references application memory, so application + * buffers can be safely overwritten. + */ + if (op->apply != cursor->insert) { + strcpy(keybuf, "no key"); + strcpy(valuebuf, "no value"); + } + + /* + * Check that get_key/value behave as expected after the + * operation. + */ + if ((ret = cursor->get_key(cursor, &key)) != 0 || + (op->apply != cursor->remove && + (ret = cursor->get_value(cursor, &value)) != 0)) { + fprintf(stderr, "Error in get_key/value: %s\n", + wiredtiger_strerror(ret)); + return (ret); + } + + /* + * Except for WT_CURSOR::insert (which does not position the + * cursor), the application now has pointers to memory owned + * by the cursor. Modifying the memory referenced by either + * key or value is not permitted. + */ + + /* Check that the cursor's key and value are what we expect. */ + if (op->apply != cursor->insert) + if (key == keybuf || + (op->apply != cursor->remove && + value == valuebuf)) { + fprintf(stderr, + "Cursor points at application memory!\n"); + return (EINVAL); + } + + if (strcmp(key, op->key) != 0 || + (op->apply != cursor->remove && + strcmp(value, op->value) != 0)) { + fprintf(stderr, "Unexpected key / value!\n"); + return (EINVAL); + } + /*! [cursor scope operation] */ + } + + return (0); +} + +int +main(void) +{ + WT_CONNECTION *conn; + WT_CURSOR *cursor; + WT_SESSION *session; + int ret, tret; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + /* Open a connection, create a simple table, open a cursor. */ + if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0 || + (ret = conn->open_session(conn, NULL, NULL, &session)) != 0) { + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + return (ret); + } + + ret = session->create(session, + "table:scope", "key_format=S,value_format=S,columns=(k,v)"); + + ret = session->open_cursor(session, + "table:scope", NULL, NULL, &cursor); + + ret = cursor_scope_ops(cursor); + + /* Close the connection and clean up. */ + if ((tret = conn->close(conn, NULL)) != 0 && ret == 0) + ret = tret; + + return (ret); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_stat.c b/src/third_party/wiredtiger/examples/c/ex_stat.c new file mode 100644 index 00000000000..0614a1de234 --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_stat.c @@ -0,0 +1,223 @@ +/*- + * Public Domain 2008-2014 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_stat.c + * This is an example demonstrating how to query database statistics. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +int print_cursor(WT_CURSOR *); +int print_database_stats(WT_SESSION *); +int print_file_stats(WT_SESSION *); +int print_overflow_pages(WT_SESSION *); +int get_stat(WT_CURSOR *cursor, int stat_field, uint64_t *valuep); +int print_derived_stats(WT_SESSION *); + +static const char *home; + +/*! [statistics display function] */ +int +print_cursor(WT_CURSOR *cursor) +{ + const char *desc, *pvalue; + uint64_t value; + int ret; + + while ((ret = cursor->next(cursor)) == 0 && + (ret = cursor->get_value(cursor, &desc, &pvalue, &value)) == 0) + if (value != 0) + printf("%s=%s\n", desc, pvalue); + + return (ret == WT_NOTFOUND ? 0 : ret); +} +/*! [statistics display function] */ + +int +print_database_stats(WT_SESSION *session) +{ + WT_CURSOR *cursor; + int ret; + + /*! [statistics database function] */ + if ((ret = session->open_cursor(session, + "statistics:", NULL, NULL, &cursor)) != 0) + return (ret); + + ret = print_cursor(cursor); + ret = cursor->close(cursor); + /*! [statistics database function] */ + + return (ret); +} + +int +print_file_stats(WT_SESSION *session) +{ + WT_CURSOR *cursor; + int ret; + + /*! [statistics table function] */ + if ((ret = session->open_cursor(session, + "statistics:table:access", NULL, NULL, &cursor)) != 0) + return (ret); + + ret = print_cursor(cursor); + ret = cursor->close(cursor); + /*! [statistics table function] */ + + return (ret); +} + +int +print_overflow_pages(WT_SESSION *session) +{ + /*! [statistics retrieve by key] */ + WT_CURSOR *cursor; + const char *desc, *pvalue; + uint64_t value; + int ret; + + if ((ret = session->open_cursor(session, + "statistics:table:access", NULL, NULL, &cursor)) != 0) + return (ret); + + cursor->set_key(cursor, WT_STAT_DSRC_BTREE_OVERFLOW); + ret = cursor->search(cursor); + ret = cursor->get_value(cursor, &desc, &pvalue, &value); + printf("%s=%s\n", desc, pvalue); + + ret = cursor->close(cursor); + /*! [statistics retrieve by key] */ + + return (ret); +} + +/*! [statistics calculation helper function] */ +int +get_stat(WT_CURSOR *cursor, int stat_field, uint64_t *valuep) +{ + const char *desc, *pvalue; + int ret; + + cursor->set_key(cursor, stat_field); + if ((ret = cursor->search(cursor)) != 0) + return (ret); + + return (cursor->get_value(cursor, &desc, &pvalue, valuep)); +} +/*! [statistics calculation helper function] */ + +int +print_derived_stats(WT_SESSION *session) +{ + WT_CURSOR *cursor; + int ret; + + /*! [statistics calculate open table stats] */ + if ((ret = session->open_cursor(session, + "statistics:table:access", NULL, NULL, &cursor)) != 0) + return (ret); + /*! [statistics calculate open table stats] */ + + { + /*! [statistics calculate table fragmentation] */ + uint64_t ckpt_size, file_size; + ret = get_stat(cursor, WT_STAT_DSRC_BLOCK_CHECKPOINT_SIZE, &ckpt_size); + ret = get_stat(cursor, WT_STAT_DSRC_BLOCK_SIZE, &file_size); + + printf("File is %d%% fragmented\n", + (int)(100 * (file_size - ckpt_size) / file_size)); + /*! [statistics calculate table fragmentation] */ + } + + { + /*! [statistics calculate write amplification] */ + uint64_t app_insert, app_remove, app_update, fs_writes; + + ret = get_stat(cursor, WT_STAT_DSRC_CURSOR_INSERT_BYTES, &app_insert); + ret = get_stat(cursor, WT_STAT_DSRC_CURSOR_REMOVE_BYTES, &app_remove); + ret = get_stat(cursor, WT_STAT_DSRC_CURSOR_UPDATE_BYTES, &app_update); + + ret = get_stat(cursor, WT_STAT_DSRC_CACHE_BYTES_WRITE, &fs_writes); + + if (app_insert + app_remove + app_update != 0) + printf("Write amplification is %.2lf\n", + (double)fs_writes / (app_insert + app_remove + app_update)); + /*! [statistics calculate write amplification] */ + } + + ret = cursor->close(cursor); + + return (ret); +} + +int +main(void) +{ + WT_CONNECTION *conn; + WT_CURSOR *cursor; + WT_SESSION *session; + int ret; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + ret = wiredtiger_open(home, NULL, "create,statistics=(all)", &conn); + ret = conn->open_session(conn, NULL, NULL, &session); + ret = session->create( + session, "table:access", "key_format=S,value_format=S"); + + ret = session->open_cursor( + session, "table:access", NULL, NULL, &cursor); + cursor->set_key(cursor, "key"); + cursor->set_value(cursor, "value"); + ret = cursor->insert(cursor); + ret = cursor->close(cursor); + + ret = session->checkpoint(session, NULL); + + ret = print_database_stats(session); + + ret = print_file_stats(session); + + ret = print_overflow_pages(session); + + ret = print_derived_stats(session); + + return (conn->close(conn, NULL) == 0 ? ret : EXIT_FAILURE); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_thread.c b/src/third_party/wiredtiger/examples/c/ex_thread.c new file mode 100644 index 00000000000..5ea3a0a4894 --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_thread.c @@ -0,0 +1,126 @@ +/*- + * Public Domain 2008-2014 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_thread.c + * This is an example demonstrating how to create and access a simple + * table from multiple threads. + */ + +#ifndef _WIN32 +#include <pthread.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifdef _WIN32 +#include "windows_shim.h" +#endif + +#include <wiredtiger.h> + +static const char *home; + +void *scan_thread(void *arg); + +#define NUM_THREADS 10 + +/*! [thread scan] */ +void * +scan_thread(void *conn_arg) +{ + WT_CONNECTION *conn; + WT_SESSION *session; + WT_CURSOR *cursor; + const char *key, *value; + int ret; + + conn = conn_arg; + ret = conn->open_session(conn, NULL, NULL, &session); + ret = session->open_cursor( + session, "table:access", NULL, NULL, &cursor); + + /* Show all records. */ + while ((ret = cursor->next(cursor)) == 0) { + ret = cursor->get_key(cursor, &key); + ret = cursor->get_value(cursor, &value); + + printf("Got record: %s : %s\n", key, value); + } + if (ret != WT_NOTFOUND) + fprintf(stderr, + "WT_CURSOR.next: %s\n", wiredtiger_strerror(ret)); + + return (NULL); +} +/*! [thread scan] */ + +/*! [thread main] */ +int +main(void) +{ + WT_CONNECTION *conn; + WT_SESSION *session; + WT_CURSOR *cursor; + pthread_t threads[NUM_THREADS]; + int i, ret; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (getenv("WIREDTIGER_HOME") == NULL) { + home = "WT_HOME"; + ret = system("rm -rf WT_HOME && mkdir WT_HOME"); + } else + home = NULL; + + if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0) + fprintf(stderr, "Error connecting to %s: %s\n", + home, wiredtiger_strerror(ret)); + /* Note: further error checking omitted for clarity. */ + + ret = conn->open_session(conn, NULL, NULL, &session); + ret = session->create(session, "table:access", + "key_format=S,value_format=S"); + ret = session->open_cursor(session, "table:access", NULL, + "overwrite", &cursor); + cursor->set_key(cursor, "key1"); + cursor->set_value(cursor, "value1"); + ret = cursor->insert(cursor); + ret = session->close(session, NULL); + + for (i = 0; i < NUM_THREADS; i++) + ret = pthread_create(&threads[i], NULL, scan_thread, conn); + + for (i = 0; i < NUM_THREADS; i++) + ret = pthread_join(threads[i], NULL); + + ret = conn->close(conn, NULL); + + return (ret); +} +/*! [thread main] */ diff --git a/src/third_party/wiredtiger/examples/java/Makefile.am b/src/third_party/wiredtiger/examples/java/Makefile.am new file mode 100644 index 00000000000..c7fbfffa48c --- /dev/null +++ b/src/third_party/wiredtiger/examples/java/Makefile.am @@ -0,0 +1,21 @@ +AM_CPPFLAGS = -I$(abs_top_builddir) + +JAVAEXAMPLES = $(top_srcdir)/examples/java/com/wiredtiger/examples + +# TODO: How to add to existing Javadoc from main API? +# JDOCDIR = $(top_srcdir)/docs/java +# java_DATA = $(JDOCDIR)/index.html + +javadir = $(datadir)/java +dist_java_JAVA = \ + $(JAVAEXAMPLES)/ex_access.java + +all-local: wiredtiger.jar + +$(JDOCDIR)/index.html: $(dist_java_JAVA) + mkdir -p $(JDOCDIR) + javadoc -public -d $(JDOCDIR) -link http://docs.oracle.com/javase/6/docs/api $(JAVAEXAMPLES)/[A-Z]*.java + +wiredtiger.jar: $(dist_java_JAVA) + (cd $(top_builddir) && \ + $(JAR) -cf wiredtiger.jar com/) diff --git a/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_access.java b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_access.java new file mode 100644 index 00000000000..d4046495df5 --- /dev/null +++ b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_access.java @@ -0,0 +1,93 @@ +/*- + * Public Domain 2008-2014 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_access.java + * demonstrates how to create and access a simple table. + */ +package com.wiredtiger.examples; +import com.wiredtiger.db.*; + +public class ex_access { + public static void main(String[] args) { + /*! [access example connection] */ + Connection conn; + Session s; + Cursor c; + + try { + conn = wiredtiger.open("WT_HOME", "create"); + s = conn.open_session(null); + } catch (WiredTigerException wte) { + System.err.println("WiredTigerException: " + wte); + return; + } + /*! [access example connection] */ + try { + /*! [access example table create] */ + s.create("table:t", "key_format=S,value_format=u"); + /*! [access example table create] */ + /*! [access example cursor open] */ + c = s.open_cursor("table:t", null, null); + /*! [access example cursor open] */ + } catch (WiredTigerException wte) { + System.err.println("WiredTigerException: " + wte); + return; + } + System.out.println("Key format: " + c.getKeyFormat()); + System.out.println("Value format: " + c.getValueFormat()); + /*! [access example cursor insert] */ + try { + c.putKeyString("foo"); + c.putValueByteArray("bar".getBytes()); + c.insert(); + } catch (WiredTigerPackingException wtpe) { + System.err.println("WiredTigerPackingException: " + wtpe); + } catch (WiredTigerException wte) { + System.err.println("WiredTigerException: " + wte); + } + /*! [access example cursor insert] */ + /*! [access example cursor list] */ + try { + c.reset(); + while (c.next() == 0) { + System.out.println("Got: " + c.getKeyString()); + } + } catch (WiredTigerPackingException wtpe) { + System.err.println("WiredTigerPackingException: " + wtpe); + } catch (WiredTigerException wte) { + System.err.println("WiredTigerException: " + wte); + } + /*! [access example cursor list] */ + + /*! [access example close] */ + try { + conn.close(null); + } catch (WiredTigerException wte) { + System.err.println("WiredTigerException: " + wte); + } + /*! [access example close] */ + } +} diff --git a/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_all.java b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_all.java new file mode 100644 index 00000000000..8648d95a185 --- /dev/null +++ b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_all.java @@ -0,0 +1,1009 @@ +/*- + * Public Domain 2008-2014 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.java + * 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. + */ +package com.wiredtiger.examples; +import com.wiredtiger.db.*; +import java.io.*; +import java.nio.*; + +/* Note: indentation in non-standard so it will display nicely in doc. */ +public class ex_all { + +public static String progname = "ex_all"; + +public static int cursor_ops(Session session) + throws WiredTigerException +{ + Cursor cursor; + int ret; + + /*! [Open a cursor] */ + cursor = session.open_cursor("table:mytable", null, null); + /*! [Open a cursor] */ + + /*! [Open a cursor on the metadata] */ + cursor = session.open_cursor("metadata:", null, null); + /*! [Open a cursor on the metadata] */ + + { + Cursor duplicate; + String key = "some key"; + /*! [Duplicate a cursor] */ + cursor = session.open_cursor("table:mytable", null, null); + cursor.putKeyString(key); + ret = cursor.search(); + + /* Duplicate the cursor. */ + duplicate = session.open_cursor(null, cursor, null); + /*! [Duplicate a cursor] */ + } + + { + Cursor overwrite_cursor; + String key = "some key", value = "some value"; + /*! [Reconfigure a cursor] */ + cursor = session.open_cursor("table:mytable", null, null); + cursor.putKeyString(key); + + /* Reconfigure the cursor to overwrite the record. */ + overwrite_cursor = session.open_cursor(null, cursor, "overwrite"); + ret = cursor.close(); + + overwrite_cursor.putValueString(value); + ret = overwrite_cursor.insert(); + /*! [Reconfigure a cursor] */ + } + + { + /*! [boolean configuration string example] */ + cursor = session.open_cursor("table:mytable", null, "overwrite"); + cursor = session.open_cursor("table:mytable", null, "overwrite=true"); + cursor = session.open_cursor("table:mytable", null, "overwrite=1"); + /*! [boolean configuration string example] */ + } + + { + /*! [open a named checkpoint] */ + cursor = session.open_cursor("table:mytable", null, "checkpoint=midnight"); + /*! [open a named checkpoint] */ + } + + { + /*! [open the default checkpoint] */ + cursor = session.open_cursor("table:mytable", null, + "checkpoint=WiredTigerCheckpoint"); + /*! [open the default checkpoint] */ + } + + { + /*! [Get the cursor's string key] */ + String key; /* Get the cursor's string key. */ + key = cursor.getKeyString(); + /*! [Get the cursor's string key] */ + } + + { + /*! [Set the cursor's string key] */ + /* Set the cursor's string key. */ + String key = "another key"; + cursor.putKeyString(key); + /*! [Set the cursor's string key] */ + } + + { + /*! [Get the cursor's record number key] */ + long recno; /* Get the cursor's record number key. */ + recno = cursor.getKeyLong(); + /*! [Get the cursor's record number key] */ + } + + { + /*! [Set the cursor's record number key] */ + long recno = 37; /* Set the cursor's record number key. */ + cursor.putKeyLong(recno); + /*! [Set the cursor's record number key] */ + } + + { + /*! [Get the cursor's composite key] */ + /* Get the cursor's "SiH" format composite key. */ + String first; + int second; + short third; + + first = cursor.getKeyString(); + second = cursor.getKeyInt(); + third = cursor.getKeyShort(); + /*! [Get the cursor's composite key] */ + } + + { + /*! [Set the cursor's composite key] */ + /* Set the cursor's "SiH" format composite key. */ + cursor.putKeyString("first"); + cursor.putKeyInt(5); + cursor.putKeyShort((short)7); + /*! [Set the cursor's composite key] */ + } + + { + /*! [Get the cursor's string value] */ + String value; /* Get the cursor's string value. */ + value = cursor.getValueString(); + /*! [Get the cursor's string value] */ + } + + { + /*! [Set the cursor's string value] */ + /* Set the cursor's string value. */ + String value = "another value"; + cursor.putValueString(value); + /*! [Set the cursor's string value] */ + } + + { + /*! [Get the cursor's raw value] */ + byte[] value; /* Get the cursor's raw value. */ + value = cursor.getValueByteArray(); + /*! [Get the cursor's raw value] */ + } + + { + /*! [Set the cursor's raw value] */ + byte[] value; /* Set the cursor's raw value. */ + value = "another value".getBytes(); + cursor.putValueByteArray(value); + /*! [Set the cursor's raw value] */ + } + + /*! [Return the next record] */ + ret = cursor.next(); + /*! [Return the next record] */ + + /*! [Return the previous record] */ + ret = cursor.prev(); + /*! [Return the previous record] */ + + /*! [Reset the cursor] */ + ret = cursor.reset(); + /*! [Reset the cursor] */ + + { + Cursor other = null; + /*! [Cursor comparison] */ + int compare; + compare = cursor.compare(other); + if (compare == 0) { + /* Cursors reference the same key */ + } else if (compare < 0) { + /* Cursor key less than other key */ + } else if (compare > 0) { + /* Cursor key greater than other key */ + } + /*! [Cursor comparison] */ + } + + { + /*! [Search for an exact match] */ + String key = "some key"; + cursor.putKeyString(key); + ret = cursor.search(); + /*! [Search for an exact match] */ + } + + cursor_search_near(cursor); + + { + /*! [Insert a new record or overwrite an existing record] */ + /* Insert a new record or overwrite an existing record. */ + String key = "some key", value = "some value"; + cursor = session.open_cursor("table:mytable", null, null); + cursor.putKeyString(key); + cursor.putValueString(value); + ret = cursor.insert(); + /*! [Insert a new record or overwrite an existing record] */ + } + + { + /*! [Insert a new record and fail if the record exists] */ + /* Insert a new record and fail if the record exists. */ + String key = "some key", value = "some value"; + cursor = session.open_cursor("table:mytable", null, "overwrite=false"); + cursor.putKeyString(key); + cursor.putValueString(value); + ret = cursor.insert(); + /*! [Insert a new record and fail if the record exists] */ + } + + { + /*! [Insert a new record and assign a record number] */ + /* Insert a new record and assign a record number. */ + long recno; + String value = "some value"; + cursor = session.open_cursor("table:mytable", null, "append"); + cursor.putValueString(value); + ret = cursor.insert(); + if (ret == 0) + recno = cursor.getKeyLong(); + /*! [Insert a new record and assign a record number] */ + } + + { + /*! [Update an existing record or insert a new record] */ + String key = "some key", value = "some value"; + cursor = session.open_cursor("table:mytable", null, null); + cursor.putKeyString(key); + cursor.putValueString(value); + ret = cursor.update(); + /*! [Update an existing record or insert a new record] */ + } + + { + /*! [Update an existing record and fail if DNE] */ + String key = "some key", value = "some value"; + cursor = session.open_cursor("table:mytable", null, "overwrite=false"); + cursor.putKeyString(key); + cursor.putValueString(value); + ret = cursor.update(); + /*! [Update an existing record and fail if DNE] */ + } + + { + /*! [Remove a record] */ + String key = "some key"; + cursor = session.open_cursor("table:mytable", null, null); + cursor.putKeyString(key); + ret = cursor.remove(); + /*! [Remove a record] */ + } + + { + /*! [Remove a record and fail if DNE] */ + String key = "some key"; + cursor = session.open_cursor("table:mytable", null, "overwrite=false"); + cursor.putKeyString(key); + ret = cursor.remove(); + /*! [Remove a record and fail if DNE] */ + } + + { + /*! [Display an error] */ + try { + String key = "non-existent key"; + cursor.putKeyString(key); + if ((ret = cursor.remove()) != 0) { + System.err.println( + "cursor.remove: " + wiredtiger.wiredtiger_strerror(ret)); + return (ret); + } + } catch (WiredTigerException wte) { /* Catch severe errors. */ + System.err.println("cursor.remove exception: " + wte); + } + /*! [Display an error] */ + } + + /*! [Close the cursor] */ + ret = cursor.close(); + /*! [Close the cursor] */ + + return (ret); +} + +static int +cursor_search_near(Cursor cursor) + throws WiredTigerException +{ + int ret; + String key = "some key"; + SearchStatus status; + + /*! [Search for an exact or adjacent match] */ + cursor.putKeyString(key); + status = cursor.search_near(); + if (status == SearchStatus.FOUND) { + /* an exact match */ + } else if (status == SearchStatus.SMALLER) { + /* returned smaller key */ + } else if (status == SearchStatus.LARGER) { + /* returned larger key */ + } else if (status == SearchStatus.NOTFOUND) { + /* no match found */ + } + /*! [Search for an exact or adjacent match] */ + + /*! [Forward scan greater than or equal] */ + cursor.putKeyString(key); + status = cursor.search_near(); + if (status == SearchStatus.FOUND || status == SearchStatus.LARGER) { + /* include first key returned in the scan */ + } + + while ((ret = cursor.next()) == 0) { + /* the rest of the scan */ + } + /*! [Forward scan greater than or equal] */ + + /*! [Backward scan less than] */ + cursor.putKeyString(key); + status = cursor.search_near(); + if (status == SearchStatus.SMALLER) { + /* include first key returned in the scan */ + } + + while ((ret = cursor.prev()) == 0) { + /* the rest of the scan */ + } + /*! [Backward scan less than] */ + + return (ret); +} + +static int +checkpoint_ops(Session session) + throws WiredTigerException +{ + int ret; + + /*! [Checkpoint examples] */ + /* Checkpoint the database. */ + ret = session.checkpoint(null); + + /* Checkpoint of the database, creating a named snapshot. */ + ret = session.checkpoint("name=June01"); + + /* + * Checkpoint a list of objects. + * JSON parsing requires quoting the list of target URIs. + */ + ret = session. + checkpoint("target=(\"table:table1\",\"table:table2\")"); + + /* + * Checkpoint a list of objects, creating a named snapshot. + * JSON parsing requires quoting the list of target URIs. + */ + ret = session. + checkpoint("target=(\"table:mytable\"),name=midnight"); + + /* Checkpoint the database, discarding all previous snapshots. */ + ret = session.checkpoint("drop=(from=all)"); + + /* Checkpoint the database, discarding the "midnight" snapshot. */ + ret = session.checkpoint("drop=(midnight)"); + + /* + * Checkpoint the database, discarding all snapshots after and + * including "noon". + */ + ret = session.checkpoint("drop=(from=noon)"); + + /* + * Checkpoint the database, discarding all snapshots before and + * including "midnight". + */ + ret = session.checkpoint("drop=(to=midnight)"); + + /* + * Create a checkpoint of a table, creating the "July01" snapshot and + * discarding the "May01" and "June01" snapshots. + * JSON parsing requires quoting the list of target URIs. + */ + ret = session.checkpoint("target=(\"table:mytable\"),name=July01,drop=(May01,June01)"); + /*! [Checkpoint examples] */ + + /*! [JSON quoting example] */ + /* + * Checkpoint a list of objects. + * JSON parsing requires quoting the list of target URIs. + */ + ret = session. + checkpoint("target=(\"table:table1\",\"table:table2\")"); + /*! [JSON quoting example] */ + + return (ret); +} + +static boolean +cursor_statistics(Session session) + throws WiredTigerException +{ + Cursor cursor; + + /*! [Statistics cursor database] */ + cursor = session.open_cursor( + "statistics:", null, null); + /*! [Statistics cursor database] */ + + /*! [Statistics cursor table] */ + cursor = session.open_cursor( + "statistics:table:mytable", null, null); + /*! [Statistics cursor table] */ + + /*! [Statistics cursor table fast] */ + cursor = session.open_cursor("statistics:table:mytable", null, "statistics=(fast)"); + /*! [Statistics cursor table fast] */ + + /*! [Statistics clear configuration] */ + cursor = session.open_cursor("statistics:", null, "statistics=(fast,clear)"); + /*! [Statistics clear configuration] */ + + /*! [Statistics cursor clear configuration] */ + cursor = session.open_cursor("statistics:table:mytable", + null, "statistics=(all,clear)"); + /*! [Statistics cursor clear configuration] */ + + return (true); +} + +static int +session_ops(Session session) + throws WiredTigerException +{ + int ret; + + /*! [Reconfigure a session] */ + ret = session.reconfigure("isolation=snapshot"); + /*! [Reconfigure a session] */ + + /*! [Create a table] */ + ret = session.create("table:mytable", "key_format=S,value_format=S"); + /*! [Create a table] */ + ret = session.drop("table:mytable", null); + + /*! [Create a column-store table] */ + ret = session.create("table:mytable", "key_format=r,value_format=S"); + /*! [Create a column-store table] */ + ret = session.drop("table:mytable", null); + + /*! [Create a table with columns] */ + /* + * Create a table with columns: keys are record numbers, values are + * (string, signed 32-bit integer, unsigned 16-bit integer). + */ + ret = session.create("table:mytable", + "key_format=r,value_format=SiH," + + "columns=(id,department,salary,year-started)"); + /*! [Create a table with columns] */ + ret = session.drop("table:mytable", null); + + /* + * This example code gets run, and the compression libraries might not + * be loaded, causing the create to fail. The documentation requires + * the code snippets, use if (false) to avoid running it. + */ + if (false) { // MIGHT_NOT_RUN + /*! [Create a bzip2 compressed table] */ + ret = session.create("table:mytable", + "block_compressor=bzip2,key_format=S,value_format=S"); + /*! [Create a bzip2 compressed table] */ + ret = session.drop("table:mytable", null); + + /*! [Create a snappy compressed table] */ + ret = session.create("table:mytable", + "block_compressor=snappy,key_format=S,value_format=S"); + /*! [Create a snappy compressed table] */ + ret = session.drop("table:mytable", null); + + /*! [Create a zlib compressed table] */ + ret = session.create("table:mytable", + "block_compressor=zlib,key_format=S,value_format=S"); + /*! [Create a zlib compressed table] */ + ret = session.drop("table:mytable", null); + } // if (false) + + /*! [Configure checksums to uncompressed] */ + ret = session.create("table:mytable", + "key_format=S,value_format=S,checksum=uncompressed"); + /*! [Configure checksums to uncompressed] */ + ret = session.drop("table:mytable", null); + + /*! [Configure dictionary compression on] */ + ret = session.create("table:mytable", + "key_format=S,value_format=S,dictionary=1000"); + /*! [Configure dictionary compression on] */ + ret = session.drop("table:mytable", null); + + /*! [Configure key prefix compression on] */ + ret = session.create("table:mytable", + "key_format=S,value_format=S,prefix_compression=true"); + /*! [Configure key prefix compression on] */ + ret = session.drop("table:mytable", null); + + if (false) { // MIGHT_NOT_RUN + /* Requires sync_file_range */ + /*! [os_cache_dirty_max configuration] */ + ret = session.create( + "table:mytable", "os_cache_dirty_max=500MB"); + /*! [os_cache_dirty_max configuration] */ + ret = session.drop("table:mytable", null); + + /* Requires posix_fadvise */ + /*! [os_cache_max configuration] */ + ret = session.create("table:mytable", "os_cache_max=1GB"); + /*! [os_cache_max configuration] */ + ret = session.drop("table:mytable", null); + } // if (false) + + /*! [Configure block_allocation] */ + ret = session.create("table:mytable", + "key_format=S,value_format=S,block_allocation=first"); + /*! [Configure block_allocation] */ + ret = session.drop("table:mytable", null); + + /*! [Create a cache-resident object] */ + ret = session.create("table:mytable", "key_format=r,value_format=S,cache_resident=true"); + /*! [Create a cache-resident object] */ + ret = session.drop("table:mytable", null); + + { + /* Create a table for the session operations. */ + ret = session.create( + "table:mytable", "key_format=S,value_format=S"); + + /*! [Compact a table] */ + ret = session.compact("table:mytable", null); + /*! [Compact a table] */ + + /*! [Rename a table] */ + ret = session.rename("table:old", "table:new", null); + /*! [Rename a table] */ + + /*! [Salvage a table] */ + ret = session.salvage("table:mytable", null); + /*! [Salvage a table] */ + + /*! [Truncate a table] */ + ret = session.truncate("table:mytable", null, null, null); + /*! [Truncate a table] */ + + { + /* + * Insert a pair of keys so we can truncate a range. + */ + Cursor cursor; + cursor = session.open_cursor( + "table:mytable", null, null); + cursor.putKeyString("June01"); + cursor.putValueString("value"); + ret = cursor.update(); + cursor.putKeyString("June30"); + cursor.putValueString("value"); + ret = cursor.update(); + cursor.close(); + + { + /*! [Truncate a range] */ + Cursor start, stop; + + start = session.open_cursor( + "table:mytable", null, null); + start.putKeyString("June01"); + ret = start.search(); + + stop = session.open_cursor( + "table:mytable", null, null); + stop.putKeyString("June30"); + ret = stop.search(); + + ret = session.truncate(null, start, stop, null); + /*! [Truncate a range] */ + } + } + + /*! [Upgrade a table] */ + ret = session.upgrade("table:mytable", null); + /*! [Upgrade a table] */ + + /*! [Verify a table] */ + ret = session.verify("table:mytable", null); + /*! [Verify a table] */ + + /*! [Drop a table] */ + ret = session.drop("table:mytable", null); + /*! [Drop a table] */ + } + + /*! [Close a session] */ + ret = session.close(null); + /*! [Close a session] */ + + return (ret); +} + +static int +transaction_ops(Connection conn, Session session) + throws WiredTigerException +{ + Cursor cursor; + int ret; + + /*! [transaction commit/rollback] */ + cursor = session.open_cursor("table:mytable", null, null); + ret = session.begin_transaction(null); + /* + * Cursors may be opened before or after the transaction begins, and in + * either case, subsequent operations are included in the transaction. + * The begin_transaction call resets all open cursors. + */ + + cursor.putKeyString("key"); + cursor.putValueString("value"); + switch (ret = cursor.update()) { + case 0: /* Update success */ + ret = session.commit_transaction(null); + /* + * The commit_transaction call resets all open cursors. + * If commit_transaction fails, the transaction was rolled-back. + */ + break; + case wiredtiger.WT_ROLLBACK: /* Update conflict */ + default: /* Other error */ + ret = session.rollback_transaction(null); + /* The rollback_transaction call resets all open cursors. */ + break; + } + + /* Cursors remain open and may be used for multiple transactions. */ + /*! [transaction commit/rollback] */ + ret = cursor.close(); + + /*! [transaction isolation] */ + /* A single transaction configured for snapshot isolation. */ + cursor = session.open_cursor("table:mytable", null, null); + ret = session.begin_transaction("isolation=snapshot"); + cursor.putKeyString("some-key"); + cursor.putValueString("some-value"); + ret = cursor.update(); + ret = session.commit_transaction(null); + /*! [transaction isolation] */ + + /*! [session isolation configuration] */ + /* Open a session configured for read-uncommitted isolation. */ + session = conn.open_session( + "isolation=read_uncommitted"); + /*! [session isolation configuration] */ + + /*! [session isolation re-configuration] */ + /* Re-configure a session for snapshot isolation. */ + ret = session.reconfigure("isolation=snapshot"); + /*! [session isolation re-configuration] */ + + return (ret); +} + +/*! [Implement WT_COLLATOR] */ +/* Not available for java */ +/*! [Implement WT_COLLATOR] */ + +/*! [WT_EXTRACTOR] */ +/* Not available for java */ +/*! [WT_EXTRACTOR] */ + +static int +connection_ops(Connection conn) + throws WiredTigerException +{ + int ret; + + if (false) { // Might not run. + /*! [Load an extension] */ + ret = conn.load_extension("my_extension.dll", null); + + ret = conn.load_extension( + "datasource/libdatasource.so", + "config=[device=/dev/sd1,alignment=64]"); + /*! [Load an extension] */ + } // if (false) + + /*! [Reconfigure a connection] */ + ret = conn.reconfigure("eviction_target=75"); + /*! [Reconfigure a connection] */ + + /*! [Get the database home directory] */ + System.out.println("The database home is " + conn.get_home()); + /*! [Get the database home directory] */ + + /*! [Check if the database is newly created] */ + if (conn.is_new() != 0) { + /* First time initialization. */ + } + /*! [Check if the database is newly created] */ + + { + /*! [Open a session] */ + Session session; + session = conn.open_session(null); + /*! [Open a session] */ + + session_ops(session); + } + + /*! [Configure method configuration] */ + /* + * Applications opening a cursor for the data-source object "my_data" + * have an additional configuration option "entries", which is an + * integer type, defaults to 5, and must be an integer between 1 and 10. + */ + ret = conn.configure_method( + "session.open_cursor", + "my_data:", "entries=5", "int", "min=1,max=10"); + + /* + * Applications opening a cursor for the data-source object "my_data" + * have an additional configuration option "devices", which is a list + * of strings. + */ + ret = conn.configure_method( + "session.open_cursor", "my_data:", "devices", "list", null); + /*! [Configure method configuration] */ + + /*! [Close a connection] */ + ret = conn.close(null); + /*! [Close a connection] */ + + return (ret); +} + +static int +pack_ops(Session session) +{ + { + /*! [Get the packed size] */ + /* Not available for java */ + /*! [Get the packed size] */ + } + + { + /*! [Pack fields into a buffer] */ + /* Not available for java */ + /*! [Pack fields into a buffer] */ + } + + { + /*! [Unpack fields from a buffer] */ + /* Not available for java */ + /*! [Unpack fields from a buffer] */ + } + + return (0); +} + +static boolean +backup(Session session) + throws WiredTigerException +{ + char buf[] = new char[1024]; + + /*! [backup]*/ + Cursor cursor; + String filename; + int ret = 0; + String databasedir = "/path/database"; + String backdir = "/path/database.backup"; + final String sep = File.separator; + + try { + /* Create the backup directory. */ + if (!(new File(backdir)).mkdir()) { + System.err.println(progname + ": cannot create backup dir: " + + backdir); + return false; + } + + /* Open the backup data source. */ + cursor = session.open_cursor("backup:", null, null); + + /* Copy the list of files. */ + while ((ret = cursor.next()) == 0 && + (filename = cursor.getKeyString()) != null) { + String src = databasedir + sep + filename; + String dest = backdir + sep + filename; + java.nio.file.Files.copy( + new java.io.File(src).toPath(), + new java.io.File(dest).toPath(), + java.nio.file.StandardCopyOption.REPLACE_EXISTING, + java.nio.file.StandardCopyOption.COPY_ATTRIBUTES); + } + if (ret == wiredtiger.WT_NOTFOUND) + ret = 0; + if (ret != 0) + System.err.println(progname + + ": cursor next(backup:) failed: " + + wiredtiger.wiredtiger_strerror(ret)); + + ret = cursor.close(); + } + catch (Exception ex) { + System.err.println(progname + + ": backup failed: " + ex.toString()); + } + /*! [backup]*/ + + /*! [backup of a checkpoint]*/ + ret = session.checkpoint("drop=(from=June01),name=June01"); + /*! [backup of a checkpoint]*/ + + return (ret == 0); +} + +public static int +allExample() + throws WiredTigerException +{ + Connection conn; + int ret = 0; + String home = "/home/example/WT_TEST"; + + /*! [Open a connection] */ + conn = wiredtiger.open(home, "create,cache_size=500M"); + /*! [Open a connection] */ + + connection_ops(conn); + /* + * The connection has been closed. + */ + + if (false) { // MIGHT_NOT_RUN + /* + * This example code gets run, and the compression libraries might not + * be installed, causing the open to fail. The documentation requires + * the code snippets, use if (false) to avoid running it. + */ + /*! [Configure bzip2 extension] */ + conn = wiredtiger.open(home, + "create," + + "extensions=[/usr/local/lib/libwiredtiger_bzip2.so]"); + /*! [Configure bzip2 extension] */ + conn.close(null); + + /*! [Configure snappy extension] */ + conn = wiredtiger.open(home, + "create," + + "extensions=[/usr/local/lib/libwiredtiger_snappy.so]"); + /*! [Configure snappy extension] */ + conn.close(null); + + /*! [Configure zlib extension] */ + conn = wiredtiger.open(home, + "create," + + "extensions=[/usr/local/lib/libwiredtiger_zlib.so]"); + /*! [Configure zlib extension] */ + conn.close(null); + + /* + * This example code gets run, and direct I/O might not be available, + * causing the open to fail. The documentation requires code snippets, + * use if (false) to avoid running it. + */ + /* Might Not Run: direct I/O may not be available. */ + /*! [Configure direct_io for data files] */ + conn = wiredtiger.open(home, "create,direct_io=[data]"); + /*! [Configure direct_io for data files] */ + conn.close(null); + } // if (false) + + /*! [Configure file_extend] */ + conn = wiredtiger.open( + home, "create,file_extend=(data=16MB)"); + /*! [Configure file_extend] */ + conn.close(null); + + /*! [Eviction configuration] */ + /* + * Configure eviction to begin at 90% full, and run until the cache + * is only 75% dirty. + */ + conn = wiredtiger.open(home, + "create,eviction_trigger=90,eviction_dirty_target=75"); + /*! [Eviction configuration] */ + conn.close(null); + + /*! [Eviction worker configuration] */ + /* Configure up to four eviction threads */ + conn = wiredtiger.open(home, + "create,eviction_trigger=90,eviction=(threads_max=4)"); + /*! [Eviction worker configuration] */ + conn.close(null); + + /*! [Statistics configuration] */ + conn = wiredtiger.open(home, "create,statistics=(all)"); + /*! [Statistics configuration] */ + conn.close(null); + + /*! [Statistics logging] */ + conn = wiredtiger.open( + home, "create,statistics_log=(wait=30)"); + /*! [Statistics logging] */ + conn.close(null); + + /*! [Statistics logging with a table] */ + conn = wiredtiger.open(home, + "create," + + "statistics_log=(sources=(\"table:table1\",\"table:table2\"))"); + /*! [Statistics logging with a table] */ + conn.close(null); + + /*! [Statistics logging with all tables] */ + conn = wiredtiger.open(home, + "create,statistics_log=(sources=(\"table:\"))"); + /*! [Statistics logging with all tables] */ + conn.close(null); + + if (false) { // MIGHT_NOT_RUN + /* + * This example code gets run, and a non-existent log file path might + * cause the open to fail. The documentation requires code snippets, + * use if (false) to avoid running it. + */ + /*! [Statistics logging with path] */ + conn = wiredtiger.open(home, + "create," + + "statistics_log=(wait=120,path=/log/log.%m.%d.%y)"); + /*! [Statistics logging with path] */ + conn.close(null); + + /* + * Don't run this code, because memory checkers get very upset when we + * leak memory. + */ + conn = wiredtiger.open(home, "create"); + /*! [Connection close leaking memory] */ + ret = conn.close("leak_memory=true"); + /*! [Connection close leaking memory] */ + } // if (false) + + /*! [Get the WiredTiger library version #1] */ + /* Not available for java */ + /*! [Get the WiredTiger library version #1] */ + + { + /*! [Get the WiredTiger library version #2] */ + /* Not available for java */ + /*! [Get the WiredTiger library version #2] */ + } + + return (0); +} + +public static int +main(String[] argv) +{ + try { + return (allExample()); + } + catch (WiredTigerException wte) { + System.err.println("Exception: " + wte); + return (-1); + } +} +} /* Non-standard indentation */ diff --git a/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_async.java b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_async.java new file mode 100644 index 00000000000..c6cb0550571 --- /dev/null +++ b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_async.java @@ -0,0 +1,222 @@ +/*- + * Public Domain 2008-2014 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_async.java + * demonstrates how to use the asynchronous API. + */ +package com.wiredtiger.examples; +import com.wiredtiger.db.*; +import java.io.*; +import java.util.*; + +/*! [async example callback implementation] */ +class AsyncKeys implements AsyncCallback { + + public int numKeys = 0; + + public AsyncKeys() {} + + public void notifyError(String desc) { + System.err.println("ERROR: notify: " + desc); + } + + public int notify(AsyncOp op, int opReturn, int flags) { + /* + * Note: we are careful not to throw any errors here. Any + * exceptions would be swallowed by a native worker thread. + */ + int ret = 0; + try { + /*! [async get type] */ + /* Retrieve the operation's type. */ + AsyncOpType optype = op.getType(); + /*! [async get type] */ + /*! [async get identifier] */ + /* Retrieve the operation's 64-bit identifier. */ + long id = op.getId(); + /*! [async get identifier] */ + + if (optype == AsyncOpType.WT_AOP_SEARCH) { + /*! [async get the operation's string key] */ + String key = op.getKeyString(); + /*! [async get the operation's string key] */ + /*! [async get the operation's string value] */ + String value = op.getValueString(); + /*! [async get the operation's string value] */ + synchronized (this) { + numKeys += 1; + } + System.out.println("Id " + id + " got record: " + key + + " : " + value); + } + else { + notifyError("unexpected optype"); + ret = 1; + } + } + catch (Exception e) { + System.err.println("ERROR: exception in notify: " + e.toString() + + ", opreturn=" + opReturn); + ret = 1; + } + return (ret); + } +} +/*! [async example callback implementation] */ + +public class ex_async { + + public static String home; + + public static final int MAX_KEYS = 15; + + public static AsyncOp tryAsyncNewOp(Connection conn, String uri, + String config, AsyncCallback cb) throws WiredTigerException + { + WiredTigerException savedwte = null; + + for (int tries = 0; tries < 10; tries++) + try { + return conn.async_new_op(uri, config, cb); + } + catch (WiredTigerException wte) { + /* + * If we used up all the handles, pause and retry to + * give the workers a chance to catch up. + */ + System.err.println( + "asynchronous operation handle not available: " + wte); + savedwte = wte; + try { + Thread.sleep(1); + } catch (InterruptedException ie) { + /* not a big problem, continue to retry */ + } + } + + throw savedwte; + } + + public static int + asyncExample() + throws WiredTigerException + { + AsyncOp op; + Connection conn; + Session session; + int i, ret; + String k[] = new String[MAX_KEYS]; + String v[] = new String[MAX_KEYS]; + + /*! [async example callback implementation part 2] */ + AsyncKeys asynciface = new AsyncKeys(); + /*! [async example callback implementation part 2] */ + + /*! [async example connection] */ + conn = wiredtiger.open(home, "create,cache_size=100MB," + + "async=(enabled=true,ops_max=20,threads=2)"); + /*! [async example connection] */ + + /*! [async example table create] */ + session = conn.open_session(null); + ret = session.create("table:async", "key_format=S,value_format=S"); + /*! [async example table create] */ + + /* Insert a set of keys asynchronously. */ + for (i = 0; i < MAX_KEYS; i++) { + /*! [async handle allocation] */ + op = tryAsyncNewOp(conn, "table:async", null, asynciface); + /*! [async handle allocation] */ + + /*! [async insert] */ + /* + * Set the operation's string key and value, and then do + * an asynchronous insert. + */ + /*! [async set the operation's string key] */ + k[i] = "key" + i; + op.putKeyString(k[i]); + /*! [async set the operation's string key] */ + + /*! [async set the operation's string value] */ + v[i] = "value" + i; + op.putValueString(v[i]); + /*! [async set the operation's string value] */ + + ret = op.insert(); + /*! [async insert] */ + } + + /*! [async flush] */ + /* Wait for all outstanding operations to complete. */ + ret = conn.async_flush(); + /*! [async flush] */ + + /*! [async compaction] */ + /* + * Compact a table asynchronously, limiting the run-time to 5 minutes. + */ + op = tryAsyncNewOp(conn, "table:async", "timeout=300", asynciface); + ret = op.compact(); + /*! [async compaction] */ + + /* Search for the keys we just inserted, asynchronously. */ + for (i = 0; i < MAX_KEYS; i++) { + op = tryAsyncNewOp(conn, "table:async", null, asynciface); + /*! [async search] */ + /* + * Set the operation's string key and value, and then do + * an asynchronous search. + */ + k[i] = "key" + i; + op.putKeyString(k[i]); + ret = op.search(); + /*! [async search] */ + } + + /* + * Connection close automatically does an async_flush so it will wait + * for all queued search operations to complete. + */ + ret = conn.close(null); + + System.out.println("Searched for " + asynciface.numKeys + " keys"); + + return (ret); + } + + public static int + main(String[] argv) + { + try { + return (asyncExample()); + } + catch (WiredTigerException wte) { + System.err.println("Exception: " + wte); + return (-1); + } + } +} diff --git a/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_call_center.java b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_call_center.java new file mode 100644 index 00000000000..553f63612bd --- /dev/null +++ b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_call_center.java @@ -0,0 +1,299 @@ +/*- + * Public Domain 2008-2014 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_call_center.java + * This is an example application that demonstrates how to map a + * moderately complex SQL application into WiredTiger. + */ + +package com.wiredtiger.examples; +import com.wiredtiger.db.*; +import java.io.*; +import java.util.*; + +/*! [call-center decl] */ +/* + * In SQL, the tables are described as follows: + * + * CREATE TABLE Customers(id INTEGER PRIMARY KEY, + * name VARCHAR(30), address VARCHAR(50), phone VARCHAR(15)) + * CREATE INDEX CustomersPhone ON Customers(phone) + * + * CREATE TABLE Calls(id INTEGER PRIMARY KEY, call_date DATE, + * cust_id INTEGER, emp_id INTEGER, call_type VARCHAR(12), + * notes VARCHAR(25)) + * CREATE INDEX CallsCustDate ON Calls(cust_id, call_date) + * + * In this example, both tables will use record numbers for their IDs, which + * will be the key. The C structs for the records are as follows. + */ + +/* Customer records. */ +class Customer { + public long id; + public String name; + public String address; + public String phone; + public Customer(long id, String name, String address, String phone) { + this.id = id; + this.name = name; + this.address = address; + this.phone = phone; + } + public Customer() {} +} + +/* Call records. */ +class Call { + public long id; + public long call_date; + public long cust_id; + public long emp_id; + public String call_type; + public String notes; + public Call(long id, long call_date, long cust_id, long emp_id, + String call_type, String notes) { + this.id = id; + this.call_date = call_date; + this.cust_id = cust_id; + this.emp_id = emp_id; + this.call_type = call_type; + this.notes = notes; + } + public Call() {} +} +/*! [call-center decl] */ + +public class ex_call_center { + + public static String home; + + public static int + callCenterExample() + throws WiredTigerException + { + Connection conn; + Cursor cursor; + Session session; + int count, ret; + SearchStatus nearstatus; + List<Customer> custSample = new ArrayList<Customer>(); + List<Call> callSample = new ArrayList<Call>(); + + custSample.add(new Customer(0, "Professor Oak", + "LeafGreen Avenue", "123-456-7890")); + custSample.add(new Customer(0, "Lorelei", + "Sevii Islands", "098-765-4321")); + callSample.add(new Call(0, 32, 1, 2, "billing", "unavailable")); + callSample.add(new Call(0, 33, 1, 2, "billing", "available")); + callSample.add(new Call(0, 34, 1, 2, "reminder", "unavailable")); + callSample.add(new Call(0, 35, 1, 2, "reminder", "available")); + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (System.getenv("WIREDTIGER_HOME") == null) { + home = "WT_HOME"; + try { + Process proc = Runtime.getRuntime().exec("/bin/rm -rf WT_HOME"); + BufferedReader br = new BufferedReader( + new InputStreamReader(proc.getInputStream())); + while(br.ready()) + System.out.println(br.readLine()); + br.close(); + new File("WT_HOME").mkdir(); + } catch (IOException ioe) { + System.err.println("IOException: WT_HOME: " + ioe); + return(1); + } + } else + home = null; + + try { + conn = wiredtiger.open(home, "create"); + session = conn.open_session(null); + } catch (WiredTigerException wte) { + System.err.println("WiredTigerException: " + wte); + return(1); + } + /* Note: further error checking omitted for clarity. */ + + /*! [call-center work] */ + /* + * Create the customers table, give names and types to the columns. + * The columns will be stored in two groups: "main" and "address", + * created below. + */ + ret = session.create("table:customers", + "key_format=r," + + "value_format=SSS," + + "columns=(id,name,address,phone)," + + "colgroups=(main,address)"); + + /* Create the main column group with value columns except address. */ + ret = session.create( + "colgroup:customers:main", "columns=(name,phone)"); + + /* Create the address column group with just the address. */ + ret = session.create( + "colgroup:customers:address", "columns=(address)"); + + /* Create an index on the customer table by phone number. */ + ret = session.create( + "index:customers:phone", "columns=(phone)"); + + /* Populate the customers table with some data. */ + cursor = session.open_cursor("table:customers", null, "append"); + for (Customer cust : custSample) { + cursor.putValueString(cust.name); + cursor.putValueString(cust.address); + cursor.putValueString(cust.phone); + ret = cursor.insert(); + } + ret = cursor.close(); + + /* + * Create the calls table, give names and types to the columns. All the + * columns will be stored together, so no column groups are declared. + */ + ret = session.create("table:calls", + "key_format=r," + + "value_format=qrrSS," + + "columns=(id,call_date,cust_id,emp_id,call_type,notes)"); + + /* + * Create an index on the calls table with a composite key of cust_id + * and call_date. + */ + ret = session.create("index:calls:cust_date", + "columns=(cust_id,call_date)"); + + /* Populate the calls table with some data. */ + cursor = session.open_cursor("table:calls", null, "append"); + for (Call call : callSample) { + cursor.putValueLong(call.call_date); + cursor.putValueLong(call.cust_id); + cursor.putValueLong(call.emp_id); + cursor.putValueString(call.call_type); + cursor.putValueString(call.notes); + ret = cursor.insert(); + } + ret = cursor.close(); + + /* + * First query: a call arrives. In SQL: + * + * SELECT id, name FROM Customers WHERE phone=? + * + * Use the cust_phone index, lookup by phone number to fill the + * customer record. The cursor will have a key format of "S" for a + * string because the cust_phone index has a single column ("phone"), + * which is of type "S". + * + * Specify the columns we want: the customer ID and the name. This + * means the cursor's value format will be "rS". + */ + cursor = session.open_cursor( + "index:customers:phone(id,name)", null, null); + cursor.putKeyString("123-456-7890"); + ret = cursor.search(); + if (ret == 0) { + Customer cust = new Customer(); + cust.id = cursor.getValueLong(); + cust.name = cursor.getValueString(); + System.out.println("Read customer record for " + cust.name + + " (ID " + cust.id + ")"); + } + ret = cursor.close(); + + /* + * Next query: get the recent order history. In SQL: + * + * SELECT * FROM Calls WHERE cust_id=? ORDER BY call_date DESC LIMIT 3 + * + * Use the call_cust_date index to find the matching calls. Since it is + * is in increasing order by date for a given customer, we want to start + * with the last record for the customer and work backwards. + * + * Specify a subset of columns to be returned. (Note that if these were + * all covered by the index, the primary would not have to be accessed.) + * Stop after getting 3 records. + */ + cursor = session.open_cursor( + "index:calls:cust_date(cust_id,call_type,notes)", + null, null); + + /* + * The keys in the index are (cust_id,call_date) -- we want the largest + * call date for a given cust_id. Search for (cust_id+1,0), then work + * backwards. + */ + long custid = 1; + cursor.putKeyLong(custid + 1); + cursor.putKeyLong(0); + nearstatus = cursor.search_near(); + + /* + * If the table is empty, search_near will return WT_NOTFOUND, else the + * cursor will be positioned on a matching key if one exists, or an + * adjacent key if one does not. If the positioned key is equal to or + * larger than the search key, go back one. + */ + if (ret == 0 && (nearstatus == SearchStatus.LARGER || + nearstatus == SearchStatus.FOUND)) + ret = cursor.prev(); + for (count = 0; ret == 0 && count < 3; ++count) { + Call call = new Call(); + call.cust_id = cursor.getValueLong(); + call.call_type = cursor.getValueString(); + call.notes = cursor.getValueString(); + if (call.cust_id != custid) + break; + System.out.println("Call record: customer " + call.cust_id + + " (" + call.call_type + + ": " + call.notes + ")"); + ret = cursor.prev(); + } + /*! [call-center work] */ + + ret = conn.close(null); + + return (ret); + } + + public static int + main(String[] argv) + { + try { + return (callCenterExample()); + } + catch (WiredTigerException wte) { + System.err.println("Exception: " + wte); + return (-1); + } + } +} diff --git a/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_cursor.java b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_cursor.java new file mode 100644 index 00000000000..7b8de7739d2 --- /dev/null +++ b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_cursor.java @@ -0,0 +1,239 @@ +/*- + * Public Domain 2008-2014 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_cursor.java + * This is an example demonstrating some cursor types and operations. + */ + +package com.wiredtiger.examples; +import com.wiredtiger.db.*; +import java.io.*; +import java.util.*; + +public class ex_cursor { + + public static String home; + + /*! [cursor next] */ + public static int + cursor_forward_scan(Cursor cursor) + throws WiredTigerException + { + String key, value; + int ret; + + while ((ret = cursor.next()) == 0) { + key = cursor.getKeyString(); + value = cursor.getValueString(); + } + return (ret); + } + /*! [cursor next] */ + + /*! [cursor prev] */ + public static int + cursor_reverse_scan(Cursor cursor) + throws WiredTigerException + { + String key, value; + int ret; + + while ((ret = cursor.prev()) == 0) { + key = cursor.getKeyString(); + value = cursor.getValueString(); + } + return (ret); + } + /*! [cursor prev] */ + + /*! [cursor reset] */ + public static int + cursor_reset(Cursor cursor) + throws WiredTigerException + { + return (cursor.reset()); + } + /*! [cursor reset] */ + + /*! [cursor search] */ + public static int + cursor_search(Cursor cursor) + throws WiredTigerException + { + String value; + int ret; + + cursor.putKeyString("foo"); + + if ((ret = cursor.search()) != 0) + value = cursor.getValueString(); + + return (ret); + } + /*! [cursor search] */ + + /*! [cursor search near] */ + public static int + cursor_search_near(Cursor cursor) + throws WiredTigerException + { + String key, value; + SearchStatus exact; + + key = "foo"; + cursor.putKeyString(key); + + exact = cursor.search_near(); + if (exact == SearchStatus.SMALLER) + /* Returned key smaller than search key */ + key = cursor.getKeyString(); + else if (exact == SearchStatus.LARGER) + /* Returned key larger than search key */ + key = cursor.getKeyString(); + /* Else exact match found, and key already set */ + + value = cursor.getValueString(); + + return (0); + } + /*! [cursor search near] */ + + /*! [cursor insert] */ + public static int + cursor_insert(Cursor cursor) + throws WiredTigerException + { + cursor.putKeyString("foo"); + cursor.putValueString("bar"); + + return (cursor.insert()); + } + /*! [cursor insert] */ + + /*! [cursor update] */ + public static int + cursor_update(Cursor cursor) + throws WiredTigerException + { + cursor.putKeyString("foo"); + cursor.putValueString("newbar"); + + return (cursor.update()); + } + /*! [cursor update] */ + + /*! [cursor remove] */ + public static int + cursor_remove(Cursor cursor) + throws WiredTigerException + { + cursor.putKeyString("foo"); + return (cursor.remove()); + } + /*! [cursor remove] */ + + public static int + cursorExample() + throws WiredTigerException + { + Connection conn; + Cursor cursor; + Session session; + int ret; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (System.getenv("WIREDTIGER_HOME") == null) { + home = "WT_HOME"; + try { + Process proc = Runtime.getRuntime().exec("/bin/rm -rf WT_HOME"); + BufferedReader br = new BufferedReader( + new InputStreamReader(proc.getInputStream())); + while(br.ready()) + System.out.println(br.readLine()); + br.close(); + new File("WT_HOME").mkdir(); + } catch (IOException ioe) { + System.err.println("IOException: WT_HOME: " + ioe); + return(1); + } + } else + home = null; + + conn = wiredtiger.open(home, "create,statistics=(fast)"); + session = conn.open_session(null); + + ret = session.create("table:world", + "key_format=r,value_format=5sii," + + "columns=(id,country,population,area)"); + + /*! [open cursor #1] */ + cursor = session.open_cursor("table:world", null, null); + /*! [open cursor #1] */ + + /*! [open cursor #2] */ + cursor = session.open_cursor("table:world(country,population)", null, null); + /*! [open cursor #2] */ + + /*! [open cursor #3] */ + cursor = session.open_cursor("statistics:", null, null); + /*! [open cursor #3] */ + + /* Create a simple string table to illustrate basic operations. */ + ret = session.create("table:map", "key_format=S,value_format=S"); + cursor = session.open_cursor("table:map", null, null); + ret = cursor_insert(cursor); + ret = cursor_reset(cursor); + ret = cursor_forward_scan(cursor); + ret = cursor_reset(cursor); + ret = cursor_reverse_scan(cursor); + ret = cursor_search_near(cursor); + ret = cursor_update(cursor); + ret = cursor_remove(cursor); + ret = cursor.close(); + + /* Note: closing the connection implicitly closes open session(s). */ + if ((ret = conn.close(null)) != 0) + System.err.println("Error connecting to " + home + ": " + + wiredtiger.wiredtiger_strerror(ret)); + + return (ret); + } + + public static int + main(String[] argv) + { + try { + return (cursorExample()); + } + catch (WiredTigerException wte) { + System.err.println("Exception: " + wte); + return (-1); + } + } +} diff --git a/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_log.java b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_log.java new file mode 100644 index 00000000000..d7bc6987878 --- /dev/null +++ b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_log.java @@ -0,0 +1,376 @@ +/*- + * Public Domain 2008-2014 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_log.java + * demonstrates how to logging and log cursors. + */ +package com.wiredtiger.examples; +import com.wiredtiger.db.*; +import java.io.*; +import java.util.*; + +class Lsn { + int file; + long offset; +} + +public class ex_log { + + public static String home1 = "WT_HOME_LOG_1"; + public static String home2 = "WT_HOME_LOG_2"; + public static String uri = "table:logtest"; + + public static final String CONN_CONFIG = + "create,cache_size=100MB,log=(archive=false,enabled=true)"; + public static final int MAX_KEYS = 10; + + static Session + setup_copy() + throws WiredTigerException + { + int ret = 0; + Connection conn; + + conn = wiredtiger.open(home2, CONN_CONFIG); + Session session = conn.open_session(null); + session.create(uri, "key_format=S,value_format=S"); + return (session); + } + + static int + compare_tables(Session session, Session sess_copy) + throws WiredTigerException + { + int ret; + + Cursor cursor = session.open_cursor(uri, null, null); + Cursor curs_copy = sess_copy.open_cursor(uri, null, null); + + while ((ret = cursor.next()) == 0) { + ret = curs_copy.next(); + String key = cursor.getKeyString(); + String value = cursor.getValueString(); + String key_copy = curs_copy.getKeyString(); + String value_copy = curs_copy.getValueString(); + if (!key.equals(key_copy) || !value.equals(value_copy)) { + System.err.println( + "Mismatched: key " + key + + ", key_copy " + key_copy + + " value " + value + + " value_copy " + value_copy); + return (1); + } + } + if (ret != wiredtiger.WT_NOTFOUND) + System.err.println("WT_CURSOR.next: " + + wiredtiger.wiredtiger_strerror(ret)); + ret = cursor.close(); + + ret = curs_copy.next(); + if (ret != wiredtiger.WT_NOTFOUND) + System.err.println("WT_CURSOR.next: " + + wiredtiger.wiredtiger_strerror(ret)); + ret = curs_copy.close(); + + return (ret); + } + + /*! [log cursor walk] */ + static void + print_record(Lsn lsn, int opcount, + int rectype, int optype, long txnid, int fileid, + byte[] key, byte[] value) + { + System.out.print( + "LSN [" + lsn.file + "][" + lsn.offset + "]." + opcount + + ": record type " + rectype + " optype " + optype + + " txnid " + txnid + " fileid " + fileid); + System.out.println(" key size " + key.length + + "value size " + value.length); + if (rectype == wiredtiger.WT_LOGREC_MESSAGE) + System.out.println("Application Record: " + new String(value)); + } + + /* + * simple_walk_log -- + * A simple walk of the log. + */ + static int + simple_walk_log(Session session) + throws WiredTigerException + { + Cursor cursor; + Lsn lsn = new Lsn(); + byte[] logrec_key, logrec_value; + long txnid; + int fileid, opcount, optype, rectype; + int ret; + + /*! [log cursor open] */ + cursor = session.open_cursor("log:", null, null); + /*! [log cursor open] */ + + while ((ret = cursor.next()) == 0) { + /*! [log cursor get_key] */ + lsn.file = cursor.getKeyInt(); + lsn.offset = cursor.getKeyLong(); + opcount = cursor.getKeyInt(); + /*! [log cursor get_key] */ + /*! [log cursor get_value] */ + txnid = cursor.getValueLong(); + rectype = cursor.getValueInt(); + optype = cursor.getValueInt(); + fileid = cursor.getValueInt(); + logrec_key = cursor.getValueByteArray(); + logrec_value = cursor.getValueByteArray(); + /*! [log cursor get_value] */ + + print_record(lsn, opcount, + rectype, optype, txnid, fileid, logrec_key, logrec_value); + } + if (ret == wiredtiger.WT_NOTFOUND) + ret = 0; + ret = cursor.close(); + return (ret); + } + /*! [log cursor walk] */ + + static int + walk_log(Session session) + throws WiredTigerException + { + Connection wt_conn2; + Cursor cursor, cursor2; + Lsn lsn, lsnsave; + byte[] logrec_key, logrec_value; + Session session2; + long txnid; + int fileid, opcount, optype, rectype; + int i, ret; + boolean in_txn, first; + + session2 = setup_copy(); + wt_conn2 = session2.getConnection(); + cursor = session.open_cursor("log:", null, null); + cursor2 = session2.open_cursor(uri, null, "raw=true"); + i = 0; + in_txn = false; + txnid = 0; + lsn = new Lsn(); + lsnsave = new Lsn(); + while ((ret = cursor.next()) == 0) { + lsn.file = cursor.getKeyInt(); + lsn.offset = cursor.getKeyLong(); + opcount = cursor.getKeyInt(); + + /* + * Save one of the LSNs we get back to search for it + * later. Pick a later one because we want to walk from + * that LSN to the end (where the multi-step transaction + * was performed). Just choose the record that is MAX_KEYS. + */ + if (++i == MAX_KEYS) + lsnsave = lsn; + txnid = cursor.getValueLong(); + rectype = cursor.getValueInt(); + optype = cursor.getValueInt(); + fileid = cursor.getValueInt(); + logrec_key = cursor.getValueByteArray(); + logrec_value = cursor.getValueByteArray(); + + print_record(lsn, opcount, + rectype, optype, txnid, fileid, logrec_key, logrec_value); + + /* + * If we are in a transaction and this is a new one, end + * the previous one. + */ + if (in_txn && opcount == 0) { + ret = session2.commit_transaction(null); + in_txn = false; + } + + /* + * If the operation is a put, replay it here on the backup + * connection. Note, we cheat by looking only for fileid 1 + * in this example. The metadata is fileid 0. + */ + if (fileid == 1 && rectype == wiredtiger.WT_LOGREC_COMMIT && + optype == wiredtiger.WT_LOGOP_ROW_PUT) { + if (!in_txn) { + ret = session2.begin_transaction(null); + in_txn = true; + } + cursor2.putKeyByteArray(logrec_key); + cursor2.putValueByteArray(logrec_value); + ret = cursor2.insert(); + } + } + if (in_txn) + ret = session2.commit_transaction(null); + + ret = cursor2.close(); + /* + * Compare the tables after replay. They should be identical. + */ + if (compare_tables(session, session2) != 0) + System.out.println("compare failed"); + ret = session2.close(null); + ret = wt_conn2.close(null); + + ret = cursor.reset(); + /*! [log cursor set_key] */ + cursor.putKeyInt(lsnsave.file); + cursor.putKeyLong(lsnsave.offset); + /*! [log cursor set_key] */ + /*! [log cursor search] */ + ret = cursor.search(); + /*! [log cursor search] */ + System.out.println("Reset to saved..."); + /* + * Walk all records starting with this key. + */ + first = true; + while (ret == 0) { /*TODO: not quite right*/ + lsn.file = cursor.getKeyInt(); + lsn.offset = cursor.getKeyLong(); + opcount = cursor.getKeyInt(); + if (first) { + first = false; + if (lsnsave.file != lsn.file || + lsnsave.offset != lsn.offset) { + System.err.println("search returned the wrong LSN"); + System.exit(1); + } + } + txnid = cursor.getValueLong(); + rectype = cursor.getValueInt(); + optype = cursor.getValueInt(); + fileid = cursor.getValueInt(); + logrec_key = cursor.getValueByteArray(); + logrec_value = cursor.getValueByteArray(); + + print_record(lsn, opcount, rectype, optype, txnid, + fileid, logrec_key, logrec_value); + + ret = cursor.next(); + if (ret != 0) + break; + } + ret = cursor.close(); + return (ret); + } + + public static int + logExample() + throws WiredTigerException + { + Connection wt_conn; + Cursor cursor; + Session session; + int i, record_count, ret; + + try { + String command = "/bin/rm -rf " + home1 + " " + home2; + Process proc = Runtime.getRuntime().exec(command); + BufferedReader br = new BufferedReader( + new InputStreamReader(proc.getInputStream())); + while(br.ready()) + System.out.println(br.readLine()); + br.close(); + new File(home1).mkdir(); + new File(home2).mkdir(); + } catch (IOException ioe) { + System.err.println("IOException: " + ioe); + return (1); + } + if ((wt_conn = wiredtiger.open(home1, CONN_CONFIG)) == null) { + System.err.println("Error connecting to " + home1); + return (1); + } + + session = wt_conn.open_session(null); + ret = session.create(uri, "key_format=S,value_format=S"); + + cursor = session.open_cursor(uri, null, null); + /* + * Perform some operations with individual auto-commit transactions. + */ + for (record_count = 0, i = 0; i < MAX_KEYS; i++, record_count++) { + String k = "key" + i; + String v = "value" + i; + cursor.putKeyString(k); + cursor.putValueString(v); + ret = cursor.insert(); + } + ret = session.begin_transaction(null); + /* + * Perform some operations within a single transaction. + */ + for (i = MAX_KEYS; i < MAX_KEYS+5; i++, record_count++) { + String k = "key" + i; + String v = "value" + i; + cursor.putKeyString(k); + cursor.putValueString(v); + ret = cursor.insert(); + } + ret = session.commit_transaction(null); + ret = cursor.close(); + + /*! [log cursor printf] */ + ret = session.log_printf("Wrote " + record_count + " records"); + /*! [log cursor printf] */ + + /* + * Close and reopen the connection so that the log ends up with + * a variety of records such as file sync and checkpoint. We + * have archiving turned off. + */ + ret = wt_conn.close(null); + if ((wt_conn = wiredtiger.open(home1, CONN_CONFIG)) == null) { + System.err.println("Error connecting to " + home1); + return (ret); + } + + session = wt_conn.open_session(null); + ret = simple_walk_log(session); + ret = walk_log(session); + ret = wt_conn.close(null); + return (ret); + } + + public static int + main() + { + try { + return (logExample()); + } + catch (WiredTigerException wte) { + System.err.println("Exception: " + wte); + return (-1); + } + } +} diff --git a/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_schema.java b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_schema.java new file mode 100644 index 00000000000..9b84912e0f0 --- /dev/null +++ b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_schema.java @@ -0,0 +1,333 @@ +/*- + * Public Domain 2008-2014 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_schema.java + * This is an example application demonstrating how to create and access + * tables using a schema. + */ +package com.wiredtiger.examples; +import com.wiredtiger.db.*; +import java.io.*; +import java.util.*; + +public class ex_schema { + + public static String home; + + /*! [schema declaration] */ + /* The class for the data we are storing in a WiredTiger table. */ + static class PopRecord { + public String country; // Stored in database as fixed size char[5]; + public short year; + public long population; + public PopRecord(String country, short year, long population) { + this.country = country; + this.year = year; + this.population = population; + } + } + + static List<PopRecord> popData; + + static { + popData = new ArrayList<PopRecord>(); + + popData.add(new PopRecord("AU", (short)1900, 4000000 )); + popData.add(new PopRecord("AU", (short)2000, 19053186 )); + popData.add(new PopRecord("CAN", (short)1900, 5500000 )); + popData.add(new PopRecord("CAN", (short)2000, 31099561 )); + popData.add(new PopRecord("UK", (short)1900, 369000000 )); + popData.add(new PopRecord("UK", (short)2000, 59522468 )); + popData.add(new PopRecord("USA", (short)1900, 76212168 )); + popData.add(new PopRecord("USA", (short)2000, 301279593 )); + }; + /*! [schema declaration] */ + + public static int + schemaExample() + throws WiredTigerException + { + Connection conn; + Cursor cursor; + Session session; + String country; + long recno, population; + short year; + int ret; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (System.getenv("WIREDTIGER_HOME") == null) { + home = "WT_HOME"; + try { + Process proc = Runtime.getRuntime().exec("/bin/rm -rf WT_HOME"); + BufferedReader br = new BufferedReader( + new InputStreamReader(proc.getInputStream())); + while(br.ready()) + System.out.println(br.readLine()); + br.close(); + new File("WT_HOME").mkdir(); + } catch (IOException ioe) { + System.err.println("IOException: WT_HOME: " + ioe); + return(1); + } + } else + home = null; + + try { + conn = wiredtiger.open(home, "create"); + session = conn.open_session(null); + } catch (WiredTigerException wte) { + System.err.println("WiredTigerException: " + wte); + return(1); + } + + /*! [Create a table with column groups] */ + /* + * Create the population table. + * Keys are record numbers, the format for values is (5-byte string, + * long, long). + * See ::wiredtiger_struct_pack for details of the format strings. + */ + ret = session.create("table:poptable", + "key_format=r,value_format=5sHQ," + + "columns=(id,country,year,population),colgroups=(main,population)"); + + /* + * Create two column groups: a primary column group with the country + * code, year and population (named "main"), and a population column + * group with the population by itself (named "population"). + */ + ret = session.create("colgroup:poptable:main", + "columns=(country,year,population)"); + ret = session.create("colgroup:poptable:population", + "columns=(population)"); + /*! [Create a table with column groups] */ + + /*! [Create an index] */ + /* Create an index with a simple key. */ + ret = session.create("index:poptable:country", + "columns=(country)"); + /*! [Create an index] */ + + /*! [Create an index with a composite key] */ + /* Create an index with a composite key (country,year). */ + ret = session.create("index:poptable:country_plus_year", + "columns=(country,year)"); + /*! [Create an index with a composite key] */ + + /*! [Insert and list records] */ + /* Insert the records into the table. */ + cursor = session.open_cursor("table:poptable", null, "append"); + for (PopRecord p : popData) { + cursor.putValueString(p.country); + cursor.putValueShort(p.year); + cursor.putValueLong(p.population); + ret = cursor.insert(); + } + ret = cursor.close(); + + /* List the records in the table. */ + cursor = session.open_cursor("table:poptable", null, null); + while ((ret = cursor.next()) == 0) { + recno = cursor.getKeyLong(); + country = cursor.getValueString(); + year = cursor.getValueShort(); + population = cursor.getValueLong(); + System.out.print("ID " + recno); + System.out.println(": country " + country + ", year " + year + + ", population " + population); + } + ret = cursor.close(); + /*! [Insert and list records] */ + + /*! [List the records in the table using raw mode.] */ + cursor = session.open_cursor("table:poptable", null, "raw"); + while ((ret = cursor.next()) == 0) { + byte[] key, value; + + key = cursor.getKeyByteArray(); + System.out.println(Arrays.toString(key)); + value = cursor.getValueByteArray(); + System.out.println("raw key: " + Arrays.toString(key) + + ", raw value: " + Arrays.toString(value)); + } + /*! [List the records in the table using raw mode.] */ + + /*! [Read population from the primary column group] */ + /* + * Open a cursor on the main column group, and return the information + * for a particular country. + */ + cursor = session.open_cursor("colgroup:poptable:main", null, null); + cursor.putKeyLong(2); + if ((ret = cursor.search()) == 0) { + country = cursor.getValueString(); + year = cursor.getValueShort(); + population = cursor.getValueLong(); + System.out.println("ID 2: country " + country + + ", year " + year + ", population " + population); + } + /*! [Read population from the primary column group] */ + ret = cursor.close(); + + /*! [Read population from the standalone column group] */ + /* + * Open a cursor on the population column group, and return the + * population of a particular country. + */ + cursor = session.open_cursor("colgroup:poptable:population", null, null); + cursor.putKeyLong(2); + if ((ret = cursor.search()) == 0) { + population = cursor.getValueLong(); + System.out.println("ID 2: population " + population); + } + /*! [Read population from the standalone column group] */ + ret = cursor.close(); + + /*! [Search in a simple index] */ + /* Search in a simple index. */ + cursor = session.open_cursor("index:poptable:country", null, null); + cursor.putKeyString("AU"); + ret = cursor.search(); + country = cursor.getValueString(); + year = cursor.getValueShort(); + population = cursor.getValueLong(); + System.out.println("AU: country " + country + ", year " + year + + ", population " + population); + /*! [Search in a simple index] */ + ret = cursor.close(); + + /*! [Search in a composite index] */ + /* Search in a composite index. */ + cursor = session.open_cursor( + "index:poptable:country_plus_year", null, null); + cursor.putKeyString("USA"); + cursor.putKeyShort((short)1900); + ret = cursor.search(); + country = cursor.getValueString(); + year = cursor.getValueShort(); + population = cursor.getValueLong(); + System.out.println("US 1900: country " + country + + ", year " + year + ", population " + population); + /*! [Search in a composite index] */ + ret = cursor.close(); + + /*! [Return a subset of values from the table] */ + /* + * Use a projection to return just the table's country and year + * columns. + */ + cursor = session.open_cursor("table:poptable(country,year)", null, null); + while ((ret = cursor.next()) == 0) { + country = cursor.getValueString(); + year = cursor.getValueShort(); + System.out.println("country " + country + ", year " + year); + } + /*! [Return a subset of values from the table] */ + ret = cursor.close(); + + /*! [Return a subset of values from the table using raw mode] */ + /* + * Use a projection to return just the table's country and year + * columns. + */ + cursor = session.open_cursor("table:poptable(country,year)", null, null); + while ((ret = cursor.next()) == 0) { + country = cursor.getValueString(); + year = cursor.getValueShort(); + System.out.println("country " + country + ", year " + year); + } + /*! [Return a subset of values from the table using raw mode] */ + ret = cursor.close(); + + /*! [Return the table's record number key using an index] */ + /* + * Use a projection to return just the table's record number key + * from an index. + */ + cursor = session.open_cursor("index:poptable:country_plus_year(id)", null, null); + while ((ret = cursor.next()) == 0) { + country = cursor.getKeyString(); + year = cursor.getKeyShort(); + recno = cursor.getValueLong(); + System.out.println("row ID " + recno + ": country " + country + + ", year " + year); + } + /*! [Return the table's record number key using an index] */ + ret = cursor.close(); + + /*! [Return a subset of the value columns from an index] */ + /* + * Use a projection to return just the population column from an + * index. + */ + cursor = session.open_cursor( + "index:poptable:country_plus_year(population)", null, null); + while ((ret = cursor.next()) == 0) { + country = cursor.getKeyString(); + year = cursor.getKeyShort(); + population = cursor.getValueLong(); + System.out.println("population " + population + + ": country " + country + ", year " + year); + } + /*! [Return a subset of the value columns from an index] */ + ret = cursor.close(); + + /*! [Access only the index] */ + /* + * Use a projection to avoid accessing any other column groups when + * using an index: supply an empty list of value columns. + */ + cursor = session.open_cursor( + "index:poptable:country_plus_year()", null, null); + while ((ret = cursor.next()) == 0) { + country = cursor.getKeyString(); + year = cursor.getKeyShort(); + System.out.println("country " + country + ", year " + year); + } + /*! [Access only the index] */ + ret = cursor.close(); + + ret = conn.close(null); + + return (ret); + } + + public static int + main(String[] argv) + { + try { + return (schemaExample()); + } + catch (WiredTigerException wte) { + System.err.println("Exception: " + wte); + return (-1); + } + } +} diff --git a/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_stat.java b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_stat.java new file mode 100644 index 00000000000..c81bb64c22a --- /dev/null +++ b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_stat.java @@ -0,0 +1,252 @@ +/*- + * Public Domain 2008-2014 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_stat.java + * This is an example demonstrating how to query database statistics. + */ +package com.wiredtiger.examples; +import com.wiredtiger.db.*; +import java.io.*; +import java.util.*; + +public class ex_stat { + + public static String home; + + /*! [statistics display function] */ + int + print_cursor(Cursor cursor) + throws WiredTigerException + { + String desc, pvalue; + long value; + int ret; + + while ((ret = cursor.next()) == 0) { + desc = cursor.getValueString(); + pvalue = cursor.getValueString(); + value = cursor.getValueLong(); + if (value != 0) + System.out.println(desc + "=" + pvalue); + } + + return (ret == wiredtiger.WT_NOTFOUND ? 0 : ret); + } + /*! [statistics display function] */ + + int + print_database_stats(Session session) + throws WiredTigerException + { + Cursor cursor; + int ret; + + /*! [statistics database function] */ + cursor = session.open_cursor("statistics:", null, null); + + ret = print_cursor(cursor); + ret = cursor.close(); + /*! [statistics database function] */ + + return (ret); + } + + int + print_file_stats(Session session) + throws WiredTigerException + { + Cursor cursor; + int ret; + + /*! [statistics table function] */ + cursor = session.open_cursor("statistics:table:access", null, null); + ret = print_cursor(cursor); + ret = cursor.close(); + /*! [statistics table function] */ + + return (ret); + } + + int + print_overflow_pages(Session session) + throws WiredTigerException + { + /*! [statistics retrieve by key] */ + Cursor cursor; + String desc, pvalue; + long value; + int ret; + + cursor = session.open_cursor("statistics:table:access", null, null); + + cursor.putKeyInt(wiredtiger.WT_STAT_DSRC_BTREE_OVERFLOW); + ret = cursor.search(); + desc = cursor.getValueString(); + pvalue = cursor.getValueString(); + value = cursor.getValueLong(); + System.out.println(desc + "=" + pvalue); + + ret = cursor.close(); + /*! [statistics retrieve by key] */ + + return (ret); + } + + /*! [statistics calculation helper function] */ + long + get_stat(Cursor cursor, int stat_field) + throws WiredTigerException + { + long value; + int ret; + + cursor.putKeyInt(stat_field); + if ((ret = cursor.search()) != 0) { + System.err.println("stat_field: " + stat_field + " not found"); + value = 0; + } + else { + String desc = cursor.getValueString(); + String pvalue = cursor.getValueString(); + value = cursor.getValueLong(); + } + return (value); + } + /*! [statistics calculation helper function] */ + + int + print_derived_stats(Session session) + throws WiredTigerException + { + Cursor cursor; + int ret; + + /*! [statistics calculate open table stats] */ + cursor = session.open_cursor("statistics:table:access", null, null); + /*! [statistics calculate open table stats] */ + + { + /*! [statistics calculate table fragmentation] */ + long ckpt_size = get_stat(cursor, + wiredtiger.WT_STAT_DSRC_BLOCK_CHECKPOINT_SIZE); + long file_size = get_stat(cursor, + wiredtiger.WT_STAT_DSRC_BLOCK_SIZE); + + System.out.println("File is " + + (int)(100 * (file_size - ckpt_size) / file_size) + + "% fragmented\n"); + /*! [statistics calculate table fragmentation] */ + } + + { + /*! [statistics calculate write amplification] */ + long app_insert = get_stat(cursor, + wiredtiger.WT_STAT_DSRC_CURSOR_INSERT_BYTES); + long app_remove = get_stat(cursor, + wiredtiger.WT_STAT_DSRC_CURSOR_REMOVE_BYTES); + long app_update = get_stat(cursor, + wiredtiger.WT_STAT_DSRC_CURSOR_UPDATE_BYTES); + + long fs_writes = get_stat(cursor, + wiredtiger.WT_STAT_DSRC_CACHE_BYTES_WRITE); + + if (app_insert + app_remove + app_update != 0) + System.out.println("Write amplification is " + + (double)fs_writes / (app_insert + app_remove + app_update)); + /*! [statistics calculate write amplification] */ + } + + ret = cursor.close(); + + return (ret); + } + + public int + statExample() + throws WiredTigerException + { + Connection conn; + Cursor cursor; + Session session; + int ret; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (System.getenv("WIREDTIGER_HOME") == null) { + home = "WT_HOME"; + try { + Process proc = Runtime.getRuntime().exec("/bin/rm -rf WT_HOME"); + BufferedReader br = new BufferedReader( + new InputStreamReader(proc.getInputStream())); + while(br.ready()) + System.out.println(br.readLine()); + br.close(); + new File("WT_HOME").mkdir(); + } catch (IOException ioe) { + System.err.println("IOException: WT_HOME: " + ioe); + return(1); + } + } else + home = null; + + conn = wiredtiger.open(home, "create,statistics=(all)"); + session = conn.open_session(null); + + ret = session.create("table:access", "key_format=S,value_format=S"); + + cursor = session.open_cursor("table:access", null, null); + cursor.putKeyString("key"); + cursor.putValueString("value"); + ret = cursor.insert(); + ret = cursor.close(); + + ret = session.checkpoint(null); + + ret = print_database_stats(session); + + ret = print_file_stats(session); + + ret = print_overflow_pages(session); + + ret = print_derived_stats(session); + + return (conn.close(null) == 0 ? ret : -1); + } + + public static int + main(String[] argv) + { + try { + return ((new ex_stat()).statExample()); + } + catch (WiredTigerException wte) { + System.err.println("Exception: " + wte); + return (-1); + } + } +} diff --git a/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_thread.java b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_thread.java new file mode 100644 index 00000000000..c6b9a5479a9 --- /dev/null +++ b/src/third_party/wiredtiger/examples/java/com/wiredtiger/examples/ex_thread.java @@ -0,0 +1,142 @@ +/*- + * Public Domain 2008-2014 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_thread.java + * This is an example demonstrating how to create and access a simple + * table from multiple threads. + */ + +package com.wiredtiger.examples; +import com.wiredtiger.db.*; +import java.io.*; +import java.util.*; + +/*! [thread scan] */ +class ScanThread extends Thread { + private Connection conn; + + public ScanThread(Connection conn) { + this.conn = conn; + } + + public void run() + { + try { + int ret; + + Session session = conn.open_session(null); + Cursor cursor = session.open_cursor("table:access", null, null); + + /* Show all records. */ + while ((ret = cursor.next()) == 0) { + String key = cursor.getKeyString(); + String value = cursor.getValueString(); + System.out.println("Got record: " + key + " : " + value); + } + if (ret != wiredtiger.WT_NOTFOUND) + System.err.println("Cursor.next: " + + wiredtiger.wiredtiger_strerror(ret)); + } catch (WiredTigerException wte) { + System.err.println("Exception " + wte); + } + } +} +/*! [thread scan] */ + +public class ex_thread { + + public static String home; + + public static final int NUM_THREADS = 10; + + /*! [thread main] */ + static int main(String[] argv) + { + try { + Thread[] threads = new Thread[NUM_THREADS]; + int i, ret; + Connection conn; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + if (System.getenv("WIREDTIGER_HOME") == null) { + home = "WT_HOME"; + try { + Process proc = Runtime.getRuntime().exec("/bin/rm -rf " + home); + BufferedReader br = new BufferedReader( + new InputStreamReader(proc.getInputStream())); + while(br.ready()) + System.out.println(br.readLine()); + br.close(); + new File(home).mkdir(); + } catch (IOException ioe) { + System.err.println("IOException: " + home + ": " + ioe); + return(1); + } + } else + home = null; + + if ((conn = wiredtiger.open(home, "create")) == null) { + System.err.println("Error connecting to " + home); + return(1); + } + + /* Note: further error checking omitted for clarity. */ + + Session session = conn.open_session(null); + ret = session.create("table:access", "key_format=S,value_format=S"); + Cursor cursor = session.open_cursor("table:access", null, "overwrite"); + cursor.putKeyString("key1"); + cursor.putValueString("value1"); + ret = cursor.insert(); + ret = session.close(null); + + for (i = 0; i < NUM_THREADS; i++) { + threads[i] = new ScanThread(conn); + threads[i].start(); + } + + for (i = 0; i < NUM_THREADS; i++) + try { + threads[i].join(); + ret = -1; + } + catch (InterruptedException ie) { + } + + ret = conn.close(null); + return (ret); + } + catch (WiredTigerException wte) { + System.err.println("Exception: " + wte); + return (-1); + } + } + /*! [thread main] */ + +} diff --git a/src/third_party/wiredtiger/examples/python/ex_access.py b/src/third_party/wiredtiger/examples/python/ex_access.py new file mode 100755 index 00000000000..addc7386f03 --- /dev/null +++ b/src/third_party/wiredtiger/examples/python/ex_access.py @@ -0,0 +1,47 @@ +# Public Domain 2008-2014 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. + +from wiredtiger import wiredtiger_open + +# Connect to the database and open a session +conn = wiredtiger_open('WT_TEST', 'create') +session = conn.open_session() + +# Create a simple table +session.create('table:T', 'key_format=S,value_format=S') + +# Open a cursor and insert a record +cursor = session.open_cursor('table:T', None) + +cursor.set_key('key1') +cursor.set_value('value1') +cursor.insert() + +# Iterate through the records +cursor.reset() +for key, value in cursor: + print('Got record: ' + key + ' : ' + value) + +conn.close() |