abbey 0.1.0.beta3 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/abbey.gemspec +3 -3
- data/lib/entity_storage.rb +28 -3
- data/lib/errors.rb +9 -1
- data/lib/version.rb +2 -2
- data/test/entity_storage_test.rb +21 -1
- metadata +16 -16
data/abbey.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "abbey"
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.1"
|
9
9
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Pavel Kalvoda"]
|
12
|
-
s.date = "2011-11-
|
12
|
+
s.date = "2011-11-17"
|
13
13
|
s.description = "Primitive JSON data store. Key-value structure with namespaces."
|
14
14
|
s.email = "me@pavelkalvoda.com"
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/entity_storage.rb
CHANGED
@@ -4,6 +4,8 @@ module Abbey
|
|
4
4
|
# JSON serialization under the hood.
|
5
5
|
class EntityStorage
|
6
6
|
|
7
|
+
ForbiddenChars = '/'
|
8
|
+
|
7
9
|
# @return [Settings]
|
8
10
|
attr_accessor :settings
|
9
11
|
|
@@ -29,6 +31,7 @@ module Abbey
|
|
29
31
|
# Set up the directory structure
|
30
32
|
# @return void
|
31
33
|
def set_up!
|
34
|
+
return if set_up?
|
32
35
|
settings.namespaces.each do |ns|
|
33
36
|
path = make_path(ns)
|
34
37
|
if !Dir.exists?(path) then
|
@@ -45,7 +48,7 @@ module Abbey
|
|
45
48
|
# @return void
|
46
49
|
def save(namespace, key, data)
|
47
50
|
path = make_path(namespace, key)
|
48
|
-
raise ItemAlreadyPresentError
|
51
|
+
raise ItemAlreadyPresentError, "Item '#{make_key(namespace,key)}' already present" if File.exist?(path)
|
49
52
|
f = File.new(path, File::CREAT | File::RDWR)
|
50
53
|
size = f.write(MultiJson.encode(data))
|
51
54
|
f.close
|
@@ -58,7 +61,7 @@ module Abbey
|
|
58
61
|
# @return [Object]
|
59
62
|
def get(namespace, key)
|
60
63
|
path = make_path(namespace, key)
|
61
|
-
raise ItemNotFoundError
|
64
|
+
raise ItemNotFoundError, "Item '#{make_key(namespace,key)}' not found" unless exists?(namespace, key)
|
62
65
|
settings.logger.info("Read #{make_key(namespace, key)}")
|
63
66
|
MultiJson.decode(File.read(path))
|
64
67
|
end
|
@@ -89,7 +92,7 @@ module Abbey
|
|
89
92
|
# @return void
|
90
93
|
def delete(namespace, key)
|
91
94
|
path = make_path(namespace, key)
|
92
|
-
raise ItemNotFoundError
|
95
|
+
raise ItemNotFoundError, "Item '#{make_key(namespace,key)}' already exists" unless exists?(namespace, key)
|
93
96
|
File.delete(path)
|
94
97
|
settings.logger.info("Deleted #{make_key(namespace,key)}")
|
95
98
|
end
|
@@ -118,13 +121,35 @@ module Abbey
|
|
118
121
|
list(namespace).each {|item| delete(namespace, item)}
|
119
122
|
end
|
120
123
|
|
124
|
+
# Check whether the key is formally valid
|
125
|
+
# @param key [String, Fixnum, Symbol or any other object whose #to_s method returns string]
|
126
|
+
# @return [Boolean]
|
127
|
+
def identifier_valid?(key)
|
128
|
+
key = key.to_s
|
129
|
+
ForbiddenChars.each_char do |char|
|
130
|
+
return false if key.include?(char)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
121
134
|
private
|
122
135
|
|
136
|
+
def validate_namespace(namespace)
|
137
|
+
raise InvalidNameError, "The namespace contains illegal characters" unless identifier_valid?(namespace)
|
138
|
+
end
|
139
|
+
|
140
|
+
def validate_key(key)
|
141
|
+
raise InvalidNameError, "The key contains illegal characters" unless identifier_valid?(key)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Compose path to a namespace or an item
|
123
145
|
def make_path(namespace, key = nil)
|
146
|
+
validate_namespace(namespace)
|
147
|
+
validate_key(key) if key
|
124
148
|
dir = File.join(settings.path, namespace.to_s)
|
125
149
|
key ? File.join(dir, key.to_s) : dir
|
126
150
|
end
|
127
151
|
|
152
|
+
# Unify IDs format
|
128
153
|
def make_key(namespace, key)
|
129
154
|
namespace.to_s + ':' + key.to_s
|
130
155
|
end
|
data/lib/errors.rb
CHANGED
@@ -1,9 +1,17 @@
|
|
1
1
|
module Abbey
|
2
2
|
|
3
|
-
#
|
3
|
+
# Raised when trying to overwrite an item
|
4
4
|
class ItemAlreadyPresentError < RuntimeError
|
5
5
|
end
|
6
6
|
|
7
7
|
class ItemNotFoundError < RuntimeError
|
8
8
|
end
|
9
|
+
|
10
|
+
# Raised when the data can't be serialized
|
11
|
+
class NotSerializableError < ArgumentError
|
12
|
+
end
|
13
|
+
|
14
|
+
# Raised when a key or a namespace containing a FS separator is passed
|
15
|
+
class InvalidNameError < ArgumentError
|
16
|
+
end
|
9
17
|
end
|
data/lib/version.rb
CHANGED
data/test/entity_storage_test.rb
CHANGED
@@ -8,7 +8,7 @@ class AbbeyTest < Test::Unit::TestCase
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def teardown
|
11
|
-
FileUtils.rm_r('/tmp/abbey')
|
11
|
+
FileUtils.rm_r('/tmp/abbey') if Dir.exist?('/tmp/abbey')
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_it_will_check_for_readiness
|
@@ -87,4 +87,24 @@ class AbbeyTest < Test::Unit::TestCase
|
|
87
87
|
assert_equal(Set.new, @abbey.list(:ns1))
|
88
88
|
assert_equal Set.new([:key]), @abbey.list(:ns2)
|
89
89
|
end
|
90
|
+
|
91
|
+
def test_special_chars_in_keys
|
92
|
+
@abbey.set_up!
|
93
|
+
@abbey.save(:ns1, "with:colon", {"a" => 1})
|
94
|
+
assert_equal ({"a" => 1}), @abbey.get(:ns1, "with:colon")
|
95
|
+
assert_raise Abbey::InvalidNameError do
|
96
|
+
@abbey.save(:ns1, "with/slash", {"a" => 5})
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_special_chars_in_namespaces
|
101
|
+
abbey = Abbey::EntityStorage.new(Abbey::Settings.new('/tmp/abbey', [:ns1, :"with:colon"], Logger.new(STDOUT)))
|
102
|
+
abbey.set_up!
|
103
|
+
abbey.save("with:colon", :key, ["datadata"])
|
104
|
+
assert_equal ["datadata"], abbey.get("with:colon", :key)
|
105
|
+
assert_raise Abbey::InvalidNameError do
|
106
|
+
Abbey::EntityStorage.new(Abbey::Settings.new('/tmp/abbey', [:ns1, :"with/slash"], Logger.new(STDOUT))).set_up!
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
90
110
|
end
|
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abbey
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.1
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Pavel Kalvoda
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-11-
|
12
|
+
date: 2011-11-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|
16
|
-
requirement: &
|
16
|
+
requirement: &6562960 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *6562960
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &6560780 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *6560780
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: bundler
|
38
|
-
requirement: &
|
38
|
+
requirement: &6559960 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *6559960
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: jeweler
|
49
|
-
requirement: &
|
49
|
+
requirement: &6610240 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.6.4
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *6610240
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rcov
|
60
|
-
requirement: &
|
60
|
+
requirement: &6608820 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *6608820
|
69
69
|
description: Primitive JSON data store. Key-value structure with namespaces.
|
70
70
|
email: me@pavelkalvoda.com
|
71
71
|
executables: []
|
@@ -104,13 +104,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
104
104
|
version: '0'
|
105
105
|
segments:
|
106
106
|
- 0
|
107
|
-
hash: -
|
107
|
+
hash: -1187583575974686402
|
108
108
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
109
|
none: false
|
110
110
|
requirements:
|
111
|
-
- - ! '
|
111
|
+
- - ! '>='
|
112
112
|
- !ruby/object:Gem::Version
|
113
|
-
version:
|
113
|
+
version: '0'
|
114
114
|
requirements: []
|
115
115
|
rubyforge_project:
|
116
116
|
rubygems_version: 1.8.10
|