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 + -
显示快捷键?