[not loaded]All predicatesShow sourcerdf_history.pl -- RDF Persistent store change history

This module deals with accessing the journal files of the RDF persistency layer to get insight in the provenance and history of the RDF database. It is designed for Wiki-like collaborative editing of an RDF graph. We make the following assumptions:

Users are identified using a URI, typically an OpenID (http://openid.net/) Triples created by a user are added to a named graph identified by the URI of the user. Changes are grouped using rdf_transaction(Goal, log(Message, User)) The number that is associated with the named graph of a triple (normally expressing the line number in the source) is used to store the time-stamp. Although this information is redundant (the time stamp is the same as for the transaction), it allows for binary search through the history file for the enclosing transaction.

- Jan Wielemaker
To be done
- Cleanup thoughts on delete and update.
Source rdfh_transaction(:Goal) is semidet
Run Goal using rdf_transaction/2, using information from the HTTP layer to provide OpenID and session-id.
Source rdfh_assert(+S, +P, +O) is det
Assert a triple, adding current user and time to the triple context.
Source rdfh_retractall(+S, +P, +O) is det
Retract triples that match {S,P,O}. Note that all matching triples are added to the journal, so we can undo the action as well as report on retracted triples, even if multiple are retracted at the same time.

One of the problems we are faced with is that a retract action goes into the journal of the user whose triple is retracted, which may or may not be the one who performed the action.

Source rdfh_update(+S, +P, +O) is det
More tricky stuff, replacing a triple by another. Typically this will be changing the predicate or object. Provenance info should move the new triple to the user making the change, surely if the object is changed. If the predicate is changed to a related predicate, this actually becomes less obvious.

Current simple-minded approach is to turn an update into a retract and assert. The S,P,O specifications are either a ground value or of the form Old -> New. Here is an example:

rdfh_update(Work, Style, wn:oldstyle -> wn:newstyle)
Source transaction_context(-Term) is det[private]
Context to pass with an RDF transaction. Note that we pass the user. We don't need this for simple additions, but we do need it to track deletions.
Source rdfh_session(-Session) is semidet[private]
Session is a (ground) identifier for the current session.
Source rdfh_user(-URI) is det[private]
Get user-id of current session.
To be done
- Make hookable, so we can use the SeRQL user/openid hooks
Source rdfh_time(-Time:integer) is det[private]
Get time stamp as integer. Second resolution is enough, and avoids rounding problems associated with floats.
Source rdfh_triple_transaction(+Triple:rdf(S,P,O), -Transaction) is nondet
True if the (partial) Triple is modified in Transaction.
Source rdfh_db_transaction(?DB, +Condition, ?Transaction) is nondet
True if Transaction satisfying Condition was executed on DB. Condition is one of:
Always true, returns all transactions.
Specifies the identifier of the transaction. Only makes sense if DB is specified as transaction identifiers are local to each DB.
True if transaction is executed at or after Time.
To be done
- More conditions (e.g. before(Time)).
Source open_journal(+File, -Stream) is det[private]
Open a journal file. Journal files are always UTF-8 encoded.
Source journal_transaction(+JournalFile, ?Transaction) is nondet[private]
True if Transaction is a transaction in JournalFile,
Source seek_journal(+Fd:stream, +Spec) is semidet[private]
See an open journal descriptor to the start of a transaction specified by Spec. Spec is one of:
First transaction at or after Time. Fails if there are no transactions after time.
Start of transaction labeled with given Id. Fails if there is no transaction labeled Id.

The implementation relies on the incrementing identifier numbers and time-stamps.

Source bsearch_journal(+Fd, +Start, +Here, +End, +Spec, !Last) is semidet[private]
Perform a binary search in the journal opened as Fd.
Source start_of_transaction(+Fd, +From, -Start, -Term) is semidet[private]
Term is the start term of the first transaction after byte position From. Fails if no transaction can be found after From.
Source rdfh_transaction_member(Action, Transaction) is nondet
True if Action is an action in Transaction.