Skip to content

Commit e370ec0

Browse files
committed
WIP - Datablob concepts for discussion
1 parent cdcc0dd commit e370ec0

File tree

8 files changed

+322
-56
lines changed

8 files changed

+322
-56
lines changed

src/DataBlobs/DataBlobs.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# using DataFrames
2+
# using CSV
3+
using JSON
4+
using SHA
5+
16
include("entities/AbstractDataStore.jl")
27
include("entities/AbstractDataEntries.jl")
38
include("entities/InMemoryDataStore.jl")
@@ -8,6 +13,8 @@ include("services/AbstractDataEntries.jl")
813
include("services/InMemoryDataStore.jl")
914
include("services/FileDataStore.jl")
1015

16+
include("services/FileDataEntryBlob.jl")
17+
1118
export AbstractDataStore
1219

1320
export AbstractDataEntry, GeneralDataEntry, MongodbDataEntry, FileDataEntry

src/DataBlobs/entities/AbstractDataEntries.jl

Lines changed: 83 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,95 @@ GeneralDataEntry is a generic multipurpose data entry that creates a unique
44
reproducible key using userId_robotId_sessionId_variableId_key.
55
"""
66
mutable struct GeneralDataEntry <: AbstractDataEntry
7-
key::Symbol
8-
storeKey::Symbol # Could swap this to string, but using it as an index later, so better as a symbol I believe.
7+
label::Symbol
8+
id::UUID # Could swap this to string, but using it as an index later, so better as a symbol I believe.
99
createdTimestamp::DateTime
1010
lastUpdatedTimestamp::DateTime
1111
mimeType::String
1212
end
1313

14+
#TODO Deprecation - Remove in v0.10
15+
Base.getproperty(x::GeneralDataEntry,f::Symbol) = begin
16+
if f == :key
17+
Base.depwarn("GeneralDataEntry field key is deprecated, use `label` instead", :getproperty)
18+
getfield(x,:label)
19+
elseif f == :storeKey
20+
Base.depwarn("GeneralDataEntry field storeKey is deprecated, use `id` instead", :getproperty)
21+
getfield(x,:id)
22+
else
23+
getfield(x,f)
24+
end
25+
end
26+
27+
#TODO Deprecation - Remove in v0.10
28+
Base.setproperty!(x::GeneralDataEntry, f::Symbol, val) = begin
29+
if f == :key
30+
Base.depwarn("GeneralDataEntry field `key` is deprecated, use `label` instead", :setproperty!)
31+
setfield(x, :label)
32+
elseif f == :storeKey
33+
Base.depwarn("GeneralDataEntry field `storeKey` is deprecated, use `id` instead", :setproperty!)
34+
setfield(x, :id)
35+
else
36+
setfield!(x,f,val)
37+
end
38+
end
39+
40+
1441
"""
1542
$(SIGNATURES)
16-
Internal function to generate a unique key for the entry - userId_robotId_sessionId_variable_key.
17-
Simple symbol.
43+
Function to generate source string - userId|robotId|sessionId|varLabel
1844
"""
19-
function _uniqueKey(dfg::G, v::V, key::Symbol)::Symbol where {G <: AbstractDFG, V <: AbstractDFGVariable}
20-
key = join(String.([dfg.userId, dfg.robotId, dfg.sessionId, getLabel(v), String(key)]), "_")
21-
return Symbol(key)
22-
end
45+
buildSourceString(dfg::AbstractDFG, label::Symbol) =
46+
"$(dfg.userId)|$(dfg.robotId)|$(dfg.sessionId)|$label"
47+
48+
49+
_uniqueKey(dfg::AbstractDFG, v::AbstractDFGVariable, key::Symbol)::Symbol =
50+
error("_uniqueKey is deprecated")
2351

2452

25-
GeneralDataEntry(key::Symbol, storeKey::Symbol;
53+
GeneralDataEntry(key::Symbol, storeKey::Symbol; mimeType::String="") = error("storeKey Deprecated, use UUID")
54+
55+
GeneralDataEntry(label::Symbol, id::UUID;
2656
mimeType::String="application/octet-stream") =
27-
GeneralDataEntry(key, storeKey, now(), now(), mimeType)
57+
GeneralDataEntry(label, uuid4(), now(UTC), now(UTC), mimeType)
58+
59+
function GeneralDataEntry(dfg::AbstractDFG, var::AbstractDFGVariable, key::Symbol;
60+
mimeType::String="application/octet-stream")
61+
return GeneralDataEntry(key, uuid4(), mimeType=mimeType)
62+
end
63+
2864

29-
function GeneralDataEntry(dfg::G, var::V, key::Symbol;
30-
mimeType::String="application/octet-stream") where {G <: AbstractDFG, V <: AbstractDFGVariable}
31-
return GeneralDataEntry(key, _uniqueKey(dfg, var, key), mimeType=mimeType)
65+
"""
66+
$(TYPEDEF)
67+
Genaral Data Store Entry.
68+
"""
69+
struct DataStoreEntry <: AbstractDataEntry
70+
label::Symbol
71+
id::UUID
72+
datastorekey::Symbol #TODO
73+
hash::String # Probably https://docs.julialang.org/en/v1/stdlib/SHA
74+
source::String # E.g. user|robot|session|varlabel
75+
description::String
76+
mimeType::String
77+
createdTimestamp::DateTime
78+
# lastUpdatedTimestamp::DateTime # don't think this makes sense?
3279
end
3380

3481
"""
3582
$(TYPEDEF)
3683
Data Entry in MongoDB.
3784
"""
3885
struct MongodbDataEntry <: AbstractDataEntry
39-
key::Symbol
86+
label::Symbol
87+
id::UUID
4088
oid::NTuple{12, UInt8} #mongodb object id
89+
hash::String
90+
91+
# mongodb
92+
# client::String
93+
# database::String
94+
# collection::String
95+
4196
#maybe other fields such as:
4297
#flags::Bool ready, valid, locked, permissions
4398
#MIMEType::String
@@ -49,6 +104,18 @@ end
49104
Data Entry in a file.
50105
"""
51106
struct FileDataEntry <: AbstractDataEntry
52-
key::Symbol
53-
filename::String
107+
label::Symbol
108+
id::UUID
109+
folder::String
110+
hash::String #using bytes2hex or perhaps Vector{Uint8}?
111+
timestamp::DateTime
112+
113+
function FileDataEntry(label, id, folder, hash, timestamp)
114+
if !isdir(folder)
115+
@warn "Folder '$folder' doesn't exist - creating."
116+
# create new folder
117+
mkpath(folder)
118+
end
119+
return new(label, id, folder, hash, timestamp)
120+
end
54121
end

src/DataBlobs/entities/FileDataStore.jl

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,26 @@
22
$(TYPEDEF)
33
Simple file data store with a specified data type and a specified key type.
44
"""
5-
struct FileDataStore <: AbstractDataStore{UInt8}
5+
struct FileDataStore{T} <: AbstractDataStore{T}
66
folder::String
7-
FileDataStore(folder::String) = begin
8-
if !isdir(folder)
9-
@warn "Folder '$folder' doesn't exist - creating."
10-
mkpath(folder)
11-
end
12-
return new(folder)
7+
end
8+
9+
function FileDataStore(folder::String)
10+
if !isdir(folder)
11+
@warn "Folder '$folder' doesn't exist - creating."
12+
# create new folder
13+
mkpath(folder)
1314
end
15+
16+
return FileDataStore{UInt8}(folder)
1417
end
18+
19+
# if !isfile(joinpath(folder,"datatable.csv"))
20+
# # create new datatable.csv
21+
# @info "Creating new datatable.csv file"
22+
# df = DataFrame(userId = String[], robotId = String[], sessionId = String[],
23+
# varLabel = Symbol[], dataLabel = Symbol[], dataId = UUID[])
24+
# CSV.write(joinpath(folder,"datatable.csv"), df)
25+
# else
26+
# @info "Existing datatable.csv found."
27+
# end

src/DataBlobs/services/AbstractDataEntries.jl

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,35 @@
1+
##
2+
3+
getHash(entry::AbstractDataEntry) = hex2bytes(entry.hash)
4+
5+
6+
##
7+
18
import Base: ==
29

310
function ==(a::GeneralDataEntry, b::GeneralDataEntry)
4-
return a.key == b.key &&
11+
return a.label == b.label &&
512
a.storeKey == b.storeKey &&
613
a.mimeType == b.mimeType &&
714
Dates.value(a.createdTimestamp - b.createdTimestamp) < 1000 &&
815
Dates.value(a.lastUpdatedTimestamp - b.lastUpdatedTimestamp) < 1000 #1 second
916
end
1017

1118
function ==(a::MongodbDataEntry, b::MongodbDataEntry)
12-
return a.key == b.key && a.oid == b.oid
19+
return a.label == b.label && a.oid == b.oid
1320
end
1421

1522
function ==(a::FileDataEntry, b::FileDataEntry)
16-
return a.key == b.key && a.filename == b.filename
23+
return a.label == b.label && a.filename == b.filename
1724
end
1825

1926
"""
2027
$(SIGNATURES)
2128
Add Big Data Entry to a DFG variable
2229
"""
2330
function addDataEntry!(var::AbstractDFGVariable, bde::AbstractDataEntry)
24-
haskey(var.dataDict, bde.key) && error("Data entry $(bde.key) already exists in variable")
25-
var.dataDict[bde.key] = bde
31+
haskey(var.dataDict, bde.label) && error("Data entry $(bde.label) already exists in variable")
32+
var.dataDict[bde.label] = bde
2633
return bde
2734
end
2835

@@ -79,7 +86,7 @@ hasDataEntry(var::DFGVariable, key::Symbol) = haskey(var.dataDict, key)
7986
Get big data entry
8087
"""
8188
function getDataEntry(var::AbstractDFGVariable, key::Symbol)
82-
!hasDataEntry(var, key) && (error("Data entry $(key) does not exist in variable"); return nothing)
89+
!hasDataEntry(var, key) && error("Data entry $(key) does not exist in variable")
8390
return var.dataDict[key]
8491
end
8592

@@ -152,8 +159,8 @@ DevNote
152159
- DF, unclear if `update` verb is applicable in this case, see #404
153160
"""
154161
function updateDataEntry!(var::AbstractDFGVariable, bde::AbstractDataEntry)
155-
!haskey(var.dataDict, bde.key) && (@warn "$(bde.key) does not exist in variable, adding")
156-
var.dataDict[bde.key] = bde
162+
!haskey(var.dataDict, bde.label) && (@warn "$(bde.label) does not exist in variable, adding")
163+
var.dataDict[bde.label] = bde
157164
return bde
158165
end
159166
function updateDataEntry!(dfg::AbstractDFG, label::Symbol, bde::AbstractDataEntry)
@@ -170,20 +177,17 @@ Notes:
170177
- users responsibility to delete big data in db before deleting entry
171178
"""
172179
function deleteDataEntry!(var::AbstractDFGVariable, key::Symbol)
173-
bde = getDataEntry(var, key)
174-
bde == nothing && return nothing
175-
delete!(var.dataDict, key)
176-
return var
180+
return pop!(var.dataDict, key)
177181
end
178182
function deleteDataEntry!(dfg::AbstractDFG, label::Symbol, key::Symbol)
179183
#users responsibility to delete big data in db before deleting entry
180-
!isVariable(dfg, label) && return nothing
184+
# !isVariable(dfg, label) && return nothing
181185
return deleteDataEntry!(getVariable(dfg, label), key)
182186
end
183187

184188
function deleteDataEntry!(var::AbstractDFGVariable, entry::AbstractDataEntry)
185189
#users responsibility to delete big data in db before deleting entry
186-
return deleteDataEntry!(var, entry.key)
190+
return deleteDataEntry!(var, entry.label)
187191
end
188192

189193
"""
@@ -195,7 +199,7 @@ function getDataEntries(var::AbstractDFGVariable)
195199
collect(values(var.dataDict))
196200
end
197201
function getDataEntries(dfg::AbstractDFG, label::Symbol)
198-
!isVariable(dfg, label) && return nothing
202+
# !isVariable(dfg, label) && return nothing
199203
#or should we return the iterator, Base.ValueIterator{Dict{Symbol,AbstractDataEntry}}?
200204
getDataEntries(getVariable(dfg, label))
201205
end
@@ -210,6 +214,6 @@ function listDataEntries(var::AbstractDFGVariable)
210214
end
211215

212216
function listDataEntries(dfg::AbstractDFG, label::Symbol)
213-
!isVariable(dfg, label) && return nothing
217+
# !isVariable(dfg, label) && return nothing
214218
listDataEntries(getVariable(dfg, label))
215219
end

0 commit comments

Comments
 (0)