dm-xml-adapter 0.582 → 0.584
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/lib/dm-xml-adapter.rb +109 -85
- data/spec/dm-xml-adapter_spec.rb +19 -12
- data/spec/spec_helper.rb +46 -34
- metadata +64 -29
data/lib/dm-xml-adapter.rb
CHANGED
@@ -3,62 +3,83 @@ require 'dm-core'
|
|
3
3
|
require 'builder'
|
4
4
|
require 'dm-core/adapters/abstract_adapter'
|
5
5
|
require 'pp'
|
6
|
+
|
6
7
|
gem 'libxml-ruby', '>= 0.8.3'
|
7
8
|
require 'xml'
|
8
9
|
require 'tempfile'
|
9
10
|
require 'simple_memoize'
|
10
11
|
require 'log4r'
|
11
12
|
|
13
|
+
# http://redcorundum.blogspot.com/2006/05/kernelqualifiedconstget.html
|
14
|
+
module Kernel
|
15
|
+
def qualified_const_get(str)
|
16
|
+
path = str.to_s.split('::')
|
17
|
+
from_root = path[0].empty?
|
18
|
+
if from_root
|
19
|
+
from_root = []
|
20
|
+
path = path[1..-1]
|
21
|
+
else
|
22
|
+
start_ns = ((Class === self)||(Module === self)) ? self : self.class
|
23
|
+
from_root = start_ns.to_s.split('::')
|
24
|
+
end
|
25
|
+
until from_root.empty?
|
26
|
+
begin
|
27
|
+
return (from_root+path).inject(Object) { |ns,name| ns.const_get(name) }
|
28
|
+
rescue NameError
|
29
|
+
from_root.delete_at(-1)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
path.inject(Object) { |ns,name| ns.const_get(name) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
12
36
|
# the XML adapter is an adapter for DataMapper that allows you to store
|
13
37
|
# data in XML files. beware, it's not transactionally safe.
|
14
38
|
module DataMapper::Adapters
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def delete_mtime(file)
|
39
|
+
class XmlAdapterCache
|
40
|
+
def initialize
|
41
|
+
@mtimes = Hash.new()
|
42
|
+
@classes = Hash.new()
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_mtime(file, mtime)
|
46
|
+
@mtimes[file] = mtime
|
47
|
+
end
|
48
|
+
|
49
|
+
def delete_mtime(file)
|
28
50
|
@mtimes.delete(file)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_mtime(file)
|
54
|
+
return @mtimes[file]
|
55
|
+
end
|
56
|
+
|
57
|
+
def put(classname, id, object)
|
36
58
|
# check to see if we have a classname entry
|
37
|
-
|
59
|
+
#puts "putting a cache entry of id: #{id}"
|
38
60
|
if (@classes[classname] == nil)
|
39
61
|
@classes[classname] = Hash.new
|
40
62
|
end
|
41
|
-
|
63
|
+
|
42
64
|
hash = @classes[classname]
|
43
65
|
hash[id.to_s] = object
|
44
|
-
|
45
|
-
|
46
|
-
|
66
|
+
end
|
67
|
+
|
68
|
+
def delete(classname, id)
|
47
69
|
hash = @classes[classname]
|
48
70
|
unless hash == nil
|
49
71
|
hash.delete(id.to_s)
|
50
72
|
end
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
73
|
+
end
|
74
|
+
|
75
|
+
def get(classname, id)
|
76
|
+
#puts "getting a cache entry for id: #{id}"
|
55
77
|
hash = @classes[classname]
|
56
78
|
return hash[id]
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
class XmlAdapter < AbstractAdapter
|
79
|
+
end
|
80
|
+
end
|
61
81
|
|
82
|
+
class XmlAdapter < AbstractAdapter
|
62
83
|
def self.threads=(count)
|
63
84
|
@@threadcount = count
|
64
85
|
end
|
@@ -69,22 +90,22 @@ module DataMapper::Adapters
|
|
69
90
|
@@threadcount = 1
|
70
91
|
@options = Hash.new
|
71
92
|
@options[:directory] = options[:directory]
|
72
|
-
@options[:directory] ||= './db'
|
73
|
-
|
93
|
+
@options[:directory] ||= './db'
|
94
|
+
|
74
95
|
@last_used_id = Hash.new
|
75
|
-
|
96
|
+
|
76
97
|
@cache = XmlAdapterCache.new
|
77
|
-
|
98
|
+
|
78
99
|
end
|
79
|
-
|
100
|
+
|
80
101
|
def destroy_model_storage(model)
|
81
|
-
|
102
|
+
FileUtils.rm_rf(classname_to_dir(model.to_s))
|
82
103
|
end
|
83
|
-
|
104
|
+
|
84
105
|
def create_model_storage(model)
|
85
|
-
|
106
|
+
FileUtils.mkdir_p(classname_to_dir(model.to_s))
|
86
107
|
end
|
87
|
-
|
108
|
+
|
88
109
|
def create(resources)
|
89
110
|
key = resources.first.model.key.first.name
|
90
111
|
resources.each do |resource|
|
@@ -96,55 +117,55 @@ module DataMapper::Adapters
|
|
96
117
|
save(resource)
|
97
118
|
end.size
|
98
119
|
end
|
99
|
-
|
120
|
+
|
100
121
|
def delete(collection)
|
101
|
-
|
122
|
+
collection.each do |result|
|
102
123
|
key = result.key.first
|
103
124
|
class_name = result.model.to_s
|
104
125
|
@last_used_id[class_name] = key
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
126
|
+
xml_destroy(result)
|
127
|
+
# also remove from cache
|
128
|
+
@cache.delete(class_name, key)
|
129
|
+
# also remove from mtimes
|
130
|
+
@cache.delete_mtime(class_name_to_file(class_name, key))
|
131
|
+
end
|
132
|
+
return collection.size
|
112
133
|
end
|
113
|
-
|
134
|
+
|
114
135
|
def update(attributes, collection)
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
136
|
+
# ok, for each object found we have to update the attribs we found
|
137
|
+
# first thing is figure out what class we are dealing with
|
138
|
+
# iterate over every object in this set and set the given attributes
|
139
|
+
collection.each do |obj|
|
140
|
+
attributes.each do |attrib|
|
141
|
+
# attrib is an array
|
142
|
+
# first member is Property object
|
143
|
+
# second member is the value
|
144
|
+
obj.instance_variable_set("@" + attrib[0].name.to_s, attrib[1])
|
145
|
+
end
|
146
|
+
save(obj)
|
147
|
+
end
|
127
148
|
return collection
|
128
149
|
end
|
129
|
-
|
150
|
+
|
130
151
|
def read(query)
|
131
|
-
|
152
|
+
return filter_result_set(get_all(query.model), query)
|
132
153
|
end
|
133
|
-
|
154
|
+
|
134
155
|
private
|
135
|
-
|
136
|
-
|
156
|
+
|
157
|
+
def xml_destroy(resource)
|
137
158
|
# take an objects class and ID and figure
|
138
159
|
# out what file it's in
|
139
160
|
# and then remove that file
|
140
161
|
File.unlink class_name_to_file(resource.class.to_s, resource.key.first)
|
141
162
|
end
|
142
|
-
|
163
|
+
|
143
164
|
def filter_result_set(objects, query)
|
144
165
|
result_set = objects.clone
|
145
166
|
return query.filter_records(result_set)
|
146
167
|
end
|
147
|
-
|
168
|
+
|
148
169
|
def get_all(model)
|
149
170
|
model_name = model.to_s
|
150
171
|
directory = classname_to_dir(model_name)
|
@@ -177,21 +198,24 @@ module DataMapper::Adapters
|
|
177
198
|
cache_mtime = @cache.get_mtime(filename)
|
178
199
|
return true if (mtime != nil and cache_mtime != nil and mtime == cache_mtime)
|
179
200
|
end
|
180
|
-
|
201
|
+
|
181
202
|
def file_to_id(file)
|
182
203
|
return file.match(/([0-9]+)\.xml/)[1]
|
183
204
|
end
|
184
|
-
|
205
|
+
|
206
|
+
def get_instance(model_name)
|
207
|
+
end
|
208
|
+
|
185
209
|
def file_to_object(file, model)
|
186
210
|
model_name = model.to_s
|
187
211
|
# allocate new object to receive these fields
|
188
212
|
if (model_name.match(/(.*)\:\:(.*)/))
|
189
213
|
modname, clazz = [$1, $2]
|
190
|
-
new_obj = Kernel.
|
214
|
+
new_obj = Kernel.qualified_const_get(model_name).new
|
191
215
|
else
|
192
216
|
new_obj = Kernel.const_get(model_name).new
|
193
217
|
end
|
194
|
-
|
218
|
+
|
195
219
|
# iterate over children
|
196
220
|
XML::Parser.string(IO.read(file)).parse.root.children.each do |child|
|
197
221
|
child_class = child.attributes["class"]
|
@@ -200,7 +224,7 @@ module DataMapper::Adapters
|
|
200
224
|
populate_instance(new_obj, child, child_class)
|
201
225
|
end
|
202
226
|
end
|
203
|
-
|
227
|
+
|
204
228
|
return new_obj
|
205
229
|
end
|
206
230
|
|
@@ -221,7 +245,7 @@ module DataMapper::Adapters
|
|
221
245
|
new_obj.instance_variable_set("@#{child.name}", Date.parse(child.content))
|
222
246
|
end
|
223
247
|
end
|
224
|
-
|
248
|
+
|
225
249
|
def find_free_id_for(class_name)
|
226
250
|
# if there are no entries in the directory
|
227
251
|
# or the directory doesn't exist
|
@@ -249,7 +273,7 @@ module DataMapper::Adapters
|
|
249
273
|
id += 1
|
250
274
|
end
|
251
275
|
end
|
252
|
-
|
276
|
+
|
253
277
|
def save(resource)
|
254
278
|
# since we're saving, purge the cache
|
255
279
|
resource_class = resource.class.to_s
|
@@ -266,7 +290,7 @@ module DataMapper::Adapters
|
|
266
290
|
# set up builder
|
267
291
|
out_string = ""
|
268
292
|
xml = Builder::XmlMarkup.new(:target => out_string, :indent => 1)
|
269
|
-
|
293
|
+
|
270
294
|
# iterate over the resource and figure out the fields
|
271
295
|
xml.tag!("RubyObject", :class => resource.model.to_s) do
|
272
296
|
resource.model.properties.each do |property|
|
@@ -282,8 +306,8 @@ module DataMapper::Adapters
|
|
282
306
|
end
|
283
307
|
end
|
284
308
|
end
|
285
|
-
|
286
|
-
#puts "the key is now: #{resource_key}"
|
309
|
+
|
310
|
+
#puts "the key is now: #{resource_key}"
|
287
311
|
xmlfile = File.new(class_name_to_file(resource_class, resource_key), "w")
|
288
312
|
#puts "saving to #{xmlfile.path}"
|
289
313
|
tempfile = Tempfile.new("dm-xml-adapter", Dir.tmpdir())
|
@@ -292,14 +316,14 @@ module DataMapper::Adapters
|
|
292
316
|
tempfile.close
|
293
317
|
FileUtils.mv(tempfile.path,xmlfile.path)
|
294
318
|
return xmlfile
|
295
|
-
|
319
|
+
|
296
320
|
end
|
297
321
|
|
298
322
|
def classname_to_dir(class_name)
|
299
323
|
return File.join(@options[:directory],
|
300
|
-
|
324
|
+
class_name.gsub("/", "_").gsub(":", "_"))
|
301
325
|
end
|
302
|
-
|
326
|
+
|
303
327
|
def class_name_to_file(class_name, id)
|
304
328
|
return File.join(classname_to_dir(class_name), id.to_s + ".xml")
|
305
329
|
end
|
@@ -307,7 +331,7 @@ module DataMapper::Adapters
|
|
307
331
|
#memoize(:file_to_id)
|
308
332
|
#memoize(:classname_to_dir)
|
309
333
|
#memoize(:class_name_to_file)
|
310
|
-
|
334
|
+
|
311
335
|
end
|
312
336
|
end
|
313
337
|
|
data/spec/dm-xml-adapter_spec.rb
CHANGED
@@ -19,12 +19,12 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
19
19
|
AutoQuote.all.each {|aq| aq.destroy }
|
20
20
|
Food.all.each {|f| f.destroy }
|
21
21
|
Drink.all.each {|d| d.destroy }
|
22
|
+
Three::Level::Test::IsFun.all.each {|d| d.destroy }
|
22
23
|
end
|
23
|
-
|
24
|
+
|
24
25
|
after(:each) do
|
25
26
|
delete_all
|
26
27
|
end
|
27
|
-
|
28
28
|
|
29
29
|
describe "CRUD" do
|
30
30
|
|
@@ -34,14 +34,14 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
34
34
|
AutoQuote.all.size.should == 1
|
35
35
|
end
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
describe "content attribute" do
|
39
39
|
it "should be able to handle a content attribute" do
|
40
40
|
XMLTest::User.create(:name => "contentking", :content => "cool")
|
41
41
|
XMLTest::User.all.size.should == 1
|
42
42
|
end
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
describe "datetime" do
|
46
46
|
it "should do datetime" do
|
47
47
|
u1 = XMLTest::User.new
|
@@ -53,7 +53,7 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
describe "date" do
|
57
57
|
it "should do date" do
|
58
58
|
u1 = XMLTest::User.new
|
59
59
|
u1.name = "cool!"
|
@@ -82,7 +82,7 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
82
82
|
u2.cool.class.should == FalseClass
|
83
83
|
end
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
describe "associations" do
|
87
87
|
it "should have associations" do
|
88
88
|
u1 = XMLTest::User.new
|
@@ -101,14 +101,14 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
101
101
|
u3.posts.size.should == 2
|
102
102
|
end
|
103
103
|
end
|
104
|
-
|
104
|
+
|
105
105
|
describe "get all" do
|
106
106
|
it "should get all" do
|
107
107
|
XMLTest::User.create(:name => :yeah)
|
108
108
|
XMLTest::User.all.should_not == nil
|
109
109
|
end
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
112
|
describe "update" do
|
113
113
|
it "should update" do
|
114
114
|
u1 = XMLTest::User.new
|
@@ -127,7 +127,7 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
127
127
|
u.user_id.should_not == nil
|
128
128
|
end
|
129
129
|
end
|
130
|
-
|
130
|
+
|
131
131
|
describe "delete" do
|
132
132
|
it "should delete someone" do
|
133
133
|
user = XMLTest::User.create
|
@@ -143,7 +143,7 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
143
143
|
user1.money.class.should == BigDecimal
|
144
144
|
end
|
145
145
|
end
|
146
|
-
|
146
|
+
|
147
147
|
describe "find not" do
|
148
148
|
it "should find someone with a not clause" do
|
149
149
|
user1 = XMLTest::User.create(:name => "joe")
|
@@ -165,9 +165,16 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
165
165
|
Drink.first(:name => "Drinky drink!").should_not == nil
|
166
166
|
end
|
167
167
|
end
|
168
|
-
|
168
|
+
|
169
|
+
describe "complex class name" do
|
170
|
+
it "should be able to persist" do
|
171
|
+
fun = Three::Level::Test::IsFun.new
|
172
|
+
fun.superfun = true
|
173
|
+
fun.save
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
169
177
|
end
|
170
|
-
|
171
178
|
|
172
179
|
end
|
173
180
|
|
data/spec/spec_helper.rb
CHANGED
@@ -4,49 +4,61 @@ require 'pathname'
|
|
4
4
|
require 'lib/dm-xml-adapter'
|
5
5
|
|
6
6
|
class Food
|
7
|
-
|
7
|
+
include DataMapper::Resource
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
property :food_id, Serial
|
10
|
+
property :name, String
|
11
11
|
end
|
12
12
|
|
13
13
|
class Drink
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
include DataMapper::Resource
|
15
|
+
|
16
|
+
property :drink_id, Serial
|
17
|
+
property :name, String
|
18
18
|
end
|
19
19
|
|
20
20
|
class AutoQuote
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
include DataMapper::Resource
|
22
|
+
|
23
|
+
property :quote_id, Serial
|
24
|
+
property :fullname, String
|
25
25
|
end
|
26
26
|
|
27
27
|
module XMLTest
|
28
|
-
class Post
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
class User
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
28
|
+
class Post
|
29
|
+
include DataMapper::Resource
|
30
|
+
|
31
|
+
property :post_id, Serial
|
32
|
+
property :title, String
|
33
|
+
property :created, DateTime
|
34
|
+
|
35
|
+
belongs_to :user, :model => "User"
|
36
|
+
end
|
37
|
+
|
38
|
+
class User
|
39
|
+
include DataMapper::Resource
|
40
|
+
|
41
|
+
property :user_id, Serial
|
42
|
+
property :name, String
|
43
|
+
property :age, Integer
|
44
|
+
property :money, Decimal
|
45
|
+
property :created, DateTime
|
46
|
+
property :cool, Boolean
|
47
|
+
property :content, String
|
48
|
+
property :date, Date
|
49
|
+
|
50
|
+
has n, :posts, :model => "Post"
|
51
|
+
end
|
51
52
|
end
|
53
|
+
|
54
|
+
module Three
|
55
|
+
module Level
|
56
|
+
module Test
|
57
|
+
class IsFun
|
58
|
+
include DataMapper::Resource
|
59
|
+
property :fun_id, Serial
|
60
|
+
property :superfun, Boolean
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
52
64
|
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-xml-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 1179
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 584
|
9
|
+
version: "0.584"
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Joshua Harding
|
@@ -9,69 +14,93 @@ autorequire: dm-xml-adapter
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date:
|
17
|
+
date: 2011-07-18 00:00:00 -04:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: libxml-ruby
|
17
|
-
|
18
|
-
|
19
|
-
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
20
25
|
requirements:
|
21
26
|
- - ">="
|
22
27
|
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
23
31
|
version: "0"
|
24
|
-
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
25
34
|
- !ruby/object:Gem::Dependency
|
26
35
|
name: builder
|
27
|
-
|
28
|
-
|
29
|
-
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
30
39
|
requirements:
|
31
40
|
- - ">="
|
32
41
|
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
33
45
|
version: "0"
|
34
|
-
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
35
48
|
- !ruby/object:Gem::Dependency
|
36
49
|
name: simple_memoize
|
37
|
-
|
38
|
-
|
39
|
-
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
40
53
|
requirements:
|
41
54
|
- - ">="
|
42
55
|
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
43
59
|
version: "0"
|
44
|
-
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
45
62
|
- !ruby/object:Gem::Dependency
|
46
63
|
name: log4r
|
47
|
-
|
48
|
-
|
49
|
-
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
50
67
|
requirements:
|
51
68
|
- - ">="
|
52
69
|
- !ruby/object:Gem::Version
|
70
|
+
hash: 3
|
71
|
+
segments:
|
72
|
+
- 0
|
53
73
|
version: "0"
|
54
|
-
|
74
|
+
type: :runtime
|
75
|
+
version_requirements: *id004
|
55
76
|
- !ruby/object:Gem::Dependency
|
56
77
|
name: dm-core
|
57
|
-
|
58
|
-
|
59
|
-
|
78
|
+
prerelease: false
|
79
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
60
81
|
requirements:
|
61
82
|
- - ">="
|
62
83
|
- !ruby/object:Gem::Version
|
84
|
+
hash: 3
|
85
|
+
segments:
|
86
|
+
- 0
|
63
87
|
version: "0"
|
64
|
-
|
88
|
+
type: :runtime
|
89
|
+
version_requirements: *id005
|
65
90
|
- !ruby/object:Gem::Dependency
|
66
91
|
name: dm-migrations
|
67
|
-
|
68
|
-
|
69
|
-
|
92
|
+
prerelease: false
|
93
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
70
95
|
requirements:
|
71
96
|
- - ">="
|
72
97
|
- !ruby/object:Gem::Version
|
98
|
+
hash: 3
|
99
|
+
segments:
|
100
|
+
- 0
|
73
101
|
version: "0"
|
74
|
-
|
102
|
+
type: :runtime
|
103
|
+
version_requirements: *id006
|
75
104
|
description:
|
76
105
|
email: josh@statewidesoftware.com
|
77
106
|
executables: []
|
@@ -96,21 +125,27 @@ rdoc_options: []
|
|
96
125
|
require_paths:
|
97
126
|
- lib
|
98
127
|
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
99
129
|
requirements:
|
100
130
|
- - ">="
|
101
131
|
- !ruby/object:Gem::Version
|
132
|
+
hash: 3
|
133
|
+
segments:
|
134
|
+
- 0
|
102
135
|
version: "0"
|
103
|
-
version:
|
104
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
105
138
|
requirements:
|
106
139
|
- - ">="
|
107
140
|
- !ruby/object:Gem::Version
|
141
|
+
hash: 3
|
142
|
+
segments:
|
143
|
+
- 0
|
108
144
|
version: "0"
|
109
|
-
version:
|
110
145
|
requirements: []
|
111
146
|
|
112
147
|
rubyforge_project:
|
113
|
-
rubygems_version: 1.3.
|
148
|
+
rubygems_version: 1.3.7
|
114
149
|
signing_key:
|
115
150
|
specification_version: 3
|
116
151
|
summary: a XML adapter for DataMapper. this adapter allows you to use DataMapper with XML files as a backing store.
|