How to build DBF > 2 GB

Moderator: Rathinagiri

Post Reply
User avatar
AUGE_OHR
Posts: 2093
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany

How to build DBF > 2 GB

Post by AUGE_OHR »

Hi,

i know that harbour can use DBF > 2 GB under 64 Bit using DB_DBFLOCK_HB64
but how to create a DBF > 2 GB ?
have fun
Jimmy
User avatar
danielmaximiliano
Posts: 2625
Joined: Fri Apr 09, 2010 4:53 pm
Location: Argentina
Contact:

Re: How to build DBF > 2 GB

Post by danielmaximiliano »

*´¨)
¸.·´¸.·*´¨) ¸.·*¨)
(¸.·´. (¸.·` *
.·`. Harbour/HMG : It's magic !
(¸.·``··*

Saludos / Regards
DaNiElMaXiMiLiAnO

Whatsapp. := +54901169026142
Telegram Name := DaNiElMaXiMiLiAnO
User avatar
AUGE_OHR
Posts: 2093
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany

Re: How to build DBF > 2 GB

Post by AUGE_OHR »

thx for the Link.
but how to setup DBF to use DB_DBFLOCK_HB64

i´m not able to create a DBF to use more than 2 GB
have fun
Jimmy
edk
Posts: 999
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland

Re: How to build DBF > 2 GB

Post by edk »

This code below creates a dbf file over 4 GB in size, I set the locking scheme to DB_DBFLOCK_HB64 and did not notice any problems with accessing the records. I compiled in 64 bits using hmg 3.6.

Code: Select all

#include "dbinfo.ch"

proc main()
local i, n := int(2^22) + 10, nStep := int ( n / 50 ), cF1, nId, nRow, nCol

   SET DBFLOCKSCHEME TO DB_DBFLOCK_HB64

   if !file("tst4GB.dbf")
      ? "Building tst4GB.dbf..., be patient ..."
      ? REPLICATE ( Chr ( 177 ), 50 )
      DevPos( ROW(), COL()-50 )
      dbcreate("tst4GB.dbf",{{"F1","C",1023,0}, {"id","+",4,0}})
      use tst4GB exclusive
      for i:=1 to n
         dbappend()
         replace F1 with str(i,10)
         IF i%nStep = 0 
	      ?? Chr ( 219 )
         endif
      next i
      close
      ?? " 100% done"
   endif
   use tst4GB shared alias tst1 new
   use tst4GB shared alias tst2 new
   ? "records:", tst1->(lastrec()), ;
      ", size:", tst1->(header())+tst1->(lastrec())*tst1->(recsize())

   ? "Alias tst1 goto:", lastrec(), tst1->(dbgoto(lastrec()))
   ? "Alias tst1 recno():", tst1->(recno()), "->", alltrim(tst1->(fieldget(1))), "->" , tst1->(fieldget(2))
   ? "Alias tst2 goto:", lastrec(), tst2->(dbgoto(lastrec()))
   ? "Alias tst2 recno():", tst2->(recno()), "->", alltrim(tst2->(fieldget(1))), "->" , tst2->(fieldget(2))
   ? "Alias tst1 FLOCK: ", tst1->(flock())

   ? "Testing reading of alias tst2 records when the file is locked in alias tst1 ..."
   ? REPLICATE ( Chr ( 177 ), 50 )
   DevPos( ROW(), COL()-50 )
   for i:=1 to n
	tst2->(dbgoto(i))
        cF1 := alltrim(tst2->(fieldget(1)))
	nId := tst2->(fieldget(2))
        IF i%nStep = 0 
	    ?? Chr ( 219 )
	    nCol := Col()
            nRow := Row()
            ? "RecNo:", tst2->(recno()), "F1:", cF1, "Id:", nId
	    DevPos( nRow, nCol )
        endif
   next i
   ?? " 100% done"
   ? "RecNo:", tst2->(recno()), "F1:", cF1, "Id:", nId
   ? "Press any key to exit ..."

   close all
   inkey ( 0 )
return
Last edited by edk on Fri Jun 21, 2024 6:39 pm, edited 1 time in total.
User avatar
AUGE_OHR
Posts: 2093
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany

Re: How to build DBF > 2 GB

Post by AUGE_OHR »

hi Edward,

Code: Select all

 dbcreate("tst4GB.dbf",{{"F1","C",1023,0}, {"id","+",4,0}})
you are absolute right.

i was not aware that Field Type C can have more than 256 length under Harbour 64 BIt
Thx for your Demo to make it clear to me
have fun
Jimmy
edk
Posts: 999
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland

Re: How to build DBF > 2 GB

Post by edk »

The code below shows what effect the choice of locking scheme has when working with large DBF files:

Code: Select all

#include "dbinfo.ch"
REQUEST HB_GT_WIN_DEFAULT

proc main()
local i, n := int(2^22) + 10, nStep := int ( n / 50 )

   ErrorBlock( { | oError | NewError( oError ) } )

   SET DBFLOCKSCHEME TO DB_DBFLOCK_HB64

   ? "DBF lock scheme is DB_DBFLOCK_HB64."

   if !file("tst4GB.dbf")
      ? "Building tst4GB.dbf..., be patient ..."
      ? REPLICATE ( Chr ( 177 ), 50 )
      DevPos( ROW(), COL()-50 )
      dbcreate("tst4GB.dbf",{{"F1","C",1023,0}, {"id","+",4,0}})
      use tst4GB exclusive
      for i:=1 to n
         dbappend()
         replace F1 with str(i,10)
         IF i%nStep = 0 
	      ?? Chr ( 219 )
         endif
      next i
      close
      ?? " 100% done"
   endif
   use tst4GB shared alias tst1 new
   use tst4GB shared alias tst2 new
   ? "records:", tst1->(lastrec()), ;
      ", size:", tst1->(header())+tst1->(lastrec())*tst1->(recsize())

   ? "Alias tst1 FLOCK: ", tst1->(flock())

   ? "Testing reading of alias tst2 records when the file is locked in alias tst1 ..."

   MakeTest ( n, nStep )
   
   tst1->(dbUnlock())
   close all
   SET DBFLOCKSCHEME TO

   ?
   ? "DBF lock scheme is default."

   use tst4GB shared alias tst1 new
   use tst4GB shared alias tst2 new
   ? "records:", tst1->(lastrec()), ;
      ", size:", tst1->(header())+tst1->(lastrec())*tst1->(recsize())

   ? "Alias tst1 FLOCK: ", tst1->(flock())
 
   ? "Same test with default DBF lock scheme ..."

   MakeTest ( n, nStep )
   ? "Press any key to exit ..."

   close all
   inkey ( 0 )
return
****************************************************
Function MakeTest ( n, nStep )
Local i, cF1, nId, nRow, nCol
? REPLICATE ( Chr ( 177 ), 50 )
DevPos( ROW(), COL()-50 )
nCol := Col()
nRow := Row()

for i:=1 to n
    tst2->(dbgoto(i))
    cF1 := alltrim(tst2->(fieldget(1)))
    nId := tst2->(fieldget(2))
    if i%nStep = 0
        DevPos( nRow, nCol )        
        ?? Chr ( 219 )
        nCol := Col()
        nRow := Row()
        ? "RecNo:", tst2->(recno()), "F1:", cF1, "Id:", nId
   endif
next i
?? " 100% done"
? "RecNo:", tst2->(recno()), "F1:", cF1, "Id:", nId

RETURN Nil
****************************************************
FUNCTION NewError( oError )
   LOCAL cMessage
   LOCAL n

   #include "error.ch"
   #INCLUDE "COMMON.CH"

   // By default, division by zero results in zero
   IF oError:genCode == EG_ZERODIV
      RETURN 0
   ENDIF

   // Set NetErr() of there was a database open error
   IF oError:genCode == EG_OPEN .AND. ;
      oError:osCode == 32 .AND. ;
      oError:canDefault
      NetErr( .T. )
      RETURN .F.
   ENDIF

   // Set NetErr() if there was a lock error on dbAppend()
   IF oError:genCode == EG_APPENDLOCK .AND. ;
      oError:canDefault
      NetErr( .T. )
      RETURN .F.
   ENDIF

   cMessage := ErrorMessage( oError )

   IF ! Empty( oError:osCode )
      cMessage += " " + "(DOS Error " + LTRIM( STR( oError:osCode ) ) + ")"
   ENDIF

   n := 2
   cMessage += CHR(13) + CHR (10) + CHR(13) + CHR (10)
   WHILE ! Empty( ProcName( n ) )
      cMessage += "Called from " + ProcName( n ) + "(" + ALLTRIM( STR( ProcLine( n++ ) ) ) + ")" +CHR(13) +CHR(10)
   ENDDO

   ? cMessage
   ? "Press any key..."
   inkey ( 0 )
   quit 

   RETURN .F.


************************************************************************************************
STATIC FUNCTION ErrorMessage( oError )
   LOCAL cMessage, n

   // start error message
   cMessage := iif( oError:severity > ES_WARNING, "Error", "Warning" ) + " "

   // add subsystem name if available
   IF ISCHARACTER( oError:subsystem )
      cMessage += oError:subsystem()
   ELSE
      cMessage += "???"
   ENDIF

   // add subsystem's error code if available
   IF ISNUMBER( oError:subCode )
      cMessage += "/" + LTRIM( STR( oError:subCode ) )
   ELSE
      cMessage += "/???"
   ENDIF

   // add error description if available
   IF ISCHARACTER( oError:description )
      cMessage += "  " + oError:description
   ENDIF

   // add either filename or operation
   IF !Empty( oError:filename )
      cMessage += ": " + oError:filename  + CHR( 13 ) + CHR( 10 )
   ENDIF
   IF !Empty( oError:operation )
      cMessage += ": " + oError:operation + CHR( 13 ) + CHR( 10 )
   ENDIF

   // add oError:Args
   if ValType( oError:Args ) == "A"              
       cMessage += "   Arguments   :" + CHR( 13 ) + CHR( 10 )
       FOR n = 1 to Len( oError:Args )
           cMessage += "     [" + Str( n, 4 ) + "] = " + ValType( oError:Args[ n ] ) + ;
                        "   " + hb_valToExp( oError:Args[ n ] ) + CHR( 13 ) + CHR( 10 )
       NEXT
   ENDIF
   IF !Empty ( Alias () )
   	cMessage += "   Alias: " + Alias()
   ENDIF

   RETURN cMessage
**********************************************************************
Post Reply