Files
mongo/examples/c/ex_data_source.c
2013-04-11 09:38:55 -04:00

371 lines
9.2 KiB
C

/*-
* Public Domain 2008-2013 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 <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <wiredtiger.h>
/*! [WT_EXTENSION_API declaration] */
#include <wiredtiger_ext.h>
static WT_EXTENSION_API *wt_api;
void
my_data_source_init()
{
wiredtiger_extension_api(&wt_api);
}
/*! [WT_EXTENSION_API declaration] */
/*! [WT_DATA_SOURCE create] */
static int
my_create(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
const char *uri, int exclusive, void *config)
/*! [WT_DATA_SOURCE create] */
{
/* Unused parameters */
(void)dsrc;
(void)session;
(void)uri;
(void)exclusive;
(void)config;
return (0);
}
/*! [WT_DATA_SOURCE compact] */
static int
my_compact(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
const char *uri, void *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, void *config)
/*! [WT_DATA_SOURCE drop] */
{
/* Unused parameters */
(void)dsrc;
(void)session;
(void)uri;
(void)config;
return (0);
}
int
data_source_cursor(void)
{
return (0);
}
const char *
data_source_error(int v)
{
return (v == 0 ? "one" : "two");
}
/*! [WT_DATA_SOURCE open_cursor] */
static int
my_open_cursor(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
const char *uri, void *config, WT_CURSOR **new_cursor)
/*! [WT_DATA_SOURCE open_cursor] */
{
int ret;
/* Unused parameters */
(void)dsrc;
(void)session;
(void)uri;
(void)config;
(void)new_cursor;
{
/*! [WT_EXTENSION_CONFIG boolean] */
WT_EXTENSION_CONFIG value;
int my_data_source_overwrite;
if ((ret =
wt_api->config(session, "overwrite", config, &value)) != 0) {
(void)wt_api->err_printf(session,
"overwrite configuration: %s", wiredtiger_strerror(ret));
return (ret);
}
my_data_source_overwrite = value.value != 0;
/*! [WT_EXTENSION_CONFIG boolean] */
}
{
/*! [WT_EXTENSION_CONFIG integer] */
WT_EXTENSION_CONFIG value;
int64_t my_data_source_page_size;
if ((ret =
wt_api->config(session, "page_size", config, &value)) != 0) {
(void)wt_api->err_printf(session,
"page_size configuration: %s", wiredtiger_strerror(ret));
return (ret);
}
my_data_source_page_size = value.value;
/*! [WT_EXTENSION_CONFIG integer] */
}
{
/*! [WT_EXTENSION_CONFIG string] */
WT_EXTENSION_CONFIG value;
const char *my_data_source_key;
if ((ret =
wt_api->config(session, "key_format", config, &value)) != 0) {
(void)wt_api->err_printf(session,
"key_format configuration: %s", wiredtiger_strerror(ret));
return (ret);
}
/*
* Strings returned from WT_EXTENSION_API::config are not necessarily
* nul-terminated; the associated length must be used instead.
*/
if (value.len == 1 && value.str[0] == 'r')
my_data_source_key = "recno";
else
my_data_source_key = "bytestring";
/*! [WT_EXTENSION_CONFIG string] */
}
{
/*! [WT_EXTENSION_CONFIG list] */
WT_EXTENSION_CONFIG value;
size_t cnt;
char **ap, **argv, *copy, *p, *t;
if ((ret =
wt_api->config(session, "paths", config, &value)) != 0) {
(void)wt_api->err_printf(session,
"paths configuration: %s", wiredtiger_strerror(ret));
return (ret);
}
/*
* Strings returned from WT_EXTENSION_API::config are not necessarily
* nul-terminated; the associated length must be used instead.
*
* The strsep function requires nul-termination of the list. Allocate
* memory and copy the list so it's nul-terminated. Parse the list,
* counting entries.
*
* Allocate an array of pointers large enough to hold a reference to
* each list element, then re-parse the list, this time filling in the
* array. Strsep nul-terminates each element in the list, so there's
* no addition work required.
*
* Finally, display the list.
*/
copy = calloc(1, value.len + 1);
memcpy(copy, value.str, value.len);
for (p = copy, cnt = 0; (t = strsep(&p, ",\t ")) != NULL;)
if (*t != '\0')
++cnt;
memcpy(copy, value.str, value.len);
argv = calloc(sizeof(char *), cnt + 1);
for (ap = argv, p = copy; (*ap = strsep(&p, ",\t ")) != NULL;)
if (**ap != '\0')
++ap;
for (ap = argv; *ap != NULL; ++ap)
printf("%s\n", *ap);
/*! [WT_EXTENSION_CONFIG list] */
}
/*! [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(
session, "my_open_cursor: %s", data_source_error(ret));
return (WT_ERROR);
}
/*! [WT_DATA_SOURCE error message] */
return (0);
}
/*! [WT_DATA_SOURCE rename] */
static int
my_rename(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
const char *uri, const char *newname, void *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, void *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, void *config)
/*! [WT_DATA_SOURCE truncate] */
{
/* Unused parameters */
(void)dsrc;
(void)session;
(void)uri;
(void)config;
return (0);
}
/*! [WT_DATA_SOURCE verify] */
static int
my_verify(
WT_DATA_SOURCE *dsrc, WT_SESSION *session, const char *uri, void *config)
/*! [WT_DATA_SOURCE verify] */
{
/* Unused parameters */
(void)dsrc;
(void)session;
(void)uri;
(void)config;
return (0);
}
int
main(void)
{
WT_CONNECTION *conn;
int ret;
ret = wiredtiger_open(NULL, NULL, "create", &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_verify
};
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 target 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] */
/*
* The paths are optional, so there's no default; limit paths to one or
* more of /device, /home, /mnt or /target.
*/
ret = conn->configure_method(conn,
"session.open_cursor", NULL,
"paths", "list", "choices=[/device, /home, /mnt, /target]");
/*! [WT_DATA_SOURCE configure list with checking] */
(void)conn->close(conn, NULL);
return (ret);
}