diff options
author | Ramon Fernandez <ramon@mongodb.com> | 2016-07-26 21:38:07 -0400 |
---|---|---|
committer | Ramon Fernandez <ramon@mongodb.com> | 2016-07-26 21:39:41 -0400 |
commit | 385faa6ca72ad599d92d3948f1a2033d908e0226 (patch) | |
tree | ea6cc0faad72d06858cc6f094166a20b19489c71 /src/third_party/wiredtiger/examples | |
parent | 482cc73bc00a09246f503fbe4026c539ac7f205b (diff) | |
download | mongo-385faa6ca72ad599d92d3948f1a2033d908e0226.tar.gz |
Import wiredtiger-wiredtiger-2.8.0-592-g848e5f5.tar.gz from wiredtiger branch mongodb-3.2
ref: 8b7110b..848e5f5
for: 3.2.9
This commit replaces a number of previous backports with the original
change, so some of the tickets listed below may have been resolved in
previous versions already as a backport to the v3.2 branch. For example,
SERVER-24580 includes change a63e21b8 as a cherry-pick of 1f4aaa44, but
this commit replaces that change with 1f4aaa44 itself.
SERVER-23659 Provide useful message when wiredTigerJournalCompressor is changed
SERVER-23661 $sample takes disproportionately long time on newly created collection
SERVER-24306 40-second journaling stall from "log files prepared" to checkpoint
SERVER-24580 Improve performance when WiredTiger cache is full
WT-2103 Add incremental backup testing to format
WT-2223 Add stress testing for in-memory
WT-2268 JSON load incorrect with UNICODE input
WT-2319 Add statistics around fsync calls
WT-2325 Fix an incomplete comment
WT-2343 Assert we don't remove or rename when backup cursor is open
WT-2349 Add ability to open databases read-only
WT-2359 WiredTiger with Python will hang if a calloc failure occurs during __wt_connection_close
WT-2360 Allow disjunctions and combinations of operations in join cursors
WT-2408 Windows error translation layer
WT-2446 Estimate WT cache hit ratio
WT-2450 Salvage releases pages, then explicitly evicts them.
WT-2453 Throughput drop in wtperf evict Jenkins tests
WT-2479 Dump utility discards table config (JSON)
WT-2491 The dhandle close_lock isn't valuable at the moment
WT-2504 Should READONLY always read basecfg file?
WT-2505 Review clang analyzer warnings
WT-2508 Test programs should remove test directories on the "clean" target
WT-2514 Log path name is an empty string.
WT-2518 LSM checkpoint handle acquisition optimization
WT-2520 WT_SESSION::verify should not alter tables
WT-2526 Mixing and matching readonly and read/write handles
WT-2535 Extend test/format to test for transactions reading their writes
WT-2537 Cannot open DB written by WT2.6.1 with WT2.8.0 due to WT_NOTFOUND on recovery
WT-2539 Implement file streaming above pluggable filesystems
WT-2540 Separate stream and file handle methods
WT-2541 Add statistics for number of threads currently in read/write
WT-2542 Fixed-length column store reconciliation overwrites original values
WT-2544 Fix eviction statistics when clear is configured
WT-2546 Eviction server not help evict pages sometimes
WT-2547 Add 1-eviction-worker jobs to Jenkins
WT-2548 Cap the amount of data handed to raw compression.
WT-2549 joins using recno keys return no values
WT-2550 java ex_schema example fails
WT-2552 Public API for pluggable filesystems
WT-2553 Document in-memory configuration and WT_CACHE_FULL error return
WT-2554 Implement a framework for adding C test cases
WT-2556 Typo in the Java example code
WT-2557 format test program should discard log files after incremental backup
WT-2558 WT_PAGE structure reorganization
WT-2559 Windows segfault in logging code
WT-2560 Stuck trying to update oldest transaction ID
WT-2562 Reconfig02 test failing sometimes on PPC
WT-2565 Item 3573 on page at [write-check] is a corrupted cell
WT-2566 All lock operations should be barriers
WT-2567 Segfault in test/format log truncate
WT-2568 Java PackTest.java compilation error
WT-2569 Win_handle_read should always call GetLastError on error
WT-2570 Minor lint cleanups.
WT-2571 Join code cleanup
WT-2572 Don't select an in-memory format run if incompatible options configured
WT-2573 Free of stack-allocated WT_REF
WT-2574 Format doesn't free all allocated configure memory
WT-2576 Variable-length column-store out-of-order return
WT-2577 Core dump discarding non-existent addresses
WT-2579 In-memory configurations break debugging support
WT-2580 Potential SWIG naming conflict in Java
WT-2581 Assert multi->disk_image == NULL
WT-2582 Cache eviction server error: WT_RESTART
WT-2583 Incremental backup can prevent future recovery
WT-2584 Don't use periods in error messages
WT-2586 Remove ex_config.c until config cursors are supported
WT-2589 Check stats using WT_STAT_SET and 'clear' usage
WT-2592 Joins using non-recno key types not working
WT-2593 Disk full with pre-allocated log files
WT-2595 Fix compiler warning in packing tests
WT-2597 JSON dump needs LSM tests
WT-2598 In-memory FS needs fast lookup on file names
WT-2599 Split out the checksum code from the support directory
WT-2600 Clean up test program #includes
WT-2602 LSM stress hangs with very large uncompressed pages
WT-2605 C tests focused on different schema types needed for join and other APIs
WT-2609 Incorrect "skips API_END call" error.
WT-2610 Investigate eviction hazard pointer check
WT-2611 wtperf and/or WT_CONFIG_PARSER do not allow escaped double quotes
WT-2612 The dist/s_prototypes script is creating a debugging file xxx.
WT-2613 Windows build failing with a C4100 error
WT-2615 Enabling checkpoints in test/format leads to reduced concurrency
WT-2616 In-memory deadlock getting size
WT-2617 Bug in pluggable file system example
WT-2621 WiredTiger fails to compile on MSVC 2013
WT-2622 Unit test failed in test_cursor_random.test_cursor_random.test_cursor_random_multiple_page_records
WT-2624 snprintf unsupported on MSVC 2013
WT-2626 snprintf errors with macro redefinition on MSVC2015
WT-2627 Coverity complaints
WT-2628 Reconciliation can return without unlocking the page lock
WT-2629 Introduction of ppc64le crc32c assembly file has made the stack executable
WT-2630 Rename WT_FSTREAM methods to avoid using C99 reserved names
WT-2632 Test format failures due to "checkpoints cannot be dropped when in-use"
WT-2637 The file-extension documentation doesn't cover not-supported cases
WT-2644 'wt load -r' (rename) fails with LSM
WT-2646 Split the lock_wait flag into two, adding a checkpoint_wait flag
WT-2651 Coverity 1355591 resource leak
WT-2652 Logging code improvements
WT-2653 The custom file-system example should show device configuration
WT-2656 Builds failing on GCC 4.7 builder
WT-2658 Only include PPC-specific files in PPC builds
WT-2659 csuite tests, assorted lint and cleanup.
WT-2660 Hang between eviction and connection close
WT-2661 Coverity failures: 1356050-1356053
WT-2662 For internal spell checking, strip out double quote literals, they confuse aspell
WT-2664 Change eviction so any eviction thread can find candidates
WT-2667 Enhance WiredTiger Evergreen testing
WT-2668 Create join statistics that are useful and are easy to understand
WT-2671 Dump more information about the file layout in verify debug mode
WT-2672 Handle system calls that don't set errno
WT-2673 Stop automatically increasing memory page max
WT-2674 Simplify metadata file check
WT-2676 Don't use key size in column store in-memory splits.
WT-2677 Fix JSON output so only printable ASCII is produced (seen on Solaris)
WT-2682 Add option to configure WiredTiger with strict compiler flags
WT-2683 WiredTiger no longer needs to return non-zero disk sizes
WT-2685 Hazard pointer failure from clear walk
WT-2686 Logging subsystem core dump
WT-2687 Test suite should verify the exit status of the wt utility
WT-2689 Use after free in WT_SESSION::open_cursor
WT-2691 Use wrappers for ctype functions to avoid sign extension errors
WT-2692 Fix race in file system example
WT-2696 Race condition on unclean shutdown may miss log records with large updates
WT-2698 Test/recovery hung
WT-2702 Under high thread load, WiredTiger exceeds cache size
WT-2704 Test/format hung on bengal
WT-2706 Race condition on log file switch can cause missing log records
WT-2707 dist/s_label enhancements, and error jump cleanups
WT-2709 Connection reconfigure segfault in __wt_conn_cache_pool_destroy
WT-2710 WT_FILE_HANDLE_INMEM no longer needs an off field
WT-2712 Coverity 1356928 and 1356929: ASSERT_SIDE_EFFECT
WT-2713 Document WT_PANIC so pluggable filesystems can panic.
WT-2714 Lint
WT-2715 random-abort test may write partial record at the end
WT-2720 Pull request tester not running Python suite
WT-2722 s_label or s_label_loop false positive
WT-2724 Eviction workers created on open exit immediately
WT-2763 Unit test test_intpack failing on OSX
Diffstat (limited to 'src/third_party/wiredtiger/examples')
25 files changed, 1278 insertions, 120 deletions
diff --git a/src/third_party/wiredtiger/examples/c/Makefile.am b/src/third_party/wiredtiger/examples/c/Makefile.am index 72fd98aff7b..d5305eec5c8 100644 --- a/src/third_party/wiredtiger/examples/c/Makefile.am +++ b/src/third_party/wiredtiger/examples/c/Makefile.am @@ -7,7 +7,6 @@ noinst_PROGRAMS = \ ex_async \ ex_backup \ ex_call_center \ - ex_config \ ex_config_parse \ ex_cursor \ ex_data_source \ @@ -15,6 +14,7 @@ noinst_PROGRAMS = \ ex_event_handler \ ex_extending \ ex_extractor \ + ex_file_system \ ex_hello \ ex_log \ ex_pack \ @@ -26,6 +26,7 @@ noinst_PROGRAMS = \ ex_thread ex_encrypt_LDFLAGS = -rdynamic +ex_file_system_LDFLAGS = -rdynamic # The examples can be run with no arguments as simple smoke tests TESTS = $(noinst_PROGRAMS) diff --git a/src/third_party/wiredtiger/examples/c/ex_access.c b/src/third_party/wiredtiger/examples/c/ex_access.c index cc42982617b..d7f3cc557ad 100644 --- a/src/third_party/wiredtiger/examples/c/ex_access.c +++ b/src/third_party/wiredtiger/examples/c/ex_access.c @@ -60,8 +60,8 @@ main(void) 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); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); } /*! [access example connection] */ @@ -95,5 +95,5 @@ main(void) ret = conn->close(conn, NULL); /*! [access example close] */ - return (ret); + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_all.c b/src/third_party/wiredtiger/examples/c/ex_all.c index 1c036b75461..dd807922c10 100644 --- a/src/third_party/wiredtiger/examples/c/ex_all.c +++ b/src/third_party/wiredtiger/examples/c/ex_all.c @@ -1037,6 +1037,13 @@ backup(WT_SESSION *session) ret = cursor->close(cursor); /*! [backup]*/ + /*! [incremental backup]*/ + /* Open the backup data source for incremental backup. */ + ret = session->open_cursor( + session, "backup:", NULL, "target=(\"log:\")", &cursor); + /*! [incremental backup]*/ + ret = cursor->close(cursor); + /*! [backup of a checkpoint]*/ ret = session->checkpoint(session, "drop=(from=June01),name=June01"); /*! [backup of a checkpoint]*/ @@ -1207,5 +1214,5 @@ main(void) /*! [Get the WiredTiger library version #2] */ } - return (ret); + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_async.c b/src/third_party/wiredtiger/examples/c/ex_async.c index ecdbd2f4fea..f7531a5c3d8 100644 --- a/src/third_party/wiredtiger/examples/c/ex_async.c +++ b/src/third_party/wiredtiger/examples/c/ex_async.c @@ -31,7 +31,9 @@ #include <errno.h> #include <inttypes.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> + #ifndef _WIN32 #include <unistd.h> #else @@ -48,7 +50,6 @@ #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] */ @@ -120,8 +121,19 @@ main(void) WT_CONNECTION *conn; WT_SESSION *session; int i, ret; + const char *home; char k[MAX_KEYS][16], v[MAX_KEYS][16]; + /* + * 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; + /*! [async example connection] */ ret = wiredtiger_open(home, NULL, "create,cache_size=100MB," @@ -148,7 +160,7 @@ main(void) if (ret == EBUSY) sleep(1); else - return (ret); + return (EXIT_FAILURE); } /*! [async handle allocation] */ @@ -198,7 +210,7 @@ main(void) if (ret == EBUSY) sleep(1); else - return (ret); + return (EXIT_FAILURE); } /*! [async search] */ @@ -220,5 +232,5 @@ main(void) printf("Searched for %" PRIu32 " keys\n", ex_asynckeys.num_keys); - return (ret); + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_backup.c b/src/third_party/wiredtiger/examples/c/ex_backup.c index 12eeaa4b7c3..0697cbb3458 100644 --- a/src/third_party/wiredtiger/examples/c/ex_backup.c +++ b/src/third_party/wiredtiger/examples/c/ex_backup.c @@ -273,12 +273,12 @@ main(void) snprintf(cmd_buf, sizeof(cmd_buf), "rm -rf %s && mkdir %s", home, home); if ((ret = system(cmd_buf)) != 0) { fprintf(stderr, "%s: failed ret %d\n", cmd_buf, ret); - return (ret); + return (EXIT_FAILURE); } if ((ret = wiredtiger_open(home, NULL, CONN_CONFIG, &wt_conn)) != 0) { fprintf(stderr, "Error connecting to %s: %s\n", home, wiredtiger_strerror(ret)); - return (ret); + return (EXIT_FAILURE); } ret = setup_directories(); @@ -320,7 +320,9 @@ main(void) * comparison between the incremental and original. */ ret = wt_conn->close(wt_conn, NULL); + printf("Final comparison: dumping and comparing data\n"); ret = compare_backups(0); - return (ret); + + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_call_center.c b/src/third_party/wiredtiger/examples/c/ex_call_center.c index d401507d165..cd53a1cdaf9 100644 --- a/src/third_party/wiredtiger/examples/c/ex_call_center.c +++ b/src/third_party/wiredtiger/examples/c/ex_call_center.c @@ -107,8 +107,8 @@ main(void) if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0) { fprintf(stderr, "Error connecting to %s: %s\n", - home, wiredtiger_strerror(ret)); - return (1); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); } /* Note: further error checking omitted for clarity. */ @@ -245,5 +245,5 @@ main(void) ret = conn->close(conn, NULL); - return (ret); + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_config_parse.c b/src/third_party/wiredtiger/examples/c/ex_config_parse.c index be3c78bedd4..40508b38204 100644 --- a/src/third_party/wiredtiger/examples/c/ex_config_parse.c +++ b/src/third_party/wiredtiger/examples/c/ex_config_parse.c @@ -32,6 +32,7 @@ #include <inttypes.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <wiredtiger.h> @@ -51,12 +52,12 @@ main(void) NULL, config_string, strlen(config_string), &parser)) != 0) { fprintf(stderr, "Error creating configuration parser: %s\n", wiredtiger_strerror(ret)); - return (ret); + return (EXIT_FAILURE); } if ((ret = parser->close(parser)) != 0) { fprintf(stderr, "Error closing configuration parser: %s\n", wiredtiger_strerror(ret)); - return (ret); + return (EXIT_FAILURE); } /*! [Create a configuration parser] */ @@ -64,7 +65,7 @@ main(void) NULL, config_string, strlen(config_string), &parser)) != 0) { fprintf(stderr, "Error creating configuration parser: %s\n", wiredtiger_strerror(ret)); - return (ret); + return (EXIT_FAILURE); } { @@ -76,7 +77,7 @@ main(void) if ((ret = parser->get(parser, "page_size", &v)) != 0) { fprintf(stderr, "page_size configuration: %s", wiredtiger_strerror(ret)); - return (ret); + return (EXIT_FAILURE); } my_page_size = v.val; /*! [get] */ @@ -91,7 +92,7 @@ main(void) NULL, config_string, strlen(config_string), &parser)) != 0) { fprintf(stderr, "Error creating configuration parser: %s\n", wiredtiger_strerror(ret)); - return (ret); + return (EXIT_FAILURE); } /*! [next] */ /* @@ -112,7 +113,7 @@ main(void) NULL, config_string, strlen(config_string), &parser)) != 0) { fprintf(stderr, "Error creating configuration parser: %s\n", wiredtiger_strerror(ret)); - return (ret); + return (EXIT_FAILURE); } /*! [nested get] */ @@ -125,7 +126,7 @@ main(void) if ((ret = parser->get(parser, "log.file_max", &v)) != 0) { fprintf(stderr, "log.file_max configuration: %s", wiredtiger_strerror(ret)); - return (ret); + return (EXIT_FAILURE); } printf("log file max: %" PRId64 "\n", v.val); /*! [nested get] */ @@ -135,7 +136,7 @@ main(void) NULL, config_string, strlen(config_string), &parser)) != 0) { fprintf(stderr, "Error creating configuration parser: %s\n", wiredtiger_strerror(ret)); - return (ret); + return (EXIT_FAILURE); } /*! [nested traverse] */ { @@ -150,11 +151,10 @@ main(void) "Error creating nested configuration " "parser: %s\n", wiredtiger_strerror(ret)); - ret = parser->close(parser); - return (ret); + break; } - while ((ret = sub_parser->next( - sub_parser, &k, &v)) == 0) + 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); } @@ -163,5 +163,5 @@ main(void) ret = parser->close(parser); } - return (ret); + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_cursor.c b/src/third_party/wiredtiger/examples/c/ex_cursor.c index 67c945ebc0b..b8ed6ab169d 100644 --- a/src/third_party/wiredtiger/examples/c/ex_cursor.c +++ b/src/third_party/wiredtiger/examples/c/ex_cursor.c @@ -181,12 +181,12 @@ main(void) if ((ret = wiredtiger_open( home, NULL, "create,statistics=(fast)", &conn)) != 0) fprintf(stderr, "Error connecting to %s: %s\n", - home, wiredtiger_strerror(ret)); + home == NULL ? "." : 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)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); ret = session->create(session, "table:world", "key_format=r,value_format=5sii," @@ -220,9 +220,11 @@ main(void) ret = cursor->close(cursor); /* Note: closing the connection implicitly closes open session(s). */ - if ((ret = conn->close(conn, NULL)) != 0) + if ((ret = conn->close(conn, NULL)) != 0) { fprintf(stderr, "Error closing %s: %s\n", - home, wiredtiger_strerror(ret)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } - return (ret); + return (EXIT_SUCCESS); } diff --git a/src/third_party/wiredtiger/examples/c/ex_data_source.c b/src/third_party/wiredtiger/examples/c/ex_data_source.c index dd2b835e6ae..6ed80dfcf19 100644 --- a/src/third_party/wiredtiger/examples/c/ex_data_source.c +++ b/src/third_party/wiredtiger/examples/c/ex_data_source.c @@ -58,6 +58,17 @@ my_create(WT_DATA_SOURCE *dsrc, WT_SESSION *session, (void)config; { +#if !defined(ERROR_BAD_COMMAND) +#define ERROR_BAD_COMMAND 37 +#endif + /*! [WT_EXTENSION_API map_windows_error] */ + int posix_error = + wt_api->map_windows_error(wt_api, session, ERROR_BAD_COMMAND); + /*! [WT_EXTENSION_API map_windows_error] */ + (void)posix_error; + } + + { const char *msg = "string"; /*! [WT_EXTENSION_API err_printf] */ (void)wt_api->err_printf( @@ -667,7 +678,7 @@ main(void) (void)wt_api->msg_printf(wt_api, NULL, "configuration complete"); /*! [WT_EXTENSION_API default_session] */ - (void)conn->close(conn, NULL); + ret = conn->close(conn, NULL); - return (ret); + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_encrypt.c b/src/third_party/wiredtiger/examples/c/ex_encrypt.c index c53a61c92ea..3b3323bc091 100644 --- a/src/third_party/wiredtiger/examples/c/ex_encrypt.c +++ b/src/third_party/wiredtiger/examples/c/ex_encrypt.c @@ -51,7 +51,7 @@ __declspec(dllexport) #endif int add_my_encryptors(WT_CONNECTION *connection); -static const char *home = NULL; +static const char *home; #define SYS_KEYID "system" #define SYS_PW "system_password" @@ -122,8 +122,8 @@ do_rotate(char *buf, size_t len, int rotn) * Now rotate */ for (i = 0; i < len; i++) - if (isalpha(buf[i])) { - if (islower(buf[i])) + if (isalpha((unsigned char)buf[i])) { + if (islower((unsigned char)buf[i])) buf[i] = ((buf[i] - 'a') + rotn) % 26 + 'a'; else buf[i] = ((buf[i] - 'A') + rotn) % 26 + 'A'; @@ -587,6 +587,8 @@ main(void) printf("Verified key %s; value %s\n", key1, val1); } + ret = conn->close(conn, NULL); - return (ret); + + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_event_handler.c b/src/third_party/wiredtiger/examples/c/ex_event_handler.c index d1e08edb04d..7122e71882e 100644 --- a/src/third_party/wiredtiger/examples/c/ex_event_handler.c +++ b/src/third_party/wiredtiger/examples/c/ex_event_handler.c @@ -68,7 +68,7 @@ handle_wiredtiger_error(WT_EVENT_HANDLER *handler, /* Report the error on the console. */ fprintf(stderr, "app_id %s, thread context %p, error %d, message %s\n", - custom_handler->app_id, session, error, message); + custom_handler->app_id, (void *)session, error, message); return (0); } @@ -83,7 +83,8 @@ handle_wiredtiger_message( { /* Cast the handler back to our custom handler. */ printf("app id %s, thread context %p, message %s\n", - ((CUSTOM_EVENT_HANDLER *)handler)->app_id, session, message); + ((CUSTOM_EVENT_HANDLER *)handler)->app_id, + (void *)session, message); return (0); } @@ -111,10 +112,10 @@ config_event_handler(void) /*! [Configure event_handler] */ /* Make an invalid API call, to ensure the event handler works. */ - (void)conn->open_session(conn, NULL, "isolation=invalid", &session); + printf("ex_event_handler: expect an error message to follow\n"); + ret = conn->open_session(conn, NULL, "isolation=invalid", &session); - if (ret == 0) - ret = conn->close(conn, NULL); + ret = conn->close(conn, NULL); return (ret); } @@ -122,6 +123,8 @@ config_event_handler(void) int main(void) { + 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). @@ -132,5 +135,7 @@ main(void) } else home = NULL; - return (config_event_handler()); + ret = config_event_handler(); + + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_extending.c b/src/third_party/wiredtiger/examples/c/ex_extending.c index 4d265ae1d2b..f276cdd3e1e 100644 --- a/src/third_party/wiredtiger/examples/c/ex_extending.c +++ b/src/third_party/wiredtiger/examples/c/ex_extending.c @@ -108,7 +108,7 @@ main(void) /* 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)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); /*! [add collator nocase] */ ret = conn->add_collator(conn, "nocase", &nocasecoll, NULL); @@ -119,15 +119,12 @@ main(void) /* 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)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); - /* XXX Do some work... */ + /* Do some work... */ - /* Note: closing the connection implicitly closes open session(s). */ - if ((ret = conn->close(conn, NULL)) != 0) + ret = conn->close(conn, NULL); /*! [add collator prefix10] */ - fprintf(stderr, "Error closing %s: %s\n", - home, wiredtiger_strerror(ret)); - return (ret); + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_extractor.c b/src/third_party/wiredtiger/examples/c/ex_extractor.c index 8623f4759fc..f9d7af4af0f 100644 --- a/src/third_party/wiredtiger/examples/c/ex_extractor.c +++ b/src/third_party/wiredtiger/examples/c/ex_extractor.c @@ -283,5 +283,5 @@ main(void) ret = conn->close(conn, NULL); - return (ret); + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_file_system.c b/src/third_party/wiredtiger/examples/c/ex_file_system.c new file mode 100644 index 00000000000..77e8f40480b --- /dev/null +++ b/src/third_party/wiredtiger/examples/c/ex_file_system.c @@ -0,0 +1,975 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * 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_system.c + * demonstrates how to use the custom file system interface + */ + +/* + * Include WiredTiger internal functions: we need architecture portable locking + * in this example, and we use the TAILQ_XXX functions to keep the code simple. + * + * Application-writers SHOULD NOT INCLUDE "wt_internal.h", the public WiredTiger + * include files should be used instead: + * + * #include <wiredtiger.h> + * #include <wiredtiger_ext.h> + */ +#include "wt_internal.h" + +/* + * This example code uses internal WiredTiger functions for portable locking. + * We use #defines to clarify the meaning and ignore errors to simplify the + * code. + * + * Application writers SHOULD NOT COPY THIS LOCKING CODE, it's special-case code + * to make this example portable across platforms. + */ +#define ALLOCATE_FILE_SYSTEM_LOCK(demo_fs) \ + (void)__wt_spin_init(NULL, &(demo_fs)->lock, "demo file handle lock") +#define DESTROY_FILE_SYSTEM_LOCK(wt_session, demo_fs) \ + __wt_spin_destroy((WT_SESSION_IMPL *)(wt_session), &(demo_fs)->lock) +#define LOCK_FILE_SYSTEM(wt_session, demo_fs) \ + __wt_spin_lock((WT_SESSION_IMPL *)(wt_session), &(demo_fs)->lock) +#define UNLOCK_FILE_SYSTEM(wt_session, demo_fs) \ + __wt_spin_unlock( \ + (WT_SESSION_IMPL *)(wt_session), &(demo_fs)->lock) + +/* + * Example file system implementation, using memory buffers to represent files. + */ +typedef struct { + WT_FILE_SYSTEM iface; + + /* + * WiredTiger performs schema and I/O operations in parallel, all file + * system and file handle access must be thread-safe. This example uses + * a single, global file system lock for simplicity; real applications + * might require finer granularity, for example, a single lock for the + * file system handle list and per-handle locks serializing I/O. + */ + WT_SPINLOCK lock; /* Lock */ + + int opened_file_count; + int opened_unique_file_count; + int closed_file_count; + int read_ops; + int write_ops; + + /* 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 { + WT_FILE_HANDLE iface; + + /* + * Add custom file handle fields after the interface. + */ + DEMO_FILE_SYSTEM *demo_fs; /* Enclosing file system */ + + TAILQ_ENTRY(demo_file_handle) q; /* Queue of handles */ + uint32_t ref; /* Reference count */ + + char *buf; /* In-memory contents */ + size_t bufsize; /* In-memory buffer size */ + + size_t size; /* Read/write data size */ +} DEMO_FILE_HANDLE; + +/* + * Extension initialization function. + */ +#ifdef _WIN32 +/* + * Explicitly export this function so it is visible when loading extensions. + */ +__declspec(dllexport) +#endif +int demo_file_system_create(WT_CONNECTION *, WT_CONFIG_ARG *); + +/* + * Forward function declarations for file system API implementation + */ +static int demo_fs_open(WT_FILE_SYSTEM *, + WT_SESSION *, const char *, WT_OPEN_FILE_TYPE, uint32_t, WT_FILE_HANDLE **); +static int demo_fs_directory_list(WT_FILE_SYSTEM *, WT_SESSION *, + const char *, const char *, char ***, uint32_t *); +static int demo_fs_directory_list_free( + WT_FILE_SYSTEM *, WT_SESSION *, char **, uint32_t); +static int demo_fs_directory_sync(WT_FILE_SYSTEM *file_system, + WT_SESSION *session, const char *directory); +static int demo_fs_exist(WT_FILE_SYSTEM *, WT_SESSION *, const char *, bool *); +static int demo_fs_remove(WT_FILE_SYSTEM *, WT_SESSION *, const char *); +static int demo_fs_rename( + WT_FILE_SYSTEM *, WT_SESSION *, const char *, const char *); +static int demo_fs_size( + WT_FILE_SYSTEM *, WT_SESSION *, const char *, wt_off_t *); +static int demo_fs_terminate(WT_FILE_SYSTEM *, WT_SESSION *); + +/* + * Forward function declarations for file handle API implementation + */ +static int demo_file_close(WT_FILE_HANDLE *, WT_SESSION *); +static int demo_file_lock(WT_FILE_HANDLE *, WT_SESSION *, bool); +static int demo_file_read( + WT_FILE_HANDLE *, WT_SESSION *, wt_off_t, size_t, void *); +static int demo_file_size(WT_FILE_HANDLE *, WT_SESSION *, wt_off_t *); +static int demo_file_sync(WT_FILE_HANDLE *, WT_SESSION *); +static int demo_file_truncate(WT_FILE_HANDLE *, WT_SESSION *, wt_off_t); +static int demo_file_write( + WT_FILE_HANDLE *, WT_SESSION *, wt_off_t, size_t, const void *); + +/* + * Forward function declarations for internal functions + */ +static int demo_handle_remove(WT_SESSION *, DEMO_FILE_HANDLE *); +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 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) +{ + 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; + + wtext = conn->get_extension_api(conn); + + 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; + + /* + * Applications may have their own configuration information to pass to + * the underlying filesystem implementation. See the main function for + * the setup of those configuration strings; here we parse configuration + * information as passed in by main, through WiredTiger. + * + * 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; + } + + ALLOCATE_FILE_SYSTEM_LOCK(demo_fs); + + /* 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; + file_system->fs_directory_sync = demo_fs_directory_sync; + file_system->fs_exist = demo_fs_exist; + file_system->fs_open_file = demo_fs_open; + file_system->fs_remove = demo_fs_remove; + file_system->fs_rename = demo_fs_rename; + file_system->fs_size = demo_fs_size; + file_system->terminate = demo_fs_terminate; + + if ((ret = conn->set_file_system(conn, file_system, NULL)) != 0) { + (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); + /* An error installing the file system is fatal. */ + exit(1); +} + +/* + * demo_fs_open -- + * fopen for our demo file system + */ +static int +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) +{ + DEMO_FILE_HANDLE *demo_fh; + DEMO_FILE_SYSTEM *demo_fs; + WT_EXTENSION_API *wtext; + WT_FILE_HANDLE *file_handle; + int ret = 0; + + (void)file_type; /* Unused */ + (void)flags; /* Unused */ + + *file_handlep = NULL; + + demo_fs = (DEMO_FILE_SYSTEM *)file_system; + demo_fh = NULL; + wtext = demo_fs->wtext; + + LOCK_FILE_SYSTEM(session, demo_fs); + ++demo_fs->opened_file_count; + + /* + * First search the file queue, if we find it, assert there's only a + * single reference, we only support a single handle on any file. + */ + demo_fh = demo_handle_search(file_system, name); + if (demo_fh != NULL) { + if (demo_fh->ref != 0) { + (void)wtext->err_printf(wtext, session, + "demo_fs_open: %s: file already open", name); + ret = EBUSY; + goto err; + } + + demo_fh->ref = 1; + + *file_handlep = (WT_FILE_HANDLE *)demo_fh; + + UNLOCK_FILE_SYSTEM(session, demo_fs); + return (0); + } + + /* The file hasn't been opened before, create a new one. */ + if ((demo_fh = calloc(1, sizeof(DEMO_FILE_HANDLE))) == NULL) { + ret = ENOMEM; + goto err; + } + + /* Initialize private information. */ + demo_fh->demo_fs = demo_fs; + demo_fh->ref = 1; + if ((demo_fh->buf = calloc(1, DEMO_FILE_SIZE_INCREMENT)) == NULL) { + ret = ENOMEM; + goto err; + } + demo_fh->bufsize = DEMO_FILE_SIZE_INCREMENT; + demo_fh->size = 0; + + /* Initialize public information. */ + file_handle = (WT_FILE_HANDLE *)demo_fh; + if ((file_handle->name = strdup(name)) == NULL) { + ret = ENOMEM; + goto err; + } + + /* + * Setup the function call table for our custom file system. Set the + * function pointer to NULL where our implementation doesn't support + * the functionality. + */ + file_handle->close = demo_file_close; + file_handle->fh_advise = NULL; + file_handle->fh_allocate = NULL; + file_handle->fh_allocate_nolock = NULL; + file_handle->fh_lock = demo_file_lock; + file_handle->fh_map = NULL; + file_handle->fh_map_discard = NULL; + file_handle->fh_map_preload = NULL; + file_handle->fh_unmap = NULL; + file_handle->fh_read = demo_file_read; + file_handle->fh_size = demo_file_size; + file_handle->fh_sync = demo_file_sync; + file_handle->fh_sync_nowait = NULL; + file_handle->fh_truncate = demo_file_truncate; + file_handle->fh_write = demo_file_write; + + TAILQ_INSERT_HEAD(&demo_fs->fileq, demo_fh, q); + ++demo_fs->opened_unique_file_count; + + *file_handlep = file_handle; + + if (0) { +err: free(demo_fh->buf); + free(demo_fh); + } + + UNLOCK_FILE_SYSTEM(session, demo_fs); + return (ret); +} + +/* + * demo_fs_directory_list -- + * Return a list of files in a given sub-directory. + */ +static int +demo_fs_directory_list(WT_FILE_SYSTEM *file_system, + WT_SESSION *session, const char *directory, + const char *prefix, char ***dirlistp, uint32_t *countp) +{ + DEMO_FILE_HANDLE *demo_fh; + DEMO_FILE_SYSTEM *demo_fs; + size_t len, prefix_len; + uint32_t allocated, count; + int ret = 0; + char *name, **entries; + + demo_fs = (DEMO_FILE_SYSTEM *)file_system; + + *dirlistp = NULL; + *countp = 0; + + entries = NULL; + allocated = count = 0; + len = strlen(directory); + prefix_len = prefix == NULL ? 0 : strlen(prefix); + + LOCK_FILE_SYSTEM(session, demo_fs); + TAILQ_FOREACH(demo_fh, &demo_fs->fileq, q) { + name = demo_fh->iface.name; + if (strncmp(name, directory, len) != 0 || + (prefix != NULL && strncmp(name, prefix, prefix_len) != 0)) + continue; + + /* + * Increase the list size in groups of 10, it doesn't + * matter if the list is a bit longer than necessary. + */ + if (count >= allocated) { + entries = realloc( + entries, (allocated + 10) * sizeof(char *)); + if (entries == NULL) { + ret = ENOMEM; + goto err; + } + memset(entries + allocated * sizeof(char *), + 0, 10 * sizeof(char *)); + allocated += 10; + } + entries[count++] = strdup(name); + } + + *dirlistp = entries; + *countp = count; + +err: UNLOCK_FILE_SYSTEM(session, demo_fs); + if (ret == 0) + return (0); + + if (entries != NULL) { + while (count > 0) + free(entries[--count]); + free(entries); + } + + return (ret); +} + +/* + * demo_fs_directory_list_free -- + * Free memory allocated by demo_fs_directory_list. + */ +static int +demo_fs_directory_list_free(WT_FILE_SYSTEM *file_system, + WT_SESSION *session, char **dirlist, uint32_t count) +{ + (void)file_system; + (void)session; + + if (dirlist != NULL) { + while (count > 0) + free(dirlist[--count]); + free(dirlist); + } + return (0); +} + +/* + * demo_fs_directory_sync -- + * Directory sync for our demo file system, which is a no-op. + */ +static int +demo_fs_directory_sync(WT_FILE_SYSTEM *file_system, + WT_SESSION *session, const char *directory) +{ + (void)file_system; /* Unused */ + (void)session; /* Unused */ + (void)directory; /* Unused */ + + return (0); +} + +/* + * demo_fs_exist -- + * Return if the file exists. + */ +static int +demo_fs_exist(WT_FILE_SYSTEM *file_system, + WT_SESSION *session, const char *name, bool *existp) +{ + DEMO_FILE_SYSTEM *demo_fs; + + demo_fs = (DEMO_FILE_SYSTEM *)file_system; + + LOCK_FILE_SYSTEM(session, demo_fs); + *existp = demo_handle_search(file_system, name) != NULL; + UNLOCK_FILE_SYSTEM(session, demo_fs); + + return (0); +} + +/* + * demo_fs_remove -- + * POSIX remove. + */ +static int +demo_fs_remove( + WT_FILE_SYSTEM *file_system, WT_SESSION *session, const char *name) +{ + DEMO_FILE_SYSTEM *demo_fs; + DEMO_FILE_HANDLE *demo_fh; + int ret = 0; + + demo_fs = (DEMO_FILE_SYSTEM *)file_system; + + ret = ENOENT; + LOCK_FILE_SYSTEM(session, demo_fs); + if ((demo_fh = demo_handle_search(file_system, name)) != NULL) + ret = demo_handle_remove(session, demo_fh); + UNLOCK_FILE_SYSTEM(session, demo_fs); + + return (ret); +} + +/* + * demo_fs_rename -- + * POSIX rename. + */ +static int +demo_fs_rename(WT_FILE_SYSTEM *file_system, + WT_SESSION *session, const char *from, const char *to) +{ + DEMO_FILE_HANDLE *demo_fh; + DEMO_FILE_SYSTEM *demo_fs; + char *copy; + int ret = 0; + + demo_fs = (DEMO_FILE_SYSTEM *)file_system; + + LOCK_FILE_SYSTEM(session, demo_fs); + if ((demo_fh = demo_handle_search(file_system, from)) == NULL) + ret = ENOENT; + else if ((copy = strdup(to)) == NULL) + ret = ENOMEM; + else { + free(demo_fh->iface.name); + demo_fh->iface.name = copy; + } + UNLOCK_FILE_SYSTEM(session, demo_fs); + return (ret); +} + +/* + * demo_fs_size -- + * Get the size of a file in bytes, by file name. + */ +static int +demo_fs_size(WT_FILE_SYSTEM *file_system, + WT_SESSION *session, const char *name, wt_off_t *sizep) +{ + DEMO_FILE_SYSTEM *demo_fs; + DEMO_FILE_HANDLE *demo_fh; + int ret = 0; + + demo_fs = (DEMO_FILE_SYSTEM *)file_system; + + ret = ENOENT; + LOCK_FILE_SYSTEM(session, demo_fs); + if ((demo_fh = demo_handle_search(file_system, name)) != NULL) + ret = demo_file_size((WT_FILE_HANDLE *)demo_fh, session, sizep); + UNLOCK_FILE_SYSTEM(session, demo_fs); + + return (ret); +} + +/* + * demo_fs_terminate -- + * Discard any resources on termination + */ +static int +demo_fs_terminate(WT_FILE_SYSTEM *file_system, WT_SESSION *session) +{ + DEMO_FILE_HANDLE *demo_fh; + DEMO_FILE_SYSTEM *demo_fs; + int ret = 0, tret; + + demo_fs = (DEMO_FILE_SYSTEM *)file_system; + + while ((demo_fh = TAILQ_FIRST(&demo_fs->fileq)) != NULL) + if ((tret = + demo_handle_remove(session, demo_fh)) != 0 && ret == 0) + ret = tret; + + printf("Custom file system\n"); + printf("\t%d unique file opens\n", demo_fs->opened_unique_file_count); + printf("\t%d files opened\n", demo_fs->opened_file_count); + printf("\t%d files closed\n", demo_fs->closed_file_count); + printf("\t%d reads, %d writes\n", + demo_fs->read_ops, demo_fs->write_ops); + + DESTROY_FILE_SYSTEM_LOCK(session, demo_fs); + free(demo_fs); + + return (ret); +} + +/* + * demo_file_close -- + * ANSI C close. + */ +static int +demo_file_close(WT_FILE_HANDLE *file_handle, WT_SESSION *session) +{ + DEMO_FILE_HANDLE *demo_fh; + DEMO_FILE_SYSTEM *demo_fs; + + demo_fh = (DEMO_FILE_HANDLE *)file_handle; + demo_fs = demo_fh->demo_fs; + + LOCK_FILE_SYSTEM(session, demo_fs); + if (--demo_fh->ref == 0) + ++demo_fs->closed_file_count; + UNLOCK_FILE_SYSTEM(session, demo_fs); + + return (0); +} + +/* + * demo_file_lock -- + * Lock/unlock a file. + */ +static int +demo_file_lock(WT_FILE_HANDLE *file_handle, WT_SESSION *session, bool lock) +{ + /* Locks are always granted. */ + (void)file_handle; /* Unused */ + (void)session; /* Unused */ + (void)lock; /* Unused */ + return (0); +} + +/* + * demo_file_read -- + * POSIX pread. + */ +static int +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; + DEMO_FILE_SYSTEM *demo_fs; + WT_EXTENSION_API *wtext; + size_t off; + int ret = 0; + + demo_fh = (DEMO_FILE_HANDLE *)file_handle; + demo_fs = demo_fh->demo_fs; + wtext = demo_fs->wtext; + off = (size_t)offset; + + LOCK_FILE_SYSTEM(session, demo_fs); + ++demo_fs->read_ops; + if (off < demo_fh->size) { + if (len > demo_fh->size - off) + len = demo_fh->size - off; + memcpy(buf, (uint8_t *)demo_fh->buf + off, len); + } else + ret = EIO; /* EOF */ + UNLOCK_FILE_SYSTEM(session, demo_fs); + if (ret == 0) + return (0); + + (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); +} + +/* + * demo_file_size -- + * Get the size of a file in bytes, by file handle. + */ +static int +demo_file_size( + WT_FILE_HANDLE *file_handle, WT_SESSION *session, wt_off_t *sizep) +{ + DEMO_FILE_HANDLE *demo_fh; + DEMO_FILE_SYSTEM *demo_fs; + + demo_fh = (DEMO_FILE_HANDLE *)file_handle; + demo_fs = demo_fh->demo_fs; + + LOCK_FILE_SYSTEM(session, demo_fs); + *sizep = (wt_off_t)demo_fh->size; + UNLOCK_FILE_SYSTEM(session, demo_fs); + return (0); +} + +/* + * demo_file_sync -- + * Ensure the content of the file is stable. This is a no-op in our + * memory backed file system. + */ +static int +demo_file_sync(WT_FILE_HANDLE *file_handle, WT_SESSION *session) +{ + (void)file_handle; /* Unused */ + (void)session; /* Unused */ + + return (0); +} + +/* + * demo_buffer_resize -- + * Resize the write buffer. + */ +static int +demo_buffer_resize( + WT_SESSION *session, DEMO_FILE_HANDLE *demo_fh, wt_off_t offset) +{ + DEMO_FILE_SYSTEM *demo_fs; + WT_EXTENSION_API *wtext; + size_t off; + void *p; + + demo_fs = demo_fh->demo_fs; + wtext = demo_fs->wtext; + off = (size_t)offset; + + /* Grow the buffer as necessary and clear any new space in the file. */ + if (demo_fh->bufsize >= off) + return (0); + + if ((p = realloc(demo_fh->buf, off)) == NULL) { + (void)wtext->err_printf(wtext, session, + "%s: failed to resize buffer", + demo_fh->iface.name, wtext->strerror(wtext, NULL, ENOMEM)); + return (ENOMEM); + } + memset((uint8_t *)p + demo_fh->bufsize, 0, off - demo_fh->bufsize); + demo_fh->buf = p; + demo_fh->bufsize = off; + + return (0); +} + +/* + * demo_file_truncate -- + * POSIX ftruncate. + */ +static int +demo_file_truncate( + WT_FILE_HANDLE *file_handle, WT_SESSION *session, wt_off_t offset) +{ + DEMO_FILE_HANDLE *demo_fh; + DEMO_FILE_SYSTEM *demo_fs; + int ret = 0; + + demo_fh = (DEMO_FILE_HANDLE *)file_handle; + demo_fs = demo_fh->demo_fs; + + LOCK_FILE_SYSTEM(session, demo_fs); + if ((ret = demo_buffer_resize(session, demo_fh, offset)) == 0) + demo_fh->size = (size_t)offset; + UNLOCK_FILE_SYSTEM(session, demo_fs); + return (ret); +} + +/* + * demo_file_write -- + * POSIX pwrite. + */ +static int +demo_file_write(WT_FILE_HANDLE *file_handle, WT_SESSION *session, + wt_off_t offset, size_t len, const void *buf) +{ + DEMO_FILE_HANDLE *demo_fh; + DEMO_FILE_SYSTEM *demo_fs; + WT_EXTENSION_API *wtext; + size_t off; + int ret = 0; + + demo_fh = (DEMO_FILE_HANDLE *)file_handle; + demo_fs = demo_fh->demo_fs; + wtext = demo_fs->wtext; + off = (size_t)offset; + + LOCK_FILE_SYSTEM(session, demo_fs); + ++demo_fs->write_ops; + if ((ret = demo_buffer_resize(session, demo_fh, + offset + (wt_off_t)(len + DEMO_FILE_SIZE_INCREMENT))) == 0) { + memcpy((uint8_t *)demo_fh->buf + off, buf, len); + if (off + len > demo_fh->size) + demo_fh->size = off + len; + } + UNLOCK_FILE_SYSTEM(session, demo_fs); + if (ret == 0) + return (0); + + (void)wtext->err_printf(wtext, session, + "%s: handle-write: failed to write %zu bytes at offset %zu: %s", + demo_fh->iface.name, len, off, wtext->strerror(wtext, NULL, ret)); + return (ret); +} + +/* + * demo_handle_remove -- + * Destroy an in-memory file handle. Should only happen on remove or + * shutdown. + */ +static int +demo_handle_remove(WT_SESSION *session, DEMO_FILE_HANDLE *demo_fh) +{ + DEMO_FILE_SYSTEM *demo_fs; + WT_EXTENSION_API *wtext; + + demo_fs = demo_fh->demo_fs; + wtext = demo_fs->wtext; + + if (demo_fh->ref != 0) { + (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); + + /* Clean up private information. */ + free(demo_fh->buf); + + /* Clean up public information. */ + free(demo_fh->iface.name); + + free(demo_fh); + + return (0); +} + +/* + * demo_handle_search -- + * Return a matching handle, if one exists. + */ +static DEMO_FILE_HANDLE * +demo_handle_search(WT_FILE_SYSTEM *file_system, const char *name) +{ + DEMO_FILE_HANDLE *demo_fh; + DEMO_FILE_SYSTEM *demo_fs; + + demo_fs = (DEMO_FILE_SYSTEM *)file_system; + + TAILQ_FOREACH(demo_fh, &demo_fs->fileq, q) + if (strcmp(demo_fh->iface.name, name) == 0) + break; + return (demo_fh); +} + +static const char *home; + +int +main(void) +{ + WT_CONNECTION *conn; + WT_CURSOR *cursor; + WT_SESSION *session; + const char *key, *open_config, *uri; + int i; + int ret = 0; + char kbuf[64]; + + /* + * 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; + + /*! [WT_FILE_SYSTEM register] */ + /* + * Setup a configuration string that will load our custom file system. + * 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. 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," + "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", + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } + /*! [WT_FILE_SYSTEM register] */ + + if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) { + fprintf(stderr, "WT_CONNECTION.open_session: %s\n", + wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } + uri = "table:fs"; + if ((ret = session->create( + session, uri, "key_format=S,value_format=S")) != 0) { + fprintf(stderr, "WT_SESSION.create: %s: %s\n", + uri, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } + if ((ret = session->open_cursor( + session, uri, NULL, NULL, &cursor)) != 0) { + fprintf(stderr, "WT_SESSION.open_cursor: %s: %s\n", + uri, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } + for (i = 0; i < 1000; ++i) { + (void)snprintf(kbuf, sizeof(kbuf), "%010d KEY -----", i); + cursor->set_key(cursor, kbuf); + cursor->set_value(cursor, "--- VALUE ---"); + if ((ret = cursor->insert(cursor)) != 0) { + fprintf(stderr, "WT_CURSOR.insert: %s: %s\n", + kbuf, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } + } + if ((ret = cursor->close(cursor)) != 0) { + fprintf(stderr, "WT_CURSOR.close: %s\n", + wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } + if ((ret = session->open_cursor( + session, uri, NULL, NULL, &cursor)) != 0) { + fprintf(stderr, "WT_SESSION.open_cursor: %s: %s\n", + uri, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } + for (i = 0; i < 1000; ++i) { + if ((ret = cursor->next(cursor)) != 0) { + fprintf(stderr, "WT_CURSOR.insert: %s: %s\n", + kbuf, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } + (void)snprintf(kbuf, sizeof(kbuf), "%010d KEY -----", i); + if ((ret = cursor->get_key(cursor, &key)) != 0) { + fprintf(stderr, "WT_CURSOR.get_key: %s\n", + wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } + if (strcmp(kbuf, key) != 0) { + fprintf(stderr, "Key mismatch: %s, %s\n", kbuf, key); + return (EXIT_FAILURE); + } + } + if ((ret = cursor->next(cursor)) != WT_NOTFOUND) { + fprintf(stderr, + "WT_CURSOR.insert: expected WT_NOTFOUND, got %s\n", + wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } + + if ((ret = conn->close(conn, NULL)) != 0) { + fprintf(stderr, "Error closing connection to %s: %s\n", + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } + + return (EXIT_SUCCESS); +} diff --git a/src/third_party/wiredtiger/examples/c/ex_hello.c b/src/third_party/wiredtiger/examples/c/ex_hello.c index 345e434741f..99534ee8868 100644 --- a/src/third_party/wiredtiger/examples/c/ex_hello.c +++ b/src/third_party/wiredtiger/examples/c/ex_hello.c @@ -56,21 +56,27 @@ main(void) home = NULL; /* Open a connection to the database, creating it if necessary. */ - if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0) + if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0) { fprintf(stderr, "Error connecting to %s: %s\n", - home, wiredtiger_strerror(ret)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } /* Open a session for the current thread's work. */ - if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) + if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) { fprintf(stderr, "Error opening a session on %s: %s\n", - home, wiredtiger_strerror(ret)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } /* Do some work... */ /* Note: closing the connection implicitly closes open session(s). */ - if ((ret = conn->close(conn, NULL)) != 0) + if ((ret = conn->close(conn, NULL)) != 0) { fprintf(stderr, "Error closing %s: %s\n", - home, wiredtiger_strerror(ret)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } - return (ret); + return (EXIT_SUCCESS); } diff --git a/src/third_party/wiredtiger/examples/c/ex_log.c b/src/third_party/wiredtiger/examples/c/ex_log.c index 78bd7e683cf..fdbc39412ae 100644 --- a/src/third_party/wiredtiger/examples/c/ex_log.c +++ b/src/third_party/wiredtiger/examples/c/ex_log.c @@ -295,12 +295,12 @@ main(void) home1, home2, home1, home2); if ((ret = system(cmd_buf)) != 0) { fprintf(stderr, "%s: failed ret %d\n", cmd_buf, ret); - return (ret); + return (EXIT_FAILURE); } 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); + return (EXIT_FAILURE); } ret = wt_conn->open_session(wt_conn, NULL, NULL, &session); @@ -348,12 +348,13 @@ main(void) 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); + return (EXIT_FAILURE); } ret = wt_conn->open_session(wt_conn, NULL, NULL, &session); ret = simple_walk_log(session, count_min); ret = walk_log(session); ret = wt_conn->close(wt_conn, NULL); - return (ret); + + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_pack.c b/src/third_party/wiredtiger/examples/c/ex_pack.c index 43b57880674..86725123f55 100644 --- a/src/third_party/wiredtiger/examples/c/ex_pack.c +++ b/src/third_party/wiredtiger/examples/c/ex_pack.c @@ -55,14 +55,18 @@ main(void) home = NULL; /* Open a connection to the database, creating it if necessary. */ - if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0) + if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0) { fprintf(stderr, "Error connecting to %s: %s\n", - home, wiredtiger_strerror(ret)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } /* Open a session for the current thread's work. */ - if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) + if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) { fprintf(stderr, "Error opening a session on %s: %s\n", - home, wiredtiger_strerror(ret)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } { /*! [packing] */ @@ -81,9 +85,11 @@ main(void) } /* Note: closing the connection implicitly closes open session(s). */ - if ((ret = conn->close(conn, NULL)) != 0) + if ((ret = conn->close(conn, NULL)) != 0) { fprintf(stderr, "Error closing %s: %s\n", - home, wiredtiger_strerror(ret)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } - return (ret); + return (EXIT_SUCCESS); } diff --git a/src/third_party/wiredtiger/examples/c/ex_process.c b/src/third_party/wiredtiger/examples/c/ex_process.c index 19f395dddaf..217730c4288 100644 --- a/src/third_party/wiredtiger/examples/c/ex_process.c +++ b/src/third_party/wiredtiger/examples/c/ex_process.c @@ -58,22 +58,28 @@ main(void) /*! [processes] */ /* Open a connection to the database, creating it if necessary. */ if ((ret = - wiredtiger_open(home, NULL, "create,multiprocess", &conn)) != 0) + wiredtiger_open(home, NULL, "create,multiprocess", &conn)) != 0) { fprintf(stderr, "Error connecting to %s: %s\n", - home, wiredtiger_strerror(ret)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } /* Open a session for the current thread's work. */ - if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) + if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) { fprintf(stderr, "Error opening a session on %s: %s\n", - home, wiredtiger_strerror(ret)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } /* XXX Do some work... */ /* Note: closing the connection implicitly closes open session(s). */ - if ((ret = conn->close(conn, NULL)) != 0) + if ((ret = conn->close(conn, NULL)) != 0) { fprintf(stderr, "Error closing %s: %s\n", - home, wiredtiger_strerror(ret)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); + } /*! [processes] */ - return (ret); + return (EXIT_SUCCESS); } diff --git a/src/third_party/wiredtiger/examples/c/ex_schema.c b/src/third_party/wiredtiger/examples/c/ex_schema.c index 70fc7eb2e62..a59d9480780 100644 --- a/src/third_party/wiredtiger/examples/c/ex_schema.c +++ b/src/third_party/wiredtiger/examples/c/ex_schema.c @@ -69,7 +69,8 @@ main(void) { POP_RECORD *p; WT_CONNECTION *conn; - WT_CURSOR *cursor, *cursor2, *join_cursor, *stat_cursor; + WT_CURSOR *country_cursor, *country_cursor2, *cursor, *join_cursor, + *stat_cursor, *subjoin_cursor, *year_cursor; WT_SESSION *session; const char *country; uint64_t recno, population; @@ -89,8 +90,8 @@ main(void) if ((ret = wiredtiger_open( home, NULL, "create,statistics=(fast)", &conn)) != 0) { fprintf(stderr, "Error connecting to %s: %s\n", - home, wiredtiger_strerror(ret)); - return (ret); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); } /* Note: error checking omitted for clarity. */ @@ -336,18 +337,18 @@ main(void) ret = session->open_cursor(session, "join:table:poptable", NULL, NULL, &join_cursor); ret = session->open_cursor(session, - "index:poptable:country", NULL, NULL, &cursor); + "index:poptable:country", NULL, NULL, &country_cursor); ret = session->open_cursor(session, - "index:poptable:immutable_year", NULL, NULL, &cursor2); + "index:poptable:immutable_year", NULL, NULL, &year_cursor); /* select values WHERE country == "AU" AND year > 1900 */ - cursor->set_key(cursor, "AU\0\0\0"); - ret = cursor->search(cursor); - ret = session->join(session, join_cursor, cursor, + country_cursor->set_key(country_cursor, "AU\0\0\0"); + ret = country_cursor->search(country_cursor); + ret = session->join(session, join_cursor, country_cursor, "compare=eq,count=10"); - cursor2->set_key(cursor2, (uint16_t)1900); - ret = cursor2->search(cursor2); - ret = session->join(session, join_cursor, cursor2, + year_cursor->set_key(year_cursor, (uint16_t)1900); + ret = year_cursor->search(year_cursor); + ret = session->join(session, join_cursor, year_cursor, "compare=gt,count=10,strategy=bloom"); /* List the values that are joined */ @@ -370,10 +371,63 @@ main(void) ret = stat_cursor->close(stat_cursor); ret = join_cursor->close(join_cursor); - ret = cursor2->close(cursor2); - ret = cursor->close(cursor); + ret = year_cursor->close(year_cursor); + ret = country_cursor->close(country_cursor); + + /*! [Complex join cursors] */ + /* Open cursors needed by the join. */ + ret = session->open_cursor(session, + "join:table:poptable", NULL, NULL, &join_cursor); + ret = session->open_cursor(session, + "join:table:poptable", NULL, NULL, &subjoin_cursor); + ret = session->open_cursor(session, + "index:poptable:country", NULL, NULL, &country_cursor); + ret = session->open_cursor(session, + "index:poptable:country", NULL, NULL, &country_cursor2); + ret = session->open_cursor(session, + "index:poptable:immutable_year", NULL, NULL, &year_cursor); + + /* + * select values WHERE (country == "AU" OR country == "UK") + * AND year > 1900 + * + * First, set up the join representing the country clause. + */ + country_cursor->set_key(country_cursor, "AU\0\0\0"); + ret = country_cursor->search(country_cursor); + ret = session->join(session, subjoin_cursor, country_cursor, + "operation=or,compare=eq,count=10"); + country_cursor2->set_key(country_cursor2, "UK\0\0\0"); + ret = country_cursor2->search(country_cursor2); + ret = session->join(session, subjoin_cursor, country_cursor2, + "operation=or,compare=eq,count=10"); + + /* Join that to the top join, and add the year clause */ + ret = session->join(session, join_cursor, subjoin_cursor, NULL); + year_cursor->set_key(year_cursor, (uint16_t)1900); + ret = year_cursor->search(year_cursor); + ret = session->join(session, join_cursor, year_cursor, + "compare=gt,count=10,strategy=bloom"); + + /* List the values that are joined */ + while ((ret = join_cursor->next(join_cursor)) == 0) { + ret = join_cursor->get_key(join_cursor, &recno); + ret = join_cursor->get_value(join_cursor, &country, &year, + &population); + printf("ID %" PRIu64, recno); + printf( + ": country %s, year %" PRIu16 ", population %" PRIu64 "\n", + country, year, population); + } + /*! [Complex join cursors] */ + + ret = join_cursor->close(join_cursor); + ret = subjoin_cursor->close(subjoin_cursor); + ret = country_cursor->close(country_cursor); + ret = country_cursor2->close(country_cursor2); + ret = year_cursor->close(year_cursor); ret = conn->close(conn, NULL); - return (ret); + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_scope.c b/src/third_party/wiredtiger/examples/c/ex_scope.c index 93878ec7e3d..795ad85d57b 100644 --- a/src/third_party/wiredtiger/examples/c/ex_scope.c +++ b/src/third_party/wiredtiger/examples/c/ex_scope.c @@ -106,10 +106,12 @@ cursor_scope_ops(WT_CURSOR *cursor) * memory, but as it does not position the cursor, it * doesn't reference memory owned by the cursor, either. */ + printf("ex_scope: " + "expect two WiredTiger error messages:\n"); if ((ret = cursor->get_key(cursor, &key)) == 0 || (ret = cursor->get_value(cursor, &value)) == 0) { fprintf(stderr, - "%s: error in s get_key/value: %s\n", + "%s: error in get_key/value: %s\n", op->op, session->strerror(session, ret)); return (ret); } @@ -122,6 +124,8 @@ cursor_scope_ops(WT_CURSOR *cursor) * reference key memory owned by the cursor, but has no * value. */ + printf("ex_scope: " + "expect one WiredTiger error message:\n"); if ((ret = cursor->get_key(cursor, &key)) != 0 || (ret = cursor->get_value(cursor, &value)) == 0) { fprintf(stderr, @@ -178,7 +182,7 @@ main(void) WT_CONNECTION *conn; WT_CURSOR *cursor; WT_SESSION *session; - int ret, tret; + int ret; /* * Create a clean test directory for this run of the test program if the @@ -194,8 +198,8 @@ main(void) 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); + home == NULL ? "." : home, wiredtiger_strerror(ret)); + return (EXIT_FAILURE); } ret = session->create(session, @@ -207,8 +211,7 @@ main(void) ret = cursor_scope_ops(cursor); /* Close the connection and clean up. */ - if ((tret = conn->close(conn, NULL)) != 0 && ret == 0) - ret = tret; + ret = conn->close(conn, NULL); - return (ret); + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_stat.c b/src/third_party/wiredtiger/examples/c/ex_stat.c index 6c5c15aacc6..ba473d6be04 100644 --- a/src/third_party/wiredtiger/examples/c/ex_stat.c +++ b/src/third_party/wiredtiger/examples/c/ex_stat.c @@ -235,9 +235,8 @@ main(void) 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,columns=(k,v)"); + ret = session->create(session, + "table:access", "key_format=S,value_format=S,columns=(k,v)"); ret = session->open_cursor( session, "table:access", NULL, NULL, &cursor); @@ -258,5 +257,7 @@ main(void) ret = print_derived_stats(session); - return (conn->close(conn, NULL) == 0 ? ret : EXIT_FAILURE); + ret = conn->close(conn, NULL); + + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_sync.c b/src/third_party/wiredtiger/examples/c/ex_sync.c index 8c3a6463a82..2c610b1e570 100644 --- a/src/third_party/wiredtiger/examples/c/ex_sync.c +++ b/src/third_party/wiredtiger/examples/c/ex_sync.c @@ -63,12 +63,12 @@ main(void) home, home); if ((ret = system(cmd_buf)) != 0) { fprintf(stderr, "%s: failed ret %d\n", cmd_buf, ret); - return (ret); + return (EXIT_FAILURE); } if ((ret = wiredtiger_open(home, NULL, CONN_CONFIG, &wt_conn)) != 0) { fprintf(stderr, "Error connecting to %s: %s\n", home, wiredtiger_strerror(ret)); - return (ret); + return (EXIT_FAILURE); } ret = wt_conn->open_session(wt_conn, NULL, NULL, &session); @@ -149,5 +149,6 @@ main(void) ret = session->log_flush(session, "sync=on"); ret = wt_conn->close(wt_conn, NULL); - return (ret); + + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/examples/c/ex_thread.c b/src/third_party/wiredtiger/examples/c/ex_thread.c index a72211b6243..7c52d3b8189 100644 --- a/src/third_party/wiredtiger/examples/c/ex_thread.c +++ b/src/third_party/wiredtiger/examples/c/ex_thread.c @@ -101,7 +101,7 @@ main(void) if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0) fprintf(stderr, "Error connecting to %s: %s\n", - home, wiredtiger_strerror(ret)); + home == NULL ? "." : home, wiredtiger_strerror(ret)); /* Note: further error checking omitted for clarity. */ ret = conn->open_session(conn, NULL, NULL, &session); @@ -122,6 +122,6 @@ main(void) ret = conn->close(conn, NULL); - return (ret); + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } /*! [thread main] */ 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 index 5fe767d49bf..48e85c9fade 100644 --- 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 @@ -878,6 +878,18 @@ backup(Session session) ": backup failed: " + ex.toString()); } /*! [backup]*/ + try { + /*! [incremental backup]*/ + /* Open the backup data source for incremental backup. */ + cursor = session.open_cursor("backup:", null, "target=(\"log:\")"); + /*! [incremental backup]*/ + + ret = cursor.close(); + } + catch (Exception ex) { + System.err.println(progname + + ": incremental backup failed: " + ex.toString()); + } /*! [backup of a checkpoint]*/ ret = session.checkpoint("drop=(from=June01),name=June01"); 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 index 7cc26acb479..76bff66a688 100644 --- 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 @@ -76,7 +76,8 @@ public class ex_schema { throws WiredTigerException { Connection conn; - Cursor cursor, cursor2, join_cursor, stat_cursor; + Cursor country_cursor, country_cursor2, cursor, join_cursor, + stat_cursor, subjoin_cursor, year_cursor; Session session; String country; long recno, population; @@ -343,18 +344,18 @@ public class ex_schema { /* Open cursors needed by the join. */ join_cursor = session.open_cursor( "join:table:poptable", null, null); - cursor = session.open_cursor( + country_cursor = session.open_cursor( "index:poptable:country", null, null); - cursor2 = session.open_cursor( + year_cursor = session.open_cursor( "index:poptable:immutable_year", null, null); /* select values WHERE country == "AU" AND year > 1900 */ - cursor.putKeyString("AU"); - ret = cursor.search(); - session.join(join_cursor, cursor, "compare=eq,count=10"); - cursor2.putKeyShort((short)1900); - ret = cursor2.search(); - session.join(join_cursor, cursor2, + country_cursor.putKeyString("AU"); + ret = country_cursor.search(); + session.join(join_cursor, country_cursor, "compare=eq,count=10"); + year_cursor.putKeyShort((short)1900); + ret = year_cursor.search(); + session.join(join_cursor, year_cursor, "compare=gt,count=10,strategy=bloom"); /* List the values that are joined */ @@ -376,8 +377,61 @@ public class ex_schema { ret = stat_cursor.close(); ret = join_cursor.close(); - ret = cursor2.close(); - ret = cursor.close(); + ret = year_cursor.close(); + ret = country_cursor.close(); + + /*! [Complex join cursors] */ + /* Open cursors needed by the join. */ + join_cursor = session.open_cursor( + "join:table:poptable", null, null); + subjoin_cursor = session.open_cursor( + "join:table:poptable", null, null); + country_cursor = session.open_cursor( + "index:poptable:country", null, null); + country_cursor2 = session.open_cursor( + "index:poptable:country", null, null); + year_cursor = session.open_cursor( + "index:poptable:immutable_year", null, null); + + /* + * select values WHERE (country == "AU" OR country == "UK") + * AND year > 1900 + * + * First, set up the join representing the country clause. + */ + country_cursor.putKeyString("AU"); + ret = country_cursor.search(); + ret = session.join(subjoin_cursor, country_cursor, + "operation=or,compare=eq,count=10"); + country_cursor2.putKeyString("UK"); + ret = country_cursor2.search(); + ret = session.join(subjoin_cursor, country_cursor2, + "operation=or,compare=eq,count=10"); + + /* Join that to the top join, and add the year clause */ + ret = session.join(join_cursor, subjoin_cursor, null); + year_cursor.putKeyShort((short)1900); + ret = year_cursor.search(); + ret = session.join(join_cursor, year_cursor, + "compare=gt,count=10,strategy=bloom"); + + /* List the values that are joined */ + while ((ret = join_cursor.next()) == 0) { + recno = join_cursor.getKeyRecord(); + country = join_cursor.getValueString(); + year = join_cursor.getValueShort(); + population = join_cursor.getValueLong(); + System.out.print("ID " + recno); + System.out.println( ": country " + country + ", year " + year + + ", population " + population); + } + /*! [Complex join cursors] */ + + ret = join_cursor.close(); + ret = subjoin_cursor.close(); + ret = year_cursor.close(); + ret = country_cursor.close(); + ret = country_cursor2.close(); ret = conn.close(null); |