From 3273cb1bb3b8f56da9f7084de9c5cab0448fc08f Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Sun, 7 Nov 2010 00:34:02 +0000 Subject: [PATCH] 2010-11-07 01:33 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * contrib/hbodbc/odbc.c ! SQLERROR(): Fixed to accept handle as pointer (not as number). ! SQLERROR(): Fixed returned cErrorMsg using proper length. ! SQLERROR(): Fixed to initialize 'out' parameters. + Added SQLGETDIAGREC( , , , @, @, @ ) -> * contrib/hbodbc/sql.ch * Added self-guard * Enclosed negative constant values in parents. + Added SQL_HANDLE_* constants. * contrib/hbodbc/tests/odbcdemo.prg * contrib/hbodbc/tests/odbccall.prg * contrib/hbodbc/tests/testodbc.prg * Added "simpleio.ch" * Formatting. ! Changed locally rolled WITH OBJECT emulation with real WITH OBJECT syntax. + Added SQLERROR() and SQLGETDIAGREC() test calls. --- harbour/ChangeLog | 20 ++++++++++++ harbour/contrib/hbodbc/odbc.c | 34 +++++++++++++++++-- harbour/contrib/hbodbc/sql.ch | 32 +++++++++++------- harbour/contrib/hbodbc/tests/odbccall.prg | 35 +++++++++----------- harbour/contrib/hbodbc/tests/odbcdemo.prg | 40 ++++++++++++----------- harbour/contrib/hbodbc/tests/testodbc.prg | 24 +++++++++++--- 6 files changed, 130 insertions(+), 55 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 0f14b6ab0c..84eeafb16e 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,26 @@ The license applies to all entries newer than 2009-04-28. */ +2010-11-07 01:33 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) + * contrib/hbodbc/odbc.c + ! SQLERROR(): Fixed to accept handle as pointer (not as number). + ! SQLERROR(): Fixed returned cErrorMsg using proper length. + ! SQLERROR(): Fixed to initialize 'out' parameters. + + Added SQLGETDIAGREC( , , , @, @, @ ) -> + + * contrib/hbodbc/sql.ch + * Added self-guard + * Enclosed negative constant values in parents. + + Added SQL_HANDLE_* constants. + + * contrib/hbodbc/tests/odbcdemo.prg + * contrib/hbodbc/tests/odbccall.prg + * contrib/hbodbc/tests/testodbc.prg + * Added "simpleio.ch" + * Formatting. + ! Changed locally rolled WITH OBJECT emulation with real WITH OBJECT syntax. + + Added SQLERROR() and SQLGETDIAGREC() test calls. + 2010-11-06 23:25 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * INSTALL * Little clarification to '2. HOW TO DO A PARTIAL [RE]BUILD' diff --git a/harbour/contrib/hbodbc/odbc.c b/harbour/contrib/hbodbc/odbc.c index c3c2ea53fe..30ba2a02bb 100644 --- a/harbour/contrib/hbodbc/odbc.c +++ b/harbour/contrib/hbodbc/odbc.c @@ -397,9 +397,14 @@ HB_FUNC( SQLERROR ) /* hEnv, hDbc, hStmt, @cErrorClass, @nType, @cErrorMsg */ SQLSMALLINT wLen; SQLTCHAR buffer[ 256 ]; SQLTCHAR szErrorMsg[ SQL_MAX_MESSAGE_LENGTH + 1 ]; + + buffer[ 0 ] = '\0'; + szErrorMsg[ 0 ] = '\0'; + wLen = 0; + hb_retni( SQLError( ( SQLHENV ) hb_parptr( 1 ), ( SQLHDBC ) hb_parptr( 2 ), - ( SQLHSTMT ) ( HB_PTRUINT ) hb_parnint( 3 ), + ( SQLHSTMT ) ( HB_PTRUINT ) hb_parptr( 3 ), ( SQLTCHAR * ) buffer, ( SQLINTEGER * ) &lError, ( SQLTCHAR * ) szErrorMsg, @@ -408,7 +413,32 @@ HB_FUNC( SQLERROR ) /* hEnv, hDbc, hStmt, @cErrorClass, @nType, @cErrorMsg */ O_HB_STORSTR( ( O_HB_CHAR * ) buffer, 4 ); hb_stornl( ( long ) lError, 5 ); - O_HB_STORSTR( ( O_HB_CHAR * ) szErrorMsg, 6 ); + O_HB_STORSTRLEN( ( O_HB_CHAR * ) szErrorMsg, wLen, 6 ); +} + +HB_FUNC( SQLGETDIAGREC ) /* nHandleType, hHandle, nRecNumber, @cSQLState, @nError, @cErrorMsg */ +{ + SQLTCHAR szSQLState[ 5 + 1 ]; + SQLINTEGER lError; + SQLTCHAR szErrorMsg[ SQL_MAX_MESSAGE_LENGTH + 1 ]; + SQLSMALLINT wLen; + + szSQLState[ 0 ] = '\0'; + szErrorMsg[ 0 ] = '\0'; + wLen = 0; + + hb_retni( SQLGetDiagRec( ( SQLSMALLINT ) hb_parni( 1 ), + ( SQLHANDLE ) ( HB_PTRUINT ) hb_parptr( 2 ), + ( SQLSMALLINT) hb_parni( 3 ), + ( SQLTCHAR * ) szSQLState, + ( SQLINTEGER * ) &lError, + ( SQLTCHAR * ) szErrorMsg, + ( SQLSMALLINT ) sizeof( szErrorMsg ), + ( SQLSMALLINT * ) &wLen ) ); + + O_HB_STORSTR( ( O_HB_CHAR * ) szSQLState, 4 ); + hb_stornl( ( long ) lError, 5 ); + O_HB_STORSTRLEN( ( O_HB_CHAR * ) szErrorMsg, wLen, 6 ); } HB_FUNC( SQLROWCOUNT ) diff --git a/harbour/contrib/hbodbc/sql.ch b/harbour/contrib/hbodbc/sql.ch index 62558b423e..70d170cc0f 100644 --- a/harbour/contrib/hbodbc/sql.ch +++ b/harbour/contrib/hbodbc/sql.ch @@ -50,9 +50,12 @@ * */ +#ifndef HBODBC_CH_ +#define HBODBC_CH_ + /* RETCODEs */ -#define SQL_INVALID_HANDLE -2 -#define SQL_ERROR -1 +#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 @@ -71,13 +74,13 @@ #define SQL_TIME 10 #define SQL_TIMESTAMP 11 #define SQL_VARCHAR 12 -#define SQL_BIT -7 -#define SQL_LONGVARCHAR -1 -#define SQL_LONGVARBINARY -4 -#define SQL_BIGINT -5 -#define SQL_TINYINT -6 +#define SQL_BIT ( -7 ) +#define SQL_LONGVARCHAR ( -1 ) +#define SQL_LONGVARBINARY ( -4 ) +#define SQL_BIGINT ( -5 ) +#define SQL_TINYINT ( -6 ) -#define SQL_NVARCHAR -9 +#define SQL_NVARCHAR ( -9 ) #define SQL_TYPE_NULL 0 #define SQL_TYPE_MIN SQL_BIT @@ -92,9 +95,9 @@ nullablity of a column in a table. */ #define SQL_NULLABLE_UNKNOWN 2 /* 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 defines */ #define SQL_CLOSE 0 @@ -249,3 +252,10 @@ nullablity of a column in a table. */ #define SQL_MAX_LENGTH 3 #define SQL_ASYNC_ENABLE 4 #define SQL_BIND_TYPE 5 + +#define SQL_HANDLE_ENV 1 +#define SQL_HANDLE_DBC 2 +#define SQL_HANDLE_STMT 3 +#define SQL_HANDLE_DESC 4 + +#endif diff --git a/harbour/contrib/hbodbc/tests/odbccall.prg b/harbour/contrib/hbodbc/tests/odbccall.prg index 13ef8bb829..0e1aa8768d 100644 --- a/harbour/contrib/hbodbc/tests/odbccall.prg +++ b/harbour/contrib/hbodbc/tests/odbccall.prg @@ -2,36 +2,33 @@ * $Id$ */ -#xcommand WITH DO => Self := -#xcommand ENDWITH => Self := NIL +#include "simpleio.ch" PROCEDURE Main() LOCAL cConStr LOCAL dsFunctions - LOCAL Self - cConStr := "DBQ=" + hb_FNameMerge( hb_DirBase(), "test.mdb" ) + ";Driver={Microsoft Access Driver (*.mdb)}" dsFunctions := TODBC():New( cConStr ) - WITH dsFunctions DO + WITH OBJECT dsFunctions - ::SetSQL( "SELECT * FROM test" ) - ::Open() - ? ::FieldByName( "First" ):Value - ? ::Skip() - ? ::FieldByName( "First" ):Value - ? ::GoTo( 1 ) - ? ::FieldByName( "First" ):Value - ? ::Prior() - ? ::FieldByName( "First" ):Value - ? ::First() - ? ::FieldByName( "First" ):Value - ? ::Last() - ? ::FieldByName( "First" ):Value - ? ::Close() + :SetSQL( "SELECT * FROM test" ) + :Open() + ? :FieldByName( "First" ):Value + ? :Skip() + ? :FieldByName( "First" ):Value + ? :GoTo( 1 ) + ? :FieldByName( "First" ):Value + ? :Prior() + ? :FieldByName( "First" ):Value + ? :First() + ? :FieldByName( "First" ):Value + ? :Last() + ? :FieldByName( "First" ):Value + ? :Close() ENDWITH diff --git a/harbour/contrib/hbodbc/tests/odbcdemo.prg b/harbour/contrib/hbodbc/tests/odbcdemo.prg index 44d25acd5e..dadc62dfbf 100644 --- a/harbour/contrib/hbodbc/tests/odbcdemo.prg +++ b/harbour/contrib/hbodbc/tests/odbcdemo.prg @@ -2,6 +2,8 @@ * $Id$ */ +#include "simpleio.ch" + PROCEDURE Main() LOCAL aOrders @@ -20,17 +22,17 @@ PROCEDURE Main() DO WHILE .T. - @ 00, 00 SAY padc( "- TODBC Demonstration -", 80 ) COLOR "B/W" + @ 0, 0 SAY PadC( "- TODBC Demonstration -", 80 ) COLOR "B/W" dsFunctions:SetSQL( "SELECT * FROM test" ) dsFunctions:Open() - @ 03, 24 TO len( dsFunctions:Fields ) + 4, 55 + @ 3, 24 TO len( dsFunctions:Fields ) + 4, 55 aOrders := {} - FOR i := 1 TO len( dsFunctions:Fields ) + FOR i := 1 TO Len( dsFunctions:Fields ) - aadd( aOrders, dsFunctions:Fields[ i ] :FieldName ) + AAdd( aOrders, dsFunctions:Fields[ i ] :FieldName ) @ i + 3, 25 PROMPT padc( "ORDER BY " + aOrders[ i ], 30 ) NEXT @@ -47,28 +49,28 @@ PROCEDURE Main() dsFunctions:Open() FOR i := 11 TO 24 - @ i, 00 SAY REPL( " ", 80 ) + @ i, 0 SAY Replicate( " ", 80 ) NEXT - @ 10, 00 TO 10, 79 - @ 24, 00 TO 24, 79 - @ 12, 00 TO 12, 79 - @ 11, 00 SAY "" + @ 10, 0 TO 10, 79 + @ 24, 0 TO 24, 79 + @ 12, 0 TO 12, 79 + @ 11, 0 SAY "" - @ 11, 02 SAY "Statement:" COLOR "GR+/B" - @ 11, col() + 1 SAY dsFunctions:cSQL + @ 11, 2 SAY "Statement:" COLOR "GR+/B" + @ 11, Col() + 1 SAY dsFunctions:cSQL - @ 14, 05 SAY " " + PadR( dsFunctions:FieldByName( "First" ) :FieldName, 3 ) + " " + ; - PadR( dsFunctions:FieldByName( "Last" ) :FieldName, 15 ) + " " + ; - PadR( dsFunctions:FieldByName( "Street" ) :FieldName, 2 ) + " " + ; - PadR( dsFunctions:FieldByName( "City" ) :FieldName, 40 ) ; + @ 14, 5 SAY " " + PadR( dsFunctions:FieldByName( "First" ):FieldName, 3 ) + " " + ; + PadR( dsFunctions:FieldByName( "Last" ):FieldName, 15 ) + " " + ; + PadR( dsFunctions:FieldByName( "Street" ):FieldName, 2 ) + " " + ; + PadR( dsFunctions:FieldByName( "City" ):FieldName, 40 ) ; COLOR "B/W" DO WHILE !dsFunctions:Eof() - ? " " + PadR( dsFunctions:FieldByName( "First" ) :Value, 3 ), "³", ; - PadR( dsFunctions:FieldByName( "Last" ) :Value, 15 ), "³", ; - PadR( dsFunctions:FieldByName( "Street" ) :Value, 2 ), "³", ; - PadR( dsFunctions:FieldByName( "City" ) :Value, 40 ) + ? " " + PadR( dsFunctions:FieldByName( "First" ):Value, 3 ), "|", ; + PadR( dsFunctions:FieldByName( "Last" ):Value, 15 ), "|", ; + PadR( dsFunctions:FieldByName( "Street" ):Value, 2 ), "|", ; + PadR( dsFunctions:FieldByName( "City" ):Value, 40 ) dsFunctions:Skip() ENDDO diff --git a/harbour/contrib/hbodbc/tests/testodbc.prg b/harbour/contrib/hbodbc/tests/testodbc.prg index 31bbe16ee2..7620b324fa 100644 --- a/harbour/contrib/hbodbc/tests/testodbc.prg +++ b/harbour/contrib/hbodbc/tests/testodbc.prg @@ -2,6 +2,8 @@ * $Id$ */ +#include "simpleio.ch" + #include "sql.ch" #xcommand GET ROW INTO => ; @@ -17,6 +19,7 @@ PROCEDURE Main() LOCAL cConstrout := SPACE(1024) LOCAL nRows := 0 LOCAL cCode, cFunc, cState, cComm + LOCAL cError1, nError, cError2 ? "Version: " + hb_NumToHex( hb_odbcVer() ) @@ -33,9 +36,22 @@ PROCEDURE Main() ? "Allocating statement... " SQLAllocStmt( hDbc, @hStmt ) + ? SQLError( hEnv,,, @cError1, @nError, @cError2 ) + ? "SQLERROR", cError1, nError, cError2 + ? SQLGetDiagRec( SQL_HANDLE_ENV, hEnv, 1, @cError1, @nError, @cError2 ) + ? "SQLGETDIAGREC", cError1, nError, cError2 + + ? "SQL: SELECT FROM test" + SQLExecDirect( hStmt, "SELECT FROM test" ) + + ? SQLError( hStmt,,, @cError1, @nError, @cError2 ) + ? "SQLERROR", cError1, nError, cError2 + ? SQLGetDiagRec( SQL_HANDLE_STMT, hStmt, 1, @cError1, @nError, @cError2 ) + ? "SQLGETDIAGREC", cError1, nError, cError2 + ? - ? "SQL: SELECT * FROM TEST" - SQLExecDirect( hStmt, "select * from test" ) + ? "SQL: SELECT * FROM test" + SQLExecDirect( hStmt, "SELECT * FROM test" ) ? @@ -45,11 +61,11 @@ PROCEDURE Main() GET ROW 2 INTO cFunc GET ROW 3 INTO cState GET ROW 4 INTO cComm - ? cCode, padr( cFunc, 20 ), cState, cComm + ? cCode, PadR( cFunc, 20 ), cState, cComm ENDDO ? "------------------------------------------------------------------------------" - ? str( nRows, 4 ), " row(s) affected." + ? Str( nRows, 4 ), " row(s) affected." SQLFreeStmt( hStmt, SQL_DROP ) SQLDisConnect( hDbc )