dbd 0.0.11 → 0.0.12
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.
- 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
|
[](http://badge.fury.io/rb/dbd)
|
11
11
|
[](http://travis-ci.org/petervandenabeele/dbd)
|
12
|
+
[](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)
|