recs.c
来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 685 行 · 第 1/2 页
C
685 行
/*************************************************************************** * * * db.* * * open source database kernel * * * * Copyright (c) 2000 Centura Software Corporation. All rights reserved. * * * * Use of this software, whether in source code format, or in executable, * * binary object code form, is governed by the CENTURA OPEN SOURCE LICENSE * * which is fully described in the LICENSE.TXT file, included within this * * distribution of source code files. * * * **************************************************************************/#include "db.star.h"/* ====================================================================== Find first record of type*/int INTERNAL_FCN drecfrst(int rec, DB_TASK *task, int dbn){ short rectype; FILE_NO ftype; DB_ADDR dba; char *recptr; int dbopen_sv; F_ADDR rno, last; RECORD_ENTRY *rec_ptr; if (nrec_check(rec, &rec, &rec_ptr, task) != S_OKAY) return (task->db_status); rec -= task->curr_db_table->rt_offset; /* get the normalized number of file containing this record type */ ftype = (short) NUM2EXT(rec_ptr->rt_file, ft_offset); if ((last = dio_pznext(rec_ptr->rt_file, task)) <= 0) return (task->db_status); rno = 1; do { /* make sure we haven't gone past the end of the file */ if (rno >= last) return (task->db_status = S_NOTFOUND); /* create the database address to read */ ENCODE_DBA(ftype, rno, &dba); /* set up to allow unlocked read */ dbopen_sv = task->dbopen; task->dbopen = 2; /* read the record */ dio_read(dba, &recptr, NOPGHOLD, task); task->dbopen = dbopen_sv; if (task->db_status != S_OKAY) return (task->db_status); /* get the record type out of the record */ memcpy(&rectype, recptr, sizeof(short)); if (dio_release(dba, NOPGFREE, task) != S_OKAY) return (task->db_status); rectype &= ~RLBMASK; ++rno; } while ((int) rectype != rec); /* set the current record and type */ task->curr_rec = dba; task->curr_rn_table->rn_type = rectype; task->curr_rn_table->rn_dba = dba; /* set timestamp */ if (task->db_tsrecs) dutscr(&task->cr_time, task, dbn);#if 0#ifndef QNX if (task->dbopen == 1 && (task->lockMgrComm == LMC_TCP || task->lockMgrComm == LMC_GENERAL) && !task->app_locks[rec_ptr->rt_file] && !task->excl_locks[rec_ptr->rt_file] && !(task->file_table[rec_ptr->rt_file].ft_flags & STATIC)) dio_close(rec_ptr->rt_file, task);#endif#endif return (task->db_status);}/* ====================================================================== d_reclast - find last record occurance in database*/int INTERNAL_FCN dreclast(int rec, DB_TASK *task, int dbn){ DB_ADDR dba; /* current database addr we're scanning */ FILE_NO ftype; /* file desc for file holding rec */ F_ADDR last; /* last slot in file */ char *recptr; /* record from database */ RECORD_ENTRY *rec_ptr; /* RECORD ENTRY for this record */ short rectype; /* record type from record */ F_ADDR rno; /* current slot we're scanning */ int dbopen_sv; /* saved copy of task->dbopen */ /* validate and convert record number */ if (nrec_check(rec, &rec, &rec_ptr, task) != S_OKAY) return (task->db_status); rec -= task->curr_db_table->rt_offset; /* get the last record # for this file */ ftype = (short) NUM2EXT(rec_ptr->rt_file, ft_offset); if ((last = dio_pznext(rec_ptr->rt_file, task)) <= 0) return (task->db_status); /* start at the end, working backwards, find a matching record */ rno = last - 1; do { if (rno < 1) return (task->db_status = S_NOTFOUND); /* create the database address, and read this record */ ENCODE_DBA(ftype, rno, &dba); dbopen_sv = task->dbopen; task->dbopen = 2; /* setup to allow unlocked read */ dio_read(dba, &recptr, NOPGHOLD, task); task->dbopen = dbopen_sv; if (task->db_status != S_OKAY) return (task->db_status); /* See if this record is of the type we're looking for */ memcpy(&rectype, recptr, sizeof(short)); if (dio_release(dba, NOPGFREE, task) != S_OKAY) return (task->db_status); rectype &= ~((short) RLBMASK); /* remove rlb */ rno--; } while ((int) rectype != rec); /* when we get here, we know a match was found */ task->curr_rec = dba; /* set current record */ task->curr_rn_table->rn_type = rectype;/* setup for future recprev,recnext */ task->curr_rn_table->rn_dba = dba; /* set timestamp */ if (task->db_tsrecs) dutscr(&task->cr_time, task, dbn);#if 0#ifndef QNX if (task->dbopen == 1 && (task->lockMgrComm == LMC_TCP || task->lockMgrComm == LMC_GENERAL) && !task->app_locks[rec_ptr->rt_file] && !task->excl_locks[rec_ptr->rt_file] && !(task->file_table[rec_ptr->rt_file].ft_flags & STATIC)) dio_close(rec_ptr->rt_file, task);#endif#endif return (task->db_status);}/* ====================================================================== Find next record of type*/int INTERNAL_FCN drecnext(DB_TASK *task, int dbn){ short rectype; short fno; FILE_NO ft; DB_ADDR dba; int dbopen_sv; int rec_ndx; /* Index into record table */ RN_ENTRY *rn_entry; RECORD_ENTRY *rec_ptr; /* Pointer to record table */ char *recptr; DB_ULONG rno, last; /* look for the current record type */ rn_entry = task->curr_rn_table; if (rn_entry->rn_type < 0) return (dberr(S_NOTYPE)); /* get the record number and file number from the current record */ if (rn_entry->rn_dba) DECODE_DBA(rn_entry->rn_dba, &fno, &rno) else { /* No current rec - get fno from rn_type */ nrec_check(rn_entry->rn_type + RECMARK, &rec_ndx, &rec_ptr, task); fno = (FILE_NO) NUM2EXT(rec_ptr->rt_file, ft_offset); rno = 1; } ft = (FILE_NO) NUM2INT(fno, ft_offset); /* start looking at the next record number */ if ((last = dio_pznext(ft, task)) <= 0) return (task->db_status); ++rno; do { /* make sure we haven't gone past the end of the file */ if (rno >= last) { rn_entry->rn_dba = NULL_DBA; /* set to wrap to beginning */ return (task->db_status = S_NOTFOUND); } /* create the database address to read */ ENCODE_DBA(fno, rno, &dba); /* set up to allow unlocked read */ dbopen_sv = task->dbopen; task->dbopen = 2; /* read the record */ dio_read(dba, &recptr, NOPGHOLD, task); task->dbopen = dbopen_sv; if (task->db_status != S_OKAY) return (task->db_status); /* get the record type out of the record */ memcpy(&rectype, recptr, sizeof(short)); if (dio_release(dba, NOPGFREE, task) != S_OKAY) return (task->db_status); rectype &= ~RLBMASK; ++rno; } while (rectype != rn_entry->rn_type); /* set the current record */ task->curr_rec = dba; rn_entry->rn_type = rectype; rn_entry->rn_dba = dba; /* set timestamp */ if (task->db_tsrecs) dutscr(&task->cr_time, task, dbn);#if 0#ifndef QNX if (task->dbopen == 1 && (task->lockMgrComm == LMC_TCP || task->lockMgrComm == LMC_GENERAL) && !task->app_locks[ft] && !task->excl_locks[ft] && !(task->file_table[ft].ft_flags & STATIC)) dio_close(ft, task);#endif#endif return (task->db_status);}/* ====================================================================== d_recprev - find previous record via database address*/int INTERNAL_FCN drecprev(DB_TASK *task, int dbn){ DB_ADDR dba; /* current database addr we're scanning */ short fno; /* current file we're scanning */ DB_ULONG last; /* last slot in file */ int rec_ndx; /* index of RECORD ENTRY (not used) */ char *recptr; /* record from database */ RN_ENTRY *rn_entry; RECORD_ENTRY *rec_ptr; /* RECORD ENTRY for this record */ short rectype; /* record type from record */ DB_ULONG rno; /* current slot we're scanning */#if 0#ifndef QNX FILE_NO ft; /* file table index for record */#endif#endif int dbopen_sv; /* saved copy of task->dbopen */ /* setup current record and file number */ rn_entry = task->curr_rn_table; if (rn_entry->rn_type < 0) return (dberr(S_NOTYPE)); if (rn_entry->rn_dba) { DECODE_DBA(rn_entry->rn_dba, &fno, &rno);#if 0#ifndef QNX ft = NUM2INT(fno, ft_offset);#endif#endif } else { /* no current rec, get fno from rn_type */ nrec_check(rn_entry->rn_type + RECMARK, &rec_ndx, &rec_ptr, task); fno = (FILE_NO) NUM2EXT(rec_ptr->rt_file, ft_offset); /* compute rno as last slot in file */ if ((last = dio_pznext(rec_ptr->rt_file, task)) <= 0) return (task->db_status); rno = last;#if 0#ifndef QNX ft = rec_ptr->rt_file;#endif#endif } /* scan backwards looking for a record of the same type */ rno--; do { if (rno < 1) { rn_entry->rn_dba = NULL_DBA; /* set to wrap to end */ return (task->db_status = S_NOTFOUND); } ENCODE_DBA(fno, rno, &dba); dbopen_sv = task->dbopen; task->dbopen = 2; /* setup to allow for unlocked read */ dio_read(dba, &recptr, NOPGHOLD, task); task->dbopen = dbopen_sv;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?