chiark / gitweb /
changelog: start 1.3.2
[chiark-tcl.git] / cdb / readonly.c
1 /*
2  * cdb, cdb-wr - Tcl bindings for tinycdb and a journalling write extension
3  * Copyright 2006-2012 Ian Jackson
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this library; if not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include "chiark_tcl_cdb.h"
20
21 typedef struct Ro {
22   int ix, fd;
23   struct cdb cdb;
24 } Ro;
25
26 static void ro_close(Ro *ro) {
27   cdb_free(&ro->cdb);
28   close(ro->fd);
29 }
30
31 static void destroy_cdb_idtabcb(Tcl_Interp *ip, void *ro_v) {
32   ro_close(ro_v);
33   TFREE(ro_v);
34 }
35
36 const IdDataSpec cdbtcl_databases= {
37   "cdb-db", "cdb-opendatabases-table", destroy_cdb_idtabcb
38 };
39
40 int cht_do_cdb_open(ClientData cd, Tcl_Interp *ip,
41                     const char *path, void **result) {
42   Ro *ro;
43   int rc, r;
44
45   ro= TALLOC(sizeof(*ro));
46   ro->ix= -1;
47   ro->fd= open(path, O_RDONLY);
48   if (ro->fd<0) PE("open database file");
49   r= cdb_init(&ro->cdb, ro->fd);
50   if (r) PE("initialise cdb");
51   *result= ro;
52   return TCL_OK;
53
54  x_rc:
55   if (ro->fd >= 0) close(ro->fd);
56   return rc;
57 }
58
59 int cht_do_cdb_close(ClientData cd, Tcl_Interp *ip, void *ro_v) {
60   ro_close(ro_v);
61   cht_tabledataid_disposing(ip, ro_v, &cdbtcl_databases);
62   TFREE(ro_v);
63   return TCL_OK;
64 }
65
66 int cht_do_cdb_lookup(ClientData cd, Tcl_Interp *ip, void *ro_v,
67                       Tcl_Obj *keyo, Tcl_Obj *def, Tcl_Obj **result) {
68   Ro *ro= ro_v;
69   const Byte *key;
70   const Byte *data;
71   int r, dlen, klen;
72
73   key= Tcl_GetStringFromObj(keyo, &klen);  assert(key);
74   
75   r= cht_cdb_lookup_cdb(ip, &ro->cdb, key, klen, &data, &dlen);
76   if (r) return r;
77   
78   return cht_cdb_donesomelookup(ip, ro_v, def, result, data, dlen,
79                                 cht_cdb_storeanswer_string);
80 }
81
82 int cht_do_cdb_lookup_hb(ClientData cd, Tcl_Interp *ip, void *ro_v,
83                          HBytes_Value key, Tcl_Obj *def, Tcl_Obj **result) {
84   Ro *ro= ro_v;
85   const Byte *data;
86   int r, dlen;
87   
88   r= cht_cdb_lookup_cdb(ip, &ro->cdb,
89                         cht_hb_data(&key), cht_hb_len(&key),
90                         &data, &dlen);
91   if (r) return r;
92   
93   return cht_cdb_donesomelookup(ip, ro_v, def, result, data, dlen,
94                                 cht_cdb_storeanswer_hb);
95 }