canery 0.1.3 → 0.1.4

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/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Canery
2
- Canery is a simple and easy to use key/value store with several commands to store and retrieve data. As the backend uses [Sequel](https://github.com/jeremyevans/sequel/) for persistence, Canery can be used in virtually any environment where a SQL database is available. (For more information please check out the section in the Sequel documentation with the available database adapters.)
2
+ Canery is a simple and easy to use key/value store with several commands to store and retrieve data. Canery uses [Sequel](https://github.com/jeremyevans/sequel/) for persistence, so it can be used in virtually any environment where a SQL database is available. (For more information about the available database adapters please check out the appropriate section in the Sequel documentation.)
3
3
 
4
4
  ## Installation
5
5
  gem install canery
@@ -29,6 +29,9 @@ Canery provides a simple and understandable API which is a bit inspired by Redis
29
29
 
30
30
  # Get this complex value
31
31
  store.get("demo_hash") # => {:first_name => "John", :last_name => "Doe"}
32
+
33
+ # If you set nil as key, Canery builds a uuid-key for you
34
+ store.set(nil, "oh my god, no key given!") # => "2cf7541a-00c1-4bda-8c75-fc32a5f5fac7"
32
35
 
33
36
  For more information consider the wiki. (Comming soon... I promise!)
34
37
 
@@ -37,7 +40,7 @@ Due to the nature of SQL databases it's (almost) impossible for Canery to be as
37
40
 
38
41
  ## Information about data types
39
42
  ### Keys & Tub names
40
- Theoretically every string can be used as a key/tub name, from a string like "foo" to the content of a JPEG file. Even an empty string is a valid key. But for better performance, short keys should be your first choice.
43
+ Theoretically every string can be used as a key/tub name, from a string like "foo" to the serialized content of a PNG file. Even an empty string is a valid key/tub name. But for better performance the max key size defaults to 255 characters.
41
44
 
42
45
  Please keep in mind that Canery uses strings for all keys/tub names, so any other data type will be converted to a string!
43
46
 
@@ -11,10 +11,18 @@ module Canery
11
11
 
12
12
  def initialize(connection_uri)
13
13
  raise ArgumentError, "connection_uri must be a String or nil" unless NilClass === connection_uri || String === connection_uri
14
+
14
15
  @connection = connection_uri.nil? ? Sequel.sqlite : Sequel.connect(connection_uri)
15
16
  @namespace_cache = {}
16
17
  end
17
18
 
19
+ # Only expose call method
20
+ def call(command, *args)
21
+ self.send(command, *args)
22
+ end
23
+
24
+ private
25
+
18
26
  # Basic namespace methods #
19
27
  ###########################
20
28
 
@@ -41,8 +49,8 @@ module Canery
41
49
  def namespace?(name)
42
50
  connection.table_exists?(basic_tub_name(name))
43
51
  end
44
-
45
-
52
+
53
+
46
54
  # Methods for get, set, etc. #
47
55
  ##############################
48
56
 
@@ -55,14 +63,14 @@ module Canery
55
63
  raise ArgumentError, "keys argument must be an Array of keys" unless Array === keys
56
64
  keys.map!{ |key| build_key(key) }
57
65
 
58
- # Sort data in the order they appear in the 'keys' Array
66
+ # Sort the data in the order they appear in the 'keys' Array
59
67
  namespace(name).where(:key => keys).sort_by { |element| keys.index(element[:key]) }.map {|dataset| load(dataset[:value]) }
60
68
  end
61
69
 
62
70
  def set(name, key, value)
63
71
  begin
64
72
  namespace(name).insert(:key => build_key(key), :value => dump(value)) && build_key(key)
65
- rescue Sequel::DatabaseError # raised if the key already exists, than update
73
+ rescue Sequel::DatabaseError # key already exists, use update instead
66
74
  update(name, key, value)
67
75
  rescue
68
76
  "ERROR"
@@ -74,7 +82,7 @@ module Canery
74
82
  begin
75
83
  namespace(name).multi_insert(data.map{ |key, value| {:key => build_key(key), :value => dump(value)} }) && "OK"
76
84
  rescue
77
- # Fallback to the slower update method
85
+ # Fallback to the O(n) update method
78
86
  data.each do |key, value|
79
87
  update(name, key, value)
80
88
  end && "OK"
@@ -116,7 +124,7 @@ module Canery
116
124
  end
117
125
 
118
126
  unless limit.nil?
119
- raise ArgumentError, "limit must be a positive Integer" unless Integer === limit
127
+ raise ArgumentError, "limit parameter must be an Integer" unless Integer === limit
120
128
  data = data.limit(limit)
121
129
  end
122
130
  data.map{ |dataset| dataset[:key] }
@@ -126,13 +134,12 @@ module Canery
126
134
  namespace(name).where(:key => build_key(old_key)).limit(1).update(:key => build_key(new_key)) && "OK"
127
135
  end
128
136
 
129
- def length(name)
137
+ def count(name)
130
138
  namespace(name).count
131
139
  end
132
140
 
133
- private
134
-
135
- # Sequel seems to have problems with escaping, so we use Base64 encoding/decoding as a simple work around
141
+ # Sequel seems to have problems with escaping,
142
+ # therefore we use Base64 encoding/decoding as a simple work around
136
143
  def load(data)
137
144
  Marshal.load(Base64.urlsafe_decode64(data))
138
145
  end
@@ -14,27 +14,29 @@ module Canery
14
14
  end
15
15
 
16
16
  def tub(name)
17
- create_tub(tub_name(name)) unless tub?(tub_name(name))
17
+ build_tub_name!(name)
18
+ create_tub(name) unless tub?(name)
18
19
  begin
19
20
  @tub_cache ||= {}
20
- @tub_cache[tub_name(name)] ||= Tub.new(backend, tub_name(name))
21
+ @tub_cache[name] ||= Tub.new(backend, name)
21
22
  rescue
22
23
  raise Canery::CaneryError, "This tub does not exist! You must create it before you can use it."
23
24
  end
24
25
  end
25
26
 
26
27
  def delete_tub(name)
27
- @tub_cache.delete(tub_name(name)) if @tub_cache[tub_name(name)]
28
- backend.delete_namespace(tub_name(name))
28
+ build_tub_name!(name)
29
+ @tub_cache.delete(name) if @tub_cache[name]
30
+ backend.call(:delete_namespace, name)
29
31
  end
30
32
 
31
33
  def has_tub?(name)
32
- backend.namespace?(tub_name(name))
34
+ backend.call(:namespace?, name)
33
35
  end
34
36
  alias :tub? :has_tub?
35
37
 
36
38
  def tubs
37
- backend.namespaces
39
+ backend.call(:namespaces)
38
40
  end
39
41
 
40
42
  private
@@ -45,14 +47,14 @@ module Canery
45
47
 
46
48
  def create_tub(name)
47
49
  begin
48
- backend.create_namespace(tub_name(name))
50
+ backend.call(:create_namespace, name)
49
51
  rescue => exception
50
52
  raise Canery::CaneryError, exception
51
53
  end
52
54
  end
53
55
 
54
- def tub_name(name)
55
- name.to_s.strip
56
+ def build_tub_name!(name)
57
+ name.to_s.strip!
56
58
  end
57
59
 
58
60
  end
@@ -14,60 +14,61 @@ module Canery
14
14
  end
15
15
 
16
16
  def get(key)
17
- backend.get(name, key)
17
+ backend.call(:get, name, key)
18
18
  end
19
19
  alias :[] :get
20
20
 
21
21
  def mget(keys)
22
- backend.mget(name, keys)
22
+ backend.call(:mget, name, keys)
23
23
  end
24
24
 
25
25
  def set(key, value)
26
- backend.set(name, key || uuid, value)
26
+ backend.call(:set, name, key || uuid, value)
27
27
  end
28
28
  alias :[]= :set
29
29
 
30
30
  def mset(data)
31
- backend.mset(name, data)
31
+ backend.call(:mset, name, data)
32
32
  end
33
33
 
34
34
  def delete(key)
35
- backend.delete(name, key)
35
+ backend.call(:delete, name, key)
36
36
  end
37
37
 
38
38
  def clear
39
- backend.clear(name)
39
+ backend.call(:clear, name)
40
40
  end
41
41
 
42
42
  def has_key?(key)
43
- backend.has_key?(name, key)
43
+ backend.call(:has_key?, name, key)
44
44
  end
45
45
  alias :key? :has_key?
46
46
 
47
47
  def keys
48
- backend.keys(name)
48
+ backend.call(:keys, name)
49
49
  end
50
50
 
51
51
  def values
52
- backend.values(name)
52
+ backend.call(:values, name)
53
53
  end
54
54
 
55
55
  def sort(order, limit = nil)
56
56
  begin
57
- backend.sort(name, order, limit)
58
- rescue ArgumentError
59
- raise Canery::CaneryError, "limit parameter must be an Integer"
57
+ backend.call(:sort, name, order, limit)
58
+ rescue ArgumentError => e
59
+ raise Canery::CaneryError, e
60
60
  end
61
61
  end
62
62
 
63
63
  def rename(old_key, new_key)
64
- backend.rename(name, old_key, new_key)
64
+ backend.call(:rename, name, old_key, new_key)
65
65
  end
66
66
 
67
67
  def length
68
- backend.length(name)
68
+ backend.call(:count, name)
69
69
  end
70
70
  alias :size :length
71
+ alias :count :length
71
72
 
72
73
  private
73
74
 
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Canery
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.4"
5
5
  end
@@ -73,6 +73,15 @@ describe Canery::Tub do
73
73
  store.get(key).should == value
74
74
  end
75
75
  end
76
+
77
+ it "should overwrite alread set values" do
78
+ store = @client.tub("store")
79
+ store.mset(demo_hash).should == "OK"
80
+ store.mset(second_demo_hash).should == "OK"
81
+ second_demo_hash.each do |key, value|
82
+ store.get(key).should == value
83
+ end
84
+ end
76
85
  end
77
86
  end
78
87
 
@@ -6,4 +6,8 @@ end
6
6
 
7
7
  def demo_hash
8
8
  {"homer" => "Homer Simpson", "marge" => "Marge Simpson", "lisa" => "Lisa Simpson", "bart" => "Bart Simpson", "maggy" => "Maggy Simpson"}
9
+ end
10
+
11
+ def second_demo_hash
12
+ {"homer" => "Simpson Homer", "marge" => "Simpson Marge", "lisa" => "Simpson Lisa", "bart" => "Simpson Bart", "maggy" => "Simpson Maggy"}
9
13
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canery
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-25 00:00:00.000000000 Z
12
+ date: 2012-08-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sequel
@@ -94,7 +94,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
94
94
  version: '0'
95
95
  segments:
96
96
  - 0
97
- hash: -281279343697412722
97
+ hash: -3305371081524146636
98
98
  required_rubygems_version: !ruby/object:Gem::Requirement
99
99
  none: false
100
100
  requirements:
@@ -103,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
103
  version: '0'
104
104
  segments:
105
105
  - 0
106
- hash: -281279343697412722
106
+ hash: -3305371081524146636
107
107
  requirements: []
108
108
  rubyforge_project:
109
109
  rubygems_version: 1.8.24