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 CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "abbey"
8
- s.version = "0.1.0.beta3"
8
+ s.version = "0.1.1"
9
9
 
10
- s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
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-13"
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 = [
@@ -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.new if File.exist?(path)
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.new unless exists?(namespace, key)
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.new unless exists?(namespace, key)
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
- # Thrown when trying to overwrite an item
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
@@ -2,8 +2,8 @@ module Abbey
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- PATCH = 0
6
- BUILD = 'beta3'
5
+ PATCH = 1
6
+ BUILD = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
9
9
  end
@@ -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.0.beta3
5
- prerelease: 6
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-13 00:00:00.000000000 Z
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: &13335600 !ruby/object:Gem::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: *13335600
24
+ version_requirements: *6562960
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &13334660 !ruby/object:Gem::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: *13334660
35
+ version_requirements: *6560780
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bundler
38
- requirement: &13333200 !ruby/object:Gem::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: *13333200
46
+ version_requirements: *6559960
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: jeweler
49
- requirement: &13332360 !ruby/object:Gem::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: *13332360
57
+ version_requirements: *6610240
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rcov
60
- requirement: &13331340 !ruby/object:Gem::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: *13331340
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: -2996718355299514668
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: 1.3.1
113
+ version: '0'
114
114
  requirements: []
115
115
  rubyforge_project:
116
116
  rubygems_version: 1.8.10