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.
- data/LICENSE +20 -0
- data/README.md +53 -0
- data/lib/ozy.rb +97 -0
- data/spec/ozy_spec.rb +106 -0
- data/spec/spec_helper.rb +2 -0
- 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
|
data/spec/spec_helper.rb
ADDED
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
|