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

📄 mapi.c

📁 这个是内存数据库的客户端
💻 C
📖 第 1 页 / 共 5 页
字号:
	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;	hdl->prev = NULL;	hdl->next = NULL;	hdl->mid = NULL;	free(hdl);	return MOK;}/* Allocate a new connection handle. */static Mapimapi_new(void){	Mapi mid;	mid = malloc(sizeof(*mid));	if (mid == NULL)		return NULL;	assert(mid);	/* initialize everything to 0 */	memset(mid, 0, sizeof(*mid));	/* then fill in some details */	mid->auto_commit = 1;	mid->error = MOK;	mid->hostname = strdup("localhost");	mid->server = NULL;	mid->language = strdup("mil");	mid->languageId = LANG_MIL;	mid->versionId = 4;	mid->noexplain = NULL;	mid->motd = NULL;	mid->mapiversion = "mapi 1.0";	mid->username = NULL;	mid->password = NULL;	mid->cachelimit = 100;	mid->redircnt = 0;	mid->tracelog = NULL;	mid->blk.eos = 0;	mid->blk.buf = malloc(BLOCK + 1);	mid->blk.buf[BLOCK] = 0;	mid->blk.buf[0] = 0;	mid->blk.nxt = 0;	mid->blk.end = 0;	mid->blk.lim = BLOCK;	mid->first = NULL;	return mid;}/* Allocate a new connection handle and fill in the information needed   to connect to a server, but don't connect yet. */Mapimapi_mapi(const char *host, int port, const char *username, const char *password, const char *lang, const char *dbname){	Mapi mid;	if (!mapi_initialized) {		mapi_initialized = 1;		if (stream_init() < 0)			return NULL;	}	mid = mapi_new();	if (mid == NULL)		return NULL;	if (host) {		free(mid->hostname);		mid->hostname = strdup(host);	}	if (port == 0) {		char *def;		if ((def = getenv("MAPIPORT")) != NULL)			port = atoi(def);	}	if (port == 0)		port = 50000;	/* hardwired default */	/* fill some defaults for user/pass, this should actually never happen */	if (username == NULL)		username = "guest";	if (mid->username != NULL) free(mid->username);	mid->username = strdup(username);	if (password == NULL)		password = "guest";	if (mid->password) free(mid->password);	mid->password = strdup(password);	mid->port = port;#ifdef HAVE_OPENSSL	mid->secure = 0;#endif	if (lang == NULL)		lang = "mil";	free(mid->language);	mid->language = strdup(lang);	if (strcmp(lang, "mil") == 0)		mid->languageId = LANG_MIL;	else if (strcmp(lang, "mal") == 0)		mid->languageId = LANG_MAL;	else if (strcmp(lang, "sql") == 0)		mid->languageId = LANG_SQL;	else if (strcmp(lang, "xquery") == 0)		mid->languageId = LANG_XQUERY;	if (mid->database) free(mid->database);	mid->database = dbname ? strdup(dbname) : NULL;	return mid;}/* Close a connection and free all memory associated with the   connection handle. */MapiMsgmapi_destroy(Mapi mid){	mapi_clrError(mid);	while (mid->first)		mapi_close_handle(mid->first);	if (mid->connected)		(void) mapi_disconnect(mid);	if (mid->blk.buf)		free(mid->blk.buf);	if (mid->errorstr)		free(mid->errorstr);	if (mid->hostname)		free(mid->hostname);	if (mid->username)		free(mid->username);	if (mid->password)		free(mid->password);	if (mid->language)		free(mid->language);	if (mid->database)		free(mid->database);	if (mid->server)		free(mid->server);	free(mid);	return MOK;}#line 1851 "/export/scratch0/monet/monet.GNU.64.64.d.14791/clients/src/mapilib/Mapi.mx"#ifdef HAVE_OPENSSLstatic char *ssl_error(int err, int ret){	char *errstr;	char buf[120];	unsigned long e;	switch (err) {	case SSL_ERROR_ZERO_RETURN:		errstr = "TLS/SSL connection has been closed";		break;	case SSL_ERROR_WANT_READ:		errstr = "The operation did not complete (read)";		break;	case SSL_ERROR_WANT_WRITE:		errstr = "The operation did not complete (write)";		break;	case SSL_ERROR_WANT_X509_LOOKUP:		errstr = "The operation did not complete (X509 lookup)";		break;	case SSL_ERROR_WANT_CONNECT:		errstr = "The operation did not complete (connect)";		break;	case SSL_ERROR_SYSCALL:		e = ERR_get_error();		if (e == 0) {			if (ret == 0) {				errstr = "EOF occurred in violation of protocol";			} else if (ret == -1) {				/* the underlying BIO reported an I/O error */				errstr = "I/O error";			} else {	/* possible? */				errstr = "Some I/O error occurred";			}		} else {			errstr = ERR_error_string(e, buf);		}		break;	case SSL_ERROR_SSL:		e = ERR_get_error();		if (e != 0)			errstr = ERR_error_string(e, buf);		else {		/* possible? */			errstr = "A failure in the SSL library occurred";		}		break;	default:		errstr = "Invalid error code";

⌨️ 快捷键说明

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