rufus-cloche 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|