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

📄 mapi.c

📁 这个是内存数据库的客户端
💻 C
📖 第 1 页 / 共 5 页
字号:
#line 654 "/export/scratch0/monet/monet.GNU.64.64.d.14791/clients/src/mapilib/Mapi.mx"#include "clients_config.h"#include <monet_utils.h>#include <stream.h>		/* include before Mapi.h */#include "Mapi.h"#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#include  <stdio.h>#ifdef HAVE_PWD_H#include  <pwd.h>#endif#include  <sys/types.h>#ifdef HAVE_SYS_SOCKET_H# include <sys/socket.h>#endif#ifdef NATIVE_WIN32# include <winsock.h>#endif#ifdef HAVE_SYS_UN_H#include <sys/un.h>#endif#include  <signal.h>#include  <string.h>#include  <memory.h>#if TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# if HAVE_SYS_TIME_H#  include <sys/time.h># else#  include <time.h># endif#endif#ifdef NATIVE_WIN32#define strdup _strdup#endif#ifdef HAVE_CRYPT_H# include <crypt.h>#else# if defined(HAVE_CRYPT) && defined(__MINGW32__)_CRTIMP char * __cdecl crypt(const char *key, const char *salt);# endif#endif#ifdef HAVE_OPENSSL# include <openssl/sha.h># include <openssl/md5.h>#endif#line 762 "/export/scratch0/monet/monet.GNU.64.64.d.14791/clients/src/mapilib/Mapi.mx"#define MAPIBLKSIZE	256	/* minimum buffer shipped *//* information about the columns in a result set */struct MapiColumn {	char *tablename;	char *columnname;	char *columntype;	int columnlength;};/* information about bound columns */struct MapiBinding {	void *outparam;		/* pointer to application variable */	int outtype;		/* type of application variable */	int precision;	int scale;};/* information about statement parameters */struct MapiParam {	void *inparam;		/* pointer to application variable */	int *sizeptr;		/* if string, points to length of string or -1 */	int intype;		/* type of application variable */	int outtype;		/* type of value */	int precision;	int scale;};#line 800 "/export/scratch0/monet/monet.GNU.64.64.d.14791/clients/src/mapilib/Mapi.mx"struct MapiRowBuf {	int rowlimit;		/* maximum number of rows to cache */	int shuffle;		/* percentage of rows to shuffle upon overflow */	int limit;		/* current storage space limit */	int writer;	int reader;	int first;		/* row # of first tuple */	int tuplecount;		/* number of tuples in the cache */	struct {		int fldcnt;	/* actual number of fields in each row */		char *rows;	/* string representation of rows received */		int tupleindex;	/* index of tuple rows */		int tuplerev;	/* reverse map of tupleindex */		char **anchors;	/* corresponding field pointers */	} *line;};struct BlockCache {	char *buf;	int lim;	int nxt;	int end;	int eos;		/* end of sequence */};/* A connection to a server is represented by a struct MapiStruct.  An   application can have any number of connections to any number of   servers.  Connections are completely independent of each other.*/#line 844 "/export/scratch0/monet/monet.GNU.64.64.d.14791/clients/src/mapilib/Mapi.mx"struct MapiStruct {	char *server;		/* server version */	char *mapiversion;	/* mapi version */	char *hostname;	int port;#ifdef HAVE_OPENSSL	int secure;#endif	char *username;	char *password;	char *language;	char *database;		/* to obtain from server */	int languageId;	int versionId;		/* Monet 4 or 5 */	char *motd;		/* welcome message from server */	int profile;		/* profile Mapi interaction */	int trace;		/* Trace Mapi interaction */	int auto_commit;	char *noexplain;	/* on error, don't explain, only print result */	MapiMsg error;		/* Error occurred */	char *errorstr;		/* error from server */	const char *action;	/* pointer to constant string */	struct BlockCache blk;	int connected;	MapiHdl first;		/* start of doubly-linked list */	MapiHdl active;		/* set when not all rows have been received */	int cachelimit;		/* default maximum number of rows to cache */	int redircnt;		/* redirection count */	stream *tracelog;	/* keep a log for inspection */	stream *from, *to;};struct MapiResultSet {	struct MapiResultSet *next;	struct MapiStatement *hdl;	int tableid;		/* SQL id of current result set */	int querytype;		/* type of SQL query */	int row_count;	int fieldcnt;	int maxfields;	char *errorstr;		/* error from server */	struct MapiColumn *fields;	struct MapiRowBuf cache;};#line 897 "/export/scratch0/monet/monet.GNU.64.64.d.14791/clients/src/mapilib/Mapi.mx"struct MapiStatement {	struct MapiStruct *mid;	char *template;		/* keep parameterized query text around */	char *query;	int maxbindings;	struct MapiBinding *bindings;	int maxparams;	struct MapiParam *params;	struct MapiResultSet *result, *active, *lastresult;	int needmore;		/* need more input */	int *pending_close;	int npending_close;	MapiHdl prev, next;};#line 917 "/export/scratch0/monet/monet.GNU.64.64.d.14791/clients/src/mapilib/Mapi.mx"#ifdef DEBUG#define debugprint(fmt,arg)	printf(fmt,arg)#else#define debugprint(fmt,arg)	((void) 0)#endif#define mapi_check(X,C)							\	do {								\		debugprint("entering %s\n", (C));			\		assert(X);						\		if ((X)->connected == 0) {				\			mapi_setError((X), "Connection lost", (C), MERROR); \			return (X)->error;				\		}							\		mapi_clrError(X);					\	} while (0)#define mapi_check0(X,C)						\	do {								\		debugprint("entering %s\n", (C));			\		assert(X);						\		if ((X)->connected == 0) {				\			mapi_setError((X), "Connection lost", (C), MERROR); \			return 0;					\		}							\		mapi_clrError(X);					\	} while (0)#define mapi_hdl_check(X,C)						\	do {								\		debugprint("entering %s\n", (C));			\		assert(X);						\		assert((X)->mid);					\		if ((X)->mid->connected == 0) {				\			mapi_setError((X)->mid, "Connection lost", (C), MERROR); \			return (X)->mid->error;				\		}							\		mapi_clrError((X)->mid);				\	} while (0)#define mapi_hdl_check0(X,C)						\	do {								\		debugprint("entering %s\n", (C));			\		assert(X);						\		assert((X)->mid);					\		if ((X)->mid->connected == 0) {				\			mapi_setError((X)->mid, "Connection lost", (C), MERROR); \			return 0;					\		}							\		mapi_clrError((X)->mid);				\	} while (0)#line 1110 "/export/scratch0/monet/monet.GNU.64.64.d.14791/clients/src/mapilib/Mapi.mx"static Mapi mapi_new(void);static int mapi_extend_bindings(MapiHdl hdl, int minbindings);static int mapi_extend_params(MapiHdl hdl, int minparams);static MapiMsg mapi_setError(Mapi mid, const char *msg, const char *action, MapiMsg error);static void close_connection(Mapi mid);static MapiMsg read_into_cache(MapiHdl hdl, int lookahead);static int unquote(const char *msg, char **start, const char **next, int endchar);static int mapi_slice_row(struct MapiResultSet *result, int cr);static void mapi_store_bind(struct MapiResultSet *result, int cr);#ifdef HAVE_OPENSSLstatic SSL_CTX *mapi_ssl_ctx = 0;#endifstatic int mapi_initialized = 0;#ifdef HAVE_LONG_LONGtypedef unsigned long long mapi_uint64;typedef long long mapi_int64;#else#ifdef HAVE___INT64typedef unsigned __int64 mapi_uint64;typedef __int64 mapi_int64;#endif#endif#define check_stream(mid,s,msg,f,e)					\	do {								\		if ((s) == NULL || stream_errnr(s)) {			\			close_connection(mid);			\			mapi_setError((mid), (msg), (f), MTIMEOUT);	\			return (e);					\		}							\	} while (0)#define REALLOC(p,c)	((p) = ((p) ? realloc((p),(c)*sizeof(*(p))) : malloc((c)*sizeof(*(p)))))#line 1159 "/export/scratch0/monet/monet.GNU.64.64.d.14791/clients/src/mapilib/Mapi.mx"static voidmapi_clrError(Mapi mid){	assert(mid);	if (mid->errorstr)		free(mid->errorstr);	mid->action = 0;	/* contains references to constants */	mid->error = 0;	mid->errorstr = 0;}static MapiMsgmapi_setError(Mapi mid, const char *msg, const char *action, MapiMsg error){	assert(msg);	REALLOC(mid->errorstr, strlen(msg) + 1);	strcpy(mid->errorstr, msg);	mid->error = error;	mid->action = action;	return mid->error;}MapiMsgmapi_error(Mapi mid){	assert(mid);	return mid->error;}char *mapi_error_str(Mapi mid){	assert(mid);	return mid->errorstr;}static voidclean_print(char *msg, const char *prefix, FILE *fd){	int len = (int) strlen(prefix);	while (msg && *msg) {		/* cut by line */		char *p = strchr(msg, '\n');		if (p)			*p++ = 0;		/* skip over prefix */		if (strncmp(msg, prefix, len) == 0)			msg += len;		/* output line */		fputs(msg, fd);		fputc('\n', fd);		msg = p;	}}static voidindented_print(const char *msg, const char *prefix, FILE *fd){	/* for multiline error messages, indent all subsequent	   lines with the space it takes to print "ERROR = " */	const char *s, *p, *q;	s = prefix;	p = msg;	while (p && *p) {		fprintf(fd, "%s", s);		s = "        ";		q = strchr(p, '\n');		if (q) {			q++;	/* also print the newline */			fprintf(fd, "%.*s", (int) (q - p), p);		} else {			/* print bit after last newline,			   adding one ourselves */			fprintf(fd, "%s\n", p);			break;	/* nothing more to do */		}		p = q;	}}voidmapi_noexplain(Mapi mid, char *errorprefix){	assert(mid);	mid->noexplain = errorprefix;}MapiMsgmapi_explain(Mapi mid, FILE *fd){	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 (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_query(MapiHdl hdl, FILE *fd){	Mapi mid;	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;

⌨️ 快捷键说明

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