dbd 0.0.9 → 0.0.10
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 +2 -2
- data/HISTORY.txt +11 -0
- data/README.md +24 -5
- data/bin/test_4.rb +2 -2
- data/bin/test_6.rb +2 -2
- data/docs/test.rb +1 -1
- data/lib/dbd/fact.rb +35 -67
- data/lib/dbd/fact/factory.rb +90 -0
- data/lib/dbd/fact/id.rb +2 -2
- data/lib/dbd/fact/subject.rb +2 -2
- data/lib/dbd/graph.rb +4 -6
- data/lib/dbd/helpers/uuid.rb +2 -2
- data/lib/dbd/resource.rb +1 -1
- data/lib/dbd/time_stamp.rb +16 -7
- data/lib/dbd/version.rb +1 -1
- data/spec/lib/dbd/fact/collection/collection_spec.rb +59 -59
- data/spec/lib/dbd/fact/factory/factory_spec.rb +109 -0
- data/spec/lib/dbd/fact/id/id_spec.rb +4 -4
- data/spec/lib/dbd/fact/id/test_factories_spec.rb +14 -0
- data/spec/lib/dbd/fact/methods_spec.rb +53 -57
- data/spec/lib/dbd/fact/new_spec.rb +32 -55
- data/spec/lib/dbd/fact/subject/subject_spec.rb +3 -3
- data/spec/lib/dbd/fact/subject/test_factories_spec.rb +23 -0
- data/spec/lib/dbd/fact/test_factories_spec.rb +82 -0
- data/spec/lib/dbd/graph/add_to_graph_spec.rb +31 -31
- data/spec/lib/dbd/graph/from_csv_spec.rb +47 -20
- data/spec/lib/dbd/graph/test_factories_spec.rb +58 -0
- data/spec/lib/dbd/graph/to_csv_spec.rb +46 -45
- data/spec/lib/dbd/helpers/ordered_set_collection/ordered_set_collection_spec.rb +17 -17
- data/spec/lib/dbd/helpers/uuid/uuid_spec.rb +11 -5
- data/spec/lib/dbd/performance_spec.rb +6 -6
- data/spec/lib/dbd/provenance_fact/methods_spec.rb +19 -19
- data/spec/lib/dbd/provenance_fact/new_spec.rb +17 -17
- data/spec/lib/dbd/provenance_fact/test_factories_spec.rb +24 -0
- data/spec/lib/dbd/provenance_resource/provenance_resource_spec.rb +24 -24
- data/spec/lib/dbd/rdf_base/rdf_base_spec.rb +7 -7
- data/spec/lib/dbd/resource/collection_spec.rb +34 -34
- data/spec/lib/dbd/resource/new_spec.rb +12 -12
- data/spec/lib/dbd/resource/test_factories_spec.rb +25 -0
- data/spec/lib/dbd/time_stamp/comparisons_spec.rb +31 -30
- data/spec/lib/dbd/time_stamp/methods_spec.rb +17 -13
- data/spec/lib/dbd/time_stamp/new_spec.rb +40 -14
- data/spec/lib/dbd/time_stamp/test_factories_spec.rb +18 -0
- data/spec/spec_helper.rb +2 -6
- data/spec/{factories → test_factories}/fact.rb +32 -25
- data/spec/{factories → test_factories}/fact/id.rb +2 -2
- data/spec/{factories → test_factories}/fact/subject.rb +3 -3
- data/spec/test_factories/graph.rb +25 -0
- data/spec/{factories → test_factories}/provenance_fact.rb +8 -10
- data/spec/{factories → test_factories}/provenance_resource.rb +3 -3
- data/spec/{factories → test_factories}/resource.rb +10 -4
- data/spec/{factories → test_factories}/time_stamp.rb +2 -2
- metadata +35 -32
- data/spec/factories/graph.rb +0 -23
- data/spec/lib/dbd/fact/factory_spec.rb +0 -82
- data/spec/lib/dbd/fact/id/factory_spec.rb +0 -16
- data/spec/lib/dbd/fact/subject/factory_spec.rb +0 -25
- data/spec/lib/dbd/graph/factory_spec.rb +0 -33
- data/spec/lib/dbd/provenance_fact/factory_spec.rb +0 -24
- data/spec/lib/dbd/resource/factory_spec.rb +0 -18
- data/spec/lib/dbd/time_stamp/factory_spec.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0ecabc694d7fb96ca29461e84ec65065d15e3ec
|
4
|
+
data.tar.gz: b31a6c1b351ddcfde4e90d10589526fb7e15bc78
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b5aac83bb9c2ae36d95121aec6570513821daf56372af99713930ab44e11e19dc585a2d730d35710c3614ca3c62e5f18fd1c3a4cfd4bff01e1e21bd74f2a7cb
|
7
|
+
data.tar.gz: 161310b4ba873d17a52707da9ae58f6b1c40a5c4163739f512410ae0c1445ecca818d88a0f7362008d8eb392fa103ae7ff0dbf883265dd838913801f315fe767
|
data/Guardfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
guard 'rspec' do
|
1
|
+
guard 'rspec', :all_after_pass => true, :all_on_start => true do
|
2
2
|
watch(%r{^spec/.+_spec\.rb$})
|
3
|
-
watch(%r{^spec/
|
3
|
+
watch(%r{^spec/test_factories}) { "spec" }
|
4
4
|
watch(%r{^lib/dbd/helpers}) { "spec" }
|
5
5
|
# watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
6
6
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}/" }
|
data/HISTORY.txt
CHANGED
@@ -50,3 +50,14 @@
|
|
50
50
|
* new function graph#to_CSV_file
|
51
51
|
* bin/test_5.rb was used to write 10M facts using ruby-2.0.0, 1.9.3 and jruby-1.7.4
|
52
52
|
* jruby is 3 time faster, but 10% more memory comsumption
|
53
|
+
|
54
|
+
0.0.10 (7 July 2013)
|
55
|
+
======
|
56
|
+
|
57
|
+
* Input validation for Graph#from_CSV (pairing with @marksim)
|
58
|
+
* Convert Graph.from_CSV => Graph#from_CSV (can apply multiple
|
59
|
+
from_CSV's on same graph)
|
60
|
+
* moved factories out of Fact to Fact::Factory
|
61
|
+
(removing the dependency injection violations from the Fact class)
|
62
|
+
* work-arounds for JRuby nanosecond rounding issues (#1)
|
63
|
+
* renamed Factories to TestFactories
|
data/README.md
CHANGED
@@ -48,7 +48,7 @@ Open Source [MIT]
|
|
48
48
|
|
49
49
|
## Examples
|
50
50
|
|
51
|
-
|
51
|
+
Running `ruby docs/test.rb` will execute the script below.
|
52
52
|
|
53
53
|
```
|
54
54
|
require 'dbd'
|
@@ -103,7 +103,7 @@ puts csv
|
|
103
103
|
# "a3da9295-b43a-4c3a-8e8c-97c3f04c1fa3","2013-06-19 22:02:20.490036790 UTC","5eb1ea27-6691-4a57-ab13-8a59021968e1","3767c493-79d3-4a97-a832-79e6361ddc4c","todo:story","A long period of peace,
|
104
104
|
# that is a ""bliss""."
|
105
105
|
|
106
|
-
imported_graph = Dbd::Graph.from_CSV(csv)
|
106
|
+
imported_graph = Dbd::Graph.new.from_CSV(csv)
|
107
107
|
|
108
108
|
puts imported_graph.map(&:short)
|
109
109
|
|
@@ -121,21 +121,40 @@ puts imported_graph.map(&:short)
|
|
121
121
|
## Performance tests on 10 M facts
|
122
122
|
|
123
123
|
In version 0.0.9 a number of test programs where added (e.g. ../bin/test_5.rb)
|
124
|
-
that where used to
|
124
|
+
that where used to populate in memory and write to disk a data set with 10 M facts.
|
125
125
|
|
126
126
|
This function was tested on ruby-2.0.0, ruby-1.9.3 and jruby-1.7.4. The facts
|
127
127
|
had an approximate size of 250 Bytes each (80 Bytes object).
|
128
128
|
|
129
129
|
The time needed and memory size (RSS) for populating the in-memory dataset was:
|
130
130
|
|
131
|
-
10 M facts (of 250 Bytes; 2.5 GB netto data):
|
131
|
+
Generate in memory 10 M facts (of 250 Bytes; 2.5 GB netto data):
|
132
132
|
|
133
|
-
| ruby | time | memory (RSS
|
133
|
+
| ruby | time | memory (RSS) |
|
134
134
|
|------------|-------------| ------------:|
|
135
135
|
| ruby-1.9.3 | 863 seconds | 8.1 GB |
|
136
136
|
| ruby-2.0.0 | 862 seconds | 9.0 GB |
|
137
137
|
|jruby-1.7.4 | 345 seconds | 10.8 GB |
|
138
138
|
|
139
|
+
In version 0.0.10 a test for reading a fact stream from a CSV file was added
|
140
|
+
(e.g. ../bin/test_6.rb). Reading back a CSV file that was written earlier with
|
141
|
+
10 M facts (with test_5.rb) was tested on jruby-1.7.4. and ruby-2.0.0.
|
142
|
+
|
143
|
+
This version also has input validation on the strings in the CSV. The time needed
|
144
|
+
and memory size (RSS) for reading the file (and populating the in-memory dataset
|
145
|
+
was):
|
146
|
+
|
147
|
+
Read from CSV (to_CSV) 10 M facts (of 250 Bytes; 2.5 GB netto data):
|
148
|
+
|
149
|
+
| ruby | time | memory (RSS) |
|
150
|
+
|------------|---------------|--------------:|
|
151
|
+
| ruby-1.9.3 | 4434 seconds | approx. 10 GB |
|
152
|
+
| ruby-2.0.0 | 5163 seconds | approx. 15 GB |
|
153
|
+
|jruby-1.7.4 | 1513 seconds | approx. 14 GB |
|
154
|
+
|
155
|
+
The significantly larger times to read from_CSV versus writing to_CSV are _not_
|
156
|
+
significantly caused by input validation (a test in JRuby without validation on
|
157
|
+
reading 1M facts was only 6% faster with the input validation turned off).
|
139
158
|
|
140
159
|
[RDF]: http://www.w3.org/RDF/
|
141
160
|
[Rationale]: http://github.com/petervandenabeele/dbd/blob/master/docs/rationale.md
|
data/bin/test_4.rb
CHANGED
@@ -19,7 +19,7 @@ row_data = [
|
|
19
19
|
"test",
|
20
20
|
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 0"]
|
21
21
|
|
22
|
-
puts "starting CSV.
|
22
|
+
puts "starting CSV.generate"
|
23
23
|
|
24
24
|
start_time = Time.now
|
25
25
|
|
@@ -29,4 +29,4 @@ csv_string = CSV.generate(force_quotes: true) do |csv|
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
puts "CSV.
|
32
|
+
puts "CSV.generate took #{Time.now - start_time} seconds"
|
data/bin/test_6.rb
CHANGED
@@ -13,9 +13,9 @@ require 'dbd'
|
|
13
13
|
start = Time.now
|
14
14
|
|
15
15
|
graph = File.open(filename) do |f|
|
16
|
-
Dbd::Graph.from_CSV(f)
|
16
|
+
Dbd::Graph.new.from_CSV(f)
|
17
17
|
end
|
18
18
|
|
19
|
-
puts "Graph is ready (took #{Time.now - start}s)
|
19
|
+
puts "Graph is ready (took #{Time.now - start}s)."
|
20
20
|
|
21
21
|
puts "graph.size is #{graph.size}"
|
data/docs/test.rb
CHANGED
@@ -50,7 +50,7 @@ puts csv
|
|
50
50
|
# "a3da9295-b43a-4c3a-8e8c-97c3f04c1fa3","2013-06-19 22:02:20.490036790 UTC","5eb1ea27-6691-4a57-ab13-8a59021968e1","3767c493-79d3-4a97-a832-79e6361ddc4c","todo:story","A long period of peace,
|
51
51
|
# that is a ""bliss""."
|
52
52
|
|
53
|
-
imported_graph = Dbd::Graph.from_CSV(csv)
|
53
|
+
imported_graph = Dbd::Graph.new.from_CSV(csv)
|
54
54
|
|
55
55
|
puts imported_graph.map(&:short)
|
56
56
|
|
data/lib/dbd/fact.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'dbd/fact/factory'
|
1
2
|
require 'dbd/fact/collection'
|
2
3
|
require 'dbd/fact/subject'
|
3
4
|
require 'dbd/fact/id'
|
@@ -57,6 +58,12 @@ module Dbd
|
|
57
58
|
# in RDF. Probably more detailed modeling using RDF object will follow.
|
58
59
|
class Fact
|
59
60
|
|
61
|
+
##
|
62
|
+
# @return [Module] The module that has the factories for Fact
|
63
|
+
def self.factory
|
64
|
+
self::Factory
|
65
|
+
end
|
66
|
+
|
60
67
|
##
|
61
68
|
# @return [Array] The 6 attributes of a Fact.
|
62
69
|
def self.attributes
|
@@ -73,13 +80,15 @@ module Dbd
|
|
73
80
|
end
|
74
81
|
|
75
82
|
##
|
76
|
-
#
|
83
|
+
# These "set once" setters implement a form of immutable behavior.
|
84
|
+
# The value can be set once (after initial creation the object),
|
85
|
+
# but can never be changed after that.
|
77
86
|
#
|
78
|
-
#
|
79
|
-
# be set once (possibly after creation the object), but can
|
80
|
-
# never be changed after that.
|
87
|
+
# A set_once setter for time_stamp.
|
81
88
|
#
|
82
89
|
# The input class is validated (easy confusion with String or Time).
|
90
|
+
#
|
91
|
+
# @param [TimeStamp] :time_stamp a time_stamp (not a Time or a String)
|
83
92
|
def time_stamp=(time_stamp)
|
84
93
|
validate_time_stamp_class(time_stamp)
|
85
94
|
set_once(:time_stamp, time_stamp)
|
@@ -88,9 +97,7 @@ module Dbd
|
|
88
97
|
##
|
89
98
|
# A set_once setter for provenance_subject.
|
90
99
|
#
|
91
|
-
#
|
92
|
-
# be set once (possibly after creation the object), but can
|
93
|
-
# never be changed after that.
|
100
|
+
# @param [String] :provenance_subject a string representation of the uuid
|
94
101
|
def provenance_subject=(provenance_subject)
|
95
102
|
set_once(:provenance_subject, provenance_subject)
|
96
103
|
end
|
@@ -98,29 +105,15 @@ module Dbd
|
|
98
105
|
##
|
99
106
|
# A set_once setter for subject.
|
100
107
|
#
|
101
|
-
#
|
102
|
-
# be set once (possibly after creation the object), but can
|
103
|
-
# never be changed after that.
|
108
|
+
# @param [String] :subject a string representation of the uuid
|
104
109
|
def subject=(subject)
|
105
110
|
set_once(:subject, subject)
|
106
111
|
end
|
107
112
|
|
108
|
-
##
|
109
|
-
# @return [String] A new subject string.
|
110
|
-
def self.new_subject
|
111
|
-
Subject.new_subject
|
112
|
-
end
|
113
|
-
|
114
|
-
##
|
115
|
-
# @return [String] A new id string.
|
116
|
-
def self.new_id
|
117
|
-
ID.new_id
|
118
|
-
end
|
119
|
-
|
120
113
|
##
|
121
114
|
# Builds a new Fact.
|
122
115
|
#
|
123
|
-
# @param [Hash{Symbol => Object}] options
|
116
|
+
# @param [Hash{Symbol => Object}] :options
|
124
117
|
# @option options [#to_s] :predicate Required : the predicate for this Fact
|
125
118
|
# @option options [#to_s] :object Required : the object for this Fact (required)
|
126
119
|
# @option options [String (uuid)] :provenance_subject (nil) Optional: the subject of the provenance(resource|fact)
|
@@ -128,13 +121,13 @@ module Dbd
|
|
128
121
|
# @option options [TimeStamp] :time_stamp (nil) Optional: the time_stamp for this Fact
|
129
122
|
# @option options [String (uuid)] :id Optional : set the id
|
130
123
|
def initialize(options)
|
131
|
-
@id = options[:id] || self.class.new_id
|
124
|
+
@id = options[:id] || self.class.factory.new_id
|
132
125
|
@time_stamp = options[:time_stamp]
|
133
|
-
validate_time_stamp_class(@time_stamp)
|
134
126
|
@provenance_subject = options[:provenance_subject]
|
135
127
|
@subject = options[:subject]
|
136
128
|
@predicate = options[:predicate]
|
137
129
|
@object = options[:object]
|
130
|
+
validate_time_stamp_class(@time_stamp)
|
138
131
|
raise PredicateError, "predicate cannot be nil" if predicate.nil?
|
139
132
|
raise ObjectError, "object cannot be nil" if object.nil?
|
140
133
|
end
|
@@ -153,18 +146,7 @@ module Dbd
|
|
153
146
|
end
|
154
147
|
|
155
148
|
##
|
156
|
-
#
|
157
|
-
# (e.g. pulled from a CSV row).
|
158
|
-
#
|
159
|
-
# @param [Array] string_values Required : the array with values, organized as in attributes
|
160
|
-
# @return [Fact, ProvenanceFact] the constructed fact
|
161
|
-
def self.from_string_values(string_values)
|
162
|
-
string_hash = hash_from_values(string_values)
|
163
|
-
fact_from_hash(values_hash(string_hash))
|
164
|
-
end
|
165
|
-
|
166
|
-
##
|
167
|
-
# Equivalent facts (have all same values, except time_stamp).
|
149
|
+
# Equivalent facts (have all same values, except time_stamp which is near?).
|
168
150
|
#
|
169
151
|
# For "equality" only a test on the id is used. If the id
|
170
152
|
# (which is a uuid) is the same, we assume that is the "same"
|
@@ -174,6 +156,9 @@ module Dbd
|
|
174
156
|
# The time_stamp may be slightly different (because shifts
|
175
157
|
# of a few nanoseconds will be required to resolve collisions
|
176
158
|
# on merge).
|
159
|
+
#
|
160
|
+
# @param [Fact] :other the other fact to compare with
|
161
|
+
# @return [trueish]
|
177
162
|
def equivalent?(other)
|
178
163
|
(self.class.attributes - [:time_stamp]).
|
179
164
|
all?{ |attribute| self.send(attribute) == other.send(attribute) } &&
|
@@ -198,6 +183,8 @@ module Dbd
|
|
198
183
|
# ProvenanceResource with this provenance_subject.
|
199
184
|
#
|
200
185
|
# This is overridden in the ProvenanceFact, since only relevant for a Fact.
|
186
|
+
#
|
187
|
+
# @param[Hash] :h the hash that contains the provenance_subject index
|
201
188
|
def update_used_provenance_subjects(h)
|
202
189
|
# using a provenance_subject sets the key
|
203
190
|
h[provenance_subject] = true
|
@@ -210,22 +197,22 @@ module Dbd
|
|
210
197
|
def errors
|
211
198
|
# * id not validated, is set automatically upon creation
|
212
199
|
# * time_stamp not validated, is set automatically later
|
213
|
-
# * predicate not validated, is validated
|
214
|
-
# * object not validated, is validated
|
215
|
-
[
|
216
|
-
|
217
|
-
a << "Subject is missing" unless subject
|
218
|
-
end.compact
|
200
|
+
# * predicate not validated, is validated upon creation
|
201
|
+
# * object not validated, is validated upon creation
|
202
|
+
[provenance_subject_error(provenance_subject),
|
203
|
+
subject ? nil : "Subject is missing"].compact
|
219
204
|
end
|
220
205
|
|
221
206
|
##
|
222
207
|
# Validates the presence or absence of provenance_subject.
|
223
208
|
#
|
224
|
-
# Here, in (base) Fact, provenance_subject must be present
|
225
|
-
#
|
209
|
+
# Here, in (base) Fact, provenance_subject must be present.
|
210
|
+
#
|
211
|
+
# In the derived ProvenanceFact it must NOT be present.
|
226
212
|
# This is how the difference is encoded between Fact and
|
227
213
|
# ProvenanceFact in the fact stream.
|
228
|
-
#
|
214
|
+
#
|
215
|
+
# @param [Object] provenance_subject
|
229
216
|
# Return [nil, String] nil or an error message
|
230
217
|
def provenance_subject_error(provenance_subject)
|
231
218
|
"Provenance subject is missing" unless provenance_subject
|
@@ -236,6 +223,8 @@ module Dbd
|
|
236
223
|
#
|
237
224
|
# Needed for validations that depend on different behavior for
|
238
225
|
# a provenance_fact (mainly, no provenance_subject).
|
226
|
+
#
|
227
|
+
# @return [trueish] false in the Fact implementation
|
239
228
|
def provenance_fact?
|
240
229
|
false
|
241
230
|
end
|
@@ -246,27 +235,6 @@ module Dbd
|
|
246
235
|
"#{provenance_subject.to_s[0...8]}"
|
247
236
|
end
|
248
237
|
|
249
|
-
# FIXME This has to move to a Fact::Factory
|
250
|
-
def self.hash_from_values(values)
|
251
|
-
# Do not keep "empty" values (e.g. the provenance_subject for a ProvenanceFact).
|
252
|
-
attributes_values_array = [attributes, values].transpose.delete_if{|a,v| v.nil? || v == ''}
|
253
|
-
Hash[attributes_values_array]
|
254
|
-
end
|
255
|
-
|
256
|
-
def self.values_hash(string_hash)
|
257
|
-
string_hash.dup.tap do |h|
|
258
|
-
h[:time_stamp] = TimeStamp.new(time: h[:time_stamp])
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
def self.fact_from_hash(hash)
|
263
|
-
if hash[:provenance_subject]
|
264
|
-
Fact.new(hash)
|
265
|
-
else
|
266
|
-
ProvenanceFact.new(hash)
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
238
|
def validate_time_stamp_class(time_stamp)
|
271
239
|
unless time_stamp.nil? || time_stamp.is_a?(TimeStamp)
|
272
240
|
raise ArgumentError, "time_stamp is of class #{time_stamp.class}, should be TimeStamp"
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Dbd
|
2
|
+
class Fact
|
3
|
+
module Factory
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
##
|
8
|
+
# @return [Class] the top class for which instances are created here.
|
9
|
+
def top_class
|
10
|
+
Fact
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# @return [String] A new subject string.
|
15
|
+
def new_subject
|
16
|
+
top_class::Subject.new_subject
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# @return [String] A new id string.
|
21
|
+
def new_id
|
22
|
+
top_class::ID.new_id
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Constructs a Fact or ProvenanceFact from a string values array
|
27
|
+
# (e.g. pulled from a CSV row).
|
28
|
+
#
|
29
|
+
# @param [Array] string_values Required : the array with values, organized as in attributes
|
30
|
+
# @return [Fact, ProvenanceFact] the constructed fact
|
31
|
+
def from_string_values(string_values, options={})
|
32
|
+
string_hash = string_hash_from_values(string_values)
|
33
|
+
validate_string_hash(string_hash) if options[:validate]
|
34
|
+
fact_from_values_hash(values_hash(string_hash))
|
35
|
+
end
|
36
|
+
|
37
|
+
def attribute_formats
|
38
|
+
# TODO clean this up
|
39
|
+
{
|
40
|
+
id: [true, Fact::ID.valid_regexp],
|
41
|
+
time_stamp: [true, TimeStamp.valid_regexp],
|
42
|
+
provenance_subject: [false, Fact::Subject.valid_regexp],
|
43
|
+
subject: [true, Fact::Subject.valid_regexp],
|
44
|
+
predicate: [true, /./],
|
45
|
+
object: [true, /./]
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def string_hash_from_values(string_values)
|
52
|
+
attributes_strings_array = [top_class.attributes, string_values].transpose
|
53
|
+
# Remove empty values (e.g. the provenance_subject for a ProvenanceFact).
|
54
|
+
attributes_strings_array.delete_if{|a,v| v.nil? || v == ''}
|
55
|
+
Hash[attributes_strings_array]
|
56
|
+
end
|
57
|
+
|
58
|
+
def values_hash(string_hash)
|
59
|
+
string_hash.tap do |h|
|
60
|
+
h[:time_stamp] = TimeStamp.new(time: h[:time_stamp])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def fact_from_values_hash(values_hash)
|
65
|
+
if values_hash[:provenance_subject]
|
66
|
+
Fact.new(values_hash)
|
67
|
+
else
|
68
|
+
ProvenanceFact.new(values_hash)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def validate_string_hash(string_hash)
|
73
|
+
attribute_formats.each do |attr, validation|
|
74
|
+
string = string_hash[attr]
|
75
|
+
mandatory, format = validation
|
76
|
+
validate_string(mandatory, string, format)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def validate_string(mandatory, string, format)
|
81
|
+
if (mandatory || string) && (string !~ format)
|
82
|
+
raise FactError, "invalid entry found : #{string}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/dbd/fact/id.rb
CHANGED