File: custom_data_sources.html

package info (click to toggle)
wiredtiger 3.2.1-1
  • links: PTS
  • area: main
  • in suites: bookworm, bullseye, sid, trixie
  • size: 25,456 kB
  • sloc: ansic: 102,922; python: 52,573; sh: 6,915; java: 6,130; cpp: 2,311; makefile: 1,018; xml: 176
file content (170 lines) | stat: -rw-r--r-- 31,021 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>WiredTiger: Custom Data Sources</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="wiredtiger.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><a href="http://wiredtiger.com/"><img alt="Logo" src="LogoFinal-header.png" alt="WiredTiger" /></a></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">
   &#160;<span id="projectnumber">Version 3.2.1</span>
   </div>
   <div id="projectbrief"><!-- 3.2.1 --></div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<div class="banner">
  <a href="https://github.com/wiredtiger/wiredtiger">Fork me on GitHub</a>
  <a class="last" href="http://groups.google.com/group/wiredtiger-users">Join my user group</a>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('',false,false,'search.php','Search');
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('custom_data_sources.html','');});
</script>
<div id="doc-content">
<div class="header">
  <div class="headertitle">
<div class="title">Custom Data Sources </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>Applications can implement their own custom data sources underneath WiredTiger using the <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html" title="Applications can extend WiredTiger by providing new implementations of the WT_DATA_SOURCE class...">WT_DATA_SOURCE</a> interface. Each data source should support a set of methods for a different URI type (for example, in the same way WiredTiger supports the built-in type "file:", an application data source might support the type "dsrc:").</p>
<p>Applications register their <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html" title="Applications can extend WiredTiger by providing new implementations of the WT_DATA_SOURCE class...">WT_DATA_SOURCE</a> interface implementations with WiredTiger using the <a class="el" href="struct_w_t___c_o_n_n_e_c_t_i_o_n.html#a459c1b71346bbcecb552ad73d43f27ea" title="Add a custom data source. ">WT_CONNECTION::add_data_source</a> method:</p>
<div class="fragment"><div class="line">        <span class="keyword">static</span> <a class="code" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html">WT_DATA_SOURCE</a> my_dsrc = {my_alter, my_create, my_compact, my_drop, my_open_cursor,</div><div class="line">          my_rename, my_salvage, my_size, my_truncate, my_range_truncate, my_verify, my_checkpoint,</div><div class="line">          my_terminate, my_lsm_pre_merge};</div><div class="line">        error_check(conn-&gt;add_data_source(conn, <span class="stringliteral">&quot;dsrc:&quot;</span>, &amp;my_dsrc, NULL));</div></div><!-- fragment --> <h1><a class="anchor" id="custom_ds_methods"></a>
WT_DATA_SOURCE methods</h1>
<p>Any of the <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html" title="Applications can extend WiredTiger by providing new implementations of the WT_DATA_SOURCE class...">WT_DATA_SOURCE</a> methods may be initialized to NULL. Calling uninitialized <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html" title="Applications can extend WiredTiger by providing new implementations of the WT_DATA_SOURCE class...">WT_DATA_SOURCE</a> methods through a WiredTiger API will result in an "operation not supported" error. For example, an underlying data source that does not support a compaction operation should set the <code>compact</code> field of their <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html" title="Applications can extend WiredTiger by providing new implementations of the WT_DATA_SOURCE class...">WT_DATA_SOURCE</a> structure to NULL.</p>
<h2><a class="anchor" id="custom_ds_create"></a>
WT_DATA_SOURCE::create method</h2>
<p>When implementing a custom data source, you may want to consider the 'r' key and 't' value formats, and whether or not they should be implemented.</p>
<p>The 'r' key format indicates keys are <code>uint64_t</code> typed record numbers. In this case, cursor methods will be passed and/or return a record number in the <code>recno</code> field of the <a class="el" href="struct_w_t___c_u_r_s_o_r.html" title="A WT_CURSOR handle is the interface to a cursor. ">WT_CURSOR</a> structure.</p>
<p>Cursor methods for data sources supporting fixed-length bit field column-stores (that is, a store with an 'r' type key and 't' type value) should accept and/or return a single byte in the value field of the <a class="el" href="struct_w_t___c_u_r_s_o_r.html" title="A WT_CURSOR handle is the interface to a cursor. ">WT_CURSOR</a> structure, where between 1 and 8 of the low-order bits of that byte contain the bit-field's value. For example, if the value format is "3t", the key's value is the bottom 3 bits.</p>
<h1><a class="anchor" id="custom_ds_cursor_methods"></a>
WT_CURSOR methods</h1>
<p>The <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html#a81e45e31dedcdeaf8ff970d3c118da2e" title="Callback to initialize a cursor. ">WT_DATA_SOURCE::open_cursor</a> method is responsible for allocating and returning a <a class="el" href="struct_w_t___c_u_r_s_o_r.html" title="A WT_CURSOR handle is the interface to a cursor. ">WT_CURSOR</a> structure. The only fields of the <a class="el" href="struct_w_t___c_u_r_s_o_r.html" title="A WT_CURSOR handle is the interface to a cursor. ">WT_CURSOR</a> structure that should be initialized by <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html#a81e45e31dedcdeaf8ff970d3c118da2e" title="Callback to initialize a cursor. ">WT_DATA_SOURCE::open_cursor</a> are a subset of the underlying methods it supports.</p>
<p>The following methods of the <a class="el" href="struct_w_t___c_u_r_s_o_r.html" title="A WT_CURSOR handle is the interface to a cursor. ">WT_CURSOR</a> structure must be initialized: </p><ul>
<li>
<a class="el" href="struct_w_t___c_u_r_s_o_r.html#aeea071f192cab12245a50fbe71c3460b" title="Close the cursor. ">WT_CURSOR::close</a> </li>
<li>
<a class="el" href="struct_w_t___c_u_r_s_o_r.html#a0503f16bd8f3d05aa3552f229b3a8e1b" title="Return the next record. ">WT_CURSOR::next</a> </li>
<li>
<a class="el" href="struct_w_t___c_u_r_s_o_r.html#a43d6664d2f68902aa63f933864242e76" title="Return the previous record. ">WT_CURSOR::prev</a> </li>
<li>
<a class="el" href="struct_w_t___c_u_r_s_o_r.html#afc1b42c22c9c85e1ba08ce3b34437565" title="Reset the cursor. ">WT_CURSOR::reset</a> </li>
<li>
<a class="el" href="struct_w_t___c_u_r_s_o_r.html#a7e25b2ced2cf3ec68bd5429bf921c79f" title="Return the record matching the key. ">WT_CURSOR::search</a> </li>
<li>
<a class="el" href="struct_w_t___c_u_r_s_o_r.html#a8068ddce20d0775f26f6dac6e5eb209c" title="Return the record matching the key if it exists, or an adjacent record. ">WT_CURSOR::search_near</a> </li>
<li>
<a class="el" href="struct_w_t___c_u_r_s_o_r.html#aac90d9fbcc031570f924db55f8a1cee3" title="Insert a record and optionally update an existing record. ">WT_CURSOR::insert</a> </li>
<li>
<a class="el" href="struct_w_t___c_u_r_s_o_r.html#a444cdc0952e7f8d55d23173516c7037f" title="Update an existing record and optionally insert a record. ">WT_CURSOR::update</a> </li>
<li>
<a class="el" href="struct_w_t___c_u_r_s_o_r.html#abbba24fe607fee519c4c9c4669cd4455" title="Remove a record. ">WT_CURSOR::remove</a> </li>
</ul>
<p>No other methods of the <a class="el" href="struct_w_t___c_u_r_s_o_r.html" title="A WT_CURSOR handle is the interface to a cursor. ">WT_CURSOR</a> structure should be initialized, for example initializing <a class="el" href="struct_w_t___c_u_r_s_o_r.html#af19f6f9d9c7fc248ab38879032620b2f" title="Get the key for the current record. ">WT_CURSOR::get_key</a> or <a class="el" href="struct_w_t___c_u_r_s_o_r.html#ad1088d719df40babc1f57d086691ebdc" title="Set the key for the next operation. ">WT_CURSOR::set_key</a> will have no effect.</p>
<p>Incorrectly configuring the <a class="el" href="struct_w_t___c_u_r_s_o_r.html" title="A WT_CURSOR handle is the interface to a cursor. ">WT_CURSOR</a> methods will likely result in a core dump.</p>
<p>The data source's <a class="el" href="struct_w_t___c_u_r_s_o_r.html#aeea071f192cab12245a50fbe71c3460b" title="Close the cursor. ">WT_CURSOR::close</a> method is responsible for discarding the allocated <a class="el" href="struct_w_t___c_u_r_s_o_r.html" title="A WT_CURSOR handle is the interface to a cursor. ">WT_CURSOR</a> structure returned by <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html#a81e45e31dedcdeaf8ff970d3c118da2e" title="Callback to initialize a cursor. ">WT_DATA_SOURCE::open_cursor</a>.</p>
<h2><a class="anchor" id="custom_ds_cursor_insert"></a>
WT_CURSOR::insert method</h2>
<p>Custom data sources supporting column-stores (that is, a store with an 'r' type key) should consider the <code>append</code> configuration string optionally specified for the <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html#a81e45e31dedcdeaf8ff970d3c118da2e" title="Callback to initialize a cursor. ">WT_DATA_SOURCE::open_cursor</a> method. The <code>append</code> string configures <a class="el" href="struct_w_t___c_u_r_s_o_r.html#aac90d9fbcc031570f924db55f8a1cee3" title="Insert a record and optionally update an existing record. ">WT_CURSOR::insert</a> to allocate and return an new record number key.</p>
<p>Custom data sources should consider the <code>overwrite</code> configuration string optionally specified for the <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html#a81e45e31dedcdeaf8ff970d3c118da2e" title="Callback to initialize a cursor. ">WT_DATA_SOURCE::open_cursor</a> method. If the <code>overwrite</code> configuration is <code>true</code>, <a class="el" href="struct_w_t___c_u_r_s_o_r.html#aac90d9fbcc031570f924db55f8a1cee3" title="Insert a record and optionally update an existing record. ">WT_CURSOR::insert</a>, <a class="el" href="struct_w_t___c_u_r_s_o_r.html#abbba24fe607fee519c4c9c4669cd4455" title="Remove a record. ">WT_CURSOR::remove</a> and <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a444cdc0952e7f8d55d23173516c7037f" title="Update an existing record and optionally insert a record. ">WT_CURSOR::update</a> should ignore the current state of the record, and these methods will succeed regardless of whether or not the record previously exists.</p>
<p>When an application configures <code>overwrite</code> to <code>false</code>, <a class="el" href="struct_w_t___c_u_r_s_o_r.html#aac90d9fbcc031570f924db55f8a1cee3" title="Insert a record and optionally update an existing record. ">WT_CURSOR::insert</a> should fail with <a class="el" href="group__wt.html#gaeca1f3c4a70b8b71b56d2c2fc99a469c" title="Attempt to insert an existing key. ">WT_DUPLICATE_KEY</a> if the record previously exists, and <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a444cdc0952e7f8d55d23173516c7037f" title="Update an existing record and optionally insert a record. ">WT_CURSOR::update</a> and <a class="el" href="struct_w_t___c_u_r_s_o_r.html#abbba24fe607fee519c4c9c4669cd4455" title="Remove a record. ">WT_CURSOR::remove</a> will fail with <a class="el" href="group__wt.html#ga3c9e1b494d95cf34404ab7a974af6bf8" title="Item not found. ">WT_NOTFOUND</a> if the record does not previously exist.</p>
<p>Custom data sources supporting fixed-length bit field column-stores (that is, a store with an 'r' type key and 't' type value) may, but are not required to, support the semantic that inserting a new record after the current maximum record in a store implicitly creates the missing records as records with a value of 0.</p>
<h1><a class="anchor" id="custom_ds_cursor_fields"></a>
WT_CURSOR key/value fields</h1>
<p>Custom data source cursor methods are expected to use the <code>recno</code>, <code>key</code> and <code>value</code> fields of the <a class="el" href="struct_w_t___c_u_r_s_o_r.html" title="A WT_CURSOR handle is the interface to a cursor. ">WT_CURSOR</a> handle.</p>
<p>The <code>recno</code> field is a uint64_t type and is the record number set or retrieved using the cursor when the data source was configured for record number keys.</p>
<p>The <code>key</code> and <code>value</code> fields are <a class="el" href="group__wt.html#struct_w_t___i_t_e_m" title="A raw item of data to be managed, including a pointer to the data and a length. ">WT_ITEM</a> structures. The <code>key.data</code>, <code>key.size</code>, <code>value.data</code> and <code>value.size</code> fields are read by the cursor methods storing items in the underlying data source and set by the cursor methods retrieving items from the underlying data source.</p>
<h1><a class="anchor" id="custom_ds_error_handling"></a>
Error handling</h1>
<p>Some specific errors should be mapped to WiredTiger errors: </p><ul>
<li>
attempts to insert an existing key should return WT_DUPLICATE_KEY </li>
<li>
failure to find a key/value pair should return WT_NOTFOUND </li>
<li>
fatal errors requiring the database restart should return WT_PANIC </li>
</ul>
<p>Otherwise, successful return from custom data source methods should be indicated by a return value of zero; error returns may be any value other than zero or an error in WiredTiger's <a class="el" href="error_handling.html">Error handling</a>. A simple approach is to always return either a system error value (that is, <code>errno</code>), or <code>WT_ERROR</code>. Error messages can be displayed using the WT_SESSION::msg_printf method. For example:</p>
<div class="fragment"><div class="line">        <span class="comment">/*</span></div><div class="line"><span class="comment">         * If an underlying function fails, log the error and then return a non-zero value.</span></div><div class="line"><span class="comment">         */</span></div><div class="line">        <span class="keywordflow">if</span> ((ret = data_source_cursor()) != 0) {</div><div class="line">            (void)wt_api-&gt;err_printf(wt_api, session, <span class="stringliteral">&quot;my_open_cursor: %s&quot;</span>, data_source_error(ret));</div><div class="line">            <span class="keywordflow">return</span> (<a class="code" href="group__wt.html#gafdfe4d6ca06cb7337272f883f60c991e">WT_ERROR</a>);</div><div class="line">        }</div></div><!-- fragment --> <h1><a class="anchor" id="custom_ds_config"></a>
Configuration strings</h1>
<h2><a class="anchor" id="custom_ds_config_parsing"></a>
Parsing configuration strings</h2>
<p>Configuration information is provided to each <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html" title="Applications can extend WiredTiger by providing new implementations of the WT_DATA_SOURCE class...">WT_DATA_SOURCE</a> method as an argument. This configuration information can be parsed using the WT_EXTENSION_API::config method, and is returned in a <a class="el" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html" title="The configuration information returned by the WiredTiger configuration parsing functions in the WT_EX...">WT_CONFIG_ITEM</a> structure.</p>
<p>For example, the <code>append</code>, <code>overwrite</code> <code>key_format</code> and <code>value_format</code> configuration strings may be required for the <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html#a81e45e31dedcdeaf8ff970d3c118da2e" title="Callback to initialize a cursor. ">WT_DATA_SOURCE::open_cursor</a> method to correctly configure itself.</p>
<p>A <code>key_format</code> value of "r" indicates the data source is being configured to use record numbers as keys. In this case initialized <a class="el" href="struct_w_t___c_u_r_s_o_r.html" title="A WT_CURSOR handle is the interface to a cursor. ">WT_CURSOR</a> methods must take their key value from the cursor's <code>recno</code> field, and not the cursor's <code>key</code> field. (It is not required that record numbers be supported by a custom data source, the <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html#a81e45e31dedcdeaf8ff970d3c118da2e" title="Callback to initialize a cursor. ">WT_DATA_SOURCE::open_cursor</a> method can return an error if an application attempts to configure a data source with a <code>key_format</code> of "r".)</p>
<p>The <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html#a81e45e31dedcdeaf8ff970d3c118da2e" title="Callback to initialize a cursor. ">WT_DATA_SOURCE::open_cursor</a> method might retrieve the boolean or integer value of a configuration string as follows:</p>
<div class="fragment"><div class="line">            <a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html">WT_CONFIG_ITEM</a> v;</div><div class="line">            <span class="keywordtype">int</span> my_data_source_overwrite;</div><div class="line"></div><div class="line">            <span class="comment">/*</span></div><div class="line"><span class="comment">             * Retrieve the value of the boolean type configuration string</span></div><div class="line"><span class="comment">             * &quot;overwrite&quot;.</span></div><div class="line"><span class="comment">             */</span></div><div class="line">            error_check(wt_api-&gt;config_get(wt_api, session, config, <span class="stringliteral">&quot;overwrite&quot;</span>, &amp;v));</div><div class="line">            my_data_source_overwrite = v.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#a4aefab7843f434e5a5cc18203e9fec5f">val</a> != 0;</div></div><!-- fragment --><div class="fragment"><div class="line">            <a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html">WT_CONFIG_ITEM</a> v;</div><div class="line">            int64_t my_data_source_page_size;</div><div class="line"></div><div class="line">            <span class="comment">/*</span></div><div class="line"><span class="comment">             * Retrieve the value of the integer type configuration string</span></div><div class="line"><span class="comment">             * &quot;page_size&quot;.</span></div><div class="line"><span class="comment">             */</span></div><div class="line">            error_check(wt_api-&gt;config_get(wt_api, session, config, <span class="stringliteral">&quot;page_size&quot;</span>, &amp;v));</div><div class="line">            my_data_source_page_size = v.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#a4aefab7843f434e5a5cc18203e9fec5f">val</a>;</div></div><!-- fragment --><p> The <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html#a81e45e31dedcdeaf8ff970d3c118da2e" title="Callback to initialize a cursor. ">WT_DATA_SOURCE::open_cursor</a> method might retrieve the string value of a configuration string as follows:</p>
<div class="fragment"><div class="line">            <a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html">WT_CONFIG_ITEM</a> v;</div><div class="line">            <span class="keyword">const</span> <span class="keywordtype">char</span> *my_data_source_key;</div><div class="line"></div><div class="line">            <span class="comment">/*</span></div><div class="line"><span class="comment">             * Retrieve the value of the string type configuration string</span></div><div class="line"><span class="comment">             * &quot;key_format&quot;.</span></div><div class="line"><span class="comment">             */</span></div><div class="line">            error_check(wt_api-&gt;config_get(wt_api, session, config, <span class="stringliteral">&quot;key_format&quot;</span>, &amp;v));</div><div class="line"></div><div class="line">            <span class="comment">/*</span></div><div class="line"><span class="comment">             * Values returned from WT_EXTENSION_API::config in the str field are not</span></div><div class="line"><span class="comment">             * nul-terminated; the associated length must be used instead.</span></div><div class="line"><span class="comment">             */</span></div><div class="line">            <span class="keywordflow">if</span> (v.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#adff0f6e5a3f781f0228015e8336f1a14">len</a> == 1 &amp;&amp; v.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>[0] == <span class="charliteral">&#39;r&#39;</span>)</div><div class="line">                my_data_source_key = <span class="stringliteral">&quot;recno&quot;</span>;</div><div class="line">            <span class="keywordflow">else</span></div><div class="line">                my_data_source_key = <span class="stringliteral">&quot;bytestring&quot;</span>;</div></div><!-- fragment --> <h2><a class="anchor" id="custom_ds_config_add"></a>
Creating data-specific configuration strings</h2>
<p>Applications can add their own configuration strings to WiredTiger methods using <a class="el" href="struct_w_t___c_o_n_n_e_c_t_i_o_n.html#ab81828b0c9dccc1ccf3d8ef863804137" title="Add configuration options for a method. ">WT_CONNECTION::configure_method</a>.</p>
<p><a class="el" href="struct_w_t___c_o_n_n_e_c_t_i_o_n.html#ab81828b0c9dccc1ccf3d8ef863804137" title="Add configuration options for a method. ">WT_CONNECTION::configure_method</a> takes the following arguments:</p>
<ul>
<li>the method being extended, where the name is the concatenation of the handle name, a period and the method name. For example, <code>"WT_SESSION.create"</code> would add new configuration strings to the <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#a358ca4141d59c345f401c58501276bbb" title="Create a table, column group, index or file. ">WT_SESSION::create</a> method, and <code>"WT_SESSION.open_cursor"</code> would add the configuration string to the <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#afb5b4a69c2c5cafe411b2b04fdc1c75d" title="Open a new cursor on a data source or duplicate an existing cursor. ">WT_SESSION::open_cursor</a> method.</li>
<li>the object type of the data source being extended. For example, <code>"table:"</code> would extend the configuration arguments for table objects, and <code>"my_data:"</code> could be used to extend the configuration arguments for a data source with URIs beginning with the "my_data" prefix. A NULL value for the object type implies all object types.</li>
<li>the additional configuration string, which consists of the name of the configuration string and an optional default value. The default value is specified by appending an equals sign and a value. For example, for a new configuration string with the name <code>"device"</code>, specifying either <code>"device=/path"</code> or <code>"device=35"</code> would configure the default values.</li>
<li>the type of the additional configuration, which must one of <code>"boolean"</code>, <code>"int"</code>, <code>"list"</code> or <code>"string"</code>.</li>
<li>value checking information for the additional configuration, or NULL if no checking information is provided.</li>
</ul>
<p>For example, an application might add new boolean, integer, list or string type configuration strings as follows:</p>
<div class="fragment"><div class="line">    <span class="comment">/* my_boolean defaults to true. */</span></div><div class="line">    error_check(conn-&gt;configure_method(</div><div class="line">      conn, <span class="stringliteral">&quot;WT_SESSION.open_cursor&quot;</span>, NULL, <span class="stringliteral">&quot;my_boolean=true&quot;</span>, <span class="stringliteral">&quot;boolean&quot;</span>, NULL));</div></div><!-- fragment --><div class="fragment"><div class="line">    <span class="comment">/* my_integer defaults to 5. */</span></div><div class="line">    error_check(</div><div class="line">      conn-&gt;configure_method(conn, <span class="stringliteral">&quot;WT_SESSION.open_cursor&quot;</span>, NULL, <span class="stringliteral">&quot;my_integer=5&quot;</span>, <span class="stringliteral">&quot;int&quot;</span>, NULL));</div></div><!-- fragment --><div class="fragment"><div class="line">    <span class="comment">/* my_list defaults to &quot;first&quot; and &quot;second&quot;. */</span></div><div class="line">    error_check(conn-&gt;configure_method(</div><div class="line">      conn, <span class="stringliteral">&quot;WT_SESSION.open_cursor&quot;</span>, NULL, <span class="stringliteral">&quot;my_list=[first, second]&quot;</span>, <span class="stringliteral">&quot;list&quot;</span>, NULL));</div></div><!-- fragment --><div class="fragment"><div class="line">    <span class="comment">/* my_string defaults to &quot;name&quot;. */</span></div><div class="line">    error_check(conn-&gt;configure_method(</div><div class="line">      conn, <span class="stringliteral">&quot;WT_SESSION.open_cursor&quot;</span>, NULL, <span class="stringliteral">&quot;my_string=name&quot;</span>, <span class="stringliteral">&quot;string&quot;</span>, NULL));</div></div><!-- fragment --><p> Once these additional configuration calls have returned, application calls to the <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#afb5b4a69c2c5cafe411b2b04fdc1c75d" title="Open a new cursor on a data source or duplicate an existing cursor. ">WT_SESSION::open_cursor</a> method could then include configuration strings such as <code>my_boolean=false</code>, or <code>my_integer=37</code>, or <code>my_source=/home</code>.</p>
<p>Additional checking information can be provided for <code>int</code>, <code>list</code> or <code>string</code> type configuration strings.</p>
<p>For integers, either or both of a maximum or minimum value can be provided, so an error will result if the application attempts to set the value outside of the acceptable range:</p>
<div class="fragment"><div class="line">    <span class="comment">/*</span></div><div class="line"><span class="comment">     * Limit the number of devices to between 1 and 30; the default is 5.</span></div><div class="line"><span class="comment">     */</span></div><div class="line">    error_check(conn-&gt;configure_method(</div><div class="line">      conn, <span class="stringliteral">&quot;WT_SESSION.open_cursor&quot;</span>, NULL, <span class="stringliteral">&quot;devices=5&quot;</span>, <span class="stringliteral">&quot;int&quot;</span>, <span class="stringliteral">&quot;min=1, max=30&quot;</span>));</div></div><!-- fragment --><p> For lists and strings, a set of valid choices can also be provided, so an error will result if the application attempts to set the value to a string not listed as a valid choice:</p>
<div class="fragment"><div class="line">    <span class="comment">/*</span></div><div class="line"><span class="comment">     * Limit the target string to one of /device, /home or /target; default to /home.</span></div><div class="line"><span class="comment">     */</span></div><div class="line">    error_check(conn-&gt;configure_method(conn, <span class="stringliteral">&quot;WT_SESSION.open_cursor&quot;</span>, NULL, <span class="stringliteral">&quot;target=/home&quot;</span>,</div><div class="line">      <span class="stringliteral">&quot;string&quot;</span>, <span class="stringliteral">&quot;choices=[/device, /home, /target]&quot;</span>));</div></div><!-- fragment --><div class="fragment"><div class="line">    <span class="comment">/*</span></div><div class="line"><span class="comment">     * Limit the paths list to one or more of /device, /home, /mnt or</span></div><div class="line"><span class="comment">     * /target; default to /mnt.</span></div><div class="line"><span class="comment">     */</span></div><div class="line">    error_check(conn-&gt;configure_method(conn, <span class="stringliteral">&quot;WT_SESSION.open_cursor&quot;</span>, NULL, <span class="stringliteral">&quot;paths=[/mnt]&quot;</span>, <span class="stringliteral">&quot;list&quot;</span>,</div><div class="line">      <span class="stringliteral">&quot;choices=[/device, /home, /mnt, /target]&quot;</span>));</div></div><!-- fragment --> <h1><a class="anchor" id="custom_ds_cursor_collator"></a>
WT_COLLATOR</h1>
<p>Custom data sources do not support custom ordering of records, and attempting to create a custom data source with a collator configured will fail.</p>
<h1><a class="anchor" id="custom_data_source_cursor_serialize"></a>
Serialization</h1>
<p>WiredTiger does not serialize calls to the <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html" title="Applications can extend WiredTiger by providing new implementations of the WT_DATA_SOURCE class...">WT_DATA_SOURCE</a> methods or to cursor methods configured by <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html#a81e45e31dedcdeaf8ff970d3c118da2e" title="Callback to initialize a cursor. ">WT_DATA_SOURCE::open_cursor</a>, and the methods may be called from multiple threads concurrently. It is the responsibility of the implementation to protect any shared data. For example, object operations such as <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html#a4569fa21343c2681357dedb4dd5facc1" title="Callback to drop an object. ">WT_DATA_SOURCE::drop</a> might not be permitted while there are open cursors for the <a class="el" href="struct_w_t___d_a_t_a___s_o_u_r_c_e.html" title="Applications can extend WiredTiger by providing new implementations of the WT_DATA_SOURCE class...">WT_DATA_SOURCE</a> object. </p>
</div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="navelem"><a class="el" href="index.html">Reference Guide</a></li><li class="navelem"><a class="el" href="programming.html">Writing WiredTiger applications</a></li>
    <li class="footer">Copyright (c) 2008-2019 MongoDB, Inc.  All rights reserved.  Contact <a href="mailto:info@wiredtiger.com">info@wiredtiger.com</a> for more information.</li>
  </ul>
</div>
</body>
</html>