dbmlite3 1.0.a1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,203 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>
7
+ File: README
8
+
9
+ &mdash; Documentation by YARD 0.9.25
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" />
16
+
17
+ <script type="text/javascript">
18
+ pathId = "README";
19
+ relpath = '';
20
+ </script>
21
+
22
+
23
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
24
+
25
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
26
+
27
+
28
+ </head>
29
+ <body>
30
+ <div class="nav_wrap">
31
+ <iframe id="nav" src="file_list.html?1"></iframe>
32
+ <div id="resizer"></div>
33
+ </div>
34
+
35
+ <div id="main" tabindex="-1">
36
+ <div id="header">
37
+ <div id="menu">
38
+
39
+ <a href="_index.html">Index</a> &raquo;
40
+ <span class="title">File: README</span>
41
+
42
+ </div>
43
+
44
+ <div id="search">
45
+
46
+ <a class="full_list_link" id="class_list_link"
47
+ href="class_list.html">
48
+
49
+ <svg width="24" height="24">
50
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
51
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
52
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
53
+ </svg>
54
+ </a>
55
+
56
+ </div>
57
+ <div class="clear"></div>
58
+ </div>
59
+
60
+ <div id="content"><div id='filecontents'><h1 id="simple-dbm-style-key-value-database-using-sqlite3">Simple DBM-style key-value database using SQLite3</h1>
61
+
62
+ <h2 id="description">Description</h2>
63
+
64
+ <p><code>dbmlite3</code> is a simple key-value store built on top of SQLite3 that
65
+ provides a Hash-like interface. It is a drop-in replacement for <code>DBM</code>
66
+ or <code>YAML::DBM</code> that uses SQLite3 to do the underlying storage.</p>
67
+
68
+ <h2 id="why">Why?</h2>
69
+
70
+ <p>Because DBM is really simple and SQLite3 is solid, reliable,
71
+ ubiquitous, and file-format-compatible across all platforms. This gem
72
+ gives you the best of both worlds.</p>
73
+
74
+ <h2 id="synopsis">Synopsis</h2>
75
+
76
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>dbmlite3</span><span class='tstring_end'>&#39;</span></span>
77
+
78
+ <span class='comment'># Open a table in a database
79
+ </span><span class='id identifier rubyid_settings'>settings</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Lite3.html" title="Lite3 (module)">Lite3</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Lite3/DBM.html" title="Lite3::DBM (class)">DBM</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Lite3/DBM.html#initialize-instance_method" title="Lite3::DBM#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>config.sqlite3</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>settings</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span>
80
+
81
+ <span class='comment'># You use it like a hash
82
+ </span><span class='id identifier rubyid_settings'>settings</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>speed</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='int'>88</span>
83
+ <span class='id identifier rubyid_settings'>settings</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>date</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='const'>Date</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='lparen'>(</span><span class='int'>1955</span><span class='comma'>,</span> <span class='int'>11</span><span class='comma'>,</span> <span class='int'>5</span><span class='rparen'>)</span> <span class='comment'># Normal Ruby values are allowed
84
+ </span><span class='id identifier rubyid_settings'>settings</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>power_threshold</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='float'>2.2</span>
85
+
86
+ <span class='id identifier rubyid_puts'>puts</span> <span class='id identifier rubyid_settings'>settings</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>power_threshold</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span>
87
+
88
+ <span class='id identifier rubyid_settings'>settings</span><span class='period'>.</span><span class='id identifier rubyid_each'>each</span><span class='lbrace'>{</span><span class='op'>|</span><span class='id identifier rubyid_k'>k</span><span class='comma'>,</span><span class='id identifier rubyid_v'>v</span><span class='op'>|</span> <span class='id identifier rubyid_puts'>puts</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>setting: </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_k'>k</span><span class='embexpr_end'>}</span><span class='tstring_content'> = </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_v'>v</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span> <span class='rbrace'>}</span>
89
+
90
+ <span class='comment'># But you also have transactions
91
+ </span><span class='id identifier rubyid_settings'>settings</span><span class='period'>.</span><span class='id identifier rubyid_transaction'>transaction</span><span class='lbrace'>{</span>
92
+ <span class='id identifier rubyid_settings'>settings</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>speed</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='id identifier rubyid_settings'>settings</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>speed</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>*</span> <span class='int'>2</span>
93
+ <span class='rbrace'>}</span>
94
+
95
+ <span class='comment'># You can open other tables in the same database if you want, as above
96
+ </span><span class='comment'># or with a block
97
+ </span><span class='const'><span class='object_link'><a href="Lite3.html" title="Lite3 (module)">Lite3</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Lite3/DBM.html" title="Lite3::DBM (class)">DBM</a></span></span><span class='period'>.</span><span class='id identifier rubyid_open'><span class='object_link'><a href="Lite3/DBM.html#open-class_method" title="Lite3::DBM.open (method)">open</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>config.sqlite3</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>stats</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_stats'>stats</span><span class='op'>|</span>
98
+ <span class='id identifier rubyid_stats'>stats</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>max</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='int'>42</span>
99
+
100
+ <span class='comment'># You can even open multiple handles to the same table if you need to
101
+ </span> <span class='const'><span class='object_link'><a href="Lite3.html" title="Lite3 (module)">Lite3</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Lite3/DBM.html" title="Lite3::DBM (class)">DBM</a></span></span><span class='period'>.</span><span class='id identifier rubyid_open'><span class='object_link'><a href="Lite3/DBM.html#open-class_method" title="Lite3::DBM.open (method)">open</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>config.sqlite3</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>stats</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_stats2'>stats2</span><span class='op'>|</span>
102
+ <span class='id identifier rubyid_stats2'>stats2</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>max</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>+=</span> <span class='int'>1</span>
103
+ <span class='rbrace'>}</span>
104
+
105
+ <span class='id identifier rubyid_puts'>puts</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>stats=</span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_stats'>stats</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>max</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span>
106
+ <span class='rbrace'>}</span>
107
+
108
+ <span class='id identifier rubyid_settings'>settings</span><span class='period'>.</span><span class='id identifier rubyid_close'>close</span>
109
+ </code></pre>
110
+
111
+ <p>Complete documentation is available in the accompanying rdoc.</p>
112
+
113
+ <h2 id="installation">Installation</h2>
114
+
115
+ <p><code>dbmlite3</code> is available as a gem:</p>
116
+
117
+ <pre class="code ruby"><code class="ruby">$ [sudo] gem install dbmlite3
118
+ </code></pre>
119
+
120
+ <p>Alternately, you can fetch the source code from GitLab and build it yourself:</p>
121
+
122
+ <pre class="code ruby"><code class="ruby">$ git clone https://gitlab.com/suetanvil/dbmlite3
123
+ $ cd dbmlite3
124
+ $ rake
125
+ </code></pre>
126
+
127
+ <p>Obviously, it depends on the gem <code>sqlite3</code>.</p>
128
+
129
+ <h2 id="quirks-and-hints">Quirks and Hints</h2>
130
+
131
+ <h3 id="remember-that-a-dbm-is-a-potentially-shared-file">Remember that a <code>DBM</code> is a (potentially) shared file</h3>
132
+
133
+ <p>It is important to keep in mind that while <code>Lite3::DBM</code> objects
134
+ look like Hashes, they are accessing files on disk that other
135
+ processes could modify at any time.</p>
136
+
137
+ <p>For example, an innocuous-looking expression like </p>
138
+
139
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_db'>db</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>foo</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='id identifier rubyid_db'>db</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>foo</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>+</span> <span class='int'>1</span>
140
+ </code></pre>
141
+
142
+ <p>or its shorter equivalent</p>
143
+
144
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_db'>db</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>foo</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>+=</span> <span class='int'>1</span>
145
+ </code></pre>
146
+
147
+ <p>contains a race condition. If (e.g.) two copies of this script are
148
+ running at the same time, it is possible for both to perform the read
149
+ before one of them writes, losing the others&#39; result.</p>
150
+
151
+ <p>There are two ways to deal with this. You can wrap the
152
+ read-modify-write cycle in a transaction:</p>
153
+
154
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_db'>db</span><span class='period'>.</span><span class='id identifier rubyid_transaction'>transaction</span> <span class='lbrace'>{</span> <span class='id identifier rubyid_db'>db</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>foo</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>+=</span> <span class='int'>1</span> <span class='rbrace'>}</span>
155
+ </code></pre>
156
+
157
+ <p>Or, of course, you could just design your script or program so that
158
+ only one program accesses the table at a time.</p>
159
+
160
+ <h3 id="transactions-and-performance">Transactions and performance</h3>
161
+
162
+ <p>If you need to do a large number of accesses in a short amount of
163
+ time (e.g. loading data from a file), it is significantly faster to
164
+ do these in batches in one or more transactions.</p>
165
+
166
+ <h3 id="forking-safely">Forking safely</h3>
167
+
168
+ <p>It is a documented limitation of SQLite3 that database objects
169
+ cannot be carried across a process fork. Either the parent or the
170
+ child process will keep the open handle and the other one must
171
+ forget it completely.</p>
172
+
173
+ <p>For this reason, if you need both the parent and child process to
174
+ be able to use <code>Lite3::DBM</code> after a <code>fork</code>, you must first call
175
+ <code>Lite3::SQL.close_all</code>. Not only will this make it safe but it
176
+ also lets the child and parent use the same <code>Lite3::DBM</code> objects.</p>
177
+
178
+ <h3 id="lite3-dbm-objects-act-like-file-handles-but-are-not"><code>Lite3::DBM</code> objects act like file handles but are not</h3>
179
+
180
+ <p>While it is generally safe to treat <code>Lite3::DBM</code> as a wrapper
181
+ around file handle (i.e. <code>open</code> and <code>close</code> work as expected), you
182
+ should be aware that this is not precisely the way things
183
+ actually work. Instead, the gem maintains a pool of database
184
+ handles, one per file, and associates them with <code>Lite3::DBM</code>
185
+ instances as needed. This is necessary for transactions to work
186
+ correctly.</p>
187
+
188
+ <p>See the reference doc for <code>Lite3::SQL</code> for more details.</p>
189
+
190
+ <p>Mostly, you don&#39;t need to worry about this but certain types of
191
+ bugs could behave in unexpected ways and knowing this may help you
192
+ make sense of them.</p>
193
+ </div></div>
194
+
195
+ <div id="footer">
196
+ Generated on Fri Feb 25 14:42:43 2022 by
197
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
198
+ 0.9.25 (ruby-2.7.0).
199
+ </div>
200
+
201
+ </div>
202
+ </body>
203
+ </html>
@@ -0,0 +1,56 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
5
+ <meta charset="utf-8" />
6
+
7
+ <link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen" />
8
+
9
+ <link rel="stylesheet" href="css/common.css" type="text/css" media="screen" />
10
+
11
+
12
+
13
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
14
+
15
+ <script type="text/javascript" charset="utf-8" src="js/full_list.js"></script>
16
+
17
+
18
+ <title>File List</title>
19
+ <base id="base_target" target="_parent" />
20
+ </head>
21
+ <body>
22
+ <div id="content">
23
+ <div class="fixed_header">
24
+ <h1 id="full_list_header">File List</h1>
25
+ <div id="full_list_nav">
26
+
27
+ <span><a target="_self" href="class_list.html">
28
+ Classes
29
+ </a></span>
30
+
31
+ <span><a target="_self" href="method_list.html">
32
+ Methods
33
+ </a></span>
34
+
35
+ <span><a target="_self" href="file_list.html">
36
+ Files
37
+ </a></span>
38
+
39
+ </div>
40
+
41
+ <div id="search">Search: <input type="text" /></div>
42
+ </div>
43
+
44
+ <ul id="full_list" class="file">
45
+
46
+
47
+ <li id="object_README" class="odd">
48
+ <div class="item"><span class="object_link"><a href="index.html" title="README">README</a></span></div>
49
+ </li>
50
+
51
+
52
+
53
+ </ul>
54
+ </div>
55
+ </body>
56
+ </html>
data/doc/frames.html ADDED
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Documentation by YARD 0.9.25</title>
6
+ </head>
7
+ <script type="text/javascript">
8
+ var match = unescape(window.location.hash).match(/^#!(.+)/);
9
+ var name = match ? match[1] : 'index.html';
10
+ name = name.replace(/^(\w+):\/\//, '').replace(/^\/\//, '');
11
+ window.top.location = name;
12
+ </script>
13
+ <noscript>
14
+ <h1>Oops!</h1>
15
+ <h2>YARD requires JavaScript!</h2>
16
+ </noscript>
17
+ </html>
data/doc/index.html ADDED
@@ -0,0 +1,203 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>
7
+ File: README
8
+
9
+ &mdash; Documentation by YARD 0.9.25
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" />
16
+
17
+ <script type="text/javascript">
18
+ pathId = "README";
19
+ relpath = '';
20
+ </script>
21
+
22
+
23
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
24
+
25
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
26
+
27
+
28
+ </head>
29
+ <body>
30
+ <div class="nav_wrap">
31
+ <iframe id="nav" src="class_list.html?1"></iframe>
32
+ <div id="resizer"></div>
33
+ </div>
34
+
35
+ <div id="main" tabindex="-1">
36
+ <div id="header">
37
+ <div id="menu">
38
+
39
+ <a href="_index.html">Index</a> &raquo;
40
+ <span class="title">File: README</span>
41
+
42
+ </div>
43
+
44
+ <div id="search">
45
+
46
+ <a class="full_list_link" id="class_list_link"
47
+ href="class_list.html">
48
+
49
+ <svg width="24" height="24">
50
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
51
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
52
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
53
+ </svg>
54
+ </a>
55
+
56
+ </div>
57
+ <div class="clear"></div>
58
+ </div>
59
+
60
+ <div id="content"><div id='filecontents'><h1 id="simple-dbm-style-key-value-database-using-sqlite3">Simple DBM-style key-value database using SQLite3</h1>
61
+
62
+ <h2 id="description">Description</h2>
63
+
64
+ <p><code>dbmlite3</code> is a simple key-value store built on top of SQLite3 that
65
+ provides a Hash-like interface. It is a drop-in replacement for <code>DBM</code>
66
+ or <code>YAML::DBM</code> that uses SQLite3 to do the underlying storage.</p>
67
+
68
+ <h2 id="why">Why?</h2>
69
+
70
+ <p>Because DBM is really simple and SQLite3 is solid, reliable,
71
+ ubiquitous, and file-format-compatible across all platforms. This gem
72
+ gives you the best of both worlds.</p>
73
+
74
+ <h2 id="synopsis">Synopsis</h2>
75
+
76
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>dbmlite3</span><span class='tstring_end'>&#39;</span></span>
77
+
78
+ <span class='comment'># Open a table in a database
79
+ </span><span class='id identifier rubyid_settings'>settings</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Lite3.html" title="Lite3 (module)">Lite3</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Lite3/DBM.html" title="Lite3::DBM (class)">DBM</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Lite3/DBM.html#initialize-instance_method" title="Lite3::DBM#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>config.sqlite3</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>settings</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span>
80
+
81
+ <span class='comment'># You use it like a hash
82
+ </span><span class='id identifier rubyid_settings'>settings</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>speed</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='int'>88</span>
83
+ <span class='id identifier rubyid_settings'>settings</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>date</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='const'>Date</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='lparen'>(</span><span class='int'>1955</span><span class='comma'>,</span> <span class='int'>11</span><span class='comma'>,</span> <span class='int'>5</span><span class='rparen'>)</span> <span class='comment'># Normal Ruby values are allowed
84
+ </span><span class='id identifier rubyid_settings'>settings</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>power_threshold</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='float'>2.2</span>
85
+
86
+ <span class='id identifier rubyid_puts'>puts</span> <span class='id identifier rubyid_settings'>settings</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>power_threshold</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span>
87
+
88
+ <span class='id identifier rubyid_settings'>settings</span><span class='period'>.</span><span class='id identifier rubyid_each'>each</span><span class='lbrace'>{</span><span class='op'>|</span><span class='id identifier rubyid_k'>k</span><span class='comma'>,</span><span class='id identifier rubyid_v'>v</span><span class='op'>|</span> <span class='id identifier rubyid_puts'>puts</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>setting: </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_k'>k</span><span class='embexpr_end'>}</span><span class='tstring_content'> = </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_v'>v</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span> <span class='rbrace'>}</span>
89
+
90
+ <span class='comment'># But you also have transactions
91
+ </span><span class='id identifier rubyid_settings'>settings</span><span class='period'>.</span><span class='id identifier rubyid_transaction'>transaction</span><span class='lbrace'>{</span>
92
+ <span class='id identifier rubyid_settings'>settings</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>speed</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='id identifier rubyid_settings'>settings</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>speed</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>*</span> <span class='int'>2</span>
93
+ <span class='rbrace'>}</span>
94
+
95
+ <span class='comment'># You can open other tables in the same database if you want, as above
96
+ </span><span class='comment'># or with a block
97
+ </span><span class='const'><span class='object_link'><a href="Lite3.html" title="Lite3 (module)">Lite3</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Lite3/DBM.html" title="Lite3::DBM (class)">DBM</a></span></span><span class='period'>.</span><span class='id identifier rubyid_open'><span class='object_link'><a href="Lite3/DBM.html#open-class_method" title="Lite3::DBM.open (method)">open</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>config.sqlite3</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>stats</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_stats'>stats</span><span class='op'>|</span>
98
+ <span class='id identifier rubyid_stats'>stats</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>max</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='int'>42</span>
99
+
100
+ <span class='comment'># You can even open multiple handles to the same table if you need to
101
+ </span> <span class='const'><span class='object_link'><a href="Lite3.html" title="Lite3 (module)">Lite3</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Lite3/DBM.html" title="Lite3::DBM (class)">DBM</a></span></span><span class='period'>.</span><span class='id identifier rubyid_open'><span class='object_link'><a href="Lite3/DBM.html#open-class_method" title="Lite3::DBM.open (method)">open</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>config.sqlite3</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>stats</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_stats2'>stats2</span><span class='op'>|</span>
102
+ <span class='id identifier rubyid_stats2'>stats2</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>max</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>+=</span> <span class='int'>1</span>
103
+ <span class='rbrace'>}</span>
104
+
105
+ <span class='id identifier rubyid_puts'>puts</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>stats=</span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_stats'>stats</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>max</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span>
106
+ <span class='rbrace'>}</span>
107
+
108
+ <span class='id identifier rubyid_settings'>settings</span><span class='period'>.</span><span class='id identifier rubyid_close'>close</span>
109
+ </code></pre>
110
+
111
+ <p>Complete documentation is available in the accompanying rdoc.</p>
112
+
113
+ <h2 id="installation">Installation</h2>
114
+
115
+ <p><code>dbmlite3</code> is available as a gem:</p>
116
+
117
+ <pre class="code ruby"><code class="ruby">$ [sudo] gem install dbmlite3
118
+ </code></pre>
119
+
120
+ <p>Alternately, you can fetch the source code from GitLab and build it yourself:</p>
121
+
122
+ <pre class="code ruby"><code class="ruby">$ git clone https://gitlab.com/suetanvil/dbmlite3
123
+ $ cd dbmlite3
124
+ $ rake
125
+ </code></pre>
126
+
127
+ <p>Obviously, it depends on the gem <code>sqlite3</code>.</p>
128
+
129
+ <h2 id="quirks-and-hints">Quirks and Hints</h2>
130
+
131
+ <h3 id="remember-that-a-dbm-is-a-potentially-shared-file">Remember that a <code>DBM</code> is a (potentially) shared file</h3>
132
+
133
+ <p>It is important to keep in mind that while <code>Lite3::DBM</code> objects
134
+ look like Hashes, they are accessing files on disk that other
135
+ processes could modify at any time.</p>
136
+
137
+ <p>For example, an innocuous-looking expression like </p>
138
+
139
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_db'>db</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>foo</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='id identifier rubyid_db'>db</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>foo</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>+</span> <span class='int'>1</span>
140
+ </code></pre>
141
+
142
+ <p>or its shorter equivalent</p>
143
+
144
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_db'>db</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>foo</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>+=</span> <span class='int'>1</span>
145
+ </code></pre>
146
+
147
+ <p>contains a race condition. If (e.g.) two copies of this script are
148
+ running at the same time, it is possible for both to perform the read
149
+ before one of them writes, losing the others&#39; result.</p>
150
+
151
+ <p>There are two ways to deal with this. You can wrap the
152
+ read-modify-write cycle in a transaction:</p>
153
+
154
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_db'>db</span><span class='period'>.</span><span class='id identifier rubyid_transaction'>transaction</span> <span class='lbrace'>{</span> <span class='id identifier rubyid_db'>db</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>foo</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>+=</span> <span class='int'>1</span> <span class='rbrace'>}</span>
155
+ </code></pre>
156
+
157
+ <p>Or, of course, you could just design your script or program so that
158
+ only one program accesses the table at a time.</p>
159
+
160
+ <h3 id="transactions-and-performance">Transactions and performance</h3>
161
+
162
+ <p>If you need to do a large number of accesses in a short amount of
163
+ time (e.g. loading data from a file), it is significantly faster to
164
+ do these in batches in one or more transactions.</p>
165
+
166
+ <h3 id="forking-safely">Forking safely</h3>
167
+
168
+ <p>It is a documented limitation of SQLite3 that database objects
169
+ cannot be carried across a process fork. Either the parent or the
170
+ child process will keep the open handle and the other one must
171
+ forget it completely.</p>
172
+
173
+ <p>For this reason, if you need both the parent and child process to
174
+ be able to use <code>Lite3::DBM</code> after a <code>fork</code>, you must first call
175
+ <code>Lite3::SQL.close_all</code>. Not only will this make it safe but it
176
+ also lets the child and parent use the same <code>Lite3::DBM</code> objects.</p>
177
+
178
+ <h3 id="lite3-dbm-objects-act-like-file-handles-but-are-not"><code>Lite3::DBM</code> objects act like file handles but are not</h3>
179
+
180
+ <p>While it is generally safe to treat <code>Lite3::DBM</code> as a wrapper
181
+ around file handle (i.e. <code>open</code> and <code>close</code> work as expected), you
182
+ should be aware that this is not precisely the way things
183
+ actually work. Instead, the gem maintains a pool of database
184
+ handles, one per file, and associates them with <code>Lite3::DBM</code>
185
+ instances as needed. This is necessary for transactions to work
186
+ correctly.</p>
187
+
188
+ <p>See the reference doc for <code>Lite3::SQL</code> for more details.</p>
189
+
190
+ <p>Mostly, you don&#39;t need to worry about this but certain types of
191
+ bugs could behave in unexpected ways and knowing this may help you
192
+ make sense of them.</p>
193
+ </div></div>
194
+
195
+ <div id="footer">
196
+ Generated on Fri Feb 25 14:42:43 2022 by
197
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
198
+ 0.9.25 (ruby-2.7.0).
199
+ </div>
200
+
201
+ </div>
202
+ </body>
203
+ </html>