rufus-cloche 1.0.2 → 1.0.3
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.
- data/CHANGELOG.txt +6 -0
- data/LICENSE.txt +1 -1
- data/Rakefile +2 -1
- data/lib/rufus/cloche/version.rb +2 -2
- data/lib/rufus/cloche.rb +53 -47
- data/rufus-cloche.gemspec +1 -1
- data/test/conc/put_vs_delete.rb +2 -1
- data/test/ct_worker.rb +4 -2
- data/test/ct_writer.rb +8 -2
- data/test/test.rb +3 -9
- metadata +25 -12
data/CHANGELOG.txt
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
= rufus-cloche CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== rufus-cloche - 1.0.3 released 2013/02/21
|
6
|
+
|
7
|
+
- fix issue when putting a just deleted doc
|
8
|
+
- standardish (no space before "(" in method signature)
|
9
|
+
|
10
|
+
|
5
11
|
== rufus-cloche - 1.0.2 released 2012/02/27
|
6
12
|
|
7
13
|
- only making sure the .gemspec doesn't require any file
|
data/LICENSE.txt
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
Copyright (c) 2009-
|
2
|
+
Copyright (c) 2009-2013, John Mettraux, jmettraux@gmail.com
|
3
3
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
of this software and associated documentation files (the "Software"), to deal
|
data/Rakefile
CHANGED
data/lib/rufus/cloche/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2009-
|
2
|
+
# Copyright (c) 2009-2013, John Mettraux, jmettraux@gmail.com
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -30,7 +30,7 @@ module Rufus
|
|
30
30
|
#
|
31
31
|
class Cloche
|
32
32
|
|
33
|
-
VERSION = '1.0.
|
33
|
+
VERSION = '1.0.3'
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
data/lib/rufus/cloche.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2009-
|
2
|
+
# Copyright (c) 2009-2013, John Mettraux, jmettraux@gmail.com
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -25,8 +25,8 @@
|
|
25
25
|
require 'thread'
|
26
26
|
require 'fileutils'
|
27
27
|
|
28
|
-
require 'rufus-json'
|
29
|
-
|
28
|
+
#require 'rufus-json/automatic'
|
29
|
+
# best left to the code using rufus-cloche, not to rufus-cloche itself
|
30
30
|
|
31
31
|
require 'rufus/cloche/version'
|
32
32
|
|
@@ -53,7 +53,7 @@ module Rufus
|
|
53
53
|
#
|
54
54
|
# On the Windows platform, :nolock is set to true automatically.
|
55
55
|
#
|
56
|
-
def initialize
|
56
|
+
def initialize(opts={})
|
57
57
|
|
58
58
|
@dir = File.expand_path(opts[:dir] || 'cloche')
|
59
59
|
@mutex = Mutex.new
|
@@ -72,7 +72,7 @@ module Rufus
|
|
72
72
|
#
|
73
73
|
# If the put is successful, nil is returned.
|
74
74
|
#
|
75
|
-
def put
|
75
|
+
def put(doc, opts={})
|
76
76
|
|
77
77
|
opts = opts.inject({}) { |h, (k, v)| h[k.to_s] = v; h }
|
78
78
|
|
@@ -91,24 +91,25 @@ module Rufus
|
|
91
91
|
ArgumentError.new("values for '_rev' must be positive integers")
|
92
92
|
) if rev.class != Fixnum && rev.class != Bignum
|
93
93
|
|
94
|
-
|
94
|
+
r =
|
95
|
+
lock(rev == -1, type, key) do |file|
|
95
96
|
|
96
|
-
|
97
|
+
cur = do_get(file)
|
97
98
|
|
98
|
-
|
99
|
-
|
99
|
+
return cur if cur && cur['_rev'] != doc['_rev']
|
100
|
+
return true if cur.nil? && doc['_rev'] != -1
|
100
101
|
|
101
|
-
|
102
|
+
doc['_rev'] += 1
|
102
103
|
|
103
|
-
|
104
|
-
|
104
|
+
File.open(file.path, 'wb') { |io| io.write(Rufus::Json.encode(doc)) }
|
105
|
+
end
|
105
106
|
|
106
|
-
nil
|
107
|
+
r == false ? true : nil
|
107
108
|
end
|
108
109
|
|
109
110
|
# Gets a document (or nil if not found (or corrupted)).
|
110
111
|
#
|
111
|
-
def get
|
112
|
+
def get(type, key)
|
112
113
|
|
113
114
|
r = lock(false, type, key) { |f| do_get(f) }
|
114
115
|
|
@@ -126,7 +127,7 @@ module Rufus
|
|
126
127
|
#
|
127
128
|
# Returns true if the deletion failed.
|
128
129
|
#
|
129
|
-
def delete
|
130
|
+
def delete(doc)
|
130
131
|
|
131
132
|
drev = doc['_rev']
|
132
133
|
|
@@ -134,22 +135,23 @@ module Rufus
|
|
134
135
|
|
135
136
|
type, key = doc['type'], doc['_id']
|
136
137
|
|
137
|
-
r =
|
138
|
+
r =
|
139
|
+
lock(false, type, key) do |f|
|
138
140
|
|
139
|
-
|
141
|
+
cur = do_get(f)
|
140
142
|
|
141
|
-
|
142
|
-
|
143
|
+
return nil unless cur
|
144
|
+
return cur if cur['_rev'] != drev
|
143
145
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
146
|
+
begin
|
147
|
+
f.close
|
148
|
+
File.delete(f.path)
|
149
|
+
nil
|
150
|
+
rescue Exception => e
|
151
|
+
#p e
|
152
|
+
false
|
153
|
+
end
|
151
154
|
end
|
152
|
-
end
|
153
155
|
|
154
156
|
r == false ? true : nil
|
155
157
|
end
|
@@ -169,7 +171,7 @@ module Rufus
|
|
169
171
|
# If :count => true, the query will simply return the number of documents
|
170
172
|
# that matched.
|
171
173
|
#
|
172
|
-
def get_many
|
174
|
+
def get_many(type, regex=nil, opts={})
|
173
175
|
|
174
176
|
opts = opts.inject({}) { |h, (k, v)| h[k.to_s] = v; h }
|
175
177
|
|
@@ -186,10 +188,7 @@ module Rufus
|
|
186
188
|
skip = opts['skip']
|
187
189
|
count = opts['count'] ? 0 : nil
|
188
190
|
|
189
|
-
files = Dir[File.join(d, '**', '*.json')].
|
190
|
-
File.basename(p0) <=> File.basename(p1)
|
191
|
-
}
|
192
|
-
|
191
|
+
files = Dir[File.join(d, '**', '*.json')].sort_by { |f| File.basename(f) }
|
193
192
|
files = files.reverse if opts['descending']
|
194
193
|
|
195
194
|
files.each do |fn|
|
@@ -225,7 +224,7 @@ module Rufus
|
|
225
224
|
|
226
225
|
# Removes entirely documents of a given type.
|
227
226
|
#
|
228
|
-
def purge_type!
|
227
|
+
def purge_type!(type)
|
229
228
|
|
230
229
|
FileUtils.rm_rf(dir_for(type))
|
231
230
|
end
|
@@ -234,10 +233,10 @@ module Rufus
|
|
234
233
|
#
|
235
234
|
# Warning : trusts the ids to be identical to the filenames
|
236
235
|
#
|
237
|
-
def ids
|
236
|
+
def ids(type)
|
238
237
|
|
239
|
-
Dir[File.join(dir_for(type), '**', '*.json')].collect { |
|
240
|
-
File.basename(
|
238
|
+
Dir[File.join(dir_for(type), '**', '*.json')].collect { |path|
|
239
|
+
File.basename(path, '.json')
|
241
240
|
}.sort
|
242
241
|
end
|
243
242
|
|
@@ -245,7 +244,7 @@ module Rufus
|
|
245
244
|
#
|
246
245
|
# Actually reads each file and returns the real _id list
|
247
246
|
#
|
248
|
-
def real_ids
|
247
|
+
def real_ids(type)
|
249
248
|
|
250
249
|
Dir[File.join(dir_for(type), '**', '*.json')].inject([]) { |a, p|
|
251
250
|
doc = do_get(p)
|
@@ -256,30 +255,30 @@ module Rufus
|
|
256
255
|
|
257
256
|
protected
|
258
257
|
|
259
|
-
def match?
|
258
|
+
def match?(key, regexes)
|
260
259
|
|
261
260
|
regexes.first.is_a?(Regexp) ?
|
262
261
|
regexes.find { |regex| regex.match(key) } :
|
263
262
|
regexes.find { |s| key[-s.length..-1] == s }
|
264
263
|
end
|
265
264
|
|
266
|
-
def self.neutralize
|
265
|
+
def self.neutralize(s)
|
267
266
|
|
268
267
|
s.to_s.strip.gsub(/[ \/:;\*\\\+\?]/, '_')
|
269
268
|
end
|
270
269
|
|
271
|
-
def do_get
|
270
|
+
def do_get(file)
|
272
271
|
|
273
272
|
s = file.is_a?(File) ? file.read : File.read(file)
|
274
273
|
Rufus::Json.decode(s) rescue nil
|
275
274
|
end
|
276
275
|
|
277
|
-
def dir_for
|
276
|
+
def dir_for(type)
|
278
277
|
|
279
278
|
File.join(@dir, Cloche.neutralize(type || 'no_type'))
|
280
279
|
end
|
281
280
|
|
282
|
-
def path_for
|
281
|
+
def path_for(type, key)
|
283
282
|
|
284
283
|
nkey = Cloche.neutralize(key)
|
285
284
|
|
@@ -288,7 +287,7 @@ module Rufus
|
|
288
287
|
[ File.join(dir_for(type), subdir), "#{nkey}.json" ]
|
289
288
|
end
|
290
289
|
|
291
|
-
def lock
|
290
|
+
def lock(create, type, key, &block)
|
292
291
|
|
293
292
|
@mutex.synchronize do
|
294
293
|
begin
|
@@ -296,16 +295,23 @@ module Rufus
|
|
296
295
|
d, f = path_for(type, key)
|
297
296
|
fn = File.join(d, f)
|
298
297
|
|
299
|
-
if create && ( ! File.exist?(
|
300
|
-
|
301
|
-
FileUtils.touch(fn) unless File.exist?(fn)
|
302
|
-
end
|
298
|
+
FileUtils.mkdir_p(d) if create && ( ! File.exist?(d))
|
299
|
+
FileUtils.touch(fn) if create && ( ! File.exist?(fn))
|
303
300
|
|
304
301
|
file = File.new(fn, 'r+') rescue nil
|
305
302
|
|
306
303
|
return false if file.nil?
|
307
304
|
|
308
305
|
file.flock(File::LOCK_EX) unless @nolock
|
306
|
+
|
307
|
+
7.times { return false unless File.exist?(fn) } unless create
|
308
|
+
#
|
309
|
+
# We got the lock, but is the file still here?
|
310
|
+
#
|
311
|
+
# Asking more than one time, since, at least on OSX snoleo,
|
312
|
+
# File.exist? might say yes for a file just deleted
|
313
|
+
# (by another process)
|
314
|
+
|
309
315
|
block.call(file)
|
310
316
|
|
311
317
|
ensure
|
data/rufus-cloche.gemspec
CHANGED
@@ -31,7 +31,7 @@ Strives to be process-safe and thread-safe.
|
|
31
31
|
'*.gemspec', '*.txt', '*.rdoc', '*.md'
|
32
32
|
]
|
33
33
|
|
34
|
-
s.add_runtime_dependency 'rufus-json', '>= 1.0.
|
34
|
+
s.add_runtime_dependency 'rufus-json', '>= 1.0.3'
|
35
35
|
|
36
36
|
s.add_development_dependency 'rake'
|
37
37
|
s.add_development_dependency 'json'
|
data/test/conc/put_vs_delete.rb
CHANGED
data/test/ct_worker.rb
CHANGED
data/test/ct_writer.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
|
2
|
-
|
3
|
-
|
2
|
+
$:.unshift(File.expand_path('../../lib', __FILE__))
|
3
|
+
|
4
|
+
require 'rufus-json/automatic'
|
5
|
+
require 'rufus-cloche'
|
4
6
|
|
5
7
|
CLO = Rufus::Cloche.new(:dir => 'cloche')
|
8
|
+
if doc = CLO.get('person', 'john')
|
9
|
+
CLO.delete(doc)
|
10
|
+
end
|
11
|
+
CLO.put('type' => 'person', '_id' => 'john')
|
6
12
|
|
7
13
|
p $$
|
8
14
|
|
data/test/test.rb
CHANGED
@@ -7,19 +7,13 @@
|
|
7
7
|
|
8
8
|
require 'rubygems'
|
9
9
|
|
10
|
-
begin
|
11
|
-
require 'yajl'
|
12
|
-
rescue
|
13
|
-
require 'json'
|
14
|
-
end
|
15
|
-
|
16
|
-
ROOT = File.join(File.dirname(__FILE__), '..')
|
17
|
-
|
18
10
|
require 'test/unit'
|
11
|
+
require 'rufus-json/automatic'
|
19
12
|
|
13
|
+
ROOT = File.join(File.dirname(__FILE__), '..')
|
20
14
|
$:.unshift(File.join(ROOT, 'lib'))
|
21
15
|
|
22
|
-
require 'rufus
|
16
|
+
require 'rufus-cloche'
|
23
17
|
|
24
18
|
|
25
19
|
class ClocheTest < Test::Unit::TestCase
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rufus-cloche
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,23 +9,27 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
default_executable:
|
12
|
+
date: 2013-02-20 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: rufus-json
|
17
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
18
17
|
none: false
|
19
18
|
requirements:
|
20
19
|
- - ! '>='
|
21
20
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.0.
|
21
|
+
version: 1.0.3
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.0.3
|
26
30
|
- !ruby/object:Gem::Dependency
|
27
31
|
name: rake
|
28
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
29
33
|
none: false
|
30
34
|
requirements:
|
31
35
|
- - ! '>='
|
@@ -33,10 +37,15 @@ dependencies:
|
|
33
37
|
version: '0'
|
34
38
|
type: :development
|
35
39
|
prerelease: false
|
36
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
37
46
|
- !ruby/object:Gem::Dependency
|
38
47
|
name: json
|
39
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
40
49
|
none: false
|
41
50
|
requirements:
|
42
51
|
- - ! '>='
|
@@ -44,7 +53,12 @@ dependencies:
|
|
44
53
|
version: '0'
|
45
54
|
type: :development
|
46
55
|
prerelease: false
|
47
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
48
62
|
description: ! "\nA very stupid JSON hash store.\n\nIt's built on top of yajl-ruby
|
49
63
|
and File.lock. Defaults to 'json' (or 'json_pure') if yajl-ruby is not present (it's
|
50
64
|
probably just a \"gem install yajl-ruby\" away.\n\nStrives to be process-safe and
|
@@ -70,7 +84,6 @@ files:
|
|
70
84
|
- LICENSE.txt
|
71
85
|
- TODO.txt
|
72
86
|
- README.rdoc
|
73
|
-
has_rdoc: true
|
74
87
|
homepage: http://ruote.rubyforge.org
|
75
88
|
licenses: []
|
76
89
|
post_install_message:
|
@@ -91,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
104
|
version: '0'
|
92
105
|
requirements: []
|
93
106
|
rubyforge_project: rufus
|
94
|
-
rubygems_version: 1.
|
107
|
+
rubygems_version: 1.8.24
|
95
108
|
signing_key:
|
96
109
|
specification_version: 3
|
97
110
|
summary: an open source Ruby workflow engine
|