abbey 0.1.0.beta3 → 0.1.1
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/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
|