diff options
Diffstat (limited to 'src/third_party/wiredtiger/examples/c/ex_data_source.c')
-rw-r--r-- | src/third_party/wiredtiger/examples/c/ex_data_source.c | 661 |
1 files changed, 661 insertions, 0 deletions
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); +} |