medea 0.2.2

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 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
+