zebris 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d82aa602d7e4e5640c78087c63c0707c0301dbb0
4
- data.tar.gz: 85bda8fd3143cd50cfa3e0b43af3e216a2fcc287
3
+ metadata.gz: 3b41c71b77c9cb0ad27d3ebc402203f2d0900a04
4
+ data.tar.gz: 12550a668b6b8701e9923b6764b3cc7ab00a6ef7
5
5
  SHA512:
6
- metadata.gz: 582d250221952c4a7694fb069681a8d2792b140ad8b25e76546d1128bb97c3d4d50d5dd3025093f344bee9ac22b34788d47bfe98c1eaefe2e89efc84829ba6ba
7
- data.tar.gz: d56c3bf257822fd2165abced26b19bb7dcb434bc5e576bf6d2305be58bd76fb3634dd47d42865b1e344dcc44317f781abb7ce39448acbe054ee134598bad52fb
6
+ metadata.gz: 03dec832c90d045b163edab0d0bc4748db9211fb07254ebe4058417675639339239ef23f37f5ae8f9aa125ebd4f7ce1b0975230052016fcb92bb5a785f04a840
7
+ data.tar.gz: 9b7be6818cbbf39b4298b1a67d518ab55d8c356ddc99881d83dafd6995976e7ad1bdb20893bed0f9725dab12151c7d2d506ed199bcfc0a7d9b65dcec3cb80e25
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Gem Version](https://badge.fury.io/rb/zebris.png)](http://badge.fury.io/rb/zebris)
2
+
1
3
  # Zebris
2
4
 
3
5
  Zebris is built to allow you to add persisting and retrieving your objects to and from Redis with a minimum of hassle or re-writing of your code.
@@ -58,6 +60,69 @@ Zebris is happy to delegate to any Redis client that supports the 2.0+ command l
58
60
 
59
61
  # Tyler is back
60
62
 
63
+ ### Custom serialization/deserialization
64
+
65
+ class WaterSample
66
+ include Zebris::Document
67
+
68
+ key {UUID.generate} # Or anything that will generate unique keys
69
+
70
+ # Redis likes strings, so you can provide a proc to serialize
71
+ # and deserialize your data to/from strings if it doesn't fit
72
+ # the built-in types
73
+ property :subject, String
74
+ property :time, lambda {|time| time.to_i.to_s}, lambda {|milli| Time.at(milli.to_i)}
75
+ property :measurement, lambda {|m| "#{m.value}:#{m.units}"}, lambda {|m| value,units = m.split(/:/); Measurement.new(value.to_f, units)}
76
+ end
77
+
78
+ sample = WaterSample.new
79
+ sample.subject = "Arsenic Levels"
80
+ sample.time = Time.now
81
+ sample.measurement = Measurement.new(0.05, "ppm")
82
+
83
+ key = sample.save
84
+ => "some uuid here"
85
+
86
+ last_sample = Sample.find(key)
87
+
88
+ ### Embedded Documents
89
+ There is also support for embedded documents. If you declare a property with a type that includes Zebris::Document, what
90
+ you will get is an embedded serialization of the property when you save. This is different than a relational model where
91
+ the two documents are stored separately and related together via keys.
92
+
93
+ class Listing
94
+ include Zebris::Document
95
+
96
+ key {UUID.generate}
97
+
98
+ collection :people, Person
99
+
100
+ class Person
101
+ include Zebris::Document
102
+
103
+ # No key needed since this is embedded
104
+
105
+ property :name, String
106
+ property :age, Integer
107
+
108
+ def initialize(name, age)
109
+ @name = name
110
+ @age = age
111
+ end
112
+ end
113
+ end
114
+
115
+ l = Listing.new
116
+ l.people << Listing::Person.new("John", 30)
117
+ l.people << Listing::Person.new("Mary", 28)
118
+
119
+ key = l.save
120
+
121
+ # ... some time later ...
122
+ l2 = Listing.find(key)
123
+
124
+ # Our listings are back
125
+
61
126
  ## Contributing
62
127
 
63
128
  1. Fork it
@@ -37,23 +37,29 @@ module Zebris
37
37
  end
38
38
  end
39
39
 
40
- def serialize(object)
41
- attributes = {"key" => object.key}
40
+ def serialize(object, embed = false)
41
+ attributes = (embed ? {} : {"key" => object.key})
42
42
 
43
43
  properties.each do |property, conversion|
44
44
  if val = object.send(property.to_sym)
45
45
  if conversion.kind_of?(Zebris::Types::GenericConverter)
46
46
  attributes[property.to_s] = conversion.serializer.call(val)
47
47
  else
48
- attributes[property.to_s] = conversion.serialize(val)
48
+ if conversion.ancestors.include?(Zebris::Document)
49
+ attributes[property.to_s] = conversion.serialize(val, true)
50
+ else
51
+ attributes[property.to_s] = conversion.serialize(val)
52
+ end
49
53
  end
50
54
  end
51
55
  end
52
56
 
53
57
  collections.each do |property, klass|
58
+ raise "#{klass} does not implement the Zebris::Document interface" unless klass.ancestors.include?(Zebris::Document)
59
+
54
60
  attributes[property] ||= []
55
61
  object.send(:instance_variable_get, :"@#{property}").each do |record|
56
- attributes[property] << record.serialize
62
+ attributes[property] << klass.serialize(record, true)
57
63
  end
58
64
  end
59
65
 
@@ -137,7 +143,10 @@ module Zebris
137
143
 
138
144
  def collection(name, klass)
139
145
  collections[name] = klass
140
- self.send(:attr_accessor, name)
146
+ self.send(:attr_writer, name)
147
+ self.send(:define_method, :"#{name}") {
148
+ self.send(:instance_variable_get, :"@#{name}") || self.send(:instance_variable_set, :"@#{name}", [])
149
+ }
141
150
  end
142
151
  end
143
152
  end
@@ -1,3 +1,3 @@
1
1
  module Zebris
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -34,6 +34,32 @@ describe Zebris::Document do
34
34
  end
35
35
  end
36
36
 
37
+ class CollectionDocument
38
+ include Zebris::Document
39
+
40
+ key {UUID.generate}
41
+
42
+ collection :people, Person
43
+
44
+ class Person
45
+ include Zebris::Document
46
+
47
+ property :name, String
48
+ property :age, Integer
49
+ end
50
+ end
51
+
52
+ class InvalidCollectionDocument
53
+ include Zebris::Document
54
+
55
+ key {UUID.generate}
56
+
57
+ collection :people, Person
58
+
59
+ class Person
60
+ end
61
+ end
62
+
37
63
  let!(:redis) {double(:redis, set: "OK", get: true)}
38
64
  let(:key) {"ABCDEFG"}
39
65
  let(:name) {"John Henry"}
@@ -89,7 +115,7 @@ describe Zebris::Document do
89
115
  person.age = age
90
116
  person.stub(:key).and_return(person_key)
91
117
 
92
- redis.should_receive(:set).with(key, {"key" => key, "person" => {"key" => person_key, "name" => name, "age" => age}}.to_json)
118
+ redis.should_receive(:set).with(key, {"key" => key, "person" => {"name" => name, "age" => age}}.to_json)
93
119
 
94
120
  document = NestedDocument.new
95
121
  document.stub(:key).and_return(key)
@@ -113,6 +139,31 @@ describe Zebris::Document do
113
139
  }.to raise_exception
114
140
  end
115
141
  end
142
+
143
+ context "collections" do
144
+ it "serializes each item in a collection properly" do
145
+ document = CollectionDocument.new
146
+ document.stub(:key).and_return(key)
147
+ redis.should_receive(:set).with(key, {"key" => key, "people" => [{"name" => name, "age" => age}]}.to_json)
148
+
149
+ p = CollectionDocument::Person.new
150
+ p.name = name
151
+ p.age = age
152
+
153
+ document.people << p
154
+ document.save
155
+ end
156
+
157
+ it "raises an error if the serialization type does not support the Zebris::Document interface" do
158
+ document = InvalidCollectionDocument.new
159
+ document.stub(:key).and_return(key)
160
+ document.people << InvalidCollectionDocument::Person.new
161
+
162
+ expect {
163
+ expect document.save
164
+ }.to raise_exception
165
+ end
166
+ end
116
167
  end
117
168
  end
118
169
 
data/zebris.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["jgailor@gmail.com"]
11
11
  spec.description = %q{Zebris is a library to persist your object data to Redis. Its goal is to be as unobtrusive as possible.}
12
12
  spec.summary = %q{Zebris makes persisting your objects to Redis easy.}
13
- spec.homepage = ""
13
+ spec.homepage = "https://github.com/JGailor/zebris"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zebris
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Gailor
@@ -86,7 +86,7 @@ files:
86
86
  - spec/lib/document_spec.rb
87
87
  - spec/lib/types_spec.rb
88
88
  - zebris.gemspec
89
- homepage: ''
89
+ homepage: https://github.com/JGailor/zebris
90
90
  licenses:
91
91
  - MIT
92
92
  metadata: {}