📄 table.c
字号:
return(_tableWriteRow(cacheEntry,row,rowNum, 0, query));}/****************************************************************************** _tableReadRow**** Purpose : Grab a row from a datafile** Args : datafile FD, length the row, pointer to active flag buf** Returns : pointer to static row buffer** Notes : Some boxes (e.g. early SPARCs etc) don't do multiply** in hardware. As tableReadRow() is the most called function** in the entire code we do a hack to reduce the hit** on boxes without hardware math.*/int tableReadRow(cacheEntry,row,rowNum) cache_t *cacheEntry; row_t *row; u_int rowNum;{ off_t seekPos; static u_int lastRow, lastLen; static off_t lastPos; if (cacheEntry->dataFD < 0) { abort(); } if (rowNum == lastRow + 1 && lastLen == cacheEntry->rowLen) { seekPos = lastPos + cacheEntry->rowLen + HEADER_SIZE; } else { seekPos = (rowNum * (cacheEntry->rowLen + HEADER_SIZE)) + SBLK_SIZE; } lastPos = seekPos; lastRow = rowNum; lastLen = cacheEntry->rowLen; if ((seekPos >= cacheEntry->size) || (!cacheEntry->dataMap)) { msqlDebug2(MOD_ACCESS,"tableReadRow() : %u of %s - No Such Row \n", rowNum, (cacheEntry->result)?cacheEntry->resInfo: cacheEntry->table); return(-1); } row->buf = ((u_char *)cacheEntry->dataMap) + seekPos; row->header = (hdr_t *)row->buf; row->data = row->buf + HEADER_SIZE; row->rowID = rowNum; msqlDebug3(MOD_ACCESS,"tableReadRow() : %u of %s - %s\n", rowNum, (cacheEntry->result)?cacheEntry->resInfo: cacheEntry->table,(row->header->active)?"Active":"Inactive"); return(1);}/****************************************************************************** _deleteRow**** Purpose : Invalidate a row in the table** Args : datafile FD, rowlength, desired row location** Returns : -1 on error** Notes : This just sets the row header byte to 0 indicating** that it's no longer in use */int tableDeleteRow(cacheEntry,rowNum) cache_t *cacheEntry; u_int rowNum;{ int rowLen; hdr_t *hdrPtr; debugTrace(TRACE_IN,"deleteRow()"); msqlDebug2(MOD_ACCESS,"deleteRow() : row %u of %s\n", rowNum, (cacheEntry->result)?cacheEntry->resInfo: cacheEntry->table); rowLen = cacheEntry->rowLen; cacheEntry->dirty = 1; hdrPtr = (hdr_t *)((char *)cacheEntry->dataMap + (rowNum * (rowLen + HEADER_SIZE) + SBLK_SIZE)); hdrPtr->active = 0; debugTrace(TRACE_OUT,"deleteRow()"); return(0);}/****************************************************************************** _fillRow**** Purpose : Create a new row-buf using the info given** Args : ** Returns : ** Notes : */int tableFillRow(entry,row,fields,flist) cache_t *entry; row_t *row; mField_t *fields; int flist[];{ char int8Val; short int16Val; int *offset, length; u_char *data, *cp; u_int overflow; mField_t *curField; debugTrace(TRACE_IN,"fillRow()"); data = row->data; curField = fields; offset = flist; while(curField) { if (curField->value->nullVal) { cp = data + *offset; bzero(cp, curField->length+1); } else { cp = data + *offset; *cp = '\001'; cp++; switch(typeBaseType(curField->type)) { case INT8_TYPE: case UINT8_TYPE: int8Val = curField->value->val.intVal; *cp = int8Val; break; case INT16_TYPE: case UINT16_TYPE: int16Val = curField->value->val.intVal; bcopy(&int16Val, cp, 2); break; case INT_TYPE: case UINT_TYPE: bcopy4(&(curField->value->val.intVal), cp); break;#ifdef HUGE_T case INT64_TYPE: case UINT64_TYPE: bcopy(&(curField->value->val.int64Val), cp, sizeof(HUGE_T)); break;#endif case CHAR_TYPE: /* XXXXXX */ length = curField->value->dataLen; curField->value->val.charVal[length]=0; length=strlen((char *) curField->value->val.charVal); bcopy(curField->value->val.charVal,cp, length); break; case TEXT_TYPE: /* XXXXXX */ length = curField->value->dataLen; curField->value->val.charVal[length]=0; length=strlen((char *) curField->value->val.charVal); if (curField->overflow != NO_POS) { overflow = curField->overflow; } else { overflow = NO_POS; if (length > curField->length) overflow = varcharWrite(entry, curField->value->val.charVal, curField->length); } bcopy(&length,cp,sizeof(int)); cp += sizeof(int); bcopy(&overflow,cp,sizeof(u_int)); cp += sizeof(u_int); bcopy(curField->value->val.charVal, cp, (length > curField->length) ? curField->length : length ); break; case REAL_TYPE: *cp = curField->value->precision; bcopy8(&(curField->value->val.realVal), cp+1); break; case BYTE_TYPE: length = typeFieldSize(curField->type); bcopy(curField->value->val.byteVal,cp, length); break; } } offset++; curField = curField->next; } debugTrace(TRACE_OUT,"fillRow()"); return(0);}/****************************************************************************** _updateValues**** Purpose : Modify a row-buf to reflect the contents of the field list** Args : ** Returns : ** Notes : */int tableUpdateValues(entry,row,fields,flist) cache_t *entry; row_t *row; mField_t *fields; int flist[];{ char int8Val; short int16Val; int *offset, length; mField_t *curField; u_char *data, *cp; u_int pos; char nullField; debugTrace(TRACE_IN,"updateValues()"); data = row->data; curField = fields; offset = flist; while(curField) { cp = data + *offset; nullField = *cp; if (!curField->value->nullVal) { *cp = '\001'; cp++; switch(typeBaseType(curField->type)) { case INT8_TYPE: case UINT8_TYPE: int8Val = curField->value->val.intVal; *cp = int8Val; break; case INT16_TYPE: case UINT16_TYPE: int16Val = curField->value->val.intVal; bcopy(&int16Val, cp, 2); break; case INT_TYPE: case UINT_TYPE: bcopy4(&(curField->value->val.intVal), cp); break; #ifdef HUGE_T case INT64_TYPE: case UINT64_TYPE: bcopy(&(curField->value->val.int64Val), cp, sizeof(HUGE_T)); break;#endif case CHAR_TYPE: length = strlen((char *) curField->value->val.charVal); strncpy(cp,curField->value->val.charVal, length); if (length < curField->length) *(cp + length) = 0; break; case TEXT_TYPE: bcopy(cp + sizeof(int), &pos, sizeof(u_int)); if (nullField == 1) varcharDelete(entry, pos); length=strlen((char *) curField->value->val.charVal); pos = NO_POS; if (length > curField->length) pos = varcharWrite(entry, curField->value->val.charVal, curField->length); bcopy(&length,cp,sizeof(int)); cp += sizeof(int); bcopy(&pos,cp,sizeof(u_int)); cp += sizeof(u_int); bcopy(curField->value->val.charVal, cp, (length > curField->length) ? curField->length : length ); break; case BYTE_TYPE: bcopy(curField->value->val.byteVal,cp, typeFieldSize(curField->type)); break; case REAL_TYPE: *cp = curField->value->precision; bcopy8(&(curField->value->val.realVal), cp+1); break; } } else { *cp = '\000'; } offset++; curField = curField->next; } debugTrace(TRACE_OUT,"updateValues()"); return(0);}/****************************************************************************** _tableExtractValues**** Purpose : Rip the required data from a row-buf** Args : ** Returns : ** Notes : */void tableExtractValues(entry,row,fields,flist,query) cache_t *entry; row_t *row; mField_t *fields; int flist[]; mQuery_t *query;{ mField_t *curField; u_char *cp = NULL, *data = NULL; char int8Val = 0; short int16Val = 0; int int32Val = 0, *offset; double *fp = 0; char buf[8];#ifdef HUGE_T HUGE_T hp;#endif debugTrace(TRACE_IN,"tableExtractValues()"); if (row) data = row->data; curField = fields; offset = flist; while(curField) { if (curField->literalParamFlag) { curField = curField->next; continue; } if (curField->function && !entry->result) { tableExtractValues(entry, row, curField->function->paramHead, curField->function->flist,query); curField = curField->next; offset++; continue; } if (curField->value) { parseFreeValue(curField->value); curField->value = NULL; } if ( *(curField->name) == '_' && ! entry->result) { sysvarGetVariable(entry,row,curField,query); curField = curField->next; continue; } if ( * (data + *offset)) { switch(typeBaseType(curField->type)) { case INT8_TYPE: case UINT8_TYPE: int8Val = *(char*)(data + *offset + 1); curField->value =(mVal_t *) parseFillValue((char *)&int8Val, curField->type, 1); break; case INT16_TYPE: case UINT16_TYPE: bcopy(data + *offset + 1,&int16Val, 2); curField->value =(mVal_t *) parseFillValue((char*)&int16Val, curField->type, 2); break; case INT_TYPE: case UINT_TYPE: bcopy4(data + *offset + 1,&int32Val); curField->value =(mVal_t *) parseFillValue((char*)&int32Val, curField->type, 4); break;#ifdef HUGE_T case INT64_TYPE: case UINT64_TYPE: bcopy(data + *offset + 1,&hp, sizeof(HUGE_T)); curField->value =(mVal_t *) parseFillValue((char *)&hp, curField->type, sizeof(HUGE_T)); break;#endif case CHAR_TYPE: cp = (u_char *)data + *offset + 1; curField->value = (mVal_t *) parseFillValue((char *)cp, CHAR_TYPE, curField->length); break; case TEXT_TYPE: cp = (u_char *)data + *offset + 1; curField->value = memMallocValue(); bcopy(cp + sizeof(u_int), &(curField->overflow), sizeof(u_int)); curField->value->type = TEXT_TYPE; curField->value->nullVal = 0; curField->value->val.charVal = varcharRead(curField->entry, cp, curField->length); curField->value->dataLen = strlen(curField->value->val.charVal); break; case REAL_TYPE: bcopy8(data + *offset + 2,buf); fp = (double *)buf; curField->value =(mVal_t *) parseFillValue((char *)fp, REAL_TYPE, 8); curField->value->precision = *( data + *offset + 1); break; case BYTE_TYPE: cp = (u_char *)data + *offset + 1; curField->value = (mVal_t *) parseFillValue((char *)cp, curField->type, curField->length); break; } } else { curField->value = parseCreateNullValue(); curField->value->type = curField->type; } curField = curField->next; offset++; } debugTrace(TRACE_OUT,"tableExtractValues()");}int tableCopyFile(from, to) char *from, *to;{ int fd1, fd2, numBytes; char buf[5 * 1024]; fd1 = open(from, O_RDONLY); if (fd1 < 0) { snprintf(errMsg,MAX_ERR_MSG,"Copy of '%s' failed (%s)",from, (char*)strerror(errno)); return(-1); } fd2 = open(to, O_CREAT | O_RDWR, 0700); if (fd2 < 0) { snprintf(errMsg,MAX_ERR_MSG,"Copy of '%s' failed (%s)",from, (char*)strerror(errno)); return(-1); } numBytes = read(fd1,buf,sizeof(buf)); while(numBytes >0 ) { if (write(fd2,buf,numBytes) != numBytes) { snprintf(errMsg,MAX_ERR_MSG,"Copy of '%s' failed (%s)", from, (char*)strerror(errno)); return(-1); } numBytes = read(fd1,buf,sizeof(buf)); } close(fd1); close(fd2); return(0);}int tableCreateDefinition(server, table, query) msqld *server; char *table; mQuery_t *query;{ int fd, fieldCount, curOffset, version; char path[255]; struct stat sbuf; mField_t *curField; (void)snprintf(path, MSQL_PATH_LEN, "%s/%s/%s.def", server->config.dbDir, query->curDB, table); if (stat(path, &sbuf) >= 0) { snprintf(errMsg,MAX_ERR_MSG,TABLE_EXISTS_ERROR,table); msqlDebug1(MOD_ERR,"Table \"%s\" exists\n",table); debugTrace(TRACE_OUT,"processCreateTable()"); return(-1); } fd = open(path,O_WRONLY | O_CREAT , 0600); if (fd < 0) { snprintf(errMsg,MAX_ERR_MSG,TABLE_FAIL_ERROR,table); msqlDebug1(MOD_ERR,"Can't create table \"%s\"\n",table); debugTrace(TRACE_OUT,"processCreateTable()"); return(-1); } /* ** Set the database version */ version = DB_VERSION; write(fd,&version, sizeof(int)); /* ** Write out the definition and check to ensure that there ** aren't too many fields */ curOffset = 0; curField = query->fieldHead; fieldCount = 0; while(curField) { (void)strcpy(curField->table,table); fieldCount++; curField->offset = curOffset; curOffset += curField->dataLength + 1; write(fd, curField, sizeof(mField_t)); curField = curField->next; } close(fd); if (fieldCount > MAX_FIELDS) { unlink(path); snprintf(errMsg,MAX_ERR_MSG,TABLE_WIDTH_ERROR,MAX_FIELDS); msqlDebug1(MOD_ERR,"Too many fields in table (%d Max)\n", MAX_FIELDS); debugTrace(TRACE_OUT,"processCreateTable()"); return(-1); } return(0);}int tableCheckTargetDefinition(query) mQuery_t *query;{ mField_t *curField, *tmpField; int curOffset; /* ** Ensure there are no duplicate fields and that the offset ** is set correctly; */ curOffset = 0; curField = query->fieldHead; while(curField) { if (curField->function) { strcpy(errMsg, "Function results are not valid for INTO clauses"); return(-1); } curField->offset = curOffset; curOffset += curField->dataLength + 1; tmpField = query->fieldHead; while(tmpField) { if (tmpField == curField) { tmpField = tmpField->next; continue; } if (*curField->name == *tmpField->name && strcmp(curField->name,tmpField->name) == 0) { snprintf(errMsg,MAX_ERR_MSG, "Duplicate field name in INTO clause '%s'", curField->name); return(-1); } tmpField = tmpField->next; } curField = curField->next; } return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -