dbd 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Guardfile +0 -1
- data/HISTORY.txt +9 -0
- data/README.md +47 -39
- data/bin/test_1.rb +4 -4
- data/bin/test_5.rb +4 -4
- data/docs/test.rb +11 -11
- data/lib/dbd.rb +2 -2
- data/lib/dbd/context.rb +65 -0
- data/lib/dbd/context_fact.rb +76 -0
- data/lib/dbd/errors.rb +1 -1
- data/lib/dbd/fact.rb +37 -37
- data/lib/dbd/fact/collection.rb +5 -5
- data/lib/dbd/fact/factory.rb +6 -6
- data/lib/dbd/graph.rb +2 -2
- data/lib/dbd/resource.rb +25 -24
- data/lib/dbd/version.rb +1 -1
- data/spec/lib/dbd/context/context_spec.rb +74 -0
- data/spec/lib/dbd/context_fact/methods_spec.rb +79 -0
- data/spec/lib/dbd/context_fact/new_spec.rb +51 -0
- data/spec/lib/dbd/context_fact/test_factories_spec.rb +24 -0
- data/spec/lib/dbd/errors/errors_spec.rb +30 -0
- data/spec/lib/dbd/fact/collection/collection_spec.rb +58 -58
- data/spec/lib/dbd/fact/factory/factory_spec.rb +3 -3
- data/spec/lib/dbd/fact/methods_spec.rb +12 -12
- data/spec/lib/dbd/fact/new_spec.rb +9 -9
- data/spec/lib/dbd/fact/subject/test_factories_spec.rb +4 -4
- data/spec/lib/dbd/fact/test_factories_spec.rb +18 -18
- data/spec/lib/dbd/graph/add_to_graph_spec.rb +22 -22
- data/spec/lib/dbd/graph/from_csv_spec.rb +16 -16
- data/spec/lib/dbd/graph/test_factories_spec.rb +11 -11
- data/spec/lib/dbd/graph/to_csv_spec.rb +18 -18
- data/spec/lib/dbd/performance_spec.rb +4 -4
- data/spec/lib/dbd/resource/collection_spec.rb +28 -30
- data/spec/lib/dbd/resource/new_spec.rb +10 -11
- data/spec/lib/dbd/resource/test_factories_spec.rb +8 -7
- data/spec/lib/dbd/version/version_spec.rb +9 -0
- data/spec/test_factories/context.rb +16 -0
- data/spec/test_factories/{provenance_fact.rb → context_fact.rb} +6 -6
- data/spec/test_factories/fact.rb +23 -23
- data/spec/test_factories/fact/subject.rb +1 -1
- data/spec/test_factories/graph.rb +7 -7
- data/spec/test_factories/resource.rb +15 -10
- metadata +20 -16
- data/lib/dbd/provenance_fact.rb +0 -77
- data/lib/dbd/provenance_resource.rb +0 -63
- data/spec/lib/dbd/provenance_fact/methods_spec.rb +0 -78
- data/spec/lib/dbd/provenance_fact/new_spec.rb +0 -51
- data/spec/lib/dbd/provenance_fact/test_factories_spec.rb +0 -24
- data/spec/lib/dbd/provenance_resource/provenance_resource_spec.rb +0 -75
- data/spec/test_factories/provenance_resource.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49a3db0e5342a8c507f107cad3afd4ae3e21964c
|
4
|
+
data.tar.gz: 0118bb6bddcdc103577080f5deddc42ff3d2d5d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04d8a0525f3acf92a9203d63a846c829922f4363a65f7b1cfe900794f2a2ba0725de11a8a6cf330c3b6308a30e031c37d37052180c61adf99c8ab74d7b0a92f2
|
7
|
+
data.tar.gz: 03087f0151bbbe1d1b8c7f7e6a9dd090122136d597453459a8ee96e082f741c9bf4d86970255bc40f93bdd317ab9a1a113d2b2f940b9358ebec5bff11bffae9b
|
data/Guardfile
CHANGED
@@ -2,7 +2,6 @@ guard 'rspec', :all_after_pass => true, :all_on_start => true do
|
|
2
2
|
watch(%r{^spec/.+_spec\.rb$})
|
3
3
|
watch(%r{^spec/test_factories}) { "spec" }
|
4
4
|
watch(%r{^lib/dbd/helpers}) { "spec" }
|
5
|
-
# watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
6
5
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}/" }
|
7
6
|
watch('spec/spec_helper.rb') { "spec" }
|
8
7
|
watch('lib/dbd.rb') { "spec" }
|
data/HISTORY.txt
CHANGED
@@ -67,3 +67,12 @@
|
|
67
67
|
|
68
68
|
* object in Fact#short now truncated to 80 bytes
|
69
69
|
* using a utf-8 safe truncation (from ruby_peter_v)
|
70
|
+
|
71
|
+
0.0.12 (10 July 2013)
|
72
|
+
======
|
73
|
+
|
74
|
+
* major renaming
|
75
|
+
* ProvenanceFact => ContextFact
|
76
|
+
* ProvenanceResource => Context
|
77
|
+
* because the context of a fact is much more than the provenance
|
78
|
+
(also visibility, encryption, license, ...)
|
data/README.md
CHANGED
@@ -9,6 +9,7 @@ This is facts based data store, inspired by [RDF] concepts, but adding a log bas
|
|
9
9
|
|
10
10
|
[![Gem Version](https://badge.fury.io/rb/dbd.png)](http://badge.fury.io/rb/dbd)
|
11
11
|
[![Build Status](https://travis-ci.org/petervandenabeele/dbd.png?branch=master)](http://travis-ci.org/petervandenabeele/dbd)
|
12
|
+
[![Code Climate](https://codeclimate.com/github/petervandenabeele/dbd.png)](https://codeclimate.com/github/petervandenabeele/dbd)
|
12
13
|
|
13
14
|
## Features
|
14
15
|
|
@@ -23,13 +24,14 @@ This is facts based data store, inspired by [RDF] concepts, but adding a log bas
|
|
23
24
|
must remove this fact and replace the back-up
|
24
25
|
* since one single back-up file suffices, replacing the *single* back-up
|
25
26
|
file will actually remove the hard deleted fact(s) for good
|
26
|
-
* Fine grained
|
27
|
-
* Each base Fact points to a
|
28
|
-
possible
|
27
|
+
* Fine grained context (including provenance)
|
28
|
+
* Each base Fact points to a Context, so separate context and
|
29
|
+
provenance is possible per fact (e.g. different properties about the same
|
30
|
+
resource can come from different sources, different visibility etc.)
|
29
31
|
* can keep the original_source reference, creator, date, …
|
30
32
|
* can have a context that allows filtering data (e.g. private, professional, …)
|
31
33
|
* separate encryption schemes per context are possible
|
32
|
-
*
|
34
|
+
* Context is flexible, since built itself from Facts
|
33
35
|
* Schemaless
|
34
36
|
* uses the [RDF] (subject, predicate, object) concepts
|
35
37
|
* predicates, types can be defined in an ontology for declaring meaning
|
@@ -50,18 +52,24 @@ Open Source [MIT]
|
|
50
52
|
|
51
53
|
Running `ruby docs/test.rb` will execute the script below.
|
52
54
|
|
55
|
+
* Facts are logically grouped (by subject) in a Resource
|
56
|
+
* ContextFacts are logically grouped (by subject) in a Context
|
57
|
+
* each Fact refers to a Context with its context_subject
|
58
|
+
* all Facts and ContextFacts are stored sequentially and immutably
|
59
|
+
in a Graph
|
60
|
+
|
53
61
|
```
|
54
62
|
require 'dbd'
|
55
63
|
|
56
|
-
|
64
|
+
context = Dbd::Context.new
|
57
65
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
66
|
+
context << Dbd::ContextFact.new(predicate: "prov:context_fact", object: "public")
|
67
|
+
context << Dbd::ContextFact.new(predicate: "prov:source", object: "http://github.com/petervandenabeele/dbd")
|
68
|
+
context << Dbd::ContextFact.new(predicate: "dcterms:creator", object: "@peter_v")
|
69
|
+
context << Dbd::ContextFact.new(predicate: "dcterms:created", object: Time.now.utc)
|
70
|
+
context << Dbd::ContextFact.new(predicate: "prov:license", object: "MIT")
|
63
71
|
|
64
|
-
nobel_peace_2012 = Dbd::Resource.new(
|
72
|
+
nobel_peace_2012 = Dbd::Resource.new(context_subject: context.subject)
|
65
73
|
|
66
74
|
nobel_peace_2012 << Dbd::Fact.new(predicate: "todo:nobelPeacePriceWinner", object: "2012")
|
67
75
|
nobel_peace_2012 << Dbd::Fact.new(predicate: "rdfs:label", object: "EU") # this will use some RDF predicates in future
|
@@ -70,21 +78,21 @@ nobel_peace_2012 << Dbd::Fact.new(predicate: "todo:story", object: "A long perio
|
|
70
78
|
|
71
79
|
graph = Dbd::Graph.new
|
72
80
|
|
73
|
-
graph <<
|
81
|
+
graph << context << nobel_peace_2012
|
74
82
|
|
75
83
|
puts "facts in short representation:"
|
76
84
|
puts graph.map(&:short)
|
77
85
|
|
78
86
|
# facts in short representation:
|
79
|
-
# [
|
80
|
-
# [
|
81
|
-
# [
|
82
|
-
# [
|
83
|
-
# [
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
87
|
+
# [ cont ] : 7d0ccaa8 : prov:context_fact : public
|
88
|
+
# [ cont ] : 7d0ccaa8 : prov:source : http://github.com/petervandenabeele/dbd
|
89
|
+
# [ cont ] : 7d0ccaa8 : dcterms:creator : @peter_v
|
90
|
+
# [ cont ] : 7d0ccaa8 : dcterms:created : 2013-07-10 21:34:32 UTC
|
91
|
+
# [ cont ] : 7d0ccaa8 : prov:license : MIT
|
92
|
+
# 7d0ccaa8 : 47acd35d : todo:nobelPeacePriceWinn : 2012
|
93
|
+
# 7d0ccaa8 : 47acd35d : rdfs:label : EU
|
94
|
+
# 7d0ccaa8 : 47acd35d : rdfs:comment : European Union
|
95
|
+
# 7d0ccaa8 : 47acd35d : todo:story : A long period of peace,_ that is a "bliss".
|
88
96
|
|
89
97
|
csv = graph.to_CSV
|
90
98
|
|
@@ -92,30 +100,30 @@ puts "facts in full detail in CSV:"
|
|
92
100
|
puts csv
|
93
101
|
|
94
102
|
# facts in full detail in CSV:
|
95
|
-
# "
|
96
|
-
# "
|
97
|
-
# "
|
98
|
-
# "
|
99
|
-
# "
|
100
|
-
# "
|
101
|
-
# "
|
102
|
-
# "
|
103
|
-
# "
|
103
|
+
# "be44bc07-0c0e-450b-8bbc-4cc1f472be33","2013-07-10 21:34:32.759424573 UTC","","7d0ccaa8-b641-4f1b-82ad-f36ba3757aa0","prov:context_fact","public"
|
104
|
+
# "dae577a3-f210-4aab-9079-d87a4a362bd5","2013-07-10 21:34:32.759475097 UTC","","7d0ccaa8-b641-4f1b-82ad-f36ba3757aa0","prov:source","http://github.com/petervandenabeele/dbd"
|
105
|
+
# "750904f8-c052-46af-8b0a-266a701a6e06","2013-07-10 21:34:32.759497534 UTC","","7d0ccaa8-b641-4f1b-82ad-f36ba3757aa0","dcterms:creator","@peter_v"
|
106
|
+
# "a62ff09f-76a5-42ab-be9a-fc66c727ba41","2013-07-10 21:34:32.759513249 UTC","","7d0ccaa8-b641-4f1b-82ad-f36ba3757aa0","dcterms:created","2013-07-10 21:34:32 UTC"
|
107
|
+
# "427f9dc3-0544-4f33-9b30-ffa32930f5a8","2013-07-10 21:34:32.759528346 UTC","","7d0ccaa8-b641-4f1b-82ad-f36ba3757aa0","prov:license","MIT"
|
108
|
+
# "a8dbdfe6-6ead-4a35-bb6e-ec3f233aed5b","2013-07-10 21:34:32.759546366 UTC","7d0ccaa8-b641-4f1b-82ad-f36ba3757aa0","47acd35d-f2b1-4b36-8a37-90b0f08217d5","todo:nobelPeacePriceWinner","2012"
|
109
|
+
# "186571ac-1eca-4621-8b7e-9f263550e27b","2013-07-10 21:34:32.759564395 UTC","7d0ccaa8-b641-4f1b-82ad-f36ba3757aa0","47acd35d-f2b1-4b36-8a37-90b0f08217d5","rdfs:label","EU"
|
110
|
+
# "5a58d782-59bc-4ac0-b410-7ac637572f74","2013-07-10 21:34:32.759579688 UTC","7d0ccaa8-b641-4f1b-82ad-f36ba3757aa0","47acd35d-f2b1-4b36-8a37-90b0f08217d5","rdfs:comment","European Union"
|
111
|
+
# "2c3e9e63-fd94-4c0f-ac39-7a85b4dbb20d","2013-07-10 21:34:32.759594496 UTC","7d0ccaa8-b641-4f1b-82ad-f36ba3757aa0","47acd35d-f2b1-4b36-8a37-90b0f08217d5","todo:story","A long period of peace,
|
104
112
|
# that is a ""bliss""."
|
105
113
|
|
106
114
|
imported_graph = Dbd::Graph.new.from_CSV(csv)
|
107
115
|
|
108
116
|
puts imported_graph.map(&:short)
|
109
117
|
|
110
|
-
# [
|
111
|
-
# [
|
112
|
-
# [
|
113
|
-
# [
|
114
|
-
# [
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
118
|
-
#
|
118
|
+
# [ cont ] : 7d0ccaa8 : prov:context_fact : public
|
119
|
+
# [ cont ] : 7d0ccaa8 : prov:source : http://github.com/petervandenabeele/dbd
|
120
|
+
# [ cont ] : 7d0ccaa8 : dcterms:creator : @peter_v
|
121
|
+
# [ cont ] : 7d0ccaa8 : dcterms:created : 2013-07-10 21:34:32 UTC
|
122
|
+
# [ cont ] : 7d0ccaa8 : prov:license : MIT
|
123
|
+
# 7d0ccaa8 : 47acd35d : todo:nobelPeacePriceWinn : 2012
|
124
|
+
# 7d0ccaa8 : 47acd35d : rdfs:label : EU
|
125
|
+
# 7d0ccaa8 : 47acd35d : rdfs:comment : European Union
|
126
|
+
# 7d0ccaa8 : 47acd35d : todo:story : A long period of peace,_ that is a "bliss".
|
119
127
|
```
|
120
128
|
|
121
129
|
## Performance tests on 10 M facts
|
data/bin/test_1.rb
CHANGED
@@ -18,16 +18,16 @@ unless filename
|
|
18
18
|
end
|
19
19
|
|
20
20
|
require 'dbd'
|
21
|
-
|
22
|
-
|
21
|
+
context = Dbd::Context.new
|
22
|
+
context << Dbd::ContextFact.new(predicate: "prov:test" , object: "A" * 10)
|
23
23
|
|
24
|
-
resource = Dbd::Resource.new(
|
24
|
+
resource = Dbd::Resource.new(context_subject: context.subject)
|
25
25
|
(0...count).each do |i|
|
26
26
|
resource << Dbd::Fact.new(predicate: "test", object: "#{'B' * 80} #{i}")
|
27
27
|
end
|
28
28
|
|
29
29
|
graph = Dbd::Graph.new
|
30
|
-
graph <<
|
30
|
+
graph << context << resource
|
31
31
|
|
32
32
|
File.open(filename, 'w') do |f|
|
33
33
|
f << graph.to_CSV
|
data/bin/test_5.rb
CHANGED
@@ -23,15 +23,15 @@ start = Time.now
|
|
23
23
|
graph = Dbd::Graph.new
|
24
24
|
|
25
25
|
(0...count).each do |i|
|
26
|
-
|
27
|
-
|
26
|
+
context = Dbd::Context.new
|
27
|
+
context << Dbd::ContextFact.new(predicate: "prov:test" , object: "A" * 10)
|
28
28
|
|
29
|
-
resource = Dbd::Resource.new(
|
29
|
+
resource = Dbd::Resource.new(context_subject: context.subject)
|
30
30
|
(0...FACTS_PER_RESOURCE).each do |j|
|
31
31
|
resource << Dbd::Fact.new(predicate: "test", object: "#{'B' * 80} #{i * FACTS_PER_RESOURCE + j}")
|
32
32
|
end
|
33
33
|
|
34
|
-
graph <<
|
34
|
+
graph << context << resource
|
35
35
|
puts ("added resource #{i} to the graph")
|
36
36
|
end
|
37
37
|
|
data/docs/test.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'dbd'
|
2
2
|
|
3
|
-
|
3
|
+
context = Dbd::Context.new
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
context << Dbd::ContextFact.new(predicate: "prov:context_fact", object: "public")
|
6
|
+
context << Dbd::ContextFact.new(predicate: "prov:source", object: "http://github.com/petervandenabeele/dbd")
|
7
|
+
context << Dbd::ContextFact.new(predicate: "dcterms:creator", object: "@peter_v")
|
8
|
+
context << Dbd::ContextFact.new(predicate: "dcterms:created", object: Time.now.utc)
|
9
|
+
context << Dbd::ContextFact.new(predicate: "prov:license", object: "MIT")
|
10
10
|
|
11
|
-
nobel_peace_2012 = Dbd::Resource.new(
|
11
|
+
nobel_peace_2012 = Dbd::Resource.new(context_subject: context.subject)
|
12
12
|
|
13
13
|
nobel_peace_2012 << Dbd::Fact.new(predicate: "todo:nobelPeacePriceWinner", object: "2012")
|
14
14
|
nobel_peace_2012 << Dbd::Fact.new(predicate: "rdfs:label", object: "EU") # this will use some RDF predicates in future
|
@@ -17,13 +17,13 @@ nobel_peace_2012 << Dbd::Fact.new(predicate: "todo:story", object: "A long perio
|
|
17
17
|
|
18
18
|
graph = Dbd::Graph.new
|
19
19
|
|
20
|
-
graph <<
|
20
|
+
graph << context << nobel_peace_2012
|
21
21
|
|
22
22
|
puts "facts in short representation:"
|
23
23
|
puts graph.map(&:short)
|
24
24
|
|
25
25
|
# facts in short representation:
|
26
|
-
# [ prov ] : 5eb1ea27 : prov:
|
26
|
+
# [ prov ] : 5eb1ea27 : prov:context_fact : public
|
27
27
|
# [ prov ] : 5eb1ea27 : prov:source : http://github.com/petervandenabeele/dbd
|
28
28
|
# [ prov ] : 5eb1ea27 : dcterms:creator : @peter_v
|
29
29
|
# [ prov ] : 5eb1ea27 : dcterms:created : 2013-06-19 22:02:20 UTC
|
@@ -39,7 +39,7 @@ puts "facts in full detail in CSV:"
|
|
39
39
|
puts csv
|
40
40
|
|
41
41
|
# facts in full detail in CSV:
|
42
|
-
# "4720034a-01ea-4b6b-b9aa-45cb8c7c5e64","2013-06-19 22:02:20.489834224 UTC","","5eb1ea27-6691-4a57-ab13-8a59021968e1","prov:
|
42
|
+
# "4720034a-01ea-4b6b-b9aa-45cb8c7c5e64","2013-06-19 22:02:20.489834224 UTC","","5eb1ea27-6691-4a57-ab13-8a59021968e1","prov:context_fact","public"
|
43
43
|
# "d05a0a6c-a003-4320-b52b-a6e49e854437","2013-06-19 22:02:20.489889896 UTC","","5eb1ea27-6691-4a57-ab13-8a59021968e1","prov:source","http://github.com/petervandenabeele/dbd"
|
44
44
|
# "fc47abbd-da2d-4562-bb6b-ed8b84005734","2013-06-19 22:02:20.489913758 UTC","","5eb1ea27-6691-4a57-ab13-8a59021968e1","dcterms:creator","@peter_v"
|
45
45
|
# "f240e975-5d39-41eb-bb5a-cc59ede4c1a6","2013-06-19 22:02:20.489932320 UTC","","5eb1ea27-6691-4a57-ab13-8a59021968e1","dcterms:created","2013-06-19 22:02:20 UTC"
|
@@ -54,7 +54,7 @@ imported_graph = Dbd::Graph.new.from_CSV(csv)
|
|
54
54
|
|
55
55
|
puts imported_graph.map(&:short)
|
56
56
|
|
57
|
-
# [ prov ] : 5eb1ea27 : prov:
|
57
|
+
# [ prov ] : 5eb1ea27 : prov:context_fact : public
|
58
58
|
# [ prov ] : 5eb1ea27 : prov:source : http://github.com/petervandenabeele/dbd
|
59
59
|
# [ prov ] : 5eb1ea27 : dcterms:creator : @peter_v
|
60
60
|
# [ prov ] : 5eb1ea27 : dcterms:created : 2013-06-19 22:02:20 UTC
|
data/lib/dbd.rb
CHANGED
@@ -5,9 +5,9 @@ require 'dbd/version'
|
|
5
5
|
require 'dbd/errors'
|
6
6
|
require 'dbd/time_stamp'
|
7
7
|
require 'dbd/fact'
|
8
|
-
require 'dbd/
|
8
|
+
require 'dbd/context_fact'
|
9
9
|
require 'dbd/resource'
|
10
|
-
require 'dbd/
|
10
|
+
require 'dbd/context'
|
11
11
|
require 'dbd/graph'
|
12
12
|
|
13
13
|
require 'dbd/rdf_base'
|
data/lib/dbd/context.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
module Dbd
|
2
|
+
##
|
3
|
+
# A Context is derived from a Resource, and is the
|
4
|
+
# set of all Contexts that share the same subject.
|
5
|
+
#
|
6
|
+
# It is pointed to by a context_subject of a Fact and has
|
7
|
+
# no context_subject itself (the context_subject
|
8
|
+
# relationship from Fact to ContextFact is not recursive).
|
9
|
+
class Context < Resource
|
10
|
+
|
11
|
+
##
|
12
|
+
# Build a new Context.
|
13
|
+
#
|
14
|
+
# The subject can be either given as an argument or a new (random)
|
15
|
+
# subject is automatically set (see Resource for details).
|
16
|
+
#
|
17
|
+
# A context_subject may not be given here.
|
18
|
+
# @option options [Fact::Subject] :subject (new_subject) Optional: the subject for the resource
|
19
|
+
def initialize(options = {})
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Add a ContextFact (strictly only a ContextFact).
|
25
|
+
#
|
26
|
+
# Side effect on the context_fact argument:
|
27
|
+
# * if it has no subject, the subject is set in the context_fact
|
28
|
+
# * if is has the same subject as the resource, added unchanged.
|
29
|
+
# * if it has a different subject, a SubjectError is raised.
|
30
|
+
def <<(context_fact)
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Should not be called in Context subclass.
|
37
|
+
def context_subject
|
38
|
+
raise NoMethodError, "context_subject should not be called in Context."
|
39
|
+
end
|
40
|
+
|
41
|
+
def set_context_subject(options)
|
42
|
+
raise ArgumentError, "context_subject must not be in the options" if options[:context_subject]
|
43
|
+
end
|
44
|
+
|
45
|
+
# Validate that context_subject is not present here.
|
46
|
+
# This should never raise as the setter was blocked above.
|
47
|
+
def validate_context_subject
|
48
|
+
raise ContextError if @context_subject
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Assert _only_ Contexts here
|
53
|
+
def assert_fact_or_context_fact(context_fact)
|
54
|
+
raise ArgumentError, "Trying to add a non-ContextFact to a Context." unless context_fact.context_fact?
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# A noop for Context.
|
59
|
+
# @param [ContextFact] context_fact
|
60
|
+
def set_fact_context_subject!(context_fact)
|
61
|
+
# Do nothing
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Dbd
|
2
|
+
|
3
|
+
##
|
4
|
+
# ContextFact
|
5
|
+
#
|
6
|
+
# ContextFact is derived from Fact and behaves very similar.
|
7
|
+
#
|
8
|
+
# The ContextFacts with same subject form a Context and
|
9
|
+
# this is used as the target for the context_subject of a Fact.
|
10
|
+
#
|
11
|
+
# The context_subject of a ContextFact itself is empty, so the
|
12
|
+
# usage of context_subject is not recursive on this level (this
|
13
|
+
# allows efficient single pass loading in an underlying database).
|
14
|
+
#
|
15
|
+
# In the serialisation of a fact stream, the presence or absence of a
|
16
|
+
# context_subject marks the difference between a Fact and a ContextFact.
|
17
|
+
#
|
18
|
+
# The predicates of the ContextFacts in a Context would
|
19
|
+
# typically come from a defined context ontology (including provenance).
|
20
|
+
# Experimental examples of ontologies are built in the dbd_onto project.
|
21
|
+
class ContextFact < Fact
|
22
|
+
|
23
|
+
##
|
24
|
+
# Builds a new ContextFact.
|
25
|
+
#
|
26
|
+
# @param [Hash{Symbol => Object}] options
|
27
|
+
# @option options [Fact::Subject] :subject (new_subject) Optional: the subject for the ContextFact
|
28
|
+
# @option options [String] :predicate Required: the subject for the ContextFact
|
29
|
+
# @option options [String] :object Required: the object for the ContextFact
|
30
|
+
def initialize(options)
|
31
|
+
validate_context_subject(options)
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Executes the required update in used_context_subjects.
|
37
|
+
#
|
38
|
+
# For a ContextFact, there is no context_subject, so
|
39
|
+
# pointless to mark it in used_context_subjects hash.
|
40
|
+
def update_used_context_subjects(h)
|
41
|
+
# Do nothing (override the behaviour from super).
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Validates the presence or absence of context_subject.
|
46
|
+
#
|
47
|
+
# Here, in the derived ContextFact, it must not be present.
|
48
|
+
# @param [#nil?] context_subject
|
49
|
+
# Return [nil, String] nil if valid, an error message if not
|
50
|
+
def context_subject_error(context_subject)
|
51
|
+
"ContextFact subject should not be present in ContextFact" if context_subject
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Confirms this is a ContextFact
|
56
|
+
#
|
57
|
+
# Needed for validations that depend on different behavior for
|
58
|
+
# a context_fact (mainly, no context_subject).
|
59
|
+
def context_fact?
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
##
|
66
|
+
# Validate that context_subject is not set here.
|
67
|
+
def validate_context_subject(options)
|
68
|
+
raise ContextError if options[:context_subject]
|
69
|
+
end
|
70
|
+
|
71
|
+
def context_subject_short
|
72
|
+
"[ cont ]"
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
data/lib/dbd/errors.rb
CHANGED
@@ -3,7 +3,7 @@ module Dbd
|
|
3
3
|
class OutOfOrderError < StandardError ; end
|
4
4
|
class FactError < StandardError ; end
|
5
5
|
|
6
|
-
class
|
6
|
+
class ContextError < StandardError ; end
|
7
7
|
class SubjectError < StandardError ; end
|
8
8
|
class PredicateError < StandardError ; end
|
9
9
|
class ObjectError < StandardError ; end
|
data/lib/dbd/fact.rb
CHANGED
@@ -26,11 +26,11 @@ module Dbd
|
|
26
26
|
# creation of the fact, but it has to increase in strictly monotic
|
27
27
|
# order in a fact stream.
|
28
28
|
#
|
29
|
-
# * a *
|
29
|
+
# * a *context_subject* (a uuid)
|
30
30
|
#
|
31
|
-
# The subject of the
|
31
|
+
# The subject of the Context (a set of Contexts with
|
32
32
|
# the same subject) about this fact. Each Fact, points *back* to a
|
33
|
-
#
|
33
|
+
# Context (the Context must have been fully
|
34
34
|
# defined, earlier in a fact stream).
|
35
35
|
#
|
36
36
|
# * a *subject* (a uuid)
|
@@ -69,7 +69,7 @@ module Dbd
|
|
69
69
|
def self.attributes
|
70
70
|
[:id,
|
71
71
|
:time_stamp,
|
72
|
-
:
|
72
|
+
:context_subject,
|
73
73
|
:subject,
|
74
74
|
:predicate,
|
75
75
|
:object]
|
@@ -88,24 +88,24 @@ module Dbd
|
|
88
88
|
#
|
89
89
|
# The input class is validated (easy confusion with String or Time).
|
90
90
|
#
|
91
|
-
# @param [TimeStamp]
|
91
|
+
# @param [TimeStamp] time_stamp a time_stamp (not a Time or a String)
|
92
92
|
def time_stamp=(time_stamp)
|
93
93
|
validate_time_stamp_class(time_stamp)
|
94
94
|
set_once(:time_stamp, time_stamp)
|
95
95
|
end
|
96
96
|
|
97
97
|
##
|
98
|
-
# A set_once setter for
|
98
|
+
# A set_once setter for context_subject.
|
99
99
|
#
|
100
|
-
# @param [String]
|
101
|
-
def
|
102
|
-
set_once(:
|
100
|
+
# @param [String] context_subject a string representation of the uuid
|
101
|
+
def context_subject=(context_subject)
|
102
|
+
set_once(:context_subject, context_subject)
|
103
103
|
end
|
104
104
|
|
105
105
|
##
|
106
106
|
# A set_once setter for subject.
|
107
107
|
#
|
108
|
-
# @param [String]
|
108
|
+
# @param [String] subject a string representation of the uuid
|
109
109
|
def subject=(subject)
|
110
110
|
set_once(:subject, subject)
|
111
111
|
end
|
@@ -113,17 +113,17 @@ module Dbd
|
|
113
113
|
##
|
114
114
|
# Builds a new Fact.
|
115
115
|
#
|
116
|
-
# @param [Hash{Symbol => Object}]
|
116
|
+
# @param [Hash{Symbol => Object}] options
|
117
117
|
# @option options [#to_s] :predicate Required : the predicate for this Fact
|
118
118
|
# @option options [#to_s] :object Required : the object for this Fact (required)
|
119
|
-
# @option options [String (uuid)] :
|
119
|
+
# @option options [String (uuid)] :context_subject (nil) Optional: the subject of the Context
|
120
120
|
# @option options [String (uuid)] :subject (nil) Optional: the subject for this Fact
|
121
121
|
# @option options [TimeStamp] :time_stamp (nil) Optional: the time_stamp for this Fact
|
122
122
|
# @option options [String (uuid)] :id Optional : set the id
|
123
123
|
def initialize(options)
|
124
124
|
@id = options[:id] || self.class.factory.new_id
|
125
125
|
@time_stamp = options[:time_stamp]
|
126
|
-
@
|
126
|
+
@context_subject = options[:context_subject]
|
127
127
|
@subject = options[:subject]
|
128
128
|
@predicate = options[:predicate]
|
129
129
|
@object = options[:object]
|
@@ -157,7 +157,7 @@ module Dbd
|
|
157
157
|
# of a few nanoseconds will be required to resolve collisions
|
158
158
|
# on merge).
|
159
159
|
#
|
160
|
-
# @param [Fact]
|
160
|
+
# @param [Fact] other the other fact to compare with
|
161
161
|
# @return [trueish]
|
162
162
|
def equivalent?(other)
|
163
163
|
(self.class.attributes - [:time_stamp]).
|
@@ -168,26 +168,26 @@ module Dbd
|
|
168
168
|
##
|
169
169
|
# @return [String] a short string representation of a Fact
|
170
170
|
def short
|
171
|
-
"#{
|
171
|
+
"#{context_subject_short} : " \
|
172
172
|
"#{subject.to_s[0...8]} : " \
|
173
173
|
"#{predicate.to_s.ljust(24, ' ').truncate_utf8(24)} : " \
|
174
174
|
"#{object.to_s.truncate_utf8(80).gsub(/\n/, '_')}"
|
175
175
|
end
|
176
176
|
|
177
177
|
##
|
178
|
-
# Executes the required update in
|
178
|
+
# Executes the required update in used_context_subjects.
|
179
179
|
#
|
180
|
-
# For a Fact, pointing to a
|
181
|
-
# marks this
|
180
|
+
# For a Fact, pointing to a Context in it's context_subject,
|
181
|
+
# marks this context_subject in the "used_context_subjects" hash that
|
182
182
|
# is passed in as an argument (DCI). This will avoid further changes to the
|
183
|
-
#
|
183
|
+
# Context with this context_subject.
|
184
184
|
#
|
185
|
-
# This is overridden in the
|
185
|
+
# This is overridden in the ContextFact, since only relevant for a Fact.
|
186
186
|
#
|
187
|
-
# @param[Hash] :h the hash that contains the
|
188
|
-
def
|
189
|
-
# using a
|
190
|
-
h[
|
187
|
+
# @param[Hash] :h the hash that contains the context_subject index
|
188
|
+
def update_used_context_subjects(h)
|
189
|
+
# using a context_subject sets the key
|
190
|
+
h[context_subject] = true
|
191
191
|
end
|
192
192
|
|
193
193
|
##
|
@@ -199,40 +199,40 @@ module Dbd
|
|
199
199
|
# * time_stamp not validated, is set automatically later
|
200
200
|
# * predicate not validated, is validated upon creation
|
201
201
|
# * object not validated, is validated upon creation
|
202
|
-
[
|
202
|
+
[context_subject_error(context_subject),
|
203
203
|
subject ? nil : "Subject is missing"].compact
|
204
204
|
end
|
205
205
|
|
206
206
|
##
|
207
|
-
# Validates the presence or absence of
|
207
|
+
# Validates the presence or absence of context_subject.
|
208
208
|
#
|
209
|
-
# Here, in (base) Fact,
|
209
|
+
# Here, in (base) Fact, context_subject must be present.
|
210
210
|
#
|
211
|
-
# In the derived
|
211
|
+
# In the derived ContextFact it must NOT be present.
|
212
212
|
# This is how the difference is encoded between Fact and
|
213
|
-
#
|
213
|
+
# ContextFact in the fact stream.
|
214
214
|
#
|
215
|
-
# @param [Object]
|
215
|
+
# @param [Object] context_subject
|
216
216
|
# Return [nil, String] nil or an error message
|
217
|
-
def
|
218
|
-
"
|
217
|
+
def context_subject_error(context_subject)
|
218
|
+
"ContextFact subject is missing" unless context_subject
|
219
219
|
end
|
220
220
|
|
221
221
|
##
|
222
|
-
# Confirms this is not a
|
222
|
+
# Confirms this is not a ContextFact.
|
223
223
|
#
|
224
224
|
# Needed for validations that depend on different behavior for
|
225
|
-
# a
|
225
|
+
# a context_fact (mainly, no context_subject).
|
226
226
|
#
|
227
227
|
# @return [trueish] false in the Fact implementation
|
228
|
-
def
|
228
|
+
def context_fact?
|
229
229
|
false
|
230
230
|
end
|
231
231
|
|
232
232
|
private
|
233
233
|
|
234
|
-
def
|
235
|
-
"#{
|
234
|
+
def context_subject_short
|
235
|
+
"#{context_subject.to_s[0...8]}"
|
236
236
|
end
|
237
237
|
|
238
238
|
def validate_time_stamp_class(time_stamp)
|