freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
- From: Craig Spannring <cts AT internetcds.com>
- To: freetds AT franklin.oit.unc.edu
- Subject: dblib and row buffering
- Date: Tue, 1 Dec 1998 11:58:17 -0800 (PST)
dbnextrow overwrites memory unless you called
dbsetopt(dbproc,DBUFFER, n). This is demonstrated
by src/dblib/unittests/t0001.c.
I've added a circular buffer to dblib.c to fix that problem and I've
also implemented dbclrbuf() and dbgetrow().
If nobody objects I'd like to commit these changes tonight or
tomorrow.
I've included the diffs as viewed by PCL-CVS. I'm also going put a
copy of the actual files in
ftp://freetds.internetcds.com/pub/tmp/freetds.tgz
Most of the changes are additional code, but I've also broken up some
lines in sybdb.h to make them <80 characters long. (Magazines don't
care for source code with long lines.)
=== cd /usr/home/cts/freetds/src/dblib/
=== /usr/bin/cvs diff -rHEAD -u -w dblib.c
Index: dblib.c
===================================================================
RCS file: /Repository/freetds/src/dblib/dblib.c,v
retrieving revision 1.15
diff -u -w -r1.15 dblib.c
--- dblib.c 1998/11/27 20:22:08 1.15
+++ dblib.c 1998/12/01 19:47:04
@@ -6,8 +6,8 @@
#include "convert.h"
#include <unistd.h>
#include <stdlib.h>
+#include <assert.h>
-
static char software_version[] = "$Id: dblib.c,v 1.15 1998/11/27 20:22:08
camber Exp $";
static void *no_unused_var_warn[] = {software_version,
no_unused_var_warn};
@@ -31,6 +31,291 @@
int g_dblib_version = DBVERSION_46;
#endif
+
+static void buffer_init(DBPROC_ROWBUF *buf)
+{
+ memset(buf, 0xad, sizeof(*buf));
+
+ buf->buffering_on = 0;
+ buf->first_in_buf = 0;
+ buf->newest = -1;
+ buf->oldest = 0;
+ buf->elcount = 0;
+ buf->element_size = 0;
+ buf->rows_in_buf = 0;
+ buf->rows = NULL;
+ buf->next_row = 1;
+} /* buffer_init() */
+
+static void buffer_clear(DBPROC_ROWBUF *buf)
+{
+ buf->next_row = 1;
+ buf->first_in_buf = 0;
+ buf->newest = -1;
+ buf->oldest = 0;
+ buf->rows_in_buf = 0;
+ buf->rows = NULL;
+} /* buffer_clear() */
+
+
+static void buffer_free(DBPROC_ROWBUF *buf)
+{
+ if (buf->rows != NULL)
+ {
+ free(buf->rows);
+ }
+ buf->rows = NULL;
+} /* clear_buffer() */
+
+static void buffer_delete_rows(
+ DBPROC_ROWBUF *buf, /* (U) buffer to clear */
+ int count) /* (I) number of elements to purge */
+{
+ assert(count <= buf->elcount); /* possibly a little to pedantic */
+
+ if (count > buf->rows_in_buf)
+ {
+ count = buf->rows_in_buf;
+ }
+
+
+ buf->oldest = (buf->oldest + count) % buf->elcount;
+ buf->rows_in_buf -= count;
+ buf->first_in_buf = count==buf->rows_in_buf ? buf->next_row-1 :
buf->first_in_buf + count;
+
+
+ assert(buf->first_in_buf >= 0);
+} /* buffer_delete_rows() */
+
+
+static int buffer_start_resultset(
+ DBPROC_ROWBUF *buf, /* (U) buffer to clear */
+ int element_size) /* */
+{
+ int space_needed = -1;
+
+ assert(element_size > 0);
+
+ if (buf->rows != NULL)
+ {
+ memset(buf->rows, 0xad, buf->element_size*buf->rows_in_buf);
+ }
+
+ free(buf->rows);
+
+ buf->first_in_buf = 0;
+ buf->next_row = 1;
+ buf->newest = -1;
+ buf->oldest = 0;
+ buf->elcount = buf->buffering_on ? buf->elcount : 1;
+ buf->element_size = element_size;
+ buf->rows_in_buf = 0;
+ space_needed = element_size * buf->elcount;
+ buf->rows = malloc(space_needed);
+
+ return buf->rows==NULL ? FAIL : SUCCEED;
+} /* buffer_start_resultset() */
+
+
+static void buffer_delete_all_rows(
+ DBPROC_ROWBUF *buf) /* (U) buffer to clear */
+{
+ buffer_delete_rows(buf, buf->rows_in_buf);
+} /* delete_all_buffer_rows() */
+
+static int buffer_index_of_resultset_row(
+ DBPROC_ROWBUF *buf, /* (U) buffer to clear */
+ int row_number) /* (I) */
+{
+ int result = -1;
+
+ if (row_number < buf->first_in_buf)
+ {
+ result = -1;
+ }
+ else if (row_number > ((buf->rows_in_buf + buf->first_in_buf) -1))
+ {
+ result = -1;
+ }
+ else
+ {
+ result = ((row_number - buf->first_in_buf)
+ + buf->oldest) % buf->elcount;
+ }
+ return result;
+} /* buffer_index_of_resultset_row() */
+
+
+static void *buffer_row_address(
+ DBPROC_ROWBUF *buf, /* (U) buffer to clear */
+ int index) /* (I) raw index of row to return */
+{
+ void *result = NULL;
+
+ assert(index >= 0);
+ assert(index < buf->elcount);
+
+ if (index>=buf->elcount || index<0)
+ {
+ result = NULL;
+ }
+ else
+ {
+ int offset = buf->element_size * (index % buf->elcount);
+ result = (char *)buf->rows + offset;
+ }
+ return result;
+} /* buffer_row_address() */
+
+
+static void buffer_add_row(
+ DBPROC_ROWBUF *buf, /* (U) buffer to add row into */
+ void *row, /* (I) pointer to the row data */
+ int row_size)
+{
+ void *dest = NULL;
+
+ assert(row_size > 0);
+ assert(row_size == buf->element_size);
+
+ assert(buf->elcount >= 1);
+
+ buf->newest = (buf->newest + 1) % buf->elcount;
+ if (buf->rows_in_buf==0 && buf->first_in_buf==0)
+ {
+ buf->first_in_buf = 1;
+ }
+ buf->rows_in_buf++;
+
+ /*
+ * if we have wrapped around we need to adjust oldest
+ * and rows_in_buf
+ */
+ if (buf->rows_in_buf > buf->elcount)
+ {
+ buf->oldest = (buf->oldest + 1) % buf->elcount;
+ buf->first_in_buf++;
+ buf->rows_in_buf--;
+ }
+
+ assert(buf->elcount >= buf->rows_in_buf);
+ assert( buf->rows_in_buf==0
+ || (((buf->oldest+buf->rows_in_buf) -
1)%buf->elcount)==buf->newest);
+ assert(buf->rows_in_buf>0 || (buf->first_in_buf==buf->next_row-1));
+ assert(buf->rows_in_buf==0 ||
+ (buf->first_in_buf<=buf->next_row));
+ assert(buf->next_row-1 <= (buf->first_in_buf + buf->rows_in_buf));
+
+ dest = buffer_row_address(buf, buf->newest);
+ memcpy(dest, row, row_size);
+} /* buffer_add_row() */
+
+
+static int buffer_is_full(DBPROC_ROWBUF *buf)
+{
+ return buf->rows_in_buf==buf->elcount;
+} /* buffer_is_full() */
+
+static void buffer_set_buffering(
+ DBPROC_ROWBUF *buf, /* (U) */
+ int buf_size) /* (I) number of rows to buffer, 0 to turn off */
+{
+ /* XXX If the user calls this routine in the middle of
+ * a result set and changes the size of the buffering
+ * they are pretty much toast.
+ *
+ * We need to figure out what to do if the user shrinks the
+ * size of the row buffer. What rows should be thrown out,
+ * what should happen to the current row, etc?
+ */
+
+ assert(buf_size >= 0);
+
+ if (buf_size < 0)
+ {
+ /* XXX is it okay to ignore this? */
+ }
+ else if (buf_size == 0)
+ {
+ buf->buffering_on = 0;
+ buf->elcount = 1;
+ buffer_delete_all_rows(buf);
+ }
+ else
+ {
+ buf->buffering_on = 1;
+ buffer_clear(buf);
+ buffer_free(buf);
+ buf->elcount = buf_size;
+ if (buf->element_size > 0)
+ {
+ buf->rows = malloc(buf->element_size * buf->elcount);
+ }
+ else
+ {
+ buf->rows = NULL;
+ }
+ }
+} /* buffer_set_buffering() */
+
+static void buffer_transfer_bound_data(
+ DBPROC_ROWBUF *buf, /* (U) */
+ DBPROCESS *dbproc, /* (I) */
+ int row_num) /* (I) resultset row number */
+{
+ int i;
+ TDSCOLINFO *curcol;
+ TDSRESULTINFO *resinfo;
+ TDSSOCKET *tds;
+ int srctype;
+ int desttype;
+
+ tds = (TDSSOCKET *) dbproc->tds_socket;
+ resinfo = tds->res_info;
+
+ for (i=0;i<resinfo->num_cols;i++)
+ {
+ curcol = resinfo->columns[i];
+ if (curcol->column_nullbind) {
+ if (curcol->column_size==0) {
+ *(curcol->column_nullbind)=-1;
+
+ } else {
+ /* *(curcol->column_nullbind)=curcol->column_size; */
+ /* need to dbconvert here and set accordingly
*/
+ *(curcol->column_nullbind)=0;
+ }
+ }
+ if (curcol->varaddr)
+ {
+ int index = buffer_index_of_resultset_row(buf, row_num);
+
+ if (index<0)
+ {
+ assert(1==0);
+ /* XXX now what? */
+ }
+ else
+ {
+ char *src = ((char*)buffer_row_address(buf, index))
+ + curcol->column_offset;
+ desttype = _db_get_server_type(curcol->column_bindtype);
+ srctype =
_get_conversion_type(curcol->column_type,curcol->column_size);
+
+ dbconvert(dbproc,
+ srctype, /*
srctype */
+ /* &resinfo->current_row[curcol->column_offset], */
+ src, /* src
*/
+ -1, /*
srclen */
+ desttype, /*
desttype */
+ curcol->varaddr, /* dest
*/
+ curcol->column_bindlen); /*
destlen */
+ }
+
+ }
+ }
+} /* buffer_transfer_bound_data() */
+
RETCODE dbinit()
{
/* set the functions in the TDS layer to point to the correct info/err
@@ -118,6 +403,8 @@
exit(1);
}
+ buffer_init(&(dbproc->row_buf));
+
return dbproc;
}
RETCODE dbcmd(DBPROCESS *dbproc, char *cmdstring)
@@ -155,7 +442,7 @@
if (tds) {
resinfo = tds->res_info;
if (resinfo) tds_free_results(resinfo);
- if (dbproc->row_buffer) free(dbproc->row_buffer);
+ buffer_free(&(dbproc->row_buf));
tds_free_socket(tds);
}
@@ -178,30 +465,23 @@
/* this mallocs a bunch of mem that needs to be freed when done */
ret = tds_process_result_tokens(dbproc->tds_socket);
- dbproc->first_row_num = 0;
- dbproc->curr_row_num = 0;
- dbproc->rows_in_buf = 0;
-
tds = (TDSSOCKET *) dbproc->tds_socket;
/* warning resinfo may be a null pointer here */
resinfo = tds->res_info;
- /* free row buffer if exist, and alloc a new one in the correct size
*/
- if (dbproc->row_buffer) {
- free(dbproc->row_buffer);
- dbproc->row_buffer=NULL;
- }
+
+ buffer_clear(&(dbproc->row_buf));
if (ret==TDS_NO_MORE_RESULTS) {
- return NO_MORE_RESULTS;
+ ret = NO_MORE_RESULTS;
}
if(resinfo)
{
- dbproc->row_buffer = (unsigned char *)
- malloc(resinfo->row_size * dbproc->num_buffer_rows);
+ assert(resinfo->row_size > 0);
+ ret = buffer_start_resultset(&(dbproc->row_buf), resinfo->row_size);
+ }
- if (!dbproc->row_buffer) return FAIL;
- } return ret;
+ return ret;
}
int dbnumcols(DBPROCESS *dbproc)
{
@@ -224,59 +504,71 @@
strcpy (buf,resinfo->columns[column-1]->column_name);
return buf;
}
+
+RETCODE dbgetrow(
+ DBPROCESS *dbproc,
+ DBINT row)
+{
+ RETCODE result = FAIL;
+ int index = buffer_index_of_resultset_row(&(dbproc->row_buf), row);
+ if (-1 == index)
+ {
+ result = NO_MORE_ROWS;
+ }
+ else
+ {
+ dbproc->row_buf.next_row = row;
+ buffer_transfer_bound_data(&(dbproc->row_buf), dbproc, row);
+ dbproc->row_buf.next_row++;
+ result = REG_ROW;
+ }
+
+ return result;
+}
+
RETCODE dbnextrow(DBPROCESS *dbproc)
{
TDSRESULTINFO *resinfo;
TDSSOCKET *tds;
RETCODE ret;
-int i;
-TDSCOLINFO *curcol;
-int srctype, desttype;
+
+ if (-1 != buffer_index_of_resultset_row(&(dbproc->row_buf),
+ dbproc->row_buf.next_row))
+ {
+ ret = TDS_SUCCEED;
+ }
+ else
+ {
tds = (TDSSOCKET *) dbproc->tds_socket;
resinfo = tds->res_info;
+
- if (dbproc->num_buffer_rows &&
- dbproc->rows_in_buf >= dbproc->num_buffer_rows)
+ if (dbproc->row_buf.buffering_on && buffer_is_full(&(dbproc->row_buf)))
+ {
return BUF_FULL;
+ }
ret = tds_process_row_tokens(dbproc->tds_socket);
if (ret == TDS_SUCCEED)
- {
- memcpy(&dbproc->row_buffer[dbproc->rows_in_buf *
resinfo->row_size],
- resinfo->current_row,resinfo->row_size);
- dbproc->rows_in_buf++;
- dbproc->curr_row_num=resinfo->row_count;
-
- for (i=0;i<resinfo->num_cols;i++)
{
- curcol = resinfo->columns[i];
- if (curcol->column_nullbind) {
- if (curcol->column_size==0) {
- *(curcol->column_nullbind)=-1;
-
- } else {
- /* *(curcol->column_nullbind)=curcol->column_size; */
- /* need to dbconvert here and set accordingly
*/
- *(curcol->column_nullbind)=0;
+ buffer_add_row(&(dbproc->row_buf), resinfo->current_row,
+ resinfo->row_size);
}
}
- if (curcol->varaddr)
- {
- desttype = _db_get_server_type(curcol->column_bindtype);
- srctype =
_get_conversion_type(curcol->column_type,curcol->column_size);
- dbconvert(dbproc,srctype,
-
&resinfo->current_row[curcol->column_offset],-1,desttype,
- curcol->varaddr,curcol->column_bindlen);
-
- }
- }
- }
if (ret==TDS_SUCCEED)
+ {
+ buffer_transfer_bound_data(&(dbproc->row_buf), dbproc,
+ dbproc->row_buf.next_row);
+ dbproc->row_buf.next_row++;
return REG_ROW;
+ }
else
+ {
return ret;
}
+} /* dbnextrow() */
+
static int _db_get_server_type(int bindtype)
{
switch (bindtype) {
@@ -397,47 +689,12 @@
resinfo = tds->res_info;
return resinfo->row_count;
}
-DBINT DBFIRSTROW(DBPROCESS *dbproc)
-{
-/*
- TDSRESULTINFO * resinfo;
- TDSSOCKET * tds;
-*/
-
- return dbproc->first_row_num;
-}
-DBINT DBLASTROW(DBPROCESS *dbproc)
-{
-TDSRESULTINFO * resinfo;
-TDSSOCKET * tds;
- tds = (TDSSOCKET *) dbproc->tds_socket;
- resinfo = tds->res_info;
- return resinfo->row_count;
-}
void dbclrbuf(DBPROCESS *dbproc, DBINT n)
{
-TDSRESULTINFO * resinfo;
-TDSSOCKET * tds;
-
if (n <= 0) return;
- if (n > dbproc->rows_in_buf) n = dbproc->rows_in_buf;
- tds = (TDSSOCKET *) dbproc->tds_socket;
- resinfo = tds->res_info;
- /*
- ** I'm not really happy with this, it will be slow if you have a large
- ** buffer and clear 1 row on each iteration of dbnextrow()
- ** A better way is to make this a circular buffer, I'll do that some
- ** time soon.
- */
- if(resinfo)
- memcpy(dbproc->row_buffer, &dbproc->row_buffer[n *
resinfo->row_size], (dbproc->num_buffer_rows - n) * resinfo->row_size);
- dbproc->rows_in_buf -= n;
- dbproc->first_row_num = dbproc->first_row_num + n;
- /* I'm not sure if this is the correct behavior */
- if (dbproc->curr_row_num < dbproc->first_row_num)
- dbproc->curr_row_num = dbproc->first_row_num;
+ buffer_delete_rows(&(dbproc->row_buf), n);
}
DBBOOL dbwillconvert(int srctype, int desttype)
{
@@ -677,9 +934,16 @@
{
switch (option) {
case DBBUFFER:
- dbproc->num_buffer_rows = atoi(char_param);
+ {
+ /* XXX should be more robust than just a atoi() */
+ buffer_set_buffering(&(dbproc->row_buf), atoi(char_param));
+ break;
+ }
+ default:
+ {
break;
}
+ }
return SUCCEED;
}
void dbsetinterrupt(DBPROCESS *dbproc, int (*ckintr)(),int (*hndlintr)())
=== cd /usr/home/cts/freetds/include/
=== /usr/bin/cvs diff -rHEAD -u -w sybdb.h
Index: sybdb.h
===================================================================
RCS file: /Repository/freetds/include/sybdb.h,v
retrieving revision 1.11
diff -u -w -r1.11 sybdb.h
--- sybdb.h 1998/11/27 20:22:08 1.11
+++ sybdb.h 1998/12/01 19:49:48
@@ -53,14 +53,34 @@
} LOGINREC;
typedef unsigned char BYTE;
+
+typedef struct tag_DBPROC_ROWBUF
+{
+ int buffering_on; /* (boolean) is row buffering turned on? */
+ int first_in_buf; /* result set row number of first row in buf */
+ int next_row; /* result set row number of next row */
+ int newest; /* index of most recent item in queue */
+ int oldest; /* index of least recent item in queue */
+ int elcount; /* max element count that buffer can hold */
+ int element_size; /* size in bytes of each element in queue */
+ int rows_in_buf; /* # of rows currently in buffer */
+ void *rows; /* pointer to the row storage */
+} DBPROC_ROWBUF;
+
typedef struct {
TDSSOCKET *tds_socket ;
+
+DBPROC_ROWBUF row_buf;
+
+#if 0
unsigned int num_buffer_rows;
int curr_row_num;
int first_row_num;
int rows_in_buf;
-BYTE *user_data;
unsigned char *row_buffer;
+#endif
+
+BYTE *user_data;
unsigned char dbbuf[4096];
} DBPROCESS;
@@ -217,7 +237,9 @@
extern RETCODE DBSETLAPP(LOGINREC *login, char *application);
extern DBPROCESS *dbopen(LOGINREC *login,char *server);
extern RETCODE dbclose(DBPROCESS *dbprocess);
-extern DBINT dbconvert(DBPROCESS *dbproc, int srctype, BYTE *src, DBINT
srclen, int desttype, BYTE *dest, DBINT destlen);
+extern DBINT dbconvert(DBPROCESS *dbproc, int srctype,
+ BYTE *src, DBINT srclen, int desttype, BYTE
*dest,
+ DBINT destlen);
extern void dbexit();
extern RETCODE DBCMDROW(DBPROCESS *dbproc);
extern RETCODE dbsetdeflang(char *language);
@@ -226,6 +248,7 @@
extern RETCODE dbsetlogintime(int seconds);
extern RETCODE dbresults(DBPROCESS *dbproc);
extern RETCODE dbnextrow(DBPROCESS *dbproc);
+extern RETCODE dbgetrow(DBPROCESS *dbproc, DBINT row);
extern DBINT dbretstatus(DBPROCESS *dbproc);
extern DBBOOL dbhasretstat(DBPROCESS *dbproc);
extern DBINT dbdatlen(DBPROCESS *dbproc, int column);
@@ -240,8 +263,10 @@
extern int dbalttype(DBPROCESS *dbproc, int computeid, int column);
extern BYTE *dbadata(DBPROCESS *dbproc, int computeid, int column);
extern int dbaltop(DBPROCESS *dbproc, int computeid, int column);
-extern RETCODE dbsetopt(DBPROCESS *dbproc, int option, char *char_param, int
int_param);
-extern void dbsetinterrupt(DBPROCESS *dbproc, int (*ckintr)(),int
(*hndlintr)());
+extern RETCODE dbsetopt(DBPROCESS *dbproc, int option, char *char_param,
+ int int_param);
+extern void dbsetinterrupt(DBPROCESS *dbproc,
+ int (*ckintr)(),int (*hndlintr)());
extern RETCODE dbcancel(DBPROCESS *dbproc);
extern int dbnumrets(DBPROCESS *dbproc);
extern char *dbretname(DBPROCESS *dbproc, int retnum);
@@ -253,22 +278,36 @@
extern void dbloginfree(LOGINREC *login);
extern int dbnumalts(DBPROCESS *dbproc,int computeid);
extern BYTE *dbbylist(DBPROCESS *dbproc, int computeid, int size);
-extern RETCODE dbrpcinit(DBPROCESS *dbproc,char *rpcname,DBSMALLINT options);
+extern RETCODE dbrpcinit(DBPROCESS *dbproc,char *rpcname,
+ DBSMALLINT options);
extern RETCODE dbrpcparam(DBPROCESS *dbproc, char *paramname, BYTE status,
- int type, DBINT maxlen, DBINT datalen, BYTE *value);
+ int type, DBINT maxlen, DBINT datalen,
+ BYTE *value);
extern RETCODE dbrpcsend(DBPROCESS *dbproc);
extern RETCODE dbuse(DBPROCESS *dbproc,char *dbname);
extern DBBOOL DBDEAD(DBPROCESS *dbproc);
+
extern int (*dbmsghandle( int (*handler)() )) ();
extern int (*dberrhandle( int (*handler)() )) ();
+
extern RETCODE BCP_SETL(LOGINREC *login, DBBOOL enable);
-extern RETCODE bcp_init(DBPROCESS *dbproc, char *tblname, char *hfile, char
*errfile, int direction);
-extern RETCODE bcp_collen(DBPROCESS *dbproc, DBINT varlen, int table_column);
+extern RETCODE bcp_init(DBPROCESS *dbproc, char *tblname, char *hfile,
+ char *errfile, int direction);
+extern RETCODE bcp_collen(DBPROCESS *dbproc, DBINT varlen,
+ int table_column);
extern RETCODE bcp_columns(DBPROCESS *dbproc, int host_colcount);
-extern RETCODE bcp_colfmt(DBPROCESS *dbproc, int host_colnum, int host_type,
int host_prefixlen, DBINT host_collen, BYTE *host_term,int host_termlen, int
table_colnum);
-extern RETCODE bcp_colfmt_ps(DBPROCESS *dbproc, int host_colnum, int
host_type, int host_prefixlen, DBINT host_collen, BYTE *host_term,int
host_termlen, int table_colnum, DBTYPEINFO *typeinfo);
+extern RETCODE bcp_colfmt(DBPROCESS *dbproc, int host_colnum,
+ int host_type, int host_prefixlen,
+ DBINT host_collen, BYTE *host_term,
+ int host_termlen, int table_colnum);
+extern RETCODE bcp_colfmt_ps(DBPROCESS *dbproc, int host_colnum,
+ int host_type, int host_prefixlen,
+ DBINT host_collen, BYTE *host_term,
+ int host_termlen, int table_colnum,
+ DBTYPEINFO *typeinfo);
extern RETCODE bcp_control(DBPROCESS *dbproc, int field, DBINT value);
-extern RETCODE bcp_colptr(DBPROCESS *dbproc, BYTE *colptr, int table_column);
+extern RETCODE bcp_colptr(DBPROCESS *dbproc, BYTE *colptr,
+ int table_column);
extern DBBOOL bcp_getl(LOGINREC *login);
extern RETCODE bcp_exec(DBPROCESS *dbproc, DBINT *rows_copied);
extern RETCODE bcp_readfmt(DBPROCESS *dbproc, char *filename);
@@ -277,46 +316,66 @@
extern RETCODE bcp_moretext(DBPROCESS *dbproc, DBINT size, BYTE *text);
extern RETCODE bcp_batch(DBPROCESS *dbproc);
extern RETCODE bcp_done(DBPROCESS *dbproc);
-extern RETCODE bcp_bind(DBPROCESS *dbproc, BYTE *varaddr, int prefixlen,
DBINT varlen,
- BYTE *terminator, int termlen, int type, int table_column);
-extern RETCODE dbmnyadd(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2, DBMONEY
*sum);
-extern RETCODE dbmnysub(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2, DBMONEY
*diff);
-extern RETCODE dbmnymul(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2, DBMONEY
*prod);
-extern RETCODE dbmnydivide(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2,
DBMONEY *quotient);
+extern RETCODE bcp_bind(DBPROCESS *dbproc, BYTE *varaddr, int prefixlen,
+ DBINT varlen, BYTE *terminator, int termlen,
+ int type, int table_column);
+extern RETCODE dbmnyadd(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2,
+ DBMONEY *sum);
+extern RETCODE dbmnysub(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2,
+ DBMONEY *diff);
+extern RETCODE dbmnymul(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2,
+ DBMONEY *prod);
+extern RETCODE dbmnydivide(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2,
+ DBMONEY *quotient);
extern RETCODE dbmnycmp(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2);
-extern RETCODE dbmnyscale(DBPROCESS *dbproc, DBMONEY *dest,int multiplier,
int addend);
+extern RETCODE dbmnyscale(DBPROCESS *dbproc, DBMONEY *dest,int multiplier,
+ int addend);
extern RETCODE dbmnyzero(DBPROCESS *dbproc, DBMONEY *dest);
extern RETCODE dbmnymaxpos(DBPROCESS *dbproc, DBMONEY *dest);
extern RETCODE dbmnymaxneg(DBPROCESS *dbproc, DBMONEY *dest);
-extern RETCODE dbmnyndigit(DBPROCESS *dbproc, DBMONEY *mnyptr,DBCHAR *value,
DBBOOL *zero);
-extern RETCODE dbmnyinit(DBPROCESS *dbproc,DBMONEY *mnyptr, int trim, DBBOOL
*negative);
-extern RETCODE dbmnydown(DBPROCESS *dbproc,DBMONEY *mnyptr, int divisor, int
*remainder);
+extern RETCODE dbmnyndigit(DBPROCESS *dbproc, DBMONEY *mnyptr,
+ DBCHAR *value, DBBOOL *zero);
+extern RETCODE dbmnyinit(DBPROCESS *dbproc,DBMONEY *mnyptr, int trim,
+ DBBOOL *negative);
+extern RETCODE dbmnydown(DBPROCESS *dbproc,DBMONEY *mnyptr, int divisor,
+ int *remainder);
extern RETCODE dbmnyinc(DBPROCESS *dbproc,DBMONEY *mnyptr);
extern RETCODE dbmnydec(DBPROCESS *dbproc,DBMONEY *mnyptr);
extern RETCODE dbmnyminus(DBPROCESS *dbproc,DBMONEY *src, DBMONEY *dest);
extern RETCODE dbmny4cmp(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2);
-extern RETCODE dbmny4minus(DBPROCESS *dbproc, DBMONEY4 *src, DBMONEY4 *dest);
+extern RETCODE dbmny4minus(DBPROCESS *dbproc, DBMONEY4 *src,
+ DBMONEY4 *dest);
extern RETCODE dbmny4zero(DBPROCESS *dbproc, DBMONEY4 *dest);
-extern RETCODE dbmny4add(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2,
DBMONEY4 *sum);
-extern RETCODE dbmny4sub(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2,
DBMONEY4 *diff);
-extern RETCODE dbmny4mul(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2,
DBMONEY4 *prod);
-extern RETCODE dbmny4divide(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2,
DBMONEY4 *quotient);
+extern RETCODE dbmny4add(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2,
+ DBMONEY4 *sum);
+extern RETCODE dbmny4sub(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2,
+ DBMONEY4 *diff);
+extern RETCODE dbmny4mul(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2,
+ DBMONEY4 *prod);
+extern RETCODE dbmny4divide(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2,
+ DBMONEY4 *quotient);
extern RETCODE dbmny4cmp(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2);
-extern RETCODE dbdatecmp(DBPROCESS *dbproc, DBDATETIME *d1, DBDATETIME *d2);
-extern RETCODE dbdatecrack(DBPROCESS *dbproc, DBDATEREC *dateinfo,
DBDATETIME *datetime);
+extern RETCODE dbdatecmp(DBPROCESS *dbproc, DBDATETIME *d1,
+ DBDATETIME *d2);
+extern RETCODE dbdatecrack(DBPROCESS *dbproc, DBDATEREC *dateinfo,
+ DBDATETIME *datetime);
extern void dbrpwclr(LOGINREC *login);
-extern RETCODE dbrpwset(LOGINREC *login, char *srvname, char *password, int
pwlen);
-extern void build_xact_string(char *xact_name, char *service_name, DBINT
commid, char *result);
+extern RETCODE dbrpwset(LOGINREC *login, char *srvname, char *password,
+ int pwlen);
+extern void build_xact_string(char *xact_name, char *service_name,
+ DBINT commid, char *result);
extern RETCODE remove_xact(DBPROCESS *connect, DBINT commid, int n);
extern RETCODE abort_xact(DBPROCESS *connect, DBINT commid);
extern void close_commit(DBPROCESS *connect);
extern RETCODE commit_xact(DBPROCESS *connect, DBINT commid);
extern DBPROCESS *open_commit(LOGINREC *login, char *servername);
extern RETCODE scan_xact(DBPROCESS *connect, DBINT commid);
-extern DBINT start_xact(DBPROCESS *connect, char *application_name, char
*xact_name, int site_count);
+extern DBINT start_xact(DBPROCESS *connect, char *application_name,
+ char *xact_name, int site_count);
extern DBINT stat_xact(DBPROCESS *connect, DBINT commid);
extern int dbspid(DBPROCESS *dbproc);
-extern char *dbmonthname(DBPROCESS *dbproc,char *language,int
monthnum,DBBOOL shortform);
+extern char *dbmonthname(DBPROCESS *dbproc,char *language,int monthnum,
+ DBBOOL shortform);
extern char *dbname(DBPROCESS *dbproc);
extern BYTE *dbdata(DBPROCESS *dbproc,int column);
extern char *dbcolname(DBPROCESS *dbproc,int column);
@@ -327,10 +386,13 @@
extern int dbnumcols(DBPROCESS *dbproc);
extern DBINT dbcollen(DBPROCESS *dbproc, int column);
extern char *dbprtype(int token);
-RETCODE dbsqlsend(DBPROCESS *dbproc);
-RETCODE dbaltutype(DBPROCESS *dbproc, int computeid, int column);
-RETCODE dbaltlen(DBPROCESS *dbproc, int computeid, int column);
-RETCODE dbpoll(DBPROCESS *dbproc, long milliseconds, DBPROCESS
**ready_dbproc, int *return_reason);
+extern RETCODE dbbind(DBPROCESS *dbproc, int column, int vartype,
+ DBINT varlen, BYTE *varaddr);
+extern RETCODE dbsqlsend(DBPROCESS *dbproc);
+extern RETCODE dbaltutype(DBPROCESS *dbproc, int computeid, int column);
+extern RETCODE dbaltlen(DBPROCESS *dbproc, int computeid, int column);
+extern RETCODE dbpoll(DBPROCESS *dbproc, long milliseconds,
+ DBPROCESS **ready_dbproc, int *return_reason);
#ifdef __cplusplus
}
=== Exit status: 1
- dblib and row buffering, Craig Spannring, 12/01/1998
Archive powered by MHonArc 2.6.24.