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, ×tamp, sizeof(DB_ULONG)); memcpy(rec + RECUPTIME, ×tamp, 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 + -
显示快捷键?