database.h revision 13cd4c8960688af11ad23b4c946149015c80d549
1/* Copyright (C) 2005 Red Hat, Inc. */
2
3#ifndef _SEMANAGE_DATABASE_H_
4#define _SEMANAGE_DATABASE_H_
5
6#ifndef DBASE_RECORD_DEFINED
7typedef void *record_t;
8typedef void *record_key_t;
9#define DBASE_RECORD_DEFINED
10#endif
11
12#ifndef DBASE_DEFINED
13typedef void *dbase_t;
14#define DBASE_DEFINED
15#endif
16
17/* Circular dependency */
18struct semanage_handle;
19
20/* RECORD interface - method table */
21typedef struct record_table {
22
23	/* Create a record */
24	int (*create) (struct semanage_handle * handle, record_t ** rec);
25
26	/* Extract key from record */
27	int (*key_extract) (struct semanage_handle * handle,
28			    const record_t * rec, record_key_t ** key);
29
30	/* Free record key */
31	void (*key_free) (record_key_t * key);
32
33	/* Return 0 if the record matches the key,
34	 * -1 if the key represents a record that should
35	 * be ordered before this record, and 1 if vice-versa */
36	int (*compare) (const record_t * rec, const record_key_t * key);
37
38	/* Return 0 if the record matches record2,
39	 * -1 if record2 should be ordered before this record,
40	 * and 1 if vice-versa */
41	int (*compare2) (const record_t * rec, const record_t * rec2);
42
43	/* Same as above, but dereferences the pointer first.
44	 * This function is intenteded to be used as a qsort
45	 * comparator. */
46	int (*compare2_qsort) (const record_t ** rec, const record_t ** rec2);
47
48	/* Deep-copy clone of this record */
49	int (*clone) (struct semanage_handle * handle,
50		      const record_t * rec, record_t ** new_rec);
51
52	/* Deallocate record resources. Must sucessfully handle NULL. */
53	void (*free) (record_t * rec);
54
55} record_table_t;
56
57/* DBASE interface - method table */
58typedef struct dbase_table {
59
60	/* --------------- Database Functionality ----------- */
61
62	/* Note: In all the functions below, the key is property
63	 * of the caller, and will not be modified by the database.
64	 * In add/set/modify, the data is also property of the caller */
65
66	/* Add the specified record to
67	 * the database. No check for duplicates is performed */
68	int (*add) (struct semanage_handle * handle,
69		    dbase_t * dbase,
70		    const record_key_t * key, const record_t * data);
71
72	/* Add the specified record to the
73	 * database if it not present.
74	 * If it's present, replace it
75	 */
76	int (*modify) (struct semanage_handle * handle,
77		       dbase_t * dbase,
78		       const record_key_t * key, const record_t * data);
79
80	/* Modify the specified record in the database
81	 * if it is present. Fail if it does not yet exist
82	 */
83	int (*set) (struct semanage_handle * handle,
84		    dbase_t * dbase,
85		    const record_key_t * key, const record_t * data);
86
87	/* Delete a record */
88	int (*del) (struct semanage_handle * handle,
89		    dbase_t * dbase, const record_key_t * key);
90
91	/* Clear all records, and leave the database in
92	 * cached, modified state. This function does
93	 * not require a call to cache() */
94	int (*clear) (struct semanage_handle * handle, dbase_t * dbase);
95
96	/* Retrieve a record
97	 *
98	 * Note: the resultant record
99	 * becomes property of the caller, and
100	 * must be freed accordingly */
101
102	int (*query) (struct semanage_handle * handle,
103		      dbase_t * dbase,
104		      const record_key_t * key, record_t ** response);
105
106	/* Check if a record exists */
107	int (*exists) (struct semanage_handle * handle,
108		       dbase_t * dbase,
109		       const record_key_t * key, int *response);
110
111	/* Count the number of records */
112	int (*count) (struct semanage_handle * handle,
113		      dbase_t * dbase, unsigned int *response);
114
115	/* Execute the specified handler over
116	 * the records of this database. The handler
117	 * can signal a successful exit by returning 1,
118	 * an error exit by returning -1, and continue by
119	 * returning 0
120	 *
121	 * Note: The record passed into the iterate handler
122	 * may or may not persist after the handler invocation,
123	 * and writing to it has unspecified behavior. It *must*
124	 * be cloned if modified, or preserved.
125	 *
126	 * Note: The iterate handler may not invoke any other
127	 * semanage read functions outside a transaction. It is only
128	 * reentrant while in transaction. The iterate handler may
129	 * not modify the underlying database.
130	 */
131	int (*iterate) (struct semanage_handle * handle,
132			dbase_t * dbase,
133			int (*fn) (const record_t * record,
134				   void *varg), void *fn_arg);
135
136	/* Construct a list of all records in this database
137	 *
138	 * Note: The list returned becomes property of the caller,
139	 * and must be freed accordingly.
140	 */
141	int (*list) (struct semanage_handle * handle,
142		     dbase_t * dbase,
143		     record_t *** records, unsigned int *count);
144
145	/* ---------- Cache/Transaction Management ---------- */
146
147	/* Cache the database (if supported).
148	 * This function must be invoked before using
149	 * any of the database functions above. It may be invoked
150	 * multiple times, and will update the cache if a commit
151	 * occured between invocations */
152	int (*cache) (struct semanage_handle * handle, dbase_t * dbase);
153
154	/* Forgets all changes that haven't been written
155	 * to the database backend */
156	void (*drop_cache) (dbase_t * dbase);
157
158	/* Checks if there are any changes not written to the backend */
159	int (*is_modified) (dbase_t * dbase);
160
161	/* Writes the database changes to its backend */
162	int (*flush) (struct semanage_handle * handle, dbase_t * dbase);
163
164	/* ------------- Polymorphism ----------------------- */
165
166	/* Retrieves the record table for this database,
167	 * which specifies how to perform basic operations
168	 * on each record. */
169	record_table_t *(*get_rtable) (dbase_t * dbase);
170
171} dbase_table_t;
172
173typedef struct dbase_config {
174
175	/* Database state */
176	dbase_t *dbase;
177
178	/* Database methods */
179	dbase_table_t *dtable;
180
181} dbase_config_t;
182
183extern int dbase_add(struct semanage_handle *handle,
184		     dbase_config_t * dconfig,
185		     const record_key_t * key, const record_t * data);
186
187extern int dbase_modify(struct semanage_handle *handle,
188			dbase_config_t * dconfig,
189			const record_key_t * key, const record_t * data);
190
191extern int dbase_set(struct semanage_handle *handle,
192		     dbase_config_t * dconfig,
193		     const record_key_t * key, const record_t * data);
194
195extern int dbase_del(struct semanage_handle *handle,
196		     dbase_config_t * dconfig, const record_key_t * key);
197
198extern int dbase_query(struct semanage_handle *handle,
199		       dbase_config_t * dconfig,
200		       const record_key_t * key, record_t ** response);
201
202extern int dbase_exists(struct semanage_handle *handle,
203			dbase_config_t * dconfig,
204			const record_key_t * key, int *response);
205
206extern int dbase_count(struct semanage_handle *handle,
207		       dbase_config_t * dconfig, unsigned int *response);
208
209extern int dbase_iterate(struct semanage_handle *handle,
210			 dbase_config_t * dconfig,
211			 int (*fn) (const record_t * record,
212				    void *fn_arg), void *fn_arg);
213
214extern int dbase_list(struct semanage_handle *handle,
215		      dbase_config_t * dconfig,
216		      record_t *** records, unsigned int *count);
217
218#endif
219