dbmlite3 1.0.a2 → 1.0.a5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4ddbc3278920ee6c02257bd8474f8f2951d91e9b4f5177eca10b8ce4b5985c5b
4
- data.tar.gz: 29ad35623686c94edf33e4dfe8dc7b4086119da4d66562dcb50fd73a1ccc1276
3
+ metadata.gz: 7697155e6f50eba81b90d74a4fbf18e8fbcbf0d5058f809a88937a13e4e0f16d
4
+ data.tar.gz: 9bb6679468e6d9c60df4dc5f0e90a43babc3a910bdb0145d8663d9664ab542f4
5
5
  SHA512:
6
- metadata.gz: 4ad0e0651a960c4a06795c81e036c7b933d4ab1d1d7e5fa982bf441fef07b6a8ad606183a4f84961647f77b6c7a15ee1300de7ed726c62209c46e4d0863a0b3e
7
- data.tar.gz: 71855d036e0f5fe458568e7e14125adfbe992a86c231b79be1750ef8fabc4e7dda297b1eaedbba1fd24a4ddc1e83caf104fa59cc36e70315339fff0e018d9f21
6
+ metadata.gz: a9b0750ce7d670c1103ed74da2293d60589b61adcf81fcd3ea26c351e3e5a6810b42c4e8c1d26cafc9abcb6f96b8074f545f0bdbe129e7d0e97fb8a75f2155e3
7
+ data.tar.gz: 7aac44f9d3ca015220dc46525b58b1338e71e7873956b5f2a1feb99bfd118ad46b3e28e4134c75234a37e7f58fb6d3ffb6d8d936c6db868b4eb68efd3f5d918a
@@ -3,7 +3,7 @@
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'dbmlite3'
6
- s.version = '1.0.a2'
6
+ s.version = '1.0.a5'
7
7
  s.date = '2022-02-21'
8
8
  s.summary = "A DBM-style key-value store using SQLite3"
9
9
  s.description = <<-EOF
@@ -21,7 +21,7 @@ EOF
21
21
 
22
22
  # I'm just going to add everything so that if you've got the gem,
23
23
  # you've also got the source distribution. Yay! Open source!
24
- s.files = ["README.md", "LICENSE.txt", "DBMLite3.gemspec",
24
+ s.files = ["README.md", "LICENSE.txt", "dbmlite3.gemspec",
25
25
  "Rakefile", ".yardopts"] +
26
26
  Dir.glob('doc/**/*') +
27
27
  Dir.glob('{spec,lib}/*.rb')
@@ -34,6 +34,6 @@ EOF
34
34
  s.add_development_dependency "rspec", '~> 3.10', '>= 3.10.0'
35
35
  s.add_development_dependency "yard", '~> 0.9.25', '>= 0.9.25'
36
36
 
37
- s.homepage = 'https://codeberg.org/suetanvil/dbmlite3-ruby'
37
+ s.homepage = 'https://codeberg.org/suetanvil/dbmlite'
38
38
  s.license = 'MIT'
39
39
  end
data/doc/Lite3/DBM.html CHANGED
@@ -1086,12 +1086,12 @@ nil if it is not present.</p>
1086
1086
  <pre class="lines">
1087
1087
 
1088
1088
 
1089
- 615
1090
- 616
1091
- 617</pre>
1089
+ 644
1090
+ 645
1091
+ 646</pre>
1092
1092
  </td>
1093
1093
  <td>
1094
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 615</span>
1094
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 644</span>
1095
1095
 
1096
1096
  <span class='kw'>def</span> <span class='op'>[]</span><span class='lparen'>(</span><span class='id identifier rubyid_key'>key</span><span class='rparen'>)</span>
1097
1097
  <span class='kw'>return</span> <span class='id identifier rubyid_fetch'>fetch</span><span class='lparen'>(</span><span class='id identifier rubyid_key'>key</span><span class='comma'>,</span> <span class='kw'>nil</span><span class='rparen'>)</span>
@@ -1148,7 +1148,36 @@ serialization method you have chosen.</p>
1148
1148
  607
1149
1149
  608
1150
1150
  609
1151
- 610</pre>
1151
+ 610
1152
+ 611
1153
+ 612
1154
+ 613
1155
+ 614
1156
+ 615
1157
+ 616
1158
+ 617
1159
+ 618
1160
+ 619
1161
+ 620
1162
+ 621
1163
+ 622
1164
+ 623
1165
+ 624
1166
+ 625
1167
+ 626
1168
+ 627
1169
+ 628
1170
+ 629
1171
+ 630
1172
+ 631
1173
+ 632
1174
+ 633
1175
+ 634
1176
+ 635
1177
+ 636
1178
+ 637
1179
+ 638
1180
+ 639</pre>
1152
1181
  </td>
1153
1182
  <td>
1154
1183
  <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 597</span>
@@ -1157,12 +1186,41 @@ serialization method you have chosen.</p>
1157
1186
  <span class='id identifier rubyid_key'>key</span> <span class='op'>=</span> <span class='id identifier rubyid_check_key'>check_key</span><span class='lparen'>(</span><span class='id identifier rubyid_key'>key</span><span class='rparen'>)</span>
1158
1187
  <span class='id identifier rubyid_valstr'>valstr</span> <span class='op'>=</span> <span class='const'>SQLite3</span><span class='op'>::</span><span class='const'>Blob</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='lparen'>(</span> <span class='ivar'>@valenc</span><span class='period'>.</span><span class='id identifier rubyid_call'>call</span><span class='lparen'>(</span><span class='id identifier rubyid_value'>value</span><span class='rparen'>)</span> <span class='rparen'>)</span>
1159
1188
 
1160
- <span class='id identifier rubyid_insert'>insert</span> <span class='op'>=</span> <span class='heredoc_beg'>&lt;&lt;~SQL</span>
1161
- <span class='tstring_content'> insert into </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_actual_tbl'>actual_tbl</span><span class='embexpr_end'>}</span><span class='tstring_content'> (key, value) values (?,?)
1162
- </span><span class='tstring_content'> on conflict(key) do update set value = ?;
1163
- </span><span class='heredoc_end'> SQL
1189
+ <span class='comment'># At one point, this operation was done with SQLite3&#39;s UPSERT:
1190
+ </span> <span class='comment'>#
1191
+ </span> <span class='comment'># insert into #{actual_tbl} (key, value) values (?,?)
1192
+ </span> <span class='comment'># on conflict(key) do update set value = ?;
1193
+ </span> <span class='comment'>#
1194
+ </span> <span class='comment'># Unfortunately, this capability was only added to SQLite3 in
1195
+ </span> <span class='comment'># 2018, which means that at the time of this writing (2022)
1196
+ </span> <span class='comment'># there are still a lot of systems out there that have older
1197
+ </span> <span class='comment'># versions of SQLite3 and so can&#39;t do this.
1198
+ </span> <span class='comment'>#
1199
+ </span> <span class='comment'># The venerable `insert or replace` feature **almost** does what
1200
+ </span> <span class='comment'># I want:
1201
+ </span> <span class='comment'>#
1202
+ </span> <span class='comment'># insert or replace into #{actual_tbl} (key, value) values (?, ?);
1203
+ </span> <span class='comment'>#
1204
+ </span> <span class='comment'># The one problem is that it changes the order of the rows,
1205
+ </span> <span class='comment'># which we need to preserve in order to remain consistent with
1206
+ </span> <span class='comment'># `Hash` semantics (and because it&#39;s useful).
1207
+ </span> <span class='comment'>#
1208
+ </span> <span class='comment'># So we kick it old school and do a `select` followed by an
1209
+ </span> <span class='comment'># `insert` or `update` wrapped in a transaction.
1164
1210
  </span> <span class='id identifier rubyid_transaction'>transaction</span> <span class='lbrace'>{</span>
1165
- <span class='ivar'>@handle</span><span class='period'>.</span><span class='id identifier rubyid_sql'>sql</span><span class='lparen'>(</span><span class='id identifier rubyid_insert'>insert</span><span class='comma'>,</span> <span class='lbracket'>[</span><span class='id identifier rubyid_key'>key</span><span class='comma'>,</span> <span class='id identifier rubyid_valstr'>valstr</span><span class='comma'>,</span> <span class='id identifier rubyid_valstr'>valstr</span><span class='rbracket'>]</span><span class='rparen'>)</span>
1211
+ <span class='id identifier rubyid_rowid'>rowid</span> <span class='op'>=</span> <span class='kw'>nil</span>
1212
+ <span class='id identifier rubyid_select'>select</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>select rowid, key, value from </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_actual_tbl'>actual_tbl</span><span class='embexpr_end'>}</span><span class='tstring_content'> where key = ?;</span><span class='tstring_end'>&quot;</span></span>
1213
+ <span class='ivar'>@handle</span><span class='period'>.</span><span class='id identifier rubyid_sql'>sql</span><span class='lparen'>(</span><span class='id identifier rubyid_select'>select</span><span class='comma'>,</span> <span class='lbracket'>[</span><span class='id identifier rubyid_key'>key</span><span class='rbracket'>]</span><span class='rparen'>)</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_row'>row</span><span class='op'>|</span>
1214
+ <span class='id identifier rubyid_rowid'>rowid</span> <span class='op'>=</span> <span class='id identifier rubyid_row'>row</span><span class='lbracket'>[</span><span class='int'>0</span><span class='rbracket'>]</span>
1215
+ <span class='rbrace'>}</span>
1216
+
1217
+ <span class='kw'>if</span> <span class='id identifier rubyid_rowid'>rowid</span>
1218
+ <span class='id identifier rubyid_update'>update</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>update </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_actual_tbl'>actual_tbl</span><span class='embexpr_end'>}</span><span class='tstring_content'> set value = ? where rowid = ?;</span><span class='tstring_end'>&quot;</span></span>
1219
+ <span class='ivar'>@handle</span><span class='period'>.</span><span class='id identifier rubyid_sql'>sql</span><span class='lparen'>(</span><span class='id identifier rubyid_update'>update</span><span class='comma'>,</span> <span class='lbracket'>[</span><span class='id identifier rubyid_valstr'>valstr</span><span class='comma'>,</span> <span class='id identifier rubyid_rowid'>rowid</span><span class='rbracket'>]</span><span class='rparen'>)</span>
1220
+ <span class='kw'>else</span>
1221
+ <span class='id identifier rubyid_insert'>insert</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>insert into </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_actual_tbl'>actual_tbl</span><span class='embexpr_end'>}</span><span class='tstring_content'> (key, value) values (?,?);</span><span class='tstring_end'>&quot;</span></span>
1222
+ <span class='ivar'>@handle</span><span class='period'>.</span><span class='id identifier rubyid_sql'>sql</span><span class='lparen'>(</span><span class='id identifier rubyid_insert'>insert</span><span class='comma'>,</span> <span class='lbracket'>[</span><span class='id identifier rubyid_key'>key</span><span class='comma'>,</span> <span class='id identifier rubyid_valstr'>valstr</span><span class='rbracket'>]</span><span class='rparen'>)</span>
1223
+ <span class='kw'>end</span>
1166
1224
  <span class='rbrace'>}</span>
1167
1225
 
1168
1226
  <span class='kw'>return</span> <span class='id identifier rubyid_value'>value</span>
@@ -1197,12 +1255,12 @@ serialization method you have chosen.</p>
1197
1255
  <pre class="lines">
1198
1256
 
1199
1257
 
1200
- 699
1201
- 700
1202
- 701</pre>
1258
+ 728
1259
+ 729
1260
+ 730</pre>
1203
1261
  </td>
1204
1262
  <td>
1205
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 699</span>
1263
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 728</span>
1206
1264
 
1207
1265
  <span class='kw'>def</span> <span class='id identifier rubyid_clear'>clear</span>
1208
1266
  <span class='id identifier rubyid_transaction'>transaction</span> <span class='lbrace'>{</span> <span class='ivar'>@handle</span><span class='period'>.</span><span class='id identifier rubyid_sql'>sql</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>delete from </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_actual_tbl'>actual_tbl</span><span class='embexpr_end'>}</span><span class='tstring_content'>;</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='lbracket'>[</span><span class='rbracket'>]</span><span class='rparen'>)</span> <span class='rbrace'>}</span>
@@ -1339,14 +1397,14 @@ not present, does nothing.</p>
1339
1397
  <pre class="lines">
1340
1398
 
1341
1399
 
1342
- 788
1343
- 789
1344
- 790
1345
- 791
1346
- 792</pre>
1400
+ 817
1401
+ 818
1402
+ 819
1403
+ 820
1404
+ 821</pre>
1347
1405
  </td>
1348
1406
  <td>
1349
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 788</span>
1407
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 817</span>
1350
1408
 
1351
1409
  <span class='kw'>def</span> <span class='id identifier rubyid_delete'>delete</span><span class='lparen'>(</span><span class='id identifier rubyid_key'>key</span><span class='rparen'>)</span>
1352
1410
  <span class='id identifier rubyid_transaction'>transaction</span> <span class='lbrace'>{</span>
@@ -1405,14 +1463,14 @@ each entry for which the block returns true.</p>
1405
1463
  <pre class="lines">
1406
1464
 
1407
1465
 
1408
- 798
1409
- 799
1410
- 800
1411
- 801
1412
- 802</pre>
1466
+ 827
1467
+ 828
1468
+ 829
1469
+ 830
1470
+ 831</pre>
1413
1471
  </td>
1414
1472
  <td>
1415
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 798</span>
1473
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 827</span>
1416
1474
 
1417
1475
  <span class='kw'>def</span> <span class='id identifier rubyid_delete_if'>delete_if</span><span class='lparen'>(</span><span class='op'>&amp;</span><span class='id identifier rubyid_block'>block</span><span class='rparen'>)</span>
1418
1476
  <span class='id identifier rubyid_transaction'>transaction</span> <span class='lbrace'>{</span>
@@ -1477,14 +1535,14 @@ own transaction.</p>
1477
1535
  <pre class="lines">
1478
1536
 
1479
1537
 
1480
- 713
1481
- 714
1482
- 715
1483
- 716
1484
- 717</pre>
1538
+ 742
1539
+ 743
1540
+ 744
1541
+ 745
1542
+ 746</pre>
1485
1543
  </td>
1486
1544
  <td>
1487
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 713</span>
1545
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 742</span>
1488
1546
 
1489
1547
  <span class='kw'>def</span> <span class='id identifier rubyid_each'>each</span><span class='lparen'>(</span><span class='op'>&amp;</span><span class='id identifier rubyid_block'>block</span><span class='rparen'>)</span>
1490
1548
  <span class='kw'>return</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_to_enum'>to_enum</span><span class='lparen'>(</span><span class='symbol'>:nt_each</span><span class='rparen'>)</span> <span class='kw'>unless</span> <span class='id identifier rubyid_block'>block</span>
@@ -1539,13 +1597,13 @@ own transaction.</p>
1539
1597
  <pre class="lines">
1540
1598
 
1541
1599
 
1542
- 763
1543
- 764
1544
- 765
1545
- 766</pre>
1600
+ 792
1601
+ 793
1602
+ 794
1603
+ 795</pre>
1546
1604
  </td>
1547
1605
  <td>
1548
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 763</span>
1606
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 792</span>
1549
1607
 
1550
1608
  <span class='kw'>def</span> <span class='id identifier rubyid_each_key'>each_key</span><span class='lparen'>(</span><span class='op'>&amp;</span><span class='id identifier rubyid_block'>block</span><span class='rparen'>)</span>
1551
1609
  <span class='kw'>return</span> <span class='const'>Enumerator</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='lbrace'>{</span><span class='op'>|</span><span class='id identifier rubyid_y'>y</span><span class='op'>|</span> <span class='id identifier rubyid_nt_each'>nt_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_y'>y</span> <span class='op'>&lt;&lt;</span> <span class='id identifier rubyid_k'>k</span> <span class='rbrace'>}</span> <span class='rbrace'>}</span> <span class='kw'>unless</span> <span class='id identifier rubyid_block'>block</span>
@@ -1599,13 +1657,13 @@ own transaction.</p>
1599
1657
  <pre class="lines">
1600
1658
 
1601
1659
 
1602
- 772
1603
- 773
1604
- 774
1605
- 775</pre>
1660
+ 801
1661
+ 802
1662
+ 803
1663
+ 804</pre>
1606
1664
  </td>
1607
1665
  <td>
1608
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 772</span>
1666
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 801</span>
1609
1667
 
1610
1668
  <span class='kw'>def</span> <span class='id identifier rubyid_each_value'>each_value</span><span class='lparen'>(</span><span class='op'>&amp;</span><span class='id identifier rubyid_block'>block</span><span class='rparen'>)</span>
1611
1669
  <span class='kw'>return</span> <span class='const'>Enumerator</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='lbrace'>{</span><span class='op'>|</span><span class='id identifier rubyid_y'>y</span><span class='op'>|</span> <span class='id identifier rubyid_nt_each'>nt_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_y'>y</span> <span class='op'>&lt;&lt;</span> <span class='id identifier rubyid_v'>v</span> <span class='rbrace'>}</span> <span class='rbrace'>}</span> <span class='kw'>unless</span> <span class='id identifier rubyid_block'>block</span>
@@ -1654,12 +1712,12 @@ own transaction.</p>
1654
1712
  <pre class="lines">
1655
1713
 
1656
1714
 
1657
- 815
1658
- 816
1659
- 817</pre>
1715
+ 844
1716
+ 845
1717
+ 846</pre>
1660
1718
  </td>
1661
1719
  <td>
1662
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 815</span>
1720
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 844</span>
1663
1721
 
1664
1722
  <span class='kw'>def</span> <span class='id identifier rubyid_empty?'>empty?</span>
1665
1723
  <span class='kw'>return</span> <span class='id identifier rubyid_size'>size</span> <span class='op'>==</span> <span class='int'>0</span>
@@ -1735,36 +1793,36 @@ exception.</p>
1735
1793
  <pre class="lines">
1736
1794
 
1737
1795
 
1738
- 633
1739
- 634
1740
- 635
1741
- 636
1742
- 637
1743
- 638
1744
- 639
1745
- 640
1746
- 641
1747
- 642
1748
- 643
1749
- 644
1750
- 645
1751
- 646
1752
- 647
1753
- 648
1754
- 649
1755
- 650
1756
- 651
1757
- 652
1758
- 653
1759
- 654
1760
- 655
1761
- 656
1762
- 657
1763
- 658
1764
- 659</pre>
1796
+ 662
1797
+ 663
1798
+ 664
1799
+ 665
1800
+ 666
1801
+ 667
1802
+ 668
1803
+ 669
1804
+ 670
1805
+ 671
1806
+ 672
1807
+ 673
1808
+ 674
1809
+ 675
1810
+ 676
1811
+ 677
1812
+ 678
1813
+ 679
1814
+ 680
1815
+ 681
1816
+ 682
1817
+ 683
1818
+ 684
1819
+ 685
1820
+ 686
1821
+ 687
1822
+ 688</pre>
1765
1823
  </td>
1766
1824
  <td>
1767
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 633</span>
1825
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 662</span>
1768
1826
 
1769
1827
  <span class='kw'>def</span> <span class='id identifier rubyid_fetch'>fetch</span><span class='lparen'>(</span><span class='id identifier rubyid_key'>key</span><span class='comma'>,</span> <span class='op'>*</span><span class='id identifier rubyid_args'>args</span><span class='comma'>,</span> <span class='op'>&amp;</span><span class='id identifier rubyid_default_block'>default_block</span><span class='rparen'>)</span>
1770
1828
 
@@ -1898,14 +1956,14 @@ to help with unit tests.</p>
1898
1956
  <pre class="lines">
1899
1957
 
1900
1958
 
1901
- 689
1902
- 690
1903
- 691
1904
- 692
1905
- 693</pre>
1959
+ 718
1960
+ 719
1961
+ 720
1962
+ 721
1963
+ 722</pre>
1906
1964
  </td>
1907
1965
  <td>
1908
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 689</span>
1966
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 718</span>
1909
1967
 
1910
1968
  <span class='kw'>def</span> <span class='id identifier rubyid_has_key?'>has_key?</span><span class='lparen'>(</span><span class='id identifier rubyid_key'>key</span><span class='rparen'>)</span>
1911
1969
  <span class='kw'>return</span> <span class='kw'>false</span> <span class='kw'>unless</span> <span class='id identifier rubyid_key'>key</span><span class='period'>.</span><span class='id identifier rubyid_class'>class</span> <span class='op'>==</span> <span class='const'>String</span> <span class='op'>||</span> <span class='id identifier rubyid_key'>key</span><span class='period'>.</span><span class='id identifier rubyid_class'>class</span> <span class='op'>==</span> <span class='const'>Symbol</span>
@@ -1961,13 +2019,13 @@ to help with unit tests.</p>
1961
2019
  <pre class="lines">
1962
2020
 
1963
2021
 
1964
- 858
1965
- 859
1966
- 860
1967
- 861</pre>
2022
+ 887
2023
+ 888
2024
+ 889
2025
+ 890</pre>
1968
2026
  </td>
1969
2027
  <td>
1970
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 858</span>
2028
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 887</span>
1971
2029
 
1972
2030
  <span class='kw'>def</span> <span class='id identifier rubyid_has_value?'>has_value?</span><span class='lparen'>(</span><span class='id identifier rubyid_val'>val</span><span class='rparen'>)</span>
1973
2031
  <span class='kw'>self</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='kw'>return</span> <span class='kw'>true</span> <span class='kw'>if</span> <span class='id identifier rubyid_v'>v</span> <span class='op'>==</span> <span class='id identifier rubyid_val'>val</span><span class='rbrace'>}</span>
@@ -2008,14 +2066,14 @@ program.</p>
2008
2066
  <pre class="lines">
2009
2067
 
2010
2068
 
2011
- 870
2012
- 871
2013
- 872
2014
- 873
2015
- 874</pre>
2069
+ 899
2070
+ 900
2071
+ 901
2072
+ 902
2073
+ 903</pre>
2016
2074
  </td>
2017
2075
  <td>
2018
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 870</span>
2076
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 899</span>
2019
2077
 
2020
2078
  <span class='kw'>def</span> <span class='id identifier rubyid_invert'>invert</span>
2021
2079
  <span class='id identifier rubyid_result'>result</span> <span class='op'>=</span> <span class='lbrace'>{</span><span class='rbrace'>}</span>
@@ -2055,14 +2113,14 @@ that the result could exceed available memory.</p>
2055
2113
  <pre class="lines">
2056
2114
 
2057
2115
 
2058
- 671
2059
- 672
2060
- 673
2061
- 674
2062
- 675</pre>
2116
+ 700
2117
+ 701
2118
+ 702
2119
+ 703
2120
+ 704</pre>
2063
2121
  </td>
2064
2122
  <td>
2065
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 671</span>
2123
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 700</span>
2066
2124
 
2067
2125
  <span class='kw'>def</span> <span class='id identifier rubyid_keys'>keys</span>
2068
2126
  <span class='id identifier rubyid_keys'>keys</span> <span class='op'>=</span> <span class='lbracket'>[</span><span class='rbracket'>]</span>
@@ -2101,19 +2159,19 @@ as determined by SQLite3.</p>
2101
2159
  <pre class="lines">
2102
2160
 
2103
2161
 
2104
- 879
2105
- 880
2106
- 881
2107
- 882
2108
- 883
2109
- 884
2110
- 885
2111
- 886
2112
- 887
2113
- 888</pre>
2162
+ 908
2163
+ 909
2164
+ 910
2165
+ 911
2166
+ 912
2167
+ 913
2168
+ 914
2169
+ 915
2170
+ 916
2171
+ 917</pre>
2114
2172
  </td>
2115
2173
  <td>
2116
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 879</span>
2174
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 908</span>
2117
2175
 
2118
2176
  <span class='kw'>def</span> <span class='id identifier rubyid_shift'>shift</span>
2119
2177
  <span class='id identifier rubyid_transaction'>transaction</span> <span class='lbrace'>{</span>
@@ -2159,15 +2217,15 @@ as determined by SQLite3.</p>
2159
2217
  <pre class="lines">
2160
2218
 
2161
2219
 
2162
- 806
2163
- 807
2164
- 808
2165
- 809
2166
- 810
2167
- 811</pre>
2220
+ 835
2221
+ 836
2222
+ 837
2223
+ 838
2224
+ 839
2225
+ 840</pre>
2168
2226
  </td>
2169
2227
  <td>
2170
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 806</span>
2228
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 835</span>
2171
2229
 
2172
2230
  <span class='kw'>def</span> <span class='id identifier rubyid_size'>size</span>
2173
2231
  <span class='ivar'>@handle</span><span class='period'>.</span><span class='id identifier rubyid_sql'>sql</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>select count(*) from </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_actual_tbl'>actual_tbl</span><span class='embexpr_end'>}</span><span class='tstring_content'>;</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='lbracket'>[</span><span class='rbracket'>]</span><span class='rparen'>)</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_row'>row</span><span class='op'>|</span>
@@ -2210,14 +2268,14 @@ program.</p>
2210
2268
  <pre class="lines">
2211
2269
 
2212
2270
 
2213
- 843
2214
- 844
2215
- 845
2216
- 846
2217
- 847</pre>
2271
+ 872
2272
+ 873
2273
+ 874
2274
+ 875
2275
+ 876</pre>
2218
2276
  </td>
2219
2277
  <td>
2220
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 843</span>
2278
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 872</span>
2221
2279
 
2222
2280
  <span class='kw'>def</span> <span class='id identifier rubyid_to_a'>to_a</span>
2223
2281
  <span class='id identifier rubyid_result'>result</span> <span class='op'>=</span> <span class='lbracket'>[</span><span class='rbracket'>]</span>
@@ -2258,14 +2316,14 @@ program.</p>
2258
2316
  <pre class="lines">
2259
2317
 
2260
2318
 
2261
- 830
2262
- 831
2263
- 832
2264
- 833
2265
- 834</pre>
2319
+ 859
2320
+ 860
2321
+ 861
2322
+ 862
2323
+ 863</pre>
2266
2324
  </td>
2267
2325
  <td>
2268
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 830</span>
2326
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 859</span>
2269
2327
 
2270
2328
  <span class='kw'>def</span> <span class='id identifier rubyid_to_hash'>to_hash</span>
2271
2329
  <span class='id identifier rubyid_result'>result</span> <span class='op'>=</span> <span class='lbrace'>{</span><span class='rbrace'>}</span>
@@ -2466,14 +2524,14 @@ including <code>Hash</code> and <code>DBM</code> objects.</p>
2466
2524
  <pre class="lines">
2467
2525
 
2468
2526
 
2469
- 780
2470
- 781
2471
- 782
2472
- 783
2473
- 784</pre>
2527
+ 809
2528
+ 810
2529
+ 811
2530
+ 812
2531
+ 813</pre>
2474
2532
  </td>
2475
2533
  <td>
2476
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 780</span>
2534
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 809</span>
2477
2535
 
2478
2536
  <span class='kw'>def</span> <span class='id identifier rubyid_update'>update</span><span class='lparen'>(</span><span class='id identifier rubyid_hash'>hash</span><span class='rparen'>)</span>
2479
2537
  <span class='id identifier rubyid_transaction'>transaction</span> <span class='lbrace'>{</span>
@@ -2513,14 +2571,14 @@ that the result could exceed available memory.</p>
2513
2571
  <pre class="lines">
2514
2572
 
2515
2573
 
2516
- 681
2517
- 682
2518
- 683
2519
- 684
2520
- 685</pre>
2574
+ 710
2575
+ 711
2576
+ 712
2577
+ 713
2578
+ 714</pre>
2521
2579
  </td>
2522
2580
  <td>
2523
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 681</span>
2581
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 710</span>
2524
2582
 
2525
2583
  <span class='kw'>def</span> <span class='id identifier rubyid_values'>values</span>
2526
2584
  <span class='id identifier rubyid_values'>values</span> <span class='op'>=</span> <span class='lbracket'>[</span><span class='rbracket'>]</span>
@@ -2558,12 +2616,12 @@ given keys.</p>
2558
2616
  <pre class="lines">
2559
2617
 
2560
2618
 
2561
- 663
2562
- 664
2563
- 665</pre>
2619
+ 692
2620
+ 693
2621
+ 694</pre>
2564
2622
  </td>
2565
2623
  <td>
2566
- <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 663</span>
2624
+ <pre class="code"><span class="info file"># File 'lib/dbmlite3.rb', line 692</span>
2567
2625
 
2568
2626
  <span class='kw'>def</span> <span class='id identifier rubyid_values_at'>values_at</span><span class='lparen'>(</span><span class='op'>*</span><span class='id identifier rubyid_keys'>keys</span><span class='rparen'>)</span>
2569
2627
  <span class='kw'>return</span> <span class='id identifier rubyid_keys'>keys</span><span class='period'>.</span><span class='id identifier rubyid_map'>map</span><span class='lbrace'>{</span><span class='op'>|</span><span class='id identifier rubyid_k'>k</span><span class='op'>|</span> <span class='kw'>self</span><span class='lbracket'>[</span><span class='id identifier rubyid_k'>k</span><span class='rbracket'>]</span><span class='rbrace'>}</span>
@@ -2578,7 +2636,7 @@ given keys.</p>
2578
2636
  </div>
2579
2637
 
2580
2638
  <div id="footer">
2581
- Generated on Fri Feb 25 20:44:51 2022 by
2639
+ Generated on Sat Feb 26 11:47:57 2022 by
2582
2640
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
2583
2641
  0.9.25 (ruby-2.7.0).
2584
2642
  </div>
data/doc/Lite3/Error.html CHANGED
@@ -125,7 +125,7 @@
125
125
  </div>
126
126
 
127
127
  <div id="footer">
128
- Generated on Fri Feb 25 20:44:51 2022 by
128
+ Generated on Sat Feb 26 11:47:56 2022 by
129
129
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
130
130
  0.9.25 (ruby-2.7.0).
131
131
  </div>
data/doc/Lite3/SQL.html CHANGED
@@ -380,7 +380,7 @@ thread safe. Just a wrapper around <code>SQLite3.threadsafe?</code></p>
380
380
  </div>
381
381
 
382
382
  <div id="footer">
383
- Generated on Fri Feb 25 20:44:51 2022 by
383
+ Generated on Sat Feb 26 11:47:56 2022 by
384
384
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
385
385
  0.9.25 (ruby-2.7.0).
386
386
  </div>
data/doc/Lite3.html CHANGED
@@ -107,7 +107,7 @@
107
107
  </div>
108
108
 
109
109
  <div id="footer">
110
- Generated on Fri Feb 25 20:44:51 2022 by
110
+ Generated on Sat Feb 26 11:47:56 2022 by
111
111
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
112
112
  0.9.25 (ruby-2.7.0).
113
113
  </div>
data/doc/_index.html CHANGED
@@ -142,7 +142,7 @@
142
142
  </div>
143
143
 
144
144
  <div id="footer">
145
- Generated on Fri Feb 25 20:44:51 2022 by
145
+ Generated on Sat Feb 26 11:47:56 2022 by
146
146
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
147
147
  0.9.25 (ruby-2.7.0).
148
148
  </div>
data/doc/file.README.html CHANGED
@@ -193,7 +193,7 @@ make sense of them.</p>
193
193
  </div></div>
194
194
 
195
195
  <div id="footer">
196
- Generated on Fri Feb 25 20:44:51 2022 by
196
+ Generated on Sat Feb 26 11:47:56 2022 by
197
197
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
198
198
  0.9.25 (ruby-2.7.0).
199
199
  </div>
data/doc/index.html CHANGED
@@ -193,7 +193,7 @@ make sense of them.</p>
193
193
  </div></div>
194
194
 
195
195
  <div id="footer">
196
- Generated on Fri Feb 25 20:44:51 2022 by
196
+ Generated on Sat Feb 26 11:47:56 2022 by
197
197
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
198
198
  0.9.25 (ruby-2.7.0).
199
199
  </div>
@@ -100,7 +100,7 @@
100
100
  </div>
101
101
 
102
102
  <div id="footer">
103
- Generated on Fri Feb 25 20:44:51 2022 by
103
+ Generated on Sat Feb 26 11:47:56 2022 by
104
104
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
105
  0.9.25 (ruby-2.7.0).
106
106
  </div>
data/lib/dbmlite3.rb CHANGED
@@ -340,7 +340,7 @@ module Lite3
340
340
  # string. you will need to do this instead:
341
341
  #
342
342
  # db.keys.include?('foo') or raise AbjectFailure.new
343
- #
343
+ #
344
344
  # Unlike DBM, values may (optionally) be any serializable Ruby type.
345
345
  #
346
346
  # You can select the serialization method with an optional third
@@ -598,12 +598,41 @@ SQL
598
598
  key = check_key(key)
599
599
  valstr = SQLite3::Blob.new( @valenc.call(value) )
600
600
 
601
- insert = <<~SQL
602
- insert into #{actual_tbl} (key, value) values (?,?)
603
- on conflict(key) do update set value = ?;
604
- SQL
601
+ # At one point, this operation was done with SQLite3's UPSERT:
602
+ #
603
+ # insert into #{actual_tbl} (key, value) values (?,?)
604
+ # on conflict(key) do update set value = ?;
605
+ #
606
+ # Unfortunately, this capability was only added to SQLite3 in
607
+ # 2018, which means that at the time of this writing (2022)
608
+ # there are still a lot of systems out there that have older
609
+ # versions of SQLite3 and so can't do this.
610
+ #
611
+ # The venerable `insert or replace` feature **almost** does what
612
+ # I want:
613
+ #
614
+ # insert or replace into #{actual_tbl} (key, value) values (?, ?);
615
+ #
616
+ # The one problem is that it changes the order of the rows,
617
+ # which we need to preserve in order to remain consistent with
618
+ # `Hash` semantics (and because it's useful).
619
+ #
620
+ # So we kick it old school and do a `select` followed by an
621
+ # `insert` or `update` wrapped in a transaction.
605
622
  transaction {
606
- @handle.sql(insert, [key, valstr, valstr])
623
+ rowid = nil
624
+ select = "select rowid, key, value from #{actual_tbl} where key = ?;"
625
+ @handle.sql(select, [key]) { |row|
626
+ rowid = row[0]
627
+ }
628
+
629
+ if rowid
630
+ update = "update #{actual_tbl} set value = ? where rowid = ?;"
631
+ @handle.sql(update, [valstr, rowid])
632
+ else
633
+ insert = "insert into #{actual_tbl} (key, value) values (?,?);"
634
+ @handle.sql(insert, [key, valstr])
635
+ end
607
636
  }
608
637
 
609
638
  return value
@@ -120,6 +120,25 @@ Serializations = Set.new
120
120
  db.close
121
121
  end
122
122
 
123
+ it "preserves order after modification" do
124
+ path = Tmp.file
125
+ db = newdb.call(path, "floop")
126
+
127
+ expect( db.keys ) .to eq []
128
+ expect( db.values ) .to eq []
129
+
130
+ db["foo"] = 42
131
+ db["bar"] = 99
132
+ db["quux"] = 123
133
+
134
+ db["foo"] = 88
135
+
136
+ expect( db.keys ) .to eq %w{foo bar quux}
137
+ expect( db.values ) .to eq [88, 99, 123]
138
+
139
+ db.close
140
+ end
141
+
123
142
  it "implements has_key?" do
124
143
  path = Tmp.file
125
144
  db = newdb.call(path, "floop")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbmlite3
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.a2
4
+ version: 1.0.a5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Reuter
@@ -79,10 +79,10 @@ extensions: []
79
79
  extra_rdoc_files: []
80
80
  files:
81
81
  - ".yardopts"
82
- - DBMLite3.gemspec
83
82
  - LICENSE.txt
84
83
  - README.md
85
84
  - Rakefile
85
+ - dbmlite3.gemspec
86
86
  - doc/Lite3.html
87
87
  - doc/Lite3/DBM.html
88
88
  - doc/Lite3/Error.html
@@ -104,7 +104,7 @@ files:
104
104
  - lib/dbmlite3.rb
105
105
  - spec/dbmlite3_spec.rb
106
106
  - spec/spec_helper.rb
107
- homepage: https://codeberg.org/suetanvil/dbmlite3-ruby
107
+ homepage: https://codeberg.org/suetanvil/dbmlite
108
108
  licenses:
109
109
  - MIT
110
110
  metadata: {}