/* Copyright (C) 2005 Red Hat, Inc. */
#ifndef _SEMANAGE_DATABASE_H_
#define _SEMANAGE_DATABASE_H_
#ifndef DBASE_RECORD_DEFINED
typedef void *record_t;
typedef void *record_key_t;
#define DBASE_RECORD_DEFINED
#endif
#ifndef DBASE_DEFINED
typedef void *dbase_t;
#define DBASE_DEFINED
#endif
/* Circular dependency */
struct semanage_handle;
/* RECORD interface - method table */
typedef struct record_table {
/* Create a record */
int (*create) (struct semanage_handle * handle, record_t ** rec);
/* Extract key from record */
int (*key_extract) (struct semanage_handle * handle,
const record_t * rec, record_key_t ** key);
/* Free record key */
void (*key_free) (record_key_t * key);
/* Return 0 if the record matches the key,
* -1 if the key represents a record that should
* be ordered before this record, and 1 if vice-versa */
int (*compare) (const record_t * rec, const record_key_t * key);
/* Return 0 if the record matches record2,
* -1 if record2 should be ordered before this record,
* and 1 if vice-versa */
int (*compare2) (const record_t * rec, const record_t * rec2);
/* Same as above, but dereferences the pointer first.
* This function is intenteded to be used as a qsort
* comparator. */
int (*compare2_qsort) (const record_t ** rec, const record_t ** rec2);
/* Deep-copy clone of this record */
int (*clone) (struct semanage_handle * handle,
const record_t * rec, record_t ** new_rec);
/* Deallocate record resources. Must sucessfully handle NULL. */
void (*free) (record_t * rec);
} record_table_t;
/* DBASE interface - method table */
typedef struct dbase_table {
/* --------------- Database Functionality ----------- */
/* Note: In all the functions below, the key is property
* of the caller, and will not be modified by the database.
* In add/set/modify, the data is also property of the caller */
/* Add the specified record to
* the database. No check for duplicates is performed */
int (*add) (struct semanage_handle * handle,
dbase_t * dbase,
const record_key_t * key, const record_t * data);
/* Add the specified record to the
* database if it not present.
* If it's present, replace it
*/
int (*modify) (struct semanage_handle * handle,
dbase_t * dbase,
const record_key_t * key, const record_t * data);
/* Modify the specified record in the database
* if it is present. Fail if it does not yet exist
*/
int (*set) (struct semanage_handle * handle,
dbase_t * dbase,
const record_key_t * key, const record_t * data);
/* Delete a record */
int (*del) (struct semanage_handle * handle,
dbase_t * dbase, const record_key_t * key);
/* Clear all records, and leave the database in
* cached, modified state. This function does
* not require a call to cache() */
int (*clear) (struct semanage_handle * handle, dbase_t * dbase);
/* Retrieve a record
*
* Note: the resultant record
* becomes property of the caller, and
* must be freed accordingly */
int (*query) (struct semanage_handle * handle,
dbase_t * dbase,
const record_key_t * key, record_t ** response);
/* Check if a record exists */
int (*exists) (struct semanage_handle * handle,
dbase_t * dbase,
const record_key_t * key, int *response);
/* Count the number of records */
int (*count) (struct semanage_handle * handle,
dbase_t * dbase, unsigned int *response);
/* Execute the specified handler over
* the records of this database. The handler
* can signal a successful exit by returning 1,
* an error exit by returning -1, and continue by
* returning 0
*
* Note: The record passed into the iterate handler
* may or may not persist after the handler invocation,
* and writing to it has unspecified behavior. It *must*
* be cloned if modified, or preserved.
*
* Note: The iterate handler may not invoke any other
* semanage read functions outside a transaction. It is only
* reentrant while in transaction. The iterate handler may
* not modify the underlying database.
*/
int (*iterate) (struct semanage_handle * handle,
dbase_t * dbase,
int (*fn) (const record_t * record,
void *varg), void *fn_arg);
/* Construct a list of all records in this database
*
* Note: The list returned becomes property of the caller,
* and must be freed accordingly.
*/
int (*list) (struct semanage_handle * handle,
dbase_t * dbase,
record_t *** records, unsigned int *count);
/* ---------- Cache/Transaction Management ---------- */
/* Cache the database (if supported).
* This function must be invoked before using
* any of the database functions above. It may be invoked
* multiple times, and will update the cache if a commit
* occured between invocations */
int (*cache) (struct semanage_handle * handle, dbase_t * dbase);
/* Forgets all changes that haven't been written
* to the database backend */
void (*drop_cache) (dbase_t * dbase);
/* Checks if there are any changes not written to the backend */
int (*is_modified) (dbase_t * dbase);
/* Writes the database changes to its backend */
int (*flush) (struct semanage_handle * handle, dbase_t * dbase);
/* ------------- Polymorphism ----------------------- */
/* Retrieves the record table for this database,
* which specifies how to perform basic operations
* on each record. */
record_table_t *(*get_rtable) (dbase_t * dbase);
} dbase_table_t;
typedef struct dbase_config {
/* Database state */
dbase_t *dbase;
/* Database methods */
dbase_table_t *dtable;
} dbase_config_t;
extern int dbase_add(struct semanage_handle *handle,
dbase_config_t * dconfig,
const record_key_t * key, const record_t * data);
extern int dbase_modify(struct semanage_handle *handle,
dbase_config_t * dconfig,
const record_key_t * key, const record_t * data);
extern int dbase_set(struct semanage_handle *handle,
dbase_config_t * dconfig,
const record_key_t * key, const record_t * data);
extern int dbase_del(struct semanage_handle *handle,
dbase_config_t * dconfig, const record_key_t * key);
extern int dbase_query(struct semanage_handle *handle,
dbase_config_t * dconfig,
const record_key_t * key, record_t ** response);
extern int dbase_exists(struct semanage_handle *handle,
dbase_config_t * dconfig,
const record_key_t * key, int *response);
extern int dbase_count(struct semanage_handle *handle,
dbase_config_t * dconfig, unsigned int *response);
extern int dbase_iterate(struct semanage_handle *handle,
dbase_config_t * dconfig,
int (*fn) (const record_t * record,
void *fn_arg), void *fn_arg);
extern int dbase_list(struct semanage_handle *handle,
dbase_config_t * dconfig,
record_t *** records, unsigned int *count);
#endif