ING_DB
This commit is contained in:
parent
1696d51d0c
commit
9465ccdf03
|
|
@ -0,0 +1,182 @@
|
|||
# include "gen.h"
|
||||
# include "../h/dbs.h"
|
||||
# include "../h/access.h"
|
||||
|
||||
# define SAMETUP 0
|
||||
# define SAMEKEYS 1
|
||||
# define DIFFTUP 2
|
||||
|
||||
/*
|
||||
** AAam_replace - replace an already existing tuple
|
||||
**
|
||||
** AAam_replace will replace the tuple specified by TID
|
||||
** with the new tuple. An attempt is made to not
|
||||
** move the tuple if at all possible.
|
||||
**
|
||||
** Three separate conditions are delt with. If the
|
||||
** new tuple is the same as the old tuple, a return
|
||||
** of zero occures and the page is not changed.
|
||||
**
|
||||
** If the keys(if any) are the same and the canonical
|
||||
** tuple lengths are the same, then the new tuple will
|
||||
** be placed in the same location.
|
||||
**
|
||||
** If the lengths or the keys are different, then the
|
||||
** tuple is deleted and the new tuple inserted
|
||||
**
|
||||
** Checkdups specifies whether to check for duplicates.
|
||||
** If the new tuple is a duplicate of one already there,
|
||||
** then the tuple at TID is deleted
|
||||
** returns:
|
||||
** <0 fatal error
|
||||
** 0 ok
|
||||
** 1 new tuple was duplicate of returned tid
|
||||
** 2 tuple not found, already deleted (TID invalid)
|
||||
**
|
||||
** If AAam_replace returns 1 then tid is set to the
|
||||
** duplicate tuple. This is necessary for updating
|
||||
** secondary indices.
|
||||
*/
|
||||
AAam_replace(d, tid, tuple, checkdups)
|
||||
register DESC *d;
|
||||
register struct tup_id *tid;
|
||||
char *tuple;
|
||||
int checkdups;
|
||||
{
|
||||
register int i;
|
||||
register int same;
|
||||
register int need;
|
||||
register int len;
|
||||
register int oldlength;
|
||||
char *new;
|
||||
char *old;
|
||||
char *oldt;
|
||||
struct tup_id primtid;
|
||||
long primpage;
|
||||
char oldtuple[MAXTUP];
|
||||
extern char *AAgetint_tuple();
|
||||
|
||||
# ifdef xATR1
|
||||
if (AAtTfp(95, 0, "REPLACE: %.14s,", d->reldum.relid))
|
||||
{
|
||||
AAdumptid(tid);
|
||||
printf("REPLACE: ");
|
||||
AAprtup(d, tuple);
|
||||
}
|
||||
# endif
|
||||
|
||||
/* make tuple canonical */
|
||||
need = AAcanonical(d, tuple);
|
||||
|
||||
/* if heap, no dup checking */
|
||||
if (abs(ctoi(d->reldum.relspec)) == M_HEAP)
|
||||
checkdups = FALSE;
|
||||
|
||||
if (i = AAgetpage(d, tid))
|
||||
return (i); /* fatal error */
|
||||
|
||||
/* check if tid exists */
|
||||
if (i = AAinvalid(tid))
|
||||
return (i); /* already deleted or AAinvalid */
|
||||
|
||||
oldt = AAgetint_tuple(d, tid, oldtuple);
|
||||
oldlength = AAtup_len(tid);
|
||||
|
||||
/* check whether tuples are the same, different lengths, different keys */
|
||||
same = DIFFTUP; /* assume diff lengths or keys */
|
||||
if (oldlength == need)
|
||||
{
|
||||
/* same size. check for same domains */
|
||||
same = SAMETUP; /* assume identical */
|
||||
new = tuple;
|
||||
old = oldt;
|
||||
for (i = 1; i <= d->reldum.relatts; i++)
|
||||
{
|
||||
len = ctou(d->relfrml[i]);
|
||||
if (AAicompare(new, old, d->relfrmt[i], len))
|
||||
{
|
||||
if (d->relxtra[i])
|
||||
{
|
||||
same = DIFFTUP;
|
||||
break;
|
||||
}
|
||||
same = SAMEKEYS;
|
||||
}
|
||||
old += len;
|
||||
new += len;
|
||||
}
|
||||
}
|
||||
|
||||
# ifdef xATR2
|
||||
AAtTfp(95, 1, "REPLACE: same=%d\n", same);
|
||||
# endif
|
||||
|
||||
switch (same)
|
||||
{
|
||||
case SAMETUP: /* new tuple same as old tuple */
|
||||
i = 1; /* flag as duplicate */
|
||||
/* though character strings may compare equal,
|
||||
** they can look different, so if they do look different
|
||||
** go ahead and do the replace using AAput_tuple. */
|
||||
if (!AAbequal(tuple, oldt, d->reldum.relwid))
|
||||
goto puttuple;
|
||||
break;
|
||||
|
||||
case SAMEKEYS: /* keys the same, lengths the same, tuples different */
|
||||
if (checkdups)
|
||||
{
|
||||
/* This is either an ISAM or HASH file. If mainpg
|
||||
** is non-zero, then the primary page = mainpg - 1.
|
||||
** Otherwise, "find" must be called to determine
|
||||
** the primary page
|
||||
*/
|
||||
if (AAcc_head->mainpg)
|
||||
{
|
||||
primpage = AAcc_head->mainpg - 1;
|
||||
AAstuff_page(&primtid, &primpage);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i = AAam_find(d, FULLKEY, &primtid, &primtid, tuple))
|
||||
return (i); /* fatal error */
|
||||
if (i = AAgetpage(d, tid)) /* restore page for tuple */
|
||||
return (i);
|
||||
}
|
||||
|
||||
if (i = AAscan_dups(d, &primtid, tuple))
|
||||
{
|
||||
if (i == 1)
|
||||
{
|
||||
AAdel_tuple(tid, oldlength); /* tuple a duplicate */
|
||||
d->reladds--;
|
||||
/* copy tid of duplicate tuple */
|
||||
AAbmove(&primtid, tid, sizeof(primtid));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
goto puttuple;
|
||||
|
||||
case DIFFTUP: /* keys different or lengths different */
|
||||
AAdel_tuple(tid, oldlength);
|
||||
|
||||
/* find where to put tuple */
|
||||
if (i = AAfindbest(d, tid, tuple, need, checkdups))
|
||||
{
|
||||
d->reladds--;
|
||||
break;
|
||||
}
|
||||
|
||||
/* place new tuple in page */
|
||||
puttuple:
|
||||
AAput_tuple(tid, AAcctuple, need);
|
||||
i = 0;
|
||||
}
|
||||
|
||||
# ifdef xATR1
|
||||
if (AAtTfp(95, 2, "REPLACE: rets %d,", i))
|
||||
AAdumptid(tid);
|
||||
# endif
|
||||
|
||||
return (i);
|
||||
}
|
||||
Loading…
Reference in New Issue