-
Notifications
You must be signed in to change notification settings - Fork 0
/
store.rb
75 lines (71 loc) · 1.41 KB
/
store.rb
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
#
# YAML::Store
#
require 'yaml'
require 'pstore'
module YAML
class Store < PStore
#
# Constructor
#
def initialize( *o )
@opt = YAML::DEFAULTS.dup
if String === o.first
super(o.shift)
end
if o.last.is_a? Hash
@opt.update(o.pop)
end
end
#
# Override Pstore#transaction
#
def transaction
raise YAML::Error, "nested transaction" if @transaction
raise YAML::Error, "no filename for transaction" unless @filename
begin
@transaction = true
value = nil
backup = @filename+"~"
if File::exist?(@filename)
file = File::open(@filename, "rb+")
orig = true
else
@table = {}
file = File::open(@filename, "wb+")
file.write( @table.to_yaml( @opt ) )
end
file.flock(File::LOCK_EX)
if orig
File::copy @filename, backup
@table = YAML::load( file )
end
begin
catch(:pstore_abort_transaction) do
value = yield(self)
end
rescue Exception
@abort = true
raise
ensure
unless @abort
begin
file.rewind
file.write( @table.to_yaml( @opt ) )
file.truncate(file.pos)
rescue
File::rename backup, @filename if File::exist?(backup)
raise
end
end
@abort = false
end
ensure
@table = nil
@transaction = false
file.close if file
end
value
end
end
end