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

📄 mapi.mx

📁 这个是内存数据库的客户端
💻 MX
📖 第 1 页 / 共 5 页
字号:
	assert(hdl);	mid = hdl->mid;	assert(mid);	if (mid->noexplain == NULL) {		fprintf(fd, "MAPI  = %s\@%s:%d\n", mid->username, mid->hostname, mid->port);		if (mid->action)			fprintf(fd, "ACTION= %s\n", mid->action);		if (hdl->query)			indented_print(hdl->query, "QUERY = ", fd);		if (mid->errorstr)			indented_print(mid->errorstr, "ERROR = ", fd);	} else if (mid->errorstr) {		clean_print(mid->errorstr, mid->noexplain, fd);	}	fflush(fd);	mapi_clrError(mid);	return MOK;}MapiMsgmapi_explain_result(MapiHdl hdl, FILE *fd){	Mapi mid;	if (hdl == NULL || hdl->result == NULL || hdl->result->errorstr == NULL)		return MOK;	assert(hdl);	assert(hdl->result);	assert(hdl->result->errorstr);	mid = hdl->mid;	assert(mid);	if (mid->noexplain == NULL) {		fprintf(fd, "MAPI  = %s\@%s:%d\n", mid->username, mid->hostname, mid->port);		if (mid->action)			fprintf(fd, "ACTION= %s\n", mid->action);		if (hdl->query)			indented_print(hdl->query, "QUERY = ", fd);		indented_print(hdl->result->errorstr, "ERROR = ", fd);	} else {		clean_print(hdl->result->errorstr, mid->noexplain, fd);	}	fflush(fd);	return MOK;}intmapi_get_trace(Mapi mid){	mapi_check0(mid, "mapi_get_trace");	return mid->trace;}MapiMsgmapi_trace_log(Mapi mid, const char *nme){	mapi_clrError(mid);	mid->tracelog = open_wastream(nme);	if (mid->tracelog == NULL || stream_errnr(mid->tracelog)) {		if (mid->tracelog)			stream_destroy(mid->tracelog);		mid->tracelog = NULL;		return mapi_setError(mid, "Could not create log file", "mapi_trace_log", MERROR);	}	return MOK;}/* send a dummy request to the server to see whether the connection is   still alive */MapiMsgmapi_ping(Mapi mid){	MapiHdl hdl = NULL;	mapi_check(mid, "mapi_ping");	switch (mid->languageId) {	case LANG_SQL:		hdl = mapi_query(mid, "select true;");		break;	case LANG_MAL:		hdl = mapi_query(mid, "io.print(1);");		break;	case LANG_MIL:		hdl = mapi_query(mid, "print(1);");		break;	}	if (hdl)		mapi_close_handle(hdl);	return mid->error;}/* allocate a new structure to represent a result set */static struct MapiResultSet *new_result(MapiHdl hdl){	struct MapiResultSet *result;	assert((hdl->lastresult == NULL && hdl->result == NULL) || (hdl->result != NULL && hdl->lastresult != NULL && hdl->lastresult->next == NULL));	if (hdl->mid->trace == MAPI_TRACE)		printf("allocating new result set\n");	/* append a newly allocated struct to the end of the linked list */	result = malloc(sizeof(*result));	result->next = NULL;	if (hdl->lastresult == NULL)		hdl->result = hdl->lastresult = result;	else {		hdl->lastresult->next = result;		hdl->lastresult = result;	}	result->hdl = hdl;	result->tableid = -1;	result->querytype = -1;	result->errorstr = NULL;	result->row_count = 0;	result->fieldcnt = 0;	result->maxfields = 0;	result->fields = NULL;	result->cache.rowlimit = hdl->mid->cachelimit;	result->cache.shuffle = 100;	result->cache.limit = 0;	result->cache.writer = 0;	result->cache.reader = -1;	result->cache.first = 0;	result->cache.tuplecount = 0;	result->cache.line = NULL;	return result;}/* close a result set, discarding any unread results */static MapiMsgclose_result(MapiHdl hdl){	struct MapiResultSet *result;	Mapi mid;	int i;	result = hdl->result;	if (result == NULL)		return MERROR;	mid = hdl->mid;	assert(mid != NULL);	if (mid->trace == MAPI_TRACE)		printf("closing result set\n");	if (result->tableid >= 0 && result->querytype != Q_PREPARE) {		if (mid->active && !mid->active->needmore && read_into_cache(mid->active, 0) != MOK)			return MERROR;		assert(hdl->npending_close == 0 || (hdl->npending_close > 0 && hdl->pending_close != NULL));		if (mid->active && result->cache.tuplecount < result->row_count) {			/* can't write "X" commands now, so save for later */			REALLOC(hdl->pending_close, hdl->npending_close + 1);			hdl->pending_close[hdl->npending_close] = result->tableid;			hdl->npending_close++;		} else if (mid->to != NULL) {			/* first close saved up to-be-closed tables */			for (i = 0; i < hdl->npending_close; i++) {				mid->active = hdl;				if (stream_printf(mid->to, "X" "close %d\n", hdl->pending_close[i]) < 0 ||				    stream_flush(mid->to)) {					close_connection(mid);					mapi_setError(mid, stream_error(mid->to), "mapi_close_handle", MTIMEOUT);					break;				}				read_into_cache(hdl, 0);			}			hdl->npending_close = 0;			if (hdl->pending_close)				free(hdl->pending_close);			hdl->pending_close = NULL;			if (mid->to != NULL && result->cache.tuplecount < result->row_count) {				mid->active = hdl;				if (stream_printf(mid->to, "X" "close %d\n", result->tableid) < 0 ||				    stream_flush(mid->to)) {					close_connection(mid);					mapi_setError(mid, stream_error(mid->to), "mapi_close_handle", MTIMEOUT);				} else					read_into_cache(hdl, 0);			}		}		result->tableid = -1;	}	if (mid->active == hdl && hdl->active == result && read_into_cache(hdl, -1) != MOK)		return MERROR;	assert(hdl->active != result);	if (result->fields) {		for (i = 0; i < result->maxfields; i++) {			if (result->fields[i].tablename)				free(result->fields[i].tablename);			if (result->fields[i].columnname)				free(result->fields[i].columnname);			if (result->fields[i].columntype)				free(result->fields[i].columntype);		}		free(result->fields);	}	result->fields = NULL;	result->maxfields = result->fieldcnt = 0;	if (result->cache.line) {		for (i = 0; i < result->cache.writer; i++) {			if (result->cache.line[i].rows)				free(result->cache.line[i].rows);			if (result->cache.line[i].anchors)				free(result->cache.line[i].anchors);		}		free(result->cache.line);		result->cache.line = NULL;		result->cache.tuplecount = 0;	}	if (result->errorstr)		free(result->errorstr);	result->errorstr = NULL;	result->hdl = NULL;	hdl->result = result->next;	if (hdl->result == NULL)		hdl->lastresult = NULL;	result->next = NULL;	free(result);	return MOK;}static voidadd_error(struct MapiResultSet *result, char *error){	/* concatenate the error messages */	size_t size = result->errorstr ? strlen(result->errorstr) : 0;	REALLOC(result->errorstr, size + strlen(error) + 2);	strcpy(result->errorstr + size, error);	strcat(result->errorstr + size, "\n");}char *mapi_result_error(MapiHdl hdl){	return hdl && hdl->result ? hdl->result->errorstr : NULL;}/* Go to the next result set, if any, and close the current result   set.  This function returns 1 if there are more result sets after   the one that was closed, otherwise, if more input is needed, return   MMORE, else, return MOK */MapiMsgmapi_next_result(MapiHdl hdl){	mapi_hdl_check(hdl, "mapi_next_result");	while (hdl->result != NULL) {		if (close_result(hdl) != MOK)			return MERROR;		if (hdl->result &&		    (hdl->result->querytype == -1 ||		     hdl->result->querytype == Q_TABLE ||		     hdl->result->querytype == Q_UPDATE ||		     hdl->result->errorstr != NULL))			return 1;	}	return hdl->needmore ? MMORE : MOK;}MapiMsgmapi_needmore(MapiHdl hdl){	return hdl->needmore ? MMORE : MOK;}intmapi_more_results(MapiHdl hdl){	struct MapiResultSet *result;	mapi_hdl_check(hdl, "mapi_more_results");	if ((result = hdl->result) == 0) {		/* there are no results at all */		return 0;	}	if (result->querytype == Q_TABLE && hdl->mid->active == hdl) {		/* read until next result (if any) */		read_into_cache(hdl, -1);	}	if (hdl->needmore) {		/* assume the application will provide more data and		   that we will then have a result */		return 1;	}	while (result->next) {		result = result->next;		if (result->querytype == -1 ||		    result->querytype == Q_TABLE ||		    result->querytype == Q_UPDATE ||		    result->errorstr != NULL)			return 1;	}	/* no more results */	return 0;}MapiHdlmapi_new_handle(Mapi mid){	MapiHdl hdl;	mapi_check0(mid, "mapi_new_handle");	hdl = malloc(sizeof(*hdl));	assert(hdl);	if (hdl == NULL) {		mapi_setError(mid, "Memory allocation failure", "mapi_new_handle", MERROR);		return NULL;	}	hdl->mid = mid;	hdl->template = NULL;	hdl->query = NULL;	hdl->maxbindings = 0;	hdl->bindings = NULL;	hdl->maxparams = 0;	hdl->params = NULL;	hdl->result = NULL;	hdl->lastresult = NULL;	hdl->active = NULL;	hdl->needmore = 0;	hdl->pending_close = NULL;	hdl->npending_close = 0;	/* add to doubly-linked list */	hdl->prev = NULL;	hdl->next = mid->first;	mid->first = hdl;	if (hdl->next)		hdl->next->prev = hdl;	return hdl;}/* close all result sets on the handle but don't close the handle itself */static MapiMsgfinish_handle(MapiHdl hdl){	Mapi mid;	int i;	if (hdl == NULL)		return MERROR;	mid = hdl->mid;	if (mid->active == hdl && !hdl->needmore && read_into_cache(hdl, 0) != MOK)		return MERROR;	if (mid->to) {		if (hdl->needmore) {			assert(mid->active == NULL || mid->active == hdl);			hdl->needmore = 0;			mid->active = hdl;			stream_flush(mid->to);			check_stream(mid, mid->to, "write error on stream", "finish_handle", mid->error);			read_into_cache(hdl, 0);		}		for (i = 0; i < hdl->npending_close; i++) {			mid->active = hdl;			if (stream_printf(mid->to, "X" "close %d\n", hdl->pending_close[i]) < 0 ||			    stream_flush(mid->to)) {				close_connection(mid);				mapi_setError(mid, stream_error(mid->to), "finish_handle", MTIMEOUT);				break;			}			read_into_cache(hdl, 0);		}	}	hdl->npending_close = 0;	if (hdl->pending_close)		free(hdl->pending_close);	hdl->pending_close = NULL;	while (hdl->result) {		if (close_result(hdl) != MOK)			return MERROR;		if (hdl->needmore) {			assert(mid->active == NULL || mid->active == hdl);			hdl->needmore = 0;			mid->active = hdl;			stream_flush(mid->to);			check_stream(mid, mid->to, "write error on stream", "finish_handle", mid->error);			read_into_cache(hdl, 0);		}	}	return MOK;}/* Close a statement handle, discarding any unread output. */MapiMsgmapi_close_handle(MapiHdl hdl){	debugprint("entering %s\n", "mapi_close_handle");		/* don't use mapi_check_hdl: it's ok if we're not connected */	mapi_clrError(hdl->mid);	if (finish_handle(hdl) != MOK)		return MERROR;	hdl->npending_close = 0;	if (hdl->pending_close)		free(hdl->pending_close);	hdl->pending_close = NULL;	if (hdl->bindings)		free(hdl->bindings);	hdl->bindings = NULL;	hdl->maxbindings = 0;	if (hdl->params)		free(hdl->params);	hdl->params = NULL;	hdl->maxparams = 0;	if (hdl->query)		free(hdl->query);	hdl->query = NULL;	if (hdl->template)		free(hdl->template);	hdl->template = NULL;	/* remove from doubly-linked list */	if (hdl->prev)		hdl->prev->next = hdl->next;	if (hdl->next)		hdl->next->prev = hdl->prev;	if (hdl->mid->first == hdl)		hdl->mid->first = hdl->next;

⌨️ 快捷键说明

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