176176
177177function getBlob (store:: FolderStore{T} , blobId:: UUID ) where {T}
178178 blobfilename = joinpath (store. folder, string (store. label), string (blobId))
179- if isfile (blobfilename)
179+ tombstonefile = blobfilename * " .deleted"
180+ if isfile (tombstonefile)
181+ throw (IdNotFoundError (" Blob (deleted)" , blobId))
182+ elseif isfile (blobfilename)
180183 open (blobfilename) do f
181184 return read (f)
182185 end
@@ -198,24 +201,28 @@ function addBlob!(store::FolderStore{T}, blobId::UUID, data::T) where {T}
198201end
199202
200203function updateBlob! (store:: FolderStore{T} , blobId:: UUID , data:: T ) where {T}
201- blobfilename = joinpath (store. folder, string (store. label), string (blobId))
202- if ! isfile (blobfilename)
203- @warn " Key '$blobId ' doesn't exist."
204- else
205- open (blobfilename, " w" ) do f
206- return write (f, data)
207- end
208- return data
209- end
204+ error (" updateBlob! is obsolete as blobsId=>Blob pairs are immutable." )
210205end
211206
212207function deleteBlob! (store:: FolderStore{T} , blobId:: UUID ) where {T}
208+ # Tombstone pattern: instead of deleting the file, create a tombstone marker file
213209 blobfilename = joinpath (store. folder, string (store. label), string (blobId))
214- if ! isfile (blobfilename)
210+ tombstonefile = blobfilename * " .deleted"
211+ if isfile (blobfilename)
212+ # Remove the actual blob file
213+ rm (blobfilename)
214+ # Create a tombstone marker
215+ open (tombstonefile, " w" ) do f
216+ write (f, " deleted" )
217+ end
218+ return 1
219+ elseif isfile (tombstonefile)
220+ # Already deleted
221+ return 0
222+ else
223+ # Not found
215224 throw (IdNotFoundError (" Blob" , blobId))
216225 end
217- rm (blobfilename)
218- return 1
219226end
220227
221228function hasBlob (store:: FolderStore , blobId:: UUID )
225232
226233hasBlob (store:: FolderStore , entry:: Blobentry ) = hasBlob (store, entry. blobId)
227234
228- listBlobs (store:: FolderStore ) = readdir (store. folder)
235+ function listBlobs (store:: FolderStore )
236+ folder = joinpath (store. folder, string (store. label))
237+ # Parse folder to only include UUIDs automatically excluding tombstone files this way.
238+ blobIds = map (readdir (folder)) do filename
239+ tryparse (UUID, filename)
240+ end
241+ return filter (! isnothing, blobIds)
242+ end
243+
229244# #==============================================================================
230245# # InMemoryBlobstore
231246# #==============================================================================
0 commit comments