summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <mjc@wiredtiger.com>2014-10-15 12:15:02 +1100
committerMichael Cahill <mjc@wiredtiger.com>2014-10-15 12:15:02 +1100
commit9d2f324da8778421ed28544a7068df7030de7a88 (patch)
tree8525cf2b8d31e326dd8beea7167cfa5a08b95574
parent9ef6222eb484e2328e90f639e49bf64584a92a38 (diff)
parent5c2c195438f899c07e9b041e139b5a95acc700a4 (diff)
downloadmongo-9d2f324da8778421ed28544a7068df7030de7a88.tar.gz
Merge pull request #1258 from wiredtiger/java-doc-examples
Java doc examples
-rw-r--r--build_posix/Make.subdirs1
-rw-r--r--examples/java/com/wiredtiger/examples/ex_access.java25
-rw-r--r--examples/java/com/wiredtiger/examples/ex_all.java1009
-rw-r--r--examples/java/com/wiredtiger/examples/ex_async.java222
-rw-r--r--examples/java/com/wiredtiger/examples/ex_call_center.java299
-rw-r--r--examples/java/com/wiredtiger/examples/ex_cursor.java239
-rw-r--r--examples/java/com/wiredtiger/examples/ex_log.java376
-rw-r--r--examples/java/com/wiredtiger/examples/ex_schema.java333
-rw-r--r--examples/java/com/wiredtiger/examples/ex_stat.java252
-rw-r--r--examples/java/com/wiredtiger/examples/ex_thread.java142
-rw-r--r--lang/java/Makefile.am10
-rw-r--r--lang/java/wiredtiger.i2
-rw-r--r--src/docs/Doxyfile2
-rw-r--r--src/docs/async.dox6
-rw-r--r--src/docs/backup.dox4
-rw-r--r--src/docs/basic-api.dox17
-rw-r--r--src/docs/checkpoint.dox2
-rw-r--r--src/docs/command-line.dox4
-rw-r--r--src/docs/compact.dox2
-rw-r--r--src/docs/compression.dox4
-rw-r--r--src/docs/config-strings.dox8
-rw-r--r--src/docs/cursor-log.dox30
-rw-r--r--src/docs/cursor-ops.dox4
-rw-r--r--src/docs/cursor-random.dox2
-rw-r--r--src/docs/cursors.dox15
-rw-r--r--src/docs/data-sources.dox15
-rw-r--r--src/docs/durability.dox8
-rw-r--r--src/docs/error-handling.dox15
-rw-r--r--src/docs/file-formats.dox17
-rw-r--r--src/docs/introduction.dox1
-rw-r--r--src/docs/lsm.dox25
-rw-r--r--src/docs/namespace.dox15
-rw-r--r--src/docs/packing.dox8
-rw-r--r--src/docs/programming.dox12
-rw-r--r--src/docs/schema.dox90
-rw-r--r--src/docs/shared-cache.dox6
-rw-r--r--src/docs/spell.ok8
-rw-r--r--src/docs/statistics.dox2
-rw-r--r--src/docs/threads.dox2
-rwxr-xr-xsrc/docs/tools/doxfilter2
-rwxr-xr-xsrc/docs/tools/doxfilter.py151
-rw-r--r--src/docs/transactions.dox2
-rw-r--r--src/docs/tune-cache.dox2
43 files changed, 3303 insertions, 88 deletions
diff --git a/build_posix/Make.subdirs b/build_posix/Make.subdirs
index 5d005f59215..2484289aae5 100644
--- a/build_posix/Make.subdirs
+++ b/build_posix/Make.subdirs
@@ -16,6 +16,7 @@ ext/test/kvs_bdb HAVE_BERKELEY_DB
api/leveldb LEVELDB
bench/wtperf
examples/c
+examples/java JAVA
lang/java JAVA
lang/python PYTHON
test/bloom
diff --git a/examples/java/com/wiredtiger/examples/ex_access.java b/examples/java/com/wiredtiger/examples/ex_access.java
index 368f16d32bf..d4046495df5 100644
--- a/examples/java/com/wiredtiger/examples/ex_access.java
+++ b/examples/java/com/wiredtiger/examples/ex_access.java
@@ -32,24 +32,45 @@ import com.wiredtiger.db.*;
public class ex_access {
public static void main(String[] args) {
+ /*! [access example connection] */
Connection conn;
Session s;
Cursor c;
+
try {
conn = wiredtiger.open("WT_HOME", "create");
s = conn.open_session(null);
+ } catch (WiredTigerException wte) {
+ System.err.println("WiredTigerException: " + wte);
+ return;
+ }
+ /*! [access example connection] */
+ try {
+ /*! [access example table create] */
s.create("table:t", "key_format=S,value_format=u");
+ /*! [access example table create] */
+ /*! [access example cursor open] */
c = s.open_cursor("table:t", null, null);
+ /*! [access example cursor open] */
} catch (WiredTigerException wte) {
System.err.println("WiredTigerException: " + wte);
return;
}
System.out.println("Key format: " + c.getKeyFormat());
System.out.println("Value format: " + c.getValueFormat());
+ /*! [access example cursor insert] */
try {
c.putKeyString("foo");
c.putValueByteArray("bar".getBytes());
c.insert();
+ } catch (WiredTigerPackingException wtpe) {
+ System.err.println("WiredTigerPackingException: " + wtpe);
+ } catch (WiredTigerException wte) {
+ System.err.println("WiredTigerException: " + wte);
+ }
+ /*! [access example cursor insert] */
+ /*! [access example cursor list] */
+ try {
c.reset();
while (c.next() == 0) {
System.out.println("Got: " + c.getKeyString());
@@ -59,10 +80,14 @@ public class ex_access {
} catch (WiredTigerException wte) {
System.err.println("WiredTigerException: " + wte);
}
+ /*! [access example cursor list] */
+
+ /*! [access example close] */
try {
conn.close(null);
} catch (WiredTigerException wte) {
System.err.println("WiredTigerException: " + wte);
}
+ /*! [access example close] */
}
}
diff --git a/examples/java/com/wiredtiger/examples/ex_all.java b/examples/java/com/wiredtiger/examples/ex_all.java
new file mode 100644
index 00000000000..a0a2e2cdc6a
--- /dev/null
+++ b/examples/java/com/wiredtiger/examples/ex_all.java
@@ -0,0 +1,1009 @@
+/*-
+ * Public Domain 2008-2014 WiredTiger, Inc.
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ex_all.java
+ * Containing a call to every method in the WiredTiger API.
+ *
+ * It doesn't do anything very useful, just demonstrates how to call each
+ * method. This file is used to populate the API reference with code
+ * fragments.
+ */
+package com.wiredtiger.examples;
+import com.wiredtiger.db.*;
+import java.io.*;
+import java.nio.*;
+
+/* Note: indentation in non-standard so it will display nicely in doc. */
+public class ex_all {
+
+public static String progname = "ex_all";
+
+public static int cursor_ops(Session session)
+ throws WiredTigerException
+{
+ Cursor cursor;
+ int ret;
+
+ /*! [Open a cursor] */
+ cursor = session.open_cursor("table:mytable", null, null);
+ /*! [Open a cursor] */
+
+ /*! [Open a cursor on the metadata] */
+ cursor = session.open_cursor("metadata:", null, null);
+ /*! [Open a cursor on the metadata] */
+
+ {
+ Cursor duplicate;
+ String key = "some key";
+ /*! [Duplicate a cursor] */
+ cursor = session.open_cursor("table:mytable", null, null);
+ cursor.putKeyString(key);
+ ret = cursor.search();
+
+ /* Duplicate the cursor. */
+ duplicate = session.open_cursor(null, cursor, null);
+ /*! [Duplicate a cursor] */
+ }
+
+ {
+ Cursor overwrite_cursor;
+ String key = "some key", value = "some value";
+ /*! [Reconfigure a cursor] */
+ cursor = session.open_cursor("table:mytable", null, null);
+ cursor.putKeyString(key);
+
+ /* Reconfigure the cursor to overwrite the record. */
+ overwrite_cursor = session.open_cursor(null, cursor, "overwrite");
+ ret = cursor.close();
+
+ overwrite_cursor.putValueString(value);
+ ret = overwrite_cursor.insert();
+ /*! [Reconfigure a cursor] */
+ }
+
+ {
+ /*! [boolean configuration string example] */
+ cursor = session.open_cursor("table:mytable", null, "overwrite");
+ cursor = session.open_cursor("table:mytable", null, "overwrite=true");
+ cursor = session.open_cursor("table:mytable", null, "overwrite=1");
+ /*! [boolean configuration string example] */
+ }
+
+ {
+ /*! [open a named checkpoint] */
+ cursor = session.open_cursor("table:mytable", null, "checkpoint=midnight");
+ /*! [open a named checkpoint] */
+ }
+
+ {
+ /*! [open the default checkpoint] */
+ cursor = session.open_cursor("table:mytable", null,
+ "checkpoint=WiredTigerCheckpoint");
+ /*! [open the default checkpoint] */
+ }
+
+ {
+ /*! [Get the cursor's string key] */
+ String key; /* Get the cursor's string key. */
+ key = cursor.getKeyString();
+ /*! [Get the cursor's string key] */
+ }
+
+ {
+ /*! [Set the cursor's string key] */
+ /* Set the cursor's string key. */
+ String key = "another key";
+ cursor.putKeyString(key);
+ /*! [Set the cursor's string key] */
+ }
+
+ {
+ /*! [Get the cursor's record number key] */
+ long recno; /* Get the cursor's record number key. */
+ recno = cursor.getKeyLong();
+ /*! [Get the cursor's record number key] */
+ }
+
+ {
+ /*! [Set the cursor's record number key] */
+ long recno = 37; /* Set the cursor's record number key. */
+ cursor.putKeyLong(recno);
+ /*! [Set the cursor's record number key] */
+ }
+
+ {
+ /*! [Get the cursor's composite key] */
+ /* Get the cursor's "SiH" format composite key. */
+ String first;
+ int second;
+ short third;
+
+ first = cursor.getKeyString();
+ second = cursor.getKeyInt();
+ third = cursor.getKeyShort();
+ /*! [Get the cursor's composite key] */
+ }
+
+ {
+ /*! [Set the cursor's composite key] */
+ /* Set the cursor's "SiH" format composite key. */
+ cursor.putKeyString("first");
+ cursor.putKeyInt(5);
+ cursor.putKeyShort((short)7);
+ /*! [Set the cursor's composite key] */
+ }
+
+ {
+ /*! [Get the cursor's string value] */
+ String value; /* Get the cursor's string value. */
+ value = cursor.getValueString();
+ /*! [Get the cursor's string value] */
+ }
+
+ {
+ /*! [Set the cursor's string value] */
+ /* Set the cursor's string value. */
+ String value = "another value";
+ cursor.putValueString(value);
+ /*! [Set the cursor's string value] */
+ }
+
+ {
+ /*! [Get the cursor's raw value] */
+ byte[] value; /* Get the cursor's raw value. */
+ value = cursor.getValueByteArray();
+ /*! [Get the cursor's raw value] */
+ }
+
+ {
+ /*! [Set the cursor's raw value] */
+ byte[] value; /* Set the cursor's raw value. */
+ value = "another value".getBytes();
+ cursor.putValueByteArray(value);
+ /*! [Set the cursor's raw value] */
+ }
+
+ /*! [Return the next record] */
+ ret = cursor.next();
+ /*! [Return the next record] */
+
+ /*! [Return the previous record] */
+ ret = cursor.prev();
+ /*! [Return the previous record] */
+
+ /*! [Reset the cursor] */
+ ret = cursor.reset();
+ /*! [Reset the cursor] */
+
+ {
+ Cursor other = null;
+ /*! [Cursor comparison] */
+ int compare;
+ compare = cursor.compare(other);
+ if (compare == 0) {
+ /* Cursors reference the same key */
+ } else if (compare < 0) {
+ /* Cursor key less than other key */
+ } else if (compare > 0) {
+ /* Cursor key greater than other key */
+ }
+ /*! [Cursor comparison] */
+ }
+
+ {
+ /*! [Search for an exact match] */
+ String key = "some key";
+ cursor.putKeyString(key);
+ ret = cursor.search();
+ /*! [Search for an exact match] */
+ }
+
+ cursor_search_near(cursor);
+
+ {
+ /*! [Insert a new record or overwrite an existing record] */
+ /* Insert a new record or overwrite an existing record. */
+ String key = "some key", value = "some value";
+ cursor = session.open_cursor("table:mytable", null, null);
+ cursor.putKeyString(key);
+ cursor.putValueString(value);
+ ret = cursor.insert();
+ /*! [Insert a new record or overwrite an existing record] */
+ }
+
+ {
+ /*! [Insert a new record and fail if the record exists] */
+ /* Insert a new record and fail if the record exists. */
+ String key = "some key", value = "some value";
+ cursor = session.open_cursor("table:mytable", null, "overwrite=false");
+ cursor.putKeyString(key);
+ cursor.putValueString(value);
+ ret = cursor.insert();
+ /*! [Insert a new record and fail if the record exists] */
+ }
+
+ {
+ /*! [Insert a new record and assign a record number] */
+ /* Insert a new record and assign a record number. */
+ long recno;
+ String value = "some value";
+ cursor = session.open_cursor("table:mytable", null, "append");
+ cursor.putValueString(value);
+ ret = cursor.insert();
+ if (ret == 0)
+ recno = cursor.getKeyLong();
+ /*! [Insert a new record and assign a record number] */
+ }
+
+ {
+ /*! [Update an existing record or insert a new record] */
+ String key = "some key", value = "some value";
+ cursor = session.open_cursor("table:mytable", null, null);
+ cursor.putKeyString(key);
+ cursor.putValueString(value);
+ ret = cursor.update();
+ /*! [Update an existing record or insert a new record] */
+ }
+
+ {
+ /*! [Update an existing record and fail if DNE] */
+ String key = "some key", value = "some value";
+ cursor = session.open_cursor("table:mytable", null, "overwrite=false");
+ cursor.putKeyString(key);
+ cursor.putValueString(value);
+ ret = cursor.update();
+ /*! [Update an existing record and fail if DNE] */
+ }
+
+ {
+ /*! [Remove a record] */
+ String key = "some key";
+ cursor = session.open_cursor("table:mytable", null, null);
+ cursor.putKeyString(key);
+ ret = cursor.remove();
+ /*! [Remove a record] */
+ }
+
+ {
+ /*! [Remove a record and fail if DNE] */
+ String key = "some key";
+ cursor = session.open_cursor("table:mytable", null, "overwrite=false");
+ cursor.putKeyString(key);
+ ret = cursor.remove();
+ /*! [Remove a record and fail if DNE] */
+ }
+
+ {
+ /*! [Display an error] */
+ try {
+ String key = "non-existent key";
+ cursor.putKeyString(key);
+ if ((ret = cursor.remove()) != 0) {
+ System.err.println(
+ "cursor.remove: " + wiredtiger.wiredtiger_strerror(ret));
+ return (ret);
+ }
+ } catch (WiredTigerException wte) { /* Catch severe errors. */
+ System.err.println("cursor.remove exception: " + wte);
+ }
+ /*! [Display an error] */
+ }
+
+ /*! [Close the cursor] */
+ ret = cursor.close();
+ /*! [Close the cursor] */
+
+ return (ret);
+}
+
+static int
+cursor_search_near(Cursor cursor)
+ throws WiredTigerException
+{
+ int ret;
+ String key = "some key";
+ SearchStatus status;
+
+ /*! [Search for an exact or adjacent match] */
+ cursor.putKeyString(key);
+ status = cursor.search_near();
+ if (status == SearchStatus.FOUND) {
+ /* an exact match */
+ } else if (status == SearchStatus.SMALLER) {
+ /* returned smaller key */
+ } else if (status == SearchStatus.LARGER) {
+ /* returned larger key */
+ } else if (status == SearchStatus.NOTFOUND) {
+ /* no match found */
+ }
+ /*! [Search for an exact or adjacent match] */
+
+ /*! [Forward scan greater than or equal] */
+ cursor.putKeyString(key);
+ status = cursor.search_near();
+ if (status == SearchStatus.FOUND || status == SearchStatus.LARGER) {
+ /* include first key returned in the scan */
+ }
+
+ while ((ret = cursor.next()) == 0) {
+ /* the rest of the scan */
+ }
+ /*! [Forward scan greater than or equal] */
+
+ /*! [Backward scan less than] */
+ cursor.putKeyString(key);
+ status = cursor.search_near();
+ if (status == SearchStatus.SMALLER) {
+ /* include first key returned in the scan */
+ }
+
+ while ((ret = cursor.prev()) == 0) {
+ /* the rest of the scan */
+ }
+ /*! [Backward scan less than] */
+
+ return (ret);
+}
+
+static int
+checkpoint_ops(Session session)
+ throws WiredTigerException
+{
+ int ret;
+
+ /*! [Checkpoint examples] */
+ /* Checkpoint the database. */
+ ret = session.checkpoint(null);
+
+ /* Checkpoint of the database, creating a named snapshot. */
+ ret = session.checkpoint("name=June01");
+
+ /*
+ * Checkpoint a list of objects.
+ * JSON parsing requires quoting the list of target URIs.
+ */
+ ret = session.
+ checkpoint("target=(\"table:table1\",\"table:table2\")");
+
+ /*
+ * Checkpoint a list of objects, creating a named snapshot.
+ * JSON parsing requires quoting the list of target URIs.
+ */
+ ret = session.
+ checkpoint("target=(\"table:mytable\"),name=midnight");
+
+ /* Checkpoint the database, discarding all previous snapshots. */
+ ret = session.checkpoint("drop=(from=all)");
+
+ /* Checkpoint the database, discarding the "midnight" snapshot. */
+ ret = session.checkpoint("drop=(midnight)");
+
+ /*
+ * Checkpoint the database, discarding all snapshots after and
+ * including "noon".
+ */
+ ret = session.checkpoint("drop=(from=noon)");
+
+ /*
+ * Checkpoint the database, discarding all snapshots before and
+ * including "midnight".
+ */
+ ret = session.checkpoint("drop=(to=midnight)");
+
+ /*
+ * Create a checkpoint of a table, creating the "July01" snapshot and
+ * discarding the "May01" and "June01" snapshots.
+ * JSON parsing requires quoting the list of target URIs.
+ */
+ ret = session.checkpoint("target=(\"table:mytable\"),name=July01,drop=(May01,June01)");
+ /*! [Checkpoint examples] */
+
+ /*! [JSON quoting example] */
+ /*
+ * Checkpoint a list of objects.
+ * JSON parsing requires quoting the list of target URIs.
+ */
+ ret = session.
+ checkpoint("target=(\"table:table1\",\"table:table2\")");
+ /*! [JSON quoting example] */
+
+ return (ret);
+}
+
+static boolean
+cursor_statistics(Session session)
+ throws WiredTigerException
+{
+ Cursor cursor;
+
+ /*! [Statistics cursor database] */
+ cursor = session.open_cursor(
+ "statistics:", null, null);
+ /*! [Statistics cursor database] */
+
+ /*! [Statistics cursor table] */
+ cursor = session.open_cursor(
+ "statistics:table:mytable", null, null);
+ /*! [Statistics cursor table] */
+
+ /*! [Statistics cursor table fast] */
+ cursor = session.open_cursor("statistics:table:mytable", null, "statistics=(fast)");
+ /*! [Statistics cursor table fast] */
+
+ /*! [Statistics clear configuration] */
+ cursor = session.open_cursor("statistics:", null, "statistics=(fast,clear)");
+ /*! [Statistics clear configuration] */
+
+ /*! [Statistics cursor clear configuration] */
+ cursor = session.open_cursor("statistics:table:mytable",
+ null, "statistics=(all,clear)");
+ /*! [Statistics cursor clear configuration] */
+
+ return (true);
+}
+
+static int
+session_ops(Session session)
+ throws WiredTigerException
+{
+ int ret;
+
+ /*! [Reconfigure a session] */
+ ret = session.reconfigure("isolation=snapshot");
+ /*! [Reconfigure a session] */
+
+ /*! [Create a table] */
+ ret = session.create("table:mytable", "key_format=S,value_format=S");
+ /*! [Create a table] */
+ ret = session.drop("table:mytable", null);
+
+ /*! [Create a column-store table] */
+ ret = session.create("table:mytable", "key_format=r,value_format=S");
+ /*! [Create a column-store table] */
+ ret = session.drop("table:mytable", null);
+
+ /*! [Create a table with columns] */
+ /*
+ * Create a table with columns: keys are record numbers, values are
+ * (string, signed 32-bit integer, unsigned 16-bit integer).
+ */
+ ret = session.create("table:mytable",
+ "key_format=r,value_format=SiH," +
+ "columns=(id,department,salary,year-started)");
+ /*! [Create a table with columns] */
+ ret = session.drop("table:mytable", null);
+
+ /*
+ * This example code gets run, and the compression libraries might not
+ * be loaded, causing the create to fail. The documentation requires
+ * the code snippets, use if (false) to avoid running it.
+ */
+ if (false) { // MIGHT_NOT_RUN
+ /*! [Create a bzip2 compressed table] */
+ ret = session.create("table:mytable",
+ "block_compressor=bzip2,key_format=S,value_format=S");
+ /*! [Create a bzip2 compressed table] */
+ ret = session.drop("table:mytable", null);
+
+ /*! [Create a snappy compressed table] */
+ ret = session.create("table:mytable",
+ "block_compressor=snappy,key_format=S,value_format=S");
+ /*! [Create a snappy compressed table] */
+ ret = session.drop("table:mytable", null);
+
+ /*! [Create a zlib compressed table] */
+ ret = session.create("table:mytable",
+ "block_compressor=zlib,key_format=S,value_format=S");
+ /*! [Create a zlib compressed table] */
+ ret = session.drop("table:mytable", null);
+ } // if (false)
+
+ /*! [Configure checksums to uncompressed] */
+ ret = session.create("table:mytable",
+ "key_format=S,value_format=S,checksum=uncompressed");
+ /*! [Configure checksums to uncompressed] */
+ ret = session.drop("table:mytable", null);
+
+ /*! [Configure dictionary compression on] */
+ ret = session.create("table:mytable",
+ "key_format=S,value_format=S,dictionary=1000");
+ /*! [Configure dictionary compression on] */
+ ret = session.drop("table:mytable", null);
+
+ /*! [Configure key prefix compression on] */
+ ret = session.create("table:mytable",
+ "key_format=S,value_format=S,prefix_compression=true");
+ /*! [Configure key prefix compression on] */
+ ret = session.drop("table:mytable", null);
+
+ if (false) { // MIGHT_NOT_RUN
+ /* Requires sync_file_range */
+ /*! [os_cache_dirty_max configuration] */
+ ret = session.create(
+ "table:mytable", "os_cache_dirty_max=500MB");
+ /*! [os_cache_dirty_max configuration] */
+ ret = session.drop("table:mytable", null);
+
+ /* Requires posix_fadvise */
+ /*! [os_cache_max configuration] */
+ ret = session.create("table:mytable", "os_cache_max=1GB");
+ /*! [os_cache_max configuration] */
+ ret = session.drop("table:mytable", null);
+ } // if (false)
+
+ /*! [Configure block_allocation] */
+ ret = session.create("table:mytable",
+ "key_format=S,value_format=S,block_allocation=first");
+ /*! [Configure block_allocation] */
+ ret = session.drop("table:mytable", null);
+
+ /*! [Create a cache-resident object] */
+ ret = session.create("table:mytable", "key_format=r,value_format=S,cache_resident=true");
+ /*! [Create a cache-resident object] */
+ ret = session.drop("table:mytable", null);
+
+ {
+ /* Create a table for the session operations. */
+ ret = session.create(
+ "table:mytable", "key_format=S,value_format=S");
+
+ /*! [Compact a table] */
+ ret = session.compact("table:mytable", null);
+ /*! [Compact a table] */
+
+ /*! [Rename a table] */
+ ret = session.rename("table:old", "table:new", null);
+ /*! [Rename a table] */
+
+ /*! [Salvage a table] */
+ ret = session.salvage("table:mytable", null);
+ /*! [Salvage a table] */
+
+ /*! [Truncate a table] */
+ ret = session.truncate("table:mytable", null, null, null);
+ /*! [Truncate a table] */
+
+ {
+ /*
+ * Insert a pair of keys so we can truncate a range.
+ */
+ Cursor cursor;
+ cursor = session.open_cursor(
+ "table:mytable", null, null);
+ cursor.putKeyString("June01");
+ cursor.putValueString("value");
+ ret = cursor.update();
+ cursor.putKeyString("June30");
+ cursor.putValueString("value");
+ ret = cursor.update();
+ cursor.close();
+
+ {
+ /*! [Truncate a range] */
+ Cursor start, stop;
+
+ start = session.open_cursor(
+ "table:mytable", null, null);
+ start.putKeyString("June01");
+ ret = start.search();
+
+ stop = session.open_cursor(
+ "table:mytable", null, null);
+ stop.putKeyString("June30");
+ ret = stop.search();
+
+ ret = session.truncate(null, start, stop, null);
+ /*! [Truncate a range] */
+ }
+ }
+
+ /*! [Upgrade a table] */
+ ret = session.upgrade("table:mytable", null);
+ /*! [Upgrade a table] */
+
+ /*! [Verify a table] */
+ ret = session.verify("table:mytable", null);
+ /*! [Verify a table] */
+
+ /*! [Drop a table] */
+ ret = session.drop("table:mytable", null);
+ /*! [Drop a table] */
+ }
+
+ /*! [Close a session] */
+ ret = session.close(null);
+ /*! [Close a session] */
+
+ return (ret);
+}
+
+static int
+transaction_ops(Connection conn, Session session)
+ throws WiredTigerException
+{
+ Cursor cursor;
+ int ret;
+
+ /*! [transaction commit/rollback] */
+ cursor = session.open_cursor("table:mytable", null, null);
+ ret = session.begin_transaction(null);
+ /*
+ * Cursors may be opened before or after the transaction begins, and in
+ * either case, subsequent operations are included in the transaction.
+ * The begin_transaction call resets all open cursors.
+ */
+
+ cursor.putKeyString("key");
+ cursor.putValueString("value");
+ switch (ret = cursor.update()) {
+ case 0: /* Update success */
+ ret = session.commit_transaction(null);
+ /*
+ * The commit_transaction call resets all open cursors.
+ * If commit_transaction fails, the transaction was rolled-back.
+ */
+ break;
+ case wiredtiger.WT_DEADLOCK: /* Update conflict */
+ default: /* Other error */
+ ret = session.rollback_transaction(null);
+ /* The rollback_transaction call resets all open cursors. */
+ break;
+ }
+
+ /* Cursors remain open and may be used for multiple transactions. */
+ /*! [transaction commit/rollback] */
+ ret = cursor.close();
+
+ /*! [transaction isolation] */
+ /* A single transaction configured for snapshot isolation. */
+ cursor = session.open_cursor("table:mytable", null, null);
+ ret = session.begin_transaction("isolation=snapshot");
+ cursor.putKeyString("some-key");
+ cursor.putValueString("some-value");
+ ret = cursor.update();
+ ret = session.commit_transaction(null);
+ /*! [transaction isolation] */
+
+ /*! [session isolation configuration] */
+ /* Open a session configured for read-uncommitted isolation. */
+ session = conn.open_session(
+ "isolation=read_uncommitted");
+ /*! [session isolation configuration] */
+
+ /*! [session isolation re-configuration] */
+ /* Re-configure a session for snapshot isolation. */
+ ret = session.reconfigure("isolation=snapshot");
+ /*! [session isolation re-configuration] */
+
+ return (ret);
+}
+
+/*! [Implement WT_COLLATOR] */
+/* Not available for java */
+/*! [Implement WT_COLLATOR] */
+
+/*! [WT_EXTRACTOR] */
+/* Not available for java */
+/*! [WT_EXTRACTOR] */
+
+static int
+connection_ops(Connection conn)
+ throws WiredTigerException
+{
+ int ret;
+
+ if (false) { // Might not run.
+ /*! [Load an extension] */
+ ret = conn.load_extension("my_extension.dll", null);
+
+ ret = conn.load_extension(
+ "datasource/libdatasource.so",
+ "config=[device=/dev/sd1,alignment=64]");
+ /*! [Load an extension] */
+ } // if (false)
+
+ /*! [Reconfigure a connection] */
+ ret = conn.reconfigure("eviction_target=75");
+ /*! [Reconfigure a connection] */
+
+ /*! [Get the database home directory] */
+ System.out.println("The database home is " + conn.get_home());
+ /*! [Get the database home directory] */
+
+ /*! [Check if the database is newly created] */
+ if (conn.is_new() != 0) {
+ /* First time initialization. */
+ }
+ /*! [Check if the database is newly created] */
+
+ {
+ /*! [Open a session] */
+ Session session;
+ session = conn.open_session(null);
+ /*! [Open a session] */
+
+ session_ops(session);
+ }
+
+ /*! [Configure method configuration] */
+ /*
+ * Applications opening a cursor for the data-source object "my_data"
+ * have an additional configuration option "entries", which is an
+ * integer type, defaults to 5, and must be an integer between 1 and 10.
+ */
+ ret = conn.configure_method(
+ "session.open_cursor",
+ "my_data:", "entries=5", "int", "min=1,max=10");
+
+ /*
+ * Applications opening a cursor for the data-source object "my_data"
+ * have an additional configuration option "devices", which is a list
+ * of strings.
+ */
+ ret = conn.configure_method(
+ "session.open_cursor", "my_data:", "devices", "list", null);
+ /*! [Configure method configuration] */
+
+ /*! [Close a connection] */
+ ret = conn.close(null);
+ /*! [Close a connection] */
+
+ return (ret);
+}
+
+static int
+pack_ops(Session session)
+{
+ {
+ /*! [Get the packed size] */
+ /* Not available for java */
+ /*! [Get the packed size] */
+ }
+
+ {
+ /*! [Pack fields into a buffer] */
+ /* Not available for java */
+ /*! [Pack fields into a buffer] */
+ }
+
+ {
+ /*! [Unpack fields from a buffer] */
+ /* Not available for java */
+ /*! [Unpack fields from a buffer] */
+ }
+
+ return (0);
+}
+
+static boolean
+backup(Session session)
+ throws WiredTigerException
+{
+ char buf[] = new char[1024];
+
+ /*! [backup]*/
+ Cursor cursor;
+ String filename;
+ int ret = 0;
+ String databasedir = "/path/database";
+ String backdir = "/path/database.backup";
+ final String sep = File.separator;
+
+ try {
+ /* Create the backup directory. */
+ if (!(new File(backdir)).mkdir()) {
+ System.err.println(progname + ": cannot create backup dir: " +
+ backdir);
+ return false;
+ }
+
+ /* Open the backup data source. */
+ cursor = session.open_cursor("backup:", null, null);
+
+ /* Copy the list of files. */
+ while ((ret = cursor.next()) == 0 &&
+ (filename = cursor.getKeyString()) != null) {
+ String src = databasedir + sep + filename;
+ String dest = backdir + sep + filename;
+ java.nio.file.Files.copy(
+ new java.io.File(src).toPath(),
+ new java.io.File(dest).toPath(),
+ java.nio.file.StandardCopyOption.REPLACE_EXISTING,
+ java.nio.file.StandardCopyOption.COPY_ATTRIBUTES);
+ }
+ if (ret == wiredtiger.WT_NOTFOUND)
+ ret = 0;
+ if (ret != 0)
+ System.err.println(progname +
+ ": cursor next(backup:) failed: " +
+ wiredtiger.wiredtiger_strerror(ret));
+
+ ret = cursor.close();
+ }
+ catch (Exception ex) {
+ System.err.println(progname +
+ ": backup failed: " + ex.toString());
+ }
+ /*! [backup]*/
+
+ /*! [backup of a checkpoint]*/
+ ret = session.checkpoint("drop=(from=June01),name=June01");
+ /*! [backup of a checkpoint]*/
+
+ return (ret == 0);
+}
+
+public static int
+allExample()
+ throws WiredTigerException
+{
+ Connection conn;
+ int ret = 0;
+ String home = "/home/example/WT_TEST";
+
+ /*! [Open a connection] */
+ conn = wiredtiger.open(home, "create,cache_size=500M");
+ /*! [Open a connection] */
+
+ connection_ops(conn);
+ /*
+ * The connection has been closed.
+ */
+
+ if (false) { // MIGHT_NOT_RUN
+ /*
+ * This example code gets run, and the compression libraries might not
+ * be installed, causing the open to fail. The documentation requires
+ * the code snippets, use if (false) to avoid running it.
+ */
+ /*! [Configure bzip2 extension] */
+ conn = wiredtiger.open(home,
+ "create," +
+ "extensions=[/usr/local/lib/libwiredtiger_bzip2.so]");
+ /*! [Configure bzip2 extension] */
+ conn.close(null);
+
+ /*! [Configure snappy extension] */
+ conn = wiredtiger.open(home,
+ "create," +
+ "extensions=[/usr/local/lib/libwiredtiger_snappy.so]");
+ /*! [Configure snappy extension] */
+ conn.close(null);
+
+ /*! [Configure zlib extension] */
+ conn = wiredtiger.open(home,
+ "create," +
+ "extensions=[/usr/local/lib/libwiredtiger_zlib.so]");
+ /*! [Configure zlib extension] */
+ conn.close(null);
+
+ /*
+ * This example code gets run, and direct I/O might not be available,
+ * causing the open to fail. The documentation requires code snippets,
+ * use if (false) to avoid running it.
+ */
+ /* Might Not Run: direct I/O may not be available. */
+ /*! [Configure direct_io for data files] */
+ conn = wiredtiger.open(home, "create,direct_io=[data]");
+ /*! [Configure direct_io for data files] */
+ conn.close(null);
+ } // if (false)
+
+ /*! [Configure file_extend] */
+ conn = wiredtiger.open(
+ home, "create,file_extend=(data=16MB)");
+ /*! [Configure file_extend] */
+ conn.close(null);
+
+ /*! [Eviction configuration] */
+ /*
+ * Configure eviction to begin at 90% full, and run until the cache
+ * is only 75% dirty.
+ */
+ conn = wiredtiger.open(home,
+ "create,eviction_trigger=90,eviction_dirty_target=75");
+ /*! [Eviction configuration] */
+ conn.close(null);
+
+ /*! [Eviction worker configuration] */
+ /* Configure up to four eviction threads */
+ conn = wiredtiger.open(home,
+ "create,eviction_trigger=90,eviction=(threads_max=4)");
+ /*! [Eviction worker configuration] */
+ conn.close(null);
+
+ /*! [Statistics configuration] */
+ conn = wiredtiger.open(home, "create,statistics=(all)");
+ /*! [Statistics configuration] */
+ conn.close(null);
+
+ /*! [Statistics logging] */
+ conn = wiredtiger.open(
+ home, "create,statistics_log=(wait=30)");
+ /*! [Statistics logging] */
+ conn.close(null);
+
+ /*! [Statistics logging with a table] */
+ conn = wiredtiger.open(home,
+ "create," +
+ "statistics_log=(sources=(\"table:table1\",\"table:table2\"))");
+ /*! [Statistics logging with a table] */
+ conn.close(null);
+
+ /*! [Statistics logging with all tables] */
+ conn = wiredtiger.open(home,
+ "create,statistics_log=(sources=(\"table:\"))");
+ /*! [Statistics logging with all tables] */
+ conn.close(null);
+
+ if (false) { // MIGHT_NOT_RUN
+ /*
+ * This example code gets run, and a non-existent log file path might
+ * cause the open to fail. The documentation requires code snippets,
+ * use if (false) to avoid running it.
+ */
+ /*! [Statistics logging with path] */
+ conn = wiredtiger.open(home,
+ "create," +
+ "statistics_log=(wait=120,path=/log/log.%m.%d.%y)");
+ /*! [Statistics logging with path] */
+ conn.close(null);
+
+ /*
+ * Don't run this code, because memory checkers get very upset when we
+ * leak memory.
+ */
+ conn = wiredtiger.open(home, "create");
+ /*! [Connection close leaking memory] */
+ ret = conn.close("leak_memory=true");
+ /*! [Connection close leaking memory] */
+ } // if (false)
+
+ /*! [Get the WiredTiger library version #1] */
+ /* Not available for java */
+ /*! [Get the WiredTiger library version #1] */
+
+ {
+ /*! [Get the WiredTiger library version #2] */
+ /* Not available for java */
+ /*! [Get the WiredTiger library version #2] */
+ }
+
+ return (0);
+}
+
+public static int
+main(String[] argv)
+{
+ try {
+ return (allExample());
+ }
+ catch (WiredTigerException wte) {
+ System.err.println("Exception: " + wte);
+ return (-1);
+ }
+}
+} /* Non-standard indentation */
diff --git a/examples/java/com/wiredtiger/examples/ex_async.java b/examples/java/com/wiredtiger/examples/ex_async.java
new file mode 100644
index 00000000000..c6cb0550571
--- /dev/null
+++ b/examples/java/com/wiredtiger/examples/ex_async.java
@@ -0,0 +1,222 @@
+/*-
+ * Public Domain 2008-2014 WiredTiger, Inc.
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ex_async.java
+ * demonstrates how to use the asynchronous API.
+ */
+package com.wiredtiger.examples;
+import com.wiredtiger.db.*;
+import java.io.*;
+import java.util.*;
+
+/*! [async example callback implementation] */
+class AsyncKeys implements AsyncCallback {
+
+ public int numKeys = 0;
+
+ public AsyncKeys() {}
+
+ public void notifyError(String desc) {
+ System.err.println("ERROR: notify: " + desc);
+ }
+
+ public int notify(AsyncOp op, int opReturn, int flags) {
+ /*
+ * Note: we are careful not to throw any errors here. Any
+ * exceptions would be swallowed by a native worker thread.
+ */
+ int ret = 0;
+ try {
+ /*! [async get type] */
+ /* Retrieve the operation's type. */
+ AsyncOpType optype = op.getType();
+ /*! [async get type] */
+ /*! [async get identifier] */
+ /* Retrieve the operation's 64-bit identifier. */
+ long id = op.getId();
+ /*! [async get identifier] */
+
+ if (optype == AsyncOpType.WT_AOP_SEARCH) {
+ /*! [async get the operation's string key] */
+ String key = op.getKeyString();
+ /*! [async get the operation's string key] */
+ /*! [async get the operation's string value] */
+ String value = op.getValueString();
+ /*! [async get the operation's string value] */
+ synchronized (this) {
+ numKeys += 1;
+ }
+ System.out.println("Id " + id + " got record: " + key +
+ " : " + value);
+ }
+ else {
+ notifyError("unexpected optype");
+ ret = 1;
+ }
+ }
+ catch (Exception e) {
+ System.err.println("ERROR: exception in notify: " + e.toString() +
+ ", opreturn=" + opReturn);
+ ret = 1;
+ }
+ return (ret);
+ }
+}
+/*! [async example callback implementation] */
+
+public class ex_async {
+
+ public static String home;
+
+ public static final int MAX_KEYS = 15;
+
+ public static AsyncOp tryAsyncNewOp(Connection conn, String uri,
+ String config, AsyncCallback cb) throws WiredTigerException
+ {
+ WiredTigerException savedwte = null;
+
+ for (int tries = 0; tries < 10; tries++)
+ try {
+ return conn.async_new_op(uri, config, cb);
+ }
+ catch (WiredTigerException wte) {
+ /*
+ * If we used up all the handles, pause and retry to
+ * give the workers a chance to catch up.
+ */
+ System.err.println(
+ "asynchronous operation handle not available: " + wte);
+ savedwte = wte;
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException ie) {
+ /* not a big problem, continue to retry */
+ }
+ }
+
+ throw savedwte;
+ }
+
+ public static int
+ asyncExample()
+ throws WiredTigerException
+ {
+ AsyncOp op;
+ Connection conn;
+ Session session;
+ int i, ret;
+ String k[] = new String[MAX_KEYS];
+ String v[] = new String[MAX_KEYS];
+
+ /*! [async example callback implementation part 2] */
+ AsyncKeys asynciface = new AsyncKeys();
+ /*! [async example callback implementation part 2] */
+
+ /*! [async example connection] */
+ conn = wiredtiger.open(home, "create,cache_size=100MB," +
+ "async=(enabled=true,ops_max=20,threads=2)");
+ /*! [async example connection] */
+
+ /*! [async example table create] */
+ session = conn.open_session(null);
+ ret = session.create("table:async", "key_format=S,value_format=S");
+ /*! [async example table create] */
+
+ /* Insert a set of keys asynchronously. */
+ for (i = 0; i < MAX_KEYS; i++) {
+ /*! [async handle allocation] */
+ op = tryAsyncNewOp(conn, "table:async", null, asynciface);
+ /*! [async handle allocation] */
+
+ /*! [async insert] */
+ /*
+ * Set the operation's string key and value, and then do
+ * an asynchronous insert.
+ */
+ /*! [async set the operation's string key] */
+ k[i] = "key" + i;
+ op.putKeyString(k[i]);
+ /*! [async set the operation's string key] */
+
+ /*! [async set the operation's string value] */
+ v[i] = "value" + i;
+ op.putValueString(v[i]);
+ /*! [async set the operation's string value] */
+
+ ret = op.insert();
+ /*! [async insert] */
+ }
+
+ /*! [async flush] */
+ /* Wait for all outstanding operations to complete. */
+ ret = conn.async_flush();
+ /*! [async flush] */
+
+ /*! [async compaction] */
+ /*
+ * Compact a table asynchronously, limiting the run-time to 5 minutes.
+ */
+ op = tryAsyncNewOp(conn, "table:async", "timeout=300", asynciface);
+ ret = op.compact();
+ /*! [async compaction] */
+
+ /* Search for the keys we just inserted, asynchronously. */
+ for (i = 0; i < MAX_KEYS; i++) {
+ op = tryAsyncNewOp(conn, "table:async", null, asynciface);
+ /*! [async search] */
+ /*
+ * Set the operation's string key and value, and then do
+ * an asynchronous search.
+ */
+ k[i] = "key" + i;
+ op.putKeyString(k[i]);
+ ret = op.search();
+ /*! [async search] */
+ }
+
+ /*
+ * Connection close automatically does an async_flush so it will wait
+ * for all queued search operations to complete.
+ */
+ ret = conn.close(null);
+
+ System.out.println("Searched for " + asynciface.numKeys + " keys");
+
+ return (ret);
+ }
+
+ public static int
+ main(String[] argv)
+ {
+ try {
+ return (asyncExample());
+ }
+ catch (WiredTigerException wte) {
+ System.err.println("Exception: " + wte);
+ return (-1);
+ }
+ }
+}
diff --git a/examples/java/com/wiredtiger/examples/ex_call_center.java b/examples/java/com/wiredtiger/examples/ex_call_center.java
new file mode 100644
index 00000000000..553f63612bd
--- /dev/null
+++ b/examples/java/com/wiredtiger/examples/ex_call_center.java
@@ -0,0 +1,299 @@
+/*-
+ * Public Domain 2008-2014 WiredTiger, Inc.
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ex_call_center.java
+ * This is an example application that demonstrates how to map a
+ * moderately complex SQL application into WiredTiger.
+ */
+
+package com.wiredtiger.examples;
+import com.wiredtiger.db.*;
+import java.io.*;
+import java.util.*;
+
+/*! [call-center decl] */
+/*
+ * In SQL, the tables are described as follows:
+ *
+ * CREATE TABLE Customers(id INTEGER PRIMARY KEY,
+ * name VARCHAR(30), address VARCHAR(50), phone VARCHAR(15))
+ * CREATE INDEX CustomersPhone ON Customers(phone)
+ *
+ * CREATE TABLE Calls(id INTEGER PRIMARY KEY, call_date DATE,
+ * cust_id INTEGER, emp_id INTEGER, call_type VARCHAR(12),
+ * notes VARCHAR(25))
+ * CREATE INDEX CallsCustDate ON Calls(cust_id, call_date)
+ *
+ * In this example, both tables will use record numbers for their IDs, which
+ * will be the key. The C structs for the records are as follows.
+ */
+
+/* Customer records. */
+class Customer {
+ public long id;
+ public String name;
+ public String address;
+ public String phone;
+ public Customer(long id, String name, String address, String phone) {
+ this.id = id;
+ this.name = name;
+ this.address = address;
+ this.phone = phone;
+ }
+ public Customer() {}
+}
+
+/* Call records. */
+class Call {
+ public long id;
+ public long call_date;
+ public long cust_id;
+ public long emp_id;
+ public String call_type;
+ public String notes;
+ public Call(long id, long call_date, long cust_id, long emp_id,
+ String call_type, String notes) {
+ this.id = id;
+ this.call_date = call_date;
+ this.cust_id = cust_id;
+ this.emp_id = emp_id;
+ this.call_type = call_type;
+ this.notes = notes;
+ }
+ public Call() {}
+}
+/*! [call-center decl] */
+
+public class ex_call_center {
+
+ public static String home;
+
+ public static int
+ callCenterExample()
+ throws WiredTigerException
+ {
+ Connection conn;
+ Cursor cursor;
+ Session session;
+ int count, ret;
+ SearchStatus nearstatus;
+ List<Customer> custSample = new ArrayList<Customer>();
+ List<Call> callSample = new ArrayList<Call>();
+
+ custSample.add(new Customer(0, "Professor Oak",
+ "LeafGreen Avenue", "123-456-7890"));
+ custSample.add(new Customer(0, "Lorelei",
+ "Sevii Islands", "098-765-4321"));
+ callSample.add(new Call(0, 32, 1, 2, "billing", "unavailable"));
+ callSample.add(new Call(0, 33, 1, 2, "billing", "available"));
+ callSample.add(new Call(0, 34, 1, 2, "reminder", "unavailable"));
+ callSample.add(new Call(0, 35, 1, 2, "reminder", "available"));
+
+ /*
+ * Create a clean test directory for this run of the test program if the
+ * environment variable isn't already set (as is done by make check).
+ */
+ if (System.getenv("WIREDTIGER_HOME") == null) {
+ home = "WT_HOME";
+ try {
+ Process proc = Runtime.getRuntime().exec("/bin/rm -rf WT_HOME");
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(proc.getInputStream()));
+ while(br.ready())
+ System.out.println(br.readLine());
+ br.close();
+ new File("WT_HOME").mkdir();
+ } catch (IOException ioe) {
+ System.err.println("IOException: WT_HOME: " + ioe);
+ return(1);
+ }
+ } else
+ home = null;
+
+ try {
+ conn = wiredtiger.open(home, "create");
+ session = conn.open_session(null);
+ } catch (WiredTigerException wte) {
+ System.err.println("WiredTigerException: " + wte);
+ return(1);
+ }
+ /* Note: further error checking omitted for clarity. */
+
+ /*! [call-center work] */
+ /*
+ * Create the customers table, give names and types to the columns.
+ * The columns will be stored in two groups: "main" and "address",
+ * created below.
+ */
+ ret = session.create("table:customers",
+ "key_format=r," +
+ "value_format=SSS," +
+ "columns=(id,name,address,phone)," +
+ "colgroups=(main,address)");
+
+ /* Create the main column group with value columns except address. */
+ ret = session.create(
+ "colgroup:customers:main", "columns=(name,phone)");
+
+ /* Create the address column group with just the address. */
+ ret = session.create(
+ "colgroup:customers:address", "columns=(address)");
+
+ /* Create an index on the customer table by phone number. */
+ ret = session.create(
+ "index:customers:phone", "columns=(phone)");
+
+ /* Populate the customers table with some data. */
+ cursor = session.open_cursor("table:customers", null, "append");
+ for (Customer cust : custSample) {
+ cursor.putValueString(cust.name);
+ cursor.putValueString(cust.address);
+ cursor.putValueString(cust.phone);
+ ret = cursor.insert();
+ }
+ ret = cursor.close();
+
+ /*
+ * Create the calls table, give names and types to the columns. All the
+ * columns will be stored together, so no column groups are declared.
+ */
+ ret = session.create("table:calls",
+ "key_format=r," +
+ "value_format=qrrSS," +
+ "columns=(id,call_date,cust_id,emp_id,call_type,notes)");
+
+ /*
+ * Create an index on the calls table with a composite key of cust_id
+ * and call_date.
+ */
+ ret = session.create("index:calls:cust_date",
+ "columns=(cust_id,call_date)");
+
+ /* Populate the calls table with some data. */
+ cursor = session.open_cursor("table:calls", null, "append");
+ for (Call call : callSample) {
+ cursor.putValueLong(call.call_date);
+ cursor.putValueLong(call.cust_id);
+ cursor.putValueLong(call.emp_id);
+ cursor.putValueString(call.call_type);
+ cursor.putValueString(call.notes);
+ ret = cursor.insert();
+ }
+ ret = cursor.close();
+
+ /*
+ * First query: a call arrives. In SQL:
+ *
+ * SELECT id, name FROM Customers WHERE phone=?
+ *
+ * Use the cust_phone index, lookup by phone number to fill the
+ * customer record. The cursor will have a key format of "S" for a
+ * string because the cust_phone index has a single column ("phone"),
+ * which is of type "S".
+ *
+ * Specify the columns we want: the customer ID and the name. This
+ * means the cursor's value format will be "rS".
+ */
+ cursor = session.open_cursor(
+ "index:customers:phone(id,name)", null, null);
+ cursor.putKeyString("123-456-7890");
+ ret = cursor.search();
+ if (ret == 0) {
+ Customer cust = new Customer();
+ cust.id = cursor.getValueLong();
+ cust.name = cursor.getValueString();
+ System.out.println("Read customer record for " + cust.name +
+ " (ID " + cust.id + ")");
+ }
+ ret = cursor.close();
+
+ /*
+ * Next query: get the recent order history. In SQL:
+ *
+ * SELECT * FROM Calls WHERE cust_id=? ORDER BY call_date DESC LIMIT 3
+ *
+ * Use the call_cust_date index to find the matching calls. Since it is
+ * is in increasing order by date for a given customer, we want to start
+ * with the last record for the customer and work backwards.
+ *
+ * Specify a subset of columns to be returned. (Note that if these were
+ * all covered by the index, the primary would not have to be accessed.)
+ * Stop after getting 3 records.
+ */
+ cursor = session.open_cursor(
+ "index:calls:cust_date(cust_id,call_type,notes)",
+ null, null);
+
+ /*
+ * The keys in the index are (cust_id,call_date) -- we want the largest
+ * call date for a given cust_id. Search for (cust_id+1,0), then work
+ * backwards.
+ */
+ long custid = 1;
+ cursor.putKeyLong(custid + 1);
+ cursor.putKeyLong(0);
+ nearstatus = cursor.search_near();
+
+ /*
+ * If the table is empty, search_near will return WT_NOTFOUND, else the
+ * cursor will be positioned on a matching key if one exists, or an
+ * adjacent key if one does not. If the positioned key is equal to or
+ * larger than the search key, go back one.
+ */
+ if (ret == 0 && (nearstatus == SearchStatus.LARGER ||
+ nearstatus == SearchStatus.FOUND))
+ ret = cursor.prev();
+ for (count = 0; ret == 0 && count < 3; ++count) {
+ Call call = new Call();
+ call.cust_id = cursor.getValueLong();
+ call.call_type = cursor.getValueString();
+ call.notes = cursor.getValueString();
+ if (call.cust_id != custid)
+ break;
+ System.out.println("Call record: customer " + call.cust_id +
+ " (" + call.call_type +
+ ": " + call.notes + ")");
+ ret = cursor.prev();
+ }
+ /*! [call-center work] */
+
+ ret = conn.close(null);
+
+ return (ret);
+ }
+
+ public static int
+ main(String[] argv)
+ {
+ try {
+ return (callCenterExample());
+ }
+ catch (WiredTigerException wte) {
+ System.err.println("Exception: " + wte);
+ return (-1);
+ }
+ }
+}
diff --git a/examples/java/com/wiredtiger/examples/ex_cursor.java b/examples/java/com/wiredtiger/examples/ex_cursor.java
new file mode 100644
index 00000000000..7b8de7739d2
--- /dev/null
+++ b/examples/java/com/wiredtiger/examples/ex_cursor.java
@@ -0,0 +1,239 @@
+/*-
+ * Public Domain 2008-2014 WiredTiger, Inc.
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ex_cursor.java
+ * This is an example demonstrating some cursor types and operations.
+ */
+
+package com.wiredtiger.examples;
+import com.wiredtiger.db.*;
+import java.io.*;
+import java.util.*;
+
+public class ex_cursor {
+
+ public static String home;
+
+ /*! [cursor next] */
+ public static int
+ cursor_forward_scan(Cursor cursor)
+ throws WiredTigerException
+ {
+ String key, value;
+ int ret;
+
+ while ((ret = cursor.next()) == 0) {
+ key = cursor.getKeyString();
+ value = cursor.getValueString();
+ }
+ return (ret);
+ }
+ /*! [cursor next] */
+
+ /*! [cursor prev] */
+ public static int
+ cursor_reverse_scan(Cursor cursor)
+ throws WiredTigerException
+ {
+ String key, value;
+ int ret;
+
+ while ((ret = cursor.prev()) == 0) {
+ key = cursor.getKeyString();
+ value = cursor.getValueString();
+ }
+ return (ret);
+ }
+ /*! [cursor prev] */
+
+ /*! [cursor reset] */
+ public static int
+ cursor_reset(Cursor cursor)
+ throws WiredTigerException
+ {
+ return (cursor.reset());
+ }
+ /*! [cursor reset] */
+
+ /*! [cursor search] */
+ public static int
+ cursor_search(Cursor cursor)
+ throws WiredTigerException
+ {
+ String value;
+ int ret;
+
+ cursor.putKeyString("foo");
+
+ if ((ret = cursor.search()) != 0)
+ value = cursor.getValueString();
+
+ return (ret);
+ }
+ /*! [cursor search] */
+
+ /*! [cursor search near] */
+ public static int
+ cursor_search_near(Cursor cursor)
+ throws WiredTigerException
+ {
+ String key, value;
+ SearchStatus exact;
+
+ key = "foo";
+ cursor.putKeyString(key);
+
+ exact = cursor.search_near();
+ if (exact == SearchStatus.SMALLER)
+ /* Returned key smaller than search key */
+ key = cursor.getKeyString();
+ else if (exact == SearchStatus.LARGER)
+ /* Returned key larger than search key */
+ key = cursor.getKeyString();
+ /* Else exact match found, and key already set */
+
+ value = cursor.getValueString();
+
+ return (0);
+ }
+ /*! [cursor search near] */
+
+ /*! [cursor insert] */
+ public static int
+ cursor_insert(Cursor cursor)
+ throws WiredTigerException
+ {
+ cursor.putKeyString("foo");
+ cursor.putValueString("bar");
+
+ return (cursor.insert());
+ }
+ /*! [cursor insert] */
+
+ /*! [cursor update] */
+ public static int
+ cursor_update(Cursor cursor)
+ throws WiredTigerException
+ {
+ cursor.putKeyString("foo");
+ cursor.putValueString("newbar");
+
+ return (cursor.update());
+ }
+ /*! [cursor update] */
+
+ /*! [cursor remove] */
+ public static int
+ cursor_remove(Cursor cursor)
+ throws WiredTigerException
+ {
+ cursor.putKeyString("foo");
+ return (cursor.remove());
+ }
+ /*! [cursor remove] */
+
+ public static int
+ cursorExample()
+ throws WiredTigerException
+ {
+ Connection conn;
+ Cursor cursor;
+ Session session;
+ int ret;
+
+ /*
+ * Create a clean test directory for this run of the test program if the
+ * environment variable isn't already set (as is done by make check).
+ */
+ if (System.getenv("WIREDTIGER_HOME") == null) {
+ home = "WT_HOME";
+ try {
+ Process proc = Runtime.getRuntime().exec("/bin/rm -rf WT_HOME");
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(proc.getInputStream()));
+ while(br.ready())
+ System.out.println(br.readLine());
+ br.close();
+ new File("WT_HOME").mkdir();
+ } catch (IOException ioe) {
+ System.err.println("IOException: WT_HOME: " + ioe);
+ return(1);
+ }
+ } else
+ home = null;
+
+ conn = wiredtiger.open(home, "create,statistics=(fast)");
+ session = conn.open_session(null);
+
+ ret = session.create("table:world",
+ "key_format=r,value_format=5sii," +
+ "columns=(id,country,population,area)");
+
+ /*! [open cursor #1] */
+ cursor = session.open_cursor("table:world", null, null);
+ /*! [open cursor #1] */
+
+ /*! [open cursor #2] */
+ cursor = session.open_cursor("table:world(country,population)", null, null);
+ /*! [open cursor #2] */
+
+ /*! [open cursor #3] */
+ cursor = session.open_cursor("statistics:", null, null);
+ /*! [open cursor #3] */
+
+ /* Create a simple string table to illustrate basic operations. */
+ ret = session.create("table:map", "key_format=S,value_format=S");
+ cursor = session.open_cursor("table:map", null, null);
+ ret = cursor_insert(cursor);
+ ret = cursor_reset(cursor);
+ ret = cursor_forward_scan(cursor);
+ ret = cursor_reset(cursor);
+ ret = cursor_reverse_scan(cursor);
+ ret = cursor_search_near(cursor);
+ ret = cursor_update(cursor);
+ ret = cursor_remove(cursor);
+ ret = cursor.close();
+
+ /* Note: closing the connection implicitly closes open session(s). */
+ if ((ret = conn.close(null)) != 0)
+ System.err.println("Error connecting to " + home + ": " +
+ wiredtiger.wiredtiger_strerror(ret));
+
+ return (ret);
+ }
+
+ public static int
+ main(String[] argv)
+ {
+ try {
+ return (cursorExample());
+ }
+ catch (WiredTigerException wte) {
+ System.err.println("Exception: " + wte);
+ return (-1);
+ }
+ }
+}
diff --git a/examples/java/com/wiredtiger/examples/ex_log.java b/examples/java/com/wiredtiger/examples/ex_log.java
new file mode 100644
index 00000000000..d7bc6987878
--- /dev/null
+++ b/examples/java/com/wiredtiger/examples/ex_log.java
@@ -0,0 +1,376 @@
+/*-
+ * Public Domain 2008-2014 WiredTiger, Inc.
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ex_log.java
+ * demonstrates how to logging and log cursors.
+ */
+package com.wiredtiger.examples;
+import com.wiredtiger.db.*;
+import java.io.*;
+import java.util.*;
+
+class Lsn {
+ int file;
+ long offset;
+}
+
+public class ex_log {
+
+ public static String home1 = "WT_HOME_LOG_1";
+ public static String home2 = "WT_HOME_LOG_2";
+ public static String uri = "table:logtest";
+
+ public static final String CONN_CONFIG =
+ "create,cache_size=100MB,log=(archive=false,enabled=true)";
+ public static final int MAX_KEYS = 10;
+
+ static Session
+ setup_copy()
+ throws WiredTigerException
+ {
+ int ret = 0;
+ Connection conn;
+
+ conn = wiredtiger.open(home2, CONN_CONFIG);
+ Session session = conn.open_session(null);
+ session.create(uri, "key_format=S,value_format=S");
+ return (session);
+ }
+
+ static int
+ compare_tables(Session session, Session sess_copy)
+ throws WiredTigerException
+ {
+ int ret;
+
+ Cursor cursor = session.open_cursor(uri, null, null);
+ Cursor curs_copy = sess_copy.open_cursor(uri, null, null);
+
+ while ((ret = cursor.next()) == 0) {
+ ret = curs_copy.next();
+ String key = cursor.getKeyString();
+ String value = cursor.getValueString();
+ String key_copy = curs_copy.getKeyString();
+ String value_copy = curs_copy.getValueString();
+ if (!key.equals(key_copy) || !value.equals(value_copy)) {
+ System.err.println(
+ "Mismatched: key " + key +
+ ", key_copy " + key_copy +
+ " value " + value +
+ " value_copy " + value_copy);
+ return (1);
+ }
+ }
+ if (ret != wiredtiger.WT_NOTFOUND)
+ System.err.println("WT_CURSOR.next: " +
+ wiredtiger.wiredtiger_strerror(ret));
+ ret = cursor.close();
+
+ ret = curs_copy.next();
+ if (ret != wiredtiger.WT_NOTFOUND)
+ System.err.println("WT_CURSOR.next: " +
+ wiredtiger.wiredtiger_strerror(ret));
+ ret = curs_copy.close();
+
+ return (ret);
+ }
+
+ /*! [log cursor walk] */
+ static void
+ print_record(Lsn lsn, int opcount,
+ int rectype, int optype, long txnid, int fileid,
+ byte[] key, byte[] value)
+ {
+ System.out.print(
+ "LSN [" + lsn.file + "][" + lsn.offset + "]." + opcount +
+ ": record type " + rectype + " optype " + optype +
+ " txnid " + txnid + " fileid " + fileid);
+ System.out.println(" key size " + key.length +
+ "value size " + value.length);
+ if (rectype == wiredtiger.WT_LOGREC_MESSAGE)
+ System.out.println("Application Record: " + new String(value));
+ }
+
+ /*
+ * simple_walk_log --
+ * A simple walk of the log.
+ */
+ static int
+ simple_walk_log(Session session)
+ throws WiredTigerException
+ {
+ Cursor cursor;
+ Lsn lsn = new Lsn();
+ byte[] logrec_key, logrec_value;
+ long txnid;
+ int fileid, opcount, optype, rectype;
+ int ret;
+
+ /*! [log cursor open] */
+ cursor = session.open_cursor("log:", null, null);
+ /*! [log cursor open] */
+
+ while ((ret = cursor.next()) == 0) {
+ /*! [log cursor get_key] */
+ lsn.file = cursor.getKeyInt();
+ lsn.offset = cursor.getKeyLong();
+ opcount = cursor.getKeyInt();
+ /*! [log cursor get_key] */
+ /*! [log cursor get_value] */
+ txnid = cursor.getValueLong();
+ rectype = cursor.getValueInt();
+ optype = cursor.getValueInt();
+ fileid = cursor.getValueInt();
+ logrec_key = cursor.getValueByteArray();
+ logrec_value = cursor.getValueByteArray();
+ /*! [log cursor get_value] */
+
+ print_record(lsn, opcount,
+ rectype, optype, txnid, fileid, logrec_key, logrec_value);
+ }
+ if (ret == wiredtiger.WT_NOTFOUND)
+ ret = 0;
+ ret = cursor.close();
+ return (ret);
+ }
+ /*! [log cursor walk] */
+
+ static int
+ walk_log(Session session)
+ throws WiredTigerException
+ {
+ Connection wt_conn2;
+ Cursor cursor, cursor2;
+ Lsn lsn, lsnsave;
+ byte[] logrec_key, logrec_value;
+ Session session2;
+ long txnid;
+ int fileid, opcount, optype, rectype;
+ int i, ret;
+ boolean in_txn, first;
+
+ session2 = setup_copy();
+ wt_conn2 = session2.getConnection();
+ cursor = session.open_cursor("log:", null, null);
+ cursor2 = session2.open_cursor(uri, null, "raw=true");
+ i = 0;
+ in_txn = false;
+ txnid = 0;
+ lsn = new Lsn();
+ lsnsave = new Lsn();
+ while ((ret = cursor.next()) == 0) {
+ lsn.file = cursor.getKeyInt();
+ lsn.offset = cursor.getKeyLong();
+ opcount = cursor.getKeyInt();
+
+ /*
+ * Save one of the LSNs we get back to search for it
+ * later. Pick a later one because we want to walk from
+ * that LSN to the end (where the multi-step transaction
+ * was performed). Just choose the record that is MAX_KEYS.
+ */
+ if (++i == MAX_KEYS)
+ lsnsave = lsn;
+ txnid = cursor.getValueLong();
+ rectype = cursor.getValueInt();
+ optype = cursor.getValueInt();
+ fileid = cursor.getValueInt();
+ logrec_key = cursor.getValueByteArray();
+ logrec_value = cursor.getValueByteArray();
+
+ print_record(lsn, opcount,
+ rectype, optype, txnid, fileid, logrec_key, logrec_value);
+
+ /*
+ * If we are in a transaction and this is a new one, end
+ * the previous one.
+ */
+ if (in_txn && opcount == 0) {
+ ret = session2.commit_transaction(null);
+ in_txn = false;
+ }
+
+ /*
+ * If the operation is a put, replay it here on the backup
+ * connection. Note, we cheat by looking only for fileid 1
+ * in this example. The metadata is fileid 0.
+ */
+ if (fileid == 1 && rectype == wiredtiger.WT_LOGREC_COMMIT &&
+ optype == wiredtiger.WT_LOGOP_ROW_PUT) {
+ if (!in_txn) {
+ ret = session2.begin_transaction(null);
+ in_txn = true;
+ }
+ cursor2.putKeyByteArray(logrec_key);
+ cursor2.putValueByteArray(logrec_value);
+ ret = cursor2.insert();
+ }
+ }
+ if (in_txn)
+ ret = session2.commit_transaction(null);
+
+ ret = cursor2.close();
+ /*
+ * Compare the tables after replay. They should be identical.
+ */
+ if (compare_tables(session, session2) != 0)
+ System.out.println("compare failed");
+ ret = session2.close(null);
+ ret = wt_conn2.close(null);
+
+ ret = cursor.reset();
+ /*! [log cursor set_key] */
+ cursor.putKeyInt(lsnsave.file);
+ cursor.putKeyLong(lsnsave.offset);
+ /*! [log cursor set_key] */
+ /*! [log cursor search] */
+ ret = cursor.search();
+ /*! [log cursor search] */
+ System.out.println("Reset to saved...");
+ /*
+ * Walk all records starting with this key.
+ */
+ first = true;
+ while (ret == 0) { /*TODO: not quite right*/
+ lsn.file = cursor.getKeyInt();
+ lsn.offset = cursor.getKeyLong();
+ opcount = cursor.getKeyInt();
+ if (first) {
+ first = false;
+ if (lsnsave.file != lsn.file ||
+ lsnsave.offset != lsn.offset) {
+ System.err.println("search returned the wrong LSN");
+ System.exit(1);
+ }
+ }
+ txnid = cursor.getValueLong();
+ rectype = cursor.getValueInt();
+ optype = cursor.getValueInt();
+ fileid = cursor.getValueInt();
+ logrec_key = cursor.getValueByteArray();
+ logrec_value = cursor.getValueByteArray();
+
+ print_record(lsn, opcount, rectype, optype, txnid,
+ fileid, logrec_key, logrec_value);
+
+ ret = cursor.next();
+ if (ret != 0)
+ break;
+ }
+ ret = cursor.close();
+ return (ret);
+ }
+
+ public static int
+ logExample()
+ throws WiredTigerException
+ {
+ Connection wt_conn;
+ Cursor cursor;
+ Session session;
+ int i, record_count, ret;
+
+ try {
+ String command = "/bin/rm -rf " + home1 + " " + home2;
+ Process proc = Runtime.getRuntime().exec(command);
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(proc.getInputStream()));
+ while(br.ready())
+ System.out.println(br.readLine());
+ br.close();
+ new File(home1).mkdir();
+ new File(home2).mkdir();
+ } catch (IOException ioe) {
+ System.err.println("IOException: " + ioe);
+ return (1);
+ }
+ if ((wt_conn = wiredtiger.open(home1, CONN_CONFIG)) == null) {
+ System.err.println("Error connecting to " + home1);
+ return (1);
+ }
+
+ session = wt_conn.open_session(null);
+ ret = session.create(uri, "key_format=S,value_format=S");
+
+ cursor = session.open_cursor(uri, null, null);
+ /*
+ * Perform some operations with individual auto-commit transactions.
+ */
+ for (record_count = 0, i = 0; i < MAX_KEYS; i++, record_count++) {
+ String k = "key" + i;
+ String v = "value" + i;
+ cursor.putKeyString(k);
+ cursor.putValueString(v);
+ ret = cursor.insert();
+ }
+ ret = session.begin_transaction(null);
+ /*
+ * Perform some operations within a single transaction.
+ */
+ for (i = MAX_KEYS; i < MAX_KEYS+5; i++, record_count++) {
+ String k = "key" + i;
+ String v = "value" + i;
+ cursor.putKeyString(k);
+ cursor.putValueString(v);
+ ret = cursor.insert();
+ }
+ ret = session.commit_transaction(null);
+ ret = cursor.close();
+
+ /*! [log cursor printf] */
+ ret = session.log_printf("Wrote " + record_count + " records");
+ /*! [log cursor printf] */
+
+ /*
+ * Close and reopen the connection so that the log ends up with
+ * a variety of records such as file sync and checkpoint. We
+ * have archiving turned off.
+ */
+ ret = wt_conn.close(null);
+ if ((wt_conn = wiredtiger.open(home1, CONN_CONFIG)) == null) {
+ System.err.println("Error connecting to " + home1);
+ return (ret);
+ }
+
+ session = wt_conn.open_session(null);
+ ret = simple_walk_log(session);
+ ret = walk_log(session);
+ ret = wt_conn.close(null);
+ return (ret);
+ }
+
+ public static int
+ main()
+ {
+ try {
+ return (logExample());
+ }
+ catch (WiredTigerException wte) {
+ System.err.println("Exception: " + wte);
+ return (-1);
+ }
+ }
+}
diff --git a/examples/java/com/wiredtiger/examples/ex_schema.java b/examples/java/com/wiredtiger/examples/ex_schema.java
new file mode 100644
index 00000000000..9b84912e0f0
--- /dev/null
+++ b/examples/java/com/wiredtiger/examples/ex_schema.java
@@ -0,0 +1,333 @@
+/*-
+ * Public Domain 2008-2014 WiredTiger, Inc.
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ex_schema.java
+ * This is an example application demonstrating how to create and access
+ * tables using a schema.
+ */
+package com.wiredtiger.examples;
+import com.wiredtiger.db.*;
+import java.io.*;
+import java.util.*;
+
+public class ex_schema {
+
+ public static String home;
+
+ /*! [schema declaration] */
+ /* The class for the data we are storing in a WiredTiger table. */
+ static class PopRecord {
+ public String country; // Stored in database as fixed size char[5];
+ public short year;
+ public long population;
+ public PopRecord(String country, short year, long population) {
+ this.country = country;
+ this.year = year;
+ this.population = population;
+ }
+ }
+
+ static List<PopRecord> popData;
+
+ static {
+ popData = new ArrayList<PopRecord>();
+
+ popData.add(new PopRecord("AU", (short)1900, 4000000 ));
+ popData.add(new PopRecord("AU", (short)2000, 19053186 ));
+ popData.add(new PopRecord("CAN", (short)1900, 5500000 ));
+ popData.add(new PopRecord("CAN", (short)2000, 31099561 ));
+ popData.add(new PopRecord("UK", (short)1900, 369000000 ));
+ popData.add(new PopRecord("UK", (short)2000, 59522468 ));
+ popData.add(new PopRecord("USA", (short)1900, 76212168 ));
+ popData.add(new PopRecord("USA", (short)2000, 301279593 ));
+ };
+ /*! [schema declaration] */
+
+ public static int
+ schemaExample()
+ throws WiredTigerException
+ {
+ Connection conn;
+ Cursor cursor;
+ Session session;
+ String country;
+ long recno, population;
+ short year;
+ int ret;
+
+ /*
+ * Create a clean test directory for this run of the test program if the
+ * environment variable isn't already set (as is done by make check).
+ */
+ if (System.getenv("WIREDTIGER_HOME") == null) {
+ home = "WT_HOME";
+ try {
+ Process proc = Runtime.getRuntime().exec("/bin/rm -rf WT_HOME");
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(proc.getInputStream()));
+ while(br.ready())
+ System.out.println(br.readLine());
+ br.close();
+ new File("WT_HOME").mkdir();
+ } catch (IOException ioe) {
+ System.err.println("IOException: WT_HOME: " + ioe);
+ return(1);
+ }
+ } else
+ home = null;
+
+ try {
+ conn = wiredtiger.open(home, "create");
+ session = conn.open_session(null);
+ } catch (WiredTigerException wte) {
+ System.err.println("WiredTigerException: " + wte);
+ return(1);
+ }
+
+ /*! [Create a table with column groups] */
+ /*
+ * Create the population table.
+ * Keys are record numbers, the format for values is (5-byte string,
+ * long, long).
+ * See ::wiredtiger_struct_pack for details of the format strings.
+ */
+ ret = session.create("table:poptable",
+ "key_format=r,value_format=5sHQ," +
+ "columns=(id,country,year,population),colgroups=(main,population)");
+
+ /*
+ * Create two column groups: a primary column group with the country
+ * code, year and population (named "main"), and a population column
+ * group with the population by itself (named "population").
+ */
+ ret = session.create("colgroup:poptable:main",
+ "columns=(country,year,population)");
+ ret = session.create("colgroup:poptable:population",
+ "columns=(population)");
+ /*! [Create a table with column groups] */
+
+ /*! [Create an index] */
+ /* Create an index with a simple key. */
+ ret = session.create("index:poptable:country",
+ "columns=(country)");
+ /*! [Create an index] */
+
+ /*! [Create an index with a composite key] */
+ /* Create an index with a composite key (country,year). */
+ ret = session.create("index:poptable:country_plus_year",
+ "columns=(country,year)");
+ /*! [Create an index with a composite key] */
+
+ /*! [Insert and list records] */
+ /* Insert the records into the table. */
+ cursor = session.open_cursor("table:poptable", null, "append");
+ for (PopRecord p : popData) {
+ cursor.putValueString(p.country);
+ cursor.putValueShort(p.year);
+ cursor.putValueLong(p.population);
+ ret = cursor.insert();
+ }
+ ret = cursor.close();
+
+ /* List the records in the table. */
+ cursor = session.open_cursor("table:poptable", null, null);
+ while ((ret = cursor.next()) == 0) {
+ recno = cursor.getKeyLong();
+ country = cursor.getValueString();
+ year = cursor.getValueShort();
+ population = cursor.getValueLong();
+ System.out.print("ID " + recno);
+ System.out.println(": country " + country + ", year " + year +
+ ", population " + population);
+ }
+ ret = cursor.close();
+ /*! [Insert and list records] */
+
+ /*! [List the records in the table using raw mode.] */
+ cursor = session.open_cursor("table:poptable", null, "raw");
+ while ((ret = cursor.next()) == 0) {
+ byte[] key, value;
+
+ key = cursor.getKeyByteArray();
+ System.out.println(Arrays.toString(key));
+ value = cursor.getValueByteArray();
+ System.out.println("raw key: " + Arrays.toString(key) +
+ ", raw value: " + Arrays.toString(value));
+ }
+ /*! [List the records in the table using raw mode.] */
+
+ /*! [Read population from the primary column group] */
+ /*
+ * Open a cursor on the main column group, and return the information
+ * for a particular country.
+ */
+ cursor = session.open_cursor("colgroup:poptable:main", null, null);
+ cursor.putKeyLong(2);
+ if ((ret = cursor.search()) == 0) {
+ country = cursor.getValueString();
+ year = cursor.getValueShort();
+ population = cursor.getValueLong();
+ System.out.println("ID 2: country " + country +
+ ", year " + year + ", population " + population);
+ }
+ /*! [Read population from the primary column group] */
+ ret = cursor.close();
+
+ /*! [Read population from the standalone column group] */
+ /*
+ * Open a cursor on the population column group, and return the
+ * population of a particular country.
+ */
+ cursor = session.open_cursor("colgroup:poptable:population", null, null);
+ cursor.putKeyLong(2);
+ if ((ret = cursor.search()) == 0) {
+ population = cursor.getValueLong();
+ System.out.println("ID 2: population " + population);
+ }
+ /*! [Read population from the standalone column group] */
+ ret = cursor.close();
+
+ /*! [Search in a simple index] */
+ /* Search in a simple index. */
+ cursor = session.open_cursor("index:poptable:country", null, null);
+ cursor.putKeyString("AU");
+ ret = cursor.search();
+ country = cursor.getValueString();
+ year = cursor.getValueShort();
+ population = cursor.getValueLong();
+ System.out.println("AU: country " + country + ", year " + year +
+ ", population " + population);
+ /*! [Search in a simple index] */
+ ret = cursor.close();
+
+ /*! [Search in a composite index] */
+ /* Search in a composite index. */
+ cursor = session.open_cursor(
+ "index:poptable:country_plus_year", null, null);
+ cursor.putKeyString("USA");
+ cursor.putKeyShort((short)1900);
+ ret = cursor.search();
+ country = cursor.getValueString();
+ year = cursor.getValueShort();
+ population = cursor.getValueLong();
+ System.out.println("US 1900: country " + country +
+ ", year " + year + ", population " + population);
+ /*! [Search in a composite index] */
+ ret = cursor.close();
+
+ /*! [Return a subset of values from the table] */
+ /*
+ * Use a projection to return just the table's country and year
+ * columns.
+ */
+ cursor = session.open_cursor("table:poptable(country,year)", null, null);
+ while ((ret = cursor.next()) == 0) {
+ country = cursor.getValueString();
+ year = cursor.getValueShort();
+ System.out.println("country " + country + ", year " + year);
+ }
+ /*! [Return a subset of values from the table] */
+ ret = cursor.close();
+
+ /*! [Return a subset of values from the table using raw mode] */
+ /*
+ * Use a projection to return just the table's country and year
+ * columns.
+ */
+ cursor = session.open_cursor("table:poptable(country,year)", null, null);
+ while ((ret = cursor.next()) == 0) {
+ country = cursor.getValueString();
+ year = cursor.getValueShort();
+ System.out.println("country " + country + ", year " + year);
+ }
+ /*! [Return a subset of values from the table using raw mode] */
+ ret = cursor.close();
+
+ /*! [Return the table's record number key using an index] */
+ /*
+ * Use a projection to return just the table's record number key
+ * from an index.
+ */
+ cursor = session.open_cursor("index:poptable:country_plus_year(id)", null, null);
+ while ((ret = cursor.next()) == 0) {
+ country = cursor.getKeyString();
+ year = cursor.getKeyShort();
+ recno = cursor.getValueLong();
+ System.out.println("row ID " + recno + ": country " + country +
+ ", year " + year);
+ }
+ /*! [Return the table's record number key using an index] */
+ ret = cursor.close();
+
+ /*! [Return a subset of the value columns from an index] */
+ /*
+ * Use a projection to return just the population column from an
+ * index.
+ */
+ cursor = session.open_cursor(
+ "index:poptable:country_plus_year(population)", null, null);
+ while ((ret = cursor.next()) == 0) {
+ country = cursor.getKeyString();
+ year = cursor.getKeyShort();
+ population = cursor.getValueLong();
+ System.out.println("population " + population +
+ ": country " + country + ", year " + year);
+ }
+ /*! [Return a subset of the value columns from an index] */
+ ret = cursor.close();
+
+ /*! [Access only the index] */
+ /*
+ * Use a projection to avoid accessing any other column groups when
+ * using an index: supply an empty list of value columns.
+ */
+ cursor = session.open_cursor(
+ "index:poptable:country_plus_year()", null, null);
+ while ((ret = cursor.next()) == 0) {
+ country = cursor.getKeyString();
+ year = cursor.getKeyShort();
+ System.out.println("country " + country + ", year " + year);
+ }
+ /*! [Access only the index] */
+ ret = cursor.close();
+
+ ret = conn.close(null);
+
+ return (ret);
+ }
+
+ public static int
+ main(String[] argv)
+ {
+ try {
+ return (schemaExample());
+ }
+ catch (WiredTigerException wte) {
+ System.err.println("Exception: " + wte);
+ return (-1);
+ }
+ }
+}
diff --git a/examples/java/com/wiredtiger/examples/ex_stat.java b/examples/java/com/wiredtiger/examples/ex_stat.java
new file mode 100644
index 00000000000..c81bb64c22a
--- /dev/null
+++ b/examples/java/com/wiredtiger/examples/ex_stat.java
@@ -0,0 +1,252 @@
+/*-
+ * Public Domain 2008-2014 WiredTiger, Inc.
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ex_stat.java
+ * This is an example demonstrating how to query database statistics.
+ */
+package com.wiredtiger.examples;
+import com.wiredtiger.db.*;
+import java.io.*;
+import java.util.*;
+
+public class ex_stat {
+
+ public static String home;
+
+ /*! [statistics display function] */
+ int
+ print_cursor(Cursor cursor)
+ throws WiredTigerException
+ {
+ String desc, pvalue;
+ long value;
+ int ret;
+
+ while ((ret = cursor.next()) == 0) {
+ desc = cursor.getValueString();
+ pvalue = cursor.getValueString();
+ value = cursor.getValueLong();
+ if (value != 0)
+ System.out.println(desc + "=" + pvalue);
+ }
+
+ return (ret == wiredtiger.WT_NOTFOUND ? 0 : ret);
+ }
+ /*! [statistics display function] */
+
+ int
+ print_database_stats(Session session)
+ throws WiredTigerException
+ {
+ Cursor cursor;
+ int ret;
+
+ /*! [statistics database function] */
+ cursor = session.open_cursor("statistics:", null, null);
+
+ ret = print_cursor(cursor);
+ ret = cursor.close();
+ /*! [statistics database function] */
+
+ return (ret);
+ }
+
+ int
+ print_file_stats(Session session)
+ throws WiredTigerException
+ {
+ Cursor cursor;
+ int ret;
+
+ /*! [statistics table function] */
+ cursor = session.open_cursor("statistics:table:access", null, null);
+ ret = print_cursor(cursor);
+ ret = cursor.close();
+ /*! [statistics table function] */
+
+ return (ret);
+ }
+
+ int
+ print_overflow_pages(Session session)
+ throws WiredTigerException
+ {
+ /*! [statistics retrieve by key] */
+ Cursor cursor;
+ String desc, pvalue;
+ long value;
+ int ret;
+
+ cursor = session.open_cursor("statistics:table:access", null, null);
+
+ cursor.putKeyInt(wiredtiger.WT_STAT_DSRC_BTREE_OVERFLOW);
+ ret = cursor.search();
+ desc = cursor.getValueString();
+ pvalue = cursor.getValueString();
+ value = cursor.getValueLong();
+ System.out.println(desc + "=" + pvalue);
+
+ ret = cursor.close();
+ /*! [statistics retrieve by key] */
+
+ return (ret);
+ }
+
+ /*! [statistics calculation helper function] */
+ long
+ get_stat(Cursor cursor, int stat_field)
+ throws WiredTigerException
+ {
+ long value;
+ int ret;
+
+ cursor.putKeyInt(stat_field);
+ if ((ret = cursor.search()) != 0) {
+ System.err.println("stat_field: " + stat_field + " not found");
+ value = 0;
+ }
+ else {
+ String desc = cursor.getValueString();
+ String pvalue = cursor.getValueString();
+ value = cursor.getValueLong();
+ }
+ return (value);
+ }
+ /*! [statistics calculation helper function] */
+
+ int
+ print_derived_stats(Session session)
+ throws WiredTigerException
+ {
+ Cursor cursor;
+ int ret;
+
+ /*! [statistics calculate open table stats] */
+ cursor = session.open_cursor("statistics:table:access", null, null);
+ /*! [statistics calculate open table stats] */
+
+ {
+ /*! [statistics calculate table fragmentation] */
+ long ckpt_size = get_stat(cursor,
+ wiredtiger.WT_STAT_DSRC_BLOCK_CHECKPOINT_SIZE);
+ long file_size = get_stat(cursor,
+ wiredtiger.WT_STAT_DSRC_BLOCK_SIZE);
+
+ System.out.println("File is " +
+ (int)(100 * (file_size - ckpt_size) / file_size) +
+ "% fragmented\n");
+ /*! [statistics calculate table fragmentation] */
+ }
+
+ {
+ /*! [statistics calculate write amplification] */
+ long app_insert = get_stat(cursor,
+ wiredtiger.WT_STAT_DSRC_CURSOR_INSERT_BYTES);
+ long app_remove = get_stat(cursor,
+ wiredtiger.WT_STAT_DSRC_CURSOR_REMOVE_BYTES);
+ long app_update = get_stat(cursor,
+ wiredtiger.WT_STAT_DSRC_CURSOR_UPDATE_BYTES);
+
+ long fs_writes = get_stat(cursor,
+ wiredtiger.WT_STAT_DSRC_CACHE_BYTES_WRITE);
+
+ if (app_insert + app_remove + app_update != 0)
+ System.out.println("Write amplification is " +
+ (double)fs_writes / (app_insert + app_remove + app_update));
+ /*! [statistics calculate write amplification] */
+ }
+
+ ret = cursor.close();
+
+ return (ret);
+ }
+
+ public int
+ statExample()
+ throws WiredTigerException
+ {
+ Connection conn;
+ Cursor cursor;
+ Session session;
+ int ret;
+
+ /*
+ * Create a clean test directory for this run of the test program if the
+ * environment variable isn't already set (as is done by make check).
+ */
+ if (System.getenv("WIREDTIGER_HOME") == null) {
+ home = "WT_HOME";
+ try {
+ Process proc = Runtime.getRuntime().exec("/bin/rm -rf WT_HOME");
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(proc.getInputStream()));
+ while(br.ready())
+ System.out.println(br.readLine());
+ br.close();
+ new File("WT_HOME").mkdir();
+ } catch (IOException ioe) {
+ System.err.println("IOException: WT_HOME: " + ioe);
+ return(1);
+ }
+ } else
+ home = null;
+
+ conn = wiredtiger.open(home, "create,statistics=(all)");
+ session = conn.open_session(null);
+
+ ret = session.create("table:access", "key_format=S,value_format=S");
+
+ cursor = session.open_cursor("table:access", null, null);
+ cursor.putKeyString("key");
+ cursor.putValueString("value");
+ ret = cursor.insert();
+ ret = cursor.close();
+
+ ret = session.checkpoint(null);
+
+ ret = print_database_stats(session);
+
+ ret = print_file_stats(session);
+
+ ret = print_overflow_pages(session);
+
+ ret = print_derived_stats(session);
+
+ return (conn.close(null) == 0 ? ret : -1);
+ }
+
+ public static int
+ main(String[] argv)
+ {
+ try {
+ return ((new ex_stat()).statExample());
+ }
+ catch (WiredTigerException wte) {
+ System.err.println("Exception: " + wte);
+ return (-1);
+ }
+ }
+}
diff --git a/examples/java/com/wiredtiger/examples/ex_thread.java b/examples/java/com/wiredtiger/examples/ex_thread.java
new file mode 100644
index 00000000000..c6b9a5479a9
--- /dev/null
+++ b/examples/java/com/wiredtiger/examples/ex_thread.java
@@ -0,0 +1,142 @@
+/*-
+ * Public Domain 2008-2014 WiredTiger, Inc.
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ex_thread.java
+ * This is an example demonstrating how to create and access a simple
+ * table from multiple threads.
+ */
+
+package com.wiredtiger.examples;
+import com.wiredtiger.db.*;
+import java.io.*;
+import java.util.*;
+
+/*! [thread scan] */
+class ScanThread extends Thread {
+ private Connection conn;
+
+ public ScanThread(Connection conn) {
+ this.conn = conn;
+ }
+
+ public void run()
+ {
+ try {
+ int ret;
+
+ Session session = conn.open_session(null);
+ Cursor cursor = session.open_cursor("table:access", null, null);
+
+ /* Show all records. */
+ while ((ret = cursor.next()) == 0) {
+ String key = cursor.getKeyString();
+ String value = cursor.getValueString();
+ System.out.println("Got record: " + key + " : " + value);
+ }
+ if (ret != wiredtiger.WT_NOTFOUND)
+ System.err.println("Cursor.next: " +
+ wiredtiger.wiredtiger_strerror(ret));
+ } catch (WiredTigerException wte) {
+ System.err.println("Exception " + wte);
+ }
+ }
+}
+/*! [thread scan] */
+
+public class ex_thread {
+
+ public static String home;
+
+ public static final int NUM_THREADS = 10;
+
+ /*! [thread main] */
+ static int main(String[] argv)
+ {
+ try {
+ Thread[] threads = new Thread[NUM_THREADS];
+ int i, ret;
+ Connection conn;
+
+ /*
+ * Create a clean test directory for this run of the test program if the
+ * environment variable isn't already set (as is done by make check).
+ */
+ if (System.getenv("WIREDTIGER_HOME") == null) {
+ home = "WT_HOME";
+ try {
+ Process proc = Runtime.getRuntime().exec("/bin/rm -rf " + home);
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(proc.getInputStream()));
+ while(br.ready())
+ System.out.println(br.readLine());
+ br.close();
+ new File(home).mkdir();
+ } catch (IOException ioe) {
+ System.err.println("IOException: " + home + ": " + ioe);
+ return(1);
+ }
+ } else
+ home = null;
+
+ if ((conn = wiredtiger.open(home, "create")) == null) {
+ System.err.println("Error connecting to " + home);
+ return(1);
+ }
+
+ /* Note: further error checking omitted for clarity. */
+
+ Session session = conn.open_session(null);
+ ret = session.create("table:access", "key_format=S,value_format=S");
+ Cursor cursor = session.open_cursor("table:access", null, "overwrite");
+ cursor.putKeyString("key1");
+ cursor.putValueString("value1");
+ ret = cursor.insert();
+ ret = session.close(null);
+
+ for (i = 0; i < NUM_THREADS; i++) {
+ threads[i] = new ScanThread(conn);
+ threads[i].start();
+ }
+
+ for (i = 0; i < NUM_THREADS; i++)
+ try {
+ threads[i].join();
+ ret = -1;
+ }
+ catch (InterruptedException ie) {
+ }
+
+ ret = conn.close(null);
+ return (ret);
+ }
+ catch (WiredTigerException wte) {
+ System.err.println("Exception: " + wte);
+ return (-1);
+ }
+ }
+ /*! [thread main] */
+
+}
diff --git a/lang/java/Makefile.am b/lang/java/Makefile.am
index 29ef00a7842..0fcb1455c6e 100644
--- a/lang/java/Makefile.am
+++ b/lang/java/Makefile.am
@@ -29,7 +29,15 @@ JAVA_SRC = \
$(JAVADESTFULL)/wiredtiger.java \
$(JAVADESTFULL)/wiredtigerConstants.java \
$(JAVADESTFULL)/wiredtigerJNI.java \
- $(JAVAEXAMPLES)/ex_access.java
+ $(JAVAEXAMPLES)/ex_access.java \
+ $(JAVAEXAMPLES)/ex_all.java \
+ $(JAVAEXAMPLES)/ex_async.java \
+ $(JAVAEXAMPLES)/ex_call_center.java \
+ $(JAVAEXAMPLES)/ex_cursor.java \
+ $(JAVAEXAMPLES)/ex_log.java \
+ $(JAVAEXAMPLES)/ex_schema.java \
+ $(JAVAEXAMPLES)/ex_stat.java \
+ $(JAVAEXAMPLES)/ex_thread.java
JAVA_JUNIT = \
$(JAVATEST)/AutoCloseTest.java \
diff --git a/lang/java/wiredtiger.i b/lang/java/wiredtiger.i
index fdcc0144508..71aed8b7866 100644
--- a/lang/java/wiredtiger.i
+++ b/lang/java/wiredtiger.i
@@ -127,7 +127,7 @@ static void throwWiredTigerException(JNIEnv *jenv, const char *msg) {
%typemap(in) WT_ITEM * (WT_ITEM item) %{
$1 = &item;
$1->data = (*jenv)->GetByteArrayElements(jenv, $input, 0);
- $1->size = (*jenv)->GetArrayLength(jenv, $input);
+ $1->size = (size_t)(*jenv)->GetArrayLength(jenv, $input);
%}
%typemap(argout) WT_ITEM * %{
diff --git a/src/docs/Doxyfile b/src/docs/Doxyfile
index 5492905f7e9..3fc4f41a36b 100644
--- a/src/docs/Doxyfile
+++ b/src/docs/Doxyfile
@@ -209,6 +209,7 @@ ALIASES = "notyet{1}=Note: <b>"\1"</b> not yet supported in Wired
"errors=@returns zero on success and a non-zero error code on failure. See @ref error_returns \"Error Returns\" for details." \
"ebusy_errors=@returns zero on success, EBUSY if there are open cursors on the object and a non-zero error code on failure. See @ref error_returns \"Error Returns\" for details." \
"ex_ref{1}=@ref \1 \"\1\"" \
+ "ref_single=@ref" \
"hrow{1}=<tr><th>\1</th></tr>" \
"hrow{2}=<tr><th>\1</th><th>\2</th></tr>" \
"hrow{3}=<tr><th>\1</th><th>\2</th><th>\3</th></tr>" \
@@ -776,6 +777,7 @@ EXCLUDE_SYMBOLS = __F \
# the \include command).
EXAMPLE_PATH = ../../examples/c \
+ ../../examples/java/com/wiredtiger/examples/ \
../../ext/compressors/nop \
./examples
diff --git a/src/docs/async.dox b/src/docs/async.dox
index 9eed1bab5b4..fcc0e590369 100644
--- a/src/docs/async.dox
+++ b/src/docs/async.dox
@@ -1,4 +1,4 @@
-/*! @page async Asynchronous operations
+/*! @m_page{{c,java},async,Asynchronous operations}
WiredTiger supports asynchronous operations; as an example of where this
can be useful, a server application handling requests from a network as
@@ -81,6 +81,10 @@ the example program @ex_ref{ex_async.c}:
@snippet ex_async.c async example callback implementation
+@m_if{java}
+@snippet ex_async.c async example callback implementation part 2
+@m_endif
+
@section async_operations Executing asynchronous operations
The WT_ASYNC_OP handle behaves similarly to the WT_CURSOR handle, that
diff --git a/src/docs/backup.dox b/src/docs/backup.dox
index 3ac32c30d26..c8ae3938dfe 100644
--- a/src/docs/backup.dox
+++ b/src/docs/backup.dox
@@ -10,7 +10,7 @@ apply to data files which don't appear in the backup.
*/
-/*! @page backup Backups
+/*! @m_page{{c,java},backup,Backups}
WiredTiger cursors provide access to data from a variety of sources.
One of these sources is the list of files required to perform a backup
@@ -66,7 +66,7 @@ example:
@section backup_util Backup from the command line
-The @ref util_backup command may also be used to create backups:
+The @ref_single util_backup command may also be used to create backups:
@code
rm -rf /path/database.backup &&
diff --git a/src/docs/basic-api.dox b/src/docs/basic-api.dox
index 9fe52517a21..2b810e6676b 100644
--- a/src/docs/basic-api.dox
+++ b/src/docs/basic-api.dox
@@ -1,4 +1,4 @@
-/*! @page basic_api Getting Started with the API
+/*! @m_page{{c,java},basic_api,Getting Started with the API}
WiredTiger applications will generally use the following classes to access
and manage data:
@@ -27,9 +27,14 @@ application. WiredTiger supports the C, C++, Java and Python programming
languages (among others).
By default, WiredTiger works as a traditional key/value store, where the
-keys and values are raw byte arrays accessed using a WT_ITEM structure.
+keys and values are
+@m_if{c}
+raw byte arrays accessed using a WT_ITEM structure.
+@m_else
+raw byte arrays.
+@m_endif
Keys and values may be up to (4GB - 512B) bytes in size, but depending
-on how @ref WT_SESSION::create "maximum item sizes" are configured,
+on how WT_SESSION::create "maximum item sizes" are configured,
large key and value items will be stored on overflow pages.
WiredTiger also supports a @ref schema "schema layer" so that keys and
@@ -51,11 +56,17 @@ for the single thread accessing the database:
The configuration string @c "create" is passed to ::wiredtiger_open to
indicate the database should be created if it does not already exist.
+@m_if{c}
The code block above also shows simple error handling with
::wiredtiger_strerror (a function that returns a string describing an
error code passed as its argument). More complex error handling can be
configured by passing an implementation of WT_EVENT_HANDLER to
::wiredtiger_open or WT_CONNECTION::open_session.
+@m_endif
+@m_if{java}
+The code block above also shows simple error handling by catching
+WiredTigerException.
+@m_endif
@section basic_create_table Creating a table
diff --git a/src/docs/checkpoint.dox b/src/docs/checkpoint.dox
index 55fa44e38f2..523c0887859 100644
--- a/src/docs/checkpoint.dox
+++ b/src/docs/checkpoint.dox
@@ -1,4 +1,4 @@
-/*! @page checkpoint Checkpoint durability
+/*! @m_page{{c,java},checkpoint,Checkpoint durability}
WiredTiger supports checkpoint durability by default, and optionally
commit-level durability when logging is enabled. In most applications,
diff --git a/src/docs/command-line.dox b/src/docs/command-line.dox
index a4de4d85e71..2d6a5435278 100644
--- a/src/docs/command-line.dox
+++ b/src/docs/command-line.dox
@@ -152,8 +152,8 @@ Load a table or file from dump output.
The \c load command reads the standard input for data and loads it into
a table or file, creating the table or file if it does not yet exist.
-The data should be the format produced by the \c dump command; see @ref
-dump_formats for details.
+The data should be the format produced by the \c dump command; see
+@ref dump_formats for details.
By default, if the table or file already exists, data in the file or
table will be overwritten by the new data (use the \c -n option to
diff --git a/src/docs/compact.dox b/src/docs/compact.dox
index 46ff42b114f..9d37bf77214 100644
--- a/src/docs/compact.dox
+++ b/src/docs/compact.dox
@@ -1,4 +1,4 @@
-/*! @page compact Compaction
+/*! @m_page{{c,java},compact,Compaction}
The WT_SESSION::compact method can be used to compact data sources.
diff --git a/src/docs/compression.dox b/src/docs/compression.dox
index 92f5c27f25e..4b305b514f5 100644
--- a/src/docs/compression.dox
+++ b/src/docs/compression.dox
@@ -1,4 +1,4 @@
-/*! @page compression Compressors
+/*! @m_page{{c,java},compression,Compressors}
This section explains how to configure WiredTiger's builtin support for
the snappy and bzip2 compression engines.
@@ -102,6 +102,6 @@ code can correctly decompress old and new blocks.
@section compression_custom Custom compression engines
WiredTiger may be extended by adding custom compression engines; see
-@ref WT_COMPRESSOR for more information.
+WT_COMPRESSOR for more information.
*/
diff --git a/src/docs/config-strings.dox b/src/docs/config-strings.dox
index 295316fe039..b78f6d21372 100644
--- a/src/docs/config-strings.dox
+++ b/src/docs/config-strings.dox
@@ -1,4 +1,4 @@
-/*! @page config_strings Configuration Strings
+/*! @m_page{{c,java},config_strings,Configuration Strings}
@section config_intro Introduction
@@ -74,8 +74,14 @@ Superfluous commas and whitespace in the configuration string are ignored
combine two configuration strings by concatenating them with a comma in
between.
+@m_if{c}
Empty configuration strings may be represented in C or C++ by passing
<code>NULL</code>.
+@m_endif
+@m_if{java}
+Empty configuration strings may be represented in Java by passing
+<code>null</code>.
+@m_endif
@section config_json JavaScript Object Notation (JSON) compatibility
diff --git a/src/docs/cursor-log.dox b/src/docs/cursor-log.dox
index 81e98203c39..fd247dd7105 100644
--- a/src/docs/cursor-log.dox
+++ b/src/docs/cursor-log.dox
@@ -1,4 +1,4 @@
-/*! @page cursor_log Log cursors
+/*! @m_page{{c,java},cursor_log,Log cursors}
WiredTiger cursors provide access to data from a variety of sources, and
one of these sources is the records in the transaction log files. Log
@@ -22,7 +22,12 @@ To open a log cursor on the database:
@snippet ex_log.c log cursor open
-A log cursor's key is a unique log record identifier, plus a uint32_t
+A log cursor's key is a unique log record identifier, plus a
+@m_if{c}
+uint32_t
+@m_else
+int
+@m_endif
operation counter within that log record. When a log record maps
one-to-one to a transaction (in other words, the returned log record has
the only database operation the transaction made), the operation counter
@@ -38,10 +43,17 @@ Here is an example of getting the log cursor's key:
The log cursor's value is comprised of six fields:
-- a uint64_t transaction ID (set for commit records only, otherwise 0),
-- a uint32_t record type
-- a uint32_t operation type (set for commit records only, otherwise 0)
-- a uint32_t file id (if applicable, otherwise 0)
+@m_if{c}
+- a \c uint64_t transaction ID (set for commit records only, otherwise 0),
+- a \c uint32_t record type
+- a \c uint32_t operation type (set for commit records only, otherwise 0)
+- a \c uint32_t file id (if applicable, otherwise 0)
+@m_else
+- a \c long transaction ID (set for commit records only, otherwise 0),
+- a \c int record type
+- a \c int operation type (set for commit records only, otherwise 0)
+- a \c int file id (if applicable, otherwise 0)
+@m_endif
- the operation key (commit records only, otherwise empty)
- the operation value
@@ -49,9 +61,9 @@ The transaction ID may not be unique across recovery, that is, closing
and reopening the database may result in transaction IDs smaller than
previously seen transaction IDs.
-The record and operation types are taken from @ref log_types; typically,
-the only record or operation type applications are concerned with is
-::WT_LOGREC_MESSAGE, which is a log record generated by the application.
+The record and operation types are taken from @ref_single log_types;
+typically, the only record or operation type applications are concerned with
+is ::WT_LOGREC_MESSAGE, which is a log record generated by the application.
The file ID may not be unique across recovery, that is, closing and
reopening the database may result in file IDs changing. Additionally,
diff --git a/src/docs/cursor-ops.dox b/src/docs/cursor-ops.dox
index ef8a7b20499..d9d8f19868c 100644
--- a/src/docs/cursor-ops.dox
+++ b/src/docs/cursor-ops.dox
@@ -1,4 +1,4 @@
-/*! @page cursor_ops Cursor operations
+/*! @m_page{{c,java},cursor_ops,Cursor operations}
Common operations in WiredTiger are performed using WT_CURSOR handles.
A cursor includes:
@@ -131,6 +131,7 @@ it may be retried without calling WT_CURSOR::set_key or
WT_CURSOR::set_value again. That is, the cursor may still reference the
application-supplied memory until it is successfully positioned.
+@m_if{c}
Any pointers returned by WT_CURSOR::get_key or WT_CURSOR::get_value are only
valid until the cursor is positioned. These pointers may reference private
WiredTiger data structures that must not be modified or freed by the
@@ -141,4 +142,5 @@ The comments in this example code explain when the application can safely
modify memory passed to WT_CURSOR::set_key or WT_CURSOR::set_value:
@snippet ex_scope.c cursor scope operation
+@m_endif
*/
diff --git a/src/docs/cursor-random.dox b/src/docs/cursor-random.dox
index abb6e53571e..70a28407ea5 100644
--- a/src/docs/cursor-random.dox
+++ b/src/docs/cursor-random.dox
@@ -1,4 +1,4 @@
-/*! @page cursor_random Cursor random
+/*! @m_page{{c,java},cursor_random,Cursor random}
The \c next_random configuration to the WT_SESSION::open_cursor method
configures the cursor to return a pseudo-random record from a row-store
diff --git a/src/docs/cursors.dox b/src/docs/cursors.dox
index 0dcfe44e4d2..046597455f2 100644
--- a/src/docs/cursors.dox
+++ b/src/docs/cursors.dox
@@ -1,4 +1,4 @@
-/*! @page cursors Cursors
+/*! @m_page{{c,java},cursors,Cursors}
Common operations in WiredTiger are performed using WT_CURSOR handles.
A cursor includes:
@@ -77,9 +77,16 @@ See @ref transactions for more information.
Cursors can be configured for raw mode by specifying the \c "raw" config
keyword to WT_SESSION::open_cursor. In this mode, the methods
WT_CURSOR::get_key, WT_CURSOR::get_value, WT_CURSOR::set_key and
-WT_CURSOR::set_value all take a single WT_ITEM in the variable-length
+WT_CURSOR::set_value all take a single
+@m_if{c}
+WT_ITEM
+@m_else
+byte array
+@m_endif
+in the variable-length
argument list instead of a separate argument for each column.
+@m_if{c}
WT_ITEM structures do not need to be cleared before use.
For WT_CURSOR::get_key and WT_CURSOR::get_value in raw mode, the WT_ITEM
@@ -91,7 +98,9 @@ cursor's \c key_format or \c value_format, respectively.
The @ex_ref{ex_schema.c} example creates a table where the value format is
\c "5sHq", where the initial string is the country, the short is a year,
-and the long is a population. The following example lists the table record
+and the long is a population.
+@m_endif
+The following example lists the table record
values, using raw mode:
@snippet ex_schema.c List the records in the table using raw mode.
diff --git a/src/docs/data-sources.dox b/src/docs/data-sources.dox
index cde5f6a3087..0c82a948fe5 100644
--- a/src/docs/data-sources.dox
+++ b/src/docs/data-sources.dox
@@ -53,7 +53,7 @@ Advanced applications may also open the following low-level cursor types:
/* ----------------- */
-/*! @page data_sources Data Sources
+/*! @m_page{{c,java},data_sources,Data Sources}
WiredTiger provides access to data from a variety of sources. At the
lowest level, data may be stored in a file using a tree structure. A
@@ -103,11 +103,11 @@ source. Database-wide statistics are retrieved with the \c "statistics:"
URI; individual data source statistics are available by specifying
\c "statistics:<data source URI>".
-The statistic key is an integer from the list of keys in @ref statistics_keys
-"Statistics Keys". Statistics cursors return three values from the
-WT_CURSOR::get_value call: a printable description of the statistic, a
-printable version of the entry's value, and the entry's unsigned 64-bit
-integral value, respectively.
+The statistic key is an integer from the list of keys in
+@ref_single statistics_keys "Statistics Keys". Statistics cursors return
+three values from the WT_CURSOR::get_value call: a printable description of
+the statistic, a printable version of the entry's value, and the entry's
+unsigned 64-bit integral value, respectively.
The following is an example of printing run-time statistics about the
WiredTiger engine:
@@ -128,5 +128,6 @@ corresponding key, as shown in the following example:
@snippet ex_stat.c statistics retrieve by key
-See @ref tune_statistics for more examples of how statistics can be used.
+See @ref_single tune_statistics for more examples of how statistics can be
+used.
*/
diff --git a/src/docs/durability.dox b/src/docs/durability.dox
index 0085e17a51b..d3f8bc6778a 100644
--- a/src/docs/durability.dox
+++ b/src/docs/durability.dox
@@ -1,4 +1,4 @@
-/*! @page durability Commit-level durability
+/*! @m_page{{c,java},durability,Commit-level durability}
WiredTiger supports checkpoint durability by default, and optionally
commit-level durability when logging is enabled. In most applications,
@@ -13,9 +13,9 @@ enabled using the \c log=(enabled) configuration to ::wiredtiger_open.
When logging is enabled, WiredTiger writes records to the log for each
transaction.
-Transactions define which updates are made durable together see @ref
-transactions for details. By default, log records are flushed to disk
-by WT_SESSION::commit_transaction, ensuring that, once
+Transactions define which updates are made durable together see
+@ref transactions for details. By default, log records are flushed to
+disk by WT_SESSION::commit_transaction, ensuring that, once
WT_SESSION::commit_transaction returns successfully, updates performed
by the transaction will be included in the database state regardless of
application or system failure.
diff --git a/src/docs/error-handling.dox b/src/docs/error-handling.dox
index f0af35a7111..0b4ac778639 100644
--- a/src/docs/error-handling.dox
+++ b/src/docs/error-handling.dox
@@ -1,4 +1,4 @@
-/*! @page error_handling Error handling
+/*! @m_page{{c,java},error_handling,Error handling}
WiredTiger operations return a value of 0 on success and a non-zero
value on error. Error codes may be either positive or negative:
@@ -9,7 +9,18 @@ are WiredTiger-specific (for example, WT_DEADLOCK).
WiredTiger-specific error codes always appear in the -31,800 to -31,999
range.
+@m_if{java}
+Informational return values, like <code>wiredtiger.WT_NOTFOUND</code>
+or <code>wiredtiger.WT_DUPLICATE_KEY</code> or 0 (success),
+are directly returned by APIs. More severe errors
+are thrown as \c WiredTigerException, which must be caught by the
+application.
+
+The following is a complete list of possible WiredTiger-specific
+return values, all constants defined in the com.wiredtiger.db.wiredtiger class:
+@m_else
The following is a list of possible WiredTiger-specific errors:
+@m_endif
@if IGNORE_BUILT_BY_API_ERR_BEGIN
@endif
@@ -37,7 +48,9 @@ associated with any WiredTiger, ISO C99, or POSIX 1003.1-2001 function:
@snippet ex_all.c Display an error
+@m_if{c}
More complex error handling can be configured by passing an implementation
of WT_EVENT_HANDLER to ::wiredtiger_open or WT_CONNECTION::open_session.
+@m_endif
*/
diff --git a/src/docs/file-formats.dox b/src/docs/file-formats.dox
index bc747433172..4d339d9b13d 100644
--- a/src/docs/file-formats.dox
+++ b/src/docs/file-formats.dox
@@ -1,4 +1,4 @@
-/*! @page file_formats File formats and compression
+/*! @m_page{{c,java},file_formats,File formats and compression}
@section file_formats_formats File formats
@@ -45,11 +45,12 @@ columns in separate files, or the underlying data is a set of bits,
column-store format may be a better choice.
Both row- and column-store formats can maintain high volumes of writes,
-but for data sets requiring sustained, extreme write throughput, @ref
-lsm are usually a better choice. For applications that do not require
-extreme write throughput, row- or column-store is likely to be a better
-choice because the read throughput is better than with LSM trees (an
-effect that becomes more pronounced as additional read threads are added).
+but for data sets requiring sustained, extreme write throughput,
+@ref lsm are usually a better choice. For applications that do not
+require extreme write throughput, row- or column-store is likely to be
+a better choice because the read throughput is better than with LSM trees
+(an effect that becomes more pronounced as additional read threads are
+added).
Applications with complex schemas may also benefit from using multiple
storage formats, that is, using a combination of different formats in
@@ -101,7 +102,7 @@ additional CPU and memory use when searching the in-memory tree (if keys
are encoded), and additional CPU and memory use when returning values
from the in-memory tree and when writing pages to disk. Note the
additional CPU cost of Huffman encoding can be high, and should be
-considered. (See @subpage huffman for details.)
+considered. (See @m_single_subpage huffman for details.)
Huffman encoding is disabled by default.
@@ -137,7 +138,7 @@ and on-disk objects by compressing individual value items. The cost is
additional CPU and memory use when returning values from the in-memory
tree and when writing pages to disk. Note the additional CPU cost of
Huffman encoding can be high, and should be considered.
-(See @ref huffman for details.)
+(See @ref_single huffman for details.)
Huffman encoding is disabled by default.
diff --git a/src/docs/introduction.dox b/src/docs/introduction.dox
index 7191540ec1d..8e8c0d9e7cf 100644
--- a/src/docs/introduction.dox
+++ b/src/docs/introduction.dox
@@ -31,6 +31,7 @@ For more information about building and installing WiredTiger, see:
For more information about writing WiredTiger applications, see:
- @subpage programming
+- @subpage programming_lang_java
- @ref wt "WiredTiger API reference manual"
- @subpage performance
diff --git a/src/docs/lsm.dox b/src/docs/lsm.dox
index b71fccd7151..08512f27c92 100644
--- a/src/docs/lsm.dox
+++ b/src/docs/lsm.dox
@@ -1,4 +1,4 @@
-/*! @page lsm Log-Structured Merge Trees
+/*! @m_page{{c,java},lsm,Log-Structured Merge Trees}
@section lsm_background Background
@@ -42,21 +42,34 @@ An LSM tree can be created as follows, in much the same way as a
WiredTiger btree file:
@code
+@m_if{c}
session->create(session, "table:bucket", "type=lsm,key_format=S,value_format=S");
+@m_else
+session.create("table:bucket", "type=lsm,key_format=S,value_format=S");
+@m_endif
@endcode
Once created, the LSM tree can be accessed using the same cursor interface
as other data sources in WiredTiger:
@code
+@m_if{c}
WT_CURSOR *c;
session->open_cursor(session, "table:bucket", NULL, NULL, &c);
for(;;) {
- c->set_key("key");
- c->set_value("value");
- c->insert();
+ c->set_key(c, "key");
+ c->set_value(c, "value");
+ c->insert(c);
}
+@m_else
+Cursor c = session.open_cursor("table:bucket", null, null);
+for(;;) {
+ c.putKeyString("key");
+ c.putValueString("value");
+ c.insert();
+}
+@m_endif
@endcode
If an LSM cursor is configured with \c "overwrite=false" passed to
@@ -91,7 +104,11 @@ Tables or indices can be stored using LSM trees. Schema support is provided
for LSM as an extension to the WT_SESSION::create method:
@code
+@m_if{c}
session->create(session, "table:T", "type=lsm");
+@m_else
+session.create("table:T", "type=lsm");
+@m_endif
@endcode
The default type for all schema objects will continue to be btree.
diff --git a/src/docs/namespace.dox b/src/docs/namespace.dox
index 2fb90d33002..8657338e369 100644
--- a/src/docs/namespace.dox
+++ b/src/docs/namespace.dox
@@ -1,9 +1,10 @@
-/*! @page namespace Name spaces
+/*! @m_page{{c,java},namespace,Name spaces}
@section namespace_env Process' environment name space
WiredTiger's environment variables begin with the string "WIREDTIGER".
+@m_if{c}
@section namespace_c C language name space
WiredTiger's public function names begin with the string "wiredtiger".
@@ -12,15 +13,27 @@ WiredTiger's public \c \#define and structure \c typedef declarations
begin with the string "WT_".
WiredTiger's private function names begin with the string "__wt_".
+@m_endif
+
+@m_if{java}
+@section namespace_c Java language name space
+
+WiredTiger's public classes are in the \c com.wiredtiger.db package.
+
+The \c com.wiredtiger.db.wiredtiger class contains static methods
+and inherited constants.
+@m_endif
@section namespace_filesystem File system name space
WiredTiger's files begin with the string "WiredTiger"; applications
should not create files in the WiredTiger file system name space.
+@m_if{c}
@section namespace_error Error return name space
WiredTiger reserves all values from -31,800 to -31,999 as possible error
return values.
+@m_endif
*/
diff --git a/src/docs/packing.dox b/src/docs/packing.dox
index ca857d1b90d..aca9cd72b46 100644
--- a/src/docs/packing.dox
+++ b/src/docs/packing.dox
@@ -1,4 +1,4 @@
-/*! @page packing Packing and Unpacking Data
+/*! @m_page{{c,java},packing,Packing and Unpacking Data}
WiredTiger's data packing uses format strings similar to those specified in the
Python struct module:
@@ -27,6 +27,7 @@ The remaining characters in the format string specify the type of each field
to be packed into or unpacked from a byte array. See @ref schema_column_types
for the list of supported types.
+@m_if{c}
@todo Describe the variable-length integer packing in sufficient detail that it can be re-implemented in other programming languages or in network clients.
@section config_examples Code samples
@@ -34,5 +35,10 @@ for the list of supported types.
The code below is taken from the complete example program @ex_ref{ex_pack.c}. It demonstrates how to pack three integer values into a buffer and then unpack them again.
@snippet ex_pack.c packing
+@m_else
+In Java, data is packed and unpacked using cursor put* and get* operations,
+for example:
+@snippet ex_schema.c Insert and list records
+@m_endif
*/
diff --git a/src/docs/programming.dox b/src/docs/programming.dox
index 4add19c833b..c16fc86657d 100644
--- a/src/docs/programming.dox
+++ b/src/docs/programming.dox
@@ -1,7 +1,11 @@
-/*! @page programming Writing WiredTiger applications
+/*! @m_page{{c,java},programming,Writing WiredTiger applications}
This section covers topics of interest for programmers writing
+@m_if{c}
WiredTiger applications.
+@m_else
+WiredTiger applications in Java.
+@m_endif
We follow SQL terminology: a database is set of tables managed together.
Tables consist of rows, where each row is a key and its associated
@@ -18,14 +22,16 @@ each of which is ordered by one or more columns.
<h2>Storage options</h2>
- @subpage schema
-- @subpage file_formats
- @subpage lsm
+- @subpage file_formats
- @subpage compression
<h2>Programming notes</h2>
- @subpage threads
- @subpage namespace
+@m_if{c}
- @subpage signals
+@m_endif
<h2>Advanced features</h2>
- @subpage checkpoint
@@ -37,9 +43,11 @@ each of which is ordered by one or more columns.
- @subpage shared_cache
- @subpage cursor_log
+@m_if{c}
<h2>Extending WiredTiger</h2>
- @subpage extensions
- @subpage custom_data_sources
- @subpage helium
+@m_endif
*/
diff --git a/src/docs/schema.dox b/src/docs/schema.dox
index de6aaa8cb55..6bdbc7d1a85 100644
--- a/src/docs/schema.dox
+++ b/src/docs/schema.dox
@@ -1,4 +1,4 @@
-/*! @page schema Schema, Columns, Column Groups, Indices and Projections
+/*! @m_page{{c,java},schema,Schema, Columns, Column Groups, Indices and Projections}
While many tables have simple key/value pairs for records, WiredTiger
also supports more complex data patterns.
@@ -57,7 +57,7 @@ Key and value types may also be chosen from a list, or composed of multiple
columns with any combination of types. Keys and values may be up to
(<code>4GB - 512B</code>) bytes in size.
-See @subpage keyvalue for more details on raw key / value items.
+See @m_single_subpage keyvalue for more details on raw key / value items.
@section schema_format_types Format types
@@ -91,14 +91,20 @@ otherwise identical to the \c 'Q' type.
The \c 'S' type is encoded as a C language string terminated by a
NUL character.
+@m_if{java}
+Because of this, the associated Java String may not contain the NUL character.
+@m_endif
The \c 't' type is used for fixed-length bit field values. If
it is preceded by a size, that indicates the number of bits to store,
between 1 and 8. That number of low-order bits will be stored in the
-table. The default is a size of 1 bit: that is, a boolean. C applications
-must always use a \c uint8_t type (or equivalently,
+table. The default is a size of 1 bit: that is, a boolean.
+@m_if{c}
+C applications must always use a \c uint8_t type (or equivalently,
<code>unsigned char</code>) for calls to WT_CURSOR::set_value, and a
-pointer to the same for calls to WT_CURSOR::get_value. If a bit field
+pointer to the same for calls to WT_CURSOR::get_value.
+@m_endif
+If a bit field
value is combined with other types in a packing format, it is equivalent to
\c 'B', and a full byte is used to store it.
@@ -127,7 +133,11 @@ natural integer ordering under the default collator.
See @subpage packing for details of WiredTiger's packing format.
WiredTiger can also be extended with custom collators by implementing the
+@m_if{c}
WT_COLLATOR interface.
+@m_else
+WT_COLLATOR interface (C only).
+@m_endif
@section schema_key_and_value_formats Key and value formats
@@ -148,10 +158,17 @@ follows:
@section schema_cursor_formats Cursor formats
-Cursors for a table have the same key format as the table itself. The key
-columns of a cursor are set with WT_CURSOR::set_key and accessed with
-WT_CURSOR::get_key. WT_CURSOR::set_key is analogous to \c printf, and takes
-a list of values in the order the key columns are configured in \c
+Cursors for a table have the same key format as the table itself.
+@m_if{c}
+The key columns of a cursor are set with WT_CURSOR::set_key and accessed with
+WT_CURSOR::get_key. WT_CURSOR::set_key is analogous to \c printf,
+and takes a list of value
+@m_else
+The key columns of a cursor are set with the \c Cursor.putKey* methods
+and accessed with the \c Cursor.getKey* methods. \c Cursor.putKey* methods
+must be called
+@m_endif
+in the order the key columns are configured in \c
key_format.
For example, setting the key for a row-store table with strings as keys
@@ -169,20 +186,31 @@ the key_format was \c "SiH", would be done as follows:
@snippet ex_all.c Set the cursor's composite key
-The key's values are accessed with WT_CURSOR::get_key, which is analogous
+The key's values are accessed with
+@m_if{c}
+WT_CURSOR::get_key, which is analogous
to \c scanf, and takes a list of pointers to values in the same order:
+@m_else
+successive calls to \c Cursor.getKey* methods:
+@m_endif
@snippet ex_all.c Get the cursor's string key
@snippet ex_all.c Get the cursor's record number key
@snippet ex_all.c Get the cursor's composite key
Cursors for a table have the same value format as the table, unless a
-projection is configured with WT_SESSION::open_cursor. See @ref
-cursor_projections for more information.
+projection is configured with WT_SESSION::open_cursor. See
+@ref cursor_projections for more information.
+@m_if{c}
WT_CURSOR::set_value is used to set value columns, and
WT_CURSOR::get_value is used to get value columns, in the same way as
described for WT_CURSOR::set_key and WT_CURSOR::get_key.
+@m_else
+\c The Cursor.putValue* methods are used to set value columns, and
+\c Cursor.getValue* are used to get value columns, in the same way as
+described for \c Cursor.putKey* and \c Cursor.getKey*.
+@m_endif
@section schema_columns Columns
@@ -271,8 +299,13 @@ Continuing the example, we might open an index on the \c country column:
Cursors are opened on indices by passing the index's URI to the
WT_SESSION::open_cursor method.
-Index cursors use the specified index key columns for WT_CURSOR::get_key
-and WT_CURSOR::set_key. For example, we can retrieve information from
+Index cursors use the specified index key columns for
+@m_if{c}
+WT_CURSOR::get_key and WT_CURSOR::set_key.
+@m_else
+\c Cursor.getKey* and \c Cursor.putKey* calls.
+@m_endif
+For example, we can retrieve information from
the \c country index as follows:
@snippet ex_schema.c Search in a simple index
@@ -282,19 +315,34 @@ to the WT_SESSION::create call:
@snippet ex_schema.c Create an index with a composite key
-To retrieve information from a composite index requires a more
-complicated WT_CURSOR::set_key call, but is otherwise the same:
+To retrieve information from a composite index requires a more complicated
+@m_if{c}
+WT_CURSOR::set_key call,
+@m_else
+set of \c Cursor.putKey* calls,
+@m_endif
+but is otherwise the same:
@snippet ex_schema.c Search in a composite index
@section schema_index_projections Index cursor projections
By default, index cursors return all of the table's value columns from
-WT_CURSOR::get_value. The application can specify that a subset of the
-usual columns should be returned in calls to WT_CURSOR::get_value by
-appending a list of columns to the \c uri parameter of the
-WT_SESSION::open_cursor call. This is called a \em projection, see @ref
-cursor_projections for more details.
+@m_if{c}
+WT_CURSOR::get_value.
+@m_else
+\c Cursor.getValue* calls.
+@m_endif
+The application can specify that a subset of the
+usual columns should be returned in calls to
+@m_if{c}
+WT_CURSOR::get_value
+@m_else
+\c Cursor.getValue
+@m_endif
+by appending a list of columns to the \c uri parameter of the
+WT_SESSION::open_cursor call. This is called a \em projection, see
+@ref cursor_projections for more details.
In the case of index cursors, a projection can be used to avoid lookups
in column groups that do not hold columns relevant to the operation.
diff --git a/src/docs/shared-cache.dox b/src/docs/shared-cache.dox
index 1cb6a58a644..95422caabda 100644
--- a/src/docs/shared-cache.dox
+++ b/src/docs/shared-cache.dox
@@ -1,10 +1,10 @@
-/*! @page shared_cache Per-process shared caches
+/*! @m_page{{c,java},shared_cache,Per-process shared caches}
WiredTiger supports sharing a single cache among multiple databases within
a process.
An application configures a shared cache by specifying a shared_cache name
-to the @ref wiredtiger_open function. Applications can optionally
+to the ::wiredtiger_open function. Applications can optionally
set a minimum amount of cache any connection in the pool will be assigned
and the granularity at which the cache pool is redistributed among
connections - called the chunk size.
@@ -35,7 +35,7 @@ period. When a database is closed any resources it is using are distributed
among the other databases.
WiredTiger shared cache tuning options can be configured when first opening a
-database via @ref wiredtiger_open or changed after open using the
+database via ::wiredtiger_open or changed after open using the
WT_CONNECTION::reconfigure method.
*/
diff --git a/src/docs/spell.ok b/src/docs/spell.ok
index 790d108c9e9..218db0c8f3a 100644
--- a/src/docs/spell.ok
+++ b/src/docs/spell.ok
@@ -72,6 +72,7 @@ Vv
WiredTiger
WiredTiger's
WiredTigerCheckpoint
+WiredTigerException
WiredTigerLog
WiredTigerTestCase
Za
@@ -196,6 +197,8 @@ freelist
fsync
gcc
gdbm
+getKey
+getValue
getopt
getter
gid
@@ -230,6 +233,7 @@ keyfmt
keyname
keyvalue
kvs
+lang
lastname
len
leveldb
@@ -329,6 +333,10 @@ priv
proc
pthread
pthreads
+putKey
+putKeyString
+putValue
+putValueString
py
qnx
rdbms
diff --git a/src/docs/statistics.dox b/src/docs/statistics.dox
index e07e594a72a..067cf342111 100644
--- a/src/docs/statistics.dox
+++ b/src/docs/statistics.dox
@@ -1,4 +1,4 @@
-/*! @page statistics Statistics
+/*! @m_page{{c,java},statistics,Statistics}
WiredTiger can be configured to maintain a variety of run-time and
data-source statistics. As maintaining statistics may involve updating
diff --git a/src/docs/threads.dox b/src/docs/threads.dox
index b5cca7911a3..16b0d7940da 100644
--- a/src/docs/threads.dox
+++ b/src/docs/threads.dox
@@ -1,4 +1,4 @@
-/*! @page threads Multithreading
+/*! @m_page{{c,java},threads,Multithreading}
All WT_CONNECTION methods are thread safe, and WT_CONNECTION handles can
be shared between threads. Applications typically open a single
diff --git a/src/docs/tools/doxfilter b/src/docs/tools/doxfilter
index 9b63982913c..298e23f6cbb 100755
--- a/src/docs/tools/doxfilter
+++ b/src/docs/tools/doxfilter
@@ -27,4 +27,4 @@
tooldir=`dirname $0`
-cat "$@" | python $tooldir/doxfilter.py
+python $tooldir/doxfilter.py "$@"
diff --git a/src/docs/tools/doxfilter.py b/src/docs/tools/doxfilter.py
index b742be16e18..8e1c78ca5d0 100755
--- a/src/docs/tools/doxfilter.py
+++ b/src/docs/tools/doxfilter.py
@@ -30,11 +30,158 @@
# WiredTiger reference manual. It changes comments to Javadoc style
# (i.e., from "/*!" to "/**"), because the latter are configured to not
# search for brief descriptions at the beginning of pages.
+# It also processes any page marked with @m_page specially to create
+# multiple per-language versions of the page.
import re, sys
+progname = 'doxfilter.py'
+linenum = 0
+filename = '<unknown>'
+
+def err(arg):
+ sys.stderr.write(filename + ':' + str(linenum) +
+ ': ERROR: ' + arg + '\n')
+ sys.exit(1)
+
+def java_post_substitutions(source):
+ result = source
+ for datatype in [['WT_CONNECTION', 'Connection'],
+ ['WT_CURSOR', 'Cursor'],
+ ['WT_SESSION', 'Session'],
+ ['WT_ASYNC_OPTYPE', 'AsyncOpType'],
+ ['WT_ASYNC_OP', 'AsyncOp']]:
+ fromdt = datatype[0]
+ todt = datatype[1]
+
+ # e.g. replace("WT_CONNECTION::", "Connection.").
+ # replace("WT_CONNECTION", "Connection")
+ # replace("::WT_CONNECTION", "Connection")
+ # etc.
+ result = result.replace(fromdt + '::', todt + '.')
+ result = re.sub(r':*' + fromdt, todt, result)
+
+ # We fix back any 'ref' entries, since we don't have
+ # many java versions of these refered-to pages.
+ #
+ # Ideally, we'd have a way ('@m_ref'?) to indicate which
+ # ones could refer to a Java version.
+ result = result.replace('ref ' + todt + '.', 'ref ' + fromdt + '::')
+ result = result.replace('::wiredtiger_open', '\c wiredtiger.open')
+ return result
+
+def process_lang(lang, lines):
+ result = ''
+ lang_ext = '.' + lang
+ class_suffix = None
+ if lang == 'c':
+ lang_suffix = ""
+ lang_desc=""
+ elif lang == 'java':
+ lang_suffix = "_lang_java"
+ lang_desc=" in Java"
+ else:
+ err('@m_page contains illegal lang: ' + lang)
+ condstack = [True]
+ linenum = 0
+ mif_pat = re.compile('^\s*@m_if{([^,}]*)}')
+ melse_pat = re.compile('^\s*@m_else\s*$')
+ mendif_pat = re.compile('^\s*@m_endif\s*$')
+ mpage_pat = re.compile('@m_page{{([^}]*)},([^,}]*),([^}]*)}')
+ mpage_rep = r'@page \2' + lang_suffix + r' \3 ' + lang_desc
+ ref_pat = re.compile('@ref\s+(\w*)')
+ ref_rep = r'@ref \1' + lang_suffix
+ snip_pat = re.compile('@snippet ex_([^.]*)[.]c\s+(.*)')
+ snip_rep = r'@snippet ex_\1' + lang_ext + r' \2'
+ section_pat = re.compile('(^@\w*section)\s+(\w*)')
+ section_rep = r'\1 \2' + lang_suffix
+ subpage_pat = re.compile('@subpage\s+(\w*)')
+ subpage_rep = r'@subpage \1' + lang_suffix
+ msinglesubpage_pat = re.compile('@m_single_subpage\s+(\w*)')
+ msinglesubpage_rep = r'\\subpage \1'
+ exref_pat = re.compile('@ex_ref{ex_([^.]*)[.]c}')
+ if lang == 'c':
+ exref_rep = r'@ex_ref{ex_\1' + lang_ext + '}'
+ else:
+ # Though we have java examples, we don't have references
+ # to them working yet, so strip the @ex_ref.
+ exref_rep = r'ex_\1' + lang_ext
+
+ # Any remaining @m_foo{...} aliases are
+ # diverted to @c_foo{...} or @java_foo{...}
+ mgeneric_pat = re.compile('@m_([^ }]*)')
+ mgeneric_rep = r'@' + lang + r'_\1'
+ for line in lines:
+ linenum += 1
+ if lang != 'c':
+ line = re.sub(exref_pat, exref_rep, line)
+ line = re.sub(ref_pat, ref_rep, line)
+ line = re.sub(section_pat, section_rep, line)
+ line = re.sub(snip_pat, snip_rep, line)
+ line = re.sub(mpage_pat, mpage_rep, line)
+ line = re.sub(subpage_pat, subpage_rep, line)
+ # msinglesubpage must be performed after subpage
+ line = re.sub(msinglesubpage_pat, msinglesubpage_rep, line)
+ if '@m_if' in line:
+ m = re.search(mif_pat, line)
+ if not m:
+ err('@m_if incorrect syntax')
+ iflang = m.groups()[0]
+ if iflang != 'java' and iflang != 'c':
+ err('@m_if unknown language')
+ condstack.append(iflang == lang)
+ elif '@m_else' in line:
+ if not re.search(melse_pat, line):
+ err('@m_else has extraneous stuff')
+ if len(condstack) <= 1:
+ err('@m_else missing if')
+ condstack[-1] = not condstack[-1]
+ elif '@m_endif' in line:
+ if not re.search(mendif_pat, line):
+ err('@m_endif has extraneous stuff')
+ if len(condstack) <= 1:
+ err('@m_endif missing if')
+ condstack.pop()
+ else:
+ if condstack[-1]:
+ # Do generic @m_... macros last
+ line = re.sub(mgeneric_pat,
+ mgeneric_rep, line)
+ result += line + '\n'
+ if lang == 'java':
+ result = java_post_substitutions(result)
+ if len(condstack) != 1:
+ err('non matching @m_if/@m_endif')
+ return result
+
+def process_multilang(source):
+ n = source.count('@m_page')
+ if n > 1:
+ err('multiple @m_page in file not allowed')
+ if n == 0:
+ err('missing @m_page in file that uses @m_ macros')
+ else:
+ m = re.search(r'@m_page{{([^}]*)},([^,}]*),([^}]*)}',
+ source, re.M)
+ if not m:
+ err('@m_page incorrect syntax')
+ groups = m.groups()
+ langs = groups[0].split(',')
+ lines = source.split('\n')
+ result = ''
+ for lang in langs:
+ result += process_lang(lang, lines)
+ return result
+
def process(source):
- return source.replace(r'/*!', r'/**')
+ source = source.replace(r'/*!', r'/**')
+ if '@m_' in source:
+ source = process_multilang(source)
+ return source
if __name__ == '__main__':
- sys.stdout.write(process(sys.stdin.read()))
+ for f in sys.argv[1:]:
+ filename = f
+ with open(f, 'r') as infile:
+ sys.stdout.write(process(infile.read()))
+ sys.exit(0)
diff --git a/src/docs/transactions.dox b/src/docs/transactions.dox
index 610932d7cdf..7f3acaa245d 100644
--- a/src/docs/transactions.dox
+++ b/src/docs/transactions.dox
@@ -1,4 +1,4 @@
-/*! @page transactions Transactions
+/*! @m_page{{c,java},transactions,Transactions}
@section transactions_acid ACID properties
diff --git a/src/docs/tune-cache.dox b/src/docs/tune-cache.dox
index 9183fe8a25a..9f4d1a6406f 100644
--- a/src/docs/tune-cache.dox
+++ b/src/docs/tune-cache.dox
@@ -56,7 +56,7 @@ eviction configuration settings can reduce latency spikes in
application threads and can improve throughput in some applications.
WiredTiger eviction tuning options can be configured when first opening
-a database via @ref wiredtiger_open, or changed after open with
+a database via ::wiredtiger_open, or changed after open with
WT_CONNECTION::reconfigure.
The \c eviction_trigger configuration value is the occupied percentage