source: git/Singular/sing_dbm.cc @ a2dde00

spielwiese
Last change on this file since a2dde00 was ebc73ed, checked in by Hans Schoenemann <hannes@…>, 14 years ago
slOpen fix git-svn-id: file:///usr/local/Singular/svn/trunk@13245 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 11.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4
5//**************************************************************************/
6//
7// $Id$
8//
9//**************************************************************************/
10//  'sing_dbm.cc' containes command to handle dbm-files under
11// Singular.
12//
13//**************************************************************************/
14
15#  include <stdio.h>
16#  include <fcntl.h>
17#  include <errno.h>
18
19#include <kernel/mod2.h>
20
21#ifdef HAVE_DBM
22
23#  include <Singular/tok.h>
24#  include <kernel/febase.h>
25#include <omalloc/omalloc.h>
26#  include <Singular/ipid.h>
27#  include <Singular/silink.h>
28#  include <Singular/sing_dbm.h>
29
30// #ifdef ix86_Win
31// #  define USE_GDBM
32// #  define BLOCKSIZE 1
33// #  define GDBM_STATIC
34// #  include <gdbm.h>
35// #endif
36
37#ifdef USE_GDBM
38typedef struct {
39  GDBM_FILE db;        // pointer to open database
40  int first;      // firstkey to look for?
41  datum actual;  // the actual key
42} GDBM_info;
43
44//**************************************************************************/
45LINKAGE BOOLEAN dbOpen(si_link l, short flag, leftv u)
46{
47  char *mode = "r";
48  GDBM_info *db;
49  datum d_key;
50  //  int dbm_flags = O_RDONLY | O_CREAT;  // open database readonly as default
51  int read_write= GDBM_READER;
52
53  if(flag & SI_LINK_WRITE)
54  {
55 //    if((l->mode==NULL)
56//     || ((l->mode[0]!='w')&&(l->mode[1]!='w')))
57//     {
58//       // request w- open, but mode is not "w" nor "rw" => fail
59//       return TRUE;
60//    }
61    //    dbm_flags = O_RDWR | O_CREAT;
62    read_write =  GDBM_WRCREAT | GDBM_NOLOCK;
63    mode = "rw";
64  }
65  if(flag & SI_LINK_READ)
66    {
67      if (strcmp(l->mode,"rw")==0) mode="rw";   
68    }
69  //if (((db = (DBM_info *)omAlloc(sizeof *db)) != NULL)
70  //&&((db->db = dbm_open(l->name, dbm_flags, 0664 )) != NULL ))
71  db = (GDBM_info *)omAlloc0(sizeof *db);
72  if((db->db = gdbm_open(l->name, BLOCKSIZE, read_write, 0664, 0)) != NULL )
73  {
74//     if (db->first) // first created?
75//       {
76//         db->actual=gdbm_firstkey(db->db);
77//       }
78//     else
79//       {
80//     d_key=db->actual;
81//     if (d_key.dptr!=NULL)
82//       {
83//         db->actual=gdbm_nextkey(db->db,db->actual);
84//       }
85//     else { db->actual=gdbm_firstkey(db->db); }
86//      }
87    db->first=1;
88    if(flag & SI_LINK_WRITE)
89      SI_LINK_SET_W_OPEN_P(l);
90    else
91      SI_LINK_SET_R_OPEN_P(l);
92    l->data=(void *)(db);
93    omFree(l->mode);
94    l->mode=omStrDup(mode);
95    return FALSE;
96  }
97  Print("%d/%s",gdbm_errno,gdbm_strerror(gdbm_errno));
98  return TRUE;
99}
100
101//**************************************************************************/
102LINKAGE BOOLEAN dbClose(si_link l)
103{
104  GDBM_info *db = (GDBM_info *)l->data;
105  gdbm_sync(db->db);
106  gdbm_close(db->db);
107  omFreeSize((ADDRESS)db,(sizeof *db));
108  l->data=NULL;
109  SI_LINK_SET_CLOSE_P(l);
110  return FALSE;
111}
112
113//**************************************************************************/
114static datum d_value;
115LINKAGE leftv dbRead2(si_link l, leftv key)
116{
117  GDBM_info *db = (GDBM_info *)l->data;
118  // GDBM_info *db;
119//   db = (GDBM_info *)omAlloc0(sizeof *db);
120//   db = (GDBM_info *)l->data;
121  leftv v=NULL;
122  datum d_key;
123  int flag;
124
125  if (!SI_LINK_R_OPEN_P(l)) //exceptions
126    //  if (strcmp(l->mode,"rw")==0) //rw-mode
127    {
128      if (!SI_LINK_CLOSE_P(l))
129        {
130          if (!dbClose(l)) {Print("cannot close link!\n");}
131        }
132      //(SI_LINK_CLOSE_P(l)) automatically
133      if (dbOpen(l, SI_LINK_READ)) return NULL;
134    }
135  if (SI_LINK_RW_OPEN_P(l)) {Print("I/O Error!\n");}
136
137  if(key!=NULL)
138  {
139    if (key->Typ()==STRING_CMD)
140    {
141      d_key.dptr = (char*)key->Data();
142      d_key.dsize = strlen(d_key.dptr)+1;
143      d_value = gdbm_fetch(db->db, d_key);
144      v=(leftv)omAlloc0Bin(sleftv_bin);
145      if (d_value.dptr!=NULL) v->data=omStrDup(d_value.dptr);
146      else                    v->data=omStrDup("");
147      v->rtyp=STRING_CMD;
148    }
149    else
150    {
151      WerrorS("read(`GDBM link`,`string`) expected");
152    }
153  }
154  else
155  {
156    if (db->first)
157    {
158      db->first=0;
159      d_key = gdbm_firstkey(db->db);
160   //    db->actual=d_key;
161//       Print("firstkey:%s\n",d_key.dptr);
162    }
163    else
164    {
165      if (db->actual.dptr==NULL)
166      {
167        db->actual=gdbm_firstkey(db->db);
168      }
169      d_key = gdbm_nextkey(db->db,db->actual);
170      db->actual=d_key;
171      if (d_key.dptr==NULL)
172      {
173        db->first=1;
174      // Print("nextkey:NULL\n");
175      }
176     //  else
177//       Print("nextkey:%s\n",d_key.dptr);
178    }
179
180    if (d_key.dptr!=NULL)
181      d_value = gdbm_fetch(db->db, d_key);
182    else
183      d_value.dptr=NULL;
184
185    v=(leftv)omAlloc0Bin(sleftv_bin);
186    v->rtyp=STRING_CMD;
187    if (d_value.dptr!=NULL)
188    {
189      v->data=omStrDup(d_key.dptr);
190      db->first = 0;
191    }
192    else
193    {
194      v->data=omStrDup("");
195      //      db->first = 1;
196    }
197
198  }
199  return v;
200}
201LINKAGE leftv dbRead1(si_link l)
202{
203  return dbRead2(l,NULL);
204}
205//**************************************************************************/
206LINKAGE BOOLEAN dbWrite(si_link l, leftv key)
207{
208  GDBM_info *db = (GDBM_info *)l->data;
209 //  GDBM_info *db;
210//   db = (GDBM_info *)omAlloc0(sizeof *db);
211//   db = (GDBM_info *)l->data;
212  BOOLEAN b=TRUE;
213  register int ret;
214
215  if (strcmp(l->mode,"rw")!=0) // r-mode
216    {
217      Print("Write error on readonly source\n");
218    }
219  else //rw-mode
220    {
221      if (!SI_LINK_W_OPEN_P(l)) //exceptions
222        {
223          if (!SI_LINK_CLOSE_P(l))
224            {
225              if (!dbClose(l)) {Print("close error\n");};
226            }
227          if (!dbOpen(l,SI_LINK_WRITE)) {Print("open_for_write error\n");}
228        }
229    }
230
231  if((key!=NULL) && (key->Typ()==STRING_CMD) )
232  {
233    if (key->next!=NULL)                   // have a second parameter ?
234    {
235      if(key->next->Typ()==STRING_CMD)     // replace (key,value)
236      {
237        datum d_key, d_value;
238
239        d_key.dptr = (char *)key->Data();
240        d_key.dsize = strlen(d_key.dptr)+1;
241        d_value.dptr = (char *)key->next->Data();
242        d_value.dsize = strlen(d_value.dptr)+1;
243        ret  = gdbm_store(db->db, d_key, d_value, GDBM_REPLACE);
244//         db->actual=d_key;
245        if (ret==-1) {Print("reader calls gdbm_store!");}
246        if (ret==0)
247          { b=FALSE; }
248        else
249        {
250          //          if(gdbm_error(db->db))
251          if (gdbm_errno != 0)
252          {
253            Werror("GDBM link I/O error: '%s' ", gdbm_errno);
254            //            Print(gdbm_strerror(gdbm_errno));
255            //dbm_clearerr(db->db);
256            //            gdbm_errno=0;
257          }
258        }
259      }
260    }
261    else
262    {                               // delete (key)
263      datum d_key;
264
265      d_key.dptr = (char *)key->Data();
266      d_key.dsize = strlen(d_key.dptr)+1;
267 //      db->actual=gdbm_nextkey(db->db,d_key);
268      gdbm_delete(db->db, d_key);
269      b=FALSE;
270    }
271  }
272  else
273  {
274    WerrorS("write(`GDBM link`,`key string` [,`data string`]) expected");
275  }
276  gdbm_sync(db->db);
277  return b;
278}
279#endif /* USE_GDBM */
280
281#ifndef USE_GDBM
282/* These are the routines in dbm. */
283#  include "ndbm.h"
284typedef struct {
285  DBM *db;        // pointer to open database
286  int first;      // firstkey to look for?
287} DBM_info;
288
289//**************************************************************************/
290LINKAGE BOOLEAN dbOpen(si_link l, short flag, leftv u)
291{
292  const char *mode = "r";
293  DBM_info *db;
294  int dbm_flags = O_RDONLY | O_CREAT;  // open database readonly as default
295
296  if((l->mode!=NULL)
297  && ((l->mode[0]=='w')||(l->mode[1]=='w')))
298  {
299    dbm_flags = O_RDWR | O_CREAT;
300    mode = "rw";
301    flag|=SI_LINK_WRITE|SI_LINK_READ;
302  }
303  else if(flag & SI_LINK_WRITE)
304  {
305    // request w- open, but mode is not "w" nor "rw" => fail
306    return TRUE;
307  }
308  //if (((db = (DBM_info *)omAlloc(sizeof *db)) != NULL)
309  //&&((db->db = dbm_open(l->name, dbm_flags, 0664 )) != NULL ))
310  db = (DBM_info *)omAlloc(sizeof *db);
311  if((db->db = dbm_open(l->name, dbm_flags, 0664 )) != NULL )
312  {
313    db->first=1;
314    if(flag & SI_LINK_WRITE)
315      SI_LINK_SET_RW_OPEN_P(l);
316    else
317      SI_LINK_SET_R_OPEN_P(l);
318    l->data=(void *)(db);
319    omFree(l->mode);
320    l->mode=omStrDup(mode);
321    return FALSE;
322  }
323  return TRUE;
324}
325
326//**************************************************************************/
327LINKAGE BOOLEAN dbClose(si_link l)
328{
329  DBM_info *db = (DBM_info *)l->data;
330
331  dbm_close(db->db);
332  omFreeSize((ADDRESS)db,(sizeof *db));
333  l->data=NULL;
334  SI_LINK_SET_CLOSE_P(l);
335  return FALSE;
336}
337
338//**************************************************************************/
339static datum d_value;
340LINKAGE leftv dbRead2(si_link l, leftv key)
341{
342  DBM_info *db = (DBM_info *)l->data;
343  leftv v=NULL;
344  datum d_key;
345
346  if(key!=NULL)
347  {
348    if (key->Typ()==STRING_CMD)
349    {
350      d_key.dptr = (char*)key->Data();
351      d_key.dsize = strlen(d_key.dptr)+1;
352      d_value = dbm_fetch(db->db, d_key);
353      v=(leftv)omAlloc0Bin(sleftv_bin);
354      if (d_value.dptr!=NULL) v->data=omStrDup(d_value.dptr);
355      else                    v->data=omStrDup("");
356      v->rtyp=STRING_CMD;
357    }
358    else
359    {
360      WerrorS("read(`DBM link`,`string`) expected");
361    }
362  }
363  else
364  {
365    if(db->first)
366      d_value = dbm_firstkey((DBM *)db->db);
367    else
368      d_value = dbm_nextkey((DBM *)db->db);
369
370    v=(leftv)omAlloc0Bin(sleftv_bin);
371    v->rtyp=STRING_CMD;
372    if (d_value.dptr!=NULL)
373    {
374      v->data=omStrDup(d_value.dptr);
375      db->first = 0;
376    }
377    else
378    {
379      v->data=omStrDup("");
380      db->first = 1;
381    }
382
383  }
384  return v;
385}
386LINKAGE leftv dbRead1(si_link l)
387{
388  return dbRead2(l,NULL);
389}
390//**************************************************************************/
391LINKAGE BOOLEAN dbWrite(si_link l, leftv key)
392{
393  DBM_info *db = (DBM_info *)l->data;
394  BOOLEAN b=TRUE;
395  register int ret;
396
397  // database is opened
398  if((key!=NULL) && (key->Typ()==STRING_CMD) )
399  {
400    if (key->next!=NULL)                   // have a second parameter ?
401    {
402      if(key->next->Typ()==STRING_CMD)     // replace (key,value)
403      {
404        datum d_key, d_value;
405
406        d_key.dptr = (char *)key->Data();
407        d_key.dsize = strlen(d_key.dptr)+1;
408        d_value.dptr = (char *)key->next->Data();
409        d_value.dsize = strlen(d_value.dptr)+1;
410        ret  = dbm_store(db->db, d_key, d_value, DBM_REPLACE);
411        if(!ret )
412          b=FALSE;
413        else
414        {
415          if(dbm_error(db->db))
416          {
417            Werror("DBM link I/O error. Is '%s' readonly?", l->name);
418            dbm_clearerr(db->db);
419          }
420        }
421      }
422    }
423    else
424    {                               // delete (key)
425      datum d_key;
426
427      d_key.dptr = (char *)key->Data();
428      d_key.dsize = strlen(d_key.dptr)+1;
429      dbm_delete(db->db, d_key);
430      b=FALSE;
431    }
432  }
433  else
434  {
435    WerrorS("write(`DBM link`,`key string` [,`data string`]) expected");
436  }
437  return b;
438}
439//**************************************************************************/
440//char *dbStatus(si_link l, char *request)
441//{
442//  if (strcmp(request, "read") == 0)
443//  {
444//    if (SI_LINK_R_OPEN_P(l))
445//      return "ready";
446//    else
447//      return "not ready";
448//  }
449//  else if (strcmp(request, "write") == 0)
450//  {
451//    if (SI_LINK_W_OPEN_P(l))
452//      return "ready";
453//    else
454//      return "not ready";
455//  }
456//  else return "unknown status request";
457//}
458//**************************************************************************/
459
460#endif /* USE_GDBM */
461#endif /* HAVE_DBM */
Note: See TracBrowser for help on using the repository browser.