comparison src/database.c @ 207:e45d5e7c476e r20-4b2

Import from CVS: tag r20-4b2
author cvs
date Mon, 13 Aug 2007 10:03:52 +0200
parents 850242ba4a81
children 41ff10fd062f
comparison
equal deleted inserted replaced
206:d3e9274cbc4e 207:e45d5e7c476e
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 /* Substantially rewritten by Martin Buchholz */ 24 /* Substantially rewritten by Martin Buchholz */
25 /* db 2.x support added by Andreas Jaeger */
25 26
26 #include <config.h> 27 #include <config.h>
27 #include "lisp.h" 28 #include "lisp.h"
28 #include <errno.h> 29 #include <errno.h>
29 30
35 36
36 #ifdef HAVE_BERKELEY_DB 37 #ifdef HAVE_BERKELEY_DB
37 /* Work around Berkeley DB's use of int types which are defined 38 /* Work around Berkeley DB's use of int types which are defined
38 slightly differently in the not quite yet standard <inttypes.h>. 39 slightly differently in the not quite yet standard <inttypes.h>.
39 See db.h for details of why we're resorting to this... */ 40 See db.h for details of why we're resorting to this... */
41 /* glibc 2.1 doesn't have this problem with DB 2.x */
42 #if !(defined __GLIBC__ && __GLIBC_MINOR__ >= 1)
40 #ifdef HAVE_INTTYPES_H 43 #ifdef HAVE_INTTYPES_H
41 #define __BIT_TYPES_DEFINED__ 44 #define __BIT_TYPES_DEFINED__
42 #include <inttypes.h> 45 #include <inttypes.h>
43 typedef uint8_t u_int8_t; 46 typedef uint8_t u_int8_t;
44 typedef uint16_t u_int16_t; 47 typedef uint16_t u_int16_t;
45 typedef uint32_t u_int32_t; 48 typedef uint32_t u_int32_t;
46 #ifdef WE_DONT_NEED_QUADS 49 #ifdef WE_DONT_NEED_QUADS
47 typedef uint64_t u_int64_t; 50 typedef uint64_t u_int64_t;
48 #endif /* WE_DONT_NEED_QUADS */ 51 #endif /* WE_DONT_NEED_QUADS */
49 #endif /* HAVE_INTTYPES_H */ 52 #endif /* HAVE_INTTYPES_H */
53 #endif /* !(defined __GLIBC__ && __GLIBC_MINOR__ >= 1) */
50 #include DB_H_PATH /* Berkeley db's header file */ 54 #include DB_H_PATH /* Berkeley db's header file */
55 #ifndef DB_VERSION_MAJOR
56 # define DB_VERSION_MAJOR 1
57 #endif /* DB_VERSION_MAJOR */
51 Lisp_Object Qberkeley_db; 58 Lisp_Object Qberkeley_db;
52 Lisp_Object Qhash; 59 Lisp_Object Qhash;
53 Lisp_Object Qbtree; 60 Lisp_Object Qbtree;
54 Lisp_Object Qrecno; 61 Lisp_Object Qrecno;
55 #endif /* HAVE_BERKELEY_DB */ 62 #endif /* HAVE_BERKELEY_DB */
59 Lisp_Object Qdbm; 66 Lisp_Object Qdbm;
60 #endif /* HAVE_DBM */ 67 #endif /* HAVE_DBM */
61 68
62 Lisp_Object Qdatabasep; 69 Lisp_Object Qdatabasep;
63 70
64 typedef enum { DB_DBM, DB_BERKELEY, DB_UNKNOWN } XEMACS_DB_TYPE; 71 typedef enum { DB_DBM, DB_BERKELEY, DB_IS_UNKNOWN } XEMACS_DB_TYPE;
65 72
66 struct database; 73 struct database;
67 typedef struct database database; 74 typedef struct database database;
68 75
69 typedef struct 76 typedef struct
136 dbase->dbm_handle = NULL; 143 dbase->dbm_handle = NULL;
137 #endif 144 #endif
138 dbase->access_ = 0; 145 dbase->access_ = 0;
139 dbase->mode = 0; 146 dbase->mode = 0;
140 dbase->dberrno = 0; 147 dbase->dberrno = 0;
141 dbase->type = DB_UNKNOWN; 148 dbase->type = DB_IS_UNKNOWN;
142 #ifdef MULE 149 #ifdef MULE
143 dbase->coding_system = Fget_coding_system (Qbinary); 150 dbase->coding_system = Fget_coding_system (Qbinary);
144 #endif 151 #endif
145 return dbase; 152 return dbase;
146 } 153 }
398 { 405 {
399 /* #### Needs mule-izing */ 406 /* #### Needs mule-izing */
400 DBT keydatum, valdatum; 407 DBT keydatum, valdatum;
401 int status = 0; 408 int status = 0;
402 409
410 #if DB_VERSION_MAJOR == 2
411 /* Always initialize keydatum, valdatum. */
412 memset(&keydatum, 0, sizeof(keydatum));
413 memset(&valdatum, 0, sizeof(valdatum));
414 #endif /* DV_VERSION_MAJOR = 2 */
415
403 keydatum.data = XSTRING_DATA (key); 416 keydatum.data = XSTRING_DATA (key);
404 keydatum.size = XSTRING_LENGTH (key); 417 keydatum.size = XSTRING_LENGTH (key);
405 418
419 #if DB_VERSION_MAJOR == 1
406 status = db->db_handle->get (db->db_handle, &keydatum, &valdatum, 0); 420 status = db->db_handle->get (db->db_handle, &keydatum, &valdatum, 0);
421 #else
422 status = db->db_handle->get (db->db_handle, NULL, &keydatum, &valdatum, 0);
423 #endif /* DB_VERSION_MAJOR */
407 424
408 if (!status) 425 if (!status)
409 return make_string ((Bufbyte *) valdatum.data, valdatum.size); 426 return make_string ((Bufbyte *) valdatum.data, valdatum.size);
410 427
428 #if DB_VERSION_MAJOR == 1
411 db->dberrno = (status == 1) ? -1 : errno; 429 db->dberrno = (status == 1) ? -1 : errno;
430 #else
431 db->dberrno = (status < 0) ? -1 : errno;
432 #endif /* DB_VERSION_MAJOR */
433
412 return Qnil; 434 return Qnil;
413 } 435 }
414 436
415 static int 437 static int
416 berkdb_put (struct database *db, 438 berkdb_put (struct database *db,
419 Lisp_Object replace) 441 Lisp_Object replace)
420 { 442 {
421 DBT keydatum, valdatum; 443 DBT keydatum, valdatum;
422 int status = 0; 444 int status = 0;
423 445
446 #if DB_VERSION_MAJOR == 2
447 /* Always initalize keydatum, valdatum. */
448 memset(&keydatum, 0, sizeof(keydatum));
449 memset(&valdatum, 0, sizeof(valdatum));
450 #endif /* DV_VERSION_MAJOR = 2 */
451
424 keydatum.data = XSTRING_DATA (key); 452 keydatum.data = XSTRING_DATA (key);
425 keydatum.size = XSTRING_LENGTH (key); 453 keydatum.size = XSTRING_LENGTH (key);
426 valdatum.data = XSTRING_DATA (val); 454 valdatum.data = XSTRING_DATA (val);
427 valdatum.size = XSTRING_LENGTH (val); 455 valdatum.size = XSTRING_LENGTH (val);
456 #if DB_VERSION_MAJOR == 1
428 status = db->db_handle->put (db->db_handle, &keydatum, &valdatum, 457 status = db->db_handle->put (db->db_handle, &keydatum, &valdatum,
429 NILP (replace) ? R_NOOVERWRITE : 0); 458 NILP (replace) ? R_NOOVERWRITE : 0);
430 db->dberrno = (status == 1) ? -1 : errno; 459 db->dberrno = (status == 1) ? -1 : errno;
460 #else
461 status = db->db_handle->put (db->db_handle, NULL, &keydatum, &valdatum,
462 NILP (replace) ? DB_NOOVERWRITE : 0);
463 db->dberrno = (status < 0) ? -1 : errno;
464 #endif/* DV_VERSION_MAJOR = 2 */
465
431 return status; 466 return status;
432 } 467 }
433 468
434 static int 469 static int
435 berkdb_remove (struct database *db, Lisp_Object key) 470 berkdb_remove (struct database *db, Lisp_Object key)
436 { 471 {
437 DBT keydatum; 472 DBT keydatum;
438 int status; 473 int status;
439 474
475 #if DB_VERSION_MAJOR == 2
476 /* Always initialize keydatum. */
477 memset(&keydatum, 0, sizeof(keydatum));
478 #endif /* DV_VERSION_MAJOR = 2 */
479
440 keydatum.data = XSTRING_DATA (key); 480 keydatum.data = XSTRING_DATA (key);
441 keydatum.size = XSTRING_LENGTH (key); 481 keydatum.size = XSTRING_LENGTH (key);
442 482
483 #if DB_VERSION_MAJOR == 1
443 status = db->db_handle->del (db->db_handle, &keydatum, 0); 484 status = db->db_handle->del (db->db_handle, &keydatum, 0);
485 #else
486 status = db->db_handle->del (db->db_handle, NULL, &keydatum, 0);
487 #endif /* DB_VERSION_MAJOR */
488
444 if (!status) 489 if (!status)
445 return 0; 490 return 0;
446 491
492 #if DB_VERSION_MAJOR == 1
447 db->dberrno = (status == 1) ? -1 : errno; 493 db->dberrno = (status == 1) ? -1 : errno;
494 #else
495 db->dberrno = (status < 0) ? -1 : errno;
496 #endif /* DB_VERSION_MAJOR */
497
448 return 1; 498 return 1;
449 } 499 }
450 500
451 static void 501 static void
452 berkdb_map (struct database *db, Lisp_Object func) 502 berkdb_map (struct database *db, Lisp_Object func)
454 DBT keydatum, valdatum; 504 DBT keydatum, valdatum;
455 Lisp_Object key, val; 505 Lisp_Object key, val;
456 DB *dbp = db->db_handle; 506 DB *dbp = db->db_handle;
457 int status; 507 int status;
458 508
509 #if DB_VERSION_MAJOR == 1
459 for (status = dbp->seq (dbp, &keydatum, &valdatum, R_FIRST); 510 for (status = dbp->seq (dbp, &keydatum, &valdatum, R_FIRST);
460 status == 0; 511 status == 0;
461 status = dbp->seq (dbp, &keydatum, &valdatum, R_NEXT)) 512 status = dbp->seq (dbp, &keydatum, &valdatum, R_NEXT))
462 { 513 {
463 /* ### Needs mule-izing */ 514 /* ### Needs mule-izing */
464 key = make_string ((Bufbyte *) keydatum.data, keydatum.size); 515 key = make_string ((Bufbyte *) keydatum.data, keydatum.size);
465 val = make_string ((Bufbyte *) valdatum.data, valdatum.size); 516 val = make_string ((Bufbyte *) valdatum.data, valdatum.size);
466 call2 (func, key, val); 517 call2 (func, key, val);
467 } 518 }
519 #else
520 DBC *dbcp;
521 /* Initialize the key/data pair so the flags aren't set. */
522 memset(&keydatum, 0, sizeof(keydatum));
523 memset(&valdatum, 0, sizeof(valdatum));
524
525 status = dbp->cursor (dbp, NULL, &dbcp);
526 for (status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_FIRST);
527 status == 0;
528 status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_NEXT))
529 {
530 /* ### Needs mule-izing */
531 key = make_string ((Bufbyte *) keydatum.data, keydatum.size);
532 val = make_string ((Bufbyte *) valdatum.data, valdatum.size);
533 call2 (func, key, val);
534 }
535 dbcp->c_close (dbcp);
536 #endif /* DB_VERSION_MAJOR */
468 } 537 }
469 538
470 static void 539 static void
471 berkdb_close (struct database *db) 540 berkdb_close (struct database *db)
472 { 541 {
473 if (db->db_handle) 542 if (db->db_handle)
474 { 543 {
544 #if DB_VERSION_MAJOR == 1
475 db->db_handle->sync (db->db_handle, 0); 545 db->db_handle->sync (db->db_handle, 0);
476 db->db_handle->close (db->db_handle); 546 db->db_handle->close (db->db_handle);
547 #else
548 db->db_handle->sync (db->db_handle, 0);
549 db->db_handle->close (db->db_handle, 0);
550 #endif /* DB_VERSION_MAJOR */
477 db->db_handle = NULL; 551 db->db_handle = NULL;
478 } 552 }
479 } 553 }
480 554
481 static DB_FUNCS berk_func_block = 555 static DB_FUNCS berk_func_block =
575 #ifdef HAVE_BERKELEY_DB 649 #ifdef HAVE_BERKELEY_DB
576 if (NILP (type) || EQ (type, Qberkeley_db)) 650 if (NILP (type) || EQ (type, Qberkeley_db))
577 { 651 {
578 DBTYPE real_subtype; 652 DBTYPE real_subtype;
579 DB *db; 653 DB *db;
580 654 int status;
655
581 if (EQ (subtype, Qhash) || NILP (subtype)) 656 if (EQ (subtype, Qhash) || NILP (subtype))
582 real_subtype = DB_HASH; 657 real_subtype = DB_HASH;
583 else if (EQ (subtype, Qbtree)) 658 else if (EQ (subtype, Qbtree))
584 real_subtype = DB_BTREE; 659 real_subtype = DB_BTREE;
585 else if (EQ (subtype, Qrecno)) 660 else if (EQ (subtype, Qrecno))
586 real_subtype = DB_RECNO; 661 real_subtype = DB_RECNO;
587 else 662 else
588 signal_simple_error ("Unsupported subtype", subtype); 663 signal_simple_error ("Unsupported subtype", subtype);
589 664
665 #if DB_VERSION_MAJOR == 1
590 db = dbopen (filename, accessmask, modemask, real_subtype, NULL); 666 db = dbopen (filename, accessmask, modemask, real_subtype, NULL);
591 if (!db) 667 if (!db)
592 return Qnil; 668 return Qnil;
593 669 #else
670 /* Berkeley DB Version 2 has only the accessmask DB_CREATE and DB_RDONLY,
671 other flags shouldn't be set */
672 if (NILP (access_))
673 {
674 accessmask = DB_CREATE;
675 }
676 else
677 {
678 char *acc;
679 CHECK_STRING (access_);
680 acc = (char *) XSTRING_DATA (access_);
681 accessmask = 0;
682
683 if (strchr (acc, '+'))
684 accessmask |= DB_CREATE;
685
686 if (strchr (acc, 'r') && !strchr (acc, 'w'))
687 accessmask |= DB_RDONLY;
688 }
689 status = db_open (filename, real_subtype, accessmask, modemask, NULL , NULL, &db);
690 if (status)
691 return Qnil;
692 #endif /* DB_VERSION_MAJOR */
693
594 dbase = new_database (); 694 dbase = new_database ();
595 dbase->db_handle = db; 695 dbase->db_handle = db;
596 dbase->type = DB_BERKELEY; 696 dbase->type = DB_BERKELEY;
597 dbase->funcs = &berk_func_block; 697 dbase->funcs = &berk_func_block;
598 goto db_done; 698 goto db_done;