/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 dpavlin 604 /*
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