/* * __curds_update -- * WT_CURSOR.update method for the data-source cursor type. */ static int __curds_update(WT_CURSOR *cursor) { WT_CURSOR *source; WT_DECL_RET; WT_SESSION_IMPL *session; source = ((WT_CURSOR_DATA_SOURCE *)cursor)->source; CURSOR_UPDATE_API_CALL(cursor, session, update); WT_STAT_CONN_INCR(session, cursor_update); WT_STAT_DATA_INCR(session, cursor_update); WT_STAT_DATA_INCRV(session, cursor_update_bytes, cursor->value.size); WT_ERR(__curds_txn_enter(session, true)); WT_ERR(__curds_key_set(cursor)); WT_ERR(__curds_value_set(cursor)); ret = __curds_cursor_resolve(cursor, source->update(source)); err: __curds_txn_leave(session); CURSOR_UPDATE_API_END(session, ret); return (ret); }
/* * Append to a table in a "racy" fashion - that is attempt to insert the * same record another thread is likely to also be inserting. */ void * thread_insert_race(void *arg) { TEST_OPTS *opts; WT_CONNECTION *conn; WT_CURSOR *cursor; WT_SESSION *session; uint64_t i, value; int ret; opts = (TEST_OPTS *)arg; conn = opts->conn; testutil_check(conn->open_session(conn, NULL, NULL, &session)); testutil_check(session->open_cursor( session, opts->uri, NULL, NULL, &cursor)); printf("Running insert thread\n"); for (i = 0; i < opts->nrecords; ++i) { testutil_check( session->begin_transaction(session, "isolation=snapshot")); cursor->set_key(cursor, 1); testutil_check(cursor->search(cursor)); testutil_check(cursor->get_value(cursor, &value)); cursor->set_key(cursor, 1); cursor->set_value(cursor, value + 1); if ((ret = cursor->update(cursor)) != 0) { if (ret == WT_ROLLBACK) { testutil_check(session->rollback_transaction( session, NULL)); i--; continue; } printf("Error in update: %d\n", ret); } testutil_check(session->commit_transaction(session, NULL)); if (i % 10000 == 0) { printf("insert: %" PRIu64 "\r", i); fflush(stdout); } } if (i > 10000) printf("\n"); opts->running = false; return (NULL); }
int transaction_ops(WT_CONNECTION *conn, WT_SESSION *session) { WT_CURSOR *cursor; int ret; /*! [transaction commit/rollback] */ ret = session->open_cursor(session, "table:mytable", NULL, NULL, &cursor); ret = session->begin_transaction(session, 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->set_key(cursor, "key"); cursor->set_value(cursor, "value"); switch (ret = cursor->update(cursor)) { case 0: /* Update success */ ret = session->commit_transaction(session, NULL); /* * The commit_transaction call resets all open cursors. * If commit_transaction fails, the transaction was rolled-back. */ break; case WT_DEADLOCK: /* Update conflict */ default: /* Other error */ ret = session->rollback_transaction(session, 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(cursor); /*! [transaction isolation] */ /* A single transaction configured for snapshot isolation. */ ret = session->open_cursor(session, "table:mytable", NULL, NULL, &cursor); ret = session->begin_transaction(session, "isolation=snapshot"); cursor->set_key(cursor, "some-key"); cursor->set_value(cursor, "some-value"); ret = cursor->update(cursor); ret = session->commit_transaction(session, NULL); /*! [transaction isolation] */ /*! [session isolation configuration] */ /* Open a session configured for read-uncommitted isolation. */ ret = conn->open_session( conn, NULL, "isolation=read_uncommitted", &session); /*! [session isolation configuration] */ /*! [session isolation re-configuration] */ /* Re-configure a session for snapshot isolation. */ ret = session->reconfigure(session, "isolation=snapshot"); /*! [session isolation re-configuration] */ return (ret); }
int cursor_ops(WT_SESSION *session) { WT_CURSOR *cursor; int ret; /*! [Open a cursor] */ ret = session->open_cursor( session, "table:mytable", NULL, NULL, &cursor); /*! [Open a cursor] */ /*! [Open a cursor on the metadata] */ ret = session->open_cursor( session, "metadata:", NULL, NULL, &cursor); /*! [Open a cursor on the metadata] */ { WT_CURSOR *duplicate; const char *key = "some key"; /*! [Duplicate a cursor] */ ret = session->open_cursor( session, "table:mytable", NULL, NULL, &cursor); cursor->set_key(cursor, key); ret = cursor->search(cursor); /* Duplicate the cursor. */ ret = session->open_cursor(session, NULL, cursor, NULL, &duplicate); /*! [Duplicate a cursor] */ } { WT_CURSOR *overwrite_cursor; const char *key = "some key", *value = "some value"; /*! [Reconfigure a cursor] */ ret = session->open_cursor( session, "table:mytable", NULL, NULL, &cursor); cursor->set_key(cursor, key); /* Reconfigure the cursor to overwrite the record. */ ret = session->open_cursor( session, NULL, cursor, "overwrite", &overwrite_cursor); ret = cursor->close(cursor); overwrite_cursor->set_value(overwrite_cursor, value); ret = overwrite_cursor->insert(cursor); /*! [Reconfigure a cursor] */ } { /*! [boolean configuration string example] */ ret = session->open_cursor(session, "table:mytable", NULL, "overwrite", &cursor); ret = session->open_cursor(session, "table:mytable", NULL, "overwrite=true", &cursor); ret = session->open_cursor(session, "table:mytable", NULL, "overwrite=1", &cursor); /*! [boolean configuration string example] */ } { /*! [open a named checkpoint] */ ret = session->open_cursor(session, "table:mytable", NULL, "checkpoint=midnight", &cursor); /*! [open a named checkpoint] */ } { /*! [open the default checkpoint] */ ret = session->open_cursor(session, "table:mytable", NULL, "checkpoint=WiredTigerCheckpoint", &cursor); /*! [open the default checkpoint] */ } { /*! [Get the cursor's string key] */ const char *key; /* Get the cursor's string key. */ ret = cursor->get_key(cursor, &key); /*! [Get the cursor's string key] */ } { /*! [Set the cursor's string key] */ /* Set the cursor's string key. */ const char *key = "another key"; cursor->set_key(cursor, key); /*! [Set the cursor's string key] */ } { /*! [Get the cursor's record number key] */ uint64_t recno; /* Get the cursor's record number key. */ ret = cursor->get_key(cursor, &recno); /*! [Get the cursor's record number key] */ } { /*! [Set the cursor's record number key] */ uint64_t recno = 37; /* Set the cursor's record number key. */ cursor->set_key(cursor, recno); /*! [Set the cursor's record number key] */ } { /*! [Get the cursor's composite key] */ /* Get the cursor's "SiH" format composite key. */ const char *first; int32_t second; uint16_t third; cursor->get_key(cursor, &first, &second, &third); /*! [Get the cursor's composite key] */ } { /*! [Set the cursor's composite key] */ /* Set the cursor's "SiH" format composite key. */ cursor->set_key(cursor, "first", (int32_t)5, (uint16_t)7); /*! [Set the cursor's composite key] */ } { /*! [Get the cursor's string value] */ const char *value; /* Get the cursor's string value. */ ret = cursor->get_value(cursor, &value); /*! [Get the cursor's string value] */ } { /*! [Set the cursor's string value] */ /* Set the cursor's string value. */ const char *value = "another value"; cursor->set_value(cursor, value); /*! [Set the cursor's string value] */ } { /*! [Get the cursor's raw value] */ WT_ITEM value; /* Get the cursor's raw value. */ ret = cursor->get_value(cursor, &value); /*! [Get the cursor's raw value] */ } { /*! [Set the cursor's raw value] */ WT_ITEM value; /* Set the cursor's raw value. */ value.data = "another value"; value.size = strlen("another value"); cursor->set_value(cursor, &value); /*! [Set the cursor's raw value] */ } /*! [Return the next record] */ ret = cursor->next(cursor); /*! [Return the next record] */ /*! [Return the previous record] */ ret = cursor->prev(cursor); /*! [Return the previous record] */ /*! [Reset the cursor] */ ret = cursor->reset(cursor); /*! [Reset the cursor] */ { WT_CURSOR *other = NULL; /*! [Cursor comparison] */ int compare; ret = cursor->compare(cursor, other, &compare); 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] */ const char *key = "some key"; cursor->set_key(cursor, key); ret = cursor->search(cursor); /*! [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. */ const char *key = "some key", *value = "some value"; ret = session->open_cursor( session, "table:mytable", NULL, NULL, &cursor); cursor->set_key(cursor, key); cursor->set_value(cursor, value); ret = cursor->insert(cursor); /*! [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. */ const char *key = "some key", *value = "some value"; ret = session->open_cursor( session, "table:mytable", NULL, "overwrite=false", &cursor); cursor->set_key(cursor, key); cursor->set_value(cursor, value); ret = cursor->insert(cursor); /*! [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. */ uint64_t recno; const char *value = "some value"; ret = session->open_cursor( session, "table:mytable", NULL, "append", &cursor); cursor->set_value(cursor, value); ret = cursor->insert(cursor); if (ret == 0) ret = cursor->get_key(cursor, &recno); /*! [Insert a new record and assign a record number] */ } { /*! [Update an existing record or insert a new record] */ const char *key = "some key", *value = "some value"; ret = session->open_cursor( session, "table:mytable", NULL, NULL, &cursor); cursor->set_key(cursor, key); cursor->set_value(cursor, value); ret = cursor->update(cursor); /*! [Update an existing record or insert a new record] */ } { /*! [Update an existing record and fail if DNE] */ const char *key = "some key", *value = "some value"; ret = session->open_cursor( session, "table:mytable", NULL, "overwrite=false", &cursor); cursor->set_key(cursor, key); cursor->set_value(cursor, value); ret = cursor->update(cursor); /*! [Update an existing record and fail if DNE] */ } { /*! [Remove a record] */ const char *key = "some key"; ret = session->open_cursor( session, "table:mytable", NULL, NULL, &cursor); cursor->set_key(cursor, key); ret = cursor->remove(cursor); /*! [Remove a record] */ } { /*! [Remove a record and fail if DNE] */ const char *key = "some key"; ret = session->open_cursor( session, "table:mytable", NULL, "overwrite=false", &cursor); cursor->set_key(cursor, key); ret = cursor->remove(cursor); /*! [Remove a record and fail if DNE] */ } { /*! [Display an error] */ const char *key = "non-existent key"; cursor->set_key(cursor, key); if ((ret = cursor->remove(cursor)) != 0) { fprintf(stderr, "cursor.remove: %s\n", wiredtiger_strerror(ret)); return (ret); } /*! [Display an error] */ } /*! [Close the cursor] */ ret = cursor->close(cursor); /*! [Close the cursor] */ return (ret); }
int session_ops(WT_SESSION *session) { int ret; /*! [Reconfigure a session] */ ret = session->reconfigure(session, "isolation=snapshot"); /*! [Reconfigure a session] */ /*! [Create a table] */ ret = session->create(session, "table:mytable", "key_format=S,value_format=S"); /*! [Create a table] */ ret = session->drop(session, "table:mytable", NULL); /*! [Create a column-store table] */ ret = session->create(session, "table:mytable", "key_format=r,value_format=S"); /*! [Create a column-store table] */ ret = session->drop(session, "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(session, "table:mytable", "key_format=r,value_format=SiH," "columns=(id,department,salary,year-started)"); /*! [Create a table with columns] */ ret = session->drop(session, "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 #ifdef's to avoid running it. */ #ifdef MIGHT_NOT_RUN /*! [Create a bzip2 compressed table] */ ret = session->create(session, "table:mytable", "block_compressor=bzip2,key_format=S,value_format=S"); /*! [Create a bzip2 compressed table] */ ret = session->drop(session, "table:mytable", NULL); /*! [Create a snappy compressed table] */ ret = session->create(session, "table:mytable", "block_compressor=snappy,key_format=S,value_format=S"); /*! [Create a snappy compressed table] */ ret = session->drop(session, "table:mytable", NULL); /*! [Create a zlib compressed table] */ ret = session->create(session, "table:mytable", "block_compressor=zlib,key_format=S,value_format=S"); /*! [Create a zlib compressed table] */ ret = session->drop(session, "table:mytable", NULL); #endif /*! [Configure checksums to uncompressed] */ ret = session->create(session, "table:mytable", "key_format=S,value_format=S,checksum=uncompressed"); /*! [Configure checksums to uncompressed] */ ret = session->drop(session, "table:mytable", NULL); /*! [Configure dictionary compression on] */ ret = session->create(session, "table:mytable", "key_format=S,value_format=S,dictionary=1000"); /*! [Configure dictionary compression on] */ ret = session->drop(session, "table:mytable", NULL); /*! [Configure key prefix compression off] */ ret = session->create(session, "table:mytable", "key_format=S,value_format=S,prefix_compression=false"); /*! [Configure key prefix compression off] */ ret = session->drop(session, "table:mytable", NULL); #ifdef MIGHT_NOT_RUN /* Requires sync_file_range */ /*! [os_cache_dirty_max configuration] */ ret = session->create( session, "table:mytable", "os_cache_dirty_max=500MB"); /*! [os_cache_dirty_max configuration] */ ret = session->drop(session, "table:mytable", NULL); /* Requires posix_fadvise */ /*! [os_cache_max configuration] */ ret = session->create(session, "table:mytable", "os_cache_max=1GB"); /*! [os_cache_max configuration] */ ret = session->drop(session, "table:mytable", NULL); #endif /*! [Configure block_allocation] */ ret = session->create(session, "table:mytable", "key_format=S,value_format=S,block_allocation=first"); /*! [Configure block_allocation] */ ret = session->drop(session, "table:mytable", NULL); /*! [Create a cache-resident object] */ ret = session->create(session, "table:mytable", "key_format=r,value_format=S,cache_resident=true"); /*! [Create a cache-resident object] */ ret = session->drop(session, "table:mytable", NULL); { /* Create a table for the session operations. */ ret = session->create( session, "table:mytable", "key_format=S,value_format=S"); /*! [Compact a table] */ ret = session->compact(session, "table:mytable", NULL); /*! [Compact a table] */ /*! [Rename a table] */ ret = session->rename(session, "table:old", "table:new", NULL); /*! [Rename a table] */ /*! [Salvage a table] */ ret = session->salvage(session, "table:mytable", NULL); /*! [Salvage a table] */ /*! [Truncate a table] */ ret = session->truncate(session, "table:mytable", NULL, NULL, NULL); /*! [Truncate a table] */ { /* * Insert a pair of keys so we can truncate a range. */ WT_CURSOR *cursor; ret = session->open_cursor( session, "table:mytable", NULL, NULL, &cursor); cursor->set_key(cursor, "June01"); cursor->set_value(cursor, "value"); ret = cursor->update(cursor); cursor->set_key(cursor, "June30"); cursor->set_value(cursor, "value"); ret = cursor->update(cursor); cursor->close(cursor); { /*! [Truncate a range] */ WT_CURSOR *start, *stop; ret = session->open_cursor( session, "table:mytable", NULL, NULL, &start); start->set_key(start, "June01"); ret = start->search(start); ret = session->open_cursor( session, "table:mytable", NULL, NULL, &stop); stop->set_key(stop, "June30"); ret = stop->search(stop); ret = session->truncate(session, NULL, start, stop, NULL); /*! [Truncate a range] */ } } /*! [Upgrade a table] */ ret = session->upgrade(session, "table:mytable", NULL); /*! [Upgrade a table] */ /*! [Verify a table] */ ret = session->verify(session, "table:mytable", NULL); /*! [Verify a table] */ /*! [Drop a table] */ ret = session->drop(session, "table:mytable", NULL); /*! [Drop a table] */ } /*! [Close a session] */ ret = session->close(session, NULL); /*! [Close a session] */ return (ret); }
int transaction_ops(WT_CONNECTION *conn, WT_SESSION *session) { WT_CURSOR *cursor; int ret; /*! [transaction commit/rollback] */ /* * Cursors may be opened before or after the transaction begins, and in * either case, subsequent operations are included in the transaction. * Opening cursors before the transaction begins allows applications to * cache cursors and use them for multiple operations. */ ret = session->open_cursor(session, "table:mytable", NULL, NULL, &cursor); ret = session->begin_transaction(session, NULL); cursor->set_key(cursor, "key"); cursor->set_value(cursor, "value"); switch (ret = cursor->update(cursor)) { case 0: /* Update success */ ret = session->commit_transaction(session, NULL); /* * If commit_transaction succeeds, cursors remain positioned; if * commit_transaction fails, the transaction was rolled-back and * and all cursors are reset. */ break; case WT_ROLLBACK: /* Update conflict */ default: /* Other error */ ret = session->rollback_transaction(session, NULL); /* The rollback_transaction call resets all cursors. */ break; } /* * Cursors remain open and may be used for multiple transactions. */ /*! [transaction commit/rollback] */ ret = cursor->close(cursor); /*! [transaction isolation] */ /* A single transaction configured for snapshot isolation. */ ret = session->open_cursor(session, "table:mytable", NULL, NULL, &cursor); ret = session->begin_transaction(session, "isolation=snapshot"); cursor->set_key(cursor, "some-key"); cursor->set_value(cursor, "some-value"); ret = cursor->update(cursor); ret = session->commit_transaction(session, NULL); /*! [transaction isolation] */ /*! [session isolation configuration] */ /* Open a session configured for read-uncommitted isolation. */ ret = conn->open_session( conn, NULL, "isolation=read_uncommitted", &session); /*! [session isolation configuration] */ /*! [session isolation re-configuration] */ /* Re-configure a session for snapshot isolation. */ ret = session->reconfigure(session, "isolation=snapshot"); /*! [session isolation re-configuration] */ { /*! [transaction pinned range] */ /* Check the transaction ID range pinned by the session handle. */ uint64_t range; ret = session->transaction_pinned_range(session, &range); /*! [transaction pinned range] */ } return (ret); }
void worker(CONFIG *cfg, uint32_t worker_type) { WT_CONNECTION *conn; WT_SESSION *session; WT_CURSOR *cursor; const char *op_name = "search"; char *data_buf, *key_buf, *value; int ret, op_ret; uint64_t next_incr, next_val; session = NULL; data_buf = key_buf = NULL; op_ret = 0; conn = cfg->conn; key_buf = calloc(cfg->key_sz + 1, 1); if (key_buf == NULL) { lprintf(cfg, ret = ENOMEM, 0, "Populate key buffer"); goto err; } if (worker_type == WORKER_INSERT || worker_type == WORKER_UPDATE) { data_buf = calloc(cfg->data_sz, 1); if (data_buf == NULL) { lprintf(cfg, ret = ENOMEM, 0, "Populate data buffer"); goto err; } memset(data_buf, 'a', cfg->data_sz - 1); } if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) { lprintf(cfg, ret, 0, "open_session failed in read thread"); goto err; } if ((ret = session->open_cursor(session, cfg->uri, NULL, NULL, &cursor)) != 0) { lprintf(cfg, ret, 0, "open_cursor failed in read thread"); goto err; } while (g_running) { /* Get a value in range, avoid zero. */ if (worker_type == WORKER_INSERT) next_incr = ATOMIC_ADD(g_nins_ops, 1); if (!F_ISSET(cfg, PERF_RAND_WORKLOAD) && worker_type == WORKER_INSERT) next_val = cfg->icount + next_incr; else next_val = wtperf_rand(cfg); /* * If the workload is started without a populate phase we * rely on at least one insert to get a valid item id. */ if (worker_type != WORKER_INSERT && wtperf_value_range(cfg) < next_val) continue; sprintf(key_buf, "%0*" PRIu64, cfg->key_sz, next_val); cursor->set_key(cursor, key_buf); switch(worker_type) { case WORKER_READ: op_name = "read"; op_ret = cursor->search(cursor); if (F_ISSET(cfg, PERF_RAND_WORKLOAD) && op_ret == WT_NOTFOUND) op_ret = 0; if (op_ret == 0) ++g_nread_ops; break; case WORKER_INSERT_RMW: op_name="insert_rmw"; op_ret = cursor->search(cursor); if (op_ret != WT_NOTFOUND) break; /* Fall through */ case WORKER_INSERT: op_name = "insert"; cursor->set_value(cursor, data_buf); op_ret = cursor->insert(cursor); if (F_ISSET(cfg, PERF_RAND_WORKLOAD) && op_ret == WT_DUPLICATE_KEY) op_ret = 0; if (op_ret != 0) ++g_nfailedins_ops; break; case WORKER_UPDATE: op_name = "update"; op_ret = cursor->search(cursor); if (op_ret == 0) { cursor->get_value(cursor, &value); memcpy(data_buf, value, cfg->data_sz); if (data_buf[0] == 'a') data_buf[0] = 'b'; else data_buf[0] = 'a'; cursor->set_value(cursor, data_buf); op_ret = cursor->update(cursor); } if (F_ISSET(cfg, PERF_RAND_WORKLOAD) && op_ret == WT_NOTFOUND) op_ret = 0; if (op_ret == 0) ++g_nupdate_ops; break; default: lprintf(cfg, EINVAL, 0, "Invalid worker type"); goto err; } /* Report errors and continue. */ if (op_ret != 0) lprintf(cfg, op_ret, 0, "%s failed for: %s", op_name, key_buf); else ++g_nworker_ops; } err: if (ret != 0) ++g_threads_quit; if (session != NULL) session->close(session, NULL); if (data_buf != NULL) free(data_buf); if (key_buf != NULL) free(key_buf); }
int cursor_ops(WT_SESSION *session) { WT_CURSOR *cursor; int ret; /*! [Open a cursor] */ ret = session->open_cursor( session, "table:mytable", NULL, NULL, &cursor); /*! [Open a cursor] */ { WT_CURSOR *duplicate; const char *key = "some key"; /*! [Duplicate a cursor] */ ret = session->open_cursor( session, "table:mytable", NULL, NULL, &cursor); cursor->set_key(cursor, key); ret = cursor->search(cursor); /* Duplicate the cursor. */ ret = session->open_cursor(session, NULL, cursor, NULL, &duplicate); /*! [Duplicate a cursor] */ } { WT_CURSOR *overwrite_cursor; const char *key = "some key", *value = "some value"; /*! [Reconfigure a cursor] */ ret = session->open_cursor( session, "table:mytable", NULL, NULL, &cursor); cursor->set_key(cursor, key); /* Reconfigure the cursor to overwrite the record. */ ret = session->open_cursor( session, NULL, cursor, "overwrite=true", &overwrite_cursor); ret = cursor->close(cursor); overwrite_cursor->set_value(overwrite_cursor, value); ret = overwrite_cursor->insert(cursor); /*! [Reconfigure a cursor] */ } { /*! [Get the cursor's string key] */ const char *key; /* Get the cursor's string key. */ ret = cursor->get_key(cursor, &key); /*! [Get the cursor's string key] */ } { /*! [Get the cursor's record number key] */ uint64_t recno; /* Get the cursor's record number key. */ ret = cursor->get_key(cursor, &recno); /*! [Get the cursor's record number key] */ } { /*! [Get the cursor's string value] */ const char *value; /* Get the cursor's string value. */ ret = cursor->get_value(cursor, &value); /*! [Get the cursor's string value] */ } { /*! [Get the cursor's raw value] */ WT_ITEM value; /* Get the cursor's raw value. */ ret = cursor->get_value(cursor, &value); /*! [Get the cursor's raw value] */ } { /*! [Set the cursor's string key] */ /* Set the cursor's string key. */ const char *key = "another key"; cursor->set_key(cursor, key); /*! [Set the cursor's string key] */ } { /*! [Set the cursor's record number key] */ uint64_t recno = 37; /* Set the cursor's record number key. */ cursor->set_key(cursor, recno); /*! [Set the cursor's record number key] */ } { /*! [Set the cursor's string value] */ /* Set the cursor's string value. */ const char *value = "another value"; cursor->set_value(cursor, value); /*! [Set the cursor's string value] */ } { /*! [Set the cursor's raw value] */ WT_ITEM value; /* Set the cursor's raw value. */ value.data = "another value"; value.size = strlen("another value"); cursor->set_value(cursor, &value); /*! [Set the cursor's raw value] */ } /*! [Return the next record] */ ret = cursor->next(cursor); /*! [Return the next record] */ /*! [Return the previous record] */ ret = cursor->prev(cursor); /*! [Return the previous record] */ /*! [Reset the cursor] */ ret = cursor->reset(cursor); /*! [Reset the cursor] */ { WT_CURSOR *other = NULL; /*! [Cursor comparison] */ int compare; ret = cursor->compare(cursor, other, &compare); 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] */ const char *key = "some key"; cursor->set_key(cursor, key); ret = cursor->search(cursor); /*! [Search for an exact match] */ } cursor_search_near(cursor); { /*! [Insert a new record] */ /* Insert a new record. */ const char *key = "some key", *value = "some value"; cursor->set_key(cursor, key); cursor->set_value(cursor, value); ret = cursor->insert(cursor); /*! [Insert a new record] */ } { const char *key = "some key", *value = "some value"; /*! [Insert a new record or overwrite an existing record] */ /* Insert a new record or overwrite an existing record. */ ret = session->open_cursor( session, "table:mytable", NULL, "overwrite", &cursor); cursor->set_key(cursor, key); cursor->set_value(cursor, value); ret = cursor->insert(cursor); /*! [Insert a new record or overwrite an existing record] */ } { /*! [Insert a new record and assign a record number] */ /* Insert a new record and assign a record number. */ uint64_t recno; const char *value = "some value"; ret = session->open_cursor( session, "table:mytable", NULL, "append", &cursor); cursor->set_value(cursor, value); ret = cursor->insert(cursor); if (ret == 0) recno = cursor->get_key(cursor, &recno); /*! [Insert a new record and assign a record number] */ } { /*! [Update an existing record] */ const char *key = "some key", *value = "some value"; cursor->set_key(cursor, key); cursor->set_value(cursor, value); ret = cursor->update(cursor); /*! [Update an existing record] */ } { /*! [Remove a record] */ const char *key = "some key"; cursor->set_key(cursor, key); ret = cursor->remove(cursor); /*! [Remove a record] */ } { /*! [Display an error] */ const char *key = "some key"; cursor->set_key(cursor, key); if ((ret = cursor->remove(cursor)) != 0) { fprintf(stderr, "cursor.remove: %s\n", wiredtiger_strerror(ret)); return (ret); } /*! [Display an error] */ } /*! [Close the cursor] */ ret = cursor->close(cursor); /*! [Close the cursor] */ return (ret); }
static void run(CONFIG *cp, int bigkey, size_t bytes) { WT_CONNECTION *conn; WT_SESSION *session; WT_CURSOR *cursor; uint64_t keyno; int ret; void *p; big[bytes - 1] = '\0'; printf(SIZET_FMT "%s%s: %s %s big %s\n", bytes < MEGABYTE ? bytes : (bytes < GIGABYTE ? bytes / MEGABYTE : bytes / GIGABYTE), bytes < MEGABYTE ? "" : (bytes < GIGABYTE ? (bytes % MEGABYTE == 0 ? "" : "+") : (bytes % GIGABYTE == 0 ? "" : "+")), bytes < MEGABYTE ? "B" : (bytes < GIGABYTE ? "MB" : "GB"), cp->uri, cp->config, bigkey ? "key" : "value"); testutil_make_work_dir(home); /* * Open/create the database, connection, session and cursor; set the * cache size large, we don't want to try and evict anything. */ if ((ret = wiredtiger_open( home, NULL, "create,cache_size=10GB", &conn)) != 0) testutil_die(ret, "wiredtiger_open"); if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) testutil_die(ret, "WT_CONNECTION.open_session"); if ((ret = session->create(session, cp->uri, cp->config)) != 0) testutil_die(ret, "WT_SESSION.create: %s %s", cp->uri, cp->config); if ((ret = session->open_cursor(session, cp->uri, NULL, NULL, &cursor)) != 0) testutil_die(ret, "WT_SESSION.open_cursor: %s", cp->uri); /* Set the key/value. */ if (bigkey) cursor->set_key(cursor, big); else if (cp->recno) { keyno = 1; cursor->set_key(cursor, keyno); } else cursor->set_key(cursor, "key001"); cursor->set_value(cursor, big); /* Insert the record (use update, insert discards the key). */ if ((ret = cursor->update(cursor)) != 0) testutil_die(ret, "WT_CURSOR.insert"); /* Retrieve the record and check it. */ if ((ret = cursor->search(cursor)) != 0) testutil_die(ret, "WT_CURSOR.search"); if (bigkey && (ret = cursor->get_key(cursor, &p)) != 0) testutil_die(ret, "WT_CURSOR.get_key"); if ((ret = cursor->get_value(cursor, &p)) != 0) testutil_die(ret, "WT_CURSOR.get_value"); if (memcmp(p, big, bytes) != 0) testutil_die(0, "retrieved big key/value item did not match original"); /* Remove the record. */ if ((ret = cursor->remove(cursor)) != 0) testutil_die(ret, "WT_CURSOR.remove"); if ((ret = conn->close(conn, NULL)) != 0) testutil_die(ret, "WT_CONNECTION.close"); big[bytes - 1] = 'a'; }
void worker(CONFIG *cfg, uint32_t worker_type) { WT_CONNECTION *conn; WT_SESSION *session; WT_CURSOR *cursor; const char *op_name = "search"; char *data_buf, *key_buf, *value; int ret, op_ret; uint64_t next_val; session = NULL; data_buf = key_buf = NULL; op_ret = 0; conn = cfg->conn; key_buf = calloc(cfg->key_sz + 1, 1); if (key_buf == NULL) { lprintf(cfg, ret = ENOMEM, 0, "Populate key buffer"); goto err; } if (worker_type == WORKER_INSERT) { data_buf = calloc(cfg->data_sz, 1); if (data_buf == NULL) { lprintf(cfg, ret = ENOMEM, 0, "Populate data buffer"); goto err; } memset(data_buf, 'a', cfg->data_sz - 1); } if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) { lprintf(cfg, ret, 0, "open_session failed in read thread"); goto err; } if ((ret = session->open_cursor(session, cfg->uri, NULL, NULL, &cursor)) != 0) { lprintf(cfg, ret, 0, "open_cursor failed in read thread"); goto err; } while (g_running) { /* Get a value in range, avoid zero. */ #define VALUE_RANGE (cfg->icount + g_nins_ops - (cfg->insert_threads + 1)) next_val = (worker_type == WORKER_INSERT ? (cfg->icount + ATOMIC_ADD(g_nins_ops, 1)) : ((uint64_t)rand() % VALUE_RANGE) + 1); /* * If the workload is started without a populate phase we * rely on at least one insert to get a valid item id. */ if (worker_type != WORKER_INSERT && VALUE_RANGE < next_val) continue; sprintf(key_buf, "%0*" PRIu64, cfg->key_sz, next_val); cursor->set_key(cursor, key_buf); switch(worker_type) { case WORKER_READ: op_name = "read"; op_ret = cursor->search(cursor); if (op_ret == 0) ++g_nread_ops; break; case WORKER_INSERT: op_name = "insert"; cursor->set_value(cursor, data_buf); op_ret = cursor->insert(cursor); if (op_ret != 0) ++g_nfailedins_ops; break; case WORKER_UPDATE: op_name = "update"; op_ret = cursor->search(cursor); if (op_ret == 0) { cursor->get_value(cursor, &value); if (value[0] == 'a') value[0] = 'b'; else value[0] = 'a'; op_ret = cursor->update(cursor); } if (op_ret == 0) ++g_nupdate_ops; break; default: lprintf(cfg, EINVAL, 0, "Invalid worker type"); goto err; } /* Report errors and continue. */ if (op_ret != 0) lprintf(cfg, op_ret, 0, "%s failed for: %s", op_name, key_buf); else ++g_nworker_ops; } err: if (ret != 0) ++g_threads_quit; if (session != NULL) session->close(session, NULL); if (data_buf != NULL) free(data_buf); if (key_buf != NULL) free(key_buf); }
static void transaction_ops(WT_SESSION *session_arg) { WT_CONNECTION *conn; WT_CURSOR *cursor; WT_SESSION *session; session = session_arg; conn = session->connection; /*! [transaction commit/rollback] */ /* * Cursors may be opened before or after the transaction begins, and in * either case, subsequent operations are included in the transaction. * Opening cursors before the transaction begins allows applications to * cache cursors and use them for multiple operations. */ error_check(session->open_cursor( session, "table:mytable", NULL, NULL, &cursor)); error_check(session->begin_transaction(session, NULL)); cursor->set_key(cursor, "key"); cursor->set_value(cursor, "value"); switch (cursor->update(cursor)) { case 0: /* Update success */ error_check(session->commit_transaction(session, NULL)); /* * If commit_transaction succeeds, cursors remain positioned; if * commit_transaction fails, the transaction was rolled-back and * and all cursors are reset. */ break; case WT_ROLLBACK: /* Update conflict */ default: /* Other error */ error_check(session->rollback_transaction(session, NULL)); /* The rollback_transaction call resets all cursors. */ break; } /* * Cursors remain open and may be used for multiple transactions. */ /*! [transaction commit/rollback] */ error_check(cursor->close(cursor)); /*! [transaction isolation] */ /* A single transaction configured for snapshot isolation. */ error_check(session->open_cursor( session, "table:mytable", NULL, NULL, &cursor)); error_check(session->begin_transaction(session, "isolation=snapshot")); cursor->set_key(cursor, "some-key"); cursor->set_value(cursor, "some-value"); error_check(cursor->update(cursor)); error_check(session->commit_transaction(session, NULL)); /*! [transaction isolation] */ { /*! [transaction prepare] */ /* * Prepare a transaction which guarantees a subsequent commit will * succeed. Only commit and rollback are allowed on a transaction after * it has been prepared. */ error_check(session->open_cursor( session, "table:mytable", NULL, NULL, &cursor)); error_check(session->begin_transaction(session, NULL)); cursor->set_key(cursor, "key"); cursor->set_value(cursor, "value"); error_check(session->prepare_transaction( session, "prepare_timestamp=2a")); error_check(session->commit_transaction( session, "commit_timestamp=2b")); /*! [transaction prepare] */ } /*! [session isolation configuration] */ /* Open a session configured for read-uncommitted isolation. */ error_check(conn->open_session( conn, NULL, "isolation=read-uncommitted", &session)); /*! [session isolation configuration] */ /*! [session isolation re-configuration] */ /* Re-configure a session for snapshot isolation. */ error_check(session->reconfigure(session, "isolation=snapshot")); /*! [session isolation re-configuration] */ error_check(session->close(session, NULL)); session = session_arg; { /*! [transaction pinned range] */ /* Check the transaction ID range pinned by the session handle. */ uint64_t range; error_check(session->transaction_pinned_range(session, &range)); /*! [transaction pinned range] */ } error_check(session->begin_transaction(session, NULL)); { /*! [query timestamp] */ char timestamp_buf[2 * sizeof(uint64_t) + 1]; /*! [transaction timestamp] */ error_check( session->timestamp_transaction(session, "commit_timestamp=2a")); /*! [transaction timestamp] */ error_check(session->commit_transaction(session, NULL)); error_check(conn->query_timestamp( conn, timestamp_buf, "get=all_committed")); /*! [query timestamp] */ } /*! [set commit timestamp] */ error_check(conn->set_timestamp(conn, "commit_timestamp=2a")); /*! [set commit timestamp] */ /*! [set oldest timestamp] */ error_check(conn->set_timestamp(conn, "oldest_timestamp=2a")); /*! [set oldest timestamp] */ /*! [set stable timestamp] */ error_check(conn->set_timestamp(conn, "stable_timestamp=2a")); /*! [set stable timestamp] */ /*! [rollback to stable] */ error_check(conn->rollback_to_stable(conn, NULL)); /*! [rollback to stable] */ }
static void session_ops(WT_SESSION *session) { WT_CONNECTION *conn; conn = session->connection; /*! [Reconfigure a session] */ error_check(session->reconfigure(session, "isolation=snapshot")); /*! [Reconfigure a session] */ /*! [Create a table] */ error_check(session->create(session, "table:mytable", "key_format=S,value_format=S")); /*! [Create a table] */ error_check(session->drop(session, "table:mytable", NULL)); /*! [Create a column-store table] */ error_check(session->create(session, "table:mytable", "key_format=r,value_format=S")); /*! [Alter a table] */ error_check(session->alter(session, "table:mytable", "access_pattern_hint=random")); /*! [Alter a table] */ /*! [Create a column-store table] */ error_check(session->drop(session, "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). */ error_check(session->create(session, "table:mytable", "key_format=r,value_format=SiH," "columns=(id,department,salary,year-started)")); /*! [Create a table with columns] */ error_check(session->drop(session, "table:mytable", NULL)); /*! [Create a table and configure the page size] */ error_check(session->create(session, "table:mytable", "key_format=S,value_format=S," "internal_page_max=16KB,leaf_page_max=1MB,leaf_value_max=64KB")); /*! [Create a table and configure the page size] */ error_check(session->drop(session, "table:mytable", NULL)); /*! [Create a table and configure a large leaf value max] */ error_check(session->create(session, "table:mytable", "key_format=S,value_format=S," "leaf_page_max=16KB,leaf_value_max=256KB")); /*! [Create a table and configure a large leaf value max] */ error_check(session->drop(session, "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 #ifdef's to avoid running it. */ #ifdef MIGHT_NOT_RUN /*! [Create a lz4 compressed table] */ error_check(session->create(session, "table:mytable", "block_compressor=lz4,key_format=S,value_format=S")); /*! [Create a lz4 compressed table] */ error_check(session->drop(session, "table:mytable", NULL)); /*! [Create a snappy compressed table] */ error_check(session->create(session, "table:mytable", "block_compressor=snappy,key_format=S,value_format=S")); /*! [Create a snappy compressed table] */ error_check(session->drop(session, "table:mytable", NULL)); /*! [Create a zlib compressed table] */ error_check(session->create(session, "table:mytable", "block_compressor=zlib,key_format=S,value_format=S")); /*! [Create a zlib compressed table] */ error_check(session->drop(session, "table:mytable", NULL)); /*! [Create a zstd compressed table] */ error_check(session->create(session, "table:mytable", "block_compressor=zstd,key_format=S,value_format=S")); /*! [Create a zstd compressed table] */ error_check(session->drop(session, "table:mytable", NULL)); #endif /*! [Configure checksums to uncompressed] */ error_check(session->create(session, "table:mytable", "key_format=S,value_format=S,checksum=uncompressed")); /*! [Configure checksums to uncompressed] */ error_check(session->drop(session, "table:mytable", NULL)); /*! [Configure dictionary compression on] */ error_check(session->create(session, "table:mytable", "key_format=S,value_format=S,dictionary=1000")); /*! [Configure dictionary compression on] */ error_check(session->drop(session, "table:mytable", NULL)); /*! [Configure key prefix compression on] */ error_check(session->create(session, "table:mytable", "key_format=S,value_format=S,prefix_compression=true")); /*! [Configure key prefix compression on] */ error_check(session->drop(session, "table:mytable", NULL)); #ifdef MIGHT_NOT_RUN /* Requires sync_file_range */ /*! [os_cache_dirty_max configuration] */ error_check(session->create( session, "table:mytable", "os_cache_dirty_max=500MB")); /*! [os_cache_dirty_max configuration] */ error_check(session->drop(session, "table:mytable", NULL)); /* Requires posix_fadvise */ /*! [os_cache_max configuration] */ error_check(session->create( session, "table:mytable", "os_cache_max=1GB")); /*! [os_cache_max configuration] */ error_check(session->drop(session, "table:mytable", NULL)); #endif /*! [Configure block_allocation] */ error_check(session->create(session, "table:mytable", "key_format=S,value_format=S,block_allocation=first")); /*! [Configure block_allocation] */ error_check(session->drop(session, "table:mytable", NULL)); /*! [Create a cache-resident object] */ error_check(session->create( session, "table:mytable", "key_format=r,value_format=S,cache_resident=true")); /*! [Create a cache-resident object] */ error_check(session->drop(session, "table:mytable", NULL)); { /* Create a table for the session operations. */ error_check(session->create( session, "table:mytable", "key_format=S,value_format=S")); /*! [Compact a table] */ error_check(session->compact(session, "table:mytable", NULL)); /*! [Compact a table] */ /*! [Rebalance a table] */ error_check(session->rebalance(session, "table:mytable", NULL)); /*! [Rebalance a table] */ error_check(session->create( session, "table:old", "key_format=r,value_format=S,cache_resident=true")); /*! [Rename a table] */ error_check(session->rename(session, "table:old", "table:new", NULL)); /*! [Rename a table] */ /*! [Salvage a table] */ error_check(session->salvage(session, "table:mytable", NULL)); /*! [Salvage a table] */ /*! [Truncate a table] */ error_check(session->truncate( session, "table:mytable", NULL, NULL, NULL)); /*! [Truncate a table] */ /*! [Transaction sync] */ error_check(session->transaction_sync(session, NULL)); /*! [Transaction sync] */ /*! [Reset the session] */ error_check(session->reset(session)); /*! [Reset the session] */ { /* * Insert a pair of keys so we can truncate a range. */ WT_CURSOR *cursor; error_check(session->open_cursor( session, "table:mytable", NULL, NULL, &cursor)); cursor->set_key(cursor, "June01"); cursor->set_value(cursor, "value"); error_check(cursor->update(cursor)); cursor->set_key(cursor, "June30"); cursor->set_value(cursor, "value"); error_check(cursor->update(cursor)); error_check(cursor->close(cursor)); { /*! [Truncate a range] */ WT_CURSOR *start, *stop; error_check(session->open_cursor( session, "table:mytable", NULL, NULL, &start)); start->set_key(start, "June01"); error_check(start->search(start)); error_check(session->open_cursor( session, "table:mytable", NULL, NULL, &stop)); stop->set_key(stop, "June30"); error_check(stop->search(stop)); error_check(session->truncate(session, NULL, start, stop, NULL)); /*! [Truncate a range] */ error_check(stop->close(stop)); error_check(start->close(start)); } } /*! [Upgrade a table] */ error_check(session->upgrade(session, "table:mytable", NULL)); /*! [Upgrade a table] */ /*! [Verify a table] */ error_check(session->verify(session, "table:mytable", NULL)); /*! [Verify a table] */ /* * We can't call the backup function because it includes absolute paths * for documentation purposes that don't exist on test systems. That * said, we have to reference the function to avoid build warnings * about unused static code. */ (void)backup; /* Call other functions, where possible. */ checkpoint_ops(session); error_check(cursor_ops(session)); cursor_statistics(session); named_snapshot_ops(session); pack_ops(session); transaction_ops(session); /*! [Close a session] */ error_check(session->close(session, NULL)); /*! [Close a session] */ /* * We close the old session first to close all cursors, open a new one * for the drop. */ error_check(conn->open_session(conn, NULL, NULL, &session)); /*! [Drop a table] */ error_check(session->drop(session, "table:mytable", NULL)); /*! [Drop a table] */ } }
static int cursor_ops(WT_SESSION *session) { WT_CURSOR *cursor; int ret; /*! [Open a cursor] */ error_check(session->open_cursor( session, "table:mytable", NULL, NULL, &cursor)); /*! [Open a cursor] */ /*! [Open a cursor on the metadata] */ error_check(session->open_cursor( session, "metadata:", NULL, NULL, &cursor)); /*! [Open a cursor on the metadata] */ { const char *key = "some key", *value = "some value"; /*! [Reconfigure a cursor] */ error_check(session->open_cursor( session, "table:mytable", NULL, "overwrite=false", &cursor)); /* Reconfigure the cursor to overwrite the record. */ error_check(cursor->reconfigure(cursor, "overwrite=true")); cursor->set_key(cursor, key); cursor->set_value(cursor, value); error_check(cursor->insert(cursor)); /*! [Reconfigure a cursor] */ } { WT_CURSOR *duplicate; const char *key = "some key"; /*! [Duplicate a cursor] */ error_check(session->open_cursor( session, "table:mytable", NULL, NULL, &cursor)); cursor->set_key(cursor, key); error_check(cursor->search(cursor)); /* Duplicate the cursor. */ error_check( session->open_cursor(session, NULL, cursor, NULL, &duplicate)); /*! [Duplicate a cursor] */ } { /*! [boolean configuration string example] */ error_check(session->open_cursor( session, "table:mytable", NULL, "overwrite", &cursor)); error_check(session->open_cursor( session, "table:mytable", NULL, "overwrite=true", &cursor)); error_check(session->open_cursor( session, "table:mytable", NULL, "overwrite=1", &cursor)); /*! [boolean configuration string example] */ } error_check(session->checkpoint(session, "name=midnight")); { /*! [open a named checkpoint] */ error_check(session->open_cursor(session, "table:mytable", NULL, "checkpoint=midnight", &cursor)); /*! [open a named checkpoint] */ } { /*! [open the default checkpoint] */ error_check(session->open_cursor(session, "table:mytable", NULL, "checkpoint=WiredTigerCheckpoint", &cursor)); /*! [open the default checkpoint] */ } { /*! [Set the cursor's string key] */ /* Set the cursor's string key. */ const char *key = "another key"; cursor->set_key(cursor, key); /*! [Set the cursor's string key] */ } { /*! [Get the cursor's string key] */ const char *key; /* Get the cursor's string key. */ error_check(cursor->get_key(cursor, &key)); /*! [Get the cursor's string key] */ } /* Switch to a recno table. */ error_check(session->create( session, "table:recno", "key_format=r,value_format=S")); error_check(session->open_cursor( session, "table:recno", NULL, NULL, &cursor)); { /*! [Set the cursor's record number key] */ uint64_t recno = 37; /* Set the cursor's record number key. */ cursor->set_key(cursor, recno); /*! [Set the cursor's record number key] */ } { /*! [Get the cursor's record number key] */ uint64_t recno; /* Get the cursor's record number key. */ error_check(cursor->get_key(cursor, &recno)); /*! [Get the cursor's record number key] */ } /* Switch to a composite table. */ error_check(session->create( session, "table:composite", "key_format=SiH,value_format=S")); error_check(session->open_cursor( session, "table:recno", NULL, NULL, &cursor)); { /*! [Set the cursor's composite key] */ /* Set the cursor's "SiH" format composite key. */ cursor->set_key(cursor, "first", (int32_t)5, (uint16_t)7); /*! [Set the cursor's composite key] */ } { /*! [Get the cursor's composite key] */ /* Get the cursor's "SiH" format composite key. */ const char *first; int32_t second; uint16_t third; error_check(cursor->get_key(cursor, &first, &second, &third)); /*! [Get the cursor's composite key] */ } { /*! [Set the cursor's string value] */ /* Set the cursor's string value. */ const char *value = "another value"; cursor->set_value(cursor, value); /*! [Set the cursor's string value] */ } { /*! [Get the cursor's string value] */ const char *value; /* Get the cursor's string value. */ error_check(cursor->get_value(cursor, &value)); /*! [Get the cursor's string value] */ } { /*! [Get the cursor's raw value] */ WT_ITEM value; /* Get the cursor's raw value. */ error_check(cursor->get_value(cursor, &value)); /*! [Get the cursor's raw value] */ } { /*! [Set the cursor's raw value] */ WT_ITEM value; /* Set the cursor's raw value. */ value.data = "another value"; value.size = strlen("another value"); cursor->set_value(cursor, &value); /*! [Set the cursor's raw value] */ error_check(cursor->insert(cursor)); } /*! [Return the next record] */ error_check(cursor->next(cursor)); /*! [Return the next record] */ /*! [Reset the cursor] */ error_check(cursor->reset(cursor)); /*! [Reset the cursor] */ /*! [Return the previous record] */ error_check(cursor->prev(cursor)); /*! [Return the previous record] */ { WT_CURSOR *other = NULL; error_check( session->open_cursor(session, NULL, cursor, NULL, &other)); { /*! [Cursor comparison] */ int compare; error_check(cursor->compare(cursor, other, &compare)); 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] */ } { /*! [Cursor equality] */ int equal; error_check(cursor->equals(cursor, other, &equal)); if (equal) { /* Cursors reference the same key */ } /*! [Cursor equality] */ } } { /*! [Insert a new record or overwrite an existing record] */ /* Insert a new record or overwrite an existing record. */ const char *key = "some key", *value = "some value"; error_check(session->open_cursor( session, "table:mytable", NULL, NULL, &cursor)); cursor->set_key(cursor, key); cursor->set_value(cursor, value); error_check(cursor->insert(cursor)); /*! [Insert a new record or overwrite an existing record] */ } { /*! [Search for an exact match] */ const char *key = "some key"; cursor->set_key(cursor, key); error_check(cursor->search(cursor)); /*! [Search for an exact match] */ } cursor_search_near(cursor); { /*! [Insert a new record and fail if the record exists] */ /* Insert a new record and fail if the record exists. */ const char *key = "new key", *value = "some value"; error_check(session->open_cursor( session, "table:mytable", NULL, "overwrite=false", &cursor)); cursor->set_key(cursor, key); cursor->set_value(cursor, value); error_check(cursor->insert(cursor)); /*! [Insert a new record and fail if the record exists] */ } error_check(session->open_cursor( session, "table:recno", NULL, "append", &cursor)); { /*! [Insert a new record and assign a record number] */ /* Insert a new record and assign a record number. */ uint64_t recno; const char *value = "some value"; cursor->set_value(cursor, value); error_check(cursor->insert(cursor)); error_check(cursor->get_key(cursor, &recno)); /*! [Insert a new record and assign a record number] */ } error_check(session->open_cursor( session, "table:mytable", NULL, NULL, &cursor)); { /*! [Reserve a record] */ const char *key = "some key"; error_check(session->begin_transaction(session, NULL)); cursor->set_key(cursor, key); error_check(cursor->reserve(cursor)); error_check(session->commit_transaction(session, NULL)); /*! [Reserve a record] */ } error_check(session->create( session, "table:blob", "key_format=S,value_format=u")); error_check(session->open_cursor( session, "table:blob", NULL, NULL, &cursor)); { WT_ITEM value; value.data = "abcdefghijklmnopqrstuvwxyz" "abcdefghijklmnopqrstuvwxyz" "abcdefghijklmnopqrstuvwxyz"; value.size = strlen(value.data); cursor->set_key(cursor, "some key"); cursor->set_value(cursor, &value); error_check(cursor->insert(cursor)); } /* Modify requires an explicit transaction. */ error_check(session->begin_transaction(session, NULL)); { /*! [Modify an existing record] */ WT_MODIFY entries[3]; const char *key = "some key"; /* Position the cursor. */ cursor->set_key(cursor, key); error_check(cursor->search(cursor)); /* Replace 20 bytes starting at byte offset 5. */ entries[0].data.data = "some data"; entries[0].data.size = strlen(entries[0].data.data); entries[0].offset = 5; entries[0].size = 20; /* Insert data at byte offset 40. */ entries[1].data.data = "and more data"; entries[1].data.size = strlen(entries[1].data.data); entries[1].offset = 40; entries[1].size = 0; /* Replace 2 bytes starting at byte offset 10. */ entries[2].data.data = "and more data"; entries[2].data.size = strlen(entries[2].data.data); entries[2].offset = 10; entries[2].size = 2; error_check(cursor->modify(cursor, entries, 3)); /*! [Modify an existing record] */ } error_check(session->commit_transaction(session, NULL)); { /*! [Update an existing record or insert a new record] */ const char *key = "some key", *value = "some value"; error_check(session->open_cursor( session, "table:mytable", NULL, NULL, &cursor)); cursor->set_key(cursor, key); cursor->set_value(cursor, value); error_check(cursor->update(cursor)); /*! [Update an existing record or insert a new record] */ } { /*! [Update an existing record and fail if DNE] */ const char *key = "some key", *value = "some value"; error_check(session->open_cursor( session, "table:mytable", NULL, "overwrite=false", &cursor)); cursor->set_key(cursor, key); cursor->set_value(cursor, value); error_check(cursor->update(cursor)); /*! [Update an existing record and fail if DNE] */ } { /*! [Remove a record and fail if DNE] */ const char *key = "some key"; error_check(session->open_cursor( session, "table:mytable", NULL, "overwrite=false", &cursor)); cursor->set_key(cursor, key); error_check(cursor->remove(cursor)); /*! [Remove a record and fail if DNE] */ } { /*! [Remove a record] */ const char *key = "some key"; error_check(session->open_cursor( session, "table:mytable", NULL, NULL, &cursor)); cursor->set_key(cursor, key); error_check(cursor->remove(cursor)); /*! [Remove a record] */ } { /*! [Display an error] */ const char *key = "non-existent key"; cursor->set_key(cursor, key); if ((ret = cursor->remove(cursor)) != 0) { fprintf(stderr, "cursor.remove: %s\n", wiredtiger_strerror(ret)); return (ret); } /*! [Display an error] */ } { /*! [Display an error thread safe] */ const char *key = "non-existent key"; cursor->set_key(cursor, key); if ((ret = cursor->remove(cursor)) != 0) { fprintf(stderr, "cursor.remove: %s\n", cursor->session->strerror(cursor->session, ret)); return (ret); } /*! [Display an error thread safe] */ } /*! [Close the cursor] */ error_check(cursor->close(cursor)); /*! [Close the cursor] */ return (0); }