ozy 0.0.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.
Files changed (6) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +53 -0
  3. data/lib/ozy.rb +97 -0
  4. data/spec/ozy_spec.rb +106 -0
  5. data/spec/spec_helper.rb +2 -0
  6. metadata +119 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Flip Sasser
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,53 @@
1
+ Addressabler
2
+ =
3
+
4
+ **Addressabler** extends the Addressable::URI class by adding TLD parsing, domain and subdomain parsing, and query modification.
5
+
6
+ Install
7
+ ==
8
+
9
+ Install using Rubygems:
10
+
11
+ gem install addressabler
12
+
13
+ Then:
14
+
15
+ require 'rubygems'
16
+ require 'addressabler'
17
+
18
+ Addressabler will automatically require `addressable/uri`.
19
+
20
+ Usage
21
+ ==
22
+
23
+ Use Addressable::URI like you normally would:
24
+
25
+ @uri = Addressable::URI.parse("http://www.google.com/")
26
+ @uri.host #=> "www.google.com"
27
+
28
+ Addressabler will add the following properties:
29
+
30
+ @uri.tld #=> "com"
31
+ @uri.domain #=> "google"
32
+ @uri.subdomain #=> "www"
33
+
34
+ You can set these values, as well:
35
+
36
+ @uri.tld = "org"
37
+ @uri.host #=> "www.google.org"
38
+ @uri.domain = "amazon"
39
+ @uri.host #=> "www.amazon.org"
40
+ @uri.subdomain = "developers"
41
+ @uri.host #=> "developers.amazon.org"
42
+
43
+ Addressabler copies some of Paul Dix's [Domaintrix](https://github.com/pauldix/domainatrix) TLD code to support fancy TLDs, as well:
44
+
45
+ @uri.host = "www.google.co.uk"
46
+ @uri.tld #=> "co.uk"
47
+
48
+ Addressabler also makes editing queries a little bit easier:
49
+
50
+ @uri.query_hash[:foo] = :bar
51
+ @uri.to_s #=> "http://www.google.co.uk/?foo=bar"
52
+
53
+ That's it. Enjoy.
data/lib/ozy.rb ADDED
@@ -0,0 +1,97 @@
1
+ require 'digest/sha1'
2
+ require 'redis'
3
+
4
+ class Ozy < ::Hash
5
+ class KeyError < ::StandardError; end
6
+
7
+ class << self
8
+ def connection
9
+ @connection ||= ::Redis.new
10
+ end
11
+
12
+ def connection=(new_connection)
13
+ @connection = new_connection
14
+ end
15
+
16
+ def create(key, attributes = {}, options = {})
17
+ instance = new(attributes, options.merge(:key => key))
18
+ instance.save
19
+ instance
20
+ end
21
+
22
+ def destroy(key)
23
+ connection.del(key)
24
+ end
25
+
26
+ def get(key)
27
+ if response = connection.get(key)
28
+ new(Marshal.load(response), :key => key)
29
+ end
30
+ end
31
+ end
32
+
33
+ def []=(key, value)
34
+ super
35
+ update_parent
36
+ end
37
+
38
+ def destroy
39
+ self.class.destroy(@options[:key])
40
+ end
41
+
42
+ def delete(value)
43
+ super
44
+ update_parent
45
+ end
46
+
47
+ def expire_in!(time)
48
+ if persisted?
49
+ save(@options[:key], :expire => time)
50
+ else
51
+ @options[:expire] = time
52
+ end
53
+ end
54
+
55
+ def expires_in
56
+ persisted? ? ttl : @options[:expire]
57
+ end
58
+
59
+ def initialize(attributes = {}, options = {})
60
+ @options = options
61
+ merge! attributes unless attributes.empty?
62
+ end
63
+
64
+ def merge!(*args)
65
+ super
66
+ update_parent
67
+ end
68
+
69
+ def persisted?
70
+ !!@persisted
71
+ end
72
+
73
+ def save(key = nil, options = {})
74
+ raise KeyError.new("You must supply a key to save a Redis-backed hash!") unless key ||= @options[:key]
75
+ options = @options.merge(options)
76
+ if options[:expire]
77
+ self.class.connection.setex(key, options[:expire], Marshal.dump(to_hash))
78
+ else
79
+ self.class.connection.set(key, Marshal.dump(to_hash))
80
+ end
81
+ @options[:key] = key
82
+ @persisted = true
83
+ end
84
+
85
+ private
86
+ def method_missing(method, *args)
87
+ if @options[:key] && self.class.connection.respond_to?(method)
88
+ self.class.connection.send(method, *[@options[:key], args].flatten)
89
+ else
90
+ super
91
+ end
92
+ end
93
+
94
+ def update_parent
95
+ save if persisted?
96
+ end
97
+ end
data/spec/ozy_spec.rb ADDED
@@ -0,0 +1,106 @@
1
+ require "spec_helper"
2
+ require "ozy"
3
+ require "redis/distributed"
4
+
5
+ describe Ozy do
6
+ it "should automatically connect using Redis defaults" do
7
+ Ozy.connection.should be_instance_of(Redis)
8
+ end
9
+
10
+ it "should let me set a connection manually" do
11
+ lambda {
12
+ Ozy.connection = Redis::Distributed.new('0.0.0.0')
13
+ }.should_not raise_error
14
+ Ozy.connection.should be_instance_of(Redis::Distributed)
15
+ end
16
+
17
+ it "should let me instantiate easily" do
18
+ Ozy.connection.should_not_receive(:set)
19
+ ozy = Ozy.new(:foo => :bar, :baz => "whaaaaaaat??")
20
+ end
21
+
22
+ it "should let me instantiate with an expiration" do
23
+ ozy = Ozy.new({:foo => :bar}, :expire => 60)
24
+ ozy.expires_in.should == 60
25
+ end
26
+
27
+ it "should let me persist the Ozy" do
28
+ ozy = Ozy.new(:foo => :bar)
29
+ ozy.save("ozy")
30
+ ozy.persisted?.should be_true
31
+ end
32
+
33
+ it "should let me retrieve an Ozy" do
34
+ ozy = Ozy.new(:bill => "lumbergh")
35
+ ozy.save("ozy")
36
+ Ozy.get("ozy").should == {:bill => "lumbergh"}
37
+ end
38
+
39
+ it "should let me delete an Ozy" do
40
+ ozy = Ozy.new(:bill => :lumbergh)
41
+ ozy.save("ozy")
42
+ ozy.destroy
43
+ Ozy.get("ozy").should be_nil
44
+ end
45
+
46
+ it "should let me set an expiration" do
47
+ ozy = Ozy.new(:foo => :bar)
48
+ ozy.expire_in!(60)
49
+ ozy.expires_in.should == 60
50
+ end
51
+
52
+ it "should fetch the real expiration for saved Ozy's" do
53
+ ozy = Ozy.new(:foo => :bar)
54
+ ozy.expire_in!(60)
55
+ ozy.save("ozy")
56
+ sleep 1
57
+ ozy.expires_in.should == 59
58
+ end
59
+
60
+ it "should re-set real expiration for saved Ozy's" do
61
+ ozy = Ozy.new(:foo => :bar)
62
+ ozy.expire_in!(60)
63
+ ozy.save("ozy")
64
+ ozy.expires_in.should == 60
65
+ ozy.expire_in!(120)
66
+ ozy.expires_in.should == 120
67
+ end
68
+
69
+ it "should update itself whenever a change occurs on the Hash" do
70
+ ozy = Ozy.new(:foo => :bar)
71
+ ozy.save("ozy")
72
+ ozy.merge!(:foo => "baz")
73
+ Ozy.get("ozy").should == {:foo => "baz"}
74
+ ozy.delete(:foo)
75
+ Ozy.get("ozy").should be_empty
76
+ ozy[:foo] = "bar"
77
+ Ozy.get("ozy").should == {:foo => "bar"}
78
+ end
79
+
80
+ it "should let me initialize and save in one step" do
81
+ ozy = Ozy.create("ozy", {:foo => :bar})
82
+ ozy.should be_instance_of(Ozy)
83
+ ozy.persisted?.should be_true
84
+ Ozy.get("ozy").should_not be_nil
85
+ end
86
+
87
+ it "should support some Redis methods seamlessly" do
88
+ ozy = Ozy.create("ozy", :foo => :bar)
89
+ lambda {
90
+ ozy.del
91
+ }.should_not raise_error
92
+ Ozy.get("ozy").should be_nil
93
+ end
94
+
95
+ it "should not just catch every method call you throw at it" do
96
+ ozy = Ozy.create("ozy", :foo => :bar)
97
+ lambda {
98
+ ozy.can_has? :cheezburger
99
+ }.should raise_error
100
+ end
101
+
102
+ it "should preserve symbols and other fun stuff" do
103
+ ozy = Ozy.create("ozy", :foo => {:bar => [:baz]})
104
+ Ozy.get("ozy").should == {:foo => {:bar => [:baz]}}
105
+ end
106
+ end
@@ -0,0 +1,2 @@
1
+ require 'rspec/core'
2
+ require 'rspec/autorun'
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ozy
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Flip Sasser
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-01-04 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rcov
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 41
30
+ segments:
31
+ - 0
32
+ - 9
33
+ - 9
34
+ version: 0.9.9
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 2
48
+ - 0
49
+ version: "2.0"
50
+ type: :development
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: redis
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 9
61
+ segments:
62
+ - 2
63
+ - 1
64
+ - 1
65
+ version: 2.1.1
66
+ type: :runtime
67
+ version_requirements: *id003
68
+ description: "\n Ozymandias (or \"Ozy\" for short) allows you to use a Hash normally, but to have its changes persisted to Redis. It's very simple and very awesome.\n "
69
+ email: flip@x451.com
70
+ executables: []
71
+
72
+ extensions: []
73
+
74
+ extra_rdoc_files:
75
+ - LICENSE
76
+ - README.md
77
+ files:
78
+ - LICENSE
79
+ - lib/ozy.rb
80
+ - README.md
81
+ - spec/ozy_spec.rb
82
+ - spec/spec_helper.rb
83
+ has_rdoc: true
84
+ homepage: http://github.com/flipsasser/ozymandias
85
+ licenses: []
86
+
87
+ post_install_message:
88
+ rdoc_options: []
89
+
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ hash: 3
98
+ segments:
99
+ - 0
100
+ version: "0"
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ hash: 3
107
+ segments:
108
+ - 0
109
+ version: "0"
110
+ requirements: []
111
+
112
+ rubyforge_project:
113
+ rubygems_version: 1.3.7
114
+ signing_key:
115
+ specification_version: 3
116
+ summary: A Redis-backed Hash class that can be used like a very (very, very) simple ORM
117
+ test_files:
118
+ - spec/ozy_spec.rb
119
+ - spec/spec_helper.rb