comparison src/database.c @ 771:943eaba38521

[xemacs-hg @ 2002-03-13 08:51:24 by ben] The big ben-mule-21-5 check-in! Various files were added and deleted. See CHANGES-ben-mule. There are still some test suite failures. No crashes, though. Many of the failures have to do with problems in the test suite itself rather than in the actual code. I'll be addressing these in the next day or so -- none of the test suite failures are at all critical. Meanwhile I'll be trying to address the biggest issues -- i.e. build or run failures, which will almost certainly happen on various platforms. All comments should be sent to ben@xemacs.org -- use a Cc: if necessary when sending to mailing lists. There will be pre- and post- tags, something like pre-ben-mule-21-5-merge-in, and post-ben-mule-21-5-merge-in.
author ben
date Wed, 13 Mar 2002 08:54:06 +0000
parents fdefd0186b75
children e38acbeb1cae
comparison
equal deleted inserted replaced
770:336a418893b5 771:943eaba38521
1 /* Database access routines 1 /* Database access routines
2 Copyright (C) 1996, William M. Perry 2 Copyright (C) 1996, William M. Perry
3 Copyright (C) 2001 Ben Wing.
3 4
4 This file is part of XEmacs. 5 This file is part of XEmacs.
5 6
6 XEmacs is free software; you can redistribute it and/or modify it 7 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the 8 under the terms of the GNU General Public License as published by the
21 /* Synched up with: Not in FSF. */ 22 /* Synched up with: Not in FSF. */
22 23
23 /* Written by Bill Perry */ 24 /* Written by Bill Perry */
24 /* Substantially rewritten by Martin Buchholz */ 25 /* Substantially rewritten by Martin Buchholz */
25 /* db 2.x support added by Andreas Jaeger */ 26 /* db 2.x support added by Andreas Jaeger */
27 /* Mule-ized 6-22-00 Ben Wing */
26 28
27 #include <config.h> 29 #include <config.h>
28 #include "lisp.h" 30 #include "lisp.h"
31
29 #include "sysfile.h" 32 #include "sysfile.h"
30 #include "buffer.h" 33 #include "buffer.h"
31 34
32 #ifndef HAVE_DATABASE 35 #ifndef HAVE_DATABASE
33 #error HAVE_DATABASE not defined!! 36 #error HAVE_DATABASE not defined!!
66 #ifdef HAVE_DBM 69 #ifdef HAVE_DBM
67 #include <ndbm.h> 70 #include <ndbm.h>
68 Lisp_Object Qdbm; 71 Lisp_Object Qdbm;
69 #endif /* HAVE_DBM */ 72 #endif /* HAVE_DBM */
70 73
71 #ifdef MULE
72 /* #### The following should be settable on a per-database level.
73 But the whole coding-system infrastructure should be rewritten someday.
74 We really need coding-system aliases. -- martin */
75 Lisp_Object Vdatabase_coding_system; 74 Lisp_Object Vdatabase_coding_system;
76 #endif
77 75
78 Lisp_Object Qdatabasep; 76 Lisp_Object Qdatabasep;
79 77
80 typedef struct 78 typedef struct
81 { 79 {
102 #endif 100 #endif
103 #ifdef HAVE_BERKELEY_DB 101 #ifdef HAVE_BERKELEY_DB
104 DB *db_handle; 102 DB *db_handle;
105 #endif 103 #endif
106 DB_FUNCS *funcs; 104 DB_FUNCS *funcs;
107 #ifdef MULE
108 Lisp_Object coding_system; 105 Lisp_Object coding_system;
109 #endif
110 }; 106 };
111 107
112 #define XDATABASE(x) XRECORD (x, database, Lisp_Database) 108 #define XDATABASE(x) XRECORD (x, database, Lisp_Database)
113 #define XSETDATABASE(x, p) XSETRECORD (x, p, database) 109 #define XSETDATABASE(x, p) XSETRECORD (x, p, database)
114 #define wrap_database(p) wrap_record (p, database) 110 #define wrap_database(p) wrap_record (p, database)
138 db->dbm_handle = NULL; 134 db->dbm_handle = NULL;
139 #endif 135 #endif
140 db->access_ = 0; 136 db->access_ = 0;
141 db->mode = 0; 137 db->mode = 0;
142 db->dberrno = 0; 138 db->dberrno = 0;
143 #ifdef MULE 139 db->coding_system = Qnil;
144 db->coding_system = Fget_coding_system (Qbinary);
145 #endif
146 return db; 140 return db;
147 } 141 }
148 142
149 static Lisp_Object 143 static Lisp_Object
150 mark_database (Lisp_Object object) 144 mark_database (Lisp_Object object)
265 for (keydatum = dbm_firstkey (db->dbm_handle); 259 for (keydatum = dbm_firstkey (db->dbm_handle);
266 keydatum.dptr != NULL; 260 keydatum.dptr != NULL;
267 keydatum = dbm_nextkey (db->dbm_handle)) 261 keydatum = dbm_nextkey (db->dbm_handle))
268 { 262 {
269 valdatum = dbm_fetch (db->dbm_handle, keydatum); 263 valdatum = dbm_fetch (db->dbm_handle, keydatum);
270 key = make_string ((unsigned char *) keydatum.dptr, keydatum.dsize); 264 key = make_ext_string (keydatum.dptr, keydatum.dsize,
271 val = make_string ((unsigned char *) valdatum.dptr, valdatum.dsize); 265 db->coding_system);
266 val = make_ext_string (valdatum.dptr, valdatum.dsize,
267 db->coding_system);
272 call2 (func, key, val); 268 call2 (func, key, val);
273 } 269 }
274 } 270 }
275 271
276 static Lisp_Object 272 static Lisp_Object
277 dbm_get (Lisp_Database *db, Lisp_Object key) 273 dbm_get (Lisp_Database *db, Lisp_Object key)
278 { 274 {
279 datum keydatum, valdatum; 275 datum keydatum, valdatum;
280 276
281 keydatum.dptr = (char *) XSTRING_DATA (key); 277 TO_EXTERNAL_FORMAT (LISP_STRING, key,
282 keydatum.dsize = XSTRING_LENGTH (key); 278 ALLOCA, (keydatum.dptr, keydatum.dsize),
279 db->coding_system);
283 valdatum = dbm_fetch (db->dbm_handle, keydatum); 280 valdatum = dbm_fetch (db->dbm_handle, keydatum);
284 281
285 return (valdatum.dptr 282 return (valdatum.dptr
286 ? make_string ((unsigned char *) valdatum.dptr, valdatum.dsize) 283 ? make_ext_string (valdatum.dptr, valdatum.dsize,
284 db->coding_system)
287 : Qnil); 285 : Qnil);
288 } 286 }
289 287
290 static int 288 static int
291 dbm_put (Lisp_Database *db, 289 dbm_put (Lisp_Database *db,
292 Lisp_Object key, Lisp_Object val, Lisp_Object replace) 290 Lisp_Object key, Lisp_Object val, Lisp_Object replace)
293 { 291 {
294 datum keydatum, valdatum; 292 datum keydatum, valdatum;
295 293
296 valdatum.dptr = (char *) XSTRING_DATA (val); 294 TO_EXTERNAL_FORMAT (LISP_STRING, val,
297 valdatum.dsize = XSTRING_LENGTH (val); 295 ALLOCA, (valdatum.dptr, valdatum.dsize),
298 keydatum.dptr = (char *) XSTRING_DATA (key); 296 db->coding_system);
299 keydatum.dsize = XSTRING_LENGTH (key); 297 TO_EXTERNAL_FORMAT (LISP_STRING, key,
298 ALLOCA, (keydatum.dptr, keydatum.dsize),
299 db->coding_system);
300 300
301 return !dbm_store (db->dbm_handle, keydatum, valdatum, 301 return !dbm_store (db->dbm_handle, keydatum, valdatum,
302 NILP (replace) ? DBM_INSERT : DBM_REPLACE); 302 NILP (replace) ? DBM_INSERT : DBM_REPLACE);
303 } 303 }
304 304
305 static int 305 static int
306 dbm_remove (Lisp_Database *db, Lisp_Object key) 306 dbm_remove (Lisp_Database *db, Lisp_Object key)
307 { 307 {
308 datum keydatum; 308 datum keydatum;
309 309
310 keydatum.dptr = (char *) XSTRING_DATA (key); 310 TO_EXTERNAL_FORMAT (LISP_STRING, key,
311 keydatum.dsize = XSTRING_LENGTH (key); 311 ALLOCA, (keydatum.dptr, keydatum.dsize),
312 db->coding_system);
312 313
313 return dbm_delete (db->dbm_handle, keydatum); 314 return dbm_delete (db->dbm_handle, keydatum);
314 } 315 }
315 316
316 static Lisp_Object 317 static Lisp_Object
393 394
394 /* DB Version 2 requires DBT's to be zeroed before use. */ 395 /* DB Version 2 requires DBT's to be zeroed before use. */
395 xzero (keydatum); 396 xzero (keydatum);
396 xzero (valdatum); 397 xzero (valdatum);
397 398
398 keydatum.data = XSTRING_DATA (key); 399 TO_EXTERNAL_FORMAT (LISP_STRING, key,
399 keydatum.size = XSTRING_LENGTH (key); 400 ALLOCA, (keydatum.data, keydatum.size),
401 db->coding_system);
400 402
401 #if DB_VERSION_MAJOR == 1 403 #if DB_VERSION_MAJOR == 1
402 status = db->db_handle->get (db->db_handle, &keydatum, &valdatum, 0); 404 status = db->db_handle->get (db->db_handle, &keydatum, &valdatum, 0);
403 #else 405 #else
404 status = db->db_handle->get (db->db_handle, NULL, &keydatum, &valdatum, 0); 406 status = db->db_handle->get (db->db_handle, NULL, &keydatum, &valdatum, 0);
405 #endif /* DB_VERSION_MAJOR */ 407 #endif /* DB_VERSION_MAJOR */
406 408
407 if (!status) 409 if (!status)
408 /* #### Not mule-ized! will crash! */ 410 return make_ext_string (valdatum.data, valdatum.size,
409 return make_string ((Intbyte *) valdatum.data, valdatum.size); 411 db->coding_system);
410 412
411 #if DB_VERSION_MAJOR == 1 413 #if DB_VERSION_MAJOR == 1
412 db->dberrno = (status == 1) ? -1 : errno; 414 db->dberrno = (status == 1) ? -1 : errno;
413 #else 415 #else
414 db->dberrno = (status < 0) ? -1 : errno; 416 db->dberrno = (status < 0) ? -1 : errno;
428 430
429 /* DB Version 2 requires DBT's to be zeroed before use. */ 431 /* DB Version 2 requires DBT's to be zeroed before use. */
430 xzero (keydatum); 432 xzero (keydatum);
431 xzero (valdatum); 433 xzero (valdatum);
432 434
433 keydatum.data = XSTRING_DATA (key); 435 TO_EXTERNAL_FORMAT (LISP_STRING, key,
434 keydatum.size = XSTRING_LENGTH (key); 436 ALLOCA, (keydatum.data, keydatum.size),
435 valdatum.data = XSTRING_DATA (val); 437 db->coding_system);
436 valdatum.size = XSTRING_LENGTH (val); 438 TO_EXTERNAL_FORMAT (LISP_STRING, val,
439 ALLOCA, (valdatum.data, valdatum.size),
440 db->coding_system);
437 #if DB_VERSION_MAJOR == 1 441 #if DB_VERSION_MAJOR == 1
438 status = db->db_handle->put (db->db_handle, &keydatum, &valdatum, 442 status = db->db_handle->put (db->db_handle, &keydatum, &valdatum,
439 NILP (replace) ? R_NOOVERWRITE : 0); 443 NILP (replace) ? R_NOOVERWRITE : 0);
440 db->dberrno = (status == 1) ? -1 : errno; 444 db->dberrno = (status == 1) ? -1 : errno;
441 #else 445 #else
454 int status; 458 int status;
455 459
456 /* DB Version 2 requires DBT's to be zeroed before use. */ 460 /* DB Version 2 requires DBT's to be zeroed before use. */
457 xzero (keydatum); 461 xzero (keydatum);
458 462
459 keydatum.data = XSTRING_DATA (key); 463 TO_EXTERNAL_FORMAT (LISP_STRING, key,
460 keydatum.size = XSTRING_LENGTH (key); 464 ALLOCA, (keydatum.data, keydatum.size),
465 db->coding_system);
461 466
462 #if DB_VERSION_MAJOR == 1 467 #if DB_VERSION_MAJOR == 1
463 status = db->db_handle->del (db->db_handle, &keydatum, 0); 468 status = db->db_handle->del (db->db_handle, &keydatum, 0);
464 #else 469 #else
465 status = db->db_handle->del (db->db_handle, NULL, &keydatum, 0); 470 status = db->db_handle->del (db->db_handle, NULL, &keydatum, 0);
491 #if DB_VERSION_MAJOR == 1 496 #if DB_VERSION_MAJOR == 1
492 for (status = dbp->seq (dbp, &keydatum, &valdatum, R_FIRST); 497 for (status = dbp->seq (dbp, &keydatum, &valdatum, R_FIRST);
493 status == 0; 498 status == 0;
494 status = dbp->seq (dbp, &keydatum, &valdatum, R_NEXT)) 499 status = dbp->seq (dbp, &keydatum, &valdatum, R_NEXT))
495 { 500 {
496 /* #### Needs mule-izing */ 501 key = make_ext_string (keydatum.data, keydatum.size,
497 key = make_string ((Intbyte *) keydatum.data, keydatum.size); 502 db->coding_system);
498 val = make_string ((Intbyte *) valdatum.data, valdatum.size); 503 val = make_ext_string (valdatum.data, valdatum.size,
504 db->coding_system);
499 call2 (func, key, val); 505 call2 (func, key, val);
500 } 506 }
501 #else 507 #else
502 { 508 {
503 DBC *dbcp; 509 DBC *dbcp;
509 #endif 515 #endif
510 for (status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_FIRST); 516 for (status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_FIRST);
511 status == 0; 517 status == 0;
512 status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_NEXT)) 518 status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_NEXT))
513 { 519 {
514 /* #### Needs mule-izing */ 520 key = make_ext_string (keydatum.data, keydatum.size,
515 key = make_string ((Intbyte *) keydatum.data, keydatum.size); 521 db->coding_system);
516 val = make_string ((Intbyte *) valdatum.data, valdatum.size); 522 val = make_ext_string (valdatum.data, valdatum.size,
523 db->coding_system);
517 call2 (func, key, val); 524 call2 (func, key, val);
518 } 525 }
519 dbcp->c_close (dbcp); 526 dbcp->c_close (dbcp);
520 } 527 }
521 #endif /* DB_VERSION_MAJOR */ 528 #endif /* DB_VERSION_MAJOR */
561 CHECK_DATABASE (database); 568 CHECK_DATABASE (database);
562 569
563 return XDATABASE (database)->funcs->last_error (XDATABASE (database)); 570 return XDATABASE (database)->funcs->last_error (XDATABASE (database));
564 } 571 }
565 572
566 DEFUN ("open-database", Fopen_database, 1, 5, 0, /* 573 DEFUN ("open-database", Fopen_database, 1, 6, 0, /*
567 Return a new database object opened on FILE. 574 Return a new database object opened on FILE.
568 Optional arguments TYPE and SUBTYPE specify the database type. 575 Optional arguments TYPE and SUBTYPE specify the database type.
569 Optional argument ACCESS specifies the access rights, which may be any 576 Optional argument ACCESS specifies the access rights, which may be any
570 combination of 'r' 'w' and '+', for read, write, and creation flags. 577 combination of 'r' 'w' and '+', for read, write, and creation flags.
571 Optional argument MODE gives the permissions to use when opening FILE, 578 Optional argument MODE gives the permissions to use when opening FILE,
572 and defaults to 0755. 579 and defaults to 0755.
573 */ 580 Optional argument CODESYS specifies the coding system used to encode/decode
574 (file, type, subtype, access_, mode)) 581 data passed to/from the database, and defaults to the value of the
582 variable `database-coding-system'.
583 */
584 (file, type, subtype, access_, mode, codesys))
575 { 585 {
576 /* This function can GC */ 586 /* This function can GC */
577 int modemask; 587 int modemask;
578 int accessmask = 0; 588 int accessmask = 0;
579 Lisp_Database *db = NULL; 589 Lisp_Database *db = NULL;
619 { 629 {
620 CHECK_INT (mode); 630 CHECK_INT (mode);
621 modemask = XINT (mode); 631 modemask = XINT (mode);
622 } 632 }
623 633
634 if (NILP (codesys))
635 codesys = Vdatabase_coding_system;
636
637 codesys = get_coding_system_for_text_file (Vdatabase_coding_system, 1);
638
624 #ifdef HAVE_DBM 639 #ifdef HAVE_DBM
625 if (NILP (type) || EQ (type, Qdbm)) 640 if (NILP (type) || EQ (type, Qdbm))
626 { 641 {
627 DBM *dbase = dbm_open (filename, accessmask, modemask); 642 DBM *dbase = dbm_open (filename, accessmask, modemask);
628 if (!dbase) 643 if (!dbase)
629 return Qnil; 644 return Qnil;
630 645
631 db = allocate_database (); 646 db = allocate_database ();
632 db->dbm_handle = dbase; 647 db->dbm_handle = dbase;
633 db->funcs = &ndbm_func_block; 648 db->funcs = &ndbm_func_block;
649 db->coding_system = codesys;
634 goto db_done; 650 goto db_done;
635 } 651 }
636 #endif /* HAVE_DBM */ 652 #endif /* HAVE_DBM */
637 653
638 #ifdef HAVE_BERKELEY_DB 654 #ifdef HAVE_BERKELEY_DB
701 #endif /* DB_VERSION_MAJOR */ 717 #endif /* DB_VERSION_MAJOR */
702 718
703 db = allocate_database (); 719 db = allocate_database ();
704 db->db_handle = dbase; 720 db->db_handle = dbase;
705 db->funcs = &berk_func_block; 721 db->funcs = &berk_func_block;
722 db->coding_system = codesys;
706 goto db_done; 723 goto db_done;
707 } 724 }
708 #endif /* HAVE_BERKELEY_DB */ 725 #endif /* HAVE_BERKELEY_DB */
709 726
710 invalid_constant ("Unsupported database type", type); 727 invalid_constant ("Unsupported database type", type);
824 #endif 841 #endif
825 #ifdef HAVE_BERKELEY_DB 842 #ifdef HAVE_BERKELEY_DB
826 Fprovide (Qberkeley_db); 843 Fprovide (Qberkeley_db);
827 #endif 844 #endif
828 845
829 #if 0 /* #### implement me! */
830 #ifdef MULE
831 DEFVAR_LISP ("database-coding-system", &Vdatabase_coding_system /* 846 DEFVAR_LISP ("database-coding-system", &Vdatabase_coding_system /*
832 Coding system used to convert data in database files. 847 Default coding system used to convert data in database files.
833 */ ); 848 */ );
834 Vdatabase_coding_system = Qnil; 849 Vdatabase_coding_system = Qnative;
835 #endif 850 }
836 #endif /* 0 */
837 }