dbcheck.c

来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 2,087 行 · 第 1/5 页

C
2,087
字号
    /* allocate structure for general database structure information */    *ppdb = dbi = (DBINFO *) psp_cGetMemory(sizeof(DBINFO), 0);    if (!dbi)        return (dberr(S_NOMEMORY));    dbi->opts = opts;    if ((status = d_on_opt(NORECOVER, task)) == S_OKAY)    {        /* set the number of virtual memory pages for database cache */        if ((status = d_setpages(opts->numpages, 3, task)) == S_OKAY)        {            /* set the number of open files */            if (opts->numfiles)            {                status = d_setfiles(opts->numfiles, task);            }            if (status == S_OKAY)            {                if ((status = d_on_opt(READNAMES, task)) == S_OKAY)                {                    /* open database in one user mode */                    if ((status = d_open_sg(opts->dbname, DB_TEXT("o"), opts->sg, task)) == S_OKAY)                    {                        /* check for existence of all db files */                        for (i = 0; i < task->size_ft; i++)                        {                            /* if name list was specified, search for name */                            if (opts->nfnames)                            {                                for (j = 0; j < opts->nfnames; j++)                                {                                    if (!psp_fileNameCmp(task->file_table[i].ft_name, opts->fnames[j]))                                        break;                                    con_dbf(filnam, opts->fnames[j], opts->dbname, task->dbfpath, task);                                    if (!psp_fileNameCmp(task->file_table[i].ft_name, filnam))                                        break;                                }                                if (j == opts->nfnames)                                    continue;                            }                            if (opts->ignorekey && task->file_table[i].ft_type == KEY)                                continue;                            vtstrcpy(dbfile, task->file_table[i].ft_name);                            if ((dbf = psp_fileOpen(dbfile, O_RDONLY, 0)) == NULL)                            {                                vftprintf(stderr, DB_TEXT("database file '%s' not found\n"), dbfile);                                return (dberr(S_NOFILE));                            }                            else                                psp_fileClose(dbf);                        }                        /* allocate record/page buffer */                        *ppbuf = (char *) psp_cGetMemory(task->page_size, 0);                        if (*ppbuf == NULL)                            return (dberr(S_NOMEMORY));                        /* allocate structure for error totals */                        dbi->errinfo = (ERRINFO *) psp_cGetMemory(sizeof(ERRINFO), 0);                        if (dbi->errinfo == NULL)                            return (dberr(S_NOMEMORY));                    }                }            }        }    }    return status;}/***************************************************************************    Get the key information in easy-to-access tables*/static int setup_keys(DBINFO *dbi, DB_TASK *task){    int           i, elements, size;    short         fd, r;    REC_KEY_INFO *kip;    FIELD_ENTRY  *kfp;    ERR_FSIZE     errsz;    /* allocate record type indicies */    dbi->keys = (REC_KEY_INFO *) psp_cGetMemory(task->size_rt *            sizeof(REC_KEY_INFO), 0);    if (!dbi->keys)        return (dberr(S_NOMEMORY));    dbi->num_recs = task->size_rt;  /* needed for freeing arrays after the database                                       is closed, when task->size_rt is no longer valid */    /* extract key information */    for (fd = 0; fd < task->size_fd; fd++)    {        kfp = task->field_table + fd;        if (kfp->fd_key != NOKEY)        {            ++(dbi->num_keys);            dbi->keys[kfp->fd_rec].cnt++;        }        /* compute number of array elements */        for (i = 0, elements = 1; i < MAXDIMS && kfp->fd_dim[i]; i++)            elements *= kfp->fd_dim[i];        size = kfp->fd_len / elements;        errsz.fsize = 0;        /* check field size */        switch (kfp->fd_type)        {            case CHARACTER:                if (size != sizeof(char))                    errsz.fsize = size;                break;            case DBADDR:                if (size != sizeof(DB_ADDR))                    errsz.fsize = size;                break;            case LONGINT:                if (size != sizeof(long))                    errsz.fsize = size;                break;            case SHORTINT:                if (size != sizeof(short))                    errsz.fsize = size;                break;            case REGINT:                if (size != sizeof(int))                {                    errsz.fsize = size;                    if (size == sizeof(short))                    {                        /* This database may have been imported from a 16-bit                           platform - treat the field as if it was a short.                        */                        kfp->fd_type = SHORTINT;                    }                }                break;            case WIDECHAR:                if (size != sizeof(wchar_t))                    errsz.fsize = size;                break;            case FLOAT:                if (size != sizeof(float))                    errsz.fsize = size;                break;            case DOUBLE:                if (size != sizeof(double))                    errsz.fsize = size;                break;        }        if (errsz.fsize)        {            errsz.fname = task->field_names[fd];            pr_err(BAD_SIZE, &errsz, dbi, task);        }    }    dbi->key_len = (short *) psp_cGetMemory(dbi->num_keys * sizeof(short), 0);    dbi->key_fld = (short *) psp_cGetMemory(dbi->num_keys * sizeof(short), 0);    if (! dbi->key_len || ! dbi->key_fld)        return (dberr(S_NOMEMORY));    for (r = 0; r < task->size_rt; r++)    {        kip = dbi->keys + r;        if (kip->cnt == 0)            kip->lst = (short *) psp_cGetMemory(sizeof(short), 0);        else            kip->lst = (short *) psp_cGetMemory(kip->cnt * sizeof(short), 0);        if (! kip->lst)            return (dberr(S_NOMEMORY));        kip->lst += kip->cnt;        kip->byt = (short) BITS_TO_BYTES(kip->cnt);    }    for (fd = 0; fd < task->size_fd; fd++)    {        kfp = task->field_table + fd;        if (kfp->fd_key != NOKEY)        {            dbi->key_len[kfp->fd_keyno] = kfp->fd_len;            dbi->key_fld[kfp->fd_keyno] = fd;        }    }    for (fd = (short) (dbi->num_keys - 1); fd >= 0; fd--)    {        r = task->field_table[dbi->key_fld[fd]].fd_rec;        *(--(dbi->keys[r].lst)) = dbi->key_fld[fd];    }    return (S_OKAY);}/*************************************************************************    Get the set information in easy-to-access tables*/static int setup_sets(DBINFO *dbi, DB_TASK *task){    register short          st,                            r,                            i,                            t;    register REC_SET_INFO  *oip,                           *mip;    /* allocate record type indices */    dbi->owners = (REC_SET_INFO *) psp_cGetMemory(task->size_rt *            sizeof(REC_SET_INFO), 0);    dbi->members = (REC_SET_INFO *) psp_cGetMemory(task->size_rt *            sizeof(REC_SET_INFO), 0);    if (!dbi->owners || !dbi->members)        return (dberr(S_NOMEMORY));    /* extract set information */    for (st = 0; st < task->size_st; st++)    {        dbi->owners[task->set_table[st].st_own_rt].cnt++;        for (i = task->set_table[st].st_members;             i < task->set_table[st].st_members + task->set_table[st].st_memtot; i++)        {            dbi->members[task->member_table[i].mt_record].cnt++;        }    }    for (r = 0; r < task->size_rt; r++)    {        oip = dbi->owners + r;        mip = dbi->members + r;        if (oip->cnt == 0)            oip->lst = (SET_INFO *) psp_cGetMemory(sizeof(SET_INFO), 0);        else            oip->lst = (SET_INFO *) psp_cGetMemory(oip->cnt * sizeof(SET_INFO), 0);        if (mip->cnt == 0)            mip->lst = (SET_INFO *) psp_cGetMemory(sizeof(SET_INFO), 0);        else            mip->lst = (SET_INFO *) psp_cGetMemory(mip->cnt * sizeof(SET_INFO), 0);        if (!oip->lst || !mip->lst)            return (dberr(S_NOMEMORY));        t = (short) (REC_KEY(0) + (2 * dbi->keys[r].byt));        for (i = 0; i < oip->cnt; i++, t += (3 * sizeof(long)))            oip->lst[i].sbfoff = t;        for (i = 0; i < mip->cnt; i++, t += (3 * sizeof(long)))            mip->lst[i].mbfoff = t;        oip->lst += oip->cnt;        mip->lst += mip->cnt;    }    for (st = (short) (task->size_st - 1); st >= 0; st--)    {        oip = dbi->owners + task->set_table[st].st_own_rt;        (--oip->lst)->setno = st;        oip->lst->setoff = task->set_table[st].st_own_ptr;        oip->lst->ownrid = task->set_table[st].st_own_rt;        oip->lst->stampd = (short) (task->set_table[st].st_flags & TIMESTAMPED);        for (i = task->set_table[st].st_members;              i < task->set_table[st].st_members + task->set_table[st].st_memtot; i++)        {            mip = dbi->members + task->member_table[i].mt_record;            (--mip->lst)->setno = st;            mip->lst->setoff = task->set_table[st].st_own_ptr;            mip->lst->sbfoff = oip->lst->sbfoff;            mip->lst->ownrid = task->set_table[st].st_own_rt;            mip->lst->memoff = task->member_table[i].mt_mem_ptr;        }    }    return (S_OKAY);}/***************************************************************************    Summarize the easy-to-access tables into still more easy-to-access tables.*/static int setup_tots(DBINFO *dbi, DB_TASK *task){    int            status = S_OKAY;    short          i;    F_ADDR         fileSize,                   pageCount,        /* max pages in file based on size */                   firstSlot,        /* first slot on last page */                   lastSlot;         /* last slot on last page */    ERR_PGZERO     pgz;    FILE_ENTRY    *filePtr;    char           dbd_ver[DBD_COMPAT_LEN + 1];    get_dbd_ver(dbi->opts->dbname, dbd_ver, task);    dbi->tops = (F_ADDR *) psp_cGetMemory(task->size_ft * sizeof(F_ADDR), 0);    if (! dbi->tops)        return (dberr(S_NOMEMORY));    for (i = 0; i < task->size_ft; i++)    {        filePtr = &task->file_table[i];        if ((filePtr->ft_type != DATA) && (filePtr->ft_type != KEY))            return (dberr(S_SYSERR));        if (dbi->opts->ignorekey == TRUE && filePtr->ft_type == KEY)            continue;        /* make sure the nextslot values are reasonable */        dbi->tops[i] = dio_pznext(i, task); /* opens file as side effect! */        /* make sure file is actually open */        if (filePtr->ft_status != OPEN)        {            if ((status = dio_open(i, task)) != S_OKAY)                return (dberr(status));        }        fileSize = psp_fileLength(filePtr->ft_desc);        if (fileSize == (F_ADDR) -1L)            continue;      /* os_filesize failed, assume pageZero is good */        if (filePtr->ft_type == KEY)        {            /* page zero tracks pages not slots for key files */            pageCount = fileSize / filePtr->ft_pgsize - 1;            lastSlot  = pageCount + 1;            firstSlot = lastSlot;        }        else        {            /* page zero tracks slots for data files */            pageCount = fileSize / filePtr->ft_pgsize - 1;            lastSlot = pageCount * filePtr->ft_slots + 1;            firstSlot = pageCount ? lastSlot - filePtr->ft_slots : 0L;        }        if ((dbi->tops[i] < firstSlot) || (dbi->tops[i] > lastSlot))        {            pgz.file = i;            pgz.slot = dbi->tops[i];            if (!strcmp(dbd_ver, dbd_VERSION_300))                pr_err(BAD_NEXTSLOT, &pgz, dbi, task); /* not for v3.01 */                        /* use a best guess */            dbi->tops[i] = min(dbi->tops[i], lastSlot);        }        /* this must be done AFTER the respective dio_pznext() */        lastSlot = task->pgzero[i].pz_dchain;        if (filePtr->ft_type == KEY && lastSlot == DCH_NONE)            lastSlot = 0L;        if (lastSlot >= dbi->tops[i])        {            pgz.file = i;            pgz.slot = lastSlot;            pr_err(BAD_DCHAIN, &pgz, dbi, task);        }    }    return (S_OKAY);}/*************************************************************************    Get the set information in easy to access tables.*/static int setup_cnts(DBINFO *dbi, DB_TASK *task){    if (!dbi->opts->counts)        return (S_OKAY);    dbi->rec_cnt = (F_ADDR *) psp_cGetMemory(task->size_rt * sizeof(F_ADDR), 0);    dbi->set_cnt = (F_ADDR *) psp_cGetMemory(task->size_st * sizeof(F_ADDR), 0);    dbi->key_cnt = (F_ADDR *) psp_cGetMemory(dbi->num_keys * sizeof(F_ADDR), 0);    if (!dbi->rec_cnt || !dbi->set_cnt || !dbi->key_cnt)    {        dbi->opts->counts = FALSE;        vftprintf(stderr,                  DB_TEXT("\n\n*** Insufficient memory for aggregating counts\n"));        return (dberr(S_NOMEMORY));    }    return (S_OKAY);}/***************************************************************************    Setup file names for the temporary files.*/static int setup_temp_files(DBINFO *dbi, DB_TASK *task){    DB_TCHAR path[256];    DB_TCHAR *p;    int len;        if ((dbi->pcache = cache_alloc()) == NULL)        return(dberr(S_NOMEMORY));    path[0] = 0;    p = psp_getenv(DB_TEXT("TMP"));    if (!p)        p = psp_getenv(DB_TEXT("TEMP"));    if (p)    {        vtstrcpy(path, p);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?