2021-03-31 21:26 UTC+0200 Aleksander Czajczynski (hb fki.pl)
* contrib/hbpgsql/hbpgsql.hbx
* contrib/hbpgsql/postgres.c
* contrib/hbpgsql/postgres.ch
+ add most new wrappers from this repository of Petr Chornyj:
https://github.com/petr-ch/hbpgsql9
Version guards have been added and "params" functions reworked
to accept hashes instead of two arrays. Other minor corrections
to fit into the contrib env.
+ add PQsslAttribute()
* some existing functions were modified to make the parameter
check (and fail if wrong) even if the underlying API is not
available, instead of silently returning a default value.
; all of the above was build-tested only and some features
require at least postgresql 8, 9 or 9.1
+ add PQlibVersion() -> <nVersion> (returns 0 for pre-9.1 postresql
versions)
Ref: https://github.com/harbour/core/pull/127/ by @VerchenkoAG
+ PQEXECPARAMS(): add 4th parameter to set <resultFormat>
Refs:
https://www.postgresql.org/docs/9.1/static/libpq-exec.html
https://groups.google.com/d/msg/harbour-users/hXhuVzU9pHA/RrDGLIiUAwAJ
+ add PQresStatus( <nNum> ) -> <cString>
+ added wrapper function
PQresultErrorField( result, nFieldCode ) -> cString
based on:
https://groups.google.com/d/msg/harbour-users/XSvRpbzfcHc/ztSL32fYpl4J
+ added PG_DIAG_* constants
+ added pg_encoding_to_char() wrapper to convert numeric
encoding ID to string
! fixed to use hb_fopen() instead of fopen()
+ TPQserver():New(): all parameters are now optional
! TPQserver():New(): fixed to escape connect parameter values
+ TPQserver():New(): added 7th optional hash parameter to pass
custom
connection parameters (e.g. SSL)
https://www.postgresql.org/docs/devel/static/libpq-connect.html
* contrib/hbpgsql/tests/test.prg
+ use pg_encoding_to_char(), plus some more feedback regarding
encodings
* contrib/hbpgsql/tests/dbf2pg.prg
+ use VF IO
+ support more source field types
; synced with Viktor's 3.4 branch at https://github.com/vszakats/hb
2017-02-15 15:14 UTC Viktor Szakats (vszakats users.noreply.github.com)
2016-09-05 18:55 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
2016-09-05 10:43 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
2016-09-02 01:58 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
2016-06-20 22:50 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
2015-07-19 11:56 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
2015-04-06 18:39 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
2015-03-31 23:31 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
2014-11-29 02:47 UTC+0100 Viktor Szakats (vszakats users.noreply.github.com)
2014-07-08 13:21 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
2014-02-11 18:18 UTC+0100 Viktor Szakats (vszakats users.noreply.github.com)
; tons of cleanups in this library, many thanks
This commit is contained in:
committed by
Aleksander Czajczynski
parent
864c0e6315
commit
ff3a726edf
@@ -7,6 +7,69 @@
|
||||
Entries may not always be in chronological/commit order.
|
||||
See license at the end of file. */
|
||||
|
||||
2021-03-31 21:26 UTC+0200 Aleksander Czajczynski (hb fki.pl)
|
||||
* contrib/hbpgsql/hbpgsql.hbx
|
||||
* contrib/hbpgsql/postgres.c
|
||||
* contrib/hbpgsql/postgres.ch
|
||||
+ add most new wrappers from this repository of Petr Chornyj:
|
||||
https://github.com/petr-ch/hbpgsql9
|
||||
Version guards have been added and "params" functions reworked
|
||||
to accept hashes instead of two arrays. Other minor corrections
|
||||
to fit into the contrib env.
|
||||
+ add PQsslAttribute()
|
||||
* some existing functions were modified to make the parameter
|
||||
check (and fail if wrong) even if the underlying API is not
|
||||
available, instead of silently returning a default value.
|
||||
; all of the above was build-tested only and some features
|
||||
require at least postgresql 8, 9 or 9.1
|
||||
|
||||
+ add PQlibVersion() -> <nVersion> (returns 0 for pre-9.1 postresql versions)
|
||||
Ref: https://github.com/harbour/core/pull/127/ by @VerchenkoAG
|
||||
|
||||
+ PQEXECPARAMS(): add 4th parameter to set <resultFormat>
|
||||
Refs:
|
||||
https://www.postgresql.org/docs/9.1/static/libpq-exec.html
|
||||
https://groups.google.com/d/msg/harbour-users/hXhuVzU9pHA/RrDGLIiUAwAJ
|
||||
|
||||
+ add PQresStatus( <nNum> ) -> <cString>
|
||||
|
||||
+ added wrapper function
|
||||
PQresultErrorField( result, nFieldCode ) -> cString
|
||||
based on: https://groups.google.com/d/msg/harbour-users/XSvRpbzfcHc/ztSL32fYpl4J
|
||||
+ added PG_DIAG_* constants
|
||||
|
||||
+ added pg_encoding_to_char() wrapper to convert numeric
|
||||
encoding ID to string
|
||||
|
||||
! fixed to use hb_fopen() instead of fopen()
|
||||
|
||||
+ TPQserver():New(): all parameters are now optional
|
||||
! TPQserver():New(): fixed to escape connect parameter values
|
||||
+ TPQserver():New(): added 7th optional hash parameter to pass custom
|
||||
connection parameters (e.g. SSL)
|
||||
https://www.postgresql.org/docs/devel/static/libpq-connect.html
|
||||
|
||||
* contrib/hbpgsql/tests/test.prg
|
||||
+ use pg_encoding_to_char(), plus some more feedback regarding encodings
|
||||
|
||||
* contrib/hbpgsql/tests/dbf2pg.prg
|
||||
+ use VF IO
|
||||
+ support more source field types
|
||||
|
||||
; synced with Viktor's 3.4 branch at https://github.com/vszakats/hb
|
||||
2017-02-15 15:14 UTC Viktor Szakats (vszakats users.noreply.github.com)
|
||||
2016-09-05 18:55 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
|
||||
2016-09-05 10:43 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
|
||||
2016-09-02 01:58 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
|
||||
2016-06-20 22:50 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
|
||||
2015-07-19 11:56 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
|
||||
2015-04-06 18:39 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
|
||||
2015-03-31 23:31 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
|
||||
2014-11-29 02:47 UTC+0100 Viktor Szakats (vszakats users.noreply.github.com)
|
||||
2014-07-08 13:21 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
|
||||
2014-02-11 18:18 UTC+0100 Viktor Szakats (vszakats users.noreply.github.com)
|
||||
; tons of cleanups in this library, many thanks
|
||||
|
||||
2021-03-31 20:38 UTC+0200 Aleksander Czajczynski (hb fki.pl)
|
||||
* contrib/hbpgsql/hbpgsql.h
|
||||
* contrib/hbpgsql/postgres.c
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PostgreSQL RDBMS wrapper header.
|
||||
*
|
||||
* Copyright 2010 Viktor Szakats (vszakats.net/harbour) (GC support)
|
||||
* Copyright 2010 Viktor Szakats (vsz.me/hb) (GC support)
|
||||
* Copyright 2003 Rodrigo Moreno rodrigo_moreno@yahoo.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -84,9 +84,10 @@
|
||||
|
||||
HB_EXTERN_BEGIN
|
||||
|
||||
extern HB_EXPORT void hb_PGconn_ret( PGconn * p );
|
||||
extern HB_EXPORT PGconn * hb_PGconn_par( int iParam );
|
||||
extern HB_EXPORT void hb_PGresult_ret( PGresult * p );
|
||||
extern HB_EXPORT void hb_PGconn_ret( PGconn * p );
|
||||
extern HB_EXPORT PGconn * hb_PGconn_par( int iParam );
|
||||
|
||||
extern HB_EXPORT void hb_PGresult_ret( PGresult * p );
|
||||
extern HB_EXPORT PGresult * hb_PGresult_par( int iParam );
|
||||
|
||||
HB_EXTERN_END
|
||||
|
||||
@@ -25,12 +25,20 @@ DYNAMIC hb_PQCopyFromWA
|
||||
DYNAMIC lo_export
|
||||
DYNAMIC lo_import
|
||||
DYNAMIC lo_unlink
|
||||
DYNAMIC pg_encoding_to_char
|
||||
DYNAMIC PQbackendPID
|
||||
DYNAMIC PQbinaryTuples
|
||||
DYNAMIC PQcancel
|
||||
DYNAMIC PQclientEncoding
|
||||
DYNAMIC PQcmdStatus
|
||||
DYNAMIC PQcmdTuples
|
||||
DYNAMIC PQconnectdb
|
||||
DYNAMIC PQconnectdbparams
|
||||
DYNAMIC PQconnectionNeedsPassword
|
||||
DYNAMIC PQconnectionUsedPassword
|
||||
DYNAMIC PQconnectPoll
|
||||
DYNAMIC PQconnectStart
|
||||
DYNAMIC PQconnectStartParams
|
||||
DYNAMIC PQconsumeInput
|
||||
DYNAMIC PQdb
|
||||
DYNAMIC PQerrorMessage
|
||||
@@ -56,14 +64,19 @@ DYNAMIC PQgetvalue
|
||||
DYNAMIC PQhost
|
||||
DYNAMIC PQisBusy
|
||||
DYNAMIC PQisnonblocking
|
||||
DYNAMIC PQisthreadsafe
|
||||
DYNAMIC PQlastrec
|
||||
DYNAMIC PQlibVersion
|
||||
DYNAMIC PQmetadata
|
||||
DYNAMIC PQnfields
|
||||
DYNAMIC PQntuples
|
||||
DYNAMIC PQoidStatus
|
||||
DYNAMIC PQoidValue
|
||||
DYNAMIC PQoptions
|
||||
DYNAMIC PQparameterStatus
|
||||
DYNAMIC PQpass
|
||||
DYNAMIC PQping
|
||||
DYNAMIC PQpingParams
|
||||
DYNAMIC PQport
|
||||
DYNAMIC PQprepare
|
||||
DYNAMIC PQprotocolVersion
|
||||
@@ -71,7 +84,11 @@ DYNAMIC PQputCopyData
|
||||
DYNAMIC PQputCopyEnd
|
||||
DYNAMIC PQrequestCancel
|
||||
DYNAMIC PQreset
|
||||
DYNAMIC PQresetPoll
|
||||
DYNAMIC PQresetStart
|
||||
DYNAMIC PQresStatus
|
||||
DYNAMIC PQresult2array
|
||||
DYNAMIC PQresultErrorField
|
||||
DYNAMIC PQresultErrorMessage
|
||||
DYNAMIC PQresultStatus
|
||||
DYNAMIC PQsendQuery
|
||||
@@ -80,6 +97,9 @@ DYNAMIC PQsetClientEncoding
|
||||
DYNAMIC PQsetdbLogin
|
||||
DYNAMIC PQsetErrorVerbosity
|
||||
DYNAMIC PQsetnonblocking
|
||||
DYNAMIC PQsocket
|
||||
DYNAMIC PQsslAttribute
|
||||
DYNAMIC PQsslInUse
|
||||
DYNAMIC PQstatus
|
||||
DYNAMIC PQtrace
|
||||
DYNAMIC PQtracecreate
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* PostgreSQL RDBMS low-level (client API) interface code.
|
||||
*
|
||||
* Copyright 2016 P.Chornyj <myorg63@mail.ru>
|
||||
* Copyright 2010-2016 Viktor Szakats (vszakats.net/harbour) (GC support, etc)
|
||||
* Copyright 2010-2016 Viktor Szakats (vsz.me/hb) (GC support, etc)
|
||||
* Copyright 2003 Rodrigo Moreno rodrigo_moreno@yahoo.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -227,9 +227,51 @@ static FILE * hb_FILE_par( int iParam )
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Connection handling functions
|
||||
*/
|
||||
/* Get the version of the libpq library in use */
|
||||
|
||||
HB_FUNC( PQLIBVERSION )
|
||||
{
|
||||
#if PG_VERSION_NUM >= 90100
|
||||
hb_retni( PQlibVersion() );
|
||||
#else
|
||||
hb_retni( 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Connection handling functions */
|
||||
|
||||
/* 31.1. Database Connection Control Functions
|
||||
The following functions deal with making a connection to a PostgreSQL backend server. */
|
||||
|
||||
HB_FUNC( PQCONNECTDBPARAMS )
|
||||
{
|
||||
PHB_ITEM pParam = hb_param( 1, HB_IT_HASH );
|
||||
int len;
|
||||
|
||||
if( pParam && ( len = ( int ) hb_hashLen( pParam ) ) > 0 )
|
||||
{
|
||||
#if PG_VERSION_NUM >= 90000
|
||||
const char ** paramKeyValues = ( const char ** ) hb_xgrab( sizeof( char * ) * len );
|
||||
const char ** paramValValues = ( const char ** ) hb_xgrab( sizeof( char * ) * len );
|
||||
int pos;
|
||||
|
||||
for( pos = 0; pos < len; ++pos )
|
||||
{
|
||||
paramKeyValues[ pos ] = hb_itemGetCPtr( hb_hashGetKeyAt( pParam, pos + 1 ) );
|
||||
paramValValues[ pos ] = hb_itemGetCPtr( hb_hashGetValueAt( pParam, pos + 1 ) );
|
||||
}
|
||||
|
||||
hb_PGconn_ret( PQconnectdbParams( paramKeyValues, paramValValues, hb_parl( 2 ) ) );
|
||||
|
||||
hb_xfree( ( void * ) paramKeyValues );
|
||||
hb_xfree( ( void * ) paramValValues );
|
||||
#else
|
||||
hb_retptr( NULL );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQCONNECTDB )
|
||||
{
|
||||
@@ -251,6 +293,54 @@ HB_FUNC( PQSETDBLOGIN )
|
||||
hb_parcx( 7 ) /* pwd */ ) );
|
||||
}
|
||||
|
||||
HB_FUNC( PQCONNECTSTARTPARAMS )
|
||||
{
|
||||
PHB_ITEM pParam = hb_param( 1, HB_IT_HASH );
|
||||
int len;
|
||||
|
||||
if( pParam && ( len = ( int ) hb_hashLen( pParam ) ) > 0 )
|
||||
{
|
||||
#if PG_VERSION_NUM >= 90000
|
||||
const char ** paramKeyValues = ( const char ** ) hb_xgrab( sizeof( char * ) * len );
|
||||
const char ** paramValValues = ( const char ** ) hb_xgrab( sizeof( char * ) * len );
|
||||
int pos;
|
||||
|
||||
for( pos = 0; pos < len; ++pos )
|
||||
{
|
||||
paramKeyValues[ pos ] = hb_itemGetCPtr( hb_hashGetKeyAt( pParam, pos + 1 ) );
|
||||
paramValValues[ pos ] = hb_itemGetCPtr( hb_hashGetValueAt( pParam, pos + 1 ) );
|
||||
}
|
||||
|
||||
hb_PGconn_ret( PQconnectStartParams( paramKeyValues, paramValValues, hb_parl( 2 ) ) );
|
||||
|
||||
hb_xfree( ( void * ) paramKeyValues );
|
||||
hb_xfree( ( void * ) paramValValues );
|
||||
#else
|
||||
hb_retptr( NULL );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQCONNECTSTART )
|
||||
{
|
||||
if( HB_ISCHAR( 1 ) )
|
||||
hb_PGconn_ret( PQconnectStart( hb_parc( 1 ) ) );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQCONNECTPOLL )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
hb_retni( PQconnectPoll( conn ) );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQRESET )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
@@ -261,16 +351,71 @@ HB_FUNC( PQRESET )
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQPROTOCOLVERSION )
|
||||
HB_FUNC( PQRESETSTART )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
hb_retni( PQprotocolVersion( conn ) );
|
||||
PQresetStart( conn );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQRESETPOLL )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
hb_retni( PQresetPoll( conn ) );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQPINGPARAMS )
|
||||
{
|
||||
PHB_ITEM pParam = hb_param( 1, HB_IT_HASH );
|
||||
int len;
|
||||
|
||||
if( pParam && ( len = ( int ) hb_hashLen( pParam ) ) > 0 )
|
||||
{
|
||||
#if PG_VERSION_NUM >= 90100
|
||||
const char ** paramKeyValues = ( const char ** ) hb_xgrab( sizeof( char * ) * len );
|
||||
const char ** paramValValues = ( const char ** ) hb_xgrab( sizeof( char * ) * len );
|
||||
int pos;
|
||||
|
||||
for( pos = 0; pos < len; ++pos )
|
||||
{
|
||||
paramKeyValues[ pos ] = hb_itemGetCPtr( hb_hashGetKeyAt( pParam, pos + 1 ) );
|
||||
paramValValues[ pos ] = hb_itemGetCPtr( hb_hashGetValueAt( pParam, pos + 1 ) );
|
||||
}
|
||||
|
||||
hb_retni( PQpingParams( paramKeyValues, paramValValues, hb_parl( 3 ) ) );
|
||||
|
||||
hb_xfree( ( void * ) paramKeyValues );
|
||||
hb_xfree( ( void * ) paramValValues );
|
||||
#else
|
||||
hb_retptr( NULL );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQPING )
|
||||
{
|
||||
if( HB_ISCHAR( 1 ) )
|
||||
#if PG_VERSION_NUM >= 90100
|
||||
hb_retni( PQping( hb_parc( 1 ) ) );
|
||||
#else
|
||||
hb_ret();
|
||||
#endif
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
/* 31.2. Connection Status Functions.
|
||||
These functions can be used to interrogate the status of an existing database connection object. */
|
||||
|
||||
HB_FUNC( PQCLIENTENCODING )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
@@ -361,6 +506,38 @@ HB_FUNC( PQOPTIONS )
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQRESULTERRORFIELD )
|
||||
{
|
||||
PGresult * res = hb_PGresult_par( 1 );
|
||||
|
||||
if( res )
|
||||
#if PG_VERSION_NUM >= 70400
|
||||
hb_retc( PQresultErrorField( res, hb_parni( 2 ) ) );
|
||||
#else
|
||||
hb_retc_null();
|
||||
#endif
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQRESSTATUS )
|
||||
{
|
||||
hb_retc( PQresStatus( ( ExecStatusType ) hb_parnl( 1 ) ) );
|
||||
}
|
||||
|
||||
/* 31.2. Connection Status Functions.
|
||||
These functions can be used to interrogate the status of an existing database connection object. */
|
||||
|
||||
HB_FUNC( PQSTATUS )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
hb_retni( PQstatus( conn ) );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQTRANSACTIONSTATUS )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
@@ -371,6 +548,40 @@ HB_FUNC( PQTRANSACTIONSTATUS )
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQPARAMETERSTATUS )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
hb_retc( PQparameterStatus( conn, hb_parcx( 2 ) ) );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQPROTOCOLVERSION )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
hb_retni( PQprotocolVersion( conn ) );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQSERVERVERSION )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
#if PG_VERSION_NUM >= 80000
|
||||
hb_retni( PQserverVersion( conn ) );
|
||||
#else
|
||||
hb_retni( 0 );
|
||||
#endif
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQERRORMESSAGE )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
@@ -381,19 +592,83 @@ HB_FUNC( PQERRORMESSAGE )
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQSTATUS )
|
||||
HB_FUNC( PQSOCKET )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
hb_retni( PQstatus( conn ) );
|
||||
hb_retni( PQsocket( conn ) );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
/*
|
||||
* Query handling functions
|
||||
*/
|
||||
HB_FUNC( PQBACKENDPID )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
hb_retni( PQbackendPID( conn ) );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQCONNECTIONNEEDSPASSWORD )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
#if PG_VERSION_NUM >= 80300
|
||||
hb_retl( PQconnectionNeedsPassword( conn ) ? HB_TRUE : HB_FALSE );
|
||||
#else
|
||||
hb_ret();
|
||||
#endif
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQCONNECTIONUSEDPASSWORD )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
#if PG_VERSION_NUM >= 80300
|
||||
hb_retl( PQconnectionUsedPassword( conn ) ? HB_TRUE : HB_FALSE );
|
||||
#else
|
||||
hb_ret();
|
||||
#endif
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQSSLINUSE )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
#if PG_VERSION_NUM >= 90500
|
||||
hb_retl( PQsslInUse( conn ) ? HB_TRUE : HB_FALSE );
|
||||
#else
|
||||
hb_ret();
|
||||
#endif
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQSSLATTRIBUTE )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
#if PG_VERSION_NUM >= 90500
|
||||
hb_retc( PQsslAttribute( conn, hb_parcx( 2 ) ) );
|
||||
#else
|
||||
hb_retc_null();
|
||||
#endif
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
/* Query handling functions */
|
||||
|
||||
HB_FUNC( PQEXEC )
|
||||
{
|
||||
@@ -420,7 +695,7 @@ HB_FUNC( PQEXECPARAMS )
|
||||
for( i = 0; i < n; ++i )
|
||||
paramvalues[ i ] = hb_arrayGetCPtr( aParam, i + 1 );
|
||||
|
||||
hb_PGresult_ret( PQexecParams( conn, hb_parcx( 2 ), n, NULL, paramvalues, NULL, NULL, 1 ) );
|
||||
hb_PGresult_ret( PQexecParams( conn, hb_parcx( 2 ), n, NULL, paramvalues, NULL, NULL, hb_parnidef( 4, 1 ) ) );
|
||||
|
||||
hb_xfree( ( void * ) paramvalues );
|
||||
}
|
||||
@@ -725,7 +1000,7 @@ HB_FUNC( PQESCAPESTRING )
|
||||
hb_retc_buffer( dest );
|
||||
}
|
||||
|
||||
HB_FUNC( PQESCAPEBYTEA ) /* deprecated */
|
||||
HB_FUNC( PQESCAPEBYTEA ) /* deprecated */
|
||||
{
|
||||
if( HB_ISCHAR( 1 ) )
|
||||
{
|
||||
@@ -777,7 +1052,7 @@ HB_FUNC( PQBINARYTUPLES )
|
||||
PGresult * res = hb_PGresult_par( 1 );
|
||||
|
||||
if( res )
|
||||
hb_retl( PQbinaryTuples( res ) );
|
||||
hb_retl( PQbinaryTuples( res ) ? HB_TRUE : HB_FALSE );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
@@ -837,7 +1112,7 @@ HB_FUNC( PQGETISNULL )
|
||||
PGresult * res = hb_PGresult_par( 1 );
|
||||
|
||||
if( res )
|
||||
hb_retl( PQgetisnull( res, hb_parni( 2 ) - 1, hb_parni( 3 ) - 1 ) );
|
||||
hb_retl( PQgetisnull( res, hb_parni( 2 ) - 1, hb_parni( 3 ) - 1 ) ? HB_TRUE : HB_FALSE );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
@@ -872,9 +1147,7 @@ HB_FUNC( PQNFIELDS )
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
/*
|
||||
* Asynchronous functions
|
||||
*/
|
||||
/* Asynchronous functions */
|
||||
|
||||
HB_FUNC( PQSENDQUERY )
|
||||
{
|
||||
@@ -901,7 +1174,7 @@ HB_FUNC( PQCONSUMEINPUT )
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
hb_retl( PQconsumeInput( conn ) );
|
||||
hb_retl( PQconsumeInput( conn ) ? HB_TRUE : HB_FALSE );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
@@ -936,12 +1209,14 @@ HB_FUNC( PQFLUSH )
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
/* Set blocking/nonblocking connection to the backend */
|
||||
|
||||
HB_FUNC( PQSETNONBLOCKING )
|
||||
{
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
hb_retl( PQsetnonblocking( conn, hb_parl( 2 ) ) );
|
||||
hb_retl( PQsetnonblocking( conn, hb_parl( 2 ) ) ? HB_TRUE : HB_FALSE );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
@@ -951,19 +1226,17 @@ HB_FUNC( PQISNONBLOCKING )
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
hb_retl( PQisnonblocking( conn ) );
|
||||
hb_retl( PQisnonblocking( conn ) ? HB_TRUE : HB_FALSE );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
/*
|
||||
* Trace Connection handling functions
|
||||
*/
|
||||
/* Trace Connection handling functions */
|
||||
|
||||
HB_FUNC( PQTRACECREATE ) /* not a direct wrapper */
|
||||
{
|
||||
#ifdef NODLL
|
||||
hb_FILE_ret( fopen( hb_parcx( 1 ), "w+b" ) );
|
||||
hb_FILE_ret( hb_fopen( hb_parcx( 1 ), "w+b" ) );
|
||||
#else
|
||||
hb_retptr( NULL );
|
||||
#endif
|
||||
@@ -1006,9 +1279,7 @@ HB_FUNC( PQSETERRORVERBOSITY )
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
/*
|
||||
* Large Object functions
|
||||
*/
|
||||
/* Large Object functions */
|
||||
|
||||
HB_FUNC( LO_IMPORT )
|
||||
{
|
||||
@@ -1040,20 +1311,6 @@ HB_FUNC( LO_UNLINK )
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
}
|
||||
|
||||
HB_FUNC( PQSERVERVERSION )
|
||||
{
|
||||
#if PG_VERSION_NUM >= 80000
|
||||
PGconn * conn = hb_PGconn_par( 1 );
|
||||
|
||||
if( conn )
|
||||
hb_retni( PQserverVersion( conn ) );
|
||||
else
|
||||
hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
||||
#else
|
||||
hb_retni( 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
HB_FUNC( PQGETCANCEL )
|
||||
{
|
||||
#if PG_VERSION_NUM >= 80000
|
||||
@@ -1079,7 +1336,7 @@ HB_FUNC( PQCANCEL )
|
||||
|
||||
errbuf[ 0 ] = '\0';
|
||||
|
||||
hb_retl( PQcancel( cancel, errbuf, sizeof( errbuf ) - 1 ) == 1 );
|
||||
hb_retl( PQcancel( cancel, errbuf, sizeof( errbuf ) - 1 ) ? HB_TRUE : HB_FALSE );
|
||||
|
||||
hb_storc( errbuf, 2 );
|
||||
}
|
||||
@@ -1173,6 +1430,22 @@ HB_FUNC( PQPUTCOPYEND )
|
||||
#endif
|
||||
}
|
||||
|
||||
HB_FUNC( PG_ENCODING_TO_CHAR )
|
||||
{
|
||||
hb_retc( pg_encoding_to_char( hb_parni( 1 ) ) );
|
||||
}
|
||||
|
||||
/* 31.19 Behavior in Threaded Programs */
|
||||
|
||||
HB_FUNC( PQISTHREADSAFE )
|
||||
{
|
||||
#if PG_VERSION_NUM >= 80200
|
||||
hb_retl( PQisthreadsafe() ? HB_TRUE : HB_FALSE );
|
||||
#else
|
||||
hb_retl( HB_FALSE );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
TODO: Implement Full Large Objects Support
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* PostgreSQL RDBMS low-level (client API) interface code.
|
||||
*
|
||||
* Copyright 2016 P.Chornyj <myorg63@mail.ru>
|
||||
* Copyright 2014 Viktor Szakats (vszakats.net/harbour)
|
||||
* Copyright 2014 Viktor Szakats (vsz.me/hb)
|
||||
* Copyright 2003 Rodrigo Moreno rodrigo_moreno@yahoo.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -60,6 +60,13 @@
|
||||
#define CONNECTION_SSL_STARTUP 7
|
||||
#define CONNECTION_NEEDED 8
|
||||
|
||||
/* PQconnectPoll(), PQresetPoll() */
|
||||
#define PGRES_POLLING_FAILED 0
|
||||
#define PGRES_POLLING_READING 1
|
||||
#define PGRES_POLLING_WRITING 2
|
||||
#define PGRES_POLLING_OK 3
|
||||
#define PGRES_POLLING_ACTIVE 4
|
||||
|
||||
/* PQresultStatus() */
|
||||
#define PGRES_EMPTY_QUERY 0
|
||||
#define PGRES_COMMAND_OK 1
|
||||
@@ -86,4 +93,34 @@
|
||||
#define HBPG_META_TABLECOL 6
|
||||
#define HBPG_META_LEN_ 6
|
||||
|
||||
/* PQsetErrorVerbosity() */
|
||||
#define PQERRORS_TERSE 0
|
||||
#define PQERRORS_DEFAULT 1
|
||||
#define PQERRORS_VERBOSE 2
|
||||
|
||||
/* PQping() */
|
||||
#define PQPING_OK 0 /* server is accepting connections */
|
||||
#define PQPING_REJECT 1 /* server is alive but rejecting connections */
|
||||
#define PQPING_NO_RESPONSE 2 /* could not establish connection */
|
||||
#define PQPING_NO_ATTEMPT 3 /* connection not attempted (bad params) */
|
||||
|
||||
/* PQresultErrorField() fieldcode parameters */
|
||||
#define PG_DIAG_SEVERITY hb_BCode( "S" )
|
||||
#define PG_DIAG_SQLSTATE hb_BCode( "C" )
|
||||
#define PG_DIAG_MESSAGE_PRIMARY hb_BCode( "M" )
|
||||
#define PG_DIAG_MESSAGE_DETAIL hb_BCode( "D" )
|
||||
#define PG_DIAG_MESSAGE_HINT hb_BCode( "H" )
|
||||
#define PG_DIAG_STATEMENT_POSITION hb_BCode( "P" )
|
||||
#define PG_DIAG_INTERNAL_POSITION hb_BCode( "p" )
|
||||
#define PG_DIAG_INTERNAL_QUERY hb_BCode( "q" )
|
||||
#define PG_DIAG_CONTEXT hb_BCode( "W" )
|
||||
#define PG_DIAG_SCHEMA_NAME hb_BCode( "s" )
|
||||
#define PG_DIAG_TABLE_NAME hb_BCode( "t" )
|
||||
#define PG_DIAG_COLUMN_NAME hb_BCode( "c" )
|
||||
#define PG_DIAG_DATATYPE_NAME hb_BCode( "d" )
|
||||
#define PG_DIAG_CONSTRAINT_NAME hb_BCode( "n" )
|
||||
#define PG_DIAG_SOURCE_FILE hb_BCode( "F" )
|
||||
#define PG_DIAG_SOURCE_LINE hb_BCode( "L" )
|
||||
#define PG_DIAG_SOURCE_FUNCTION hb_BCode( "R" )
|
||||
|
||||
#endif
|
||||
|
||||
@@ -274,8 +274,8 @@ HB_FUNC( HB_PQCOPYFROMWA )
|
||||
static const char * sc_szDelim = ",";
|
||||
|
||||
const char * szTable = hb_parcx( 2 );
|
||||
PHB_ITEM pWhile = hb_param( 3, HB_IT_BLOCK );
|
||||
PHB_ITEM pFor = hb_param( 4, HB_IT_BLOCK );
|
||||
PHB_ITEM pWhile = hb_param( 3, HB_IT_EVALITEM );
|
||||
PHB_ITEM pFor = hb_param( 4, HB_IT_EVALITEM );
|
||||
PHB_ITEM pFields = hb_param( 5, HB_IT_ARRAY );
|
||||
HB_ULONG nCount = hb_parnldef( 6, 0 );
|
||||
HB_BOOL str_rtrim = hb_parldef( 7, HB_TRUE );
|
||||
@@ -296,8 +296,7 @@ HB_FUNC( HB_PQCOPYFROMWA )
|
||||
|
||||
pItem = hb_itemNew( NULL );
|
||||
|
||||
context = ( pgCopyContext * ) hb_xgrab( sizeof( pgCopyContext ) );
|
||||
memset( context, 0, sizeof( pgCopyContext ) );
|
||||
context = ( pgCopyContext * ) hb_xgrabz( sizeof( pgCopyContext ) );
|
||||
|
||||
context->buffer = ( char * ) hb_xgrab( sizeof( char ) * nBufLen * 1400 );
|
||||
context->position = 0;
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
/*
|
||||
* This sample show howto use asynchronous/nonblocking queries
|
||||
*/
|
||||
/* This sample show howto use asynchronous/non-blocking queries */
|
||||
|
||||
#require "hbpgsql"
|
||||
|
||||
#include "inkey.ch"
|
||||
|
||||
PROCEDURE Main( cServer, cDatabase, cUser, cPass )
|
||||
PROCEDURE Main( cHost, cDatabase, cUser, cPass )
|
||||
|
||||
LOCAL conn
|
||||
|
||||
CLS
|
||||
|
||||
? "Connect", conn := PQconnectdb( "dbname = " + cDatabase + " host = " + cServer + " user = " + cUser + " password = " + cPass + " port = 5432" )
|
||||
? "Connect", conn := PQconnectdb( ;
|
||||
"dbname = '" + hb_defaultValue( cDatabase, "postgres" ) + "' " + ;
|
||||
"host = '" + hb_defaultValue( cHost, "localhost" ) + "' " + ;
|
||||
"user = '" + hb_defaultValue( cUser, hb_UserName() ) + "' " + ;
|
||||
"password = '" + hb_defaultValue( cPass, "" ) + "' " + ;
|
||||
"port = 5432" )
|
||||
|
||||
? "Conection status", PQerrorMessage( conn ), PQstatus( conn )
|
||||
|
||||
@@ -22,9 +25,9 @@ PROCEDURE Main( cServer, cDatabase, cUser, cPass )
|
||||
|
||||
RETURN
|
||||
|
||||
PROCEDURE Query( conn, cQuery, lCancel )
|
||||
STATIC PROCEDURE Query( conn, cQuery, lCancel )
|
||||
|
||||
LOCAL pCancel, cErrMsg := Space( 30 )
|
||||
LOCAL pCancel, cErrMsg := ""
|
||||
LOCAL res, x, y, cTime
|
||||
|
||||
? "PQSendQuery", PQsendQuery( conn, cQuery )
|
||||
@@ -32,20 +35,16 @@ PROCEDURE Query( conn, cQuery, lCancel )
|
||||
cTime := Time()
|
||||
CLEAR TYPEAHEAD
|
||||
|
||||
DO WHILE Inkey() != K_ESC
|
||||
DO WHILE hb_keyStd( Inkey() ) != K_ESC
|
||||
DevPos( Row(), 20 )
|
||||
DevOut( "Processing: " + ElapTime( cTime, Time() ) )
|
||||
DevOut( "Processing:", ElapTime( cTime, Time() ) )
|
||||
|
||||
Inkey( 1 )
|
||||
|
||||
IF lCancel
|
||||
IF .T.
|
||||
pCancel := PQgetCancel( conn )
|
||||
? "Canceled: ", PQcancel( pCancel, @cErrMsg ), cErrMsg
|
||||
pCancel := NIL
|
||||
ELSE
|
||||
? PQrequestCancel( conn ) /* Deprecated */
|
||||
ENDIF
|
||||
pCancel := PQgetCancel( conn )
|
||||
? "Canceled:", PQcancel( pCancel, @cErrMsg ), cErrMsg
|
||||
pCancel := NIL
|
||||
ENDIF
|
||||
|
||||
IF PQconsumeInput( conn )
|
||||
@@ -55,15 +54,17 @@ PROCEDURE Query( conn, cQuery, lCancel )
|
||||
ENDIF
|
||||
ENDDO
|
||||
|
||||
IF Inkey() != K_ESC
|
||||
IF hb_keyStd( Inkey() ) != K_ESC
|
||||
? "PQgetResult", hb_ValToExp( res := PQgetResult( conn ) )
|
||||
|
||||
FOR x := 1 TO PQlastrec( res )
|
||||
?
|
||||
FOR y := 1 TO PQfcount( res )
|
||||
?? PQgetvalue( res, x, y ), " "
|
||||
IF ! Empty( res )
|
||||
FOR x := 1 TO PQlastrec( res )
|
||||
?
|
||||
FOR y := 1 TO PQfcount( res )
|
||||
?? PQgetvalue( res, x, y ), " "
|
||||
NEXT
|
||||
NEXT
|
||||
NEXT
|
||||
ENDIF
|
||||
ELSE
|
||||
? "Canceling Query", PQrequestCancel( conn )
|
||||
ENDIF
|
||||
|
||||
@@ -1,56 +1,49 @@
|
||||
/*
|
||||
* This samples show how to use dbf to cache postgres records.
|
||||
*/
|
||||
/* This samples show how to use dbf to cache postgres records. */
|
||||
|
||||
#require "hbpgsql"
|
||||
|
||||
#define DB_ALIAS 1
|
||||
#define DB_FILE 2
|
||||
#define DB_QUERY 3
|
||||
#define DB_ROW 4
|
||||
#define DB_FETCH 5
|
||||
#define DB_ALIAS 1 // Table Name
|
||||
#define DB_QUERY 2 // Object Query
|
||||
#define DB_ROW 3 // Current Row
|
||||
#define DB_FETCH 4 // Fetch Status
|
||||
|
||||
STATIC s_oServer
|
||||
STATIC s_aTableTemp := {}
|
||||
STATIC s_aTempDBF := {}
|
||||
THREAD STATIC t_oServer
|
||||
THREAD STATIC t_aTableTemp := {}
|
||||
|
||||
PROCEDURE Main( cServer, cDatabase, cUser, cPass )
|
||||
PROCEDURE Main( cHost, cDatabase, cUser, cPass )
|
||||
|
||||
LOCAL i
|
||||
LOCAL cQuery
|
||||
|
||||
IF SQLConnect( cServer, cDatabase, cUser, cPass )
|
||||
IF SQLConnect( cHost, hb_defaultValue( cDatabase, "postgres" ), cUser, cPass )
|
||||
|
||||
QuickQuery( "DROP TABLE test" )
|
||||
|
||||
cQuery := "CREATE TABLE test ( "
|
||||
cQuery += " codigo integer primary key, "
|
||||
cQuery += " descri char(50), "
|
||||
cQuery += " email varchar(50) ) "
|
||||
SQLQuery( cQuery )
|
||||
SQLQuery( "CREATE TABLE test (" + ;
|
||||
" codigo integer primary key," + ;
|
||||
" descri char(50)," + ;
|
||||
" email varchar(50) )" )
|
||||
|
||||
SQLOpen( "nomes", "SELECT * FROM test" )
|
||||
|
||||
FOR i := 1 TO 50
|
||||
APPEND BLANK
|
||||
REPLACE codigo WITH i
|
||||
REPLACE descri WITH "test " + Str( i )
|
||||
dbAppend()
|
||||
nomes->codigo := i
|
||||
nomes->descri := "test " + hb_ntos( i )
|
||||
NEXT
|
||||
|
||||
SQLApplyUpdates()
|
||||
|
||||
cQuery := "SELECT * FROM test WHERE codigo >= :1 ORDER BY codigo"
|
||||
cQuery := SQLPrepare( cQuery, 1 )
|
||||
SQLOpen( "nomes", cQuery )
|
||||
SQLOpen( "nomes", SQLPrepare( "SELECT * FROM test WHERE codigo >= :1 ORDER BY codigo", 1 ) )
|
||||
|
||||
DO WHILE ! Eof()
|
||||
? RecNo(), nomes->Codigo, nomes->descri, nomes->email
|
||||
|
||||
IF RecNo() == 10
|
||||
DELETE
|
||||
dbDelete()
|
||||
ENDIF
|
||||
|
||||
IF RecNo() == 20
|
||||
REPLACE email WITH "teste"
|
||||
nomes->email := "teste"
|
||||
ENDIF
|
||||
|
||||
SQLFetch()
|
||||
@@ -63,7 +56,6 @@ PROCEDURE Main( cServer, cDatabase, cUser, cPass )
|
||||
|
||||
RETURN
|
||||
|
||||
|
||||
/* Put theses functions in a library */
|
||||
|
||||
FUNCTION SQLApplyUpdates()
|
||||
@@ -76,11 +68,9 @@ FUNCTION SQLApplyUpdates()
|
||||
LOCAL lError := .F.
|
||||
LOCAL cError
|
||||
|
||||
i := AScan( s_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } )
|
||||
IF ( i := AScan( t_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } ) ) > 0
|
||||
|
||||
IF i != 0
|
||||
|
||||
oQuery := s_aTableTemp[ i ][ 3 ]
|
||||
oQuery := t_aTableTemp[ i ][ DB_QUERY ]
|
||||
|
||||
FOR i := 1 TO LastRec()
|
||||
|
||||
@@ -88,7 +78,7 @@ FUNCTION SQLApplyUpdates()
|
||||
|
||||
IF i > oQuery:LastRec()
|
||||
|
||||
/* Verifica se eh um registro novo */
|
||||
/* Check if it's a new record */
|
||||
IF ! Deleted()
|
||||
|
||||
oRow := oQuery:GetBlankRow()
|
||||
@@ -100,44 +90,32 @@ FUNCTION SQLApplyUpdates()
|
||||
NEXT
|
||||
|
||||
oQuery:Append( oRow )
|
||||
|
||||
cError := oQuery:ErrorMsg()
|
||||
|
||||
lError := oQuery:NetErr()
|
||||
|
||||
ENDIF
|
||||
ELSE
|
||||
|
||||
oRow := oQuery:GetRow( i )
|
||||
|
||||
lUpdate := .F.
|
||||
|
||||
IF Deleted()
|
||||
|
||||
oQuery:Delete( oRow )
|
||||
cError := oQuery:ErrorMsg()
|
||||
lError := oQuery:NetErr()
|
||||
ELSE
|
||||
/* Update if any of the fields have changed */
|
||||
|
||||
/* Faz update, mas compara quais campos sao diferentes */
|
||||
|
||||
lUpdate := .F.
|
||||
FOR x := 1 TO FCount()
|
||||
|
||||
IF oRow:FieldPos( FieldName( x ) ) != 0
|
||||
|
||||
IF ! ( FieldGet( x ) == oRow:FieldGet( FieldName( x ) ) )
|
||||
oRow:FieldPut( FieldName( x ), FieldGet( x ) )
|
||||
lUpdate := .T.
|
||||
ENDIF
|
||||
IF oRow:FieldPos( FieldName( x ) ) != 0 .AND. ;
|
||||
! FieldGet( x ) == oRow:FieldGet( FieldName( x ) )
|
||||
oRow:FieldPut( FieldName( x ), FieldGet( x ) )
|
||||
lUpdate := .T.
|
||||
ENDIF
|
||||
NEXT
|
||||
|
||||
IF lUpdate
|
||||
|
||||
oQuery:Update( oRow )
|
||||
cError := oQuery:ErrorMsg()
|
||||
lError := oQuery:NetErr()
|
||||
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
@@ -149,68 +127,43 @@ FUNCTION SQLApplyUpdates()
|
||||
ENDIF
|
||||
|
||||
IF lError
|
||||
Alert( cError )
|
||||
? cError
|
||||
ENDIF
|
||||
|
||||
RETURN ! lError
|
||||
|
||||
|
||||
PROCEDURE SQLCloseTemp( cAlias )
|
||||
|
||||
LOCAL x
|
||||
|
||||
IF ! Empty( Select( cAlias ) )
|
||||
IF Select( cAlias ) != 0
|
||||
( cAlias )->( dbCloseArea() )
|
||||
ENDIF
|
||||
|
||||
x := AScan( s_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } )
|
||||
|
||||
IF ! Empty( x )
|
||||
ADel( s_aTableTemp, x )
|
||||
// ASize( s_aTableTemp, Len( s_aTableTemp ) - 1 )
|
||||
IF ( x := AScan( t_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } ) ) > 0
|
||||
hb_ADel( t_aTableTemp, x, .F. /* .T. */ )
|
||||
ENDIF
|
||||
|
||||
RETURN
|
||||
|
||||
|
||||
PROCEDURE SQLGarbageCollector()
|
||||
|
||||
LOCAL i
|
||||
LOCAL item
|
||||
LOCAL oQuery
|
||||
|
||||
dbCloseAll()
|
||||
|
||||
FOR i := 1 TO Len( s_aTableTemp )
|
||||
/* Apaga arquivos dbfs criados */
|
||||
FErase( s_aTableTemp[ i ][ DB_FILE ] )
|
||||
oQuery := s_aTableTemp[ i ][ DB_QUERY ]
|
||||
|
||||
IF oQuery != NIL
|
||||
FOR EACH item IN t_aTableTemp
|
||||
IF ( oQuery := item[ DB_QUERY ] ) != NIL
|
||||
oQuery:Destroy()
|
||||
ENDIF
|
||||
NEXT
|
||||
|
||||
FOR i := 1 TO Len( s_aTempDBF )
|
||||
IF hb_FileExists( s_aTempDBF[ i ] )
|
||||
FErase( s_aTempDBF[ i ] )
|
||||
ENDIF
|
||||
|
||||
IF hb_FileExists( StrTran( s_aTempDBF[ i ], ".tmp", ".dbf" ) )
|
||||
FErase( StrTran( s_aTempDBF[ i ], ".tmp", ".dbf" ) )
|
||||
ENDIF
|
||||
|
||||
IF hb_FileExists( StrTran( s_aTempDBF[ i ], ".tmp", ".dbt" ) )
|
||||
FErase( StrTran( s_aTempDBF[ i ], ".tmp", ".dbt" ) )
|
||||
ENDIF
|
||||
NEXT
|
||||
|
||||
s_aTableTemp := {}
|
||||
s_aTempDBF := {}
|
||||
ASize( t_aTableTemp, 0 )
|
||||
|
||||
RETURN
|
||||
|
||||
|
||||
FUNCTION SQLFetch( fetchall )
|
||||
FUNCTION SQLFetch( lFetchAll )
|
||||
|
||||
LOCAL oQuery
|
||||
LOCAL oRow
|
||||
@@ -219,26 +172,24 @@ FUNCTION SQLFetch( fetchall )
|
||||
LOCAL nPos
|
||||
LOCAL lEof := .F.
|
||||
|
||||
hb_default( @Fetchall, .F. )
|
||||
hb_default( @lFetchAll, .F. )
|
||||
|
||||
/* Procura pela tabela no array */
|
||||
i := AScan( s_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } )
|
||||
/* Search for table in array */
|
||||
IF ( i := AScan( t_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } ) ) > 0
|
||||
|
||||
IF i != 0
|
||||
/* Traz registros da base de dados */
|
||||
/* Get database records */
|
||||
oQuery := t_aTableTemp[ i ][ DB_QUERY ]
|
||||
nPos := t_aTableTemp[ i ][ DB_ROW ] + 1
|
||||
|
||||
oQuery := s_aTableTemp[ i ][ DB_QUERY ]
|
||||
nPos := s_aTableTemp[ i ][ DB_ROW ] + 1
|
||||
|
||||
IF Fetchall
|
||||
s_aTableTemp[ i ][ DB_FETCH ] := .T.
|
||||
IF lFetchAll
|
||||
t_aTableTemp[ i ][ DB_FETCH ] := .T.
|
||||
ENDIF
|
||||
|
||||
IF oQuery:LastRec() >= nPos
|
||||
|
||||
y := nPos
|
||||
|
||||
DO WHILE nPos <= iif( FetchAll, oQuery:LastRec(), y )
|
||||
DO WHILE nPos <= iif( lFetchAll, oQuery:LastRec(), y )
|
||||
oRow := oQuery:GetRow( nPos )
|
||||
dbAppend()
|
||||
|
||||
@@ -246,7 +197,7 @@ FUNCTION SQLFetch( fetchall )
|
||||
FieldPut( FieldPos( oRow:FieldName( x ) ), oRow:FieldGet( x ) )
|
||||
NEXT
|
||||
|
||||
s_aTableTemp[ i ][ DB_ROW ] := nPos
|
||||
t_aTableTemp[ i ][ DB_ROW ] := nPos
|
||||
nPos++
|
||||
ENDDO
|
||||
|
||||
@@ -260,7 +211,6 @@ FUNCTION SQLFetch( fetchall )
|
||||
|
||||
RETURN lEof
|
||||
|
||||
|
||||
PROCEDURE SQLFetchAll()
|
||||
|
||||
SQLFetch( .T. )
|
||||
@@ -268,25 +218,19 @@ PROCEDURE SQLFetchAll()
|
||||
|
||||
RETURN
|
||||
|
||||
|
||||
FUNCTION SQLOpen( cAlias, cQuery, xFetch, cOrder )
|
||||
|
||||
LOCAL cFile
|
||||
LOCAL Result := .T.
|
||||
LOCAL x
|
||||
LOCAL s_oServer
|
||||
LOCAL oServer
|
||||
LOCAL oQuery
|
||||
LOCAL aStrudbf
|
||||
LOCAL lFetch
|
||||
|
||||
s_oServer := SQLCurrentServer()
|
||||
oServer := SQLCurrentServer()
|
||||
cAlias := Upper( cAlias )
|
||||
|
||||
/* Procura por query na area temporaria */
|
||||
x := AScan( s_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } )
|
||||
|
||||
IF ! Empty( x )
|
||||
oQuery := s_aTableTemp[ x ][ 3 ]
|
||||
/* Search by query in temporary area */
|
||||
IF ( x := AScan( t_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } ) ) > 0
|
||||
oQuery := t_aTableTemp[ x ][ DB_QUERY ]
|
||||
oQuery:Destroy()
|
||||
ENDIF
|
||||
|
||||
@@ -297,28 +241,18 @@ FUNCTION SQLOpen( cAlias, cQuery, xFetch, cOrder )
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
cQuery := cQuery
|
||||
oQuery := s_oServer:Query( cQuery )
|
||||
oQuery := oServer:Query( cQuery )
|
||||
|
||||
IF oQuery:NetErr()
|
||||
Alert( oQuery:ErrorMsg() )
|
||||
? oQuery:ErrorMsg()
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
IF Empty( Select( cAlias ) )
|
||||
/* Pega estrutura da base de dados */
|
||||
aStrudbf := oQuery:Struct()
|
||||
|
||||
/* Cria tabela */
|
||||
cFile := TempFile()
|
||||
dbCreate( cFile, aStrudbf )
|
||||
|
||||
/* Abre Tabela */
|
||||
dbUseArea( .T., NIL, cFile, cAlias, .F. )
|
||||
|
||||
IF Select( cAlias ) == 0
|
||||
hb_dbCreateTemp( cAlias, oQuery:Struct() )
|
||||
ELSE
|
||||
Select( cAlias )
|
||||
ZAP
|
||||
dbSelectArea( cAlias )
|
||||
hb_dbZap()
|
||||
ENDIF
|
||||
|
||||
IF xFetch != NIL
|
||||
@@ -327,182 +261,165 @@ FUNCTION SQLOpen( cAlias, cQuery, xFetch, cOrder )
|
||||
lFetch := .F.
|
||||
ENDIF
|
||||
|
||||
/* Se nao houver query na area temporaria entao adiciona, caso contrario, apenas atualiza */
|
||||
IF Empty( x )
|
||||
AAdd( s_aTableTemp, { ;
|
||||
cAlias, ; // Table Name
|
||||
cFile, ; // Temporary File Name
|
||||
oQuery, ; // Object Query
|
||||
0, ; // Current Row
|
||||
lFetch } ) // Fetch Status
|
||||
/* If there is no query in the temporary area then add, otherwise just refresh. */
|
||||
IF x == 0
|
||||
AAdd( t_aTableTemp, { ;
|
||||
cAlias, ; // DB_ALIAS
|
||||
oQuery, ; // DB_QUERY
|
||||
0, ; // DB_ROW
|
||||
lFetch } ) // DB_FETCH
|
||||
ELSE
|
||||
|
||||
s_aTableTemp[ x ][ DB_QUERY ] := oQuery
|
||||
s_aTableTemp[ x ][ DB_ROW ] := 0
|
||||
s_aTableTemp[ x ][ DB_FETCH ] := lFetch
|
||||
t_aTableTemp[ x ][ DB_QUERY ] := oQuery
|
||||
t_aTableTemp[ x ][ DB_ROW ] := 0
|
||||
t_aTableTemp[ x ][ DB_FETCH ] := lFetch
|
||||
|
||||
ENDIF
|
||||
|
||||
/* Traz registros da base de dados */
|
||||
/* Get database records */
|
||||
SQLFetch( lFetch )
|
||||
|
||||
IF lFetch
|
||||
dbGoTop()
|
||||
ENDIF
|
||||
|
||||
RETURN result
|
||||
RETURN .T.
|
||||
|
||||
|
||||
FUNCTION SQLConnect( cServer, cDatabase, cUser, cPassword, cSchema )
|
||||
FUNCTION SQLConnect( cHost, cDatabase, cUser, cPassword, cSchema )
|
||||
|
||||
LOCAL lRetval := .T.
|
||||
|
||||
s_oServer := TPQServer():New( cServer, cDatabase, cUser, cPassWord, 5432, cSchema )
|
||||
IF s_oServer:NetErr()
|
||||
Alert( s_oServer:ErrorMsg() )
|
||||
t_oServer := TPQServer():New( cHost, cDatabase, cUser, cPassword, 5432, cSchema )
|
||||
IF t_oServer:NetErr()
|
||||
? t_oServer:ErrorMsg()
|
||||
lRetval := .F.
|
||||
ENDIF
|
||||
s_oServer:lAllCols := .F.
|
||||
t_oServer:lAllCols := .F.
|
||||
|
||||
RETURN lRetval
|
||||
|
||||
|
||||
PROCEDURE SQLDestroy()
|
||||
|
||||
IF s_oServer != NIL
|
||||
s_oServer:Destroy()
|
||||
IF t_oServer != NIL
|
||||
t_oServer:Destroy()
|
||||
ENDIF
|
||||
|
||||
RETURN
|
||||
|
||||
|
||||
FUNCTION SQLCurrentServer
|
||||
RETURN s_oServer
|
||||
|
||||
RETURN t_oServer
|
||||
|
||||
FUNCTION SQLQuery( cQuery )
|
||||
|
||||
LOCAL oQuery := s_oServer:Query( cQuery )
|
||||
LOCAL oQuery := t_oServer:Query( cQuery )
|
||||
|
||||
IF oQuery:NetErr()
|
||||
Alert( cQuery + ":" + oQuery:ErrorMsg() )
|
||||
? cQuery + ":" + oQuery:ErrorMsg()
|
||||
ENDIF
|
||||
|
||||
RETURN oQuery
|
||||
|
||||
|
||||
FUNCTION SQLExecQuery( cQuery )
|
||||
|
||||
LOCAL oQuery
|
||||
LOCAL result := .T.
|
||||
LOCAL oQuery := t_oServer:Query( cQuery )
|
||||
|
||||
oQuery := s_oServer:Query( cQuery )
|
||||
IF oQuery:NetErr()
|
||||
Alert( "Cannot execute " + cQuery + ":" + oQuery:ErrorMsg() )
|
||||
|
||||
result := .F.
|
||||
ELSE
|
||||
oQuery:Destroy()
|
||||
? "Cannot execute", cQuery + ":" + oQuery:ErrorMsg()
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
RETURN result
|
||||
oQuery:Destroy()
|
||||
|
||||
RETURN .T.
|
||||
|
||||
FUNCTION SQLPrepare( cQuery, ... )
|
||||
|
||||
LOCAL i, x
|
||||
|
||||
IF PCount() >= 2
|
||||
/* Limpa espacos desnecessarios */
|
||||
DO WHILE At( Space( 2 ), cQuery ) != 0
|
||||
/* Remove unnecessary whitespace */
|
||||
DO WHILE Space( 2 ) $ cQuery
|
||||
cQuery := StrTran( cQuery, Space( 2 ), Space( 1 ) )
|
||||
ENDDO
|
||||
|
||||
/* Coloca {} nos parametros */
|
||||
/* Place {} in the parameters */
|
||||
FOR i := 1 TO PCount() - 1
|
||||
IF ! Empty( x := At( ":" + hb_ntos( i ), cQuery ) )
|
||||
IF ( x := At( ":" + hb_ntos( i ), cQuery ) ) > 0
|
||||
cQuery := Stuff( cQuery, x, 0, "{" )
|
||||
cQuery := Stuff( cQuery, x + Len( hb_ntos( i ) ) + 2, 0, "}" )
|
||||
ENDIF
|
||||
NEXT
|
||||
|
||||
/* Substitui parametros por valores passados */
|
||||
/* Replace parameters with values */
|
||||
FOR i := 2 TO PCount()
|
||||
x := hb_PValue( i )
|
||||
|
||||
IF x != NIL .AND. Empty( x )
|
||||
DO CASE
|
||||
CASE x != NIL .AND. Empty( x )
|
||||
x := "null"
|
||||
|
||||
ELSEIF HB_ISNUMERIC( x )
|
||||
CASE HB_ISNUMERIC( x )
|
||||
x := hb_ntos( x )
|
||||
|
||||
ELSEIF HB_ISDATE( x )
|
||||
x := DToQ( x )
|
||||
CASE HB_ISDATE( x )
|
||||
x := "'" + hb_DToC( x, "yyyy-mm-dd" ) + "'"
|
||||
|
||||
ELSEIF HB_ISLOGICAL( x )
|
||||
CASE HB_ISLOGICAL( x )
|
||||
x := iif( x, "'t'", "'f'" )
|
||||
|
||||
ELSEIF HB_ISSTRING( x )
|
||||
CASE HB_ISSTRING( x )
|
||||
x := SToQ( RTrim( x ) )
|
||||
|
||||
ELSE
|
||||
OTHERWISE
|
||||
x := "null"
|
||||
ENDIF
|
||||
ENDCASE
|
||||
|
||||
cQuery := StrTran( cQuery, "{:" + hb_ntos( i - 1 ) + "}", x )
|
||||
NEXT
|
||||
ENDIF
|
||||
|
||||
cQuery := StrTran( cQuery, "==", "=" )
|
||||
cQuery := StrTran( cQuery, "!=", "<>" )
|
||||
cQuery := StrTran( cQuery, ".and.", "and" )
|
||||
cQuery := StrTran( cQuery, ".or.", "or" )
|
||||
cQuery := StrTran( cQuery, ".not.", "not" )
|
||||
RETURN hb_StrReplace( cQuery, { ;
|
||||
"==" => "=" , ;
|
||||
"!=" => "<>" , ;
|
||||
".and." => "and" , ;
|
||||
".or." => "or" , ;
|
||||
".not." => "not" } )
|
||||
|
||||
RETURN cQuery
|
||||
|
||||
|
||||
/* Pega resultado de uma sequence */
|
||||
/* Get next result of a sequence */
|
||||
FUNCTION SQLSequence( Sequence_name )
|
||||
RETURN Val( QuickQuery( "SELECT nextval(" + SToQ( sequence_name ) + ")" ) )
|
||||
|
||||
|
||||
PROCEDURE SQLStartTrans()
|
||||
|
||||
IF PQtransactionStatus( s_oServer:pDB ) != PQTRANS_INTRANS
|
||||
s_oServer:StartTransaction()
|
||||
IF PQtransactionStatus( t_oServer:pDB ) != PQTRANS_INTRANS
|
||||
t_oServer:StartTransaction()
|
||||
ENDIF
|
||||
|
||||
RETURN
|
||||
|
||||
|
||||
FUNCTION SQLInTrans()
|
||||
RETURN PQtransactionStatus( s_oServer:pDB ) == PQTRANS_INTRANS
|
||||
|
||||
RETURN PQtransactionStatus( t_oServer:pDB ) == PQTRANS_INTRANS
|
||||
|
||||
PROCEDURE SQLCommitTrans()
|
||||
|
||||
s_oServer:Commit()
|
||||
t_oServer:Commit()
|
||||
|
||||
RETURN
|
||||
|
||||
|
||||
PROCEDURE SQLRollbackTrans()
|
||||
|
||||
s_oServer:rollback()
|
||||
t_oServer:rollback()
|
||||
|
||||
RETURN
|
||||
|
||||
|
||||
/* Faz querie que retorna apenas 1 valor de coluna */
|
||||
/* Do query that returns only 1 column value */
|
||||
FUNCTION QuickQuery( cQuery )
|
||||
|
||||
LOCAL pQuery
|
||||
LOCAL result := ""
|
||||
LOCAL temp, aTemp
|
||||
LOCAL x, y
|
||||
|
||||
pQuery := PQexec( s_oServer:pDB, cQuery )
|
||||
LOCAL pQuery := PQexec( t_oServer:pDB, cQuery )
|
||||
|
||||
IF PQresultStatus( pQuery ) == PGRES_TUPLES_OK
|
||||
IF PQlastrec( pQuery ) != 0
|
||||
@@ -525,51 +442,5 @@ FUNCTION QuickQuery( cQuery )
|
||||
|
||||
RETURN result
|
||||
|
||||
|
||||
PROCEDURE MakeDBF( cAlias, aStructure, aIndex )
|
||||
|
||||
LOCAL cFile, i, cIndex, cKey
|
||||
|
||||
hb_default( @aIndex, {} )
|
||||
|
||||
cFile := TempFile()
|
||||
dbCreate( cFile, aStructure )
|
||||
|
||||
/* Abre Tabela */
|
||||
dbUseArea( .T., NIL, cFile, cAlias, .F. )
|
||||
|
||||
FOR i := 1 TO Len( aIndex )
|
||||
cKey := aIndex[ i ]
|
||||
cIndex := TempFile()
|
||||
|
||||
INDEX ON &cKey TO ( cIndex )
|
||||
|
||||
AAdd( s_aTempDBF, cIndex )
|
||||
NEXT
|
||||
|
||||
AAdd( s_aTempDBF, cFile )
|
||||
|
||||
RETURN
|
||||
|
||||
|
||||
FUNCTION TempFile( cPath, cExt )
|
||||
|
||||
LOCAL cString
|
||||
|
||||
hb_default( @cPath, hb_DirTemp() )
|
||||
hb_default( @cExt, "tmp" )
|
||||
|
||||
cString := cPath + StrZero( Int( hb_Random( Val( StrTran( Time(), ":" ) ) ) ), 8 ) + "." + cExt
|
||||
|
||||
DO WHILE hb_FileExists( cString )
|
||||
cString := cPath + StrZero( Int( hb_Random( Val( StrTran( Time(), ":" ) ) ) ), 8 ) + "." + cExt
|
||||
ENDDO
|
||||
|
||||
RETURN cString
|
||||
|
||||
|
||||
FUNCTION DToQ( cData )
|
||||
RETURN "'" + Str( Year( cData ), 4 ) + "-" + StrZero( Month( cData ), 2 ) + "-" + StrZero( Day( cData ), 2 ) + "'"
|
||||
|
||||
FUNCTION SToQ( cData )
|
||||
RETURN "'" + cData + "'"
|
||||
|
||||
@@ -47,27 +47,26 @@
|
||||
|
||||
#require "hbpgsql"
|
||||
|
||||
#include "inkey.ch"
|
||||
#include "fileio.ch"
|
||||
#include "inkey.ch"
|
||||
|
||||
#include "hbextcdp.ch"
|
||||
|
||||
PROCEDURE Main( ... )
|
||||
PROCEDURE Main()
|
||||
|
||||
LOCAL cTok
|
||||
LOCAL cHostName := "localhost"
|
||||
LOCAL cUser := "postgres"
|
||||
LOCAL cPassWord := ""
|
||||
LOCAL cDataBase, cTable, cFile
|
||||
LOCAL aDbfStruct, i
|
||||
LOCAL cHostName
|
||||
LOCAL cUser
|
||||
LOCAL cPassword
|
||||
LOCAL cDatabase := "postgres", cTable, cFile
|
||||
LOCAL i
|
||||
LOCAL lCreateTable := .F.
|
||||
LOCAL oServer, oTable, oRecord
|
||||
LOCAL cField
|
||||
LOCAL sType
|
||||
LOCAL dType
|
||||
LOCAL cTypeDB
|
||||
LOCAL cTypePG
|
||||
LOCAL cValue
|
||||
LOCAL nCommit := 100
|
||||
LOCAL nHandle
|
||||
LOCAL hFile
|
||||
LOCAL nCount := 0
|
||||
LOCAL nRecno := 0
|
||||
LOCAL lTruncate := .F.
|
||||
@@ -75,80 +74,48 @@ PROCEDURE Main( ... )
|
||||
LOCAL cPath := "public"
|
||||
|
||||
Set( _SET_DATEFORMAT, "yyyy-mm-dd" )
|
||||
SET DELETE ON
|
||||
Set( _SET_DELETED, .T. )
|
||||
|
||||
rddSetDefault( "DBFDBT" )
|
||||
|
||||
IF PCount() < 6
|
||||
help()
|
||||
QUIT
|
||||
ENDIF
|
||||
|
||||
i := 1
|
||||
/* Scan parameters and setup workings */
|
||||
DO WHILE i <= PCount()
|
||||
|
||||
cTok := hb_PValue( i++ )
|
||||
|
||||
DO CASE
|
||||
CASE cTok == "-h"
|
||||
cHostName := hb_PValue( i++ )
|
||||
|
||||
CASE cTok == "-d"
|
||||
cDataBase := hb_PValue( i++ )
|
||||
|
||||
CASE cTok == "-t"
|
||||
cTable := hb_PValue( i++ )
|
||||
|
||||
CASE cTok == "-f"
|
||||
cFile := hb_PValue( i++ )
|
||||
|
||||
CASE cTok == "-u"
|
||||
cUser := hb_PValue( i++ )
|
||||
|
||||
CASE cTok == "-p"
|
||||
cPassWord := hb_PValue( i++ )
|
||||
|
||||
CASE cTok == "-c"
|
||||
lCreateTable := .T.
|
||||
|
||||
CASE cTok == "-x"
|
||||
lTruncate := .T.
|
||||
|
||||
CASE cTok == "-s"
|
||||
lUseTrans := .T.
|
||||
|
||||
CASE cTok == "-m"
|
||||
nCommit := Val( hb_PValue( i++ ) )
|
||||
|
||||
CASE cTok == "-r"
|
||||
nRecno := Val( hb_PValue( i++ ) )
|
||||
|
||||
CASE cTok == "-e"
|
||||
cPath := hb_PValue( i++ )
|
||||
|
||||
CASE cTok == "-cp"
|
||||
hb_cdpSelect( hb_PValue( i++ ) )
|
||||
FOR i := 1 TO PCount()
|
||||
|
||||
SWITCH hb_PValue( i )
|
||||
CASE "-h" ; cHostName := hb_PValue( ++i ) ; EXIT
|
||||
CASE "-d" ; cDatabase := hb_PValue( ++i ) ; EXIT
|
||||
CASE "-t" ; cTable := AllTrim( hb_PValue( ++i ) ) ; EXIT
|
||||
CASE "-f" ; cFile := hb_PValue( ++i ) ; EXIT
|
||||
CASE "-u" ; cUser := hb_PValue( ++i ) ; EXIT
|
||||
CASE "-p" ; cPassword := hb_PValue( ++i ) ; EXIT
|
||||
CASE "-c" ; lCreateTable := .T. ; EXIT
|
||||
CASE "-x" ; lTruncate := .T. ; EXIT
|
||||
CASE "-s" ; lUseTrans := .T. ; EXIT
|
||||
CASE "-m" ; nCommit := Val( hb_PValue( ++i ) ) ; EXIT
|
||||
CASE "-r" ; nRecno := Val( hb_PValue( ++i ) ) ; EXIT
|
||||
CASE "-e" ; cPath := hb_PValue( ++i ) ; EXIT
|
||||
CASE "-cp" ; Set( _SET_DBCODEPAGE, hb_PValue( ++i ) ) ; EXIT
|
||||
OTHERWISE
|
||||
help()
|
||||
QUIT
|
||||
ENDCASE
|
||||
ENDDO
|
||||
RETURN
|
||||
ENDSWITCH
|
||||
NEXT
|
||||
|
||||
// create log file
|
||||
IF ( nHandle := FCreate( RTrim( cTable ) + ".log" ) ) == F_ERROR
|
||||
? "Cannot create log file"
|
||||
QUIT
|
||||
IF Empty( cTable ) .OR. cFile == ""
|
||||
help()
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
USE ( cFile ) SHARED
|
||||
aDbfStruct := dbStruct()
|
||||
// create log file
|
||||
IF ( hFile := hb_vfOpen( cTable + ".log", FO_CREAT + FO_TRUNC + FO_WRITE ) ) == NIL
|
||||
? "Cannot create log file"
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
oServer := TPQServer():New( cHostName, cDatabase, cUser, cPassWord, NIL, cPath )
|
||||
USE ( cFile ) SHARED READONLY
|
||||
|
||||
oServer := TPQServer():New( cHostName, cDatabase, cUser, cPassword, , cPath )
|
||||
IF oServer:NetErr()
|
||||
? oServer:ErrorMsg()
|
||||
QUIT
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
oServer:lallCols := .F.
|
||||
@@ -158,18 +125,18 @@ PROCEDURE Main( ... )
|
||||
oServer:DeleteTable( cTable )
|
||||
IF oServer:NetErr()
|
||||
? oServer:ErrorMsg()
|
||||
FWrite( nHandle, "Error: " + oServer:ErrorMsg() + hb_eol() )
|
||||
FClose( nHandle )
|
||||
QUIT
|
||||
hb_vfWrite( hFile, "Error: " + oServer:ErrorMsg() + hb_eol() )
|
||||
hb_vfClose( hFile )
|
||||
RETURN
|
||||
ENDIF
|
||||
ENDIF
|
||||
oServer:CreateTable( cTable, aDbfStruct )
|
||||
|
||||
oServer:CreateTable( cTable, dbStruct() )
|
||||
IF oServer:NetErr()
|
||||
? oServer:ErrorMsg()
|
||||
FWrite( nHandle, "Error: " + oServer:ErrorMsg() + hb_eol() )
|
||||
FClose( nHandle )
|
||||
QUIT
|
||||
hb_vfWrite( hFile, "Error: " + oServer:ErrorMsg() + hb_eol() )
|
||||
hb_vfClose( hFile )
|
||||
RETURN
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
@@ -177,75 +144,57 @@ PROCEDURE Main( ... )
|
||||
oServer:Execute( "truncate table " + cTable )
|
||||
IF oServer:NetErr()
|
||||
? oServer:ErrorMsg()
|
||||
FWrite( nHandle, "Error: " + oServer:ErrorMsg() + hb_eol() )
|
||||
FClose( nHandle )
|
||||
QUIT
|
||||
hb_vfWrite( hFile, "Error: " + oServer:ErrorMsg() + hb_eol() )
|
||||
hb_vfClose( hFile )
|
||||
RETURN
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
oTable := oServer:Query( "SELECT * FROM " + cTable + " LIMIT 1" )
|
||||
IF oTable:NetErr()
|
||||
Alert( oTable:ErrorMsg() )
|
||||
FWrite( nHandle, "Error: " + oTable:ErrorMsg() + hb_eol() )
|
||||
FClose( nHandle )
|
||||
QUIT
|
||||
? oTable:ErrorMsg()
|
||||
hb_vfWrite( hFile, "Error: " + oTable:ErrorMsg() + hb_eol() )
|
||||
hb_vfClose( hFile )
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
IF lUseTrans
|
||||
oServer:StartTransaction()
|
||||
ENDIF
|
||||
|
||||
FWrite( nHandle, "Start: " + Time() + hb_eol() )
|
||||
hb_vfWrite( hFile, "Start: " + Time() + hb_eol() )
|
||||
|
||||
? "Start: ", Time()
|
||||
? "Start:", Time()
|
||||
?
|
||||
|
||||
IF ! Empty( nRecno )
|
||||
IF nRecno != 0
|
||||
dbGoto( nRecno )
|
||||
ENDIF
|
||||
|
||||
DO WHILE ! Eof() .AND. Inkey() != K_ESC .AND. ( Empty( nRecno ) .OR. nRecno == RecNo() )
|
||||
DO WHILE ! Eof() .AND. hb_keyStd( Inkey() ) != K_ESC .AND. ( nRecno == 0 .OR. nRecno == RecNo() )
|
||||
oRecord := oTable:GetBlankRow()
|
||||
|
||||
FOR i := 1 TO oTable:FCount()
|
||||
cField := Lower( oTable:FieldName( i ) )
|
||||
sType := FieldType( FieldPos( cField ) )
|
||||
dType := oRecord:FieldType( i )
|
||||
cTypeDB := Left( hb_FieldType( FieldPos( cField ) ), 1 )
|
||||
cTypePG := oRecord:FieldType( i )
|
||||
cValue := FieldGet( FieldPos( cField ) )
|
||||
|
||||
IF cValue != NIL
|
||||
IF dType != sType
|
||||
IF dType == "C" .AND. sType == "N"
|
||||
cValue := Str( cValue )
|
||||
|
||||
ELSEIF dType == "C" .AND. sType == "D"
|
||||
cValue := DToC( cValue )
|
||||
|
||||
ELSEIF dType == "C" .AND. sType == "L"
|
||||
cValue := iif( cValue, "S", "N" )
|
||||
|
||||
ELSEIF dType == "N" .AND. sType == "C"
|
||||
cValue := Val( cValue )
|
||||
|
||||
ELSEIF dType == "N" .AND. sType == "D"
|
||||
cValue := Val( DToS( cValue ) )
|
||||
|
||||
ELSEIF dType == "N" .AND. sType == "L"
|
||||
cValue := iif( cValue, 1, 0 )
|
||||
|
||||
ELSEIF dType == "D" .AND. sType == "C"
|
||||
cValue := CToD( cValue )
|
||||
|
||||
ELSEIF dType == "D" .AND. sType == "N"
|
||||
cValue := hb_SToD( Str( cValue ) )
|
||||
|
||||
ELSEIF dType == "L" .AND. sType == "N"
|
||||
cValue := ! Empty( cValue )
|
||||
|
||||
ELSEIF dType == "L" .AND. sType == "C"
|
||||
cValue := iif( AllTrim( cValue ) $ "YySs1", .T., .F. )
|
||||
|
||||
ENDIF
|
||||
IF cTypePG != cTypeDB
|
||||
DO CASE
|
||||
CASE cTypePG == "C" .AND. cTypeDB $ "NIYF8BZ24" ; cValue := hb_ntos( cValue )
|
||||
CASE cTypePG == "C" .AND. cTypeDB == "D" ; cValue := DToC( cValue )
|
||||
CASE cTypePG == "C" .AND. cTypeDB $ "T@" ; cValue := hb_TToC( cValue )
|
||||
CASE cTypePG == "C" .AND. cTypeDB == "L" ; cValue := iif( cValue, "S", "N" )
|
||||
CASE cTypePG == "N" .AND. cTypeDB $ "CQ" ; cValue := Val( cValue )
|
||||
CASE cTypePG == "N" .AND. cTypeDB == "D" ; cValue := Val( DToS( cValue ) )
|
||||
CASE cTypePG == "N" .AND. cTypeDB == "L" ; cValue := iif( cValue, 1, 0 )
|
||||
CASE cTypePG == "D" .AND. cTypeDB $ "CQ" ; cValue := CToD( cValue )
|
||||
CASE cTypePG == "D" .AND. cTypeDB $ "NIYF8BZ24" ; cValue := hb_SToD( hb_ntos( cValue ) )
|
||||
CASE cTypePG == "L" .AND. cTypeDB $ "NIYF8BZ24" ; cValue := ! Empty( cValue )
|
||||
CASE cTypePG == "L" .AND. cTypeDB $ "CQ" ; cValue := AllTrim( cValue ) $ "YySs1"
|
||||
ENDCASE
|
||||
ENDIF
|
||||
|
||||
IF cValue != NIL
|
||||
@@ -262,18 +211,18 @@ PROCEDURE Main( ... )
|
||||
|
||||
IF oTable:NetErr()
|
||||
?
|
||||
? "Error Record: ", RecNo(), Left( oTable:ErrorMsg(), 70 )
|
||||
? "Error Record:", RecNo(), Left( oTable:ErrorMsg(), 70 )
|
||||
?
|
||||
FWrite( nHandle, "Error at record: " + hb_ntos( RecNo() ) + " Description: " + oTable:ErrorMsg() + hb_eol() )
|
||||
hb_vfWrite( hFile, "Error at record: " + hb_ntos( RecNo() ) + " Description: " + oTable:ErrorMsg() + hb_eol() )
|
||||
ELSE
|
||||
nCount++
|
||||
ENDIF
|
||||
|
||||
dbSkip()
|
||||
|
||||
IF ( nCount % nCommit ) == 0
|
||||
IF nCount % nCommit == 0
|
||||
DevPos( Row(), 1 )
|
||||
DevOut( "imported recs: " + Str( nCount ) )
|
||||
DevOut( "imported recs:", hb_ntos( nCount ) )
|
||||
|
||||
IF lUseTrans
|
||||
oServer:commit()
|
||||
@@ -282,41 +231,38 @@ PROCEDURE Main( ... )
|
||||
ENDIF
|
||||
ENDDO
|
||||
|
||||
IF ( nCount % nCommit ) != 0
|
||||
IF lUseTrans
|
||||
oServer:commit()
|
||||
ENDIF
|
||||
IF nCount % nCommit != 0 .AND. lUseTrans
|
||||
oServer:commit()
|
||||
ENDIF
|
||||
|
||||
FWrite( nHandle, "End: " + Time() + ", records in dbf: " + hb_ntos( RecNo() ) + ", imported recs: " + hb_ntos( nCount ) + hb_eol() )
|
||||
hb_vfWrite( hFile, "End: " + Time() + ", records in dbf: " + hb_ntos( RecNo() ) + ", imported recs: " + hb_ntos( nCount ) + hb_eol() )
|
||||
|
||||
? "End: ", Time()
|
||||
?
|
||||
? "End:", Time()
|
||||
|
||||
FClose( nHandle )
|
||||
hb_vfClose( hFile )
|
||||
|
||||
dbCloseAll()
|
||||
|
||||
CLOSE ALL
|
||||
oTable:Destroy()
|
||||
oServer:Destroy()
|
||||
|
||||
RETURN
|
||||
|
||||
PROCEDURE Help()
|
||||
STATIC PROCEDURE Help()
|
||||
|
||||
? "dbf2pg - dbf file to PostgreSQL table conversion utility"
|
||||
? "-h hostname (default: localhost)"
|
||||
? "-u user (default: root)"
|
||||
? "-p password (default no password)"
|
||||
? "-d name of database to use"
|
||||
? "-t name of table to add records to"
|
||||
? "-h hostname"
|
||||
? "-u user"
|
||||
? "-p password"
|
||||
? "-d name of database to use (default: postgres)"
|
||||
? "-t name of table to add records to (required)"
|
||||
? "-c delete existing table and create a new one"
|
||||
? "-f name of .dbf file to import"
|
||||
? "-f name of .dbf file to import (required)"
|
||||
? "-x truncate table before append records"
|
||||
? "-s use transaction"
|
||||
? "-m commit interval"
|
||||
? "-r insert only record number"
|
||||
? "-e search path"
|
||||
|
||||
? ""
|
||||
?
|
||||
|
||||
RETURN
|
||||
|
||||
75
contrib/hbpgsql/tests/ping.prg
Normal file
75
contrib/hbpgsql/tests/ping.prg
Normal file
@@ -0,0 +1,75 @@
|
||||
#require "hbpgsql"
|
||||
|
||||
PROCEDURE Main( cHost, cDatabase, cUser, cPass )
|
||||
|
||||
LOCAL nVersion
|
||||
|
||||
CLS
|
||||
|
||||
? "The function PQlibVersion() returns", nVersion := PQlibVersion()
|
||||
?
|
||||
|
||||
IF nVersion < 90100
|
||||
? "Function PQping() not supported."
|
||||
QUIT
|
||||
ENDIF
|
||||
|
||||
hb_default( @cHost, "localhost" )
|
||||
hb_default( @cDatabase, "postgres" )
|
||||
hb_default( @cUser, hb_UserName() )
|
||||
hb_default( @cPass, "" )
|
||||
|
||||
/* PQping() reports the status of the server.
|
||||
It accepts connection parameters identical to those of PQconnectdb().
|
||||
It is not, however, necessary to supply correct user name, password,
|
||||
or database name values to obtain the server status. */
|
||||
HB_SYMBOL_UNUSED( cDatabase )
|
||||
HB_SYMBOL_UNUSED( cUser )
|
||||
HB_SYMBOL_UNUSED( cPass )
|
||||
|
||||
/* the ConnInfo string can be empty to use ALL default parameters */
|
||||
PingTest( "" )
|
||||
|
||||
/* 'database' is not allowed parameter key, you can find the currently
|
||||
recognized parameter key words on
|
||||
https://www.postgresql.org/docs/9.1/static/libpq-connect.html */
|
||||
PingTest( ;
|
||||
"host = localhost" + " " + ;
|
||||
"database = test" )
|
||||
|
||||
/* the default port for Postgres is 5432, but we can try connect to an
|
||||
alternate port and see what happens. */
|
||||
PingTest( ;
|
||||
"host = " + cHost + " " + ;
|
||||
"port = " + "3333" )
|
||||
|
||||
/* next attempt */
|
||||
PingTest( ;
|
||||
"host = " + cHost + " " + ;
|
||||
"hostaddr = " + "127.0.0.1" + " " + ;
|
||||
"port = " + "5432" + " " + ;
|
||||
"connect_timeout = " + "10" )
|
||||
|
||||
RETURN
|
||||
|
||||
STATIC PROCEDURE PingTest( cConnInfo )
|
||||
|
||||
? "cConnInfo is", '"' + cConnInfo + '"'
|
||||
? "PQPing( cConnInfo ) returns:", GetPingResult( PQPing( cConnInfo ) )
|
||||
?
|
||||
|
||||
RETURN
|
||||
|
||||
STATIC FUNCTION GetPingResult( n )
|
||||
|
||||
LOCAL aMsg := { ;
|
||||
{ "PQPING_OK" , "Server is accepting connections" }, ;
|
||||
{ "PQPING_REJECT" , "Server is alive but rejecting connections" }, ;
|
||||
{ "PQPING_NO_RESPONSE", "Could not establish connection" }, ;
|
||||
{ "PQPING_NO_ATTEMPT" , "Connection not attempted (bad params)" } }
|
||||
|
||||
IF n >= 0 .AND. n < Len( aMsg )
|
||||
RETURN aMsg[ n + 1 ][ 1 ] + " " + aMsg[ n + 1 ][ 2 ]
|
||||
ENDIF
|
||||
|
||||
RETURN ""
|
||||
@@ -2,15 +2,13 @@
|
||||
|
||||
PROCEDURE Main( cHost, cDatabase, cUser, cPass )
|
||||
|
||||
LOCAL oServer, oQuery, oRow, i, x, aTables, aStruct
|
||||
LOCAL cQuery, oQuery, oRow, i, x
|
||||
|
||||
LOCAL cQuery
|
||||
|
||||
oServer := TPQServer():New( cHost, cDatabase, cUser, cPass )
|
||||
LOCAL oServer := TPQServer():New( cHost, hb_defaultValue( cDatabase, "postgres" ), cUser, cPass )
|
||||
|
||||
IF oServer:NetErr()
|
||||
? oServer:ErrorMsg()
|
||||
QUIT
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
oServer:SetVerbosity( 2 )
|
||||
@@ -18,32 +16,29 @@ PROCEDURE Main( cHost, cDatabase, cUser, cPass )
|
||||
|
||||
? "Tables..."
|
||||
|
||||
FOR x := 1 TO 1
|
||||
aTables := oServer:ListTables()
|
||||
|
||||
FOR i := 1 TO Len( aTables )
|
||||
? aTables[ i ]
|
||||
NEXT
|
||||
FOR EACH i IN oServer:ListTables()
|
||||
? i
|
||||
NEXT
|
||||
|
||||
IF oServer:TableExists( "TEST" )
|
||||
? oQuery := oServer:Execute( "DROP TABLE Test" )
|
||||
IF oServer:TableExists( "test" )
|
||||
? oQuery := oServer:Execute( "DROP TABLE test" )
|
||||
|
||||
oQuery:Destroy()
|
||||
ENDIF
|
||||
|
||||
? "Creating test table..."
|
||||
cQuery := "CREATE TABLE test("
|
||||
cQuery += " Code integer not null primary key, "
|
||||
cQuery += " dept Integer, "
|
||||
cQuery += " Name Varchar(40), "
|
||||
cQuery += " Sales boolean, "
|
||||
cQuery += " Tax Float4, "
|
||||
cQuery += " Salary Double Precision, "
|
||||
cQuery += " Budget Numeric(12,2), "
|
||||
cQuery += " Discount Numeric(5,2), "
|
||||
cQuery += " Creation Date, "
|
||||
cQuery += " Description text ) "
|
||||
cQuery := ;
|
||||
"CREATE TABLE test(" + ;
|
||||
" Code integer not null primary key," + ;
|
||||
" dept Integer," + ;
|
||||
" Name Varchar(40)," + ;
|
||||
" Sales boolean," + ;
|
||||
" Tax Float4," + ;
|
||||
" Salary Double Precision," + ;
|
||||
" Budget Numeric(12,2)," + ;
|
||||
" Discount Numeric(5,2)," + ;
|
||||
" Creation Date," + ;
|
||||
" Description text )"
|
||||
|
||||
oQuery := oServer:Query( cQuery )
|
||||
|
||||
@@ -54,21 +49,20 @@ PROCEDURE Main( cHost, cDatabase, cUser, cPass )
|
||||
oQuery:Destroy()
|
||||
|
||||
? "Structure of test table"
|
||||
aStruct := oServer:TableStruct( "test" )
|
||||
|
||||
FOR i := 1 TO Len( aStruct )
|
||||
FOR EACH i IN oServer:TableStruct( "test" )
|
||||
?
|
||||
FOR x := 1 TO Len( aStruct[ i ] )
|
||||
?? aStruct[ i ][ x ], " "
|
||||
FOR EACH x IN i
|
||||
?? x, ""
|
||||
NEXT
|
||||
NEXT
|
||||
|
||||
? "Inserting, declared transaction control "
|
||||
? "Inserting, declared transaction control"
|
||||
oServer:StartTransaction()
|
||||
|
||||
FOR i := 1 TO 10
|
||||
cQuery := "INSERT INTO test(code, dept, name, sales, tax, salary, budget, Discount, Creation, Description) " + ;
|
||||
"VALUES( " + Str( i ) + ", 2, 'TEST', 'y', 5, 3000, 1500.2, 7.5, '2003-12-17', 'Short Description about what ? ')"
|
||||
"VALUES( " + hb_ntos( i ) + ", 2, 'TEST', 'y', 5, 3000, 1500.2, 7.5, '2003-12-17', 'Short Description about what ?')"
|
||||
|
||||
oQuery := oServer:Query( cQuery )
|
||||
|
||||
@@ -83,13 +77,11 @@ PROCEDURE Main( cHost, cDatabase, cUser, cPass )
|
||||
|
||||
oQuery := oServer:Query( "SELECT code, name, description, sales FROM test" )
|
||||
|
||||
aStruct := oQuery:Struct()
|
||||
|
||||
FOR i := 1 TO Len( aStruct )
|
||||
? aStruct[ i ][ 1 ], aStruct[ i ][ 2 ], aStruct[ i ][ 3 ], aStruct[ i ][ 4 ]
|
||||
FOR EACH i IN oQuery:Struct()
|
||||
? i[ 1 ], i[ 2 ], i[ 3 ], i[ 4 ]
|
||||
NEXT
|
||||
|
||||
? "Fields: ", oQuery:FCount()
|
||||
? "Fields:", oQuery:FCount()
|
||||
|
||||
oRow := oQuery:Blank()
|
||||
|
||||
@@ -130,12 +122,12 @@ PROCEDURE Main( cHost, cDatabase, cUser, cPass )
|
||||
oRow := oQuery:getrow()
|
||||
|
||||
oRow:FieldPut( 2, "My Second test" )
|
||||
? "Update: ", oQuery:Update( oRow )
|
||||
? "Update:", oQuery:Update( oRow )
|
||||
ENDIF
|
||||
|
||||
IF oQuery:RecNo() == 60
|
||||
oRow := oQuery:getrow()
|
||||
? "Delete: ", oQuery:Delete( oRow )
|
||||
? "Delete:", oQuery:Delete( oRow )
|
||||
ENDIF
|
||||
|
||||
oQuery:Skip()
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/*
|
||||
* VERY IMPORTANT: Don't use this querys as sample, they are used for stress tests !!!
|
||||
*/
|
||||
/* IMPORTANT: Don't use these queries as sample, they are used for stress tests!!! */
|
||||
|
||||
#require "hbpgsql"
|
||||
|
||||
PROCEDURE Main( cServer, cDatabase, cUser, cPass )
|
||||
PROCEDURE Main( cHost, cDatabase, cUser, cPass )
|
||||
|
||||
LOCAL conn, res, i, x
|
||||
|
||||
@@ -12,13 +10,18 @@ PROCEDURE Main( cServer, cDatabase, cUser, cPass )
|
||||
|
||||
CLS
|
||||
|
||||
? "Connecting...."
|
||||
conn := PQconnectdb( "dbname = " + cDatabase + " host = " + cServer + " user = " + cUser + " password = " + cPass + " port = 5432" )
|
||||
? "Connecting..."
|
||||
conn := PQconnectdb( ;
|
||||
"dbname = '" + hb_defaultValue( cDatabase, "postgres" ) + "' " + ;
|
||||
"host = '" + hb_defaultValue( cHost, "localhost" ) + "' " + ;
|
||||
"user = '" + hb_defaultValue( cUser, hb_UserName() ) + "' " + ;
|
||||
"password = '" + hb_defaultValue( cPass, "" ) + "' " + ;
|
||||
"port = 5432" )
|
||||
|
||||
? PQstatus( conn ), PQerrorMessage( conn )
|
||||
|
||||
IF PQstatus( conn ) != CONNECTION_OK
|
||||
QUIT
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
? "Dropping table..."
|
||||
@@ -26,55 +29,57 @@ PROCEDURE Main( cServer, cDatabase, cUser, cPass )
|
||||
PQexec( conn, "DROP TABLE test" )
|
||||
|
||||
? "Creating test table..."
|
||||
cQuery := "CREATE TABLE test("
|
||||
cQuery += " Code integer not null primary key, "
|
||||
cQuery += " dept Integer, "
|
||||
cQuery += " Name Varchar(40), "
|
||||
cQuery += " Sales boolean, "
|
||||
cQuery += " Tax Float4, "
|
||||
cQuery += " Salary Double Precision, "
|
||||
cQuery += " Budget Numeric(12,2), "
|
||||
cQuery += " Discount Numeric(5,2), "
|
||||
cQuery += " Creation Date, "
|
||||
cQuery += " Description text ) "
|
||||
cQuery := ;
|
||||
"CREATE TABLE test(" + ;
|
||||
" Code integer not null primary key," + ;
|
||||
" dept Integer," + ;
|
||||
" Name Varchar(40)," + ;
|
||||
" Sales boolean," + ;
|
||||
" Tax Float4," + ;
|
||||
" Salary Double Precision," + ;
|
||||
" Budget Numeric(12,2)," + ;
|
||||
" Discount Numeric(5,2)," + ;
|
||||
" Creation Date," + ;
|
||||
" Description text )"
|
||||
|
||||
PQexec( conn, cQuery )
|
||||
PQexec( conn, "SELECT code, dept, name, sales, salary, creation FROM test" )
|
||||
PQexec( conn, "BEGIN" )
|
||||
|
||||
?
|
||||
FOR i := 1 TO 10000
|
||||
@ 15, 0 SAY "Inserting values...." + Str( i )
|
||||
@ 15, 0 SAY "Inserting values... " + hb_ntos( i )
|
||||
|
||||
cQuery := "INSERT INTO test(code, dept, name, sales, salary, creation) " + ;
|
||||
"VALUES( " + Str( i ) + "," + Str( i + 1 ) + ", 'DEPARTMENT NAME " + StrZero( i ) + "', 'y', " + Str( 300.49 + i ) + ", '2003-12-28' )"
|
||||
"VALUES( " + hb_ntos( i ) + "," + hb_ntos( i + 1 ) + ", 'DEPARTMENT NAME " + StrZero( i ) + "', 'y', " + hb_ntos( 300.49 + i ) + ", '2003-12-28' )"
|
||||
|
||||
PQexec( conn, cQuery )
|
||||
|
||||
IF Mod( i, 100 ) == 0
|
||||
IF i % 100 == 0
|
||||
? PQexec( conn, "COMMIT" )
|
||||
? PQexec( conn, "BEGIN" )
|
||||
ENDIF
|
||||
NEXT
|
||||
|
||||
FOR i := 5000 TO 7000
|
||||
@ 16, 0 SAY "Deleting values...." + Str( i )
|
||||
@ 16, 0 SAY "Deleting values... " + hb_ntos( i )
|
||||
|
||||
cQuery := "DELETE FROM test WHERE code = " + Str( i )
|
||||
cQuery := "DELETE FROM test WHERE code = " + hb_ntos( i )
|
||||
PQexec( conn, cQuery )
|
||||
|
||||
IF Mod( i, 100 ) == 0
|
||||
IF i % 100 == 0
|
||||
PQexec( conn, "COMMIT" )
|
||||
PQexec( conn, "BEGIN" )
|
||||
ENDIF
|
||||
NEXT
|
||||
|
||||
FOR i := 2000 TO 3000
|
||||
@ 17, 0 SAY "Updating values...." + Str( i )
|
||||
@ 17, 0 SAY "Updating values... " + hb_ntos( i )
|
||||
|
||||
cQuery := "UPDATE FROM test SET salary = 400 WHERE code = " + Str( i )
|
||||
cQuery := "UPDATE FROM test SET salary = 400 WHERE code = " + hb_ntos( i )
|
||||
PQexec( conn, cQuery )
|
||||
|
||||
IF Mod( i, 100 ) == 0
|
||||
IF i % 100 == 0
|
||||
PQexec( conn, "COMMIT" )
|
||||
PQexec( conn, "BEGIN" )
|
||||
ENDIF
|
||||
@@ -83,21 +88,20 @@ PROCEDURE Main( cServer, cDatabase, cUser, cPass )
|
||||
res := PQexec( conn, "SELECT sum(salary) as sum_salary FROM test WHERE code between 1 and 4000" )
|
||||
|
||||
IF PQresultStatus( res ) == PGRES_TUPLES_OK
|
||||
@ 18, 0 SAY "Sum values...." + PQgetvalue( res, 1, 1 )
|
||||
@ 18, 0 SAY "Sum values... " + PQgetvalue( res, 1, 1 )
|
||||
ENDIF
|
||||
|
||||
x := 0
|
||||
FOR i := 1 TO 4000
|
||||
res := PQexec( conn, "SELECT salary FROM test WHERE code = " + Str( i ) )
|
||||
res := PQexec( conn, "SELECT salary FROM test WHERE code = " + hb_ntos( i ) )
|
||||
|
||||
IF PQresultStatus( res ) == PGRES_TUPLES_OK
|
||||
x += Val( PQgetvalue( res, 1, 1 ) )
|
||||
|
||||
@ 19, 0 SAY "Sum values...." + Str( x )
|
||||
@ 19, 0 SAY "Sum values... " + hb_ntos( x )
|
||||
ENDIF
|
||||
NEXT
|
||||
|
||||
? "Closing..."
|
||||
conn := NIL
|
||||
|
||||
RETURN
|
||||
|
||||
@@ -1,37 +1,39 @@
|
||||
#require "hbpgsql"
|
||||
|
||||
PROCEDURE Main()
|
||||
PROCEDURE Main( cHost, cDatabase, cUser, cPass )
|
||||
|
||||
LOCAL conn, res, aTemp, x, y, pFile
|
||||
LOCAL cDb := "test"
|
||||
LOCAL cUser := "user"
|
||||
LOCAL cPass := "pass"
|
||||
LOCAL conn, res, x, y, pFile
|
||||
|
||||
CLS
|
||||
|
||||
conn := PQsetdbLogin( "localhost", "5432", NIL, NIL, cDb, cUser, cPass )
|
||||
conn := PQsetdbLogin( cHost, "5432", , , cDatabase, cUser, cPass )
|
||||
? PQdb( conn ), PQuser( conn ), PQpass( conn ), PQhost( conn ), PQport( conn ), PQtty( conn ), PQoptions( conn )
|
||||
|
||||
conn := PQconnectdb( "dbname = " + cDb + " host = localhost user = " + cUser + " password = " + cPass + " port = 5432" )
|
||||
conn := PQconnectdb( ;
|
||||
"dbname = '" + hb_defaultValue( cDatabase, "postgres" ) + "' " + ;
|
||||
"host = '" + hb_defaultValue( cHost, "localhost" ) + "' " + ;
|
||||
"user = '" + hb_defaultValue( cUser, hb_UserName() ) + "' " + ;
|
||||
"password = '" + hb_defaultValue( cPass, "" ) + "' " + ;
|
||||
"port = 5432" )
|
||||
|
||||
? PQstatus( conn ), PQerrorMessage( conn )
|
||||
|
||||
IF PQstatus( conn ) != CONNECTION_OK
|
||||
QUIT
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
? "Blocking: ", PQisnonblocking( conn ), PQsetnonblocking( conn, .T. ), PQisnonblocking( conn )
|
||||
? "Blocking:", PQisnonblocking( conn ), PQsetnonblocking( conn, .T. ), PQisnonblocking( conn )
|
||||
|
||||
pFile := PQtracecreate( "trace.log" )
|
||||
pFile := PQtracecreate( hb_DirBase() + "trace.log" )
|
||||
PQtrace( conn, pFile )
|
||||
|
||||
? "Verbose: ", PQsetErrorVerbosity( conn, 2 )
|
||||
? "Verbose:", PQsetErrorVerbosity( conn, 2 )
|
||||
|
||||
? ;
|
||||
"Protocol: ", PQprotocolVersion( conn ), ;
|
||||
" Server Version: ", PQserverVersion( conn ), ;
|
||||
" Client Encoding: ", PQsetClientEncoding( conn, "ASCII" ), ;
|
||||
"New encode: ", PQclientEncoding( conn )
|
||||
? "Protocol:", PQprotocolVersion( conn )
|
||||
? "Server version:", PQserverVersion( conn )
|
||||
? "Client encoding (old):", pg_encoding_to_char( PQclientEncoding( conn ) )
|
||||
? "Set client encoding:", PQsetClientEncoding( conn, "UTF-8" )
|
||||
? "Client encoding (new):", pg_encoding_to_char( PQclientEncoding( conn ) )
|
||||
|
||||
? PQdb( conn ), PQuser( conn ), PQpass( conn ), PQhost( conn ), PQport( conn ), PQtty( conn ), PQoptions( conn )
|
||||
|
||||
@@ -42,8 +44,8 @@ PROCEDURE Main()
|
||||
res := PQexec( conn, "create table products ( product_no numeric(10), name varchar(20), price numeric(10,2) )" )
|
||||
? PQresultStatus( res ), PQresultErrorMessage( res )
|
||||
|
||||
res := PQexecParams( conn, "insert into products(product_no, name, price) values ($1, $2, $3)", { "2", "bread", "10.95" } )
|
||||
? "Oid Row: ", PQoidValue( res ), PQoidStatus( res )
|
||||
res := PQexecParams( conn, "insert into products( product_no, name, price ) values ($1, $2, $3)", { "2", "bread", "10.95" } )
|
||||
? "Oid Row:", PQoidValue( res ), PQoidStatus( res )
|
||||
|
||||
IF PQresultStatus( res ) != PGRES_COMMAND_OK
|
||||
? PQresultStatus( res ), PQresultErrorMessage( res )
|
||||
@@ -55,16 +57,15 @@ PROCEDURE Main()
|
||||
? PQresultStatus( res ), PQresultErrorMessage( res )
|
||||
ENDIF
|
||||
|
||||
? "Binary: ", PQbinaryTuples( res )
|
||||
? "Rows: ", PQntuples( res ), "Cols: ", PQnfields( res )
|
||||
? "Binary:", PQbinaryTuples( res )
|
||||
? "Rows:", PQntuples( res )
|
||||
? "Cols:", PQnfields( res )
|
||||
? PQfname( res, 1 ), PQftable( res, 1 ), PQftype( res, 1 ), PQfnumber( res, "name" ), PQfmod( res, 1 ), PQfsize( res, 1 ), PQgetisnull( res, 1, 1 )
|
||||
|
||||
aTemp := PQmetadata( res )
|
||||
|
||||
FOR x := 1 TO Len( aTemp )
|
||||
? "Linha 1: "
|
||||
FOR EACH x IN PQmetadata( res )
|
||||
? "Line 1:", ""
|
||||
FOR y := 1 TO 6
|
||||
?? aTemp[ x ][ y ], ", "
|
||||
?? x[ y ], ",", ""
|
||||
NEXT
|
||||
NEXT
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user