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