spira 0.0.12 → 0.5.0
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/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 [](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
|