dm-xml-adapter 0.58 → 0.59
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 +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
|