dbmlite3 2.0.0.pre.alpha.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,110 @@
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
+ Top Level Namespace
8
+
9
+ &mdash; Documentation by YARD 0.9.34
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 = "";
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
+
41
+
42
+ <span class="title">Top Level Namespace</span>
43
+
44
+ </div>
45
+
46
+ <div id="search">
47
+
48
+ <a class="full_list_link" id="class_list_link"
49
+ href="class_list.html">
50
+
51
+ <svg width="24" height="24">
52
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
53
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
54
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
55
+ </svg>
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <div id="content"><h1>Top Level Namespace
63
+
64
+
65
+
66
+ </h1>
67
+ <div class="box_info">
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+ </div>
80
+
81
+ <h2>Defined Under Namespace</h2>
82
+ <p class="children">
83
+
84
+
85
+ <strong class="modules">Modules:</strong> <span class='object_link'><a href="Lite3.html" title="Lite3 (module)">Lite3</a></span>
86
+
87
+
88
+
89
+
90
+ </p>
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+ </div>
101
+
102
+ <div id="footer">
103
+ Generated on Sat Aug 19 13:22:01 2023 by
104
+ <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
+ 0.9.34 (ruby-3.2.1).
106
+ </div>
107
+
108
+ </div>
109
+ </body>
110
+ </html>
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Lite3
3
-
3
+
4
4
  # Lite3::DBM encapsulates a single table in a single SQLite3
5
5
  # database file and lets you access it as easily as a Hash.
6
6
  # Multiple instances may be opened on different tables in the same
@@ -202,7 +202,7 @@ module Lite3
202
202
  # Begins a transaction, evaluates the given block and then ends
203
203
  # the transaction. If no error occurred (i.e. an exception was
204
204
  # thrown), the transaction is committed; otherwise, it is rolled
205
- # back.
205
+ # back. Returns the block's result.
206
206
  #
207
207
  # It is safe to call `DBM.transaction` within another
208
208
  # `DBM.transaction` block's call chain because `DBM` will not
@@ -220,8 +220,10 @@ module Lite3
220
220
  # transactions were always executed in `:deferred` mode via the
221
221
  # `sqlite3` gem.
222
222
  #
223
- # @yield [db] The block takes a reference to the receiver as an
224
- # argument.
223
+ # @return [obj] Returns the block's result.
224
+ #
225
+ # @yield [db] The block takes a reference to the receiver as an
226
+ # argument.
225
227
  #
226
228
  def transaction(&block)
227
229
  return @handle.transaction { block.call(self) }
@@ -265,7 +267,7 @@ module Lite3
265
267
  #
266
268
  # `key` **must** be a String or a Symbol; Symbols are
267
269
  # transparently converted to Strings.
268
- #
270
+ #
269
271
  # If it is not present and a block is given, evaluate the block
270
272
  # with the key as its argument and return that.
271
273
  #
@@ -368,7 +370,7 @@ module Lite3
368
370
  }
369
371
  end
370
372
 
371
-
373
+
372
374
  # Calls the given block with each key-value pair in the usual
373
375
  # order, then return self. The entire call takes place in its own
374
376
  # transaction.
@@ -10,18 +10,14 @@ module Lite3
10
10
 
11
11
  private
12
12
 
13
-
14
13
  module ErrUtil
15
-
16
14
  # Error check: if block evaluates to false, raise a Lite3::DBM::Error
17
15
  # with the given message.
18
16
  def check(message, &block)
19
17
  return if block && block.call
20
18
  raise InternalError.new(message)
21
19
  end
22
-
23
20
  end
24
21
 
25
-
26
22
  private_constant :ErrUtil
27
23
  end
@@ -41,7 +41,7 @@ module Lite3
41
41
  end
42
42
  alias inspect to_s
43
43
 
44
-
44
+
45
45
  #
46
46
  # References to the DBM object(s) using this handle.
47
47
  #
@@ -85,10 +85,14 @@ module Lite3
85
85
  #
86
86
  # Transactions
87
87
  #
88
-
88
+
89
89
  # Perform &block in a transaction. See DBM.transaction.
90
90
  def transaction(&block)
91
- @db.transaction({}, &block)
91
+ result = nil
92
+ @db.transaction({}) {
93
+ result = block.call
94
+ }
95
+ return result
92
96
  end
93
97
 
94
98
  # Test if there is currently a transaction in progress
@@ -64,7 +64,10 @@ module Lite3
64
64
  # corresponding `DBM`s have been closed or reclaimed).
65
65
  #
66
66
  # Returns a hash mapping the path to each open database file to
67
- # the number of live DBM objects referencing it.
67
+ # the number of live DBM objects referencing it. (Note that DBM
68
+ # objects that have gone out of scope but are not yet finalized
69
+ # count as "live"; as a result, this will differ across Ruby
70
+ # implementations due to differing garbage collector semantics.)
68
71
  #
69
72
  # You normally won't need to explicitly call this, but it's
70
73
  # useful for testing and debugging.
@@ -5,6 +5,10 @@ require_relative '../lib/dbmlite3.rb'
5
5
  require 'fileutils'
6
6
  require 'set'
7
7
 
8
+ def jruby?
9
+ return RUBY_PLATFORM == "java"
10
+ end
11
+
8
12
  module Tmp
9
13
  @root = File.join( File.dirname(__FILE__), "tmpdata")
10
14
  @count = 0
@@ -468,6 +472,13 @@ Serializations = Set.new
468
472
  db.close
469
473
  end
470
474
 
475
+ it "transaction returns the result of the transaction block" do
476
+ db = newdb.call(Tmp.file, "floop")
477
+
478
+ result = db.transaction { db['foo'] = 42 }
479
+ expect( result ) .to be 42
480
+ end
481
+
471
482
  it "provides the rest of DBM's interface as convenience methods." do
472
483
  db = newdb.call(Tmp.file, "blopp")
473
484
  vv = {
@@ -877,7 +888,8 @@ describe Lite3::SQL do
877
888
  }
878
889
 
879
890
  it "lets you close the actual handle without impeding database use" do
880
- expect( Lite3::SQL.gc.size ) .to eq 0
891
+ jruby? or # JRuby GC semantics throw this off
892
+ expect( Lite3::SQL.gc.size ) .to eq 0
881
893
 
882
894
  file = Tmp.file
883
895
  db1 = newbasic.call(file, "first")
@@ -885,14 +897,17 @@ describe Lite3::SQL do
885
897
 
886
898
  # The above should be using the same handle, which is currently
887
899
  # open.
888
-
889
- stats = Lite3::SQL.gc
890
- expect( stats.keys.size ) .to eq 1
891
-
892
- # Referencing DBM objects should be db1 and db2
893
- path, refs = stats.to_a[0]
894
- expect( path ) .to eq file
895
- expect( refs ) .to eq 2
900
+ #
901
+ # (Depends on GC wierdness so we skip this part for JRuby.)
902
+ unless jruby?
903
+ stats = Lite3::SQL.gc
904
+ expect( stats.keys.size ) .to eq 1
905
+
906
+ # Referencing DBM objects should be db1 and db2
907
+ path, refs = stats.to_a[0]
908
+ expect( path ) .to eq file
909
+ expect( refs ) .to eq 2
910
+ end
896
911
 
897
912
  # We can no longer test if the underlying file handles are still
898
913
  # open, so we don't.
@@ -908,7 +923,8 @@ describe Lite3::SQL do
908
923
  db1.close
909
924
  db2.close
910
925
 
911
- expect( Lite3::SQL.gc.keys.size ) .to eq 0
926
+ jruby? or
927
+ expect( Lite3::SQL.gc.keys.size ) .to eq 0
912
928
  end
913
929
 
914
930
  it "allows multiple table accesses in the same transaction" do
@@ -971,6 +987,7 @@ describe Lite3::SQL do
971
987
  #
972
988
  # (Dropping into the debugger after GC.start seems to help.)
973
989
 
990
+ skip "JRuby GC is capricious" if jruby?
974
991
 
975
992
  file = Tmp.file
976
993
  db1 = newbasic.call(file, "first")
@@ -1010,6 +1027,7 @@ end
1010
1027
 
1011
1028
  describe self do
1012
1029
  it "(this test) closes all handles when done with them" do
1030
+ skip "JRuby GC is capricious"if jruby?
1013
1031
  expect( Lite3::SQL.gc.size ) .to eq 0
1014
1032
  end
1015
1033
  end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbmlite3
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre.alpha.4
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Reuter
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2022-02-21 00:00:00.000000000 Z
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 5.65.0
19
+ version: 5.71.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 5.65.0
26
+ version: 5.71.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sqlite3
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -87,7 +87,7 @@ description: |2
87
87
  (almost) any Ruby type to be stored. In addition, there is
88
88
  rudimentary support for transactions with emphasis on simplicity
89
89
  and safety.
90
- email: chris@isplitonyourgrave.com
90
+ email: chris@remove-this-part.blit.ca
91
91
  executables: []
92
92
  extensions: []
93
93
  extra_rdoc_files: []
@@ -97,7 +97,25 @@ files:
97
97
  - README.md
98
98
  - Rakefile
99
99
  - dbmlite3.gemspec
100
- - extras/benchmark.rb
100
+ - doc/Lite3.html
101
+ - doc/Lite3/DBM.html
102
+ - doc/Lite3/Error.html
103
+ - doc/Lite3/InternalError.html
104
+ - doc/Lite3/SQL.html
105
+ - doc/_index.html
106
+ - doc/class_list.html
107
+ - doc/css/common.css
108
+ - doc/css/full_list.css
109
+ - doc/css/style.css
110
+ - doc/file.README.html
111
+ - doc/file_list.html
112
+ - doc/frames.html
113
+ - doc/index.html
114
+ - doc/js/app.js
115
+ - doc/js/full_list.js
116
+ - doc/js/jquery.js
117
+ - doc/method_list.html
118
+ - doc/top-level-namespace.html
101
119
  - lib/dbmlite3.rb
102
120
  - lib/internal_lite3/dbm.rb
103
121
  - lib/internal_lite3/error.rb
@@ -109,7 +127,7 @@ homepage: https://codeberg.org/suetanvil/dbmlite3
109
127
  licenses:
110
128
  - MIT
111
129
  metadata: {}
112
- post_install_message:
130
+ post_install_message:
113
131
  rdoc_options: []
114
132
  require_paths:
115
133
  - lib
@@ -120,13 +138,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
120
138
  version: 2.7.0
121
139
  required_rubygems_version: !ruby/object:Gem::Requirement
122
140
  requirements:
123
- - - ">"
141
+ - - ">="
124
142
  - !ruby/object:Gem::Version
125
- version: 1.3.1
143
+ version: '0'
126
144
  requirements:
127
145
  - Sequel, sqlite3, Ruby MRI
128
- rubygems_version: 3.2.15
129
- signing_key:
146
+ rubygems_version: 3.4.6
147
+ signing_key:
130
148
  specification_version: 4
131
149
  summary: A DBM-style key-value store using SQLite3
132
150
  test_files: []
data/extras/benchmark.rb DELETED
@@ -1,172 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Low-effort benchmark comparing Lite3::DBM in various modes against
4
- # other equivalent Hash-like Ruby storage mechanisms.
5
-
6
- require 'dbmlite3'
7
- require 'yaml/dbm' unless RUBY_PLATFORM == "java"
8
- require 'fileutils'
9
- require 'optparse'
10
-
11
- COUNT = 10000
12
-
13
- Opts = proc do
14
- opt_defaults = {
15
- count: COUNT,
16
- transaction_only: true,
17
- }
18
-
19
- opts = Struct.new(*opt_defaults.keys).new(*opt_defaults.values)
20
-
21
- OptionParser.new do |opo|
22
- opo.banner = "Usage: bench_1.rb [options]"
23
-
24
- opo.on("-t", "--multi-transaction",
25
- "Don't batch Lite3 accesses in one big transaction.") {
26
- opts.transaction_only = false
27
- }
28
-
29
- opo.on("-c", "--count N", Integer, "Set test count.") { |c|
30
- opts.count = c
31
- }
32
- end.parse!
33
-
34
- next opts
35
- end.call
36
-
37
-
38
- module Tmp
39
- @root = File.join( File.dirname(__FILE__), "tmpdata")
40
- @count = 0
41
-
42
- def self.file
43
- FileUtils.mkdir(@root) unless File.directory?(@root)
44
-
45
- file = "testfile_#{@count}_#{$$}.sqlite3"
46
- @count += 1
47
-
48
- return File.join(@root, file)
49
- end
50
-
51
- def self.cleanup
52
- return unless File.directory?(@root)
53
- FileUtils.rm_rf(@root)
54
- end
55
- end
56
-
57
-
58
-
59
- def insert(count, db, offset)
60
- for n in 0 .. count
61
- db["k_#{n}"] = "#{n + offset}"
62
- end
63
- end
64
-
65
-
66
- def lookup(count, db)
67
- rnd = Random.new(69_420)
68
- sz = db.size
69
-
70
- for _ in 0 .. count * 3
71
- idx = rnd.rand(sz)
72
- v = db["k_#{idx}"]
73
- raise "Invalid value: #{v}" unless v.to_s == "#{idx + 1}"
74
- end
75
- end
76
-
77
-
78
- Times = {}
79
-
80
- def time_it(type, task, db, use_tr, &block)
81
- print "#{type} #{task} - "
82
- STDOUT.flush
83
-
84
- start = Time.now
85
-
86
- if use_tr && db.respond_to?(:transaction)
87
- db.transaction { block.call }
88
- else
89
- block.call
90
- end
91
-
92
- finish = Time.now
93
-
94
- elapsed = (finish - start).to_f
95
- Times[type] = Times.fetch(type, 0) + elapsed
96
-
97
- puts "#{elapsed.round(4)}"
98
- end
99
-
100
- def bench(count, desc, db, use_tr)
101
- time_it(desc, "insert", db, use_tr) {
102
- insert(count, db, 0)
103
- }
104
- time_it(desc, "upsert", db, use_tr) {
105
- insert(count, db, 1)
106
- }
107
- time_it(desc, "lookup", db, use_tr) {
108
- lookup(count, db)
109
- }
110
- time_it(desc, "delete_if", db, use_tr) {
111
- rnd = Random.new(69_420)
112
- db.delete_if{|k,v| rnd.rand(2) == 0}
113
- }
114
- puts
115
- end
116
-
117
-
118
-
119
- def main
120
- puts "Count = #{Opts.count}\n"
121
-
122
- Tmp.cleanup
123
-
124
- bench(Opts.count, "hash", {}, false)
125
-
126
- if RUBY_PLATFORM != "java"
127
- DBM.open(Tmp.file) {|dbm|
128
- bench(Opts.count, "DBM", dbm, false)
129
- }
130
-
131
- YAML::DBM.open(Tmp.file) {|dbm|
132
- bench(Opts.count, "YAML::DBM", dbm, false)
133
- }
134
- end
135
-
136
- Lite3::DBM.open(Tmp.file, "benchmark", :yaml) { |dbm|
137
- bench(Opts.count, "Lite3::DBM(yaml)", dbm, true)
138
- }
139
-
140
- Lite3::DBM.open(Tmp.file, "benchmark", :marshal) { |dbm|
141
- bench(Opts.count, "Lite3::DBM(marshal)", dbm, true)
142
- }
143
-
144
- Lite3::DBM.open(Tmp.file, "benchmark", :string) { |dbm|
145
- bench(Opts.count, "Lite3::DBM(string)", dbm, true)
146
- }
147
-
148
- if !Opts.transaction_only
149
- Lite3::DBM.open(Tmp.file, "benchmark", :yaml) { |dbm|
150
- bench(Opts.count, "Lite3::DBM(yaml, single-trans)", dbm, false)
151
- }
152
-
153
- Lite3::DBM.open(Tmp.file, "benchmark", :marshal) { |dbm|
154
- bench(Opts.count, "Lite3::DBM(marshal, single-trans)", dbm, false)
155
- }
156
-
157
- Lite3::DBM.open(Tmp.file, "benchmark", :string) { |dbm|
158
- bench(Opts.count, "Lite3::DBM(string, single-trans)", dbm, false)
159
- }
160
- end
161
-
162
-
163
- puts
164
- puts "Totals:"
165
- Times.each{|k,v|
166
- puts " #{k} - #{v.round(4)}"
167
- }
168
-
169
- Tmp.cleanup
170
- end
171
-
172
- main