foundationdb/api-ruby.html

1894 lines
198 KiB
HTML

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Ruby API &#8212; FoundationDB 7.1</title>
<link rel="stylesheet" href="_static/basic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="_static/bootstrap-3.3.4/css/bootstrap.min.css" type="text/css" />
<link rel="stylesheet" href="_static/bootstrap-3.3.4/css/bootstrap-theme.min.css" type="text/css" />
<link rel="stylesheet" href="_static/bootstrap-sphinx.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '7.1.23',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/js/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="_static/js/jquery-fix.js"></script>
<script type="text/javascript" src="_static/bootstrap-3.3.4/js/bootstrap.min.js"></script>
<script type="text/javascript" src="_static/bootstrap-sphinx.js"></script>
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="C API" href="api-c.html" />
<link rel="prev" title="Python API" href="api-python.html" />
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
<meta name="apple-mobile-web-app-capable" content="yes">
</head>
<body role="document">
<div id="navbar" class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<!-- .btn-navbar is used as the toggle for collapsed navbar content -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.html">
FoundationDB</a>
<span class="navbar-text navbar-version pull-left"><b>7.1</b></span>
</div>
<div class="collapse navbar-collapse nav-collapse">
<ul class="nav navbar-nav">
<li><a href="contents.html">Site Map</a></li>
<li class="dropdown globaltoc-container">
<a role="button"
id="dLabelGlobalToc"
data-toggle="dropdown"
data-target="#"
href="index.html">Site <b class="caret"></b></a>
<ul class="dropdown-menu globaltoc"
role="menu"
aria-labelledby="dLabelGlobalToc"></ul>
</li>
<li class="dropdown">
<a role="button"
id="dLabelLocalToc"
data-toggle="dropdown"
data-target="#"
href="#">Page <b class="caret"></b></a>
<ul class="dropdown-menu localtoc"
role="menu"
aria-labelledby="dLabelLocalToc"><ul>
<li><a class="reference internal" href="#">Ruby API</a><ul>
<li><a class="reference internal" href="#installation">Installation</a></li>
<li><a class="reference internal" href="#api-versioning">API versioning</a></li>
<li><a class="reference internal" href="#opening-a-database">Opening a database</a></li>
<li><a class="reference internal" href="#keys-and-values">Keys and values</a><ul>
<li><a class="reference internal" href="#as-foundationdb-key-and-as-foundationdb-value"><code class="docutils literal"><span class="pre">as_foundationdb_key</span></code> and <code class="docutils literal"><span class="pre">as_foundationdb_value</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#keyvalue-objects">KeyValue objects</a></li>
<li><a class="reference internal" href="#key-selectors">Key selectors</a></li>
<li><a class="reference internal" href="#database-objects">Database objects</a><ul>
<li><a class="reference internal" href="#database-options">Database options</a></li>
</ul>
</li>
<li><a class="reference internal" href="#transaction-objects">Transaction objects</a><ul>
<li><a class="reference internal" href="#attributes">Attributes</a></li>
<li><a class="reference internal" href="#reading-data">Reading data</a></li>
<li><a class="reference internal" href="#snapshot-reads">Snapshot reads</a></li>
<li><a class="reference internal" href="#writing-data">Writing data</a></li>
<li><a class="reference internal" href="#atomic-operations">Atomic operations</a></li>
<li><a class="reference internal" href="#committing">Committing</a></li>
<li><a class="reference internal" href="#watches">Watches</a></li>
<li><a class="reference internal" href="#conflict-ranges">Conflict ranges</a></li>
<li><a class="reference internal" href="#versions">Versions</a></li>
<li><a class="reference internal" href="#transaction-misc-functions">Transaction misc functions</a></li>
<li><a class="reference internal" href="#transaction-options">Transaction options</a></li>
</ul>
</li>
<li><a class="reference internal" href="#the-transact-method">The transact method</a></li>
<li><a class="reference internal" href="#future-objects">Future objects</a></li>
<li><a class="reference internal" href="#streaming-modes">Streaming modes</a></li>
<li><a class="reference internal" href="#errors">Errors</a></li>
<li><a class="reference internal" href="#module-FDB::Tuple">Tuple layer</a></li>
<li><a class="reference internal" href="#subspaces">Subspaces</a></li>
<li><a class="reference internal" href="#directories">Directories</a><ul>
<li><a class="reference internal" href="#directorysubspace">DirectorySubspace</a></li>
</ul>
</li>
<li><a class="reference internal" href="#module-FDB::Locality">Locality information</a></li>
</ul>
</li>
</ul>
</ul>
</li>
<li>
<a href="api-python.html" title="Previous Chapter: Python API"><span class="glyphicon glyphicon-chevron-left visible-sm"></span><span class="hidden-sm hidden-tablet">&laquo; Python API</span>
</a>
</li>
<li>
<a href="api-c.html" title="Next Chapter: C API"><span class="glyphicon glyphicon-chevron-right visible-sm"></span><span class="hidden-sm hidden-tablet">C API &raquo;</span>
</a>
</li>
</ul>
<form class="navbar-form navbar-right" action="search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" placeholder="Search" />
</div>
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-3">
<div id="sidebar" class="bs-sidenav" role="complementary"><ul>
<li><a class="reference internal" href="#">Ruby API</a><ul>
<li><a class="reference internal" href="#installation">Installation</a></li>
<li><a class="reference internal" href="#api-versioning">API versioning</a></li>
<li><a class="reference internal" href="#opening-a-database">Opening a database</a></li>
<li><a class="reference internal" href="#keys-and-values">Keys and values</a><ul>
<li><a class="reference internal" href="#as-foundationdb-key-and-as-foundationdb-value"><code class="docutils literal"><span class="pre">as_foundationdb_key</span></code> and <code class="docutils literal"><span class="pre">as_foundationdb_value</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#keyvalue-objects">KeyValue objects</a></li>
<li><a class="reference internal" href="#key-selectors">Key selectors</a></li>
<li><a class="reference internal" href="#database-objects">Database objects</a><ul>
<li><a class="reference internal" href="#database-options">Database options</a></li>
</ul>
</li>
<li><a class="reference internal" href="#transaction-objects">Transaction objects</a><ul>
<li><a class="reference internal" href="#attributes">Attributes</a></li>
<li><a class="reference internal" href="#reading-data">Reading data</a></li>
<li><a class="reference internal" href="#snapshot-reads">Snapshot reads</a></li>
<li><a class="reference internal" href="#writing-data">Writing data</a></li>
<li><a class="reference internal" href="#atomic-operations">Atomic operations</a></li>
<li><a class="reference internal" href="#committing">Committing</a></li>
<li><a class="reference internal" href="#watches">Watches</a></li>
<li><a class="reference internal" href="#conflict-ranges">Conflict ranges</a></li>
<li><a class="reference internal" href="#versions">Versions</a></li>
<li><a class="reference internal" href="#transaction-misc-functions">Transaction misc functions</a></li>
<li><a class="reference internal" href="#transaction-options">Transaction options</a></li>
</ul>
</li>
<li><a class="reference internal" href="#the-transact-method">The transact method</a></li>
<li><a class="reference internal" href="#future-objects">Future objects</a></li>
<li><a class="reference internal" href="#streaming-modes">Streaming modes</a></li>
<li><a class="reference internal" href="#errors">Errors</a></li>
<li><a class="reference internal" href="#module-FDB::Tuple">Tuple layer</a></li>
<li><a class="reference internal" href="#subspaces">Subspaces</a></li>
<li><a class="reference internal" href="#directories">Directories</a><ul>
<li><a class="reference internal" href="#directorysubspace">DirectorySubspace</a></li>
</ul>
</li>
<li><a class="reference internal" href="#module-FDB::Locality">Locality information</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="col-md-9 content">
<span class="target" id="module-FDB"></span><div class="section" id="ruby-api">
<h1>Ruby API</h1>
<div class="section" id="installation">
<h2>Installation</h2>
<p>The FoundationDB Ruby API is distributed in our <a class="reference internal" href="downloads.html"><span class="doc">Downloads</span></a>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">For the language binding to function, FoundationDB client binaries whose version is at least as recent
must be installed. If you upgrade a language binding to a new version, you may need to upgrade the FoundationDB client binaries as well. See <a class="reference internal" href="api-general.html#installing-client-binaries"><span class="std std-ref">Installing FoundationDB client binaries</span></a>.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you have a project with automatic dependency installation and have expressed a dependency on foundationdb, it may automatically install the lastest version of the language binding when you deploy your project to a new machine. If you have not also upgraded the Foundation client binary, an unplanned upgrade of the language binding may encounter an incompatibility. You should therefore configure any project dependency on foundationdb in coordination with your overall upgrade strategy.</p>
</div>
</div>
<div class="section" id="api-versioning">
<h2>API versioning</h2>
<p>When you require the <code class="docutils literal"><span class="pre">FDB</span></code> gem, it exposes only one useful method:</p>
<dl class="function">
<dt id="FDB.api_version">
<code class="descclassname">FDB.</code><code class="descname">api_version</code><span class="sig-paren">(</span><em>version</em><span class="sig-paren">)</span></dt>
<dd><p>Specifies the version of the API that the application uses. This allows future versions of FoundationDB to make API changes without breaking existing programs. The current version of the API is 710.</p>
</dd></dl>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">You must call <code class="docutils literal"><span class="pre">FDB.api_version(...)</span></code> before using any other part of the API. Once you have done so, the rest of the API will become available in the <code class="docutils literal"><span class="pre">FDB</span></code> module.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">FoundationDB encapsulates multiple versions of its interface by requiring the client to explicitly specify the version of the API it uses. The purpose of this design is to allow you to upgrade the server, client libraries, or bindings without having to modify client code. The client libraries support all previous versions of the API. The API version specified by the client is used to control the behavior of the binding. You can therefore upgrade to more recent packages (and thus receive various improvements) without having to change your code.</p>
</div>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">When using the <a class="reference internal" href="api-general.html#multi-version-client-api"><span class="std std-ref">multi-version client API</span></a>, setting an API version that is not supported by a particular client library will prevent that client from being used to connect to the cluster. In particular, you should not advance the API version of your application after upgrading your client until the cluster has also been upgraded.</p>
</div>
<p>For API changes between version 14 and 710 (for the purpose of porting older programs), see <a class="reference internal" href="release-notes/release-notes-710.html#release-notes"><span class="std std-ref">Release Notes</span></a> and <a class="reference internal" href="api-version-upgrade-guide.html"><span class="doc">API Version Upgrade Guide</span></a>.</p>
</div>
<div class="section" id="opening-a-database">
<h2>Opening a database</h2>
<p>After requiring the <code class="docutils literal"><span class="pre">FDB</span></code> gem and selecting an API version, you probably want to open a <a class="reference internal" href="#FDB::Database" title="FDB::Database"><code class="xref rb rb-class docutils literal"><span class="pre">Database</span></code></a> using <a class="reference internal" href="#FDB.open" title="FDB.open"><code class="xref rb rb-func docutils literal"><span class="pre">open</span></code></a>:</p>
<div class="highlight-ruby"><div class="highlight"><pre><span></span><span class="nb">require</span> <span class="s1">&#39;fdb&#39;</span>
<span class="no">FDB</span><span class="o">.</span><span class="n">api_version</span> <span class="mi">710</span>
<span class="n">db</span> <span class="o">=</span> <span class="no">FDB</span><span class="o">.</span><span class="n">open</span>
</pre></div>
</div>
<dl class="function">
<dt id="FDB.open">
<code class="descclassname">FDB.</code><code class="descname">open</code><span class="sig-paren">(</span><em>cluster_file=nil</em><span class="sig-paren">)</span> &#x2192; Database</dt>
<dd><p>Connects to the cluster specified by the <a class="reference internal" href="administration.html#foundationdb-cluster-file"><span class="std std-ref">cluster file</span></a>. This function is often called without any parameters, using only the defaults. If no cluster file is passed, FoundationDB automatically <a class="reference internal" href="administration.html#specifying-a-cluster-file"><span class="std std-ref">determines a cluster file</span></a> with which to connect to a cluster.</p>
<p>A single client can use this function multiple times to connect to different clusters simultaneously, with each invocation requiring its own cluster file. To connect to multiple clusters running at different, incompatible versions, the <a class="reference internal" href="api-general.html#multi-version-client-api"><span class="std std-ref">multi-version client API</span></a> must be used.</p>
</dd></dl>
<dl class="global">
<dt id="options">
<code class="descclassname">FDB.</code><code class="descname">options</code></dt>
<dd><p>A singleton providing options which affect the entire FoundationDB client. Note that network options can also be <a class="reference internal" href="api-general.html#network-options-using-environment-variables"><span class="std std-ref">set using environment variables</span></a>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">It is an error to set these options after the first call to <a class="reference internal" href="#FDB.open" title="FDB.open"><code class="xref rb rb-func docutils literal"><span class="pre">FDB.open</span></code></a> anywhere in your application.</p>
</div>
<dl class="method">
<dt id="FDB::FDB.options.set_trace_enable">
<code class="descclassname">FDB.options.</code><code class="descname">set_trace_enable</code><span class="sig-paren">(</span><em>output_directory</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Enables trace file generation on this FoundationDB client. Trace files will be generated in the specified output directory. If the directory is specified as <code class="docutils literal"><span class="pre">nil</span></code>, then the output directory will be the current working directory.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">The specified output directory must be unique to this client. In the present release, trace logging does not allow two clients to share a directory.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::FDB.options.set_trace_max_logs_size">
<code class="descclassname">FDB.options.</code><code class="descname">set_trace_max_logs_size</code><span class="sig-paren">(</span><em>bytes</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Sets the maximum size in bytes for the sum of this FoundationDB client&#8217;s trace output files in a single log directory.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::FDB.options.set_trace_roll_size">
<code class="descclassname">FDB.options.</code><code class="descname">set_trace_roll_size</code><span class="sig-paren">(</span><em>bytes</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Sets the maximum size in bytes of a single trace output file for this FoundationDB client.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::FDB.options.set_trace_format">
<code class="descclassname">FDB.options.</code><code class="descname">set_trace_format</code><span class="sig-paren">(</span><em>format</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Select the format of the trace files for this FoundationDB client. xml (the default) and json are supported.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::FDB.options.set_trace_clock_source">
<code class="descclassname">FDB.options.</code><code class="descname">set_trace_clock_source</code><span class="sig-paren">(</span><em>source</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Select clock source for trace files. now (the default) or realtime are supported.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::FDB.options.set_disable_multi_version_client_api">
<code class="descclassname">FDB.options.</code><code class="descname">set_disable_multi_version_client_api</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Disables the <a class="reference internal" href="api-general.html#multi-version-client-api"><span class="std std-ref">multi-version client API</span></a> and instead uses the local client directly. Must be set before setting up the network.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::FDB.options.set_callbacks_on_external_threads">
<code class="descclassname">FDB.options.</code><code class="descname">set_callbacks_on_external_threads</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>If set, callbacks from <a class="reference internal" href="api-general.html#multi-version-client-api"><span class="std std-ref">external client libraries</span></a> can be called from threads created by the FoundationDB client library. Otherwise, callbacks will be called from either the thread used to add the callback or the network thread. Setting this option can improve performance when connected using an external client, but may not be safe to use in all environments. Must be set before setting up the network. WARNING: This feature is considered experimental at this time.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::FDB.options.set_external_client_library">
<code class="descclassname">FDB.options.</code><code class="descname">set_external_client_library</code><span class="sig-paren">(</span><em>path_to_lib</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Adds an external client library for use by the <a class="reference internal" href="api-general.html#multi-version-client-api"><span class="std std-ref">multi-version client API</span></a>. Must be set before setting up the network.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::FDB.options.set_external_client_directory">
<code class="descclassname">FDB.options.</code><code class="descname">set_external_client_directory</code><span class="sig-paren">(</span><em>path_to_lib_directory</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Searches the specified path for dynamic libraries and adds them to the list of client libraries for use by the <a class="reference internal" href="api-general.html#multi-version-client-api"><span class="std std-ref">multi-version client API</span></a>. Must be set before setting up the network.</p>
</dd></dl>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The following options are only used when connecting to a <a class="reference internal" href="tls.html"><span class="doc">TLS-enabled cluster</span></a>.</p>
</div>
<dl class="method">
<dt id="FDB::FDB.options.set_tls_plugin">
<code class="descclassname">FDB.options.</code><code class="descname">set_tls_plugin</code><span class="sig-paren">(</span><em>plugin_path_or_name</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Sets the <a class="reference internal" href="tls.html#configuring-tls"><span class="std std-ref">TLS plugin</span></a> to load. This option, if used, must be set before any other TLS options.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::FDB.options.set_tls_cert_path">
<code class="descclassname">FDB.options.</code><code class="descname">set_tls_cert_path</code><span class="sig-paren">(</span><em>path_to_file</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Sets the path for the file from which the <a class="reference internal" href="tls.html#tls-certificate-file"><span class="std std-ref">certificate chain</span></a> will be loaded.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::FDB.options.set_tls_key_path">
<code class="descclassname">FDB.options.</code><code class="descname">set_tls_key_path</code><span class="sig-paren">(</span><em>path_to_file</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Sets the path for the file from which to load the <a class="reference internal" href="tls.html#tls-key-file"><span class="std std-ref">private key</span></a> corresponding to your own certificate.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::FDB.options.set_tls_verify_peers">
<code class="descclassname">FDB.options.</code><code class="descname">set_tls_verify_peers</code><span class="sig-paren">(</span><em>criteria</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Sets the <a class="reference internal" href="tls.html#tls-verify-peers"><span class="std std-ref">peer certificate field verification criteria</span></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::FDB.options.set_tls_cert_bytes">
<code class="descclassname">FDB.options.</code><code class="descname">set_tls_cert_bytes</code><span class="sig-paren">(</span><em>bytes</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Sets the certificate chain.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::FDB.options.set_tls_key_bytes">
<code class="descclassname">FDB.options.</code><code class="descname">set_tls_key_bytes</code><span class="sig-paren">(</span><em>bytes</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Set the private key corresponding to your own certificate.</p>
</dd></dl>
<dl class="method">
<dt>
<code class="descclassname">FDB.options.</code><code class="descname">set_disable_multi_version_client_api</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd></dd></dl>
</dd></dl>
</div>
<div class="section" id="keys-and-values">
<span id="api-ruby-keys"></span><h2>Keys and values</h2>
<p>Keys and values in FoundationDB are simple byte strings.</p>
<p>To encode other data types, see <a class="reference internal" href="data-modeling.html#encoding-data-types"><span class="std std-ref">Encoding data types</span></a> and the <a class="reference internal" href="#api-ruby-tuple-layer"><span class="std std-ref">tuple layer</span></a>.</p>
<div class="section" id="as-foundationdb-key-and-as-foundationdb-value">
<h3><code class="docutils literal"><span class="pre">as_foundationdb_key</span></code> and <code class="docutils literal"><span class="pre">as_foundationdb_value</span></code></h3>
<p>In some cases, you may have objects that are used to <em>represent</em> specific keys or values (for example, see <a class="reference internal" href="#FDB::Subspace" title="FDB::Subspace"><code class="xref rb rb-class docutils literal"><span class="pre">Subspace</span></code></a>). As a convenience, the language binding API can work seamlessly with such objects if they implement the <code class="xref rb rb-meth docutils literal"><span class="pre">as_foundationdb_key</span></code> or <code class="xref rb rb-meth docutils literal"><span class="pre">as_foundationdb_value</span></code> methods, respectively. API methods that accept a key will alternately accept an object that implements the <code class="xref rb rb-meth docutils literal"><span class="pre">as_foundationdb_key</span></code> method. Likewise, API methods accepting a value will also accept an object that implements the <code class="xref rb rb-meth docutils literal"><span class="pre">as_foundationdb_value</span></code> method.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last"><code class="xref rb rb-meth docutils literal"><span class="pre">as_foundationdb_key</span></code> and <code class="xref rb rb-meth docutils literal"><span class="pre">as_foundationdb_value</span></code> are not intended to implement serialization protocols for object storage. Use these functions only when your object represents a specific key or value.</p>
</div>
</div>
</div>
<div class="section" id="keyvalue-objects">
<h2>KeyValue objects</h2>
<dl class="class">
<dt id="FDB::KeyValue">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">KeyValue</code></dt>
<dd><p>Represents a single key-value pair in the database. This is a simple value type; mutating it won&#8217;t affect your <a class="reference internal" href="#FDB::Transaction" title="FDB::Transaction"><code class="xref rb rb-class docutils literal"><span class="pre">Transaction</span></code></a> or <a class="reference internal" href="#FDB::Database" title="FDB::Database"><code class="xref rb rb-class docutils literal"><span class="pre">Database</span></code></a>.</p>
<dl class="attr_reader">
<dt id="FDB::KeyValue#key">
<em class="property">attribute [R] </em><code class="descname">key</code></dt>
<dd></dd></dl>
<dl class="attr_reader">
<dt id="FDB::KeyValue#value">
<em class="property">attribute [R] </em><code class="descname">value</code></dt>
<dd></dd></dl>
</dd></dl>
</div>
<div class="section" id="key-selectors">
<h2>Key selectors</h2>
<p>FoundationDB&#8217;s lexicographically ordered data model permits finding keys based on their order (for example, finding the first key in the database greater than a given key). Key selectors represent a description of a key in the database that could be resolved to an actual key by <a class="reference internal" href="#FDB::Transaction.get_key" title="FDB::Transaction.get_key"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get_key</span></code></a> or used directly as the beginning or end of a range in <a class="reference internal" href="#FDB::Transaction.get_range" title="FDB::Transaction.get_range"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get_range</span></code></a>.</p>
<p>For more about how key selectors work, see <a class="reference internal" href="developer-guide.html#key-selectors"><span class="std std-ref">Key selectors</span></a>.</p>
<dl class="class">
<dt id="FDB::KeySelector">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">KeySelector</code><span class="sig-paren">(</span><em>key</em>, <em>or_equal</em>, <em>offset</em><span class="sig-paren">)</span></dt>
<dd><p>Creates a key selector with the given reference key, equality flag, and offset. It is usually more convenient to obtain a key selector with one of the following methods:</p>
<dl class="classmethod">
<dt id="FDB::KeySelector.last_less_than">
<em class="property">classmethod KeySelector.</em><code class="descname">last_less_than</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; KeySelector</dt>
<dd><p>Returns a key selector referencing the last (greatest) key in the database less than the specified key.</p>
</dd></dl>
<dl class="classmethod">
<dt id="FDB::KeySelector.last_less_or_equal">
<em class="property">classmethod KeySelector.</em><code class="descname">last_less_or_equal</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; KeySelector</dt>
<dd><p>Returns a key selector referencing the last (greatest) key less than, or equal to, the specified key.</p>
</dd></dl>
<dl class="classmethod">
<dt id="FDB::KeySelector.first_greater_than">
<em class="property">classmethod KeySelector.</em><code class="descname">first_greater_than</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; KeySelector</dt>
<dd><p>Returns a key selector referencing the first (least) key greater than the specified key.</p>
</dd></dl>
<dl class="classmethod">
<dt id="FDB::KeySelector.first_greater_or_equal">
<em class="property">classmethod KeySelector.</em><code class="descname">first_greater_or_equal</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; KeySelector</dt>
<dd><p>Returns a key selector referencing the first key greater than, or equal to, the specified key.</p>
</dd></dl>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">KeySelector.+(offset) -&gt; KeySelector</code></dt>
<dd><p>Adding an integer <code class="docutils literal"><span class="pre">offset</span></code> to a <a class="reference internal" href="#FDB::KeySelector" title="FDB::KeySelector"><code class="xref rb rb-class docutils literal"><span class="pre">KeySelector</span></code></a> returns a new key selector referencing a key <code class="docutils literal"><span class="pre">offset</span></code> keys after the original <a class="reference internal" href="#FDB::KeySelector" title="FDB::KeySelector"><code class="xref rb rb-class docutils literal"><span class="pre">KeySelector</span></code></a>. FoundationDB does not efficiently resolve key selectors with large offsets, so <a class="reference internal" href="known-limitations.html#dont-use-key-selectors-for-paging"><span class="std std-ref">Key selectors with large offsets are slow</span></a>.</p>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">KeySelector.-(offset) -&gt; KeySelector</code></dt>
<dd><p>Subtracting an integer <code class="docutils literal"><span class="pre">offset</span></code> from a <a class="reference internal" href="#FDB::KeySelector" title="FDB::KeySelector"><code class="xref rb rb-class docutils literal"><span class="pre">KeySelector</span></code></a> returns a new key selector referencing a key <code class="docutils literal"><span class="pre">offset</span></code> keys before the original <a class="reference internal" href="#FDB::KeySelector" title="FDB::KeySelector"><code class="xref rb rb-class docutils literal"><span class="pre">KeySelector</span></code></a>. FoundationDB does not efficiently resolve key selectors with large offsets, so <a class="reference internal" href="known-limitations.html#dont-use-key-selectors-for-paging"><span class="std std-ref">Key selectors with large offsets are slow</span></a>.</p>
</dd></dl>
</div>
<div class="section" id="database-objects">
<h2>Database objects</h2>
<dl class="class">
<dt id="FDB::Database">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">Database</code></dt>
<dd></dd></dl>
<p>A <code class="docutils literal"><span class="pre">Database</span></code> represents a FoundationDB database &#8212; a mutable, lexicographically ordered mapping from binary keys to binary values. Although <code class="docutils literal"><span class="pre">Database</span></code> provides convenience methods for reading and writing, modifications to a database are usually via transactions, which are usually created and committed automatically by <code class="xref rb rb-meth docutils literal"><span class="pre">Database.transact</span></code>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The convenience methods provided by <code class="docutils literal"><span class="pre">Database</span></code> have the same signature as the corresponding methods of <code class="docutils literal"><span class="pre">Transaction</span></code>. However, most of the <code class="docutils literal"><span class="pre">Database</span></code> methods are fully synchronous. (An exception is the methods for watches.) As a result, the <code class="docutils literal"><span class="pre">Database</span></code> methods do not support the use of <a class="reference internal" href="developer-guide.html#developer-guide-programming-with-futures"><span class="std std-ref">implicit parallelism with futures</span></a>.</p>
</div>
<dl class="method">
<dt>
<code class="descname">Database.transact() {|tr| block }</code></dt>
<dd><p>Executes the provided block with a new transaction, commits the transaction, and retries the block as necessary in response to retryable database errors such as transaction conflicts. This is the recommended way to do operations transactionally.</p>
<p>This method, along with <code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.transact</span></code>, makes it easy to write a transactional functions which accept either a <a class="reference internal" href="#FDB::Database" title="FDB::Database"><code class="xref rb rb-class docutils literal"><span class="pre">Database</span></code></a> or a <a class="reference internal" href="#FDB::Transaction" title="FDB::Transaction"><code class="xref rb rb-class docutils literal"><span class="pre">Transaction</span></code></a> as a parameter. See <a class="reference internal" href="#transact"><span class="std std-ref">The transact method</span></a> for explanation and examples.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">In some failure scenarios, it is possible that your transaction will be executed twice. See <a class="reference internal" href="developer-guide.html#developer-guide-unknown-results"><span class="std std-ref">Transactions with unknown results</span></a> for more information.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.create_transaction">
<code class="descclassname">Database.</code><code class="descname">create_transaction</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; Transaction</dt>
<dd><p>Starts a new transaction on the database. Consider using <code class="xref rb rb-meth docutils literal"><span class="pre">Database.transact</span></code> instead, since it will automatically provide you with appropriate commit and retry behavior.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.get">
<code class="descclassname">Database.</code><code class="descname">get</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; String or nil</dt>
<dd><p>Returns the value associated with the specified key in the database (or <code class="docutils literal"><span class="pre">nil</span></code> if the key does not exist). This read is fully synchronous.</p>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">Database.[](key) -&gt; String or nil</code></dt>
<dd><p>Alias of <a class="reference internal" href="#FDB::Database.get" title="FDB::Database.get"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.get</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.get_key">
<code class="descclassname">Database.</code><code class="descname">get_key</code><span class="sig-paren">(</span><em>key_selector</em><span class="sig-paren">)</span> &#x2192; String</dt>
<dd><p>Returns the key referenced by the specified <a class="reference internal" href="#FDB::KeySelector" title="FDB::KeySelector"><code class="xref rb rb-class docutils literal"><span class="pre">KeySelector</span></code></a>. This read is fully synchronous.</p>
<p>The key is cached, providing a potential performance benefit. However, the
value of the key is also retrieved, using network bandwidth.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.get_range">
<code class="descclassname">Database.</code><code class="descname">get_range</code><span class="sig-paren">(</span><em>begin</em>, <em>end</em>, <em>options={}</em><span class="sig-paren">)</span> &#x2192; Array</dt>
<dd><p>Returns all keys <code class="docutils literal"><span class="pre">k</span></code> such that <code class="docutils literal"><span class="pre">begin</span> <span class="pre">&lt;=</span> <span class="pre">k</span> <span class="pre">&lt;</span> <span class="pre">end</span></code> and their associated values as an <code class="xref rb rb-class docutils literal"><span class="pre">Array</span></code> of <a class="reference internal" href="#FDB::KeyValue" title="FDB::KeyValue"><code class="xref rb rb-class docutils literal"><span class="pre">KeyValue</span></code></a> objects. Note the exclusion of <code class="docutils literal"><span class="pre">end</span></code> from the range. This read is fully synchronous.</p>
<p>Each of <code class="docutils literal"><span class="pre">begin</span></code> and <code class="docutils literal"><span class="pre">end</span></code> may be a key (<code class="xref rb rb-class docutils literal"><span class="pre">String</span></code> or <a class="reference internal" href="#FDB::Key" title="FDB::Key"><code class="xref rb rb-class docutils literal"><span class="pre">Key</span></code></a>) or a <a class="reference internal" href="#FDB::KeySelector" title="FDB::KeySelector"><code class="xref rb rb-class docutils literal"><span class="pre">KeySelector</span></code></a>. Note that in the case of a <a class="reference internal" href="#FDB::KeySelector" title="FDB::KeySelector"><code class="xref rb rb-class docutils literal"><span class="pre">KeySelector</span></code></a>, the exclusion of <code class="docutils literal"><span class="pre">end</span></code> from the range still applies.</p>
<p>The <code class="docutils literal"><span class="pre">options</span></code> hash accepts the following optional parameters:</p>
<dl class="docutils">
<dt><code class="docutils literal"><span class="pre">:limit</span></code></dt>
<dd>Only the first <code class="docutils literal"><span class="pre">limit</span></code> keys (and their values) in the range will be returned.</dd>
<dt><code class="docutils literal"><span class="pre">:reverse</span></code></dt>
<dd><p class="first">If <code class="docutils literal"><span class="pre">true</span></code>, then the keys in the range will be returned in reverse order. Reading ranges in reverse is supported natively by the database and should have minimal extra cost.</p>
<p class="last">If <code class="docutils literal"><span class="pre">:limit</span></code> is also specified, the <em>last</em> <code class="docutils literal"><span class="pre">limit</span></code> keys in the range will be returned in reverse order.</p>
</dd>
<dt><code class="docutils literal"><span class="pre">:streaming_mode</span></code></dt>
<dd>A valid <a class="reference internal" href="#ruby-streaming-mode"><span class="std std-ref">streaming mode</span></a>, which provides a hint to FoundationDB about how to retrieve the specified range. This option should generally not be specified, allowing FoundationDB to retrieve the full range very efficiently.</dd>
</dl>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">Database.get_range(begin, end, options={}) {|kv| block } -&gt; nil</code></dt>
<dd><p>If given a block, <a class="reference internal" href="#FDB::Database.get_range" title="FDB::Database.get_range"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.get_range</span></code></a> yields each <a class="reference internal" href="#FDB::KeyValue" title="FDB::KeyValue"><code class="xref rb rb-class docutils literal"><span class="pre">KeyValue</span></code></a> in the range that would otherwise have been returned to <code class="docutils literal"><span class="pre">block</span></code>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.get_range_start_with">
<code class="descclassname">Database.</code><code class="descname">get_range_start_with</code><span class="sig-paren">(</span><em>prefix</em>, <em>options={}</em><span class="sig-paren">)</span> &#x2192; Array</dt>
<dd><p>Returns all keys <code class="docutils literal"><span class="pre">k</span></code> such that <code class="docutils literal"><span class="pre">k.start_with?</span> <span class="pre">prefix</span></code>, and their associated values, as an <code class="xref rb rb-class docutils literal"><span class="pre">Array</span></code> of <a class="reference internal" href="#FDB::KeyValue" title="FDB::KeyValue"><code class="xref rb rb-class docutils literal"><span class="pre">KeyValue</span></code></a> objects. The <code class="docutils literal"><span class="pre">options</span></code> hash accepts the same values as <a class="reference internal" href="#FDB::Database.get_range" title="FDB::Database.get_range"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.get_range</span></code></a>. This read is fully synchronous.</p>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">Database.get_range_start_with(prefix, options={}) {|kv| block } -&gt; nil</code></dt>
<dd><p>If given a block, <a class="reference internal" href="#FDB::Database.get_range_start_with" title="FDB::Database.get_range_start_with"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.get_range_start_with</span></code></a> yields each <a class="reference internal" href="#FDB::KeyValue" title="FDB::KeyValue"><code class="xref rb rb-class docutils literal"><span class="pre">KeyValue</span></code></a> in the range that would otherwise have been returned to <code class="docutils literal"><span class="pre">block</span></code>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.set">
<code class="descclassname">Database.</code><code class="descname">set</code><span class="sig-paren">(</span><em>key</em>, <em>value</em><span class="sig-paren">)</span> &#x2192; value</dt>
<dd><p>Associates the given <code class="docutils literal"><span class="pre">key</span></code> and <code class="docutils literal"><span class="pre">value</span></code>. Overwrites any prior value associated with <code class="docutils literal"><span class="pre">key</span></code>. Returns the same value that was passed in. This change will be committed immediately, and is fully synchronous.</p>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">Database.[]=(key, value) -&gt; value</code></dt>
<dd><p>Alias of <a class="reference internal" href="#FDB::Database.set" title="FDB::Database.set"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.set</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.clear">
<code class="descclassname">Database.</code><code class="descname">clear</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Removes the specified <code class="docutils literal"><span class="pre">key</span></code> (and any associated value), if it exists. This change will be committed immediately, and is fully synchronous.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.clear_range">
<code class="descclassname">Database.</code><code class="descname">clear_range</code><span class="sig-paren">(</span><em>begin</em>, <em>end</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Removes all keys <code class="docutils literal"><span class="pre">k</span></code> such that <code class="docutils literal"><span class="pre">begin</span> <span class="pre">&lt;=</span> <span class="pre">k</span> <span class="pre">&lt;</span> <span class="pre">end</span></code>, and their associated values. This change will be committed immediately, and is fully synchronous.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.clear_range_start_with">
<code class="descclassname">Database.</code><code class="descname">clear_range_start_with</code><span class="sig-paren">(</span><em>prefix</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Removes all keys <code class="docutils literal"><span class="pre">k</span></code> such that <code class="docutils literal"><span class="pre">k.start_with?</span> <span class="pre">prefix</span></code>, and their associated values. This change will be committed immediately, and is fully synchronous.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.get_and_watch">
<code class="descclassname">Database.</code><code class="descname">get_and_watch</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; [value, FutureNil]</dt>
<dd><p>Returns an array <code class="docutils literal"><span class="pre">[value,</span> <span class="pre">watch]</span></code>, where <code class="docutils literal"><span class="pre">value</span></code> is the value associated with <code class="docutils literal"><span class="pre">key</span></code> or <code class="docutils literal"><span class="pre">nil</span></code> if the key does not exist, and <code class="docutils literal"><span class="pre">watch</span></code> is a <a class="reference internal" href="#FDB::FutureNil" title="FDB::FutureNil"><code class="xref rb rb-class docutils literal"><span class="pre">FutureNil</span></code></a> that will become ready after <code class="docutils literal"><span class="pre">value</span></code> changes.</p>
<p>See <a class="reference internal" href="#FDB::Transaction.watch" title="FDB::Transaction.watch"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.watch</span></code></a> for a general description of watches and their limitations.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.set_and_watch">
<code class="descclassname">Database.</code><code class="descname">set_and_watch</code><span class="sig-paren">(</span><em>key</em>, <em>value</em><span class="sig-paren">)</span> &#x2192; FutureNil</dt>
<dd><p>Sets <code class="docutils literal"><span class="pre">key</span></code> to <code class="docutils literal"><span class="pre">value</span></code> and returns a <a class="reference internal" href="#FDB::FutureNil" title="FDB::FutureNil"><code class="xref rb rb-class docutils literal"><span class="pre">FutureNil</span></code></a> that will become ready after a subsequent change to <code class="docutils literal"><span class="pre">value</span></code>.</p>
<p>See <a class="reference internal" href="#FDB::Transaction.watch" title="FDB::Transaction.watch"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.watch</span></code></a> for a general description of watches and their limitations.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.clear_and_watch">
<code class="descclassname">Database.</code><code class="descname">clear_and_watch</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; FutureNil</dt>
<dd><p>Removes <code class="docutils literal"><span class="pre">key</span></code> (and any associated value) if it exists and returns a <a class="reference internal" href="#FDB::FutureNil" title="FDB::FutureNil"><code class="xref rb rb-class docutils literal"><span class="pre">FutureNil</span></code></a> that will become ready after the value is subsequently set.</p>
<p>See <a class="reference internal" href="#FDB::Transaction.watch" title="FDB::Transaction.watch"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.watch</span></code></a> for a general description of watches and their limitations.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.add">
<code class="descclassname">Database.</code><code class="descname">add</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd></dd></dl>
<dl class="method">
<dt id="FDB::Database.bit_and">
<code class="descclassname">Database.</code><code class="descname">bit_and</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd></dd></dl>
<dl class="method">
<dt id="FDB::Database.bit_or">
<code class="descclassname">Database.</code><code class="descname">bit_or</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd></dd></dl>
<dl class="method">
<dt id="FDB::Database.bit_xor">
<code class="descclassname">Database.</code><code class="descname">bit_xor</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>These atomic operations behave exactly like the <a class="reference internal" href="#api-ruby-transaction-atomic-operations"><span class="std std-ref">associated operations</span></a> on <a class="reference internal" href="#FDB::Transaction" title="FDB::Transaction"><code class="xref rb rb-class docutils literal"><span class="pre">Transaction</span></code></a> objects except that the change will immediately be committed, and is fully synchronous.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Note that since some atomic operations are not idempotent, the implicit use of <code class="xref rb rb-meth docutils literal"><span class="pre">Database.transact</span></code> could interact with a <a class="reference internal" href="api-error-codes.html#developer-guide-error-codes"><span class="std std-ref">commit_unknown_result</span></a> exception in unpredictable ways. For more information, see <a class="reference internal" href="developer-guide.html#developer-guide-unknown-results"><span class="std std-ref">Transactions with unknown results</span></a>.</p>
</div>
</dd></dl>
<div class="section" id="database-options">
<h3>Database options</h3>
<p>Database options alter the behavior of FoundationDB databases.</p>
<dl class="method">
<dt id="FDB::Database.options.set_location_cache_size">
<code class="descclassname">Database.options.</code><code class="descname">set_location_cache_size</code><span class="sig-paren">(</span><em>size</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Set the size of the client location cache. Raising this value can boost performance in very large databases where clients access data in a near-random pattern. This value must be an integer in the range [0, 2<sup>31</sup>-1]. Defaults to 100000.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.options.set_max_watches">
<code class="descclassname">Database.options.</code><code class="descname">set_max_watches</code><span class="sig-paren">(</span><em>max_watches</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Set the maximum number of watches allowed to be outstanding on a database connection. Increasing this number could result in increased resource usage. Reducing this number will not cancel any outstanding watches. Defaults to 10000 and cannot be larger than 1000000.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.options.set_machine_id">
<code class="descclassname">Database.options.</code><code class="descname">set_machine_id</code><span class="sig-paren">(</span><em>id</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Specify the machine ID of a server to be preferentially used for database operations. ID must be a string of up to 16 hexadecimal digits that was used to configure <a class="reference internal" href="configuration.html#foundationdb-conf-fdbserver"><span class="std std-ref">fdbserver processes</span></a>. Load balancing uses this option for location-awareness, attempting to send database operations first to servers on a specified machine, then a specified datacenter, then returning to its default algorithm.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.options.set_datacenter_id">
<code class="descclassname">Database.options.</code><code class="descname">set_datacenter_id</code><span class="sig-paren">(</span><em>id</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Specify the datacenter ID to be preferentially used for database operations. ID must be a string of up to 16 hexadecimal digits that was used to configure <a class="reference internal" href="configuration.html#foundationdb-conf-fdbserver"><span class="std std-ref">fdbserver processes</span></a>. Load balancing uses this option for location-awareness, attempting to send database operations first to servers on a specified machine, then a specified datacenter, then returning to its default algorithm.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.options.set_transaction_timeout">
<code class="descclassname">Database.options.</code><code class="descname">set_transaction_timeout</code><span class="sig-paren">(</span><em>timeout</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Set the default timeout duration in milliseconds after which all transactions created by this database will automatically be cancelled. This is equivalent to calling <a class="reference internal" href="#FDB::Transaction.options.set_timeout" title="FDB::Transaction.options.set_timeout"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.options.set_timeout</span></code></a> on each transaction created by this database. This option can only be called if the API version is at least 610.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.options.set_transaction_retry_limit">
<code class="descclassname">Database.options.</code><code class="descname">set_transaction_retry_limit</code><span class="sig-paren">(</span><em>retry_limit</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Set the default maximum number of retries for each transaction after which additional calls to <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a> will throw the most recently seen error code. This is equivalent to calling <a class="reference internal" href="#FDB::Transaction.options.set_retry_limit" title="FDB::Transaction.options.set_retry_limit"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.options.set_retry_limit</span></code></a> on each transaction created by this database.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.options.set_transaction_max_retry_delay">
<code class="descclassname">Database.options.</code><code class="descname">set_transaction_max_retry_delay</code><span class="sig-paren">(</span><em>delay_limit</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Set the default maximum backoff delay incurred by each transaction in the call to <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a> if the error is retryable. This is equivalent to calling <a class="reference internal" href="#FDB::Transaction.options.set_max_retry_delay" title="FDB::Transaction.options.set_max_retry_delay"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.options.set_max_retry_delay</span></code></a> on each transaction created by this database.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.options.set_transaction_size_limit">
<code class="descclassname">Database.options.</code><code class="descname">set_transaction_size_limit</code><span class="sig-paren">(</span><em>size_limit</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Set the default maximum transaction size in bytes. This is equivalent to calling <a class="reference internal" href="#FDB::Database.options.set_transaction_size_limit" title="FDB::Database.options.set_transaction_size_limit"><code class="xref rb rb-func docutils literal"><span class="pre">Database.options.set_transaction_size_limit</span></code></a> on each transaction created by this database.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.options.set_transaction_causal_read_risky">
<code class="descclassname">Database.options.</code><code class="descname">set_transaction_causal_read_risky</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Transactions do not require the strict causal consistency guarantee that FoundationDB provides by default. The read version will be committed, and usually will be the latest committed, but might not be the latest committed in the event of a simultaneous fault and misbehaving clock. Enabling this option is equivalent to calling <a class="reference internal" href="#FDB::Transaction.options.set_causal_read_risky" title="FDB::Transaction.options.set_causal_read_risky"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.options.set_causal_read_risky</span></code></a> on each transaction created by this database.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.options.set_transaction_logging_max_field_length">
<code class="descclassname">Database.options.</code><code class="descname">set_transaction_logging_max_field_length</code><span class="sig-paren">(</span><em>size_limit</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Sets the maximum escaped length of key and value fields to be logged to the trace file via the LOG_TRANSACTION option. This is equivalent to calling <a class="reference internal" href="#FDB::Transaction.options.set_transaction_logging_max_field_length" title="FDB::Transaction.options.set_transaction_logging_max_field_length"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.options.set_transaction_logging_max_field_length</span></code></a> on each transaction created by this database.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.options.set_snapshot_ryw_enable">
<code class="descclassname">Database.options.</code><code class="descname">set_snapshot_ryw_enable</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>If this option has been set an equal or more times with this database than the disable option, snapshot reads <em>will</em> see the effects of prior writes in the same transaction. Enabling this option is equivalent to calling <a class="reference internal" href="#FDB::Transaction.options.set_snapshot_ryw_enable" title="FDB::Transaction.options.set_snapshot_ryw_enable"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.options.set_snapshot_ryw_enable</span></code></a> on each transaction created by this database.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Database.options.set_snapshot_ryw_disable">
<code class="descclassname">Database.options.</code><code class="descname">set_snapshot_ryw_disable</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>If this option has been set more times with this database than the disable option, snapshot reads will <em>not</em> see the effects of prior writes in the same transaction. Disabling this option is equivalent to calling <a class="reference internal" href="#FDB::Transaction.options.set_snapshot_ryw_disable" title="FDB::Transaction.options.set_snapshot_ryw_disable"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.options.set_snapshot_ryw_disable</span></code></a> on each transaction created by this database.</p>
</dd></dl>
</div>
</div>
<div class="section" id="transaction-objects">
<h2>Transaction objects</h2>
<dl class="class">
<dt id="FDB::Transaction">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">Transaction</code></dt>
<dd></dd></dl>
<p>A <code class="docutils literal"><span class="pre">Transaction</span></code> object represents a FoundationDB database transaction. All operations on FoundationDB take place, explicitly or implicitly, through a <code class="docutils literal"><span class="pre">Transaction</span></code>.</p>
<p>In FoundationDB, a transaction is a mutable snapshot of a database. All read and write operations on a transaction see and modify an otherwise-unchanging version of the database and only change the underlying database if and when the transaction is committed. Read operations do see the effects of previous write operations on the same transaction. Committing a transaction usually succeeds in the absence of <a class="reference internal" href="developer-guide.html#conflict-ranges"><span class="std std-ref">conflicts</span></a>.</p>
<p>Transactions group operations into a unit with the properties of <em>atomicity</em>, <em>isolation</em>, and <em>durability</em>. Transactions also provide the ability to maintain an application&#8217;s invariants or integrity constraints, supporting the property of <em>consistency</em>. Together these properties are known as <a class="reference internal" href="developer-guide.html#acid"><span class="std std-ref">ACID</span></a>.</p>
<p>Transactions are also causally consistent: once a transaction has been successfully committed, all subsequently created transactions will see the modifications made by it.</p>
<p>The most convenient way to create and use transactions is using the <code class="xref rb rb-meth docutils literal"><span class="pre">Database.transact</span></code> method.</p>
<p>Keys and values in FoundationDB are byte strings. FoundationDB will accept Ruby strings with any encoding, but will always return strings with <code class="docutils literal"><span class="pre">ASCII-8BIT</span></code> encoding (also known as <code class="docutils literal"><span class="pre">BINARY</span></code>). To encode other data types, see the <a class="reference internal" href="#module-FDB::Tuple"><code class="xref rb rb-mod docutils literal"><span class="pre">FDB::Tuple</span></code></a> module and <a class="reference internal" href="data-modeling.html#encoding-data-types"><span class="std std-ref">Encoding data types</span></a>.</p>
<div class="section" id="attributes">
<h3>Attributes</h3>
<dl class="global">
<dt id="db">
<code class="descclassname">Transaction.</code><code class="descname">db</code></dt>
<dd><p>The <a class="reference internal" href="#FDB::Database" title="FDB::Database"><code class="xref rb rb-class docutils literal"><span class="pre">Database</span></code></a> that this transaction is interacting with.</p>
</dd></dl>
</div>
<div class="section" id="reading-data">
<h3>Reading data</h3>
<dl class="method">
<dt id="FDB::Transaction.get">
<code class="descclassname">Transaction.</code><code class="descname">get</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; Value</dt>
<dd><p>Returns the value associated with the specified key in the database (which may be <code class="docutils literal"><span class="pre">nil</span></code> if the key does not exist).</p>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">Transaction.[](key)</code></dt>
<dd><p>Alias of <a class="reference internal" href="#FDB::Transaction.get" title="FDB::Transaction.get"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.get_key">
<code class="descclassname">Transaction.</code><code class="descname">get_key</code><span class="sig-paren">(</span><em>key_selector</em><span class="sig-paren">)</span> &#x2192; Key</dt>
<dd><p>Returns the key referenced by the specified <a class="reference internal" href="#FDB::KeySelector" title="FDB::KeySelector"><code class="xref rb rb-class docutils literal"><span class="pre">KeySelector</span></code></a>.</p>
<p>By default, the key is cached for the duration of the transaction, providing
a potential performance benefit. However, the value of the key is also retrieved,
using network bandwidth. Invoking <a class="reference internal" href="#FDB::Transaction.options.set_read_your_writes_disable" title="FDB::Transaction.options.set_read_your_writes_disable"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.options.set_read_your_writes_disable</span></code></a> will avoid
both the caching and the increased network bandwidth.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.get_range">
<code class="descclassname">Transaction.</code><code class="descname">get_range</code><span class="sig-paren">(</span><em>begin</em>, <em>end</em>, <em>options={}</em><span class="sig-paren">)</span> &#x2192; an_enumerable</dt>
<dd><p>Returns all keys <code class="docutils literal"><span class="pre">k</span></code> such that <code class="docutils literal"><span class="pre">begin</span> <span class="pre">&lt;=</span> <span class="pre">k</span> <span class="pre">&lt;</span> <span class="pre">end</span></code> and their associated values as an enumerable of <a class="reference internal" href="#FDB::KeyValue" title="FDB::KeyValue"><code class="xref rb rb-class docutils literal"><span class="pre">KeyValue</span></code></a> objects. Note the exclusion of <code class="docutils literal"><span class="pre">end</span></code> from the range.</p>
<p>Like a <a class="reference internal" href="#api-ruby-future"><span class="std std-ref">Future</span></a> object, the returned enumerable issues asynchronous read operations to fetch data in the range, and may block while enumerating its values if the read has not completed. Data will be fetched in one more more efficient batches (depending on the value of the <code class="docutils literal"><span class="pre">:streaming_mode</span></code> parameter).</p>
<p>Each of <code class="docutils literal"><span class="pre">begin</span></code> and <code class="docutils literal"><span class="pre">end</span></code> may be a key (<code class="xref rb rb-class docutils literal"><span class="pre">String</span></code> or <a class="reference internal" href="#FDB::Key" title="FDB::Key"><code class="xref rb rb-class docutils literal"><span class="pre">Key</span></code></a>) or a <a class="reference internal" href="#FDB::KeySelector" title="FDB::KeySelector"><code class="xref rb rb-class docutils literal"><span class="pre">KeySelector</span></code></a>. Note that in the case of a <a class="reference internal" href="#FDB::KeySelector" title="FDB::KeySelector"><code class="xref rb rb-class docutils literal"><span class="pre">KeySelector</span></code></a>, the exclusion of <code class="docutils literal"><span class="pre">end</span></code> from the range still applies.</p>
<p>The <code class="docutils literal"><span class="pre">options</span></code> hash accepts the following optional parameters:</p>
<dl class="docutils">
<dt><code class="docutils literal"><span class="pre">:limit</span></code></dt>
<dd>Only the first <code class="docutils literal"><span class="pre">limit</span></code> keys (and their values) in the range will be returned.</dd>
<dt><code class="docutils literal"><span class="pre">:reverse</span></code></dt>
<dd><p class="first">If <code class="docutils literal"><span class="pre">true</span></code>, then the keys in the range will be returned in reverse order. Reading ranges in reverse is supported natively by the database and should have minimal extra cost.</p>
<p class="last">If <code class="docutils literal"><span class="pre">:limit</span></code> is also specified, the <em>last</em> <code class="docutils literal"><span class="pre">limit</span></code> keys in the range will be returned in reverse order.</p>
</dd>
<dt><code class="docutils literal"><span class="pre">:streaming_mode</span></code></dt>
<dd>A valid <a class="reference internal" href="#ruby-streaming-mode"><span class="std std-ref">streaming mode</span></a>, which provides a hint to FoundationDB about how the returned enumerable is likely to be used. The default is <code class="docutils literal"><span class="pre">:iterator</span></code>.</dd>
</dl>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">Transaction.get_range(begin, end, options={}) {|kv| block } -&gt; nil</code></dt>
<dd><p>If given a block, <a class="reference internal" href="#FDB::Transaction.get_range" title="FDB::Transaction.get_range"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get_range</span></code></a> yields each <a class="reference internal" href="#FDB::KeyValue" title="FDB::KeyValue"><code class="xref rb rb-class docutils literal"><span class="pre">KeyValue</span></code></a> in the range that would otherwise have been returned to <code class="docutils literal"><span class="pre">block</span></code>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.get_range_start_with">
<code class="descclassname">Transaction.</code><code class="descname">get_range_start_with</code><span class="sig-paren">(</span><em>prefix</em>, <em>options={}</em><span class="sig-paren">)</span> &#x2192; an_enumerable</dt>
<dd><p>Returns all keys <code class="docutils literal"><span class="pre">k</span></code> such that <code class="docutils literal"><span class="pre">k.start_with?</span> <span class="pre">prefix</span></code>, and their associated values, as an enumerable of <a class="reference internal" href="#FDB::KeyValue" title="FDB::KeyValue"><code class="xref rb rb-class docutils literal"><span class="pre">KeyValue</span></code></a> objects (see <a class="reference internal" href="#FDB::Transaction.get_range" title="FDB::Transaction.get_range"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get_range</span></code></a> for a description of the returned enumerable).</p>
<p>The <code class="docutils literal"><span class="pre">options</span></code> hash accepts the same values as <a class="reference internal" href="#FDB::Transaction.get_range" title="FDB::Transaction.get_range"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get_range</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">Transaction.get_range_start_with(prefix, options={}) {|kv| block } -&gt; nil</code></dt>
<dd><p>If given a block, <a class="reference internal" href="#FDB::Transaction.get_range_start_with" title="FDB::Transaction.get_range_start_with"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get_range_start_with</span></code></a> yields each <a class="reference internal" href="#FDB::KeyValue" title="FDB::KeyValue"><code class="xref rb rb-class docutils literal"><span class="pre">KeyValue</span></code></a> in the range that would otherwise have been returned to <code class="docutils literal"><span class="pre">block</span></code>.</p>
</dd></dl>
</div>
<div class="section" id="snapshot-reads">
<h3>Snapshot reads</h3>
<dl class="global">
<dt id="snapshot">
<code class="descclassname">Transaction.</code><code class="descname">snapshot</code></dt>
<dd><p>Snapshot reads selectively relax FoundationDB&#8217;s isolation property, reducing <a class="reference internal" href="developer-guide.html#developer-guide-transaction-conflicts"><span class="std std-ref">conflicts</span></a> but making it harder to reason about concurrency.</p>
<p>By default, FoundationDB transactions guarantee <a class="reference internal" href="developer-guide.html#acid"><span class="std std-ref">strictly serializable isolation</span></a>, resulting in a state that is <em>as if</em> transactions were executed one at a time, even if they were executed concurrently. Serializability has little performance cost when there are few <a class="reference internal" href="developer-guide.html#developer-guide-transaction-conflicts"><span class="std std-ref">conflicts</span></a> but can be expensive when there are many. FoundationDB therefore also permits individual reads within a transaction to be done as snapshot reads.</p>
<p>Snapshot reads differ from ordinary (strictly serializable) reads by permitting the values they read to be modified by concurrent transactions, whereas strictly serializable reads cause conflicts in that case. Like strictly serializable reads, snapshot reads see the effects of prior writes in the same transaction. For more information on the use of snapshot reads, see <a class="reference internal" href="developer-guide.html#snapshot-isolation"><span class="std std-ref">Snapshot reads</span></a>.</p>
<p>Snapshot reads also interact with transaction commit a little differently than normal reads. If a snapshot read is outstanding when transaction commit is called that read will immediately return an error. (Normally, transaction commit will wait until outstanding reads return before committing.)</p>
</dd></dl>
<dl class="global">
<dt>
<code class="descclassname">Transaction.snapshot.</code><code class="descname">db</code></dt>
<dd><p>The <a class="reference internal" href="#FDB::Database" title="FDB::Database"><code class="xref rb rb-class docutils literal"><span class="pre">Database</span></code></a> that this transaction is interacting with.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.snapshot.get">
<code class="descclassname">Transaction.snapshot.</code><code class="descname">get</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; Value</dt>
<dd><p>Like <a class="reference internal" href="#FDB::Transaction.get" title="FDB::Transaction.get"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get</span></code></a>, but as a snapshot read.</p>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">Transaction.snapshot.[](key) -&gt; Value</code></dt>
<dd><p>Alias of <a class="reference internal" href="#FDB::Transaction.snapshot.get" title="FDB::Transaction.snapshot.get"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.snapshot.get</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.snapshot.get_key">
<code class="descclassname">Transaction.snapshot.</code><code class="descname">get_key</code><span class="sig-paren">(</span><em>key_selector</em><span class="sig-paren">)</span> &#x2192; Key</dt>
<dd><p>Like <a class="reference internal" href="#FDB::Transaction.get_key" title="FDB::Transaction.get_key"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get_key</span></code></a>, but as a snapshot read.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.snapshot.get_range">
<code class="descclassname">Transaction.snapshot.</code><code class="descname">get_range</code><span class="sig-paren">(</span><em>begin</em>, <em>end</em>, <em>options={}</em><span class="sig-paren">)</span> &#x2192; an_enumerable</dt>
<dd><p>Like <a class="reference internal" href="#FDB::Transaction.get_range" title="FDB::Transaction.get_range"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get_range</span></code></a>, but as a snapshot read.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.snapshot.get_range_start_with">
<code class="descclassname">Transaction.snapshot.</code><code class="descname">get_range_start_with</code><span class="sig-paren">(</span><em>prefix</em>, <em>options={}</em><span class="sig-paren">)</span> &#x2192; an_enumerable</dt>
<dd><p>Like <a class="reference internal" href="#FDB::Transaction.get_range_start_with" title="FDB::Transaction.get_range_start_with"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get_range_start_with</span></code></a>, but as a snapshot read.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.snapshot.get_read_version">
<code class="descclassname">Transaction.snapshot.</code><code class="descname">get_read_version</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; Int64Future</dt>
<dd><p>Identical to <a class="reference internal" href="#FDB::Transaction.get_read_version" title="FDB::Transaction.get_read_version"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get_read_version</span></code></a> (since snapshot and strictly serializable reads use the same read version).</p>
</dd></dl>
</div>
<div class="section" id="writing-data">
<h3>Writing data</h3>
<dl class="method">
<dt id="FDB::Transaction.set">
<code class="descclassname">Transaction.</code><code class="descname">set</code><span class="sig-paren">(</span><em>key</em>, <em>value</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Associates the given <code class="docutils literal"><span class="pre">key</span></code> and <code class="docutils literal"><span class="pre">value</span></code>. Overwrites any prior value associated with <code class="docutils literal"><span class="pre">key</span></code>. Returns immediately, having modified the snapshot represented by this <a class="reference internal" href="#FDB::Transaction" title="FDB::Transaction"><code class="xref rb rb-class docutils literal"><span class="pre">Transaction</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">Transaction.[]=(key, value) -&gt; nil</code></dt>
<dd><p>Alias of <a class="reference internal" href="#FDB::Transaction.set" title="FDB::Transaction.set"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.set</span></code></a>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Although the above method returns nil, assignments in Ruby evaluate to the value assigned, so the expression <code class="docutils literal"><span class="pre">tr[key]</span> <span class="pre">=</span> <span class="pre">value</span></code> will return <code class="docutils literal"><span class="pre">value</span></code>.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.clear">
<code class="descclassname">Transaction.</code><code class="descname">clear</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Removes the specified key (and any associated value), if it exists. Returns immediately, having modified the snapshot represented by this <a class="reference internal" href="#FDB::Transaction" title="FDB::Transaction"><code class="xref rb rb-class docutils literal"><span class="pre">Transaction</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.clear_range">
<code class="descclassname">Transaction.</code><code class="descname">clear_range</code><span class="sig-paren">(</span><em>begin</em>, <em>end</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Removes all keys <code class="docutils literal"><span class="pre">k</span></code> such that <code class="docutils literal"><span class="pre">begin</span> <span class="pre">&lt;=</span> <span class="pre">k</span> <span class="pre">&lt;</span> <span class="pre">end</span></code>, and their associated values. Returns immediately, having modified the snapshot represented by this <a class="reference internal" href="#FDB::Transaction" title="FDB::Transaction"><code class="xref rb rb-class docutils literal"><span class="pre">Transaction</span></code></a>.</p>
<p>Range clears are efficient with FoundationDB &#8211; clearing large amounts of data will be fast. However, this will not immediately free up disk - data for the deleted range is cleaned up in the background. For purposes of computing the transaction size, only the begin and end keys of a clear range are counted. The size of the data stored in the range does not count against the transaction size limit.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Unlike in the case of <a class="reference internal" href="#FDB::Transaction.get_range" title="FDB::Transaction.get_range"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get_range</span></code></a>, <code class="docutils literal"><span class="pre">begin</span></code> and <code class="docutils literal"><span class="pre">end</span></code> must be keys (<code class="xref rb rb-class docutils literal"><span class="pre">String</span></code> or <a class="reference internal" href="#FDB::Key" title="FDB::Key"><code class="xref rb rb-class docutils literal"><span class="pre">Key</span></code></a>), not <a class="reference internal" href="#FDB::KeySelector" title="FDB::KeySelector"><code class="xref rb rb-class docutils literal"><span class="pre">KeySelector</span></code></a>s. (Resolving arbitrary key selectors would prevent this method from returning immediately, introducing concurrency issues.)</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.clear_range_start_with">
<code class="descclassname">Transaction.</code><code class="descname">clear_range_start_with</code><span class="sig-paren">(</span><em>prefix</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Removes all the keys <code class="docutils literal"><span class="pre">k</span></code> such that <code class="docutils literal"><span class="pre">k.start_with?</span> <span class="pre">prefix</span></code>, and their associated values. Returns immediately, having modified the snapshot represented by this <a class="reference internal" href="#FDB::Transaction" title="FDB::Transaction"><code class="xref rb rb-class docutils literal"><span class="pre">Transaction</span></code></a>.</p>
<p>Range clears are efficient with FoundationDB &#8211; clearing large amounts of data will be fast. However, this will not immediately free up disk - data for the deleted range is cleaned up in the background. For purposes of computing the transaction size, only the begin and end keys of a clear range are counted. The size of the data stored in the range does not count against the transaction size limit.</p>
</dd></dl>
</div>
<div class="section" id="atomic-operations">
<span id="api-ruby-transaction-atomic-operations"></span><h3>Atomic operations</h3>
<p>An atomic operation is a single database command that carries out several logical steps: reading the value of a key, performing a transformation on that value, and writing the result. Different atomic operations perform different transformations. Like other database operations, an atomic operation is used within a transaction; however, its use within a transaction will not cause the transaction to conflict.</p>
<p>Atomic operations do not expose the current value of the key to the client but simply send the database the transformation to apply. In regard to conflict checking, an atomic operation is equivalent to a write without a read. It can only cause <em>other</em> transactions performing reads of the key to conflict.</p>
<p>By combining these logical steps into a single, read-free operation, FoundationDB can guarantee that the transaction will not conflict due to the operation. This makes atomic operations ideal for operating on keys that are frequently modified. A common example is the use of a key-value pair as a counter.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">If a transaction uses both an atomic operation and a strictly serializable read on the same key, the benefits of using the atomic operation (for both conflict checking and performance) are lost.</p>
</div>
<p>In each of the methods below, <code class="docutils literal"><span class="pre">param</span></code> should be a string appropriately packed to represent the desired value. For example:</p>
<div class="highlight-ruby"><div class="highlight"><pre><span></span><span class="c1"># wrong</span>
<span class="n">tr</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s1">&#39;key&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="c1"># right</span>
<span class="n">tr</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s1">&#39;key&#39;</span><span class="p">,</span> <span class="o">[</span><span class="mi">1</span><span class="o">].</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;q&lt;&#39;</span><span class="p">))</span>
</pre></div>
</div>
<dl class="method">
<dt id="FDB::Transaction.add">
<code class="descclassname">Transaction.</code><code class="descname">add</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Performs an addition of little-endian integers. If the existing value in the database is not present or shorter than <code class="docutils literal"><span class="pre">param</span></code>, it is first extended to the length of <code class="docutils literal"><span class="pre">param</span></code> with zero bytes. If <code class="docutils literal"><span class="pre">param</span></code> is shorter than the existing value in the database, the existing value is truncated to match the length of <code class="docutils literal"><span class="pre">param</span></code>. In case of overflow, the result is truncated to the width of <code class="docutils literal"><span class="pre">param</span></code>.</p>
<p>The integers to be added must be stored in a little-endian representation. They can be signed in two&#8217;s complement representation or unsigned. You can add to an integer at a known offset in the value by prepending the appropriate number of zero bytes to <code class="docutils literal"><span class="pre">param</span></code> and padding with zero bytes to match the length of the value. However, this offset technique requires that you know the addition will not cause the integer field within the value to overflow.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.bit_and">
<code class="descclassname">Transaction.</code><code class="descname">bit_and</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Performs a bitwise &#8220;and&#8221; operation. If the existing value in the database is not present, then <code class="docutils literal"><span class="pre">param</span></code> is stored in the database. If the existing value in the database is shorter than <code class="docutils literal"><span class="pre">param</span></code>, it is first extended to the length of <code class="docutils literal"><span class="pre">param</span></code> with zero bytes. If <code class="docutils literal"><span class="pre">param</span></code> is shorter than the existing value in the database, the existing value is truncated to match the length of <code class="docutils literal"><span class="pre">param</span></code>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.bit_or">
<code class="descclassname">Transaction.</code><code class="descname">bit_or</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Performs a bitwise &#8220;or&#8221; operation. If the existing value in the database is not present or shorter than <code class="docutils literal"><span class="pre">param</span></code>, it is first extended to the length of <code class="docutils literal"><span class="pre">param</span></code> with zero bytes. If <code class="docutils literal"><span class="pre">param</span></code> is shorter than the existing value in the database, the existing value is truncated to match the length of <code class="docutils literal"><span class="pre">param</span></code>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.bit_xor">
<code class="descclassname">Transaction.</code><code class="descname">bit_xor</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Performs a bitwise &#8220;xor&#8221; operation. If the existing value in the database is not present or shorter than <code class="docutils literal"><span class="pre">param</span></code>, it is first extended to the length of <code class="docutils literal"><span class="pre">param</span></code> with zero bytes. If <code class="docutils literal"><span class="pre">param</span></code> is shorter than the existing value in the database, the existing value is truncated to match the length of <code class="docutils literal"><span class="pre">param</span></code>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.compare_and_clear">
<code class="descclassname">Transaction.</code><code class="descname">compare_and_clear</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Performs an atomic <code class="docutils literal"><span class="pre">compare</span> <span class="pre">and</span> <span class="pre">clear</span></code> operation. If the existing value in the database is equal to the given value, then given key is cleared.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.max">
<code class="descclassname">Transaction.</code><code class="descname">max</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Sets the value in the database to the larger of the existing value and <code class="docutils literal"><span class="pre">param</span></code>. If the existing value in the database is not present or shorter than <code class="docutils literal"><span class="pre">param</span></code>, it is first extended to the length of <code class="docutils literal"><span class="pre">param</span></code> with zero bytes. If <code class="docutils literal"><span class="pre">param</span></code> is shorter than the existing value in the database, the existing value is truncated to match the length of <code class="docutils literal"><span class="pre">param</span></code>.</p>
<p>Both the existing value and <code class="docutils literal"><span class="pre">param</span></code> are treated as unsigned integers. (This differs from the behavior of atomic addition.)</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.byte_max">
<code class="descclassname">Transaction.</code><code class="descname">byte_max</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Performs lexicographic comparison of byte strings. If the existing value in the database is not present, then <code class="docutils literal"><span class="pre">param</span></code> is stored. Otherwise the larger of the two values is then stored in the database.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.min">
<code class="descclassname">Transaction.</code><code class="descname">min</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Sets the value in the database to the smaller of the existing value and <code class="docutils literal"><span class="pre">param</span></code>. If the existing value in the database is not present, then <code class="docutils literal"><span class="pre">param</span></code> is stored in the database. If the existing value in the database is shorter than <code class="docutils literal"><span class="pre">param</span></code>, it is first extended to the length of <code class="docutils literal"><span class="pre">param</span></code> with zero bytes. If <code class="docutils literal"><span class="pre">param</span></code> is shorter than the existing value in the database, the existing value is truncated to match the length of <code class="docutils literal"><span class="pre">param</span></code>.</p>
<p>Both the existing value and <code class="docutils literal"><span class="pre">param</span></code> are treated as unsigned integers. (This differs from the behavior of atomic addition.)</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.byte_min">
<code class="descclassname">Transaction.</code><code class="descname">byte_min</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Performs lexicographic comparison of byte strings. If the existing value in the database is not present, then <code class="docutils literal"><span class="pre">param</span></code> is stored. Otherwise the smaller of the two values is then stored in the database.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.set_versionstamped_key">
<code class="descclassname">Transaction.</code><code class="descname">set_versionstamped_key</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Transforms <code class="docutils literal"><span class="pre">key</span></code> using a versionstamp for the transaction. This key must be at least 14 bytes long. The final 4 bytes will be interpreted as a 32-bit little-endian integer denoting an index into the key at which to perform the transformation, and then trimmed off the key. The 10 bytes in the key beginning at the index will be overwritten with the versionstamp. If the index plus 10 bytes points past the end of the key, the result will be an error. Sets the transformed key in the database to <code class="docutils literal"><span class="pre">param</span></code>.</p>
<p>A versionstamp is a 10 byte, unique, monotonically (but not sequentially) increasing value for each committed transaction. The first 8 bytes are the committed version of the database (serialized in big-endian order). The last 2 bytes are monotonic in the serialization order for transactions (serialized in big-endian order).</p>
<p>A transaction is not permitted to read any transformed key or value previously set within that transaction, and an attempt to do so will result in an <code class="docutils literal"><span class="pre">accessed_unreadable</span></code> error. The range of keys marked unreadable when setting a versionstamped key begins at the transactions&#8217;s read version if it is known, otherwise a versionstamp of all <code class="docutils literal"><span class="pre">0x00</span></code> bytes is conservatively assumed. The upper bound of the unreadable range is a versionstamp of all <code class="docutils literal"><span class="pre">0xFF</span></code> bytes.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">At this time, versionstamped keys are not compatible with the Tuple layer except in Java, Python, and Go. Note that this implies versionstamped keys may not be used with the Subspace and Directory layers except in those languages.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.set_versionstamped_value">
<code class="descclassname">Transaction.</code><code class="descname">set_versionstamped_value</code><span class="sig-paren">(</span><em>key</em>, <em>param</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Transforms <code class="docutils literal"><span class="pre">param</span></code> using a versionstamp for the transaction. This parameter must be at least 14 bytes long. The final 4 bytes will be interpreted as a 32-bit little-endian integer denoting an index into the parameter at which to perform the transformation, and then trimmed off the key. The 10 bytes in the parameter beginning at the index will be overwritten with the versionstamp. If the index plus 10 bytes points past the end of the parameter, the result will be an error. Sets <code class="docutils literal"><span class="pre">key</span></code> in the database to the transformed parameter.</p>
<p>A versionstamp is a 10 byte, unique, monotonically (but not sequentially) increasing value for each committed transaction. The first 8 bytes are the committed version of the database (serialized in big-endian order). The last 2 bytes are monotonic in the serialization order for transactions (serialized in big-endian order).</p>
<p>A transaction is not permitted to read any transformed key or value previously set within that transaction, and an attempt to do so will result in an <code class="docutils literal"><span class="pre">accessed_unreadable</span></code> error. The range of keys marked unreadable when setting a versionstamped key begins at the transactions&#8217;s read version if it is known, otherwise a versionstamp of all <code class="docutils literal"><span class="pre">0x00</span></code> bytes is conservatively assumed. The upper bound of the unreadable range is a versionstamp of all <code class="docutils literal"><span class="pre">0xFF</span></code> bytes.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">At this time, versionstamped values are not compatible with the Tuple layer except in Java, Python, and Go. Note that this implies versionstamped values may not be used with the Subspace and Directory layers except in those languages.</p>
</div>
</dd></dl>
</div>
<div class="section" id="committing">
<h3>Committing</h3>
<dl class="method">
<dt>
<code class="descname">Transaction.transact() {|tr| block }</code></dt>
<dd><p>Yields <code class="docutils literal"><span class="pre">self</span></code> to the given block.</p>
<p>This method, along with <code class="xref rb rb-meth docutils literal"><span class="pre">Database.transact</span></code>, makes it easy to write transactional functions which accept either a <a class="reference internal" href="#FDB::Database" title="FDB::Database"><code class="xref rb rb-class docutils literal"><span class="pre">Database</span></code></a> or a <a class="reference internal" href="#FDB::Transaction" title="FDB::Transaction"><code class="xref rb rb-class docutils literal"><span class="pre">Transaction</span></code></a> as a parameter. See <a class="reference internal" href="#transact"><span class="std std-ref">The transact method</span></a> for explanation and examples.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.commit">
<code class="descclassname">Transaction.</code><code class="descname">commit</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; FutureNil</dt>
<dd><p>Attempt to commit the changes made in the transaction to the database. Returns a <a class="reference internal" href="#FDB::FutureNil" title="FDB::FutureNil"><code class="xref rb rb-class docutils literal"><span class="pre">FutureNil</span></code></a>, representing the asynchronous result of the commit. You <strong>must</strong> call the <code class="xref rb rb-meth docutils literal"><span class="pre">wait()</span></code> method on the returned <a class="reference internal" href="#FDB::FutureNil" title="FDB::FutureNil"><code class="xref rb rb-class docutils literal"><span class="pre">FutureNil</span></code></a>, which will raise an exception if the commit failed.</p>
<p>As with other client/server databases, in some failure scenarios a client may be unable to determine whether a transaction succeeded. In these cases, <a class="reference internal" href="#FDB::Transaction.commit" title="FDB::Transaction.commit"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.commit</span></code></a> will raise a <a class="reference internal" href="api-error-codes.html#developer-guide-error-codes"><span class="std std-ref">commit_unknown_result</span></a> exception. The <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a> function treats this exception as retryable, so retry loops that don&#8217;t check for <a class="reference internal" href="api-error-codes.html#developer-guide-error-codes"><span class="std std-ref">commit_unknown_result</span></a> could execute the transaction twice. In these cases, you must consider the idempotence of the transaction. For more information, see <a class="reference internal" href="developer-guide.html#developer-guide-unknown-results"><span class="std std-ref">Transactions with unknown results</span></a>.</p>
<p>Normally, commit will wait for outstanding reads to return. However, if those reads were snapshot reads or the transaction option for disabling &#8220;read-your-writes&#8221; has been invoked, any outstanding reads will immediately return errors.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Consider using <code class="xref rb rb-meth docutils literal"><span class="pre">Database.transact</span></code>, which not only calls <a class="reference internal" href="#FDB::Database.create_transaction" title="FDB::Database.create_transaction"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.create_transaction</span></code></a> and <a class="reference internal" href="#FDB::Transaction.commit" title="FDB::Transaction.commit"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.commit</span></code></a> for you, but also implements the required error handling and retry logic for transactions.</p>
</div>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">If any operation is performed on a transaction after a commit has been issued but before it has returned, both the commit and the operation will raise a <a class="reference internal" href="api-error-codes.html#developer-guide-error-codes"><span class="std std-ref">used_during_commit</span></a> exception. In this case, all subsequent operations on this transaction will raise this error until <a class="reference internal" href="#FDB::Transaction.reset" title="FDB::Transaction.reset"><code class="xref rb rb-meth docutils literal"><span class="pre">reset</span></code></a> is called.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.on_error">
<code class="descclassname">Transaction.</code><code class="descname">on_error</code><span class="sig-paren">(</span><em>exception</em><span class="sig-paren">)</span> &#x2192; FutureNil</dt>
<dd><p>Determine whether an exception raised by a <a class="reference internal" href="#FDB::Transaction" title="FDB::Transaction"><code class="xref rb rb-class docutils literal"><span class="pre">Transaction</span></code></a> method is retryable. Returns a <a class="reference internal" href="#FDB::FutureNil" title="FDB::FutureNil"><code class="xref rb rb-class docutils literal"><span class="pre">FutureNil</span></code></a>. You <strong>must</strong> call the <code class="xref rb rb-meth docutils literal"><span class="pre">wait()</span></code> method on the <a class="reference internal" href="#FDB::FutureNil" title="FDB::FutureNil"><code class="xref rb rb-class docutils literal"><span class="pre">FutureNil</span></code></a>, which will return after a delay if the exception was retryable, or re-raise the exception if it was not.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Consider using <code class="xref rb rb-meth docutils literal"><span class="pre">Database.transact</span></code>, which calls this method for you.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.reset">
<code class="descclassname">Transaction.</code><code class="descname">reset</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Rollback a transaction, completely resetting it to its initial state. This is logically equivalent to destroying the transaction and creating a new one.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.cancel">
<code class="descclassname">Transaction.</code><code class="descname">cancel</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Cancels the transaction. All pending or future uses of the transaction will raise a <a class="reference internal" href="api-error-codes.html#developer-guide-error-codes"><span class="std std-ref">transaction_cancelled</span></a> exception. The transaction can be used again after it is <a class="reference internal" href="#FDB::Transaction.reset" title="FDB::Transaction.reset"><code class="xref rb rb-meth docutils literal"><span class="pre">reset</span></code></a>.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">Be careful if you are using <a class="reference internal" href="#FDB::Transaction.reset" title="FDB::Transaction.reset"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.reset</span></code></a> and <a class="reference internal" href="#FDB::Transaction.cancel" title="FDB::Transaction.cancel"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.cancel</span></code></a> concurrently with the same transaction. Since they negate each other&#8217;s effects, a race condition between these calls will leave the transaction in an unknown state.</p>
</div>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">If your program attempts to cancel a transaction after <a class="reference internal" href="#FDB::Transaction.commit" title="FDB::Transaction.commit"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.commit</span></code></a> has been called but before it returns, unpredictable behavior will result. While it is guaranteed that the transaction will eventually end up in a cancelled state, the commit may or may not occur. Moreover, even if the call to <a class="reference internal" href="#FDB::Transaction.commit" title="FDB::Transaction.commit"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.commit</span></code></a> appears to raise a <a class="reference internal" href="api-error-codes.html#developer-guide-error-codes"><span class="std std-ref">transaction_cancelled</span></a> exception, the commit may have occurred or may occur in the future. This can make it more difficult to reason about the order in which transactions occur.</p>
</div>
</dd></dl>
</div>
<div class="section" id="watches">
<h3>Watches</h3>
<dl class="method">
<dt id="FDB::Transaction.watch">
<code class="descclassname">Transaction.</code><code class="descname">watch</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; FutureNil</dt>
<dd><p>Creates a watch and returns a <a class="reference internal" href="#FDB::FutureNil" title="FDB::FutureNil"><code class="xref rb rb-class docutils literal"><span class="pre">FutureNil</span></code></a> that will become ready when the watch reports a change to the value of the specified key.</p>
<p>A watch&#8217;s behavior is relative to the transaction that created it. A watch will report a change in relation to the key&#8217;s value as readable by that transaction. The initial value used for comparison is either that of the transaction&#8217;s read version or the value as modified by the transaction itself prior to the creation of the watch. If the value changes and then changes back to its initial value, the watch might not report the change.</p>
<p>Until the transaction that created it has been committed, a watch will not report changes made by <em>other</em> transactions. In contrast, a watch will immediately report changes made by the transaction itself. Watches cannot be created if the transaction has set <a class="reference internal" href="#FDB::Transaction.options.set_read_your_writes_disable" title="FDB::Transaction.options.set_read_your_writes_disable"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.options.set_read_your_writes_disable</span></code></a>, and an attempt to do so will raise an <a class="reference internal" href="api-error-codes.html#developer-guide-error-codes"><span class="std std-ref">watches_disabled</span></a> exception.</p>
<p>If the transaction used to create a watch encounters an exception during commit, then the watch will be set with that exception. A transaction whose <a class="reference internal" href="developer-guide.html#developer-guide-unknown-results"><span class="std std-ref">commit result is unknown</span></a> will set all of its watches with the <a class="reference internal" href="api-error-codes.html#developer-guide-error-codes"><span class="std std-ref">commit_unknown_result</span></a> exception. If an uncommitted transaction is reset or destroyed, then any watches it created will be set with the <a class="reference internal" href="api-error-codes.html#developer-guide-error-codes"><span class="std std-ref">transaction_cancelled</span></a> exception.</p>
<p>By default, each database connection can have no more than 10,000 watches that have not yet reported a change. When this number is exceeded, an attempt to create a watch will raise a <a class="reference internal" href="api-error-codes.html#developer-guide-error-codes"><span class="std std-ref">too_many_watches</span></a> exception. This limit can be changed using <a class="reference internal" href="#FDB::Database.options.set_max_watches" title="FDB::Database.options.set_max_watches"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.options.set_max_watches</span></code></a>. Because a watch outlives the transaction that creates it, any watch that is no longer needed should be cancelled by calling <a class="reference internal" href="#FDB::Future.cancel" title="FDB::Future.cancel"><code class="xref rb rb-meth docutils literal"><span class="pre">Future.cancel</span></code></a> on its returned future.</p>
</dd></dl>
</div>
<div class="section" id="conflict-ranges">
<h3>Conflict ranges</h3>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Most applications will use the strictly serializable isolation that transactions provide by default and will not need to manipulate conflict ranges.</p>
</div>
<p>The following make it possible to add <a class="reference internal" href="developer-guide.html#conflict-ranges"><span class="std std-ref">conflict ranges</span></a> to a transaction.</p>
<dl class="method">
<dt id="FDB::Transaction.add_read_conflict_range">
<code class="descclassname">Transaction.</code><code class="descname">add_read_conflict_range</code><span class="sig-paren">(</span><em>begin</em>, <em>end</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Adds a range of keys to the transaction&#8217;s read conflict ranges as if you had read the range. As a result, other transactions that write a key in this range could cause the transaction to fail with a conflict.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.add_read_conflict_key">
<code class="descclassname">Transaction.</code><code class="descname">add_read_conflict_key</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Adds a key to the transaction&#8217;s read conflict ranges as if you had read the key. As a result, other transactions that concurrently write this key could cause the transaction to fail with a conflict.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.add_write_conflict_range">
<code class="descclassname">Transaction.</code><code class="descname">add_write_conflict_range</code><span class="sig-paren">(</span><em>begin</em>, <em>end</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Adds a range of keys to the transaction&#8217;s write conflict ranges as if you had cleared the range. As a result, other transactions that concurrently read a key in this range could fail with a conflict.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.add_write_conflict_key">
<code class="descclassname">Transaction.</code><code class="descname">add_write_conflict_key</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Adds a key to the transaction&#8217;s write conflict ranges as if you had written the key. As a result, other transactions that concurrently read this key could fail with a conflict.</p>
</dd></dl>
</div>
<div class="section" id="versions">
<h3>Versions</h3>
<p>Most applications should use the read version that FoundationDB determines automatically during the transaction&#8217;s first read, and ignore all of these methods.</p>
<dl class="method">
<dt id="FDB::Transaction.set_read_version">
<code class="descclassname">Transaction.</code><code class="descname">set_read_version</code><span class="sig-paren">(</span><em>version</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p><em>Infrequently used</em>. Sets the database version that the transaction will read from the database. The database cannot guarantee causal consistency if this method is used (the transaction&#8217;s reads will be causally consistent only if the provided read version has that property).</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.get_read_version">
<code class="descclassname">Transaction.</code><code class="descname">get_read_version</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; Int64Future</dt>
<dd><p><em>Infrequently used</em>. Returns the transaction&#8217;s read version.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.get_committed_version">
<code class="descclassname">Transaction.</code><code class="descname">get_committed_version</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; Integer</dt>
<dd><p><em>Infrequently used</em>. Gets the version number at which a successful commit modified the database. This must be called only after the successful (non-error) completion of a call to <a class="reference internal" href="#FDB::Transaction.commit" title="FDB::Transaction.commit"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.commit</span></code></a> on this Transaction, or the behavior is undefined. Read-only transactions do not modify the database when committed and will have a committed version of -1. Keep in mind that a transaction which reads keys and then sets them to their current values may be optimized to a read-only transaction.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.get_versionstamp">
<code class="descclassname">Transaction.</code><code class="descname">get_versionstamp</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; String</dt>
<dd><p><em>Infrequently used</em>. Returns a future which will contain the versionstamp which was used by any versionstamp operations in this transaction. This function must be called before a call to <a class="reference internal" href="#FDB::Transaction.commit" title="FDB::Transaction.commit"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.commit</span></code></a> on this Transaction. The future will be ready only after the successful completion of a call to <a class="reference internal" href="#FDB::Transaction.commit" title="FDB::Transaction.commit"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.commit</span></code></a> on this Transaction. Read-only transactions do not modify the database when committed and will result in the future completing with an error. Keep in mind that a transaction which reads keys and then sets them to their current values may be optimized to a read-only transaction.</p>
</dd></dl>
</div>
<div class="section" id="transaction-misc-functions">
<h3>Transaction misc functions</h3>
<dl class="method">
<dt id="FDB::Transaction.get_estimated_range_size_bytes">
<code class="descclassname">Transaction.</code><code class="descname">get_estimated_range_size_bytes</code><span class="sig-paren">(</span><em>begin_key</em>, <em>end_key</em><span class="sig-paren">)</span> &#x2192; Int64Future</dt>
<dd><p>Gets the estimated byte size of the given key range. Returns a <a class="reference internal" href="#FDB::Int64Future" title="FDB::Int64Future"><code class="xref rb rb-class docutils literal"><span class="pre">Int64Future</span></code></a>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The estimated size is calculated based on the sampling done by FDB server. The sampling algorithm works roughly in this way: the larger the key-value pair is, the more likely it would be sampled and the more accurate its sampled size would be. And due to that reason it is recommended to use this API to query against large ranges for accuracy considerations. For a rough reference, if the returned size is larger than 3MB, one can consider the size to be accurate.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.get_range_split_points">
<code class="descclassname">Transaction.</code><code class="descname">get_range_split_points</code><span class="sig-paren">(</span><em>begin_key</em>, <em>end_key</em>, <em>chunk_size</em><span class="sig-paren">)</span> &#x2192; FutureKeyArray</dt>
<dd><p>Gets a list of keys that can split the given range into (roughly) equally sized chunks based on <code class="docutils literal"><span class="pre">chunk_size</span></code>. Returns a <code class="xref rb rb-class docutils literal"><span class="pre">FutureKeyArray</span></code>.
.. note:: The returned split points contain the start key and end key of the given range</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.get_approximate_size">
<code class="descclassname">Transaction.</code><code class="descname">get_approximate_size</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; Int64Future</dt>
<dd><p>Gets the the approximate transaction size so far, which is the summation of the estimated size of mutations, read conflict ranges, and write conflict ranges. Returns a <a class="reference internal" href="#FDB::Int64Future" title="FDB::Int64Future"><code class="xref rb rb-class docutils literal"><span class="pre">Int64Future</span></code></a>.</p>
</dd></dl>
</div>
<div class="section" id="transaction-options">
<h3>Transaction options</h3>
<p>Transaction options alter the behavior of FoundationDB transactions. FoundationDB defaults to extremely safe transaction behavior, and we have worked hard to make the performance excellent with the default setting, so you should not often need to use transaction options.</p>
<span class="target" id="api-ruby-snapshot-ryw"></span><dl class="method">
<dt id="FDB::Transaction.options.set_snapshot_ryw_disable">
<code class="descclassname">Transaction.options.</code><code class="descname">set_snapshot_ryw_disable</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>If this option is set more times in this transaction than the enable option, snapshot reads will <em>not</em> see the effects of prior writes in the same transaction. Note that prior to API version 300, this was the default behavior. This option can be disabled one or more times at the database level by calling <a class="reference internal" href="#FDB::Database.options.set_snapshot_ryw_disable" title="FDB::Database.options.set_snapshot_ryw_disable"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.options.set_snapshot_ryw_disable</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_snapshot_ryw_enable">
<code class="descclassname">Transaction.options.</code><code class="descname">set_snapshot_ryw_enable</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>If this option is set an equal or more times in this transaction than the disable option, snapshot reads <em>will</em> see the effects of prior writes in the same transaction. This option can be enabled one or more times at the database-level by calling <a class="reference internal" href="#FDB::Database.options.set_snapshot_ryw_enable" title="FDB::Database.options.set_snapshot_ryw_enable"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.options.set_snapshot_ryw_enable</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_priority_batch">
<code class="descclassname">Transaction.options.</code><code class="descname">set_priority_batch</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>This transaction should be treated as low priority (other transactions will be processed first). Batch priority transactions will also be throttled at load levels smaller than for other types of transactions and may be fully cut off in the event of machine failures. Useful for doing potentially saturating batch work without interfering with the latency of other operations.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_priority_system_immediate">
<code class="descclassname">Transaction.options.</code><code class="descname">set_priority_system_immediate</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>This transaction should be treated as extremely high priority, taking priority over other transactions and bypassing controls on transaction queuing.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">This is intended for the use of internal database functions and low-level tools; use by applications may result in severe database performance or availability problems.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_causal_read_risky">
<code class="descclassname">Transaction.options.</code><code class="descname">set_causal_read_risky</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>This transaction does not require the strict causal consistency guarantee that FoundationDB provides by default. The read version will be committed, and usually will be the latest committed, but might not be the latest committed in the event of a simultaneous fault and misbehaving clock. One can set this for all transactions by calling <a class="reference internal" href="#FDB::Database.options.set_transaction_causal_read_risky" title="FDB::Database.options.set_transaction_causal_read_risky"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.options.set_transaction_causal_read_risky</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_causal_write_risky">
<code class="descclassname">Transaction.options.</code><code class="descname">set_causal_write_risky</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>The application either knows that this transaction will be self-conflicting (at least one read overlaps at least one set or clear), or is willing to accept a small risk that the transaction could be committed a second time after its commit apparently succeeds. This option provides a small performance benefit.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_next_write_no_write_conflict_range">
<code class="descclassname">Transaction.options.</code><code class="descname">set_next_write_no_write_conflict_range</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>The next write performed on this transaction will not generate a write conflict range. As a result, other transactions which read the key(s) being modified by the next write will not necessarily conflict with this transaction.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Care needs to be taken when using this option on a transaction that is shared between multiple threads. When setting this option, write conflict ranges will be disabled on the next write operation, regardless of what thread it is on.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_read_your_writes_disable">
<code class="descclassname">Transaction.options.</code><code class="descname">set_read_your_writes_disable</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>When this option is invoked, a read performed by a transaction will not see any prior mutations that occured in that transaction, instead seeing the value which was in the database at the transaction&#8217;s read version. This option may provide a small performance benefit for the client, but also disables a number of client-side optimizations which are beneficial for transactions which tend to read and write the same keys within a single transaction.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">It is an error to set this option after performing any reads or writes on the transaction.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_read_ahead_disable">
<code class="descclassname">Transaction.options.</code><code class="descname">set_read_ahead_disable</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Disables read-ahead caching for range reads. Under normal operation, a transaction will read extra rows from the database into cache if range reads are used to page through a series of data one row at a time (i.e. if a range read with a one row limit is followed by another one row range read starting immediately after the result of the first).</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_access_system_keys">
<code class="descclassname">Transaction.options.</code><code class="descname">set_access_system_keys</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Allows this transaction to read and modify system keys (those that start with the byte <code class="docutils literal"><span class="pre">0xFF</span></code>).</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">Writing into system keys will likely break your database. Further, even for readers, the format of data in the system keys may change from version to version in FoundationDB.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_read_system_keys">
<code class="descclassname">Transaction.options.</code><code class="descname">set_read_system_keys</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Allows this transaction to read system keys (those that start with the byte <code class="docutils literal"><span class="pre">0xFF</span></code>).</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">The format of data in the system keys may change from version to version in FoundationDB.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_retry_limit">
<code class="descclassname">Transaction.options.</code><code class="descname">set_retry_limit</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Set a maximum number of retries after which additional calls to <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a> will throw the most recently seen error code. (By default, a transaction permits an unlimited number of retries.) Valid parameter values are [-1, INT_MAX]. If set to -1, the transaction returns to the default of unlimited retries.</p>
<p>Prior to API version 610, Like all other transaction options, the retry limit must be reset after a call to <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a>. If the API version is 610 or newer, then the retry limit is not reset. Note that at all API versions, it is safe and legal to call this option after each call to <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a>, so most code written assuming the older behavior can be upgraded without requiring any modification. This also means there is no need to introduce logic to conditionally set this option within retry loops. One can also set the default retry limit for all transactions by calling <a class="reference internal" href="#FDB::Database.options.set_transaction_retry_limit" title="FDB::Database.options.set_transaction_retry_limit"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.options.set_transaction_retry_limit</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_max_retry_delay">
<code class="descclassname">Transaction.options.</code><code class="descname">set_max_retry_delay</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Set the maximum backoff delay incurred in the call to <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a> if the error is retryable. Prior to API version 610, like all other transaction options, the maximum retry delay must be reset after a call to <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a>. If the API version is 610 or newer, then the maximum retry delay is not reset. Note that at all API versions, it is safe and legal to call this option after each call to <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a>, so most cade written assuming the older behavior can be upgraded without requiring any modification. This also means there is no need to introduce logic to conditionally set this option within retry loops. One can set the default retry limit for all transactions by calling <a class="reference internal" href="#FDB::Database.options.set_transaction_max_retry_delay" title="FDB::Database.options.set_transaction_max_retry_delay"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.options.set_transaction_max_retry_delay</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_size_limit">
<code class="descclassname">Transaction.options.</code><code class="descname">set_size_limit</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Set the transaction size limit in bytes. The size is calculated by combining the sizes of all keys and values written or mutated, all key ranges cleared, and all read and write conflict ranges. (In other words, it includes the total size of all data included in the request to the cluster to commit the transaction.) Large transactions can cause performance problems on FoundationDB clusters, so setting this limit to a smaller value than the default can help prevent the client from accidentally degrading the cluster&#8217;s performance. This value must be at least 32 and cannot be set to higher than 10,000,000, the default transaction size limit.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_timeout">
<code class="descclassname">Transaction.options.</code><code class="descname">set_timeout</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Set a timeout duration in milliseconds after which the transaction automatically to be cancelled. The time is measured from transaction creation (or the most call to <a class="reference internal" href="#FDB::Transaction.reset" title="FDB::Transaction.reset"><code class="xref rb rb-meth docutils literal"><span class="pre">reset</span></code></a>, if any). Valid parameter values are [0, INT_MAX]. If set to 0, all timeouts will be disabled. Once a transaction has timed out, all pending or future uses of the transaction will raise a <a class="reference internal" href="api-error-codes.html#developer-guide-error-codes"><span class="std std-ref">transaction_timed_out</span></a> exception. The transaction can be used again after it is <a class="reference internal" href="#FDB::Transaction.reset" title="FDB::Transaction.reset"><code class="xref rb rb-meth docutils literal"><span class="pre">reset</span></code></a>.</p>
<p>Timeouts employ transaction cancellation, so you should note the issues raised by <a class="reference internal" href="#FDB::Transaction.cancel" title="FDB::Transaction.cancel"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.cancel</span></code></a> when using timeouts.</p>
<p>Prior to API version 610, like all other transaction options, a timeout must be reset after a call to <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a>. Note that resetting this option resets only the timeout <em>duration</em>, not the starting point from which the time is measured. If the API version is 610 or newer, then the timeout is not reset. This allows the user to specify a timeout for specific transactions that is longer than the timeout specified by <a class="reference internal" href="#FDB::Database.options.set_transaction_timeout" title="FDB::Database.options.set_transaction_timeout"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.options.set_transaction_timeout</span></code></a>. Note that at all API versions, it is safe and legal to call this option after each call to <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a>, so most code written assuming the older behavior can be upgraded without requiring any modification. This also means that there is no need to introduce logic to conditionally set this option within retry loops. One can set the default timeout for all transactions by calling <a class="reference internal" href="#FDB::Database.options.set_transaction_timeout" title="FDB::Database.options.set_transaction_timeout"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.options.set_transaction_timeout</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_transaction_logging_max_field_length">
<code class="descclassname">Transaction.options.</code><code class="descname">set_transaction_logging_max_field_length</code><span class="sig-paren">(</span><em>size_limit</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Sets the maximum escaped length of key and value fields to be logged to the trace file via the LOG_TRANSACTION option, after which the field will be truncated. A negative value disables truncation. One can set the default max field length for all transactions by calling <a class="reference internal" href="#FDB::Database.options.set_transaction_logging_max_field_length" title="FDB::Database.options.set_transaction_logging_max_field_length"><code class="xref rb rb-meth docutils literal"><span class="pre">Database.options.set_transaction_logging_max_field_length</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_debug_transaction_identifier">
<code class="descclassname">Transaction.options.</code><code class="descname">set_debug_transaction_identifier</code><span class="sig-paren">(</span><em>id_string</em><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Sets a client provided string identifier for the transaction that will be used in scenarios like tracing or profiling. Client trace logging or transaction profiling must be separately enabled.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Transaction.options.set_log_transaction">
<code class="descclassname">Transaction.options.</code><code class="descname">set_log_transaction</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Enables tracing for this transaction and logs results to the client trace logs. The DEBUG_TRANSACTION_IDENTIFIER option must be set before using this option, and client trace logging must be enabled to get log output.</p>
</dd></dl>
</div>
</div>
<div class="section" id="the-transact-method">
<span id="transact"></span><h2>The transact method</h2>
<p>When performing a database transaction, any read operation, as well as the commit itself, may fail with one of a number of errors. If the error is a retryable error, the transaction needs to be restarted from the beginning. Committing a transaction is also an asynchronous operation, and the returned <a class="reference internal" href="#FDB::FutureNil" title="FDB::FutureNil"><code class="xref rb rb-class docutils literal"><span class="pre">FutureNil</span></code></a> object needs to be waited on to ensure that no errors occurred.</p>
<p>The methods <code class="xref rb rb-meth docutils literal"><span class="pre">Database.transact</span></code> and <code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.transact</span></code> are convenient wrappers that allow much of this complexity to be handled automatically. A call like</p>
<div class="highlight-ruby"><div class="highlight"><pre><span></span><span class="n">db</span><span class="o">.</span><span class="n">transact</span> <span class="k">do</span> <span class="o">|</span><span class="n">tr</span><span class="o">|</span>
<span class="n">tr</span><span class="o">[</span><span class="s1">&#39;a&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;A&#39;</span>
<span class="n">tr</span><span class="o">[</span><span class="s1">&#39;b&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;B&#39;</span>
<span class="k">end</span>
</pre></div>
</div>
<p>is equivalent to</p>
<div class="highlight-ruby"><div class="highlight"><pre><span></span><span class="n">tr</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">create_transaction</span>
<span class="n">committed</span> <span class="o">=</span> <span class="kp">false</span>
<span class="k">while</span> <span class="o">!</span><span class="n">committed</span>
<span class="k">begin</span>
<span class="n">tr</span><span class="o">[</span><span class="s1">&#39;a&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;A&#39;</span>
<span class="n">tr</span><span class="o">[</span><span class="s1">&#39;b&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;B&#39;</span>
<span class="n">tr</span><span class="o">.</span><span class="n">commit</span><span class="o">.</span><span class="n">wait</span>
<span class="n">committed</span> <span class="o">=</span> <span class="kp">true</span>
<span class="k">rescue</span> <span class="no">FDB</span><span class="o">::</span><span class="no">Error</span> <span class="o">=&gt;</span> <span class="n">e</span>
<span class="n">tr</span><span class="o">.</span><span class="n">on_error</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="o">.</span><span class="n">wait</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
</div>
<p>The first form is considerably easier to read, and ensures that the transaction is correctly committed (and retried, when necessary).</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Be careful when using control flow constructs within the block passed to <code class="xref rb rb-meth docutils literal"><span class="pre">transact</span></code>. <code class="docutils literal"><span class="pre">return</span></code> or <code class="docutils literal"><span class="pre">break</span></code> will exit the retry loop <em>without committing</em> the transaction. Use <code class="docutils literal"><span class="pre">next</span></code> to exit the block and commit the transaction.</p>
</div>
<p>The <code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.transact</span></code> method, which logically does nothing, makes it easy to write functions that operate on either a <a class="reference internal" href="#FDB::Database" title="FDB::Database"><code class="xref rb rb-class docutils literal"><span class="pre">Database</span></code></a> or <a class="reference internal" href="#FDB::Transaction" title="FDB::Transaction"><code class="xref rb rb-class docutils literal"><span class="pre">Transaction</span></code></a>. Consider the following method:</p>
<div class="highlight-ruby"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">increment</span><span class="p">(</span><span class="n">db_or_tr</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
<span class="n">db_or_tr</span><span class="o">.</span><span class="n">transact</span> <span class="k">do</span> <span class="o">|</span><span class="n">tr</span><span class="o">|</span>
<span class="n">tr</span><span class="o">[</span><span class="n">key</span><span class="o">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">tr</span><span class="o">[</span><span class="n">key</span><span class="o">].</span><span class="n">to_i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">to_s</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
</div>
<p>This method can be called with a <a class="reference internal" href="#FDB::Database" title="FDB::Database"><code class="xref rb rb-class docutils literal"><span class="pre">Database</span></code></a>, and it will do its job atomically:</p>
<div class="highlight-ruby"><div class="highlight"><pre><span></span><span class="n">increment</span><span class="p">(</span><span class="n">db</span><span class="p">,</span> <span class="s1">&#39;number&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>It can also be called by another transactional method with a transaction:</p>
<div class="highlight-ruby"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">increment_both</span><span class="p">(</span><span class="n">db_or_tr</span><span class="p">,</span> <span class="n">key1</span><span class="p">,</span> <span class="n">key2</span><span class="p">)</span>
<span class="n">db_or_tr</span><span class="o">.</span><span class="n">transact</span> <span class="k">do</span> <span class="o">|</span><span class="n">tr</span><span class="o">|</span>
<span class="n">increment</span><span class="p">(</span><span class="n">tr</span><span class="p">,</span> <span class="n">key1</span><span class="p">)</span>
<span class="n">increment</span><span class="p">(</span><span class="n">tr</span><span class="p">,</span> <span class="n">key2</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
</div>
<p>In the second case, <code class="docutils literal"><span class="pre">increment</span></code> will use provided transaction and will not commit it or retry errors, since that is the responsibility of its caller, <code class="docutils literal"><span class="pre">increment_both</span></code>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">In some failure scenarios, it is possible that your transaction will be executed twice. See <a class="reference internal" href="developer-guide.html#developer-guide-unknown-results"><span class="std std-ref">Transactions with unknown results</span></a> for more information.</p>
</div>
</div>
<div class="section" id="future-objects">
<span id="api-ruby-future"></span><h2>Future objects</h2>
<p>Many FoundationDB API functions return &#8220;future&#8221; objects. A brief overview of futures is included in the <a class="reference internal" href="class-scheduling.html"><span class="doc">class scheduling tutorial</span></a>. Most future objects behave just like a normal object, but block when you use them for the first time if the asynchronous function which returned the future has not yet completed its action. A future object is considered ready when either a value is available, or when an error has occurred.</p>
<p id="api-ruby-block">When a future object &#8220;blocks&#8221;, the ruby thread is blocked, but the global interpreter lock is released.</p>
<p>When used in a conditional expression, a future object will evaluate to true, even if its value is nil. To test for nil, you must explicitly use the nil?() method:</p>
<div class="highlight-ruby"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">tr</span><span class="o">[</span><span class="s1">&#39;a&#39;</span><span class="o">].</span><span class="n">nil?</span>
</pre></div>
</div>
<p>All future objects are a subclass of the <a class="reference internal" href="#FDB::Future" title="FDB::Future"><code class="xref rb rb-class docutils literal"><span class="pre">Future</span></code></a> type.</p>
<dl class="class">
<dt id="FDB::Future">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">Future</code></dt>
<dd><dl class="method">
<dt id="FDB::Future.ready?">
<code class="descname">ready?</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; bool</dt>
<dd><p>Immediately returns true if the future object is ready, false otherwise.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Future.block_until_ready">
<code class="descname">block_until_ready</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Blocks until the future object is ready.</p>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">Future.on_ready() {|future| block } -&gt; nil</code></dt>
<dd><p>Yields <code class="docutils literal"><span class="pre">self</span></code> to the given block when the future object is ready. If the future object is ready at the time <code class="xref rb rb-meth docutils literal"><span class="pre">on_ready</span></code> is called, the block may be called immediately in the current thread (although this behavior is not guaranteed). Otherwise, the call may be delayed and take place on the thread with which the client was initialized. Therefore, the block is responsible for any needed thread synchronization (and/or for posting work to your application&#8217;s event loop, thread pool, etc., as may be required by your application&#8217;s architecture).</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">This function guarantees the callback will be executed <strong>at most once</strong>.</p>
</div>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">There are a number of requirements and constraints to be aware of when using callbacks with FoundationDB. Please read <a class="reference internal" href="developer-guide.html#developer-guide-programming-with-futures"><span class="std std-ref">Programming with futures</span></a>.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Future.cancel">
<code class="descname">cancel</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>Cancels a <a class="reference internal" href="#FDB::Future" title="FDB::Future"><code class="xref rb rb-class docutils literal"><span class="pre">Future</span></code></a> and its associated asynchronous operation. If called before the future is ready, attempts to access its value will raise an <a class="reference internal" href="api-error-codes.html#developer-guide-error-codes"><span class="std std-ref">operation_cancelled</span></a> exception. Cancelling a future which is already ready has no effect. Note that even if a future is not ready, its associated asynchronous operation may have succesfully completed and be unable to be cancelled.</p>
</dd></dl>
<dl class="classmethod">
<dt id="FDB::Future.wait_for_any">
<em class="property">classmethod Future.</em><code class="descname">wait_for_any</code><span class="sig-paren">(</span><em>*futures</em><span class="sig-paren">)</span> &#x2192; Fixnum</dt>
<dd><p>Does not return until at least one of the given future objects is ready. Returns the index in the parameter list of a ready future object.</p>
</dd></dl>
</dd></dl>
<p>Asynchronous methods return one of the following subclasses of <a class="reference internal" href="#FDB::Future" title="FDB::Future"><code class="xref rb rb-class docutils literal"><span class="pre">Future</span></code></a>:</p>
<dl class="class">
<dt id="FDB::Value">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">Value</code></dt>
<dd></dd></dl>
<dl class="class">
<dt id="FDB::Key">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">Key</code></dt>
<dd><p>Both types are future <code class="xref rb rb-class docutils literal"><span class="pre">String</span></code> objects. Objects of these types respond to the same methods as objects of type <code class="xref rb rb-class docutils literal"><span class="pre">String</span></code>, and may be passed to any method that expects a <code class="xref rb rb-class docutils literal"><span class="pre">String</span></code>.</p>
<p>An implementation quirk of <a class="reference internal" href="#FDB::Value" title="FDB::Value"><code class="xref rb rb-class docutils literal"><span class="pre">Value</span></code></a> is that it will never evaluate to <code class="docutils literal"><span class="pre">false</span></code>, even if its value is <code class="docutils literal"><span class="pre">nil</span></code>. It is important to use <code class="docutils literal"><span class="pre">if</span> <span class="pre">value.nil?</span></code> rather than <code class="docutils literal"><span class="pre">if</span> <span class="pre">~value</span></code> when checking to see if a key was not present in the database.</p>
</dd></dl>
<dl class="class">
<dt id="FDB::Int64Future">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">Int64Future</code></dt>
<dd><p>This type is a future <code class="xref rb rb-class docutils literal"><span class="pre">Integer</span></code> object. Objects of this type respond to the same methods as objects of type <code class="xref rb rb-class docutils literal"><span class="pre">Integer</span></code>, and may be passed to any method that expects a <code class="xref rb rb-class docutils literal"><span class="pre">Integer</span></code>.</p>
</dd></dl>
<dl class="class">
<dt id="FDB::FutureArray">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">FutureArray</code></dt>
<dd><p>This type is a future <code class="xref rb rb-class docutils literal"><span class="pre">Array</span></code> object. Objects of this type respond to the same methods as objects of type <code class="xref rb rb-class docutils literal"><span class="pre">Array</span></code>, and may be passed to any method that expects a <code class="xref rb rb-class docutils literal"><span class="pre">Array</span></code>.</p>
</dd></dl>
<dl class="class">
<dt id="FDB::FutureNil">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">FutureNil</code></dt>
<dd><p>This type is a future returned from asynchronous methods that logically have no return value.</p>
<dl class="method">
<dt id="FDB::FutureNil.wait">
<code class="descname">wait</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; nil</dt>
<dd><p>For a <a class="reference internal" href="#FDB::FutureNil" title="FDB::FutureNil"><code class="xref rb rb-class docutils literal"><span class="pre">FutureNil</span></code></a> object returned by <a class="reference internal" href="#FDB::Transaction.commit" title="FDB::Transaction.commit"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.commit</span></code></a> or <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a>, you must call <a class="reference internal" href="#FDB::FutureNil.wait" title="FDB::FutureNil.wait"><code class="xref rb rb-meth docutils literal"><span class="pre">FutureNil.wait</span></code></a>, which will return <code class="docutils literal"><span class="pre">nil</span></code> if the operation succeeds or raise an <a class="reference internal" href="#FDB::Error" title="FDB::Error"><code class="xref rb rb-exc docutils literal"><span class="pre">FDB::Error</span></code></a> if an error occurred. Failure to call <a class="reference internal" href="#FDB::FutureNil.wait" title="FDB::FutureNil.wait"><code class="xref rb rb-meth docutils literal"><span class="pre">FutureNil.wait</span></code></a> on a returned <a class="reference internal" href="#FDB::FutureNil" title="FDB::FutureNil"><code class="xref rb rb-class docutils literal"><span class="pre">FutureNil</span></code></a> object means that any potential errors raised by the asynchronous operation that returned the object <em>will not be seen</em>, and represents a significant error in your code.</p>
</dd></dl>
</dd></dl>
</div>
<div class="section" id="streaming-modes">
<span id="ruby-streaming-mode"></span><h2>Streaming modes</h2>
<p>When using <a class="reference internal" href="#FDB::Transaction.get_range" title="FDB::Transaction.get_range"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.get_range</span></code></a> and similar interfaces, API clients can request large ranges of the database to iterate over. Making such a request doesn&#8217;t necessarily mean that the client will consume all of the data in the range - sometimes the client doesn&#8217;t know how far it intends to iterate in advance. FoundationDB tries to balance latency and bandwidth by requesting data for iteration in batches.</p>
<p>Streaming modes permit the API client to customize this performance tradeoff by providing extra information about how the iterator will be used.</p>
<p>The following streaming modes are available:</p>
<dl class="const">
<dt>
<code class="descname">:iterator</code></dt>
<dd><p><em>The default.</em> The client doesn&#8217;t know how much of the range it is likely to used and wants different performance concerns to be balanced.</p>
<p>Only a small portion of data is transferred to the client initially (in order to minimize costs if the client doesn&#8217;t read the entire range), and as the caller iterates over more items in the range larger batches will be transferred in order to maximize throughput.</p>
</dd></dl>
<dl class="const">
<dt>
<code class="descname">:want_all</code></dt>
<dd><p>The client intends to consume the entire range and would like it all transferred as early as possible.</p>
</dd></dl>
<dl class="const">
<dt>
<code class="descname">:small</code></dt>
<dd><p><em>Infrequently used</em>. Transfer data in batches small enough to not be much more expensive than reading individual rows, to minimize cost if iteration stops early.</p>
</dd></dl>
<dl class="const">
<dt>
<code class="descname">:medium</code></dt>
<dd><p><em>Infrequently used</em>. Transfer data in batches sized in between <code class="docutils literal"><span class="pre">:small</span></code> and <code class="docutils literal"><span class="pre">:large</span></code>.</p>
</dd></dl>
<dl class="const">
<dt>
<code class="descname">:large</code></dt>
<dd><p><em>Infrequently used</em>. Transfer data in batches large enough to be, in a high-concurrency environment, nearly as efficient as possible. If the client stops iteration early, some disk and network bandwidth may be wasted. The batch size may still be too small to allow a single client to get high throughput from the database, so if that is what you need consider <code class="docutils literal"><span class="pre">:serial</span></code>.</p>
</dd></dl>
<dl class="const">
<dt>
<code class="descname">:serial</code></dt>
<dd><p>Transfer data in batches large enough that an individual client can get reasonable read bandwidth from the database. If the client stops iteration early, considerable disk and network bandwidth may be wasted.</p>
</dd></dl>
<dl class="const">
<dt>
<code class="descname">:exact</code></dt>
<dd><p><em>Infrequently used</em>. The client has passed a specific row limit and wants that many rows delivered in a single batch. This is not particularly useful in Ruby because enumerable functionality makes batches of data transparent, so use <code class="docutils literal"><span class="pre">:want_all</span></code> instead.</p>
</dd></dl>
</div>
<div class="section" id="errors">
<h2>Errors</h2>
<p>Errors in the FoundationDB API are raised as exceptions of type <a class="reference internal" href="#FDB::Error" title="FDB::Error"><code class="xref rb rb-class docutils literal"><span class="pre">FDB::Error</span></code></a>. These errors may be displayed for diagnostic purposes, but generally should be passed to <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a>. When using <code class="xref rb rb-meth docutils literal"><span class="pre">Database.transact</span></code>, appropriate errors will be retried automatically.</p>
<dl class="class">
<dt id="FDB::Error">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">Error</code></dt>
<dd><dl class="attr_reader">
<dt id="FDB::Error#code">
<em class="property">attribute [R] </em><code class="descname">code</code></dt>
<dd><p>A <code class="xref rb rb-class docutils literal"><span class="pre">Fixnum</span></code> associated with the error type.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Error#description">
<code class="descname">description</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; String</dt>
<dd><p>Returns a somewhat human-readable description of the error.</p>
</dd></dl>
</dd></dl>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">You should only use the <code class="xref rb rb-attr docutils literal"><span class="pre">code</span></code> attribute for programmatic comparisons, as the description of the error may change at any time. Whenever possible, use the <a class="reference internal" href="#FDB::Transaction.on_error" title="FDB::Transaction.on_error"><code class="xref rb rb-meth docutils literal"><span class="pre">Transaction.on_error</span></code></a> method to handle <a class="reference internal" href="#FDB::Error" title="FDB::Error"><code class="xref rb rb-class docutils literal"><span class="pre">FDB::Error</span></code></a> exceptions.</p>
</div>
</div>
<div class="section" id="module-FDB::Tuple">
<span id="tuple-layer"></span><span id="api-ruby-tuple-layer"></span><h2>Tuple layer</h2>
<p>The FoundationDB API comes with a built-in layer for encoding tuples into keys usable by FoundationDB. The encoded key maintains the same sort order as the original tuple: sorted first by the first element, then by the second element, etc. This makes the tuple layer ideal for building a variety of higher-level data models.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">For general guidance on tuple usage, see the discussion in the document on <a class="reference internal" href="data-modeling.html#data-modeling-tuples"><span class="std std-ref">Data Modeling</span></a>.</p>
</div>
<p>In the FoundationDB Ruby API, a tuple is an <code class="xref rb rb-class docutils literal"><span class="pre">Enumerable</span></code> of elements of the following data types:</p>
<table border="1" class="docutils">
<colgroup>
<col width="12%" />
<col width="44%" />
<col width="44%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Type</th>
<th class="head">Legal Values</th>
<th class="head">Canonical Value</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>Null value</td>
<td><code class="docutils literal"><span class="pre">nil</span></code></td>
<td><code class="docutils literal"><span class="pre">nil</span></code></td>
</tr>
<tr class="row-odd"><td>Byte string</td>
<td>Any value <code class="docutils literal"><span class="pre">v</span></code> where <code class="docutils literal"><span class="pre">v.kind_of?</span> <span class="pre">String</span> <span class="pre">==</span> <span class="pre">true</span></code> and <code class="docutils literal"><span class="pre">v.encoding</span></code> is
either <code class="docutils literal"><span class="pre">Encoding::ASCII_8BIT</span></code> (aka <code class="docutils literal"><span class="pre">Encoding::BINARY</span></code>) or
<code class="docutils literal"><span class="pre">Encoding::US_ASCII</span></code> (aka <code class="docutils literal"><span class="pre">Encoding::ASCII</span></code>)</td>
<td><code class="docutils literal"><span class="pre">String</span></code> with encoding <code class="docutils literal"><span class="pre">Encoding::ASCII_8BIT</span></code></td>
</tr>
<tr class="row-even"><td>Unicode string</td>
<td>Any value <code class="docutils literal"><span class="pre">v</span></code> where <code class="docutils literal"><span class="pre">v.kind_of?</span> <span class="pre">String</span> <span class="pre">==</span> <span class="pre">true</span></code> and <code class="docutils literal"><span class="pre">v.encoding</span></code> is
<code class="docutils literal"><span class="pre">Encoding::UTF_8</span></code></td>
<td><code class="docutils literal"><span class="pre">String</span></code> with encoding <code class="docutils literal"><span class="pre">Encoding::UTF_8</span></code></td>
</tr>
<tr class="row-odd"><td>Integer</td>
<td>Any value <code class="docutils literal"><span class="pre">v</span></code> where <code class="docutils literal"><span class="pre">v.kind_of?</span> <span class="pre">Integer</span> <span class="pre">==</span> <span class="pre">true</span></code> and
<code class="docutils literal"><span class="pre">-2**2040+1</span> <span class="pre">&lt;=</span> <span class="pre">v</span> <span class="pre">&lt;=</span> <span class="pre">2**2040-1</span></code></td>
<td><code class="docutils literal"><span class="pre">Integer</span></code></td>
</tr>
<tr class="row-even"><td>Floating point number
(single-precision)</td>
<td>Any value <code class="docutils literal"><span class="pre">v</span></code> where <code class="docutils literal"><span class="pre">v.kind_of?</span> <span class="pre">FDB::Tuple::SingleFloat</span></code> where
<code class="docutils literal"><span class="pre">v.value.kind_of?</span> <span class="pre">Float</span></code> and <code class="docutils literal"><span class="pre">v.value</span></code> fits inside an IEEE 754 32-bit
floating-point number.</td>
<td><code class="xref rb rb-class docutils literal"><span class="pre">FDB::Tuple::SingleFloat</span></code></td>
</tr>
<tr class="row-odd"><td>Floating point number
(double-precision)</td>
<td>Any value <code class="docutils literal"><span class="pre">v</span></code> where <code class="docutils literal"><span class="pre">v.kind_of?</span> <span class="pre">Float</span></code></td>
<td><code class="docutils literal"><span class="pre">Float</span></code></td>
</tr>
<tr class="row-even"><td>Boolean</td>
<td>Any value <code class="docutils literal"><span class="pre">v</span></code> where <code class="docutils literal"><span class="pre">v.kind_of?</span> <span class="pre">Boolean</span></code></td>
<td><code class="docutils literal"><span class="pre">Boolean</span></code></td>
</tr>
<tr class="row-odd"><td>UUID</td>
<td>Any value <code class="docutils literal"><span class="pre">v</span></code> where <code class="docutils literal"><span class="pre">v.kind_of?</span> <span class="pre">FDB::Tuple::UUID</span></code> where
<code class="docutils literal"><span class="pre">v.data.kind_of?</span> <span class="pre">String</span></code> and <code class="docutils literal"><span class="pre">v.data.encoding</span></code> is <code class="docutils literal"><span class="pre">Encoding::BINARY</span></code>
and <code class="docutils literal"><span class="pre">v.data.length</span> <span class="pre">==</span> <span class="pre">16</span></code></td>
<td><code class="xref rb rb-class docutils literal"><span class="pre">FDB::Tuple::UUID</span></code></td>
</tr>
<tr class="row-even"><td>Array</td>
<td>Any value <code class="docutils literal"><span class="pre">v</span></code> such that <code class="docutils literal"><span class="pre">v.kind_of?</span> <span class="pre">Array</span></code> and each element within
<code class="docutils literal"><span class="pre">v</span></code> is one of the supported types with a legal value.</td>
<td><code class="docutils literal"><span class="pre">Array</span></code></td>
</tr>
</tbody>
</table>
<p>Note that as Ruby does not have native support for single-precision floating point values and UUIDs, tuple elements
of those types are returned instead as <code class="xref rb rb-class docutils literal"><span class="pre">FDB::Tuple::SingleFloat</span></code> and <code class="xref rb rb-class docutils literal"><span class="pre">FDB::Tuple::UUID</span></code> instances.
These are simple classes that just wrap their underlying values, and they are not intended to offer all of the methods
that a more fully-featured library for handling floating point values or UUIDs might offer. Most applications
should use their library of choice for handling these values and then convert to the appropriate tuple-type
when serializing for storage into the key-value store.</p>
<p>A single tuple element is ordered first by its type, and then by its value.</p>
<p>If <code class="docutils literal"><span class="pre">T</span></code> is an <code class="xref rb rb-class docutils literal"><span class="pre">Enumerable</span></code> meeting these criteria, then conceptually:</p>
<div class="highlight-ruby"><div class="highlight"><pre><span></span><span class="n">T</span> <span class="o">==</span> <span class="no">FDB</span><span class="o">::</span><span class="no">Tuple</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="no">FDB</span><span class="o">::</span><span class="no">Tuple</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="n">T</span><span class="p">))</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Unpacking a tuple always returns an <code class="xref rb rb-class docutils literal"><span class="pre">Array</span></code> of elements in a canonical representation, so packing and then unpacking a tuple may result in an equivalent but not identical representation.</p>
</div>
<dl class="function">
<dt id="FDB::Tuple.pack">
<code class="descclassname">FDB::Tuple.</code><code class="descname">pack</code><span class="sig-paren">(</span><em>tuple</em><span class="sig-paren">)</span> &#x2192; String</dt>
<dd><p>Returns a key encoding the given tuple.</p>
</dd></dl>
<dl class="function">
<dt id="FDB::Tuple.unpack">
<code class="descclassname">FDB::Tuple.</code><code class="descname">unpack</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; Array</dt>
<dd><p>Returns the tuple encoded by the given key. Each element in the <code class="xref rb rb-class docutils literal"><span class="pre">Array</span></code> will either be <code class="docutils literal"><span class="pre">nil</span></code>, a <code class="xref rb rb-class docutils literal"><span class="pre">String</span></code> (with encoding <code class="docutils literal"><span class="pre">Encoding::ASCII_8BIT</span></code> for byte strings or <code class="docutils literal"><span class="pre">Encoding::UTF_8</span></code> for unicode strings), or a <code class="xref rb rb-class docutils literal"><span class="pre">Fixnum</span></code> or <code class="xref rb rb-class docutils literal"><span class="pre">Bignum</span></code> for integers, depending on the magnitude.</p>
</dd></dl>
<dl class="function">
<dt id="FDB::Tuple.range">
<code class="descclassname">FDB::Tuple.</code><code class="descname">range</code><span class="sig-paren">(</span><em>tuple</em><span class="sig-paren">)</span> &#x2192; Array</dt>
<dd><p>Returns the range containing all keys that encode tuples strictly starting with <code class="docutils literal"><span class="pre">tuple</span></code> (that is, all tuples of greater length than tuple of which tuple is a prefix).</p>
<p>The range will be returned as an <code class="xref rb rb-class docutils literal"><span class="pre">Array</span></code> of two elements, and may be used with any FoundationDB methods that require a range:</p>
<div class="highlight-ruby"><div class="highlight"><pre><span></span><span class="n">r</span> <span class="o">=</span> <span class="no">FDB</span><span class="o">::</span><span class="no">Tuple</span><span class="o">.</span><span class="n">range</span><span class="p">(</span><span class="n">T</span><span class="p">)</span>
<span class="n">tr</span><span class="o">.</span><span class="n">get_range</span><span class="p">(</span><span class="n">r</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span> <span class="n">r</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">kv</span><span class="o">|</span> <span class="o">...</span> <span class="p">}</span>
</pre></div>
</div>
</dd></dl>
<dl class="class">
<dt>
<code class="descname">FDB::Tuple::SingleFloat(value)</code></dt>
<dd><p>Wrapper around a single-precision floating point value. The <code class="docutils literal"><span class="pre">value</span></code> parameter should be a <code class="docutils literal"><span class="pre">Float</span></code> that
can be encoded as an IEEE 754 floating point number. If the float does not fit within a IEEE 754 floating point
integer, there may be a loss of precision.</p>
</dd></dl>
<dl class="attr_reader">
<dt>
<code class="descname">FDB::Tuple::SingleFloat.value</code></dt>
<dd><p>The underlying value of the <code class="docutils literal"><span class="pre">SingleFloat</span></code> object. This should have type <code class="docutils literal"><span class="pre">Float</span></code>.</p>
</dd></dl>
<dl class="function">
<dt>
<code class="descname">FDB::Tuple::SingleFloat.&lt;=&gt; -&gt; Fixnum</code></dt>
<dd><p>Comparison method for <code class="docutils literal"><span class="pre">SingleFloat</span></code> objects. This will compare the values based on their float value. This
will sort the values in a manner consistent with the way items are sorted as keys in the database, which can
be different from standard float comparison in that -0.0 is considered to be strictly less than 0.0 and NaN
values are sorted based on their byte representation rather than being considered incomparable.</p>
</dd></dl>
<dl class="function">
<dt>
<code class="descname">FDB::Tuple::SingleFloat.to_s -&gt; String</code></dt>
<dd><p>Creates a string representation of the <code class="docutils literal"><span class="pre">SingleFloat</span></code>. This will just return the string representation of the underlying
value.</p>
</dd></dl>
<dl class="class">
<dt>
<code class="descname">FDB::Tuple::UUID(data)</code></dt>
<dd><p>Wrapper around a 128-bit UUID. The <code class="docutils literal"><span class="pre">data</span></code> parameter should be a byte string of length 16 and is taken to
be the big-endian byte representation of the UUID. If <code class="docutils literal"><span class="pre">data</span></code> is not of length 16, an exception is thrown.</p>
</dd></dl>
<dl class="attr_reader">
<dt>
<code class="descname">FDB::Tuple::UUID.data</code></dt>
<dd><p>The UUID data as a byte array of length 16. This is stored in big-endian order.</p>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">FDB::Tuple::UUID.&lt;=&gt; -&gt; Fixnum</code></dt>
<dd><p>Comparison method for <code class="docutils literal"><span class="pre">UUID</span></code> objects. It will compare the UUID representations as unsigned byte arrays.
This is the same order the database uses when comparing serialized UUIDs when they are used as part
of a key.</p>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">FDB::Tuple::UUID.to_s -&gt; String</code></dt>
<dd><p>Creates a string representation of the <code class="docutils literal"><span class="pre">UUID</span></code>. This will be a string of length 32 containing the hex representation
of the UUID bytes.</p>
</dd></dl>
</div>
<div class="section" id="subspaces">
<span id="api-ruby-subspaces"></span><h2>Subspaces</h2>
<p>Subspaces provide a convenient way to use the <a class="reference internal" href="#api-ruby-tuple-layer"><span class="std std-ref">tuple layer</span></a> to define namespaces for different categories of data. The namespace is specified by a prefix tuple which is prepended to all tuples packed by the subspace. When unpacking a key with the subspace, the prefix tuple will be removed from the result.</p>
<p>As a best practice, API clients should use at least one subspace for application data.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">For general guidance on subspace usage, see the discussion in the <a class="reference internal" href="developer-guide.html#developer-guide-sub-keyspaces"><span class="std std-ref">Developer Guide</span></a>.</p>
</div>
<dl class="class">
<dt id="FDB::Subspace">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">Subspace</code><span class="sig-paren">(</span><em>prefix_tuple=</em>, <span class="optional">[</span><span class="optional">]</span><em>raw_prefix=''</em><span class="sig-paren">)</span></dt>
<dd><p>Creates a subspace with the specified prefix tuple. If the raw prefix byte string is specified, then it will be prepended to all packed keys. Likewise, the raw prefix will be removed from all unpacked keys.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Subspace.key">
<code class="descclassname">Subspace.</code><code class="descname">key</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; String</dt>
<dd><p>Returns the key encoding the prefix used for the subspace. This is equivalent to packing the empty tuple.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Subspace.pack">
<code class="descclassname">Subspace.</code><code class="descname">pack</code><span class="sig-paren">(</span><em>tuple</em><span class="sig-paren">)</span> &#x2192; String</dt>
<dd><p>Returns the key encoding the specified tuple in the subspace. For example, if you have a subspace with prefix tuple <code class="docutils literal"><span class="pre">('users')</span></code> and you use it to pack the tuple <code class="docutils literal"><span class="pre">('Smith')</span></code>, the result is the same as if you packed the tuple <code class="docutils literal"><span class="pre">('users',</span> <span class="pre">'Smith')</span></code> with the <a class="reference internal" href="#api-ruby-tuple-layer"><span class="std std-ref">tuple layer</span></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Subspace.unpack">
<code class="descclassname">Subspace.</code><code class="descname">unpack</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; Array</dt>
<dd><p>Returns the tuple encoded by the given key, with the subspace&#8217;s prefix tuple and raw prefix removed.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Subspace.range">
<code class="descclassname">Subspace.</code><code class="descname">range</code><span class="sig-paren">(</span><em>tuple=</em><span class="optional">[</span><span class="optional">]</span><span class="sig-paren">)</span> &#x2192; Array</dt>
<dd><p>Returns a range representing all keys in the subspace that encode tuples strictly starting with the specifed tuple.</p>
<p>The range will be returned as an <code class="xref rb rb-class docutils literal"><span class="pre">Array</span></code> of two elements, and may be used with any FoundationDB methods that require a range:</p>
<div class="highlight-ruby"><div class="highlight"><pre><span></span><span class="n">r</span> <span class="o">=</span> <span class="n">subspace</span><span class="o">.</span><span class="n">range</span><span class="p">(</span><span class="o">[</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="o">]</span><span class="p">)</span>
<span class="n">tr</span><span class="o">.</span><span class="n">get_range</span><span class="p">(</span><span class="n">r</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span> <span class="n">r</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">kv</span><span class="o">|</span> <span class="o">...</span> <span class="p">}</span>
</pre></div>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::Subspace.contains?">
<code class="descclassname">Subspace.</code><code class="descname">contains?</code><span class="sig-paren">(</span><em>key</em><span class="sig-paren">)</span> &#x2192; bool</dt>
<dd><p>Returns true if <code class="docutils literal"><span class="pre">key</span></code> starts with <a class="reference internal" href="#FDB::Subspace.key" title="FDB::Subspace.key"><code class="xref rb rb-meth docutils literal"><span class="pre">Subspace.key</span></code></a>, indicating that the subspace logically contains <code class="docutils literal"><span class="pre">key</span></code>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Subspace.as_foundationdb_key">
<code class="descclassname">Subspace.</code><code class="descname">as_foundationdb_key</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; String</dt>
<dd><p>Returns the key encoding the prefix used for the subspace, like <a class="reference internal" href="#FDB::Subspace.key" title="FDB::Subspace.key"><code class="xref rb rb-meth docutils literal"><span class="pre">Subspace.key</span></code></a>. This method serves to support the <a class="reference internal" href="#api-ruby-keys"><span class="std std-ref">as_foundationdb_key()</span></a> convenience interface.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::Subspace.subspace">
<code class="descclassname">Subspace.</code><code class="descname">subspace</code><span class="sig-paren">(</span><em>tuple</em><span class="sig-paren">)</span> &#x2192; Subspace</dt>
<dd><p>Returns a new subspace which is equivalent to this subspace with its prefix tuple extended by the specified tuple.</p>
</dd></dl>
<dl class="method">
<dt>
<code class="descname">Subspace.[](item) -&gt; Subspace</code></dt>
<dd><p>Shorthand for Subspace.subspace([item]). This function can be combined with the <a class="reference internal" href="#FDB::Subspace.as_foundationdb_key" title="FDB::Subspace.as_foundationdb_key"><code class="xref rb rb-meth docutils literal"><span class="pre">Subspace.as_foundationdb_key()</span></code></a> convenience to turn this:</p>
<div class="highlight-ruby"><div class="highlight"><pre><span></span><span class="n">s</span> <span class="o">=</span> <span class="no">FDB</span><span class="o">::</span><span class="no">Subspace</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="s1">&#39;x&#39;</span><span class="o">]</span><span class="p">)</span>
<span class="n">tr</span><span class="o">[</span><span class="n">s</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="o">[</span><span class="s1">&#39;foo&#39;</span><span class="p">,</span> <span class="s1">&#39;bar&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="o">]</span><span class="p">)</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
</pre></div>
</div>
<p>into this:</p>
<div class="highlight-ruby"><div class="highlight"><pre><span></span><span class="n">s</span> <span class="o">=</span> <span class="no">FDB</span><span class="o">::</span><span class="no">Subspace</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="s1">&#39;x&#39;</span><span class="o">]</span><span class="p">)</span>
<span class="n">tr</span><span class="o">[</span><span class="n">s</span><span class="o">[</span><span class="s1">&#39;foo&#39;</span><span class="o">][</span><span class="s1">&#39;bar&#39;</span><span class="o">][</span><span class="mi">1</span><span class="o">]]</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
</pre></div>
</div>
</dd></dl>
</div>
<div class="section" id="directories">
<span id="api-ruby-directories"></span><h2>Directories</h2>
<p>The FoundationDB API provides <a class="reference internal" href="developer-guide.html#developer-guide-directories"><span class="std std-ref">directories</span></a> as a tool for managing related <a class="reference internal" href="#api-ruby-subspaces"><span class="std std-ref">subspaces</span></a>. Directories are a recommended approach for administering applications. Each application should create or open at least one directory to manage its subspaces.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">For general guidance on directory usage, see the discussion in the <a class="reference internal" href="developer-guide.html#developer-guide-directories"><span class="std std-ref">Developer Guide</span></a>.</p>
</div>
<p>Directories are identified by hierarchical paths analogous to the paths in a Unix-like file system. A path is represented as an <code class="xref rb rb-class docutils literal"><span class="pre">Enumerable</span></code> of strings. Each directory has an associated subspace used to store its content. The directory layer maps each path to a short prefix used for the corresponding subspace. In effect, directories provide a level of indirection for access to subspaces.</p>
<p>Except where noted, directory methods interpret the provided path(s) relative to the path of the directory object. When opening a directory, a byte string <code class="docutils literal"><span class="pre">layer</span></code> option may be specified as a metadata identifier.</p>
<dl class="global">
<dt>
<code class="descname">FDB::directory</code></dt>
<dd><p>The default instance of <a class="reference internal" href="#FDB::DirectoryLayer" title="FDB::DirectoryLayer"><code class="xref rb rb-class docutils literal"><span class="pre">DirectoryLayer</span></code></a>.</p>
</dd></dl>
<dl class="class">
<dt id="FDB::DirectoryLayer">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">DirectoryLayer</code><span class="sig-paren">(</span><em>node_subspace=Subspace.new(</em>, <span class="optional">[</span><span class="optional">]</span><em>&quot;\xFE&quot;)</em>, <em>content_subspace=Subspace.new</em>, <em>allow_manual_prefixes=false</em><span class="sig-paren">)</span></dt>
<dd><p>Each instance defines a new root directory. The subspaces <code class="docutils literal"><span class="pre">node_subspace</span></code> and <code class="docutils literal"><span class="pre">content_subspace</span></code> control where the directory metadata and contents, respectively, are stored. The default root directory has a <code class="docutils literal"><span class="pre">node_subspace</span></code> with raw prefix <code class="docutils literal"><span class="pre">\xFE</span></code> and a <code class="docutils literal"><span class="pre">content_subspace</span></code> with no prefix. Specifying more restrictive values for <code class="docutils literal"><span class="pre">node_subspace</span></code> and <code class="docutils literal"><span class="pre">content_subspace</span></code> will allow using the directory layer alongside other content in a database. If <code class="docutils literal"><span class="pre">allow_manual_prefixes</span></code> is false, attempts to create a directory with a manual prefix under the directory layer will raise an exception. The default root directory does not allow manual prefixes.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::DirectoryLayer.create_or_open">
<code class="descclassname">DirectoryLayer.</code><code class="descname">create_or_open</code><span class="sig-paren">(</span><em>db_or_tr</em>, <em>path</em>, <em>options={}</em><span class="sig-paren">)</span> &#x2192; DirectorySubspace</dt>
<dd><p>Opens the directory with <code class="docutils literal"><span class="pre">path</span></code> specified as an <code class="xref rb rb-class docutils literal"><span class="pre">Enumerable</span></code> of strings. <code class="docutils literal"><span class="pre">path</span></code> can also be a string, in which case it will be automatically wrapped in an <code class="xref rb rb-class docutils literal"><span class="pre">Enumerable</span></code>. All string values in a path will be converted to unicode. If the directory does not exist, it is created (creating parent directories if necessary).</p>
<p>If the byte string <code class="docutils literal"><span class="pre">:layer</span></code> is specified in <code class="docutils literal"><span class="pre">options</span></code> and the directory is new, it is recorded as the layer; if <code class="docutils literal"><span class="pre">:layer</span></code> is specified and the directory already exists, it is compared against the layer specified when the directory was created, and the method will raise an exception if they differ.</p>
<p>Returns the directory and its contents as a <a class="reference internal" href="#FDB::DirectorySubspace" title="FDB::DirectorySubspace"><code class="xref rb rb-class docutils literal"><span class="pre">DirectorySubspace</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::DirectoryLayer.open">
<code class="descclassname">DirectoryLayer.</code><code class="descname">open</code><span class="sig-paren">(</span><em>db_or_tr</em>, <em>path</em>, <em>options={}</em><span class="sig-paren">)</span> &#x2192; DirectorySubspace</dt>
<dd><p>Opens the directory with <code class="docutils literal"><span class="pre">path</span></code> specified as an <code class="xref rb rb-class docutils literal"><span class="pre">Enumerable</span></code> of strings. <code class="docutils literal"><span class="pre">path</span></code> can also be a string, in which case it will be automatically wrapped in an <code class="xref rb rb-class docutils literal"><span class="pre">Enumerable</span></code>. All string values in a path will be converted to unicode. The method will raise an exception if the directory does not exist.</p>
<p>If the byte string <code class="docutils literal"><span class="pre">:layer</span></code> is specified in <code class="docutils literal"><span class="pre">options</span></code>, it is compared against the layer specified when the directory was created, and the method will raise an exception if they differ.</p>
<p>Returns the directory and its contents as a <a class="reference internal" href="#FDB::DirectorySubspace" title="FDB::DirectorySubspace"><code class="xref rb rb-class docutils literal"><span class="pre">DirectorySubspace</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::DirectoryLayer.create">
<code class="descclassname">DirectoryLayer.</code><code class="descname">create</code><span class="sig-paren">(</span><em>db_or_tr</em>, <em>path</em>, <em>options={}</em><span class="sig-paren">)</span> &#x2192; DirectorySubspace</dt>
<dd><p>Creates a directory with <code class="docutils literal"><span class="pre">path</span></code> specified as an <code class="xref rb rb-class docutils literal"><span class="pre">Enumerable</span></code> of strings. <code class="docutils literal"><span class="pre">path</span></code> can also be a string, in which case it will be automatically wrapped in an <code class="xref rb rb-class docutils literal"><span class="pre">Enumerable</span></code>. All string values in a path will be converted to unicode. Parent directories are created if necessary. The method will raise an exception if the given directory already exists.</p>
<p>If the byte string <code class="docutils literal"><span class="pre">:prefix</span></code> is specified in <code class="docutils literal"><span class="pre">options</span></code>, the directory is created with the given physical prefix; otherwise a prefix is allocated automatically.</p>
<p>If the byte string <code class="docutils literal"><span class="pre">:layer</span></code> is specified in <code class="docutils literal"><span class="pre">options</span></code>, it is recorded with the directory and will be checked by future calls to open.</p>
<p>Returns the directory and its contents as a <a class="reference internal" href="#FDB::DirectorySubspace" title="FDB::DirectorySubspace"><code class="xref rb rb-class docutils literal"><span class="pre">DirectorySubspace</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::DirectoryLayer.move">
<code class="descclassname">DirectoryLayer.</code><code class="descname">move</code><span class="sig-paren">(</span><em>db_or_tr</em>, <em>old_path</em>, <em>new_path</em><span class="sig-paren">)</span> &#x2192; DirectorySubspace</dt>
<dd><p>Moves the directory at <code class="docutils literal"><span class="pre">old_path</span></code> to <code class="docutils literal"><span class="pre">new_path</span></code>. There is no effect on the physical prefix of the given directory or on clients that already have the directory open. The method will raise an exception if a directory does not exist at <code class="docutils literal"><span class="pre">old_path</span></code>, a directory already exists at <code class="docutils literal"><span class="pre">new_path</span></code>, or the parent directory of <code class="docutils literal"><span class="pre">new_path</span></code> does not exist.</p>
<p>Returns the directory at its new location as a <a class="reference internal" href="#FDB::DirectorySubspace" title="FDB::DirectorySubspace"><code class="xref rb rb-class docutils literal"><span class="pre">DirectorySubspace</span></code></a>.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::DirectoryLayer.remove">
<code class="descclassname">DirectoryLayer.</code><code class="descname">remove</code><span class="sig-paren">(</span><em>db_or_tr</em>, <em>path</em><span class="sig-paren">)</span> &#x2192; bool</dt>
<dd><p>Removes the directory at <code class="docutils literal"><span class="pre">path</span></code>, its contents, and all subdirectories. The method will raise an exception if the directory does not exist.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">Clients that have already opened the directory might still insert data into its contents after removal.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::DirectoryLayer.remove_if_exists">
<code class="descclassname">DirectoryLayer.</code><code class="descname">remove_if_exists</code><span class="sig-paren">(</span><em>db_or_tr</em>, <em>path</em><span class="sig-paren">)</span> &#x2192; bool</dt>
<dd><p>Checks if the directory at <code class="docutils literal"><span class="pre">path</span></code> exists and, if so, removes the directory, its contents, and all subdirectories. Returns <code class="docutils literal"><span class="pre">true</span></code> if the directory existed and <code class="docutils literal"><span class="pre">false</span></code> otherwise.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">Clients that have already opened the directory might still insert data into its contents after removal.</p>
</div>
</dd></dl>
<dl class="method">
<dt id="FDB::DirectoryLayer.list">
<code class="descclassname">DirectoryLayer.</code><code class="descname">list</code><span class="sig-paren">(</span><em>db_or_tr</em>, <em>path=</em><span class="optional">[</span><span class="optional">]</span><span class="sig-paren">)</span> &#x2192; Enumerable</dt>
<dd><p>Returns an <code class="xref rb rb-class docutils literal"><span class="pre">Enumerable</span></code> of names of the immediate subdirectories of the directory at <code class="docutils literal"><span class="pre">path</span></code>. Each name is a unicode string representing the last component of a subdirectory&#8217;s path.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::DirectoryLayer.exists?">
<code class="descclassname">DirectoryLayer.</code><code class="descname">exists?</code><span class="sig-paren">(</span><em>db_or_tr</em>, <em>path</em><span class="sig-paren">)</span> &#x2192; bool</dt>
<dd><p>Returns <code class="docutils literal"><span class="pre">true</span></code> if the directory at <code class="docutils literal"><span class="pre">path</span></code> exists and <code class="docutils literal"><span class="pre">false</span></code> otherwise.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::DirectoryLayer.layer">
<code class="descclassname">DirectoryLayer.</code><code class="descname">layer</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; String</dt>
<dd><p>Returns the layer specified when the directory was created.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::DirectoryLayer.path">
<code class="descclassname">DirectoryLayer.</code><code class="descname">path</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; Enumerable</dt>
<dd><p>Returns the path with which the directory was opened.</p>
</dd></dl>
<div class="section" id="directorysubspace">
<span id="api-ruby-directory-subspace"></span><h3>DirectorySubspace</h3>
<dl class="class">
<dt id="FDB::DirectorySubspace">
<em class="property">class </em><code class="descclassname">FDB::</code><code class="descname">DirectorySubspace</code></dt>
<dd><p>A directory subspace represents a specific directory and its contents. It stores the <code class="docutils literal"><span class="pre">path</span></code> with which it was opened and supports all <a class="reference internal" href="#FDB::DirectoryLayer" title="FDB::DirectoryLayer"><code class="xref rb rb-class docutils literal"><span class="pre">DirectoryLayer</span></code></a> methods for operating on itself and its subdirectories. It also implements all <a class="reference internal" href="#FDB::Subspace" title="FDB::Subspace"><code class="xref rb rb-class docutils literal"><span class="pre">Subspace</span></code></a> methods for working with the contents of that directory.</p>
</dd></dl>
<dl class="method">
<dt id="FDB::DirectorySubspace.move_to">
<code class="descclassname">DirectorySubspace.</code><code class="descname">move_to</code><span class="sig-paren">(</span><em>db_or_tr</em>, <em>new_absolute_path</em><span class="sig-paren">)</span> &#x2192; DirectorySubspace</dt>
<dd><p>Moves this directory to <code class="docutils literal"><span class="pre">new_path</span></code>, interpreting <code class="docutils literal"><span class="pre">new_path</span></code> absolutely. There is no effect on the physical prefix of the given directory or on clients that already have the directory open. The method will raise an exception if a directory already exists at <code class="docutils literal"><span class="pre">new_path</span></code> or the parent directory of <code class="docutils literal"><span class="pre">new_path</span></code> does not exist.</p>
<p>Returns the directory at its new location as a <a class="reference internal" href="#FDB::DirectorySubspace" title="FDB::DirectorySubspace"><code class="xref rb rb-class docutils literal"><span class="pre">DirectorySubspace</span></code></a>.</p>
</dd></dl>
</div>
</div>
<div class="section" id="module-FDB::Locality">
<span id="locality-information"></span><h2>Locality information</h2>
<p>The FoundationDB API comes with a set of functions for discovering the storage locations of keys within your cluster. This information can be useful for advanced users who wish to take into account the location of keys in the design of applications or processes.</p>
<dl class="function">
<dt id="FDB::Locality.get_boundary_keys">
<code class="descclassname">FDB::Locality.</code><code class="descname">get_boundary_keys</code><span class="sig-paren">(</span><em>db_or_tr</em>, <em>begin</em>, <em>end</em><span class="sig-paren">)</span> &#x2192; Enumerator</dt>
<dd><p>Returns a <code class="xref rb rb-class docutils literal"><span class="pre">Enumerator</span></code> of keys <code class="docutils literal"><span class="pre">k</span></code> such that <code class="docutils literal"><span class="pre">begin</span> <span class="pre">&lt;=</span> <span class="pre">k</span> <span class="pre">&lt;</span> <span class="pre">end</span></code> and <code class="docutils literal"><span class="pre">k</span></code> is located at the start of a contiguous range stored on a single server.</p>
<p>The first parameter to this function may be either a <a class="reference internal" href="#FDB::Database" title="FDB::Database"><code class="xref rb rb-class docutils literal"><span class="pre">Database</span></code></a> or a <a class="reference internal" href="#FDB::Transaction" title="FDB::Transaction"><code class="xref rb rb-class docutils literal"><span class="pre">Transaction</span></code></a>. If it is passed a <a class="reference internal" href="#FDB::Transaction" title="FDB::Transaction"><code class="xref rb rb-class docutils literal"><span class="pre">Transaction</span></code></a>, the transaction will not be committed, reset, or modified in any way, nor will its transaction options (such as retry limit) be applied within the function. However, if the database is unavailable prior to the function call, any timeout set on the transaction will still trigger.</p>
<p>Like a <a class="reference internal" href="#api-ruby-future"><span class="std std-ref">Future</span></a> object, the returned <code class="xref rb rb-class docutils literal"><span class="pre">Enumerator</span></code> issues asynchronous read operations to fetch data in the range, and may block while enumerating its values if the read has not completed.</p>
<p>This method is not transactional. It will return an answer no older than the Transaction or Database object it is passed, but the returned boundaries are an estimate and may not represent the exact boundary locations at any database version.</p>
</dd></dl>
<dl class="function">
<dt id="FDB::Locality.get_addresses_for_key">
<code class="descclassname">FDB::Locality.</code><code class="descname">get_addresses_for_key</code><span class="sig-paren">(</span><em>tr</em>, <em>key</em><span class="sig-paren">)</span> &#x2192; Array</dt>
<dd><p>Returns a list of public network addresses as strings, one for each of the storage servers responsible for storing <code class="docutils literal"><span class="pre">key</span></code> and its associated value.</p>
</dd></dl>
</div>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<p class="pull-right">
<a href="#">Back to top</a>
<br/>
<div id="sourcelink">
<a href="_sources/api-ruby.rst.txt"
rel="nofollow">Source</a>
</div>
</p>
<p>
&copy; Copyright 2013-2021 Apple, Inc and the FoundationDB project authors.<br/>
Last updated on Sep 19, 2022.<br/>
</p>
</div>
</footer>
</body>
</html>