medea 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require 'rake'
2
+
3
+ begin
4
+ require 'jeweler'
5
+ Jeweler::Tasks.new do |s|
6
+ s.name = "medea"
7
+ s.summary = "Simple wrapper for persisting objects to JasonDB"
8
+ s.email = "michaelj@jasondb.com"
9
+ s.homepage = "https://github.com/rob-linton/Medea"
10
+ s.description = "Simple wrapper for persisting objects to JasonDB"
11
+ s.authors = ["Michael Jensen"]
12
+ s.files = FileList["[A-Z]*", "{lib}/medea.rb", "{lib}/medea/*"]
13
+ s.files.exclude '{lib}/test*'
14
+ s.add_dependency 'json'
15
+ s.add_dependency 'rest-client'
16
+ end
17
+ rescue LoadError
18
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
19
+ end
20
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.2
data/assets.file ADDED
File without changes
data/assets.http ADDED
File without changes
data/index.html ADDED
@@ -0,0 +1,78 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
7
+
8
+ <title>rob-linton/Medea @ GitHub</title>
9
+
10
+ <style type="text/css">
11
+ body {
12
+ margin-top: 1.0em;
13
+ background-color: #28904b;
14
+ font-family: "Helvetica,Arial,FreeSans";
15
+ color: #ffffff;
16
+ }
17
+ #container {
18
+ margin: 0 auto;
19
+ width: 700px;
20
+ }
21
+ h1 { font-size: 3.8em; color: #d76fb4; margin-bottom: 3px; }
22
+ h1 .small { font-size: 0.4em; }
23
+ h1 a { text-decoration: none }
24
+ h2 { font-size: 1.5em; color: #d76fb4; }
25
+ h3 { text-align: center; color: #d76fb4; }
26
+ a { color: #d76fb4; }
27
+ .description { font-size: 1.2em; margin-bottom: 30px; margin-top: 30px; font-style: italic;}
28
+ .download { float: right; }
29
+ pre { background: #000; color: #fff; padding: 15px;}
30
+ hr { border: 0; width: 80%; border-bottom: 1px solid #aaa}
31
+ .footer { text-align:center; padding-top:30px; font-style: italic; }
32
+ </style>
33
+
34
+ </head>
35
+
36
+ <body>
37
+ <a href="http://github.com/rob-linton/Medea"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
38
+
39
+ <div id="container">
40
+
41
+ <div class="download">
42
+ <a href="http://github.com/rob-linton/Medea/zipball/master">
43
+ <img border="0" width="90" src="http://github.com/images/modules/download/zip.png"></a>
44
+ <a href="http://github.com/rob-linton/Medea/tarball/master">
45
+ <img border="0" width="90" src="http://github.com/images/modules/download/tar.png"></a>
46
+ </div>
47
+
48
+ <h1><a href="http://github.com/rob-linton/Medea">Medea</a>
49
+ <span class="small">by <a href="http://github.com/rob-linton">rob-linton</a></span></h1>
50
+
51
+ <div class="description">
52
+ Jasondb library for Ruby
53
+ </div>
54
+
55
+ <p>This is the main site for the Ruby interface to Jasondb. </p><h2>Contact</h2>
56
+ <p>robl@jasondb.com
57
+
58
+
59
+ <h2>Download</h2>
60
+ <p>
61
+ You can download this project in either
62
+ <a href="http://github.com/rob-linton/Medea/zipball/master">zip</a> or
63
+ <a href="http://github.com/rob-linton/Medea/tarball/master">tar</a> formats.
64
+ </p>
65
+ <p>You can also clone the project with <a href="http://git-scm.com">Git</a>
66
+ by running:
67
+ <pre>$ git clone git://github.com/rob-linton/Medea</pre>
68
+ </p>
69
+
70
+ <div class="footer">
71
+ get the source code on GitHub : <a href="http://github.com/rob-linton/Medea">rob-linton/Medea</a>
72
+ </div>
73
+
74
+ </div>
75
+
76
+
77
+ </body>
78
+ </html>
data/lib/medea.rb ADDED
@@ -0,0 +1,8 @@
1
+
2
+ module Medea
3
+ require 'medea/inheritable_attributes'
4
+ require 'medea/jasonobject'
5
+ require 'medea/jasondeferredquery'
6
+ require 'medea/jasonlistproperty'
7
+ require 'medea/jasondb'
8
+ end
@@ -0,0 +1,28 @@
1
+ #This module allows for an attribute to be defined on a superclass and carry down into sub-classes with its default.
2
+ #Taken from http://railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/
3
+
4
+ module ClassLevelInheritableAttributes
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def inheritable_attributes(*args)
11
+ @inheritable_attributes ||= [:inheritable_attributes]
12
+ @inheritable_attributes += args
13
+ args.each do |arg|
14
+ class_eval %(
15
+ class << self; attr_accessor :#{arg} end
16
+ )
17
+ end
18
+ @inheritable_attributes
19
+ end
20
+
21
+ def inherited(subclass)
22
+ @inheritable_attributes.each do |inheritable_attribute|
23
+ instance_var = "@#{inheritable_attribute}"
24
+ subclass.instance_variable_set(instance_var, instance_variable_get(instance_var))
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ module JasonDB
2
+ #jason_url here doesn't include the http[s]:// part, but does include the domain and a trailing '/'
3
+ #( so it's "rest.jasondb.com/<domain>/" )
4
+ attr_accessor :jason_url, :user, :password
5
+
6
+
7
+
8
+ def JasonDB::db_auth_url mode=:secure
9
+ user = "michael"
10
+ jason_url = "rest.jasondb.com/medea-test/"
11
+ password = "password"
12
+ protocol = "http"
13
+ protocol << "s" if mode == :secure
14
+ "#{protocol}://#{user}:#{password}@#{jason_url}"
15
+ end
16
+
17
+ end
@@ -0,0 +1,125 @@
1
+ module Medea
2
+ class JasonDeferredQuery
3
+ require 'rest_client'
4
+
5
+ attr_accessor :time_limit, :result_format, :type, :result_format, :time_limit, :state, :contents, :filters
6
+
7
+ def initialize a_class, format=:json
8
+ @type = a_class
9
+ @filters = {:FILTER => {:HTTP_X_CLASS => a_class.name.to_s}}
10
+ @result_format = format
11
+ @time_limit = 0
12
+ @state = :prefetch
13
+ @contents = []
14
+ end
15
+
16
+ #Here we're going to put the "query" interface
17
+
18
+ #here we will capture:
19
+ #members_of(object) (where object is an instance of a class that this class can be a member of)
20
+ #members_of_<classname>(key)
21
+ #find_by_<property>(value)
22
+ #Will return a JasonDeferredQuery for this class with the appropriate data filter set
23
+ def method_missing(name, *args, &block)
24
+ #if we are postfetch, we throw away all our cached results
25
+ if self.state == :postfetch
26
+ self.state = :prefetch
27
+ self.contents = []
28
+ end
29
+
30
+ if name =~ /^members_of$/
31
+ #use the type and key of the first arg (being a JasonObject)
32
+ #args[0] must be a JasonObject (or child)
33
+ raise ArgumentError, "When looking for members, you must pass a JasonObject" unless args[0].is_a? JasonObject
34
+
35
+ self.filters[:DATA_FILTER] ||= {}
36
+ self.filters[:DATA_FILTER]["__member_of"] ||= []
37
+ self.filters[:DATA_FILTER]["__member_of"] << args[0].jason_key
38
+ elsif name =~ /^find_by_(.*)$/
39
+ #use the property name from the name variable, and the value from the first arg
40
+ add_data_filter $1, args[0].to_s
41
+ else
42
+ #no method!
43
+ super
44
+ return
45
+ end
46
+ #return self, so that we can chain up query refinements
47
+ self
48
+ end
49
+ #end query interface
50
+
51
+ def add_data_filter property, value
52
+ self.filters[:DATA_FILTER] ||= {}
53
+ self.filters[:DATA_FILTER][property] = value
54
+ end
55
+
56
+ def to_url
57
+ url = "#{JasonDB::db_auth_url}@#{self.time_limit}.#{self.result_format}?"
58
+ filter_array = []
59
+ self.filters.each do |name, val|
60
+ if not val
61
+ filter_array << name.to_s
62
+ next
63
+ else
64
+ #FILTER's value is a hash (to avoid dupes)
65
+ #DATA_FILTER's value is a hash
66
+ if val.is_a? Hash
67
+ #for each k/v in the hash, we want to add an entry to filter_array
68
+ val.each do |field ,value|
69
+ if value.is_a? Array
70
+ value.each do |i|
71
+ filter_array << "#{name.to_s}=#{field}:#{i}"
72
+ end
73
+ else
74
+ filter_array << "#{name.to_s}=#{field.to_s}:#{value.to_s}"
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ url + filter_array.join("&")
82
+ end
83
+
84
+ #array access interface
85
+ def [](index)
86
+ execute_query unless self.state == :postfetch
87
+ self.contents[index]
88
+ end
89
+
90
+ def each(&block)
91
+ execute_query unless self.state == :postfetch
92
+ self.contents.each &block
93
+ end
94
+
95
+ def count
96
+ execute_query unless self.state == :postfetch
97
+ self.contents.count
98
+ end
99
+ #end array interface
100
+
101
+ def execute_query
102
+ #hit the URL
103
+ #fill self.contents with :ghost versions of JasonObjects
104
+ begin
105
+ #puts " = Executing #{type.name} deferred query! (#{to_url})"
106
+ result = JSON.parse(RestClient.get to_url)
107
+
108
+ #results are in a hash, their keys are just numbers
109
+ result.keys.each do |k|
110
+ if k =~ /^[0-9]+$/
111
+ #this is a result! get the key
112
+ /\/([^\/]*)\/([^\/]*)$/.match result[k]["POST_TO"]
113
+ #$1 is the class name, $2 is the key
114
+ item = type.new($2, :lazy)
115
+ self.contents << item
116
+ end
117
+ end
118
+ rescue
119
+ self.contents = []
120
+ ensure
121
+ self.state = :postfetch
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,102 @@
1
+ module Medea
2
+ require 'uri'
3
+ require 'rest_client'
4
+ class JasonListProperty < JasonDeferredQuery
5
+
6
+ attr_accessor :list_name, :parent, :list_type
7
+
8
+ def initialize parent, list_name, list_class, list_type
9
+ @type = list_class
10
+ @list_name = list_name
11
+ @list_type = list_type
12
+ @parent = parent
13
+ @result_format = :json
14
+ @time_limit = 0
15
+ @state = :prefetch
16
+ @contents = []
17
+ end
18
+
19
+ def method_missing name, *args, &block
20
+ #is this a list property on the base class?
21
+ if (@type.class_variable_defined? :@@lists) && (@type.class_variable_get(:@@lists).has_key? name)
22
+ #if so, we'll just return a new ListProperty with my query as the parent
23
+ new_list_class, new_list_type = @type.class_variable_get(:@@lists)[name]
24
+ base_query = self.clone
25
+ base_query.result_format = :keylist
26
+ JasonListProperty.new base_query, name.to_sym, new_list_class, new_list_type
27
+ else
28
+ #no method, let JasonDeferredQuery handle it
29
+ super
30
+ end
31
+ end
32
+
33
+ def add! member, save=true
34
+ raise RuntimeError, "You can only add an item if you are accessing this list from an object." unless @parent.is_a? JasonObject
35
+ raise ArgumentError, "You can only add #{@type.name} items to this collection!" unless member.is_a? @type
36
+
37
+ if @list_type == :value
38
+ member.jason_parent = @parent
39
+ member.jason_parent_list = @list_name
40
+ elsif @list_type == :reference
41
+
42
+ #post to JasonDB::db_auth_url/a_class.name/
43
+ url = "#{JasonDB::db_auth_url}#{@type.name}/#{@parent.jason_key}/#{@list_name}/#{member.jason_key}"
44
+ post_headers = {
45
+ :content_type => 'application/json',
46
+ "X-CLASS" => @type.name,
47
+ "X-KEY" => member.jason_key,
48
+ "X-PARENT" => @parent.jason_key,
49
+ "X-LIST" => @list_name.to_s
50
+ }
51
+ content = {
52
+ "_id" => member.jason_key,
53
+ "_parent" => @parent.jason_key
54
+ }
55
+ #puts " = " + url
56
+ #puts " = #{post_headers}"
57
+ response = RestClient.post url, content.to_json, post_headers
58
+
59
+ if response.code == 201
60
+ #save successful!
61
+ #store the new eTag for this object
62
+ #puts response.raw_headers
63
+ #@__jason_etag = response.headers[:location] + ":" + response.headers[:content_md5]
64
+ else
65
+ raise "POST failed! Could not save membership"
66
+ end
67
+ else
68
+ #parent is a JasonObject, but this list is something other than :value or :reference??
69
+ raise "Invalid list type or trying to add an item to a subquery list!"
70
+ end
71
+
72
+ if member.jason_state == :new
73
+ #we want to save it? probably...
74
+ member.save! if save
75
+ end
76
+
77
+ @state = :prefetch
78
+ end
79
+
80
+ def to_url
81
+ url = "#{JasonDB::db_auth_url}@#{@time_limit}.#{@result_format}?"
82
+ params = ["VERSION0"]
83
+
84
+ params << "FILTER=HTTP_X_CLASS:#{@type.name}"
85
+
86
+ if @parent.is_a? JasonObject
87
+ params << "FILTER=HTTP_X_PARENT:#{@parent.jason_key}"
88
+ else # @parent.is_a? JasonListProperty ##(or DeferredQuery?)
89
+ #we can get the insecure url here, because it will be resolved and executed at JasonDB - on a secure subnet.
90
+
91
+ #subquery = "<%@LANGUAGE=\"URL\" #{@parent.to_url}%>"
92
+ #puts " = Fetching subquery stupidly. (#{@parent.to_url})"
93
+
94
+ subquery = (RestClient.get @parent.to_url).strip
95
+ #puts " = Result: #{subquery}"
96
+ params << URI.escape("FILTER={HTTP_X_PARENT:#{subquery}}", Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
97
+ end
98
+
99
+ url << params.join("&")
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,236 @@
1
+ #Medea/JasonObject - Written by Michael Jensen
2
+
3
+ module Medea
4
+ require 'rest_client'
5
+ require 'json'
6
+
7
+ class JasonObject
8
+
9
+ #include JasonDB
10
+
11
+ #meta-programming interface for lists
12
+ include ClassLevelInheritableAttributes
13
+ inheritable_attributes :owned
14
+ @owned = false
15
+
16
+ def self.create_member_list list_name, list_class, list_type
17
+ list = {}
18
+ list = self.class_variable_get :@@lists if self.class_variable_defined? :@@lists
19
+ list[list_name] = [list_class, list_type]
20
+ self.class_variable_set :@@lists, list
21
+
22
+ define_method list_name, do
23
+ #puts "Looking at the #{list_name.to_s} list, which is full of #{list_type.name}s"
24
+ JasonListProperty.new self, list_name, list_class, list_type
25
+ end
26
+ end
27
+
28
+ def self.has_many list_name, list_class
29
+ create_member_list list_name, list_class, :reference
30
+ end
31
+
32
+ def self.owns_many list_name, list_class
33
+ create_member_list list_name, list_class, :value
34
+
35
+ #also modify the items in the list so that they know that they're owned
36
+ #list_type.class_variable_set :@@owner, self
37
+ list_class.owned = true
38
+ end
39
+
40
+ #end meta
41
+
42
+ #Here we're going to put the "query" interface
43
+
44
+ #create a JasonDeferredQuery with no conditions, other than HTTP_X_CLASS=self.name
45
+ #if mode is set to :eager, we create the JasonDeferredQuery, invoke it's execution and then return it
46
+ def JasonObject.all(mode=:lazy)
47
+ JasonDeferredQuery.new self
48
+ end
49
+
50
+ #returns the JasonObject by directly querying the URL
51
+ #if mode is :lazy, we return a GHOST, if mode is :eager, we return a STALE JasonObject
52
+ def JasonObject.get_by_key(key, mode=:eager)
53
+ return self.new key, mode
54
+ end
55
+
56
+ #here we will capture:
57
+ #members_of(object) (where object is an instance of a class that this class can be a member of)
58
+ #find_by_<property>(value)
59
+ #Will return a JasonDeferredQuery for this class with the appropriate data filter set
60
+ def JasonObject.method_missing(name, *args, &block)
61
+ q = JasonDeferredQuery.new self
62
+ if name =~ /^members_of$/
63
+ #use the type and key of the first arg (being a JasonObject)
64
+ return q.members_of args[0]
65
+ elsif name =~ /^find_by_(.*)$/
66
+ #use the property name from the name variable, and the value from the first arg
67
+ q.add_data_filter $1, args[0]
68
+
69
+ return q
70
+ else
71
+ #no method!
72
+ super
73
+ end
74
+ end
75
+ #end query interface
76
+
77
+ #"flexihash" access interface
78
+ def []=(key, value)
79
+ @__jason_data ||= {}
80
+ @__jason_data[key] = value
81
+ end
82
+
83
+ def [](key)
84
+ @__jason_data[key]
85
+ end
86
+
87
+ #The "Magic" component of candy (https://github.com/SFEley/candy), repurposed to make this a
88
+ # "weak object" that can take any attribute.
89
+ # Assigning any attribute will add it to the object's hash (and then be POSTed to JasonDB on the next save)
90
+ def method_missing(name, *args, &block)
91
+ load if @__jason_state == :ghost
92
+ if name =~ /(.*)=$/ # We're assigning
93
+ @__jason_state = :dirty if @__jason_state == :stale
94
+ self[$1] = args[0]
95
+ elsif name =~ /(.*)\?$/ # We're asking
96
+ (self[$1] ? true : false)
97
+ else
98
+ self[name.to_s]
99
+ end
100
+ end
101
+ #end "flexihash" access
102
+
103
+ def initialize key = nil, mode = :eager
104
+ if key
105
+ @__id = key
106
+ if mode == :eager
107
+ load
108
+ else
109
+ @__jason_state = :ghost
110
+ end
111
+ else
112
+ @__jason_state = :new
113
+ @__jason_data = {}
114
+ end
115
+ end
116
+
117
+ def jason_key
118
+ #TODO: Replace this string with a guid generator of some kind
119
+ @__id ||= "p#{Time.now.nsec.to_s}"
120
+ end
121
+
122
+ def jason_state
123
+ @__jason_state
124
+ end
125
+
126
+ def jason_etag
127
+ @__jason_etag ||= ""
128
+ end
129
+
130
+ def jason_parent
131
+ @__jason_parent ||= nil
132
+ end
133
+
134
+ def jason_parent_list
135
+ @__jason_parent_list ||= nil
136
+ end
137
+
138
+ def jason_parent_list= value
139
+ @__jason_parent_list = value
140
+ end
141
+
142
+ def jason_parent= parent
143
+ @__jason_parent = parent
144
+ end
145
+
146
+ #object persistence methods
147
+
148
+ #POSTs the current values of this object back to JasonDB
149
+ #on successful post, sets state to STALE and updates eTag
150
+ def save!
151
+ #no changes? no save!
152
+ return if @__jason_state == :stale or @__jason_state == :ghost
153
+
154
+
155
+ payload = self.to_json
156
+ post_headers = {
157
+ :content_type => 'application/json',
158
+
159
+ "X-KEY" => self.jason_key,
160
+ "X-CLASS" => self.class.name
161
+ #also want to add the eTag here!
162
+ #may also want to add any other indexable fields that the user specifies?
163
+ }
164
+ post_headers["IF-MATCH"] = @__jason_etag if @__jason_state == :dirty
165
+
166
+ if self.class.owned
167
+ #the parent object needs to be defined!
168
+ raise "#{self.class.name} cannot be saved without setting a parent and list!" unless self.jason_parent && self.jason_parent_list
169
+ post_headers["X-PARENT"] = self.jason_parent.jason_key
170
+ url = "#{JasonDB::db_auth_url}#{self.jason_parent.class.name}/#{self.jason_parent.jason_key}/#{self.jason_parent_list}/#{self.jason_key}"
171
+ post_headers["X-LIST"] = self.jason_parent_list
172
+ else
173
+ url = JasonDB::db_auth_url + self.class.name + "/" + self.jason_key
174
+ end
175
+
176
+
177
+ #puts "Posted to JasonDB!"
178
+
179
+ #puts "Saving to #{url}"
180
+ response = RestClient.post url, payload, post_headers
181
+
182
+ if response.code == 201
183
+ #save successful!
184
+ #store the new eTag for this object
185
+ #puts response.raw_headers
186
+ #@__jason_etag = response.headers[:location] + ":" + response.headers[:content_md5]
187
+ else
188
+ raise "POST failed! Could not save object"
189
+ end
190
+
191
+ @__jason_state = :stale
192
+ end
193
+
194
+ def delete!
195
+ url = "#{JasonDB::db_auth_url}#{self.class.name}/#{self.jason_key}"
196
+ response = RestClient.delete url
197
+ raise "DELETE failed!" unless response.code == 201
198
+ end
199
+
200
+ #end object persistence
201
+
202
+ #converts the data hash (that is, @__jason_data) to JSON format
203
+ def to_json
204
+ JSON.generate(@__jason_data)
205
+ end
206
+
207
+ private
208
+
209
+ #fetches the data from the JasonDB
210
+ def load
211
+ #because this object might be owned by another, we need to search by key.
212
+ #not passing a format to the query is a shortcut to getting just the object.
213
+ url = "#{JasonDB::db_auth_url}@0.content?"
214
+ params = [
215
+ "VERSION0",
216
+ "FILTER=HTTP_X_CLASS:#{self.class.name}",
217
+ "FILTER=HTTP_X_KEY:#{self.jason_key}"
218
+ ]
219
+
220
+ url << params.join("&")
221
+
222
+ #puts " = Retrieving #{self.class.name} at #{url}"
223
+ response = RestClient.get url
224
+ @__jason_data = JSON.parse response
225
+ @__jason_etag = response.headers[:etag]
226
+ @__jason_state = :stale
227
+ end
228
+
229
+ def lazy_load meta
230
+ #TODO Implement lazy load
231
+
232
+ @__jason_state = :ghost
233
+ end
234
+
235
+ end
236
+ end
data/medea-0.2.1.gem ADDED
Binary file
data/medea.gemspec ADDED
@@ -0,0 +1,55 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{medea}
8
+ s.version = "0.2.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Michael Jensen"]
12
+ s.date = %q{2010-12-21}
13
+ s.description = %q{Simple wrapper for persisting objects to JasonDB}
14
+ s.email = %q{michaelj@jasondb.com}
15
+ s.extra_rdoc_files = [
16
+ "README"
17
+ ]
18
+ s.files = [
19
+ "README",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "assets.file",
23
+ "assets.http",
24
+ "index.html",
25
+ "lib/medea.rb",
26
+ "lib/medea/inheritable_attributes.rb",
27
+ "lib/medea/jasondb.rb",
28
+ "lib/medea/jasondeferredquery.rb",
29
+ "lib/medea/jasonlistproperty.rb",
30
+ "lib/medea/jasonobject.rb",
31
+ "medea-0.2.1.gem",
32
+ "medea.gemspec"
33
+ ]
34
+ s.homepage = %q{https://github.com/rob-linton/Medea}
35
+ s.rdoc_options = ["--charset=UTF-8"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.3.7}
38
+ s.summary = %q{Simple wrapper for persisting objects to JasonDB}
39
+
40
+ if s.respond_to? :specification_version then
41
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
42
+ s.specification_version = 3
43
+
44
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
+ s.add_runtime_dependency(%q<json>, [">= 0"])
46
+ s.add_runtime_dependency(%q<rest-client>, [">= 0"])
47
+ else
48
+ s.add_dependency(%q<json>, [">= 0"])
49
+ s.add_dependency(%q<rest-client>, [">= 0"])
50
+ end
51
+ else
52
+ s.add_dependency(%q<json>, [">= 0"])
53
+ s.add_dependency(%q<rest-client>, [">= 0"])
54
+ end
55
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: medea
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 2
9
+ version: 0.2.2
10
+ platform: ruby
11
+ authors:
12
+ - Michael Jensen
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-12-21 00:00:00 +11:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: json
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: rest-client
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :runtime
45
+ version_requirements: *id002
46
+ description: Simple wrapper for persisting objects to JasonDB
47
+ email: michaelj@jasondb.com
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ extra_rdoc_files:
53
+ - README
54
+ files:
55
+ - README
56
+ - Rakefile
57
+ - VERSION
58
+ - assets.file
59
+ - assets.http
60
+ - index.html
61
+ - lib/medea.rb
62
+ - lib/medea/inheritable_attributes.rb
63
+ - lib/medea/jasondb.rb
64
+ - lib/medea/jasondeferredquery.rb
65
+ - lib/medea/jasonlistproperty.rb
66
+ - lib/medea/jasonobject.rb
67
+ - medea-0.2.1.gem
68
+ - medea.gemspec
69
+ has_rdoc: true
70
+ homepage: https://github.com/rob-linton/Medea
71
+ licenses: []
72
+
73
+ post_install_message:
74
+ rdoc_options:
75
+ - --charset=UTF-8
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ requirements: []
95
+
96
+ rubyforge_project:
97
+ rubygems_version: 1.3.7
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: Simple wrapper for persisting objects to JasonDB
101
+ test_files: []
102
+