ING_DB
This commit is contained in:
parent
d0d9668d32
commit
b51ff19095
|
|
@ -0,0 +1,240 @@
|
|||
# include "gen.h"
|
||||
# include "../h/dbs.h"
|
||||
# include "../h/access.h"
|
||||
# include "../h/aux.h"
|
||||
# include "../h/lock.h"
|
||||
# include "../h/bs.h"
|
||||
|
||||
/* access method buffers and */
|
||||
/* other data areas for buffer maintenance */
|
||||
static ACCBUF AAcc_buf[NACCBUFS]; /* the buffers */
|
||||
ACCBUF *AAcc_head; /* head of usage list */
|
||||
ACCBUF *AAcc_tail; /* tail of usage list */
|
||||
LOCKREQ AALOCKREQ;
|
||||
|
||||
/* structs for AA_ADMIN file data */
|
||||
struct admin AAdmin;
|
||||
|
||||
/* global flag indicating if access methods */
|
||||
/* have been initialized. */
|
||||
int AAcc_init = FALSE;
|
||||
|
||||
/* dummy procedure for importing AAdmin via ranlib(1) */
|
||||
AACCESS() {};
|
||||
|
||||
/* Flush the indicated page and reset all */
|
||||
/* important information including the name */
|
||||
AAresetacc(b)
|
||||
register ACCBUF *b;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (!b)
|
||||
b = AAcc_head;
|
||||
|
||||
# ifdef xATR3
|
||||
if (AAtTfp(80, 0, "RESETACC: "))
|
||||
AAdumpbuf(b);
|
||||
# endif
|
||||
|
||||
i = AApageflush(b); /* write the page if necessary */
|
||||
b->rel_tupid = -1;
|
||||
b->filedesc = -1;
|
||||
b->thispage = -1;
|
||||
b->bufstatus = 0;
|
||||
return (i);
|
||||
}
|
||||
|
||||
|
||||
/* initialize access method data areas */
|
||||
AAam_start()
|
||||
{
|
||||
register ACCBUF *last;
|
||||
register ACCBUF *b;
|
||||
struct stat stbuf;
|
||||
extern char *AAdbpath;
|
||||
extern int errno;
|
||||
|
||||
# ifdef xATR3
|
||||
AAtTfp(81, 0, "ACC_INIT=%d\n", AAcc_init);
|
||||
# endif
|
||||
|
||||
if (AAcc_init)
|
||||
return; /* already initialized */
|
||||
|
||||
last = (ACCBUF *) 0;
|
||||
for (b = AAcc_buf; b < &AAcc_buf[NACCBUFS]; )
|
||||
{
|
||||
AAresetacc(b);
|
||||
b->modb = last;
|
||||
last = b;
|
||||
b++;
|
||||
last->modf = b;
|
||||
}
|
||||
last->modf = (ACCBUF *) 0;
|
||||
AAcc_head = AAcc_buf;
|
||||
AAcc_tail = last;
|
||||
|
||||
/* get the AA_ADMIN file */
|
||||
AAreadadmin();
|
||||
|
||||
/* Set up locking information. If the database has concurrency */
|
||||
/* control then the concurrency device will */
|
||||
/* be opened for writing. If there is no concurrency for the */
|
||||
/* data base or if the lock device isn't installed, then AAlockdes */
|
||||
/* = -1 and no locking will (or can) occure. */
|
||||
if ((AAdmin.adhdr.adflags & A_DBCONCUR) && AAlockdes < 0)
|
||||
AAlockdes = open(AA_DBS_LOCK, 1);
|
||||
errno = 0; /* clear in case AA_DBS_LOCK isn't available */
|
||||
AAcclock = TRUE;
|
||||
stat(AAdbpath? AAdbpath: ".", &stbuf);
|
||||
AAbmove(&stbuf, &AALOCKREQ.l_db, sizeof (long));
|
||||
AALOCKREQ.l_pid = getpid();
|
||||
|
||||
AAcc_init = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* place buffer at top of LRU list */
|
||||
AAtop_acc(b)
|
||||
register ACCBUF *b;
|
||||
{
|
||||
if (b == AAcc_head)
|
||||
return;
|
||||
|
||||
if (b == AAcc_tail)
|
||||
AAcc_tail = b->modb;
|
||||
else
|
||||
b->modf->modb = b->modb;
|
||||
b->modb->modf = b->modf;
|
||||
AAcc_head->modb = b;
|
||||
b->modf = AAcc_head;
|
||||
AAcc_head = b;
|
||||
b->modb = (ACCBUF *) 0;
|
||||
|
||||
# ifdef xATR3
|
||||
if (AAtTfp(80, 0, "TOP_ACC: "))
|
||||
AAdumpbuf(b);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
/* AAam_flush_rel -- flush all pages associated with the relation */
|
||||
/* described by the descriptor. If resetflag is TRUE, */
|
||||
/* then the buffers are reset so the pages will not be */
|
||||
/* found on subsequent calls to AAfind_page(). */
|
||||
/* Returns "or'ed" result from calls to AApageflush. */
|
||||
AAam_flush_rel(d, resetflag)
|
||||
register DESC *d;
|
||||
int resetflag;
|
||||
{
|
||||
register ACCBUF *b;
|
||||
register int i;
|
||||
|
||||
if (d->reldum.relock[0] & R_LOCKED)
|
||||
AAunlrl(d->reltid);
|
||||
for (i = 0, b = AAcc_head; b; b = b->modf)
|
||||
if (d->reltid == b->rel_tupid)
|
||||
i |= resetflag? AAresetacc(b): AApageflush(b);
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
|
||||
/* AAchoose_buf -- Try to find an empty buffer for assignment. */
|
||||
/* If there is no empty buffer, pick the last buffer */
|
||||
/* in the LRU queue and make sure it is flushed. */
|
||||
/* AAchoose_buf guarantees that the buffer will be reset */
|
||||
/* if it was used previously for a different relation. */
|
||||
/* */
|
||||
/* AAchoose_buf -- choose a buffer for use with the given relation on */
|
||||
/* the given page. If a relation does not have a buffer, it */
|
||||
/* is given a free one (if any) or else the Least Recently Used. */
|
||||
ACCBUF *AAchoose_buf(d, pageid)
|
||||
register DESC *d;
|
||||
long pageid;
|
||||
{
|
||||
register ACCBUF *b;
|
||||
register ACCBUF *free;
|
||||
# ifdef xATR3
|
||||
register ACCBUF *mine;
|
||||
|
||||
mine = (ACCBUF *) 0;
|
||||
# endif
|
||||
for (free = (ACCBUF *) 0, b = AAcc_head; b; b = b->modf)
|
||||
{
|
||||
if (b->rel_tupid == -1)
|
||||
free = b;
|
||||
else if (d->reltid == b->rel_tupid)
|
||||
{
|
||||
if (pageid == b->thispage)
|
||||
{
|
||||
if (d->relopn < 0)
|
||||
b->filedesc = d->relfp;
|
||||
return (b);
|
||||
}
|
||||
# ifdef xATR3
|
||||
mine = b;
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
# ifdef xATR3
|
||||
/* "Free" and "Mine" now reflect the current state of the buffers. */
|
||||
/* There is no buffer with the currently requested page */
|
||||
AAtTfp(82, 9, "CHOOSEBUF free 0%o,mine 0%o\n", free, mine);
|
||||
# endif
|
||||
|
||||
/* no current buffer. Choose a free one or LRU */
|
||||
if (!free) /* error if can't reset the LRU */
|
||||
free = AAresetacc(AAcc_tail)? (ACCBUF *) 0: AAcc_tail;
|
||||
if (free)
|
||||
{
|
||||
/* copy relevent material (in this order in case of rubout */
|
||||
free->filedesc = d->relfp;
|
||||
free->rel_tupid = d->reltid;
|
||||
}
|
||||
|
||||
# ifdef xATR1
|
||||
AAtTfp(82, 8, "CHOOSEBUF: rets 0%o\n", free);
|
||||
# endif
|
||||
|
||||
return (free);
|
||||
}
|
||||
|
||||
|
||||
/* AAam_exit -- flush any buffers left around */
|
||||
/* and then close the files for relation & attribute. */
|
||||
/* The relation and attribute relation are normally left open */
|
||||
/* until the end of an DBS session but must be closed */
|
||||
/* and re-opened in the dbu's whenever a new overlay is loaded. */
|
||||
AAam_exit()
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (i = AApageflush((ACCBUF *) 0))
|
||||
AAsyserr(10000, i);
|
||||
close(AAdmin.adreld.relfp);
|
||||
close(AAdmin.adattd.relfp);
|
||||
AAdmin.adreld.relopn = AAdmin.adattd.relopn = 0;
|
||||
if (AAlockdes >= 0)
|
||||
close(AAlockdes);
|
||||
AAlockdes = -1;
|
||||
AAcc_init = FALSE;
|
||||
sync();
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
AAdumpbuf(buf)
|
||||
register ACCBUF *buf;
|
||||
{
|
||||
printf("page# %ld, bufstatus 0%o, filedesc %u, rel_",
|
||||
buf->thispage, buf->bufstatus, buf->filedesc);
|
||||
AAdumptid(&buf->rel_tupid);
|
||||
printf("mainpg %ld, ovflpg %ld, nxtlino 0%o, free 0%o\n",
|
||||
buf->mainpg, buf->ovflopg, buf->nxtlino,
|
||||
buf->linetab[LINETAB(buf->nxtlino)]);
|
||||
printf("(HEAD 0%o) 0%o <- 0%o -> 0%o (0%o TAIL)\n",
|
||||
AAcc_head, buf->modb, buf, buf->modf, AAcc_tail);
|
||||
}
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
# include "gen.h"
|
||||
# include "../h/dbs.h"
|
||||
# include "../h/aux.h"
|
||||
# include "../h/access.h"
|
||||
# include "../h/lock.h"
|
||||
|
||||
/*
|
||||
** AArelopen -- Open a relation into a descriptor
|
||||
**
|
||||
** AArelopen will open the named relation into the given descriptor
|
||||
** according to the mode specified. When searching for a name,
|
||||
** a relation owner by the current user will be searched for first.
|
||||
** If none is found then one owned by the DBA will be search for.
|
||||
**
|
||||
** There are several available modes for opening a relation. The
|
||||
** most common are
|
||||
** mode 0 -- open for reading
|
||||
** mode 2 -- open for writing (mode 1 works identically).
|
||||
** Other modes which can be used to optimize performance:
|
||||
** mode -1 -- get catalog AA_REL tuple and tid only.
|
||||
** Does not open the relation.
|
||||
** mode -2 -- open relation for reading after a previous
|
||||
** call of mode -1.
|
||||
** mode -3 -- open relation for writing after a previous
|
||||
** call of mode -1.
|
||||
** mode -4 -- open relation for reading. Assumes that relation
|
||||
** was previously open (eg relation & attributed
|
||||
** have been filled) and file was closed by AArelclose.
|
||||
** mode -5 -- open relation for writing. Same assumptions as
|
||||
** mode -4.
|
||||
**
|
||||
** Parameters:
|
||||
** d - a pointer to a DESC (defined in dbs.h)
|
||||
** mode - can be 2, 0, -1, -2, -3, -4, -5
|
||||
** name - a null terminated name (only first 12 chars looked at)
|
||||
**
|
||||
** Returns:
|
||||
** 1 - relation does not exist
|
||||
** 0 - ok
|
||||
** <0 - error. Refer to the error codes in access.h
|
||||
**
|
||||
** Side Effects:
|
||||
** Opens the physical file if required. Fill the
|
||||
** descriptor structure. Initializes the access methods
|
||||
** if necessary.
|
||||
*/
|
||||
AArelopen(d, mode, name)
|
||||
register DESC *d;
|
||||
int mode;
|
||||
char *name;
|
||||
{
|
||||
register int retval;
|
||||
register int filemode;
|
||||
char filename[MAXNAME + 3];
|
||||
extern char *AArelpath();
|
||||
|
||||
# ifdef xATR1
|
||||
AAtTfp(90, -1, "OPENR: %.12s,%d\n", name, mode);
|
||||
# endif
|
||||
# ifdef xATM
|
||||
if (AAtTf(76, 2))
|
||||
timtrace(21, 0);
|
||||
# endif
|
||||
|
||||
AAam_start();
|
||||
|
||||
/* process according to mode */
|
||||
filemode = 0;
|
||||
switch (mode)
|
||||
{
|
||||
case -1:
|
||||
retval = AAgetrel_tuple(d, name);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case 2:
|
||||
filemode = 2;
|
||||
|
||||
case 0:
|
||||
if (retval = AAgetrel_tuple(d, name))
|
||||
break;
|
||||
|
||||
case -2:
|
||||
case -3:
|
||||
if (retval = AAgetatt_tuples(d))
|
||||
break;
|
||||
|
||||
case -5:
|
||||
if (mode == -3 || mode == -5)
|
||||
filemode = 2;
|
||||
|
||||
case -4:
|
||||
AAam_clearkeys(d);
|
||||
/* descriptor is filled. open file */
|
||||
AAdbname(d->reldum.relid, d->reldum.relowner, filename);
|
||||
/* can't open a view */
|
||||
if (d->reldum.relstat & S_VIEW)
|
||||
{
|
||||
retval = AAam_error(AMOPNVIEW_ERR); /* view */
|
||||
break;
|
||||
}
|
||||
if ((d->relfp = open(AArelpath(filename), filemode)) < 0)
|
||||
{
|
||||
retval = AAam_error(AMNOFILE_ERR); /* can't open file */
|
||||
break;
|
||||
}
|
||||
if (filemode == 2)
|
||||
{
|
||||
d->relopn = RELWOPEN(d->relfp);
|
||||
d->reldum.relock[1] = P_EXCL;
|
||||
}
|
||||
else
|
||||
{
|
||||
d->relopn = RELROPEN(d->relfp);
|
||||
d->reldum.relock[1] = P_SHR;
|
||||
}
|
||||
d->reldum.relock[0] = d->reldum.relock[1];
|
||||
d->reladds = 0;
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
AAsyserr(10017, mode, name);
|
||||
}
|
||||
|
||||
# ifdef xATR1
|
||||
if (AAtTf(90, 4) && mode != -1 && retval != 1)
|
||||
AAprdesc(d);
|
||||
AAtTfp(90, -1, "OPENR: rets %d\n", retval);
|
||||
# endif
|
||||
# ifdef xATM
|
||||
if (AAtTf(76, 2))
|
||||
timtrace(22, 0);
|
||||
# endif
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** AAgetrel_tuple
|
||||
** Get the tuple for the relation specified by 'name'
|
||||
** and put it in the descriptor 'd'.
|
||||
**
|
||||
** First a relation named 'name' owned
|
||||
** by the current user is searched for. If that fails,
|
||||
** then a relation owned by the dba is searched for.
|
||||
*/
|
||||
AAgetrel_tuple(d, name)
|
||||
register DESC *d;
|
||||
register char *name;
|
||||
{
|
||||
register int i;
|
||||
struct relation rel;
|
||||
|
||||
AAam_clearkeys(&AAdmin.adreld);
|
||||
|
||||
/* make believe catalog AA_REL is read only for concurrency */
|
||||
/* that means, readed pages are not locked */
|
||||
AAdmin.adreld.relopn = RELROPEN(AAdmin.adreld.relfp);
|
||||
|
||||
/* catalog AA_REL is open. Search for relation 'name' */
|
||||
AAam_setkey(&AAdmin.adreld, &rel, name, RELID);
|
||||
AAam_setkey(&AAdmin.adreld, &rel, AAusercode, RELOWNER);
|
||||
|
||||
if ((i = AAgetequal(&AAdmin.adreld, &rel, d, &d->reltid)) == 1)
|
||||
{
|
||||
/* not a user relation. try relation owner by dba */
|
||||
AAam_setkey(&AAdmin.adreld, &rel, AAdmin.adhdr.adowner, RELOWNER);
|
||||
i = AAgetequal(&AAdmin.adreld, &rel, d, &d->reltid);
|
||||
}
|
||||
|
||||
/* free all buffers connected with catalog AA_REL */
|
||||
AAam_flush_rel(&AAdmin.adreld, TRUE);
|
||||
|
||||
# ifdef xATR1
|
||||
AAtTfp(90, 1, "GET_RELTUPLE: %d\n", i);
|
||||
# endif
|
||||
|
||||
/* restore catalog AA_REL to read/write mode */
|
||||
AAdmin.adreld.relopn = RELWOPEN(AAdmin.adreld.relfp);
|
||||
return (i);
|
||||
}
|
||||
|
||||
|
||||
AAgetatt_tuples(d)
|
||||
register DESC *d;
|
||||
{
|
||||
register int i;
|
||||
register int dom;
|
||||
register int numatts;
|
||||
struct attribute attr;
|
||||
struct attribute attkey;
|
||||
struct tup_id tid1;
|
||||
struct tup_id tid2;
|
||||
|
||||
AAam_clearkeys(&AAdmin.adattd);
|
||||
|
||||
/* zero all format types */
|
||||
for (i = 0; i <= d->reldum.relatts; i++)
|
||||
d->relfrmt[i] = 0;
|
||||
|
||||
/* prepare to scan attribute relation */
|
||||
AAam_setkey(&AAdmin.adattd, &attkey, d->reldum.relid, ATTRELID);
|
||||
AAam_setkey(&AAdmin.adattd, &attkey, d->reldum.relowner, ATTOWNER);
|
||||
if (i = AAam_find(&AAdmin.adattd, EXACTKEY, &tid1, &tid2, &attkey))
|
||||
return (i);
|
||||
|
||||
numatts = d->reldum.relatts;
|
||||
|
||||
while (numatts && !AAam_get(&AAdmin.adattd, &tid1, &tid2, &attr, TRUE))
|
||||
{
|
||||
/* does this attribute belong? */
|
||||
if (AAbequal(&attr, &attkey, MAXNAME + 2))
|
||||
{
|
||||
/* this attribute belongs */
|
||||
dom = attr.attid; /* get domain number */
|
||||
|
||||
if (d->relfrmt[dom])
|
||||
break; /* duplicate attribute. force error */
|
||||
|
||||
numatts--;
|
||||
d->reloff[dom] = attr.attoff;
|
||||
d->relfrmt[dom] = attr.attfrmt;
|
||||
d->relfrml[dom] = attr.attfrml;
|
||||
d->relxtra[dom] = attr.attxtra;
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure all the atributes were there */
|
||||
for (dom = 1; dom <= d->reldum.relatts; dom++)
|
||||
if (!d->relfrmt[dom])
|
||||
numatts = 1; /* force an error */
|
||||
if (numatts)
|
||||
i = AAam_error(AMNOATTS_ERR);
|
||||
|
||||
AAam_flush_rel(&AAdmin.adattd, TRUE);
|
||||
|
||||
# ifdef xATR1
|
||||
AAtTfp(90, 3, "GET_ATTR: ret %d\n", i);
|
||||
# endif
|
||||
|
||||
return (i);
|
||||
}
|
||||
Loading…
Reference in New Issue