/[webpac]/openisis/0.9.9e/core/db.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /openisis/0.9.9e/core/db.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 604 - (show annotations)
Mon Dec 27 21:49:01 2004 UTC (19 years, 2 months ago) by dpavlin
File MIME type: text/plain
File size: 7330 byte(s)
import of new openisis release, 0.9.9e

1 /*
2 The Malete project - the Z39.2/Z39.50 database framework of OpenIsis.
3 Version 0.9.x (patchlevel see file Version)
4 Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 see README for more information
21 EOH */
22
23 /*
24 $Id: db.c,v 1.27 2004/11/08 12:00:12 kripke Exp $
25 implementation of general db access functions.
26 */
27
28
29 #include "core/core.h"
30
31
32 /* ************************************************************
33 private types
34 */
35
36 /** file extensions not listed on filext.com */
37
38 /** B-Link-Tree malete query data/index */
39 static const char EXT_MQD[] = ".mqd";
40 static const char EXT_MQX[] = ".mqx";
41 /** plaintext malete record data/index */
42 static const char EXT_MRD[] = ".mrd";
43 static const char EXT_MRX[] = ".mrx";
44 /** record 0 options data */
45 static const char EXT_M0D[] = ".m0d";
46
47
48
49 /* ************************************************************
50 data
51 */
52
53 /* linked list of open dbs. */
54 static Db *dbs;
55
56
57 enum {
58 /* additional flg outside the short range */
59 OPEN_TRY = 0x10000, /* try writable, open readonly else */
60 OPEN_UC = 0x20000, /* use uppercase ext */
61 /* commonly used combinations */
62 /* 1) open as is, do not complain about any failure, do not create */
63 OPEN_ASIS = FIL_RDWR|OPEN_TRY,
64 /* 2) open readonly, do not complain about any failure, do not create */
65 OPEN_RDIF = FIL_RD|FIL_TRY,
66 /* 3) open readonly, complain about any failure */
67 OPEN_RD = FIL_RD,
68 /* 4) open or create writable, complain on failure */
69 OPEN_NEW = FIL_RDWR|FIL_CREAT,
70 OPEN_BLANK = FIL_RDWR|FIL_CREAT|FIL_TRUNC
71 };
72
73
74 /* set extension. fname MUST already end with .xxx.
75 */
76 static char *setext ( char *fname, const char *ext )
77 {
78 int l = strlen( fname ) - 4;
79 memcpy( fname+l, ext, 4 );
80 return fname;
81 }
82
83
84 Db *dOpen (const char *dbname)
85 {
86 const Fld *cfg;
87 Fld opt;
88 file optf;
89 /* options during open */
90 int withrdx = !0;
91 int withqdx = !0;
92 int filmode = FIL_RD, async = DX_ASYNC; /* changed by -w */
93 int lck = FIL_TLOCK; /* set to BLOCK by -b */
94 /* misc vars */
95 Db *db;
96 int plen, ret = 0;
97
98 #ifdef BUILD_SHMODE
99 if (ENV_SHARED==env.wri) async = 0; /* default to sync */
100 #endif
101 for ( db = dbs; db; db = db->nxt )
102 if ( !strcmp(db->nam, dbname) ) {
103 if ( DX_OPEN & db->flg ) {
104 db->mnt++;
105 return db;
106 }
107 return 0; /* hmmm ... should not be here */
108 }
109
110 cfg = rKey(env.opt->fld, 1, dbname);
111 db = mAlloc(sizeof(Db));
112 db->rdx.mrd = db->rdx.mrx.fil = FIL_NONE;
113 db->rdx.mrx.lim = env.rml;
114 db->qdx.mqd = db->qdx.mqx.fil = FIL_NONE;
115 db->qdx.mqx.lim = env.qml;
116 plen = strlen(dbname);
117 memcpy(db->nam = mAlloc(plen+1), dbname, plen+1);
118
119 /* pre-options defaults */
120 db->qdx.typ = QDX_LEAF1K;
121 db->qdx.ptr = QDX_ISIS;
122 db->qdx.ksz = 255;
123 if ( env.wri )
124 db->flg |= DX_WRITE;
125
126 if ( cfg ) for ( opt.val = 0; vGet(&opt, cfg, "bfqrw"); )
127 switch (opt.tag) {
128 case 'b': /* blocking */
129 lck = FIL_BLOCK;
130 continue;
131 case 'f': /* file/path */
132 if ( !opt.len ) {
133 eRr(LOG_WARN, "bad empty file");
134 continue;
135 }
136 db->pat = mAlloc(opt.len + plen + 5);
137 memcpy(db->pat, opt.val, opt.len);
138 switch ( opt.val[opt.len - 1] ) {
139 case '/':
140 #ifdef WIN32
141 case '\\':
142 #endif
143 memcpy(db->pat+opt.len, dbname, plen);
144 plen += opt.len;
145 break;
146 default:
147 plen = opt.len;
148 }
149 eRr(LOG_INFO, "using path %.*s", plen, db->pat);
150 continue;
151 case 'q': /* qdx type */
152 if ( !opt.len )
153 withqdx = 0;
154 else {
155 unsigned char val = (unsigned char) a2i(opt.val+1, opt.len-1);
156 switch (*opt.val) {
157 case 'k': db->qdx.ksz = val; break;
158 case 'l': db->qdx.let = val; break;
159 case 'p': db->qdx.ptr = val; break;
160 case 't': db->qdx.typ = val; break;
161 }
162 }
163 continue;
164 case 'r': /* mrx type */
165 if ( !opt.len )
166 withrdx = 0;
167 else
168 db->rdx.typ = a2i(opt.val, opt.len);
169 continue;
170 case 'w': /* writable */
171 if ( opt.len )
172 switch ( *opt.val ) {
173 case '0': db->flg &= ~DX_WRITE; break;
174 case 'a': async = DX_ASYNC; break;
175 case 's': async = 0; break;
176 }
177 continue;
178 }
179
180 /* post-options defaults */
181 if ( DX_WRITE & db->flg ) {
182 db->rdx.flg |= DX_WRITE;
183 db->qdx.flg |= DX_WRITE;
184 filmode |= FIL_WR|FIL_CREAT;
185 if ( !(DX_ASYNC & (db->flg |= async)) )
186 filmode |= FIL_SYNC;
187 }
188 if ( !db->pat )
189 memcpy(db->pat = mAlloc(plen+5), dbname, plen);
190 memcpy(db->pat+plen, ".???", 5);
191
192 #if 1
193 /* check options file */
194 if ( ! fOpen(&optf, setext(db->pat,EXT_M0D), FIL_RD|FIL_TRY) ) {
195 char buf[0x10000];
196 int sz;
197 if ( 0 < (sz = fSize(optf)) ) {
198 char *p = sz < (int)sizeof(buf) ? buf : mAlloc(sz);
199 eRr(LOG_INFO, "reading %d bytes options from '%s'", sz, db->pat);
200 if ( sz == fRead(&optf, p, sz) ) {
201 List dbopt;
202 lParse(lInit(&dbopt,0), p, sz);
203 db->opt = LCAN(&dbopt);
204 }
205 if ( buf != p )
206 mFree(p);
207 }
208 fClose(&optf);
209 }
210 #endif
211
212 #ifdef BUILD_SHMODE
213 if (ENV_SHARED==env.wri) lck = 0; /* we lock on demand */
214 #endif
215 #define CLEANUP( args ) do { ret = eRr args; goto cleanup; } while (0)
216 if ( withrdx ) {
217 if ( fOpen( &db->rdx.mrd, setext(db->pat,EXT_MRD), filmode|lck ) )
218 CLEANUP((LOG_ERROR, "no master file '%s'", db->pat ));
219 if ( fMOpen( &db->rdx.mrx, setext(db->pat,EXT_MRX), filmode ) )
220 CLEANUP((LOG_ERROR, "no pointer file '%s'", db->pat ));
221 if ( rInit( &db->rdx ) )
222 CLEANUP((LOG_ERROR, "could not rInit '%s'", db->pat ));
223 }
224
225 if ( withqdx ) {
226 if (db->opt)
227 db->qdx.cdx = cOpen(db->opt);
228 if ( fOpen( &db->qdx.mqd, setext(db->pat,EXT_MQD), filmode|lck ) )
229 CLEANUP((LOG_ERROR, "no index leaves file '%s'", db->pat ));
230 if ( fMOpen( &db->qdx.mqx, setext(db->pat,EXT_MQX), filmode ) )
231 CLEANUP((LOG_ERROR, "no index tree file '%s'", db->pat ));
232 if ( qInit( &db->qdx ) )
233 CLEANUP((LOG_ERROR, "could not qInit '%s'", db->pat ));
234 }
235
236 db->pat[plen] = 0; /* cut .ext */
237 db->flg |= DX_OPEN;
238 db->nxt = dbs;
239 dbs = db;
240 return db;
241
242 cleanup:
243 /* cleanup ... */
244 db->flg = 0;
245 fClose( &db->qdx.mqd );
246 fMClose( &db->qdx.mqx );
247 fClose( &db->rdx.mrd );
248 fMClose( &db->rdx.mrx );
249 return 0;
250 } /* dOpen */
251
252
253 void dClose ( Db *db )
254 {
255 Db **d;
256
257 for ( d = &dbs; *d; d = &(*d)->nxt ) /* unlink */
258 if ( db == *d ) {
259 if ( --db->mnt )
260 return;
261 *d = db->nxt;
262 break;
263 }
264 if ( FIL_NONE != db->rdx.mrd ) {
265 rFini( &db->rdx );
266 fClose( &db->rdx.mrd );
267 fMClose( &db->rdx.mrx );
268 }
269 if ( FIL_NONE != db->qdx.mqd ) {
270 qFini( &db->qdx );
271 fClose( &db->qdx.mqd );
272 fMClose( &db->qdx.mqx );
273 }
274 db->flg = 0L;
275 mFree( (void*)db->pat );
276 mFree( (void*)db->opt );
277 mFree( (void*)db->nam );
278 memset( db, 0, sizeof(db) );
279 mFree( db );
280 } /* dClose */
281
282
283 void dCloseAll ()
284 {
285 Db *d, *nxt;
286 for ( d = dbs; d; d = nxt ) {
287 nxt = d->nxt;
288 dClose(d);
289 }
290 } /* dCloseAll */

  ViewVC Help
Powered by ViewVC 1.1.26