summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/c/ex_file_system.c150
1 files changed, 118 insertions, 32 deletions
diff --git a/examples/c/ex_file_system.c b/examples/c/ex_file_system.c
index 3b632df252e..f2ea5cfae75 100644
--- a/examples/c/ex_file_system.c
+++ b/examples/c/ex_file_system.c
@@ -29,6 +29,7 @@
* demonstrates how to use the custom file system interface
*/
#include <errno.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#if (defined(_WIN32) && _MSC_VER < 1900)
@@ -37,6 +38,8 @@
#endif
#include <wiredtiger.h>
+#include <wiredtiger_ext.h>
+
#include "queue_example.h"
static const char *home;
@@ -58,6 +61,8 @@ typedef struct {
/* Queue of file handles */
TAILQ_HEAD(demo_file_handle_qh, demo_file_handle) fileq;
+ WT_EXTENSION_API *wtext; /* Extension functions */
+
} DEMO_FILE_SYSTEM;
typedef struct demo_file_handle {
@@ -131,22 +136,93 @@ static DEMO_FILE_HANDLE *demo_handle_search(WT_FILE_SYSTEM *, const char *);
#define DEMO_FILE_SIZE_INCREMENT 32768
/*
+ * string_match --
+ * Return if a string matches a byte string of len bytes.
+ */
+static inline bool
+byte_string_match(const char *str, const char *bytes, size_t len)
+{
+ return (strncmp(str, bytes, len) == 0 && (str)[(len)] == '\0');
+}
+
+/*
* demo_file_system_create --
* Initialization point for demo file system
*/
int
demo_file_system_create(WT_CONNECTION *conn, WT_CONFIG_ARG *config)
{
- WT_FILE_SYSTEM *file_system;
DEMO_FILE_SYSTEM *demo_fs;
+ WT_CONFIG_ITEM k, v;
+ WT_CONFIG_PARSER *config_parser;
+ WT_EXTENSION_API *wtext;
+ WT_FILE_SYSTEM *file_system;
int ret = 0;
- (void)config; /* Unused */
+ wtext = conn->get_extension_api(conn);
- if ((demo_fs = calloc(1, sizeof(DEMO_FILE_SYSTEM))) == NULL)
+ if ((demo_fs = calloc(1, sizeof(DEMO_FILE_SYSTEM))) == NULL) {
+ (void)wtext->err_printf(wtext, NULL,
+ "demo_file_system_create: %s",
+ wtext->strerror(wtext, NULL, ENOMEM));
return (ENOMEM);
+ }
+ demo_fs->wtext = wtext;
file_system = (WT_FILE_SYSTEM *)demo_fs;
+ /* Retrieve our configuration information, the "config" value. */
+ if ((ret = wtext->config_get(wtext, NULL, config, "config", &v)) != 0) {
+ (void)wtext->err_printf(wtext, NULL,
+ "WT_EXTENSION_API.config_get: config: %s",
+ wtext->strerror(wtext, NULL, ret));
+ goto err;
+ }
+
+ /* Open a WiredTiger parser on the "config" value. */
+ if ((ret = wtext->config_parser_open(
+ wtext, NULL, v.str, v.len, &config_parser)) != 0) {
+ (void)wtext->err_printf(wtext, NULL,
+ "WT_EXTENSION_API.config_parser_open: config: %s",
+ wtext->strerror(wtext, NULL, ret));
+ goto err;
+ }
+
+ /* Step through our configuration values. */
+ printf("Custom file system configuration\n");
+ while ((ret = config_parser->next(config_parser, &k, &v)) == 0) {
+ if (byte_string_match("config_string", k.str, k.len)) {
+ printf("\t" "key %.*s=\"%.*s\"\n",
+ (int)k.len, k.str, (int)v.len, v.str);
+ continue;
+ }
+ if (byte_string_match("config_value", k.str, k.len)) {
+ printf("\t" "key %.*s=%" PRId64 "\n",
+ (int)k.len, k.str, v.val);
+ continue;
+ }
+ ret = EINVAL;
+ (void)wtext->err_printf(wtext, NULL,
+ "WT_CONFIG_PARSER.next: unexpected configuration "
+ "information: %.*s=%.*s: %s",
+ (int)k.len, k.str, (int)v.len, v.str,
+ wtext->strerror(wtext, NULL, ret));
+ goto err;
+ }
+
+ /* Check for expected parser termination and close the parser. */
+ if (ret != WT_NOTFOUND) {
+ (void)wtext->err_printf(wtext, NULL,
+ "WT_CONFIG_PARSER.next: config: %s",
+ wtext->strerror(wtext, NULL, ret));
+ goto err;
+ }
+ if ((ret = config_parser->close(config_parser)) != 0) {
+ (void)wtext->err_printf(wtext, NULL,
+ "WT_CONFIG_PARSER.close: config: %s",
+ wtext->strerror(wtext, NULL, ret));
+ goto err;
+ }
+
/* Initialize the in-memory jump table. */
file_system->fs_directory_list = demo_fs_directory_list;
file_system->fs_directory_list_free = demo_fs_directory_list_free;
@@ -159,11 +235,11 @@ demo_file_system_create(WT_CONNECTION *conn, WT_CONFIG_ARG *config)
file_system->terminate = demo_fs_terminate;
if ((ret = conn->set_file_system(conn, file_system, NULL)) != 0) {
- fprintf(stderr, "Error setting custom file system: %s\n",
- wiredtiger_strerror(ret));
+ (void)wtext->err_printf(wtext, NULL,
+ "WT_CONNECTION.set_file_system: %s",
+ wtext->strerror(wtext, NULL, ret));
goto err;
}
-
return (0);
err: free(demo_fs);
@@ -180,16 +256,17 @@ demo_fs_open(WT_FILE_SYSTEM *file_system, WT_SESSION *session,
const char *name, WT_OPEN_FILE_TYPE file_type, uint32_t flags,
WT_FILE_HANDLE **file_handlep)
{
- WT_FILE_HANDLE *file_handle;
DEMO_FILE_HANDLE *demo_fh;
DEMO_FILE_SYSTEM *demo_fs;
+ WT_EXTENSION_API *wtext;
+ WT_FILE_HANDLE *file_handle;
(void)file_type; /* Unused */
- (void)session; /* Unused */
(void)flags; /* Unused */
demo_fs = (DEMO_FILE_SYSTEM *)file_system;
demo_fh = NULL;
+ wtext = demo_fs->wtext;
++demo_fs->opened_file_count;
@@ -200,9 +277,8 @@ demo_fs_open(WT_FILE_SYSTEM *file_system, WT_SESSION *session,
demo_fh = demo_handle_search(file_system, name);
if (demo_fh != NULL) {
if (demo_fh->ref != 0) {
- fprintf(stderr,
- "demo_file_open of already open file %s\n",
- name);
+ (void)wtext->err_printf(wtext, session,
+ "demo_fs_open: %s: file already open", name);
return (EBUSY);
}
@@ -461,12 +537,14 @@ static int
demo_file_close(WT_FILE_HANDLE *file_handle, WT_SESSION *session)
{
DEMO_FILE_HANDLE *demo_fh;
-
- (void)session; /* Unused */
+ WT_EXTENSION_API *wtext;
demo_fh = (DEMO_FILE_HANDLE *)file_handle;
+ wtext = demo_fh->demo_fs->wtext;
+
if (demo_fh->ref < 1) {
- fprintf(stderr, "Closing already closed handle: %s\n",
+ (void)wtext->err_printf(wtext, session,
+ "demo_file_close: %s: handle already closed",
demo_fh->iface.name);
return (EINVAL);
}
@@ -501,11 +579,12 @@ demo_file_read(WT_FILE_HANDLE *file_handle,
WT_SESSION *session, wt_off_t offset, size_t len, void *buf)
{
DEMO_FILE_HANDLE *demo_fh;
+ WT_EXTENSION_API *wtext;
size_t off;
int ret = 0;
- (void)session; /* Unused */
demo_fh = (DEMO_FILE_HANDLE *)file_handle;
+ wtext = demo_fh->demo_fs->wtext;
off = (size_t)offset;
if (off < demo_fh->size) {
@@ -518,14 +597,15 @@ demo_file_read(WT_FILE_HANDLE *file_handle,
if (ret == 0)
return (0);
+
/*
* WiredTiger should never request data past the end of a file, so
* flag an error if it does.
*/
- fprintf(stderr,
- "%s: handle-read: failed to read %zu bytes at offset %zu\n",
- demo_fh->iface.name, len, off);
- return (EINVAL);
+ (void)wtext->err_printf(wtext, session,
+ "%s: handle-read: failed to read %zu bytes at offset %zu: %s",
+ demo_fh->iface.name, len, off, wtext->strerror(wtext, NULL, ret));
+ return (ret);
}
/*
@@ -582,10 +662,11 @@ demo_file_truncate(
WT_FILE_HANDLE *file_handle, WT_SESSION *session, wt_off_t offset)
{
DEMO_FILE_HANDLE *demo_fh;
+ WT_EXTENSION_API *wtext;
size_t off;
- (void)session; /* Unused */
demo_fh = (DEMO_FILE_HANDLE *)file_handle;
+ wtext = demo_fh->demo_fs->wtext;
/*
* Grow the buffer as necessary, clear any new space in the file,
@@ -594,9 +675,11 @@ demo_file_truncate(
off = (size_t)offset;
if (demo_fh->bufsize < off ) {
if ((demo_fh->buf = realloc(demo_fh->buf, off)) == NULL) {
- fprintf(stderr,
- "Failed to resize buffer in truncate\n");
- return (ENOSPC);
+ (void)wtext->err_printf(wtext, session,
+ "demo_file_truncate: %s: failed to resize buffer",
+ demo_fh->iface.name,
+ wtext->strerror(wtext, NULL, ENOMEM));
+ return (ENOMEM);
}
demo_fh->bufsize = off;
}
@@ -645,16 +728,16 @@ static int
demo_handle_remove(WT_SESSION *session, DEMO_FILE_HANDLE *demo_fh)
{
DEMO_FILE_SYSTEM *demo_fs;
+ WT_EXTENSION_API *wtext;
- (void)session; /* Unused */
demo_fs = demo_fh->demo_fs;
+ wtext = demo_fh->demo_fs->wtext;
if (demo_fh->ref != 0) {
- fprintf(stderr,
- "demo_handle_remove on file %s with non-zero reference "
- "count of %u\n",
- demo_fh->iface.name, demo_fh->ref);
- return (EINVAL);
+ (void)wtext->err_printf(wtext, session,
+ "demo_handle_remove: %s: file is currently open",
+ demo_fh->iface.name, wtext->strerror(wtext, NULL, EBUSY));
+ return (EBUSY);
}
TAILQ_REMOVE(&demo_fs->fileq, demo_fh, q);
@@ -716,10 +799,13 @@ main(void)
* Use the special local extension to indicate that the entry point is
* in the same executable. Also enable early load for this extension,
* since WiredTiger needs to be able to find it before doing any file
- * operations.
+ * operations. Finally, pass in two pieces of configuration information
+ * to our initialization function as the "config" value.
*/
- open_config = "create,log=(enabled=true),extensions=(local="
- "{entry=demo_file_system_create,early_load=true})";
+ open_config = "create,log=(enabled=true),extensions=(local={"
+ "entry=demo_file_system_create,early_load=true,"
+ "config={config_string=\"demo-file-system\",config_value=37}"
+ "})";
/* Open a connection to the database, creating it if necessary. */
if ((ret = wiredtiger_open(home, NULL, open_config, &conn)) != 0) {
fprintf(stderr, "Error connecting to %s: %s\n",