Mercurial > hg > xemacs-beta
comparison src/database.c @ 185:3d6bfa290dbd r20-3b19
Import from CVS: tag r20-3b19
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:55:28 +0200 |
parents | 6075d714658b |
children | b405438285a2 |
comparison
equal
deleted
inserted
replaced
184:bcd2674570bf | 185:3d6bfa290dbd |
---|---|
19 Boston, MA 02111-1307, USA. */ | 19 Boston, MA 02111-1307, USA. */ |
20 | 20 |
21 /* Synched up with: Not in FSF. */ | 21 /* Synched up with: Not in FSF. */ |
22 | 22 |
23 /* Written by Bill Perry */ | 23 /* Written by Bill Perry */ |
24 /* Hacked on by Martin Buchholz */ | 24 /* Substantially rewritten by Martin Buchholz */ |
25 | 25 |
26 #include <config.h> | 26 #include <config.h> |
27 #include "lisp.h" | 27 #include "lisp.h" |
28 #include <errno.h> | 28 #include <errno.h> |
29 | 29 |
61 | 61 |
62 Lisp_Object Qdatabasep; | 62 Lisp_Object Qdatabasep; |
63 | 63 |
64 typedef enum { DB_DBM, DB_BERKELEY, DB_UNKNOWN } XEMACS_DB_TYPE; | 64 typedef enum { DB_DBM, DB_BERKELEY, DB_UNKNOWN } XEMACS_DB_TYPE; |
65 | 65 |
66 struct database_struct; | 66 struct database; |
67 typedef struct database_struct database_struct; | 67 typedef struct database database; |
68 | 68 |
69 typedef struct | 69 typedef struct |
70 { | 70 { |
71 CONST char * (*get_subtype) (struct database_struct *); | 71 CONST char * (*get_subtype) (struct database *); |
72 CONST char * (*get_type) (struct database_struct *); | 72 CONST char * (*get_type) (struct database *); |
73 void * (*open_file) (CONST char *, Lisp_Object, int, int); | 73 Lisp_Object (*get) (struct database *, Lisp_Object); |
74 Lisp_Object (*get) (struct database_struct *, Lisp_Object); | 74 int (*put) (struct database *, Lisp_Object, Lisp_Object, Lisp_Object); |
75 int (*put) (struct database_struct *, Lisp_Object, Lisp_Object, Lisp_Object); | 75 int (*rem) (struct database *, Lisp_Object); |
76 int (*rem) (struct database_struct *, Lisp_Object); | 76 void (*map) (struct database *, Lisp_Object); |
77 void (*map) (struct database_struct *, Lisp_Object); | 77 Lisp_Object (*get_lisp_type) (struct database *); |
78 Lisp_Object (*get_lisp_type) (struct database_struct *); | 78 void (*close) (struct database *); |
79 void (*close) (struct database_struct *); | 79 Lisp_Object (*last_error) (struct database *); |
80 Lisp_Object (*last_error) (struct database_struct *); | |
81 } DB_FUNCS; | 80 } DB_FUNCS; |
82 | 81 |
83 struct database_struct | 82 struct database |
84 { | 83 { |
85 struct lcrecord_header header; | 84 struct lcrecord_header header; |
86 Lisp_Object fname; | 85 Lisp_Object fname; |
87 XEMACS_DB_TYPE type; | 86 XEMACS_DB_TYPE type; |
88 int mode; | 87 int mode; |
89 int access_; | 88 int access_; |
90 int dberrno; | 89 int dberrno; |
91 void *db_handle; | 90 int live_p; |
91 #ifdef HAVE_DBM | |
92 DBM *dbm_handle; | |
93 #endif | |
94 #ifdef HAVE_BERKELEY_DB | |
95 DB *db_handle; | |
96 #endif | |
92 DB_FUNCS *funcs; | 97 DB_FUNCS *funcs; |
93 #ifdef MULE | 98 #ifdef MULE |
94 Lisp_Object coding_system; | 99 Lisp_Object coding_system; |
95 #endif | 100 #endif |
96 }; | 101 }; |
97 | 102 |
98 #define XDATABASE(x) XRECORD (x, database, struct database_struct) | 103 #define XDATABASE(x) XRECORD (x, database, struct database) |
99 #define XSETDATABASE(x, p) XSETRECORD (x, p, database) | 104 #define XSETDATABASE(x, p) XSETRECORD (x, p, database) |
100 #define DATABASEP(x) RECORDP (x, database) | 105 #define DATABASEP(x) RECORDP (x, database) |
101 #define GC_DATABASEP(x) GC_RECORDP (x, database) | 106 #define GC_DATABASEP(x) GC_RECORDP (x, database) |
102 #define CHECK_DATABASE(x) CHECK_RECORD (x, database) | 107 #define CHECK_DATABASE(x) CHECK_RECORD (x, database) |
103 #define DATABASE_LIVE_P(x) (x->db_handle) | 108 #define DATABASE_LIVE_P(x) (x->live_p) |
104 static Lisp_Object mark_database (Lisp_Object, void (*) (Lisp_Object)); | 109 static Lisp_Object mark_database (Lisp_Object, void (*) (Lisp_Object)); |
105 static void print_database (Lisp_Object, Lisp_Object, int); | 110 static void print_database (Lisp_Object, Lisp_Object, int); |
106 static void finalize_database (void *, int); | 111 static void finalize_database (void *, int); |
107 DEFINE_LRECORD_IMPLEMENTATION ("database", database, | 112 DEFINE_LRECORD_IMPLEMENTATION ("database", database, |
108 mark_database, print_database, | 113 mark_database, print_database, |
109 finalize_database, 0, 0, | 114 finalize_database, 0, 0, |
110 struct database_struct); | 115 struct database); |
111 | 116 |
112 static struct database_struct * | 117 #define CHECK_LIVE_DATABASE(db) do { \ |
118 CHECK_DATABASE(db); \ | |
119 if (!DATABASE_LIVE_P (XDATABASE(db))) \ | |
120 signal_simple_error ("Attempting to access closed database", db); \ | |
121 } while (0) | |
122 | |
123 | |
124 static struct database * | |
113 new_database (void) | 125 new_database (void) |
114 { | 126 { |
115 struct database_struct *dbase | 127 struct database *dbase = |
116 = alloc_lcrecord (sizeof (struct database_struct), lrecord_database); | 128 alloc_lcrecord_type (struct database, lrecord_database); |
117 | 129 |
118 dbase->fname = Qnil; | 130 dbase->fname = Qnil; |
131 dbase->live_p = 0; | |
132 #ifdef HAVE_BERKELEY_DB | |
119 dbase->db_handle = NULL; | 133 dbase->db_handle = NULL; |
134 #endif | |
135 #ifdef HAVE_DBM | |
136 dbase->dbm_handle = NULL; | |
137 #endif | |
120 dbase->access_ = 0; | 138 dbase->access_ = 0; |
121 dbase->mode = 0; | 139 dbase->mode = 0; |
122 dbase->dberrno = 0; | 140 dbase->dberrno = 0; |
123 dbase->type = DB_UNKNOWN; | 141 dbase->type = DB_UNKNOWN; |
124 #ifdef MULE | 142 #ifdef MULE |
128 } | 146 } |
129 | 147 |
130 static Lisp_Object | 148 static Lisp_Object |
131 mark_database (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 149 mark_database (Lisp_Object obj, void (*markobj) (Lisp_Object)) |
132 { | 150 { |
133 struct database_struct *dbase = XDATABASE (obj); | 151 struct database *dbase = XDATABASE (obj); |
134 | 152 |
135 ((markobj) (dbase->fname)); | 153 ((markobj) (dbase->fname)); |
136 return Qnil; | 154 return Qnil; |
137 } | 155 } |
138 | 156 |
139 static void | 157 static void |
140 print_database (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | 158 print_database (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) |
141 { | 159 { |
142 struct database_struct *dbase = XDATABASE (obj); | 160 struct database *dbase = XDATABASE (obj); |
143 char buf[200]; | 161 char buf[200]; |
144 | 162 |
145 if (print_readably) | 163 if (print_readably) |
146 { | 164 { |
147 error ("printing unreadable object #<database 0x%x>", dbase->header.uid); | 165 error ("printing unreadable object #<database 0x%x>", dbase->header.uid); |
148 } | 166 } |
149 else | 167 else |
150 { | 168 { |
151 CONST char *type; | 169 sprintf (buf, "#<database \"%s\" (%s/%s/%s) 0x%x>", |
152 CONST char *subtype; | 170 XSTRING_DATA (dbase->fname), |
153 CONST char *perms; | 171 dbase->funcs->get_type (dbase), |
154 | 172 dbase->funcs->get_subtype (dbase), |
155 perms = (!dbase->db_handle) ? "closed" : | 173 (!DATABASE_LIVE_P (dbase) ? "closed" : |
156 (dbase->access_ & O_WRONLY) ? "writeonly" : | 174 (dbase->access_ & O_WRONLY) ? "writeonly" : |
157 (dbase->access_ & O_RDWR) ? "readwrite" : "readonly"; | 175 (dbase->access_ & O_RDWR) ? "readwrite" : "readonly"), |
158 | |
159 type = dbase->funcs->get_type (dbase); | |
160 subtype = dbase->funcs->get_subtype (dbase); | |
161 | |
162 sprintf (buf, "#<database %s (%s/%s/%s) 0x%x>", | |
163 XSTRING_DATA (dbase->fname), type, subtype, perms, | |
164 dbase->header.uid); | 176 dbase->header.uid); |
165 write_c_string (buf, printcharfun); | 177 write_c_string (buf, printcharfun); |
166 } | 178 } |
167 } | 179 } |
168 | 180 |
169 static void | 181 static void |
170 finalize_database (void *header, int for_disksave) | 182 finalize_database (void *header, int for_disksave) |
171 { | 183 { |
172 struct database_struct *db = (struct database_struct *) header; | 184 struct database *db = (struct database *) header; |
173 | 185 |
174 if (for_disksave) | 186 if (for_disksave) |
175 { | 187 { |
176 Lisp_Object obj; | 188 Lisp_Object obj; |
177 XSETOBJ (obj, Lisp_Record, (void *) db); | 189 XSETOBJ (obj, Lisp_Type_Record, (void *) db); |
178 | 190 |
179 signal_simple_error | 191 signal_simple_error |
180 ("Can't dump an emacs containing window system objects", obj); | 192 ("Can't dump an emacs containing window system objects", obj); |
181 } | 193 } |
182 db->funcs->close (db); | 194 db->funcs->close (db); |
183 } | 195 } |
185 DEFUN ("close-database", Fdatabase_close, 1, 1, 0, /* | 197 DEFUN ("close-database", Fdatabase_close, 1, 1, 0, /* |
186 Close database OBJ. | 198 Close database OBJ. |
187 */ | 199 */ |
188 (obj)) | 200 (obj)) |
189 { | 201 { |
190 struct database_struct *db; | 202 CHECK_LIVE_DATABASE (obj); |
191 CHECK_DATABASE (obj); | 203 XDATABASE (obj)->funcs->close (XDATABASE (obj)); |
192 db = XDATABASE (obj); | 204 XDATABASE (obj)->live_p = 0; |
193 | |
194 if (DATABASE_LIVE_P (db)) | |
195 db->funcs->close (db); | |
196 else | |
197 signal_simple_error ("Attempting to access closed database", obj); | |
198 | |
199 return Qnil; | 205 return Qnil; |
200 } | 206 } |
201 | 207 |
202 DEFUN ("database-type", Fdatabase_type, 1, 1, 0, /* | 208 DEFUN ("database-type", Fdatabase_type, 1, 1, 0, /* |
203 Return the type of database OBJ. | 209 Return the type of database OBJ. |
204 */ | 210 */ |
205 (obj)) | 211 (obj)) |
206 { | 212 { |
207 struct database_struct *db; | |
208 CHECK_DATABASE (obj); | 213 CHECK_DATABASE (obj); |
209 db = XDATABASE (obj); | 214 |
210 | 215 return XDATABASE (obj)->funcs->get_lisp_type (XDATABASE (obj)); |
211 return db->funcs->get_lisp_type (db); | |
212 } | 216 } |
213 | 217 |
214 DEFUN ("database-subtype", Fdatabase_subtype, 1, 1, 0, /* | 218 DEFUN ("database-subtype", Fdatabase_subtype, 1, 1, 0, /* |
215 Return the subtype of database OBJ, if any. | 219 Return the subtype of database OBJ, if any. |
216 */ | 220 */ |
217 (obj)) | 221 (obj)) |
218 { | 222 { |
219 struct database_struct *db; | |
220 | |
221 CHECK_DATABASE (obj); | 223 CHECK_DATABASE (obj); |
222 db = XDATABASE (obj); | 224 |
223 | 225 return intern (XDATABASE (obj)->funcs->get_subtype (XDATABASE (obj))); |
224 return intern (db->funcs->get_subtype (db)); | |
225 } | 226 } |
226 | 227 |
227 DEFUN ("database-live-p", Fdatabase_live_p, 1, 1, 0, /* | 228 DEFUN ("database-live-p", Fdatabase_live_p, 1, 1, 0, /* |
228 Return t iff OBJ is an active database, else nil. | 229 Return t iff OBJ is an active database, else nil. |
229 */ | 230 */ |
230 (obj)) | 231 (obj)) |
231 { | 232 { |
232 struct database_struct *db; | |
233 CHECK_DATABASE (obj); | 233 CHECK_DATABASE (obj); |
234 db = XDATABASE (obj); | 234 |
235 | 235 return DATABASE_LIVE_P (XDATABASE (obj)) ? Qt : Qnil; |
236 return DATABASE_LIVE_P (db) ? Qt : Qnil; | |
237 } | 236 } |
238 | 237 |
239 DEFUN ("database-file-name", Fdatabase_file_name, 1, 1, 0, /* | 238 DEFUN ("database-file-name", Fdatabase_file_name, 1, 1, 0, /* |
240 Return the filename associated with the database OBJ. | 239 Return the filename associated with the database OBJ. |
241 */ | 240 */ |
242 (obj)) | 241 (obj)) |
243 { | 242 { |
244 struct database_struct *db; | |
245 CHECK_DATABASE (obj); | 243 CHECK_DATABASE (obj); |
246 db = XDATABASE (obj); | 244 |
247 return db->fname; | 245 return XDATABASE (obj)->fname; |
248 } | 246 } |
249 | 247 |
250 DEFUN ("databasep", Fdatabasep, 1, 1, 0, /* | 248 DEFUN ("databasep", Fdatabasep, 1, 1, 0, /* |
251 Return t iff OBJ is a database, else nil. | 249 Return t iff OBJ is a database, else nil. |
252 */ | 250 */ |
255 return DATABASEP (obj) ? Qt : Qnil; | 253 return DATABASEP (obj) ? Qt : Qnil; |
256 } | 254 } |
257 | 255 |
258 #ifdef HAVE_DBM | 256 #ifdef HAVE_DBM |
259 static void | 257 static void |
260 dbm_map (struct database_struct *db, Lisp_Object func) | 258 dbm_map (struct database *db, Lisp_Object func) |
261 { | 259 { |
262 datum keydatum, valdatum; | 260 datum keydatum, valdatum; |
263 DBM *handle = (DBM *)db->db_handle; | |
264 Lisp_Object key, val; | 261 Lisp_Object key, val; |
265 | 262 |
266 for (keydatum = dbm_firstkey (handle); | 263 for (keydatum = dbm_firstkey (db->dbm_handle); |
267 keydatum.dptr != NULL; | 264 keydatum.dptr != NULL; |
268 keydatum = dbm_nextkey (handle)) | 265 keydatum = dbm_nextkey (db->dbm_handle)) |
269 { | 266 { |
270 valdatum = dbm_fetch (handle, keydatum); | 267 valdatum = dbm_fetch (db->dbm_handle, keydatum); |
271 key = make_string ((unsigned char *) keydatum.dptr, keydatum.dsize); | 268 key = make_string ((unsigned char *) keydatum.dptr, keydatum.dsize); |
272 val = make_string ((unsigned char *) valdatum.dptr, valdatum.dsize); | 269 val = make_string ((unsigned char *) valdatum.dptr, valdatum.dsize); |
273 call2 (func, key, val); | 270 call2 (func, key, val); |
274 } | 271 } |
275 } | 272 } |
276 | 273 |
277 static Lisp_Object | 274 static Lisp_Object |
278 dbm_get (struct database_struct *db, Lisp_Object key) | 275 dbm_get (struct database *db, Lisp_Object key) |
279 { | 276 { |
280 datum keydatum, valdatum; | 277 datum keydatum, valdatum; |
281 DBM *handle = (DBM *)db->db_handle; | 278 |
282 keydatum.dptr = (char *) XSTRING_DATA (key); | 279 keydatum.dptr = (char *) XSTRING_DATA (key); |
283 keydatum.dsize = XSTRING_LENGTH (key); | 280 keydatum.dsize = XSTRING_LENGTH (key); |
284 valdatum = dbm_fetch (handle, keydatum); | 281 valdatum = dbm_fetch (db->dbm_handle, keydatum); |
285 | 282 |
286 return (valdatum.dptr | 283 return (valdatum.dptr |
287 ? make_string ((unsigned char *) valdatum.dptr, valdatum.dsize) | 284 ? make_string ((unsigned char *) valdatum.dptr, valdatum.dsize) |
288 : Qnil); | 285 : Qnil); |
289 } | 286 } |
290 | 287 |
291 static int | 288 static int |
292 dbm_put (struct database_struct *db, | 289 dbm_put (struct database *db, |
293 Lisp_Object key, | 290 Lisp_Object key, Lisp_Object val, Lisp_Object replace) |
294 Lisp_Object val, | 291 { |
295 Lisp_Object replace) | |
296 { | |
297 DBM *handle = (DBM *)db->db_handle; | |
298 datum keydatum, valdatum; | 292 datum keydatum, valdatum; |
299 | 293 |
300 valdatum.dptr = (char *) XSTRING_DATA (val); | 294 valdatum.dptr = (char *) XSTRING_DATA (val); |
301 valdatum.dsize = XSTRING_LENGTH (val); | 295 valdatum.dsize = XSTRING_LENGTH (val); |
302 keydatum.dptr = (char *) XSTRING_DATA (key); | 296 keydatum.dptr = (char *) XSTRING_DATA (key); |
303 keydatum.dsize = XSTRING_LENGTH (key); | 297 keydatum.dsize = XSTRING_LENGTH (key); |
304 | 298 |
305 return (!dbm_store (handle, keydatum, valdatum, | 299 return !dbm_store (db->dbm_handle, keydatum, valdatum, |
306 (NILP (replace)) ? DBM_INSERT : DBM_REPLACE)); | 300 NILP (replace) ? DBM_INSERT : DBM_REPLACE); |
307 } | 301 } |
308 | 302 |
309 static int | 303 static int |
310 dbm_remove (struct database_struct *db, Lisp_Object key) | 304 dbm_remove (struct database *db, Lisp_Object key) |
311 { | 305 { |
312 datum keydatum; | 306 datum keydatum; |
307 | |
313 keydatum.dptr = (char *) XSTRING_DATA (key); | 308 keydatum.dptr = (char *) XSTRING_DATA (key); |
314 keydatum.dsize = XSTRING_LENGTH (key); | 309 keydatum.dsize = XSTRING_LENGTH (key); |
315 return dbm_delete (db->db_handle, keydatum); | 310 |
311 return dbm_delete (db->dbm_handle, keydatum); | |
316 } | 312 } |
317 | 313 |
318 static Lisp_Object | 314 static Lisp_Object |
319 dbm_lisp_type (struct database_struct *db) | 315 dbm_lisp_type (struct database *db) |
320 { | 316 { |
321 return Qdbm; | 317 return Qdbm; |
322 } | 318 } |
323 | 319 |
324 static CONST char * | 320 static CONST char * |
325 dbm_type (struct database_struct *db) | 321 dbm_type (struct database *db) |
326 { | 322 { |
327 return "dbm"; | 323 return "dbm"; |
328 } | 324 } |
329 | 325 |
330 static CONST char * | 326 static CONST char * |
331 dbm_subtype (struct database_struct *db) | 327 dbm_subtype (struct database *db) |
332 { | 328 { |
333 return "nil"; | 329 return "nil"; |
334 } | 330 } |
335 | 331 |
336 static void * | |
337 new_dbm_file (CONST char *file, Lisp_Object subtype, int access_, int mode) | |
338 { | |
339 DBM *db = NULL; | |
340 db = dbm_open ((char *) file, access_, mode); | |
341 return (void *) db; | |
342 } | |
343 | |
344 static Lisp_Object | 332 static Lisp_Object |
345 dbm_lasterr (struct database_struct *dbp) | 333 dbm_lasterr (struct database *dbp) |
346 { | 334 { |
347 return lisp_strerror (dbp->dberrno); | 335 return lisp_strerror (dbp->dberrno); |
348 } | 336 } |
349 | 337 |
350 static void | 338 static void |
351 dbm_closeit (struct database_struct *db) | 339 dbm_closeit (struct database *db) |
352 { | 340 { |
353 if (db->db_handle) | 341 if (db->dbm_handle) |
354 dbm_close ((DBM *)db->db_handle); | 342 { |
355 db->db_handle = NULL; | 343 dbm_close (db->dbm_handle); |
344 db->dbm_handle = NULL; | |
345 } | |
356 } | 346 } |
357 | 347 |
358 static DB_FUNCS ndbm_func_block = | 348 static DB_FUNCS ndbm_func_block = |
359 { | 349 { |
360 dbm_subtype, | 350 dbm_subtype, |
361 dbm_type, | 351 dbm_type, |
362 new_dbm_file, | |
363 dbm_get, | 352 dbm_get, |
364 dbm_put, | 353 dbm_put, |
365 dbm_remove, | 354 dbm_remove, |
366 dbm_map, | 355 dbm_map, |
367 dbm_lisp_type, | 356 dbm_lisp_type, |
368 dbm_closeit, | 357 dbm_closeit, |
369 dbm_lasterr | 358 dbm_lasterr |
370 }; | 359 }; |
371 #endif | 360 #endif /* HAVE_DBM */ |
372 | 361 |
373 #ifdef HAVE_BERKELEY_DB | 362 #ifdef HAVE_BERKELEY_DB |
374 static Lisp_Object | 363 static Lisp_Object |
375 berkdb_lisp_type (struct database_struct *db) | 364 berkdb_lisp_type (struct database *db) |
376 { | 365 { |
377 return Qberkeley_db; | 366 return Qberkeley_db; |
378 } | 367 } |
379 | 368 |
380 static CONST char * | 369 static CONST char * |
381 berkdb_type (struct database_struct *db) | 370 berkdb_type (struct database *db) |
382 { | 371 { |
383 return "berkeley"; | 372 return "berkeley"; |
384 } | 373 } |
385 | 374 |
386 static CONST char * | 375 static CONST char * |
387 berkdb_subtype (struct database_struct *db) | 376 berkdb_subtype (struct database *db) |
388 { | 377 { |
389 DB *temp = (DB *)db->db_handle; | 378 if (!db->db_handle) |
390 | |
391 if (!temp) | |
392 return "nil"; | 379 return "nil"; |
393 | 380 |
394 switch (temp->type) | 381 switch (db->db_handle->type) |
395 { | 382 { |
396 case DB_BTREE: | 383 case DB_BTREE: return "btree"; |
397 return "btree"; | 384 case DB_HASH: return "hash"; |
398 case DB_HASH: | 385 case DB_RECNO: return "recno"; |
399 return "hash"; | 386 default: return "unknown"; |
400 case DB_RECNO: | 387 } |
401 return "recno"; | |
402 } | |
403 return "unknown"; | |
404 } | |
405 | |
406 static void * | |
407 berkdb_open (CONST char *file, Lisp_Object subtype, int access_, int mode) | |
408 { | |
409 DB *db; | |
410 DBTYPE real_subtype; | |
411 | |
412 if (EQ (subtype, Qhash) || NILP (subtype)) | |
413 real_subtype = DB_HASH; | |
414 else if (EQ (subtype, Qbtree)) | |
415 real_subtype = DB_BTREE; | |
416 else if (EQ (subtype, Qrecno)) | |
417 real_subtype = DB_RECNO; | |
418 else | |
419 signal_simple_error ("Unsupported subtype", subtype); | |
420 | |
421 db = dbopen (file, access_, mode, real_subtype, NULL); | |
422 | |
423 return (void *) db; | |
424 } | 388 } |
425 | 389 |
426 static Lisp_Object | 390 static Lisp_Object |
427 berkdb_lasterr (struct database_struct *dbp) | 391 berkdb_lasterr (struct database *dbp) |
428 { | 392 { |
429 return lisp_strerror (dbp->dberrno); | 393 return lisp_strerror (dbp->dberrno); |
430 } | 394 } |
431 | 395 |
432 static Lisp_Object | 396 static Lisp_Object |
433 berkdb_get (struct database_struct *db, Lisp_Object key) | 397 berkdb_get (struct database *db, Lisp_Object key) |
434 { | 398 { |
399 /* #### Needs mule-izing */ | |
435 DBT keydatum, valdatum; | 400 DBT keydatum, valdatum; |
436 DB *dbp = (DB *) db->db_handle; | |
437 int status = 0; | 401 int status = 0; |
438 | 402 |
439 keydatum.data = XSTRING_DATA (key); | 403 keydatum.data = XSTRING_DATA (key); |
440 keydatum.size = XSTRING_LENGTH (key); | 404 keydatum.size = XSTRING_LENGTH (key); |
441 | 405 |
442 status = dbp->get (dbp, &keydatum, &valdatum, 0); | 406 status = db->db_handle->get (db->db_handle, &keydatum, &valdatum, 0); |
443 | 407 |
444 if (!status) | 408 if (!status) |
445 return make_string (valdatum.data, valdatum.size); | 409 return make_string ((Bufbyte *) valdatum.data, valdatum.size); |
446 | 410 |
447 db->dberrno = (status == 1) ? -1 : errno; | 411 db->dberrno = (status == 1) ? -1 : errno; |
448 return Qnil; | 412 return Qnil; |
449 } | 413 } |
450 | 414 |
451 static int | 415 static int |
452 berkdb_put (struct database_struct *db, | 416 berkdb_put (struct database *db, |
453 Lisp_Object key, | 417 Lisp_Object key, |
454 Lisp_Object val, | 418 Lisp_Object val, |
455 Lisp_Object replace) | 419 Lisp_Object replace) |
456 { | 420 { |
457 DBT keydatum, valdatum; | 421 DBT keydatum, valdatum; |
458 DB *dbp = (DB *) db->db_handle; | |
459 int status = 0; | 422 int status = 0; |
460 | 423 |
461 keydatum.data = XSTRING_DATA (key); | 424 keydatum.data = XSTRING_DATA (key); |
462 keydatum.size = XSTRING_LENGTH (key); | 425 keydatum.size = XSTRING_LENGTH (key); |
463 valdatum.data = XSTRING_DATA (val); | 426 valdatum.data = XSTRING_DATA (val); |
464 valdatum.size = XSTRING_LENGTH (val); | 427 valdatum.size = XSTRING_LENGTH (val); |
465 status = dbp->put (dbp, &keydatum, &valdatum, NILP (replace) | 428 status = db->db_handle->put (db->db_handle, &keydatum, &valdatum, |
466 ? R_NOOVERWRITE : 0); | 429 NILP (replace) ? R_NOOVERWRITE : 0); |
467 db->dberrno = (status == 1) ? -1 : errno; | 430 db->dberrno = (status == 1) ? -1 : errno; |
468 return status; | 431 return status; |
469 } | 432 } |
470 | 433 |
471 static int | 434 static int |
472 berkdb_remove (struct database_struct *db, Lisp_Object key) | 435 berkdb_remove (struct database *db, Lisp_Object key) |
473 { | 436 { |
474 DBT keydatum; | 437 DBT keydatum; |
475 DB *dbp = (DB *) db->db_handle; | |
476 int status; | 438 int status; |
477 | 439 |
478 keydatum.data = XSTRING_DATA (key); | 440 keydatum.data = XSTRING_DATA (key); |
479 keydatum.size = XSTRING_LENGTH (key); | 441 keydatum.size = XSTRING_LENGTH (key); |
480 | 442 |
481 status = dbp->del (dbp, &keydatum, 0); | 443 status = db->db_handle->del (db->db_handle, &keydatum, 0); |
482 if (!status) | 444 if (!status) |
483 return 0; | 445 return 0; |
484 | 446 |
485 db->dberrno = (status == 1) ? -1 : errno; | 447 db->dberrno = (status == 1) ? -1 : errno; |
486 return 1; | 448 return 1; |
487 } | 449 } |
488 | 450 |
489 static void | 451 static void |
490 berkdb_map (struct database_struct *db, Lisp_Object func) | 452 berkdb_map (struct database *db, Lisp_Object func) |
491 { | 453 { |
492 DBT keydatum, valdatum; | 454 DBT keydatum, valdatum; |
493 Lisp_Object key, val; | 455 Lisp_Object key, val; |
494 DB *dbp = (DB *) db->db_handle; | 456 DB *dbp = db->db_handle; |
495 int status; | 457 int status; |
496 | 458 |
497 for (status = dbp->seq (dbp, &keydatum, &valdatum, R_FIRST); | 459 for (status = dbp->seq (dbp, &keydatum, &valdatum, R_FIRST); |
498 status == 0; | 460 status == 0; |
499 status = dbp->seq (dbp, &keydatum, &valdatum, R_NEXT)) | 461 status = dbp->seq (dbp, &keydatum, &valdatum, R_NEXT)) |
500 { | 462 { |
501 key = make_string (keydatum.data, keydatum.size); | 463 /* ### Needs mule-izing */ |
502 val = make_string (valdatum.data, valdatum.size); | 464 key = make_string ((Bufbyte *) keydatum.data, keydatum.size); |
465 val = make_string ((Bufbyte *) valdatum.data, valdatum.size); | |
503 call2 (func, key, val); | 466 call2 (func, key, val); |
504 } | 467 } |
505 } | 468 } |
506 | 469 |
507 static void | 470 static void |
508 berkdb_close (struct database_struct *db) | 471 berkdb_close (struct database *db) |
509 { | 472 { |
510 DB *dbp = (DB *)db->db_handle; | 473 if (db->db_handle) |
511 if (dbp) | 474 { |
512 { | 475 db->db_handle->sync (db->db_handle, 0); |
513 dbp->sync (dbp, 0); | 476 db->db_handle->close (db->db_handle); |
514 dbp->close (dbp); | 477 db->db_handle = NULL; |
515 } | 478 } |
516 db->db_handle = NULL; | |
517 } | 479 } |
518 | 480 |
519 static DB_FUNCS berk_func_block = | 481 static DB_FUNCS berk_func_block = |
520 { | 482 { |
521 berkdb_subtype, | 483 berkdb_subtype, |
522 berkdb_type, | 484 berkdb_type, |
523 berkdb_open, | |
524 berkdb_get, | 485 berkdb_get, |
525 berkdb_put, | 486 berkdb_put, |
526 berkdb_remove, | 487 berkdb_remove, |
527 berkdb_map, | 488 berkdb_map, |
528 berkdb_lisp_type, | 489 berkdb_lisp_type, |
529 berkdb_close, | 490 berkdb_close, |
530 berkdb_lasterr | 491 berkdb_lasterr |
531 }; | 492 }; |
532 #endif | 493 #endif /* HAVE_BERKELEY_DB */ |
533 | 494 |
534 DEFUN ("database-last-error", Fdatabase_error, 0, 1, 0, /* | 495 DEFUN ("database-last-error", Fdatabase_error, 0, 1, 0, /* |
535 Return the last error associated with database OBJ. | 496 Return the last error associated with database OBJ. |
536 */ | 497 */ |
537 (obj)) | 498 (obj)) |
538 { | 499 { |
539 struct database_struct *db; | |
540 | |
541 if (NILP (obj)) | 500 if (NILP (obj)) |
542 return lisp_strerror (errno); | 501 return lisp_strerror (errno); |
543 | 502 |
544 CHECK_DATABASE (obj); | 503 CHECK_DATABASE (obj); |
545 db = XDATABASE (obj); | 504 |
546 return db->funcs->last_error (db); | 505 return XDATABASE (obj)->funcs->last_error (XDATABASE (obj)); |
547 } | 506 } |
548 | 507 |
549 DEFUN ("open-database", Fmake_database, 1, 5, 0, /* | 508 DEFUN ("open-database", Fmake_database, 1, 5, 0, /* |
550 Open database FILE, using database method TYPE and SUBTYPE, with | 509 Open database FILE, using database method TYPE and SUBTYPE, with |
551 access rights ACCESS and permissions MODE. ACCESS can be any | 510 access rights ACCESS and permissions MODE. ACCESS can be any |
554 (file, type, subtype, access_, mode)) | 513 (file, type, subtype, access_, mode)) |
555 { | 514 { |
556 Lisp_Object retval = Qnil; | 515 Lisp_Object retval = Qnil; |
557 int modemask; | 516 int modemask; |
558 int accessmask = 0; | 517 int accessmask = 0; |
559 XEMACS_DB_TYPE the_type; | 518 struct database *dbase = NULL; |
560 DB_FUNCS *funcblock; | 519 char *filename; |
561 struct database_struct *dbase = NULL; | |
562 void *db = NULL; | |
563 | 520 |
564 CHECK_STRING (file); | 521 CHECK_STRING (file); |
522 filename = (char *) XSTRING_DATA (file); | |
565 | 523 |
566 if (NILP (access_)) | 524 if (NILP (access_)) |
567 { | 525 { |
568 accessmask = O_RDWR | O_CREAT; | 526 accessmask = O_RDWR | O_CREAT; |
569 } | 527 } |
570 else | 528 else |
571 { | 529 { |
572 char *acc; | 530 char *acc; |
573 CHECK_STRING (access_); | 531 CHECK_STRING (access_); |
574 acc = (char *) XSTRING_DATA (access_); | 532 acc = (char *) XSTRING_DATA (access_); |
575 | 533 |
576 if (strchr (acc, '+')) | 534 if (strchr (acc, '+')) |
577 accessmask |= O_CREAT; | 535 accessmask |= O_CREAT; |
578 | 536 |
579 if (strchr (acc, 'r') && strchr (acc, 'w')) | 537 if (strchr (acc, 'r') && strchr (acc, 'w')) |
580 { | |
581 accessmask |= O_RDWR; | 538 accessmask |= O_RDWR; |
582 } | |
583 else if (strchr (acc, 'w')) | 539 else if (strchr (acc, 'w')) |
584 { | |
585 accessmask |= O_WRONLY; | 540 accessmask |= O_WRONLY; |
586 } | |
587 else | 541 else |
588 { | |
589 accessmask |= O_RDONLY; | 542 accessmask |= O_RDONLY; |
590 } | |
591 } | 543 } |
592 | 544 |
593 if (NILP (mode)) | 545 if (NILP (mode)) |
594 { | 546 { |
595 modemask = 493; /* rwxr-xr-x */ | 547 modemask = 0755; /* rwxr-xr-x */ |
596 } | 548 } |
597 else | 549 else |
598 { | 550 { |
599 CHECK_INT (mode); | 551 CHECK_INT (mode); |
600 modemask = XINT (mode); | 552 modemask = XINT (mode); |
601 } | 553 } |
602 | 554 |
603 #ifdef HAVE_DBM | 555 #ifdef HAVE_DBM |
604 if (NILP (type) || EQ (type, Qdbm)) | 556 if (NILP (type) || EQ (type, Qdbm)) |
605 { | 557 { |
606 the_type = DB_DBM; | 558 DBM *dbm = dbm_open (filename, accessmask, modemask); |
607 funcblock = &ndbm_func_block; | 559 if (!dbm) |
560 return Qnil; | |
561 | |
562 dbase = new_database (); | |
563 dbase->dbm_handle = dbm; | |
564 dbase->type = DB_DBM; | |
565 dbase->funcs = &ndbm_func_block; | |
608 goto db_done; | 566 goto db_done; |
609 } | 567 } |
610 #endif | 568 #endif /* HAVE_DBM */ |
611 | 569 |
612 #ifdef HAVE_BERKELEY_DB | 570 #ifdef HAVE_BERKELEY_DB |
613 if (NILP (type) || EQ (type, Qberkeley_db)) | 571 if (NILP (type) || EQ (type, Qberkeley_db)) |
614 { | 572 { |
615 | 573 DBTYPE real_subtype; |
616 funcblock = &berk_func_block; | 574 DB *db; |
617 the_type = DB_BERKELEY; | 575 |
576 if (EQ (subtype, Qhash) || NILP (subtype)) | |
577 real_subtype = DB_HASH; | |
578 else if (EQ (subtype, Qbtree)) | |
579 real_subtype = DB_BTREE; | |
580 else if (EQ (subtype, Qrecno)) | |
581 real_subtype = DB_RECNO; | |
582 else | |
583 signal_simple_error ("Unsupported subtype", subtype); | |
584 | |
585 db = dbopen (filename, accessmask, modemask, real_subtype, NULL); | |
586 if (!db) | |
587 return Qnil; | |
588 | |
589 dbase = new_database (); | |
590 dbase->db_handle = db; | |
591 dbase->type = DB_BERKELEY; | |
592 dbase->funcs = &berk_func_block; | |
618 goto db_done; | 593 goto db_done; |
619 } | 594 } |
620 #endif | 595 #endif /* HAVE_BERKELEY_DB */ |
621 | 596 |
622 signal_simple_error ("Unsupported database type", type); | 597 signal_simple_error ("Unsupported database type", type); |
623 return Qnil; | 598 return Qnil; |
624 | 599 |
625 db_done: | 600 db_done: |
626 db = funcblock->open_file ((char *) XSTRING_DATA (file), subtype, | 601 dbase->live_p = 1; |
627 accessmask, modemask); | |
628 | |
629 if (!db) | |
630 { | |
631 return Qnil; | |
632 } | |
633 | |
634 dbase = new_database (); | |
635 dbase->fname = file; | 602 dbase->fname = file; |
636 dbase->type = the_type; | |
637 dbase->mode = modemask; | 603 dbase->mode = modemask; |
638 dbase->access_ = accessmask; | 604 dbase->access_ = accessmask; |
639 dbase->db_handle = db; | |
640 dbase->funcs = funcblock; | |
641 XSETDATABASE (retval, dbase); | 605 XSETDATABASE (retval, dbase); |
642 | 606 |
643 return retval; | 607 return retval; |
644 } | 608 } |
645 | 609 |
646 DEFUN ("put-database", Fputdatabase, 3, 4, 0, /* | 610 DEFUN ("put-database", Fputdatabase, 3, 4, 0, /* |
647 Store KEY and VAL in DATABASE. If optinal fourth arg REPLACE is | 611 Store KEY and VAL in DATABASE. If optional fourth arg REPLACE is |
648 non-nil, replace any existing entry in the database. | 612 non-nil, replace any existing entry in the database. |
649 */ | 613 */ |
650 (key, val, dbase, replace)) | 614 (key, val, dbase, replace)) |
651 { | 615 { |
652 struct database_struct *db; | 616 CHECK_LIVE_DATABASE (dbase); |
653 int status; | |
654 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | |
655 | |
656 CHECK_DATABASE (dbase); | |
657 CHECK_STRING (key); | 617 CHECK_STRING (key); |
658 CHECK_STRING (val); | 618 CHECK_STRING (val); |
659 db = XDATABASE (dbase); | 619 |
660 if (!DATABASE_LIVE_P (db)) | 620 { |
661 signal_simple_error ("Attempting to access closed database", dbase); | 621 int status = |
662 | 622 XDATABASE (dbase)->funcs->put (XDATABASE (dbase), key, val, replace); |
663 GCPRO4 (key, val, dbase, replace); | 623 return status ? Qt : Qnil; |
664 status = db->funcs->put (db, key, val, replace); | 624 } |
665 UNGCPRO; | |
666 return status ? Qt : Qnil; | |
667 } | 625 } |
668 | 626 |
669 DEFUN ("remove-database", Fremdatabase, 2, 2, 0, /* | 627 DEFUN ("remove-database", Fremdatabase, 2, 2, 0, /* |
670 Remove KEY from DATABASE. | 628 Remove KEY from DATABASE. |
671 */ | 629 */ |
672 (key, dbase)) | 630 (key, dbase)) |
673 { | 631 { |
674 struct database_struct *db; | 632 CHECK_LIVE_DATABASE (dbase); |
675 CHECK_DATABASE (dbase); | |
676 CHECK_STRING (key); | 633 CHECK_STRING (key); |
677 | 634 |
678 db = XDATABASE (dbase); | 635 return XDATABASE (dbase)->funcs->rem (XDATABASE (dbase), key) ? Qt : Qnil; |
679 if (!DATABASE_LIVE_P (db)) | 636 } |
680 signal_simple_error ("Attempting to access closed database", dbase); | 637 |
681 return db->funcs->rem (db, key) ? Qt : Qnil; | |
682 } | |
683 | |
684 DEFUN ("get-database", Fgetdatabase, 2, 3, 0, /* | 638 DEFUN ("get-database", Fgetdatabase, 2, 3, 0, /* |
685 Find value for KEY in DATABASE. | 639 Find value for KEY in DATABASE. |
686 If there is no corresponding value, return DEFAULT (defaults to nil). | 640 If there is no corresponding value, return DEFAULT (defaults to nil). |
687 */ | 641 */ |
688 (key, dbase, default_)) | 642 (key, dbase, default_)) |
689 { | 643 { |
690 Lisp_Object retval; | 644 |
691 struct database_struct *db; | 645 CHECK_LIVE_DATABASE (dbase); |
692 | |
693 CHECK_DATABASE (dbase); | |
694 CHECK_STRING (key); | 646 CHECK_STRING (key); |
695 db = XDATABASE (dbase); | 647 |
696 if (!DATABASE_LIVE_P (db)) | 648 { |
697 signal_simple_error ("Attempting to access closed database", dbase); | 649 Lisp_Object retval = |
698 | 650 XDATABASE (dbase)->funcs->get (XDATABASE (dbase), key); |
699 retval = db->funcs->get (db, key); | 651 return NILP (retval) ? default_ : retval; |
700 | 652 } |
701 return NILP (retval) ? default_ : retval; | |
702 } | 653 } |
703 | 654 |
704 DEFUN ("map-database", Fmapdatabase, 2, 2, 0, /* | 655 DEFUN ("map-database", Fmapdatabase, 2, 2, 0, /* |
705 Map FUNCTION over entries in DATABASE, calling it with two args, | 656 Map FUNCTION over entries in DATABASE, calling it with two args, |
706 each key and value in the database. | 657 each key and value in the database. |
707 */ | 658 */ |
708 (function, dbase)) | 659 (function, dbase)) |
709 { | 660 { |
710 struct gcpro gcpro1, gcpro2; | 661 CHECK_LIVE_DATABASE (dbase); |
711 struct database_struct *db; | 662 |
712 | 663 XDATABASE (dbase)->funcs->map (XDATABASE (dbase), function); |
713 CHECK_DATABASE (dbase); | 664 |
714 GCPRO2 (dbase, function); | |
715 | |
716 db = XDATABASE (dbase); | |
717 if (!DATABASE_LIVE_P (db)) | |
718 signal_simple_error ("Attempting to access closed database", dbase); | |
719 db->funcs->map (db, function); | |
720 UNGCPRO; | |
721 return Qnil; | 665 return Qnil; |
722 } | 666 } |
723 | 667 |
724 void | 668 void |
725 syms_of_dbm (void) | 669 syms_of_dbm (void) |