recfcns.c

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

C
758
字号
/*************************************************************************** *                                                                         * * 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"/* ======================================================================    Check a field for permission to change it*/int INTERNAL_FCN r_chkfld(    short         field,     /* task->field_table entry number */    FIELD_ENTRY  *fld_ptr,   /* corresponds to field */    char         *rec,       /* pointer to record slot */    const char   *data,      /* ptr to data area containing fld contents */    DB_TASK      *task){    DB_ADDR       dba;    long          fld;    short         rn;    char         *fptr;    char          ckey[MAXKEYSIZE];    short         i;    FIELD_ENTRY  *sfld_ptr;    RECORD_ENTRY *rec_ptr;    int           cmp;    memcpy(&rn, rec, sizeof(short));    rn &= ~RLBMASK;                     /* mask off rlb */    if (rn != NUM2EXT(fld_ptr->fd_rec, rt_offset))        return (dberr(S_INVFLD));    rec_ptr = &task->record_table[fld_ptr->fd_rec];    fld = FLDMARK * rn + field - rec_ptr->rt_fields;    if (fld_ptr->fd_type == COMKEY)    {        /* build compound key value. NOTE: cflag MUST be the same here as           for the call to key_bldcom in recwrite, which calls this           function.        */        fptr = rec + rec_ptr->rt_data;        key_bldcom(field, fptr, ckey, FALSE, task);        fptr = ckey;    }    else        fptr = rec + fld_ptr->fd_ptr;    /* do nothing unless the new value is different */    if (fld_ptr->fd_key != NOKEY)        cmp = fldcmp(fld_ptr, data, fptr, task);    else if (fld_ptr->fd_type == CHARACTER && fld_ptr->fd_dim[1] == 0)        cmp = strncmp(data, fptr, fld_ptr->fd_len);    else if (fld_ptr->fd_type == WIDECHAR && fld_ptr->fd_dim[1] == 0)    {        cmp = vwcsncmp((const wchar_t *)data, (const wchar_t *)fptr,              fld_ptr->fd_len / sizeof(wchar_t));    }    else        cmp = memcmp(data, fptr, fld_ptr->fd_len);    if (cmp == 0)        return (task->db_status);    /* if this is a unique key field, make sure the key does not       already exist    */    if (fld_ptr->fd_key == UNIQUE)    {        dba = task->curr_rec;        /* If the key field is not optional, or optional and stored */        if (!(fld_ptr->fd_flags & OPTKEYMASK) || r_tstopt(fld_ptr, rec, task))        {            if (dkeyfind(fld, data, task, task->curr_db) == S_OKAY)            {                /* another record is already using this key value */                task->db_status = S_DUPLICATE;            }            else if (task->db_status == S_NOTFOUND)                task->db_status = S_OKAY;        }        task->curr_rec = dba;        if (task->db_status == S_DUPLICATE)            return task->db_status;    }    /* if field is grouped, call r_chkfld for 1st entry of each sub-field */    if (fld_ptr->fd_type == GROUPED)    {        for ( i = (short) (field + 1), sfld_ptr = fld_ptr + 1;              (i < task->size_fd) && (sfld_ptr->fd_flags & STRUCTFLD);              ++i, ++sfld_ptr)        {            fptr = (char *) data + (sfld_ptr->fd_ptr - fld_ptr->fd_ptr);            if (r_chkfld(i, sfld_ptr, rec, fptr, task) != S_OKAY)                return task->db_status;        }    }    return (task->db_status);}/* ======================================================================    Delete the current record*/int INTERNAL_FCN r_delrec(    short    rt,               /* record table index */    DB_ADDR  db_addr,    DB_TASK *task){    char         *rec;                   /* ptr to record slot */    char         *fptr;                  /* field data ptr */    char          ckey[MAXKEYSIZE];      /* compound key data */    DB_ULONG      timestamp;    short         fno;    DB_ULONG      rno;    int           stat;    int           fld;    RECORD_ENTRY *rec_ptr;    FIELD_ENTRY  *fld_ptr;    if (dio_read(db_addr, &rec, PGHOLD, task) != S_OKAY)        return task->db_status;    rec_ptr = &task->record_table[rt];    /* remove any key fields from the key files */    for ( fld = rec_ptr->rt_fields, fld_ptr = &task->field_table[fld];          (fld < task->size_fd) && (fld_ptr->fd_rec == rt);          ++fld, ++fld_ptr)    {        if (fld_ptr->fd_key == NOKEY)            continue;        if (fld_ptr->fd_type == COMKEY)        {            key_bldcom(fld, rec + rec_ptr->rt_data, ckey, TRUE, task);            fptr = ckey;        }        else            fptr = rec + fld_ptr->fd_ptr;        /* delete the key if it exists */        if ((!(fld_ptr->fd_flags & OPTKEYMASK) || r_tstopt(fld_ptr, rec, task)) &&            key_delete(fld, fptr, db_addr, task) != S_OKAY)        {            stat = task->db_status;            if (dio_release(db_addr, PGFREE, task) != S_OKAY)                return task->db_status;            return (task->db_status = stat);        }    }    DECODE_DBA(db_addr, &fno, &rno);    fno = (FILE_NO) NUM2INT(fno, ft_offset);    /* update timestamp, if necessary */    if (rec_ptr->rt_flags & TIMESTAMPED)    {        timestamp = dio_pzgetts(fno, task);        memcpy(rec + RECCRTIME, &timestamp, sizeof(DB_ULONG));        memcpy(rec + RECUPTIME, &timestamp, sizeof(DB_ULONG));    }    if (dio_write(db_addr, PGFREE, task) != S_OKAY)        return task->db_status;    /* place this record onto the delete chain */    dio_pzdel(fno, rno, task);    return task->db_status;}/* ======================================================================    Get data field from record*/int INTERNAL_FCN r_gfld(    FIELD_ENTRY     *fld_ptr,    char            *rec,    char            *data,    DB_TASK *task){    short        rn;    int          kt_lc;      /* loop control */    FIELD_ENTRY *kfld_ptr;    KEY_ENTRY   *key_ptr;    memcpy(&rn, rec, sizeof(short));    if (rn < 0)        return (task->db_status = S_DELETED);    if (rn & RLBMASK)    {        rn &= ~RLBMASK;                  /* mask off rlb */        task->rlb_status = S_LOCKED;    }    else        task->rlb_status = S_UNLOCKED;    rn += task->curr_db_table->rt_offset;    if (fld_ptr->fd_rec != rn)        return (dberr(S_INVFLD));    switch (fld_ptr->fd_type)    {        case COMKEY:            /* clear compound key data area */            memset(data, '\0', fld_ptr->fd_len);            /* copy each field of compound key to data area */            for ( kt_lc = task->size_kt - fld_ptr->fd_ptr,                  key_ptr = &task->key_table[fld_ptr->fd_ptr]; (--kt_lc >= 0) &&                  (&task->field_table[key_ptr->kt_key] == fld_ptr); ++key_ptr)            {                kfld_ptr = &task->field_table[key_ptr->kt_field];                memcpy(data + key_ptr->kt_ptr, rec + kfld_ptr->fd_ptr,                          kfld_ptr->fd_len);            }            break;        default:            memcpy(data, rec + fld_ptr->fd_ptr, fld_ptr->fd_len);            break;    }    return (task->db_status);}/* ======================================================================    Get member pointer from record*/int INTERNAL_FCN r_gmem(    int      set,       /* set table entry number */    char    *rec,       /* pointer to record */    MEM_PTR *mem_addr,  /* pointer to member pointer */    DB_TASK *task){    short         rt;    int           mem;    int           memtot;    SET_ENTRY    *set_ptr;    MEMBER_ENTRY *mem_ptr;    /* search member list of set for record */    set_ptr = &task->set_table[set];    memcpy(&rt, rec, sizeof(short));    rt &= ~RLBMASK;    for ( mem = set_ptr->st_members, memtot = mem + set_ptr->st_memtot,          mem_ptr = &task->member_table[mem]; mem < memtot; ++mem, ++mem_ptr)    {        if (NUM2EXT(mem_ptr->mt_record, rt_offset) == rt)        {            /* have found correct member record */            memcpy(mem_addr, rec + mem_ptr->mt_mem_ptr, MEMPSIZE);            return (task->db_status);        }    }    /* this record is not member of set */    return (dberr(S_INVMEM));}/* ======================================================================    Get set pointer from record*/int INTERNAL_FCN r_gset(    int      set,         /* set table entry number */    char    *rec,         /* pointer to record */    SET_PTR *setptr,      /* pointer to set pointer */    DB_TASK *task){    short      rt;    int        len;    SET_ENTRY *set_ptr;    set_ptr = &task->set_table[set];    memcpy(&rt, rec, sizeof(short));    if (NUM2EXT(set_ptr->st_own_rt, rt_offset) == (rt & ~RLBMASK))    {        if (set_ptr->st_flags & TIMESTAMPED)            len = SETPSIZE;        else            len = SETPSIZE - sizeof(DB_ULONG);        memcpy(setptr, rec + set_ptr->st_own_ptr, len);        return (task->db_status);    }    return (dberr(S_INVOWN));}/* ======================================================================    Put data field into record*/int INTERNAL_FCN r_pfld(    short         field,     /* task->field_table entry number */    FIELD_ENTRY  *fld_ptr,   /* corresponds to field */    char         *rec,       /* pointer to existing record */    const char   *data,      /* ptr to new fld contents */    DB_ADDR      *db_addr,    DB_TASK      *task){    FILE_ENTRY   *file_ptr;    int           file;    DB_ADDR       mdba;    DB_ADDR       odba;    DB_ADDR       dba;    int           cmp;    int           set;    int           sn;    MEM_PTR       memp;    DB_ADDR      *co_ptr;    DB_ADDR      *cm_ptr;    unsigned long co_ts = 0;    unsigned long cm_ts = 0;                 /* save the timestamps */    int           s;    int           strfld;    short         i;    const char   *tfptr;    FIELD_ENTRY  *sfld_ptr = NULL;    SORT_ENTRY   *srt_ptr;    char         *fptr;    fptr = rec + fld_ptr->fd_ptr;    if (fld_ptr->fd_type == CHARACTER && fld_ptr->fd_dim[1] == 0)        cmp = strncmp(fptr, data, fld_ptr->fd_len);    else if (fld_ptr->fd_type == WIDECHAR && fld_ptr->fd_dim[1] == 0)    {        cmp = vwcsncmp((const wchar_t *)fptr, (const wchar_t *)data,                fld_ptr->fd_len / sizeof(wchar_t));    }    else        cmp = memcmp(fptr, data, fld_ptr->fd_len);    if (cmp == 0)        return task->db_status;    memcpy(&dba, db_addr, DB_ADDR_SIZE);    /* if this field is part of an ordered set, check locks */    if ((task->dbopen == 1) && cmp && (fld_ptr->fd_flags & SORTFLD))    {        for (s = 0, srt_ptr = task->sort_table; s < task->size_srt; ++s, ++srt_ptr)        {            if (srt_ptr->se_fld != field)                continue;            sn = srt_ptr->se_set;            if (r_gmem(sn, rec, &memp, task) != S_OKAY)                return task->db_status;            if (null_dba(memp.owner))                continue;                    /* Owner record's file */            file = task->record_table[task->set_table[sn].st_own_rt].rt_file;            file_ptr = &task->file_table[file];            /* check shared access privileges */            if ((!task->app_locks[file]) && !task->excl_locks[file] &&

⌨️ 快捷键说明

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