Mercurial > hg > xemacs-beta
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; |