Files
harbour-core/harbour/contrib/hbpgsql/tests/cache.prg
Viktor Szakats df2b7a9ebd 2012-10-31 13:25 UTC+0200 Viktor Szakats (harbour syenar.net)
* include/harbour.hbx
    * fixes/changes to some function names

  * config/hb_c.cfg
    + updated to do better vertical aligment in
      structs, var declarations and assignments
    ; TODO: move this to /bin folder and add to 'install'-ed
            file list, rename to 'harbour.ucf'

  * src/debug/*.prg
  * src/rdd/*.prg
  * src/rdd/hbsix/*.prg
  * src/rdd/usrrdd/rdds/*.prg
  * src/rtl/*.prg
  * src/vm/*.prg
  * utils/hbi18n/hbi18n.prg
  * utils/hbmk2/hbmk2.prg
  * utils/hbmk2/examples/*.hb
  * contrib/hbblat/blatcls.prg
  * contrib/gtwvg/*.prg
  * contrib/gtwvg/tests/*.prg
  * contrib/hbblink/*.prg
  * contrib/hbcairo/tests/*.prg
  * contrib/hbcomm/*.prg
  * contrib/hbcomm/tests/*.prg
  * contrib/hbcups/tests/*.prg
  * contrib/hbcurl/tests/*.prg
  * contrib/hbexpat/*.prg
  * contrib/hbexpat/tests/*.prg
  * contrib/hbfbird/*.prg
  * contrib/hbfbird/tests/*.prg
  * contrib/hbfoxpro/*.prg
  * contrib/hbfship/*.prg
  * contrib/hbgd/*.prg
  * contrib/hbgd/tests/*.prg
  * contrib/hbgs/tests/*.prg
  * contrib/hbhpdf/*.prg
  * contrib/hbhpdf/tests/*.prg
  * contrib/hbhttpd/*.prg
  * contrib/hbhttpd/tests/*.prg
  * contrib/hblzf/tests/*.prg
  * contrib/hbmagic/tests/*.prg
  * contrib/hbmisc/*.prg
  * contrib/hbmisc/tests/*.prg
  * contrib/hbct/*.prg
  * contrib/hbct/tests/*.prg
  * contrib/hbmlzo/tests/*.prg
  * contrib/hbmxml/*.prg
  * contrib/hbmxml/tests/*.prg
  * contrib/hbmysql/*.prg
  * contrib/hbmysql/tests/*.prg
  * contrib/hboslib/*.prg
  * contrib/hbsms/*.prg
  * contrib/hbtinymt/tests/*.prg
  * contrib/hbtpathy/*.prg
  * contrib/hbtpathy/tests/*.prg
  * contrib/hbunix/tests/*.prg
  * contrib/hbxdiff/tests/*.prg
  * contrib/hbzebra/tests/*.prg
  * contrib/hbziparc/*.prg
  * contrib/hbziparc/tests/*.prg
  * contrib/rddads/*.prg
  * contrib/rddads/tests/*.prg
  * contrib/hbodbc/*.prg
  * contrib/hbodbc/tests/*.prg
  * contrib/hbpgsql/*.prg
  * contrib/hbpgsql/tests/*.prg
  * contrib/hbsqlit3/*.prg
  * contrib/hbsqlit3/tests/*.prg
  * contrib/hbwin/*.prg
  * contrib/hbwin/tests/*.prg
  * contrib/hbxpp/*.prg
  * contrib/hbxpp/tests/*.prg
  * contrib/hbxhb/*.prg
  * contrib/hbxhb/tests/*.prg
  * contrib/hbnetio/*.prg
  * contrib/hbnetio/utils/hbnetio/*.hb
  * contrib/hbnetio/utils/hbnetio/*.prg
  * contrib/hbtip/*.prg
  * contrib/hbtip/tests/*.prg
  * tests/usrrdd/*.prg
  * tests/funcarr.prg
  * extras/gfspell/spell.prg
  * extras/gtwvw/tests/*.prg
  * extras/guestbk/*.prg
  * extras/hbdoc/*.prg
  * extras/rddado/*.prg
  * extras/rddado/tests/*.prg
  * extras/hbxlsxml/*.prg
  * extras/httpsrv/*.prg
  * extras/httpsrv/modules/*.prg
  * extras/hbsuper/*.prg
  * extras/hbvpdf/*.prg
  * extras/hbvpdf/tests/*.prg
  * tests/*.prg (except some which are well formatted but in different/fast-typing style)
  * tests/*.hb
  * bin/*.hb
  * contrib/*.hb
  * config/*.hb
    * some manual formatting to better be able to verify
      changes made by hbformat and be friendlier with hbformat.
    * most files reformatted with hbformat using Maurizio's
      patch, with mostly minor manual corrections and verification.
      All hbformat changes for revised one-by-one.
    ! __DIR(): fixed to be unicode compatible
    ! __hbdoc_ToSource(): make sure to not generate line ending
      spaces in output.
    + hbmk2/hbrun: HBMK_WITH_GTXWC built-time option to include
      GTXWC. Useful for hbrun.
    * hbct tests: change to not use [] as string delimiter
    + added full prototypes to Array class declaration

  ; NOTE: Only these were not or not fully formatted:
          contrib/hbnetio/tests/*.prg
          tests/hbpptest/*.prg
          tests/mt/*.prg
          tests/multifnc/*.prg
          tests/rddtest/*.prg
          utils/hbmk2/hbmk2.prg (for the most part)
          src/rtl/tbrowse.prg (for the most part)
          utils/hbtest/*.prg
          *.ch, *.c, *.h

  * src/rtl/cdpapihb.c
  * src/rtl/hbadler.c
  * src/rtl/hbsocket.c
  * src/rtl/sha1.c
  * src/vm/classes.c
  * src/vm/dynsym.c
  * src/vm/garbage.c
  * src/debug/dbgentry.c
    * do not end macros with ';' to avoid uncrustify warning
      and wrong formatting as a consequence

  * src/compiler/cmdcheck.c
    * minor changes for uncrustify-friendliness

  * contrib/hbformat/utils/hbfmtcls.prg
  * contrib/hbformat/utils/hbformat.prg
    % optimizations in hbformat.prg
    ! fixed mask/filename handling to be
      multiplatform in hbformat.prg
    + added 'HBXList=' hbformat.ini parameter allowing
      to add any .hbx file for proper function name
      casing.
    ! fixed progress bar to display correctly

  * tests/speedstr.prg
    ! fixed to run as intended in unicode code
    * hbformatted

  - contrib/hbwin/tests/dlg.xml
  * contrib/hbwin/tests/dlg.rc
  - extras/gtwvw/tests/wvwtest9.xml
  + extras/gtwvw/tests/wvwtest9.mft
  * extras/gtwvw/tests/wvwtest9.rc
    * renamed manifest to have .mft extension
    % deleted unnecessary manifest
    * "Win32 API" -> "Windows API"
    ! deleted CPU arch from manifest

  * package/harb_win.mft
    * formatting

  * src/common/hbver.c
    + added version detection for win 8 and win server 2012
    * minor formatting/code cleanup

  * tests/gfx.prg
    * updated to run in script mode.
    ; TOFIX: it doesn't draw anything with GTWVT

  * tests/gfx.prg
  * tests/gtwin.prg
  * tests/gtxfnt.prg
  * tests/wvt_fs.prg
  * tests/wvtext.prg
    + support for GTXWC when run as script

  * doc/en/*.txt
  * contrib/hbct/doc/en/*.txt
  * contrib/hbgd/doc/en/*.txt
  * contrib/hbgt/doc/en/*.txt
  * contrib/hbmisc/doc/en/*.txt
  * contrib/hbnf/doc/en/*.txt
  * contrib/hbziparc/doc/en/*.txt
  * contrib/rddads/doc/en/*.txt
    ! fixed few broken tags reported by Carlos
    % deleted line ending spaces
    * some minor formatting

  * contrib/hbnf/*.c
  * contrib/hbnf/*.h
  * extras/gfspell/spellc.c
    * uncrustified with updated hb_c.cfg

  * contrib/hbnf/*.prg
  * contrib/hbnf/tests/*.prg
    * hbformatted with Mauriozo's patch.
    * a few manual corrections (avoiding #translates, using hb_ColorIndex())
      in general and to make hbformat happy.

  + contrib/hbnf/tests/menuto.prg
    + added sample code for MENU TO (adatped from docs)

  - src/rdd/dbfntx/dbfntx0.prg
    - deleted unused file with no enabled code in it

  * contrib/hbtip/tests/dbtohtml.prg
  * contrib/hbtip/tests/loadhtml.prg
  * contrib/hbtip/tests/tipmmail.prg
    * minor cleanups

  * contrib/hbtip/thtml.prg
    ! fixed typo due to s&r
    % use hb_memowrit()

  * src/rtl/tbrowse.prg
    * conditional code sorted to be hbformat friendly
    * some formatting

  * INSTALL
  * package/harbour.rb
  * package/mpkg_src_nightly.sh
  * package/mpkg_win_nightly.bat
  * package/updt_web_nightly.sh
  * website/changelog.html
  * website/faq/harbour17.html
  * website/faq/harbour27.html
  * website/index.html
  * website/menu/harbour-menu.js
    * updated repository URL to new sf.net one

  * tests/function.cfm
  * contrib/hbhttpd/tests/tpl/_main.tpl
  * contrib/hbtip/tests/tipmmail.prg
  * website/faq/*.html
  * website/samples/*.html
    * use utf-8 in html and email

  * contrib/hbrun/hbrun.hbp
    + support for HBMK_WITH_GTXWC

  * tests/rto_get.prg
  * tests/onidle.prg
  * tests/mousetst.prg
  * tests/wcecon.prg
  * tests/vmasort.prg
  - contrib/hbnf/tests/metaph.prg
    * minor cleanups

  * contrib/hbmysql/tests/test.prg
  * contrib/hbmysql/tests/dbf2mysq.prg
    % minor optimization, deleted outdated comment/line

  * src/compiler/harbour.yyc
  * src/compiler/harbour.y
    * minor formatting
2012-10-31 13:04:01 +00:00

582 lines
12 KiB
Plaintext

/*
* $Id$
*/
/*
* This samples show how to use dbf to cache postgres records.
*/
#require "hbpgsql"
#include "postgres.ch"
#define DB_ALIAS 1
#define DB_FILE 2
#define DB_QUERY 3
#define DB_ROW 4
#define DB_FETCH 5
STATIC s_oServer
STATIC s_aTableTemp := {}
STATIC s_aTempDBF := {}
PROCEDURE Main( cServer, cDatabase, cUser, cPass )
LOCAL i
LOCAL cQuery
IF SQLConnect( cServer, cDatabase, 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 )
SQLOpen( "nomes", "SELECT * FROM test" )
FOR i := 1 TO 50
APPEND BLANK
REPLACE codigo WITH i
REPLACE descri WITH "test " + Str( i )
NEXT
SQLApplyUpdates()
cQuery := "SELECT * FROM test WHERE codigo >= :1 ORDER BY codigo"
cQuery := SQLPrepare( cQuery, 1 )
SQLOpen( "nomes", cQuery )
DO WHILE ! Eof()
? RecNo(), nomes->Codigo, nomes->descri, nomes->email
IF RecNo() == 10
DELETE
ENDIF
IF RecNo() == 20
REPLACE email WITH "teste"
ENDIF
SQLFetch()
ENDDO
SQLApplyUpdates()
ENDIF
SQLGarbageCollector()
RETURN
/* Put theses functions in a library */
FUNCTION SQLApplyUpdates()
LOCAL cAlias := Upper( Alias() )
LOCAL i, x
LOCAL oQuery
LOCAL oRow
LOCAL lUpdate
LOCAL lError := .F.
LOCAL cError
i := AScan( s_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } )
IF i != 0
oQuery := s_aTableTemp[ i ][ 3 ]
FOR i := 1 TO LastRec()
dbGoto( i )
IF i > oQuery:LastRec()
/* Verifica se eh um registro novo */
IF ! Deleted()
oRow := oQuery:GetBlankRow()
FOR x := 1 TO FCount()
IF oRow:FieldPos( FieldName( x ) ) != 0
oRow:FieldPut( FieldName( x ), FieldGet( x ) )
ENDIF
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
/* Faz update, mas compara quais campos sao diferentes */
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
ENDIF
NEXT
IF lUpdate
oQuery:Update( oRow )
cError := oQuery:ErrorMsg()
lError := oQuery:NetErr()
ENDIF
ENDIF
ENDIF
IF lError
EXIT
ENDIF
NEXT
ENDIF
IF lError
Alert( cError )
ENDIF
RETURN ! lError
PROCEDURE SQLCloseTemp( cAlias )
LOCAL x
IF ! Empty( Select( cAlias ) )
CLOSE &calias
ENDIF
x := AScan( s_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } )
IF ! Empty( x )
ADel( s_aTableTemp, x )
// ASize( s_aTableTemp, Len( s_aTableTemp ) - 1 )
ENDIF
RETURN
PROCEDURE SQLGarbageCollector()
LOCAL i
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
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 := {}
RETURN
FUNCTION SQLFetch( fetchall )
LOCAL oQuery
LOCAL oRow
LOCAL cAlias := Upper( Alias() )
LOCAL i, x, y
LOCAL nPos
LOCAL lEof := .F.
hb_default( @Fetchall, .F. )
/* Procura pela tabela no array */
i := AScan( s_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } )
IF i != 0
/* Traz registros da base de dados */
oQuery := s_aTableTemp[ i ][ DB_QUERY ]
nPos := s_aTableTemp[ i ][ DB_ROW ] + 1
IF Fetchall
s_aTableTemp[ i ][ DB_FETCH ] := .T.
ENDIF
IF oQuery:LastRec() >= nPos
y := nPos
DO WHILE nPos <= iif( FetchAll, oQuery:LastRec(), y )
oRow := oQuery:GetRow( nPos )
dbAppend()
FOR x := 1 TO oRow:FCount()
FieldPut( FieldPos( oRow:FieldName( x ) ), oRow:FieldGet( x ) )
NEXT
s_aTableTemp[ i ][ DB_ROW ] := nPos
nPos++
ENDDO
ELSE
// Posiciona registro no eof
dbSkip()
ENDIF
lEof := nPos > oQuery:LastRec()
ENDIF
RETURN lEof
PROCEDURE SQLFetchAll()
SQLFetch( .T. )
dbGoTop()
RETURN
FUNCTION SQLOpen( cAlias, cQuery, xFetch, cOrder )
LOCAL cFile
LOCAL Result := .T.
LOCAL x
LOCAL s_oServer
LOCAL oQuery
LOCAL aStrudbf
LOCAL lFetch
s_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 ]
oQuery:Destroy()
ENDIF
IF cQuery == NIL
cQuery := "SELECT * FROM " + cAlias
IF ! Empty( cOrder )
cQuery += " ORDER BY " + cOrder
ENDIF
ENDIF
cQuery := cQuery
oQuery := s_oServer:Query( cQuery )
IF oQuery:NetErr()
Alert( 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. )
ELSE
SELECT &cAlias
ZAP
ENDIF
IF xFetch != NIL
lFetch := xFetch
ELSE
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
ELSE
s_aTableTemp[ x ][ DB_QUERY ] := oQuery
s_aTableTemp[ x ][ DB_ROW ] := 0
s_aTableTemp[ x ][ DB_FETCH ] := lFetch
ENDIF
/* Traz registros da base de dados */
SQLFetch( lFetch )
IF lFetch
dbGoTop()
ENDIF
RETURN result
FUNCTION SQLConnect( cServer, 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() )
lRetval := .F.
ENDIF
s_oServer:lAllCols := .F.
RETURN lRetval
PROCEDURE SQLDestroy()
IF s_oServer != NIL
s_oServer:Destroy()
ENDIF
RETURN
FUNCTION SQLCurrentServer
RETURN s_oServer
FUNCTION SQLQuery( cQuery )
LOCAL oQuery := s_oServer:Query( cQuery )
IF oQuery:NetErr()
Alert( cQuery + ":" + oQuery:ErrorMsg() )
ENDIF
RETURN oQuery
FUNCTION SQLExecQuery( cQuery )
LOCAL oQuery
LOCAL result := .T.
oQuery := s_oServer:Query( cQuery )
IF oQuery:NetErr()
Alert( "Cannot execute " + cQuery + ":" + oQuery:ErrorMsg() )
result := .F.
ELSE
oQuery:Destroy()
ENDIF
RETURN result
FUNCTION SQLPrepare( cQuery, ... )
LOCAL i, x
IF PCount() >= 2
/* Limpa espacos desnecessarios */
DO WHILE At( Space( 2 ), cQuery ) != 0
cQuery := StrTran( cQuery, Space( 2 ), Space( 1 ) )
ENDDO
/* Coloca {} nos parametros */
FOR i := 1 TO PCount() - 1
IF ! Empty( x := At( ":" + hb_ntos( i ), cQuery ) )
cQuery := Stuff( cQuery, x, 0, "{" )
cQuery := Stuff( cQuery, x + Len( hb_ntos( i ) ) + 2, 0, "}" )
ENDIF
NEXT
/* Substitui parametros por valores passados */
FOR i := 2 TO PCount()
x := hb_PValue( i )
IF x != NIL .AND. Empty( x )
x := "null"
ELSEIF HB_ISNUMBER( x )
x := hb_ntos( x )
ELSEIF HB_ISDATE( x )
x := DToQ( x )
ELSEIF HB_ISLOGICAL( x )
x := iif( x, "'t'", "'f'" )
ELSEIF HB_ISSTRING( x )
x := SToQ( RTrim( x ) )
ELSE
x := "null"
ENDIF
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 cQuery
/* Pega resultado de uma 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()
ENDIF
RETURN
FUNCTION SQLInTrans()
RETURN PQtransactionstatus( s_oServer:pDB ) == PQTRANS_INTRANS
PROCEDURE SQLCommitTrans()
s_oServer:Commit()
RETURN
PROCEDURE SQLRollbackTrans()
s_oServer:rollback()
RETURN
/* Faz querie que retorna apenas 1 valor de coluna */
FUNCTION QuickQuery( cQuery )
LOCAL pQuery
LOCAL result := ""
LOCAL temp, aTemp
LOCAL x, y
pQuery := PQexec( s_oServer:pDB, cQuery )
IF PQresultstatus( pQuery ) == PGRES_TUPLES_OK
IF PQLastrec( pQuery ) != 0
IF PQFcount( pQuery ) == 1 .AND. PQLastrec( pQuery ) == 1
temp := PQGetValue( pQuery, 1, 1 )
result := iif( temp == NIL, "", temp )
ELSE
result := {}
FOR x := 1 TO PQLastrec( pQuery )
aTemp := {}
FOR y := 1 TO PQfcount( pQuery )
temp := PQGetValue( pQuery, x, y )
AAdd( aTemp, iif( temp == NIL, "", temp ) )
NEXT
AAdd( result, aTemp )
NEXT
ENDIF
ENDIF
ENDIF
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 + "'"