GnuCOBOL  2.0
A free COBOL compiler
isrewrite.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003 Trevor van Bremen
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 2.1,
7  * or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; see the file COPYING.LIB. If
16  * not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor
17  * Boston, MA 02110-1301 USA
18  */
19 
20 #include "isinternal.h"
21 
22 /* Local functions */
23 
24 static int
25 irowupdate (const int ihandle, char *pcrow, off_t trownumber)
26 {
27  struct VBKEY *pskey;
28  struct DICTINFO *psvbptr;
29  struct keydesc *pskeyptr;
30  off_t tdupnumber = 0;
31  int ikeynumber, iresult;
32  unsigned char ckeyvalue[VB_MAX_KEYLEN];
33 
34  psvbptr = psvbfile[ihandle];
35  /*
36  * Step 1:
37  * For each index that's changing, confirm that the NEW value
38  * doesn't conflict with an existing ISNODUPS flag.
39  */
40  for (ikeynumber = 0; ikeynumber < psvbptr->inkeys; ikeynumber++) {
41  pskeyptr = psvbptr->pskeydesc[ikeynumber];
42  if (pskeyptr->k_nparts == 0) {
43  continue;
44  }
45  if (pskeyptr->k_flags & ISDUPS) {
46  continue;
47  }
48  vvbmakekey (pskeyptr, pcrow, ckeyvalue);
49  iresult = ivbkeysearch (ihandle, ISGTEQ, ikeynumber, 0, ckeyvalue, (off_t)0);
50  if (iresult != 1
51  || trownumber == psvbptr->pskeycurr[ikeynumber]->trownode
52  || psvbptr->pskeycurr[ikeynumber]->iisdummy) {
53  continue;
54  }
55  iserrno = EDUPL;
56  return -1;
57  }
58 
59  /*
60  * Step 2:
61  * Check each index for existance of trownumber
62  * This 'preload' additionally helps determine which indexes change
63  */
64  for (ikeynumber = 0; ikeynumber < psvbptr->inkeys; ikeynumber++) {
65  pskeyptr = psvbptr->pskeydesc[ikeynumber];
66  if (pskeyptr->k_nparts == 0) {
67  continue;
68  }
69  if (ivbkeylocaterow (ihandle, ikeynumber, trownumber)) {
70  iserrno = EBADFILE;
71  return -1;
72  }
73  }
74 
75  /*
76  * Step 3:
77  * Perform the actual deletion / insertion with each index
78  * But *ONLY* for those indexes that have actually CHANGED!
79  */
80  for (ikeynumber = 0; ikeynumber < psvbptr->inkeys; ikeynumber++) {
81  pskeyptr = psvbptr->pskeydesc[ikeynumber];
82  if (pskeyptr->k_nparts == 0) {
83  continue;
84  }
85  /* pcrow is the UPDATED key! */
86  vvbmakekey (pskeyptr, pcrow, ckeyvalue);
87  if (!memcmp (ckeyvalue, psvbptr->pskeycurr[ikeynumber]->ckey,
88  (size_t)pskeyptr->k_len)) {
89  continue;
90  }
91  /* If NEW key is DIFFERENT than CURRENT, remove CURRENT */
92  iresult = ivbkeydelete (ihandle, ikeynumber);
93  if (iresult) {
94  /* An error occured. Let's put back what we removed! */
95  while (ikeynumber >= 0) {
96 /* BUG - We need to do SOMETHING sane here? Dunno WHAT */
97  ivbkeyinsert (ihandle, NULL, ikeynumber, ckeyvalue,
98  trownumber, tdupnumber, NULL);
99  ikeynumber--;
100  vvbmakekey (pskeyptr,
101  psvbptr->ppcrowbuffer, ckeyvalue);
102  }
103  iserrno = EBADFILE;
104  return -1;
105  }
106  iresult = ivbkeysearch (ihandle, ISGREAT, ikeynumber, 0, ckeyvalue, (off_t)0);
107  tdupnumber = 0;
108  if (iresult >= 0) {
109  iresult = ivbkeyload (ihandle, ikeynumber, ISPREV, 1, &pskey);
110  if (!iresult) {
111  if (pskeyptr->k_flags & ISDUPS
112  && !memcmp (pskey->ckey, ckeyvalue,
113  (size_t)pskeyptr->k_len)) {
114  tdupnumber = pskey->tdupnumber + 1;
115  }
116  psvbptr->pskeycurr[ikeynumber] =
117  psvbptr->pskeycurr[ikeynumber]->psnext;
118  psvbptr->pskeycurr[ikeynumber]->psparent->pskeycurr =
119  psvbptr->pskeycurr[ikeynumber];
120  }
121  iresult = ivbkeysearch (ihandle, ISGTEQ, ikeynumber, 0, ckeyvalue,
122  tdupnumber);
123  iresult = ivbkeyinsert (ihandle, NULL, ikeynumber, ckeyvalue,
124  trownumber, tdupnumber, NULL);
125  }
126  if (iresult) {
127  /* An error occured. Let's remove what we added */
128  while (ikeynumber >= 0) {
129 /* BUG - This is WRONG, we should re-establish what we had before! */
130  /* ivbkeydelete (ihandle, ikeynumber); */
131  ikeynumber--;
132  }
133  return iresult;
134  }
135  }
136 
137  iserrno = 0;
138  return 0;
139 }
140 
141 /* Global functions */
142 
143 int
144 isrewrite (const int ihandle, char *pcrow)
145 {
146  struct DICTINFO *psvbptr;
147  off_t trownumber;
148  int ideleted, inewreclen, ioldreclen = 0, iresult = 0;
149  unsigned char ckeyvalue[VB_MAX_KEYLEN];
150 
151  if (ivbenter (ihandle, 1, 0)) {
152  return -1;
153  }
154  psvbptr = psvbfile[ihandle];
155  if ((psvbptr->iopenmode & ISVARLEN) && (isreclen > psvbptr->imaxrowlength
156  || isreclen < psvbptr->iminrowlength)) {
157  iserrno = EBADARG;
158  return -1;
159  }
160 
161  inewreclen = isreclen;
162  if (psvbptr->pskeydesc[0]->k_flags & ISDUPS) {
163  iresult = -1;
164  iserrno = ENOREC;
165  } else {
166  vvbmakekey (psvbptr->pskeydesc[0], pcrow, ckeyvalue);
167  iresult = ivbkeysearch (ihandle, ISEQUAL, 0, 0, ckeyvalue, (off_t)0);
168  switch (iresult) {
169  case 1: /* Exact match */
170  iresult = 0;
171  psvbptr->iisdictlocked |= 0x02;
172  trownumber = psvbptr->pskeycurr[0]->trownode;
173  if (psvbptr->iopenmode & ISTRANS) {
174  iserrno = ivbdatalock (ihandle, VBWRLOCK, trownumber);
175  if (iserrno) {
176  iresult = -1;
177  goto isrewrite_exit;
178  }
179  }
180  iserrno = ivbdataread (ihandle, psvbptr->ppcrowbuffer,
181  &ideleted, trownumber);
182  if (!iserrno && ideleted) {
183  iserrno = ENOREC;
184  }
185  if (iserrno) {
186  iresult = -1;
187  } else {
188  ioldreclen = isreclen;
189  }
190 
191  if (!iresult) {
192  iresult = irowupdate (ihandle, pcrow, trownumber);
193  }
194  if (!iresult) {
196  isreclen = inewreclen;
197  iresult =
198  ivbdatawrite (ihandle, pcrow, 0, (off_t)isrecnum);
199  }
200  if (!iresult) {
201  if (psvbptr->iopenmode & ISVARLEN) {
202  iresult =
203  ivbtransupdate (ihandle, trownumber, ioldreclen,
204  inewreclen, pcrow);
205  } else {
206  iresult =
207  ivbtransupdate (ihandle, trownumber,
208  psvbptr->iminrowlength,
209  psvbptr->iminrowlength,
210  pcrow);
211  }
212  }
213  break;
214 
215  case 0: /* LESS than */
216  case 2: /* GREATER than */
217  case 3: /* EMPTY file */
218  iserrno = ENOREC;
219  iresult = -1;
220  break;
221 
222  default:
223  iserrno = EBADFILE;
224  iresult = -1;
225  break;
226  }
227  }
228 
229 isrewrite_exit:
230  iresult |= ivbexit (ihandle);
231  return iresult;
232 }
233 
234 int
235 isrewcurr (const int ihandle, char *pcrow)
236 {
237  struct DICTINFO *psvbptr;
238  int ideleted, inewreclen, ioldreclen = 0, iresult = 0;
239 
240  if (ivbenter (ihandle, 1, 0)) {
241  return -1;
242  }
243 
244  psvbptr = psvbfile[ihandle];
245  if ((psvbptr->iopenmode & ISVARLEN) && (isreclen > psvbptr->imaxrowlength
246  || isreclen < psvbptr->iminrowlength)) {
247  iserrno = EBADARG;
248  return -1;
249  }
250 
251  inewreclen = isreclen;
252  if (psvbptr->trownumber > 0) {
253  if (psvbptr->iopenmode & ISTRANS) {
254  iserrno = ivbdatalock (ihandle, VBWRLOCK, psvbptr->trownumber);
255  if (iserrno) {
256  iresult = -1;
257  goto isrewcurr_exit;
258  }
259  }
260  iserrno = ivbdataread (ihandle, psvbptr->ppcrowbuffer, &ideleted,
261  psvbptr->trownumber);
262  if (!iserrno && ideleted) {
263  iserrno = ENOREC;
264  } else {
265  ioldreclen = isreclen;
266  }
267  if (iserrno) {
268  iresult = -1;
269  }
270  if (!iresult) {
271  iresult = irowupdate (ihandle, pcrow, psvbptr->trownumber);
272  }
273  if (!iresult) {
274  isrecnum = psvbptr->trownumber;
275  isreclen = inewreclen;
276  iresult = ivbdatawrite (ihandle, pcrow, 0, (off_t)isrecnum);
277  }
278  if (!iresult) {
279  if (psvbptr->iopenmode & ISVARLEN) {
280  iresult =
281  ivbtransupdate (ihandle, psvbptr->trownumber,
282  ioldreclen, inewreclen, pcrow);
283  } else {
284  iresult =
285  ivbtransupdate (ihandle, psvbptr->trownumber,
286  psvbptr->iminrowlength,
287  psvbptr->iminrowlength, pcrow);
288  }
289  }
290  }
291 isrewcurr_exit:
292  psvbptr->iisdictlocked |= 0x02;
293  iresult |= ivbexit (ihandle);
294  return iresult;
295 }
296 
297 int
298 isrewrec (const int ihandle, const vbisam_off_t trownumber, char *pcrow)
299 {
300  struct DICTINFO *psvbptr;
301  int ideleted, inewreclen, ioldreclen = 0, iresult = 0;
302 
303  if (ivbenter (ihandle, 1, 0)) {
304  return -1;
305  }
306 
307  psvbptr = psvbfile[ihandle];
308  if ((psvbptr->iopenmode & ISVARLEN) && (isreclen > psvbptr->imaxrowlength
309  || isreclen < psvbptr->iminrowlength)) {
310  iserrno = EBADARG;
311  return -1;
312  }
313 
314  inewreclen = isreclen;
315  if (trownumber < 1) {
316  iresult = -1;
317  iserrno = ENOREC;
318  } else {
319  if (psvbptr->iopenmode & ISTRANS) {
320  iserrno = ivbdatalock (ihandle, VBWRLOCK, trownumber);
321  if (iserrno) {
322  iresult = -1;
323  goto isrewrec_exit;
324  }
325  }
326  iserrno = ivbdataread (ihandle, psvbptr->ppcrowbuffer, &ideleted,
327  trownumber);
328  if (!iserrno && ideleted) {
329  iserrno = ENOREC;
330  }
331  if (iserrno) {
332  iresult = -1;
333  } else {
334  ioldreclen = isreclen;
335  }
336  if (!iresult) {
337  iresult = irowupdate (ihandle, pcrow, trownumber);
338  }
339  if (!iresult) {
341  isreclen = inewreclen;
342  iresult = ivbdatawrite (ihandle, pcrow, 0, (off_t)isrecnum);
343  }
344  if (!iresult) {
345  if (psvbptr->iopenmode & ISVARLEN) {
346  iresult = ivbtransupdate (ihandle, trownumber,
347  ioldreclen, inewreclen,
348  pcrow);
349  } else {
350  iresult = ivbtransupdate (ihandle, trownumber,
351  psvbptr->iminrowlength,
352  psvbptr->iminrowlength, pcrow);
353  }
354  }
355  }
356 isrewrec_exit:
357  if (!iresult) {
358  psvbptr->iisdictlocked |= 0x02;
359  }
360  iresult |= ivbexit (ihandle);
361  return iresult;
362 }
int inkeys
Definition: isinternal.h:400
int imaxrowlength
Definition: isinternal.h:404
int isrewrite(const int ihandle, char *pcrow)
Definition: isrewrite.c:144
int isrewrec(const int ihandle, const long long trownumber, char *pcrow)
Definition: isrewrite.c:298
int ivbkeysearch(const int ihandle, const int imode, const int ikeynumber, int ilength, unsigned char *pckeyvalue, off_t tdupnumber)
Definition: vbkeysio.c:372
unsigned char ckey[1]
Definition: isinternal.h:334
int ivbtransupdate(const int ihandle, const off_t trownumber, const int ioldrowlen, const int inewrowlen, const char *pcrow)
Definition: istrans.c:1014
int isreclen
Definition: vbmemio.c:29
int ivbkeylocaterow(const int ihandle, const int ikeynumber, off_t trownumber)
Definition: vbkeysio.c:435
int ivbdatawrite(const int ihandle, char *pcbuffer, int ideletedrow, const off_t trownumber)
Definition: vbdataio.c:611
int ivbenter(const int ihandle, const unsigned int imodifying, const unsigned int ispecial)
Definition: vblocking.c:178
unsigned char iisdummy
Definition: isinternal.h:332
int ivbkeyload(const int ihandle, const int ikeynumber, const int imode, const int isetcurr, struct VBKEY **ppskey)
Definition: vbkeysio.c:503
int iminrowlength
Definition: isinternal.h:403
int ivbkeydelete(const int ihandle, const int ikeynumber)
Definition: vbkeysio.c:777
struct VBTREE * psparent
Definition: isinternal.h:326
struct VBKEY * pskeycurr
Definition: isinternal.h:342
unsigned char iisdictlocked
Definition: isinternal.h:427
EC ARGUMENT EC EC BOUND EC BOUND EC BOUND EC BOUND TABLE EC DATA EC DATA EC DATA PTR NULL
Definition: exception.def:95
int ivbdatalock(const int ihandle, const int imode, const off_t trownumber)
Definition: vblocking.c:432
struct VBKEY * pskeycurr[32]
Definition: isinternal.h:448
off_t trownode
Definition: isinternal.h:328
int isrewcurr(const int ihandle, char *pcrow)
Definition: isrewrite.c:235
void vvbmakekey(const struct keydesc *pskeydesc, char *pcrow_buffer, unsigned char *pckeyvalue)
Definition: vbkeysio.c:212
int ivbdataread(const int ihandle, char *pcbuffer, int *pideletedrow, const off_t trownumber)
Definition: vbdataio.c:493
#define VBWRLOCK
Definition: isinternal.h:297
struct DICTINFO * psvbfile[128+1]
Definition: vblowlevel.c:23
off_t tdupnumber
Definition: isinternal.h:329
int ivbkeyinsert(const int ihandle, struct VBTREE *pstree, const int ikeynumber, unsigned char *pckeyvalue, off_t trownode, off_t tdupnumber, struct VBTREE *pschild)
Definition: vbkeysio.c:727
int ivbexit(const int ihandle)
Definition: vblocking.c:290
int iopenmode
Definition: isinternal.h:412
struct keydesc * pskeydesc[32]
Definition: isinternal.h:445
off_t trownumber
Definition: isinternal.h:416
struct VBKEY * psnext
Definition: isinternal.h:324
static int irowupdate(const int ihandle, char *pcrow, off_t trownumber)
Definition: isrewrite.c:25
char * ppcrowbuffer
Definition: isinternal.h:423
int iserrno
Definition: vbmemio.c:27
int isrecnum
Definition: vbmemio.c:30