Page 1 of 2

tsunami interface beginnings

Posted: Fri Nov 07, 2003 4:07 am
by ppjm99
Thanks to blueb for getting me started,

I modified your code and added some functions.
It took me a while to get the Structure/Pointer stuff figured out.

Anyways here is my tsunami.pbi include file, feel free to help out and add to it. Also blueb ihanged your constant names so they would match the manual, I hope you dont mind.

tsunami.pbi

Code: Select all


; English forum: http://jconserv.net/purebasic/viewtopic.php?t=7698
; Author: blueb modified by ppjm99
; Date: 29. September 2003
; Works For the Tsunami Record Manager - TRMPRO.DLL and TRM.DLL (free version) 
; Version 3.3 ... 2002-09-02 
; the demo sample data and the Tsunami.DLL can be downloaded from: http://www.trm-ug.com 

Structure TsunamiStructure 
    op.l        ; Tsunami operation number 
    file.l      ; Tsunami file handle 
    dataptr.l   ; Address of data buffer 
    datalen.l   ; Length of data buffer 
    keyptr.l    ; Address of key buffer 
    keylen.l    ; Length of key buffer 
    keyno.l     ; Key number 
EndStructure 

Structure TsunamiKeySegment
    title.b[25]
    keyno.b
    keypos.w
    keylen.b
    KeyFlags.b
EndStructure
    
Structure TsunamiFileDef
    PageSize.b
    compression.b
    Segments.b
    segment.TsunamiKeySegment[128]
EndStructure

Global TFD.TsunamiFileDef
Global Tsu.TsunamiStructure
Global FieldCount


;Tsunami Constants
  #CASE_SENSITIVE = 1 
  #NO_DUPLICATES  = 2 
  #NO_COMPRESSION = 4 
  #BINARY_KEY     = 8 
; 
  #KEY_ONLY = 16384 
;  
  #REBUILD_IDS = 2 
;The following EQUATES (constants) represent the Tsunami 
; operation codes (Op) used with the pointer-based APIs... 
#Trm_Accelerate        = 32 
#Trm_Close             =  1 
#Trm_CloseAll          = 28 
#Trm_Count             = 17 
#Trm_Create            = 14 
#Trm_CurrKeyPos        = 45 
#Trm_Delete            =  4 
#Trm_FileIsOpen        = 16 
#Trm_FileMaxIncr       = 41 
#Trm_FileSize          = 18 
#Trm_Flush             = 27 
#Trm_FlushAll          = 29 
#Trm_GetByKeyPos       = 44 
#Trm_GetDirect         = 23 
#Trm_GetEqual          =  5 
#Trm_GetEqualOrGreater =  9 
#Trm_GetEqualOrLess    = 11 
#Trm_GetFileDef        = 36 
#Trm_GetFileVer        = 25 
#Trm_GetFirst          = 12 
#Trm_GetGreater        =  8 
#Trm_GetLast           = 13 
#Trm_GetLess           = 10 
#Trm_GetNext           =  6 
#Trm_GetPosition       = 22 
#Trm_GetPrev           =  7 
#Trm_Insert            =  2 
#Trm_Integrity         = 37 
#Trm_Open              =  0 
#Trm_Rebuild           = 38 
#Trm_Recover           = 39 
#Trm_SetEncryptionKey  = 40 
#Trm_SetKeyPath        = 30 
#Trm_StepFirst         = 33 
#Trm_StepLast          = 34 
#Trm_StepNext          = 24 
#Trm_StepPrev          = 35 
#Trm_TimeOut           = 31 
#Trm_Update            =  3 
#Trm_Version           = 26 
;End of Tsunami Include Information 

;TPB = TsunamiPureBasic

Procedure TPBInitFileDefHdr(PageSize.b,Compress.b,Segments.b)
    TFD\PageSize = 1
    TFD\compression = 1
    TFD\Segments = 1
EndProcedure

Procedure TPBAddFieldDef(Name$,KeyNum.b,SegPos.w,SegLen.b,KeyFlags.b)
    title$ = LSet(Name$,25)
    
    TFD\segment[FieldCount]\title = @title$
    TFD\segment[FieldCount]\keyno = KeyNum
    TFD\segment[FieldCount]\keypos = SegPos
    TFD\segment[FieldCount]\keylen = SegLen
    TFD\segment[FieldCount]\KeyFlags = 0 ;#NO_COMPRESSION & #NO_DUPLICATES
    FieldCount + 1
EndProcedure

Procedure TPBCreateFile(File$,OverWrite.b)
    Tsu\op = #Trm_Create 
    Tsu\file = 0
    Tsu\dataptr = TFD
    Tsu\datalen =  3 + (30 * TFD\Segments)
    Tsu\keyptr = @File$
    Tsu\keylen = Len(File$)
    Tsu\keyno = OverWrite
    Result = CallFunction(0, "trm_udt", @Tsu) 
    
    If Result <> 0 
        MessageRequester("Error", "Error creating file:" + Str(Result), 0) 
        End 
    EndIf 
EndProcedure

Procedure TPBInsertRecord(hFile,Record$)
    Tsu\op = #Trm_Insert 
    Tsu\file = hFile
    Tsu\dataptr = @Record$
    Tsu\datalen =  Len(Record$)
    Result = CallFunction(0, "trm_udt", @Tsu) 
    
    If Result <> 0 
        MessageRequester("Error", "Error inserting record:" + Str(Result), 0) 
        End 
    EndIf 
EndProcedure

Procedure.l TPBOpenTable(FileName$)
    Tsu\op = #Trm_Open
    Tsu\keyptr = @FileName$ 
    Tsu\keylen = Len(FileName$) 
    Tsu\keyno = 0 ; single user 
    Result = CallFunction(0, "trm_udt", @Tsu) 
    
    If Result <> 0 
        MessageRequester("Error", "Sorry, Can't find the data file", 0) 
        End 
    EndIf 
    
    ProcedureReturn Tsu\file
EndProcedure

Procedure TPBCloseTable(hFile)
    Tsu\op = #Trm_Close 
    Tsu\file = hFile
    Result = CallFunction(0, "trm_udt", @Tsu) 
    
    If Result <> 0 
        MessageRequester("Error", "Problem closing the data file: " + Str(Result), 0) 
        End 
    EndIf 
EndProcedure

Procedure.s TPBGetRecord(hFile,keyno,op)
    Record$ = Space(100)
    Tsu\op = op 
    Tsu\dataptr = @Record$
    Tsu\datalen =  Len(Record$)
    Tsu\keyno = keyno
    Result = CallFunction(0, "trm_udt", @Tsu) 
    
    If Result <> 0 
        MessageRequester("Error", "Error getting record:" + Str(Result), 0) 
        End 
    EndIf 
    
    ProcedureReturn Record$
EndProcedure

Procedure TPBAccelerate(hFile,CacheSizeMB)
    Tsu\op = #Trm_Accelerate
    Tsu\file = hFile
    Tsu\keyno = CacheSizeMB
    Result = CallFunction(0, "trm_udt", @Tsu) 
    
    If Result <> 0 
        MessageRequester("Error", "Problem accelerating data file: " + Str(Result), 0) 
        End 
    EndIf 
EndProcedure

Procedure TPBRecordCount(hFile)
    Tsu\op = #Trm_Count
    Tsu\file = hFile
    Result = CallFunction(0, "trm_udt", @Tsu) 
    
    If Result <> 0 
        MessageRequester("Error", "Problem getting record count: " + Str(Result), 0) 
        End 
    EndIf 
    
    ProcedureReturn Tsu\keyno
EndProcedure 

***************************************************
;Example Call to create new table
Procedure CreateDocsTable()
    FieldCount = 0
    TPBAddFieldDef("DocPath",1,1,10,#NO_COMPRESSION & NO_DUPLICATES)
    TPBInitFileDefHdr(1,1,FieldCount)
    TPBCreateFile("docs.dat",1 )
EndProcedure

;Example insert a record
hFile = TPBOpenTable("docs.dat")
Record$ = DocPath$
TPBInsertRecord(hFile,Record$)
TPBCloseTable(hFile)


Posted: Sun Nov 09, 2003 6:17 pm
by blueb
Hi ppjm99,

Thanks for the code, very good work!

I'm in the process of combining our code to produce a usable introduction to the Tsunami record manager.

Unfortunately, I've got work to think about, but I'd like to keep working together to improve what we've got so far.

A little at a time, or so they say. :wink:

Contact me at: blueb@shaw.ca

--blueb

Posted: Sun Nov 09, 2003 7:38 pm
by Kale
This is great, i was about to start a similar project but i think i'll see what you two come up with :twisted:

Re: Tsunami Collaboration

Posted: Tue Nov 11, 2003 2:40 am
by ppjm99
I also have work to think about,

And right now we are right in the final stages of hammering out a release,
you know that last 10% can be brutal, I am not sure what else I will have time for but if I do add to these functions I will post them.

A Fellow Canuck.

Brrr, winter is coming.

But more time for coding Eh!

Posted: Wed Dec 31, 2003 3:50 am
by Kale
Anymore happened on this? :)

Posted: Thu Jan 01, 2004 8:42 pm
by blueb
As ppjm99 said: Brrr Winter is coming....

I just got back from 3 weeks in Puerto Vallarta, Mexico, so I know ppjm99 feels r-e-a-l sorry for me. :P

I'll try to get another example out as soon as I can get re-started!

Regards,
blueb

I don't have any more time right now for this project.

Posted: Thu Jan 08, 2004 2:14 pm
by ppjm99
I am just finishing up a commercial product my company is producing, we are in the homestretch and the pressure to deliver is very great.

Posted: Thu Jan 08, 2004 4:48 pm
by Edwin Knoppert
Hey bob, how did you travel?

Posted: Fri Jan 09, 2004 4:37 am
by blueb
Edwin,

First class... of course! :wink:

Actually, we got delayed a day at the airport in Seattle, Wash. (USA) because of severe storms in the area. Other than that little glitch, everything went very smoothly. We go every winter to P.V. because it's 28 or 29 deg. Celsius.

Great place, great vacation. Now I'm ready to get back to work.

PS - Thanks for updating PBDev so quickly. Helps a lot. :)

--blueb

Tsunami Procedures

Posted: Mon Jan 26, 2004 9:32 pm
by the.weavster
I created these procedures to simplify using the Tsunami dll.
I'm a newbie programmer so if there are inefficiencies or errors in my code be gentle with me.
They seem to work though, just Xinclude this file with your program.
I haven't done all the commands yet, just the ones I needed to get going.

Code: Select all

;Contributed by the.weavster
;I hope they work ok...

;-Define Structures
Structure TFS 
    op.l           ; Tsunami operation number 
    file.l          ; File handle 
    dataptr.l   ; Data buffer address 
    datalen.l   ; Data buffer length
    keyptr.l    ; Key buffer address
    keylen.l    ; Key buffer length 
    keyno.l     ; Key number 
EndStructure

Structure TsunamiTable
FileName.s    ;The name (including full path) of the Tsunami *.DAT file
FileHandle.l   ;Returned by w_open
KeyNo.l        ;The index or 'Key Path'
FileMode.l     ;0=Single User 1=Multi User R/W 2=Multi User RO
RecLength.l   ;Number of characters making up one record
EndStructure

;-Declare global variable
Global Tsu.TFS

;- Internal Procedures
;You will never have to call these from your program code
Procedure ResetTsu()
Tsu\op = 0
Tsu\file = 0
Tsu\dataptr = 0 
Tsu\datalen = 0
Tsu\keyptr = 0
Tsu\keylen = 0
Tsu\keyno = 0
EndProcedure

Procedure ExplainError(ErrCode.l)
Text$ = "Unknown Error"
Select ErrCode
Case 1
   Text$ = "Not A Tsunami File"
Case 2
   Text$ = "I/O Error"
Case 3
   Text$ = "File Not Open"
Case 4
   Text$ = "Key Not Found"
Case 5
   Text$ = "Duplicate Key"
Case 6
   Text$ = "Invalid Key Number"
Case 7
   Text$ = "File Corrupt"
Case 8
   Text$ = "No Current Position"
Case 9
   Text$ = "End Of File"
Case 10
   Text$ = "Invalid Page Size"
Case 11
   Text$ = "Invalid Number Of Key Segments"
Case 12
   Text$ = "Invalid File Definition String"
Case 13
   Text$ = "Invalid Key Segment Postion"
Case 14
   Text$ = "Invalid Key Segment Length"
Case 15
   Text$ = "Inconsistent Key Segment Definitions"
Case 20
   Text$ = "Invalid Record Length"
Case 21
   Text$ = "Invalid Record Pointer" 
Case 22
   Text$ = "Lost Record Position"
Case 30
   Text$ = "Access Denied"
Case 31
   Text$ = "File Already Exists"
Case 32
   Text$ = "No More File Handles"
Case 33
   Text$ = "Max Files Open"
Case 40
   Text$ = "Accelerated Access Denied"
Case 41
   Text$ = "Acceleration Cache Error"
Case 46
   Text$ = "Access To File Denied"
Case 50
   Text$ = "Data Buffer Too Small"
Case 99
   Text$ = "Time Out"
EndSelect
MessageRequester("Error",Text$,#PB_MessageRequester_OK)
EndProcedure
;End of internal procedures 


;-Procedures to replace Tsunami commands start here
Procedure.l w_Open(*tblInfo.TsunamiTable)
;Reset starting values
ResetTsu()
;Initialise variables for this op
FileName$ = *tblInfo\FileName
FileMode.l = *tblInfo\FileMode
 
Tsu\op = 0 ;Open
Tsu\keyptr = @FileName$ 
Tsu\keylen = Len(FileName$) 
Tsu\keyno = FileMode
;Open the data file 
Result = CallFunction(0, "trm_udt", @Tsu)
;Check Response            
If Result <> 0 
    ExplainError(Result)
Else
   FileHandle.l = Tsu\file
EndIf
;Pass back the file handle
ProcedureReturn FileHandle
EndProcedure

Procedure.l w_Count(*tblInfo.TsunamiTable)
;Reset starting values
ResetTsu()
;Initialise variables for this op
Tsu\op = 17 ;Count
Tsu\file = *tblInfo\FileHandle
;Count the records
Result = CallFunction(0,"trm_udt",@Tsu)
;Did it work?
If Result = 0
   RecordCount.l = Tsu\keyno
Else
   ExplainError(Result)
EndIf
;Pass back the number 
ProcedureReturn RecordCount
EndProcedure

Procedure w_SetKeyPath(*tblInfo.TsunamiTable)
;Reset starting values
ResetTsu()
;Initialise variables for this op
Tsu\op = 30 ;Set Key Path
Tsu\file = *tblInfo\FileHandle
Tsu\keyno = *tblInfo\KeyNo
Result = CallFunction(0,"trm_udt",@Tsu)
;Warn user if failed
If Result <> 0
   ExplainError(Result)
EndIf
EndProcedure

Procedure.s w_GetFirst(*tblInfo.TsunamiTable)
ResetTsu()
sRecord$ = ""
FileName$ = *tblInfo\FileName
RecLen.l = *tblInfo\RecLength
sRecord$ = Space(RecLen)

Tsu\op = 12 ;Get First
Tsu\file = *tblInfo\FileHandle
Tsu\keyno = *tblInfo\KeyNo
Tsu\dataptr = @sRecord$
Tsu\datalen = RecLen

If RecLen = 0
   MessageRequester("Error","Record length can not be zero",#PB_MessageRequester_OK)
Else
   Result = CallFunction(0,"trm_udt",@Tsu)
   If Result <> 0
      ExplainError(Result)
   EndIf
EndIf
;Pass back the record
ProcedureReturn (sRecord$)
EndProcedure

Procedure.s w_GetNext(*tblInfo.TsunamiTable)
ResetTsu()
sRecord$ = ""
FileName$ = *tblInfo\FileName
RecLen.l = *tblInfo\RecLength
sRecord$ = Space(RecLen)

Tsu\op = 6 ;Get Next
Tsu\file = *tblInfo\FileHandle
Tsu\keyno = *tblInfo\KeyNo
Tsu\dataptr = @sRecord$
Tsu\datalen = RecLen

If RecLen = 0
   MessageRequester("Error","Record length can not be zero",#PB_MessageRequester_OK)
Else
   Result = CallFunction(0,"trm_udt",@Tsu)
   If Result <> 0
      ExplainError(Result)
   EndIf
EndIf
;Pass back the record
ProcedureReturn (sRecord$)
EndProcedure

Procedure.s w_GetPrevious(*tblInfo.TsunamiTable)
ResetTsu()
sRecord$ = ""
FileName$ = *tblInfo\FileName
RecLen.l = *tblInfo\RecLength
sRecord$ = Space(RecLen)

Tsu\op = 7 ;Get Previous
Tsu\file = *tblInfo\FileHandle
Tsu\keyno = *tblInfo\KeyNo
Tsu\dataptr = @sRecord$
Tsu\datalen = RecLen

If RecLen = 0
   MessageRequester("Error","Record length can not be zero",#PB_MessageRequester_OK)
Else
   Result = CallFunction(0,"trm_udt",@Tsu)
   If Result <> 0
      ExplainError(Result)
   EndIf
EndIf
;Pass back the record
ProcedureReturn (sRecord$)
EndProcedure

Procedure.s w_GetLast(*tblInfo.TsunamiTable)
ResetTsu()
sRecord$ = ""
FileName$ = *tblInfo\FileName
RecLen.l = *tblInfo\RecLength
sRecord$ = Space(RecLen)

Tsu\op = 13 ;Get Last
Tsu\file = *tblInfo\FileHandle
Tsu\keyno = *tblInfo\KeyNo
Tsu\dataptr = @sRecord$
Tsu\datalen = RecLen

If RecLen = 0
   MessageRequester("Error","Record length can not be zero",#PB_MessageRequester_OK)
Else
   Result = CallFunction(0,"trm_udt",@Tsu)
   If Result <> 0
      ExplainError(Result)
   EndIf
EndIf
;Pass back the record
ProcedureReturn (sRecord$)
EndProcedure
   
Procedure w_Insert(*tblInfo.TsunamiTable,Record$)
ResetTsu()
sRecord$ = Record$
RecLen.l = *tblInfo\RecLength

Tsu\op = 2 ;Insert
Tsu\file = *tblInfo\FileHandle
Tsu\dataptr = @sRecord$
Tsu\datalen = RecLen
;Look up the record length from the structure file
Result = CallFunction(0,"trm_udt",@Tsu)
If Result <> 0
   ExplainError(Result)
EndIf
EndProcedure 

Procedure w_Delete(*tblInfo.TsunamiTable)
ResetTsu()
Tsu\op = 4 ;Delete
Tsu\file = *tblInfo\FileHandle
Result = CallFunction(0,"trm_udt",@Tsu)
If Result <> 0
   ExplainError(Result)
EndIf
EndProcedure

Procedure w_Close(*tblInfo.TsunamiTable)
ResetTsu()
Tsu\op = 1 ;Close
Tsu\file = *tblInfo\FileHandle
Result = CallFunction(0,"trm_udt",@Tsu)
If Result <> 0
   ExplainError(Result)
EndIf
EndProcedure

Procedure w_CloseAll()
ResetTsu()
Tsu\op = 28 ;Close All
Result = CallFunction(0,"trm_udt",@Tsu)
If Result <> 0
   ExplainError(Result)
EndIf
EndProcedure

Procedure.l w_Version(*tblInfo.TsunamiTable)
ResetTsu()
Tsu\op = 26 ;Version

Result = CallFunction(0,"trm_udt",@Tsu)
If Result <> 0
   ExplainError(Result)
Else
   lVersion.l = Tsu\KeyNo
EndIf
ProcedureReturn lVersion
EndProcedure

Procedure.l w_CurrKeyPos(*tblInfo.TsunamiTable)
ResetTsu()
Tsu\op = 45 ;Current Key Position
Tsu\file = *tblInfo\FileHandle
Result = CallFunction(0,"trm_udt",@Tsu)
If Result <> 0
   ExplainError(Result)
Else
   lKeyPos.l = Tsu\KeyNo
EndIf
ProcedureReturn lKeyPos
EndProcedure

Procedure w_Accelerate(*tblInfo.TsunamiTable,lCache.l)
ResetTsu()
Tsu\op = 32 ;Accelerate
Tsu\file = *tblInfo\FileHandle
Tsu\KeyNo = lCache
Result = CallFunction(0,"trm_udt",@Tsu)
If Result <> 0
   ExplainError(Result)
EndIf
EndProcedure

Procedure.l w_FileIsOpen(*tblInfo.TsunamiTable)
ResetTsu()
Tsu\op = 16 ;File Is Open
Tsu\file = *tblInfo\FileHandle
Result = CallFunction(0,"trm_udt",@Tsu)
ProcedureReturn Result
EndProcedure      
      
Procedure.l w_FileSize(*tblInfo.TsunamiTable)
ResetTsu()
Tsu\op = 18 ;File Size
Tsu\file = *tblInfo\FileHandle
Result = CallFunction(0,"trm_udt",@Tsu)
If Result <> 0
   ExplainError(Result)
Else
   lFileSize.l = Tsu\KeyNo
EndIf
ProcedureReturn lFileSize
EndProcedure

Procedure.l w_Flush()
ResetTsu()
Tsu\op = 29 ;Flush
Result = CallFunction(0,"trm_udt",@Tsu)
ProcedureReturn Result
EndProcedure

Procedure.s w_GetByKeyPos(*tblInfo.TsunamiTable,lKeyPos.l)
ResetTsu()
sRecord$ = ""
RecLen.l = *tblInfo\RecLength
sRecord$ = Space(RecLen)

Tsu\op = 44 ;Get By Key Position
Tsu\file = *tblInfo\FileHandle
Tsu\dataptr = @sRecord$
Tsu\datalen = RecLen
Tsu\keyno = lKeyPos

If RecLen = 0
   MessageRequester("Error","Record length can not be zero",#PB_MessageRequester_OK)
Else
   Result = CallFunction(0,"trm_udt",@Tsu)
   If Result <> 0
      ExplainError(Result)
   EndIf
EndIf
;Pass back the record
ProcedureReturn (sRecord$)
EndProcedure

Procedure.s w_GetEqual(*tblInfo.TsunamiTable,KeyVal$)
ResetTsu()
sRecord$ = ""
RecLen.l = *tblInfo\RecLength
sRecord$ = Space(RecLen)

Tsu\op = 5 ;Get Equal
Tsu\file = *tblInfo\FileHandle
Tsu\keyno = *tblInfo\KeyNo
Tsu\dataptr = @sRecord$
Tsu\datalen = RecLen
Tsu\KeyPtr = @KeyVal$
Tsu\KeyLen = Len(KeyVal$)

If RecLen = 0
   MessageRequester("Error","Record length can not be zero",#PB_MessageRequester_OK)
Else
   Result = CallFunction(0,"trm_udt",@Tsu)
   If Result <> 0
      ExplainError(Result)
   EndIf
EndIf
;Pass back the record
ProcedureReturn (sRecord$)
EndProcedure

Procedure.s w_GetEqualOrGreater(*tblInfo.TsunamiTable,KeyVal$)
ResetTsu()
sRecord$ = ""
RecLen.l = *tblInfo\RecLength
sRecord$ = Space(RecLen)

Tsu\op = 9 ;Get Equal Or Greater
Tsu\file = *tblInfo\FileHandle
Tsu\keyno = *tblInfo\KeyNo
Tsu\dataptr = @sRecord$
Tsu\datalen = RecLen
Tsu\KeyPtr = @KeyVal$
Tsu\KeyLen = Len(KeyVal$)

If RecLen = 0
   MessageRequester("Error","Record length can not be zero",#PB_MessageRequester_OK)
Else
   Result = CallFunction(0,"trm_udt",@Tsu)
   If Result <> 0
      ExplainError(Result)
   EndIf
EndIf
;Pass back the record
ProcedureReturn (sRecord$)
EndProcedure

Procedure.s w_GetEqualOrLess(*tblInfo.TsunamiTable,KeyVal$)
ResetTsu()
sRecord$ = ""
RecLen.l = *tblInfo\RecLength
sRecord$ = Space(RecLen)

Tsu\op = 11 ;Get Equal Or Less
Tsu\file = *tblInfo\FileHandle
Tsu\keyno = *tblInfo\KeyNo
Tsu\dataptr = @sRecord$
Tsu\datalen = RecLen
Tsu\KeyPtr = @KeyVal$
Tsu\KeyLen = Len(KeyVal$)

If RecLen = 0
   MessageRequester("Error","Record length can not be zero",#PB_MessageRequester_OK)
Else
   Result = CallFunction(0,"trm_udt",@Tsu)
   If Result <> 0
      ExplainError(Result)
   EndIf
EndIf
;Pass back the record
ProcedureReturn (sRecord$)
EndProcedure
Declare your table as a TsunamiTable
e.g.
Global tblCustomer.TsunamiTable

Set the filename, keypath and record length
tblCustomer\FileName = "c:\Data\Customer.dat"
tblCustomer\KeyNo = 1
tblCustomer\RecLength = 500

get the File handle
tblCustomer\FileHandle = w_Open(tblCustomer)

and you're away
now you can just pass the table structure and parameters (string or long) to your procedures and not worry about pointers etc..

the.weavster

Small Update, I understand how keys work a little better now

Posted: Sat Feb 07, 2004 5:53 am
by ppjm99
I now understand that tsunami stores variable length records in a file and allows you to specify by position which parts of the record to maintain indexes for. You can also have multi-part indexes. This is a little out of the ordinary as the unindexed part of the record is completely flexible and the field locations and sizes are based on how you would like to define them at any given time. I was using sqlite but have been getting crashes I can't explain, so I am shifting my focus back to tsunami. In my original tests sqlite seemed slightly faster and I am more familiar with SQL so I chose it, however the instability issues, and the "must increment DBIndex" problem are causing me to look in this direction for now.

Here is a small update to the .pbi file and the test platform. I know there is still lots left to do.

file: tsunami.pbi

Code: Select all

; English forum: http://jconserv.net/purebasic/viewtopic.php?t=7698
; Original Author: blueb, modified by ppjm99
; Date: 29. September 2003
; Works For the Tsunami Record Manager - TRMPRO.DLL and TRM.DLL (free version) 
; Version 3.3 ... 2002-09-02 
; the demo sample data and the Tsunami.DLL can be downloaded from: http://www.trm-ug.com 

Structure TsunamiStructure 
    op.l        ; Tsunami operation number 
    file.l      ; Tsunami file handle 
    dataptr.l   ; Address of data buffer 
    datalen.l   ; Length of data buffer 
    keyptr.l    ; Address of key buffer 
    keylen.l    ; Length of key buffer 
    keyno.l     ; Key number 
EndStructure 

Structure TsunamiKeySegment
    keysegname.b[25]
    keyno.b
    keypos.w
    keylen.b
    keyflags.b
EndStructure
    
Structure TsunamiFileDef
    PageSize.b
    compression.b
    Segments.b
    segment.TsunamiKeySegment[128]
EndStructure

Global TFD.TsunamiFileDef
Global Tsu.TsunamiStructure
Global KeySegCount

#MAX_REC_LENGTH = 2000

;Tsunami Constants
  #CASE_SENSITIVE = 1 
  #NO_DUPLICATES  = 2 
  #NO_COMPRESSION = 4 
  #BINARY_KEY     = 8 
; 
  #KEY_ONLY = 16384 
;  
  #REBUILD_IDS = 2 
;The following EQUATES (constants) represent the Tsunami 
; operation codes (Op) used with the pointer-based APIs... 
#Trm_Accelerate        = 32 
#Trm_Close             =  1 
#Trm_CloseAll          = 28 
#Trm_Count             = 17 
#Trm_Create            = 14 
#Trm_CurrKeyPos        = 45 
#Trm_Delete            =  4 
#Trm_FileIsOpen        = 16 
#Trm_FileMaxIncr       = 41 
#Trm_FileSize          = 18 
#Trm_Flush             = 27 
#Trm_FlushAll          = 29 
#Trm_GetByKeyPos       = 44 
#Trm_GetDirect         = 23 
#Trm_GetEqual          =  5 
#Trm_GetEqualOrGreater =  9 
#Trm_GetEqualOrLess    = 11 
#Trm_GetFileDef        = 36 
#Trm_GetFileVer        = 25 
#Trm_GetFirst          = 12 
#Trm_GetGreater        =  8 
#Trm_GetLast           = 13 
#Trm_GetLess           = 10 
#Trm_GetNext           =  6 
#Trm_GetPosition       = 22 
#Trm_GetPrev           =  7 
#Trm_Insert            =  2 
#Trm_Integrity         = 37 
#Trm_Open              =  0 
#Trm_Rebuild           = 38 
#Trm_Recover           = 39 
#Trm_SetEncryptionKey  = 40 
#Trm_SetKeyPath        = 30 
#Trm_StepFirst         = 33 
#Trm_StepLast          = 34 
#Trm_StepNext          = 24 
#Trm_StepPrev          = 35 
#Trm_TimeOut           = 31 
#Trm_Update            =  3 
#Trm_Version           = 26 
;End of Tsunami Include Information 


Procedure TPBInitFileDefHdr(PageSize.b,Compress.b)
    TFD\PageSize = PageSize
    TFD\compression = Compress
    TFD\Segments = KeySegCount
EndProcedure

Procedure TPBAddKeySegment(KeySegName$,KeyNum.b,SegPos.w,SegLen.b,KeySegFlags.b)
    KeySegName$ = LSet(KeySegName$,25)
    
    TFD\segment[KeySegCount]\keysegname = @KeySegName$
    TFD\segment[KeySegCount]\keyno = KeyNum
    TFD\segment[KeySegCount]\keypos = SegPos
    TFD\segment[KeySegCount]\keylen = SegLen
    TFD\segment[KeySegCount]\keyflags = KeySegFlags ;0 ;#NO_COMPRESSION & #NO_DUPLICATES
    KeySegCount + 1
EndProcedure

Procedure TPBCreateFile(File$,OverWrite.b)
    Tsu\op = #Trm_Create 
    Tsu\file = 0
    Tsu\dataptr = TFD
    Tsu\datalen =  3 + (30 * TFD\Segments)
    Tsu\keyptr = @File$
    Tsu\keylen = Len(File$)
    Tsu\keyno = OverWrite
    Result = CallFunction(0, "trm_udt", @Tsu) 
    
    If Result <> 0 
        MessageRequester("Error", "Error creating file:" + Str(Result), 0) 
        End 
    EndIf 
EndProcedure

Procedure TPBInsertRecord(hFile,Record$)
    Record$=Left(Record$,#MAX_REC_LENGTH)
    
    Tsu\op = #Trm_Insert 
    Tsu\file = hFile
    Tsu\dataptr = @Record$
    Tsu\datalen =  Len(Record$)
    Result = CallFunction(0, "trm_udt", @Tsu) 
    
    If Result <> 0 
        MessageRequester("Error", "Error inserting record:" + Str(Result), 0) 
        End 
    EndIf 
EndProcedure

Procedure.l TPBOpenTable(FileName$)
    Tsu\op = #Trm_Open
    Tsu\keyptr = @FileName$ 
    Tsu\keylen = Len(FileName$) 
    Tsu\keyno = 0 ; single user 
    Result = CallFunction(0, "trm_udt", @Tsu) 
    
    If Result <> 0 
        MessageRequester("Error", "Sorry, Can't find the data file", 0) 
        End 
    EndIf 
    
    ProcedureReturn Tsu\file
EndProcedure

Procedure TPBCloseTable(hFile)
    Tsu\op = #Trm_Close 
    Tsu\file = hFile
    Result = CallFunction(0, "trm_udt", @Tsu) 
    
    If Result <> 0 
        MessageRequester("Error", "Problem closing the data file: " + Str(Result), 0) 
        End 
    EndIf 
EndProcedure

Procedure.s TPBGetRecord(hFile,keyno,op)
    Record$ = Space(#MAX_REC_LENGTH)
    Tsu\op = op 
    Tsu\dataptr = @Record$
    Tsu\datalen =  Len(Record$)
    Tsu\keyno = keyno
    Result = CallFunction(0, "trm_udt", @Tsu) 
    
    If Result <> 0 
        MessageRequester("Error", "Error getting record:" + Str(Result), 0) 
        End 
    EndIf 
    
    ProcedureReturn Record$
EndProcedure

Procedure TPBAccelerate(hFile,CacheSizeMB)
    Tsu\op = #Trm_Accelerate
    Tsu\file = hFile
    Tsu\keyno = CacheSizeMB
    Result = CallFunction(0, "trm_udt", @Tsu) 
    
    If Result <> 0 
        MessageRequester("Error", "Problem accelerating data file: " + Str(Result), 0) 
        End 
    EndIf 
EndProcedure

And some sample code calling this stuff

Code: Select all

IncludeFile "Tsunami.pbi"

Procedure CreateTestTable(TableName$)
    KeySegCount = 0

    ;Two-Part Key 7+10 bytes
    TPBAddKeySegment("KeySeg01",1,1,7,#NO_COMPRESSION & #NO_DUPLICATES) ;Name, Num, Start, Len
    TPBAddKeySegment("KeySeg02",1,11,10,#NO_COMPRESSION & #NO_DUPLICATES) ;Name, Num, Start, Len

    ;One-Part Key 10 bytes
    TPBAddKeySegment("KeySeg03",2,21,10,#NO_COMPRESSION & #NO_DUPLICATES) ;Name, Num, Start, Len

    TPBInitFileDefHdr(1,1) ;Pagesizek 1=1k, 2=2k etc., Compress 1=yes,0=no
    TPBCreateFile(TableName$ + ".dat",1 )
EndProcedure

Procedure Main()
    If OpenLibrary(0, "TRM.DLL") = 0 
        MessageRequester("Error", "Sorry, Can't find the Database Engine", 0) 
        End 
    EndIf 

    MyTable$ = "Test"
    CreateTestTable(MyTable$)
    hFile = TPBOpenTable(MyTable$ + ".dat")
    tt = gettickcount_()
    
    TPBAccelerate(hFile,5) ;Accelerate with 1 mb cache
    For n = 1 To 5000
        TPBInsertRecord(hFile,LSet("Indexed",7)+ LSet(Str(n),10,"0") + LSet(Str(n),10,"0") + "The unindexed part of The record goes here as long as you want up To maxreclength.")
    Next
    TPBAccelerate(hFile,0) ;Turn off accelerate
    
    Debug "Insert took " + Str(gettickcount_() - tt) + " milliseconds"
    
    Record$ = TPBGetRecord(hFile,1,#Trm_GetFirst)
    For n = 1 To 20
        Debug Record$
        Record$ = TPBGetRecord(hFile,1,#Trm_GetNext)
    Next n
    
    TPBCloseTable(hFile)
    
    CloseLibrary(0) 
    
EndProcedure

Main()
End


Posted: Sat Feb 07, 2004 4:50 pm
by blueb
Thanks again ppjm99 for the update. Your Tsunami code is starting to come along nicely.
In my original tests sqlite seemed slightly faster
I found that SQLite was "slower" than Tsunami when I played around with a 30,000 record table.

Here's a link to SQLite's website on when not to use SQLite.
http://www.sqlite.org/cvstrac/wiki?p=WhenToUseSqlite

HTH,
--blueb

Tsunami and Purebasic

Posted: Fri Apr 30, 2004 3:25 pm
by nicksteel
Trying to get started with Purebasic. My windows background is weak, my xbase background (Clipper) strong. From the forum, I think tsunami may be my best option. When I try to run examples, I get windows error (the one that asks if you want to report error to Microsoft).

Exactly which tsumani.dll should I be using?

Could anyone email me a known working example (with necessary files)? If I have a working "go by", I should be able to understand.

I would really appreciate as I'm very confused. I can rewrite my xbase type functions with Purebasic if I can get access to database structures. My applications involve large databases and a lot of indexing.

Posted: Fri Apr 30, 2004 7:40 pm
by the.weavster
Tsunami is very different to xBase. The tables do not have defined fields or types. The indexed part of each record has to be a fixed length and is always at the start of each record. The data part can be fixed length, variable length, delimited or whatever. The Tsunami commands work with records, it's up to you to pick out the fields.

I don't think the string API works with PB you have to use the pointer API.
I included a list of procedures above which simplify using the Tsunami library "TRMPRO.DLL" available from: http://www.trm-ug.com

These were my first ever attempt at programming (apart from MS Access and I'm not sure that counts). I have revised them since, maybe I'll post the new versions here later. These should get you started though.

I still think the Apollo API maybe easier for an xBase programmer to master. Go to http://www.xHarbour.com and download the demo, the fully functioning API *.DLLs and a help file are included in the harbour zip file.

Weave

P.S. Have you checked out:
http://www.codebase.com
or xBase++
or Flagship
or MS Visual Foxpro
or Delphi and Topaz
or Alpha 5

Posted: Sat May 01, 2004 2:35 pm
by blueb
I too have an interest in database programming.

I've sold many commercial programs with Alpha Five. (used it since 1987)

I also use Apollo with Purebasic (works well). While it's reasonably fast, Cheetah (designed with PowerBASIC) outruns them all, but I haven't been able to get the API to work with PureBasic yet. I need to figure out Pure's CallFunction or CallCFunction use for this DLL. Some parts work... others don't. Very confusing.

Tsunami is very fast as well, but I still need to work on it.

blueb