1: # include "../ingres.h" 2: # include "../aux.h" 3: # include "../symbol.h" 4: # include "../access.h" 5: # include "../batch.h" 6: 7: /* 8: ** Update reads a batch file written by the 9: ** access method routines (openbatch, addbatch, closebatch) 10: ** and performs the updates stored in the file. 11: ** 12: ** It assumes that it is running in the database. It 13: ** is driven by the data in the Batchhd struct (see ../batch.h). 14: ** If the relation has a secondary index then update calls 15: ** secupdate. As a last step the batch file is removed. 16: ** 17: ** The global flag Batch_recovery is tested in case 18: ** of an error. It should be FALSE if update is being 19: ** run as the dbu deferred update processor. It should 20: ** be TRUE if it is being used as part of the recovery 21: ** procedure. 22: */ 23: 24: update() 25: { 26: register int i, mode; 27: struct descriptor rel; 28: long oldtid, tupcnt; 29: char oldtup[MAXTUP], newtup[MAXTUP]; 30: char *batchname(); 31: extern int Dburetflag; 32: extern struct retcode Dburetcode; 33: 34: # ifdef xZTR1 35: if (tTf(15, -1)) 36: printf("Update on %s\n", batchname()); 37: # endif 38: /* set up to read batchhd */ 39: Batch_cnt = BATCHSIZE; /* force a read on next getbatch */ 40: Batch_dirty = FALSE; 41: if ((Batch_fp = open(batchname(), 2)) < 0) 42: syserr("prim:can't open %s", batchname()); 43: getbatch(&Batchhd, sizeof Batchhd); 44: 45: tupcnt = Batchhd.num_updts; 46: # ifdef xZTR1 47: if (tTf(15, 0)) 48: printf("rel=%s tups=%s\n", Batchhd.rel_name, locv(tupcnt)); 49: # endif 50: Dburetflag = TRUE; 51: Dburetcode.rc_tupcount = 0; 52: if (!tupcnt) 53: { 54: rmbatch(); 55: return (1); 56: } 57: 58: /* update the primary relation */ 59: if (i = openr(&rel, 2, Batchhd.rel_name)) 60: syserr("prim:can't openr %s %d", Batchhd.rel_name, i); 61: mode = Batchhd.mode_up; 62: 63: while (tupcnt--) 64: { 65: getbatch(&oldtid, Batchhd.tido_size); /* read old tid */ 66: getbatch(oldtup, Batchhd.tupo_size); /* and portions of old tuple */ 67: getbatch(newtup, Batchhd.tupn_size); /* and the newtup */ 68: 69: switch (mode) 70: { 71: 72: case mdDEL: 73: if ((i = delete(&rel, &oldtid)) < 0) 74: syserr("prim:bad del %d %s", i, Batchhd.rel_name); 75: break; 76: 77: case mdREPL: 78: if (i = replace(&rel, &oldtid, newtup, TRUE)) 79: { 80: /* if newtuple is a duplicate, then ok */ 81: if (i == 1) 82: break; 83: /* if this is recovery and oldtup not there, try to insert newtup */ 84: if (Batch_recovery && i == 2) 85: goto upinsert; 86: syserr("prim:Non-functional replace on %s (%d)", i, Batchhd.rel_name); 87: } 88: Dburetcode.rc_tupcount++; 89: break; 90: 91: case mdAPP: 92: upinsert: 93: if ((i = insert(&rel, &oldtid, newtup, TRUE)) < 0) 94: syserr("prim:bad insert %d %s", i, Batchhd.rel_name); 95: break; 96: 97: default: 98: syserr("prim:impossible mode %d", mode); 99: } 100: putbatch(&oldtid, Batchhd.tidn_size); /* write new tid if necessary */ 101: } 102: /* fix the tupchanged count if delete or append */ 103: if (mode != mdREPL) 104: Dburetcode.rc_tupcount = rel.reladds >= 0 ? rel.reladds : -rel.reladds; 105: /* close the relation but secupdate will still use the decriptor */ 106: if (i = closer(&rel)) 107: syserr("prim:close err %d %s", i, Batchhd.rel_name); 108: batchflush(); 109: 110: /* if this relation is indexed, update the indexes */ 111: if (rel.relindxd > 0) 112: secupdate(&rel); 113: rmbatch(); 114: 115: # ifdef xZTR1 116: if (tTf(15, 2)) 117: printf("%s tups changed\n", locv(Dburetcode.rc_tupcount)); 118: # endif 119: return (0); 120: }