source: git/Singular/links/sing_dbm.cc @ fb1675

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