mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-30 10:01:14 +02:00
Well I haven't received any feedback pro or con re my suggested new Tcl
function so I am going to assume that it is such a good idea that no one sees any point in discussing it. :-) I have made two changes - I have merged this into pgtclCmds.c and I have taken out any code for updating tuples after the loop body runs. See comments for discussion of this. I have also fixed up the error checking stuff so that break, continue and syntax errors have the expected result. Submitted by: D'Arcy Cain
This commit is contained in:
parent
ea733aa997
commit
4e8f5c337c
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.1.1.1 1996/07/09 06:22:16 scrappy Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.2 1996/10/07 21:19:06 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -44,6 +44,11 @@ Pg_Init (Tcl_Interp *interp)
|
|||||||
Pg_exec,
|
Pg_exec,
|
||||||
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
|
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
|
||||||
|
|
||||||
|
Tcl_CreateCommand(interp,
|
||||||
|
"pg_select",
|
||||||
|
Pg_select,
|
||||||
|
(ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
|
||||||
|
|
||||||
Tcl_CreateCommand(interp,
|
Tcl_CreateCommand(interp,
|
||||||
"pg_result",
|
"pg_result",
|
||||||
Pg_result,
|
Pg_result,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.3 1996/09/16 05:54:53 scrappy Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.4 1996/10/07 21:19:07 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1031,4 +1031,116 @@ Pg_lo_export(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
|
|||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************
|
||||||
|
* pg_select
|
||||||
|
send a select query string to the backend connection
|
||||||
|
|
||||||
|
syntax:
|
||||||
|
pg_select connection query var proc
|
||||||
|
|
||||||
|
The query must be a select statement
|
||||||
|
The var is used in the proc as an array
|
||||||
|
The proc is run once for each row found
|
||||||
|
|
||||||
|
Originally I was also going to update changes but that has turned out
|
||||||
|
to be not so simple. Instead, the caller should get the OID of any
|
||||||
|
table they want to update and update it themself in the loop. I may
|
||||||
|
try to write a simplified table lookup and update function to make
|
||||||
|
that task a little easier.
|
||||||
|
|
||||||
|
The return is either TCL_OK, TCL_ERROR or TCL_RETURN and interp->result
|
||||||
|
may contain more information.
|
||||||
|
**********************************/
|
||||||
|
|
||||||
|
int
|
||||||
|
Pg_select(ClientData cData, Tcl_Interp *interp, int argc, char **argv)
|
||||||
|
{
|
||||||
|
PGconn *conn;
|
||||||
|
PGresult *result;
|
||||||
|
int ch_flag, r;
|
||||||
|
size_t tupno, column, ncols;
|
||||||
|
Tcl_DString headers;
|
||||||
|
struct {
|
||||||
|
char *cname;
|
||||||
|
char *data;
|
||||||
|
int change;
|
||||||
|
} *info;
|
||||||
|
|
||||||
|
if (argc != 5)
|
||||||
|
{
|
||||||
|
Tcl_AppendResult(interp, "Wrong # of arguments\n",
|
||||||
|
"pg_select connection queryString var proc", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! PgValidId(argv[1]))
|
||||||
|
{
|
||||||
|
Tcl_AppendResult(interp,
|
||||||
|
"Argument passed in is not a valid connection\n", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn = (PGconn*)PgGetId(argv[1]);
|
||||||
|
|
||||||
|
if ((result = PQexec(conn, argv[2])) == 0)
|
||||||
|
{
|
||||||
|
/* error occurred during the query */
|
||||||
|
Tcl_SetResult(interp, conn->errorMessage, TCL_STATIC);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((info = malloc(sizeof(*info) * (ncols = PQnfields(result)))) == NULL)
|
||||||
|
{
|
||||||
|
Tcl_AppendResult(interp, "Not enough memory", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tcl_DStringInit(&headers);
|
||||||
|
|
||||||
|
for (column = 0; column < ncols; column++)
|
||||||
|
{
|
||||||
|
info[column].cname = PQfname(result, column);
|
||||||
|
info[column].data = malloc(2000);
|
||||||
|
info[column].change = 0;
|
||||||
|
Tcl_DStringAppendElement(&headers, info[column].cname);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tcl_SetVar2(interp, argv[3], ".headers", Tcl_DStringValue(&headers), 0);
|
||||||
|
sprintf(info[0].data, "%d", ncols);
|
||||||
|
Tcl_SetVar2(interp, argv[3], ".numcols", info[0].data, 0);
|
||||||
|
|
||||||
|
for (tupno = 0; tupno < PQntuples(result); tupno++)
|
||||||
|
{
|
||||||
|
sprintf(info[0].data, "%d", tupno);
|
||||||
|
Tcl_SetVar2(interp, argv[3], ".tupno", info[0].data, 0);
|
||||||
|
|
||||||
|
for (column = 0; column < ncols; column++)
|
||||||
|
{
|
||||||
|
strcpy(info[column].data, PQgetvalue(result, tupno, column));
|
||||||
|
Tcl_SetVar2(interp, argv[3], info[column].cname, info[column].data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tcl_SetVar2(interp, argv[3], ".command", "update", 0);
|
||||||
|
|
||||||
|
if ((r = Tcl_Eval(interp, argv[4])) != TCL_OK && r != TCL_CONTINUE)
|
||||||
|
{
|
||||||
|
if (r == TCL_BREAK)
|
||||||
|
return TCL_OK;
|
||||||
|
|
||||||
|
if (r == TCL_ERROR)
|
||||||
|
{
|
||||||
|
char msg[60];
|
||||||
|
|
||||||
|
sprintf(msg, "\n (\"pg_select\" body line %d)",
|
||||||
|
interp->errorLine);
|
||||||
|
Tcl_AddErrorInfo(interp, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Tcl_AppendResult(interp, "", 0);
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pgtclCmds.h,v 1.1.1.1 1996/07/09 06:22:16 scrappy Exp $
|
* $Id: pgtclCmds.h,v 1.2 1996/10/07 21:19:09 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -24,6 +24,8 @@ extern int Pg_disconnect(
|
|||||||
ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
|
ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
|
||||||
extern int Pg_exec(
|
extern int Pg_exec(
|
||||||
ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
|
ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
|
||||||
|
extern int Pg_select(
|
||||||
|
ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
|
||||||
extern int Pg_result(
|
extern int Pg_result(
|
||||||
ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
|
ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
|
||||||
extern int Pg_lo_open(
|
extern int Pg_lo_open(
|
||||||
|
Loading…
Reference in New Issue
Block a user