rdf-mapper 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +18 -4
- data/VERSION +1 -1
- data/lib/lib/adapters/rails.rb +18 -10
- data/lib/lib/associations/base.rb +1 -1
- data/lib/lib/associations/belongs_to.rb +6 -0
- data/lib/lib/associations/has_many.rb +36 -14
- data/lib/lib/model/base.rb +51 -14
- data/lib/lib/model/property.rb +1 -1
- data/lib/lib/scope/collection.rb +19 -0
- data/lib/lib/scope/condition.rb +12 -3
- data/lib/lib/scope/loader.rb +22 -7
- data/lib/lib/scope/model.rb +13 -5
- data/lib/lib/scope/query.rb +19 -5
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -25,10 +25,10 @@ The latest version of RDFMapper can be found at
|
|
25
25
|
|
26
26
|
== Contribute
|
27
27
|
|
28
|
-
Please note that RDFMapper in under heavy development right now, it's not
|
29
|
-
production
|
30
|
-
welcome. Email us at team@42cities.com or submit
|
31
|
-
GitHub[http://github.com/42cities/rdf-mapper/issues]
|
28
|
+
Please note that RDFMapper in under *heavy* *development* right now, it's *not*
|
29
|
+
*yet* suitable for production environment. Any contribution (bug tickets,
|
30
|
+
code patches) is more than welcome. Email us at team@42cities.com or submit
|
31
|
+
a ticket on GitHub[http://github.com/42cities/rdf-mapper/issues].
|
32
32
|
|
33
33
|
|
34
34
|
= 5-minute crash course
|
@@ -186,3 +186,17 @@ That's pretty much all you need to know. Go try and let us know what you think!
|
|
186
186
|
|
187
187
|
RDFMapper is free and unencumbered public domain software. For more information,
|
188
188
|
see http://unlicense.org or the accompanying UNLICENSE file.
|
189
|
+
|
190
|
+
|
191
|
+
== Roadmap
|
192
|
+
|
193
|
+
Several important features are not yet implemented. Here's a rough list of what is still
|
194
|
+
to be done:
|
195
|
+
|
196
|
+
* Test coverage is extremely low (~10%)
|
197
|
+
* Documentation coverage is mediocre
|
198
|
+
* REST adapter is missing
|
199
|
+
* SPARQL adapter supports only simple `DESCRIBE` queries. At later stages it will most
|
200
|
+
likely use {sparql-client}[http://github.com/bendiken/sparql-client] library.
|
201
|
+
* JSON support is missing. Will use {rdf-json}[http://github.com/bendiken/rdf-json] library.
|
202
|
+
* `has_one` and `has_and_belongs_to_many` are missing
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3
|
data/lib/lib/adapters/rails.rb
CHANGED
@@ -38,7 +38,7 @@ module RDFMapper
|
|
38
38
|
def save(instance)
|
39
39
|
if instance[:rails_id].nil?
|
40
40
|
obj = instance.class.find(instance.id.to_s).from(:rails)
|
41
|
-
instance[:rails_id] = obj
|
41
|
+
instance[:rails_id] = obj[:rails_id] unless obj.nil?
|
42
42
|
end
|
43
43
|
if instance[:rails_id].nil?
|
44
44
|
create(instance)
|
@@ -59,24 +59,27 @@ module RDFMapper
|
|
59
59
|
# [-]
|
60
60
|
##
|
61
61
|
def update(instance)
|
62
|
-
|
63
|
-
Query.new(query, @options).update
|
62
|
+
Query.new(default_query(instance), @options).update
|
64
63
|
end
|
65
64
|
|
66
65
|
##
|
67
66
|
# [-]
|
68
67
|
##
|
69
68
|
def create(instance)
|
70
|
-
|
71
|
-
Query.new(query, @options).create
|
69
|
+
Query.new(default_query(instance), @options).create
|
72
70
|
end
|
73
71
|
|
74
72
|
|
75
73
|
private
|
76
74
|
|
77
|
-
|
75
|
+
##
|
76
|
+
# [-]
|
77
|
+
##
|
78
|
+
def default_query(instance) #nodoc
|
79
|
+
conditions = {}.merge(instance.properties).merge(instance.foreign_keys)
|
80
|
+
RDFMapper::Scope::Query.new(instance.class, :conditions => conditions)
|
78
81
|
end
|
79
|
-
|
82
|
+
|
80
83
|
class Query
|
81
84
|
|
82
85
|
include RDFMapper::Logger
|
@@ -109,8 +112,8 @@ module RDFMapper
|
|
109
112
|
def find
|
110
113
|
@query.check(:rails_id)
|
111
114
|
#
|
112
|
-
debug 'Searching for %s with %s' % [@rails, @query.inspect]
|
113
|
-
debug 'Query: %s' % find_options.inspect
|
115
|
+
#debug 'Searching for %s with %s' % [@rails, @query.inspect]
|
116
|
+
#debug 'Query: %s' % find_options.inspect
|
114
117
|
#
|
115
118
|
@rails.find(:all, find_options).map do |record|
|
116
119
|
record_attributes(record)
|
@@ -138,7 +141,12 @@ module RDFMapper
|
|
138
141
|
def save_options
|
139
142
|
Hash[@query.to_a.map do |condition|
|
140
143
|
name = @replace[condition.name]
|
141
|
-
|
144
|
+
if condition.value.kind_of? RDFMapper::Model
|
145
|
+
value = condition.value[:rails_id]
|
146
|
+
else
|
147
|
+
value = condition.value
|
148
|
+
end
|
149
|
+
[name, value]
|
142
150
|
end.reject do |name, value|
|
143
151
|
name.nil? or value.nil?
|
144
152
|
end]
|
@@ -10,8 +10,12 @@ module RDFMapper
|
|
10
10
|
# objects as appropriate.
|
11
11
|
##
|
12
12
|
def replace(objects)
|
13
|
-
|
14
|
-
|
13
|
+
unless objects.kind_of? Array
|
14
|
+
objects = [objects]
|
15
|
+
end
|
16
|
+
|
17
|
+
new_objects = filter(objects)
|
18
|
+
return self if new_objects.empty?
|
15
19
|
|
16
20
|
new_objects.each do |child|
|
17
21
|
self << child
|
@@ -22,7 +26,7 @@ module RDFMapper
|
|
22
26
|
delete(child) unless new_objects.include?(child)
|
23
27
|
end
|
24
28
|
|
25
|
-
|
29
|
+
self
|
26
30
|
end
|
27
31
|
|
28
32
|
##
|
@@ -68,17 +72,18 @@ module RDFMapper
|
|
68
72
|
# Finds an associated object according to the same rules as
|
69
73
|
# RDFMapper::Model.find.
|
70
74
|
##
|
71
|
-
def find
|
72
|
-
|
75
|
+
def find(*args)
|
76
|
+
@association.find(*args).from(value)
|
73
77
|
end
|
74
78
|
|
75
79
|
##
|
76
|
-
# Returns
|
77
|
-
#
|
78
|
-
#
|
80
|
+
# Returns a new object of the collection type that has been
|
81
|
+
# instantiated with attributes and linked to this object,
|
82
|
+
# but not yet saved.
|
79
83
|
##
|
80
|
-
def build
|
81
|
-
|
84
|
+
def build(attributes)
|
85
|
+
obj = @association.new(attributes)
|
86
|
+
(self << obj).last
|
82
87
|
end
|
83
88
|
|
84
89
|
##
|
@@ -86,16 +91,24 @@ module RDFMapper
|
|
86
91
|
# instantiated with attributes, linked to this object through
|
87
92
|
# a foreign key, and that has already been saved.
|
88
93
|
##
|
89
|
-
def create
|
90
|
-
|
94
|
+
def create(attributes = {})
|
95
|
+
obj = @association.create(attributes.merge({ reverse => @instance }))
|
96
|
+
(self << obj).last
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# Either finds or creates a new object in the collection.
|
101
|
+
##
|
102
|
+
def find_or_create(attributes = {})
|
103
|
+
obj = attributes[:id].nil? ? nil : find(attributes[:id])
|
104
|
+
obj.nil? ? create(attributes) : obj
|
91
105
|
end
|
92
106
|
|
93
107
|
##
|
94
108
|
# Returns true if a given object is present in the collection
|
95
109
|
##
|
96
110
|
def include?(object)
|
97
|
-
|
98
|
-
@value.include?(object)
|
111
|
+
value.include?(object)
|
99
112
|
end
|
100
113
|
|
101
114
|
##
|
@@ -105,6 +118,13 @@ module RDFMapper
|
|
105
118
|
value
|
106
119
|
end
|
107
120
|
|
121
|
+
##
|
122
|
+
# [-]
|
123
|
+
##
|
124
|
+
def kind_of?(cls)
|
125
|
+
cls == self.class || cls == Enumerable || cls == Array
|
126
|
+
end
|
127
|
+
|
108
128
|
|
109
129
|
private
|
110
130
|
|
@@ -124,10 +144,12 @@ module RDFMapper
|
|
124
144
|
if @instance.id.nil?
|
125
145
|
return []
|
126
146
|
end
|
147
|
+
@value = []
|
127
148
|
replace @association.find(:all, {
|
128
149
|
:conditions => { reverse => @instance },
|
129
150
|
:skip => [reverse]
|
130
151
|
})
|
152
|
+
@value
|
131
153
|
end
|
132
154
|
|
133
155
|
##
|
data/lib/lib/model/base.rb
CHANGED
@@ -56,8 +56,20 @@ module RDFMapper
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
##
|
60
|
+
# Returns the short name for model's namespace. Defaults to `myrdf`
|
61
|
+
#
|
62
|
+
# class Person < RDFMapper::Model
|
63
|
+
# namespace 'http://example.org/schema#', :name => 'my'
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# Person.ns #=> 'example'
|
67
|
+
# Person.to_xml #=> '<my:Person></my:Person>'
|
68
|
+
#
|
69
|
+
# @return [String]
|
70
|
+
##
|
59
71
|
def ns
|
60
|
-
@ns || 'myrdf'
|
72
|
+
@ns.to_s || 'myrdf'
|
61
73
|
end
|
62
74
|
|
63
75
|
##
|
@@ -267,13 +279,11 @@ module RDFMapper
|
|
267
279
|
# successfully to the database or not.
|
268
280
|
#
|
269
281
|
# @param [Hash] attributes attributes of the new object
|
270
|
-
# @param [RDF::URI, String] id object's ID
|
271
|
-
#
|
272
282
|
# @return [Object] instance of RDFMapper::Model
|
273
283
|
# @return [nil] if save was unsuccessful
|
274
284
|
##
|
275
|
-
def create(attributes
|
276
|
-
new(attributes).save(id)
|
285
|
+
def create(attributes)
|
286
|
+
new(attributes).save(attributes[:id])
|
277
287
|
end
|
278
288
|
|
279
289
|
##
|
@@ -310,15 +320,13 @@ module RDFMapper
|
|
310
320
|
##
|
311
321
|
# Either finds or creates an object with the specified ID.
|
312
322
|
#
|
313
|
-
# @param [RDF::URI, String] id object's ID
|
314
323
|
# @param [Hash] attributes attributes of the new object
|
315
|
-
#
|
316
324
|
# @return [Object] instance of RDFMapper::Model
|
317
325
|
# @return [nil] if save was unsuccessful
|
318
326
|
##
|
319
|
-
def find_or_create(
|
320
|
-
instance = find(id)
|
321
|
-
instance.nil? ? create(
|
327
|
+
def find_or_create(atts = {})
|
328
|
+
instance = atts[:id].nil? ? nil : find(atts[:id])
|
329
|
+
instance.nil? ? create(atts) : instance
|
322
330
|
end
|
323
331
|
|
324
332
|
##
|
@@ -440,7 +448,7 @@ module RDFMapper
|
|
440
448
|
##
|
441
449
|
# Returns objects's unique ID.
|
442
450
|
#
|
443
|
-
# @return [
|
451
|
+
# @return [String] object's ID (URI)
|
444
452
|
##
|
445
453
|
def id(*args)
|
446
454
|
@id.nil? ? nil : @id.dup
|
@@ -452,6 +460,7 @@ module RDFMapper
|
|
452
460
|
# @return [Boolean]
|
453
461
|
##
|
454
462
|
def ==(other)
|
463
|
+
return false unless other.kind_of? self.class
|
455
464
|
(other.nil? or other.id.nil?) ? false : (id == other.id)
|
456
465
|
end
|
457
466
|
|
@@ -491,6 +500,32 @@ module RDFMapper
|
|
491
500
|
name.nil? ? nil : set_attribute(name, value)
|
492
501
|
end
|
493
502
|
|
503
|
+
##
|
504
|
+
# Returns a hash of all the properties (i.e. attributes without
|
505
|
+
# associations).
|
506
|
+
#
|
507
|
+
# @return [Hash] all properties of an instance (name => value)
|
508
|
+
##
|
509
|
+
def properties(*args)
|
510
|
+
Hash[self.class.properties.keys.map do |name|
|
511
|
+
[ name, self[name] ]
|
512
|
+
end].merge(@arbitrary).merge({ :id => id })
|
513
|
+
end
|
514
|
+
|
515
|
+
##
|
516
|
+
# Returns a hash of all foreign keys (i.e. URIs) for belongs_to
|
517
|
+
# type of associations.
|
518
|
+
#
|
519
|
+
# @return [Hash] all foreign keys of an instance (name => uri)
|
520
|
+
##
|
521
|
+
def foreign_keys
|
522
|
+
Hash[self.class.associations.select do |name, assoc|
|
523
|
+
assoc.belongs_to?
|
524
|
+
end.map do |name, assoc|
|
525
|
+
[ name, @attributes[name].keys ]
|
526
|
+
end]
|
527
|
+
end
|
528
|
+
|
494
529
|
##
|
495
530
|
# Returns a hash of all the attributes with their names as keys and
|
496
531
|
# the attributes' values as values.
|
@@ -498,7 +533,9 @@ module RDFMapper
|
|
498
533
|
# @return [Hash] all attributes of an instance (name => value)
|
499
534
|
##
|
500
535
|
def attributes(*args)
|
501
|
-
@attributes.
|
536
|
+
Hash[@attributes.keys.map do |name|
|
537
|
+
[ name, self[name] ]
|
538
|
+
end].merge(@arbitrary).merge({ :id => id })
|
502
539
|
end
|
503
540
|
|
504
541
|
##
|
@@ -537,7 +574,7 @@ module RDFMapper
|
|
537
574
|
def save(id = nil)
|
538
575
|
# Raise error if adapter is unspecified
|
539
576
|
check_for_adapter
|
540
|
-
|
577
|
+
|
541
578
|
if new? and id.nil?
|
542
579
|
raise RuntimeError, 'Save failed. ID must be specified'
|
543
580
|
end
|
@@ -588,7 +625,7 @@ module RDFMapper
|
|
588
625
|
# Sets ID of this object (must be RDF::URI or a String).
|
589
626
|
##
|
590
627
|
def id=(value) #nodoc
|
591
|
-
@id =
|
628
|
+
@id = value.to_s
|
592
629
|
end
|
593
630
|
|
594
631
|
##
|
data/lib/lib/model/property.rb
CHANGED
data/lib/lib/scope/collection.rb
CHANGED
@@ -127,6 +127,18 @@ module RDFMapper
|
|
127
127
|
items.include?(object)
|
128
128
|
end
|
129
129
|
|
130
|
+
##
|
131
|
+
# Invokes the block passing in successive elements from array,
|
132
|
+
# returning an array containing those elements for which the
|
133
|
+
# block returns a true value.
|
134
|
+
#
|
135
|
+
# @yield [Object]
|
136
|
+
# @return [Array]
|
137
|
+
##
|
138
|
+
def select(&block)
|
139
|
+
items.select { |x| block.call(x) }
|
140
|
+
end
|
141
|
+
|
130
142
|
##
|
131
143
|
# Converts collection into Array.
|
132
144
|
#
|
@@ -141,6 +153,13 @@ module RDFMapper
|
|
141
153
|
alias_method :slice, :[]
|
142
154
|
alias_method :include?, :exists?
|
143
155
|
|
156
|
+
##
|
157
|
+
# [-]
|
158
|
+
##
|
159
|
+
def kind_of?(cls)
|
160
|
+
cls == self.class || cls == Enumerable || cls == Array
|
161
|
+
end
|
162
|
+
|
144
163
|
##
|
145
164
|
# Developer-friendly representation of the instance
|
146
165
|
#
|
data/lib/lib/scope/condition.rb
CHANGED
@@ -18,10 +18,10 @@ module RDFMapper
|
|
18
18
|
if @att == :id
|
19
19
|
return @att
|
20
20
|
end
|
21
|
-
|
22
|
-
raise RuntimeError, 'Undefined attribute %s for %s' % [@att, @cls]
|
23
|
-
else
|
21
|
+
if att = @cls.has?(@att)
|
24
22
|
att.name
|
23
|
+
else
|
24
|
+
@att
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -34,6 +34,15 @@ module RDFMapper
|
|
34
34
|
|
35
35
|
alias_method :check, :value
|
36
36
|
|
37
|
+
##
|
38
|
+
# Checks whether specified object passes all conditions of the query.
|
39
|
+
#
|
40
|
+
# @param [RDFMapper::Model] object
|
41
|
+
##
|
42
|
+
def matches?(object)
|
43
|
+
object.send(name) == value
|
44
|
+
end
|
45
|
+
|
37
46
|
##
|
38
47
|
# [-]
|
39
48
|
##
|
data/lib/lib/scope/loader.rb
CHANGED
@@ -24,14 +24,29 @@ module RDFMapper
|
|
24
24
|
end
|
25
25
|
|
26
26
|
##
|
27
|
-
# Sets data adapter
|
27
|
+
# Sets data adapter or collection.
|
28
28
|
#
|
29
|
-
# @
|
30
|
-
#
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
# @overload type(adapter, options = {})
|
30
|
+
# Sets data adapter, this will override default model adapter
|
31
|
+
# @param [Symbol] adapter (:rails, :sparql, :rest)
|
32
|
+
# @param [Hash] options options to pass on to the adapter constructor
|
33
|
+
# @return [Object] adapter instance
|
34
|
+
#
|
35
|
+
# @overload type(collection)
|
36
|
+
# Sets collection of instances that should be queried.
|
37
|
+
# @param [Array] collection
|
38
|
+
##
|
39
|
+
def from(adapter_or_collection, options = {})
|
40
|
+
if adapter_or_collection.kind_of? Array
|
41
|
+
@loaded = true
|
42
|
+
adapter_or_collection.select do |instance|
|
43
|
+
@conditions.matches?(instance)
|
44
|
+
end.each do |instance|
|
45
|
+
@objects << instance.properties
|
46
|
+
end
|
47
|
+
return
|
48
|
+
end
|
49
|
+
@adapter = RDFMapper::Adapters.register(adapter_or_collection, @cls, options)
|
35
50
|
end
|
36
51
|
|
37
52
|
##
|
data/lib/lib/scope/model.rb
CHANGED
@@ -46,13 +46,21 @@ module RDFMapper
|
|
46
46
|
# In addition to the original method, preloads the model.
|
47
47
|
##
|
48
48
|
def [](name)
|
49
|
-
|
49
|
+
@arbitrary[name] || (@loaded ? super(name) : load[name])
|
50
50
|
end
|
51
51
|
|
52
52
|
##
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
53
|
+
# In addition to the original method, preloads the model.
|
54
|
+
#
|
55
|
+
# @return [Hash] all attributes of an instance (name => value)
|
56
|
+
##
|
57
|
+
def properties
|
58
|
+
check_for_nil_error
|
59
|
+
@loaded ? super : load.properties
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# In addition to the original method, preloads the model.
|
56
64
|
#
|
57
65
|
# @return [Hash] all attributes of an instance (name => value)
|
58
66
|
##
|
@@ -104,7 +112,7 @@ module RDFMapper
|
|
104
112
|
# In addition to the original method, preloads the model.
|
105
113
|
##
|
106
114
|
def get_attribute(name, *args)
|
107
|
-
@loaded ? super : load.send(name, *args)
|
115
|
+
@loaded ? super(name, *args) : load.send(name, *args)
|
108
116
|
end
|
109
117
|
|
110
118
|
##
|
data/lib/lib/scope/query.rb
CHANGED
@@ -74,6 +74,23 @@ module RDFMapper
|
|
74
74
|
nil
|
75
75
|
end
|
76
76
|
|
77
|
+
##
|
78
|
+
# Checks whether specified object passes all conditions of the query.
|
79
|
+
#
|
80
|
+
# @param [RDFMapper::Model] object
|
81
|
+
##
|
82
|
+
def matches?(object)
|
83
|
+
unless object.kind_of? RDFMapper::Model
|
84
|
+
return false
|
85
|
+
end
|
86
|
+
unless object.class == @cls
|
87
|
+
return false
|
88
|
+
end
|
89
|
+
to_a.reject do |condition|
|
90
|
+
condition.matches?(object)
|
91
|
+
end.empty?
|
92
|
+
end
|
93
|
+
|
77
94
|
##
|
78
95
|
# [-]
|
79
96
|
##
|
@@ -141,12 +158,9 @@ module RDFMapper
|
|
141
158
|
else
|
142
159
|
RDF::URI.new(self[:id].to_s)
|
143
160
|
end
|
144
|
-
|
145
|
-
:predicate => RDF.type,
|
146
|
-
:object => @cls.type
|
147
|
-
}] + to_a(:id).map do |condition|
|
161
|
+
to_a(:id).map do |condition|
|
148
162
|
condition.to_statements(target)
|
149
|
-
end.flatten.compact
|
163
|
+
end.flatten.compact + @cls.to_statements(:short => true)
|
150
164
|
end
|
151
165
|
|
152
166
|
##
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 3
|
9
|
+
version: 0.0.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Alex Serebryakov
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-05-
|
17
|
+
date: 2010-05-28 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|