dm-xml-adapter 0.58 → 0.59
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/dm-xml-adapter.rb +150 -115
- data/spec/dm-xml-adapter_spec.rb +39 -17
- data/spec/spec_helper.rb +47 -35
- metadata +121 -75
data/lib/dm-xml-adapter.rb
CHANGED
@@ -3,154 +3,189 @@ 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
|
-
require '
|
10
|
-
require '
|
10
|
+
require 'logger'
|
11
|
+
require 'lrucache'
|
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
|
11
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 = LRUCache.new(:max => 20)
|
42
|
+
@classes = LRUCache.new(:max => 20)
|
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
|
if (@classes[classname] == nil)
|
38
60
|
@classes[classname] = Hash.new
|
39
61
|
end
|
40
|
-
|
62
|
+
|
41
63
|
hash = @classes[classname]
|
42
64
|
hash[id.to_s] = object
|
43
|
-
|
44
|
-
|
45
|
-
|
65
|
+
end
|
66
|
+
|
67
|
+
def delete(classname, id)
|
46
68
|
hash = @classes[classname]
|
47
69
|
unless hash == nil
|
48
70
|
hash.delete(id.to_s)
|
49
71
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
72
|
+
end
|
73
|
+
|
74
|
+
def get(classname, id)
|
53
75
|
hash = @classes[classname]
|
54
76
|
return hash[id]
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
class XmlAdapter < AbstractAdapter
|
77
|
+
end
|
78
|
+
end
|
59
79
|
|
60
|
-
|
61
|
-
|
80
|
+
class XmlAdapter < AbstractAdapter
|
81
|
+
|
82
|
+
def loglevel=(loglevel)
|
83
|
+
@options[:loglevel] = loglevel
|
84
|
+
@logger.level = loglevel
|
85
|
+
end
|
86
|
+
|
87
|
+
def logger=(logger)
|
88
|
+
@options[:logger] = logger
|
89
|
+
@logger = logger
|
62
90
|
end
|
63
91
|
|
64
92
|
def initialize(name, options)
|
65
93
|
super
|
66
94
|
|
67
|
-
|
68
|
-
@options
|
69
|
-
@options[:
|
70
|
-
@options[:
|
71
|
-
|
95
|
+
@options = options
|
96
|
+
@options[:directory] ||= './db'
|
97
|
+
@options[:loglevel] ||= Logger::FATAL
|
98
|
+
@options[:logger] ||= Logger.new(STDERR)
|
99
|
+
@logger = @options[:logger]
|
100
|
+
@logger.level = @options[:loglevel]
|
101
|
+
@logger.debug('DM-XML-Adapter Initialized!')
|
72
102
|
@last_used_id = Hash.new
|
73
|
-
|
103
|
+
|
74
104
|
@cache = XmlAdapterCache.new
|
75
|
-
|
105
|
+
|
76
106
|
end
|
77
|
-
|
78
|
-
def destroy_model_storage(
|
79
|
-
|
107
|
+
|
108
|
+
def destroy_model_storage(model)
|
109
|
+
FileUtils.rm_rf(classname_to_dir(model.to_s))
|
110
|
+
@logger.debug("Removing model storage for #{model}")
|
80
111
|
end
|
81
|
-
|
82
|
-
def create_model_storage(
|
83
|
-
|
112
|
+
|
113
|
+
def create_model_storage(model)
|
114
|
+
FileUtils.mkdir_p(classname_to_dir(model.to_s))
|
115
|
+
@logger.debug("Creating model storage for: #{model}")
|
84
116
|
end
|
85
|
-
|
117
|
+
|
86
118
|
def create(resources)
|
87
119
|
key = resources.first.model.key.first.name
|
88
120
|
resources.each do |resource|
|
89
121
|
id = find_free_id_for(resources.first.class.to_s)
|
90
122
|
# find name of key attribute
|
91
123
|
resource.attributes[key] = id
|
92
|
-
resource.instance_variable_set(
|
124
|
+
resource.instance_variable_set('@' + key.to_s, id)
|
93
125
|
save(resource)
|
94
126
|
end.size
|
95
127
|
end
|
96
|
-
|
128
|
+
|
97
129
|
def delete(collection)
|
98
|
-
|
130
|
+
collection.each do |result|
|
99
131
|
key = result.key.first
|
100
132
|
class_name = result.model.to_s
|
101
133
|
@last_used_id[class_name] = key
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
134
|
+
xml_destroy(result)
|
135
|
+
@logger.debug("Destroying #{result}")
|
136
|
+
# also remove from cache
|
137
|
+
@cache.delete(class_name, key)
|
138
|
+
# also remove from mtimes
|
139
|
+
@cache.delete_mtime(class_name_to_file(class_name, key))
|
140
|
+
end
|
141
|
+
return collection.size
|
109
142
|
end
|
110
|
-
|
143
|
+
|
111
144
|
def update(attributes, collection)
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
145
|
+
# ok, for each object found we have to update the attribs we found
|
146
|
+
# first thing is figure out what class we are dealing with
|
147
|
+
# iterate over every object in this set and set the given attributes
|
148
|
+
collection.each do |obj|
|
149
|
+
attributes.each do |attrib|
|
150
|
+
# attrib is an array
|
151
|
+
# first member is Property object
|
152
|
+
# second member is the value
|
153
|
+
obj.instance_variable_set('@' + attrib[0].name.to_s, attrib[1])
|
154
|
+
@logger.debug("Updating instance variable #{attrib[0].name.to_s} to #{attrib[1]}")
|
155
|
+
end
|
156
|
+
save(obj)
|
157
|
+
end
|
124
158
|
return collection
|
125
159
|
end
|
126
|
-
|
160
|
+
|
127
161
|
def read(query)
|
128
|
-
|
162
|
+
return filter_result_set(get_all(query.model), query)
|
129
163
|
end
|
130
|
-
|
164
|
+
|
131
165
|
private
|
132
|
-
|
133
|
-
|
166
|
+
|
167
|
+
def xml_destroy(resource)
|
134
168
|
# take an objects class and ID and figure
|
135
169
|
# out what file it's in
|
136
170
|
# and then remove that file
|
137
171
|
File.unlink class_name_to_file(resource.class.to_s, resource.key.first)
|
138
172
|
end
|
139
|
-
|
173
|
+
|
140
174
|
def filter_result_set(objects, query)
|
141
175
|
result_set = objects.clone
|
142
176
|
return query.filter_records(result_set)
|
143
177
|
end
|
144
|
-
|
178
|
+
|
145
179
|
def get_all(model)
|
146
180
|
model_name = model.to_s
|
181
|
+
@logger.debug("Getting all for model #{model_name}")
|
147
182
|
directory = classname_to_dir(model_name)
|
148
183
|
if ! File.exists?(directory)
|
149
184
|
return []
|
150
185
|
end
|
151
186
|
|
152
187
|
objects = []
|
153
|
-
Dir[directory +
|
188
|
+
Dir[directory + '/*.xml'].each do |filename|
|
154
189
|
# see if we have a nice cached version
|
155
190
|
if has_cached_version?(filename)
|
156
191
|
# we have a nice cached object..
|
@@ -159,7 +194,10 @@ module DataMapper::Adapters
|
|
159
194
|
# the file's newer OR older (aha!!), so we gotta load it up
|
160
195
|
object = file_to_object(filename, model)
|
161
196
|
objects << object
|
162
|
-
|
197
|
+
key = object.key
|
198
|
+
next if (key == nil)
|
199
|
+
key = object.key.first
|
200
|
+
@cache.put(model_name, key, object)
|
163
201
|
@cache.set_mtime(filename, File.mtime(filename))
|
164
202
|
end
|
165
203
|
end
|
@@ -171,51 +209,50 @@ module DataMapper::Adapters
|
|
171
209
|
cache_mtime = @cache.get_mtime(filename)
|
172
210
|
return true if (mtime != nil and cache_mtime != nil and mtime == cache_mtime)
|
173
211
|
end
|
174
|
-
|
212
|
+
|
175
213
|
def file_to_id(file)
|
176
214
|
return file.match(/([0-9]+)\.xml/)[1]
|
177
215
|
end
|
178
|
-
|
216
|
+
|
179
217
|
def file_to_object(file, model)
|
180
218
|
model_name = model.to_s
|
181
219
|
# allocate new object to receive these fields
|
182
|
-
if (model_name.match(
|
183
|
-
|
184
|
-
new_obj = Kernel.const_get(modname).const_get(clazz).new
|
220
|
+
if (model_name.match(/.*\:\:.*/))
|
221
|
+
new_obj = Kernel.qualified_const_get(model_name).new
|
185
222
|
else
|
186
223
|
new_obj = Kernel.const_get(model_name).new
|
187
224
|
end
|
188
|
-
|
225
|
+
|
189
226
|
# iterate over children
|
190
227
|
XML::Parser.string(IO.read(file)).parse.root.children.each do |child|
|
191
|
-
child_class = child.attributes[
|
228
|
+
child_class = child.attributes['class']
|
192
229
|
if child_class != nil
|
193
230
|
# this means we have an attribute
|
194
231
|
populate_instance(new_obj, child, child_class)
|
195
232
|
end
|
196
233
|
end
|
197
|
-
|
234
|
+
|
198
235
|
return new_obj
|
199
236
|
end
|
200
237
|
|
201
238
|
def populate_instance(new_obj, child, child_class)
|
202
|
-
if (child_class ==
|
239
|
+
if (child_class == 'String')
|
203
240
|
new_obj.instance_variable_set("@#{child.name}", child.content)
|
204
|
-
elsif (child_class ==
|
241
|
+
elsif (child_class == 'Integer')
|
205
242
|
new_obj.instance_variable_set("@#{child.name}", child.content.to_i)
|
206
|
-
elsif (child_class ==
|
243
|
+
elsif (child_class == 'TrueClass')
|
207
244
|
new_obj.instance_variable_set("@#{child.name}", true)
|
208
|
-
elsif (child_class ==
|
245
|
+
elsif (child_class == 'FalseClass')
|
209
246
|
new_obj.instance_variable_set("@#{child.name}", false)
|
210
|
-
elsif (child_class ==
|
247
|
+
elsif (child_class == 'BigDecimal')
|
211
248
|
new_obj.instance_variable_set("@#{child.name}", BigDecimal.new(child.content))
|
212
|
-
elsif (child_class ==
|
249
|
+
elsif (child_class == 'DateTime')
|
213
250
|
new_obj.instance_variable_set("@#{child.name}", DateTime.parse(child.content))
|
214
|
-
elsif (child_class ==
|
251
|
+
elsif (child_class == 'Date')
|
215
252
|
new_obj.instance_variable_set("@#{child.name}", Date.parse(child.content))
|
216
253
|
end
|
217
254
|
end
|
218
|
-
|
255
|
+
|
219
256
|
def find_free_id_for(class_name)
|
220
257
|
# if there are no entries in the directory
|
221
258
|
# or the directory doesn't exist
|
@@ -230,14 +267,15 @@ module DataMapper::Adapters
|
|
230
267
|
end
|
231
268
|
id = @last_used_id[class_name] || 1
|
232
269
|
while true do
|
233
|
-
|
270
|
+
filename = File.join(directory.path, id.to_s + '.xml')
|
271
|
+
if ! File.exists?(filename)
|
234
272
|
@last_used_id[class_name] = id
|
235
273
|
return id
|
236
274
|
end
|
237
275
|
id += 1
|
238
276
|
end
|
239
277
|
end
|
240
|
-
|
278
|
+
|
241
279
|
def save(resource)
|
242
280
|
# since we're saving, purge the cache
|
243
281
|
resource_class = resource.class.to_s
|
@@ -251,47 +289,44 @@ module DataMapper::Adapters
|
|
251
289
|
end
|
252
290
|
|
253
291
|
# set up builder
|
254
|
-
out_string =
|
292
|
+
out_string = ''
|
255
293
|
xml = Builder::XmlMarkup.new(:target => out_string, :indent => 1)
|
256
|
-
|
294
|
+
|
257
295
|
# iterate over the resource and figure out the fields
|
258
|
-
xml.tag!(
|
296
|
+
xml.tag!('RubyObject', :class => resource.model.to_s) do
|
259
297
|
resource.model.properties.each do |property|
|
260
298
|
property_name = property.name.to_s
|
261
|
-
value = resource.instance_variable_get(
|
299
|
+
value = resource.instance_variable_get('@' + property_name)
|
262
300
|
# special case for false
|
263
301
|
if property.primitive == TrueClass and value == false
|
264
302
|
xml.tag!(property_name, false, :class => FalseClass.to_s)
|
265
303
|
elsif (property.primitive == BigDecimal and value != nil)
|
266
|
-
xml.tag!(property_name, value.to_s(
|
304
|
+
xml.tag!(property_name, value.to_s('F'), :class => BigDecimal)
|
267
305
|
elsif (value != nil)
|
268
306
|
xml.tag!(property_name, value, :class => property.primitive)
|
269
307
|
end
|
270
308
|
end
|
271
309
|
end
|
272
|
-
|
273
|
-
xmlfile = File.new(class_name_to_file(resource_class, resource_key),
|
274
|
-
tempfile = Tempfile.new(
|
310
|
+
|
311
|
+
xmlfile = File.new(class_name_to_file(resource_class, resource_key), 'w')
|
312
|
+
tempfile = Tempfile.new('dm-xml-adapter', Dir.tmpdir())
|
275
313
|
tempfile.puts out_string
|
276
314
|
tempfile.close
|
277
315
|
FileUtils.mv(tempfile.path,xmlfile.path)
|
316
|
+
@logger.debug("Saved to: #{xmlfile.path}")
|
278
317
|
return xmlfile
|
279
|
-
|
318
|
+
|
280
319
|
end
|
281
320
|
|
282
321
|
def classname_to_dir(class_name)
|
283
322
|
return File.join(@options[:directory],
|
284
|
-
|
323
|
+
class_name.gsub('/', '_').gsub(':', '_'))
|
285
324
|
end
|
286
|
-
|
325
|
+
|
287
326
|
def class_name_to_file(class_name, id)
|
288
|
-
return File.join(classname_to_dir(class_name), id.to_s +
|
327
|
+
return File.join(classname_to_dir(class_name), id.to_s + '.xml')
|
289
328
|
end
|
290
329
|
|
291
|
-
memoize(:file_to_id)
|
292
|
-
memoize(:classname_to_dir)
|
293
|
-
memoize(:class_name_to_file)
|
294
|
-
|
295
330
|
end
|
296
331
|
end
|
297
332
|
|
data/spec/dm-xml-adapter_spec.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'dm-core'
|
3
3
|
require 'pathname'
|
4
|
+
require 'dm-migrations'
|
4
5
|
require Pathname(__FILE__).dirname.expand_path + 'spec_helper'
|
5
6
|
|
6
|
-
DataMapper::Adapters::XmlAdapter.threads = 2
|
7
|
-
|
8
7
|
describe DataMapper::Adapters::XmlAdapter do
|
9
8
|
before(:each) do
|
10
9
|
@adapter = DataMapper.setup(:default, {:adapter => 'xml', :directory => 'db'})
|
10
|
+
DataMapper.auto_migrate!
|
11
11
|
delete_all
|
12
12
|
end
|
13
13
|
|
@@ -15,14 +15,14 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
15
15
|
XMLTest::User.all.each {|u| u.destroy }
|
16
16
|
XMLTest::Post.all.each {|p| p.destroy }
|
17
17
|
AutoQuote.all.each {|aq| aq.destroy }
|
18
|
-
|
19
|
-
|
18
|
+
Food.all.each {|f| f.destroy }
|
19
|
+
Drink.all.each {|d| d.destroy }
|
20
|
+
Three::Level::Test::IsFun.all.each {|d| d.destroy }
|
20
21
|
end
|
21
|
-
|
22
|
+
|
22
23
|
after(:each) do
|
23
24
|
delete_all
|
24
25
|
end
|
25
|
-
|
26
26
|
|
27
27
|
describe "CRUD" do
|
28
28
|
|
@@ -32,14 +32,14 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
32
32
|
AutoQuote.all.size.should == 1
|
33
33
|
end
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
describe "content attribute" do
|
37
37
|
it "should be able to handle a content attribute" do
|
38
38
|
XMLTest::User.create(:name => "contentking", :content => "cool")
|
39
39
|
XMLTest::User.all.size.should == 1
|
40
40
|
end
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
describe "datetime" do
|
44
44
|
it "should do datetime" do
|
45
45
|
u1 = XMLTest::User.new
|
@@ -51,7 +51,7 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
describe "date" do
|
55
55
|
it "should do date" do
|
56
56
|
u1 = XMLTest::User.new
|
57
57
|
u1.name = "cool!"
|
@@ -80,7 +80,7 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
80
80
|
u2.cool.class.should == FalseClass
|
81
81
|
end
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
describe "associations" do
|
85
85
|
it "should have associations" do
|
86
86
|
u1 = XMLTest::User.new
|
@@ -99,14 +99,14 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
99
99
|
u3.posts.size.should == 2
|
100
100
|
end
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
describe "get all" do
|
104
104
|
it "should get all" do
|
105
105
|
XMLTest::User.create(:name => :yeah)
|
106
106
|
XMLTest::User.all.should_not == nil
|
107
107
|
end
|
108
108
|
end
|
109
|
-
|
109
|
+
|
110
110
|
describe "update" do
|
111
111
|
it "should update" do
|
112
112
|
u1 = XMLTest::User.new
|
@@ -125,7 +125,7 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
125
125
|
u.user_id.should_not == nil
|
126
126
|
end
|
127
127
|
end
|
128
|
-
|
128
|
+
|
129
129
|
describe "delete" do
|
130
130
|
it "should delete someone" do
|
131
131
|
user = XMLTest::User.create
|
@@ -141,7 +141,7 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
141
141
|
user1.money.class.should == BigDecimal
|
142
142
|
end
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
145
|
describe "find not" do
|
146
146
|
it "should find someone with a not clause" do
|
147
147
|
user1 = XMLTest::User.create(:name => "joe")
|
@@ -156,15 +156,37 @@ describe DataMapper::Adapters::XmlAdapter do
|
|
156
156
|
100.times {|n| Drink.create(:name => "Drink#{n}") }
|
157
157
|
# pick a random one
|
158
158
|
ids = Drink.all.map {|d| d.drink_id }
|
159
|
-
|
159
|
+
random_key = ids[rand(100).to_i]
|
160
|
+
drink = Drink.get(random_key)
|
160
161
|
drink.name = "Drinky drink!"
|
161
162
|
drink.save
|
162
163
|
Drink.first(:name => "Drinky drink!").should_not == nil
|
163
164
|
end
|
164
165
|
end
|
165
|
-
|
166
|
+
|
167
|
+
describe "complex class name" do
|
168
|
+
it "should be able to persist" do
|
169
|
+
fun = Three::Level::Test::IsFun.new
|
170
|
+
fun.superfun = true
|
171
|
+
fun.save
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "logging support" do
|
176
|
+
it "should work with logging" do
|
177
|
+
@adapter.loglevel = Logger::DEBUG
|
178
|
+
@adapter.logger = Logger.new("/dev/null")
|
179
|
+
XMLTest::User.create(:name => "contentking", :content => "cool")
|
180
|
+
XMLTest::User.all.size.should == 1
|
181
|
+
DataMapper.repository.adapter.loglevel = Logger::DEBUG
|
182
|
+
DataMapper.repository.adapter.logger = Logger.new('/dev/null')
|
183
|
+
XMLTest::User.create(:name => "contentking", :content => "cool")
|
184
|
+
XMLTest::User.all.size.should == 2
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
166
189
|
end
|
167
|
-
|
168
190
|
|
169
191
|
end
|
170
192
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,52 +1,64 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'dm-core'
|
3
3
|
require 'pathname'
|
4
|
-
require
|
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,109 +1,155 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-xml-adapter
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.59'
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
|
-
authors:
|
7
|
+
authors:
|
7
8
|
- Joshua Harding
|
8
9
|
autorequire: dm-xml-adapter
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2013-05-16 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
16
15
|
name: libxml-ruby
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
17
22
|
type: :runtime
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
26
31
|
name: builder
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
27
38
|
type: :runtime
|
28
|
-
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name:
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: dm-core
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
37
54
|
type: :runtime
|
38
|
-
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
- !ruby/object:Gem::Dependency
|
46
|
-
name:
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: dm-migrations
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
47
70
|
type: :runtime
|
48
|
-
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
57
86
|
type: :runtime
|
58
|
-
|
59
|
-
version_requirements: !ruby/object:Gem::Requirement
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: lrucache
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
65
110
|
description:
|
66
111
|
email: josh@statewidesoftware.com
|
67
112
|
executables: []
|
68
|
-
|
69
113
|
extensions: []
|
70
|
-
|
71
|
-
extra_rdoc_files:
|
114
|
+
extra_rdoc_files:
|
72
115
|
- README
|
73
|
-
files:
|
116
|
+
files:
|
74
117
|
- lib/dm-xml-adapter.rb
|
75
118
|
- lib/ratecounter.rb
|
76
119
|
- spec/dm-xml-adapter_spec.rb
|
77
120
|
- spec/spec_helper.rb
|
78
121
|
- README
|
79
|
-
has_rdoc: true
|
80
122
|
homepage:
|
81
123
|
licenses: []
|
82
|
-
|
83
124
|
post_install_message:
|
84
125
|
rdoc_options: []
|
85
|
-
|
86
|
-
require_paths:
|
126
|
+
require_paths:
|
87
127
|
- lib
|
88
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
hash: 758938256756139992
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
segments:
|
144
|
+
- 0
|
145
|
+
hash: 758938256756139992
|
100
146
|
requirements: []
|
101
|
-
|
102
147
|
rubyforge_project:
|
103
|
-
rubygems_version: 1.
|
148
|
+
rubygems_version: 1.8.24
|
104
149
|
signing_key:
|
105
150
|
specification_version: 3
|
106
|
-
summary: a XML adapter for DataMapper. this adapter allows you to use DataMapper with
|
107
|
-
|
151
|
+
summary: a XML adapter for DataMapper. this adapter allows you to use DataMapper with
|
152
|
+
XML files as a backing store.
|
153
|
+
test_files:
|
108
154
|
- spec/dm-xml-adapter_spec.rb
|
109
155
|
- spec/spec_helper.rb
|