source: git/Singular/sing_dbm.cc @ 06c0b3

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