
persistency.pl -- Provide persistent dynamic predicates
This module provides simple persistent storage for one or more dynamic predicates. A database is always associated with a module. A module that wishes to maintain a database must declare the terms that can be placed in the database using the directive persistent/1.
The persistent/1 expands each declaration into four predicates:
- name(Arg,...)
- assert_name(Arg,...)
- retract_name(Arg,...)
- retractall_name(Arg,...)
As mentioned, a database can only be accessed from within a single module. This limitation is on purpose, forcing the user to provide a proper API for accessing the shared persistent data.
Below is a simple example:
:- module(user_db,
[ attach_user_db/1, % +File
current_user_role/2, % ?User, ?Role
add_user/2, % +User, +Role
set_user_role/2 % +User, +Role
]).
:- persistent
user_role(name:atom, role:oneof([user,administrator])).
attach_user_db(File) :-
db_attach(File, []).
%% current_user_role(+Name, -Role) is semidet.
current_user_role(Name, Role) :-
with_mutex(user_db, user_role(Name, Role)).
add_user(Name, Role) :-
assert_user_role(Name, Role).
set_user_role(Name, Role) :-
user_role(Name, Role), !.
set_user_role(Name, Role) :-
with_mutex(user_db,
( retractall_user_role(Name, _),
assert_user_role(Name, Role))).
- persistent(+Spec)
- Declare dynamic database terms. Declarations appear in a
directive and have the following format:
:- persistent <callable>, <callable>, ...Each specification is a callable term, following the conventions of library(record), where each argument is of the form
name:type
Types are defined by library(error).
- current_persistent_predicate(:PI) is nondet
- True if PI is a predicate that provides access to the persistent database DB.
- db_attach(:File, +Options)
- Use File as persistent database for the calling module. The
calling module must defined persistent/1 to declare the database
terms. Defined options:
- sync(+Sync)
- One of
close(close journal after write),flush(default, flush journal after write) ornone(handle as fully buffered stream).
- db_sync(:What)
- Synchronise database with the associated file. What is one of:
- reload
- Database is reloaded from file
- gc
- Database was re-written, deleting all retractall
statements. This is the same as
gc(50). - gc(Percentage)
- GC DB if the number of deleted terms is the given percentage of the total number of terms.
- close
- Database stream was closed
- nop
- No-operation performed
With unbound What, db_sync/1 reloads the database if it was modified on disk, gc it if it is dirty and close it if it is opened.
- db_sync_all(+What)
- Sync all registered databases.