remodel 0.3.0 → 0.3.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/README.md +4 -3
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/example/book.rb +1 -1
- data/lib/remodel/entity.rb +26 -8
- data/test/test_entity.rb +1 -1
- data/test/test_entity_shortnames.rb +36 -0
- metadata +10 -9
- data/bin/redis-monitor.rb +0 -25
data/README.md
CHANGED
@@ -10,6 +10,7 @@ entities are serialized to json and stored as fields in a redis hash. using diff
|
|
10
10
|
for example.
|
11
11
|
|
12
12
|
|
13
|
+
|
13
14
|
## why redis?
|
14
15
|
|
15
16
|
redis offers in-memory read and write performance — on the order of 10K to 100K
|
@@ -51,7 +52,7 @@ define your domain model [like this](http://github.com/tlossen/remodel/blob/mast
|
|
51
52
|
|
52
53
|
class Book < Remodel::Entity
|
53
54
|
has_many :chapters, :class => 'Chapter', :reverse => :book
|
54
|
-
property :title, :class => 'String'
|
55
|
+
property :title, :short => 't', :class => 'String'
|
55
56
|
property :year, :class => 'Integer'
|
56
57
|
property :author, :class => 'String', :default => '(anonymous)'
|
57
58
|
end
|
@@ -75,7 +76,7 @@ now you can do:
|
|
75
76
|
all entities have been created in the redis hash 'shelf' we have used as context:
|
76
77
|
|
77
78
|
>> Remodel.redis.hgetall 'shelf'
|
78
|
-
=> {"b"=>"1", "b1"=>"{\"
|
79
|
+
=> {"b"=>"1", "b1"=>"{\"t\":\"Moby Dick\",\"year\":1851}", "c"=>"1",
|
79
80
|
"c1"=>"{\"title\":\"Ishmael\"}", "c1_book"=>"b1", "b1_chapters"=>"[\"c1\"]"}
|
80
81
|
|
81
82
|
## inspired by
|
@@ -102,4 +103,4 @@ it has some rough edges, but i have successfully been using remodel in productio
|
|
102
103
|
|
103
104
|
## license
|
104
105
|
|
105
|
-
[MIT](http://github.com/tlossen/remodel/raw/master/LICENSE)
|
106
|
+
[MIT](http://github.com/tlossen/remodel/raw/master/LICENSE)
|
data/Rakefile
CHANGED
@@ -5,8 +5,8 @@ begin
|
|
5
5
|
require 'jeweler'
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
7
|
gem.name = "remodel"
|
8
|
-
gem.summary = "
|
9
|
-
gem.description = "persist your objects to redis hashes
|
8
|
+
gem.summary = "a minimal ORM (object-redis-mapper)"
|
9
|
+
gem.description = "persist your objects to redis hashes"
|
10
10
|
gem.email = "tim@lossen.de"
|
11
11
|
gem.homepage = "http://github.com/tlossen/remodel"
|
12
12
|
gem.authors = ["Tim Lossen"]
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.1
|
data/example/book.rb
CHANGED
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + "/../lib/remodel"
|
|
2
2
|
|
3
3
|
class Book < Remodel::Entity
|
4
4
|
has_many :chapters, :class => 'Chapter', :reverse => :book
|
5
|
-
property :title, :class => 'String'
|
5
|
+
property :title, :short => 't', :class => 'String'
|
6
6
|
property :year, :class => 'Integer'
|
7
7
|
property :author, :class => 'String', :default => '(anonymous)'
|
8
8
|
end
|
data/lib/remodel/entity.rb
CHANGED
@@ -83,6 +83,7 @@ module Remodel
|
|
83
83
|
def self.property(name, options = {})
|
84
84
|
name = name.to_sym
|
85
85
|
mapper[name] = Remodel.mapper_for(options[:class])
|
86
|
+
define_shortname(name, options[:short])
|
86
87
|
default_value = options[:default]
|
87
88
|
define_method(name) { @attributes[name].nil? ? self.class.copy_of(default_value) : @attributes[name] }
|
88
89
|
define_method("#{name}=") { |value| @attributes[name] = value }
|
@@ -186,31 +187,48 @@ module Remodel
|
|
186
187
|
def self.pack(attributes)
|
187
188
|
result = {}
|
188
189
|
attributes.each do |name, value|
|
189
|
-
|
190
|
+
short = shortname[name] || name
|
191
|
+
result[short] = mapper[name].pack(value)
|
190
192
|
end
|
191
193
|
result
|
192
194
|
end
|
193
195
|
|
194
196
|
def self.unpack(attributes)
|
195
197
|
result = {}
|
196
|
-
attributes.each do |
|
197
|
-
|
198
|
+
attributes.each do |short, value|
|
199
|
+
short = short.to_sym
|
200
|
+
name = fullname[short] || short
|
198
201
|
result[name] = mapper[name].unpack(value) if mapper[name]
|
199
202
|
end
|
200
203
|
result
|
201
204
|
end
|
202
205
|
|
203
|
-
|
206
|
+
def self.copy_of(value)
|
207
|
+
value.is_a?(Array) || value.is_a?(Hash) ? value.dup : value
|
208
|
+
end
|
209
|
+
|
210
|
+
def self.define_shortname(name, short)
|
211
|
+
return unless short
|
212
|
+
short = short.to_sym
|
213
|
+
shortname[name] = short
|
214
|
+
fullname[short] = name
|
215
|
+
end
|
216
|
+
|
217
|
+
# class instance variables (lazy init)
|
204
218
|
def self.mapper
|
205
219
|
@mapper ||= {}
|
206
220
|
end
|
207
221
|
|
208
|
-
def self.
|
209
|
-
@
|
222
|
+
def self.shortname
|
223
|
+
@shortname ||= {}
|
210
224
|
end
|
211
225
|
|
212
|
-
def self.
|
213
|
-
|
226
|
+
def self.fullname
|
227
|
+
@fullname ||= {}
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.associations
|
231
|
+
@associations ||= []
|
214
232
|
end
|
215
233
|
|
216
234
|
end
|
data/test/test_entity.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestEntityShortnames < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class Bar < Remodel::Entity
|
6
|
+
property :foo, :short => 'z'
|
7
|
+
end
|
8
|
+
|
9
|
+
context "[short names]" do
|
10
|
+
setup do
|
11
|
+
@bar = Bar.create('cx', :foo => 42)
|
12
|
+
end
|
13
|
+
|
14
|
+
should "be used when storing properties" do
|
15
|
+
serialized = redis.hget('cx', @bar.key)
|
16
|
+
assert !serialized.match(/foo/)
|
17
|
+
assert serialized.match(/z/)
|
18
|
+
end
|
19
|
+
|
20
|
+
should "work in roundtrip" do
|
21
|
+
@bar.reload
|
22
|
+
assert_equal 42, @bar.foo
|
23
|
+
end
|
24
|
+
|
25
|
+
should "not be used in as_json" do
|
26
|
+
assert !@bar.as_json.has_key?(:z)
|
27
|
+
assert @bar.as_json.has_key?(:foo)
|
28
|
+
end
|
29
|
+
|
30
|
+
should "not be used in inspect" do
|
31
|
+
assert !@bar.inspect.match(/z/)
|
32
|
+
assert @bar.inspect.match(/foo/)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
8
|
+
- 1
|
9
|
+
version: 0.3.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Tim Lossen
|
@@ -14,14 +14,14 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
18
|
-
default_executable:
|
17
|
+
date: 2011-06-16 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
21
|
-
description: persist your objects to redis hashes
|
21
|
+
description: persist your objects to redis hashes
|
22
22
|
email: tim@lossen.de
|
23
|
-
executables:
|
24
|
-
|
23
|
+
executables: []
|
24
|
+
|
25
25
|
extensions: []
|
26
26
|
|
27
27
|
extra_rdoc_files:
|
@@ -32,7 +32,6 @@ files:
|
|
32
32
|
- README.md
|
33
33
|
- Rakefile
|
34
34
|
- VERSION
|
35
|
-
- bin/redis-monitor.rb
|
36
35
|
- docs/docco.css
|
37
36
|
- docs/remodel.html
|
38
37
|
- example/book.rb
|
@@ -44,6 +43,7 @@ files:
|
|
44
43
|
- test/test_entity.rb
|
45
44
|
- test/test_entity_defaults.rb
|
46
45
|
- test/test_entity_delete.rb
|
46
|
+
- test/test_entity_shortnames.rb
|
47
47
|
- test/test_many_to_many.rb
|
48
48
|
- test/test_many_to_one.rb
|
49
49
|
- test/test_mappers.rb
|
@@ -81,12 +81,13 @@ rubyforge_project:
|
|
81
81
|
rubygems_version: 1.3.7
|
82
82
|
signing_key:
|
83
83
|
specification_version: 3
|
84
|
-
summary:
|
84
|
+
summary: a minimal ORM (object-redis-mapper)
|
85
85
|
test_files:
|
86
86
|
- test/helper.rb
|
87
87
|
- test/test_entity.rb
|
88
88
|
- test/test_entity_defaults.rb
|
89
89
|
- test/test_entity_delete.rb
|
90
|
+
- test/test_entity_shortnames.rb
|
90
91
|
- test/test_many_to_many.rb
|
91
92
|
- test/test_many_to_one.rb
|
92
93
|
- test/test_mappers.rb
|
data/bin/redis-monitor.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# http://gist.github.com/267149 (mathias meyer)
|
4
|
-
|
5
|
-
require 'socket'
|
6
|
-
host = ARGV[0] || 'localhost'
|
7
|
-
port = ARGV[1] || '6379'
|
8
|
-
|
9
|
-
trap(:INT) {
|
10
|
-
exit
|
11
|
-
}
|
12
|
-
|
13
|
-
puts "Connecting to #{host}:#{port}"
|
14
|
-
begin
|
15
|
-
sock = TCPSocket.new(host, port)
|
16
|
-
sock.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
|
17
|
-
|
18
|
-
sock.write("monitor\r\n")
|
19
|
-
|
20
|
-
while line = sock.gets
|
21
|
-
puts line
|
22
|
-
end
|
23
|
-
rescue Errno::ECONNREFUSED
|
24
|
-
puts "Connection refused"
|
25
|
-
end
|