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

📄 pgtclcmds.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 3 页
字号:
/*------------------------------------------------------------------------- * * pgtclCmds.c *	  C functions which implement pg_* tcl commands * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/interfaces/libpgtcl/pgtclCmds.c,v 1.44 1999/05/25 22:43:43 momjian Exp $ * *------------------------------------------------------------------------- */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "postgres.h"#include "pgtclCmds.h"#include "pgtclId.h"#include "libpq/libpq-fs.h"		/* large-object interface */#ifdef TCL_ARRAYS#define ISOCTAL(c)		(((c) >= '0') && ((c) <= '7'))#define DIGIT(c)		((c) - '0')/* * translate_escape() * * This function performs in-place translation of a single C-style * escape sequence pointed by p. Curly braces { } and double-quote * are left escaped if they appear inside an array. * The value returned is the pointer to the last character (the one * just before the rest of the buffer). */static inline char *translate_escape(char *p, int isArray){	char		c,			   *q,			   *s;#ifdef TCL_ARRAYS_DEBUG_ESCAPE	printf("   escape = '%s'\n", p);#endif	/* Address of the first character after the escape sequence */	s = p + 2;	switch (c = *(p + 1))	{		case '0':		case '1':		case '2':		case '3':		case '4':		case '5':		case '6':		case '7':			c = DIGIT(c);			if (ISOCTAL(*s))				c = (c << 3) + DIGIT(*s++);			if (ISOCTAL(*s))				c = (c << 3) + DIGIT(*s++);			*p = c;			break;		case 'b':			*p = '\b';			break;		case 'f':			*p = '\f';			break;		case 'n':			*p = '\n';			break;		case 'r':			*p = '\r';			break;		case 't':			*p = '\t';			break;		case 'v':			*p = '\v';			break;		case '\\':		case '{':		case '}':		case '"':			/*			 * Backslahes, curly braces and double-quotes are left escaped			 * if they appear inside an array. They will be unescaped by			 * Tcl in Tcl_AppendElement. The buffer position is advanced			 * by 1 so that the this character is not processed again by			 * the caller.			 */			if (isArray)				return p + 1;			else				*p = c;			break;		case '\0':			/*			 * This means a backslash at the end of the string. It should			 * never happen but in that case replace the \ with a \0 but			 * don't shift the rest of the buffer so that the caller can			 * see the end of the string and terminate.			 */			*p = c;			return p;			break;		default:			/*			 * Default case, store the escaped character over the			 * backslash and shift the buffer over itself.			 */			*p = c;	}	/* Shift the rest of the buffer over itself after the current char */	q = p + 1;	for (; *s;)		*q++ = *s++;	*q = '\0';#ifdef TCL_ARRAYS_DEBUG_ESCAPE	printf("   after  = '%s'\n", p);#endif	return p;}/* * tcl_value() * * This function does in-line conversion of a value returned by libpq * into a tcl string or into a tcl list if the value looks like the * representation of a postgres array. */static char *tcl_value(char *value){	int			literal,				last;	char	   *p;	if (!value)		return (char *) NULL;#ifdef TCL_ARRAYS_DEBUG	printf("pq_value  = '%s'\n", value);#endif	last = strlen(value) - 1;	if ((last >= 1) && (value[0] == '{') && (value[last] == '}'))	{		/* Looks like an array, replace ',' with spaces */		/* Remove the outer pair of { }, the last first! */		value[last] = '\0';		value++;		literal = 0;		for (p = value; *p; p++)		{			if (!literal)			{				/* We are at the list level, look for ',' and '"' */				switch (*p)				{					case '"':	/* beginning of literal */						literal = 1;						break;					case ',':	/* replace the ',' with space */						*p = ' ';						break;				}			}			else			{				/* We are inside a C string */				switch (*p)				{					case '"':	/* end of literal */						literal = 0;						break;					case '\\':						/*						 * escape sequence, translate it						 */						p = translate_escape(p, 1);						break;				}			}			if (!*p)				break;		}	}	else	{		/* Looks like a normal scalar value */		for (p = value; *p; p++)		{			if (*p == '\\')			{				/*				 * escape sequence, translate it				 */				p = translate_escape(p, 0);			}			if (!*p)				break;		}	}#ifdef TCL_ARRAYS_DEBUG	printf("tcl_value = '%s'\n\n", value);#endif	return value;}#endif	 /* TCL_ARRAYS *//********************************** * pg_conndefaults syntax: pg_conndefaults the return result is a list describing the possible options and their current default values for a call to pg_connect with the new -conninfo syntax. Each entry in the list is a sublist of the format:	 {optname label dispchar dispsize value} **********************************/intPg_conndefaults(ClientData cData, Tcl_Interp *interp, int argc, char **argv){	PQconninfoOption *option;	Tcl_DString result;	char		ibuf[32];	Tcl_DStringInit(&result);	for (option = PQconndefaults(); option->keyword != NULL; option++)	{		char	   *val = option->val ? option->val : "";		sprintf(ibuf, "%d", option->dispsize);		Tcl_DStringStartSublist(&result);		Tcl_DStringAppendElement(&result, option->keyword);		Tcl_DStringAppendElement(&result, option->label);		Tcl_DStringAppendElement(&result, option->dispchar);		Tcl_DStringAppendElement(&result, ibuf);		Tcl_DStringAppendElement(&result, val);		Tcl_DStringEndSublist(&result);	}	Tcl_DStringResult(interp, &result);	return TCL_OK;}/********************************** * pg_connect make a connection to a backend. syntax: pg_connect dbName [-host hostName] [-port portNumber] [-tty pqtty]] the return result is either an error message or a handle for a database connection.  Handles start with the prefix "pgp" **********************************/intPg_connect(ClientData cData, Tcl_Interp *interp, int argc, char *argv[]){	char	   *pghost = NULL;	char	   *pgtty = NULL;	char	   *pgport = NULL;	char	   *pgoptions = NULL;	char	   *dbName;	int			i;	PGconn	   *conn;	if (argc == 1)	{		Tcl_AppendResult(interp, "pg_connect: database name missing\n", 0);		Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]\n", 0);		Tcl_AppendResult(interp, "pg_connect -conninfo <conninfo-string>", 0);		return TCL_ERROR;	}	if (!strcmp("-conninfo", argv[1]))	{		/*		 * Establish a connection using the new PQconnectdb() interface		 */		if (argc != 3)		{			Tcl_AppendResult(interp, "pg_connect: syntax error\n", 0);			Tcl_AppendResult(interp, "pg_connect -conninfo <conninfo-string>", 0);			return TCL_ERROR;		}		conn = PQconnectdb(argv[2]);	}	else	{		/*		 * Establish a connection using the old PQsetdb() interface		 */		if (argc > 2)		{			/* parse for pg environment settings */			i = 2;			while (i + 1 < argc)			{				if (strcmp(argv[i], "-host") == 0)				{					pghost = argv[i + 1];					i += 2;				}				else if (strcmp(argv[i], "-port") == 0)				{					pgport = argv[i + 1];					i += 2;				}				else if (strcmp(argv[i], "-tty") == 0)				{					pgtty = argv[i + 1];					i += 2;				}				else if (strcmp(argv[i], "-options") == 0)				{					pgoptions = argv[i + 1];					i += 2;				}				else				{					Tcl_AppendResult(interp, "Bad option to pg_connect : \n",									 argv[i], 0);					Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]", 0);					return TCL_ERROR;				}			}					/* while */			if ((i % 2 != 0) || i != argc)			{				Tcl_AppendResult(interp, "wrong # of arguments to pg_connect\n", argv[i], 0);				Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]", 0);				return TCL_ERROR;			}		}		dbName = argv[1];		conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);	}	if (PQstatus(conn) == CONNECTION_OK)	{		PgSetConnectionId(interp, conn);		return TCL_OK;	}	else	{		Tcl_AppendResult(interp, "Connection to database failed\n",						 PQerrorMessage(conn), 0);		PQfinish(conn);		return TCL_ERROR;	}}/********************************** * pg_disconnect close a backend connection syntax: pg_disconnect connection The argument passed in must be a connection pointer. **********************************/intPg_disconnect(ClientData cData, Tcl_Interp *interp, int argc, char *argv[]){	Tcl_Channel conn_chan;	if (argc != 2)	{		Tcl_AppendResult(interp, "Wrong # of arguments\n", "pg_disconnect connection", 0);		return TCL_ERROR;	}	conn_chan = Tcl_GetChannel(interp, argv[1], 0);	if (conn_chan == NULL)	{		Tcl_ResetResult(interp);		Tcl_AppendResult(interp, argv[1], " is not a valid connection\n", 0);		return TCL_ERROR;	}	return Tcl_UnregisterChannel(interp, conn_chan);}/********************************** * pg_exec send a query string to the backend connection syntax: pg_exec connection query the return result is either an error message or a handle for a query result.  Handles start with the prefix "pgp" **********************************/intPg_exec(ClientData cData, Tcl_Interp *interp, int argc, char *argv[]){	Pg_ConnectionId *connid;	PGconn	   *conn;	PGresult   *result;	if (argc != 3)	{		Tcl_AppendResult(interp, "Wrong # of arguments\n",						 "pg_exec connection queryString", 0);		return TCL_ERROR;	}	conn = PgGetConnectionId(interp, argv[1], &connid);	if (conn == (PGconn *) NULL)		return TCL_ERROR;	if (connid->res_copyStatus != RES_COPY_NONE)	{		Tcl_SetResult(interp, "Attempt to query while COPY in progress", TCL_STATIC);		return TCL_ERROR;	}	result = PQexec(conn, argv[2]);	/* Transfer any notify events from libpq to Tcl event queue. */	PgNotifyTransferEvents(connid);	if (result)	{		int			rId = PgSetResultId(interp, argv[1], result);		ExecStatusType rStat = PQresultStatus(result);		if (rStat == PGRES_COPY_IN || rStat == PGRES_COPY_OUT)		{			connid->res_copyStatus = RES_COPY_INPROGRESS;			connid->res_copy = rId;		}		return TCL_OK;	}	else	{		/* error occurred during the query */		Tcl_SetResult(interp, PQerrorMessage(conn), TCL_VOLATILE);		return TCL_ERROR;	}}/********************************** * pg_result get information about the results of a query syntax:	pg_result result ?option? the options are:	-status		the status of the result	-error		the error message, if the status indicates error; otherwise				an empty string	-conn		the connection that produced the result	-oid		if command was an INSERT, the OID of the inserted tuple	-numTuples	the number of tuples in the query	-numAttrs	returns the number of attributes returned by the query	-assign arrayName				assign the results to an array, using subscripts of the form				(tupno,attributeName)	-assignbyidx arrayName ?appendstr?				assign the results to an array using the first field's value				as a key.				All but the first field of each tuple are stored, using				subscripts of the form (field0value,attributeNameappendstr)	-getTuple tupleNumber				returns the values of the tuple in a list	-tupleArray tupleNumber arrayName				stores the values of the tuple in array arrayName, indexed				by the attributes returned	-attributes				returns a list of the name/type pairs of the tuple attributes	-lAttributes				returns a list of the {name type len} entries of the tuple				attributes	-clear		clear the result buffer. Do not reuse after this **********************************/intPg_result(ClientData cData, Tcl_Interp *interp, int argc, char *argv[]){	PGresult   *result;	char	   *opt;	int			i;	int			tupno;

⌨️ 快捷键说明

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