⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 table.c

📁 uClinux下用的数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
/*** Copyright (c) 1995-2001  Hughes Technologies Pty Ltd.  All rights** reserved.  **** Terms under which this software may be used or copied are** provided in the  specific license associated with this product.**** Hughes Technologies disclaims all warranties with regard to this ** software, including all implied warranties of merchantability and ** fitness, in no event shall Hughes Technologies be liable for any ** special, indirect or consequential damages or any damages whatsoever ** resulting from loss of use, data or profits, whether in an action of ** contract, negligence or other tortious action, arising out of or in ** connection with the use or performance of this software.****** $Id: table.c,v 1.28 2003/08/11 05:27:31 bambi Exp $***//*** Module	: main : table** Purpose	: ** Exports	: ** Depends Upon	: *//**************************************************************************** STANDARD INCLUDES**************************************************************************/#include <common/config.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <common/config_extras.h>#include <common/config/config.h>#ifdef HAVE_UNISTD_H#  include <unistd.h>#endif#ifdef HAVE_STRING_H#  include <string.h>#endif#ifdef HAVE_STRINGS_H#  include <strings.h>#endif/**************************************************************************** MODULE SPECIFIC INCLUDES**************************************************************************/#ifdef HAVE_DIRENT_H#    include <dirent.h>#endif#ifdef HAVE_SYS_DIR_H#  include <sys/dir.h>#endif#if HAVE_SYS_MMAN_H#  include <sys/mman.h>#endif#include <fcntl.h>#include <errno.h>#include <sys/stat.h>#include <common/msql_defs.h>#include <common/debug/debug.h>#include <common/portability.h>#include <msqld/index/index.h>#include <msqld/includes/errmsg.h>#include <msqld/includes/msqld.h>#include <msqld/main/main.h>#include <msqld/main/yaccer.h>#include <msqld/main/version.h>#include <msqld/main/table.h>#include <msqld/main/sysvar.h>#include <msqld/main/varchar.h>#include <msqld/main/index.h>#include <msqld/main/parse.h>#include <msqld/main/memory.h>#include <common/types/types.h>#include <libmsql/msql.h>/**************************************************************************** GLOBAL VARIABLES**************************************************************************/extern	char		errMsg[];extern	cache_t 	*tableCache;char *msql_tmpnam();/**************************************************************************** PRIVATE ROUTINES**************************************************************************/static mField_t *_readTableDef(server, table, alias, db)	msqld		*server;	char		*table,			*alias,			*db;{	mField_t	*headField=NULL,			*tmpField=NULL,			*prevField=NULL,			*curField=NULL;	char		path[MSQL_PATH_LEN];	int		numFields,			numBytes,			fieldCount,			fd,			version;	static	char 	buf[MAX_FIELDS * sizeof(mField_t) + sizeof(int)];	debugTrace(TRACE_IN,"readTableDef()");	(void)snprintf(path, MSQL_PATH_LEN, "%s/%s/%s.def",		server->config.dbDir, db,table);	fd = open(path,O_RDONLY,0);	if (fd < 0)	{		snprintf(errMsg, MAX_ERR_MSG, BAD_TABLE_ERROR,table);		msqlDebug1(MOD_ERR,"Unknown table \"%s\"\n",table);		debugTrace(TRACE_OUT,"readTableDef()");		return(NULL);	}	numBytes = read(fd,buf,sizeof(buf));	if (numBytes < 1)	{		snprintf(errMsg, MAX_ERR_MSG, TABLE_READ_ERROR,table,			(char*)strerror(errno));		msqlDebug1(MOD_ERR,			"Error reading table \"%s\" definition\n",			table);		close(fd);		debugTrace(TRACE_OUT,"readTableDef()");		return(NULL);	}	bcopy(buf,&version,sizeof(int));	if (version != DB_VERSION)	{		snprintf(errMsg, MAX_ERR_MSG, 			"Table \"%s\" wrong database format\n", table);		msqlDebug1(MOD_ERR,			"Table \"%s\" wrong database format\n", table);		close(fd);		debugTrace(TRACE_OUT,"readTableDef()");		return(NULL);	}	numFields = (numBytes - sizeof(int)) / sizeof(mField_t);	fieldCount = 0;	headField = NULL;	while(fieldCount < numFields)	{		tmpField = (mField_t *)(buf + sizeof(int) +			(fieldCount * sizeof(mField_t)));		curField = memMallocField();		if (!headField)		{			headField = prevField = curField;		}		else		{			prevField->next = curField;			prevField = curField;		}		/*bcopy(tmpField, curField, sizeof(mField_t));*/		memCopyField(tmpField, curField);		if (alias)		{			strcpy(curField->table,alias);		}		curField->value = NULL;		fieldCount++;	}	close(fd);	debugTrace(TRACE_OUT,"readTableDef()");	return(headField);}static int findRowLen(cacheEntry)	cache_t	*cacheEntry;{	int	rowLen;	mField_t	*fieldDef;	rowLen = 0;	fieldDef = cacheEntry->def;	while(fieldDef)	{		rowLen += fieldDef->dataLength +1;  /* +1 for NULL indicator */		fieldDef = fieldDef->next;	}	return(rowLen);}static cache_t *_createTargetTable(path,name,table1,table2,fields, flag)	char	*path,		*name;	cache_t	*table1,		*table2;	mField_t	*fields;	int	flag;{	cache_t 	*new;	mField_t	*curField,			*newField,			*tmpField;	int		fd,			foundField,			foundTable,			curOffset = 0;	sblk_t		sblk;	/*	** start building the table cache entry	*/	debugTrace(TRACE_IN,"createTargetTable()");	new = (cache_t *)malloc(sizeof(cache_t));	if (!new)	{		snprintf(errMsg,MAX_ERR_MSG,TMP_MEM_ERROR);		msqlDebug1(MOD_ERR,"Out of memory for temporary table (%s)\n"		,path);		debugTrace(TRACE_OUT,"createTargetTable()");		return(NULL);	}	bzero(new, sizeof(cache_t));	(void)strcpy(new->table,name);	fd = open(path,O_RDWR|O_CREAT|O_TRUNC, 0700);	if (fd < 0)	{		snprintf(errMsg,MAX_ERR_MSG,TMP_CREATE_ERROR, 			(char*)strerror(errno));		msqlDebug1(MOD_ERR,"Couldn't create temporary table (%s)\n",			path);		(void)free(new);		debugTrace(TRACE_OUT,"createTargetTable()");		return(NULL);	}	sblk.version = DB_VERSION;	sblk.activeRows = sblk.numRows = 0;	sblk.sequence.step = sblk.sequence.value = 0;	sblk.freeList = NO_POS;	if (write(fd, &sblk, SBLK_SIZE) < SBLK_SIZE)	{		snprintf(errMsg,MAX_ERR_MSG, TMP_CREATE_ERROR, 			(char*)strerror(errno));		msqlDebug1(MOD_ERR,"Couldn't create temporary table (%s)\n",			path);		(void)free(new);		debugTrace(TRACE_OUT,"createTargetTable()");		return(NULL);	}	new->dataFD = fd;	new->result = 1;	new->size = SBLK_SIZE;	new->dirty = 0;	/*	** Map the tmp table and setup the superblock	*/	new->dataMap = (caddr_t)mmap(NULL, (size_t)new->size,		(PROT_READ|PROT_WRITE), MAP_SHARED, new->dataFD, (off_t)0);#ifdef HAVE_MADVISE	madvise(new->dataMap, new->size, MADV_SEQUENTIAL);#endif	if (new->dataMap == (caddr_t)-1)	{		free(new);		return(NULL);	}	new->sblk=(sblk_t*)new->dataMap;	/*	** Add the field definitions. Ensure that any key fields are	** not flagged as such as we can't access the key data of the	** original table when accessing this.	*/	curField = table1->def;	newField = NULL;	while(curField)	{		/*		** If we've been given a list of fields, only add this		** field to the tmp table if it's in the list.		*/		if (fields && flag == QUERY_FIELDS_ONLY)		{			foundField = 0;			tmpField = fields;			while(tmpField)			{				if(strcmp(tmpField->name,curField->name)==0 &&				   strcmp(tmpField->table,curField->table)==0)				{					foundField = 1;					break;				}				tmpField = tmpField->next;			}			if (!foundField)			{				curField = curField->next;				continue;			}		}		/*		** O.k.  Add this field		*/		if (newField)		{			newField->next = memMallocField();			newField = newField->next;		}		else		{			new->def = memMallocField();			newField = new->def;		}		memCopyField(curField,newField);		if (newField->function)			newField->function = NULL;		if( *(newField->table) == 0)		{			(void)strcpy(newField->table,table1->table);		}		new->rowLen += curField->dataLength + 1;		newField->offset = curOffset;		curOffset += curField->dataLength + 1;		newField->value = NULL;		newField->entry = curField->entry;		if (newField->entry == NULL)			newField->entry = table1;		curField = curField->next;	}	if (table2)	{		curField = table2->def;		while(curField)		{			/*			** If we've been given a list of fields, only add this			** field to the tmp table if it's in the list.			*/			if (fields && flag == QUERY_FIELDS_ONLY)			{				foundField = 0;				tmpField = fields;				while(tmpField)				{					if(strcmp(tmpField->name,						curField->name)==0 &&				   	strcmp(tmpField->table,						curField->table)==0)					{						foundField = 1;						break;					}					tmpField = tmpField->next;				}				if (!foundField)				{					curField = curField->next;					continue;				}			}			/*			** Add it.			*/			if (newField)			{				newField->next = memMallocField();				newField = newField->next;			}			else			{				new->def = newField = memMallocField();			}			/*bcopy(curField,newField,sizeof(mField_t));*/			memCopyField(curField,newField);			if( *(newField->table) == 0)			{				(void)strcpy(newField->table,table2->table);			}			new->rowLen += curField->dataLength + 1;			newField->offset = curOffset;			newField->value = NULL;			newField->entry = curField->entry;			if (newField->entry == NULL)				newField->entry = table2;			curOffset += curField->dataLength + 1;			curField = curField->next;		}	}	/*	** Create real fields for any function return values	*/	curField = fields;	while(curField)	{		if (curField->function == NULL)		{			curField = curField->next;			continue;		}		if (newField)		{			newField->next = memMallocField();			newField = newField->next;		}		else		{			new->def = memMallocField();			newField = new->def;		}		/*bcopy(curField,newField,sizeof(mField_t));*/		memCopyField(curField,newField);		if (newField->function)			newField->function = NULL;		if( *(newField->table) == 0)		{			(void)strcpy(newField->table,table1->table);		}		new->rowLen += curField->dataLength + 1;		newField->offset = curOffset;		curOffset += curField->dataLength + 1;		newField->value = NULL;		newField->entry = curField->entry;		if (newField->entry == NULL)			newField->entry = table1;		curField = curField->next;	}	/*	** Now the ugly bit.  We have to create "real" fields for any	** system variables the we want selected.  This is so that we	** get the actual sysvar from the original table (such as _rowid)	** rather than getting it generated on the fly from the result	** table.	*/	curField = fields;	while(curField)	{		if (*(curField->name) == '_')		{			foundTable = 0;			if (strcmp(curField->table, table1->table) == 0)			{				foundTable = 1;			}			else if (table2)			{				if(strcmp(curField->table,table2->table) == 0)				{					foundTable = 1;				}			}			if ( !foundTable)			{				curField = curField->next;				continue;			}			/*			** Add the field definition			*/			if (newField)			{				newField->next=sysvarGetDefinition(curField);				newField = newField->next;			}			else			{				new->def=newField=sysvarGetDefinition(curField);			}			if (!newField)			{				snprintf(errMsg, MAX_ERR_MSG, SYSVAR_ERROR, 					curField->name);				return(NULL);			}			new->rowLen += newField->dataLength + 1;			newField->offset = curOffset;			curOffset += newField->dataLength + 1;		}		curField = curField->next;	}	if (newField)		{		newField->next = NULL;	}	/*	** Setup the 8 byte padding for the new table row	*/	new->rowDataLen = new->rowLen;        new->rowLen = new->rowDataLen + (8 -  		((new->rowDataLen + HEADER_SIZE) % 8));	new->row.buf = (u_char *)malloc(new->rowLen + HEADER_SIZE + 2);	new->row.header = (hdr_t *)new->row.buf;	new->row.data = new->row.buf + HEADER_SIZE;	debugTrace(TRACE_OUT,"createTargetTable()");	return(new);}static int _tableWriteRow(cacheEntry,row,rowNum, active, query)	cache_t		*cacheEntry;	row_t		*row;	u_int		rowNum;	int		active;	mQuery_t	*query;{	off_t		seekPos;	char		*buf;	struct stat 	sbuf;	int		expandSize;	if (cacheEntry->dataFD < 0)	{		abort();	}	cacheEntry->dirty = 1;	if (rowNum == NO_POS)	{		msqlDebug1(MOD_ACCESS,"tableWriteRow() : append to %s\n",			(cacheEntry->result)?cacheEntry->resInfo:			cacheEntry->table);	}	else	{		msqlDebug2(MOD_ACCESS,			"tableWriteRow() : write at row %u of %s\n",			rowNum, (cacheEntry->result)?cacheEntry->resInfo:			cacheEntry->table);	}	/*	** Write the row to the table	*/	if (rowNum == NO_POS)  /* append */	{		seekPos = cacheEntry->sblk->numRows * 			(cacheEntry->rowLen + HEADER_SIZE) + SBLK_SIZE;		cacheEntry->sblk->numRows++;	}	else	{		seekPos = rowNum * (cacheEntry->rowLen + HEADER_SIZE) +			SBLK_SIZE;	}	if (seekPos + cacheEntry->rowLen + HEADER_SIZE >= cacheEntry->size)	{		if (cacheEntry->result)			expandSize = 2048;		else			expandSize = 512;               	munmap(cacheEntry->dataMap, cacheEntry->size);		cacheEntry->dataMap = NULL;		cacheEntry->size = 0;		lseek(cacheEntry->dataFD, seekPos + 			(expandSize * cacheEntry->rowLen + HEADER_SIZE),			SEEK_SET);		write(cacheEntry->dataFD, "\0", 1);		fstat(cacheEntry->dataFD, &sbuf);		cacheEntry->size = sbuf.st_size;		if (cacheEntry->size)		{			cacheEntry->dataMap = (caddr_t)mmap(NULL, 				(size_t)cacheEntry->size,(PROT_READ|PROT_WRITE),				MAP_SHARED, cacheEntry->dataFD, (off_t)0);			if (cacheEntry->dataMap == (caddr_t)-1)					return(-1);#ifdef HAVE_MADVISE			madvise(cacheEntry->dataMap, cacheEntry->size, 					MADV_SEQUENTIAL);#endif			cacheEntry->sblk=(sblk_t*)cacheEntry->dataMap;			cacheEntry->sblk->dataSize = cacheEntry->size;		}	}	buf = ((char *)cacheEntry->dataMap) + seekPos;	if (row)	{		if (active)			row->header->active = 1;		bcopy(&(query->queryTime),&(row->header->timestamp),			sizeof(query->queryTime));		bcopy(row->buf, buf, HEADER_SIZE +			cacheEntry->rowLen);	}	else	{		if (active)			cacheEntry->row.header->active = 1;		bcopy(&(query->queryTime),&(cacheEntry->row.header->timestamp),			sizeof(query->queryTime));		bcopy(cacheEntry->row.buf, buf,			cacheEntry->rowLen + HEADER_SIZE);	}	return(0);}/**************************************************************************** PUBLIC ROUTINES**************************************************************************//****************************************************************************** 	_tableOpenTable****	Purpose	: Open the datafile for a given table**	Args	: Database and Table names**	Returns	: file descriptor for the data file**	Notes	: */int tableOpenTable(server,table,db)	msqld	*server;	char	*table;	char	*db;{	char	path[MSQL_PATH_LEN];	(void)snprintf(path, MSQL_PATH_LEN, "%s/%s/%s.dat",		server->config.dbDir,db, table);	return(open(path,O_RDWR | O_CREAT, 0600));}int tableOpenOverflow(server,table,db)	msqld	*server;	char	*table;

⌨️ 快捷键说明

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