aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpgtcl/pgtclId.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>1998-09-03 02:10:56 +0000
committerBruce Momjian <bruce@momjian.us>1998-09-03 02:10:56 +0000
commitf71d0cf64ebd53fc277adddfd81c9913badb92ba (patch)
treedfb56c71e84e52703f11c5c233461369baad2d0d /src/interfaces/libpgtcl/pgtclId.c
parentbcc15f15e10630b2624a1610d61bedb88e4c4901 (diff)
downloadpostgresql-f71d0cf64ebd53fc277adddfd81c9913badb92ba.tar.gz
postgresql-f71d0cf64ebd53fc277adddfd81c9913badb92ba.zip
Attached is a patch to remove the definitions of libpq's internal
structs from libpq-fe.h, as we previously discussed. There turned out to be sloppy coding practices in more places than I had realized :-(, but all in all I think it was a well-worth-while exercise. I ended up adding several routines to libpq's API in order to respond to application requirements that were exposed by this work. I owe the docs crew updates for libpq.sgml to describe these changes. I'm way too tired to work on the docs tonight, however. This is the last major change I intend to submit for 6.4. I do want to see if I can make libpgtcl work with Tcl 8.0 before we go final, but hopefully that will be a minor bug fix.
Diffstat (limited to 'src/interfaces/libpgtcl/pgtclId.c')
-rw-r--r--src/interfaces/libpgtcl/pgtclId.c104
1 files changed, 32 insertions, 72 deletions
diff --git a/src/interfaces/libpgtcl/pgtclId.c b/src/interfaces/libpgtcl/pgtclId.c
index 9377e322e7e..8853c1fdbea 100644
--- a/src/interfaces/libpgtcl/pgtclId.c
+++ b/src/interfaces/libpgtcl/pgtclId.c
@@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.14 1998/09/01 04:39:58 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.15 1998/09/03 02:10:44 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -33,98 +33,62 @@ PgEndCopy(Pg_ConnectionId * connid, int *errorCodePtr)
connid->res_copyStatus = RES_COPY_NONE;
if (PQendcopy(connid->conn))
{
- connid->results[connid->res_copy]->resultStatus = PGRES_BAD_RESPONSE;
+ PQclear(connid->results[connid->res_copy]);
+ connid->results[connid->res_copy] =
+ PQmakeEmptyPGresult(connid->conn, PGRES_BAD_RESPONSE);
connid->res_copy = -1;
*errorCodePtr = EIO;
return -1;
}
else
{
- connid->results[connid->res_copy]->resultStatus = PGRES_COMMAND_OK;
+ PQclear(connid->results[connid->res_copy]);
+ connid->results[connid->res_copy] =
+ PQmakeEmptyPGresult(connid->conn, PGRES_COMMAND_OK);
connid->res_copy = -1;
return 0;
}
}
/*
- * Called when reading data (via gets) for a copy <rel> to stdout.
- *
- * NOTE: this routine knows way more than it ought to about libpq's
- * internal buffering mechanisms.
+ * Called when reading data (via gets) for a copy <rel> to stdout.
*/
-int
-PgInputProc(DRIVER_INPUT_PROTO)
+int PgInputProc(DRIVER_INPUT_PROTO)
{
- Pg_ConnectionId *connid;
- PGconn *conn;
- char c;
- int avail;
+ Pg_ConnectionId *connid;
+ PGconn *conn;
+ int avail;
- connid = (Pg_ConnectionId *) cData;
- conn = connid->conn;
+ connid = (Pg_ConnectionId *)cData;
+ conn = connid->conn;
- if (connid->res_copy < 0 ||
- connid->results[connid->res_copy]->resultStatus != PGRES_COPY_OUT)
+ if (connid->res_copy < 0 ||
+ PQresultStatus(connid->results[connid->res_copy]) != PGRES_COPY_OUT)
{
*errorCodePtr = EBUSY;
return -1;
- }
+ }
- /* Try to load any newly arrived data */
- conn->errorMessage[0] = '\0';
- PQconsumeInput(conn);
- if (conn->errorMessage[0])
+ /* Read any newly arrived data into libpq's buffer,
+ * thereby clearing the socket's read-ready condition.
+ */
+ if (! PQconsumeInput(conn))
{
*errorCodePtr = EIO;
return -1;
- }
+ }
- /*
- * Move data from libpq's buffer to Tcl's. We want to accept data only
- * in units of whole lines, not partial lines. This ensures that we
- * can recognize the terminator line "\\.\n". (Otherwise, if it
- * happened to cross a packet/buffer boundary, we might hand the first
- * one or two characters off to Tcl, which we shouldn't.)
- */
+ /* Move data from libpq's buffer to Tcl's. */
- conn->inCursor = conn->inStart;
+ avail = PQgetlineAsync(conn, buf, bufSize);
- avail = bufSize;
- while (avail > 0 && conn->inCursor < conn->inEnd)
+ if (avail < 0)
{
- c = conn->inBuffer[conn->inCursor++];
- *buf++ = c;
- --avail;
- if (c == '\n')
- {
- /* Got a complete line; mark the data removed from libpq */
- conn->inStart = conn->inCursor;
- /* Is it the endmarker line? */
- if (bufSize - avail == 3 && buf[-3] == '\\' && buf[-2] == '.')
- {
- /* Yes, change state and return 0 */
- return PgEndCopy(connid, errorCodePtr);
- }
- /* No, return the data to Tcl */
- /* fprintf(stderr, "returning %d chars\n", bufSize - avail); */
- return bufSize - avail;
- }
- }
+ /* Endmarker detected, change state and return 0 */
+ return PgEndCopy(connid, errorCodePtr);
+ }
- /*
- * We don't have a complete line. We'd prefer to leave it in libpq's
- * buffer until the rest arrives, but there is a special case: what if
- * the line is longer than the buffer Tcl is offering us? In that
- * case we'd better hand over a partial line, else we'd get into an
- * infinite loop. Do this in a way that ensures we can't misrecognize
- * a terminator line later: leave last 3 characters in libpq buffer.
- */
- if (avail == 0 && bufSize > 3)
- {
- conn->inStart = conn->inCursor - 3;
- return bufSize - 3;
- }
- return 0;
+ return avail;
}
/*
@@ -140,17 +104,13 @@ PgOutputProc(DRIVER_OUTPUT_PROTO)
conn = connid->conn;
if (connid->res_copy < 0 ||
- connid->results[connid->res_copy]->resultStatus != PGRES_COPY_IN)
+ PQresultStatus(connid->results[connid->res_copy]) != PGRES_COPY_IN)
{
*errorCodePtr = EBUSY;
return -1;
}
- conn->errorMessage[0] = '\0';
-
- PQputnbytes(conn, buf, bufSize);
-
- if (conn->errorMessage[0])
+ if (PQputnbytes(conn, buf, bufSize))
{
*errorCodePtr = EIO;
return -1;
@@ -398,7 +358,7 @@ getresid(Tcl_Interp * interp, char *id, Pg_ConnectionId ** connid_p)
connid = (Pg_ConnectionId *) Tcl_GetChannelInstanceData(conn_chan);
- if (resid < 0 || resid > connid->res_max || connid->results[resid] == NULL)
+ if (resid < 0 || resid >= connid->res_max || connid->results[resid] == NULL)
{
Tcl_SetResult(interp, "Invalid result handle", TCL_STATIC);
return -1;