chiark / gitweb /
Debian package wip
[chiark-tcl.git] / cdb / readonly.c
1 /*
2  * cdb, cdb-wr - Tcl bindings for tinycdb and a journalling write extension
3  * Copyright 2006 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, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18  * 02110-1301, USA.
19  */
20
21 #include "chiark_tcl_cdb.h"
22
23 typedef struct Ro {
24   int ix, fd;
25   struct cdb cdb;
26 } Ro;
27
28 static void ro_close(Ro *ro) {
29   cdb_free(&ro->cdb);
30   close(ro->fd);
31 }
32
33 static void destroy_cdb_idtabcb(Tcl_Interp *ip, void *ro_v) {
34   ro_close(ro_v);
35   TFREE(ro_v);
36 }
37
38 const IdDataSpec cdbtcl_databases= {
39   "cdb-db", "cdb-opendatabases-table", destroy_cdb_idtabcb
40 };
41
42 int cht_do_cdb_open(ClientData cd, Tcl_Interp *ip,
43                     const char *path, void **result) {
44   Ro *ro;
45   int rc, r;
46
47   ro= TALLOC(sizeof(*ro));
48   ro->ix= -1;
49   ro->fd= open(path, O_RDONLY);
50   if (ro->fd<0) PE("open database file");
51   r= cdb_init(&ro->cdb, ro->fd);
52   if (r) PE("initialise cdb");
53   *result= ro;
54   return TCL_OK;
55
56  x_rc:
57   if (ro->fd >= 0) close(ro->fd);
58   return rc;
59 }
60
61 int cht_do_cdb_close(ClientData cd, Tcl_Interp *ip, void *ro_v) {
62   ro_close(ro_v);
63   cht_tabledataid_disposing(ip, ro_v, &cdbtcl_databases);
64   TFREE(ro_v);
65   return TCL_OK;
66 }
67
68 int cht_do_cdb_lookup(ClientData cd, Tcl_Interp *ip, void *ro_v,
69                       Tcl_Obj *keyo, Tcl_Obj *def, Tcl_Obj **result) {
70   Ro *ro= ro_v;
71   const Byte *key;
72   const Byte *data;
73   int r, dlen, klen;
74
75   key= Tcl_GetStringFromObj(keyo, &klen);  assert(key);
76   
77   r= cht_cdb_lookup_cdb(ip, &ro->cdb, key, klen, &data, &dlen);
78   if (r) return r;
79   
80   return cht_cdb_donesomelookup(ip, ro_v, def, result, data, dlen,
81                                 cht_cdb_storeanswer_string);
82 }
83
84 int cht_do_cdb_lookup_hb(ClientData cd, Tcl_Interp *ip, void *ro_v,
85                          HBytes_Value key, Tcl_Obj *def, Tcl_Obj **result) {
86   Ro *ro= ro_v;
87   const Byte *data;
88   int r, dlen;
89   
90   r= cht_cdb_lookup_cdb(ip, &ro->cdb,
91                         cht_hb_data(&key), cht_hb_len(&key),
92                         &data, &dlen);
93   if (r) return r;
94   
95   return cht_cdb_donesomelookup(ip, ro_v, def, result, data, dlen,
96                                 cht_cdb_storeanswer_hb);
97 }
98
99 int cht_do_cdbtoplevel_cdb(ClientData cd, Tcl_Interp *ip,
100                            const Cdb_SubCommand* subcmd,
101                            int objc, Tcl_Obj *const *objv) {
102   return subcmd->func((void*)subcmd,ip,objc,objv);
103 }