mirror of
https://github.com/postgres/postgres.git
synced 2025-11-24 00:23:06 +03:00
pgindent run. Make it all clean.
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
int print_err(SQLSMALLINT handletype, SQLINTEGER handle);
|
||||
|
||||
int
|
||||
example1(SQLCHAR * server, SQLCHAR * uid, SQLCHAR * authen)
|
||||
example1(SQLCHAR *server, SQLCHAR *uid, SQLCHAR *authen)
|
||||
{
|
||||
SQLHENV henv;
|
||||
SQLHDBC hdbc;
|
||||
@@ -135,12 +135,12 @@ example1(SQLCHAR * server, SQLCHAR * uid, SQLCHAR * authen)
|
||||
/* this time, explicitly allocate an application row descriptor */
|
||||
SQLAllocHandle(SQL_HANDLE_DESC, hdbc, &hdesc);
|
||||
SQLSetDescRec(hdesc, 1, SQL_INTEGER, 0, 0L, 0, 0,
|
||||
(SQLPOINTER) & id, (SQLINTEGER *) NULL, (SQLSMALLINT *) & idind);
|
||||
(SQLPOINTER) & id, (SQLINTEGER *) NULL, (SQLSMALLINT *) &idind);
|
||||
|
||||
SQLSetDescRec(hdesc, 2, SQL_
|
||||
CHAR, 0, (SQLINTEGER) sizeof(name),
|
||||
0, 0, (SQLPOINTER) & name, (SQLINTEGER *) & namelen,
|
||||
(SQLSMALLINT *) & nameind);
|
||||
0, 0, (SQLPOINTER) & name, (SQLINTEGER *) &namelen,
|
||||
(SQLSMALLINT *) &nameind);
|
||||
/* associate descriptor with statement handle */
|
||||
SQLSetStmtAttr(hstmt, SQL_ATTR_APP_ROW_DESC, &hdesc, 0);
|
||||
/* execute the fetch */
|
||||
|
||||
@@ -39,17 +39,17 @@
|
||||
#define max(a,b) (a>b?a:b)
|
||||
|
||||
int print_err(SQLSMALLINT handletype, SQLINTEGER handle);
|
||||
int build_indicator_message(SQLCHAR * errmsg,
|
||||
int build_indicator_message(SQLCHAR *errmsg,
|
||||
SQLPOINTER * data,
|
||||
SQLINTEGER collen,
|
||||
SQLINTEGER * outlen,
|
||||
SQLINTEGER *outlen,
|
||||
SQLSMALLINT colnum);
|
||||
|
||||
SQLINTEGER display_length(SQLSMALLINT coltype,
|
||||
SQLINTEGER collen,
|
||||
SQLCHAR * colname);
|
||||
SQLCHAR *colname);
|
||||
|
||||
example2(SQLCHAR * server, SQLCHAR * uid, SQLCHAR * authen, SQLCHAR * sqlstr)
|
||||
example2(SQLCHAR *server, SQLCHAR *uid, SQLCHAR *authen, SQLCHAR *sqlstr)
|
||||
{
|
||||
int i;
|
||||
SQLHENV henv;
|
||||
@@ -214,13 +214,13 @@ example2(SQLCHAR * server, SQLCHAR * uid, SQLCHAR * authen, SQLCHAR * sqlstr)
|
||||
|
||||
SQLINTEGER
|
||||
display_length(SQLSMALLINT coltype, SQLINTEGER collen,
|
||||
SQLCHAR * colname)
|
||||
SQLCHAR *colname)
|
||||
{
|
||||
switch (coltype)
|
||||
{
|
||||
|
||||
case SQL_VARCHAR:
|
||||
case SQL_CHAR:
|
||||
case SQL_VARCHAR:
|
||||
case SQL_CHAR:
|
||||
return (max(collen, strlen((char *) colname)));
|
||||
break;
|
||||
|
||||
@@ -252,8 +252,8 @@ display_length(SQLSMALLINT coltype, SQLINTEGER collen,
|
||||
}
|
||||
|
||||
int
|
||||
build_indicator_message(SQLCHAR * errmsg, SQLPOINTER * data,
|
||||
SQLINTEGER collen, SQLINTEGER * outlen, SQLSMALLINT colnum)
|
||||
build_indicator_message(SQLCHAR *errmsg, SQLPOINTER * data,
|
||||
SQLINTEGER collen, SQLINTEGER *outlen, SQLSMALLINT colnum)
|
||||
{
|
||||
if (*outlen == SQL_NULL_DATA)
|
||||
{
|
||||
|
||||
@@ -473,7 +473,7 @@ SQLRETURN SQLAllocEnv(SQLHENV * EnvironmentHandle);
|
||||
|
||||
SQLRETURN SQLAllocHandle(SQLSMALLINT HandleType,
|
||||
SQLINTEGER InputHandle,
|
||||
SQLINTEGER * OutputHandle);
|
||||
SQLINTEGER *OutputHandle);
|
||||
|
||||
SQLRETURN SQLAllocStmt(SQLHDBC ConnectionHandle,
|
||||
SQLSTMT * StatementHandle);
|
||||
@@ -483,7 +483,7 @@ SQLRETURN SQLBindCol(SQLHSTMT StatementHandle,
|
||||
SQLSMALLINT BufferType,
|
||||
SQLPOINTER Data,
|
||||
SQLINTEGER BufferLength,
|
||||
SQLINTEGER * DataLength);
|
||||
SQLINTEGER *DataLength);
|
||||
|
||||
SQLRETURN SQLBindParam(SQLHSTMT StatementHandle,
|
||||
SQLSMALLINT ParamNumber,
|
||||
@@ -492,7 +492,7 @@ SQLRETURN SQLBindParam(SQLHSTMT StatementHandle,
|
||||
SQLINTEGER ParamLength,
|
||||
SQLSMALLINT Scale,
|
||||
SQLPOINTER Data,
|
||||
SQLINTEGER * DataLength);
|
||||
SQLINTEGER *DataLength);
|
||||
|
||||
SQLRETURN SQLCancel(SQLHSTMT StatementHandle);
|
||||
|
||||
@@ -501,17 +501,17 @@ SQLRETURN SQLCloseCursor(SQLHSTMT StatementHandle);
|
||||
SQLRETURN SQLColAttribute(SQLHSTMT StatementHandle,
|
||||
SQLSMALLINT ColumnNumber,
|
||||
SQLSMALLINT FieldIdentifier,
|
||||
SQLCHAR * CharacterAttribute,
|
||||
SQLCHAR *CharacterAttribute,
|
||||
SQLINTEGER BufferLength,
|
||||
SQLINTEGER * AttributetLength,
|
||||
SQLINTEGER * NumericAttribute);
|
||||
SQLINTEGER *AttributetLength,
|
||||
SQLINTEGER *NumericAttribute);
|
||||
|
||||
SQLRETURN SQLConnect(SQLHDBC ConnectionHandle,
|
||||
SQLCHAR * ServerName,
|
||||
SQLCHAR *ServerName,
|
||||
SQLSMALLINT NameLength1,
|
||||
SQLCHAR * UserName,
|
||||
SQLCHAR *UserName,
|
||||
SQLSMALLINT NameLength2,
|
||||
SQLCHAR * Authentication,
|
||||
SQLCHAR *Authentication,
|
||||
SQLSMALLINT NameLength3);
|
||||
|
||||
SQLRETURN SQLCopyDesc(SQLHDESC SourceDescHandle,
|
||||
@@ -519,22 +519,22 @@ SQLRETURN SQLCopyDesc(SQLHDESC SourceDescHandle,
|
||||
|
||||
SQLRETURN SQLDataSources(SQLHENV EnvironmentHandle,
|
||||
SQLSMALLINT Direction,
|
||||
SQLCHAR * ServerName,
|
||||
SQLCHAR *ServerName,
|
||||
SQLSMALLINT BufferLength1,
|
||||
SQLSMALLINT * NameLength1,
|
||||
SQLCHAR * Description,
|
||||
SQLSMALLINT *NameLength1,
|
||||
SQLCHAR *Description,
|
||||
SQLSMALLINT BufferLength2,
|
||||
SQLSMALLINT * NameLength2);
|
||||
SQLSMALLINT *NameLength2);
|
||||
|
||||
SQLRETURN SQLDescribeCol(SQLHSTMT StatementHandle,
|
||||
SQLSMALLINT ColumnNumber,
|
||||
SQLCHAR * ColumnName,
|
||||
SQLCHAR *ColumnName,
|
||||
SQLSMALLINT BufferLength,
|
||||
SQLSMALLINT * ColumnNameLength,
|
||||
SQLSMALLINT * ColumnType,
|
||||
SQLINTEGER * ColumnLength,
|
||||
SQLSMALLINT * ColumnScale,
|
||||
SQLSMALLINT * Nullable);
|
||||
SQLSMALLINT *ColumnNameLength,
|
||||
SQLSMALLINT *ColumnType,
|
||||
SQLINTEGER *ColumnLength,
|
||||
SQLSMALLINT *ColumnScale,
|
||||
SQLSMALLINT *Nullable);
|
||||
|
||||
SQLRETURN SQLDisconnect(SQLHDBC ConnectionHandle);
|
||||
|
||||
@@ -545,14 +545,14 @@ SQLRETURN SQLEndTran(SQLSMALLINT HandleType,
|
||||
SQLRETURN SQLError(SQLHENV EnvironmentHandle,
|
||||
SQLHDBC ConnectionHandle,
|
||||
SQLSTMT StatementHandle,
|
||||
SQLCHAR * Sqlstate,
|
||||
SQLINTEGER * NativeError,
|
||||
SQLCHAR * MessageText,
|
||||
SQLCHAR *Sqlstate,
|
||||
SQLINTEGER *NativeError,
|
||||
SQLCHAR *MessageText,
|
||||
SQLINTEGER BufferLength,
|
||||
SQLINTEGER * TextLength);
|
||||
SQLINTEGER *TextLength);
|
||||
|
||||
SQLRETURN SQLExecDirect(SQLHSTMT StatementHandle,
|
||||
SQLCHAR * StatementText,
|
||||
SQLCHAR *StatementText,
|
||||
SQLSMALLINT StringLength);
|
||||
|
||||
SQLRETURN SQLExecute(SQLHSTMT StatementHandle);
|
||||
@@ -576,38 +576,38 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC ConnectionHandle,
|
||||
SQLINTEGER Attribute,
|
||||
SQLPOINTER Value,
|
||||
SQLINTEGER BufferLength,
|
||||
SQLINTEGER * StringLength);
|
||||
SQLINTEGER *StringLength);
|
||||
|
||||
SQLRETURN SQLGetCursorName(SQLHSTMT StatementHandle,
|
||||
SQLCHAR * CursorName,
|
||||
SQLCHAR *CursorName,
|
||||
SQLSMALLINT BufferLength,
|
||||
SQLSMALLINT * NameLength);
|
||||
SQLSMALLINT *NameLength);
|
||||
|
||||
SQLRETURN SQLGetData(SQLHSTMT StatementHandle,
|
||||
SQLSMALLINT ColumnNumber,
|
||||
SQLSMALLINT TargetType,
|
||||
SQLPOINTER TargetValue,
|
||||
SQLINTEGER BufferLength,
|
||||
SQLINTEGER * IndicatorValue);
|
||||
SQLINTEGER *IndicatorValue);
|
||||
|
||||
SQLRETURN SQLGetDescField(SQLHDESC DescriptorHandle,
|
||||
SQLSMALLINT RecordNumber,
|
||||
SQLSMALLINT FieldIdentifier,
|
||||
SQLPOINTER Value,
|
||||
SQLINTEGER BufferLength,
|
||||
SQLINTEGER * StringLength);
|
||||
SQLINTEGER *StringLength);
|
||||
|
||||
SQLRETURN SQLGetDescRec(SQLHDESC DescriptorHandle,
|
||||
SQLSMALLINT RecordNumber,
|
||||
SQLCHAR * Name,
|
||||
SQLCHAR *Name,
|
||||
SQLSMALLINT BufferLength,
|
||||
SQLSMALLINT * StringLength,
|
||||
SQLSMALLINT * Type,
|
||||
SQLSMALLINT * SubType,
|
||||
SQLINTEGER * Length,
|
||||
SQLSMALLINT * Precision,
|
||||
SQLSMALLINT * Scale,
|
||||
SQLSMALLINT * Nullable);
|
||||
SQLSMALLINT *StringLength,
|
||||
SQLSMALLINT *Type,
|
||||
SQLSMALLINT *SubType,
|
||||
SQLINTEGER *Length,
|
||||
SQLSMALLINT *Precision,
|
||||
SQLSMALLINT *Scale,
|
||||
SQLSMALLINT *Nullable);
|
||||
|
||||
SQLRETURN SQLGetDiagField(SQLSMALLINT HandleType,
|
||||
SQLINTEGER Handle,
|
||||
@@ -615,51 +615,51 @@ SQLRETURN SQLGetDiagField(SQLSMALLINT HandleType,
|
||||
SQLSMALLINT DiagIdentifier,
|
||||
SQLPOINTER DiagInfo,
|
||||
SQLSMALLINT BufferLength,
|
||||
SQLSMALLINT * StringLength);
|
||||
SQLSMALLINT *StringLength);
|
||||
|
||||
|
||||
SQLRETURN SQLGetDiagRec(SQLSMALLINT HandleType,
|
||||
SQLINTEGER Handle,
|
||||
SQLSMALLINT RecordNumber,
|
||||
SQLCHAR * Sqlstate,
|
||||
SQLINTEGER * NativeError,
|
||||
SQLCHAR * MessageText,
|
||||
SQLCHAR *Sqlstate,
|
||||
SQLINTEGER *NativeError,
|
||||
SQLCHAR *MessageText,
|
||||
SQLSMALLINT BufferLength,
|
||||
SQLSMALLINT * StringLength);
|
||||
SQLSMALLINT *StringLength);
|
||||
|
||||
SQLRETURN SQLGetEnvAttr(SQLHENV EnvironmentHandle,
|
||||
SQLINTEGER Attribute,
|
||||
SQLPOINTER Value,
|
||||
SQLINTEGER BufferLength,
|
||||
SQLINTEGER * StringLength);
|
||||
SQLINTEGER *StringLength);
|
||||
|
||||
SQLRETURN SQLGetFunctions(SQLHDBC ConnectionHandle,
|
||||
SQLSMALLINT FunctionId,
|
||||
SQLSMALLINT * Supported);
|
||||
SQLSMALLINT *Supported);
|
||||
|
||||
SQLRETURN SQLGetInfo(SQLHDBC ConnectionHandle,
|
||||
SQLSMALLINT InfoType,
|
||||
SQLPOINTER InfoValue,
|
||||
SQLSMALLINT BufferLength,
|
||||
SQLSMALLINT * StringLength);
|
||||
SQLSMALLINT *StringLength);
|
||||
|
||||
SQLRETURN SQLGetStmtAttr(SQLHSTMT StatementHandle,
|
||||
SQLINTEGER Attribute,
|
||||
SQLPOINTER Value,
|
||||
SQLINTEGER BufferLength,
|
||||
SQLINTEGER * StringLength);
|
||||
SQLINTEGER *StringLength);
|
||||
|
||||
SQLRETURN SQLGetTypeInfo(SQLHSTMT StatementHandle,
|
||||
SQLSMALLINT DataType);
|
||||
|
||||
SQLRETURN SQLNumResultCols(SQLHSTMT StatementHandle,
|
||||
SQLINTEGER * ColumnCount);
|
||||
SQLINTEGER *ColumnCount);
|
||||
|
||||
SQLRETURN SQLParamData(SQLHSTMT StatementHandle,
|
||||
SQLPOINTER * Value);
|
||||
|
||||
SQLRETURN SQLPrepare(SQLHSTMT StatementHandle,
|
||||
SQLCHAR * StatementText,
|
||||
SQLCHAR *StatementText,
|
||||
SQLSMALLINT StringLength);
|
||||
|
||||
|
||||
@@ -668,7 +668,7 @@ SQLRETURN SQLPutData(SQLHSTMT StatementHandle,
|
||||
SQLINTEGER StringLength);
|
||||
|
||||
SQLRETURN SQLRowCount(SQLHSTMT StatementHandle,
|
||||
SQLINTEGER * RowCount);
|
||||
SQLINTEGER *RowCount);
|
||||
|
||||
SQLRETURN SQLSetConnectAttr(SQLHDBC ConnectionHandle,
|
||||
SQLINTEGER AttributeCursorName,
|
||||
@@ -676,7 +676,7 @@ SQLRETURN SQLSetConnectAttr(SQLHDBC ConnectionHandle,
|
||||
SQLINTEGER StringLength);
|
||||
|
||||
SQLRETURN SQLSetCursorName(SQLHSTMT StatementHandle,
|
||||
SQLCHAR * CursorName,
|
||||
SQLCHAR *CursorName,
|
||||
SQLSMALLINT NameLength);
|
||||
|
||||
SQLRETURN SQLSetDescField(SQLHDESC DescriptorHandle,
|
||||
@@ -692,8 +692,8 @@ SQLRETURN SQLSetDescRec(SQLHDESC DescriptorHandle,
|
||||
SQLSMALLINT Precision,
|
||||
SQLSMALLINT Scale,
|
||||
SQLPOINTER Data,
|
||||
SQLINTEGER * StringLength,
|
||||
SQLSMALLINT * Indicator);
|
||||
SQLINTEGER *StringLength,
|
||||
SQLSMALLINT *Indicator);
|
||||
|
||||
SQLRETURN SQLSetEnvAttr(SQLHENV EnvironmentHandle,
|
||||
SQLINTEGER Attribute,
|
||||
|
||||
@@ -44,18 +44,22 @@
|
||||
#define ECPG_CONNECT -402
|
||||
|
||||
/* backend notices, starting at 600 */
|
||||
#define ECPG_NOTICE_UNRECOGNIZED -600
|
||||
/* NOTICE: (transaction aborted): queries ignored until END */
|
||||
/* NOTICE: current transaction is aborted, queries ignored until end of transaction block */
|
||||
#define ECPG_NOTICE_QUERY_IGNORED -601
|
||||
/* NOTICE: PerformPortalClose: portal "*" not found */
|
||||
#define ECPG_NOTICE_UNKNOWN_PORTAL -602
|
||||
/* NOTICE: BEGIN: already a transaction in progress */
|
||||
#define ECPG_NOTICE_IN_TRANSACTION -603
|
||||
/* NOTICE: AbortTransaction and not in in-progress state */
|
||||
/* NOTICE: COMMIT: no transaction in progress */
|
||||
#define ECPG_NOTICE_NO_TRANSACTION -604
|
||||
/* NOTICE: BlankPortalAssignName: portal * already exists */
|
||||
#define ECPG_NOTICE_PORTAL_EXISTS -605
|
||||
|
||||
#define ECPG_NOTICE_UNRECOGNIZED -600
|
||||
/* NOTICE: (transaction aborted): queries ignored until END */
|
||||
|
||||
/*
|
||||
* NOTICE: current transaction is aborted, queries ignored until end of
|
||||
* transaction block
|
||||
*/
|
||||
#define ECPG_NOTICE_QUERY_IGNORED -601
|
||||
/* NOTICE: PerformPortalClose: portal "*" not found */
|
||||
#define ECPG_NOTICE_UNKNOWN_PORTAL -602
|
||||
/* NOTICE: BEGIN: already a transaction in progress */
|
||||
#define ECPG_NOTICE_IN_TRANSACTION -603
|
||||
/* NOTICE: AbortTransaction and not in in-progress state */
|
||||
/* NOTICE: COMMIT: no transaction in progress */
|
||||
#define ECPG_NOTICE_NO_TRANSACTION -604
|
||||
/* NOTICE: BlankPortalAssignName: portal * already exists */
|
||||
#define ECPG_NOTICE_PORTAL_EXISTS -605
|
||||
|
||||
#endif /* !_ECPG_ERROR_H */
|
||||
|
||||
@@ -9,26 +9,26 @@
|
||||
#ifndef __cplusplus
|
||||
#ifndef bool
|
||||
#define bool char
|
||||
#endif /* ndef bool */
|
||||
#endif /* ndef bool */
|
||||
|
||||
#ifndef true
|
||||
#define true ((bool) 1)
|
||||
#endif /* ndef true */
|
||||
#ifndef false
|
||||
#define false ((bool) 0)
|
||||
#endif /* ndef false */
|
||||
#endif /* not C++ */
|
||||
#else /* __BEOS__ */
|
||||
#define true ((bool) 1)
|
||||
#endif /* ndef true */
|
||||
#ifndef false
|
||||
#define false ((bool) 0)
|
||||
#endif /* ndef false */
|
||||
#endif /* not C++ */
|
||||
#else /* __BEOS__ */
|
||||
#include <SupportDefs.h>
|
||||
#endif /* __BEOS__ */
|
||||
#endif /* __BEOS__ */
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif /* TRUE */
|
||||
#define TRUE 1
|
||||
#endif /* TRUE */
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif /* FALSE */
|
||||
#define FALSE 0
|
||||
#endif /* FALSE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
||||
@@ -23,17 +23,21 @@ extern "C"
|
||||
/* Element 0: empty */
|
||||
/* 1: OID of processed tuple if applicable */
|
||||
/* 2: number of rows processed */
|
||||
/* after an INSERT, UPDATE or */
|
||||
/* after an INSERT, UPDATE or */
|
||||
/* DELETE statement */
|
||||
/* 3: empty */
|
||||
/* 4: empty */
|
||||
/* 5: empty */
|
||||
char sqlwarn[8];
|
||||
/* Element 0: set to 'W' if at least one other is 'W' */
|
||||
/* 1: if 'W' at least one character string */
|
||||
/* value was truncated when it was */
|
||||
/* stored into a host variable. */
|
||||
/* 2: if 'W' a (hopefully) non-fatal notice occured */ /* 3: empty */
|
||||
/* Element 0: set to 'W' if at least one other is 'W' */
|
||||
/* 1: if 'W' at least one character string */
|
||||
/* value was truncated when it was */
|
||||
/* stored into a host variable. */
|
||||
|
||||
/*
|
||||
* 2: if 'W' a (hopefully) non-fatal notice occured *//* 3:
|
||||
* empty
|
||||
*/
|
||||
/* 4: empty */
|
||||
/* 5: empty */
|
||||
/* 6: empty */
|
||||
@@ -47,6 +51,7 @@ extern "C"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,8 +27,9 @@ ecpg_finish(struct connection * act)
|
||||
{
|
||||
if (act != NULL)
|
||||
{
|
||||
struct ECPGtype_information_cache *cache, *ptr;
|
||||
|
||||
struct ECPGtype_information_cache *cache,
|
||||
*ptr;
|
||||
|
||||
ECPGlog("ecpg_finish: finishing %s.\n", act->name);
|
||||
PQfinish(act->connection);
|
||||
|
||||
@@ -115,114 +116,141 @@ ECPGnoticeProcessor_raise(int code, const char *message)
|
||||
{
|
||||
sqlca.sqlcode = code;
|
||||
strncpy(sqlca.sqlerrm.sqlerrmc, message, sizeof(sqlca.sqlerrm.sqlerrmc));
|
||||
sqlca.sqlerrm.sqlerrmc[sizeof(sqlca.sqlerrm.sqlerrmc)-1]=0;
|
||||
sqlca.sqlerrm.sqlerrmc[sizeof(sqlca.sqlerrm.sqlerrmc) - 1] = 0;
|
||||
sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
|
||||
|
||||
|
||||
/* remove trailing newline */
|
||||
if (sqlca.sqlerrm.sqlerrml
|
||||
&& sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml-1]=='\n')
|
||||
if (sqlca.sqlerrm.sqlerrml
|
||||
&& sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml - 1] == '\n')
|
||||
{
|
||||
sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml-1]=0;
|
||||
sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml - 1] = 0;
|
||||
sqlca.sqlerrm.sqlerrml--;
|
||||
}
|
||||
|
||||
ECPGlog("raising sqlcode %d\n",code);
|
||||
|
||||
ECPGlog("raising sqlcode %d\n", code);
|
||||
}
|
||||
|
||||
/*
|
||||
* I know this is a mess, but we can't redesign the backend
|
||||
/*
|
||||
* I know this is a mess, but we can't redesign the backend
|
||||
*/
|
||||
|
||||
static void
|
||||
ECPGnoticeProcessor(void *arg, const char *message)
|
||||
{
|
||||
/* these notices raise an error */
|
||||
if (strncmp(message,"NOTICE: ",8))
|
||||
/* these notices raise an error */
|
||||
if (strncmp(message, "NOTICE: ", 8))
|
||||
{
|
||||
ECPGlog("ECPGnoticeProcessor: strange notice '%s'\n", message);
|
||||
ECPGnoticeProcessor_raise(ECPG_NOTICE_UNRECOGNIZED, message);
|
||||
return;
|
||||
}
|
||||
|
||||
message+=8;
|
||||
while (*message==' ') message++;
|
||||
|
||||
message += 8;
|
||||
while (*message == ' ')
|
||||
message++;
|
||||
ECPGlog("NOTICE: %s", message);
|
||||
|
||||
/* NOTICE: (transaction aborted): queries ignored until END */
|
||||
/* NOTICE: current transaction is aborted, queries ignored until end of transaction block */
|
||||
if (strstr(message,"queries ignored") && strstr(message,"transaction")
|
||||
&& strstr(message,"aborted"))
|
||||
|
||||
/* NOTICE: (transaction aborted): queries ignored until END */
|
||||
|
||||
/*
|
||||
* NOTICE: current transaction is aborted, queries ignored until end
|
||||
* of transaction block
|
||||
*/
|
||||
if (strstr(message, "queries ignored") && strstr(message, "transaction")
|
||||
&& strstr(message, "aborted"))
|
||||
{
|
||||
ECPGnoticeProcessor_raise(ECPG_NOTICE_QUERY_IGNORED, message);
|
||||
return;
|
||||
}
|
||||
|
||||
/* NOTICE: PerformPortalClose: portal "*" not found */
|
||||
if ((!strncmp(message,"PerformPortalClose: portal",26)
|
||||
|| !strncmp(message,"PerformPortalFetch: portal",26))
|
||||
&& strstr(message+26,"not found"))
|
||||
|
||||
/* NOTICE: PerformPortalClose: portal "*" not found */
|
||||
if ((!strncmp(message, "PerformPortalClose: portal", 26)
|
||||
|| !strncmp(message, "PerformPortalFetch: portal", 26))
|
||||
&& strstr(message + 26, "not found"))
|
||||
{
|
||||
ECPGnoticeProcessor_raise(ECPG_NOTICE_UNKNOWN_PORTAL, message);
|
||||
return;
|
||||
}
|
||||
|
||||
/* NOTICE: BEGIN: already a transaction in progress */
|
||||
if (!strncmp(message,"BEGIN: already a transaction in progress",40))
|
||||
|
||||
/* NOTICE: BEGIN: already a transaction in progress */
|
||||
if (!strncmp(message, "BEGIN: already a transaction in progress", 40))
|
||||
{
|
||||
ECPGnoticeProcessor_raise(ECPG_NOTICE_IN_TRANSACTION, message);
|
||||
return;
|
||||
}
|
||||
|
||||
/* NOTICE: AbortTransaction and not in in-progress state */
|
||||
/* NOTICE: COMMIT: no transaction in progress */
|
||||
/* NOTICE: ROLLBACK: no transaction in progress */
|
||||
if (!strncmp(message,"AbortTransaction and not in in-progress state",45)
|
||||
|| !strncmp(message,"COMMIT: no transaction in progress",34)
|
||||
|| !strncmp(message,"ROLLBACK: no transaction in progress",36))
|
||||
|
||||
/* NOTICE: AbortTransaction and not in in-progress state */
|
||||
/* NOTICE: COMMIT: no transaction in progress */
|
||||
/* NOTICE: ROLLBACK: no transaction in progress */
|
||||
if (!strncmp(message, "AbortTransaction and not in in-progress state", 45)
|
||||
|| !strncmp(message, "COMMIT: no transaction in progress", 34)
|
||||
|| !strncmp(message, "ROLLBACK: no transaction in progress", 36))
|
||||
{
|
||||
ECPGnoticeProcessor_raise(ECPG_NOTICE_NO_TRANSACTION, message);
|
||||
return;
|
||||
}
|
||||
|
||||
/* NOTICE: BlankPortalAssignName: portal * already exists */
|
||||
if (!strncmp(message,"BlankPortalAssignName: portal",29)
|
||||
&& strstr(message+29,"already exists"))
|
||||
|
||||
/* NOTICE: BlankPortalAssignName: portal * already exists */
|
||||
if (!strncmp(message, "BlankPortalAssignName: portal", 29)
|
||||
&& strstr(message + 29, "already exists"))
|
||||
{
|
||||
ECPGnoticeProcessor_raise(ECPG_NOTICE_PORTAL_EXISTS, message);
|
||||
return;
|
||||
}
|
||||
|
||||
/* these are harmless - do nothing */
|
||||
/* NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index '*' for table '*' */
|
||||
/* NOTICE: ALTER TABLE ... ADD CONSTRAINT will create implicit trigger(s) for FOREIGN KEY check(s) */
|
||||
/* NOTICE: CREATE TABLE will create implicit sequence '*' for SERIAL column '*.*' */
|
||||
/* NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) */
|
||||
if ((!strncmp(message,"CREATE TABLE",12) || !strncmp(message,"ALTER TABLE",11))
|
||||
&& strstr(message+11,"will create implicit"))
|
||||
|
||||
/*
|
||||
* NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index '*'
|
||||
* for table '*'
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: ALTER TABLE ... ADD CONSTRAINT will create implicit
|
||||
* trigger(s) for FOREIGN KEY check(s)
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: CREATE TABLE will create implicit sequence '*' for SERIAL
|
||||
* column '*.*'
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN
|
||||
* KEY check(s)
|
||||
*/
|
||||
if ((!strncmp(message, "CREATE TABLE", 12) || !strncmp(message, "ALTER TABLE", 11))
|
||||
&& strstr(message + 11, "will create implicit"))
|
||||
return;
|
||||
|
||||
/* NOTICE: QUERY PLAN: */
|
||||
if (!strncmp(message,"QUERY PLAN:",11)) /* do we really see these? */
|
||||
|
||||
/* NOTICE: QUERY PLAN: */
|
||||
if (!strncmp(message, "QUERY PLAN:", 11)) /* do we really see these? */
|
||||
return;
|
||||
|
||||
/* NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "*" */
|
||||
if (!strncmp(message,"DROP TABLE implicitly drops",27))
|
||||
|
||||
/*
|
||||
* NOTICE: DROP TABLE implicitly drops referential integrity trigger
|
||||
* from table "*"
|
||||
*/
|
||||
if (!strncmp(message, "DROP TABLE implicitly drops", 27))
|
||||
return;
|
||||
|
||||
/* NOTICE: Caution: DROP INDEX cannot be rolled back, so don't abort now */
|
||||
if (strstr(message,"cannot be rolled back"))
|
||||
|
||||
/*
|
||||
* NOTICE: Caution: DROP INDEX cannot be rolled back, so don't abort
|
||||
* now
|
||||
*/
|
||||
if (strstr(message, "cannot be rolled back"))
|
||||
return;
|
||||
|
||||
/* these and other unmentioned should set sqlca.sqlwarn[2] */
|
||||
/* NOTICE: The ':' operator is deprecated. Use exp(x) instead. */
|
||||
/* NOTICE: Rel *: Uninitialized page 0 - fixing */
|
||||
/* NOTICE: PortalHeapMemoryFree: * not in alloc set! */
|
||||
/* NOTICE: Too old parent tuple found - can't continue vc_repair_frag */
|
||||
/* NOTICE: identifier "*" will be truncated to "*" */
|
||||
/* NOTICE: InvalidateSharedInvalid: cache state reset */
|
||||
/* NOTICE: RegisterSharedInvalid: SI buffer overflow */
|
||||
sqlca.sqlwarn[2]='W';
|
||||
sqlca.sqlwarn[0]='W';
|
||||
/* NOTICE: The ':' operator is deprecated. Use exp(x) instead. */
|
||||
/* NOTICE: Rel *: Uninitialized page 0 - fixing */
|
||||
/* NOTICE: PortalHeapMemoryFree: * not in alloc set! */
|
||||
/* NOTICE: Too old parent tuple found - can't continue vc_repair_frag */
|
||||
/* NOTICE: identifier "*" will be truncated to "*" */
|
||||
/* NOTICE: InvalidateSharedInvalid: cache state reset */
|
||||
/* NOTICE: RegisterSharedInvalid: SI buffer overflow */
|
||||
sqlca.sqlwarn[2] = 'W';
|
||||
sqlca.sqlwarn[0] = 'W';
|
||||
}
|
||||
|
||||
/* this contains some quick hacks, needs to be cleaned up, but it works */
|
||||
@@ -230,7 +258,12 @@ bool
|
||||
ECPGconnect(int lineno, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
|
||||
{
|
||||
struct connection *this;
|
||||
char *dbname = strdup(name), *host = NULL, *tmp, *port = NULL, *realname = NULL, *options = NULL;
|
||||
char *dbname = strdup(name),
|
||||
*host = NULL,
|
||||
*tmp,
|
||||
*port = NULL,
|
||||
*realname = NULL,
|
||||
*options = NULL;
|
||||
|
||||
init_sqlca();
|
||||
|
||||
@@ -239,72 +272,74 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
|
||||
|
||||
if (dbname == NULL && connection_name == NULL)
|
||||
connection_name = "DEFAULT";
|
||||
|
||||
|
||||
/* get the detail information out of dbname */
|
||||
if (strchr(dbname, '@') != NULL)
|
||||
{
|
||||
/* old style: dbname[@server][:port] */
|
||||
tmp = strrchr(dbname, ':');
|
||||
if (tmp != NULL) /* port number given */
|
||||
{
|
||||
port = strdup(tmp + 1);
|
||||
*tmp = '\0';
|
||||
}
|
||||
{
|
||||
/* old style: dbname[@server][:port] */
|
||||
tmp = strrchr(dbname, ':');
|
||||
if (tmp != NULL) /* port number given */
|
||||
{
|
||||
port = strdup(tmp + 1);
|
||||
*tmp = '\0';
|
||||
}
|
||||
|
||||
tmp = strrchr(dbname, '@');
|
||||
if (tmp != NULL) /* host name given */
|
||||
{
|
||||
host = strdup(tmp + 1);
|
||||
*tmp = '\0';
|
||||
tmp = strrchr(dbname, '@');
|
||||
if (tmp != NULL) /* host name given */
|
||||
{
|
||||
host = strdup(tmp + 1);
|
||||
*tmp = '\0';
|
||||
}
|
||||
realname = strdup(dbname);
|
||||
}
|
||||
else if (strncmp(dbname, "tcp:", 4) == 0 || strncmp(dbname, "unix:", 5) == 0)
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
int offset = 0;
|
||||
|
||||
/*
|
||||
* only allow protocols tcp and unix
|
||||
*/
|
||||
if (strncmp(dbname, "tcp:", 4) == 0)
|
||||
offset = 4;
|
||||
offset = 4;
|
||||
else if (strncmp(dbname, "unix:", 5) == 0)
|
||||
offset = 5;
|
||||
|
||||
if (strncmp(dbname + offset, "postgresql://", strlen("postgresql://")) == 0)
|
||||
{
|
||||
/*
|
||||
offset = 5;
|
||||
|
||||
if (strncmp(dbname + offset, "postgresql://", strlen("postgresql://")) == 0)
|
||||
{
|
||||
|
||||
/*
|
||||
* new style:
|
||||
* <tcp|unix>:postgresql://server[:port|:/unixsocket/path:][/dbname][?options]
|
||||
*/
|
||||
offset += strlen("postgresql://");
|
||||
|
||||
tmp = strrchr(dbname + offset, '?');
|
||||
if (tmp != NULL) /* options given */
|
||||
{
|
||||
options = strdup(tmp + 1);
|
||||
*tmp = '\0';
|
||||
}
|
||||
|
||||
tmp = strrchr(dbname + offset, '/');
|
||||
if (tmp != NULL) /* database name given */
|
||||
{
|
||||
realname = strdup(tmp + 1);
|
||||
*tmp = '\0';
|
||||
}
|
||||
|
||||
tmp = strrchr(dbname + offset, ':');
|
||||
if (tmp != NULL) /* port number or Unix socket path given */
|
||||
{
|
||||
char *tmp2;
|
||||
|
||||
*tmp = '\0';
|
||||
* <tcp|unix>:postgresql://server[:port|:/unixsocket/path:][/db
|
||||
* name][?options]
|
||||
*/
|
||||
offset += strlen("postgresql://");
|
||||
|
||||
tmp = strrchr(dbname + offset, '?');
|
||||
if (tmp != NULL) /* options given */
|
||||
{
|
||||
options = strdup(tmp + 1);
|
||||
*tmp = '\0';
|
||||
}
|
||||
|
||||
tmp = strrchr(dbname + offset, '/');
|
||||
if (tmp != NULL) /* database name given */
|
||||
{
|
||||
realname = strdup(tmp + 1);
|
||||
*tmp = '\0';
|
||||
}
|
||||
|
||||
tmp = strrchr(dbname + offset, ':');
|
||||
if (tmp != NULL) /* port number or Unix socket path given */
|
||||
{
|
||||
char *tmp2;
|
||||
|
||||
*tmp = '\0';
|
||||
if ((tmp2 = strchr(tmp + 1, ':')) != NULL)
|
||||
{
|
||||
*tmp2 = '\0';
|
||||
host = strdup(tmp + 1);
|
||||
if (strncmp(dbname, "unix:", 5) != 0)
|
||||
{
|
||||
if (strncmp(dbname, "unix:", 5) != 0)
|
||||
{
|
||||
ECPGlog("connect: socketname %s given for TCP connection in line %d\n", host, lineno);
|
||||
ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>");
|
||||
if (host)
|
||||
@@ -318,19 +353,17 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
|
||||
if (dbname)
|
||||
free(dbname);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
port = strdup(tmp + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (strncmp(dbname, "unix:", 5) == 0)
|
||||
{
|
||||
if (strcmp(dbname + offset, "localhost") != 0 && strcmp(dbname + offset, "127.0.0.1") != 0)
|
||||
{
|
||||
ECPGlog("connect: non-localhost access via sockets in line %d\n", lineno);
|
||||
}
|
||||
}
|
||||
else
|
||||
port = strdup(tmp + 1);
|
||||
}
|
||||
|
||||
if (strncmp(dbname, "unix:", 5) == 0)
|
||||
{
|
||||
if (strcmp(dbname + offset, "localhost") != 0 && strcmp(dbname + offset, "127.0.0.1") != 0)
|
||||
{
|
||||
ECPGlog("connect: non-localhost access via sockets in line %d\n", lineno);
|
||||
ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>");
|
||||
if (host)
|
||||
free(host);
|
||||
@@ -340,27 +373,25 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
|
||||
free(options);
|
||||
if (realname)
|
||||
free(realname);
|
||||
if(dbname)
|
||||
if (dbname)
|
||||
free(dbname);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
host = strdup(dbname + offset);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
host = strdup(dbname + offset);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
realname = strdup(dbname);
|
||||
|
||||
|
||||
/* add connection to our list */
|
||||
if (connection_name != NULL)
|
||||
this->name = ecpg_strdup(connection_name, lineno);
|
||||
else
|
||||
this->name = ecpg_strdup(realname, lineno);
|
||||
|
||||
|
||||
this->cache_head = NULL;
|
||||
|
||||
if (all_connections == NULL)
|
||||
@@ -371,9 +402,9 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
|
||||
actual_connection = all_connections = this;
|
||||
|
||||
ECPGlog("ECPGconnect: opening database %s on %s port %s %s%s%s%s\n",
|
||||
realname ? realname : "<DEFAULT>",
|
||||
host ? host : "<DEFAULT>",
|
||||
port ? port : "<DEFAULT>",
|
||||
realname ? realname : "<DEFAULT>",
|
||||
host ? host : "<DEFAULT>",
|
||||
port ? port : "<DEFAULT>",
|
||||
options ? "with options " : "", options ? options : "",
|
||||
user ? "for user " : "", user ? user : "");
|
||||
|
||||
@@ -389,25 +420,25 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
|
||||
free(realname);
|
||||
if (dbname)
|
||||
free(dbname);
|
||||
|
||||
|
||||
if (PQstatus(this->connection) == CONNECTION_BAD)
|
||||
{
|
||||
ecpg_finish(this);
|
||||
ECPGlog("connect: could not open database %s on %s port %s %s%s%s%s in line %d\n",
|
||||
realname ? realname : "<DEFAULT>",
|
||||
host ? host : "<DEFAULT>",
|
||||
port ? port : "<DEFAULT>",
|
||||
options ? "with options " : "", options ? options : "",
|
||||
user ? "for user " : "", user ? user : "",
|
||||
lineno);
|
||||
realname ? realname : "<DEFAULT>",
|
||||
host ? host : "<DEFAULT>",
|
||||
port ? port : "<DEFAULT>",
|
||||
options ? "with options " : "", options ? options : "",
|
||||
user ? "for user " : "", user ? user : "",
|
||||
lineno);
|
||||
ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>");
|
||||
return false;
|
||||
}
|
||||
|
||||
this->committed = true;
|
||||
this->autocommit = autocommit;
|
||||
|
||||
PQsetNoticeProcessor(this->connection,&ECPGnoticeProcessor,(void*)this);
|
||||
|
||||
PQsetNoticeProcessor(this->connection, &ECPGnoticeProcessor, (void *) this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
switch (type)
|
||||
{
|
||||
case ECPGt_char:
|
||||
case ECPGt_unsigned_char:
|
||||
case ECPGt_varchar:
|
||||
break;
|
||||
|
||||
default:
|
||||
pval++;
|
||||
break;
|
||||
case ECPGt_unsigned_char:
|
||||
case ECPGt_varchar:
|
||||
break;
|
||||
|
||||
default:
|
||||
pval++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,12 +64,12 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
break;
|
||||
#ifdef HAVE_LONG_LONG_INT_64
|
||||
case ECPGt_long_long:
|
||||
((long long int*) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
|
||||
break;
|
||||
((long long int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
|
||||
break;
|
||||
case ECPGt_unsigned_long_long:
|
||||
((unsigned long long int*) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
|
||||
break;
|
||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||
((unsigned long long int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
|
||||
break;
|
||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||
case ECPGt_NO_INDICATOR:
|
||||
if (PQgetisnull(results, act_tuple, act_field))
|
||||
{
|
||||
@@ -159,7 +159,7 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
break;
|
||||
|
||||
#ifdef HAVE_LONG_LONG_INT_64
|
||||
# ifdef HAVE_STRTOLL
|
||||
#ifdef HAVE_STRTOLL
|
||||
case ECPGt_long_long:
|
||||
if (pval)
|
||||
{
|
||||
@@ -168,15 +168,15 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
|| (!isarray && *scan_length != '\0')) /* Garbage left */
|
||||
{
|
||||
ECPGraise(lineno, ECPG_INT_FORMAT, pval);
|
||||
return (false);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
else
|
||||
((long long int *) var)[act_tuple] = 0LL;
|
||||
|
||||
else
|
||||
((long long int *) var)[act_tuple] = (long long) 0;
|
||||
|
||||
break;
|
||||
# endif /* HAVE_STRTOLL */
|
||||
# ifdef HAVE_STRTOULL
|
||||
#endif /* HAVE_STRTOLL */
|
||||
#ifdef HAVE_STRTOULL
|
||||
case ECPGt_unsigned_long_long:
|
||||
if (pval)
|
||||
{
|
||||
@@ -185,16 +185,16 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
|| (!isarray && *scan_length != '\0')) /* Garbage left */
|
||||
{
|
||||
ECPGraise(lineno, ECPG_UINT_FORMAT, pval);
|
||||
return (false);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
else
|
||||
((unsigned long long int *) var)[act_tuple] = 0LL;
|
||||
|
||||
else
|
||||
((unsigned long long int *) var)[act_tuple] = (long long) 0;
|
||||
|
||||
break;
|
||||
# endif /* HAVE_STRTOULL */
|
||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||
|
||||
#endif /* HAVE_STRTOULL */
|
||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||
|
||||
case ECPGt_float:
|
||||
case ECPGt_double:
|
||||
if (pval)
|
||||
@@ -203,10 +203,10 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
dres = strtod(pval + 1, &scan_length);
|
||||
else
|
||||
dres = strtod(pval, &scan_length);
|
||||
|
||||
|
||||
if (isarray && *scan_length == '"')
|
||||
scan_length++;
|
||||
|
||||
scan_length++;
|
||||
|
||||
if ((isarray && *scan_length != ',' && *scan_length != '}')
|
||||
|| (!isarray && *scan_length != '\0')) /* Garbage left */
|
||||
{
|
||||
@@ -236,16 +236,22 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
{
|
||||
if (pval[0] == 'f' && pval[1] == '\0')
|
||||
{
|
||||
if (offset==sizeof(char)) ((char *) var)[act_tuple] = false;
|
||||
else if (offset==sizeof(int)) ((int *) var)[act_tuple] = false;
|
||||
else ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size");
|
||||
if (offset == sizeof(char))
|
||||
((char *) var)[act_tuple] = false;
|
||||
else if (offset == sizeof(int))
|
||||
((int *) var)[act_tuple] = false;
|
||||
else
|
||||
ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size");
|
||||
break;
|
||||
}
|
||||
else if (pval[0] == 't' && pval[1] == '\0')
|
||||
{
|
||||
if (offset==sizeof(char)) ((char *) var)[act_tuple] = true;
|
||||
else if (offset==sizeof(int)) ((int *) var)[act_tuple] = true;
|
||||
else ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size");
|
||||
if (offset == sizeof(char))
|
||||
((char *) var)[act_tuple] = true;
|
||||
else if (offset == sizeof(int))
|
||||
((int *) var)[act_tuple] = true;
|
||||
else
|
||||
ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size");
|
||||
break;
|
||||
}
|
||||
else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
|
||||
|
||||
@@ -65,7 +65,7 @@ get_int_item(int lineno, void *var, enum ECPGttype vartype, int value)
|
||||
{
|
||||
switch (vartype)
|
||||
{
|
||||
case ECPGt_short:
|
||||
case ECPGt_short:
|
||||
*(short *) var = (short) value;
|
||||
break;
|
||||
case ECPGt_int:
|
||||
@@ -90,7 +90,7 @@ get_int_item(int lineno, void *var, enum ECPGttype vartype, int value)
|
||||
case ECPGt_unsigned_long_long:
|
||||
*(unsigned long long int *) var = (unsigned long long int) value;
|
||||
break;
|
||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||
case ECPGt_float:
|
||||
*(float *) var = (float) value;
|
||||
break;
|
||||
|
||||
@@ -119,15 +119,16 @@ ECPGraise(int line, int code, const char *str)
|
||||
break;
|
||||
|
||||
case ECPG_PGSQL:
|
||||
{
|
||||
int slen = strlen(str);
|
||||
/* strip trailing newline */
|
||||
if (slen > 0 && str[slen - 1] == '\n')
|
||||
slen--;
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"'%.*s' in line %d.", slen, str, line);
|
||||
break;
|
||||
}
|
||||
{
|
||||
int slen = strlen(str);
|
||||
|
||||
/* strip trailing newline */
|
||||
if (slen > 0 && str[slen - 1] == '\n')
|
||||
slen--;
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"'%.*s' in line %d.", slen, str, line);
|
||||
break;
|
||||
}
|
||||
|
||||
case ECPG_TRANS:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
|
||||
@@ -104,7 +104,7 @@ quote_postgres(char *arg, int lineno)
|
||||
return (res);
|
||||
|
||||
res[ri++] = '\'';
|
||||
|
||||
|
||||
for (i = 0; arg[i]; i++, ri++)
|
||||
{
|
||||
switch (arg[i])
|
||||
@@ -121,7 +121,7 @@ quote_postgres(char *arg, int lineno)
|
||||
|
||||
res[ri] = arg[i];
|
||||
}
|
||||
|
||||
|
||||
res[ri++] = '\'';
|
||||
res[ri] = '\0';
|
||||
|
||||
@@ -253,11 +253,10 @@ next_insert(char *text)
|
||||
|
||||
for (; *ptr != '\0' && (*ptr != '?' || string); ptr++)
|
||||
{
|
||||
if (*ptr == '\\') /* escape character */
|
||||
if (*ptr == '\\') /* escape character */
|
||||
ptr++;
|
||||
else
|
||||
if (*ptr == '\'' )
|
||||
string = string ? false : true;
|
||||
else if (*ptr == '\'')
|
||||
string = string ? false : true;
|
||||
}
|
||||
|
||||
return (*ptr == '\0') ? NULL : ptr;
|
||||
@@ -268,10 +267,11 @@ next_insert(char *text)
|
||||
*/
|
||||
|
||||
static void
|
||||
ECPGtypeinfocache_push(struct ECPGtype_information_cache **cache, int oid, bool isarray, int lineno)
|
||||
ECPGtypeinfocache_push(struct ECPGtype_information_cache ** cache, int oid, bool isarray, int lineno)
|
||||
{
|
||||
struct ECPGtype_information_cache *new_entry
|
||||
= (struct ECPGtype_information_cache *) ecpg_alloc(sizeof(struct ECPGtype_information_cache), lineno);
|
||||
struct ECPGtype_information_cache *new_entry
|
||||
= (struct ECPGtype_information_cache *) ecpg_alloc(sizeof(struct ECPGtype_information_cache), lineno);
|
||||
|
||||
new_entry->oid = oid;
|
||||
new_entry->isarray = isarray;
|
||||
new_entry->next = *cache;
|
||||
@@ -279,17 +279,21 @@ ECPGtypeinfocache_push(struct ECPGtype_information_cache **cache, int oid, bool
|
||||
}
|
||||
|
||||
static bool
|
||||
ECPGis_type_an_array(int type,const struct statement * stmt,const struct variable *var)
|
||||
ECPGis_type_an_array(int type, const struct statement * stmt, const struct variable * var)
|
||||
{
|
||||
char *array_query;
|
||||
int isarray = 0;
|
||||
PGresult *query;
|
||||
struct ECPGtype_information_cache *cache_entry;
|
||||
|
||||
if ((stmt->connection->cache_head)==NULL)
|
||||
{
|
||||
/* Text like types are not an array for ecpg, but postgres counts them as
|
||||
an array. This define reminds you to not 'correct' these values. */
|
||||
int isarray = 0;
|
||||
PGresult *query;
|
||||
struct ECPGtype_information_cache *cache_entry;
|
||||
|
||||
if ((stmt->connection->cache_head) == NULL)
|
||||
{
|
||||
|
||||
/*
|
||||
* Text like types are not an array for ecpg, but postgres counts
|
||||
* them as an array. This define reminds you to not 'correct'
|
||||
* these values.
|
||||
*/
|
||||
#define not_an_array_in_ecpg false
|
||||
|
||||
/* populate cache with well known types to speed things up */
|
||||
@@ -310,7 +314,7 @@ ECPGis_type_an_array(int type,const struct statement * stmt,const struct variabl
|
||||
ECPGtypeinfocache_push(&(stmt->connection->cache_head), OIDVECTOROID, true, stmt->lineno);
|
||||
ECPGtypeinfocache_push(&(stmt->connection->cache_head), POINTOID, true, stmt->lineno);
|
||||
ECPGtypeinfocache_push(&(stmt->connection->cache_head), LSEGOID, true, stmt->lineno);
|
||||
ECPGtypeinfocache_push(&(stmt->connection->cache_head), PATHOID, not_an_array_in_ecpg , stmt->lineno);
|
||||
ECPGtypeinfocache_push(&(stmt->connection->cache_head), PATHOID, not_an_array_in_ecpg, stmt->lineno);
|
||||
ECPGtypeinfocache_push(&(stmt->connection->cache_head), BOXOID, true, stmt->lineno);
|
||||
ECPGtypeinfocache_push(&(stmt->connection->cache_head), POLYGONOID, false, stmt->lineno);
|
||||
ECPGtypeinfocache_push(&(stmt->connection->cache_head), LINEOID, true, stmt->lineno);
|
||||
@@ -336,12 +340,12 @@ ECPGis_type_an_array(int type,const struct statement * stmt,const struct variabl
|
||||
ECPGtypeinfocache_push(&(stmt->connection->cache_head), NUMERICOID, false, stmt->lineno);
|
||||
}
|
||||
|
||||
for (cache_entry = (stmt->connection->cache_head);cache_entry != NULL;cache_entry=cache_entry->next)
|
||||
for (cache_entry = (stmt->connection->cache_head); cache_entry != NULL; cache_entry = cache_entry->next)
|
||||
{
|
||||
if (cache_entry->oid==type)
|
||||
if (cache_entry->oid == type)
|
||||
return cache_entry->isarray;
|
||||
}
|
||||
|
||||
|
||||
array_query = (char *) ecpg_alloc(strlen("select typelem from pg_type where oid=") + 11, stmt->lineno);
|
||||
sprintf(array_query, "select typelem from pg_type where oid=%d", type);
|
||||
query = PQexec(stmt->connection->connection, array_query);
|
||||
@@ -354,8 +358,7 @@ ECPGis_type_an_array(int type,const struct statement * stmt,const struct variabl
|
||||
{
|
||||
|
||||
/*
|
||||
* arrays of character strings are not yet
|
||||
* implemented
|
||||
* arrays of character strings are not yet implemented
|
||||
*/
|
||||
isarray = false;
|
||||
}
|
||||
@@ -391,7 +394,7 @@ ECPGexecute(struct statement * stmt)
|
||||
char *tobeinserted = NULL;
|
||||
char *p;
|
||||
char buff[20];
|
||||
int hostvarl = 0;
|
||||
int hostvarl = 0;
|
||||
|
||||
/*
|
||||
* Some special treatment is needed for records since we want
|
||||
@@ -422,10 +425,10 @@ ECPGexecute(struct statement * stmt)
|
||||
#ifdef HAVE_LONG_LONG_INT_64
|
||||
case ECPGt_long_long:
|
||||
case ECPGt_unsigned_long_long:
|
||||
if (*(long long int*) var->ind_value < 0LL)
|
||||
if (*(long long int *) var->ind_value < (long long) 0)
|
||||
strcpy(buff, "null");
|
||||
break;
|
||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||
break;
|
||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -583,11 +586,11 @@ ECPGexecute(struct statement * stmt)
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
}
|
||||
else
|
||||
sprintf(mallocedval, "%llu", *((unsigned long long*) var->value));
|
||||
sprintf(mallocedval, "%llu", *((unsigned long long *) var->value));
|
||||
|
||||
tobeinserted = mallocedval;
|
||||
break;
|
||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||
case ECPGt_float:
|
||||
if (!(mallocedval = ecpg_alloc(var->arrsize * 20, stmt->lineno)))
|
||||
return false;
|
||||
@@ -634,11 +637,15 @@ ECPGexecute(struct statement * stmt)
|
||||
{
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
if (var->offset==sizeof(char))
|
||||
if (var->offset == sizeof(char))
|
||||
for (element = 0; element < var->arrsize; element++)
|
||||
sprintf(mallocedval + strlen(mallocedval), "%c,", (((char *) var->value)[element]) ? 't' : 'f');
|
||||
/* this is necessary since sizeof(C++'s bool)==sizeof(int) */
|
||||
else if (var->offset==sizeof(int))
|
||||
|
||||
/*
|
||||
* this is necessary since sizeof(C++'s
|
||||
* bool)==sizeof(int)
|
||||
*/
|
||||
else if (var->offset == sizeof(int))
|
||||
for (element = 0; element < var->arrsize; element++)
|
||||
sprintf(mallocedval + strlen(mallocedval), "%c,", (((int *) var->value)[element]) ? 't' : 'f');
|
||||
else
|
||||
@@ -648,9 +655,9 @@ ECPGexecute(struct statement * stmt)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (var->offset==sizeof(char))
|
||||
if (var->offset == sizeof(char))
|
||||
sprintf(mallocedval, "'%c'", (*((char *) var->value)) ? 't' : 'f');
|
||||
else if (var->offset==sizeof(int))
|
||||
else if (var->offset == sizeof(int))
|
||||
sprintf(mallocedval, "'%c'", (*((int *) var->value)) ? 't' : 'f');
|
||||
else
|
||||
ECPGraise(stmt->lineno, ECPG_CONVERT_BOOL, "different size");
|
||||
@@ -734,6 +741,7 @@ ECPGexecute(struct statement * stmt)
|
||||
strcpy(newcopy, copiedquery);
|
||||
if ((p = next_insert(newcopy + hostvarl)) == NULL)
|
||||
{
|
||||
|
||||
/*
|
||||
* We have an argument but we dont have the matched up string
|
||||
* in the string
|
||||
@@ -932,9 +940,9 @@ ECPGexecute(struct statement * stmt)
|
||||
sqlca.sqlerrd[1] = atol(PQoidStatus(results));
|
||||
sqlca.sqlerrd[2] = atol(PQcmdTuples(results));
|
||||
ECPGlog("ECPGexecute line %d Ok: %s\n", stmt->lineno, PQcmdStatus(results));
|
||||
if (!sqlca.sqlerrd[2] && (!strncmp(PQcmdStatus(results),"UPDATE",6)
|
||||
|| !strncmp(PQcmdStatus(results),"INSERT",6)
|
||||
|| !strncmp(PQcmdStatus(results),"DELETE",6)))
|
||||
if (!sqlca.sqlerrd[2] && (!strncmp(PQcmdStatus(results), "UPDATE", 6)
|
||||
|| !strncmp(PQcmdStatus(results), "INSERT", 6)
|
||||
|| !strncmp(PQcmdStatus(results), "DELETE", 6)))
|
||||
ECPGraise(stmt->lineno, ECPG_NOT_FOUND, NULL);
|
||||
break;
|
||||
case PGRES_NONFATAL_ERROR:
|
||||
@@ -1024,7 +1032,7 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
|
||||
*
|
||||
* Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.18 2001/02/12 13:56:37 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.19 2001/03/22 04:01:19 momjian Exp $
|
||||
*/
|
||||
|
||||
PGconn *ECPG_internal_get_connection(char *name);
|
||||
|
||||
@@ -24,12 +24,12 @@ struct ECPGgeneric_varchar
|
||||
/*
|
||||
* type information cache
|
||||
*/
|
||||
|
||||
|
||||
struct ECPGtype_information_cache
|
||||
{
|
||||
struct ECPGtype_information_cache *next;
|
||||
int oid;
|
||||
bool isarray;
|
||||
struct ECPGtype_information_cache *next;
|
||||
int oid;
|
||||
bool isarray;
|
||||
};
|
||||
|
||||
/* structure to store one statement */
|
||||
@@ -47,8 +47,8 @@ struct connection
|
||||
{
|
||||
char *name;
|
||||
PGconn *connection;
|
||||
bool committed;
|
||||
int autocommit;
|
||||
struct ECPGtype_information_cache *cache_head;
|
||||
bool committed;
|
||||
int autocommit;
|
||||
struct ECPGtype_information_cache *cache_head;
|
||||
struct connection *next;
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ ECPGtype_name(enum ECPGttype typ)
|
||||
{
|
||||
switch (typ)
|
||||
{
|
||||
case ECPGt_char:
|
||||
case ECPGt_char:
|
||||
return "char";
|
||||
case ECPGt_unsigned_char:
|
||||
return "unsigned char";
|
||||
@@ -36,7 +36,7 @@ ECPGtype_name(enum ECPGttype typ)
|
||||
return "long long";
|
||||
case ECPGt_unsigned_long_long:
|
||||
return "unsigned long long";
|
||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||
#endif /* HAVE_LONG_LONG_INT_64 */
|
||||
case ECPGt_float:
|
||||
return "float";
|
||||
case ECPGt_double:
|
||||
@@ -58,18 +58,29 @@ ECPGDynamicType(Oid type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case BOOLOID: return SQL3_BOOLEAN; /* bool */
|
||||
case INT2OID: return SQL3_SMALLINT; /* int2 */
|
||||
case INT4OID: return SQL3_INTEGER;/* int4 */
|
||||
case TEXTOID: return SQL3_CHARACTER; /* text */
|
||||
case FLOAT4OID: return SQL3_REAL; /* float4 */
|
||||
case FLOAT8OID: return SQL3_DOUBLE_PRECISION; /* float8 */
|
||||
case BPCHAROID: return SQL3_CHARACTER; /* bpchar */
|
||||
case VARCHAROID: return SQL3_CHARACTER_VARYING; /* varchar */
|
||||
case DATEOID: return SQL3_DATE_TIME_TIMESTAMP; /* date */
|
||||
case TIMEOID: return SQL3_DATE_TIME_TIMESTAMP; /* time */
|
||||
case TIMESTAMPOID: return SQL3_DATE_TIME_TIMESTAMP; /* datetime */
|
||||
case NUMERICOID: return SQL3_NUMERIC;/* numeric */
|
||||
case BOOLOID:return SQL3_BOOLEAN; /* bool */
|
||||
case INT2OID:
|
||||
return SQL3_SMALLINT; /* int2 */
|
||||
case INT4OID:
|
||||
return SQL3_INTEGER;/* int4 */
|
||||
case TEXTOID:
|
||||
return SQL3_CHARACTER; /* text */
|
||||
case FLOAT4OID:
|
||||
return SQL3_REAL; /* float4 */
|
||||
case FLOAT8OID:
|
||||
return SQL3_DOUBLE_PRECISION; /* float8 */
|
||||
case BPCHAROID:
|
||||
return SQL3_CHARACTER; /* bpchar */
|
||||
case VARCHAROID:
|
||||
return SQL3_CHARACTER_VARYING; /* varchar */
|
||||
case DATEOID:
|
||||
return SQL3_DATE_TIME_TIMESTAMP; /* date */
|
||||
case TIMEOID:
|
||||
return SQL3_DATE_TIME_TIMESTAMP; /* time */
|
||||
case TIMESTAMPOID:
|
||||
return SQL3_DATE_TIME_TIMESTAMP; /* datetime */
|
||||
case NUMERICOID:
|
||||
return SQL3_NUMERIC;/* numeric */
|
||||
default:
|
||||
return -type;
|
||||
}
|
||||
|
||||
@@ -114,7 +114,8 @@ drop_descriptor(char *name, char *connection)
|
||||
}
|
||||
|
||||
struct descriptor
|
||||
*lookup_descriptor(char *name, char *connection)
|
||||
*
|
||||
lookup_descriptor(char *name, char *connection)
|
||||
{
|
||||
struct descriptor *i;
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@ usage(char *progname)
|
||||
fprintf(stderr, "ecpg - the postgresql preprocessor, version: %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
|
||||
fprintf(stderr, "Usage: %s: "
|
||||
#ifdef YYDEBUG
|
||||
"[-d]"
|
||||
"[-d]"
|
||||
#endif
|
||||
" [-v] [-t] [-I include path] [ -o output file name] [-D define name] file1 [file2] ...\n", progname);
|
||||
" [-v] [-t] [-I include path] [ -o output file name] [-D define name] file1 [file2] ...\n", progname);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -92,9 +92,9 @@ main(int argc, char *const argv[])
|
||||
case 'D':
|
||||
add_preprocessor_define(optarg);
|
||||
break;
|
||||
#ifdef YYDEBUG
|
||||
#ifdef YYDEBUG
|
||||
case 'd':
|
||||
yydebug=1;
|
||||
yydebug = 1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* lexical token lookup for reserved words in postgres embedded SQL
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.22 2001/02/21 18:53:47 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.23 2001/03/22 04:01:20 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -104,16 +104,16 @@ ScanECPGKeywordLookup(char *text)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Apply an ASCII-only downcasing. We must not use tolower() since
|
||||
* it may produce the wrong translation in some locales (eg, Turkish),
|
||||
* Apply an ASCII-only downcasing. We must not use tolower() since it
|
||||
* may produce the wrong translation in some locales (eg, Turkish),
|
||||
* and we don't trust isupper() very much either. In an ASCII-based
|
||||
* encoding the tests against A and Z are sufficient, but we also check
|
||||
* isupper() so that we will work correctly under EBCDIC. The actual
|
||||
* case conversion step should work for either ASCII or EBCDIC.
|
||||
* encoding the tests against A and Z are sufficient, but we also
|
||||
* check isupper() so that we will work correctly under EBCDIC. The
|
||||
* actual case conversion step should work for either ASCII or EBCDIC.
|
||||
*/
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
char ch = text[i];
|
||||
char ch = text[i];
|
||||
|
||||
if (ch >= 'A' && ch <= 'Z' && isupper((unsigned char) ch))
|
||||
ch += 'a' - 'A';
|
||||
|
||||
@@ -19,8 +19,10 @@ extern char *connection;
|
||||
extern char *input_filename;
|
||||
extern char *yytext,
|
||||
errortext[128];
|
||||
|
||||
#ifdef YYDEBUG
|
||||
extern int yydebug;
|
||||
extern int yydebug;
|
||||
|
||||
#endif
|
||||
extern int yylineno,
|
||||
yyleng;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.38 2001/02/21 18:53:47 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.39 2001/03/22 04:01:21 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -37,7 +37,7 @@ static ScanKeyword ScanKeywords[] = {
|
||||
{"aggregate", AGGREGATE},
|
||||
{"all", ALL},
|
||||
{"alter", ALTER},
|
||||
{"analyse", ANALYSE}, /* British spelling */
|
||||
{"analyse", ANALYSE}, /* British spelling */
|
||||
{"analyze", ANALYZE},
|
||||
{"and", AND},
|
||||
{"any", ANY},
|
||||
@@ -312,16 +312,16 @@ ScanKeywordLookup(char *text)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Apply an ASCII-only downcasing. We must not use tolower() since
|
||||
* it may produce the wrong translation in some locales (eg, Turkish),
|
||||
* Apply an ASCII-only downcasing. We must not use tolower() since it
|
||||
* may produce the wrong translation in some locales (eg, Turkish),
|
||||
* and we don't trust isupper() very much either. In an ASCII-based
|
||||
* encoding the tests against A and Z are sufficient, but we also check
|
||||
* isupper() so that we will work correctly under EBCDIC. The actual
|
||||
* case conversion step should work for either ASCII or EBCDIC.
|
||||
* encoding the tests against A and Z are sufficient, but we also
|
||||
* check isupper() so that we will work correctly under EBCDIC. The
|
||||
* actual case conversion step should work for either ASCII or EBCDIC.
|
||||
*/
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
char ch = text[i];
|
||||
char ch = text[i];
|
||||
|
||||
if (ch >= 'A' && ch <= 'Z' && isupper((unsigned char) ch))
|
||||
ch += 'a' - 'A';
|
||||
|
||||
@@ -203,10 +203,10 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *in
|
||||
{
|
||||
/* if (ind_typ == NULL)
|
||||
{
|
||||
ind_typ = &ecpg_no_indicator;
|
||||
ind_name = "no_indicator";
|
||||
ind_typ = &ecpg_no_indicator;
|
||||
ind_name = "no_indicator";
|
||||
}*/
|
||||
|
||||
|
||||
switch (typ->typ)
|
||||
{
|
||||
case ECPGt_array:
|
||||
|
||||
@@ -23,7 +23,7 @@ main(int argc, char **argv)
|
||||
avarchar[51],
|
||||
atext[51];
|
||||
time_t aabstime;
|
||||
char optstr[256];
|
||||
char optstr[256];
|
||||
|
||||
if (argc != 2)
|
||||
halt("Usage: %s database\n", argv[0]);
|
||||
|
||||
@@ -34,7 +34,7 @@ main(int argc, char **argv)
|
||||
avarchar_null,
|
||||
atext_null,
|
||||
aabstime_null;
|
||||
char optstr[256];
|
||||
char optstr[256];
|
||||
|
||||
if (argc != 2)
|
||||
halt("Usage: %s database\n", argv[0]);
|
||||
|
||||
@@ -15,7 +15,7 @@ main(int argc, char **argv)
|
||||
int row = 0;
|
||||
int count;
|
||||
char line[4000];
|
||||
char optstr[256];
|
||||
char optstr[256];
|
||||
|
||||
if (argc != 2)
|
||||
halt("Usage: %s database\n", argv[0]);
|
||||
|
||||
@@ -40,17 +40,17 @@ halt(char *format,...)
|
||||
fflush(stderr);
|
||||
|
||||
/* call one clean up function if defined */
|
||||
if ((sig_func = signal(SIGTERM, SIG_DFL)) !=SIG_DFL &&
|
||||
sig_func !=SIG_IGN)
|
||||
if ((sig_func = signal(SIGTERM, SIG_DFL)) != SIG_DFL &&
|
||||
sig_func != SIG_IGN)
|
||||
(*sig_func) (0);
|
||||
else if ((sig_func = signal(SIGHUP, SIG_DFL)) !=SIG_DFL &&
|
||||
sig_func !=SIG_IGN)
|
||||
else if ((sig_func = signal(SIGHUP, SIG_DFL)) != SIG_DFL &&
|
||||
sig_func != SIG_IGN)
|
||||
(*sig_func) (0);
|
||||
else if ((sig_func = signal(SIGINT, SIG_DFL)) !=SIG_DFL &&
|
||||
sig_func !=SIG_IGN)
|
||||
else if ((sig_func = signal(SIGINT, SIG_DFL)) != SIG_DFL &&
|
||||
sig_func != SIG_IGN)
|
||||
(*sig_func) (0);
|
||||
else if ((sig_func = signal(SIGQUIT, SIG_DFL)) !=SIG_DFL &&
|
||||
sig_func !=SIG_IGN)
|
||||
else if ((sig_func = signal(SIGQUIT, SIG_DFL)) != SIG_DFL &&
|
||||
sig_func != SIG_IGN)
|
||||
(*sig_func) (0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
PGresult *doquery(char *query);
|
||||
PGconn *connectdb(char *options);
|
||||
PGconn *connectdb(char *options);
|
||||
void disconnectdb(void);
|
||||
int fetch(void *param,...);
|
||||
int fetchwithnulls(void *param,...);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.20 2001/02/10 02:31:29 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.21 2001/03/22 04:01:23 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -87,14 +87,14 @@ Pgtcl_Init(Tcl_Interp *interp)
|
||||
|
||||
#ifdef PGTCL_USE_TCLOBJ
|
||||
Tcl_CreateObjCommand(interp,
|
||||
"pg_lo_read",
|
||||
Pg_lo_read,
|
||||
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
"pg_lo_read",
|
||||
Pg_lo_read,
|
||||
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
|
||||
Tcl_CreateObjCommand(interp,
|
||||
"pg_lo_write",
|
||||
Pg_lo_write,
|
||||
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
"pg_lo_write",
|
||||
Pg_lo_write,
|
||||
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
#else
|
||||
Tcl_CreateCommand(interp,
|
||||
"pg_lo_read",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.54 2001/02/10 02:31:29 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.55 2001/03/22 04:01:23 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -24,7 +24,7 @@
|
||||
* Local function forward declarations
|
||||
*/
|
||||
static int execute_put_values(Tcl_Interp *interp, char *array_varname,
|
||||
PGresult *result, int tupno);
|
||||
PGresult *result, int tupno);
|
||||
|
||||
|
||||
#ifdef TCL_ARRAYS
|
||||
@@ -790,7 +790,7 @@ Pg_result_errReturn:
|
||||
|
||||
the return result is the number of tuples processed. If the query
|
||||
returns tuples (i.e. a SELECT statement), the result is placed into
|
||||
variables
|
||||
variables
|
||||
**********************************/
|
||||
|
||||
int
|
||||
@@ -808,8 +808,8 @@ Pg_execute(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
char buf[64];
|
||||
|
||||
char *usage = "Wrong # of arguments\n"
|
||||
"pg_execute ?-array arrayname? ?-oid varname? "
|
||||
"connection queryString ?loop_body?";
|
||||
"pg_execute ?-array arrayname? ?-oid varname? "
|
||||
"connection queryString ?loop_body?";
|
||||
|
||||
/*
|
||||
* First we parse the options
|
||||
@@ -817,18 +817,19 @@ Pg_execute(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
i = 1;
|
||||
while (i < argc)
|
||||
{
|
||||
if (argv[i][0] != '-')
|
||||
if (argv[i][0] != '-')
|
||||
break;
|
||||
|
||||
if (strcmp(argv[i], "-array") == 0)
|
||||
{
|
||||
|
||||
/*
|
||||
* The rows should appear in an array vs. to single variables
|
||||
*/
|
||||
i++;
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
Tcl_SetResult(interp, usage, TCL_VOLATILE);
|
||||
Tcl_SetResult(interp, usage, TCL_VOLATILE);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
array_varname = argv[i++];
|
||||
@@ -837,13 +838,14 @@ Pg_execute(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
|
||||
if (strcmp(argv[i], "-oid") == 0)
|
||||
{
|
||||
|
||||
/*
|
||||
* We should place PQoidValue() somewhere
|
||||
*/
|
||||
i++;
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
Tcl_SetResult(interp, usage, TCL_VOLATILE);
|
||||
Tcl_SetResult(interp, usage, TCL_VOLATILE);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
oid_varname = argv[i++];
|
||||
@@ -854,7 +856,7 @@ Pg_execute(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Check that after option parsing at least 'connection' and 'query'
|
||||
* are left
|
||||
*/
|
||||
@@ -897,15 +899,15 @@ Pg_execute(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the oid variable to the returned oid of an INSERT statement
|
||||
* if requested (or an empty string if it wasn't an INSERT)
|
||||
* Set the oid variable to the returned oid of an INSERT statement if
|
||||
* requested (or an empty string if it wasn't an INSERT)
|
||||
*/
|
||||
if (oid_varname != NULL)
|
||||
{
|
||||
if (Tcl_SetVar(interp, oid_varname,
|
||||
PQoidStatus(result), TCL_LEAVE_ERR_MSG) != TCL_OK)
|
||||
if (Tcl_SetVar(interp, oid_varname,
|
||||
PQoidStatus(result), TCL_LEAVE_ERR_MSG) != TCL_OK)
|
||||
{
|
||||
PQclear(result);
|
||||
PQclear(result);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -919,7 +921,7 @@ Pg_execute(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
/* fall through if we have tuples */
|
||||
break;
|
||||
|
||||
case PGRES_EMPTY_QUERY:
|
||||
case PGRES_EMPTY_QUERY:
|
||||
case PGRES_COMMAND_OK:
|
||||
case PGRES_COPY_IN:
|
||||
case PGRES_COPY_OUT:
|
||||
@@ -940,11 +942,12 @@ Pg_execute(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
/*
|
||||
* We reach here only for queries that returned tuples
|
||||
*/
|
||||
if (i == argc) {
|
||||
if (i == argc)
|
||||
{
|
||||
|
||||
/*
|
||||
* We don't have a loop body. If we have at least one
|
||||
* result row, we set all the variables to the first one
|
||||
* and return.
|
||||
* We don't have a loop body. If we have at least one result row,
|
||||
* we set all the variables to the first one and return.
|
||||
*/
|
||||
if (PQntuples(result) > 0)
|
||||
{
|
||||
@@ -954,7 +957,7 @@ Pg_execute(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sprintf(buf, "%d", PQntuples(result));
|
||||
Tcl_SetResult(interp, buf, TCL_VOLATILE);
|
||||
PQclear(result);
|
||||
@@ -962,15 +965,15 @@ Pg_execute(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a loop body. For each row in the result set put the
|
||||
* values into the Tcl variables and execute the body.
|
||||
* We have a loop body. For each row in the result set put the values
|
||||
* into the Tcl variables and execute the body.
|
||||
*/
|
||||
ntup = PQntuples(result);
|
||||
for (tupno = 0; tupno < ntup; tupno++)
|
||||
{
|
||||
if (execute_put_values(interp, array_varname, result, tupno) != TCL_OK)
|
||||
if (execute_put_values(interp, array_varname, result, tupno) != TCL_OK)
|
||||
{
|
||||
PQclear(result);
|
||||
PQclear(result);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -995,12 +998,12 @@ Pg_execute(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
}
|
||||
|
||||
/*
|
||||
* At the end of the loop we put the number of rows we
|
||||
* got into the interpreter result and clear the result set.
|
||||
* At the end of the loop we put the number of rows we got into the
|
||||
* interpreter result and clear the result set.
|
||||
*/
|
||||
sprintf(buf, "%d", ntup);
|
||||
Tcl_SetResult(interp, buf, TCL_VOLATILE);
|
||||
PQclear(result);
|
||||
PQclear(result);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1011,36 +1014,35 @@ Pg_execute(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
Put the values of one tuple into Tcl variables named like the
|
||||
column names, or into an array indexed by the column names.
|
||||
**********************************/
|
||||
static int
|
||||
static int
|
||||
execute_put_values(Tcl_Interp *interp, char *array_varname,
|
||||
PGresult *result, int tupno)
|
||||
PGresult *result, int tupno)
|
||||
{
|
||||
int i;
|
||||
int n;
|
||||
char *fname;
|
||||
char *value;
|
||||
int i;
|
||||
int n;
|
||||
char *fname;
|
||||
char *value;
|
||||
|
||||
/*
|
||||
* For each column get the column name and value
|
||||
* and put it into a Tcl variable (either scalar or
|
||||
* array item)
|
||||
* For each column get the column name and value and put it into a Tcl
|
||||
* variable (either scalar or array item)
|
||||
*/
|
||||
n = PQnfields(result);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
fname = PQfname(result, i);
|
||||
fname = PQfname(result, i);
|
||||
value = PQgetvalue(result, tupno, i);
|
||||
|
||||
if (array_varname != NULL)
|
||||
{
|
||||
if (Tcl_SetVar2(interp, array_varname, fname, value,
|
||||
TCL_LEAVE_ERR_MSG) == NULL)
|
||||
return TCL_ERROR;
|
||||
if (Tcl_SetVar2(interp, array_varname, fname, value,
|
||||
TCL_LEAVE_ERR_MSG) == NULL)
|
||||
return TCL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Tcl_SetVar(interp, fname, value, TCL_LEAVE_ERR_MSG) == NULL)
|
||||
return TCL_ERROR;
|
||||
if (Tcl_SetVar(interp, fname, value, TCL_LEAVE_ERR_MSG) == NULL)
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1163,15 +1165,15 @@ Pg_lo_close(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
**********************/
|
||||
#ifdef PGTCL_USE_TCLOBJ
|
||||
int
|
||||
Pg_lo_read(ClientData cData, Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *CONST objv[])
|
||||
Pg_lo_read(ClientData cData, Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *CONST objv[])
|
||||
{
|
||||
PGconn *conn;
|
||||
int fd;
|
||||
int nbytes = 0;
|
||||
char *buf;
|
||||
Tcl_Obj *bufVar;
|
||||
Tcl_Obj *bufObj;
|
||||
Tcl_Obj *bufVar;
|
||||
Tcl_Obj *bufObj;
|
||||
int len;
|
||||
int rc = TCL_OK;
|
||||
|
||||
@@ -1182,8 +1184,8 @@ Pg_lo_read(ClientData cData, Tcl_Interp *interp, int objc,
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
conn = PgGetConnectionId(interp, Tcl_GetStringFromObj(objv[1], NULL),
|
||||
(Pg_ConnectionId **) NULL);
|
||||
conn = PgGetConnectionId(interp, Tcl_GetStringFromObj(objv[1], NULL),
|
||||
(Pg_ConnectionId **) NULL);
|
||||
if (conn == (PGconn *) NULL)
|
||||
return TCL_ERROR;
|
||||
|
||||
@@ -1205,16 +1207,17 @@ Pg_lo_read(ClientData cData, Tcl_Interp *interp, int objc,
|
||||
nbytes = lo_read(conn, fd, buf, len);
|
||||
bufObj = Tcl_NewStringObj(buf, nbytes);
|
||||
|
||||
if (Tcl_ObjSetVar2(interp, bufVar, NULL, bufObj,
|
||||
TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1) == NULL)
|
||||
if (Tcl_ObjSetVar2(interp, bufVar, NULL, bufObj,
|
||||
TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1) == NULL)
|
||||
rc = TCL_ERROR;
|
||||
else
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes));
|
||||
|
||||
|
||||
ckfree(buf);
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
int
|
||||
Pg_lo_read(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
@@ -1258,6 +1261,7 @@ Pg_lo_read(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
return TCL_OK;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***********************************
|
||||
@@ -1270,8 +1274,8 @@ Pg_lo_write
|
||||
***********************************/
|
||||
#ifdef PGTCL_USE_TCLOBJ
|
||||
int
|
||||
Pg_lo_write(ClientData cData, Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *CONST objv[])
|
||||
Pg_lo_write(ClientData cData, Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *CONST objv[])
|
||||
{
|
||||
PGconn *conn;
|
||||
char *buf;
|
||||
@@ -1286,8 +1290,8 @@ Pg_lo_write(ClientData cData, Tcl_Interp *interp, int objc,
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
conn = PgGetConnectionId(interp, Tcl_GetStringFromObj(objv[1], NULL),
|
||||
(Pg_ConnectionId **) NULL);
|
||||
conn = PgGetConnectionId(interp, Tcl_GetStringFromObj(objv[1], NULL),
|
||||
(Pg_ConnectionId **) NULL);
|
||||
if (conn == (PGconn *) NULL)
|
||||
return TCL_ERROR;
|
||||
|
||||
@@ -1312,6 +1316,7 @@ Pg_lo_write(ClientData cData, Tcl_Interp *interp, int objc,
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#else
|
||||
int
|
||||
Pg_lo_write(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
@@ -1349,6 +1354,7 @@ Pg_lo_write(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
|
||||
sprintf(interp->result, "%d", nbytes);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***********************************
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pgtclCmds.h,v 1.20 2001/01/24 19:43:29 momjian Exp $
|
||||
* $Id: pgtclCmds.h,v 1.21 2001/03/22 04:01:24 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -24,9 +24,9 @@
|
||||
* From Tcl verion 8.0 on we can make large object access binary.
|
||||
*/
|
||||
#ifdef TCL_MAJOR_VERSION
|
||||
# if (TCL_MAJOR_VERSION >= 8)
|
||||
# define PGTCL_USE_TCLOBJ
|
||||
# endif
|
||||
#if (TCL_MAJOR_VERSION >= 8)
|
||||
#define PGTCL_USE_TCLOBJ
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -85,7 +85,7 @@ extern int Pg_disconnect(
|
||||
extern int Pg_exec(
|
||||
ClientData cData, Tcl_Interp *interp, int argc, char *argv[]);
|
||||
extern int Pg_execute(
|
||||
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(
|
||||
@@ -94,18 +94,21 @@ extern int Pg_lo_open(
|
||||
ClientData cData, Tcl_Interp *interp, int argc, char *argv[]);
|
||||
extern int Pg_lo_close(
|
||||
ClientData cData, Tcl_Interp *interp, int argc, char *argv[]);
|
||||
|
||||
#ifdef PGTCL_USE_TCLOBJ
|
||||
extern int Pg_lo_read(
|
||||
ClientData cData, Tcl_Interp *interp, int objc,
|
||||
ClientData cData, Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *CONST objv[]);
|
||||
extern int Pg_lo_write(
|
||||
ClientData cData, Tcl_Interp *interp, int objc,
|
||||
ClientData cData, Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *CONST objv[]);
|
||||
|
||||
#else
|
||||
extern int Pg_lo_read(
|
||||
ClientData cData, Tcl_Interp *interp, int argc, char *argv[]);
|
||||
extern int Pg_lo_write(
|
||||
ClientData cData, Tcl_Interp *interp, int argc, char *argv[]);
|
||||
|
||||
#endif
|
||||
extern int Pg_lo_lseek(
|
||||
ClientData cData, Tcl_Interp *interp, int argc, char *argv[]);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* exceed INITIAL_EXPBUFFER_SIZE (currently 256 bytes).
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.46 2001/02/10 02:31:30 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.47 2001/03/22 04:01:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -118,7 +118,7 @@ static void
|
||||
pg_krb4_init()
|
||||
{
|
||||
char *realm;
|
||||
static int init_done = 0;
|
||||
static int init_done = 0;
|
||||
|
||||
if (init_done)
|
||||
return;
|
||||
@@ -265,7 +265,7 @@ pg_an_to_ln(char *aname)
|
||||
* Various krb5 state which is not connection specfic, and a flag to
|
||||
* indicate whether we have initialised it yet.
|
||||
*/
|
||||
static int pg_krb5_initialised;
|
||||
static int pg_krb5_initialised;
|
||||
static krb5_context pg_krb5_context;
|
||||
static krb5_ccache pg_krb5_ccache;
|
||||
static krb5_principal pg_krb5_client;
|
||||
@@ -281,7 +281,8 @@ pg_krb5_init(char *PQerrormsg)
|
||||
return STATUS_OK;
|
||||
|
||||
retval = krb5_init_context(&pg_krb5_context);
|
||||
if (retval) {
|
||||
if (retval)
|
||||
{
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
"pg_krb5_init: krb5_init_context: %s",
|
||||
error_message(retval));
|
||||
@@ -289,27 +290,30 @@ pg_krb5_init(char *PQerrormsg)
|
||||
}
|
||||
|
||||
retval = krb5_cc_default(pg_krb5_context, &pg_krb5_ccache);
|
||||
if (retval) {
|
||||
if (retval)
|
||||
{
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
"pg_krb5_init: krb5_cc_default: %s",
|
||||
error_message(retval));
|
||||
krb5_free_context(pg_krb5_context);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
retval = krb5_cc_get_principal(pg_krb5_context, pg_krb5_ccache,
|
||||
retval = krb5_cc_get_principal(pg_krb5_context, pg_krb5_ccache,
|
||||
&pg_krb5_client);
|
||||
if (retval) {
|
||||
if (retval)
|
||||
{
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
"pg_krb5_init: krb5_cc_get_principal: %s",
|
||||
error_message(retval));
|
||||
krb5_cc_close(pg_krb5_context, pg_krb5_ccache);
|
||||
krb5_free_context(pg_krb5_context);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
retval = krb5_unparse_name(pg_krb5_context, pg_krb5_client, &pg_krb5_name);
|
||||
if (retval) {
|
||||
retval = krb5_unparse_name(pg_krb5_context, pg_krb5_client, &pg_krb5_name);
|
||||
if (retval)
|
||||
{
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
"pg_krb5_init: krb5_unparse_name: %s",
|
||||
error_message(retval));
|
||||
@@ -317,7 +321,7 @@ pg_krb5_init(char *PQerrormsg)
|
||||
krb5_cc_close(pg_krb5_context, pg_krb5_ccache);
|
||||
krb5_free_context(pg_krb5_context);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
pg_krb5_name = pg_an_to_ln(pg_krb5_name);
|
||||
|
||||
@@ -351,32 +355,34 @@ pg_krb5_sendauth(char *PQerrormsg, int sock,
|
||||
const char *hostname)
|
||||
{
|
||||
krb5_error_code retval;
|
||||
int ret;
|
||||
int ret;
|
||||
krb5_principal server;
|
||||
krb5_auth_context auth_context = NULL;
|
||||
krb5_error *err_ret = NULL;
|
||||
int flags;
|
||||
krb5_error *err_ret = NULL;
|
||||
int flags;
|
||||
|
||||
ret = pg_krb5_init(PQerrormsg);
|
||||
if (ret != STATUS_OK)
|
||||
return ret;
|
||||
|
||||
retval = krb5_sname_to_principal(pg_krb5_context, hostname, PG_KRB_SRVNAM,
|
||||
retval = krb5_sname_to_principal(pg_krb5_context, hostname, PG_KRB_SRVNAM,
|
||||
KRB5_NT_SRV_HST, &server);
|
||||
if (retval) {
|
||||
if (retval)
|
||||
{
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
"pg_krb5_sendauth: krb5_sname_to_principal: %s",
|
||||
error_message(retval));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* libpq uses a non-blocking socket. But kerberos needs a blocking
|
||||
* socket, and we have to block somehow to do mutual authentication
|
||||
* anyway. So we temporarily make it blocking.
|
||||
*/
|
||||
flags = fcntl(sock, F_GETFL);
|
||||
if (flags < 0 || fcntl(sock, F_SETFL, (long)(flags & ~O_NONBLOCK))) {
|
||||
if (flags < 0 || fcntl(sock, F_SETFL, (long) (flags & ~O_NONBLOCK)))
|
||||
{
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
"pg_krb5_sendauth: fcntl: %s", strerror(errno));
|
||||
krb5_free_principal(pg_krb5_context, server);
|
||||
@@ -384,32 +390,36 @@ pg_krb5_sendauth(char *PQerrormsg, int sock,
|
||||
}
|
||||
|
||||
retval = krb5_sendauth(pg_krb5_context, &auth_context,
|
||||
(krb5_pointer) &sock, PG_KRB_SRVNAM,
|
||||
(krb5_pointer) & sock, PG_KRB_SRVNAM,
|
||||
pg_krb5_client, server,
|
||||
AP_OPTS_MUTUAL_REQUIRED,
|
||||
NULL, 0, /* no creds, use ccache instead */
|
||||
pg_krb5_ccache, &err_ret, NULL, NULL);
|
||||
if (retval) {
|
||||
if (retval == KRB5_SENDAUTH_REJECTED && err_ret) {
|
||||
if (retval)
|
||||
{
|
||||
if (retval == KRB5_SENDAUTH_REJECTED && err_ret)
|
||||
{
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
"pg_krb5_sendauth: authentication rejected: \"%*s\"",
|
||||
err_ret->text.length, err_ret->text.data);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
"pg_krb5_sendauth: krb5_sendauth: %s",
|
||||
error_message(retval));
|
||||
}
|
||||
|
||||
|
||||
if (err_ret)
|
||||
krb5_free_error(pg_krb5_context, err_ret);
|
||||
|
||||
|
||||
ret = STATUS_ERROR;
|
||||
}
|
||||
|
||||
krb5_free_principal(pg_krb5_context, server);
|
||||
|
||||
if (fcntl(sock, F_SETFL, (long)flags)) {
|
||||
|
||||
if (fcntl(sock, F_SETFL, (long) flags))
|
||||
{
|
||||
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
|
||||
"pg_krb5_sendauth: fcntl: %s", strerror(errno));
|
||||
ret = STATUS_ERROR;
|
||||
@@ -575,8 +585,8 @@ fe_getauthname(char *PQerrormsg)
|
||||
#endif
|
||||
|
||||
if (authsvc == STARTUP_MSG
|
||||
|| (authsvc == STARTUP_KRB4_MSG && !name)
|
||||
|| (authsvc == STARTUP_KRB5_MSG && !name))
|
||||
|| (authsvc == STARTUP_KRB4_MSG && !name)
|
||||
|| (authsvc == STARTUP_KRB5_MSG && !name))
|
||||
{
|
||||
#ifdef WIN32
|
||||
char username[128];
|
||||
@@ -593,7 +603,7 @@ fe_getauthname(char *PQerrormsg)
|
||||
}
|
||||
|
||||
if (authsvc != STARTUP_MSG && authsvc != STARTUP_KRB4_MSG && authsvc != STARTUP_KRB5_MSG)
|
||||
sprintf(PQerrormsg,"fe_getauthname: invalid authentication system: %d\n", authsvc);
|
||||
sprintf(PQerrormsg, "fe_getauthname: invalid authentication system: %d\n", authsvc);
|
||||
|
||||
if (name && (authn = (char *) malloc(strlen(name) + 1)))
|
||||
strcpy(authn, name);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.160 2001/02/10 02:31:30 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.161 2001/03/22 04:01:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#ifdef HAVE_NETINET_TCP_H
|
||||
# include <netinet/tcp.h>
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
@@ -65,6 +65,7 @@ inet_aton(const char *cp, struct in_addr * inp)
|
||||
|
||||
#ifdef USE_SSL
|
||||
static SSL_CTX *SSL_context = NULL;
|
||||
|
||||
#endif
|
||||
|
||||
#define NOTIFYLIST_INITIAL_SIZE 10
|
||||
@@ -108,7 +109,7 @@ static const PQconninfoOption PQconninfoOptions[] = {
|
||||
"Database-Authtype", "D", 20},
|
||||
|
||||
{"service", "PGSERVICE", NULL, NULL,
|
||||
"Database-Service", "", 20},
|
||||
"Database-Service", "", 20},
|
||||
|
||||
{"user", "PGUSER", NULL, NULL,
|
||||
"Database-User", "", 20},
|
||||
@@ -137,7 +138,7 @@ static const PQconninfoOption PQconninfoOptions[] = {
|
||||
|
||||
#ifdef USE_SSL
|
||||
{"requiressl", "PGREQUIRESSL", "0", NULL,
|
||||
"Require-SSL", "", 1 },
|
||||
"Require-SSL", "", 1},
|
||||
#endif
|
||||
|
||||
/* Terminating entry --- MUST BE LAST */
|
||||
@@ -186,8 +187,8 @@ static PQconninfoOption *conninfo_parse(const char *conninfo,
|
||||
static char *conninfo_getval(PQconninfoOption *connOptions,
|
||||
const char *keyword);
|
||||
static void defaultNoticeProcessor(void *arg, const char *message);
|
||||
static int parseServiceInfo(PQconninfoOption *options,
|
||||
PQExpBuffer errorMessage);
|
||||
static int parseServiceInfo(PQconninfoOption *options,
|
||||
PQExpBuffer errorMessage);
|
||||
|
||||
|
||||
/* ----------------
|
||||
@@ -316,7 +317,7 @@ PQconnectStart(const char *conninfo)
|
||||
conn->pgpass = tmp ? strdup(tmp) : NULL;
|
||||
#ifdef USE_SSL
|
||||
tmp = conninfo_getval(connOptions, "requiressl");
|
||||
conn->require_ssl = tmp ? (tmp[0]=='1'?true:false) : false;
|
||||
conn->require_ssl = tmp ? (tmp[0] == '1' ? true : false) : false;
|
||||
#endif
|
||||
|
||||
/* ----------
|
||||
@@ -516,7 +517,7 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
|
||||
|
||||
#ifdef USE_SSL
|
||||
if ((tmp = getenv("PGREQUIRESSL")) != NULL)
|
||||
conn->require_ssl = (tmp[0]=='1')?true:false;
|
||||
conn->require_ssl = (tmp[0] == '1') ? true : false;
|
||||
else
|
||||
conn->require_ssl = 0;
|
||||
#endif
|
||||
@@ -533,7 +534,7 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
|
||||
}
|
||||
|
||||
|
||||
#ifdef NOT_USED /* because it's broken */
|
||||
#ifdef NOT_USED /* because it's broken */
|
||||
/*
|
||||
* update_db_info -
|
||||
* get all additional info out of dbName
|
||||
@@ -542,7 +543,8 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
|
||||
static int
|
||||
update_db_info(PGconn *conn)
|
||||
{
|
||||
char *tmp, *tmp2,
|
||||
char *tmp,
|
||||
*tmp2,
|
||||
*old = conn->dbName;
|
||||
|
||||
if (strchr(conn->dbName, '@') != NULL)
|
||||
@@ -588,7 +590,8 @@ update_db_info(PGconn *conn)
|
||||
|
||||
/*
|
||||
* new style:
|
||||
* <tcp|unix>:postgresql://server[:port|:/unixsocket/path:][/dbname][?options]
|
||||
* <tcp|unix>:postgresql://server[:port|:/unixsocket/path:][/db
|
||||
* name][?options]
|
||||
*/
|
||||
offset += strlen("postgresql://");
|
||||
|
||||
@@ -611,7 +614,11 @@ update_db_info(PGconn *conn)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Why do we default only this value from the environment again? */
|
||||
|
||||
/*
|
||||
* Why do we default only this value from the environment
|
||||
* again?
|
||||
*/
|
||||
if ((tmp = getenv("PGDATABASE")) != NULL)
|
||||
{
|
||||
if (conn->dbName)
|
||||
@@ -635,10 +642,10 @@ update_db_info(PGconn *conn)
|
||||
if (strncmp(old, "unix:", 5) != 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"connectDBStart() -- "
|
||||
"socket name can only be specified with "
|
||||
"non-TCP\n");
|
||||
return 1;
|
||||
"connectDBStart() -- "
|
||||
"socket name can only be specified with "
|
||||
"non-TCP\n");
|
||||
return 1;
|
||||
}
|
||||
*tmp2 = '\0';
|
||||
if (conn->pgunixsocket)
|
||||
@@ -682,7 +689,8 @@ update_db_info(PGconn *conn)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* NOT_USED */
|
||||
|
||||
#endif /* NOT_USED */
|
||||
|
||||
|
||||
/* ----------
|
||||
@@ -696,12 +704,14 @@ connectMakeNonblocking(PGconn *conn)
|
||||
{
|
||||
#ifdef WIN32
|
||||
int on = 1;
|
||||
|
||||
if (ioctlsocket(conn->sock, FIONBIO, &on) != 0)
|
||||
#elif defined(__BEOS__)
|
||||
int on = 1;
|
||||
if (ioctl(conn->sock, FIONBIO, &on) != 0)
|
||||
int on = 1;
|
||||
|
||||
if (ioctl(conn->sock, FIONBIO, &on) != 0)
|
||||
#else
|
||||
if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) < 0)
|
||||
if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) < 0)
|
||||
#endif
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
@@ -754,7 +764,7 @@ connectFailureMessage(PGconn *conn, const char *caller, int errorno)
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"%s -- connect() failed: %s\n"
|
||||
"\tIs the postmaster running locally\n"
|
||||
"\tand accepting connections on Unix socket '%s'?\n",
|
||||
"\tand accepting connections on Unix socket '%s'?\n",
|
||||
caller,
|
||||
strerror(errorno),
|
||||
conn->raddr.un.sun_path);
|
||||
@@ -762,8 +772,8 @@ connectFailureMessage(PGconn *conn, const char *caller, int errorno)
|
||||
#endif
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"%s -- connect() failed: %s\n"
|
||||
"\tIs the postmaster running (with -i) at '%s'\n"
|
||||
"\tand accepting connections on TCP/IP port %s?\n",
|
||||
"\tIs the postmaster running (with -i) at '%s'\n"
|
||||
"\tand accepting connections on TCP/IP port %s?\n",
|
||||
caller,
|
||||
strerror(errorno),
|
||||
conn->pghost ? conn->pghost : "localhost",
|
||||
@@ -794,6 +804,7 @@ connectDBStart(PGconn *conn)
|
||||
return 0;
|
||||
|
||||
#ifdef NOT_USED
|
||||
|
||||
/*
|
||||
* parse dbName to get all additional info in it, if any
|
||||
*/
|
||||
@@ -822,7 +833,7 @@ connectDBStart(PGconn *conn)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"connectDBStart() -- "
|
||||
"invalid host address: %s\n", conn->pghostaddr);
|
||||
"invalid host address: %s\n", conn->pghostaddr);
|
||||
goto connect_errReturn;
|
||||
}
|
||||
|
||||
@@ -963,15 +974,15 @@ connectDBStart(PGconn *conn)
|
||||
if (pqPacketSend(conn, (char *) &np, sizeof(StartupPacket)) != STATUS_OK)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"connectDB() -- couldn't send SSL negotiation packet: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
"connectDB() -- couldn't send SSL negotiation packet: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
goto connect_errReturn;
|
||||
}
|
||||
/* Now receive the postmasters response */
|
||||
if (recv(conn->sock, &SSLok, 1, 0) != 1)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage, "PQconnectDB() -- couldn't read postmaster response: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
errno, strerror(errno));
|
||||
goto connect_errReturn;
|
||||
}
|
||||
if (SSLok == 'S')
|
||||
@@ -985,7 +996,7 @@ connectDBStart(PGconn *conn)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"connectDB() -- couldn't create SSL context: %s\n",
|
||||
ERR_reason_error_string(ERR_get_error()));
|
||||
ERR_reason_error_string(ERR_get_error()));
|
||||
goto connect_errReturn;
|
||||
}
|
||||
}
|
||||
@@ -995,7 +1006,7 @@ connectDBStart(PGconn *conn)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"connectDB() -- couldn't establish SSL connection: %s\n",
|
||||
ERR_reason_error_string(ERR_get_error()));
|
||||
ERR_reason_error_string(ERR_get_error()));
|
||||
goto connect_errReturn;
|
||||
}
|
||||
/* SSL connection finished. Continue to send startup packet */
|
||||
@@ -1012,15 +1023,15 @@ connectDBStart(PGconn *conn)
|
||||
else if (SSLok != 'N')
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"Received invalid negotiation response.\n");
|
||||
"Received invalid negotiation response.\n");
|
||||
goto connect_errReturn;
|
||||
}
|
||||
}
|
||||
if (conn->require_ssl && !conn->ssl)
|
||||
if (conn->require_ssl && !conn->ssl)
|
||||
{
|
||||
/* Require SSL, but server does not support/want it */
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"Server does not support SSL when SSL was required.\n");
|
||||
"Server does not support SSL when SSL was required.\n");
|
||||
goto connect_errReturn;
|
||||
}
|
||||
#endif
|
||||
@@ -1065,6 +1076,7 @@ static int
|
||||
connectDBComplete(PGconn *conn)
|
||||
{
|
||||
PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
|
||||
|
||||
if (conn == NULL || conn->status == CONNECTION_BAD)
|
||||
return 0;
|
||||
|
||||
@@ -1144,6 +1156,7 @@ PostgresPollingStatusType
|
||||
PQconnectPoll(PGconn *conn)
|
||||
{
|
||||
PGresult *res;
|
||||
|
||||
if (conn == NULL)
|
||||
return PGRES_POLLING_FAILED;
|
||||
|
||||
@@ -1621,8 +1634,11 @@ keep_going: /* We will come back to here until there
|
||||
env = getenv(envname);
|
||||
if (!env || *env == '\0')
|
||||
{
|
||||
/* query server encoding if PGCLIENTENCODING
|
||||
is not specified */
|
||||
|
||||
/*
|
||||
* query server encoding if PGCLIENTENCODING is not
|
||||
* specified
|
||||
*/
|
||||
if (!PQsendQuery(conn,
|
||||
"select getdatabaseencoding()"))
|
||||
goto error_return;
|
||||
@@ -1633,16 +1649,17 @@ keep_going: /* We will come back to here until there
|
||||
else
|
||||
{
|
||||
/* otherwise set client encoding in pg_conn struct */
|
||||
int encoding = pg_char_to_encoding(env);
|
||||
int encoding = pg_char_to_encoding(env);
|
||||
|
||||
if (encoding < 0)
|
||||
{
|
||||
strcpy(conn->errorMessage.data,
|
||||
"PGCLIENTENCODING has no valid encoding name.\n");
|
||||
"PGCLIENTENCODING has no valid encoding name.\n");
|
||||
goto error_return;
|
||||
}
|
||||
conn->client_encoding = encoding;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
case SETENV_STATE_ENCODINGS_WAIT:
|
||||
@@ -2209,7 +2226,7 @@ pqPacketSend(PGconn *conn, const char *buf, size_t len)
|
||||
|
||||
|
||||
#ifndef SYSCONFDIR
|
||||
# error "You must compile this file with SYSCONFDIR defined."
|
||||
#error "You must compile this file with SYSCONFDIR defined."
|
||||
#endif
|
||||
|
||||
#define MAXBUFSIZE 256
|
||||
@@ -2217,111 +2234,131 @@ pqPacketSend(PGconn *conn, const char *buf, size_t len)
|
||||
static int
|
||||
parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
|
||||
{
|
||||
char *service = conninfo_getval(options, "service");
|
||||
char *serviceFile = SYSCONFDIR "/pg_service.conf";
|
||||
int group_found = 0;
|
||||
int linenr=0, i;
|
||||
char *service = conninfo_getval(options, "service");
|
||||
char *serviceFile = SYSCONFDIR "/pg_service.conf";
|
||||
int group_found = 0;
|
||||
int linenr = 0,
|
||||
i;
|
||||
|
||||
if(service != NULL) {
|
||||
FILE *f;
|
||||
char buf[MAXBUFSIZE], *line;
|
||||
|
||||
f = fopen(serviceFile, "r");
|
||||
if(f == NULL) {
|
||||
printfPQExpBuffer(errorMessage, "ERROR: Service file '%s' not found\n",
|
||||
serviceFile);
|
||||
return 1;
|
||||
}
|
||||
if (service != NULL)
|
||||
{
|
||||
FILE *f;
|
||||
char buf[MAXBUFSIZE],
|
||||
*line;
|
||||
|
||||
/* As default, set the database name to the name of the service */
|
||||
for(i = 0; options[i].keyword; i++)
|
||||
if(strcmp(options[i].keyword, "dbname") == 0) {
|
||||
if(options[i].val != NULL)
|
||||
free(options[i].val);
|
||||
options[i].val = strdup(service);
|
||||
}
|
||||
|
||||
while((line = fgets(buf, MAXBUFSIZE-1, f)) != NULL) {
|
||||
linenr++;
|
||||
f = fopen(serviceFile, "r");
|
||||
if (f == NULL)
|
||||
{
|
||||
printfPQExpBuffer(errorMessage, "ERROR: Service file '%s' not found\n",
|
||||
serviceFile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(strlen(line) >= MAXBUFSIZE - 2) {
|
||||
fclose(f);
|
||||
printfPQExpBuffer(errorMessage,
|
||||
"ERROR: line %d too long in service file '%s'\n",
|
||||
linenr,
|
||||
serviceFile);
|
||||
return 2;
|
||||
}
|
||||
/* As default, set the database name to the name of the service */
|
||||
for (i = 0; options[i].keyword; i++)
|
||||
if (strcmp(options[i].keyword, "dbname") == 0)
|
||||
{
|
||||
if (options[i].val != NULL)
|
||||
free(options[i].val);
|
||||
options[i].val = strdup(service);
|
||||
}
|
||||
|
||||
/* ignore EOL at end of line */
|
||||
if(strlen(line) && line[strlen(line)-1] == '\n')
|
||||
line[strlen(line)-1] = 0;
|
||||
while ((line = fgets(buf, MAXBUFSIZE - 1, f)) != NULL)
|
||||
{
|
||||
linenr++;
|
||||
|
||||
/* ignore leading blanks */
|
||||
while(*line && isspace((unsigned char) line[0]))
|
||||
line++;
|
||||
if (strlen(line) >= MAXBUFSIZE - 2)
|
||||
{
|
||||
fclose(f);
|
||||
printfPQExpBuffer(errorMessage,
|
||||
"ERROR: line %d too long in service file '%s'\n",
|
||||
linenr,
|
||||
serviceFile);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* ignore comments and empty lines */
|
||||
if(strlen(line) == 0 || line[0] == '#')
|
||||
continue;
|
||||
/* ignore EOL at end of line */
|
||||
if (strlen(line) && line[strlen(line) - 1] == '\n')
|
||||
line[strlen(line) - 1] = 0;
|
||||
|
||||
/* Check for right groupname */
|
||||
if(line[0] == '[')
|
||||
{
|
||||
if(group_found) {
|
||||
/* group info already read */
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
/* ignore leading blanks */
|
||||
while (*line && isspace((unsigned char) line[0]))
|
||||
line++;
|
||||
|
||||
if(strncmp(line+1, service, strlen(service)) == 0 &&
|
||||
line[strlen(service)+1] == ']')
|
||||
group_found = 1;
|
||||
else
|
||||
group_found = 0;
|
||||
} else {
|
||||
if(group_found) {
|
||||
/* Finally, we are in the right group and can parse the line */
|
||||
char *key, *val;
|
||||
int found_keyword;
|
||||
/* ignore comments and empty lines */
|
||||
if (strlen(line) == 0 || line[0] == '#')
|
||||
continue;
|
||||
|
||||
key = strtok(line, "=");
|
||||
if(key == NULL) {
|
||||
printfPQExpBuffer(errorMessage,
|
||||
"ERROR: syntax error in service file '%s', line %d\n",
|
||||
serviceFile,
|
||||
linenr);
|
||||
fclose(f);
|
||||
return 3;
|
||||
}
|
||||
val = line + strlen(line) + 1;
|
||||
|
||||
found_keyword = 0;
|
||||
for(i = 0; options[i].keyword; i++) {
|
||||
if(strcmp(options[i].keyword, key) == 0) {
|
||||
if(options[i].val != NULL)
|
||||
free(options[i].val);
|
||||
options[i].val = strdup(val);
|
||||
found_keyword = 1;
|
||||
}
|
||||
}
|
||||
/* Check for right groupname */
|
||||
if (line[0] == '[')
|
||||
{
|
||||
if (group_found)
|
||||
{
|
||||
/* group info already read */
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!found_keyword) {
|
||||
printfPQExpBuffer(errorMessage,
|
||||
"ERROR: syntax error in service file '%s', line %d\n",
|
||||
serviceFile,
|
||||
linenr);
|
||||
fclose(f);
|
||||
return 3;
|
||||
}
|
||||
if (strncmp(line + 1, service, strlen(service)) == 0 &&
|
||||
line[strlen(service) + 1] == ']')
|
||||
group_found = 1;
|
||||
else
|
||||
group_found = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (group_found)
|
||||
{
|
||||
|
||||
/*
|
||||
* Finally, we are in the right group and can parse
|
||||
* the line
|
||||
*/
|
||||
char *key,
|
||||
*val;
|
||||
int found_keyword;
|
||||
|
||||
key = strtok(line, "=");
|
||||
if (key == NULL)
|
||||
{
|
||||
printfPQExpBuffer(errorMessage,
|
||||
"ERROR: syntax error in service file '%s', line %d\n",
|
||||
serviceFile,
|
||||
linenr);
|
||||
fclose(f);
|
||||
return 3;
|
||||
}
|
||||
val = line + strlen(line) + 1;
|
||||
|
||||
found_keyword = 0;
|
||||
for (i = 0; options[i].keyword; i++)
|
||||
{
|
||||
if (strcmp(options[i].keyword, key) == 0)
|
||||
{
|
||||
if (options[i].val != NULL)
|
||||
free(options[i].val);
|
||||
options[i].val = strdup(val);
|
||||
found_keyword = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_keyword)
|
||||
{
|
||||
printfPQExpBuffer(errorMessage,
|
||||
"ERROR: syntax error in service file '%s', line %d\n",
|
||||
serviceFile,
|
||||
linenr);
|
||||
fclose(f);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2500,11 +2537,12 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage)
|
||||
|
||||
}
|
||||
|
||||
/* Now check for service info */
|
||||
if(parseServiceInfo(options, errorMessage)) {
|
||||
PQconninfoFree(options);
|
||||
free(buf);
|
||||
return NULL;
|
||||
/* Now check for service info */
|
||||
if (parseServiceInfo(options, errorMessage))
|
||||
{
|
||||
PQconninfoFree(options);
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Done with the modifiable input string */
|
||||
@@ -2749,12 +2787,14 @@ PQsetClientEncoding(PGconn *conn, const char *encoding)
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSL
|
||||
SSL *PQgetssl(PGconn *conn)
|
||||
SSL *
|
||||
PQgetssl(PGconn *conn)
|
||||
{
|
||||
if (!conn)
|
||||
return NULL;
|
||||
return conn->ssl;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
@@ -2819,31 +2859,32 @@ defaultNoticeProcessor(void *arg, const char *message)
|
||||
* if there's no valid encoding, returns -1
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int encoding; /* encoding symbol value */
|
||||
char *name; /* encoding string */
|
||||
} PQ_encoding_conv_tbl;
|
||||
typedef struct
|
||||
{
|
||||
int encoding; /* encoding symbol value */
|
||||
char *name; /* encoding string */
|
||||
} PQ_encoding_conv_tbl;
|
||||
|
||||
static PQ_encoding_conv_tbl pq_conv_tbl[] = {
|
||||
{SQL_ASCII, "SQL_ASCII"},
|
||||
{EUC_JP, "EUC_JP"},
|
||||
{EUC_CN, "EUC_CN"},
|
||||
{EUC_KR, "EUC_KR"},
|
||||
{EUC_TW, "EUC_TW"},
|
||||
{UNICODE, "UNICODE"},
|
||||
{MULE_INTERNAL, "MULE_INTERNAL"},
|
||||
{LATIN1, "LATIN1"},
|
||||
{LATIN2, "LATIN2"},
|
||||
{LATIN3, "LATIN3"},
|
||||
{LATIN4, "LATIN4"},
|
||||
{LATIN5, "LATIN5"},
|
||||
{KOI8, "KOI8"},
|
||||
{WIN, "WIN"},
|
||||
{ALT, "ALT"},
|
||||
{SJIS, "SJIS"},
|
||||
{BIG5, "BIG5"},
|
||||
{WIN1250, "WIN1250"},
|
||||
{-1, ""}
|
||||
{SQL_ASCII, "SQL_ASCII"},
|
||||
{EUC_JP, "EUC_JP"},
|
||||
{EUC_CN, "EUC_CN"},
|
||||
{EUC_KR, "EUC_KR"},
|
||||
{EUC_TW, "EUC_TW"},
|
||||
{UNICODE, "UNICODE"},
|
||||
{MULE_INTERNAL, "MULE_INTERNAL"},
|
||||
{LATIN1, "LATIN1"},
|
||||
{LATIN2, "LATIN2"},
|
||||
{LATIN3, "LATIN3"},
|
||||
{LATIN4, "LATIN4"},
|
||||
{LATIN5, "LATIN5"},
|
||||
{KOI8, "KOI8"},
|
||||
{WIN, "WIN"},
|
||||
{ALT, "ALT"},
|
||||
{SJIS, "SJIS"},
|
||||
{BIG5, "BIG5"},
|
||||
{WIN1250, "WIN1250"},
|
||||
{-1, ""}
|
||||
};
|
||||
|
||||
int
|
||||
@@ -2878,4 +2919,5 @@ pg_encoding_to_char(int encoding)
|
||||
}
|
||||
return ("");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.46 2001/02/17 03:37:22 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.47 2001/03/22 04:01:26 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -208,7 +208,7 @@ pqGetnchar(char *s, size_t len, PGconn *conn)
|
||||
conn->inCursor += len;
|
||||
|
||||
if (conn->Pfdebug)
|
||||
fprintf(conn->Pfdebug, "From backend (%lu)> %.*s\n", (unsigned long)len, (int) len, s);
|
||||
fprintf(conn->Pfdebug, "From backend (%lu)> %.*s\n", (unsigned long) len, (int) len, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -259,13 +259,13 @@ pqGetInt(int *result, size_t bytes, PGconn *conn)
|
||||
break;
|
||||
default:
|
||||
sprintf(noticeBuf,
|
||||
"pqGetInt: int size %lu not supported\n", (unsigned long)bytes);
|
||||
"pqGetInt: int size %lu not supported\n", (unsigned long) bytes);
|
||||
DONOTICE(conn, noticeBuf);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (conn->Pfdebug)
|
||||
fprintf(conn->Pfdebug, "From backend (#%lu)> %d\n", (unsigned long)bytes, *result);
|
||||
fprintf(conn->Pfdebug, "From backend (#%lu)> %d\n", (unsigned long) bytes, *result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -296,13 +296,13 @@ pqPutInt(int value, size_t bytes, PGconn *conn)
|
||||
break;
|
||||
default:
|
||||
sprintf(noticeBuf,
|
||||
"pqPutInt: int size %lu not supported\n", (unsigned long)bytes);
|
||||
"pqPutInt: int size %lu not supported\n", (unsigned long) bytes);
|
||||
DONOTICE(conn, noticeBuf);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (conn->Pfdebug)
|
||||
fprintf(conn->Pfdebug, "To backend (%lu#)> %d\n", (unsigned long)bytes, value);
|
||||
fprintf(conn->Pfdebug, "To backend (%lu#)> %d\n", (unsigned long) bytes, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -645,9 +645,9 @@ pqFlush(PGconn *conn)
|
||||
case ECONNRESET:
|
||||
#endif
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"pqFlush() -- backend closed the channel unexpectedly.\n"
|
||||
"\tThis probably means the backend terminated abnormally"
|
||||
" before or while processing the request.\n");
|
||||
"pqFlush() -- backend closed the channel unexpectedly.\n"
|
||||
"\tThis probably means the backend terminated abnormally"
|
||||
" before or while processing the request.\n");
|
||||
|
||||
/*
|
||||
* We used to close the socket here, but that's a bad
|
||||
@@ -661,8 +661,8 @@ pqFlush(PGconn *conn)
|
||||
|
||||
default:
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"pqFlush() -- couldn't send data: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
"pqFlush() -- couldn't send data: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
/* We don't assume it's a fatal error... */
|
||||
return EOF;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* didn't really belong there.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.41 2001/02/10 02:31:30 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.42 2001/03/22 04:01:27 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -92,14 +92,17 @@ PQprint(FILE *fout,
|
||||
int usePipe = 0;
|
||||
pqsigfunc oldsigpipehandler = NULL;
|
||||
char *pagerenv;
|
||||
|
||||
#ifdef TIOCGWINSZ
|
||||
struct winsize screen_size;
|
||||
|
||||
#else
|
||||
struct winsize
|
||||
{
|
||||
int ws_row;
|
||||
int ws_col;
|
||||
} screen_size;
|
||||
|
||||
#endif
|
||||
|
||||
nTups = PQntuples(res);
|
||||
@@ -149,9 +152,10 @@ PQprint(FILE *fout,
|
||||
#endif
|
||||
)
|
||||
{
|
||||
|
||||
/*
|
||||
* If we think there'll be more than one screen of output,
|
||||
* try to pipe to the pager program.
|
||||
* If we think there'll be more than one screen of output, try
|
||||
* to pipe to the pager program.
|
||||
*/
|
||||
#ifdef TIOCGWINSZ
|
||||
if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1 ||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: libpq-fe.h,v 1.70 2001/01/24 19:43:31 momjian Exp $
|
||||
* $Id: libpq-fe.h,v 1.71 2001/03/22 04:01:27 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -227,7 +227,7 @@ extern "C"
|
||||
extern int PQsetClientEncoding(PGconn *conn, const char *encoding);
|
||||
#ifdef USE_SSL
|
||||
/* Get the SSL structure associated with a connection */
|
||||
extern SSL *PQgetssl(PGconn *conn);
|
||||
extern SSL *PQgetssl(PGconn *conn);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: libpq-int.h,v 1.32 2001/02/10 02:31:30 tgl Exp $
|
||||
* $Id: libpq-int.h,v 1.33 2001/03/22 04:01:27 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -204,8 +204,9 @@ struct pg_conn
|
||||
* numbers-and-dots notation. Takes
|
||||
* precedence over above. */
|
||||
char *pgport; /* the server's communication port */
|
||||
char *pgunixsocket; /* the Unix-domain socket that the server is listening on;
|
||||
* if NULL, uses a default constructed from pgport */
|
||||
char *pgunixsocket; /* the Unix-domain socket that the server
|
||||
* is listening on; if NULL, uses a
|
||||
* default constructed from pgport */
|
||||
char *pgtty; /* tty on which the backend messages is
|
||||
* displayed (NOT ACTUALLY USED???) */
|
||||
char *pgoptions; /* options to start the backend with */
|
||||
@@ -266,7 +267,7 @@ struct pg_conn
|
||||
|
||||
#ifdef USE_SSL
|
||||
bool allow_ssl_try; /* Allowed to try SSL negotiation */
|
||||
bool require_ssl; /* Require SSL to make connection */
|
||||
bool require_ssl; /* Require SSL to make connection */
|
||||
SSL *ssl; /* SSL status, if have SSL connection */
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
|
||||
/* Module: bind.c
|
||||
/* Module: bind.c
|
||||
*
|
||||
* Description: This module contains routines related to binding
|
||||
* columns and parameters.
|
||||
* Description: This module contains routines related to binding
|
||||
* columns and parameters.
|
||||
*
|
||||
* Classes: BindInfoClass, ParameterInfoClass
|
||||
* Classes: BindInfoClass, ParameterInfoClass
|
||||
*
|
||||
* API functions: SQLBindParameter, SQLBindCol, SQLDescribeParam, SQLNumParams,
|
||||
* SQLParamOptions(NI)
|
||||
* API functions: SQLBindParameter, SQLBindCol, SQLDescribeParam, SQLNumParams,
|
||||
* SQLParamOptions(NI)
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -34,39 +34,44 @@
|
||||
#include "sqlext.h"
|
||||
#endif
|
||||
|
||||
/* Bind parameters on a statement handle */
|
||||
/* Bind parameters on a statement handle */
|
||||
|
||||
RETCODE SQL_API SQLBindParameter(
|
||||
HSTMT hstmt,
|
||||
UWORD ipar,
|
||||
SWORD fParamType,
|
||||
SWORD fCType,
|
||||
SWORD fSqlType,
|
||||
UDWORD cbColDef,
|
||||
SWORD ibScale,
|
||||
PTR rgbValue,
|
||||
SDWORD cbValueMax,
|
||||
SDWORD FAR *pcbValue)
|
||||
RETCODE SQL_API
|
||||
SQLBindParameter(
|
||||
HSTMT hstmt,
|
||||
UWORD ipar,
|
||||
SWORD fParamType,
|
||||
SWORD fCType,
|
||||
SWORD fSqlType,
|
||||
UDWORD cbColDef,
|
||||
SWORD ibScale,
|
||||
PTR rgbValue,
|
||||
SDWORD cbValueMax,
|
||||
SDWORD FAR *pcbValue)
|
||||
{
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
static char *func="SQLBindParameter";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
static char *func = "SQLBindParameter";
|
||||
|
||||
mylog( "%s: entering...\n", func);
|
||||
mylog("%s: entering...\n", func);
|
||||
|
||||
if( ! stmt) {
|
||||
if (!stmt)
|
||||
{
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if(stmt->parameters_allocated < ipar) {
|
||||
if (stmt->parameters_allocated < ipar)
|
||||
{
|
||||
ParameterInfoClass *old_parameters;
|
||||
int i, old_parameters_allocated;
|
||||
int i,
|
||||
old_parameters_allocated;
|
||||
|
||||
old_parameters = stmt->parameters;
|
||||
old_parameters_allocated = stmt->parameters_allocated;
|
||||
|
||||
stmt->parameters = (ParameterInfoClass *) malloc(sizeof(ParameterInfoClass)*(ipar));
|
||||
if ( ! stmt->parameters) {
|
||||
stmt->parameters = (ParameterInfoClass *) malloc(sizeof(ParameterInfoClass) * (ipar));
|
||||
if (!stmt->parameters)
|
||||
{
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
stmt->errormsg = "Could not allocate memory for statement parameters";
|
||||
SC_log_error(func, "", stmt);
|
||||
@@ -76,18 +81,23 @@ static char *func="SQLBindParameter";
|
||||
stmt->parameters_allocated = ipar;
|
||||
|
||||
/* copy the old parameters over */
|
||||
for(i = 0; i < old_parameters_allocated; i++) {
|
||||
for (i = 0; i < old_parameters_allocated; i++)
|
||||
{
|
||||
/* a structure copy should work */
|
||||
stmt->parameters[i] = old_parameters[i];
|
||||
}
|
||||
|
||||
/* get rid of the old parameters, if there were any */
|
||||
if(old_parameters)
|
||||
if (old_parameters)
|
||||
free(old_parameters);
|
||||
|
||||
/* zero out the newly allocated parameters (in case they skipped some, */
|
||||
/*
|
||||
* zero out the newly allocated parameters (in case they skipped
|
||||
* some,
|
||||
*/
|
||||
/* so we don't accidentally try to use them later) */
|
||||
for(; i < stmt->parameters_allocated; i++) {
|
||||
for (; i < stmt->parameters_allocated; i++)
|
||||
{
|
||||
stmt->parameters[i].buflen = 0;
|
||||
stmt->parameters[i].buffer = 0;
|
||||
stmt->parameters[i].used = 0;
|
||||
@@ -103,7 +113,8 @@ static char *func="SQLBindParameter";
|
||||
}
|
||||
}
|
||||
|
||||
ipar--; /* use zero based column numbers for the below part */
|
||||
ipar--; /* use zero based column numbers for the
|
||||
* below part */
|
||||
|
||||
/* store the given info */
|
||||
stmt->parameters[ipar].buflen = cbValueMax;
|
||||
@@ -115,74 +126,84 @@ static char *func="SQLBindParameter";
|
||||
stmt->parameters[ipar].precision = cbColDef;
|
||||
stmt->parameters[ipar].scale = ibScale;
|
||||
|
||||
/* If rebinding a parameter that had data-at-exec stuff in it,
|
||||
then free that stuff
|
||||
*/
|
||||
if (stmt->parameters[ipar].EXEC_used) {
|
||||
/*
|
||||
* If rebinding a parameter that had data-at-exec stuff in it, then
|
||||
* free that stuff
|
||||
*/
|
||||
if (stmt->parameters[ipar].EXEC_used)
|
||||
{
|
||||
free(stmt->parameters[ipar].EXEC_used);
|
||||
stmt->parameters[ipar].EXEC_used = NULL;
|
||||
}
|
||||
|
||||
if (stmt->parameters[ipar].EXEC_buffer) {
|
||||
if (stmt->parameters[ipar].EXEC_buffer)
|
||||
{
|
||||
if (stmt->parameters[ipar].SQLType != SQL_LONGVARBINARY)
|
||||
free(stmt->parameters[ipar].EXEC_buffer);
|
||||
stmt->parameters[ipar].EXEC_buffer = NULL;
|
||||
}
|
||||
|
||||
/* Data at exec macro only valid for C char/binary data */
|
||||
/* Data at exec macro only valid for C char/binary data */
|
||||
if ((fSqlType == SQL_LONGVARBINARY || fSqlType == SQL_LONGVARCHAR) && pcbValue && *pcbValue <= SQL_LEN_DATA_AT_EXEC_OFFSET)
|
||||
stmt->parameters[ipar].data_at_exec = TRUE;
|
||||
else
|
||||
stmt->parameters[ipar].data_at_exec = FALSE;
|
||||
|
||||
mylog("SQLBindParamater: ipar=%d, paramType=%d, fCType=%d, fSqlType=%d, cbColDef=%d, ibScale=%d, rgbValue=%d, *pcbValue = %d, data_at_exec = %d\n", ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, pcbValue ? *pcbValue: -777, stmt->parameters[ipar].data_at_exec);
|
||||
mylog("SQLBindParamater: ipar=%d, paramType=%d, fCType=%d, fSqlType=%d, cbColDef=%d, ibScale=%d, rgbValue=%d, *pcbValue = %d, data_at_exec = %d\n", ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, pcbValue ? *pcbValue : -777, stmt->parameters[ipar].data_at_exec);
|
||||
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - */
|
||||
/* - - - - - - - - - */
|
||||
|
||||
/* Associate a user-supplied buffer with a database column. */
|
||||
RETCODE SQL_API SQLBindCol(
|
||||
HSTMT hstmt,
|
||||
UWORD icol,
|
||||
SWORD fCType,
|
||||
PTR rgbValue,
|
||||
SDWORD cbValueMax,
|
||||
SDWORD FAR *pcbValue)
|
||||
/* Associate a user-supplied buffer with a database column. */
|
||||
RETCODE SQL_API
|
||||
SQLBindCol(
|
||||
HSTMT hstmt,
|
||||
UWORD icol,
|
||||
SWORD fCType,
|
||||
PTR rgbValue,
|
||||
SDWORD cbValueMax,
|
||||
SDWORD FAR *pcbValue)
|
||||
{
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
static char *func="SQLBindCol";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
static char *func = "SQLBindCol";
|
||||
|
||||
mylog( "%s: entering...\n", func);
|
||||
|
||||
mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
|
||||
mylog("%s: entering...\n", func);
|
||||
|
||||
if ( ! stmt) {
|
||||
mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
|
||||
|
||||
if (!stmt)
|
||||
{
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
|
||||
SC_clear_error(stmt);
|
||||
|
||||
if( stmt->status == STMT_EXECUTING) {
|
||||
|
||||
if (stmt->status == STMT_EXECUTING)
|
||||
{
|
||||
stmt->errormsg = "Can't bind columns while statement is still executing.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
/* If the bookmark column is being bound, then just save it */
|
||||
if (icol == 0) {
|
||||
/* If the bookmark column is being bound, then just save it */
|
||||
if (icol == 0)
|
||||
{
|
||||
|
||||
if (rgbValue == NULL) {
|
||||
if (rgbValue == NULL)
|
||||
{
|
||||
stmt->bookmark.buffer = NULL;
|
||||
stmt->bookmark.used = NULL;
|
||||
}
|
||||
else {
|
||||
/* Make sure it is the bookmark data type */
|
||||
if ( fCType != SQL_C_BOOKMARK) {
|
||||
else
|
||||
{
|
||||
/* Make sure it is the bookmark data type */
|
||||
if (fCType != SQL_C_BOOKMARK)
|
||||
{
|
||||
stmt->errormsg = "Column 0 is not of type SQL_C_BOOKMARK";
|
||||
stmt->errornumber = STMT_PROGRAM_TYPE_OUT_OF_RANGE;
|
||||
SC_log_error(func, "", stmt);
|
||||
@@ -195,37 +216,42 @@ mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
/* allocate enough bindings if not already done */
|
||||
/* Most likely, execution of a statement would have setup the */
|
||||
/* necessary bindings. But some apps call BindCol before any */
|
||||
/* statement is executed. */
|
||||
if ( icol > stmt->bindings_allocated)
|
||||
/* allocate enough bindings if not already done */
|
||||
/* Most likely, execution of a statement would have setup the */
|
||||
/* necessary bindings. But some apps call BindCol before any */
|
||||
/* statement is executed. */
|
||||
if (icol > stmt->bindings_allocated)
|
||||
extend_bindings(stmt, icol);
|
||||
|
||||
/* check to see if the bindings were allocated */
|
||||
if ( ! stmt->bindings) {
|
||||
/* check to see if the bindings were allocated */
|
||||
if (!stmt->bindings)
|
||||
{
|
||||
stmt->errormsg = "Could not allocate memory for bindings.";
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
icol--; /* use zero based col numbers from here out */
|
||||
icol--; /* use zero based col numbers from here
|
||||
* out */
|
||||
|
||||
/* Reset for SQLGetData */
|
||||
/* Reset for SQLGetData */
|
||||
stmt->bindings[icol].data_left = -1;
|
||||
|
||||
if (rgbValue == NULL) {
|
||||
if (rgbValue == NULL)
|
||||
{
|
||||
/* we have to unbind the column */
|
||||
stmt->bindings[icol].buflen = 0;
|
||||
stmt->bindings[icol].buffer = NULL;
|
||||
stmt->bindings[icol].used = NULL;
|
||||
stmt->bindings[icol].used = NULL;
|
||||
stmt->bindings[icol].returntype = SQL_C_CHAR;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ok, bind that column */
|
||||
stmt->bindings[icol].buflen = cbValueMax;
|
||||
stmt->bindings[icol].buffer = rgbValue;
|
||||
stmt->bindings[icol].used = pcbValue;
|
||||
stmt->bindings[icol].buflen = cbValueMax;
|
||||
stmt->bindings[icol].buffer = rgbValue;
|
||||
stmt->bindings[icol].used = pcbValue;
|
||||
stmt->bindings[icol].returntype = fCType;
|
||||
|
||||
mylog(" bound buffer[%d] = %u\n", icol, stmt->bindings[icol].buffer);
|
||||
@@ -234,34 +260,37 @@ mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - */
|
||||
/* - - - - - - - - - */
|
||||
|
||||
/* Returns the description of a parameter marker. */
|
||||
/* Returns the description of a parameter marker. */
|
||||
/* This function is listed as not being supported by SQLGetFunctions() because it is */
|
||||
/* used to describe "parameter markers" (not bound parameters), in which case, */
|
||||
/* the dbms should return info on the markers. Since Postgres doesn't support that, */
|
||||
/* it is best to say this function is not supported and let the application assume a */
|
||||
/* data type (most likely varchar). */
|
||||
|
||||
RETCODE SQL_API SQLDescribeParam(
|
||||
HSTMT hstmt,
|
||||
UWORD ipar,
|
||||
SWORD FAR *pfSqlType,
|
||||
UDWORD FAR *pcbColDef,
|
||||
SWORD FAR *pibScale,
|
||||
SWORD FAR *pfNullable)
|
||||
RETCODE SQL_API
|
||||
SQLDescribeParam(
|
||||
HSTMT hstmt,
|
||||
UWORD ipar,
|
||||
SWORD FAR *pfSqlType,
|
||||
UDWORD FAR *pcbColDef,
|
||||
SWORD FAR *pibScale,
|
||||
SWORD FAR *pfNullable)
|
||||
{
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
static char *func = "SQLDescribeParam";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
static char *func = "SQLDescribeParam";
|
||||
|
||||
mylog( "%s: entering...\n", func);
|
||||
mylog("%s: entering...\n", func);
|
||||
|
||||
if( ! stmt) {
|
||||
if (!stmt)
|
||||
{
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if( (ipar < 1) || (ipar > stmt->parameters_allocated) ) {
|
||||
if ((ipar < 1) || (ipar > stmt->parameters_allocated))
|
||||
{
|
||||
stmt->errormsg = "Invalid parameter number for SQLDescribeParam.";
|
||||
stmt->errornumber = STMT_BAD_PARAMETER_NUMBER_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
@@ -270,41 +299,45 @@ static char *func = "SQLDescribeParam";
|
||||
|
||||
ipar--;
|
||||
|
||||
/* This implementation is not very good, since it is supposed to describe */
|
||||
/* parameter markers, not bound parameters. */
|
||||
if(pfSqlType)
|
||||
/*
|
||||
* This implementation is not very good, since it is supposed to
|
||||
* describe
|
||||
*/
|
||||
/* parameter markers, not bound parameters. */
|
||||
if (pfSqlType)
|
||||
*pfSqlType = stmt->parameters[ipar].SQLType;
|
||||
|
||||
if(pcbColDef)
|
||||
if (pcbColDef)
|
||||
*pcbColDef = stmt->parameters[ipar].precision;
|
||||
|
||||
if(pibScale)
|
||||
if (pibScale)
|
||||
*pibScale = stmt->parameters[ipar].scale;
|
||||
|
||||
if(pfNullable)
|
||||
if (pfNullable)
|
||||
*pfNullable = pgtype_nullable(stmt, stmt->parameters[ipar].paramType);
|
||||
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - */
|
||||
/* - - - - - - - - - */
|
||||
|
||||
/* Sets multiple values (arrays) for the set of parameter markers. */
|
||||
/* Sets multiple values (arrays) for the set of parameter markers. */
|
||||
|
||||
RETCODE SQL_API SQLParamOptions(
|
||||
HSTMT hstmt,
|
||||
UDWORD crow,
|
||||
UDWORD FAR *pirow)
|
||||
RETCODE SQL_API
|
||||
SQLParamOptions(
|
||||
HSTMT hstmt,
|
||||
UDWORD crow,
|
||||
UDWORD FAR *pirow)
|
||||
{
|
||||
static char *func = "SQLParamOptions";
|
||||
static char *func = "SQLParamOptions";
|
||||
|
||||
mylog( "%s: entering...\n", func);
|
||||
mylog("%s: entering...\n", func);
|
||||
|
||||
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - */
|
||||
/* - - - - - - - - - */
|
||||
|
||||
/* This function should really talk to the dbms to determine the number of */
|
||||
/* "parameter markers" (not bound parameters) in the statement. But, since */
|
||||
@@ -313,43 +346,51 @@ static char *func = "SQLParamOptions";
|
||||
/* like it does for SQLDescribeParam is that some applications don't care and try */
|
||||
/* to call it anyway. */
|
||||
/* If the statement does not have parameters, it should just return 0. */
|
||||
RETCODE SQL_API SQLNumParams(
|
||||
HSTMT hstmt,
|
||||
SWORD FAR *pcpar)
|
||||
RETCODE SQL_API
|
||||
SQLNumParams(
|
||||
HSTMT hstmt,
|
||||
SWORD FAR *pcpar)
|
||||
{
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
char in_quote = FALSE;
|
||||
unsigned int i;
|
||||
static char *func = "SQLNumParams";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
char in_quote = FALSE;
|
||||
unsigned int i;
|
||||
static char *func = "SQLNumParams";
|
||||
|
||||
mylog( "%s: entering...\n", func);
|
||||
mylog("%s: entering...\n", func);
|
||||
|
||||
if(!stmt) {
|
||||
if (!stmt)
|
||||
{
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (pcpar)
|
||||
*pcpar = 0;
|
||||
else {
|
||||
else
|
||||
{
|
||||
SC_log_error(func, "pcpar was null", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if(!stmt->statement) {
|
||||
if (!stmt->statement)
|
||||
{
|
||||
/* no statement has been allocated */
|
||||
stmt->errormsg = "SQLNumParams called with no statement ready.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
for(i=0; i < strlen(stmt->statement); i++) {
|
||||
for (i = 0; i < strlen(stmt->statement); i++)
|
||||
{
|
||||
|
||||
if(stmt->statement[i] == '?' && !in_quote)
|
||||
if (stmt->statement[i] == '?' && !in_quote)
|
||||
(*pcpar)++;
|
||||
else {
|
||||
else
|
||||
{
|
||||
if (stmt->statement[i] == '\'')
|
||||
in_quote = (in_quote ? FALSE : TRUE);
|
||||
}
|
||||
@@ -360,20 +401,20 @@ static char *func = "SQLNumParams";
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Bindings Implementation
|
||||
* Bindings Implementation
|
||||
*/
|
||||
BindInfoClass *
|
||||
create_empty_bindings(int num_columns)
|
||||
{
|
||||
BindInfoClass *new_bindings;
|
||||
int i;
|
||||
BindInfoClass *new_bindings;
|
||||
int i;
|
||||
|
||||
new_bindings = (BindInfoClass *)malloc(num_columns * sizeof(BindInfoClass));
|
||||
if(!new_bindings) {
|
||||
new_bindings = (BindInfoClass *) malloc(num_columns * sizeof(BindInfoClass));
|
||||
if (!new_bindings)
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i=0; i < num_columns; i++) {
|
||||
for (i = 0; i < num_columns; i++)
|
||||
{
|
||||
new_bindings[i].buflen = 0;
|
||||
new_bindings[i].buffer = NULL;
|
||||
new_bindings[i].used = NULL;
|
||||
@@ -386,21 +427,24 @@ int i;
|
||||
void
|
||||
extend_bindings(StatementClass *stmt, int num_columns)
|
||||
{
|
||||
static char *func="extend_bindings";
|
||||
BindInfoClass *new_bindings;
|
||||
int i;
|
||||
static char *func = "extend_bindings";
|
||||
BindInfoClass *new_bindings;
|
||||
int i;
|
||||
|
||||
mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func, stmt, stmt->bindings_allocated, num_columns);
|
||||
mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func, stmt, stmt->bindings_allocated, num_columns);
|
||||
|
||||
/* if we have too few, allocate room for more, and copy the old */
|
||||
/* entries into the new structure */
|
||||
if(stmt->bindings_allocated < num_columns) {
|
||||
if (stmt->bindings_allocated < num_columns)
|
||||
{
|
||||
|
||||
new_bindings = create_empty_bindings(num_columns);
|
||||
if ( ! new_bindings) {
|
||||
mylog("%s: unable to create %d new bindings from %d old bindings\n", func, num_columns, stmt->bindings_allocated);
|
||||
if (!new_bindings)
|
||||
{
|
||||
mylog("%s: unable to create %d new bindings from %d old bindings\n", func, num_columns, stmt->bindings_allocated);
|
||||
|
||||
if (stmt->bindings) {
|
||||
if (stmt->bindings)
|
||||
{
|
||||
free(stmt->bindings);
|
||||
stmt->bindings = NULL;
|
||||
}
|
||||
@@ -408,8 +452,9 @@ mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func,
|
||||
return;
|
||||
}
|
||||
|
||||
if(stmt->bindings) {
|
||||
for(i=0; i<stmt->bindings_allocated; i++)
|
||||
if (stmt->bindings)
|
||||
{
|
||||
for (i = 0; i < stmt->bindings_allocated; i++)
|
||||
new_bindings[i] = stmt->bindings[i];
|
||||
|
||||
free(stmt->bindings);
|
||||
@@ -418,14 +463,14 @@ mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func,
|
||||
stmt->bindings = new_bindings;
|
||||
stmt->bindings_allocated = num_columns;
|
||||
|
||||
}
|
||||
/* There is no reason to zero out extra bindings if there are */
|
||||
/* more than needed. If an app has allocated extra bindings, */
|
||||
/* let it worry about it by unbinding those columns. */
|
||||
}
|
||||
/* There is no reason to zero out extra bindings if there are */
|
||||
/* more than needed. If an app has allocated extra bindings, */
|
||||
/* let it worry about it by unbinding those columns. */
|
||||
|
||||
/* SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings */
|
||||
/* SQLExecDirect(...) # returns 5 cols */
|
||||
/* SQLExecDirect(...) # returns 10 cols (now OK) */
|
||||
/* SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings */
|
||||
/* SQLExecDirect(...) # returns 5 cols */
|
||||
/* SQLExecDirect(...) # returns 10 cols (now OK) */
|
||||
|
||||
mylog("exit extend_bindings\n");
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
/* File: bind.h
|
||||
/* File: bind.h
|
||||
*
|
||||
* Description: See "bind.c"
|
||||
* Description: See "bind.c"
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -15,33 +15,40 @@
|
||||
/*
|
||||
* BindInfoClass -- stores information about a bound column
|
||||
*/
|
||||
struct BindInfoClass_ {
|
||||
Int4 buflen; /* size of buffer */
|
||||
Int4 data_left; /* amount of data left to read (SQLGetData) */
|
||||
char *buffer; /* pointer to the buffer */
|
||||
Int4 *used; /* used space in the buffer (for strings not counting the '\0') */
|
||||
Int2 returntype; /* kind of conversion to be applied when returning (SQL_C_DEFAULT, SQL_C_CHAR...) */
|
||||
struct BindInfoClass_
|
||||
{
|
||||
Int4 buflen; /* size of buffer */
|
||||
Int4 data_left; /* amount of data left to read
|
||||
* (SQLGetData) */
|
||||
char *buffer; /* pointer to the buffer */
|
||||
Int4 *used; /* used space in the buffer (for strings
|
||||
* not counting the '\0') */
|
||||
Int2 returntype; /* kind of conversion to be applied when
|
||||
* returning (SQL_C_DEFAULT,
|
||||
* SQL_C_CHAR...) */
|
||||
};
|
||||
|
||||
/*
|
||||
* ParameterInfoClass -- stores information about a bound parameter
|
||||
*/
|
||||
struct ParameterInfoClass_ {
|
||||
Int4 buflen;
|
||||
char *buffer;
|
||||
Int4 *used;
|
||||
Int2 paramType;
|
||||
Int2 CType;
|
||||
Int2 SQLType;
|
||||
UInt4 precision;
|
||||
Int2 scale;
|
||||
Oid lobj_oid;
|
||||
Int4 *EXEC_used; /* amount of data OR the oid of the large object */
|
||||
char *EXEC_buffer; /* the data or the FD of the large object */
|
||||
char data_at_exec;
|
||||
struct ParameterInfoClass_
|
||||
{
|
||||
Int4 buflen;
|
||||
char *buffer;
|
||||
Int4 *used;
|
||||
Int2 paramType;
|
||||
Int2 CType;
|
||||
Int2 SQLType;
|
||||
UInt4 precision;
|
||||
Int2 scale;
|
||||
Oid lobj_oid;
|
||||
Int4 *EXEC_used; /* amount of data OR the oid of the large
|
||||
* object */
|
||||
char *EXEC_buffer; /* the data or the FD of the large object */
|
||||
char data_at_exec;
|
||||
};
|
||||
|
||||
BindInfoClass *create_empty_bindings(int num_columns);
|
||||
void extend_bindings(StatementClass *stmt, int num_columns);
|
||||
void extend_bindings(StatementClass *stmt, int num_columns);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
|
||||
/* Module: columninfo.c
|
||||
/* Module: columninfo.c
|
||||
*
|
||||
* Description: This module contains routines related to
|
||||
* reading and storing the field information from a query.
|
||||
* Description: This module contains routines related to
|
||||
* reading and storing the field information from a query.
|
||||
*
|
||||
* Classes: ColumnInfoClass (Functions prefix: "CI_")
|
||||
* Classes: ColumnInfoClass (Functions prefix: "CI_")
|
||||
*
|
||||
* API functions: none
|
||||
* API functions: none
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -21,11 +21,12 @@
|
||||
ColumnInfoClass *
|
||||
CI_Constructor()
|
||||
{
|
||||
ColumnInfoClass *rv;
|
||||
ColumnInfoClass *rv;
|
||||
|
||||
rv = (ColumnInfoClass *) malloc(sizeof(ColumnInfoClass));
|
||||
|
||||
if (rv) {
|
||||
if (rv)
|
||||
{
|
||||
rv->num_fields = 0;
|
||||
rv->name = NULL;
|
||||
rv->adtid = NULL;
|
||||
@@ -45,21 +46,21 @@ CI_Destructor(ColumnInfoClass *self)
|
||||
free(self);
|
||||
}
|
||||
|
||||
/* Read in field descriptions.
|
||||
If self is not null, then also store the information.
|
||||
/* Read in field descriptions.
|
||||
If self is not null, then also store the information.
|
||||
If self is null, then just read, don't store.
|
||||
*/
|
||||
char
|
||||
CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
|
||||
{
|
||||
Int2 lf;
|
||||
int new_num_fields;
|
||||
Oid new_adtid;
|
||||
Int2 new_adtsize;
|
||||
Int4 new_atttypmod = -1;
|
||||
char new_field_name[MAX_MESSAGE_LEN+1];
|
||||
SocketClass *sock;
|
||||
ConnInfo *ci;
|
||||
Int2 lf;
|
||||
int new_num_fields;
|
||||
Oid new_adtid;
|
||||
Int2 new_adtsize;
|
||||
Int4 new_atttypmod = -1;
|
||||
char new_field_name[MAX_MESSAGE_LEN + 1];
|
||||
SocketClass *sock;
|
||||
ConnInfo *ci;
|
||||
|
||||
sock = CC_get_socket(conn);
|
||||
ci = &conn->connInfo;
|
||||
@@ -69,24 +70,27 @@ ConnInfo *ci;
|
||||
|
||||
mylog("num_fields = %d\n", new_num_fields);
|
||||
|
||||
if (self) { /* according to that allocate memory */
|
||||
if (self)
|
||||
{ /* according to that allocate memory */
|
||||
CI_set_num_fields(self, new_num_fields);
|
||||
}
|
||||
|
||||
/* now read in the descriptions */
|
||||
for(lf = 0; lf < new_num_fields; lf++) {
|
||||
for (lf = 0; lf < new_num_fields; lf++)
|
||||
{
|
||||
|
||||
SOCK_get_string(sock, new_field_name, MAX_MESSAGE_LEN);
|
||||
new_adtid = (Oid) SOCK_get_int(sock, 4);
|
||||
new_adtsize = (Int2) SOCK_get_int(sock, 2);
|
||||
|
||||
/* If 6.4 protocol, then read the atttypmod field */
|
||||
if (PG_VERSION_GE(conn, 6.4)) {
|
||||
/* If 6.4 protocol, then read the atttypmod field */
|
||||
if (PG_VERSION_GE(conn, 6.4))
|
||||
{
|
||||
|
||||
mylog("READING ATTTYPMOD\n");
|
||||
new_atttypmod = (Int4) SOCK_get_int(sock, 4);
|
||||
|
||||
/* Subtract the header length */
|
||||
/* Subtract the header length */
|
||||
new_atttypmod -= 4;
|
||||
if (new_atttypmod < 0)
|
||||
new_atttypmod = -1;
|
||||
@@ -107,15 +111,16 @@ ConnInfo *ci;
|
||||
void
|
||||
CI_free_memory(ColumnInfoClass *self)
|
||||
{
|
||||
register Int2 lf;
|
||||
int num_fields = self->num_fields;
|
||||
register Int2 lf;
|
||||
int num_fields = self->num_fields;
|
||||
|
||||
for (lf = 0; lf < num_fields; lf++) {
|
||||
if( self->name[lf])
|
||||
free (self->name[lf]);
|
||||
for (lf = 0; lf < num_fields; lf++)
|
||||
{
|
||||
if (self->name[lf])
|
||||
free(self->name[lf]);
|
||||
}
|
||||
|
||||
/* Safe to call even if null */
|
||||
/* Safe to call even if null */
|
||||
free(self->name);
|
||||
free(self->adtid);
|
||||
free(self->adtsize);
|
||||
@@ -127,33 +132,31 @@ int num_fields = self->num_fields;
|
||||
void
|
||||
CI_set_num_fields(ColumnInfoClass *self, int new_num_fields)
|
||||
{
|
||||
CI_free_memory(self); /* always safe to call */
|
||||
CI_free_memory(self); /* always safe to call */
|
||||
|
||||
self->num_fields = new_num_fields;
|
||||
|
||||
self->name = (char **) malloc (sizeof(char *) * self->num_fields);
|
||||
self->adtid = (Oid *) malloc (sizeof(Oid) * self->num_fields);
|
||||
self->adtsize = (Int2 *) malloc (sizeof(Int2) * self->num_fields);
|
||||
self->name = (char **) malloc(sizeof(char *) * self->num_fields);
|
||||
self->adtid = (Oid *) malloc(sizeof(Oid) * self->num_fields);
|
||||
self->adtsize = (Int2 *) malloc(sizeof(Int2) * self->num_fields);
|
||||
self->display_size = (Int2 *) malloc(sizeof(Int2) * self->num_fields);
|
||||
self->atttypmod = (Int4 *) malloc(sizeof(Int4) * self->num_fields);
|
||||
}
|
||||
|
||||
void
|
||||
CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
|
||||
Oid new_adtid, Int2 new_adtsize, Int4 new_atttypmod)
|
||||
CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
|
||||
Oid new_adtid, Int2 new_adtsize, Int4 new_atttypmod)
|
||||
{
|
||||
|
||||
|
||||
/* check bounds */
|
||||
if((field_num < 0) || (field_num >= self->num_fields)) {
|
||||
if ((field_num < 0) || (field_num >= self->num_fields))
|
||||
return;
|
||||
}
|
||||
|
||||
/* store the info */
|
||||
self->name[field_num] = strdup(new_name);
|
||||
self->name[field_num] = strdup(new_name);
|
||||
self->adtid[field_num] = new_adtid;
|
||||
self->adtsize[field_num] = new_adtsize;
|
||||
self->atttypmod[field_num] = new_atttypmod;
|
||||
|
||||
self->display_size[field_num] = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
/* File: columninfo.h
|
||||
/* File: columninfo.h
|
||||
*
|
||||
* Description: See "columninfo.c"
|
||||
* Description: See "columninfo.c"
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -12,13 +12,14 @@
|
||||
|
||||
#include "psqlodbc.h"
|
||||
|
||||
struct ColumnInfoClass_ {
|
||||
Int2 num_fields;
|
||||
char **name; /* list of type names */
|
||||
Oid *adtid; /* list of type ids */
|
||||
Int2 *adtsize; /* list type sizes */
|
||||
Int2 *display_size; /* the display size (longest row) */
|
||||
Int4 *atttypmod; /* the length of bpchar/varchar */
|
||||
struct ColumnInfoClass_
|
||||
{
|
||||
Int2 num_fields;
|
||||
char **name; /* list of type names */
|
||||
Oid *adtid; /* list of type ids */
|
||||
Int2 *adtsize; /* list type sizes */
|
||||
Int2 *display_size; /* the display size (longest row) */
|
||||
Int4 *atttypmod; /* the length of bpchar/varchar */
|
||||
};
|
||||
|
||||
#define CI_get_num_fields(self) (self->num_fields)
|
||||
@@ -29,15 +30,15 @@ struct ColumnInfoClass_ {
|
||||
#define CI_get_atttypmod(self, col) (self->atttypmod[col])
|
||||
|
||||
ColumnInfoClass *CI_Constructor(void);
|
||||
void CI_Destructor(ColumnInfoClass *self);
|
||||
void CI_free_memory(ColumnInfoClass *self);
|
||||
char CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn);
|
||||
void CI_Destructor(ColumnInfoClass *self);
|
||||
void CI_free_memory(ColumnInfoClass *self);
|
||||
char CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn);
|
||||
|
||||
/* functions for setting up the fields from within the program, */
|
||||
/* without reading from a socket */
|
||||
void CI_set_num_fields(ColumnInfoClass *self, int new_num_fields);
|
||||
void CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
|
||||
Oid new_adtid, Int2 new_adtsize, Int4 atttypmod);
|
||||
void CI_set_num_fields(ColumnInfoClass *self, int new_num_fields);
|
||||
void CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
|
||||
Oid new_adtid, Int2 new_adtsize, Int4 atttypmod);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
|
||||
/* File: connection.h
|
||||
/* File: connection.h
|
||||
*
|
||||
* Description: See "connection.c"
|
||||
* Description: See "connection.c"
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -27,11 +27,14 @@
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum {
|
||||
CONN_NOT_CONNECTED, /* Connection has not been established */
|
||||
CONN_CONNECTED, /* Connection is up and has been established */
|
||||
CONN_DOWN, /* Connection is broken */
|
||||
CONN_EXECUTING /* the connection is currently executing a statement */
|
||||
typedef enum
|
||||
{
|
||||
CONN_NOT_CONNECTED, /* Connection has not been established */
|
||||
CONN_CONNECTED, /* Connection is up and has been
|
||||
* established */
|
||||
CONN_DOWN, /* Connection is broken */
|
||||
CONN_EXECUTING /* the connection is currently executing a
|
||||
* statement */
|
||||
} CONN_Status;
|
||||
|
||||
/* These errors have general sql error state */
|
||||
@@ -50,7 +53,7 @@ typedef enum {
|
||||
#define CONN_INIREAD_ERROR 201
|
||||
#define CONN_OPENDB_ERROR 202
|
||||
#define CONN_STMT_ALLOC_ERROR 203
|
||||
#define CONN_IN_USE 204
|
||||
#define CONN_IN_USE 204
|
||||
#define CONN_UNSUPPORTED_OPTION 205
|
||||
/* Used by SetConnectoption to indicate unsupported options */
|
||||
#define CONN_INVALID_ARGUMENT_NO 206
|
||||
@@ -112,49 +115,50 @@ typedef unsigned int ProtocolVersion;
|
||||
/* This startup packet is to support latest Postgres protocol (6.4, 6.3) */
|
||||
typedef struct _StartupPacket
|
||||
{
|
||||
ProtocolVersion protoVersion;
|
||||
char database[SM_DATABASE];
|
||||
char user[SM_USER];
|
||||
char options[SM_OPTIONS];
|
||||
char unused[SM_UNUSED];
|
||||
char tty[SM_TTY];
|
||||
ProtocolVersion protoVersion;
|
||||
char database[SM_DATABASE];
|
||||
char user[SM_USER];
|
||||
char options[SM_OPTIONS];
|
||||
char unused[SM_UNUSED];
|
||||
char tty[SM_TTY];
|
||||
} StartupPacket;
|
||||
|
||||
|
||||
/* This startup packet is to support pre-Postgres 6.3 protocol */
|
||||
typedef struct _StartupPacket6_2
|
||||
{
|
||||
unsigned int authtype;
|
||||
char database[PATH_SIZE];
|
||||
char user[NAMEDATALEN];
|
||||
char options[ARGV_SIZE];
|
||||
char execfile[ARGV_SIZE];
|
||||
char tty[PATH_SIZE];
|
||||
} StartupPacket6_2;
|
||||
unsigned int authtype;
|
||||
char database[PATH_SIZE];
|
||||
char user[NAMEDATALEN];
|
||||
char options[ARGV_SIZE];
|
||||
char execfile[ARGV_SIZE];
|
||||
char tty[PATH_SIZE];
|
||||
} StartupPacket6_2;
|
||||
|
||||
|
||||
/* Structure to hold all the connection attributes for a specific
|
||||
connection (used for both registry and file, DSN and DRIVER)
|
||||
*/
|
||||
typedef struct {
|
||||
char dsn[MEDIUM_REGISTRY_LEN];
|
||||
char desc[MEDIUM_REGISTRY_LEN];
|
||||
char driver[MEDIUM_REGISTRY_LEN];
|
||||
char server[MEDIUM_REGISTRY_LEN];
|
||||
char database[MEDIUM_REGISTRY_LEN];
|
||||
char username[MEDIUM_REGISTRY_LEN];
|
||||
char password[MEDIUM_REGISTRY_LEN];
|
||||
char conn_settings[LARGE_REGISTRY_LEN];
|
||||
char protocol[SMALL_REGISTRY_LEN];
|
||||
char port[SMALL_REGISTRY_LEN];
|
||||
char onlyread[SMALL_REGISTRY_LEN];
|
||||
char fake_oid_index[SMALL_REGISTRY_LEN];
|
||||
char show_oid_column[SMALL_REGISTRY_LEN];
|
||||
char row_versioning[SMALL_REGISTRY_LEN];
|
||||
char show_system_tables[SMALL_REGISTRY_LEN];
|
||||
char translation_dll[MEDIUM_REGISTRY_LEN];
|
||||
char translation_option[SMALL_REGISTRY_LEN];
|
||||
char focus_password;
|
||||
typedef struct
|
||||
{
|
||||
char dsn[MEDIUM_REGISTRY_LEN];
|
||||
char desc[MEDIUM_REGISTRY_LEN];
|
||||
char driver[MEDIUM_REGISTRY_LEN];
|
||||
char server[MEDIUM_REGISTRY_LEN];
|
||||
char database[MEDIUM_REGISTRY_LEN];
|
||||
char username[MEDIUM_REGISTRY_LEN];
|
||||
char password[MEDIUM_REGISTRY_LEN];
|
||||
char conn_settings[LARGE_REGISTRY_LEN];
|
||||
char protocol[SMALL_REGISTRY_LEN];
|
||||
char port[SMALL_REGISTRY_LEN];
|
||||
char onlyread[SMALL_REGISTRY_LEN];
|
||||
char fake_oid_index[SMALL_REGISTRY_LEN];
|
||||
char show_oid_column[SMALL_REGISTRY_LEN];
|
||||
char row_versioning[SMALL_REGISTRY_LEN];
|
||||
char show_system_tables[SMALL_REGISTRY_LEN];
|
||||
char translation_dll[MEDIUM_REGISTRY_LEN];
|
||||
char translation_option[SMALL_REGISTRY_LEN];
|
||||
char focus_password;
|
||||
} ConnInfo;
|
||||
|
||||
/* Macro to determine is the connection using 6.2 protocol? */
|
||||
@@ -180,15 +184,15 @@ typedef struct {
|
||||
#define SERVER_VERSION_LE(conn, major, minor) (! SERVER_VERSION_GT(conn, major, minor))
|
||||
#define SERVER_VERSION_LT(conn, major, minor) (! SERVER_VERSION_GE(conn, major, minor))
|
||||
/*#if ! defined(HAVE_CONFIG_H) || defined(HAVE_STRINGIZE)*/
|
||||
#define STRING_AFTER_DOT(string) (strchr(#string, '.') + 1)
|
||||
#define STRING_AFTER_DOT(string) (strchr(#string, '.') + 1)
|
||||
/*#else
|
||||
#define STRING_AFTER_DOT(str) (strchr("str", '.') + 1)
|
||||
#define STRING_AFTER_DOT(str) (strchr("str", '.') + 1)
|
||||
#endif*/
|
||||
/*
|
||||
* Simplified macros to compare the server's version with a
|
||||
* specified version
|
||||
* Note: Never pass a variable as the second parameter.
|
||||
* It must be a decimal constant of the form %d.%d .
|
||||
* It must be a decimal constant of the form %d.%d .
|
||||
*/
|
||||
#define PG_VERSION_GT(conn, ver) \
|
||||
(SERVER_VERSION_GT(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
|
||||
@@ -200,9 +204,10 @@ typedef struct {
|
||||
#define PG_VERSION_LT(conn, ver) (! PG_VERSION_GE(conn, ver))
|
||||
|
||||
/* This is used to store cached table information in the connection */
|
||||
struct col_info {
|
||||
QResultClass *result;
|
||||
char name[MAX_TABLE_LEN+1];
|
||||
struct col_info
|
||||
{
|
||||
QResultClass *result;
|
||||
char name[MAX_TABLE_LEN + 1];
|
||||
};
|
||||
|
||||
/* Translation DLL entry points */
|
||||
@@ -214,52 +219,58 @@ struct col_info {
|
||||
#define HINSTANCE void *
|
||||
#endif
|
||||
|
||||
typedef BOOL (FAR WINAPI *DataSourceToDriverProc) (UDWORD,
|
||||
SWORD,
|
||||
PTR,
|
||||
SDWORD,
|
||||
PTR,
|
||||
SDWORD,
|
||||
SDWORD FAR *,
|
||||
UCHAR FAR *,
|
||||
SWORD,
|
||||
SWORD FAR *);
|
||||
typedef BOOL (FAR WINAPI * DataSourceToDriverProc) (UDWORD,
|
||||
SWORD,
|
||||
PTR,
|
||||
SDWORD,
|
||||
PTR,
|
||||
SDWORD,
|
||||
SDWORD FAR *,
|
||||
UCHAR FAR *,
|
||||
SWORD,
|
||||
SWORD FAR *);
|
||||
|
||||
typedef BOOL (FAR WINAPI *DriverToDataSourceProc) (UDWORD,
|
||||
SWORD,
|
||||
PTR,
|
||||
SDWORD,
|
||||
PTR,
|
||||
SDWORD,
|
||||
SDWORD FAR *,
|
||||
UCHAR FAR *,
|
||||
SWORD,
|
||||
SWORD FAR *);
|
||||
typedef BOOL (FAR WINAPI * DriverToDataSourceProc) (UDWORD,
|
||||
SWORD,
|
||||
PTR,
|
||||
SDWORD,
|
||||
PTR,
|
||||
SDWORD,
|
||||
SDWORD FAR *,
|
||||
UCHAR FAR *,
|
||||
SWORD,
|
||||
SWORD FAR *);
|
||||
|
||||
/******* The Connection handle ************/
|
||||
struct ConnectionClass_ {
|
||||
HENV henv; /* environment this connection was created on */
|
||||
struct ConnectionClass_
|
||||
{
|
||||
HENV henv; /* environment this connection was created
|
||||
* on */
|
||||
StatementOptions stmtOptions;
|
||||
char *errormsg;
|
||||
int errornumber;
|
||||
CONN_Status status;
|
||||
ConnInfo connInfo;
|
||||
StatementClass **stmts;
|
||||
int num_stmts;
|
||||
SocketClass *sock;
|
||||
int lobj_type;
|
||||
int ntables;
|
||||
COL_INFO **col_info;
|
||||
long translation_option;
|
||||
HINSTANCE translation_handle;
|
||||
DataSourceToDriverProc DataSourceToDriver;
|
||||
DriverToDataSourceProc DriverToDataSource;
|
||||
char transact_status; /* Is a transaction is currently in progress */
|
||||
char errormsg_created; /* has an informative error msg been created? */
|
||||
char pg_version[MAX_INFO_STRING]; /* Version of PostgreSQL we're connected to - DJP 25-1-2001 */
|
||||
float pg_version_number;
|
||||
Int2 pg_version_major;
|
||||
Int2 pg_version_minor;
|
||||
char *errormsg;
|
||||
int errornumber;
|
||||
CONN_Status status;
|
||||
ConnInfo connInfo;
|
||||
StatementClass **stmts;
|
||||
int num_stmts;
|
||||
SocketClass *sock;
|
||||
int lobj_type;
|
||||
int ntables;
|
||||
COL_INFO **col_info;
|
||||
long translation_option;
|
||||
HINSTANCE translation_handle;
|
||||
DataSourceToDriverProc DataSourceToDriver;
|
||||
DriverToDataSourceProc DriverToDataSource;
|
||||
char transact_status;/* Is a transaction is currently in
|
||||
* progress */
|
||||
char errormsg_created; /* has an informative error msg
|
||||
* been created? */
|
||||
char pg_version[MAX_INFO_STRING]; /* Version of PostgreSQL
|
||||
* we're connected to -
|
||||
* DJP 25-1-2001 */
|
||||
float pg_version_number;
|
||||
Int2 pg_version_major;
|
||||
Int2 pg_version_minor;
|
||||
};
|
||||
|
||||
|
||||
@@ -272,31 +283,31 @@ struct ConnectionClass_ {
|
||||
#define CC_is_onlyread(x) (x->connInfo.onlyread[0] == '1')
|
||||
|
||||
|
||||
/* for CC_DSN_info */
|
||||
/* for CC_DSN_info */
|
||||
#define CONN_DONT_OVERWRITE 0
|
||||
#define CONN_OVERWRITE 1
|
||||
#define CONN_OVERWRITE 1
|
||||
|
||||
|
||||
/* prototypes */
|
||||
ConnectionClass *CC_Constructor(void);
|
||||
char CC_Destructor(ConnectionClass *self);
|
||||
int CC_cursor_count(ConnectionClass *self);
|
||||
char CC_cleanup(ConnectionClass *self);
|
||||
char CC_abort(ConnectionClass *self);
|
||||
int CC_set_translation (ConnectionClass *self);
|
||||
char CC_connect(ConnectionClass *self, char do_password);
|
||||
char CC_add_statement(ConnectionClass *self, StatementClass *stmt);
|
||||
char CC_remove_statement(ConnectionClass *self, StatementClass *stmt);
|
||||
char CC_get_error(ConnectionClass *self, int *number, char **message);
|
||||
char CC_Destructor(ConnectionClass *self);
|
||||
int CC_cursor_count(ConnectionClass *self);
|
||||
char CC_cleanup(ConnectionClass *self);
|
||||
char CC_abort(ConnectionClass *self);
|
||||
int CC_set_translation(ConnectionClass *self);
|
||||
char CC_connect(ConnectionClass *self, char do_password);
|
||||
char CC_add_statement(ConnectionClass *self, StatementClass *stmt);
|
||||
char CC_remove_statement(ConnectionClass *self, StatementClass *stmt);
|
||||
char CC_get_error(ConnectionClass *self, int *number, char **message);
|
||||
QResultClass *CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi);
|
||||
void CC_clear_error(ConnectionClass *self);
|
||||
char *CC_create_errormsg(ConnectionClass *self);
|
||||
int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs);
|
||||
char CC_send_settings(ConnectionClass *self);
|
||||
void CC_lookup_lo(ConnectionClass *conn);
|
||||
void CC_lookup_pg_version(ConnectionClass *conn);
|
||||
void CC_initialize_pg_version(ConnectionClass *conn);
|
||||
void CC_log_error(char *func, char *desc, ConnectionClass *self);
|
||||
void CC_clear_error(ConnectionClass *self);
|
||||
char *CC_create_errormsg(ConnectionClass *self);
|
||||
int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs);
|
||||
char CC_send_settings(ConnectionClass *self);
|
||||
void CC_lookup_lo(ConnectionClass *conn);
|
||||
void CC_lookup_pg_version(ConnectionClass *conn);
|
||||
void CC_initialize_pg_version(ConnectionClass *conn);
|
||||
void CC_log_error(char *func, char *desc, ConnectionClass *self);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
|
||||
/* File: convert.h
|
||||
/* File: convert.h
|
||||
*
|
||||
* Description: See "convert.c"
|
||||
* Description: See "convert.c"
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -13,39 +13,40 @@
|
||||
#include "psqlodbc.h"
|
||||
|
||||
/* copy_and_convert results */
|
||||
#define COPY_OK 0
|
||||
#define COPY_UNSUPPORTED_TYPE 1
|
||||
#define COPY_OK 0
|
||||
#define COPY_UNSUPPORTED_TYPE 1
|
||||
#define COPY_UNSUPPORTED_CONVERSION 2
|
||||
#define COPY_RESULT_TRUNCATED 3
|
||||
#define COPY_GENERAL_ERROR 4
|
||||
#define COPY_NO_DATA_FOUND 5
|
||||
#define COPY_RESULT_TRUNCATED 3
|
||||
#define COPY_GENERAL_ERROR 4
|
||||
#define COPY_NO_DATA_FOUND 5
|
||||
|
||||
typedef struct {
|
||||
int m;
|
||||
int d;
|
||||
int y;
|
||||
int hh;
|
||||
int mm;
|
||||
int ss;
|
||||
typedef struct
|
||||
{
|
||||
int m;
|
||||
int d;
|
||||
int y;
|
||||
int hh;
|
||||
int mm;
|
||||
int ss;
|
||||
} SIMPLE_TIME;
|
||||
|
||||
int copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col);
|
||||
int copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType,
|
||||
PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue);
|
||||
int copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col);
|
||||
int copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType,
|
||||
PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue);
|
||||
|
||||
int copy_statement_with_parameters(StatementClass *stmt);
|
||||
char *convert_escape(char *value);
|
||||
char *convert_money(char *s);
|
||||
char parse_datetime(char *buf, SIMPLE_TIME *st);
|
||||
int convert_linefeeds(char *s, char *dst, size_t max);
|
||||
char *convert_special_chars(char *si, char *dst, int used);
|
||||
int copy_statement_with_parameters(StatementClass *stmt);
|
||||
char *convert_escape(char *value);
|
||||
char *convert_money(char *s);
|
||||
char parse_datetime(char *buf, SIMPLE_TIME *st);
|
||||
int convert_linefeeds(char *s, char *dst, size_t max);
|
||||
char *convert_special_chars(char *si, char *dst, int used);
|
||||
|
||||
int convert_pgbinary_to_char(char *value, char *rgbValue, int cbValueMax);
|
||||
int convert_from_pgbinary(unsigned char *value, unsigned char *rgbValue, int cbValueMax);
|
||||
int convert_to_pgbinary(unsigned char *in, char *out, int len);
|
||||
void encode(char *in, char *out);
|
||||
void decode(char *in, char *out);
|
||||
int convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
|
||||
int convert_pgbinary_to_char(char *value, char *rgbValue, int cbValueMax);
|
||||
int convert_from_pgbinary(unsigned char *value, unsigned char *rgbValue, int cbValueMax);
|
||||
int convert_to_pgbinary(unsigned char *in, char *out, int len);
|
||||
void encode(char *in, char *out);
|
||||
void decode(char *in, char *out);
|
||||
int convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
|
||||
SDWORD cbValueMax, SDWORD *pcbValue);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
|
||||
/* File: dlg_specific.h
|
||||
/* File: dlg_specific.h
|
||||
*
|
||||
* Description: See "dlg_specific.c"
|
||||
* Description: See "dlg_specific.c"
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -31,40 +31,48 @@
|
||||
|
||||
/* INI File Stuff */
|
||||
#ifndef WIN32
|
||||
# define ODBC_INI ".odbc.ini"
|
||||
# ifdef ODBCINSTDIR
|
||||
# define ODBCINST_INI ODBCINSTDIR "/odbcinst.ini"
|
||||
# else
|
||||
# define ODBCINST_INI "/etc/odbcinst.ini"
|
||||
# endif
|
||||
#else /* WIN32 */
|
||||
# define ODBC_INI "ODBC.INI" /* ODBC initialization file */
|
||||
# define ODBCINST_INI "ODBCINST.INI" /* ODBC Installation file */
|
||||
#endif /* WIN32 */
|
||||
#define ODBC_INI ".odbc.ini"
|
||||
#ifdef ODBCINSTDIR
|
||||
#define ODBCINST_INI ODBCINSTDIR "/odbcinst.ini"
|
||||
#else
|
||||
#define ODBCINST_INI "/etc/odbcinst.ini"
|
||||
#endif
|
||||
#else /* WIN32 */
|
||||
#define ODBC_INI "ODBC.INI" /* ODBC initialization file */
|
||||
#define ODBCINST_INI "ODBCINST.INI" /* ODBC Installation file */
|
||||
#endif /* WIN32 */
|
||||
|
||||
|
||||
#define INI_DSN DBMS_NAME /* Name of default Datasource in ini file (not used?) */
|
||||
#define INI_KDESC "Description" /* Data source description */
|
||||
#define INI_SERVER "Servername" /* Name of Server running the Postgres service */
|
||||
#define INI_PORT "Port" /* Port on which the Postmaster is listening */
|
||||
#define INI_DATABASE "Database" /* Database Name */
|
||||
#define INI_USER "Username" /* Default User Name */
|
||||
#define INI_PASSWORD "Password" /* Default Password */
|
||||
#define INI_DEBUG "Debug" /* Debug flag */
|
||||
#define INI_FETCH "Fetch" /* Fetch Max Count */
|
||||
#define INI_SOCKET "Socket" /* Socket buffer size */
|
||||
#define INI_READONLY "ReadOnly" /* Database is read only */
|
||||
#define INI_COMMLOG "CommLog" /* Communication to backend logging */
|
||||
#define INI_PROTOCOL "Protocol" /* What protocol (6.2) */
|
||||
#define INI_OPTIMIZER "Optimizer" /* Use backend genetic optimizer */
|
||||
#define INI_KSQO "Ksqo" /* Keyset query optimization */
|
||||
#define INI_CONNSETTINGS "ConnSettings" /* Anything to send to backend on successful connection */
|
||||
#define INI_UNIQUEINDEX "UniqueIndex" /* Recognize unique indexes */
|
||||
#define INI_UNKNOWNSIZES "UnknownSizes" /* How to handle unknown result set sizes */
|
||||
#define INI_DSN DBMS_NAME /* Name of default Datasource in
|
||||
* ini file (not used?) */
|
||||
#define INI_KDESC "Description" /* Data source description */
|
||||
#define INI_SERVER "Servername" /* Name of Server running the
|
||||
* Postgres service */
|
||||
#define INI_PORT "Port"/* Port on which the Postmaster is
|
||||
* listening */
|
||||
#define INI_DATABASE "Database" /* Database Name */
|
||||
#define INI_USER "Username" /* Default User Name */
|
||||
#define INI_PASSWORD "Password" /* Default Password */
|
||||
#define INI_DEBUG "Debug" /* Debug flag */
|
||||
#define INI_FETCH "Fetch" /* Fetch Max Count */
|
||||
#define INI_SOCKET "Socket" /* Socket buffer size */
|
||||
#define INI_READONLY "ReadOnly" /* Database is read only */
|
||||
#define INI_COMMLOG "CommLog" /* Communication to backend
|
||||
* logging */
|
||||
#define INI_PROTOCOL "Protocol" /* What protocol (6.2) */
|
||||
#define INI_OPTIMIZER "Optimizer" /* Use backend genetic optimizer */
|
||||
#define INI_KSQO "Ksqo"/* Keyset query optimization */
|
||||
#define INI_CONNSETTINGS "ConnSettings" /* Anything to send to
|
||||
* backend on successful
|
||||
* connection */
|
||||
#define INI_UNIQUEINDEX "UniqueIndex" /* Recognize unique indexes */
|
||||
#define INI_UNKNOWNSIZES "UnknownSizes" /* How to handle unknown
|
||||
* result set sizes */
|
||||
|
||||
#define INI_CANCELASFREESTMT "CancelAsFreeStmt"
|
||||
|
||||
#define INI_USEDECLAREFETCH "UseDeclareFetch" /* Use Declare/Fetch cursors */
|
||||
#define INI_USEDECLAREFETCH "UseDeclareFetch" /* Use Declare/Fetch
|
||||
* cursors */
|
||||
|
||||
/* More ini stuff */
|
||||
#define INI_TEXTASLONGVARCHAR "TextAsLongVarchar"
|
||||
@@ -81,15 +89,16 @@
|
||||
#define INI_PARSE "Parse"
|
||||
#define INI_EXTRASYSTABLEPREFIXES "ExtraSysTablePrefixes"
|
||||
|
||||
#define INI_TRANSLATIONNAME "TranslationName"
|
||||
#define INI_TRANSLATIONDLL "TranslationDLL"
|
||||
#define INI_TRANSLATIONOPTION "TranslationOption"
|
||||
#define INI_TRANSLATIONNAME "TranslationName"
|
||||
#define INI_TRANSLATIONDLL "TranslationDLL"
|
||||
#define INI_TRANSLATIONOPTION "TranslationOption"
|
||||
|
||||
|
||||
/* Connection Defaults */
|
||||
#define DEFAULT_PORT "5432"
|
||||
#define DEFAULT_READONLY 1
|
||||
#define DEFAULT_PROTOCOL "6.4" /* the latest protocol is the default */
|
||||
#define DEFAULT_PROTOCOL "6.4" /* the latest protocol is
|
||||
* the default */
|
||||
#define DEFAULT_USEDECLAREFETCH 0
|
||||
#define DEFAULT_TEXTASLONGVARCHAR 1
|
||||
#define DEFAULT_UNKNOWNSASLONGVARCHAR 0
|
||||
@@ -113,29 +122,30 @@
|
||||
|
||||
#define DEFAULT_EXTRASYSTABLEPREFIXES "dd_;"
|
||||
|
||||
/* prototypes */
|
||||
void getGlobalDefaults(char *section, char *filename, char override);
|
||||
/* prototypes */
|
||||
void getGlobalDefaults(char *section, char *filename, char override);
|
||||
|
||||
#ifdef WIN32
|
||||
void SetDlgStuff(HWND hdlg, ConnInfo *ci);
|
||||
void GetDlgStuff(HWND hdlg, ConnInfo *ci);
|
||||
void SetDlgStuff(HWND hdlg, ConnInfo *ci);
|
||||
void GetDlgStuff(HWND hdlg, ConnInfo *ci);
|
||||
|
||||
int CALLBACK driver_optionsProc(HWND hdlg,
|
||||
WORD wMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
int CALLBACK ds_optionsProc(HWND hdlg,
|
||||
WORD wMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
#endif /* WIN32 */
|
||||
int CALLBACK driver_optionsProc(HWND hdlg,
|
||||
WORD wMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
int CALLBACK ds_optionsProc(HWND hdlg,
|
||||
WORD wMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
void updateGlobals(void);
|
||||
void writeDSNinfo(ConnInfo *ci);
|
||||
void getDSNdefaults(ConnInfo *ci);
|
||||
void getDSNinfo(ConnInfo *ci, char overwrite);
|
||||
void makeConnectString(char *connect_string, ConnInfo *ci);
|
||||
void copyAttributes(ConnInfo *ci, char *attribute, char *value);
|
||||
#endif /* WIN32 */
|
||||
|
||||
void updateGlobals(void);
|
||||
void writeDSNinfo(ConnInfo *ci);
|
||||
void getDSNdefaults(ConnInfo *ci);
|
||||
void getDSNinfo(ConnInfo *ci, char overwrite);
|
||||
void makeConnectString(char *connect_string, ConnInfo *ci);
|
||||
void copyAttributes(ConnInfo *ci, char *attribute, char *value);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
|
||||
/* Module: drvconn.c
|
||||
/* Module: drvconn.c
|
||||
*
|
||||
* Description: This module contains only routines related to
|
||||
* implementing SQLDriverConnect.
|
||||
* Description: This module contains only routines related to
|
||||
* implementing SQLDriverConnect.
|
||||
*
|
||||
* Classes: n/a
|
||||
* Classes: n/a
|
||||
*
|
||||
* API functions: SQLDriverConnect
|
||||
* API functions: SQLDriverConnect
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -53,45 +53,50 @@
|
||||
#include "dlg_specific.h"
|
||||
|
||||
/* prototypes */
|
||||
void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci);
|
||||
void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci);
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL FAR PASCAL dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
|
||||
RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci);
|
||||
RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci);
|
||||
|
||||
extern HINSTANCE NEAR s_hModule;/* Saved module handle. */
|
||||
|
||||
extern HINSTANCE NEAR s_hModule; /* Saved module handle. */
|
||||
#endif
|
||||
|
||||
extern GLOBAL_VALUES globals;
|
||||
|
||||
|
||||
RETCODE SQL_API SQLDriverConnect(
|
||||
HDBC hdbc,
|
||||
HWND hwnd,
|
||||
UCHAR FAR *szConnStrIn,
|
||||
SWORD cbConnStrIn,
|
||||
UCHAR FAR *szConnStrOut,
|
||||
SWORD cbConnStrOutMax,
|
||||
SWORD FAR *pcbConnStrOut,
|
||||
UWORD fDriverCompletion)
|
||||
RETCODE SQL_API
|
||||
SQLDriverConnect(
|
||||
HDBC hdbc,
|
||||
HWND hwnd,
|
||||
UCHAR FAR *szConnStrIn,
|
||||
SWORD cbConnStrIn,
|
||||
UCHAR FAR *szConnStrOut,
|
||||
SWORD cbConnStrOutMax,
|
||||
SWORD FAR *pcbConnStrOut,
|
||||
UWORD fDriverCompletion)
|
||||
{
|
||||
static char *func = "SQLDriverConnect";
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
ConnInfo *ci;
|
||||
static char *func = "SQLDriverConnect";
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
ConnInfo *ci;
|
||||
|
||||
#ifdef WIN32
|
||||
RETCODE dialog_result;
|
||||
RETCODE dialog_result;
|
||||
|
||||
#endif
|
||||
RETCODE result;
|
||||
char connStrIn[MAX_CONNECT_STRING];
|
||||
char connStrOut[MAX_CONNECT_STRING];
|
||||
int retval;
|
||||
char password_required = FALSE;
|
||||
int len = 0;
|
||||
RETCODE result;
|
||||
char connStrIn[MAX_CONNECT_STRING];
|
||||
char connStrOut[MAX_CONNECT_STRING];
|
||||
int retval;
|
||||
char password_required = FALSE;
|
||||
int len = 0;
|
||||
|
||||
|
||||
mylog("%s: entering...\n", func);
|
||||
|
||||
if ( ! conn) {
|
||||
if (!conn)
|
||||
{
|
||||
CC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
@@ -103,17 +108,17 @@ int len = 0;
|
||||
|
||||
ci = &(conn->connInfo);
|
||||
|
||||
/* Parse the connect string and fill in conninfo for this hdbc. */
|
||||
/* Parse the connect string and fill in conninfo for this hdbc. */
|
||||
dconn_get_connect_attributes(connStrIn, ci);
|
||||
|
||||
/* If the ConnInfo in the hdbc is missing anything, */
|
||||
/* this function will fill them in from the registry (assuming */
|
||||
/* of course there is a DSN given -- if not, it does nothing!) */
|
||||
/* If the ConnInfo in the hdbc is missing anything, */
|
||||
/* this function will fill them in from the registry (assuming */
|
||||
/* of course there is a DSN given -- if not, it does nothing!) */
|
||||
getDSNinfo(ci, CONN_DONT_OVERWRITE);
|
||||
|
||||
/* Fill in any default parameters if they are not there. */
|
||||
/* Fill in any default parameters if they are not there. */
|
||||
getDSNdefaults(ci);
|
||||
/* initialize pg_version */
|
||||
/* initialize pg_version */
|
||||
CC_initialize_pg_version(conn);
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -121,51 +126,54 @@ dialog:
|
||||
#endif
|
||||
ci->focus_password = password_required;
|
||||
|
||||
switch(fDriverCompletion) {
|
||||
switch (fDriverCompletion)
|
||||
{
|
||||
#ifdef WIN32
|
||||
case SQL_DRIVER_PROMPT:
|
||||
dialog_result = dconn_DoDialog(hwnd, ci);
|
||||
if(dialog_result != SQL_SUCCESS) {
|
||||
return dialog_result;
|
||||
}
|
||||
break;
|
||||
|
||||
case SQL_DRIVER_COMPLETE_REQUIRED:
|
||||
|
||||
/* Fall through */
|
||||
|
||||
case SQL_DRIVER_COMPLETE:
|
||||
|
||||
/* Password is not a required parameter. */
|
||||
if( ci->username[0] == '\0' ||
|
||||
ci->server[0] == '\0' ||
|
||||
ci->database[0] == '\0' ||
|
||||
ci->port[0] == '\0' ||
|
||||
password_required) {
|
||||
|
||||
case SQL_DRIVER_PROMPT:
|
||||
dialog_result = dconn_DoDialog(hwnd, ci);
|
||||
if(dialog_result != SQL_SUCCESS) {
|
||||
if (dialog_result != SQL_SUCCESS)
|
||||
return dialog_result;
|
||||
break;
|
||||
|
||||
case SQL_DRIVER_COMPLETE_REQUIRED:
|
||||
|
||||
/* Fall through */
|
||||
|
||||
case SQL_DRIVER_COMPLETE:
|
||||
|
||||
/* Password is not a required parameter. */
|
||||
if (ci->username[0] == '\0' ||
|
||||
ci->server[0] == '\0' ||
|
||||
ci->database[0] == '\0' ||
|
||||
ci->port[0] == '\0' ||
|
||||
password_required)
|
||||
{
|
||||
|
||||
dialog_result = dconn_DoDialog(hwnd, ci);
|
||||
if (dialog_result != SQL_SUCCESS)
|
||||
return dialog_result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
#else
|
||||
case SQL_DRIVER_PROMPT:
|
||||
case SQL_DRIVER_COMPLETE:
|
||||
case SQL_DRIVER_COMPLETE_REQUIRED:
|
||||
case SQL_DRIVER_PROMPT:
|
||||
case SQL_DRIVER_COMPLETE:
|
||||
case SQL_DRIVER_COMPLETE_REQUIRED:
|
||||
#endif
|
||||
case SQL_DRIVER_NOPROMPT:
|
||||
break;
|
||||
case SQL_DRIVER_NOPROMPT:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Password is not a required parameter unless authentication asks for it.
|
||||
For now, I think it's better to just let the application ask over and over until
|
||||
a password is entered (the user can always hit Cancel to get out)
|
||||
*/
|
||||
if( ci->username[0] == '\0' ||
|
||||
/*
|
||||
* Password is not a required parameter unless authentication asks for
|
||||
* it. For now, I think it's better to just let the application ask
|
||||
* over and over until a password is entered (the user can always hit
|
||||
* Cancel to get out)
|
||||
*/
|
||||
if (ci->username[0] == '\0' ||
|
||||
ci->server[0] == '\0' ||
|
||||
ci->database[0] == '\0' ||
|
||||
ci->port[0] == '\0') {
|
||||
ci->database[0] == '\0' ||
|
||||
ci->port[0] == '\0')
|
||||
{
|
||||
/* (password_required && ci->password[0] == '\0')) */
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
@@ -174,12 +182,16 @@ dialog:
|
||||
|
||||
/* do the actual connect */
|
||||
retval = CC_connect(conn, password_required);
|
||||
if (retval < 0) { /* need a password */
|
||||
if (fDriverCompletion == SQL_DRIVER_NOPROMPT) {
|
||||
if (retval < 0)
|
||||
{ /* need a password */
|
||||
if (fDriverCompletion == SQL_DRIVER_NOPROMPT)
|
||||
{
|
||||
CC_log_error(func, "Need password but Driver_NoPrompt", conn);
|
||||
return SQL_ERROR; /* need a password but not allowed to prompt so error */
|
||||
return SQL_ERROR; /* need a password but not allowed to
|
||||
* prompt so error */
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
#ifdef WIN32
|
||||
password_required = TRUE;
|
||||
goto dialog;
|
||||
@@ -188,39 +200,44 @@ dialog:
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (retval == 0) {
|
||||
/* error msg filled in above */
|
||||
else if (retval == 0)
|
||||
{
|
||||
/* error msg filled in above */
|
||||
CC_log_error(func, "Error from CC_Connect", conn);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Create the Output Connection String */
|
||||
/* Create the Output Connection String */
|
||||
/*********************************************/
|
||||
result = SQL_SUCCESS;
|
||||
|
||||
makeConnectString(connStrOut, ci);
|
||||
len = strlen(connStrOut);
|
||||
|
||||
if(szConnStrOut) {
|
||||
if (szConnStrOut)
|
||||
{
|
||||
|
||||
/* Return the completed string to the caller. The correct method is to
|
||||
only construct the connect string if a dialog was put up, otherwise,
|
||||
it should just copy the connection input string to the output.
|
||||
However, it seems ok to just always construct an output string. There
|
||||
are possible bad side effects on working applications (Access) by
|
||||
implementing the correct behavior, anyway.
|
||||
*/
|
||||
/*
|
||||
* Return the completed string to the caller. The correct method
|
||||
* is to only construct the connect string if a dialog was put up,
|
||||
* otherwise, it should just copy the connection input string to
|
||||
* the output. However, it seems ok to just always construct an
|
||||
* output string. There are possible bad side effects on working
|
||||
* applications (Access) by implementing the correct behavior,
|
||||
* anyway.
|
||||
*/
|
||||
strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax);
|
||||
|
||||
if (len >= cbConnStrOutMax) {
|
||||
if (len >= cbConnStrOutMax)
|
||||
{
|
||||
result = SQL_SUCCESS_WITH_INFO;
|
||||
conn->errornumber = CONN_TRUNCATED;
|
||||
conn->errormsg = "The buffer was too small for the result.";
|
||||
}
|
||||
}
|
||||
|
||||
if(pcbConnStrOut)
|
||||
if (pcbConnStrOut)
|
||||
*pcbConnStrOut = len;
|
||||
|
||||
mylog("szConnStrOut = '%s'\n", szConnStrOut);
|
||||
@@ -232,108 +249,117 @@ dialog:
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci)
|
||||
RETCODE
|
||||
dconn_DoDialog(HWND hwnd, ConnInfo *ci)
|
||||
{
|
||||
int dialog_result;
|
||||
int dialog_result;
|
||||
|
||||
mylog("dconn_DoDialog: ci = %u\n", ci);
|
||||
mylog("dconn_DoDialog: ci = %u\n", ci);
|
||||
|
||||
if(hwnd) {
|
||||
if (hwnd)
|
||||
{
|
||||
dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_CONFIG),
|
||||
hwnd, dconn_FDriverConnectProc, (LPARAM) ci);
|
||||
if(!dialog_result || (dialog_result == -1)) {
|
||||
hwnd, dconn_FDriverConnectProc, (LPARAM) ci);
|
||||
if (!dialog_result || (dialog_result == -1))
|
||||
return SQL_NO_DATA_FOUND;
|
||||
} else {
|
||||
else
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
BOOL FAR PASCAL dconn_FDriverConnectProc(
|
||||
HWND hdlg,
|
||||
UINT wMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
BOOL FAR PASCAL
|
||||
dconn_FDriverConnectProc(
|
||||
HWND hdlg,
|
||||
UINT wMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
ConnInfo *ci;
|
||||
ConnInfo *ci;
|
||||
|
||||
switch (wMsg) {
|
||||
case WM_INITDIALOG:
|
||||
ci = (ConnInfo *) lParam;
|
||||
switch (wMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
ci = (ConnInfo *) lParam;
|
||||
|
||||
/* Change the caption for the setup dialog */
|
||||
SetWindowText(hdlg, "PostgreSQL Connection");
|
||||
/* Change the caption for the setup dialog */
|
||||
SetWindowText(hdlg, "PostgreSQL Connection");
|
||||
|
||||
SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), "Connection");
|
||||
SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), "Connection");
|
||||
|
||||
/* Hide the DSN and description fields */
|
||||
ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE);
|
||||
/* Hide the DSN and description fields */
|
||||
ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE);
|
||||
|
||||
SetWindowLong(hdlg, DWL_USER, lParam);/* Save the ConnInfo for the "OK" */
|
||||
SetWindowLong(hdlg, DWL_USER, lParam); /* Save the ConnInfo for
|
||||
* the "OK" */
|
||||
|
||||
SetDlgStuff(hdlg, ci);
|
||||
SetDlgStuff(hdlg, ci);
|
||||
|
||||
if (ci->database[0] == '\0')
|
||||
; /* default focus */
|
||||
else if (ci->server[0] == '\0')
|
||||
SetFocus(GetDlgItem(hdlg, IDC_SERVER));
|
||||
else if (ci->port[0] == '\0')
|
||||
SetFocus(GetDlgItem(hdlg, IDC_PORT));
|
||||
else if (ci->username[0] == '\0')
|
||||
SetFocus(GetDlgItem(hdlg, IDC_USER));
|
||||
else if (ci->focus_password)
|
||||
SetFocus(GetDlgItem(hdlg, IDC_PASSWORD));
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
|
||||
case IDOK:
|
||||
|
||||
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
|
||||
|
||||
GetDlgStuff(hdlg, ci);
|
||||
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
|
||||
return TRUE;
|
||||
|
||||
case IDC_DRIVER:
|
||||
|
||||
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
|
||||
hdlg, driver_optionsProc, (LPARAM) NULL);
|
||||
if (ci->database[0] == '\0')
|
||||
; /* default focus */
|
||||
else if (ci->server[0] == '\0')
|
||||
SetFocus(GetDlgItem(hdlg, IDC_SERVER));
|
||||
else if (ci->port[0] == '\0')
|
||||
SetFocus(GetDlgItem(hdlg, IDC_PORT));
|
||||
else if (ci->username[0] == '\0')
|
||||
SetFocus(GetDlgItem(hdlg, IDC_USER));
|
||||
else if (ci->focus_password)
|
||||
SetFocus(GetDlgItem(hdlg, IDC_PASSWORD));
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case IDC_DATASOURCE:
|
||||
case WM_COMMAND:
|
||||
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||
{
|
||||
case IDOK:
|
||||
|
||||
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
|
||||
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
|
||||
hdlg, ds_optionsProc, (LPARAM) ci);
|
||||
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
|
||||
|
||||
break;
|
||||
}
|
||||
GetDlgStuff(hdlg, ci);
|
||||
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
|
||||
return TRUE;
|
||||
|
||||
case IDC_DRIVER:
|
||||
|
||||
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
|
||||
hdlg, driver_optionsProc, (LPARAM) NULL);
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case IDC_DATASOURCE:
|
||||
|
||||
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
|
||||
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
|
||||
hdlg, ds_optionsProc, (LPARAM) ci);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
#endif /* WIN32 */
|
||||
|
||||
void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci)
|
||||
void
|
||||
dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci)
|
||||
{
|
||||
char *our_connect_string;
|
||||
char *pair, *attribute, *value, *equals;
|
||||
char *strtok_arg;
|
||||
char *our_connect_string;
|
||||
char *pair,
|
||||
*attribute,
|
||||
*value,
|
||||
*equals;
|
||||
char *strtok_arg;
|
||||
|
||||
memset(ci, 0, sizeof(ConnInfo));
|
||||
|
||||
@@ -342,29 +368,28 @@ char *strtok_arg;
|
||||
|
||||
mylog("our_connect_string = '%s'\n", our_connect_string);
|
||||
|
||||
while(1) {
|
||||
while (1)
|
||||
{
|
||||
pair = strtok(strtok_arg, ";");
|
||||
if(strtok_arg) {
|
||||
if (strtok_arg)
|
||||
strtok_arg = 0;
|
||||
}
|
||||
if(!pair) {
|
||||
if (!pair)
|
||||
break;
|
||||
}
|
||||
|
||||
equals = strchr(pair, '=');
|
||||
if ( ! equals)
|
||||
if (!equals)
|
||||
continue;
|
||||
|
||||
*equals = '\0';
|
||||
attribute = pair; /* ex. DSN */
|
||||
value = equals + 1; /* ex. 'CEO co1' */
|
||||
attribute = pair; /* ex. DSN */
|
||||
value = equals + 1; /* ex. 'CEO co1' */
|
||||
|
||||
mylog("attribute = '%s', value = '%s'\n", attribute, value);
|
||||
|
||||
if( !attribute || !value)
|
||||
continue;
|
||||
if (!attribute || !value)
|
||||
continue;
|
||||
|
||||
/* Copy the appropriate value to the conninfo */
|
||||
/* Copy the appropriate value to the conninfo */
|
||||
copyAttributes(ci, attribute, value);
|
||||
|
||||
}
|
||||
@@ -372,4 +397,3 @@ char *strtok_arg;
|
||||
|
||||
free(our_connect_string);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
|
||||
/* Module: environ.c
|
||||
/* Module: environ.c
|
||||
*
|
||||
* Description: This module contains routines related to
|
||||
* the environment, such as storing connection handles,
|
||||
* and returning errors.
|
||||
* Description: This module contains routines related to
|
||||
* the environment, such as storing connection handles,
|
||||
* and returning errors.
|
||||
*
|
||||
* Classes: EnvironmentClass (Functions prefix: "EN_")
|
||||
* Classes: EnvironmentClass (Functions prefix: "EN_")
|
||||
*
|
||||
* API functions: SQLAllocEnv, SQLFreeEnv, SQLError
|
||||
* API functions: SQLAllocEnv, SQLFreeEnv, SQLError
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -26,40 +26,45 @@ extern GLOBAL_VALUES globals;
|
||||
ConnectionClass *conns[MAX_CONNECTIONS];
|
||||
|
||||
|
||||
RETCODE SQL_API SQLAllocEnv(HENV FAR *phenv)
|
||||
RETCODE SQL_API
|
||||
SQLAllocEnv(HENV FAR *phenv)
|
||||
{
|
||||
static char *func = "SQLAllocEnv";
|
||||
static char *func = "SQLAllocEnv";
|
||||
|
||||
mylog("**** in SQLAllocEnv ** \n");
|
||||
|
||||
/*
|
||||
* Hack for systems on which none of the constructor-making techniques
|
||||
* in psqlodbc.c work: if globals appears not to have been initialized,
|
||||
* then cause it to be initialized. Since this should be the first
|
||||
* function called in this shared library, doing it here should work.
|
||||
* in psqlodbc.c work: if globals appears not to have been
|
||||
* initialized, then cause it to be initialized. Since this should be
|
||||
* the first function called in this shared library, doing it here
|
||||
* should work.
|
||||
*/
|
||||
if (globals.socket_buffersize <= 0)
|
||||
getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE);
|
||||
|
||||
*phenv = (HENV) EN_Constructor();
|
||||
if ( ! *phenv) {
|
||||
if (!*phenv)
|
||||
{
|
||||
*phenv = SQL_NULL_HENV;
|
||||
EN_log_error(func, "Error allocating environment", NULL);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
mylog("** exit SQLAllocEnv: phenv = %u **\n", *phenv);
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
RETCODE SQL_API SQLFreeEnv(HENV henv)
|
||||
RETCODE SQL_API
|
||||
SQLFreeEnv(HENV henv)
|
||||
{
|
||||
static char *func = "SQLFreeEnv";
|
||||
EnvironmentClass *env = (EnvironmentClass *) henv;
|
||||
static char *func = "SQLFreeEnv";
|
||||
EnvironmentClass *env = (EnvironmentClass *) henv;
|
||||
|
||||
mylog("**** in SQLFreeEnv: env = %u ** \n", env);
|
||||
mylog("**** in SQLFreeEnv: env = %u ** \n", env);
|
||||
|
||||
if (env && EN_Destructor(env)) {
|
||||
if (env && EN_Destructor(env))
|
||||
{
|
||||
mylog(" ok\n");
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
@@ -69,321 +74,349 @@ mylog("**** in SQLFreeEnv: env = %u ** \n", env);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
/* Returns the next SQL error information. */
|
||||
/* Returns the next SQL error information. */
|
||||
|
||||
RETCODE SQL_API SQLError(
|
||||
HENV henv,
|
||||
HDBC hdbc,
|
||||
HSTMT hstmt,
|
||||
UCHAR FAR *szSqlState,
|
||||
SDWORD FAR *pfNativeError,
|
||||
UCHAR FAR *szErrorMsg,
|
||||
SWORD cbErrorMsgMax,
|
||||
SWORD FAR *pcbErrorMsg)
|
||||
RETCODE SQL_API
|
||||
SQLError(
|
||||
HENV henv,
|
||||
HDBC hdbc,
|
||||
HSTMT hstmt,
|
||||
UCHAR FAR *szSqlState,
|
||||
SDWORD FAR *pfNativeError,
|
||||
UCHAR FAR *szErrorMsg,
|
||||
SWORD cbErrorMsgMax,
|
||||
SWORD FAR *pcbErrorMsg)
|
||||
{
|
||||
char *msg;
|
||||
int status;
|
||||
|
||||
char *msg;
|
||||
int status;
|
||||
|
||||
mylog("**** SQLError: henv=%u, hdbc=%u, hstmt=%u\n", henv, hdbc, hstmt);
|
||||
|
||||
if (SQL_NULL_HSTMT != hstmt) {
|
||||
/* CC: return an error of a hstmt */
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
|
||||
if (SC_get_error(stmt, &status, &msg)) {
|
||||
if (SQL_NULL_HSTMT != hstmt)
|
||||
{
|
||||
/* CC: return an error of a hstmt */
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
|
||||
if (SC_get_error(stmt, &status, &msg))
|
||||
{
|
||||
mylog("SC_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||
if (NULL == msg) {
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = (SWORD)strlen(msg);
|
||||
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||
|
||||
if (NULL != pfNativeError)
|
||||
*pfNativeError = status;
|
||||
|
||||
if (NULL != szSqlState)
|
||||
|
||||
switch (status) {
|
||||
/* now determine the SQLSTATE to be returned */
|
||||
case STMT_TRUNCATED:
|
||||
strcpy(szSqlState, "01004");
|
||||
/* data truncated */
|
||||
break;
|
||||
case STMT_INFO_ONLY:
|
||||
strcpy(szSqlState, "00000");
|
||||
/* just information that is returned, no error */
|
||||
break;
|
||||
case STMT_BAD_ERROR:
|
||||
strcpy(szSqlState, "08S01");
|
||||
/* communication link failure */
|
||||
break;
|
||||
case STMT_CREATE_TABLE_ERROR:
|
||||
strcpy(szSqlState, "S0001");
|
||||
/* table already exists */
|
||||
break;
|
||||
case STMT_STATUS_ERROR:
|
||||
case STMT_SEQUENCE_ERROR:
|
||||
strcpy(szSqlState, "S1010");
|
||||
/* Function sequence error */
|
||||
break;
|
||||
case STMT_NO_MEMORY_ERROR:
|
||||
strcpy(szSqlState, "S1001");
|
||||
/* memory allocation failure */
|
||||
break;
|
||||
case STMT_COLNUM_ERROR:
|
||||
strcpy(szSqlState, "S1002");
|
||||
/* invalid column number */
|
||||
break;
|
||||
case STMT_NO_STMTSTRING:
|
||||
strcpy(szSqlState, "S1001");
|
||||
/* having no stmtstring is also a malloc problem */
|
||||
break;
|
||||
case STMT_ERROR_TAKEN_FROM_BACKEND:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
case STMT_INTERNAL_ERROR:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
case STMT_ROW_OUT_OF_RANGE:
|
||||
strcpy(szSqlState, "S1107");
|
||||
break;
|
||||
if (NULL == msg)
|
||||
{
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
case STMT_OPERATION_CANCELLED:
|
||||
strcpy(szSqlState, "S1008");
|
||||
break;
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = (SWORD) strlen(msg);
|
||||
|
||||
case STMT_NOT_IMPLEMENTED_ERROR:
|
||||
strcpy(szSqlState, "S1C00"); /* == 'driver not capable' */
|
||||
break;
|
||||
case STMT_OPTION_OUT_OF_RANGE_ERROR:
|
||||
strcpy(szSqlState, "S1092");
|
||||
break;
|
||||
case STMT_BAD_PARAMETER_NUMBER_ERROR:
|
||||
strcpy(szSqlState, "S1093");
|
||||
break;
|
||||
case STMT_INVALID_COLUMN_NUMBER_ERROR:
|
||||
strcpy(szSqlState, "S1002");
|
||||
break;
|
||||
case STMT_RESTRICTED_DATA_TYPE_ERROR:
|
||||
strcpy(szSqlState, "07006");
|
||||
break;
|
||||
case STMT_INVALID_CURSOR_STATE_ERROR:
|
||||
strcpy(szSqlState, "24000");
|
||||
break;
|
||||
case STMT_OPTION_VALUE_CHANGED:
|
||||
strcpy(szSqlState, "01S02");
|
||||
break;
|
||||
case STMT_INVALID_CURSOR_NAME:
|
||||
strcpy(szSqlState, "34000");
|
||||
break;
|
||||
case STMT_NO_CURSOR_NAME:
|
||||
strcpy(szSqlState, "S1015");
|
||||
break;
|
||||
case STMT_INVALID_ARGUMENT_NO:
|
||||
strcpy(szSqlState, "S1009");
|
||||
/* invalid argument value */
|
||||
break;
|
||||
case STMT_INVALID_CURSOR_POSITION:
|
||||
strcpy(szSqlState, "S1109");
|
||||
break;
|
||||
|
||||
case STMT_VALUE_OUT_OF_RANGE:
|
||||
strcpy(szSqlState, "22003");
|
||||
break;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||
|
||||
case STMT_OPERATION_INVALID:
|
||||
strcpy(szSqlState, "S1011");
|
||||
break;
|
||||
if (NULL != pfNativeError)
|
||||
*pfNativeError = status;
|
||||
|
||||
case STMT_EXEC_ERROR:
|
||||
default:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* also a general error */
|
||||
break;
|
||||
}
|
||||
if (NULL != szSqlState)
|
||||
|
||||
switch (status)
|
||||
{
|
||||
/* now determine the SQLSTATE to be returned */
|
||||
case STMT_TRUNCATED:
|
||||
strcpy(szSqlState, "01004");
|
||||
/* data truncated */
|
||||
break;
|
||||
case STMT_INFO_ONLY:
|
||||
strcpy(szSqlState, "00000");
|
||||
/* just information that is returned, no error */
|
||||
break;
|
||||
case STMT_BAD_ERROR:
|
||||
strcpy(szSqlState, "08S01");
|
||||
/* communication link failure */
|
||||
break;
|
||||
case STMT_CREATE_TABLE_ERROR:
|
||||
strcpy(szSqlState, "S0001");
|
||||
/* table already exists */
|
||||
break;
|
||||
case STMT_STATUS_ERROR:
|
||||
case STMT_SEQUENCE_ERROR:
|
||||
strcpy(szSqlState, "S1010");
|
||||
/* Function sequence error */
|
||||
break;
|
||||
case STMT_NO_MEMORY_ERROR:
|
||||
strcpy(szSqlState, "S1001");
|
||||
/* memory allocation failure */
|
||||
break;
|
||||
case STMT_COLNUM_ERROR:
|
||||
strcpy(szSqlState, "S1002");
|
||||
/* invalid column number */
|
||||
break;
|
||||
case STMT_NO_STMTSTRING:
|
||||
strcpy(szSqlState, "S1001");
|
||||
/* having no stmtstring is also a malloc problem */
|
||||
break;
|
||||
case STMT_ERROR_TAKEN_FROM_BACKEND:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
case STMT_INTERNAL_ERROR:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
case STMT_ROW_OUT_OF_RANGE:
|
||||
strcpy(szSqlState, "S1107");
|
||||
break;
|
||||
|
||||
case STMT_OPERATION_CANCELLED:
|
||||
strcpy(szSqlState, "S1008");
|
||||
break;
|
||||
|
||||
case STMT_NOT_IMPLEMENTED_ERROR:
|
||||
strcpy(szSqlState, "S1C00"); /* == 'driver not
|
||||
* capable' */
|
||||
break;
|
||||
case STMT_OPTION_OUT_OF_RANGE_ERROR:
|
||||
strcpy(szSqlState, "S1092");
|
||||
break;
|
||||
case STMT_BAD_PARAMETER_NUMBER_ERROR:
|
||||
strcpy(szSqlState, "S1093");
|
||||
break;
|
||||
case STMT_INVALID_COLUMN_NUMBER_ERROR:
|
||||
strcpy(szSqlState, "S1002");
|
||||
break;
|
||||
case STMT_RESTRICTED_DATA_TYPE_ERROR:
|
||||
strcpy(szSqlState, "07006");
|
||||
break;
|
||||
case STMT_INVALID_CURSOR_STATE_ERROR:
|
||||
strcpy(szSqlState, "24000");
|
||||
break;
|
||||
case STMT_OPTION_VALUE_CHANGED:
|
||||
strcpy(szSqlState, "01S02");
|
||||
break;
|
||||
case STMT_INVALID_CURSOR_NAME:
|
||||
strcpy(szSqlState, "34000");
|
||||
break;
|
||||
case STMT_NO_CURSOR_NAME:
|
||||
strcpy(szSqlState, "S1015");
|
||||
break;
|
||||
case STMT_INVALID_ARGUMENT_NO:
|
||||
strcpy(szSqlState, "S1009");
|
||||
/* invalid argument value */
|
||||
break;
|
||||
case STMT_INVALID_CURSOR_POSITION:
|
||||
strcpy(szSqlState, "S1109");
|
||||
break;
|
||||
|
||||
case STMT_VALUE_OUT_OF_RANGE:
|
||||
strcpy(szSqlState, "22003");
|
||||
break;
|
||||
|
||||
case STMT_OPERATION_INVALID:
|
||||
strcpy(szSqlState, "S1011");
|
||||
break;
|
||||
|
||||
case STMT_EXEC_ERROR:
|
||||
default:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* also a general error */
|
||||
break;
|
||||
}
|
||||
|
||||
mylog(" szSqlState = '%s', szError='%s'\n", szSqlState, szErrorMsg);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
mylog(" szSqlState = '%s', szError='%s'\n", szSqlState, szErrorMsg);
|
||||
|
||||
} else {
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
mylog(" returning NO_DATA_FOUND\n");
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
return SQL_SUCCESS;
|
||||
|
||||
} else if (SQL_NULL_HDBC != hdbc) {
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
return SQL_SUCCESS;
|
||||
|
||||
}
|
||||
else if (SQL_NULL_HDBC != hdbc)
|
||||
{
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
|
||||
mylog("calling CC_get_error\n");
|
||||
if (CC_get_error(conn, &status, &msg)) {
|
||||
if (CC_get_error(conn, &status, &msg))
|
||||
{
|
||||
mylog("CC_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||
if (NULL == msg) {
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = (SWORD)strlen(msg);
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||
if (NULL != pfNativeError)
|
||||
*pfNativeError = status;
|
||||
|
||||
if (NULL != szSqlState)
|
||||
switch(status) {
|
||||
case STMT_OPTION_VALUE_CHANGED:
|
||||
case CONN_OPTION_VALUE_CHANGED:
|
||||
strcpy(szSqlState, "01S02");
|
||||
break;
|
||||
case STMT_TRUNCATED:
|
||||
case CONN_TRUNCATED:
|
||||
strcpy(szSqlState, "01004");
|
||||
/* data truncated */
|
||||
break;
|
||||
case CONN_INIREAD_ERROR:
|
||||
strcpy(szSqlState, "IM002");
|
||||
/* data source not found */
|
||||
break;
|
||||
case CONN_OPENDB_ERROR:
|
||||
strcpy(szSqlState, "08001");
|
||||
/* unable to connect to data source */
|
||||
break;
|
||||
case CONN_INVALID_AUTHENTICATION:
|
||||
case CONN_AUTH_TYPE_UNSUPPORTED:
|
||||
strcpy(szSqlState, "28000");
|
||||
break;
|
||||
case CONN_STMT_ALLOC_ERROR:
|
||||
strcpy(szSqlState, "S1001");
|
||||
/* memory allocation failure */
|
||||
break;
|
||||
case CONN_IN_USE:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
case CONN_UNSUPPORTED_OPTION:
|
||||
strcpy(szSqlState, "IM001");
|
||||
/* driver does not support this function */
|
||||
case CONN_INVALID_ARGUMENT_NO:
|
||||
strcpy(szSqlState, "S1009");
|
||||
/* invalid argument value */
|
||||
break;
|
||||
case CONN_TRANSACT_IN_PROGRES:
|
||||
strcpy(szSqlState, "S1010");
|
||||
/* when the user tries to switch commit mode in a transaction */
|
||||
/* -> function sequence error */
|
||||
break;
|
||||
case CONN_NO_MEMORY_ERROR:
|
||||
strcpy(szSqlState, "S1001");
|
||||
break;
|
||||
case CONN_NOT_IMPLEMENTED_ERROR:
|
||||
case STMT_NOT_IMPLEMENTED_ERROR:
|
||||
strcpy(szSqlState, "S1C00");
|
||||
break;
|
||||
if (NULL == msg)
|
||||
{
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
case CONN_VALUE_OUT_OF_RANGE:
|
||||
case STMT_VALUE_OUT_OF_RANGE:
|
||||
strcpy(szSqlState, "22003");
|
||||
break;
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
|
||||
default:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = (SWORD) strlen(msg);
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||
if (NULL != pfNativeError)
|
||||
*pfNativeError = status;
|
||||
|
||||
if (NULL != szSqlState)
|
||||
switch (status)
|
||||
{
|
||||
case STMT_OPTION_VALUE_CHANGED:
|
||||
case CONN_OPTION_VALUE_CHANGED:
|
||||
strcpy(szSqlState, "01S02");
|
||||
break;
|
||||
case STMT_TRUNCATED:
|
||||
case CONN_TRUNCATED:
|
||||
strcpy(szSqlState, "01004");
|
||||
/* data truncated */
|
||||
break;
|
||||
case CONN_INIREAD_ERROR:
|
||||
strcpy(szSqlState, "IM002");
|
||||
/* data source not found */
|
||||
break;
|
||||
case CONN_OPENDB_ERROR:
|
||||
strcpy(szSqlState, "08001");
|
||||
/* unable to connect to data source */
|
||||
break;
|
||||
case CONN_INVALID_AUTHENTICATION:
|
||||
case CONN_AUTH_TYPE_UNSUPPORTED:
|
||||
strcpy(szSqlState, "28000");
|
||||
break;
|
||||
case CONN_STMT_ALLOC_ERROR:
|
||||
strcpy(szSqlState, "S1001");
|
||||
/* memory allocation failure */
|
||||
break;
|
||||
case CONN_IN_USE:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
case CONN_UNSUPPORTED_OPTION:
|
||||
strcpy(szSqlState, "IM001");
|
||||
/* driver does not support this function */
|
||||
case CONN_INVALID_ARGUMENT_NO:
|
||||
strcpy(szSqlState, "S1009");
|
||||
/* invalid argument value */
|
||||
break;
|
||||
case CONN_TRANSACT_IN_PROGRES:
|
||||
strcpy(szSqlState, "S1010");
|
||||
|
||||
/*
|
||||
* when the user tries to switch commit mode in a
|
||||
* transaction
|
||||
*/
|
||||
/* -> function sequence error */
|
||||
break;
|
||||
case CONN_NO_MEMORY_ERROR:
|
||||
strcpy(szSqlState, "S1001");
|
||||
break;
|
||||
case CONN_NOT_IMPLEMENTED_ERROR:
|
||||
case STMT_NOT_IMPLEMENTED_ERROR:
|
||||
strcpy(szSqlState, "S1C00");
|
||||
break;
|
||||
|
||||
case CONN_VALUE_OUT_OF_RANGE:
|
||||
case STMT_VALUE_OUT_OF_RANGE:
|
||||
strcpy(szSqlState, "22003");
|
||||
break;
|
||||
|
||||
default:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog("CC_Get_error returned nothing.\n");
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
return SQL_SUCCESS;
|
||||
|
||||
} else if (SQL_NULL_HENV != henv) {
|
||||
EnvironmentClass *env = (EnvironmentClass *)henv;
|
||||
if(EN_get_error(env, &status, &msg)) {
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
return SQL_SUCCESS;
|
||||
|
||||
}
|
||||
else if (SQL_NULL_HENV != henv)
|
||||
{
|
||||
EnvironmentClass *env = (EnvironmentClass *) henv;
|
||||
|
||||
if (EN_get_error(env, &status, &msg))
|
||||
{
|
||||
mylog("EN_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||
if (NULL == msg) {
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
if (NULL == msg)
|
||||
{
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = (SWORD)strlen(msg);
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||
if (NULL != pfNativeError)
|
||||
*pfNativeError = status;
|
||||
|
||||
if(szSqlState) {
|
||||
switch(status) {
|
||||
case ENV_ALLOC_ERROR:
|
||||
/* memory allocation failure */
|
||||
strcpy(szSqlState, "S1001");
|
||||
break;
|
||||
default:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = (SWORD) strlen(msg);
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||
if (NULL != pfNativeError)
|
||||
*pfNativeError = status;
|
||||
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
if (szSqlState)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case ENV_ALLOC_ERROR:
|
||||
/* memory allocation failure */
|
||||
strcpy(szSqlState, "S1001");
|
||||
break;
|
||||
default:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
|
||||
|
||||
@@ -395,25 +428,27 @@ int status;
|
||||
|
||||
|
||||
EnvironmentClass
|
||||
*EN_Constructor(void)
|
||||
*
|
||||
EN_Constructor(void)
|
||||
{
|
||||
EnvironmentClass *rv;
|
||||
EnvironmentClass *rv;
|
||||
|
||||
rv = (EnvironmentClass *) malloc(sizeof(EnvironmentClass));
|
||||
if( rv) {
|
||||
rv = (EnvironmentClass *) malloc(sizeof(EnvironmentClass));
|
||||
if (rv)
|
||||
{
|
||||
rv->errormsg = 0;
|
||||
rv->errornumber = 0;
|
||||
}
|
||||
|
||||
return rv;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
EN_Destructor(EnvironmentClass *self)
|
||||
{
|
||||
int lf;
|
||||
char rv = 1;
|
||||
int lf;
|
||||
char rv = 1;
|
||||
|
||||
mylog("in EN_Destructor, self=%u\n", self);
|
||||
|
||||
@@ -421,7 +456,8 @@ char rv = 1;
|
||||
/* the source--they should not be freed */
|
||||
|
||||
/* Free any connections belonging to this environment */
|
||||
for (lf = 0; lf < MAX_CONNECTIONS; lf++) {
|
||||
for (lf = 0; lf < MAX_CONNECTIONS; lf++)
|
||||
{
|
||||
if (conns[lf] && conns[lf]->henv == self)
|
||||
rv = rv && CC_Destructor(conns[lf]);
|
||||
}
|
||||
@@ -434,26 +470,29 @@ char rv = 1;
|
||||
char
|
||||
EN_get_error(EnvironmentClass *self, int *number, char **message)
|
||||
{
|
||||
if(self && self->errormsg && self->errornumber) {
|
||||
if (self && self->errormsg && self->errornumber)
|
||||
{
|
||||
*message = self->errormsg;
|
||||
*number = self->errornumber;
|
||||
self->errormsg = 0;
|
||||
self->errornumber = 0;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
char
|
||||
EN_add_connection(EnvironmentClass *self, ConnectionClass *conn)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
mylog("EN_add_connection: self = %u, conn = %u\n", self, conn);
|
||||
mylog("EN_add_connection: self = %u, conn = %u\n", self, conn);
|
||||
|
||||
for (i = 0; i < MAX_CONNECTIONS; i++) {
|
||||
if ( ! conns[i]) {
|
||||
for (i = 0; i < MAX_CONNECTIONS; i++)
|
||||
{
|
||||
if (!conns[i])
|
||||
{
|
||||
conn->henv = self;
|
||||
conns[i] = conn;
|
||||
|
||||
@@ -469,10 +508,11 @@ mylog("EN_add_connection: self = %u, conn = %u\n", self, conn);
|
||||
char
|
||||
EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CONNECTIONS; i++)
|
||||
if (conns[i] == conn && conns[i]->status != CONN_EXECUTING) {
|
||||
if (conns[i] == conn && conns[i]->status != CONN_EXECUTING)
|
||||
{
|
||||
conns[i] = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -483,9 +523,8 @@ int i;
|
||||
void
|
||||
EN_log_error(char *func, char *desc, EnvironmentClass *self)
|
||||
{
|
||||
if (self) {
|
||||
if (self)
|
||||
qlog("ENVIRON ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg);
|
||||
}
|
||||
else
|
||||
qlog("INVALID ENVIRON HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
/* File: environ.h
|
||||
/* File: environ.h
|
||||
*
|
||||
* Description: See "environ.c"
|
||||
* Description: See "environ.c"
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -29,17 +29,18 @@
|
||||
#define ENV_ALLOC_ERROR 1
|
||||
|
||||
/********** Environment Handle *************/
|
||||
struct EnvironmentClass_ {
|
||||
char *errormsg;
|
||||
int errornumber;
|
||||
struct EnvironmentClass_
|
||||
{
|
||||
char *errormsg;
|
||||
int errornumber;
|
||||
};
|
||||
|
||||
/* Environment prototypes */
|
||||
EnvironmentClass *EN_Constructor(void);
|
||||
char EN_Destructor(EnvironmentClass *self);
|
||||
char EN_get_error(EnvironmentClass *self, int *number, char **message);
|
||||
char EN_add_connection(EnvironmentClass *self, ConnectionClass *conn);
|
||||
char EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn);
|
||||
void EN_log_error(char *func, char *desc, EnvironmentClass *self);
|
||||
char EN_Destructor(EnvironmentClass *self);
|
||||
char EN_get_error(EnvironmentClass *self, int *number, char **message);
|
||||
char EN_add_connection(EnvironmentClass *self, ConnectionClass *conn);
|
||||
char EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn);
|
||||
void EN_log_error(char *func, char *desc, EnvironmentClass *self);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,7 @@
|
||||
#ifndef WIN32
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h" /* produced by configure */
|
||||
#include "config.h" /* produced by configure */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -38,82 +38,86 @@
|
||||
|
||||
|
||||
DWORD
|
||||
GetPrivateProfileString(char *theSection, /* section name */
|
||||
char *theKey, /* search key name */
|
||||
char *theDefault, /* default value if not found */
|
||||
char *theReturnBuffer, /* return value stored here */
|
||||
size_t theReturnBufferLength, /* byte length of return buffer */
|
||||
char *theIniFileName) /* pathname of ini file to search */
|
||||
GetPrivateProfileString(char *theSection, /* section name */
|
||||
char *theKey, /* search key name */
|
||||
char *theDefault, /* default value if not
|
||||
* found */
|
||||
char *theReturnBuffer, /* return value stored
|
||||
* here */
|
||||
size_t theReturnBufferLength, /* byte length of return
|
||||
* buffer */
|
||||
char *theIniFileName) /* pathname of ini file to
|
||||
* search */
|
||||
{
|
||||
char buf[MAXPGPATH];
|
||||
char* ptr = 0;
|
||||
FILE* aFile = 0;
|
||||
size_t aLength;
|
||||
char aLine[2048];
|
||||
char *aValue;
|
||||
char *aStart;
|
||||
char *aString;
|
||||
size_t aLineLength;
|
||||
size_t aReturnLength = 0;
|
||||
BOOL aSectionFound = FALSE;
|
||||
BOOL aKeyFound = FALSE;
|
||||
int j = 0;
|
||||
char buf[MAXPGPATH];
|
||||
char *ptr = 0;
|
||||
FILE *aFile = 0;
|
||||
size_t aLength;
|
||||
char aLine[2048];
|
||||
char *aValue;
|
||||
char *aStart;
|
||||
char *aString;
|
||||
size_t aLineLength;
|
||||
size_t aReturnLength = 0;
|
||||
BOOL aSectionFound = FALSE;
|
||||
BOOL aKeyFound = FALSE;
|
||||
int j = 0;
|
||||
|
||||
j = strlen(theIniFileName) + 1;
|
||||
ptr = (char*)getpwuid(getuid()); /* get user info */
|
||||
ptr = (char *) getpwuid(getuid()); /* get user info */
|
||||
|
||||
if( ptr == NULL)
|
||||
if (ptr == NULL)
|
||||
{
|
||||
if( MAXPGPATH-1 < j )
|
||||
theIniFileName[MAXPGPATH-1] = '\0';
|
||||
if (MAXPGPATH - 1 < j)
|
||||
theIniFileName[MAXPGPATH - 1] = '\0';
|
||||
|
||||
sprintf(buf,"%s",theIniFileName);
|
||||
sprintf(buf, "%s", theIniFileName);
|
||||
}
|
||||
ptr = ((struct passwd*)ptr)->pw_dir; /* get user home dir */
|
||||
if( ptr == NULL || *ptr == '\0' )
|
||||
ptr = ((struct passwd *) ptr)->pw_dir; /* get user home dir */
|
||||
if (ptr == NULL || *ptr == '\0')
|
||||
ptr = "/home";
|
||||
|
||||
/* This doesn't make it so we find an ini file but allows normal
|
||||
* processing to continue further on down. The likelihood is that
|
||||
* the file won't be found and thus the default value will be
|
||||
* returned.
|
||||
*/
|
||||
if( MAXPGPATH-1 < strlen(ptr) + j )
|
||||
/*
|
||||
* This doesn't make it so we find an ini file but allows normal
|
||||
* processing to continue further on down. The likelihood is that the
|
||||
* file won't be found and thus the default value will be returned.
|
||||
*/
|
||||
if (MAXPGPATH - 1 < strlen(ptr) + j)
|
||||
{
|
||||
if( MAXPGPATH-1 < strlen(ptr) )
|
||||
ptr[MAXPGPATH-1] = '\0';
|
||||
if (MAXPGPATH - 1 < strlen(ptr))
|
||||
ptr[MAXPGPATH - 1] = '\0';
|
||||
else
|
||||
theIniFileName[MAXPGPATH-1-strlen(ptr)] = '\0';
|
||||
theIniFileName[MAXPGPATH - 1 - strlen(ptr)] = '\0';
|
||||
}
|
||||
|
||||
sprintf( buf, "%s/%s",ptr,theIniFileName );
|
||||
sprintf(buf, "%s/%s", ptr, theIniFileName);
|
||||
|
||||
/* This code makes it so that a file in the users home dir
|
||||
* overrides a the "default" file as passed in
|
||||
*/
|
||||
aFile = (FILE*)(buf ? fopen(buf, PG_BINARY_R) : NULL);
|
||||
if(!aFile) {
|
||||
sprintf(buf,"%s",theIniFileName);
|
||||
aFile = (FILE*)(buf ? fopen(buf, PG_BINARY_R) : NULL);
|
||||
/*
|
||||
* This code makes it so that a file in the users home dir overrides a
|
||||
* the "default" file as passed in
|
||||
*/
|
||||
aFile = (FILE *) (buf ? fopen(buf, PG_BINARY_R) : NULL);
|
||||
if (!aFile)
|
||||
{
|
||||
sprintf(buf, "%s", theIniFileName);
|
||||
aFile = (FILE *) (buf ? fopen(buf, PG_BINARY_R) : NULL);
|
||||
}
|
||||
|
||||
|
||||
aLength = (theDefault == NULL) ? 0 : strlen(theDefault);
|
||||
|
||||
if(theReturnBufferLength == 0 || theReturnBuffer == NULL)
|
||||
if (theReturnBufferLength == 0 || theReturnBuffer == NULL)
|
||||
{
|
||||
if(aFile)
|
||||
{
|
||||
if (aFile)
|
||||
fclose(aFile);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(aFile == NULL)
|
||||
if (aFile == NULL)
|
||||
{
|
||||
/* no ini file specified, return the default */
|
||||
|
||||
++aLength; /* room for NULL char */
|
||||
++aLength; /* room for NULL char */
|
||||
aLength = theReturnBufferLength < aLength ?
|
||||
theReturnBufferLength : aLength;
|
||||
strncpy(theReturnBuffer, theDefault, aLength);
|
||||
@@ -122,86 +126,79 @@ GetPrivateProfileString(char *theSection, /* section name */
|
||||
}
|
||||
|
||||
|
||||
while(fgets(aLine, sizeof(aLine), aFile) != NULL)
|
||||
while (fgets(aLine, sizeof(aLine), aFile) != NULL)
|
||||
{
|
||||
aLineLength = strlen(aLine);
|
||||
/* strip final '\n' */
|
||||
if(aLineLength > 0 && aLine[aLineLength - 1] == '\n')
|
||||
{
|
||||
if (aLineLength > 0 && aLine[aLineLength - 1] == '\n')
|
||||
aLine[aLineLength - 1] = '\0';
|
||||
}
|
||||
switch(*aLine)
|
||||
switch (*aLine)
|
||||
{
|
||||
case ' ': /* blank line */
|
||||
case ';': /* comment line */
|
||||
case ' ': /* blank line */
|
||||
case ';': /* comment line */
|
||||
continue;
|
||||
break;
|
||||
break;
|
||||
|
||||
case '[': /* section marker */
|
||||
case '[': /* section marker */
|
||||
|
||||
if( (aString = strchr(aLine, ']')) )
|
||||
if ((aString = strchr(aLine, ']')))
|
||||
{
|
||||
aStart = aLine + 1;
|
||||
aString--;
|
||||
while (isspace((unsigned char) *aStart)) aStart++;
|
||||
while (isspace((unsigned char) *aString)) aString--;
|
||||
*(aString+1) = '\0';
|
||||
while (isspace((unsigned char) *aStart))
|
||||
aStart++;
|
||||
while (isspace((unsigned char) *aString))
|
||||
aString--;
|
||||
*(aString + 1) = '\0';
|
||||
|
||||
/* accept as matched if NULL key or exact match */
|
||||
|
||||
if(!theSection || !strcmp(aStart, theSection))
|
||||
if (!theSection || !strcmp(aStart, theSection))
|
||||
aSectionFound = TRUE;
|
||||
else
|
||||
aSectionFound = FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* try to match value keys if in proper section */
|
||||
|
||||
if(aSectionFound)
|
||||
if (aSectionFound)
|
||||
{
|
||||
/* try to match requested key */
|
||||
|
||||
if( (aString = aValue = strchr(aLine, '=')) )
|
||||
if ((aString = aValue = strchr(aLine, '=')))
|
||||
{
|
||||
*aValue = '\0';
|
||||
++aValue;
|
||||
|
||||
/* strip leading blanks in value field */
|
||||
|
||||
while(*aValue == ' ' && aValue < aLine + sizeof(aLine))
|
||||
{
|
||||
while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
|
||||
*aValue++ = '\0';
|
||||
}
|
||||
if(aValue >= aLine + sizeof(aLine))
|
||||
{
|
||||
if (aValue >= aLine + sizeof(aLine))
|
||||
aValue = "";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aValue = "";
|
||||
}
|
||||
|
||||
aStart = aLine;
|
||||
while (isspace((unsigned char) *aStart)) aStart++;
|
||||
while (isspace((unsigned char) *aStart))
|
||||
aStart++;
|
||||
|
||||
/* strip trailing blanks from key */
|
||||
|
||||
if(aString)
|
||||
if (aString)
|
||||
{
|
||||
while(--aString >= aStart && *aString == ' ')
|
||||
{
|
||||
while (--aString >= aStart && *aString == ' ')
|
||||
*aString = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* see if key is matched */
|
||||
|
||||
if(theKey == NULL || !strcmp(theKey, aStart))
|
||||
if (theKey == NULL || !strcmp(theKey, aStart))
|
||||
{
|
||||
/* matched -- first, terminate value part */
|
||||
|
||||
@@ -212,7 +209,7 @@ GetPrivateProfileString(char *theSection, /* section name */
|
||||
|
||||
aString = aValue + aLength - 1;
|
||||
|
||||
while(--aString > aValue && *aString == ' ')
|
||||
while (--aString > aValue && *aString == ' ')
|
||||
{
|
||||
*aString = '\0';
|
||||
--aLength;
|
||||
@@ -220,7 +217,7 @@ GetPrivateProfileString(char *theSection, /* section name */
|
||||
|
||||
/* unquote value if quoted */
|
||||
|
||||
if(aLength >= 2 && aValue[0] == '"' &&
|
||||
if (aLength >= 2 && aValue[0] == '"' &&
|
||||
aValue[aLength - 1] == '"')
|
||||
{
|
||||
/* string quoted with double quotes */
|
||||
@@ -233,7 +230,7 @@ GetPrivateProfileString(char *theSection, /* section name */
|
||||
{
|
||||
/* single quotes allowed also... */
|
||||
|
||||
if(aLength >= 2 && aValue[0] == '\'' &&
|
||||
if (aLength >= 2 && aValue[0] == '\'' &&
|
||||
aValue[aLength - 1] == '\'')
|
||||
{
|
||||
aValue[aLength - 1] = '\0';
|
||||
@@ -245,23 +242,23 @@ GetPrivateProfileString(char *theSection, /* section name */
|
||||
/* compute maximum length copyable */
|
||||
|
||||
aLineLength = (aLength <
|
||||
theReturnBufferLength - aReturnLength) ? aLength :
|
||||
theReturnBufferLength - aReturnLength) ? aLength :
|
||||
theReturnBufferLength - aReturnLength;
|
||||
|
||||
/* do the copy to return buffer */
|
||||
|
||||
if(aLineLength)
|
||||
if (aLineLength)
|
||||
{
|
||||
strncpy(&theReturnBuffer[aReturnLength],
|
||||
aValue, aLineLength);
|
||||
aValue, aLineLength);
|
||||
aReturnLength += aLineLength;
|
||||
if(aReturnLength < theReturnBufferLength)
|
||||
if (aReturnLength < theReturnBufferLength)
|
||||
{
|
||||
theReturnBuffer[aReturnLength] = '\0';
|
||||
++aReturnLength;
|
||||
}
|
||||
}
|
||||
if(aFile)
|
||||
if (aFile)
|
||||
{
|
||||
fclose(aFile);
|
||||
aFile = NULL;
|
||||
@@ -271,17 +268,16 @@ GetPrivateProfileString(char *theSection, /* section name */
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(aFile)
|
||||
{
|
||||
if (aFile)
|
||||
fclose(aFile);
|
||||
}
|
||||
|
||||
if(!aKeyFound) { /* key wasn't found return default */
|
||||
++aLength; /* room for NULL char */
|
||||
if (!aKeyFound)
|
||||
{ /* key wasn't found return default */
|
||||
++aLength; /* room for NULL char */
|
||||
aLength = theReturnBufferLength < aLength ?
|
||||
theReturnBufferLength : aLength;
|
||||
strncpy(theReturnBuffer, theDefault, aLength);
|
||||
@@ -292,10 +288,11 @@ GetPrivateProfileString(char *theSection, /* section name */
|
||||
}
|
||||
|
||||
DWORD
|
||||
WritePrivateProfileString(char *theSection, /* section name */
|
||||
char *theKey, /* write key name */
|
||||
char *theBuffer, /* input buffer */
|
||||
char *theIniFileName) /* pathname of ini file to write */
|
||||
WritePrivateProfileString(char *theSection, /* section name */
|
||||
char *theKey, /* write key name */
|
||||
char *theBuffer, /* input buffer */
|
||||
char *theIniFileName) /* pathname of ini file to
|
||||
* write */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -306,69 +303,74 @@ WritePrivateProfileString(char *theSection, /* section name */
|
||||
* I find out different.
|
||||
*/
|
||||
DWORD
|
||||
WritePrivateProfileString(char *theSection, /* section name */
|
||||
char *theKey, /* write key name */
|
||||
char *theBuffer, /* input buffer */
|
||||
char *theIniFileName) /* pathname of ini file to write */
|
||||
WritePrivateProfileString(char *theSection, /* section name */
|
||||
char *theKey, /* write key name */
|
||||
char *theBuffer, /* input buffer */
|
||||
char *theIniFileName) /* pathname of ini file to
|
||||
* write */
|
||||
{
|
||||
char buf[MAXPGPATH];
|
||||
char* ptr = 0;
|
||||
FILE* aFile = 0;
|
||||
size_t aLength;
|
||||
char aLine[2048];
|
||||
char *aValue;
|
||||
char *aString;
|
||||
size_t aLineLength;
|
||||
size_t aReturnLength = 0;
|
||||
char buf[MAXPGPATH];
|
||||
char *ptr = 0;
|
||||
FILE *aFile = 0;
|
||||
size_t aLength;
|
||||
char aLine[2048];
|
||||
char *aValue;
|
||||
char *aString;
|
||||
size_t aLineLength;
|
||||
size_t aReturnLength = 0;
|
||||
|
||||
BOOL aSectionFound = FALSE;
|
||||
BOOL keyFound = FALSE;
|
||||
int j = 0;
|
||||
BOOL aSectionFound = FALSE;
|
||||
BOOL keyFound = FALSE;
|
||||
int j = 0;
|
||||
|
||||
/* If this isn't correct processing we'll change it later */
|
||||
if(theSection == NULL || theKey == NULL || theBuffer == NULL ||
|
||||
theIniFileName == NULL) return 0;
|
||||
if (theSection == NULL || theKey == NULL || theBuffer == NULL ||
|
||||
theIniFileName == NULL)
|
||||
return 0;
|
||||
|
||||
aLength = strlen(theBuffer);
|
||||
if(aLength == 0) return 0;
|
||||
if (aLength == 0)
|
||||
return 0;
|
||||
|
||||
j = strlen(theIniFileName) + 1;
|
||||
ptr = (char*)getpwuid(getuid()); /* get user info */
|
||||
ptr = (char *) getpwuid(getuid()); /* get user info */
|
||||
|
||||
if( ptr == NULL)
|
||||
if (ptr == NULL)
|
||||
{
|
||||
if( MAXPGPATH-1 < j )
|
||||
theIniFileName[MAXPGPATH-1] = '\0';
|
||||
if (MAXPGPATH - 1 < j)
|
||||
theIniFileName[MAXPGPATH - 1] = '\0';
|
||||
|
||||
sprintf(buf,"%s",theIniFileName);
|
||||
sprintf(buf, "%s", theIniFileName);
|
||||
}
|
||||
ptr = ((struct passwd*)ptr)->pw_dir; /* get user home dir */
|
||||
if( ptr == NULL || *ptr == '\0' )
|
||||
ptr = ((struct passwd *) ptr)->pw_dir; /* get user home dir */
|
||||
if (ptr == NULL || *ptr == '\0')
|
||||
ptr = "/home";
|
||||
|
||||
/* This doesn't make it so we find an ini file but allows normal */
|
||||
/* processing to continue further on down. The likelihood is that */
|
||||
/* processing to continue further on down. The likelihood is that */
|
||||
/* the file won't be found and thus the default value will be */
|
||||
/* returned. */
|
||||
/* */
|
||||
if( MAXPGPATH-1 < strlen(ptr) + j )
|
||||
if (MAXPGPATH - 1 < strlen(ptr) + j)
|
||||
{
|
||||
if( MAXPGPATH-1 < strlen(ptr) )
|
||||
ptr[MAXPGPATH-1] = '\0';
|
||||
if (MAXPGPATH - 1 < strlen(ptr))
|
||||
ptr[MAXPGPATH - 1] = '\0';
|
||||
else
|
||||
theIniFileName[MAXPGPATH-1-strlen(ptr)] = '\0';
|
||||
theIniFileName[MAXPGPATH - 1 - strlen(ptr)] = '\0';
|
||||
}
|
||||
|
||||
sprintf( buf, "%s/%s",ptr,theIniFileName );
|
||||
sprintf(buf, "%s/%s", ptr, theIniFileName);
|
||||
|
||||
/* This code makes it so that a file in the users home dir */
|
||||
/* overrides a the "default" file as passed in */
|
||||
/* overrides a the "default" file as passed in */
|
||||
/* */
|
||||
aFile = (FILE*)(buf ? fopen(buf, "r+") : NULL);
|
||||
if(!aFile) {
|
||||
sprintf(buf,"%s",theIniFileName);
|
||||
aFile = (FILE*)(buf ? fopen(buf, "r+") : NULL);
|
||||
if(!aFile) return 0;
|
||||
aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
|
||||
if (!aFile)
|
||||
{
|
||||
sprintf(buf, "%s", theIniFileName);
|
||||
aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
|
||||
if (!aFile)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -378,104 +380,92 @@ WritePrivateProfileString(char *theSection, /* section name */
|
||||
/* exists we have to overwrite it. If it doesn't exist */
|
||||
/* we just write a new line to the file. */
|
||||
/* */
|
||||
while(fgets(aLine, sizeof(aLine), aFile) != NULL)
|
||||
while (fgets(aLine, sizeof(aLine), aFile) != NULL)
|
||||
{
|
||||
aLineLength = strlen(aLine);
|
||||
/* strip final '\n' */
|
||||
if(aLineLength > 0 && aLine[aLineLength - 1] == '\n')
|
||||
{
|
||||
if (aLineLength > 0 && aLine[aLineLength - 1] == '\n')
|
||||
aLine[aLineLength - 1] = '\0';
|
||||
}
|
||||
switch(*aLine)
|
||||
switch (*aLine)
|
||||
{
|
||||
case ' ': /* blank line */
|
||||
case ';': /* comment line */
|
||||
case ' ': /* blank line */
|
||||
case ';': /* comment line */
|
||||
continue;
|
||||
break;
|
||||
break;
|
||||
|
||||
case '[': /* section marker */
|
||||
case '[': /* section marker */
|
||||
|
||||
if( (aString = strchr(aLine, ']')) )
|
||||
if ((aString = strchr(aLine, ']')))
|
||||
{
|
||||
*aString = '\0';
|
||||
|
||||
/* accept as matched if key exact match */
|
||||
|
||||
if(!strcmp(aLine + 1, theSection))
|
||||
{
|
||||
if (!strcmp(aLine + 1, theSection))
|
||||
aSectionFound = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* try to match value keys if in proper section */
|
||||
|
||||
if(aSectionFound)
|
||||
if (aSectionFound)
|
||||
{
|
||||
/* try to match requested key */
|
||||
|
||||
if( (aString = aValue = strchr(aLine, '=')) )
|
||||
if ((aString = aValue = strchr(aLine, '=')))
|
||||
{
|
||||
*aValue = '\0';
|
||||
++aValue;
|
||||
|
||||
/* strip leading blanks in value field */
|
||||
|
||||
while(*aValue == ' ' && aValue < aLine + sizeof(aLine))
|
||||
{
|
||||
while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
|
||||
*aValue++ = '\0';
|
||||
}
|
||||
if(aValue >= aLine + sizeof(aLine))
|
||||
{
|
||||
if (aValue >= aLine + sizeof(aLine))
|
||||
aValue = "";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aValue = "";
|
||||
}
|
||||
|
||||
/* strip trailing blanks from key */
|
||||
|
||||
if(aString)
|
||||
if (aString)
|
||||
{
|
||||
while(--aString >= aLine && *aString == ' ')
|
||||
{
|
||||
while (--aString >= aLine && *aString == ' ')
|
||||
*aString = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* see if key is matched */
|
||||
|
||||
if(!strcmp(theKey, aLine))
|
||||
if (!strcmp(theKey, aLine))
|
||||
{
|
||||
keyFound = TRUE;
|
||||
/* matched -- first, terminate value part */
|
||||
|
||||
/* overwrite current value */
|
||||
fseek(aFile,-aLineLength,SEEK_CUR);
|
||||
fseek(aFile, -aLineLength, SEEK_CUR);
|
||||
/* overwrite key and value */
|
||||
sprintf(aLine,"%s = %s\n",theKey,theBuffer);
|
||||
fputs(aLine,aFile);
|
||||
}
|
||||
sprintf(aLine, "%s = %s\n", theKey, theBuffer);
|
||||
fputs(aLine, aFile);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!keyFound) { /* theKey wasn't in file so */
|
||||
if(aFile)
|
||||
{
|
||||
fclose(aFile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!keyFound)
|
||||
{ /* theKey wasn't in file so */
|
||||
if (aFile)
|
||||
fclose(aFile);
|
||||
|
||||
return aReturnLength > 0 ? aReturnLength - 1 : 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -13,25 +13,32 @@
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
DWORD
|
||||
GetPrivateProfileString(char *theSection, /* section name */
|
||||
char *theKey, /* search key name */
|
||||
char *theDefault, /* default value if not found */
|
||||
char *theReturnBuffer, /* return valuse stored here */
|
||||
size_t theBufferLength, /* byte length of return buffer */
|
||||
char *theIniFileName); /* pathname of ini file to search */
|
||||
DWORD
|
||||
GetPrivateProfileString(char *theSection, /* section name */
|
||||
char *theKey, /* search key name */
|
||||
char *theDefault, /* default value if not
|
||||
* found */
|
||||
char *theReturnBuffer, /* return valuse stored
|
||||
* here */
|
||||
size_t theBufferLength, /* byte length of return
|
||||
* buffer */
|
||||
char *theIniFileName); /* pathname of ini file
|
||||
* to search */
|
||||
|
||||
DWORD
|
||||
WritePrivateProfileString(char *theSection, /* section name */
|
||||
char *theKey, /* write key name */
|
||||
char *theBuffer, /* input buffer */
|
||||
char *theIniFileName); /* pathname of ini file to write */
|
||||
DWORD
|
||||
WritePrivateProfileString(char *theSection, /* section name */
|
||||
char *theKey, /* write key name */
|
||||
char *theBuffer, /* input buffer */
|
||||
char *theIniFileName); /* pathname of ini file
|
||||
* to write */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,66 +1,66 @@
|
||||
#ifndef _IODBC_H
|
||||
#define _IODBC_H
|
||||
#ifndef _IODBC_H
|
||||
#define _IODBC_H
|
||||
|
||||
# if !defined(WIN32) && !defined(WIN32_SYSTEM)
|
||||
# define _UNIX_
|
||||
#if !defined(WIN32) && !defined(WIN32_SYSTEM)
|
||||
#define _UNIX_
|
||||
|
||||
# include <stdlib.h>
|
||||
# include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
# define MEM_ALLOC(size) (malloc((size_t)(size)))
|
||||
# define MEM_FREE(ptr) {if(ptr) free(ptr);}
|
||||
#define MEM_ALLOC(size) (malloc((size_t)(size)))
|
||||
#define MEM_FREE(ptr) {if(ptr) free(ptr);}
|
||||
|
||||
# define STRCPY(t, s) (strcpy((char*)(t), (char*)(s)))
|
||||
# define STRNCPY(t,s,n) (strncpy((char*)(t), (char*)(s), (size_t)(n)))
|
||||
# define STRCAT(t, s) (strcat((char*)(t), (char*)(s)))
|
||||
# define STRNCAT(t,s,n) (strncat((char*)(t), (char*)(s), (size_t)(n)))
|
||||
# define STREQ(a, b) (strcmp((char*)(a), (char*)(b)) == 0)
|
||||
# define STRLEN(str) ((str)? strlen((char*)(str)):0)
|
||||
#define STRCPY(t, s) (strcpy((char*)(t), (char*)(s)))
|
||||
#define STRNCPY(t,s,n) (strncpy((char*)(t), (char*)(s), (size_t)(n)))
|
||||
#define STRCAT(t, s) (strcat((char*)(t), (char*)(s)))
|
||||
#define STRNCAT(t,s,n) (strncat((char*)(t), (char*)(s), (size_t)(n)))
|
||||
#define STREQ(a, b) (strcmp((char*)(a), (char*)(b)) == 0)
|
||||
#define STRLEN(str) ((str)? strlen((char*)(str)):0)
|
||||
|
||||
# define EXPORT
|
||||
# define CALLBACK
|
||||
# define FAR
|
||||
#define EXPORT
|
||||
#define CALLBACK
|
||||
#define FAR
|
||||
|
||||
typedef signed short SSHOR;
|
||||
typedef short WORD;
|
||||
typedef long DWORD;
|
||||
typedef signed short SSHOR;
|
||||
typedef short WORD;
|
||||
typedef long DWORD;
|
||||
|
||||
typedef WORD WPARAM;
|
||||
typedef DWORD LPARAM;
|
||||
typedef void* HWND;
|
||||
typedef int BOOL;
|
||||
typedef WORD WPARAM;
|
||||
typedef DWORD LPARAM;
|
||||
typedef void *HWND;
|
||||
typedef int BOOL;
|
||||
|
||||
# endif /* _UNIX_ */
|
||||
#endif /* _UNIX_ */
|
||||
|
||||
# if defined(WIN32) || defined(WIN32_SYSTEM)
|
||||
#if defined(WIN32) || defined(WIN32_SYSTEM)
|
||||
|
||||
# include <windows.h>
|
||||
# include <windowsx.h>
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
# ifdef _MSVC_
|
||||
# define MEM_ALLOC(size) (fmalloc((size_t)(size)))
|
||||
# define MEM_FREE(ptr) ((ptr)? ffree((PTR)(ptr)):0))
|
||||
# define STRCPY(t, s) (fstrcpy((char FAR*)(t), (char FAR*)(s)))
|
||||
# define STRNCPY(t,s,n) (fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n)))
|
||||
# define STRLEN(str) ((str)? fstrlen((char FAR*)(str)):0)
|
||||
# define STREQ(a, b) (fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
|
||||
# endif
|
||||
#ifdef _MSVC_
|
||||
#define MEM_ALLOC(size) (fmalloc((size_t)(size)))
|
||||
#define MEM_FREE(ptr) ((ptr)? ffree((PTR)(ptr)):0))
|
||||
#define STRCPY(t, s) (fstrcpy((char FAR*)(t), (char FAR*)(s)))
|
||||
#define STRNCPY(t,s,n) (fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n)))
|
||||
#define STRLEN(str) ((str)? fstrlen((char FAR*)(str)):0)
|
||||
#define STREQ(a, b) (fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
|
||||
#endif
|
||||
|
||||
# ifdef _BORLAND_
|
||||
# define MEM_ALLOC(size) (farmalloc((unsigned long)(size))
|
||||
# define MEM_FREE(ptr) ((ptr)? farfree((void far*)(ptr)):0)
|
||||
# define STRCPY(t, s) (_fstrcpy((char FAR*)(t), (char FAR*)(s)))
|
||||
# define STRNCPY(t,s,n) (_fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n)))
|
||||
# define STRLEN(str) ((str)? _fstrlen((char FAR*)(str)):0)
|
||||
# define STREQ(a, b) (_fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
|
||||
# endif
|
||||
#ifdef _BORLAND_
|
||||
#define MEM_ALLOC(size) (farmalloc((unsigned long)(size))
|
||||
#define MEM_FREE(ptr) ((ptr)? farfree((void far*)(ptr)):0)
|
||||
#define STRCPY(t, s) (_fstrcpy((char FAR*)(t), (char FAR*)(s)))
|
||||
#define STRNCPY(t,s,n) (_fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n)))
|
||||
#define STRLEN(str) ((str)? _fstrlen((char FAR*)(str)):0)
|
||||
#define STREQ(a, b) (_fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
|
||||
#endif
|
||||
|
||||
# endif /* WIN32 */
|
||||
#endif /* WIN32 */
|
||||
|
||||
# define SYSERR (-1)
|
||||
#define SYSERR (-1)
|
||||
|
||||
# ifndef NULL
|
||||
# define NULL ((void FAR*)0UL)
|
||||
# endif
|
||||
#ifndef NULL
|
||||
#define NULL ((void FAR*)0UL)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,97 +2,97 @@
|
||||
* include path to be used to create ODBC compliant applications.
|
||||
*/
|
||||
#ifndef _INTRINSIC_SQL_H
|
||||
# define _INTRINSIC_SQL_H
|
||||
#define _INTRINSIC_SQL_H
|
||||
|
||||
typedef unsigned char UCHAR;
|
||||
typedef long int SDWORD;
|
||||
typedef short int SWORD;
|
||||
typedef unsigned long int UDWORD;
|
||||
typedef unsigned short int UWORD;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef long int SDWORD;
|
||||
typedef short int SWORD;
|
||||
typedef unsigned long int UDWORD;
|
||||
typedef unsigned short int UWORD;
|
||||
|
||||
typedef void FAR* PTR;
|
||||
typedef void FAR *PTR;
|
||||
|
||||
typedef void FAR* HENV;
|
||||
typedef void FAR* HDBC;
|
||||
typedef void FAR* HSTMT;
|
||||
typedef void FAR *HENV;
|
||||
typedef void FAR *HDBC;
|
||||
typedef void FAR *HSTMT;
|
||||
|
||||
typedef signed short RETCODE;
|
||||
typedef signed short RETCODE;
|
||||
|
||||
# ifdef WIN32
|
||||
# define SQL_API __stdcall
|
||||
# else
|
||||
# define SQL_API EXPORT CALLBACK
|
||||
# endif
|
||||
#ifdef WIN32
|
||||
#define SQL_API __stdcall
|
||||
#else
|
||||
#define SQL_API EXPORT CALLBACK
|
||||
#endif
|
||||
|
||||
# define ODBCVER 0x0250
|
||||
#define ODBCVER 0x0250
|
||||
|
||||
# define SQL_MAX_MESSAGE_LENGTH 512
|
||||
# define SQL_MAX_DSN_LENGTH 32
|
||||
#define SQL_MAX_MESSAGE_LENGTH 512
|
||||
#define SQL_MAX_DSN_LENGTH 32
|
||||
|
||||
/* return code */
|
||||
# define SQL_INVALID_HANDLE (-2)
|
||||
# define SQL_ERROR (-1)
|
||||
# define SQL_SUCCESS 0
|
||||
# define SQL_SUCCESS_WITH_INFO 1
|
||||
# define SQL_NO_DATA_FOUND 100
|
||||
#define SQL_INVALID_HANDLE (-2)
|
||||
#define SQL_ERROR (-1)
|
||||
#define SQL_SUCCESS 0
|
||||
#define SQL_SUCCESS_WITH_INFO 1
|
||||
#define SQL_NO_DATA_FOUND 100
|
||||
|
||||
/* standard SQL datatypes (agree with ANSI type numbering) */
|
||||
# define SQL_CHAR 1
|
||||
# define SQL_NUMERIC 2
|
||||
# define SQL_DECIMAL 3
|
||||
# define SQL_INTEGER 4
|
||||
# define SQL_SMALLINT 5
|
||||
# define SQL_FLOAT 6
|
||||
# define SQL_REAL 7
|
||||
# define SQL_DOUBLE 8
|
||||
# define SQL_VARCHAR 12
|
||||
#define SQL_CHAR 1
|
||||
#define SQL_NUMERIC 2
|
||||
#define SQL_DECIMAL 3
|
||||
#define SQL_INTEGER 4
|
||||
#define SQL_SMALLINT 5
|
||||
#define SQL_FLOAT 6
|
||||
#define SQL_REAL 7
|
||||
#define SQL_DOUBLE 8
|
||||
#define SQL_VARCHAR 12
|
||||
|
||||
# define SQL_TYPE_MIN SQL_CHAR
|
||||
# define SQL_TYPE_NULL 0
|
||||
# define SQL_TYPE_MAX SQL_VARCHAR
|
||||
#define SQL_TYPE_MIN SQL_CHAR
|
||||
#define SQL_TYPE_NULL 0
|
||||
#define SQL_TYPE_MAX SQL_VARCHAR
|
||||
|
||||
/* C to SQL datatype mapping */
|
||||
# define SQL_C_CHAR SQL_CHAR
|
||||
# define SQL_C_LONG SQL_INTEGER
|
||||
# define SQL_C_SHORT SQL_SMALLINT
|
||||
# define SQL_C_FLOAT SQL_REAL
|
||||
# define SQL_C_DOUBLE SQL_DOUBLE
|
||||
# define SQL_C_DEFAULT 99
|
||||
#define SQL_C_CHAR SQL_CHAR
|
||||
#define SQL_C_LONG SQL_INTEGER
|
||||
#define SQL_C_SHORT SQL_SMALLINT
|
||||
#define SQL_C_FLOAT SQL_REAL
|
||||
#define SQL_C_DOUBLE SQL_DOUBLE
|
||||
#define SQL_C_DEFAULT 99
|
||||
|
||||
# define SQL_NO_NULLS 0
|
||||
# define SQL_NULLABLE 1
|
||||
# define SQL_NULLABLE_UNKNOWN 2
|
||||
#define SQL_NO_NULLS 0
|
||||
#define SQL_NULLABLE 1
|
||||
#define SQL_NULLABLE_UNKNOWN 2
|
||||
|
||||
/* some special length values */
|
||||
# define SQL_NULL_DATA (-1)
|
||||
# define SQL_DATA_AT_EXEC (-2)
|
||||
# define SQL_NTS (-3)
|
||||
#define SQL_NULL_DATA (-1)
|
||||
#define SQL_DATA_AT_EXEC (-2)
|
||||
#define SQL_NTS (-3)
|
||||
|
||||
/* SQLFreeStmt flag values */
|
||||
# define SQL_CLOSE 0
|
||||
# define SQL_DROP 1
|
||||
# define SQL_UNBIND 2
|
||||
# define SQL_RESET_PARAMS 3
|
||||
#define SQL_CLOSE 0
|
||||
#define SQL_DROP 1
|
||||
#define SQL_UNBIND 2
|
||||
#define SQL_RESET_PARAMS 3
|
||||
|
||||
/* SQLTransact flag values */
|
||||
# define SQL_COMMIT 0
|
||||
# define SQL_ROLLBACK 1
|
||||
#define SQL_COMMIT 0
|
||||
#define SQL_ROLLBACK 1
|
||||
|
||||
/* SQLColAttributes flag values */
|
||||
# define SQL_COLUMN_COUNT 0
|
||||
# define SQL_COLUMN_LABEL 18
|
||||
# define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL
|
||||
# define SQL_COLUMN_DRIVER_START 1000
|
||||
#define SQL_COLUMN_COUNT 0
|
||||
#define SQL_COLUMN_LABEL 18
|
||||
#define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL
|
||||
#define SQL_COLUMN_DRIVER_START 1000
|
||||
|
||||
# define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT
|
||||
#define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT
|
||||
|
||||
/* Null handles */
|
||||
# define SQL_NULL_HENV 0
|
||||
# define SQL_NULL_HDBC 0
|
||||
# define SQL_NULL_HSTMT 0
|
||||
#define SQL_NULL_HENV 0
|
||||
#define SQL_NULL_HDBC 0
|
||||
#define SQL_NULL_HSTMT 0
|
||||
|
||||
/* All code below has been added to the original isql.h coming from iodbc */
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* More SQLColAttributes flag values */
|
||||
#define SQL_COLUMN_NAME 1
|
||||
@@ -116,9 +116,9 @@ typedef unsigned char BYTE;
|
||||
/* SQLColAttributes Searchable flags */
|
||||
#define SQL_UNSEARCHABLE 0
|
||||
#define SQL_LIKE_ONLY 1
|
||||
#define SQL_ALL_EXCEPT_LIKE 2
|
||||
#define SQL_ALL_EXCEPT_LIKE 2
|
||||
#define SQL_SEARCHABLE 3
|
||||
#define SQL_PRED_SEARCHABLE SQL_SEARCHABLE
|
||||
#define SQL_PRED_SEARCHABLE SQL_SEARCHABLE
|
||||
|
||||
/* SQLColAttributes Updateable flags */
|
||||
#define SQL_ATTR_READONLY 0
|
||||
@@ -126,112 +126,113 @@ typedef unsigned char BYTE;
|
||||
#define SQL_ATTR_READWRITE_UNKNOWN 2
|
||||
|
||||
/*
|
||||
* function prototypes previously not contained in isql.h
|
||||
* function prototypes previously not contained in isql.h
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
RETCODE SQL_API SQLAllocConnect (HENV henv,
|
||||
HDBC FAR * phdbc);
|
||||
RETCODE SQL_API SQLAllocEnv (HENV FAR * phenv);
|
||||
RETCODE SQL_API SQLAllocStmt (HDBC hdbc,
|
||||
HSTMT FAR * phstmt);
|
||||
RETCODE SQL_API SQLBindCol (HSTMT hstmt,
|
||||
UWORD icol,
|
||||
SWORD fCType,
|
||||
PTR rgbValue,
|
||||
SDWORD cbValueMax,
|
||||
SDWORD FAR * pcbValue);
|
||||
RETCODE SQL_API SQLAllocConnect(HENV henv,
|
||||
HDBC FAR *phdbc);
|
||||
RETCODE SQL_API SQLAllocEnv(HENV FAR *phenv);
|
||||
RETCODE SQL_API SQLAllocStmt(HDBC hdbc,
|
||||
HSTMT FAR *phstmt);
|
||||
RETCODE SQL_API SQLBindCol(HSTMT hstmt,
|
||||
UWORD icol,
|
||||
SWORD fCType,
|
||||
PTR rgbValue,
|
||||
SDWORD cbValueMax,
|
||||
SDWORD FAR *pcbValue);
|
||||
|
||||
RETCODE SQL_API SQLCancel (HSTMT hstmt);
|
||||
RETCODE SQL_API SQLCancel(HSTMT hstmt);
|
||||
|
||||
RETCODE SQL_API SQLColAttributes (HSTMT hstmt,
|
||||
UWORD icol,
|
||||
UWORD fDescType,
|
||||
PTR rgbDesc,
|
||||
SWORD cbDescMax,
|
||||
SWORD FAR * pcbDesc,
|
||||
SDWORD FAR * pfDesc);
|
||||
RETCODE SQL_API SQLColAttributes(HSTMT hstmt,
|
||||
UWORD icol,
|
||||
UWORD fDescType,
|
||||
PTR rgbDesc,
|
||||
SWORD cbDescMax,
|
||||
SWORD FAR *pcbDesc,
|
||||
SDWORD FAR *pfDesc);
|
||||
|
||||
RETCODE SQL_API SQLConnect (HDBC hdbc,
|
||||
UCHAR FAR * szDSN,
|
||||
SWORD cbDSN,
|
||||
UCHAR FAR * szUID,
|
||||
SWORD cbUID,
|
||||
UCHAR FAR * szAuthStr,
|
||||
SWORD cbAuthStr);
|
||||
RETCODE SQL_API SQLConnect(HDBC hdbc,
|
||||
UCHAR FAR *szDSN,
|
||||
SWORD cbDSN,
|
||||
UCHAR FAR *szUID,
|
||||
SWORD cbUID,
|
||||
UCHAR FAR *szAuthStr,
|
||||
SWORD cbAuthStr);
|
||||
|
||||
RETCODE SQL_API SQLDescribeCol (HSTMT hstmt,
|
||||
UWORD icol,
|
||||
UCHAR FAR * szColName,
|
||||
SWORD cbColNameMax,
|
||||
SWORD FAR * pcbColName,
|
||||
SWORD FAR * pfSqlType,
|
||||
UDWORD FAR * pcbColDef,
|
||||
SWORD FAR * pibScale,
|
||||
SWORD FAR * pfNullable);
|
||||
RETCODE SQL_API SQLDescribeCol(HSTMT hstmt,
|
||||
UWORD icol,
|
||||
UCHAR FAR *szColName,
|
||||
SWORD cbColNameMax,
|
||||
SWORD FAR *pcbColName,
|
||||
SWORD FAR *pfSqlType,
|
||||
UDWORD FAR *pcbColDef,
|
||||
SWORD FAR *pibScale,
|
||||
SWORD FAR *pfNullable);
|
||||
|
||||
RETCODE SQL_API SQLDisconnect (HDBC hdbc);
|
||||
RETCODE SQL_API SQLDisconnect(HDBC hdbc);
|
||||
|
||||
RETCODE SQL_API SQLError (HENV henv,
|
||||
HDBC hdbc,
|
||||
HSTMT hstmt,
|
||||
UCHAR FAR * szSqlState,
|
||||
SDWORD FAR * pfNativeError,
|
||||
UCHAR FAR * szErrorMsg,
|
||||
SWORD cbErrorMsgMax,
|
||||
SWORD FAR * pcbErrorMsg);
|
||||
RETCODE SQL_API SQLError(HENV henv,
|
||||
HDBC hdbc,
|
||||
HSTMT hstmt,
|
||||
UCHAR FAR *szSqlState,
|
||||
SDWORD FAR *pfNativeError,
|
||||
UCHAR FAR *szErrorMsg,
|
||||
SWORD cbErrorMsgMax,
|
||||
SWORD FAR *pcbErrorMsg);
|
||||
|
||||
RETCODE SQL_API SQLExecDirect (HSTMT hstmt,
|
||||
UCHAR FAR * szSqlStr,
|
||||
SDWORD cbSqlStr);
|
||||
RETCODE SQL_API SQLExecDirect(HSTMT hstmt,
|
||||
UCHAR FAR *szSqlStr,
|
||||
SDWORD cbSqlStr);
|
||||
|
||||
RETCODE SQL_API SQLExecute (HSTMT hstmt);
|
||||
RETCODE SQL_API SQLExecute(HSTMT hstmt);
|
||||
|
||||
RETCODE SQL_API SQLFetch (HSTMT hstmt);
|
||||
RETCODE SQL_API SQLFetch(HSTMT hstmt);
|
||||
|
||||
RETCODE SQL_API SQLFreeConnect (HDBC hdbc);
|
||||
RETCODE SQL_API SQLFreeConnect(HDBC hdbc);
|
||||
|
||||
RETCODE SQL_API SQLFreeEnv (HENV henv);
|
||||
RETCODE SQL_API SQLFreeEnv(HENV henv);
|
||||
|
||||
RETCODE SQL_API SQLFreeStmt (HSTMT hstmt,
|
||||
UWORD fOption);
|
||||
RETCODE SQL_API SQLFreeStmt(HSTMT hstmt,
|
||||
UWORD fOption);
|
||||
|
||||
RETCODE SQL_API SQLGetCursorName (HSTMT hstmt,
|
||||
UCHAR FAR * szCursor,
|
||||
SWORD cbCursorMax,
|
||||
SWORD FAR * pcbCursor);
|
||||
RETCODE SQL_API SQLGetCursorName(HSTMT hstmt,
|
||||
UCHAR FAR *szCursor,
|
||||
SWORD cbCursorMax,
|
||||
SWORD FAR *pcbCursor);
|
||||
|
||||
RETCODE SQL_API SQLNumResultCols (HSTMT hstmt,
|
||||
SWORD FAR * pccol);
|
||||
RETCODE SQL_API SQLNumResultCols(HSTMT hstmt,
|
||||
SWORD FAR *pccol);
|
||||
|
||||
RETCODE SQL_API SQLPrepare (HSTMT hstmt,
|
||||
UCHAR FAR * szSqlStr,
|
||||
SDWORD cbSqlStr);
|
||||
RETCODE SQL_API SQLPrepare(HSTMT hstmt,
|
||||
UCHAR FAR *szSqlStr,
|
||||
SDWORD cbSqlStr);
|
||||
|
||||
RETCODE SQL_API SQLRowCount (HSTMT hstmt,
|
||||
SDWORD FAR * pcrow);
|
||||
RETCODE SQL_API SQLRowCount(HSTMT hstmt,
|
||||
SDWORD FAR *pcrow);
|
||||
|
||||
RETCODE SQL_API SQLSetCursorName (HSTMT hstmt,
|
||||
UCHAR FAR * szCursor,
|
||||
SWORD cbCursor);
|
||||
RETCODE SQL_API SQLSetCursorName(HSTMT hstmt,
|
||||
UCHAR FAR *szCursor,
|
||||
SWORD cbCursor);
|
||||
|
||||
RETCODE SQL_API SQLTransact (HENV henv,
|
||||
HDBC hdbc,
|
||||
UWORD fType);
|
||||
RETCODE SQL_API SQLTransact(HENV henv,
|
||||
HDBC hdbc,
|
||||
UWORD fType);
|
||||
|
||||
RETCODE SQL_API SQLSetParam (HSTMT hstmt,
|
||||
UWORD ipar,
|
||||
SWORD fCType,
|
||||
SWORD fSqlType,
|
||||
UDWORD cbColDef,
|
||||
SWORD ibScale,
|
||||
PTR rgbValue,
|
||||
SDWORD FAR * pcbValue);
|
||||
RETCODE SQL_API SQLSetParam(HSTMT hstmt,
|
||||
UWORD ipar,
|
||||
SWORD fCType,
|
||||
SWORD fSqlType,
|
||||
UDWORD cbColDef,
|
||||
SWORD ibScale,
|
||||
PTR rgbValue,
|
||||
SDWORD FAR *pcbValue);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,14 @@
|
||||
|
||||
/* Module: lobj.c
|
||||
/* Module: lobj.c
|
||||
*
|
||||
* Description: This module contains routines related to manipulating
|
||||
* large objects.
|
||||
* Description: This module contains routines related to manipulating
|
||||
* large objects.
|
||||
*
|
||||
* Classes: none
|
||||
* Classes: none
|
||||
*
|
||||
* API functions: none
|
||||
* API functions: none
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -19,15 +19,16 @@
|
||||
Oid
|
||||
lo_creat(ConnectionClass *conn, int mode)
|
||||
{
|
||||
LO_ARG argv[1];
|
||||
int retval, result_len;
|
||||
LO_ARG argv[1];
|
||||
int retval,
|
||||
result_len;
|
||||
|
||||
argv[0].isint = 1;
|
||||
argv[0].len = 4;
|
||||
argv[0].u.integer = mode;
|
||||
|
||||
if ( ! CC_send_function(conn, LO_CREAT, &retval, &result_len, 1, argv, 1))
|
||||
return 0; /* invalid oid */
|
||||
if (!CC_send_function(conn, LO_CREAT, &retval, &result_len, 1, argv, 1))
|
||||
return 0; /* invalid oid */
|
||||
else
|
||||
return retval;
|
||||
|
||||
@@ -37,9 +38,9 @@ int retval, result_len;
|
||||
int
|
||||
lo_open(ConnectionClass *conn, int lobjId, int mode)
|
||||
{
|
||||
int fd;
|
||||
int result_len;
|
||||
LO_ARG argv[2];
|
||||
int fd;
|
||||
int result_len;
|
||||
LO_ARG argv[2];
|
||||
|
||||
|
||||
argv[0].isint = 1;
|
||||
@@ -50,7 +51,7 @@ LO_ARG argv[2];
|
||||
argv[1].len = 4;
|
||||
argv[1].u.integer = mode;
|
||||
|
||||
if ( ! CC_send_function(conn, LO_OPEN, &fd, &result_len, 1, argv, 2))
|
||||
if (!CC_send_function(conn, LO_OPEN, &fd, &result_len, 1, argv, 2))
|
||||
return -1;
|
||||
|
||||
if (fd >= 0 && lo_lseek(conn, fd, 0L, SEEK_SET) < 0)
|
||||
@@ -59,18 +60,19 @@ LO_ARG argv[2];
|
||||
return fd;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
lo_close(ConnectionClass *conn, int fd)
|
||||
{
|
||||
LO_ARG argv[1];
|
||||
int retval, result_len;
|
||||
LO_ARG argv[1];
|
||||
int retval,
|
||||
result_len;
|
||||
|
||||
|
||||
argv[0].isint = 1;
|
||||
argv[0].len = 4;
|
||||
argv[0].u.integer = fd;
|
||||
|
||||
if ( ! CC_send_function(conn, LO_CLOSE, &retval, &result_len, 1, argv, 1))
|
||||
if (!CC_send_function(conn, LO_CLOSE, &retval, &result_len, 1, argv, 1))
|
||||
return -1;
|
||||
|
||||
else
|
||||
@@ -82,8 +84,8 @@ int retval, result_len;
|
||||
int
|
||||
lo_read(ConnectionClass *conn, int fd, char *buf, int len)
|
||||
{
|
||||
LO_ARG argv[2];
|
||||
int result_len;
|
||||
LO_ARG argv[2];
|
||||
int result_len;
|
||||
|
||||
|
||||
argv[0].isint = 1;
|
||||
@@ -94,7 +96,7 @@ int result_len;
|
||||
argv[1].len = 4;
|
||||
argv[1].u.integer = len;
|
||||
|
||||
if ( ! CC_send_function(conn, LO_READ, (int *) buf, &result_len, 0, argv, 2))
|
||||
if (!CC_send_function(conn, LO_READ, (int *) buf, &result_len, 0, argv, 2))
|
||||
return -1;
|
||||
|
||||
else
|
||||
@@ -104,8 +106,9 @@ int result_len;
|
||||
int
|
||||
lo_write(ConnectionClass *conn, int fd, char *buf, int len)
|
||||
{
|
||||
LO_ARG argv[2];
|
||||
int retval, result_len;
|
||||
LO_ARG argv[2];
|
||||
int retval,
|
||||
result_len;
|
||||
|
||||
|
||||
if (len <= 0)
|
||||
@@ -119,7 +122,7 @@ int retval, result_len;
|
||||
argv[1].len = len;
|
||||
argv[1].u.ptr = (char *) buf;
|
||||
|
||||
if ( ! CC_send_function(conn, LO_WRITE, &retval, &result_len, 1, argv, 2))
|
||||
if (!CC_send_function(conn, LO_WRITE, &retval, &result_len, 1, argv, 2))
|
||||
return -1;
|
||||
|
||||
else
|
||||
@@ -129,8 +132,9 @@ int retval, result_len;
|
||||
int
|
||||
lo_lseek(ConnectionClass *conn, int fd, int offset, int whence)
|
||||
{
|
||||
LO_ARG argv[3];
|
||||
int retval, result_len;
|
||||
LO_ARG argv[3];
|
||||
int retval,
|
||||
result_len;
|
||||
|
||||
|
||||
argv[0].isint = 1;
|
||||
@@ -145,7 +149,7 @@ int retval, result_len;
|
||||
argv[2].len = 4;
|
||||
argv[2].u.integer = whence;
|
||||
|
||||
if ( ! CC_send_function(conn, LO_LSEEK, &retval, &result_len, 1, argv, 3))
|
||||
if (!CC_send_function(conn, LO_LSEEK, &retval, &result_len, 1, argv, 3))
|
||||
return -1;
|
||||
|
||||
else
|
||||
@@ -155,43 +159,37 @@ int retval, result_len;
|
||||
int
|
||||
lo_tell(ConnectionClass *conn, int fd)
|
||||
{
|
||||
LO_ARG argv[1];
|
||||
int retval, result_len;
|
||||
LO_ARG argv[1];
|
||||
int retval,
|
||||
result_len;
|
||||
|
||||
|
||||
argv[0].isint = 1;
|
||||
argv[0].len = 4;
|
||||
argv[0].u.integer = fd;
|
||||
|
||||
if ( ! CC_send_function(conn, LO_TELL, &retval, &result_len, 1, argv, 1))
|
||||
if (!CC_send_function(conn, LO_TELL, &retval, &result_len, 1, argv, 1))
|
||||
return -1;
|
||||
|
||||
else
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
lo_unlink(ConnectionClass *conn, Oid lobjId)
|
||||
{
|
||||
LO_ARG argv[1];
|
||||
int retval, result_len;
|
||||
LO_ARG argv[1];
|
||||
int retval,
|
||||
result_len;
|
||||
|
||||
|
||||
argv[0].isint = 1;
|
||||
argv[0].len = 4;
|
||||
argv[0].u.integer = lobjId;
|
||||
|
||||
if ( ! CC_send_function(conn, LO_UNLINK, &retval, &result_len, 1, argv, 1))
|
||||
if (!CC_send_function(conn, LO_UNLINK, &retval, &result_len, 1, argv, 1))
|
||||
return -1;
|
||||
|
||||
else
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
/* File: lobj.h
|
||||
/* File: lobj.h
|
||||
*
|
||||
* Description: See "lobj.c"
|
||||
* Description: See "lobj.c"
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -13,14 +13,15 @@
|
||||
|
||||
#include "psqlodbc.h"
|
||||
|
||||
struct lo_arg {
|
||||
int isint;
|
||||
int len;
|
||||
struct lo_arg
|
||||
{
|
||||
int isint;
|
||||
int len;
|
||||
union
|
||||
{
|
||||
int integer;
|
||||
char *ptr;
|
||||
} u;
|
||||
int integer;
|
||||
char *ptr;
|
||||
} u;
|
||||
};
|
||||
|
||||
#define LO_CREAT 957
|
||||
@@ -35,14 +36,13 @@ struct lo_arg {
|
||||
#define INV_WRITE 0x00020000
|
||||
#define INV_READ 0x00040000
|
||||
|
||||
Oid lo_creat(ConnectionClass *conn, int mode);
|
||||
int lo_open(ConnectionClass *conn, int lobjId, int mode);
|
||||
int lo_close(ConnectionClass *conn, int fd);
|
||||
int lo_read(ConnectionClass *conn, int fd, char *buf, int len);
|
||||
int lo_write(ConnectionClass *conn, int fd, char *buf, int len);
|
||||
int lo_lseek(ConnectionClass *conn, int fd, int offset, int len);
|
||||
int lo_tell(ConnectionClass *conn, int fd);
|
||||
int lo_unlink(ConnectionClass *conn, Oid lobjId);
|
||||
Oid lo_creat(ConnectionClass *conn, int mode);
|
||||
int lo_open(ConnectionClass *conn, int lobjId, int mode);
|
||||
int lo_close(ConnectionClass *conn, int fd);
|
||||
int lo_read(ConnectionClass *conn, int fd, char *buf, int len);
|
||||
int lo_write(ConnectionClass *conn, int fd, char *buf, int len);
|
||||
int lo_lseek(ConnectionClass *conn, int fd, int offset, int len);
|
||||
int lo_tell(ConnectionClass *conn, int fd);
|
||||
int lo_unlink(ConnectionClass *conn, Oid lobjId);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
|
||||
/* Module: misc.c
|
||||
/* Module: misc.c
|
||||
*
|
||||
* Description: This module contains miscellaneous routines
|
||||
* such as for debugging/logging and string functions.
|
||||
* Description: This module contains miscellaneous routines
|
||||
* such as for debugging/logging and string functions.
|
||||
*
|
||||
* Classes: n/a
|
||||
* Classes: n/a
|
||||
*
|
||||
* API functions: none
|
||||
* API functions: none
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -25,49 +25,54 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <process.h> /* Byron: is this where Windows keeps def. of getpid ? */
|
||||
#include <process.h> /* Byron: is this where Windows keeps def.
|
||||
* of getpid ? */
|
||||
#endif
|
||||
|
||||
extern GLOBAL_VALUES globals;
|
||||
void generate_filename(char*,char*,char*);
|
||||
void generate_filename(char *, char *, char *);
|
||||
|
||||
void
|
||||
generate_filename(char* dirname,char* prefix,char* filename)
|
||||
generate_filename(char *dirname, char *prefix, char *filename)
|
||||
{
|
||||
int pid = 0;
|
||||
int pid = 0;
|
||||
|
||||
#ifndef WIN32
|
||||
struct passwd *ptr = 0;
|
||||
|
||||
ptr = getpwuid(getuid());
|
||||
#endif
|
||||
pid = getpid();
|
||||
if(dirname == 0 || filename == 0)
|
||||
if (dirname == 0 || filename == 0)
|
||||
return;
|
||||
|
||||
strcpy(filename,dirname);
|
||||
strcat(filename,DIRSEPARATOR);
|
||||
if(prefix != 0)
|
||||
strcat(filename,prefix);
|
||||
strcpy(filename, dirname);
|
||||
strcat(filename, DIRSEPARATOR);
|
||||
if (prefix != 0)
|
||||
strcat(filename, prefix);
|
||||
#ifndef WIN32
|
||||
strcat(filename,ptr->pw_name);
|
||||
strcat(filename, ptr->pw_name);
|
||||
#endif
|
||||
sprintf(filename,"%s%u%s",filename,pid,".log");
|
||||
sprintf(filename, "%s%u%s", filename, pid, ".log");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MY_LOG
|
||||
|
||||
void
|
||||
mylog(char * fmt, ...)
|
||||
mylog(char *fmt,...)
|
||||
{
|
||||
va_list args;
|
||||
char filebuf[80];
|
||||
FILE* LOGFP = globals.mylogFP;
|
||||
va_list args;
|
||||
char filebuf[80];
|
||||
FILE *LOGFP = globals.mylogFP;
|
||||
|
||||
if ( globals.debug) {
|
||||
if (globals.debug)
|
||||
{
|
||||
va_start(args, fmt);
|
||||
|
||||
if (! LOGFP) {
|
||||
generate_filename(MYLOGDIR,MYLOGFILE,filebuf);
|
||||
if (!LOGFP)
|
||||
{
|
||||
generate_filename(MYLOGDIR, MYLOGFILE, filebuf);
|
||||
LOGFP = fopen(filebuf, PG_BINARY_W);
|
||||
globals.mylogFP = LOGFP;
|
||||
setbuf(LOGFP, NULL);
|
||||
@@ -79,23 +84,26 @@ mylog(char * fmt, ...)
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef Q_LOG
|
||||
|
||||
void
|
||||
qlog(char * fmt, ...)
|
||||
qlog(char *fmt,...)
|
||||
{
|
||||
va_list args;
|
||||
char filebuf[80];
|
||||
FILE* LOGFP = globals.qlogFP;
|
||||
va_list args;
|
||||
char filebuf[80];
|
||||
FILE *LOGFP = globals.qlogFP;
|
||||
|
||||
if ( globals.commlog) {
|
||||
if (globals.commlog)
|
||||
{
|
||||
va_start(args, fmt);
|
||||
|
||||
if (! LOGFP) {
|
||||
generate_filename(QLOGDIR,QLOGFILE,filebuf);
|
||||
if (!LOGFP)
|
||||
{
|
||||
generate_filename(QLOGDIR, QLOGFILE, filebuf);
|
||||
LOGFP = fopen(filebuf, PG_BINARY_W);
|
||||
globals.qlogFP = LOGFP;
|
||||
setbuf(LOGFP, NULL);
|
||||
@@ -107,9 +115,10 @@ qlog(char * fmt, ...)
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Undefine these because windows.h will redefine and cause a warning */
|
||||
/* Undefine these because windows.h will redefine and cause a warning */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
@@ -136,7 +145,8 @@ my_strcpy(char *dst, int dst_len, char *src, int src_len)
|
||||
if (dst_len <= 0)
|
||||
return STRCPY_FAIL;
|
||||
|
||||
if (src_len == SQL_NULL_DATA) {
|
||||
if (src_len == SQL_NULL_DATA)
|
||||
{
|
||||
dst[0] = '\0';
|
||||
return STRCPY_NULL;
|
||||
}
|
||||
@@ -146,14 +156,17 @@ my_strcpy(char *dst, int dst_len, char *src, int src_len)
|
||||
if (src_len <= 0)
|
||||
return STRCPY_FAIL;
|
||||
|
||||
else {
|
||||
if (src_len < dst_len) {
|
||||
else
|
||||
{
|
||||
if (src_len < dst_len)
|
||||
{
|
||||
memcpy(dst, src, src_len);
|
||||
dst[src_len] = '\0';
|
||||
}
|
||||
else {
|
||||
memcpy(dst, src, dst_len-1);
|
||||
dst[dst_len-1] = '\0'; /* truncated */
|
||||
else
|
||||
{
|
||||
memcpy(dst, src, dst_len - 1);
|
||||
dst[dst_len - 1] = '\0'; /* truncated */
|
||||
return STRCPY_TRUNCATED;
|
||||
}
|
||||
}
|
||||
@@ -165,28 +178,29 @@ my_strcpy(char *dst, int dst_len, char *src, int src_len)
|
||||
/* the destination string if src has len characters or more. */
|
||||
/* instead, I want it to copy up to len-1 characters and always */
|
||||
/* terminate the destination string. */
|
||||
char *strncpy_null(char *dst, const char *src, int len)
|
||||
char *
|
||||
strncpy_null(char *dst, const char *src, int len)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
|
||||
if (NULL != dst) {
|
||||
if (NULL != dst)
|
||||
{
|
||||
|
||||
/* Just in case, check for special lengths */
|
||||
if (len == SQL_NULL_DATA) {
|
||||
/* Just in case, check for special lengths */
|
||||
if (len == SQL_NULL_DATA)
|
||||
{
|
||||
dst[0] = '\0';
|
||||
return NULL;
|
||||
}
|
||||
else if (len == SQL_NTS)
|
||||
len = strlen(src) + 1;
|
||||
|
||||
for(i = 0; src[i] && i < len - 1; i++) {
|
||||
for (i = 0; src[i] && i < len - 1; i++)
|
||||
dst[i] = src[i];
|
||||
}
|
||||
|
||||
if(len > 0) {
|
||||
if (len > 0)
|
||||
dst[i] = '\0';
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
@@ -197,22 +211,24 @@ int i;
|
||||
char *
|
||||
make_string(char *s, int len, char *buf)
|
||||
{
|
||||
int length;
|
||||
char *str;
|
||||
int length;
|
||||
char *str;
|
||||
|
||||
if(s && (len > 0 || (len == SQL_NTS && strlen(s) > 0))) {
|
||||
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
|
||||
{
|
||||
length = (len > 0) ? len : strlen(s);
|
||||
|
||||
if (buf) {
|
||||
strncpy_null(buf, s, length+1);
|
||||
if (buf)
|
||||
{
|
||||
strncpy_null(buf, s, length + 1);
|
||||
return buf;
|
||||
}
|
||||
|
||||
str = malloc(length + 1);
|
||||
if ( ! str)
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
strncpy_null(str, s, length+1);
|
||||
strncpy_null(str, s, length + 1);
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -227,10 +243,11 @@ char *
|
||||
my_strcat(char *buf, char *fmt, char *s, int len)
|
||||
{
|
||||
|
||||
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0))) {
|
||||
int length = (len > 0) ? len : strlen(s);
|
||||
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
|
||||
{
|
||||
int length = (len > 0) ? len : strlen(s);
|
||||
|
||||
int pos = strlen(buf);
|
||||
int pos = strlen(buf);
|
||||
|
||||
sprintf(&buf[pos], fmt, length, s);
|
||||
return buf;
|
||||
@@ -238,24 +255,26 @@ my_strcat(char *buf, char *fmt, char *s, int len)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void remove_newlines(char *string)
|
||||
void
|
||||
remove_newlines(char *string)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for(i=0; i < strlen(string); i++) {
|
||||
if((string[i] == '\n') ||
|
||||
(string[i] == '\r')) {
|
||||
for (i = 0; i < strlen(string); i++)
|
||||
{
|
||||
if ((string[i] == '\n') ||
|
||||
(string[i] == '\r'))
|
||||
string[i] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
trim(char *s)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = strlen(s) - 1; i >= 0; i--) {
|
||||
for (i = strlen(s) - 1; i >= 0; i--)
|
||||
{
|
||||
if (s[i] == ' ')
|
||||
s[i] = '\0';
|
||||
else
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
/* File: misc.h
|
||||
/* File: misc.h
|
||||
*
|
||||
* Description: See "misc.c"
|
||||
* Description: See "misc.c"
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -39,35 +39,37 @@
|
||||
|
||||
|
||||
#ifdef MY_LOG
|
||||
#define MYLOGFILE "mylog_"
|
||||
#ifndef WIN32
|
||||
#define MYLOGDIR "/tmp"
|
||||
#else
|
||||
#define MYLOGDIR "c:"
|
||||
#endif
|
||||
extern void mylog(char * fmt, ...);
|
||||
#define MYLOGFILE "mylog_"
|
||||
#ifndef WIN32
|
||||
#define MYLOGDIR "/tmp"
|
||||
#else
|
||||
#ifndef WIN32
|
||||
#define mylog(args...) /* GNU convention for variable arguments */
|
||||
#else
|
||||
#define mylog /* mylog */
|
||||
#endif
|
||||
#define MYLOGDIR "c:"
|
||||
#endif
|
||||
extern void mylog(char *fmt,...);
|
||||
|
||||
#else
|
||||
#ifndef WIN32
|
||||
#define mylog(args...) /* GNU convention for variable arguments */
|
||||
#else
|
||||
#define mylog /* mylog */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef Q_LOG
|
||||
#define QLOGFILE "psqlodbc_"
|
||||
#ifndef WIN32
|
||||
#define QLOGDIR "/tmp"
|
||||
#else
|
||||
#define QLOGDIR "c:"
|
||||
#endif
|
||||
extern void qlog(char * fmt, ...);
|
||||
#define QLOGFILE "psqlodbc_"
|
||||
#ifndef WIN32
|
||||
#define QLOGDIR "/tmp"
|
||||
#else
|
||||
#ifndef WIN32
|
||||
#define qlog(args...) /* GNU convention for variable arguments */
|
||||
#else
|
||||
#define qlog /* qlog */
|
||||
#endif
|
||||
#define QLOGDIR "c:"
|
||||
#endif
|
||||
extern void qlog(char *fmt,...);
|
||||
|
||||
#else
|
||||
#ifndef WIN32
|
||||
#define qlog(args...) /* GNU convention for variable arguments */
|
||||
#else
|
||||
#define qlog /* qlog */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
@@ -78,20 +80,20 @@
|
||||
|
||||
#ifdef WIN32
|
||||
#define PG_BINARY O_BINARY
|
||||
#define PG_BINARY_R "rb"
|
||||
#define PG_BINARY_W "wb"
|
||||
#define PG_BINARY_R "rb"
|
||||
#define PG_BINARY_W "wb"
|
||||
#else
|
||||
#define PG_BINARY 0
|
||||
#define PG_BINARY_R "r"
|
||||
#define PG_BINARY_W "w"
|
||||
#define PG_BINARY 0
|
||||
#define PG_BINARY_R "r"
|
||||
#define PG_BINARY_W "w"
|
||||
#endif
|
||||
|
||||
|
||||
void remove_newlines(char *string);
|
||||
char *strncpy_null(char *dst, const char *src, int len);
|
||||
char *trim(char *string);
|
||||
char *make_string(char *s, int len, char *buf);
|
||||
char *my_strcat(char *buf, char *fmt, char *s, int len);
|
||||
void remove_newlines(char *string);
|
||||
char *strncpy_null(char *dst, const char *src, int len);
|
||||
char *trim(char *string);
|
||||
char *make_string(char *s, int len, char *buf);
|
||||
char *my_strcat(char *buf, char *fmt, char *s, int len);
|
||||
|
||||
/* defines for return value of my_strcpy */
|
||||
#define STRCPY_SUCCESS 1
|
||||
@@ -99,6 +101,6 @@ char *my_strcat(char *buf, char *fmt, char *s, int len);
|
||||
#define STRCPY_TRUNCATED -1
|
||||
#define STRCPY_NULL -2
|
||||
|
||||
int my_strcpy(char *dst, int dst_len, char *src, int src_len);
|
||||
int my_strcpy(char *dst, int dst_len, char *src, int src_len);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,71 +5,74 @@
|
||||
*
|
||||
* Create 2001-03-03 Eiji Tokuya
|
||||
*
|
||||
*/
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "multibyte.h"
|
||||
|
||||
int multibyte_client_encoding ; /* Multibyte Client Encoding. */
|
||||
int multibyte_status ; /* Multibyte Odds and ends character. */
|
||||
int multibyte_client_encoding; /* Multibyte Client Encoding. */
|
||||
int multibyte_status; /* Multibyte Odds and ends character. */
|
||||
|
||||
unsigned char *multibyte_strchr(unsigned char *s,unsigned char c)
|
||||
unsigned char *
|
||||
multibyte_strchr(unsigned char *s, unsigned char c)
|
||||
{
|
||||
int mb_st = 0 ,i = 0;
|
||||
int mb_st = 0,
|
||||
i = 0;
|
||||
|
||||
while (!(mb_st == 0 && (s[i] == c || s[i] == 0)))
|
||||
{
|
||||
if (s[i] == 0)
|
||||
return (0);
|
||||
switch ( multibyte_client_encoding )
|
||||
switch (multibyte_client_encoding)
|
||||
{
|
||||
case SJIS:
|
||||
{
|
||||
if (mb_st < 2 && s[i] > 0x80 && !(s[i] > 0x9f && s[i] < 0xe0))
|
||||
mb_st = 2;
|
||||
else if (mb_st == 2)
|
||||
{
|
||||
if (mb_st < 2 && s[i] > 0x80 && !(s[i] > 0x9f && s[i] < 0xe0))
|
||||
mb_st = 2;
|
||||
else if (mb_st == 2)
|
||||
mb_st = 1;
|
||||
else
|
||||
mb_st = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
/* Chinese Big5 Support. */
|
||||
case BIG5:
|
||||
{
|
||||
if ( mb_st < 2 && s[i] > 0xA0 )
|
||||
case BIG5:
|
||||
{
|
||||
if (mb_st < 2 && s[i] > 0xA0)
|
||||
mb_st = 2;
|
||||
else if ( mb_st == 2 )
|
||||
else if (mb_st == 2)
|
||||
mb_st = 1;
|
||||
else
|
||||
mb_st = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
mb_st = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
mb_st = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
qlog("i = %d\n",i);
|
||||
qlog("i = %d\n", i);
|
||||
#endif
|
||||
return (s + i);
|
||||
}
|
||||
|
||||
void multibyte_init(void)
|
||||
void
|
||||
multibyte_init(void)
|
||||
{
|
||||
multibyte_status = 0;
|
||||
}
|
||||
|
||||
unsigned char *check_client_encoding(unsigned char *str)
|
||||
unsigned char *
|
||||
check_client_encoding(unsigned char *str)
|
||||
{
|
||||
if(strstr(str,"%27SJIS%27")||strstr(str,"'SJIS'")||strstr(str,"'sjis'"))
|
||||
if (strstr(str, "%27SJIS%27") || strstr(str, "'SJIS'") || strstr(str, "'sjis'"))
|
||||
{
|
||||
multibyte_client_encoding = SJIS;
|
||||
return ("SJIS");
|
||||
}
|
||||
if(strstr(str,"%27BIG5%27")||strstr(str,"'BIG5'")||strstr(str,"'big5'"))
|
||||
if (strstr(str, "%27BIG5%27") || strstr(str, "'BIG5'") || strstr(str, "'big5'"))
|
||||
{
|
||||
multibyte_client_encoding = BIG5;
|
||||
return ("BIG5");
|
||||
@@ -77,48 +80,47 @@ unsigned char *check_client_encoding(unsigned char *str)
|
||||
return ("OHTER");
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Multibyte Status Function.
|
||||
* Input char
|
||||
* Output 0 : 1 Byte Character.
|
||||
* 1 : MultibyteCharacter Last Byte.
|
||||
* N : MultibyteCharacter Fast or Middle Byte.
|
||||
*/
|
||||
int multibyte_char_check(unsigned char s)
|
||||
int
|
||||
multibyte_char_check(unsigned char s)
|
||||
{
|
||||
switch ( multibyte_client_encoding )
|
||||
switch (multibyte_client_encoding)
|
||||
{
|
||||
/* Japanese Shift-JIS(CP932) Support. */
|
||||
case SJIS:
|
||||
{
|
||||
if ( multibyte_status < 2 && s > 0x80 && !(s > 0x9f && s < 0xE0))
|
||||
multibyte_status = 2;
|
||||
else if (multibyte_status == 2)
|
||||
multibyte_status = 1;
|
||||
else
|
||||
multibyte_status = 0;
|
||||
}
|
||||
break;
|
||||
case SJIS:
|
||||
{
|
||||
if (multibyte_status < 2 && s > 0x80 && !(s > 0x9f && s < 0xE0))
|
||||
multibyte_status = 2;
|
||||
else if (multibyte_status == 2)
|
||||
multibyte_status = 1;
|
||||
else
|
||||
multibyte_status = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
/* Chinese Big5(CP950) Support. */
|
||||
case BIG5:
|
||||
{
|
||||
if ( multibyte_status < 2 && s > 0xA0)
|
||||
multibyte_status = 2;
|
||||
else if (multibyte_status == 2)
|
||||
multibyte_status = 1;
|
||||
else
|
||||
case BIG5:
|
||||
{
|
||||
if (multibyte_status < 2 && s > 0xA0)
|
||||
multibyte_status = 2;
|
||||
else if (multibyte_status == 2)
|
||||
multibyte_status = 1;
|
||||
else
|
||||
multibyte_status = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
multibyte_status = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
multibyte_status = 0;
|
||||
}
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
qlog("multibyte_client_encoding = %d s = 0x%02X multibyte_stat = %d\n", multibyte_client_encoding, s, multibyte_status );
|
||||
qlog("multibyte_client_encoding = %d s = 0x%02X multibyte_stat = %d\n", multibyte_client_encoding, s, multibyte_status);
|
||||
#endif
|
||||
return( multibyte_status );
|
||||
return (multibyte_status);
|
||||
}
|
||||
|
||||
@@ -6,34 +6,34 @@
|
||||
*/
|
||||
|
||||
/* PostgreSQL client encoding */
|
||||
#define SQL_ASCII 0 /* SQL/ASCII */
|
||||
#define EUC_JP 1 /* EUC for Japanese */
|
||||
#define EUC_CN 2 /* EUC for Chinese */
|
||||
#define EUC_KR 3 /* EUC for Korean */
|
||||
#define EUC_TW 4 /* EUC for Taiwan */
|
||||
#define UNICODE 5 /* Unicode UTF-8 */
|
||||
#define MULE_INTERNAL 6 /* Mule internal code */
|
||||
#define LATIN1 7 /* ISO-8859 Latin 1 */
|
||||
#define LATIN2 8 /* ISO-8859 Latin 2 */
|
||||
#define LATIN3 9 /* ISO-8859 Latin 3 */
|
||||
#define LATIN4 10 /* ISO-8859 Latin 4 */
|
||||
#define LATIN5 11 /* ISO-8859 Latin 5 */
|
||||
#define LATIN6 12 /* ISO-8859 Latin 6 */
|
||||
#define LATIN7 13 /* ISO-8859 Latin 7 */
|
||||
#define LATIN8 14 /* ISO-8859 Latin 8 */
|
||||
#define LATIN9 15 /* ISO-8859 Latin 9 */
|
||||
#define KOI8 16 /* KOI8-R */
|
||||
#define WIN 17 /* windows-1251 */
|
||||
#define ALT 18 /* Alternativny Variant (MS-DOS CP866) */
|
||||
#define SJIS 32 /* Shift JIS */
|
||||
#define BIG5 33 /* Big5 */
|
||||
#define WIN1250 34 /* windows-1250 */
|
||||
#define SQL_ASCII 0 /* SQL/ASCII */
|
||||
#define EUC_JP 1 /* EUC for Japanese */
|
||||
#define EUC_CN 2 /* EUC for Chinese */
|
||||
#define EUC_KR 3 /* EUC for Korean */
|
||||
#define EUC_TW 4 /* EUC for Taiwan */
|
||||
#define UNICODE 5 /* Unicode UTF-8 */
|
||||
#define MULE_INTERNAL 6 /* Mule internal code */
|
||||
#define LATIN1 7 /* ISO-8859 Latin 1 */
|
||||
#define LATIN2 8 /* ISO-8859 Latin 2 */
|
||||
#define LATIN3 9 /* ISO-8859 Latin 3 */
|
||||
#define LATIN4 10 /* ISO-8859 Latin 4 */
|
||||
#define LATIN5 11 /* ISO-8859 Latin 5 */
|
||||
#define LATIN6 12 /* ISO-8859 Latin 6 */
|
||||
#define LATIN7 13 /* ISO-8859 Latin 7 */
|
||||
#define LATIN8 14 /* ISO-8859 Latin 8 */
|
||||
#define LATIN9 15 /* ISO-8859 Latin 9 */
|
||||
#define KOI8 16 /* KOI8-R */
|
||||
#define WIN 17 /* windows-1251 */
|
||||
#define ALT 18 /* Alternativny Variant (MS-DOS CP866) */
|
||||
#define SJIS 32 /* Shift JIS */
|
||||
#define BIG5 33 /* Big5 */
|
||||
#define WIN1250 34 /* windows-1250 */
|
||||
|
||||
|
||||
extern int multibyte_client_encoding ; /* Multibyte client encoding. */
|
||||
extern int multibyte_status ; /* Multibyte charcter status. */
|
||||
extern int multibyte_client_encoding; /* Multibyte client encoding. */
|
||||
extern int multibyte_status; /* Multibyte charcter status. */
|
||||
|
||||
void multibyte_init(void);
|
||||
void multibyte_init(void);
|
||||
unsigned char *check_client_encoding(unsigned char *str);
|
||||
int multibyte_char_check(unsigned char s);
|
||||
int multibyte_char_check(unsigned char s);
|
||||
unsigned char *multibyte_strchr(unsigned char *s, unsigned char c);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
|
||||
/* File: pgtypes.h
|
||||
/* File: pgtypes.h
|
||||
*
|
||||
* Description: See "pgtypes.c"
|
||||
* Description: See "pgtypes.c"
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -17,48 +17,48 @@
|
||||
|
||||
|
||||
#if 0
|
||||
#define PG_TYPE_LO ???? /* waiting for permanent type */
|
||||
#define PG_TYPE_LO ????/* waiting for permanent type */
|
||||
#endif
|
||||
|
||||
#define PG_TYPE_BOOL 16
|
||||
#define PG_TYPE_BYTEA 17
|
||||
#define PG_TYPE_CHAR 18
|
||||
#define PG_TYPE_NAME 19
|
||||
#define PG_TYPE_INT8 20
|
||||
#define PG_TYPE_INT2 21
|
||||
#define PG_TYPE_INT2VECTOR 22
|
||||
#define PG_TYPE_INT4 23
|
||||
#define PG_TYPE_REGPROC 24
|
||||
#define PG_TYPE_TEXT 25
|
||||
#define PG_TYPE_OID 26
|
||||
#define PG_TYPE_TID 27
|
||||
#define PG_TYPE_XID 28
|
||||
#define PG_TYPE_CID 29
|
||||
#define PG_TYPE_OIDVECTOR 30
|
||||
#define PG_TYPE_SET 32
|
||||
#define PG_TYPE_CHAR2 409
|
||||
#define PG_TYPE_CHAR4 410
|
||||
#define PG_TYPE_CHAR8 411
|
||||
#define PG_TYPE_POINT 600
|
||||
#define PG_TYPE_LSEG 601
|
||||
#define PG_TYPE_PATH 602
|
||||
#define PG_TYPE_BOX 603
|
||||
#define PG_TYPE_POLYGON 604
|
||||
#define PG_TYPE_FILENAME 605
|
||||
#define PG_TYPE_FLOAT4 700
|
||||
#define PG_TYPE_FLOAT8 701
|
||||
#define PG_TYPE_ABSTIME 702
|
||||
#define PG_TYPE_RELTIME 703
|
||||
#define PG_TYPE_TINTERVAL 704
|
||||
#define PG_TYPE_UNKNOWN 705
|
||||
#define PG_TYPE_BOOL 16
|
||||
#define PG_TYPE_BYTEA 17
|
||||
#define PG_TYPE_CHAR 18
|
||||
#define PG_TYPE_NAME 19
|
||||
#define PG_TYPE_INT8 20
|
||||
#define PG_TYPE_INT2 21
|
||||
#define PG_TYPE_INT2VECTOR 22
|
||||
#define PG_TYPE_INT4 23
|
||||
#define PG_TYPE_REGPROC 24
|
||||
#define PG_TYPE_TEXT 25
|
||||
#define PG_TYPE_OID 26
|
||||
#define PG_TYPE_TID 27
|
||||
#define PG_TYPE_XID 28
|
||||
#define PG_TYPE_CID 29
|
||||
#define PG_TYPE_OIDVECTOR 30
|
||||
#define PG_TYPE_SET 32
|
||||
#define PG_TYPE_CHAR2 409
|
||||
#define PG_TYPE_CHAR4 410
|
||||
#define PG_TYPE_CHAR8 411
|
||||
#define PG_TYPE_POINT 600
|
||||
#define PG_TYPE_LSEG 601
|
||||
#define PG_TYPE_PATH 602
|
||||
#define PG_TYPE_BOX 603
|
||||
#define PG_TYPE_POLYGON 604
|
||||
#define PG_TYPE_FILENAME 605
|
||||
#define PG_TYPE_FLOAT4 700
|
||||
#define PG_TYPE_FLOAT8 701
|
||||
#define PG_TYPE_ABSTIME 702
|
||||
#define PG_TYPE_RELTIME 703
|
||||
#define PG_TYPE_TINTERVAL 704
|
||||
#define PG_TYPE_UNKNOWN 705
|
||||
#define PG_TYPE_MONEY 790
|
||||
#define PG_TYPE_OIDINT2 810
|
||||
#define PG_TYPE_OIDINT4 910
|
||||
#define PG_TYPE_OIDNAME 911
|
||||
#define PG_TYPE_BPCHAR 1042
|
||||
#define PG_TYPE_OIDINT2 810
|
||||
#define PG_TYPE_OIDINT4 910
|
||||
#define PG_TYPE_OIDNAME 911
|
||||
#define PG_TYPE_BPCHAR 1042
|
||||
#define PG_TYPE_VARCHAR 1043
|
||||
#define PG_TYPE_DATE 1082
|
||||
#define PG_TYPE_TIME 1083
|
||||
#define PG_TYPE_DATE 1082
|
||||
#define PG_TYPE_TIME 1083
|
||||
#define PG_TYPE_DATETIME 1184
|
||||
#define PG_TYPE_TIMESTAMP 1296
|
||||
#define PG_TYPE_NUMERIC 1700
|
||||
@@ -67,32 +67,31 @@
|
||||
extern Int2 sqlTypes[];
|
||||
|
||||
/* Defines for pgtype_precision */
|
||||
#define PG_STATIC -1
|
||||
#define PG_STATIC -1
|
||||
|
||||
Int4 sqltype_to_pgtype(Int2 fSqlType);
|
||||
Int4 sqltype_to_pgtype(Int2 fSqlType);
|
||||
|
||||
Int2 pgtype_to_sqltype(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type);
|
||||
char *pgtype_to_name(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_to_sqltype(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type);
|
||||
char *pgtype_to_name(StatementClass *stmt, Int4 type);
|
||||
|
||||
/* These functions can use static numbers or result sets(col parameter) */
|
||||
Int4 pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
|
||||
Int4 pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
|
||||
Int4 pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
|
||||
Int4 pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
|
||||
Int4 pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
|
||||
Int4 pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
|
||||
|
||||
Int2 pgtype_scale(StatementClass *stmt, Int4 type, int col);
|
||||
Int2 pgtype_radix(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_nullable(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_case_sensitive(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_money(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_searchable(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_unsigned(StatementClass *stmt, Int4 type);
|
||||
char *pgtype_literal_prefix(StatementClass *stmt, Int4 type);
|
||||
char *pgtype_literal_suffix(StatementClass *stmt, Int4 type);
|
||||
char *pgtype_create_params(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_scale(StatementClass *stmt, Int4 type, int col);
|
||||
Int2 pgtype_radix(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_nullable(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_case_sensitive(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_money(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_searchable(StatementClass *stmt, Int4 type);
|
||||
Int2 pgtype_unsigned(StatementClass *stmt, Int4 type);
|
||||
char *pgtype_literal_prefix(StatementClass *stmt, Int4 type);
|
||||
char *pgtype_literal_suffix(StatementClass *stmt, Int4 type);
|
||||
char *pgtype_create_params(StatementClass *stmt, Int4 type);
|
||||
|
||||
Int2 sqltype_to_default_ctype(Int2 sqltype);
|
||||
Int2 sqltype_to_default_ctype(Int2 sqltype);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
|
||||
/* Module: psqlodbc.c
|
||||
/* Module: psqlodbc.c
|
||||
*
|
||||
* Description: This module contains the main entry point (DllMain) for the library.
|
||||
* It also contains functions to get and set global variables for the
|
||||
* driver in the registry.
|
||||
* Description: This module contains the main entry point (DllMain) for the library.
|
||||
* It also contains functions to get and set global variables for the
|
||||
* driver in the registry.
|
||||
*
|
||||
* Classes: n/a
|
||||
* Classes: n/a
|
||||
*
|
||||
* API functions: none
|
||||
* API functions: none
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -36,57 +36,60 @@ GLOBAL_VALUES globals;
|
||||
RETCODE SQL_API SQLDummyOrdinal(void);
|
||||
|
||||
#ifdef WIN32
|
||||
HINSTANCE NEAR s_hModule; /* Saved module handle. */
|
||||
HINSTANCE NEAR s_hModule; /* Saved module handle. */
|
||||
|
||||
/* This is where the Driver Manager attaches to this Driver */
|
||||
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
|
||||
BOOL WINAPI
|
||||
DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
s_hModule = hInst; /* Save for dialog boxes */
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
s_hModule = hInst; /* Save for dialog boxes */
|
||||
|
||||
/* Load the WinSock Library */
|
||||
wVersionRequested = MAKEWORD(1, 1);
|
||||
/* Load the WinSock Library */
|
||||
wVersionRequested = MAKEWORD(1, 1);
|
||||
|
||||
if ( WSAStartup(wVersionRequested, &wsaData))
|
||||
return FALSE;
|
||||
if (WSAStartup(wVersionRequested, &wsaData))
|
||||
return FALSE;
|
||||
|
||||
/* Verify that this is the minimum version of WinSock */
|
||||
if ( LOBYTE( wsaData.wVersion ) != 1 ||
|
||||
HIBYTE( wsaData.wVersion ) != 1 ) {
|
||||
/* Verify that this is the minimum version of WinSock */
|
||||
if (LOBYTE(wsaData.wVersion) != 1 ||
|
||||
HIBYTE(wsaData.wVersion) != 1)
|
||||
{
|
||||
|
||||
WSACleanup();
|
||||
return FALSE;
|
||||
}
|
||||
WSACleanup();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE);
|
||||
break;
|
||||
getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE);
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
|
||||
WSACleanup();
|
||||
WSACleanup();
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
UNREFERENCED_PARAMETER(lpReserved);
|
||||
return TRUE;
|
||||
|
||||
UNREFERENCED_PARAMETER(lpReserved);
|
||||
}
|
||||
|
||||
#else /* not WIN32 */
|
||||
#else /* not WIN32 */
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (BOOL)1
|
||||
@@ -97,7 +100,7 @@ WSADATA wsaData;
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
/* This function is called at library initialization time. */
|
||||
/* This function is called at library initialization time. */
|
||||
|
||||
static BOOL
|
||||
__attribute__((constructor))
|
||||
@@ -107,7 +110,7 @@ init(void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else /* not __GNUC__ */
|
||||
#else /* not __GNUC__ */
|
||||
|
||||
/* These two functions do shared library initialziation on UNIX, well at least
|
||||
* on Linux. I don't know about other systems.
|
||||
@@ -125,9 +128,9 @@ _fini(void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* not __GNUC__ */
|
||||
#endif /* not __GNUC__ */
|
||||
|
||||
#endif /* not WIN32 */
|
||||
#endif /* not WIN32 */
|
||||
|
||||
/* This function is used to cause the Driver Manager to
|
||||
call functions by number rather than name, which is faster.
|
||||
@@ -135,8 +138,8 @@ _fini(void)
|
||||
Driver Manager do this. Also, the ordinal values of the
|
||||
functions must match the value of fFunction in SQLGetFunctions()
|
||||
*/
|
||||
RETCODE SQL_API SQLDummyOrdinal(void)
|
||||
RETCODE SQL_API
|
||||
SQLDummyOrdinal(void)
|
||||
{
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
/* File: psqlodbc.h
|
||||
/* File: psqlodbc.h
|
||||
*
|
||||
* Description: This file contains defines and declarations that are related to
|
||||
* the entire driver.
|
||||
* Description: This file contains defines and declarations that are related to
|
||||
* the entire driver.
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
* $Id: psqlodbc.h,v 1.39 2001/03/16 01:17:23 inoue Exp $
|
||||
* $Id: psqlodbc.h,v 1.40 2001/03/22 04:01:35 momjian Exp $
|
||||
*/
|
||||
|
||||
#ifndef __PSQLODBC_H__
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* for FILE* pointers: see GLOBAL_VALUES */
|
||||
#include <stdio.h> /* for FILE* pointers: see GLOBAL_VALUES */
|
||||
|
||||
#ifndef WIN32
|
||||
#define Int4 long int
|
||||
@@ -25,6 +25,7 @@
|
||||
#define UInt2 unsigned short
|
||||
typedef float SFLOAT;
|
||||
typedef double SDOUBLE;
|
||||
|
||||
#else
|
||||
#define Int4 int
|
||||
#define UInt4 unsigned int
|
||||
@@ -38,8 +39,8 @@ typedef UInt4 Oid;
|
||||
#define ODBCVER 0x0250
|
||||
#define DRIVER_ODBC_VER "02.50"
|
||||
|
||||
#define DRIVERNAME "PostgreSQL ODBC"
|
||||
#define DBMS_NAME "PostgreSQL"
|
||||
#define DRIVERNAME "PostgreSQL ODBC"
|
||||
#define DBMS_NAME "PostgreSQL"
|
||||
|
||||
#define POSTGRESDRIVERVERSION "07.01.0004"
|
||||
|
||||
@@ -51,17 +52,21 @@ typedef UInt4 Oid;
|
||||
|
||||
/* Limits */
|
||||
#ifdef WIN32
|
||||
#define BLCKSZ 4096
|
||||
#define BLCKSZ 4096
|
||||
#endif
|
||||
|
||||
#define MAX_MESSAGE_LEN 65536 /* This puts a limit on query size but I don't */
|
||||
/* see an easy way round this - DJP 24-1-2001 */
|
||||
#define MAX_MESSAGE_LEN 65536 /* This puts a limit on
|
||||
* query size but I don't */
|
||||
/* see an easy way round this - DJP 24-1-2001 */
|
||||
#define MAX_CONNECT_STRING 4096
|
||||
#define ERROR_MSG_LENGTH 4096
|
||||
#define FETCH_MAX 100 /* default number of rows to cache for declare/fetch */
|
||||
#define FETCH_MAX 100 /* default number of rows to cache
|
||||
* for declare/fetch */
|
||||
#define TUPLE_MALLOC_INC 100
|
||||
#define SOCK_BUFFER_SIZE 4096 /* default socket buffer size */
|
||||
#define MAX_CONNECTIONS 128 /* conns per environment (arbitrary) */
|
||||
#define SOCK_BUFFER_SIZE 4096 /* default socket buffer
|
||||
* size */
|
||||
#define MAX_CONNECTIONS 128 /* conns per environment
|
||||
* (arbitrary) */
|
||||
#define MAX_FIELDS 512
|
||||
#define BYTELEN 8
|
||||
#define VARHDRSZ sizeof(Int4)
|
||||
@@ -71,28 +76,33 @@ typedef UInt4 Oid;
|
||||
#define MAX_CURSOR_LEN 32
|
||||
|
||||
/* Registry length limits */
|
||||
#define LARGE_REGISTRY_LEN 4096 /* used for special cases */
|
||||
#define MEDIUM_REGISTRY_LEN 256 /* normal size for user,database,etc. */
|
||||
#define SMALL_REGISTRY_LEN 10 /* for 1/0 settings */
|
||||
#define LARGE_REGISTRY_LEN 4096 /* used for special cases */
|
||||
#define MEDIUM_REGISTRY_LEN 256 /* normal size for
|
||||
* user,database,etc. */
|
||||
#define SMALL_REGISTRY_LEN 10 /* for 1/0 settings */
|
||||
|
||||
|
||||
/* These prefixes denote system tables */
|
||||
#define POSTGRES_SYS_PREFIX "pg_"
|
||||
#define POSTGRES_SYS_PREFIX "pg_"
|
||||
#define KEYS_TABLE "dd_fkey"
|
||||
|
||||
/* Info limits */
|
||||
#define MAX_INFO_STRING 128
|
||||
#define MAX_KEYPARTS 20
|
||||
#define MAX_KEYLEN 512 /* max key of the form "date+outlet+invoice" */
|
||||
#define MAX_ROW_SIZE 0 /* Unlimited rowsize with the Tuple Toaster */
|
||||
#define MAX_STATEMENT_LEN 0 /* Unlimited statement size with 7.0 */
|
||||
#define MAX_KEYLEN 512 /* max key of the form
|
||||
* "date+outlet+invoice" */
|
||||
#define MAX_ROW_SIZE 0 /* Unlimited rowsize with the Tuple
|
||||
* Toaster */
|
||||
#define MAX_STATEMENT_LEN 0 /* Unlimited statement size with 7.0 */
|
||||
|
||||
/* Previously, numerous query strings were defined of length MAX_STATEMENT_LEN */
|
||||
/* Now that's 0, lets use this instead. DJP 24-1-2001 */
|
||||
#define STD_STATEMENT_LEN MAX_MESSAGE_LEN
|
||||
|
||||
#define PG62 "6.2" /* "Protocol" key setting to force Postgres 6.2 */
|
||||
#define PG63 "6.3" /* "Protocol" key setting to force postgres 6.3 */
|
||||
#define PG62 "6.2" /* "Protocol" key setting to force
|
||||
* Postgres 6.2 */
|
||||
#define PG63 "6.3" /* "Protocol" key setting to force
|
||||
* postgres 6.3 */
|
||||
#define PG64 "6.4"
|
||||
|
||||
typedef struct ConnectionClass_ ConnectionClass;
|
||||
@@ -112,61 +122,69 @@ typedef struct lo_arg LO_ARG;
|
||||
|
||||
typedef struct GlobalValues_
|
||||
{
|
||||
int fetch_max;
|
||||
int socket_buffersize;
|
||||
int unknown_sizes;
|
||||
int max_varchar_size;
|
||||
int max_longvarchar_size;
|
||||
char debug;
|
||||
char commlog;
|
||||
char disable_optimizer;
|
||||
char ksqo;
|
||||
char unique_index;
|
||||
char onlyread; /* readonly is reserved on Digital C++ compiler */
|
||||
char use_declarefetch;
|
||||
char text_as_longvarchar;
|
||||
char unknowns_as_longvarchar;
|
||||
char bools_as_char;
|
||||
char lie;
|
||||
char parse;
|
||||
char cancel_as_freestmt;
|
||||
char extra_systable_prefixes[MEDIUM_REGISTRY_LEN];
|
||||
char conn_settings[LARGE_REGISTRY_LEN];
|
||||
char protocol[SMALL_REGISTRY_LEN];
|
||||
int fetch_max;
|
||||
int socket_buffersize;
|
||||
int unknown_sizes;
|
||||
int max_varchar_size;
|
||||
int max_longvarchar_size;
|
||||
char debug;
|
||||
char commlog;
|
||||
char disable_optimizer;
|
||||
char ksqo;
|
||||
char unique_index;
|
||||
char onlyread; /* readonly is reserved on Digital C++
|
||||
* compiler */
|
||||
char use_declarefetch;
|
||||
char text_as_longvarchar;
|
||||
char unknowns_as_longvarchar;
|
||||
char bools_as_char;
|
||||
char lie;
|
||||
char parse;
|
||||
char cancel_as_freestmt;
|
||||
char extra_systable_prefixes[MEDIUM_REGISTRY_LEN];
|
||||
char conn_settings[LARGE_REGISTRY_LEN];
|
||||
char protocol[SMALL_REGISTRY_LEN];
|
||||
|
||||
|
||||
FILE* mylogFP;
|
||||
FILE* qlogFP;
|
||||
FILE *mylogFP;
|
||||
FILE *qlogFP;
|
||||
} GLOBAL_VALUES;
|
||||
|
||||
typedef struct StatementOptions_ {
|
||||
int maxRows;
|
||||
int maxLength;
|
||||
int rowset_size;
|
||||
int keyset_size;
|
||||
int cursor_type;
|
||||
int scroll_concurrency;
|
||||
int retrieve_data;
|
||||
int bind_size; /* size of each structure if using Row Binding */
|
||||
int use_bookmarks;
|
||||
typedef struct StatementOptions_
|
||||
{
|
||||
int maxRows;
|
||||
int maxLength;
|
||||
int rowset_size;
|
||||
int keyset_size;
|
||||
int cursor_type;
|
||||
int scroll_concurrency;
|
||||
int retrieve_data;
|
||||
int bind_size; /* size of each structure if using Row
|
||||
* Binding */
|
||||
int use_bookmarks;
|
||||
} StatementOptions;
|
||||
|
||||
/* Used to pass extra query info to send_query */
|
||||
typedef struct QueryInfo_ {
|
||||
int row_size;
|
||||
QResultClass *result_in;
|
||||
char *cursor;
|
||||
typedef struct QueryInfo_
|
||||
{
|
||||
int row_size;
|
||||
QResultClass *result_in;
|
||||
char *cursor;
|
||||
} QueryInfo;
|
||||
|
||||
|
||||
#define PG_TYPE_LO -999 /* hack until permanent type available */
|
||||
#define PG_TYPE_LO -999 /* hack until permanent type
|
||||
* available */
|
||||
#define PG_TYPE_LO_NAME "lo"
|
||||
#define OID_ATTNUM -2 /* the attnum in pg_index of the oid */
|
||||
#define OID_ATTNUM -2 /* the attnum in pg_index of the
|
||||
* oid */
|
||||
|
||||
/* sizes */
|
||||
#define TEXT_FIELD_SIZE 8190 /* size of text fields (not including null term) */
|
||||
#define TEXT_FIELD_SIZE 8190 /* size of text fields (not
|
||||
* including null term) */
|
||||
#define NAME_FIELD_SIZE 32 /* size of name fields */
|
||||
#define MAX_VARCHAR_SIZE 254 /* maximum size of a varchar (not including null term) */
|
||||
#define MAX_VARCHAR_SIZE 254 /* maximum size of a varchar (not
|
||||
* including null term) */
|
||||
|
||||
#define PG_NUMERIC_MAX_PRECISION 1000
|
||||
#define PG_NUMERIC_MAX_SCALE 1000
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
|
||||
/* Module: qresult.c
|
||||
/* Module: qresult.c
|
||||
*
|
||||
* Description: This module contains functions related to
|
||||
* managing result information (i.e, fetching rows from the backend,
|
||||
* managing the tuple cache, etc.) and retrieving it.
|
||||
* Depending on the situation, a QResultClass will hold either data
|
||||
* from the backend or a manually built result (see "qresult.h" to
|
||||
* see which functions/macros are for manual or backend results.
|
||||
* For manually built results, the QResultClass simply points to
|
||||
* TupleList and ColumnInfo structures, which actually hold the data.
|
||||
* Description: This module contains functions related to
|
||||
* managing result information (i.e, fetching rows from the backend,
|
||||
* managing the tuple cache, etc.) and retrieving it.
|
||||
* Depending on the situation, a QResultClass will hold either data
|
||||
* from the backend or a manually built result (see "qresult.h" to
|
||||
* see which functions/macros are for manual or backend results.
|
||||
* For manually built results, the QResultClass simply points to
|
||||
* TupleList and ColumnInfo structures, which actually hold the data.
|
||||
*
|
||||
* Classes: QResultClass (Functions prefix: "QR_")
|
||||
* Classes: QResultClass (Functions prefix: "QR_")
|
||||
*
|
||||
* API functions: none
|
||||
* API functions: none
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -32,23 +32,23 @@
|
||||
|
||||
extern GLOBAL_VALUES globals;
|
||||
|
||||
/* Used for building a Manual Result only */
|
||||
/* Used for building a Manual Result only */
|
||||
/* All info functions call this function to create the manual result set. */
|
||||
void
|
||||
void
|
||||
QR_set_num_fields(QResultClass *self, int new_num_fields)
|
||||
{
|
||||
mylog("in QR_set_num_fields\n");
|
||||
|
||||
CI_set_num_fields(self->fields, new_num_fields);
|
||||
if(self->manual_tuples)
|
||||
TL_Destructor(self->manual_tuples);
|
||||
CI_set_num_fields(self->fields, new_num_fields);
|
||||
if (self->manual_tuples)
|
||||
TL_Destructor(self->manual_tuples);
|
||||
|
||||
self->manual_tuples = TL_Constructor(new_num_fields);
|
||||
self->manual_tuples = TL_Constructor(new_num_fields);
|
||||
|
||||
mylog("exit QR_set_num_fields\n");
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
QR_set_position(QResultClass *self, int pos)
|
||||
{
|
||||
self->tupleField = self->backend_tuples + ((self->base + pos) * self->num_fields);
|
||||
@@ -60,7 +60,7 @@ QR_set_cache_size(QResultClass *self, int cache_size)
|
||||
self->cache_size = cache_size;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
QR_set_rowset_size(QResultClass *self, int rowset_size)
|
||||
{
|
||||
self->rowset_size = rowset_size;
|
||||
@@ -73,27 +73,29 @@ QR_inc_base(QResultClass *self, int base_inc)
|
||||
}
|
||||
|
||||
/************************************/
|
||||
/* CLASS QResult */
|
||||
/* CLASS QResult */
|
||||
/************************************/
|
||||
|
||||
QResultClass *
|
||||
QR_Constructor(void)
|
||||
{
|
||||
QResultClass *rv;
|
||||
QResultClass *rv;
|
||||
|
||||
mylog("in QR_Constructor\n");
|
||||
rv = (QResultClass *) malloc(sizeof(QResultClass));
|
||||
|
||||
if (rv != NULL) {
|
||||
if (rv != NULL)
|
||||
{
|
||||
rv->status = PGRES_EMPTY_QUERY;
|
||||
|
||||
/* construct the column info */
|
||||
if ( ! (rv->fields = CI_Constructor())) {
|
||||
if (!(rv->fields = CI_Constructor()))
|
||||
{
|
||||
free(rv);
|
||||
return NULL;
|
||||
}
|
||||
rv->manual_tuples = NULL;
|
||||
rv->backend_tuples = NULL;
|
||||
rv->manual_tuples = NULL;
|
||||
rv->backend_tuples = NULL;
|
||||
rv->message = NULL;
|
||||
rv->command = NULL;
|
||||
rv->notice = NULL;
|
||||
@@ -126,26 +128,26 @@ QR_Destructor(QResultClass *self)
|
||||
if (self->manual_tuples)
|
||||
TL_Destructor(self->manual_tuples);
|
||||
|
||||
/* If conn is defined, then we may have used "backend_tuples", */
|
||||
/* so in case we need to, free it up. Also, close the cursor. */
|
||||
/* If conn is defined, then we may have used "backend_tuples", */
|
||||
/* so in case we need to, free it up. Also, close the cursor. */
|
||||
if (self->conn && self->conn->sock && CC_is_in_trans(self->conn))
|
||||
QR_close(self); /* close the cursor if there is one */
|
||||
|
||||
QR_free_memory(self); /* safe to call anyway */
|
||||
QR_free_memory(self); /* safe to call anyway */
|
||||
|
||||
/* Should have been freed in the close() but just in case... */
|
||||
/* Should have been freed in the close() but just in case... */
|
||||
if (self->cursor)
|
||||
free(self->cursor);
|
||||
|
||||
/* Free up column info */
|
||||
/* Free up column info */
|
||||
if (self->fields)
|
||||
CI_Destructor(self->fields);
|
||||
|
||||
/* Free command info (this is from strdup()) */
|
||||
/* Free command info (this is from strdup()) */
|
||||
if (self->command)
|
||||
free(self->command);
|
||||
|
||||
/* Free notice info (this is from strdup()) */
|
||||
/* Free notice info (this is from strdup()) */
|
||||
if (self->notice)
|
||||
free(self->notice);
|
||||
|
||||
@@ -164,7 +166,7 @@ QR_set_command(QResultClass *self, char *msg)
|
||||
self->command = msg ? strdup(msg) : NULL;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
QR_set_notice(QResultClass *self, char *msg)
|
||||
{
|
||||
if (self->notice)
|
||||
@@ -173,27 +175,32 @@ QR_set_notice(QResultClass *self, char *msg)
|
||||
self->notice = msg ? strdup(msg) : NULL;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
QR_free_memory(QResultClass *self)
|
||||
{
|
||||
register int lf, row;
|
||||
register TupleField *tuple = self->backend_tuples;
|
||||
int fcount = self->fcount;
|
||||
int num_fields = self->num_fields;
|
||||
register int lf,
|
||||
row;
|
||||
register TupleField *tuple = self->backend_tuples;
|
||||
int fcount = self->fcount;
|
||||
int num_fields = self->num_fields;
|
||||
|
||||
mylog("QResult: free memory in, fcount=%d\n", fcount);
|
||||
|
||||
if ( self->backend_tuples) {
|
||||
if (self->backend_tuples)
|
||||
{
|
||||
|
||||
for (row = 0; row < fcount; row++) {
|
||||
for (row = 0; row < fcount; row++)
|
||||
{
|
||||
mylog("row = %d, num_fields = %d\n", row, num_fields);
|
||||
for (lf=0; lf < num_fields; lf++) {
|
||||
if (tuple[lf].value != NULL) {
|
||||
for (lf = 0; lf < num_fields; lf++)
|
||||
{
|
||||
if (tuple[lf].value != NULL)
|
||||
{
|
||||
mylog("free [lf=%d] %u\n", lf, tuple[lf].value);
|
||||
free(tuple[lf].value);
|
||||
}
|
||||
}
|
||||
tuple += num_fields; /* next row */
|
||||
tuple += num_fields;/* next row */
|
||||
}
|
||||
|
||||
free(self->backend_tuples);
|
||||
@@ -209,37 +216,42 @@ int num_fields = self->num_fields;
|
||||
char
|
||||
QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
|
||||
{
|
||||
int tuple_size;
|
||||
int tuple_size;
|
||||
|
||||
/* If called from send_query the first time (conn != NULL), */
|
||||
/* then set the inTuples state, */
|
||||
/* and read the tuples. If conn is NULL, */
|
||||
/* it implies that we are being called from next_tuple(), */
|
||||
/* like to get more rows so don't call next_tuple again! */
|
||||
if (conn != NULL) {
|
||||
/* If called from send_query the first time (conn != NULL), */
|
||||
/* then set the inTuples state, */
|
||||
/* and read the tuples. If conn is NULL, */
|
||||
/* it implies that we are being called from next_tuple(), */
|
||||
/* like to get more rows so don't call next_tuple again! */
|
||||
if (conn != NULL)
|
||||
{
|
||||
self->conn = conn;
|
||||
|
||||
mylog("QR_fetch_tuples: cursor = '%s', self->cursor=%u\n", (cursor==NULL)?"":cursor, self->cursor);
|
||||
mylog("QR_fetch_tuples: cursor = '%s', self->cursor=%u\n", (cursor == NULL) ? "" : cursor, self->cursor);
|
||||
|
||||
if (self->cursor)
|
||||
free(self->cursor);
|
||||
|
||||
if ( globals.use_declarefetch) {
|
||||
if (! cursor || cursor[0] == '\0') {
|
||||
if (globals.use_declarefetch)
|
||||
{
|
||||
if (!cursor || cursor[0] == '\0')
|
||||
{
|
||||
self->status = PGRES_INTERNAL_ERROR;
|
||||
QR_set_message(self, "Internal Error -- no cursor for fetch");
|
||||
return FALSE;
|
||||
}
|
||||
self->cursor = strdup(cursor);
|
||||
}
|
||||
|
||||
/* Read the field attributes. */
|
||||
/* $$$$ Should do some error control HERE! $$$$ */
|
||||
if ( CI_read_fields(self->fields, self->conn)) {
|
||||
|
||||
/* Read the field attributes. */
|
||||
/* $$$$ Should do some error control HERE! $$$$ */
|
||||
if (CI_read_fields(self->fields, self->conn))
|
||||
{
|
||||
self->status = PGRES_FIELDS_OK;
|
||||
self->num_fields = CI_get_num_fields(self->fields);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
self->status = PGRES_BAD_RESPONSE;
|
||||
QR_set_message(self, "Error reading field information");
|
||||
return FALSE;
|
||||
@@ -247,7 +259,7 @@ int tuple_size;
|
||||
|
||||
mylog("QR_fetch_tuples: past CI_read_fields: num_fields = %d\n", self->num_fields);
|
||||
|
||||
if (globals.use_declarefetch)
|
||||
if (globals.use_declarefetch)
|
||||
tuple_size = self->cache_size;
|
||||
else
|
||||
tuple_size = TUPLE_MALLOC_INC;
|
||||
@@ -255,8 +267,9 @@ int tuple_size;
|
||||
/* allocate memory for the tuple cache */
|
||||
mylog("MALLOC: tuple_size = %d, size = %d\n", tuple_size, self->num_fields * sizeof(TupleField) * tuple_size);
|
||||
self->backend_tuples = (TupleField *) malloc(self->num_fields * sizeof(TupleField) * tuple_size);
|
||||
if ( ! self->backend_tuples) {
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
if (!self->backend_tuples)
|
||||
{
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
QR_set_message(self, "Could not get memory for tuple cache.");
|
||||
return FALSE;
|
||||
}
|
||||
@@ -264,19 +277,21 @@ int tuple_size;
|
||||
self->inTuples = TRUE;
|
||||
|
||||
|
||||
/* Force a read to occur in next_tuple */
|
||||
self->fcount = tuple_size+1;
|
||||
self->fetch_count = tuple_size+1;
|
||||
/* Force a read to occur in next_tuple */
|
||||
self->fcount = tuple_size + 1;
|
||||
self->fetch_count = tuple_size + 1;
|
||||
self->base = 0;
|
||||
|
||||
return QR_next_tuple(self);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
|
||||
/* Always have to read the field attributes. */
|
||||
/* But we dont have to reallocate memory for them! */
|
||||
/* Always have to read the field attributes. */
|
||||
/* But we dont have to reallocate memory for them! */
|
||||
|
||||
if ( ! CI_read_fields(NULL, self->conn)) {
|
||||
if (!CI_read_fields(NULL, self->conn))
|
||||
{
|
||||
self->status = PGRES_BAD_RESPONSE;
|
||||
QR_set_message(self, "Error reading field information");
|
||||
return FALSE;
|
||||
@@ -290,10 +305,11 @@ int tuple_size;
|
||||
int
|
||||
QR_close(QResultClass *self)
|
||||
{
|
||||
QResultClass *res;
|
||||
QResultClass *res;
|
||||
|
||||
if (globals.use_declarefetch && self->conn && self->cursor) {
|
||||
char buf[64];
|
||||
if (globals.use_declarefetch && self->conn && self->cursor)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
sprintf(buf, "close %s", self->cursor);
|
||||
mylog("QResult: closing cursor: '%s'\n", buf);
|
||||
@@ -306,22 +322,25 @@ QResultClass *res;
|
||||
free(self->cursor);
|
||||
self->cursor = NULL;
|
||||
|
||||
if (res == NULL) {
|
||||
if (res == NULL)
|
||||
{
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
QR_set_message(self, "Error closing cursor.");
|
||||
return FALSE;
|
||||
}
|
||||
QR_Destructor(res);
|
||||
|
||||
/* End the transaction if there are no cursors left on this conn */
|
||||
if (CC_cursor_count(self->conn) == 0) {
|
||||
/* End the transaction if there are no cursors left on this conn */
|
||||
if (CC_cursor_count(self->conn) == 0)
|
||||
{
|
||||
mylog("QResult: END transaction on conn=%u\n", self->conn);
|
||||
|
||||
res = CC_send_query(self->conn, "END", NULL);
|
||||
|
||||
CC_set_no_trans(self->conn);
|
||||
|
||||
if (res == NULL) {
|
||||
if (res == NULL)
|
||||
{
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
QR_set_message(self, "Error ending transaction.");
|
||||
return FALSE;
|
||||
@@ -338,54 +357,65 @@ QResultClass *res;
|
||||
int
|
||||
QR_next_tuple(QResultClass *self)
|
||||
{
|
||||
int id;
|
||||
QResultClass *res;
|
||||
SocketClass *sock;
|
||||
/* Speed up access */
|
||||
int fetch_count = self->fetch_count;
|
||||
int fcount = self->fcount;
|
||||
int fetch_size, offset= 0;
|
||||
int end_tuple = self->rowset_size + self->base;
|
||||
char corrected = FALSE;
|
||||
TupleField *the_tuples = self->backend_tuples;
|
||||
static char msgbuffer[MAX_MESSAGE_LEN+1];
|
||||
char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont need static */
|
||||
char fetch[128];
|
||||
QueryInfo qi;
|
||||
int id;
|
||||
QResultClass *res;
|
||||
SocketClass *sock;
|
||||
|
||||
if (fetch_count < fcount) { /* return a row from cache */
|
||||
/* Speed up access */
|
||||
int fetch_count = self->fetch_count;
|
||||
int fcount = self->fcount;
|
||||
int fetch_size,
|
||||
offset = 0;
|
||||
int end_tuple = self->rowset_size + self->base;
|
||||
char corrected = FALSE;
|
||||
TupleField *the_tuples = self->backend_tuples;
|
||||
static char msgbuffer[MAX_MESSAGE_LEN + 1];
|
||||
char cmdbuffer[MAX_MESSAGE_LEN + 1]; /* QR_set_command() dups
|
||||
* this string so dont
|
||||
* need static */
|
||||
char fetch[128];
|
||||
QueryInfo qi;
|
||||
|
||||
if (fetch_count < fcount)
|
||||
{ /* return a row from cache */
|
||||
mylog("next_tuple: fetch_count < fcount: returning tuple %d, fcount = %d\n", fetch_count, fcount);
|
||||
self->tupleField = the_tuples + (fetch_count * self->num_fields); /* next row */
|
||||
self->tupleField = the_tuples + (fetch_count * self->num_fields); /* next row */
|
||||
self->fetch_count++;
|
||||
return TRUE;
|
||||
}
|
||||
else if (self->fcount < self->cache_size) { /* last row from cache */
|
||||
/* We are done because we didn't even get CACHE_SIZE tuples */
|
||||
mylog("next_tuple: fcount < CACHE_SIZE: fcount = %d, fetch_count = %d\n", fcount, fetch_count);
|
||||
self->tupleField = NULL;
|
||||
self->status = PGRES_END_TUPLES;
|
||||
return -1; /* end of tuples */
|
||||
else if (self->fcount < self->cache_size)
|
||||
{ /* last row from cache */
|
||||
/* We are done because we didn't even get CACHE_SIZE tuples */
|
||||
mylog("next_tuple: fcount < CACHE_SIZE: fcount = %d, fetch_count = %d\n", fcount, fetch_count);
|
||||
self->tupleField = NULL;
|
||||
self->status = PGRES_END_TUPLES;
|
||||
return -1; /* end of tuples */
|
||||
}
|
||||
else {
|
||||
/* See if we need to fetch another group of rows.
|
||||
We may be being called from send_query(), and
|
||||
if so, don't send another fetch, just fall through
|
||||
and read the tuples.
|
||||
*/
|
||||
else
|
||||
{
|
||||
|
||||
/*
|
||||
* See if we need to fetch another group of rows. We may be being
|
||||
* called from send_query(), and if so, don't send another fetch,
|
||||
* just fall through and read the tuples.
|
||||
*/
|
||||
self->tupleField = NULL;
|
||||
|
||||
if ( ! self->inTuples) {
|
||||
if (!self->inTuples)
|
||||
{
|
||||
|
||||
if ( ! globals.use_declarefetch) {
|
||||
if (!globals.use_declarefetch)
|
||||
{
|
||||
mylog("next_tuple: ALL_ROWS: done, fcount = %d, fetch_count = %d\n", fcount, fetch_count);
|
||||
self->tupleField = NULL;
|
||||
self->status = PGRES_END_TUPLES;
|
||||
return -1; /* end of tuples */
|
||||
return -1; /* end of tuples */
|
||||
}
|
||||
|
||||
if (self->base == fcount) { /* not a correction */
|
||||
if (self->base == fcount)
|
||||
{ /* not a correction */
|
||||
|
||||
/* Determine the optimum cache size. */
|
||||
/* Determine the optimum cache size. */
|
||||
if (globals.fetch_max % self->rowset_size == 0)
|
||||
fetch_size = globals.fetch_max;
|
||||
else if (self->rowset_size < globals.fetch_max)
|
||||
@@ -394,9 +424,10 @@ QueryInfo qi;
|
||||
fetch_size = self->rowset_size;
|
||||
|
||||
self->cache_size = fetch_size;
|
||||
self->fetch_count = 1;
|
||||
}
|
||||
else { /* need to correct */
|
||||
self->fetch_count = 1;
|
||||
}
|
||||
else
|
||||
{ /* need to correct */
|
||||
|
||||
corrected = TRUE;
|
||||
|
||||
@@ -411,8 +442,9 @@ QueryInfo qi;
|
||||
|
||||
|
||||
self->backend_tuples = (TupleField *) realloc(self->backend_tuples, self->num_fields * sizeof(TupleField) * self->cache_size);
|
||||
if ( ! self->backend_tuples) {
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
if (!self->backend_tuples)
|
||||
{
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
QR_set_message(self, "Out of memory while reading tuples.");
|
||||
return FALSE;
|
||||
}
|
||||
@@ -420,29 +452,34 @@ QueryInfo qi;
|
||||
|
||||
mylog("next_tuple: sending actual fetch (%d) query '%s'\n", fetch_size, fetch);
|
||||
|
||||
/* don't read ahead for the next tuple (self) ! */
|
||||
/* don't read ahead for the next tuple (self) ! */
|
||||
qi.row_size = self->cache_size;
|
||||
qi.result_in = self;
|
||||
qi.cursor = NULL;
|
||||
res = CC_send_query(self->conn, fetch, &qi);
|
||||
if (res == NULL) {
|
||||
if (res == NULL)
|
||||
{
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
QR_set_message(self, "Error fetching next group.");
|
||||
return FALSE;
|
||||
}
|
||||
self->inTuples = TRUE;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
mylog("next_tuple: inTuples = true, falling through: fcount = %d, fetch_count = %d\n", self->fcount, self->fetch_count);
|
||||
/* This is a pre-fetch (fetching rows right after query
|
||||
but before any real SQLFetch() calls. This is done
|
||||
so the field attributes are available.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a pre-fetch (fetching rows right after query but
|
||||
* before any real SQLFetch() calls. This is done so the
|
||||
* field attributes are available.
|
||||
*/
|
||||
self->fetch_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! corrected) {
|
||||
if (!corrected)
|
||||
{
|
||||
self->base = 0;
|
||||
self->fcount = 0;
|
||||
}
|
||||
@@ -451,88 +488,98 @@ QueryInfo qi;
|
||||
sock = CC_get_socket(self->conn);
|
||||
self->tupleField = NULL;
|
||||
|
||||
for ( ; ;) {
|
||||
for (;;)
|
||||
{
|
||||
|
||||
id = SOCK_get_char(sock);
|
||||
|
||||
switch (id) {
|
||||
case 'T': /* Tuples within tuples cannot be handled */
|
||||
self->status = PGRES_BAD_RESPONSE;
|
||||
QR_set_message(self, "Tuples within tuples cannot be handled");
|
||||
return FALSE;
|
||||
case 'B': /* Tuples in binary format */
|
||||
case 'D': /* Tuples in ASCII format */
|
||||
switch (id)
|
||||
{
|
||||
case 'T': /* Tuples within tuples cannot be handled */
|
||||
self->status = PGRES_BAD_RESPONSE;
|
||||
QR_set_message(self, "Tuples within tuples cannot be handled");
|
||||
return FALSE;
|
||||
case 'B': /* Tuples in binary format */
|
||||
case 'D': /* Tuples in ASCII format */
|
||||
|
||||
if ( ! globals.use_declarefetch && self->fcount > 0 && ! (self->fcount % TUPLE_MALLOC_INC)) {
|
||||
size_t old_size = self->fcount * self->num_fields * sizeof(TupleField);
|
||||
mylog("REALLOC: old_size = %d\n", old_size);
|
||||
if (!globals.use_declarefetch && self->fcount > 0 && !(self->fcount % TUPLE_MALLOC_INC))
|
||||
{
|
||||
size_t old_size = self->fcount * self->num_fields * sizeof(TupleField);
|
||||
|
||||
self->backend_tuples = (TupleField *) realloc(self->backend_tuples, old_size + (self->num_fields * sizeof(TupleField) * TUPLE_MALLOC_INC));
|
||||
if ( ! self->backend_tuples) {
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
QR_set_message(self, "Out of memory while reading tuples.");
|
||||
mylog("REALLOC: old_size = %d\n", old_size);
|
||||
|
||||
self->backend_tuples = (TupleField *) realloc(self->backend_tuples, old_size + (self->num_fields * sizeof(TupleField) * TUPLE_MALLOC_INC));
|
||||
if (!self->backend_tuples)
|
||||
{
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
QR_set_message(self, "Out of memory while reading tuples.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!QR_read_tuple(self, (char) (id == 0)))
|
||||
{
|
||||
self->status = PGRES_BAD_RESPONSE;
|
||||
QR_set_message(self, "Error reading the tuple");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! QR_read_tuple(self, (char) (id == 0))) {
|
||||
self->status = PGRES_BAD_RESPONSE;
|
||||
QR_set_message(self, "Error reading the tuple");
|
||||
self->fcount++;
|
||||
break; /* continue reading */
|
||||
|
||||
|
||||
case 'C': /* End of tuple list */
|
||||
SOCK_get_string(sock, cmdbuffer, MAX_MESSAGE_LEN);
|
||||
QR_set_command(self, cmdbuffer);
|
||||
|
||||
mylog("end of tuple list -- setting inUse to false: this = %u\n", self);
|
||||
|
||||
self->inTuples = FALSE;
|
||||
if (self->fcount > 0)
|
||||
{
|
||||
|
||||
qlog(" [ fetched %d rows ]\n", self->fcount);
|
||||
mylog("_next_tuple: 'C' fetch_max && fcount = %d\n", self->fcount);
|
||||
|
||||
/* set to first row */
|
||||
self->tupleField = self->backend_tuples + (offset * self->num_fields);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{ /* We are surely done here (we read 0
|
||||
* tuples) */
|
||||
qlog(" [ fetched 0 rows ]\n");
|
||||
mylog("_next_tuple: 'C': DONE (fcount == 0)\n");
|
||||
return -1; /* end of tuples */
|
||||
}
|
||||
|
||||
case 'E': /* Error */
|
||||
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
|
||||
QR_set_message(self, msgbuffer);
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
|
||||
if (!strncmp(msgbuffer, "FATAL", 5))
|
||||
CC_set_no_trans(self->conn);
|
||||
|
||||
qlog("ERROR from backend in next_tuple: '%s'\n", msgbuffer);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
self->fcount++;
|
||||
break; /* continue reading */
|
||||
|
||||
case 'N': /* Notice */
|
||||
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
|
||||
QR_set_message(self, msgbuffer);
|
||||
self->status = PGRES_NONFATAL_ERROR;
|
||||
qlog("NOTICE from backend in next_tuple: '%s'\n", msgbuffer);
|
||||
continue;
|
||||
|
||||
case 'C': /* End of tuple list */
|
||||
SOCK_get_string(sock, cmdbuffer, MAX_MESSAGE_LEN);
|
||||
QR_set_command(self, cmdbuffer);
|
||||
|
||||
mylog("end of tuple list -- setting inUse to false: this = %u\n", self);
|
||||
|
||||
self->inTuples = FALSE;
|
||||
if (self->fcount > 0) {
|
||||
|
||||
qlog(" [ fetched %d rows ]\n", self->fcount);
|
||||
mylog("_next_tuple: 'C' fetch_max && fcount = %d\n", self->fcount);
|
||||
|
||||
/* set to first row */
|
||||
self->tupleField = self->backend_tuples + (offset * self->num_fields);
|
||||
return TRUE;
|
||||
}
|
||||
else { /* We are surely done here (we read 0 tuples) */
|
||||
qlog(" [ fetched 0 rows ]\n");
|
||||
mylog("_next_tuple: 'C': DONE (fcount == 0)\n");
|
||||
return -1; /* end of tuples */
|
||||
}
|
||||
|
||||
case 'E': /* Error */
|
||||
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
|
||||
QR_set_message(self, msgbuffer);
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
|
||||
if ( ! strncmp(msgbuffer, "FATAL", 5))
|
||||
default: /* this should only happen if the backend
|
||||
* dumped core */
|
||||
mylog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id);
|
||||
qlog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id);
|
||||
QR_set_message(self, "Unexpected result from backend. It probably crashed");
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
CC_set_no_trans(self->conn);
|
||||
|
||||
qlog("ERROR from backend in next_tuple: '%s'\n", msgbuffer);
|
||||
|
||||
return FALSE;
|
||||
|
||||
case 'N': /* Notice */
|
||||
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
|
||||
QR_set_message(self, msgbuffer);
|
||||
self->status = PGRES_NONFATAL_ERROR;
|
||||
qlog("NOTICE from backend in next_tuple: '%s'\n", msgbuffer);
|
||||
continue;
|
||||
|
||||
default: /* this should only happen if the backend dumped core */
|
||||
mylog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id);
|
||||
qlog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id);
|
||||
QR_set_message(self, "Unexpected result from backend. It probably crashed");
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
CC_set_no_trans(self->conn);
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
@@ -541,17 +588,18 @@ QueryInfo qi;
|
||||
char
|
||||
QR_read_tuple(QResultClass *self, char binary)
|
||||
{
|
||||
Int2 field_lf;
|
||||
TupleField *this_tuplefield;
|
||||
char bmp, bitmap[MAX_FIELDS]; /* Max. len of the bitmap */
|
||||
Int2 bitmaplen; /* len of the bitmap in bytes */
|
||||
Int2 bitmap_pos;
|
||||
Int2 bitcnt;
|
||||
Int4 len;
|
||||
char *buffer;
|
||||
int num_fields = self->num_fields; /* speed up access */
|
||||
SocketClass *sock = CC_get_socket(self->conn);
|
||||
ColumnInfoClass *flds;
|
||||
Int2 field_lf;
|
||||
TupleField *this_tuplefield;
|
||||
char bmp,
|
||||
bitmap[MAX_FIELDS]; /* Max. len of the bitmap */
|
||||
Int2 bitmaplen; /* len of the bitmap in bytes */
|
||||
Int2 bitmap_pos;
|
||||
Int2 bitcnt;
|
||||
Int4 len;
|
||||
char *buffer;
|
||||
int num_fields = self->num_fields; /* speed up access */
|
||||
SocketClass *sock = CC_get_socket(self->conn);
|
||||
ColumnInfoClass *flds;
|
||||
|
||||
|
||||
/* set the current row to read the fields into */
|
||||
@@ -562,31 +610,36 @@ ColumnInfoClass *flds;
|
||||
bitmaplen++;
|
||||
|
||||
/*
|
||||
At first the server sends a bitmap that indicates which
|
||||
database fields are null
|
||||
*/
|
||||
* At first the server sends a bitmap that indicates which database
|
||||
* fields are null
|
||||
*/
|
||||
SOCK_get_n_char(sock, bitmap, bitmaplen);
|
||||
|
||||
bitmap_pos = 0;
|
||||
bitcnt = 0;
|
||||
bmp = bitmap[bitmap_pos];
|
||||
|
||||
for(field_lf = 0; field_lf < num_fields; field_lf++) {
|
||||
for (field_lf = 0; field_lf < num_fields; field_lf++)
|
||||
{
|
||||
/* Check if the current field is NULL */
|
||||
if(!(bmp & 0200)) {
|
||||
if (!(bmp & 0200))
|
||||
{
|
||||
/* YES, it is NULL ! */
|
||||
this_tuplefield[field_lf].len = 0;
|
||||
this_tuplefield[field_lf].value = 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/*
|
||||
NO, the field is not null. so get at first the
|
||||
length of the field (four bytes)
|
||||
*/
|
||||
* NO, the field is not null. so get at first the length of
|
||||
* the field (four bytes)
|
||||
*/
|
||||
len = SOCK_get_int(sock, VARHDRSZ);
|
||||
if (!binary)
|
||||
len -= VARHDRSZ;
|
||||
|
||||
buffer = (char *)malloc(len+1);
|
||||
buffer = (char *) malloc(len + 1);
|
||||
SOCK_get_n_char(sock, buffer, len);
|
||||
buffer[len] = '\0';
|
||||
|
||||
@@ -595,27 +648,31 @@ ColumnInfoClass *flds;
|
||||
this_tuplefield[field_lf].len = len;
|
||||
this_tuplefield[field_lf].value = buffer;
|
||||
|
||||
/* This can be used to set the longest length of the column for any
|
||||
row in the tuple cache. It would not be accurate for varchar and
|
||||
text fields to use this since a tuple cache is only 100 rows.
|
||||
Bpchar can be handled since the strlen of all rows is fixed,
|
||||
assuming there are not 100 nulls in a row!
|
||||
*/
|
||||
/*
|
||||
* This can be used to set the longest length of the column
|
||||
* for any row in the tuple cache. It would not be accurate
|
||||
* for varchar and text fields to use this since a tuple cache
|
||||
* is only 100 rows. Bpchar can be handled since the strlen of
|
||||
* all rows is fixed, assuming there are not 100 nulls in a
|
||||
* row!
|
||||
*/
|
||||
|
||||
flds = self->fields;
|
||||
if (flds->display_size[field_lf] < len)
|
||||
flds->display_size[field_lf] = len;
|
||||
}
|
||||
|
||||
/*
|
||||
Now adjust for the next bit to be scanned in the
|
||||
next loop.
|
||||
*/
|
||||
* Now adjust for the next bit to be scanned in the next loop.
|
||||
*/
|
||||
bitcnt++;
|
||||
if (BYTELEN == bitcnt) {
|
||||
if (BYTELEN == bitcnt)
|
||||
{
|
||||
bitmap_pos++;
|
||||
bmp = bitmap[bitmap_pos];
|
||||
bitcnt = 0;
|
||||
} else
|
||||
}
|
||||
else
|
||||
bmp <<= 1;
|
||||
}
|
||||
self->currTuple++;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
/* File: qresult.h
|
||||
/* File: qresult.h
|
||||
*
|
||||
* Description: See "qresult.c"
|
||||
* Description: See "qresult.c"
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -17,69 +17,76 @@
|
||||
#include "psqlodbc.h"
|
||||
#include "tuple.h"
|
||||
|
||||
enum QueryResultCode_ {
|
||||
PGRES_EMPTY_QUERY = 0,
|
||||
PGRES_COMMAND_OK, /* a query command that doesn't return */
|
||||
/* anything was executed properly by the backend */
|
||||
PGRES_TUPLES_OK, /* a query command that returns tuples */
|
||||
/* was executed properly by the backend, PGresult */
|
||||
/* contains the resulttuples */
|
||||
PGRES_COPY_OUT,
|
||||
PGRES_COPY_IN,
|
||||
PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from the backend */
|
||||
PGRES_NONFATAL_ERROR,
|
||||
PGRES_FATAL_ERROR,
|
||||
PGRES_FIELDS_OK, /* field information from a query was successful */
|
||||
PGRES_END_TUPLES,
|
||||
PGRES_INTERNAL_ERROR
|
||||
enum QueryResultCode_
|
||||
{
|
||||
PGRES_EMPTY_QUERY = 0,
|
||||
PGRES_COMMAND_OK, /* a query command that doesn't return */
|
||||
/* anything was executed properly by the backend */
|
||||
PGRES_TUPLES_OK, /* a query command that returns tuples */
|
||||
/* was executed properly by the backend, PGresult */
|
||||
/* contains the resulttuples */
|
||||
PGRES_COPY_OUT,
|
||||
PGRES_COPY_IN,
|
||||
PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from
|
||||
* the backend */
|
||||
PGRES_NONFATAL_ERROR,
|
||||
PGRES_FATAL_ERROR,
|
||||
PGRES_FIELDS_OK, /* field information from a query was
|
||||
* successful */
|
||||
PGRES_END_TUPLES,
|
||||
PGRES_INTERNAL_ERROR
|
||||
};
|
||||
typedef enum QueryResultCode_ QueryResultCode;
|
||||
|
||||
|
||||
struct QResultClass_ {
|
||||
ColumnInfoClass *fields; /* the Column information */
|
||||
TupleListClass *manual_tuples; /* manual result tuple list */
|
||||
ConnectionClass *conn; /* the connection this result is using (backend) */
|
||||
struct QResultClass_
|
||||
{
|
||||
ColumnInfoClass *fields; /* the Column information */
|
||||
TupleListClass *manual_tuples; /* manual result tuple list */
|
||||
ConnectionClass *conn; /* the connection this result is using
|
||||
* (backend) */
|
||||
|
||||
/* Stuff for declare/fetch tuples */
|
||||
int fetch_count; /* logical rows read so far */
|
||||
int fcount; /* actual rows read in the fetch */
|
||||
int currTuple;
|
||||
int base;
|
||||
/* Stuff for declare/fetch tuples */
|
||||
int fetch_count; /* logical rows read so far */
|
||||
int fcount; /* actual rows read in the fetch */
|
||||
int currTuple;
|
||||
int base;
|
||||
|
||||
int num_fields; /* number of fields in the result */
|
||||
int cache_size;
|
||||
int rowset_size;
|
||||
int num_fields; /* number of fields in the result */
|
||||
int cache_size;
|
||||
int rowset_size;
|
||||
|
||||
QueryResultCode status;
|
||||
QueryResultCode status;
|
||||
|
||||
char *message;
|
||||
char *cursor; /* The name of the cursor for select statements */
|
||||
char *command;
|
||||
char *notice;
|
||||
char *message;
|
||||
char *cursor; /* The name of the cursor for select
|
||||
* statements */
|
||||
char *command;
|
||||
char *notice;
|
||||
|
||||
TupleField *backend_tuples; /* data from the backend (the tuple cache) */
|
||||
TupleField *tupleField; /* current backend tuple being retrieved */
|
||||
TupleField *backend_tuples; /* data from the backend (the tuple cache) */
|
||||
TupleField *tupleField; /* current backend tuple being retrieved */
|
||||
|
||||
char inTuples; /* is a fetch of rows from the backend in progress? */
|
||||
char aborted; /* was aborted?*/
|
||||
char inTuples; /* is a fetch of rows from the backend in
|
||||
* progress? */
|
||||
char aborted; /* was aborted? */
|
||||
};
|
||||
|
||||
#define QR_get_fields(self) (self->fields)
|
||||
|
||||
|
||||
/* These functions are for retrieving data from the qresult */
|
||||
#define QR_get_value_manual(self, tupleno, fieldno) (TL_get_fieldval(self->manual_tuples, tupleno, fieldno))
|
||||
#define QR_get_value_backend(self, fieldno) (self->tupleField[fieldno].value)
|
||||
#define QR_get_value_manual(self, tupleno, fieldno) (TL_get_fieldval(self->manual_tuples, tupleno, fieldno))
|
||||
#define QR_get_value_backend(self, fieldno) (self->tupleField[fieldno].value)
|
||||
#define QR_get_value_backend_row(self, tupleno, fieldno) ((self->backend_tuples + (tupleno * self->num_fields))[fieldno].value)
|
||||
|
||||
/* These functions are used by both manual and backend results */
|
||||
#define QR_NumResultCols(self) (CI_get_num_fields(self->fields))
|
||||
#define QR_get_fieldname(self, fieldno_) (CI_get_fieldname(self->fields, fieldno_))
|
||||
#define QR_get_fieldsize(self, fieldno_) (CI_get_fieldsize(self->fields, fieldno_))
|
||||
#define QR_get_display_size(self, fieldno_) (CI_get_display_size(self->fields, fieldno_))
|
||||
#define QR_get_atttypmod(self, fieldno_) (CI_get_atttypmod(self->fields, fieldno_))
|
||||
#define QR_get_field_type(self, fieldno_) (CI_get_oid(self->fields, fieldno_))
|
||||
#define QR_get_fieldsize(self, fieldno_) (CI_get_fieldsize(self->fields, fieldno_))
|
||||
#define QR_get_display_size(self, fieldno_) (CI_get_display_size(self->fields, fieldno_))
|
||||
#define QR_get_atttypmod(self, fieldno_) (CI_get_atttypmod(self->fields, fieldno_))
|
||||
#define QR_get_field_type(self, fieldno_) (CI_get_oid(self->fields, fieldno_))
|
||||
|
||||
/* These functions are used only for manual result sets */
|
||||
#define QR_get_num_tuples(self) (self->manual_tuples ? TL_get_num_tuples(self->manual_tuples) : self->fcount)
|
||||
@@ -104,20 +111,20 @@ struct QResultClass_ {
|
||||
|
||||
/* Core Functions */
|
||||
QResultClass *QR_Constructor(void);
|
||||
void QR_Destructor(QResultClass *self);
|
||||
char QR_read_tuple(QResultClass *self, char binary);
|
||||
int QR_next_tuple(QResultClass *self);
|
||||
int QR_close(QResultClass *self);
|
||||
char QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor);
|
||||
void QR_free_memory(QResultClass *self);
|
||||
void QR_set_command(QResultClass *self, char *msg);
|
||||
void QR_set_notice(QResultClass *self, char *msg);
|
||||
void QR_Destructor(QResultClass *self);
|
||||
char QR_read_tuple(QResultClass *self, char binary);
|
||||
int QR_next_tuple(QResultClass *self);
|
||||
int QR_close(QResultClass *self);
|
||||
char QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor);
|
||||
void QR_free_memory(QResultClass *self);
|
||||
void QR_set_command(QResultClass *self, char *msg);
|
||||
void QR_set_notice(QResultClass *self, char *msg);
|
||||
|
||||
void QR_set_num_fields(QResultClass *self, int new_num_fields); /* manual result only */
|
||||
void QR_set_num_fields(QResultClass *self, int new_num_fields); /* manual result only */
|
||||
|
||||
void QR_inc_base(QResultClass *self, int base_inc);
|
||||
void QR_set_cache_size(QResultClass *self, int cache_size);
|
||||
void QR_set_rowset_size(QResultClass *self, int rowset_size);
|
||||
void QR_set_position(QResultClass *self, int pos);
|
||||
|
||||
void QR_inc_base(QResultClass *self, int base_inc);
|
||||
void QR_set_cache_size(QResultClass *self, int cache_size);
|
||||
void QR_set_rowset_size(QResultClass *self, int rowset_size);
|
||||
void QR_set_position(QResultClass *self, int pos);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,61 +2,61 @@
|
||||
/* Microsoft Developer Studio generated include file. */
|
||||
/* Used by psqlodbc.rc */
|
||||
|
||||
#define IDS_BADDSN 1
|
||||
#define IDS_MSGTITLE 2
|
||||
#define DLG_OPTIONS_DRV 102
|
||||
#define DLG_OPTIONS_DS 103
|
||||
#define IDC_DSNAME 400
|
||||
#define IDC_DSNAMETEXT 401
|
||||
#define IDC_DESC 404
|
||||
#define IDC_SERVER 407
|
||||
#define IDC_DATABASE 408
|
||||
#define DLG_CONFIG 1001
|
||||
#define IDC_PORT 1002
|
||||
#define IDC_USER 1006
|
||||
#define IDC_PASSWORD 1009
|
||||
#define DS_READONLY 1011
|
||||
#define DS_SHOWOIDCOLUMN 1012
|
||||
#define DS_FAKEOIDINDEX 1013
|
||||
#define DRV_COMMLOG 1014
|
||||
#define DS_PG62 1016
|
||||
#define IDC_DATASOURCE 1018
|
||||
#define DRV_OPTIMIZER 1019
|
||||
#define DS_CONNSETTINGS 1020
|
||||
#define IDC_DRIVER 1021
|
||||
#define DRV_CONNSETTINGS 1031
|
||||
#define DRV_UNIQUEINDEX 1032
|
||||
#define DRV_UNKNOWN_MAX 1035
|
||||
#define DRV_UNKNOWN_DONTKNOW 1036
|
||||
#define DRV_READONLY 1037
|
||||
#define IDC_DESCTEXT 1039
|
||||
#define DRV_MSG_LABEL 1040
|
||||
#define DRV_UNKNOWN_LONGEST 1041
|
||||
#define DRV_TEXT_LONGVARCHAR 1043
|
||||
#define DRV_UNKNOWNS_LONGVARCHAR 1044
|
||||
#define DRV_CACHE_SIZE 1045
|
||||
#define DRV_VARCHAR_SIZE 1046
|
||||
#define DRV_LONGVARCHAR_SIZE 1047
|
||||
#define IDDEFAULTS 1048
|
||||
#define DRV_USEDECLAREFETCH 1049
|
||||
#define DRV_BOOLS_CHAR 1050
|
||||
#define DS_SHOWSYSTEMTABLES 1051
|
||||
#define DRV_EXTRASYSTABLEPREFIXES 1051
|
||||
#define DS_ROWVERSIONING 1052
|
||||
#define DRV_PARSE 1052
|
||||
#define DRV_CANCELASFREESTMT 1053
|
||||
#define IDC_OPTIONS 1054
|
||||
#define DRV_KSQO 1055
|
||||
#define DS_PG64 1057
|
||||
#define DS_PG63 1058
|
||||
#define IDS_BADDSN 1
|
||||
#define IDS_MSGTITLE 2
|
||||
#define DLG_OPTIONS_DRV 102
|
||||
#define DLG_OPTIONS_DS 103
|
||||
#define IDC_DSNAME 400
|
||||
#define IDC_DSNAMETEXT 401
|
||||
#define IDC_DESC 404
|
||||
#define IDC_SERVER 407
|
||||
#define IDC_DATABASE 408
|
||||
#define DLG_CONFIG 1001
|
||||
#define IDC_PORT 1002
|
||||
#define IDC_USER 1006
|
||||
#define IDC_PASSWORD 1009
|
||||
#define DS_READONLY 1011
|
||||
#define DS_SHOWOIDCOLUMN 1012
|
||||
#define DS_FAKEOIDINDEX 1013
|
||||
#define DRV_COMMLOG 1014
|
||||
#define DS_PG62 1016
|
||||
#define IDC_DATASOURCE 1018
|
||||
#define DRV_OPTIMIZER 1019
|
||||
#define DS_CONNSETTINGS 1020
|
||||
#define IDC_DRIVER 1021
|
||||
#define DRV_CONNSETTINGS 1031
|
||||
#define DRV_UNIQUEINDEX 1032
|
||||
#define DRV_UNKNOWN_MAX 1035
|
||||
#define DRV_UNKNOWN_DONTKNOW 1036
|
||||
#define DRV_READONLY 1037
|
||||
#define IDC_DESCTEXT 1039
|
||||
#define DRV_MSG_LABEL 1040
|
||||
#define DRV_UNKNOWN_LONGEST 1041
|
||||
#define DRV_TEXT_LONGVARCHAR 1043
|
||||
#define DRV_UNKNOWNS_LONGVARCHAR 1044
|
||||
#define DRV_CACHE_SIZE 1045
|
||||
#define DRV_VARCHAR_SIZE 1046
|
||||
#define DRV_LONGVARCHAR_SIZE 1047
|
||||
#define IDDEFAULTS 1048
|
||||
#define DRV_USEDECLAREFETCH 1049
|
||||
#define DRV_BOOLS_CHAR 1050
|
||||
#define DS_SHOWSYSTEMTABLES 1051
|
||||
#define DRV_EXTRASYSTABLEPREFIXES 1051
|
||||
#define DS_ROWVERSIONING 1052
|
||||
#define DRV_PARSE 1052
|
||||
#define DRV_CANCELASFREESTMT 1053
|
||||
#define IDC_OPTIONS 1054
|
||||
#define DRV_KSQO 1055
|
||||
#define DS_PG64 1057
|
||||
#define DS_PG63 1058
|
||||
|
||||
/* Next default values for new objects */
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 104
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1060
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#define _APS_NEXT_RESOURCE_VALUE 104
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1060
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,15 @@
|
||||
|
||||
/* Module: setup.c
|
||||
/* Module: setup.c
|
||||
*
|
||||
* Description: This module contains the setup functions for
|
||||
* adding/modifying a Data Source in the ODBC.INI portion
|
||||
* of the registry.
|
||||
* Description: This module contains the setup functions for
|
||||
* adding/modifying a Data Source in the ODBC.INI portion
|
||||
* of the registry.
|
||||
*
|
||||
* Classes: n/a
|
||||
* Classes: n/a
|
||||
*
|
||||
* API functions: ConfigDSN
|
||||
* API functions: ConfigDSN
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*************************************************************************************/
|
||||
|
||||
@@ -26,288 +26,313 @@
|
||||
|
||||
#define INTFUNC __stdcall
|
||||
|
||||
extern HINSTANCE NEAR s_hModule; /* Saved module handle. */
|
||||
extern HINSTANCE NEAR s_hModule;/* Saved module handle. */
|
||||
extern GLOBAL_VALUES globals;
|
||||
|
||||
/* Constants --------------------------------------------------------------- */
|
||||
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
||||
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
#ifdef WIN32
|
||||
#define MAXPGPATH (255+1)
|
||||
#define MAXPGPATH (255+1)
|
||||
#endif
|
||||
|
||||
#define MAXKEYLEN (15+1) /* Max keyword length */
|
||||
#define MAXDESC (255+1) /* Max description length */
|
||||
#define MAXDSNAME (32+1) /* Max data source name length */
|
||||
#define MAXKEYLEN (15+1) /* Max keyword length */
|
||||
#define MAXDESC (255+1) /* Max description length */
|
||||
#define MAXDSNAME (32+1) /* Max data source name length */
|
||||
|
||||
|
||||
/* Globals ----------------------------------------------------------------- */
|
||||
/* NOTE: All these are used by the dialog procedures */
|
||||
typedef struct tagSETUPDLG {
|
||||
HWND hwndParent; /* Parent window handle */
|
||||
LPCSTR lpszDrvr; /* Driver description */
|
||||
ConnInfo ci;
|
||||
char szDSN[MAXDSNAME]; /* Original data source name */
|
||||
BOOL fNewDSN; /* New data source flag */
|
||||
BOOL fDefault; /* Default data source flag */
|
||||
typedef struct tagSETUPDLG
|
||||
{
|
||||
HWND hwndParent; /* Parent window handle */
|
||||
LPCSTR lpszDrvr; /* Driver description */
|
||||
ConnInfo ci;
|
||||
char szDSN[MAXDSNAME]; /* Original data source name */
|
||||
BOOL fNewDSN; /* New data source flag */
|
||||
BOOL fDefault; /* Default data source flag */
|
||||
|
||||
} SETUPDLG, FAR *LPSETUPDLG;
|
||||
} SETUPDLG, FAR *LPSETUPDLG;
|
||||
|
||||
|
||||
|
||||
/* Prototypes -------------------------------------------------------------- */
|
||||
void INTFUNC CenterDialog(HWND hdlg);
|
||||
int CALLBACK ConfigDlgProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam);
|
||||
void INTFUNC ParseAttributes (LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg);
|
||||
int CALLBACK ConfigDlgProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam);
|
||||
void INTFUNC ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg);
|
||||
BOOL INTFUNC SetDSNAttributes(HWND hwnd, LPSETUPDLG lpsetupdlg);
|
||||
|
||||
|
||||
/* ConfigDSN ---------------------------------------------------------------
|
||||
Description: ODBC Setup entry point
|
||||
This entry point is called by the ODBC Installer
|
||||
(see file header for more details)
|
||||
Input : hwnd ----------- Parent window handle
|
||||
fRequest ------- Request type (i.e., add, config, or remove)
|
||||
lpszDriver ----- Driver name
|
||||
lpszAttributes - data source attribute string
|
||||
Output : TRUE success, FALSE otherwise
|
||||
Description: ODBC Setup entry point
|
||||
This entry point is called by the ODBC Installer
|
||||
(see file header for more details)
|
||||
Input : hwnd ----------- Parent window handle
|
||||
fRequest ------- Request type (i.e., add, config, or remove)
|
||||
lpszDriver ----- Driver name
|
||||
lpszAttributes - data source attribute string
|
||||
Output : TRUE success, FALSE otherwise
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
BOOL CALLBACK ConfigDSN (HWND hwnd,
|
||||
WORD fRequest,
|
||||
LPCSTR lpszDriver,
|
||||
LPCSTR lpszAttributes)
|
||||
BOOL CALLBACK
|
||||
ConfigDSN(HWND hwnd,
|
||||
WORD fRequest,
|
||||
LPCSTR lpszDriver,
|
||||
LPCSTR lpszAttributes)
|
||||
{
|
||||
BOOL fSuccess; /* Success/fail flag */
|
||||
GLOBALHANDLE hglbAttr;
|
||||
LPSETUPDLG lpsetupdlg;
|
||||
|
||||
BOOL fSuccess; /* Success/fail flag */
|
||||
GLOBALHANDLE hglbAttr;
|
||||
LPSETUPDLG lpsetupdlg;
|
||||
|
||||
|
||||
/* Allocate attribute array */
|
||||
hglbAttr = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(SETUPDLG));
|
||||
if (!hglbAttr)
|
||||
return FALSE;
|
||||
lpsetupdlg = (LPSETUPDLG)GlobalLock(hglbAttr);
|
||||
hglbAttr = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(SETUPDLG));
|
||||
if (!hglbAttr)
|
||||
return FALSE;
|
||||
lpsetupdlg = (LPSETUPDLG) GlobalLock(hglbAttr);
|
||||
|
||||
/* Parse attribute string */
|
||||
if (lpszAttributes)
|
||||
ParseAttributes(lpszAttributes, lpsetupdlg);
|
||||
/* Parse attribute string */
|
||||
if (lpszAttributes)
|
||||
ParseAttributes(lpszAttributes, lpsetupdlg);
|
||||
|
||||
/* Save original data source name */
|
||||
if (lpsetupdlg->ci.dsn[0])
|
||||
lstrcpy(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn);
|
||||
else
|
||||
lpsetupdlg->szDSN[0] = '\0';
|
||||
/* Save original data source name */
|
||||
if (lpsetupdlg->ci.dsn[0])
|
||||
lstrcpy(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn);
|
||||
else
|
||||
lpsetupdlg->szDSN[0] = '\0';
|
||||
|
||||
/* Remove data source */
|
||||
if (ODBC_REMOVE_DSN == fRequest) {
|
||||
/* Remove data source */
|
||||
if (ODBC_REMOVE_DSN == fRequest)
|
||||
{
|
||||
/* Fail if no data source name was supplied */
|
||||
if (!lpsetupdlg->ci.dsn[0])
|
||||
fSuccess = FALSE;
|
||||
if (!lpsetupdlg->ci.dsn[0])
|
||||
fSuccess = FALSE;
|
||||
|
||||
/* Otherwise remove data source from ODBC.INI */
|
||||
else
|
||||
fSuccess = SQLRemoveDSNFromIni(lpsetupdlg->ci.dsn);
|
||||
}
|
||||
/* Otherwise remove data source from ODBC.INI */
|
||||
else
|
||||
fSuccess = SQLRemoveDSNFromIni(lpsetupdlg->ci.dsn);
|
||||
}
|
||||
|
||||
/* Add or Configure data source */
|
||||
else {
|
||||
/* Add or Configure data source */
|
||||
else
|
||||
{
|
||||
/* Save passed variables for global access (e.g., dialog access) */
|
||||
lpsetupdlg->hwndParent = hwnd;
|
||||
lpsetupdlg->lpszDrvr = lpszDriver;
|
||||
lpsetupdlg->fNewDSN = (ODBC_ADD_DSN == fRequest);
|
||||
lpsetupdlg->fDefault = !lstrcmpi(lpsetupdlg->ci.dsn, INI_DSN);
|
||||
lpsetupdlg->hwndParent = hwnd;
|
||||
lpsetupdlg->lpszDrvr = lpszDriver;
|
||||
lpsetupdlg->fNewDSN = (ODBC_ADD_DSN == fRequest);
|
||||
lpsetupdlg->fDefault = !lstrcmpi(lpsetupdlg->ci.dsn, INI_DSN);
|
||||
|
||||
/* Display the appropriate dialog (if parent window handle supplied) */
|
||||
if (hwnd) {
|
||||
/* Display dialog(s) */
|
||||
fSuccess = (IDOK == DialogBoxParam(s_hModule,
|
||||
MAKEINTRESOURCE(DLG_CONFIG),
|
||||
hwnd,
|
||||
ConfigDlgProc,
|
||||
(LONG)(LPSTR)lpsetupdlg));
|
||||
}
|
||||
/*
|
||||
* Display the appropriate dialog (if parent window handle
|
||||
* supplied)
|
||||
*/
|
||||
if (hwnd)
|
||||
{
|
||||
/* Display dialog(s) */
|
||||
fSuccess = (IDOK == DialogBoxParam(s_hModule,
|
||||
MAKEINTRESOURCE(DLG_CONFIG),
|
||||
hwnd,
|
||||
ConfigDlgProc,
|
||||
(LONG) (LPSTR) lpsetupdlg));
|
||||
}
|
||||
|
||||
else if (lpsetupdlg->ci.dsn[0])
|
||||
fSuccess = SetDSNAttributes(hwnd, lpsetupdlg);
|
||||
else
|
||||
fSuccess = FALSE;
|
||||
}
|
||||
else if (lpsetupdlg->ci.dsn[0])
|
||||
fSuccess = SetDSNAttributes(hwnd, lpsetupdlg);
|
||||
else
|
||||
fSuccess = FALSE;
|
||||
}
|
||||
|
||||
GlobalUnlock(hglbAttr);
|
||||
GlobalFree(hglbAttr);
|
||||
GlobalUnlock(hglbAttr);
|
||||
GlobalFree(hglbAttr);
|
||||
|
||||
return fSuccess;
|
||||
return fSuccess;
|
||||
}
|
||||
|
||||
|
||||
/* CenterDialog ------------------------------------------------------------
|
||||
Description: Center the dialog over the frame window
|
||||
Input : hdlg -- Dialog window handle
|
||||
Output : None
|
||||
Description: Center the dialog over the frame window
|
||||
Input : hdlg -- Dialog window handle
|
||||
Output : None
|
||||
--------------------------------------------------------------------------*/
|
||||
void INTFUNC CenterDialog(HWND hdlg)
|
||||
void INTFUNC
|
||||
CenterDialog(HWND hdlg)
|
||||
{
|
||||
HWND hwndFrame;
|
||||
RECT rcDlg, rcScr, rcFrame;
|
||||
int cx, cy;
|
||||
HWND hwndFrame;
|
||||
RECT rcDlg,
|
||||
rcScr,
|
||||
rcFrame;
|
||||
int cx,
|
||||
cy;
|
||||
|
||||
hwndFrame = GetParent(hdlg);
|
||||
hwndFrame = GetParent(hdlg);
|
||||
|
||||
GetWindowRect(hdlg, &rcDlg);
|
||||
cx = rcDlg.right - rcDlg.left;
|
||||
cy = rcDlg.bottom - rcDlg.top;
|
||||
GetWindowRect(hdlg, &rcDlg);
|
||||
cx = rcDlg.right - rcDlg.left;
|
||||
cy = rcDlg.bottom - rcDlg.top;
|
||||
|
||||
GetClientRect(hwndFrame, &rcFrame);
|
||||
ClientToScreen(hwndFrame, (LPPOINT)(&rcFrame.left));
|
||||
ClientToScreen(hwndFrame, (LPPOINT)(&rcFrame.right));
|
||||
rcDlg.top = rcFrame.top + (((rcFrame.bottom - rcFrame.top) - cy) >> 1);
|
||||
rcDlg.left = rcFrame.left + (((rcFrame.right - rcFrame.left) - cx) >> 1);
|
||||
rcDlg.bottom = rcDlg.top + cy;
|
||||
rcDlg.right = rcDlg.left + cx;
|
||||
GetClientRect(hwndFrame, &rcFrame);
|
||||
ClientToScreen(hwndFrame, (LPPOINT) (&rcFrame.left));
|
||||
ClientToScreen(hwndFrame, (LPPOINT) (&rcFrame.right));
|
||||
rcDlg.top = rcFrame.top + (((rcFrame.bottom - rcFrame.top) - cy) >> 1);
|
||||
rcDlg.left = rcFrame.left + (((rcFrame.right - rcFrame.left) - cx) >> 1);
|
||||
rcDlg.bottom = rcDlg.top + cy;
|
||||
rcDlg.right = rcDlg.left + cx;
|
||||
|
||||
GetWindowRect(GetDesktopWindow(), &rcScr);
|
||||
if (rcDlg.bottom > rcScr.bottom)
|
||||
{
|
||||
rcDlg.bottom = rcScr.bottom;
|
||||
rcDlg.top = rcDlg.bottom - cy;
|
||||
}
|
||||
if (rcDlg.right > rcScr.right)
|
||||
{
|
||||
rcDlg.right = rcScr.right;
|
||||
rcDlg.left = rcDlg.right - cx;
|
||||
}
|
||||
GetWindowRect(GetDesktopWindow(), &rcScr);
|
||||
if (rcDlg.bottom > rcScr.bottom)
|
||||
{
|
||||
rcDlg.bottom = rcScr.bottom;
|
||||
rcDlg.top = rcDlg.bottom - cy;
|
||||
}
|
||||
if (rcDlg.right > rcScr.right)
|
||||
{
|
||||
rcDlg.right = rcScr.right;
|
||||
rcDlg.left = rcDlg.right - cx;
|
||||
}
|
||||
|
||||
if (rcDlg.left < 0) rcDlg.left = 0;
|
||||
if (rcDlg.top < 0) rcDlg.top = 0;
|
||||
if (rcDlg.left < 0)
|
||||
rcDlg.left = 0;
|
||||
if (rcDlg.top < 0)
|
||||
rcDlg.top = 0;
|
||||
|
||||
MoveWindow(hdlg, rcDlg.left, rcDlg.top, cx, cy, TRUE);
|
||||
return;
|
||||
MoveWindow(hdlg, rcDlg.left, rcDlg.top, cx, cy, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* ConfigDlgProc -----------------------------------------------------------
|
||||
Description: Manage add data source name dialog
|
||||
Input : hdlg --- Dialog window handle
|
||||
wMsg --- Message
|
||||
wParam - Message parameter
|
||||
lParam - Message parameter
|
||||
Output : TRUE if message processed, FALSE otherwise
|
||||
Description: Manage add data source name dialog
|
||||
Input : hdlg --- Dialog window handle
|
||||
wMsg --- Message
|
||||
wParam - Message parameter
|
||||
lParam - Message parameter
|
||||
Output : TRUE if message processed, FALSE otherwise
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
int CALLBACK ConfigDlgProc(HWND hdlg,
|
||||
WORD wMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
int CALLBACK
|
||||
ConfigDlgProc(HWND hdlg,
|
||||
WORD wMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
|
||||
switch (wMsg) {
|
||||
/* Initialize the dialog */
|
||||
case WM_INITDIALOG:
|
||||
switch (wMsg)
|
||||
{
|
||||
LPSETUPDLG lpsetupdlg = (LPSETUPDLG) lParam;
|
||||
ConnInfo *ci = &lpsetupdlg->ci;
|
||||
|
||||
/* Hide the driver connect message */
|
||||
ShowWindow(GetDlgItem(hdlg, DRV_MSG_LABEL), SW_HIDE);
|
||||
|
||||
SetWindowLong(hdlg, DWL_USER, lParam);
|
||||
CenterDialog(hdlg); /* Center dialog */
|
||||
|
||||
/* NOTE: Values supplied in the attribute string will always */
|
||||
/* override settings in ODBC.INI */
|
||||
|
||||
/* Get the rest of the common attributes */
|
||||
getDSNinfo(ci, CONN_DONT_OVERWRITE);
|
||||
|
||||
/* Fill in any defaults */
|
||||
getDSNdefaults(ci);
|
||||
|
||||
|
||||
/* Initialize dialog fields */
|
||||
SetDlgStuff(hdlg, ci);
|
||||
|
||||
|
||||
if (lpsetupdlg->fDefault) {
|
||||
EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
|
||||
EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
|
||||
}
|
||||
else
|
||||
SendDlgItemMessage(hdlg, IDC_DSNAME,
|
||||
EM_LIMITTEXT, (WPARAM)(MAXDSNAME-1), 0L);
|
||||
|
||||
SendDlgItemMessage(hdlg, IDC_DESC,
|
||||
EM_LIMITTEXT, (WPARAM)(MAXDESC-1), 0L);
|
||||
return TRUE; /* Focus was not set */
|
||||
}
|
||||
|
||||
|
||||
/* Process buttons */
|
||||
case WM_COMMAND:
|
||||
|
||||
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
|
||||
/* Ensure the OK button is enabled only when a data source name */
|
||||
/* is entered */
|
||||
case IDC_DSNAME:
|
||||
if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
|
||||
/* Initialize the dialog */
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
char szItem[MAXDSNAME]; /* Edit control text */
|
||||
LPSETUPDLG lpsetupdlg = (LPSETUPDLG) lParam;
|
||||
ConnInfo *ci = &lpsetupdlg->ci;
|
||||
|
||||
/* Enable/disable the OK button */
|
||||
EnableWindow(GetDlgItem(hdlg, IDOK),
|
||||
GetDlgItemText(hdlg, IDC_DSNAME,
|
||||
szItem, sizeof(szItem)));
|
||||
/* Hide the driver connect message */
|
||||
ShowWindow(GetDlgItem(hdlg, DRV_MSG_LABEL), SW_HIDE);
|
||||
|
||||
return TRUE;
|
||||
SetWindowLong(hdlg, DWL_USER, lParam);
|
||||
CenterDialog(hdlg); /* Center dialog */
|
||||
|
||||
/*
|
||||
* NOTE: Values supplied in the attribute string will
|
||||
* always
|
||||
*/
|
||||
/* override settings in ODBC.INI */
|
||||
|
||||
/* Get the rest of the common attributes */
|
||||
getDSNinfo(ci, CONN_DONT_OVERWRITE);
|
||||
|
||||
/* Fill in any defaults */
|
||||
getDSNdefaults(ci);
|
||||
|
||||
|
||||
/* Initialize dialog fields */
|
||||
SetDlgStuff(hdlg, ci);
|
||||
|
||||
|
||||
if (lpsetupdlg->fDefault)
|
||||
{
|
||||
EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
|
||||
EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
|
||||
}
|
||||
else
|
||||
SendDlgItemMessage(hdlg, IDC_DSNAME,
|
||||
EM_LIMITTEXT, (WPARAM) (MAXDSNAME - 1), 0L);
|
||||
|
||||
SendDlgItemMessage(hdlg, IDC_DESC,
|
||||
EM_LIMITTEXT, (WPARAM) (MAXDESC - 1), 0L);
|
||||
return TRUE; /* Focus was not set */
|
||||
}
|
||||
|
||||
|
||||
/* Process buttons */
|
||||
case WM_COMMAND:
|
||||
|
||||
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||
{
|
||||
|
||||
/*
|
||||
* Ensure the OK button is enabled only when a data
|
||||
* source name
|
||||
*/
|
||||
/* is entered */
|
||||
case IDC_DSNAME:
|
||||
if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
|
||||
{
|
||||
char szItem[MAXDSNAME]; /* Edit control text */
|
||||
|
||||
/* Enable/disable the OK button */
|
||||
EnableWindow(GetDlgItem(hdlg, IDOK),
|
||||
GetDlgItemText(hdlg, IDC_DSNAME,
|
||||
szItem, sizeof(szItem)));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Accept results */
|
||||
case IDOK:
|
||||
{
|
||||
LPSETUPDLG lpsetupdlg;
|
||||
|
||||
lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER);
|
||||
/* Retrieve dialog values */
|
||||
if (!lpsetupdlg->fDefault)
|
||||
GetDlgItemText(hdlg, IDC_DSNAME,
|
||||
lpsetupdlg->ci.dsn,
|
||||
sizeof(lpsetupdlg->ci.dsn));
|
||||
|
||||
|
||||
/* Get Dialog Values */
|
||||
GetDlgStuff(hdlg, &lpsetupdlg->ci);
|
||||
|
||||
/* Update ODBC.INI */
|
||||
SetDSNAttributes(hdlg, lpsetupdlg);
|
||||
}
|
||||
|
||||
/* Return to caller */
|
||||
case IDCANCEL:
|
||||
EndDialog(hdlg, wParam);
|
||||
return TRUE;
|
||||
|
||||
case IDC_DRIVER:
|
||||
|
||||
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
|
||||
hdlg, driver_optionsProc, (LPARAM) NULL);
|
||||
|
||||
return TRUE;
|
||||
|
||||
case IDC_DATASOURCE:
|
||||
{
|
||||
LPSETUPDLG lpsetupdlg;
|
||||
|
||||
lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER);
|
||||
|
||||
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
|
||||
hdlg, ds_optionsProc, (LPARAM) &lpsetupdlg->ci);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
/* Accept results */
|
||||
case IDOK:
|
||||
{
|
||||
LPSETUPDLG lpsetupdlg;
|
||||
|
||||
lpsetupdlg = (LPSETUPDLG)GetWindowLong(hdlg, DWL_USER);
|
||||
/* Retrieve dialog values */
|
||||
if (!lpsetupdlg->fDefault)
|
||||
GetDlgItemText(hdlg, IDC_DSNAME,
|
||||
lpsetupdlg->ci.dsn,
|
||||
sizeof(lpsetupdlg->ci.dsn));
|
||||
|
||||
|
||||
/* Get Dialog Values */
|
||||
GetDlgStuff(hdlg, &lpsetupdlg->ci);
|
||||
|
||||
/* Update ODBC.INI */
|
||||
SetDSNAttributes(hdlg, lpsetupdlg);
|
||||
}
|
||||
|
||||
/* Return to caller */
|
||||
case IDCANCEL:
|
||||
EndDialog(hdlg, wParam);
|
||||
return TRUE;
|
||||
|
||||
case IDC_DRIVER:
|
||||
|
||||
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
|
||||
hdlg, driver_optionsProc, (LPARAM) NULL);
|
||||
|
||||
return TRUE;
|
||||
|
||||
case IDC_DATASOURCE:
|
||||
{
|
||||
LPSETUPDLG lpsetupdlg;
|
||||
|
||||
lpsetupdlg = (LPSETUPDLG)GetWindowLong(hdlg, DWL_USER);
|
||||
|
||||
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
|
||||
hdlg, ds_optionsProc, (LPARAM) &lpsetupdlg->ci);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Message not processed */
|
||||
@@ -316,97 +341,98 @@ int CALLBACK ConfigDlgProc(HWND hdlg,
|
||||
|
||||
|
||||
/* ParseAttributes ---------------------------------------------------------
|
||||
Description: Parse attribute string moving values into the aAttr array
|
||||
Input : lpszAttributes - Pointer to attribute string
|
||||
Output : None (global aAttr normally updated)
|
||||
Description: Parse attribute string moving values into the aAttr array
|
||||
Input : lpszAttributes - Pointer to attribute string
|
||||
Output : None (global aAttr normally updated)
|
||||
--------------------------------------------------------------------------*/
|
||||
void INTFUNC ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
|
||||
void INTFUNC
|
||||
ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
|
||||
{
|
||||
LPCSTR lpsz;
|
||||
LPCSTR lpszStart;
|
||||
char aszKey[MAXKEYLEN];
|
||||
int cbKey;
|
||||
char value[MAXPGPATH];
|
||||
LPCSTR lpsz;
|
||||
LPCSTR lpszStart;
|
||||
char aszKey[MAXKEYLEN];
|
||||
int cbKey;
|
||||
char value[MAXPGPATH];
|
||||
|
||||
memset(&lpsetupdlg->ci, 0, sizeof(ConnInfo));
|
||||
memset(&lpsetupdlg->ci, 0, sizeof(ConnInfo));
|
||||
|
||||
for (lpsz=lpszAttributes; *lpsz; lpsz++)
|
||||
{ /* Extract key name (e.g., DSN), it must be terminated by an equals */
|
||||
lpszStart = lpsz;
|
||||
for (;; lpsz++)
|
||||
{
|
||||
if (!*lpsz)
|
||||
return; /* No key was found */
|
||||
else if (*lpsz == '=')
|
||||
break; /* Valid key found */
|
||||
}
|
||||
/* Determine the key's index in the key table (-1 if not found) */
|
||||
cbKey = lpsz - lpszStart;
|
||||
if (cbKey < sizeof(aszKey))
|
||||
{
|
||||
for (lpsz = lpszAttributes; *lpsz; lpsz++)
|
||||
{ /* Extract key name (e.g., DSN), it must
|
||||
* be terminated by an equals */
|
||||
lpszStart = lpsz;
|
||||
for (;; lpsz++)
|
||||
{
|
||||
if (!*lpsz)
|
||||
return; /* No key was found */
|
||||
else if (*lpsz == '=')
|
||||
break; /* Valid key found */
|
||||
}
|
||||
/* Determine the key's index in the key table (-1 if not found) */
|
||||
cbKey = lpsz - lpszStart;
|
||||
if (cbKey < sizeof(aszKey))
|
||||
{
|
||||
|
||||
_fmemcpy(aszKey, lpszStart, cbKey);
|
||||
aszKey[cbKey] = '\0';
|
||||
}
|
||||
_fmemcpy(aszKey, lpszStart, cbKey);
|
||||
aszKey[cbKey] = '\0';
|
||||
}
|
||||
|
||||
/* Locate end of key value */
|
||||
lpszStart = ++lpsz;
|
||||
for (; *lpsz; lpsz++);
|
||||
/* Locate end of key value */
|
||||
lpszStart = ++lpsz;
|
||||
for (; *lpsz; lpsz++);
|
||||
|
||||
|
||||
/* lpsetupdlg->aAttr[iElement].fSupplied = TRUE; */
|
||||
_fmemcpy(value, lpszStart, MIN(lpsz-lpszStart+1, MAXPGPATH));
|
||||
/* lpsetupdlg->aAttr[iElement].fSupplied = TRUE; */
|
||||
_fmemcpy(value, lpszStart, MIN(lpsz - lpszStart + 1, MAXPGPATH));
|
||||
|
||||
mylog("aszKey='%s', value='%s'\n", aszKey, value);
|
||||
mylog("aszKey='%s', value='%s'\n", aszKey, value);
|
||||
|
||||
/* Copy the appropriate value to the conninfo */
|
||||
copyAttributes(&lpsetupdlg->ci, aszKey, value);
|
||||
}
|
||||
return;
|
||||
/* Copy the appropriate value to the conninfo */
|
||||
copyAttributes(&lpsetupdlg->ci, aszKey, value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* SetDSNAttributes --------------------------------------------------------
|
||||
Description: Write data source attributes to ODBC.INI
|
||||
Input : hwnd - Parent window handle (plus globals)
|
||||
Output : TRUE if successful, FALSE otherwise
|
||||
Description: Write data source attributes to ODBC.INI
|
||||
Input : hwnd - Parent window handle (plus globals)
|
||||
Output : TRUE if successful, FALSE otherwise
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
BOOL INTFUNC SetDSNAttributes(HWND hwndParent, LPSETUPDLG lpsetupdlg)
|
||||
BOOL INTFUNC
|
||||
SetDSNAttributes(HWND hwndParent, LPSETUPDLG lpsetupdlg)
|
||||
{
|
||||
LPCSTR lpszDSN; /* Pointer to data source name */
|
||||
|
||||
lpszDSN = lpsetupdlg->ci.dsn;
|
||||
LPCSTR lpszDSN; /* Pointer to data source name */
|
||||
|
||||
/* Validate arguments */
|
||||
if (lpsetupdlg->fNewDSN && !*lpsetupdlg->ci.dsn)
|
||||
return FALSE;
|
||||
lpszDSN = lpsetupdlg->ci.dsn;
|
||||
|
||||
/* Write the data source name */
|
||||
if (!SQLWriteDSNToIni(lpszDSN, lpsetupdlg->lpszDrvr))
|
||||
{
|
||||
if (hwndParent)
|
||||
{
|
||||
char szBuf[MAXPGPATH];
|
||||
char szMsg[MAXPGPATH];
|
||||
/* Validate arguments */
|
||||
if (lpsetupdlg->fNewDSN && !*lpsetupdlg->ci.dsn)
|
||||
return FALSE;
|
||||
|
||||
LoadString(s_hModule, IDS_BADDSN, szBuf, sizeof(szBuf));
|
||||
wsprintf(szMsg, szBuf, lpszDSN);
|
||||
LoadString(s_hModule, IDS_MSGTITLE, szBuf, sizeof(szBuf));
|
||||
MessageBox(hwndParent, szMsg, szBuf, MB_ICONEXCLAMATION | MB_OK);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
/* Write the data source name */
|
||||
if (!SQLWriteDSNToIni(lpszDSN, lpsetupdlg->lpszDrvr))
|
||||
{
|
||||
if (hwndParent)
|
||||
{
|
||||
char szBuf[MAXPGPATH];
|
||||
char szMsg[MAXPGPATH];
|
||||
|
||||
LoadString(s_hModule, IDS_BADDSN, szBuf, sizeof(szBuf));
|
||||
wsprintf(szMsg, szBuf, lpszDSN);
|
||||
LoadString(s_hModule, IDS_MSGTITLE, szBuf, sizeof(szBuf));
|
||||
MessageBox(hwndParent, szMsg, szBuf, MB_ICONEXCLAMATION | MB_OK);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Update ODBC.INI */
|
||||
writeDSNinfo(&lpsetupdlg->ci);
|
||||
/* Update ODBC.INI */
|
||||
writeDSNinfo(&lpsetupdlg->ci);
|
||||
|
||||
|
||||
/* If the data source name has changed, remove the old name */
|
||||
if (lstrcmpi(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn))
|
||||
{
|
||||
SQLRemoveDSNFromIni(lpsetupdlg->szDSN);
|
||||
}
|
||||
return TRUE;
|
||||
if (lstrcmpi(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn))
|
||||
SQLRemoveDSNFromIni(lpsetupdlg->szDSN);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
|
||||
/* Module: socket.c
|
||||
/* Module: socket.c
|
||||
*
|
||||
* Description: This module contains functions for low level socket
|
||||
* operations (connecting/reading/writing to the backend)
|
||||
* Description: This module contains functions for low level socket
|
||||
* operations (connecting/reading/writing to the backend)
|
||||
*
|
||||
* Classes: SocketClass (Functions prefix: "SOCK_")
|
||||
* Classes: SocketClass (Functions prefix: "SOCK_")
|
||||
*
|
||||
* API functions: none
|
||||
* API functions: none
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#ifndef WIN32
|
||||
#include <stdlib.h>
|
||||
#include <string.h> /* for memset */
|
||||
#include <string.h> /* for memset */
|
||||
#endif
|
||||
|
||||
extern GLOBAL_VALUES globals;
|
||||
@@ -39,51 +39,53 @@ extern GLOBAL_VALUES globals;
|
||||
void
|
||||
SOCK_clear_error(SocketClass *self)
|
||||
{
|
||||
self->errornumber = 0;
|
||||
self->errormsg = NULL;
|
||||
self->errornumber = 0;
|
||||
self->errormsg = NULL;
|
||||
}
|
||||
|
||||
SocketClass *
|
||||
SocketClass *
|
||||
SOCK_Constructor()
|
||||
{
|
||||
SocketClass *rv;
|
||||
SocketClass *rv;
|
||||
|
||||
rv = (SocketClass *) malloc(sizeof(SocketClass));
|
||||
rv = (SocketClass *) malloc(sizeof(SocketClass));
|
||||
|
||||
if (rv != NULL) {
|
||||
rv->socket = (SOCKETFD) -1;
|
||||
if (rv != NULL)
|
||||
{
|
||||
rv->socket = (SOCKETFD) - 1;
|
||||
rv->buffer_filled_in = 0;
|
||||
rv->buffer_filled_out = 0;
|
||||
rv->buffer_read_in = 0;
|
||||
|
||||
rv->buffer_in = (unsigned char *) malloc(globals.socket_buffersize);
|
||||
if ( ! rv->buffer_in)
|
||||
if (!rv->buffer_in)
|
||||
{
|
||||
free(rv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rv->buffer_out = (unsigned char *) malloc(globals.socket_buffersize);
|
||||
if ( ! rv->buffer_out)
|
||||
if (!rv->buffer_out)
|
||||
{
|
||||
free(rv->buffer_in);
|
||||
free(rv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rv->errormsg = NULL;
|
||||
rv->errornumber = 0;
|
||||
|
||||
rv->errormsg = NULL;
|
||||
rv->errornumber = 0;
|
||||
|
||||
rv->reverse = FALSE;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
SOCK_Destructor(SocketClass *self)
|
||||
{
|
||||
if (self->socket != -1) {
|
||||
if (self->socket != -1)
|
||||
{
|
||||
SOCK_put_char(self, 'X');
|
||||
SOCK_flush_output(self);
|
||||
closesocket(self->socket);
|
||||
@@ -100,28 +102,31 @@ SOCK_Destructor(SocketClass *self)
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
char
|
||||
SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname)
|
||||
{
|
||||
struct hostent *host;
|
||||
struct sockaddr_in sadr;
|
||||
unsigned long iaddr;
|
||||
struct hostent *host;
|
||||
struct sockaddr_in sadr;
|
||||
unsigned long iaddr;
|
||||
|
||||
if (self->socket != -1) {
|
||||
if (self->socket != -1)
|
||||
{
|
||||
self->errornumber = SOCKET_ALREADY_CONNECTED;
|
||||
self->errormsg = "Socket is already connected";
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset((char *)&sadr, 0, sizeof(sadr));
|
||||
memset((char *) &sadr, 0, sizeof(sadr));
|
||||
|
||||
/* If it is a valid IP address, use it.
|
||||
Otherwise use hostname lookup.
|
||||
*/
|
||||
/*
|
||||
* If it is a valid IP address, use it. Otherwise use hostname lookup.
|
||||
*/
|
||||
iaddr = inet_addr(hostname);
|
||||
if (iaddr == INADDR_NONE) {
|
||||
if (iaddr == INADDR_NONE)
|
||||
{
|
||||
host = gethostbyname(hostname);
|
||||
if (host == NULL) {
|
||||
if (host == NULL)
|
||||
{
|
||||
self->errornumber = SOCKET_HOST_NOT_FOUND;
|
||||
self->errormsg = "Could not resolve hostname.";
|
||||
return 0;
|
||||
@@ -129,177 +134,187 @@ unsigned long iaddr;
|
||||
memcpy(&(sadr.sin_addr), host->h_addr, host->h_length);
|
||||
}
|
||||
else
|
||||
memcpy(&(sadr.sin_addr), (struct in_addr *) &iaddr, sizeof(iaddr));
|
||||
memcpy(&(sadr.sin_addr), (struct in_addr *) & iaddr, sizeof(iaddr));
|
||||
|
||||
sadr.sin_family = AF_INET;
|
||||
sadr.sin_port = htons(port);
|
||||
|
||||
self->socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (self->socket == -1) {
|
||||
if (self->socket == -1)
|
||||
{
|
||||
self->errornumber = SOCKET_COULD_NOT_CREATE_SOCKET;
|
||||
self->errormsg = "Could not create Socket.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( connect(self->socket, (struct sockaddr *)&(sadr),
|
||||
sizeof(sadr)) < 0) {
|
||||
if (connect(self->socket, (struct sockaddr *) & (sadr),
|
||||
sizeof(sadr)) < 0)
|
||||
{
|
||||
|
||||
self->errornumber = SOCKET_COULD_NOT_CONNECT;
|
||||
self->errormsg = "Could not connect to remote socket.";
|
||||
closesocket(self->socket);
|
||||
self->socket = (SOCKETFD) -1;
|
||||
self->socket = (SOCKETFD) - 1;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
SOCK_get_n_char(SocketClass *self, char *buffer, int len)
|
||||
{
|
||||
int lf;
|
||||
int lf;
|
||||
|
||||
if ( ! buffer) {
|
||||
if (!buffer)
|
||||
{
|
||||
self->errornumber = SOCKET_NULLPOINTER_PARAMETER;
|
||||
self->errormsg = "get_n_char was called with NULL-Pointer";
|
||||
return;
|
||||
}
|
||||
|
||||
for(lf=0; lf < len; lf++)
|
||||
for (lf = 0; lf < len; lf++)
|
||||
buffer[lf] = SOCK_get_next_byte(self);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
SOCK_put_n_char(SocketClass *self, char *buffer, int len)
|
||||
{
|
||||
int lf;
|
||||
int lf;
|
||||
|
||||
if ( ! buffer) {
|
||||
if (!buffer)
|
||||
{
|
||||
self->errornumber = SOCKET_NULLPOINTER_PARAMETER;
|
||||
self->errormsg = "put_n_char was called with NULL-Pointer";
|
||||
return;
|
||||
}
|
||||
|
||||
for(lf=0; lf < len; lf++)
|
||||
SOCK_put_next_byte(self, (unsigned char)buffer[lf]);
|
||||
for (lf = 0; lf < len; lf++)
|
||||
SOCK_put_next_byte(self, (unsigned char) buffer[lf]);
|
||||
}
|
||||
|
||||
|
||||
/* bufsize must include room for the null terminator
|
||||
will read at most bufsize-1 characters + null.
|
||||
/* bufsize must include room for the null terminator
|
||||
will read at most bufsize-1 characters + null.
|
||||
*/
|
||||
void
|
||||
void
|
||||
SOCK_get_string(SocketClass *self, char *buffer, int bufsize)
|
||||
{
|
||||
register int lf = 0;
|
||||
register int lf = 0;
|
||||
|
||||
for (lf = 0; lf < bufsize; lf++)
|
||||
if ( ! (buffer[lf] = SOCK_get_next_byte(self)))
|
||||
if (!(buffer[lf] = SOCK_get_next_byte(self)))
|
||||
return;
|
||||
|
||||
buffer[bufsize-1] = '\0';
|
||||
|
||||
buffer[bufsize - 1] = '\0';
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
SOCK_put_string(SocketClass *self, char *string)
|
||||
{
|
||||
register int lf;
|
||||
int len;
|
||||
register int lf;
|
||||
int len;
|
||||
|
||||
len = strlen(string)+1;
|
||||
len = strlen(string) + 1;
|
||||
|
||||
for(lf = 0; lf < len; lf++)
|
||||
SOCK_put_next_byte(self, (unsigned char)string[lf]);
|
||||
for (lf = 0; lf < len; lf++)
|
||||
SOCK_put_next_byte(self, (unsigned char) string[lf]);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
int
|
||||
SOCK_get_int(SocketClass *self, short len)
|
||||
{
|
||||
char buf[4];
|
||||
char buf[4];
|
||||
|
||||
switch (len) {
|
||||
case 2:
|
||||
SOCK_get_n_char(self, buf, len);
|
||||
if (self->reverse)
|
||||
return *((unsigned short *) buf);
|
||||
else
|
||||
return ntohs( *((unsigned short *) buf) );
|
||||
switch (len)
|
||||
{
|
||||
case 2:
|
||||
SOCK_get_n_char(self, buf, len);
|
||||
if (self->reverse)
|
||||
return *((unsigned short *) buf);
|
||||
else
|
||||
return ntohs(*((unsigned short *) buf));
|
||||
|
||||
case 4:
|
||||
SOCK_get_n_char(self, buf, len);
|
||||
if (self->reverse)
|
||||
return *((unsigned int *) buf);
|
||||
else
|
||||
return ntohl( *((unsigned int *) buf) );
|
||||
case 4:
|
||||
SOCK_get_n_char(self, buf, len);
|
||||
if (self->reverse)
|
||||
return *((unsigned int *) buf);
|
||||
else
|
||||
return ntohl(*((unsigned int *) buf));
|
||||
|
||||
default:
|
||||
self->errornumber = SOCKET_GET_INT_WRONG_LENGTH;
|
||||
self->errormsg = "Cannot read ints of that length";
|
||||
return 0;
|
||||
default:
|
||||
self->errornumber = SOCKET_GET_INT_WRONG_LENGTH;
|
||||
self->errormsg = "Cannot read ints of that length";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
SOCK_put_int(SocketClass *self, int value, short len)
|
||||
{
|
||||
unsigned int rv;
|
||||
unsigned int rv;
|
||||
|
||||
switch (len) {
|
||||
case 2:
|
||||
rv = self->reverse ? value : htons( (unsigned short) value);
|
||||
SOCK_put_n_char(self, (char *) &rv, 2);
|
||||
return;
|
||||
switch (len)
|
||||
{
|
||||
case 2:
|
||||
rv = self->reverse ? value : htons((unsigned short) value);
|
||||
SOCK_put_n_char(self, (char *) &rv, 2);
|
||||
return;
|
||||
|
||||
case 4:
|
||||
rv = self->reverse ? value : htonl( (unsigned int) value);
|
||||
SOCK_put_n_char(self, (char *) &rv, 4);
|
||||
return;
|
||||
case 4:
|
||||
rv = self->reverse ? value : htonl((unsigned int) value);
|
||||
SOCK_put_n_char(self, (char *) &rv, 4);
|
||||
return;
|
||||
|
||||
default:
|
||||
self->errornumber = SOCKET_PUT_INT_WRONG_LENGTH;
|
||||
self->errormsg = "Cannot write ints of that length";
|
||||
return;
|
||||
}
|
||||
default:
|
||||
self->errornumber = SOCKET_PUT_INT_WRONG_LENGTH;
|
||||
self->errormsg = "Cannot write ints of that length";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
SOCK_flush_output(SocketClass *self)
|
||||
{
|
||||
int written;
|
||||
int written;
|
||||
|
||||
written = send(self->socket, (char *)self->buffer_out, self->buffer_filled_out, 0);
|
||||
if (written != self->buffer_filled_out) {
|
||||
written = send(self->socket, (char *) self->buffer_out, self->buffer_filled_out, 0);
|
||||
if (written != self->buffer_filled_out)
|
||||
{
|
||||
self->errornumber = SOCKET_WRITE_ERROR;
|
||||
self->errormsg = "Could not flush socket buffer.";
|
||||
}
|
||||
self->buffer_filled_out = 0;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
unsigned char
|
||||
SOCK_get_next_byte(SocketClass *self)
|
||||
{
|
||||
|
||||
if (self->buffer_read_in >= self->buffer_filled_in) {
|
||||
if (self->buffer_read_in >= self->buffer_filled_in)
|
||||
{
|
||||
/* there are no more bytes left in the buffer so */
|
||||
/* reload the buffer */
|
||||
/* reload the buffer */
|
||||
|
||||
self->buffer_read_in = 0;
|
||||
self->buffer_filled_in = recv(self->socket, (char *)self->buffer_in, globals.socket_buffersize, 0);
|
||||
self->buffer_filled_in = recv(self->socket, (char *) self->buffer_in, globals.socket_buffersize, 0);
|
||||
|
||||
mylog("read %d, global_socket_buffersize=%d\n", self->buffer_filled_in, globals.socket_buffersize);
|
||||
|
||||
if (self->buffer_filled_in < 0) {
|
||||
if (self->buffer_filled_in < 0)
|
||||
{
|
||||
self->errornumber = SOCKET_READ_ERROR;
|
||||
self->errormsg = "Error while reading from the socket.";
|
||||
self->buffer_filled_in = 0;
|
||||
return 0;
|
||||
}
|
||||
if (self->buffer_filled_in == 0) {
|
||||
if (self->buffer_filled_in == 0)
|
||||
{
|
||||
self->errornumber = SOCKET_CLOSED;
|
||||
self->errormsg = "Socket has been closed.";
|
||||
self->buffer_filled_in = 0;
|
||||
@@ -309,17 +324,19 @@ SOCK_get_next_byte(SocketClass *self)
|
||||
return self->buffer_in[self->buffer_read_in++];
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
SOCK_put_next_byte(SocketClass *self, unsigned char next_byte)
|
||||
{
|
||||
int bytes_sent;
|
||||
int bytes_sent;
|
||||
|
||||
self->buffer_out[self->buffer_filled_out++] = next_byte;
|
||||
|
||||
if (self->buffer_filled_out == globals.socket_buffersize) {
|
||||
if (self->buffer_filled_out == globals.socket_buffersize)
|
||||
{
|
||||
/* buffer is full, so write it out */
|
||||
bytes_sent = send(self->socket, (char *)self->buffer_out, globals.socket_buffersize, 0);
|
||||
if (bytes_sent != globals.socket_buffersize) {
|
||||
bytes_sent = send(self->socket, (char *) self->buffer_out, globals.socket_buffersize, 0);
|
||||
if (bytes_sent != globals.socket_buffersize)
|
||||
{
|
||||
self->errornumber = SOCKET_WRITE_ERROR;
|
||||
self->errormsg = "Error while writing to the socket.";
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
/* File: socket.h
|
||||
/* File: socket.h
|
||||
*
|
||||
* Description: See "socket.c"
|
||||
* Description: See "socket.c"
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -25,10 +25,11 @@
|
||||
#define closesocket(xxx) close(xxx)
|
||||
#define SOCKETFD int
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#ifndef INADDR_NONE
|
||||
#ifndef _IN_ADDR_T
|
||||
#define _IN_ADDR_T
|
||||
typedef unsigned int in_addr_t;
|
||||
typedef unsigned int in_addr_t;
|
||||
|
||||
#endif
|
||||
#define INADDR_NONE ((in_addr_t)-1)
|
||||
#endif
|
||||
@@ -52,20 +53,22 @@ typedef unsigned int in_addr_t;
|
||||
#define SOCKET_CLOSED 10
|
||||
|
||||
|
||||
struct SocketClass_ {
|
||||
struct SocketClass_
|
||||
{
|
||||
|
||||
int buffer_filled_in;
|
||||
int buffer_filled_out;
|
||||
int buffer_read_in;
|
||||
int buffer_filled_in;
|
||||
int buffer_filled_out;
|
||||
int buffer_read_in;
|
||||
unsigned char *buffer_in;
|
||||
unsigned char *buffer_out;
|
||||
|
||||
SOCKETFD socket;
|
||||
SOCKETFD socket;
|
||||
|
||||
char *errormsg;
|
||||
int errornumber;
|
||||
char *errormsg;
|
||||
int errornumber;
|
||||
|
||||
char reverse; /* used to handle Postgres 6.2 protocol (reverse byte order) */
|
||||
char reverse; /* used to handle Postgres 6.2 protocol
|
||||
* (reverse byte order) */
|
||||
|
||||
};
|
||||
|
||||
@@ -80,17 +83,17 @@ struct SocketClass_ {
|
||||
|
||||
/* Socket prototypes */
|
||||
SocketClass *SOCK_Constructor(void);
|
||||
void SOCK_Destructor(SocketClass *self);
|
||||
char SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname);
|
||||
void SOCK_get_n_char(SocketClass *self, char *buffer, int len);
|
||||
void SOCK_put_n_char(SocketClass *self, char *buffer, int len);
|
||||
void SOCK_get_string(SocketClass *self, char *buffer, int bufsize);
|
||||
void SOCK_put_string(SocketClass *self, char *string);
|
||||
int SOCK_get_int(SocketClass *self, short len);
|
||||
void SOCK_put_int(SocketClass *self, int value, short len);
|
||||
void SOCK_flush_output(SocketClass *self);
|
||||
void SOCK_Destructor(SocketClass *self);
|
||||
char SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname);
|
||||
void SOCK_get_n_char(SocketClass *self, char *buffer, int len);
|
||||
void SOCK_put_n_char(SocketClass *self, char *buffer, int len);
|
||||
void SOCK_get_string(SocketClass *self, char *buffer, int bufsize);
|
||||
void SOCK_put_string(SocketClass *self, char *string);
|
||||
int SOCK_get_int(SocketClass *self, short len);
|
||||
void SOCK_put_int(SocketClass *self, int value, short len);
|
||||
void SOCK_flush_output(SocketClass *self);
|
||||
unsigned char SOCK_get_next_byte(SocketClass *self);
|
||||
void SOCK_put_next_byte(SocketClass *self, unsigned char next_byte);
|
||||
void SOCK_clear_error(SocketClass *self);
|
||||
void SOCK_put_next_byte(SocketClass *self, unsigned char next_byte);
|
||||
void SOCK_clear_error(SocketClass *self);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
|
||||
/* File: statement.h
|
||||
/* File: statement.h
|
||||
*
|
||||
* Description: See "statement.c"
|
||||
* Description: See "statement.c"
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -33,21 +33,28 @@
|
||||
#define TRUE (BOOL)1
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
STMT_ALLOCATED, /* The statement handle is allocated, but not used so far */
|
||||
STMT_READY, /* the statement is waiting to be executed */
|
||||
STMT_PREMATURE, /* ODBC states that it is legal to call e.g. SQLDescribeCol before
|
||||
a call to SQLExecute, but after SQLPrepare. To get all the necessary
|
||||
information in such a case, we simply execute the query _before_ the
|
||||
actual call to SQLExecute, so that statement is considered to be "premature".
|
||||
*/
|
||||
STMT_FINISHED, /* statement execution has finished */
|
||||
STMT_EXECUTING /* statement execution is still going on */
|
||||
typedef enum
|
||||
{
|
||||
STMT_ALLOCATED, /* The statement handle is allocated, but
|
||||
* not used so far */
|
||||
STMT_READY, /* the statement is waiting to be executed */
|
||||
STMT_PREMATURE, /* ODBC states that it is legal to call
|
||||
* e.g. SQLDescribeCol before a call to
|
||||
* SQLExecute, but after SQLPrepare. To
|
||||
* get all the necessary information in
|
||||
* such a case, we simply execute the
|
||||
* query _before_ the actual call to
|
||||
* SQLExecute, so that statement is
|
||||
* considered to be "premature". */
|
||||
STMT_FINISHED, /* statement execution has finished */
|
||||
STMT_EXECUTING /* statement execution is still going on */
|
||||
} STMT_Status;
|
||||
|
||||
#define STMT_TRUNCATED -2
|
||||
#define STMT_INFO_ONLY -1 /* not an error message, just a notification to be returned by SQLError */
|
||||
#define STMT_OK 0 /* will be interpreted as "no error pending" */
|
||||
#define STMT_INFO_ONLY -1 /* not an error message, just a
|
||||
* notification to be returned by SQLError */
|
||||
#define STMT_OK 0 /* will be interpreted as "no error
|
||||
* pending" */
|
||||
#define STMT_EXEC_ERROR 1
|
||||
#define STMT_STATUS_ERROR 2
|
||||
#define STMT_SEQUENCE_ERROR 3
|
||||
@@ -77,7 +84,8 @@ typedef enum {
|
||||
#define STMT_BAD_ERROR 27
|
||||
|
||||
/* statement types */
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
STMT_TYPE_UNKNOWN = -2,
|
||||
STMT_TYPE_OTHER = -1,
|
||||
STMT_TYPE_SELECT = 0,
|
||||
@@ -95,7 +103,8 @@ enum {
|
||||
|
||||
|
||||
/* Parsing status */
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
STMT_PARSE_NONE = 0,
|
||||
STMT_PARSE_COMPLETE,
|
||||
STMT_PARSE_INCOMPLETE,
|
||||
@@ -103,92 +112,110 @@ enum {
|
||||
};
|
||||
|
||||
/* Result style */
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
STMT_FETCH_NONE = 0,
|
||||
STMT_FETCH_NORMAL,
|
||||
STMT_FETCH_EXTENDED,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
COL_INFO *col_info; /* cached SQLColumns info for this table */
|
||||
char name[MAX_TABLE_LEN+1];
|
||||
char alias[MAX_TABLE_LEN+1];
|
||||
typedef struct
|
||||
{
|
||||
COL_INFO *col_info; /* cached SQLColumns info for this table */
|
||||
char name[MAX_TABLE_LEN + 1];
|
||||
char alias[MAX_TABLE_LEN + 1];
|
||||
} TABLE_INFO;
|
||||
|
||||
typedef struct {
|
||||
TABLE_INFO *ti; /* resolve to explicit table names */
|
||||
int precision;
|
||||
int display_size;
|
||||
int length;
|
||||
int type;
|
||||
char nullable;
|
||||
char func;
|
||||
char expr;
|
||||
char quote;
|
||||
char dquote;
|
||||
char numeric;
|
||||
char dot[MAX_TABLE_LEN+1];
|
||||
char name[MAX_COLUMN_LEN+1];
|
||||
char alias[MAX_COLUMN_LEN+1];
|
||||
typedef struct
|
||||
{
|
||||
TABLE_INFO *ti; /* resolve to explicit table names */
|
||||
int precision;
|
||||
int display_size;
|
||||
int length;
|
||||
int type;
|
||||
char nullable;
|
||||
char func;
|
||||
char expr;
|
||||
char quote;
|
||||
char dquote;
|
||||
char numeric;
|
||||
char dot[MAX_TABLE_LEN + 1];
|
||||
char name[MAX_COLUMN_LEN + 1];
|
||||
char alias[MAX_COLUMN_LEN + 1];
|
||||
} FIELD_INFO;
|
||||
|
||||
|
||||
/******** Statement Handle ***********/
|
||||
struct StatementClass_ {
|
||||
ConnectionClass *hdbc; /* pointer to ConnectionClass this statement belongs to */
|
||||
QResultClass *result; /* result of the current statement */
|
||||
HSTMT FAR *phstmt;
|
||||
struct StatementClass_
|
||||
{
|
||||
ConnectionClass *hdbc; /* pointer to ConnectionClass this
|
||||
* statement belongs to */
|
||||
QResultClass *result; /* result of the current statement */
|
||||
HSTMT FAR *phstmt;
|
||||
StatementOptions options;
|
||||
|
||||
STMT_Status status;
|
||||
char *errormsg;
|
||||
int errornumber;
|
||||
STMT_Status status;
|
||||
char *errormsg;
|
||||
int errornumber;
|
||||
|
||||
/* information on bindings */
|
||||
BindInfoClass *bindings; /* array to store the binding information */
|
||||
/* information on bindings */
|
||||
BindInfoClass *bindings; /* array to store the binding information */
|
||||
BindInfoClass bookmark;
|
||||
int bindings_allocated;
|
||||
int bindings_allocated;
|
||||
|
||||
/* information on statement parameters */
|
||||
int parameters_allocated;
|
||||
ParameterInfoClass *parameters;
|
||||
/* information on statement parameters */
|
||||
int parameters_allocated;
|
||||
ParameterInfoClass *parameters;
|
||||
|
||||
Int4 currTuple; /* current absolute row number (GetData, SetPos, SQLFetch) */
|
||||
int save_rowset_size; /* saved rowset size in case of change/FETCH_NEXT */
|
||||
int rowset_start; /* start of rowset (an absolute row number) */
|
||||
int bind_row; /* current offset for Multiple row/column binding */
|
||||
int last_fetch_count; /* number of rows retrieved in last fetch/extended fetch */
|
||||
int current_col; /* current column for GetData -- used to handle multiple calls */
|
||||
int lobj_fd; /* fd of the current large object */
|
||||
Int4 currTuple; /* current absolute row number (GetData,
|
||||
* SetPos, SQLFetch) */
|
||||
int save_rowset_size; /* saved rowset size in case of
|
||||
* change/FETCH_NEXT */
|
||||
int rowset_start; /* start of rowset (an absolute row
|
||||
* number) */
|
||||
int bind_row; /* current offset for Multiple row/column
|
||||
* binding */
|
||||
int last_fetch_count; /* number of rows retrieved in
|
||||
* last fetch/extended fetch */
|
||||
int current_col; /* current column for GetData -- used to
|
||||
* handle multiple calls */
|
||||
int lobj_fd; /* fd of the current large object */
|
||||
|
||||
char *statement; /* if non--null pointer to the SQL statement that has been executed */
|
||||
char *statement; /* if non--null pointer to the SQL
|
||||
* statement that has been executed */
|
||||
|
||||
TABLE_INFO **ti;
|
||||
FIELD_INFO **fi;
|
||||
TABLE_INFO **ti;
|
||||
FIELD_INFO **fi;
|
||||
int nfld;
|
||||
int ntab;
|
||||
|
||||
int parse_status;
|
||||
int parse_status;
|
||||
|
||||
int statement_type; /* According to the defines above */
|
||||
int data_at_exec; /* Number of params needing SQLPutData */
|
||||
int current_exec_param; /* The current parameter for SQLPutData */
|
||||
int statement_type; /* According to the defines above */
|
||||
int data_at_exec; /* Number of params needing SQLPutData */
|
||||
int current_exec_param; /* The current parameter for
|
||||
* SQLPutData */
|
||||
|
||||
char put_data; /* Has SQLPutData been called yet? */
|
||||
char put_data; /* Has SQLPutData been called yet? */
|
||||
|
||||
char errormsg_created; /* has an informative error msg been created? */
|
||||
char manual_result; /* Is the statement result manually built? */
|
||||
char prepare; /* is this statement a prepared statement or direct */
|
||||
char errormsg_created; /* has an informative error msg
|
||||
* been created? */
|
||||
char manual_result; /* Is the statement result manually built? */
|
||||
char prepare; /* is this statement a prepared statement
|
||||
* or direct */
|
||||
|
||||
char internal; /* Is this statement being called internally? */
|
||||
char internal; /* Is this statement being called
|
||||
* internally? */
|
||||
|
||||
char cursor_name[MAX_CURSOR_LEN+1];
|
||||
char cursor_name[MAX_CURSOR_LEN + 1];
|
||||
|
||||
char stmt_with_params[STD_STATEMENT_LEN]; /* statement after parameter substitution */
|
||||
char stmt_with_params[STD_STATEMENT_LEN]; /* statement after
|
||||
* parameter
|
||||
* substitution */
|
||||
|
||||
};
|
||||
|
||||
#define SC_get_conn(a) (a->hdbc)
|
||||
#define SC_get_conn(a) (a->hdbc)
|
||||
#define SC_get_Result(a) (a->result);
|
||||
|
||||
/* options for SC_free_params() */
|
||||
@@ -197,21 +224,21 @@ struct StatementClass_ {
|
||||
|
||||
/* Statement prototypes */
|
||||
StatementClass *SC_Constructor(void);
|
||||
void InitializeStatementOptions(StatementOptions *opt);
|
||||
char SC_Destructor(StatementClass *self);
|
||||
int statement_type(char *statement);
|
||||
char parse_statement(StatementClass *stmt);
|
||||
void SC_pre_execute(StatementClass *self);
|
||||
char SC_unbind_cols(StatementClass *self);
|
||||
char SC_recycle_statement(StatementClass *self);
|
||||
void InitializeStatementOptions(StatementOptions *opt);
|
||||
char SC_Destructor(StatementClass *self);
|
||||
int statement_type(char *statement);
|
||||
char parse_statement(StatementClass *stmt);
|
||||
void SC_pre_execute(StatementClass *self);
|
||||
char SC_unbind_cols(StatementClass *self);
|
||||
char SC_recycle_statement(StatementClass *self);
|
||||
|
||||
void SC_clear_error(StatementClass *self);
|
||||
char SC_get_error(StatementClass *self, int *number, char **message);
|
||||
char *SC_create_errormsg(StatementClass *self);
|
||||
RETCODE SC_execute(StatementClass *self);
|
||||
RETCODE SC_fetch(StatementClass *self);
|
||||
void SC_free_params(StatementClass *self, char option);
|
||||
void SC_log_error(char *func, char *desc, StatementClass *self);
|
||||
void SC_clear_error(StatementClass *self);
|
||||
char SC_get_error(StatementClass *self, int *number, char **message);
|
||||
char *SC_create_errormsg(StatementClass *self);
|
||||
RETCODE SC_execute(StatementClass *self);
|
||||
RETCODE SC_fetch(StatementClass *self);
|
||||
void SC_free_params(StatementClass *self, char option);
|
||||
void SC_log_error(char *func, char *desc, StatementClass *self);
|
||||
unsigned long SC_get_bookmark(StatementClass *self);
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
|
||||
/* Module: tuple.c
|
||||
/* Module: tuple.c
|
||||
*
|
||||
* Description: This module contains functions for setting the data for individual
|
||||
* fields (TupleField structure) of a manual result set.
|
||||
* Description: This module contains functions for setting the data for individual
|
||||
* fields (TupleField structure) of a manual result set.
|
||||
*
|
||||
* Important Note: These functions are ONLY used in building manual result sets for
|
||||
* info functions (SQLTables, SQLColumns, etc.)
|
||||
* Important Note: These functions are ONLY used in building manual result sets for
|
||||
* info functions (SQLTables, SQLColumns, etc.)
|
||||
*
|
||||
* Classes: n/a
|
||||
* Classes: n/a
|
||||
*
|
||||
* API functions: none
|
||||
* API functions: none
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -19,39 +19,43 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void set_tuplefield_null(TupleField *tuple_field)
|
||||
void
|
||||
set_tuplefield_null(TupleField *tuple_field)
|
||||
{
|
||||
tuple_field->len = 0;
|
||||
tuple_field->value = NULL; /* strdup(""); */
|
||||
tuple_field->value = NULL; /* strdup(""); */
|
||||
}
|
||||
|
||||
void set_tuplefield_string(TupleField *tuple_field, char *string)
|
||||
void
|
||||
set_tuplefield_string(TupleField *tuple_field, char *string)
|
||||
{
|
||||
tuple_field->len = strlen(string);
|
||||
tuple_field->value = malloc(strlen(string)+1);
|
||||
tuple_field->value = malloc(strlen(string) + 1);
|
||||
strcpy(tuple_field->value, string);
|
||||
}
|
||||
|
||||
|
||||
void set_tuplefield_int2(TupleField *tuple_field, Int2 value)
|
||||
void
|
||||
set_tuplefield_int2(TupleField *tuple_field, Int2 value)
|
||||
{
|
||||
char buffer[10];
|
||||
char buffer[10];
|
||||
|
||||
|
||||
sprintf(buffer,"%d", value);
|
||||
sprintf(buffer, "%d", value);
|
||||
|
||||
tuple_field->len = strlen(buffer)+1;
|
||||
tuple_field->len = strlen(buffer) + 1;
|
||||
/* +1 ... is this correct (better be on the save side-...) */
|
||||
tuple_field->value = strdup(buffer);
|
||||
}
|
||||
|
||||
void set_tuplefield_int4(TupleField *tuple_field, Int4 value)
|
||||
void
|
||||
set_tuplefield_int4(TupleField *tuple_field, Int4 value)
|
||||
{
|
||||
char buffer[15];
|
||||
char buffer[15];
|
||||
|
||||
sprintf(buffer,"%ld", value);
|
||||
sprintf(buffer, "%ld", value);
|
||||
|
||||
tuple_field->len = strlen(buffer)+1;
|
||||
tuple_field->len = strlen(buffer) + 1;
|
||||
/* +1 ... is this correct (better be on the save side-...) */
|
||||
tuple_field->value = strdup(buffer);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
|
||||
/* File: tuple.h
|
||||
/* File: tuple.h
|
||||
*
|
||||
* Description: See "tuple.c"
|
||||
* Description: See "tuple.c"
|
||||
*
|
||||
* Important NOTE: The TupleField structure is used both to hold backend data and
|
||||
* manual result set data. The "set_" functions and the TupleNode
|
||||
* structure are only used for manual result sets by info routines.
|
||||
* Important NOTE: The TupleField structure is used both to hold backend data and
|
||||
* manual result set data. The "set_" functions and the TupleNode
|
||||
* structure are only used for manual result sets by info routines.
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -17,15 +17,18 @@
|
||||
#include "psqlodbc.h"
|
||||
|
||||
/* Used by backend data AND manual result sets */
|
||||
struct TupleField_ {
|
||||
Int4 len; /* length of the current Tuple */
|
||||
void *value; /* an array representing the value */
|
||||
struct TupleField_
|
||||
{
|
||||
Int4 len; /* length of the current Tuple */
|
||||
void *value; /* an array representing the value */
|
||||
};
|
||||
|
||||
/* Used ONLY for manual result sets */
|
||||
struct TupleNode_ {
|
||||
struct TupleNode_ *prev, *next;
|
||||
TupleField tuple[1];
|
||||
struct TupleNode_
|
||||
{
|
||||
struct TupleNode_ *prev,
|
||||
*next;
|
||||
TupleField tuple[1];
|
||||
};
|
||||
|
||||
/* These macros are wrappers for the corresponding set_tuplefield functions
|
||||
@@ -36,9 +39,9 @@ struct TupleNode_ {
|
||||
#define set_nullfield_int2(FLD, VAL) ((VAL) != -1 ? set_tuplefield_int2(FLD, (VAL)) : set_tuplefield_null(FLD))
|
||||
#define set_nullfield_int4(FLD, VAL) ((VAL) != -1 ? set_tuplefield_int4(FLD, (VAL)) : set_tuplefield_null(FLD))
|
||||
|
||||
void set_tuplefield_null(TupleField *tuple_field);
|
||||
void set_tuplefield_string(TupleField *tuple_field, char *string);
|
||||
void set_tuplefield_int2(TupleField *tuple_field, Int2 value);
|
||||
void set_tuplefield_int4(TupleField *tuple_field, Int4 value);
|
||||
void set_tuplefield_null(TupleField *tuple_field);
|
||||
void set_tuplefield_string(TupleField *tuple_field, char *string);
|
||||
void set_tuplefield_int2(TupleField *tuple_field, Int2 value);
|
||||
void set_tuplefield_int4(TupleField *tuple_field, Int4 value);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
|
||||
/* Module: tuplelist.c
|
||||
/* Module: tuplelist.c
|
||||
*
|
||||
* Description: This module contains functions for creating a manual result set
|
||||
* (the TupleList) and retrieving data from it for a specific row/column.
|
||||
* Description: This module contains functions for creating a manual result set
|
||||
* (the TupleList) and retrieving data from it for a specific row/column.
|
||||
*
|
||||
* Classes: TupleListClass (Functions prefix: "TL_")
|
||||
* Classes: TupleListClass (Functions prefix: "TL_")
|
||||
*
|
||||
* API functions: none
|
||||
* API functions: none
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -19,19 +19,20 @@
|
||||
TupleListClass *
|
||||
TL_Constructor(UInt4 fieldcnt)
|
||||
{
|
||||
TupleListClass *rv;
|
||||
TupleListClass *rv;
|
||||
|
||||
mylog("in TL_Constructor\n");
|
||||
|
||||
rv = (TupleListClass *) malloc(sizeof(TupleListClass));
|
||||
if (rv) {
|
||||
if (rv)
|
||||
{
|
||||
|
||||
rv->num_fields = fieldcnt;
|
||||
rv->num_tuples = 0;
|
||||
rv->list_start = NULL;
|
||||
rv->list_end = NULL;
|
||||
rv->lastref = NULL;
|
||||
rv->last_indexed = -1;
|
||||
rv->num_fields = fieldcnt;
|
||||
rv->num_tuples = 0;
|
||||
rv->list_start = NULL;
|
||||
rv->list_end = NULL;
|
||||
rv->lastref = NULL;
|
||||
rv->last_indexed = -1;
|
||||
}
|
||||
|
||||
mylog("exit TL_Constructor\n");
|
||||
@@ -42,35 +43,38 @@ TupleListClass *rv;
|
||||
void
|
||||
TL_Destructor(TupleListClass *self)
|
||||
{
|
||||
int lf;
|
||||
TupleNode *node, *tp;
|
||||
int lf;
|
||||
TupleNode *node,
|
||||
*tp;
|
||||
|
||||
mylog("TupleList: in DESTRUCTOR\n");
|
||||
|
||||
node = self->list_start;
|
||||
while(node != NULL) {
|
||||
for (lf=0; lf < self->num_fields; lf++)
|
||||
if (node->tuple[lf].value != NULL) {
|
||||
free(node->tuple[lf].value);
|
||||
}
|
||||
tp = node->next;
|
||||
free(node);
|
||||
node = tp;
|
||||
}
|
||||
node = self->list_start;
|
||||
while (node != NULL)
|
||||
{
|
||||
for (lf = 0; lf < self->num_fields; lf++)
|
||||
if (node->tuple[lf].value != NULL)
|
||||
free(node->tuple[lf].value);
|
||||
tp = node->next;
|
||||
free(node);
|
||||
node = tp;
|
||||
}
|
||||
|
||||
free(self);
|
||||
|
||||
mylog("TupleList: exit DESTRUCTOR\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno)
|
||||
{
|
||||
Int4 lf;
|
||||
Int4 delta, from_end;
|
||||
char end_is_closer, start_is_closer;
|
||||
TupleNode *rv;
|
||||
Int4 lf;
|
||||
Int4 delta,
|
||||
from_end;
|
||||
char end_is_closer,
|
||||
start_is_closer;
|
||||
TupleNode *rv;
|
||||
|
||||
if (self->last_indexed == -1)
|
||||
/* we have an empty tuple list */
|
||||
@@ -85,67 +89,88 @@ TupleNode *rv;
|
||||
/* illegel field number range */
|
||||
return NULL;
|
||||
|
||||
/* check if we are accessing the same tuple that was used in
|
||||
the last fetch (e.g: for fetching all the fields one after
|
||||
another. Do this to speed things up
|
||||
*/
|
||||
/*
|
||||
* check if we are accessing the same tuple that was used in the last
|
||||
* fetch (e.g: for fetching all the fields one after another. Do this
|
||||
* to speed things up
|
||||
*/
|
||||
if (tupleno == self->last_indexed)
|
||||
return self->lastref->tuple[fieldno].value;
|
||||
|
||||
/* now for the tricky part... */
|
||||
/* now for the tricky part... */
|
||||
|
||||
/*
|
||||
Since random access is quite inefficient for linked lists we use
|
||||
the lastref pointer that points to the last element referenced
|
||||
by a get_fieldval() call in conjunction with the its index number
|
||||
that is stored in last_indexed. (So we use some locality of
|
||||
reference principle to speed things up)
|
||||
*/
|
||||
/*
|
||||
* Since random access is quite inefficient for linked lists we use
|
||||
* the lastref pointer that points to the last element referenced by a
|
||||
* get_fieldval() call in conjunction with the its index number that
|
||||
* is stored in last_indexed. (So we use some locality of reference
|
||||
* principle to speed things up)
|
||||
*/
|
||||
|
||||
delta = tupleno - self->last_indexed;
|
||||
/* if delta is positive, we have to go forward */
|
||||
|
||||
/* now check if we are closer to the start or the end of the list
|
||||
than to our last_indexed pointer
|
||||
*/
|
||||
/*
|
||||
* now check if we are closer to the start or the end of the list than
|
||||
* to our last_indexed pointer
|
||||
*/
|
||||
from_end = (self->num_tuples - 1) - tupleno;
|
||||
|
||||
start_is_closer = labs(delta) > tupleno;
|
||||
/* true if we are closer to the start of the list than to the
|
||||
last_indexed pointer
|
||||
*/
|
||||
|
||||
/*
|
||||
* true if we are closer to the start of the list than to the
|
||||
* last_indexed pointer
|
||||
*/
|
||||
|
||||
end_is_closer = labs(delta) > from_end;
|
||||
/* true if we are closer at the end of the list */
|
||||
|
||||
if (end_is_closer) {
|
||||
if (end_is_closer)
|
||||
{
|
||||
/* scanning from the end is the shortest way. so we do that... */
|
||||
rv = self->list_end;
|
||||
for (lf=0; lf < from_end; lf++)
|
||||
for (lf = 0; lf < from_end; lf++)
|
||||
rv = rv->prev;
|
||||
} else if (start_is_closer) {
|
||||
/* the shortest way is to start the search from the head of the list */
|
||||
}
|
||||
else if (start_is_closer)
|
||||
{
|
||||
|
||||
/*
|
||||
* the shortest way is to start the search from the head of the
|
||||
* list
|
||||
*/
|
||||
rv = self->list_start;
|
||||
for (lf=0; lf < tupleno; lf++)
|
||||
for (lf = 0; lf < tupleno; lf++)
|
||||
rv = rv->next;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the closest way is starting from our lastref - pointer */
|
||||
rv = self->lastref;
|
||||
/* at first determine whether we have to search forward or backwards */
|
||||
if (delta < 0) {
|
||||
|
||||
/*
|
||||
* at first determine whether we have to search forward or
|
||||
* backwards
|
||||
*/
|
||||
if (delta < 0)
|
||||
{
|
||||
/* we have to search backwards */
|
||||
for(lf=0; lf < (-1)*delta; lf++)
|
||||
for (lf = 0; lf < (-1) * delta; lf++)
|
||||
rv = rv->prev;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ok, we have to search forward... */
|
||||
for (lf=0; lf < delta; lf++)
|
||||
rv = rv->next;
|
||||
for (lf = 0; lf < delta; lf++)
|
||||
rv = rv->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* now we have got our return pointer, so update the lastref
|
||||
and the last_indexed values
|
||||
*/
|
||||
/*
|
||||
* now we have got our return pointer, so update the lastref and the
|
||||
* last_indexed values
|
||||
*/
|
||||
self->lastref = rv;
|
||||
self->last_indexed = tupleno;
|
||||
|
||||
@@ -157,23 +182,30 @@ TupleNode *rv;
|
||||
char
|
||||
TL_add_tuple(TupleListClass *self, TupleNode *new_field)
|
||||
{
|
||||
/* we append the tuple at the end of the doubly linked list
|
||||
of the tuples we have already read in
|
||||
*/
|
||||
|
||||
/*
|
||||
* we append the tuple at the end of the doubly linked list of the
|
||||
* tuples we have already read in
|
||||
*/
|
||||
|
||||
new_field->prev = NULL;
|
||||
new_field->next = NULL;
|
||||
|
||||
if (self->list_start == NULL) {
|
||||
if (self->list_start == NULL)
|
||||
{
|
||||
/* the list is empty, we have to add the first tuple */
|
||||
self->list_start = new_field;
|
||||
self->list_end = new_field;
|
||||
self->lastref = new_field;
|
||||
self->last_indexed = 0;
|
||||
} else {
|
||||
/* there is already an element in the list, so add the new
|
||||
one at the end of the list
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/*
|
||||
* there is already an element in the list, so add the new one at
|
||||
* the end of the list
|
||||
*/
|
||||
self->list_end->next = new_field;
|
||||
new_field->prev = self->list_end;
|
||||
self->list_end = new_field;
|
||||
@@ -183,5 +215,3 @@ TL_add_tuple(TupleListClass *self, TupleNode *new_field)
|
||||
/* this method of building a list cannot fail, so we return 1 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
/* File: tuplelist.h
|
||||
/* File: tuplelist.h
|
||||
*
|
||||
* Description: See "tuplelist.c"
|
||||
* Description: See "tuplelist.c"
|
||||
*
|
||||
* Important Note: This structure and its functions are ONLY used in building manual result
|
||||
* sets for info functions (SQLTables, SQLColumns, etc.)
|
||||
* Important Note: This structure and its functions are ONLY used in building manual result
|
||||
* sets for info functions (SQLTables, SQLColumns, etc.)
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -15,19 +15,22 @@
|
||||
|
||||
#include "psqlodbc.h"
|
||||
|
||||
struct TupleListClass_ {
|
||||
Int4 num_fields;
|
||||
Int4 num_tuples;
|
||||
TupleNode *list_start, *list_end, *lastref;
|
||||
Int4 last_indexed;
|
||||
struct TupleListClass_
|
||||
{
|
||||
Int4 num_fields;
|
||||
Int4 num_tuples;
|
||||
TupleNode *list_start,
|
||||
*list_end,
|
||||
*lastref;
|
||||
Int4 last_indexed;
|
||||
};
|
||||
|
||||
#define TL_get_num_tuples(x) (x->num_tuples)
|
||||
|
||||
/* Create a TupleList. Each tuple consits of fieldcnt columns */
|
||||
TupleListClass *TL_Constructor(UInt4 fieldcnt);
|
||||
void TL_Destructor(TupleListClass *self);
|
||||
void *TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno);
|
||||
char TL_add_tuple(TupleListClass *self, TupleNode *new_field);
|
||||
void TL_Destructor(TupleListClass *self);
|
||||
void *TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno);
|
||||
char TL_add_tuple(TupleListClass *self, TupleNode *new_field);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
|
||||
/* Copyright (C) 1999, Kenneth Albanowski. This code may be used and
|
||||
distributed under the same license as any version of Perl. */
|
||||
|
||||
|
||||
/* For the latest version of this code, please retreive the Devel::PPPort
|
||||
module from CPAN, contact the author at <kjahds@kjahds.com>, or check
|
||||
with the Perl maintainers. */
|
||||
|
||||
|
||||
/* If you needed to customize this file for your project, please mention
|
||||
your changes, and visible alter the version number. */
|
||||
|
||||
@@ -29,29 +29,29 @@
|
||||
for a static include, or use the GLOBAL request in a single module to
|
||||
produce a global definition that can be referenced from the other
|
||||
modules.
|
||||
|
||||
Function: Static define: Extern define:
|
||||
newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL
|
||||
|
||||
Function: Static define: Extern define:
|
||||
newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* To verify whether ppport.h is needed for your module, and whether any
|
||||
special defines should be used, ppport.h can be run through Perl to check
|
||||
your source code. Simply say:
|
||||
|
||||
perl -x ppport.h *.c *.h *.xs foo/*.c [etc]
|
||||
|
||||
|
||||
perl -x ppport.h *.c *.h *.xs foo/*.c [etc]
|
||||
|
||||
The result will be a list of patches suggesting changes that should at
|
||||
least be acceptable, if not necessarily the most efficient solution, or a
|
||||
fix for all possible problems. It won't catch where dTHR is needed, and
|
||||
doesn't attempt to account for global macro or function definitions,
|
||||
nested includes, typemaps, etc.
|
||||
|
||||
|
||||
In order to test for the need of dTHR, please try your module under a
|
||||
recent version of Perl that has threading compiled-in.
|
||||
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
@@ -109,11 +109,11 @@ foreach $filename (map(glob($_),@ARGV)) {
|
||||
$need_include = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (scalar(keys %add_func) or $need_include != $has_include) {
|
||||
if (!$has_include) {
|
||||
$inc = join('',map("#define NEED_$_\n", sort keys %add_func)).
|
||||
"#include \"ppport.h\"\n";
|
||||
"#include \"ppport.h\"\n";
|
||||
$c = "$inc$c" unless $c =~ s/#.*include.*XSUB.*\n/$&$inc/m;
|
||||
} elsif (keys %add_func) {
|
||||
$inc = join('',map("#define NEED_$_\n", sort keys %add_func));
|
||||
@@ -125,7 +125,7 @@ foreach $filename (map(glob($_),@ARGV)) {
|
||||
}
|
||||
$changes++;
|
||||
}
|
||||
|
||||
|
||||
if ($changes) {
|
||||
open(OUT,">/tmp/ppport.h.$$");
|
||||
print OUT $c;
|
||||
@@ -142,87 +142,90 @@ __DATA__
|
||||
*/
|
||||
|
||||
#ifndef PERL_REVISION
|
||||
# ifndef __PATCHLEVEL_H_INCLUDED__
|
||||
# include "patchlevel.h"
|
||||
# endif
|
||||
# ifndef PERL_REVISION
|
||||
# define PERL_REVISION (5)
|
||||
/* Replace: 1 */
|
||||
# define PERL_VERSION PATCHLEVEL
|
||||
# define PERL_SUBVERSION SUBVERSION
|
||||
/* Replace PERL_PATCHLEVEL with PERL_VERSION */
|
||||
/* Replace: 0 */
|
||||
# endif
|
||||
#ifndef __PATCHLEVEL_H_INCLUDED__
|
||||
#include "patchlevel.h"
|
||||
#endif
|
||||
#ifndef PERL_REVISION
|
||||
#define PERL_REVISION (5)
|
||||
/* Replace: 1 */
|
||||
#define PERL_VERSION PATCHLEVEL
|
||||
#define PERL_SUBVERSION SUBVERSION
|
||||
/* Replace PERL_PATCHLEVEL with PERL_VERSION */
|
||||
/* Replace: 0 */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define PERL_BCDVERSION ((PERL_REVISION * 0x1000000L) + (PERL_VERSION * 0x1000L) + PERL_SUBVERSION)
|
||||
|
||||
#ifndef ERRSV
|
||||
# define ERRSV perl_get_sv("@",FALSE)
|
||||
#define ERRSV perl_get_sv("@",FALSE)
|
||||
#endif
|
||||
|
||||
#if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5))
|
||||
/* Replace: 1 */
|
||||
# define PL_sv_undef sv_undef
|
||||
# define PL_sv_yes sv_yes
|
||||
# define PL_sv_no sv_no
|
||||
# define PL_na na
|
||||
# define PL_stdingv stdingv
|
||||
# define PL_hints hints
|
||||
# define PL_curcop curcop
|
||||
# define PL_curstash curstash
|
||||
# define PL_copline copline
|
||||
# define PL_Sv Sv
|
||||
#define PL_sv_undef sv_undef
|
||||
#define PL_sv_yes sv_yes
|
||||
#define PL_sv_no sv_no
|
||||
#define PL_na na
|
||||
#define PL_stdingv stdingv
|
||||
#define PL_hints hints
|
||||
#define PL_curcop curcop
|
||||
#define PL_curstash curstash
|
||||
#define PL_copline copline
|
||||
#define PL_Sv Sv
|
||||
/* Replace: 0 */
|
||||
#endif
|
||||
|
||||
#ifndef dTHR
|
||||
# ifdef WIN32
|
||||
# define dTHR extern int Perl___notused
|
||||
# else
|
||||
# define dTHR extern int errno
|
||||
# endif
|
||||
#ifdef WIN32
|
||||
#define dTHR extern int Perl___notused
|
||||
#else
|
||||
#define dTHR extern int errno
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef boolSV
|
||||
# define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no)
|
||||
#define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no)
|
||||
#endif
|
||||
|
||||
#ifndef gv_stashpvn
|
||||
# define gv_stashpvn(str,len,flags) gv_stashpv(str,flags)
|
||||
#define gv_stashpvn(str,len,flags) gv_stashpv(str,flags)
|
||||
#endif
|
||||
|
||||
#ifndef newSVpvn
|
||||
# define newSVpvn(data,len) ((len) ? newSVpv ((data), (len)) : newSVpv ("", 0))
|
||||
#define newSVpvn(data,len) ((len) ? newSVpv ((data), (len)) : newSVpv ("", 0))
|
||||
#endif
|
||||
|
||||
#ifndef newRV_inc
|
||||
/* Replace: 1 */
|
||||
# define newRV_inc(sv) newRV(sv)
|
||||
#define newRV_inc(sv) newRV(sv)
|
||||
/* Replace: 0 */
|
||||
#endif
|
||||
|
||||
#ifndef newRV_noinc
|
||||
# ifdef __GNUC__
|
||||
# define newRV_noinc(sv) \
|
||||
({ \
|
||||
SV *nsv = (SV*)newRV(sv); \
|
||||
SvREFCNT_dec(sv); \
|
||||
nsv; \
|
||||
})
|
||||
# else
|
||||
# if defined(CRIPPLED_CC) || defined(USE_THREADS)
|
||||
static SV * newRV_noinc (SV * sv)
|
||||
#ifdef __GNUC__
|
||||
#define newRV_noinc(sv) \
|
||||
({ \
|
||||
SV *nsv = (SV*)newRV(sv); \
|
||||
SvREFCNT_dec(sv); \
|
||||
nsv; \
|
||||
})
|
||||
#else
|
||||
#if defined(CRIPPLED_CC) || defined(USE_THREADS)
|
||||
static SV *
|
||||
newRV_noinc(SV * sv)
|
||||
{
|
||||
SV *nsv = (SV*)newRV(sv);
|
||||
SvREFCNT_dec(sv);
|
||||
return nsv;
|
||||
SV *nsv = (SV *) newRV(sv);
|
||||
|
||||
SvREFCNT_dec(sv);
|
||||
return nsv;
|
||||
}
|
||||
# else
|
||||
# define newRV_noinc(sv) \
|
||||
((PL_Sv=(SV*)newRV(sv), SvREFCNT_dec(sv), (SV*)PL_Sv)
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#else
|
||||
#define newRV_noinc(sv) \
|
||||
((PL_Sv=(SV*)newRV(sv), SvREFCNT_dec(sv), (SV*)PL_Sv)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Provide: newCONSTSUB */
|
||||
@@ -233,20 +236,22 @@ static SV * newRV_noinc (SV * sv)
|
||||
#if defined(NEED_newCONSTSUB)
|
||||
static
|
||||
#else
|
||||
extern void newCONSTSUB _((HV * stash, char * name, SV *sv));
|
||||
extern void newCONSTSUB _((HV * stash, char *name, SV * sv));
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL)
|
||||
void
|
||||
newCONSTSUB(stash,name,sv)
|
||||
HV *stash;
|
||||
char *name;
|
||||
SV *sv;
|
||||
newCONSTSUB(stash, name, sv)
|
||||
HV *stash;
|
||||
char *name;
|
||||
SV *sv;
|
||||
{
|
||||
U32 oldhints = PL_hints;
|
||||
HV *old_cop_stash = PL_curcop->cop_stash;
|
||||
HV *old_curstash = PL_curstash;
|
||||
line_t oldline = PL_curcop->cop_line;
|
||||
U32 oldhints = PL_hints;
|
||||
HV *old_cop_stash = PL_curcop->cop_stash;
|
||||
HV *old_curstash = PL_curstash;
|
||||
line_t oldline = PL_curcop->cop_line;
|
||||
|
||||
PL_curcop->cop_line = PL_copline;
|
||||
|
||||
PL_hints &= ~HINT_BLOCK_SCOPE;
|
||||
@@ -256,31 +261,33 @@ SV *sv;
|
||||
newSUB(
|
||||
|
||||
#if (PERL_VERSION < 3) || ((PERL_VERSION == 3) && (PERL_SUBVERSION < 22))
|
||||
/* before 5.003_22 */
|
||||
start_subparse(),
|
||||
/* before 5.003_22 */
|
||||
start_subparse(),
|
||||
#else
|
||||
# if (PERL_VERSION == 3) && (PERL_SUBVERSION == 22)
|
||||
/* 5.003_22 */
|
||||
start_subparse(0),
|
||||
# else
|
||||
/* 5.003_23 onwards */
|
||||
start_subparse(FALSE, 0),
|
||||
# endif
|
||||
#if (PERL_VERSION == 3) && (PERL_SUBVERSION == 22)
|
||||
/* 5.003_22 */
|
||||
start_subparse(0),
|
||||
#else
|
||||
/* 5.003_23 onwards */
|
||||
start_subparse(FALSE, 0),
|
||||
#endif
|
||||
#endif
|
||||
|
||||
newSVOP(OP_CONST, 0, newSVpv(name,0)),
|
||||
newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */
|
||||
newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv))
|
||||
);
|
||||
newSVOP(OP_CONST, 0, newSVpv(name, 0)),
|
||||
newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == ""
|
||||
* -- GMB */
|
||||
newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv))
|
||||
);
|
||||
|
||||
PL_hints = oldhints;
|
||||
PL_curcop->cop_stash = old_cop_stash;
|
||||
PL_curstash = old_curstash;
|
||||
PL_curcop->cop_line = oldline;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* newCONSTSUB */
|
||||
#endif /* newCONSTSUB */
|
||||
|
||||
|
||||
#endif /* _P_P_PORTABILITY_H_ */
|
||||
#endif /* _P_P_PORTABILITY_H_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user