diff --git a/docs/Doxyfile b/docs/Doxyfile
index 7d7dba2521c..689cc51ec70 100644
--- a/docs/Doxyfile
+++ b/docs/Doxyfile
@@ -115,7 +115,7 @@ INLINE_INHERITED_MEMB = NO
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
-FULL_PATH_NAMES = YES
+FULL_PATH_NAMES = NO
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user-defined part of the path. Stripping is
@@ -189,11 +189,12 @@ TAB_SIZE = 8
# will result in a user-defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.
-ALIASES = config{3}=
| \1 | \2 | \3 |
\
- configend= \
- "configstart=\param config Configuration string, see \ref config_strings. Permitted values:\n\n| Key | Value [Default] | Notes |
" \
+ALIASES = configend=
\
"configempty=\param config Configuration string, see \ref config_strings. No values currently permitted." \
- "errors=\returns zero on success and a non-zero error code on failure"
+ "errors=\returns zero on success and a non-zero error code on failure" \
+ "ex_ref{1}=\ref \1 \"\1\", available in the source tree as \c examples/c/\1" \
+ "config{3}=| \1 | \3 \2 |
" \
+ "configstart=\param config Configuration string, see \ref config_strings. Permitted values:\n\n| Key | Effect [Default] |
"
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
# sources only. Doxygen will then generate output that is more tailored for C.
@@ -399,7 +400,7 @@ HIDE_SCOPE_NAMES = NO
# will put a list of the files that are included by a file in the documentation
# of that file.
-SHOW_INCLUDE_FILES = YES
+SHOW_INCLUDE_FILES = NO
# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
# will list include files with double quotes in the documentation
@@ -489,13 +490,13 @@ ENABLED_SECTIONS =
# documentation can be controlled using \showinitializer or \hideinitializer
# command in the documentation regardless of this setting.
-MAX_INITIALIZER_LINES = 32
+MAX_INITIALIZER_LINES = 0
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
# at the bottom of the documentation of classes and structs. If set to YES the
# list will mention the files that were used to generate the documentation.
-SHOW_USED_FILES = YES
+SHOW_USED_FILES = NO
# If the sources in your project are distributed over multiple directories
# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
@@ -507,13 +508,13 @@ SHOW_DIRECTORIES = NO
# This will remove the Files entry from the Quick Index and from the
# Folder Tree View (if specified). The default is YES.
-SHOW_FILES = YES
+SHOW_FILES = NO
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
# Namespaces page. This will remove the Namespaces entry from the Quick Index
# and from the Folder Tree View (if specified). The default is YES.
-SHOW_NAMESPACES = YES
+SHOW_NAMESPACES = NO
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
# doxygen should invoke to get the current version for each file (typically from
@@ -594,8 +595,8 @@ WARN_LOGFILE = doxygen.log
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = src \
- ../include/wiredtiger.h
+INPUT = ../include/wiredtiger.h \
+ src
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
diff --git a/docs/src/basic-api.dox b/docs/src/basic-api.dox
index bf4323b2a56..15930f0e11a 100644
--- a/docs/src/basic-api.dox
+++ b/docs/src/basic-api.dox
@@ -1,10 +1,10 @@
/* vim: set filetype=c.doxygen : */
-/*! \page basic_api Getting Started with the WiredTiger API
+/*! \page basic_api Getting Started with the API
\dontinclude ex_access.c
-All applications that use WiredTiger will be structured roughly as follows. The code below is taken from the complete example program \ref ex_access.c "ex_access.c" which is available in the source tree as \c examples/c/ex_access.c.
+All applications that use WiredTiger will be structured roughly as follows. The code below is taken from the complete example program \ex_ref{ex_access.c}.
\section basic_connection Connecting to a database
@@ -34,7 +34,7 @@ This call creates a table called \c "access", configured to use strings for its
Now that we're sure we have a table, we open a cursor to perform some operations on it:
-\until }
+\until insert
Here, the string \c "table:access" specifies that we are opening the cursor on the table named \c "access" that we created above.
diff --git a/docs/src/command-line.dox b/docs/src/command-line.dox
index 4bb98f95e8f..c32bbc792f0 100644
--- a/docs/src/command-line.dox
+++ b/docs/src/command-line.dox
@@ -1,4 +1,4 @@
/* vim: set filetype=c.doxygen : */
-/*! \page command_line Command Line Interface to WiredTiger
+/*! \page command_line Command Line Interface
*/
diff --git a/docs/src/config-strings.dox b/docs/src/config-strings.dox
index f36cbce2789..b0cc31852d2 100644
--- a/docs/src/config-strings.dox
+++ b/docs/src/config-strings.dox
@@ -26,16 +26,20 @@ Keys are processed in order from left to right, with later settings overriding e
\section config_examples Code Samples
-The code below is taken from the complete example program \ref ex_config.c "ex_config.c" which is available in the source tree as \c examples/c/ex_config.c.
+The code below is taken from the complete example program \ex_ref{ex_config.c}.
\dontinclude ex_config.c
-\skip wiredtiger_open
-\until close
-
-- To open a connection to a database, creating it if it does not exist and set a cache size of 10MiB, pass
"create,cache_size=10M" to ::wiredtiger_open.
- - Create a table that uses C language strings for keys and values: pass
"keyfmt=S,valuefmt=S" to WT_SESSION::create_table.
-- Assign a name to a transaction for debugging purposes: pass
"name=mytxn" to WT_SESSION::begin_transaction.
-- Assign a priority to a transaction to avoid aborting: pass
"priority=100" to WT_SESSION::begin_transaction.
-
+Open a connection to a database, creating it if it does not exist and set a cache size of 10MiB:
+
+\skip wiredtiger_open
+\until != 0
+
+Create a table that uses C language strings for keys and values:
+
+\skipline create_table
+
+Assign a priority to a transaction to reduce aborts and give it a name for debugging:
+
+\skipline begin_transaction
*/
diff --git a/docs/src/cursors.dox b/docs/src/cursors.dox
index df3d629dbbf..f9d7f7227c0 100644
--- a/docs/src/cursors.dox
+++ b/docs/src/cursors.dox
@@ -1,6 +1,6 @@
/* vim: set filetype=c.doxygen : */
-/*! \page cursors WiredTiger Cursors
+/*! \page cursors Cursors
Most common operations in WiredTiger are performed using cursors. A cursor includes:
@@ -34,4 +34,19 @@ This is particularly useful with index cursors, because if all columns in the pr
\section cursor_ranges Restricting the Range of a Scan
XXX
+
+\section cursor_examples Code Samples
+
+The code below is taken from the complete example program \ex_ref{ex_cursor.c}.
+
+\dontinclude ex_cursor.c
+
+\skipline open_cursor
+
+\skipline open_cursor
+
+\skipline open_cursor
+
+\skipline open_cursor
+
*/
diff --git a/docs/src/examples.dox b/docs/src/examples.dox
index d510371cca8..45ed1cd84e1 100644
--- a/docs/src/examples.dox
+++ b/docs/src/examples.dox
@@ -10,13 +10,27 @@ Create, insert and access a simple table.
\example ex_config.c
Demonstrate how to configure some properties of the database and tables.
+\example ex_cursor.c
+
+\example ex_pack.c
+
+\example ex_process.c
+
\example ex_stat.c
Shows how to access database and table statistics.
\example ex_schema.c
Shows how to create column-oriented data and access individual columns.
+\example ex_thread.c
+Shows how to access a database with multiple threads.
+
+\example ex_transaction.c
+
\example ex_call_center.c
A more complex schema based on a call center example, showing how to map some
SQL constructs onto the WiredTiger API.
+
+\example ex_extending.c
+Shows how to extend WiredTiger with application-specific collations, extractors and cursor types.
*/
diff --git a/docs/src/extending.dox b/docs/src/extending.dox
index c79a0ce2b0a..44f69e5f524 100644
--- a/docs/src/extending.dox
+++ b/docs/src/extending.dox
@@ -19,4 +19,12 @@ XXX
\section extractors Custom Field Extractors
XXX
+
+\section extending_example Code Samples
+
+The code below is taken from the complete example program \ex_ref{ex_extending.c}.
+
+\dontinclude ex_extending.c
+\skip main
+\until ->close
*/
diff --git a/docs/src/packing.dox b/docs/src/packing.dox
index 5df7e903a59..3283757bad0 100644
--- a/docs/src/packing.dox
+++ b/docs/src/packing.dox
@@ -6,4 +6,12 @@ XXX What are WT_CURSOR::get_key, WT_CURSOR::get_value, WT_CURSOR::set_key and WT
- native C structs
- portability between programming languages
+
+\section config_examples Code Samples
+
+The code below is taken from the complete example program \ex_ref{ex_pack.c}.
+
+\dontinclude ex_pack.c
+\skip struct_size
+\until unpack
*/
diff --git a/docs/src/processes.dox b/docs/src/processes.dox
index 893b8aada2a..0a9c068008c 100644
--- a/docs/src/processes.dox
+++ b/docs/src/processes.dox
@@ -10,7 +10,7 @@ The server can be embedded in an application or run from the command line. To e
For details on running a standalone RPC server, see \ref command_line.
-\section processes_sharing Multiple Processes calling ::wiredtiger_open
+\section processes_sharing Opening Connections from Multiple Processes
When ::wiredtiger_open is called for a database, one of the following occurs:
@@ -19,4 +19,11 @@ When ::wiredtiger_open is called for a database, one of the following occurs:
# another process has the database open and is running the RPC server, in which case the opening process becomes a client.
# another process has the database open but is not running the RPC server, in which case the open fails.
e
+
+\section processes_example Code Samples
+
+The code below is taken from the complete example program \ex_ref{ex_process.c}.
+
+\dontinclude ex_process.c
+\skipline wiredtiger_open
*/
diff --git a/docs/src/schema.dox b/docs/src/schema.dox
index 8f8257239d2..c7f5efcbd3b 100644
--- a/docs/src/schema.dox
+++ b/docs/src/schema.dox
@@ -50,6 +50,26 @@ XXX
XXX
+\section schema_examples Code Samples
+
+The code below is taken from the complete example program \ex_ref{ex_schema.c}.
+
+\dontinclude ex_schema.c
+\skip C struct
+\until POP_RECORD
+
+\skip open_session
+\until conn->close
+
+The code below is taken from the complete example program \ex_ref{ex_call_center.c}.
+
+\dontinclude ex_call_center.c
+\skip home
+\until CALL
+
+\skip create_table
+\until conn->close
+
\section schema_advanced Advanced Schemas
- non-relational data such as multiple index keys per row
diff --git a/docs/src/threads.dox b/docs/src/threads.dox
index ba727a514e6..aaa7b035453 100644
--- a/docs/src/threads.dox
+++ b/docs/src/threads.dox
@@ -2,7 +2,14 @@
/*! \page threads Multithreading
-Just add WT_SESSION ;-)
-
WT_CONNECTION handles can be shared between threads, and applications should generally only open one connection per process. WT_SESSION and WT_CURSOR handles cannot be shared between threads: applications should open one WT_SESSION for each thread that accesses a database.
+
+\section threads_example Code Samples
+
+The code below is taken from the complete example program \ex_ref{ex_thread.c}.
+
+\dontinclude ex_thread.c
+\skip {
+\until conn->close
+
*/
diff --git a/docs/src/transactions.dox b/docs/src/transactions.dox
index 8c595f68f83..b38feb6b413 100644
--- a/docs/src/transactions.dox
+++ b/docs/src/transactions.dox
@@ -38,4 +38,12 @@ Recovery is run automatically during ::wiredtiger_open when required. See \ref
Recovery works by using a database log that contains a record of the actions of all transactions. Recovery first finds the last complete checkpoint, and then scans forward through the log from that point to determine which transactions committed after the checkpoint. All actions are rolled forward from the checkpoint so that the in-memory tree matches its state when the crash occurred. Then the "losing" transactions (those that did not commit) are rolled back to return the database to a consistent state.
This suggests the importance of regular checkpoints: they limit the amount of work required during recovery, which speeds up the ::wiredtiger_open call. See WT_SESSION::checkpoint for information about triggering checkpoints.
+
+\section transaction_example Code Samples
+
+The code below is taken from the complete example program \ex_ref{ex_transaction.c}.
+
+\dontinclude ex_transaction.c
+\skip begin_transaction
+\until commit
*/
diff --git a/docs/src/using.dox b/docs/src/using.dox
index e5ade136f0e..e2a2623c4ae 100644
--- a/docs/src/using.dox
+++ b/docs/src/using.dox
@@ -2,6 +2,8 @@
/*! \page using Using WiredTiger
+This section explains how to use WiredTiger by developing a sequence of example programs:
+
- \subpage basic_api
- \subpage config_strings
- \subpage packing
diff --git a/examples/c/Makefile b/examples/c/Makefile
index affd20e1aa7..f3c0e7de817 100644
--- a/examples/c/Makefile
+++ b/examples/c/Makefile
@@ -1,5 +1,8 @@
CC = gcc -W -Wall -I../../include # -Wno-unused -x c++
-OBJS = ex_access.o ex_call_center.o ex_config.o ex_hello.o ex_sequence.o ex_stat.o ex_schema.o ex_thread.o
+OBJS = \
+ ex_access.o ex_call_center.o ex_config.o ex_cursor.o ex_extending.o \
+ ex_hello.o ex_pack.o ex_process.o ex_schema.o ex_sequence.o ex_stat.o \
+ ex_thread.o ex_transaction.o
all: $(OBJS)
diff --git a/examples/c/ex_config.c b/examples/c/ex_config.c
index 3f54863765f..9c4481e9ff5 100644
--- a/examples/c/ex_config.c
+++ b/examples/c/ex_config.c
@@ -21,15 +21,17 @@ int main()
const char *key, *value;
if ((ret = wiredtiger_open(home, NULL,
- "create,cache_size=10000000", &conn)) != 0 ||
- (ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
+ "create,cache_size=10M", &conn)) != 0)
fprintf(stderr, "Error connecting to %s: %s\n",
home, wiredtiger_strerror(ret));
/* Note: further error checking omitted for clarity. */
+ ret = conn->open_session(conn, NULL, NULL, &session);
+
session->create_table(session, "access", "key_format=S,value_format=S");
- /* Open a cursor on the (virtual) configuration table. */
+ session->begin_transaction(session, "priority=100,name=mytxn");
+
ret = session->open_cursor(session, "config:", NULL, &cursor);
while ((ret = cursor->next(cursor)) == 0) {
@@ -39,6 +41,8 @@ int main()
printf("Got configuration value: %s = %s\n", key, value);
}
+ ret = session->commit_transaction(session);
+
ret = conn->close(conn, NULL);
return (ret);
diff --git a/examples/c/ex_cursor.c b/examples/c/ex_cursor.c
new file mode 100644
index 00000000000..5f4862a70e8
--- /dev/null
+++ b/examples/c/ex_cursor.c
@@ -0,0 +1,53 @@
+/*
+ * ex_cursor.c Copyright (c) 2010 WiredTiger, Inc. All rights reserved.
+ *
+ * This is an example demonstrating some cursor types and operations.
+ */
+
+#include
+#include
+
+#include
+
+const char *home = "WT_TEST";
+
+int main()
+{
+ int ret;
+ WT_CONNECTION *conn;
+ WT_SESSION *session;
+ WT_CURSOR *cursor;
+
+ /* Open a connection to the database, creating it if necessary. */
+ if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0)
+ fprintf(stderr, "Error connecting to %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ /* Open a session for the current thread's work. */
+ if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
+ fprintf(stderr, "Error opening a session on %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ ret = session->create_table(session, "map",
+ "key_format=r,value_format=5sii,"
+ "columns=(id,country,population,area)");
+
+ ret = session->open_cursor(session, "table:map", NULL, &cursor);
+ cursor->close(cursor, NULL);
+
+ ret = session->open_cursor(session, "table:map(country,population)", NULL, &cursor);
+ cursor->close(cursor, NULL);
+
+ ret = session->open_cursor(session, "table:", NULL, &cursor);
+ cursor->close(cursor, NULL);
+
+ ret = session->open_cursor(session, "statistics:", NULL, &cursor);
+ cursor->close(cursor, NULL);
+
+ /* Note: closing the connection implicitly closes open session(s). */
+ if ((ret = conn->close(conn, NULL)) != 0)
+ fprintf(stderr, "Error connecting to %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ return (ret);
+}
diff --git a/examples/c/ex_extending.c b/examples/c/ex_extending.c
new file mode 100644
index 00000000000..280ac44122f
--- /dev/null
+++ b/examples/c/ex_extending.c
@@ -0,0 +1,39 @@
+/*
+ * ex_extending.c Copyright (c) 2010 WiredTiger, Inc. All rights reserved.
+ *
+ * This is an example demonstrating ways to extend WiredTiger with extractors,
+ * collators and loadable modules.
+ */
+
+#include
+#include
+
+#include
+
+const char *home = "WT_TEST";
+
+int main()
+{
+ int ret;
+ WT_CONNECTION *conn;
+ WT_SESSION *session;
+
+ /* Open a connection to the database, creating it if necessary. */
+ if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0)
+ fprintf(stderr, "Error connecting to %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ /* Open a session for the current thread's work. */
+ if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
+ fprintf(stderr, "Error opening a session on %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ /* XXX Do some work... */
+
+ /* Note: closing the connection implicitly closes open session(s). */
+ if ((ret = conn->close(conn, NULL)) != 0)
+ fprintf(stderr, "Error connecting to %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ return (ret);
+}
diff --git a/examples/c/ex_pack.c b/examples/c/ex_pack.c
new file mode 100644
index 00000000000..69c34c9496b
--- /dev/null
+++ b/examples/c/ex_pack.c
@@ -0,0 +1,45 @@
+/*
+ * ex_pack.c Copyright (c) 2010 WiredTiger, Inc. All rights reserved.
+ *
+ * This is an example demonstrating some basic packing and unpacking.
+ */
+
+#include
+#include
+
+#include
+
+const char *home = "WT_TEST";
+
+int main()
+{
+ WT_CONNECTION *conn;
+ WT_SESSION *session;
+ char buf[50];
+ size_t size;
+ int i, j, k, ret;
+
+ /* Open a connection to the database, creating it if necessary. */
+ if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0)
+ fprintf(stderr, "Error connecting to %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ /* Open a session for the current thread's work. */
+ if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
+ fprintf(stderr, "Error opening a session on %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ size = wiredtiger_struct_size("iii", 42, 1000, -9);
+ if (size > sizeof (buf)) {
+ /* Allocate a bigger buffer. */
+ }
+ wiredtiger_struct_pack(buf, size, "iii", 42, 1000, -9);
+ wiredtiger_struct_unpack(buf, size, "iii", &i, &j, &k);
+
+ /* Note: closing the connection implicitly closes open session(s). */
+ if ((ret = conn->close(conn, NULL)) != 0)
+ fprintf(stderr, "Error connecting to %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ return (ret);
+}
diff --git a/examples/c/ex_process.c b/examples/c/ex_process.c
new file mode 100644
index 00000000000..ae69ad4a792
--- /dev/null
+++ b/examples/c/ex_process.c
@@ -0,0 +1,39 @@
+/*
+ * ex_process.c Copyright (c) 2010 WiredTiger, Inc. All rights reserved.
+ *
+ * This is an example demonstrating how to connect to a database from multiple
+ * processes.
+ */
+
+#include
+#include
+
+#include
+
+const char *home = "WT_TEST";
+
+int main()
+{
+ int ret;
+ WT_CONNECTION *conn;
+ WT_SESSION *session;
+
+ /* Open a connection to the database, creating it if necessary. */
+ if ((ret = wiredtiger_open(home, NULL, "create,share", &conn)) != 0)
+ fprintf(stderr, "Error connecting to %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ /* Open a session for the current thread's work. */
+ if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
+ fprintf(stderr, "Error opening a session on %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ /* XXX Do some work... */
+
+ /* Note: closing the connection implicitly closes open session(s). */
+ if ((ret = conn->close(conn, NULL)) != 0)
+ fprintf(stderr, "Error connecting to %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ return (ret);
+}
diff --git a/examples/c/ex_sequence.c b/examples/c/ex_sequence.c
index 1d0379e0a4d..904efb2d5d8 100644
--- a/examples/c/ex_sequence.c
+++ b/examples/c/ex_sequence.c
@@ -1,5 +1,5 @@
/*
- * ex_access.c Copyright (c) 2010 WiredTiger, Inc. All rights reserved.
+ * ex_sequence.c Copyright (c) 2010 WiredTiger, Inc. All rights reserved.
*
* This is an example demonstrating how to create and access a sequence.
*/
diff --git a/examples/c/ex_thread.c b/examples/c/ex_thread.c
index 7fce44e002b..0e1e277a114 100644
--- a/examples/c/ex_thread.c
+++ b/examples/c/ex_thread.c
@@ -11,6 +11,7 @@
#include
const char *home = "WT_TEST";
+#define NUM_THREADS 10
WT_CONNECTION *conn;
@@ -24,9 +25,7 @@ void *scan_thread(void *arg) {
ret = session->open_cursor(session, "table:access", NULL, &cursor);
/* Show all records. */
- for (ret = cursor->first(cursor);
- ret == 0;
- ret = cursor->next(cursor)) {
+ while ((ret = cursor->next(cursor)) == 0) {
ret = cursor->get_key(cursor, &key);
ret = cursor->get_value(cursor, &value);
@@ -40,7 +39,8 @@ int main()
{
WT_SESSION *session;
WT_CURSOR *cursor;
- int ret;
+ pthread_t threads[NUM_THREADS];
+ int i, ret;
if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0)
fprintf(stderr, "Error connecting to %s: %s\n",
@@ -57,8 +57,11 @@ int main()
ret = cursor->insert(cursor);
ret = session->close(session, NULL);
- /* XXX start threads */
- /* XXX join threads */
+ for (i = 0; i < NUM_THREADS; i++)
+ ret = pthread_create(&threads[i], NULL, scan_thread, NULL);
+
+ for (i = 0; i < NUM_THREADS; i++)
+ ret = pthread_join(threads[i], NULL);
ret = conn->close(conn, NULL);
diff --git a/examples/c/ex_transaction.c b/examples/c/ex_transaction.c
new file mode 100644
index 00000000000..5aa51abb7a6
--- /dev/null
+++ b/examples/c/ex_transaction.c
@@ -0,0 +1,39 @@
+/*
+ * ex_hello.c Copyright (c) 2010 WiredTiger, Inc. All rights reserved.
+ *
+ * This is an example demonstrating how to create and connect to a database.
+ */
+
+#include
+#include
+
+#include
+
+const char *home = "WT_TEST";
+
+int main()
+{
+ int ret;
+ WT_CONNECTION *conn;
+ WT_SESSION *session;
+
+ /* Open a connection to the database, creating it if necessary. */
+ if ((ret = wiredtiger_open(home, NULL, "create", &conn)) != 0)
+ fprintf(stderr, "Error connecting to %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ /* Open a session for the current thread's work. */
+ if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
+ fprintf(stderr, "Error opening a session on %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ session->begin_transaction(session, NULL);
+ session->commit_transaction(session);
+
+ /* Note: closing the connection implicitly closes open session(s). */
+ if ((ret = conn->close(conn, NULL)) != 0)
+ fprintf(stderr, "Error connecting to %s: %s\n",
+ home, wiredtiger_strerror(ret));
+
+ return (ret);
+}
diff --git a/include/wiredtiger.h b/include/wiredtiger.h
index c1bca08406f..f4a89ce6eba 100644
--- a/include/wiredtiger.h
+++ b/include/wiredtiger.h
@@ -698,7 +698,7 @@ const char *wiredtiger_version(int *majorp, int *minorp, int *patchp);
* \param format the data format, see ::wiredtiger_struct_pack
* \errors
*/
-int wiredtiger_struct_pack(void *buffer, int size, const char *format, ...);
+int wiredtiger_struct_pack(void *buffer, size_t size, const char *format, ...);
/*! Pack a structure into a buffer.
*
@@ -710,7 +710,7 @@ int wiredtiger_struct_pack(void *buffer, int size, const char *format, ...);
* \param ap the list of values to pack
* \errors
*/
-int wiredtiger_struct_packv(void *buffer, int size,
+int wiredtiger_struct_packv(void *buffer, size_t size,
const char *format, va_list ap);
/*! Calculate the size required to pack a structure.
@@ -723,7 +723,7 @@ int wiredtiger_struct_packv(void *buffer, int size,
* \returns the number of bytes needed for the matching call to
* ::wiredtiger_struct_pack
*/
-int wiredtiger_struct_size(const char *format, ...);
+size_t wiredtiger_struct_size(const char *format, ...);
/*! Calculate the size required to pack a structure.
*
@@ -734,7 +734,7 @@ int wiredtiger_struct_size(const char *format, ...);
* \returns the number of bytes needed for the matching call to
* ::wiredtiger_struct_pack
*/
-int wiredtiger_struct_sizev(const char *format, va_list ap);
+size_t wiredtiger_struct_sizev(const char *format, va_list ap);
/*! Unpack a structure from a buffer.
*
@@ -745,7 +745,7 @@ int wiredtiger_struct_sizev(const char *format, va_list ap);
* \param format the data format, see ::wiredtiger_struct_pack
* \errors
*/
-int wiredtiger_struct_unpack(const void *buffer, int size,
+int wiredtiger_struct_unpack(const void *buffer, size_t size,
const char *format, ...);
/*! Unpack a structure from a buffer.
@@ -758,7 +758,7 @@ int wiredtiger_struct_unpack(const void *buffer, int size,
* \param ap the list of locations where values are unpacked
* \errors
*/
-int wiredtiger_struct_unpackv(const void *buffer, int size,
+int wiredtiger_struct_unpackv(const void *buffer, size_t size,
const char *format, va_list ap);
/*! Entry point to an extension, implemented by loadable modules.
diff --git a/lang/python/src/server.py b/lang/python/src/server.py
new file mode 100644
index 00000000000..c8fcaa7f889
--- /dev/null
+++ b/lang/python/src/server.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+
+# WiredTiger Python RPC server for testing and tutorials.
+# Copyright (c) 2011 WiredTiger, Inc. All rights reserved.
+
+import sys
+
+from wiredtiger.service import WiredTiger
+from wiredtiger.service.ttypes import *
+
+from wiredtiger.impl import *
+
+from thrift.transport import TSocket
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+from thrift.server import TServer
+
+class WiredTigerHandler:
+
+handler = WiredTigerHandler()
+processor = WiredTiger.Processor(handler)
+transport = TSocket.TServerSocket(9090)
+tfactory = TTransport.TBufferedTransportFactory()
+pfactory = TBinaryProtocol.TBinaryProtocolFactory()
+
+server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
+
+# We could do one of these for a multithreaded server
+#server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
+#server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)
+
+print 'Starting the server...'
+server.serve()
+print 'done.'
diff --git a/lang/python/src/wiredtiger/impl/__init__.py b/lang/python/src/wiredtiger/impl/__init__.py
new file mode 100644
index 00000000000..cf6e71fb2ac
--- /dev/null
+++ b/lang/python/src/wiredtiger/impl/__init__.py
@@ -0,0 +1,212 @@
+# WiredTiger API implementation
+
+'''
+WiredTiger Python API implementation.
+'''
+
+import struct
+from urlparse import urlparse
+from wiredtiger import pack, unpack
+from wiredtiger.util import parse_config
+
+# Import the BDB symbols with the 'db.' prefix, it avoids polluting the
+# namespace of this package
+from bsddb3 import db
+
+class Table:
+ def __init__(self, db, name, key_format='u', value_format='u', columns=(,), column_sets=(,), indices=(,)):
+ self.db = db
+ self.name = name
+ self.key_format = key_format
+ self.value_format = value_format
+ self.columns = columns
+ self.column_sets = column_sets
+ self.indices = indices
+
+ def close(self):
+ self.db.close(db.DB_NOSYNC)
+
+ def check_schema(self, key_format='u', value_format='u', columns=(,), column_sets=(,), indices=(,)):
+ if (self.key_format != key_format or
+ self.value_format != value_format or
+ self.columns != columns or
+ self.column_sets != column_sets or
+ self.indices != indices):
+ raise 'Schemas don\'t match for table "' + self.name + '"'
+
+class Cursor:
+ def __init__(self, session, table):
+ self.session = session
+ self.table = table
+ self.key_format = table.key_format
+ self.value_format = table.value_format
+ self.dbc = table.db.cursor()
+
+ def close(self, config=''):
+ self.dbc.close()
+ self.session.cursors.remove(self)
+
+ def get_key(self):
+ return unpack(self.key_format, self.key)
+
+ def get_value(self):
+ return unpack(self.key_format, self.value)
+
+ def set_key(self, *args):
+ self.key = pack(self.key_format, *args)
+
+ def set_value(self, *args):
+ self.value = pack(self.value_format, *args)
+
+ def first(self):
+ self.key, self.value = self.dbc.first()
+
+ def last(self):
+ self.key, self.value = self.dbc.last()
+
+ def next(self):
+ self.key, self.value = self.dbc.next()
+
+ def prev(self):
+ self.key, self.value = self.dbc.prev()
+
+ def search(self):
+ searchkey = self.key
+ self.key, self.value = self.dbc.set_range(self.key)
+ return (self.key == searchkey)
+
+ def insert(self):
+ self.dbc.put(self.key, self.value)
+ return self.key
+
+ def update(self):
+ self.dbc.put(self.key, self.value, db.DB_CURRENT)
+
+ def delete(self):
+ self.dbc.delete()
+
+
+class Session:
+ def __init__(self, conn, id):
+ self.conn = conn
+ self.cursors = []
+ self.tables = {'schema' : conn.schematab}
+
+ def _close_cursors(self):
+ # Work on a copy of the list because Cursor.close removes itself
+ for c in self.cursors[:]:
+ c.close()
+
+ def close(self, config=''):
+ self._close_cursors()
+ self.conn.sessions.remove(self)
+
+ def open_cursor(self, uri, config=''):
+ c = self.conn._open_cursor(self, uri, config)
+ self.cursors.append(c)
+ return c
+
+ def dup_cursor(self, c, config=''):
+ dupc = c.dup()
+ self.cursors.append(dupc)
+ return dupc
+
+ def _open_table(self, name):
+ schema_cur = Cursor(self, self.conn.schematab)
+ schema_cur.set_key(name)
+ if schema_cur.search():
+ k, v, c, cset, idx = schema_cur.get_value()
+ c = tuple(parse_config(c))
+ cset = tuple(parse_config(cset))
+ idx = tuple(parse_config(idx))
+ self.tables[name] = Table(k, v, c, cset, idx)
+
+ def create_table(self, name, config=''):
+ schema = {}
+ for k, v in parse_config(config):
+ if k in ('key_format', 'value_format', 'columns'):
+ schema[k] = v
+ elif k == 'column_set':
+ schema['column_sets'] = schema.get('column_sets', (,)) + (v,)
+ elif k == 'index':
+ schema['indices'] = schema.get('indices', (,)) + (v,)
+ else:
+ raise 'Unknown configuration "' + k + '"'
+ if name in self.tables:
+ self.tables[name].check_schema(**schema)
+ # XXX else try to open the table and retry
+
+ def rename_table(self, oldname, newname, config=''):
+ pass
+
+ def drop_table(self, name, config=''):
+ pass
+
+ def truncate_table(self, name, start=None, end=None, config=''):
+ pass
+
+ def verify_table(self, name, config=''):
+ pass
+
+ def begin_transaction(self, config=''):
+ if self.cursors:
+ raise 'Transactions cannot be started with cursors open'
+
+ def commit_transaction(self):
+ self._close_cursors()
+ pass
+
+ def rollback_transaction(self):
+ self._close_cursors()
+ pass
+
+ def checkpoint(self, config=''):
+ pass
+
+
+class Connection:
+ def __init__(self, uri, config=''):
+ url = urlparse(uri)
+ parts = url[1].split(':')
+ self.host = parts[0]
+ if len(parts) > 1:
+ port = int(parts[1])
+ else:
+ port = 9090
+
+ self.home = url[2]
+ self.sessions = []
+
+ self.env = db.DBEnv();
+ self.env.open(self.home,
+ db.DB_PRIVATE | db.DB_CREATE | db.DB_INIT_MPOOL | db.DB_THREAD)
+ schemadb = db.DB(self.env);
+ schemadb.open("__wt_schema.db", None, db.DB_BTREE, db.DB_CREATE)
+
+ # The schema of the schema table.
+ self.schematab = Table(schemadb, key_format='S', value_format='SSSSS',
+ columns=('name', 'key_format', 'value_format', 'column_sets', 'indices'))
+
+ def close(self, config=''):
+ # Work on a copy of the list because Session.close removes itself
+ for s in self.sessions[:]:
+ s.close()
+ self.schematab.close()
+ self.env.close()
+
+ def version(self):
+ return ("WiredTiger Python API 0.0.1", 0, 0, 1)
+
+ def open_session(self, config=''):
+ s = Session(self, config)
+ self.sessions.append(s)
+ return s
+
+ def _open_cursor(self, session, uri, config):
+ if uri == 'table:':
+ return Cursor(session, self.schematab)
+ elif uri.startswith('table:'):
+ # XXX projections
+ return Cursor(session, session._get_table(uri[6:]))
+ # XXX application-specific cursor types?
+ raise 'Unknown cursor type for "' + uri + '"'
diff --git a/lang/python/src/wiredtiger/util.py b/lang/python/src/wiredtiger/util.py
new file mode 100644
index 00000000000..ad4281ffc7c
--- /dev/null
+++ b/lang/python/src/wiredtiger/util.py
@@ -0,0 +1,6 @@
+import re
+
+def parse_config(config):
+ for l in re.findall(r'(?:\(.*?\)|[^,])+', config):
+ for k, v in (l+"=yes").split('=')[0:2]:
+ yield (k.strip(), v.strip())
diff --git a/src/api/pack.c b/src/api/pack.c
index 4a100b94ade..06c2c68dcbb 100644
--- a/src/api/pack.c
+++ b/src/api/pack.c
@@ -2,22 +2,22 @@
#include "wiredtiger.h"
-int wiredtiger_struct_sizev(const char *fmt, va_list ap)
+size_t wiredtiger_struct_sizev(const char *fmt, va_list ap)
{
return 0;
}
-int wiredtiger_struct_packv(void *buffer, int size, const char *fmt, va_list ap)
+int wiredtiger_struct_packv(void *buffer, size_t size, const char *fmt, va_list ap)
{
return 0;
}
-int wiredtiger_struct_unpackv(const void *buffer, int size, const char *fmt, va_list ap)
+int wiredtiger_struct_unpackv(const void *buffer, size_t size, const char *fmt, va_list ap)
{
return 0;
}
-int wiredtiger_struct_size(const char *fmt, ...)
+size_t wiredtiger_struct_size(const char *fmt, ...)
{
va_list ap;
@@ -25,7 +25,7 @@ int wiredtiger_struct_size(const char *fmt, ...)
return wiredtiger_struct_sizev(fmt, ap);
}
-int wiredtiger_struct_pack(void *buffer, int size, const char *fmt, ...)
+int wiredtiger_struct_pack(void *buffer, size_t size, const char *fmt, ...)
{
va_list ap;
@@ -33,7 +33,7 @@ int wiredtiger_struct_pack(void *buffer, int size, const char *fmt, ...)
return wiredtiger_struct_packv(buffer, size, fmt, ap);
}
-int wiredtiger_struct_unpack(const void *buffer, int size, const char *fmt, ...)
+int wiredtiger_struct_unpack(const void *buffer, size_t size, const char *fmt, ...)
{
va_list ap;