spira 0.0.12 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +2 -0
- data/CHANGES.md +6 -3
- data/{README → README.md} +91 -120
- data/lib/rdf/ext/uri.rb +37 -0
- data/lib/spira.rb +47 -86
- data/lib/spira/association_reflection.rb +25 -0
- data/lib/spira/base.rb +353 -4
- data/lib/spira/exceptions.rb +13 -7
- data/lib/spira/persistence.rb +531 -0
- data/lib/spira/reflections.rb +19 -0
- data/lib/spira/resource.rb +165 -60
- data/lib/spira/serialization.rb +27 -0
- data/lib/spira/type.rb +7 -7
- data/lib/spira/types.rb +8 -11
- data/lib/spira/types/boolean.rb +3 -3
- data/lib/spira/types/date.rb +4 -5
- data/lib/spira/types/dateTime.rb +26 -0
- data/lib/spira/types/decimal.rb +2 -2
- data/lib/spira/types/float.rb +3 -3
- data/lib/spira/types/gYear.rb +26 -0
- data/lib/spira/types/int.rb +27 -0
- data/lib/spira/types/integer.rb +3 -3
- data/lib/spira/types/long.rb +27 -0
- data/lib/spira/types/negativeInteger.rb +27 -0
- data/lib/spira/types/nonNegativeInteger.rb +27 -0
- data/lib/spira/types/nonPositiveInteger.rb +27 -0
- data/lib/spira/types/positiveInteger.rb +27 -0
- data/lib/spira/types/string.rb +1 -1
- data/lib/spira/utils.rb +29 -0
- data/lib/spira/validations.rb +77 -0
- data/lib/spira/validations/uniqueness.rb +33 -0
- data/lib/spira/version.rb +3 -6
- metadata +218 -123
- data/lib/spira/errors.rb +0 -94
- data/lib/spira/extensions.rb +0 -14
- data/lib/spira/resource/class_methods.rb +0 -260
- data/lib/spira/resource/dsl.rb +0 -279
- data/lib/spira/resource/instance_methods.rb +0 -567
- data/lib/spira/resource/validations.rb +0 -47
data/AUTHORS
CHANGED
data/CHANGES.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
# Changelog for Spira <http://github.com/
|
1
|
+
# Changelog for Spira <http://github.com/rdf-ruby/spira>
|
2
|
+
|
3
|
+
## 0.3.0
|
4
|
+
* General updates to bring up to date.
|
2
5
|
|
3
6
|
## 0.0.12
|
4
7
|
* Implemented #validate, #validate! (refactored from #save!)
|
@@ -33,7 +36,7 @@
|
|
33
36
|
## 0.0.8
|
34
37
|
* Remove type checking for repository addition. More power in return for
|
35
38
|
slightly more difficult error messages.
|
36
|
-
* Repositories added via klass,
|
39
|
+
* Repositories added via klass, \*arg are now only instantiated on first use
|
37
40
|
instead of immediately.
|
38
41
|
* RDF::URI#as, RDF::Node#as, Resource.for, and Resource#new can now all accept
|
39
42
|
a block, which yields the new instance and saves it after the block.
|
@@ -46,7 +49,7 @@
|
|
46
49
|
permitted.
|
47
50
|
|
48
51
|
## 0.0.7
|
49
|
-
* Added Resource
|
52
|
+
* Added Resource.\[\], an alias for Resource.for
|
50
53
|
* Resource.each now correctly raises an exception when a repository isn't found
|
51
54
|
|
52
55
|
## 0.0.6
|
data/{README → README.md}
RENAMED
@@ -1,9 +1,7 @@
|
|
1
|
-
# Spira
|
1
|
+
# Spira [![Build Status](https://travis-ci.org/ruby-rdf/spira.png?branch=master)](http://travis-ci.org/ruby-rdf/spira)
|
2
2
|
|
3
3
|
It's time to breathe life into your linked data.
|
4
4
|
|
5
|
-
---
|
6
|
-
|
7
5
|
## Synopsis
|
8
6
|
Spira is a framework for using the information in [RDF.rb][] repositories as model
|
9
7
|
objects. It gives you the ability to work in a resource-oriented way without
|
@@ -17,11 +15,9 @@ A changelog is available in the {file:CHANGES.md} file.
|
|
17
15
|
|
18
16
|
### Example
|
19
17
|
|
20
|
-
class Person
|
21
|
-
|
22
|
-
include Spira::Resource
|
18
|
+
class Person < Spira::Base
|
23
19
|
|
24
|
-
base_uri "http://example.org/example/people"
|
20
|
+
configure :base_uri => "http://example.org/example/people"
|
25
21
|
|
26
22
|
property :name, :predicate => FOAF.name, :type => String
|
27
23
|
property :age, :predicate => FOAF.age, :type => Integer
|
@@ -48,6 +44,49 @@ A changelog is available in the {file:CHANGES.md} file.
|
|
48
44
|
* No need to put everything about an object into Spira
|
49
45
|
* Easy to use a resource as multiple models
|
50
46
|
|
47
|
+
## ActiveModel integration
|
48
|
+
|
49
|
+
This is a version of Spira that makes use of ActiveModel. The goal of this version is
|
50
|
+
to replace all the internals of Spira with ActiveModel hooks, and thus get rid of
|
51
|
+
superfluous code and increase compatibility with Rails stack. I want it to be
|
52
|
+
a drop-in replacement for ActiveRecord or any other mature ORM solution they use
|
53
|
+
with Ruby on Rails.
|
54
|
+
|
55
|
+
Although I've been trying to make the impact of this transition to be as little
|
56
|
+
as possible, there are a few changes that you should be aware of:
|
57
|
+
|
58
|
+
* Read the comments on "new_record?" and "reload" methods. They are key methods in
|
59
|
+
understanding how Spira is working with the repository. Basically, a Spira record
|
60
|
+
is new, if the repository has no statements with this record as subject. This means,
|
61
|
+
that *the repository is queried every time you invoke "new_record?"*.
|
62
|
+
Also note that if Spira.repository is not set, your Spira resource will always be "new".
|
63
|
+
Also note that instantiating a new Spira resource sends a query to the repository,
|
64
|
+
if it is set, but should work just fine even if it's not (until you try to "save" it).
|
65
|
+
* Customary Rails' record manipulation methods are preferred now.
|
66
|
+
This means, you should use more habitual "save", "destroy", "update_attributes", etc.
|
67
|
+
instead of the "save!", "destroy!", "update", "update!" and others, as introduced
|
68
|
+
by the original Spira gem.
|
69
|
+
* Callbacks are now handled by ActiveModel. Previous ways of defining them are
|
70
|
+
no longer valid. This also introduces the "before_", "after_" and "around_" callbacks
|
71
|
+
as well as their "_validation", "_save", "_update" and "_create" companions for you to enjoy.
|
72
|
+
* Validations are also handled by ActiveModel. With all the helper methods you have in
|
73
|
+
ActiveRecord.
|
74
|
+
* A spira resource (class) must be defined by *inheriting* it from Spira::Base.
|
75
|
+
Using "include Spira::Resource" is *temporarily* broken, but will be back at some point,
|
76
|
+
with improvements and stuff.
|
77
|
+
* "after/before_create" callbacks are *not* called when only the properties of your
|
78
|
+
Spira resource are getting persisted. That is, you may create a "type"-less Spira resource,
|
79
|
+
assign properties to it, then #save it -- "_create" callbacks will not be triggered,
|
80
|
+
because Spira cannot infer a resource definition ("resource - RDF.type - type")
|
81
|
+
for such resource and will only persist its properties.
|
82
|
+
Although this is how the original Spira behaves too, I thought I'd state it
|
83
|
+
explicitly here before you start freaking out.
|
84
|
+
* Configuration options "base_uri", "default_vocabulary" and "repository_name" are
|
85
|
+
now configured via "configure" method (see the examples below).
|
86
|
+
* A couple of (not so) subtle changes:
|
87
|
+
1) Global caching is gone. This means that "artist.works.first.artist" (reverse lookup)
|
88
|
+
does not return the original artist, but its copy retrieved from the database.
|
89
|
+
|
51
90
|
## Getting Started
|
52
91
|
|
53
92
|
The easiest way to work with Spira is to install it via Rubygems:
|
@@ -64,16 +103,14 @@ without the `RDF::` prefix. For example:
|
|
64
103
|
|
65
104
|
require 'spira'
|
66
105
|
|
67
|
-
class CD
|
68
|
-
|
69
|
-
base_uri 'http://example.org/cds'
|
106
|
+
class CD < Spira::Base
|
107
|
+
configure :base_uri => 'http://example.org/cds'
|
70
108
|
property :name, :predicate => DC.title, :type => XSD.string
|
71
109
|
property :artist, :predicate => URI.new('http://example.org/vocab/artist'), :type => :artist
|
72
110
|
end
|
73
111
|
|
74
|
-
class Artist
|
75
|
-
|
76
|
-
base_uri 'http://example.org/artists'
|
112
|
+
class Artist < Spira::Base
|
113
|
+
configure :base_uri => 'http://example.org/artists'
|
77
114
|
property :name, :predicate => DC.title, :type => XSD.string
|
78
115
|
has_many :cds, :predicate => URI.new('http://example.org/vocab/published_cd'), :type => XSD.string
|
79
116
|
end
|
@@ -147,8 +184,7 @@ Example
|
|
147
184
|
|
148
185
|
A class with a `type` set is assigned an `RDF.type` on creation and saving.
|
149
186
|
|
150
|
-
class Album
|
151
|
-
include Spira::Resource
|
187
|
+
class Album < Spira::Base
|
152
188
|
type URI.new('http://example.org/types/album')
|
153
189
|
property :name, :predicate => DC.title
|
154
190
|
end
|
@@ -162,6 +198,21 @@ In addition, one can count the members of a class with a `type` defined:
|
|
162
198
|
|
163
199
|
Album.count #=> 1
|
164
200
|
|
201
|
+
|
202
|
+
It is possible to assign multiple types to a Spira class:
|
203
|
+
|
204
|
+
class Man < Spira::Base
|
205
|
+
type RDF::URI.new('http://example.org/people/father')
|
206
|
+
type RDF::URI.new('http://example.org/people/cop')
|
207
|
+
end
|
208
|
+
|
209
|
+
All assigned types are accessible via "types":
|
210
|
+
|
211
|
+
Man.types #=> #<Set: {#<RDF::URI:0xd5ebc0(http://example.org/people/father)>, #<RDF::URI:0xd5e4b8(http://example.org/people/cop)>}>
|
212
|
+
|
213
|
+
Also note that "type" actually returns a first type from the list of types.
|
214
|
+
|
215
|
+
|
165
216
|
#### property
|
166
217
|
|
167
218
|
A class declares property members with the `property` function. See `Property Options` for more information.
|
@@ -174,10 +225,9 @@ A class declares list members with the `has_many` function. See `Property Optio
|
|
174
225
|
|
175
226
|
A class with a `default_vocabulary` set will transparently create predicates for defined properties:
|
176
227
|
|
177
|
-
class Song
|
178
|
-
|
179
|
-
|
180
|
-
base_uri 'http://example.org/songs'
|
228
|
+
class Song < Spira::Base
|
229
|
+
configure :default_vocabulary => URI.new('http://example.org/vocab'),
|
230
|
+
:base_uri => 'http://example.org/songs'
|
181
231
|
property :title
|
182
232
|
property :author, :type => :artist
|
183
233
|
end
|
@@ -189,22 +239,17 @@ A class with a `default_vocabulary` set will transparently create predicates for
|
|
189
239
|
dancing_queen.has_predicate?(RDF::URI.new('http://example.org/vocab/title')) #=> true
|
190
240
|
dancing_queen.has_predicate?(RDF::URI.new('http://example.org/vocab/artist')) #=> true
|
191
241
|
|
192
|
-
####
|
242
|
+
#### repository_name
|
193
243
|
|
194
244
|
Provides this class with a default repository to use instead of the `:default`
|
195
245
|
repository if one is not set.
|
196
246
|
|
197
|
-
class Song
|
198
|
-
|
247
|
+
class Song < Spira::Base
|
248
|
+
configure :repository_name => :songs
|
199
249
|
end
|
200
250
|
|
201
251
|
See 'Defining Repositories' for more information.
|
202
252
|
|
203
|
-
#### validate
|
204
|
-
|
205
|
-
Provides the name of a function which does some sort of validation. See
|
206
|
-
'Validations' for more information.
|
207
|
-
|
208
253
|
### Property Options
|
209
254
|
|
210
255
|
Spira classes can have properties that are either singular or a list. For a
|
@@ -256,16 +301,15 @@ is usually expressed as a URI. Here is the built-in Spira Integer class:
|
|
256
301
|
RDF::Literal.new(value)
|
257
302
|
end
|
258
303
|
|
259
|
-
register_alias XSD.integer
|
304
|
+
register_alias RDF::XSD.integer
|
260
305
|
end
|
261
306
|
end
|
262
307
|
|
263
308
|
Classes can now use this particular type like so:
|
264
309
|
|
265
|
-
class Test
|
266
|
-
include Spira::Resource
|
310
|
+
class Test < Spira::Base
|
267
311
|
property :test1, :type => Integer
|
268
|
-
property :test2, :type => XSD.integer
|
312
|
+
property :test2, :type => RDF::XSD.integer
|
269
313
|
end
|
270
314
|
|
271
315
|
Spira classes include the Spira::Types namespace, where several default types
|
@@ -297,8 +341,7 @@ turn an RDF::Value into a ruby object, and vice versa.
|
|
297
341
|
end
|
298
342
|
end
|
299
343
|
|
300
|
-
class MyClass
|
301
|
-
include Spira::Resource
|
344
|
+
class MyClass < Spira::Base
|
302
345
|
property :property1, :type => MyModule::MyType
|
303
346
|
end
|
304
347
|
|
@@ -311,8 +354,12 @@ You can define multiple repositories with Spira, and use more than one at a time
|
|
311
354
|
Spira.add_repository! :cds, RDF::Sesame::Repository.new 'some_server'
|
312
355
|
Spira.add_repository! :albums, RDF::Repository.load('some_file.nt')
|
313
356
|
|
314
|
-
CD
|
315
|
-
|
357
|
+
class CD < Spira::Base
|
358
|
+
configure :repository_name => :cds
|
359
|
+
end
|
360
|
+
class Album < Spira::Base
|
361
|
+
configure :repository_name => :albums
|
362
|
+
end
|
316
363
|
|
317
364
|
Objects can reference each other cross-repository.
|
318
365
|
|
@@ -323,94 +370,23 @@ If no repository has been specified, the `:default` repository will be used.
|
|
323
370
|
Artist.repository == repo #=> true
|
324
371
|
|
325
372
|
Classes can specify a default repository to use other than `:default` with the
|
326
|
-
`
|
373
|
+
`repository_name` function:
|
327
374
|
|
328
|
-
class Song
|
329
|
-
|
375
|
+
class Song < Spira::Base
|
376
|
+
configure :repository_name => :songs
|
330
377
|
end
|
331
378
|
|
332
379
|
Song.repository #=> nil, won't use :default
|
333
380
|
|
334
381
|
## Validations
|
335
382
|
|
336
|
-
|
337
|
-
|
338
|
-
{Spira::Errors} object will be populated with any errors. You can use the
|
339
|
-
built in `assert` and assert helpers such as `assert_set` and
|
340
|
-
`asssert_numeric`.
|
341
|
-
|
342
|
-
|
343
|
-
class CD
|
344
|
-
validate :is_real_music
|
345
|
-
def is_real_music
|
346
|
-
assert(artist.name != "Nickelback", :artist, "cannot be Nickelback")
|
347
|
-
end
|
348
|
-
|
349
|
-
validate :track_count_numeric
|
350
|
-
def track_count_numeric
|
351
|
-
assert_numeric(track_count)
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
dancing_queen.artist = nickelback
|
356
|
-
dancing_queen.save! #=> ValidationError
|
357
|
-
dancing_queen.errors.each #=> ["artist cannot be Nickelback"]
|
358
|
-
|
359
|
-
dancing_queen.artist = abba
|
360
|
-
dancing_queen.save! #=> true
|
383
|
+
[removed]
|
384
|
+
See the description of ActiveModel::Validations.
|
361
385
|
|
362
386
|
## Hooks
|
363
387
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
class CD
|
368
|
-
def before_save
|
369
|
-
self.publisher = 'No publisher set' if self.publisher.nil?
|
370
|
-
end
|
371
|
-
end
|
372
|
-
|
373
|
-
The `after_update` hook only fires on the `update` method, not simple property
|
374
|
-
accessors (to allow you to easily set properties in these without going into a
|
375
|
-
recursive loop):
|
376
|
-
|
377
|
-
class CD
|
378
|
-
def after_update
|
379
|
-
self.artist = 'Queen' # every artist should be Queen!
|
380
|
-
end
|
381
|
-
end
|
382
|
-
|
383
|
-
# ...snip ...
|
384
|
-
dancing_queen.artist
|
385
|
-
#=> "ABBA"
|
386
|
-
dancing_queen.name = "Dancing Queen"
|
387
|
-
dancing_queen.artist
|
388
|
-
#=> "ABBA"
|
389
|
-
dancing_queen.update(:name => "Dancing Queen")
|
390
|
-
dancing_queen.artist
|
391
|
-
#=> "Queen"
|
392
|
-
|
393
|
-
## Inheritance
|
394
|
-
|
395
|
-
You can extend Spira resources without a problem:
|
396
|
-
|
397
|
-
class BoxedSet < CD
|
398
|
-
include Spira::Resource
|
399
|
-
property cd_count, :predicate => CD.count, :type => Integer
|
400
|
-
end
|
401
|
-
|
402
|
-
You can also make Spira modules and include them into other classes:
|
403
|
-
|
404
|
-
module Media
|
405
|
-
include Spira::Resource
|
406
|
-
property :format, :predicate => Media.format
|
407
|
-
end
|
408
|
-
|
409
|
-
class CD
|
410
|
-
include Spira::Resource
|
411
|
-
include Media
|
412
|
-
end
|
413
|
-
|
388
|
+
[removed]
|
389
|
+
See the description of ActiveModel::Callbacks.
|
414
390
|
|
415
391
|
## Using Model Objects as RDF.rb Objects
|
416
392
|
|
@@ -427,16 +403,11 @@ There are a number of ways to ask for help. In declining order of preference:
|
|
427
403
|
* You can post issues to the Github issue queue
|
428
404
|
* (there might one day be a google group or other such support channel, but not yet)
|
429
405
|
|
430
|
-
##
|
431
|
-
|
432
|
-
#### Authors
|
433
|
-
* Ben Lavender <blavender@gmail.com>
|
434
|
-
|
435
|
-
#### 'License'
|
406
|
+
## 'License'
|
436
407
|
Spira is free and unemcumbered software released into the public
|
437
408
|
domain. For more information, see the included UNLICENSE file.
|
438
409
|
|
439
|
-
|
410
|
+
## Contributing
|
440
411
|
Fork it on Github and go. Please make sure you're kosher with the UNLICENSE
|
441
412
|
file before contributing.
|
442
413
|
|
data/lib/rdf/ext/uri.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module RDF
|
2
|
+
class URI
|
3
|
+
##
|
4
|
+
# Create a projection of this URI as the given Spira::Resource class.
|
5
|
+
# Equivalent to `klass.for(self, *args)`
|
6
|
+
#
|
7
|
+
# @example Instantiating a URI as a Spira Resource
|
8
|
+
# RDF::URI('http://example.org/person/bob').as(Person)
|
9
|
+
# @param [Class] klass
|
10
|
+
# @param [*Any] args Any arguments to pass to klass.for
|
11
|
+
# @yield [self] Executes a given block and calls `#save!`
|
12
|
+
# @yieldparam [self] self The newly created instance
|
13
|
+
# @return [Klass] An instance of klass
|
14
|
+
def as(klass, *args, &block)
|
15
|
+
raise ArgumentError, "#{klass} is not a Spira resource" unless klass.is_a?(Class) && klass.ancestors.include?(Spira::Base)
|
16
|
+
klass.for(self, *args, &block)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Node
|
21
|
+
##
|
22
|
+
# Create a projection of this Node as the given Spira::Resource class.
|
23
|
+
# Equivalent to `klass.for(self, *args)`
|
24
|
+
#
|
25
|
+
# @example Instantiating a blank node as a Spira Resource
|
26
|
+
# RDF::Node.new.as(Person)
|
27
|
+
# @param [Class] klass
|
28
|
+
# @param [*Any] args Any arguments to pass to klass.for
|
29
|
+
# @yield [self] Executes a given block and calls `#save!`
|
30
|
+
# @yieldparam [self] self The newly created instance
|
31
|
+
# @return [Klass] An instance of klass
|
32
|
+
def as(klass, *args)
|
33
|
+
raise ArgumentError, "#{klass} is not a Spira resource" unless klass.is_a?(Class) && klass.ancestors.include?(Spira::Base)
|
34
|
+
klass.for(self, *args)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/spira.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "rdf"
|
2
|
+
require "rdf/ext/uri"
|
3
|
+
require "promise"
|
4
|
+
require "spira/exceptions"
|
5
|
+
require "spira/utils"
|
4
6
|
|
5
7
|
##
|
6
8
|
# Spira is a framework for building projections of RDF data into Ruby classes.
|
@@ -9,66 +11,59 @@ require 'spira/exceptions'
|
|
9
11
|
# @see http://rdf.rubyforge.org
|
10
12
|
# @see http://github.com/bhuga/spira
|
11
13
|
# @see Spira::Resource
|
12
|
-
module Spira
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
#
|
17
|
-
# @see http://rdf.rubyforge.org/RDF/Repository.html
|
18
|
-
# @return [Hash{Symbol => RDF::Repository}]
|
19
|
-
# @private
|
20
|
-
def repositories
|
21
|
-
settings[:repositories] ||= {}
|
15
|
+
module RDF
|
16
|
+
class Repository
|
22
17
|
end
|
23
|
-
|
18
|
+
end
|
19
|
+
|
20
|
+
module Spira
|
21
|
+
|
22
|
+
autoload :Base, 'spira/base'
|
23
|
+
autoload :Type, 'spira/type'
|
24
|
+
autoload :Types, 'spira/types'
|
25
|
+
autoload :VERSION, 'spira/version'
|
24
26
|
|
25
27
|
##
|
26
28
|
# The list of all property types available for Spira resources
|
27
|
-
#
|
29
|
+
#
|
28
30
|
# @see Spira::Types
|
29
31
|
# @return [Hash{Symbol => Spira::Type}]
|
30
32
|
def types
|
31
|
-
|
33
|
+
@types ||= {}
|
32
34
|
end
|
33
35
|
module_function :types
|
34
36
|
|
35
|
-
##
|
36
|
-
# A thread-local hash for storing settings. Used by Resource classes.
|
37
|
-
#
|
38
|
-
# @see Spira::Resource
|
39
|
-
# @see Spira.repositories
|
40
|
-
# @see Spira.types
|
41
|
-
def settings
|
42
|
-
Thread.current[:spira] ||= {}
|
43
|
-
end
|
44
|
-
module_function :settings
|
45
|
-
|
46
37
|
##
|
47
38
|
# Add a repository to Spira's list of repositories.
|
48
39
|
#
|
49
40
|
# @overload add_repository(name, repo)
|
50
|
-
#
|
51
|
-
#
|
41
|
+
# @param [Symbol] name The name of this repository
|
42
|
+
# @param [RDF::Repository] repo
|
43
|
+
#
|
52
44
|
# @overload add_repository(name, klass, *args)
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
45
|
+
# @param [Symbol] name The name of this repository
|
46
|
+
# @param [Class] klass
|
47
|
+
# A Class that inherits from `RDF::Repository`
|
48
|
+
# @param [Array] args
|
49
|
+
# The list of arguments to instantiate the class
|
50
|
+
#
|
56
51
|
# @example Adding an ntriples file as a repository
|
57
52
|
# Spira.add_repository(:default, RDF::Repository.load('http://datagraph.org/jhacker/foaf.nt'))
|
58
53
|
# @example Adding an empty repository to be instantiated on use
|
59
54
|
# Spira.add_repository(:default, RDF::Repository)
|
60
55
|
# @return [Void]
|
61
|
-
# @see RDF::Repository
|
62
56
|
def add_repository(name, klass, *args)
|
63
|
-
repositories[name] =
|
57
|
+
repositories[name] =
|
58
|
+
case klass
|
64
59
|
when Class
|
65
60
|
promise { klass.new(*args) }
|
66
61
|
else
|
67
62
|
klass
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
63
|
+
end
|
64
|
+
if (name == :default) && repository(name).nil?
|
65
|
+
warn "WARNING: Adding nil default repository"
|
66
|
+
end
|
72
67
|
end
|
73
68
|
alias_method :add_repository!, :add_repository
|
74
69
|
module_function :add_repository, :add_repository!
|
@@ -91,10 +86,23 @@ module Spira
|
|
91
86
|
# @return [Void]
|
92
87
|
# @private
|
93
88
|
def clear_repositories!
|
94
|
-
|
89
|
+
@repositories = {}
|
95
90
|
end
|
96
91
|
module_function :clear_repositories!
|
97
92
|
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
##
|
97
|
+
# The list of repositories available for Spira resources
|
98
|
+
#
|
99
|
+
# @see http://rdf.rubyforge.org/RDF/Repository.html
|
100
|
+
# @return [Hash{Symbol => RDF::Repository}]
|
101
|
+
def repositories
|
102
|
+
@repositories ||= {}
|
103
|
+
end
|
104
|
+
module_function :repositories
|
105
|
+
|
98
106
|
##
|
99
107
|
# Alias a property type to another. This allows a range of options to be
|
100
108
|
# specified for a property type which all reference one Spira::Type
|
@@ -102,55 +110,8 @@ module Spira
|
|
102
110
|
# @param [Any] new The new symbol or reference
|
103
111
|
# @param [Any] original The type the new symbol should refer to
|
104
112
|
# @return [Void]
|
105
|
-
# @private
|
106
113
|
def type_alias(new, original)
|
107
|
-
types[new] = original
|
114
|
+
types[new] = original
|
108
115
|
end
|
109
116
|
module_function :type_alias
|
110
|
-
|
111
|
-
autoload :Resource, 'spira/resource'
|
112
|
-
autoload :Base, 'spira/base'
|
113
|
-
autoload :Type, 'spira/type'
|
114
|
-
autoload :Types, 'spira/types'
|
115
|
-
autoload :Errors, 'spira/errors'
|
116
|
-
autoload :VERSION, 'spira/version'
|
117
|
-
|
118
|
-
end
|
119
|
-
|
120
|
-
module RDF
|
121
|
-
class URI
|
122
|
-
##
|
123
|
-
# Create a projection of this URI as the given Spira::Resource class.
|
124
|
-
# Equivalent to `klass.for(self, *args)`
|
125
|
-
#
|
126
|
-
# @example Instantiating a URI as a Spira Resource
|
127
|
-
# RDF::URI('http://example.org/person/bob').as(Person)
|
128
|
-
# @param [Class] klass
|
129
|
-
# @param [*Any] args Any arguments to pass to klass.for
|
130
|
-
# @yield [self] Executes a given block and calls `#save!`
|
131
|
-
# @yieldparam [self] self The newly created instance
|
132
|
-
# @return [Klass] An instance of klass
|
133
|
-
def as(klass, *args, &block)
|
134
|
-
raise ArgumentError, "#{klass} is not a Spira resource" unless klass.is_a?(Class) && klass.ancestors.include?(Spira::Resource)
|
135
|
-
klass.for(self, *args, &block)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
class Node
|
140
|
-
##
|
141
|
-
# Create a projection of this Node as the given Spira::Resource class.
|
142
|
-
# Equivalent to `klass.for(self, *args)`
|
143
|
-
#
|
144
|
-
# @example Instantiating a blank node as a Spira Resource
|
145
|
-
# RDF::Node.new.as(Person)
|
146
|
-
# @param [Class] klass
|
147
|
-
# @param [*Any] args Any arguments to pass to klass.for
|
148
|
-
# @yield [self] Executes a given block and calls `#save!`
|
149
|
-
# @yieldparam [self] self The newly created instance
|
150
|
-
# @return [Klass] An instance of klass
|
151
|
-
def as(klass, *args)
|
152
|
-
raise ArgumentError, "#{klass} is not a Spira resource" unless klass.is_a?(Class) && klass.ancestors.include?(Spira::Resource)
|
153
|
-
klass.for(self, *args)
|
154
|
-
end
|
155
|
-
end
|
156
117
|
end
|