source: git/Singular/links/sing_dbm.cc @ 6b288b

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