Alpes Software Homepage Real Isam Home Page


Summary Main WordsA B C D E F G H I J K L M N O P Q R S T U V W X Y Z Other


Test Application


Principles


The goal of this application is to build a dictionary from sequential files provided by the webster dictionnary. Each sequential file is associated to a letter : wb_a, wb_b, .... wb_z. Sequential files should installed in a subdirectory ("dictionary") of your application. The program will build an Isam database, where entries can be accessed directly or sequentially.

How to Build the Index

Allow or Not Allow Duplicate Keys
Number of Files to index : 26-1 (26 = all letters of the alphabet)
Build also another Index (index 1)
CloseReopen after indexation
and Click On "Start Indexation"
Indexation with duplicate keys allowed : 176043 Entries
Indexation with unique keys : Only 111730 Entries



Basic Sequential Access
First Key : Returns the first key of the index
Last Key : Returns the Last Key of the index
Next Key : Next Key in the index
Previous Key : Previous Key in the index



Direct Access
Search for a word : Enter a Word and click on the "Search" button
Sequential read after direct read : you can read next or read previous from this location
You can select a word in the displayed definition to search for the selected word.


Other operations
Clear the Display Box
Add a New Entry
Update an Entry
Delete an Entry


Backup, Restore, Duplicate
Backup database : Sequential read of the database and save the content in the dict.txt file
Restore database : Delete the database, and restore it from the dict.txt file
Duplicate database : Duplicate the Dict Database in the Dupli Database

Download Project


Files are packed in a ZIP file Borland DLL,or BPL are also incuded if you want to run the TESTISAM.EXE program without having the BCB development compiler.
The ZIP file countains the following files

- borlndmm.dll
- cc3250mt.dll
- main.cpp
- main.dfm
- main.h
- realisam.dll
- realisam.h
- realisam.lib
- testisam.bpr
- testisam.cpp
- testisam.exe
- testisam.res
- vcl50.bpl

and a subdirectory Dictionary that contains 26 html files,
wb_a. html .... wb_z.html
Download Example TestIsam.zip (6.2 MB)

Statistics



Letters Entries Indexation time (sec)
a-a 11616 1.21
a-f 63974 7.64
a-k 86064 9.59
a-p 123648 13.97
a-u 167742 19.16
a-z 176043 20.12

These measures were conducted using a desktop PC, under Windows XP-SP2, processor AMD Athlon XP 2800 (2.0 Ghz), RAM 512 MB, Hard Drive 120 GBytes. Values can vary depending on the PC characteristics.
We get approximately 8740 Read/Write operations per second, each operation includes the following actions:

-Read Sequential record in the dictionnary file
-Extract Entry Word into Key
-Read Key
-Write Key if Key doesn't exists
-Concatenate definition if No duplicate Key option is set, else store definition in record
-Write or rewrite Record

Source Program



This program is written using the Borland C++ Builder (Version BCB5)

Include File MAIN.H

//---------------------------------------------------------------------------

#ifndef MainH
#define MainH
//---------------------------------------------------------------------------
#include 
#include 
#include 
#include 
#include 
#include 

#include   
#include   
#include 

#include "Realisam.h"
#include 


//---------------------------------------------------------------------------
class TMainForm : public TForm
{
__published:	// IDE-managed Components
        TPageControl *PageControl1;
        TTabSheet *TabSheet2;
        TButton *btStart;
        TLabel *Label15;
        TEdit *eWord;
        TMemo *mWord;
        TLabel *lelapsed;
        TStatusBar *StatusBar1;
        TButton *btSearch;
        TLabel *lElap;
        TButton *btNext;
        TButton *btPrev;
        TButton *btFirst;
        TButton *btLast;
        TMainMenu *MainMenu1;
        TMenuItem *Exit1;
        TMenuItem *Exit2;
        TLabel *Label16;
        TLabel *Label17;
        TLabel *lRecords;
        TLabel *lKeys;
        TCheckBox *cb;
        TLabel *Label18;
        TEdit *edFile;
        TLabel *Label20;
        TLabel *RK;
        TLabel *Label22;
        TButton *btBackup;
        TButton *btRestore;
        TBevel *Bevel1;
        TBevel *Bevel2;
        TCheckBox *CheckBox1;
        TBevel *Bevel3;
        TLabel *Label1;
        TButton *btUpdate;
        TButton *btDelete;
        TButton *btDupl;
        TButton *btClear;
        TButton *btAdd;
        TCheckBox *cbSec;
        TLabel *lIndex;
        TLabel *Label3;
        TButton *btVersion;
     
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
        void __fastcall btStartClick(TObject *Sender);
        void __fastcall btSearchClick(TObject *Sender);
        void __fastcall btFirstClick(TObject *Sender);
        void __fastcall btNextClick(TObject *Sender);
        void __fastcall btLastClick(TObject *Sender);
        void __fastcall btPrevClick(TObject *Sender);
        void __fastcall Exit2Click(TObject *Sender);
        void __fastcall mWordMouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y);
        void __fastcall btBackupClick(TObject *Sender);
        void __fastcall btRestoreClick(TObject *Sender);
        void __fastcall eWordKeyUp(TObject *Sender, WORD &Key,
          TShiftState Shift);
        void __fastcall btUpdateClick(TObject *Sender);
        void __fastcall btDeleteClick(TObject *Sender);
        void __fastcall btDuplClick(TObject *Sender);
        void __fastcall btClearClick(TObject *Sender);
        void __fastcall btAddClick(TObject *Sender);
        void __fastcall btVersionClick(TObject *Sender);
private:	// User declarations

#define MAX_KEY 250
#define BUF_LEN 50000
   struct  time t1;
   struct  time t2;
   int     nbsec1,nbsec2,delta;

   realisam *dict;    // working database
   realisam *dupli;   // another instance for duplication example

   char    base_directory[MAX_PATH];
   char    dict_directory[MAX_PATH];
   int     nbrecords;
   int     multi;
   int     INDEX;
   int    M_recdata;       // memorizes data record pointer
   char   M_Key[MAX_KEY];  // memorizes Key

   int __fastcall ExtractValue(char *result, char *buff, char *tag, int posdeb);
   int __fastcall IndexBuffer(char *buff);
   void __fastcall Search();
   void __fastcall First();
   void __fastcall EnableButtons();
   void __fastcall DisableButtons();

public:		// User declarations
        __fastcall TMainForm(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TMainForm *MainForm;
//---------------------------------------------------------------------------
#endif


Include and Constructor

//---------------------------------------------------------------------------

#include 
#pragma hdrstop
                                                                                    

#include "Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
        : TForm(Owner)
{

}
//---------------------------------------------------------------------------

Extract Value Between XML tags

int __fastcall TMainForm::ExtractValue(char *result, char *buff, char *tag, int posdeb)
{
 char tmp[250];
 char *p,*p1,*p2;
 int pos,l;

 result[0]=0;
 strcpy(tmp,"<"); strcat(tmp,tag); strcat(tmp,">");
 p = strstr(buff,tmp);
 l=0;
 if (p)
   {
    strcpy(tmp,"");
    p1= strstr(buff,tmp);
    if (p1)
      {
       p2=p + strlen(tag)+2; l= p1-p2;
       strncpy(result,p2,l);
       result[l]=0;
      }
   }
 return l;
}


Init Routine

///////////////////////////////////////////////////////////
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
 char name[250]; AnsiString Dir;
 int rc;
 int mode;
 char tmp[100];

 Dir = GetCurrentDir(); strcpy(base_directory,Dir.c_str());
 strcpy(dict_directory,base_directory); strcat(dict_directory,"\\dictionary\\");

 // REALISAM ALLOWS 64 INDEXES  : Value from 0 to 63

 INDEX=0;


 strcpy(name,dict_directory);strcat(name,"dict");
 dict = new realisam();
 rc = dict->OpenEngine(name,120,"ndx","dat");   //120 = 128 - 8
 multi = dict->GetIndexMode(INDEX);
 if (multi==0)  cb->Checked==false; else cb->Checked=true;

 // GetVersion Number
 dict->Version(tmp);
 MainForm->Caption = "Alpes Software - " + AnsiString(tmp);

 // Get Number of Keys

 rc = dict->NumberOfKeys(INDEX);
 lKeys->Caption = AnsiString(rc);
 if (rc) First();
}
//---------------------------------------------------------------------------


Action before leaving

void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
{
 dict->CloseEngine();
 Action = caFree;
}
//---------------------------------------------------------------------------


Indexation Routine

void __fastcall TMainForm::btStartClick(TObject *Sender)
{
 char tmp[250]; char name[250]; char html[250];
 int i; FILE *fp;
 int rc;
 char buffer[BUF_LEN];
 struct time t; int nbsec1,nbsec2;
 int hund1,hund2;
 int nbf;  int K;

 TCursor oldCursor = Screen->Cursor;
 if (cb->Checked==true) multi=1; else multi=0;
  strcpy(tmp,"Indexation will delete and rebuild the dictionary, OK ? ");
 if (Application->MessageBoxA(tmp,"Isam Dictionary",MB_YESNO)==IDNO) return;


 rc=dict->CloseEngine();

 // delete isam files
 strcpy(tmp,dict_directory);strcat(tmp,"dict.ndx");
 rc = unlink (tmp);
 strcpy(name,dict_directory);strcat(name,"dict.dat");
 rc =unlink (name);


 Screen->Cursor = crHourGlass;

 DisableButtons();

 eWord->Text="";
 mWord->Clear();
 RK->Caption = "";
 lKeys->Caption = "";
 lRecords->Caption="";
 lElap->Caption="";

 // GET INDEX VALUE;
 strcpy(tmp,lIndex->Caption.c_str());
 INDEX=atoi(tmp);
 if (INDEX <0 || INDEX>63)
  {
   Application->MessageBoxA("Index Number Not Correct (0-63)","RealIsam",MB_OK);
   return;
  }


 Application->ProcessMessages();
 // Get Number of Files to Index
 strcpy(tmp,edFile->Text.c_str());
 nbf=atoi(tmp);
 nbf--;
 if (nbf<0) nbf=0;
 if (nbf>25)nbf=25;


   gettime(&t);
   nbsec1 = t.ti_hour*3600+t.ti_min*60 + t.ti_sec;
   hund1 =  nbsec1*100 + t.ti_hund;

 // create a new database
 strcpy(name,dict_directory);strcat(name,"dict");
 rc = dict->OpenEngine(name,120,"ndx","dat");   //120 = 128 - 8
 rc = dict->SetIndexMode(INDEX,multi); // if MULTI == 1 duplicate key allowed
 rc = dict->SetIndexMode(INDEX+1,multi);
 nbrecords=0;
  //  read contents of the 1-26 HTML Files  (in alphabetic reverse order, just for fun)
  for (i=nbf;i>=0;i--)
 // for (i=0;i<=nbf;i++) // if you prefer alphabetic order
   {

    strcpy(tmp,"wb_?.html");  tmp[3]=i+97;  // a,b,c, ...
    StatusBar1->SimpleText = "Indexing " + AnsiString(tmp) + " File";
    strcpy(html,dict_directory); strcat(html,tmp);
    fp = fopen(html,"r");
    if (!fp) {Application->MessageBoxA(html,"File Not Found",MB_OK);
              EnableButtons();
              Screen->Cursor = oldCursor;
              return; }

    // read sequential data
    while (!feof(fp))
     {
      tmp[0]=0;
      fgets(buffer,BUF_LEN,fp);  //
      IndexBuffer(buffer);
      Application->ProcessMessages();

     }
    fclose(fp);
   }
  int nbk = dict->NumberOfKeys(INDEX);
  lRecords->Caption = AnsiString(nbrecords);
  lKeys->Caption = AnsiString(nbk);

  gettime(&t);
  nbsec2 = t.ti_hour*3600+t.ti_min*60 + t.ti_sec;
  hund2 = nbsec2*100 + t.ti_hund;
  float diff = float(hund2-hund1);
  sprintf(tmp,"%.02f",diff/100.0);

  int elapsed = nbsec2-nbsec1;
  lElap->Caption = AnsiString(tmp);  // elapsed);

  // Close ReOpen

 if (CheckBox1->Checked==true)
  {
   strcpy(name,dict_directory);strcat(name,"dict");
   rc = dict->CloseReopen(name,120,"ndx","dat");   //120 = 128 - 8
   rc = dict->SetIndexMode(INDEX,multi);
   rc = dict->SetIndexMode(INDEX+1,multi);
  }
  StatusBar1->SimpleText = "";
  First();
  Screen->Cursor = oldCursor;
  Beep();
  EnableButtons();
  Application->MessageBoxA("Indexation Finished","RealIsam",MB_OK);

}
//---------------------------------------------------------------------------


Buffer Indexation

/////////////////////////////////////////////////////

int __fastcall TMainForm::IndexBuffer(char *buff)
{
 char str[BUF_LEN],definition[BUF_LEN]; int length;
 char Key[MAX_KEY],RetKey[MAX_KEY];
 int  rc,recdata; char *p;
 char SKey[MAX_KEY]; int l,i;
 length=ExtractValue(str,buff,"P",0);   // extract a paragraph 

...

if (length==0) return 0; // Extract Key between tag and length=ExtractValue(definition,str,"B",0); if (length==0) return 0; // no key if (length>250) { //Application->MessageBoxA("Key Length > 250 : Record Discarded","Isam",MB_OK); return 0; } // all strings are lowered strcpy(Key,definition); strlwr(Key); nbrecords++; // pointer on the italic tag) skip italic tag p=strstr(str,")"); if (p) strcpy(definition,p+1); else strcpy(definition,str); // Write Key in index file and definition in Data file rc = dict->ReadDirectKey(INDEX,Key,RetKey,&recdata); l=strlen(Key); for (i=0;iReadRecord(str,recdata); strcat(str,"\r\n"); strcat(str,definition); rc = dict->RewriteRecord(str, strlen(str)+1,recdata); } else { recdata=dict->GetNewRecordNumber(); rc = dict->WriteKey(INDEX,Key,recdata); if (cbSec->Checked==true) rc = dict->WriteKey(INDEX+1,SKey,recdata); rc = dict->WriteRecord(definition,strlen(definition)+1); } } else // Key does not exist { recdata=dict->GetNewRecordNumber(); rc = dict->WriteKey(INDEX,Key,recdata); if (cbSec->Checked==true) rc = dict->WriteKey(INDEX+1,SKey,recdata); rc = dict->WriteRecord(definition,strlen(definition)+1); } return 1; // OK }


Search for a word

void __fastcall TMainForm::btSearchClick(TObject *Sender)
{
 Search();
 }
//---------------------------------------------------------------------------

void __fastcall TMainForm::Search()
{
 int rc,recdata;
 char Key[MAX_KEY],RetKey[MAX_KEY];
 char buffer[BUF_LEN];
 char tmp[256];

 if (eWord->Text=="") { mWord->Clear(); return; }
 INDEX=0;


 strcpy(Key,eWord->Text.c_str());
 strlwr(Key);
 rc = dict->ReadDirectKey(INDEX,Key,RetKey,&recdata);

 RK->Caption=AnsiString(RetKey);
 eWord->Text=AnsiString(RetKey);
 if (rc==1)
   {
    rc=dict->ReadRecord(buffer,recdata);
    if (rc)
      {
       mWord->Clear();
       mWord->SetTextBuf(buffer);
      }
   }
 else
   {
    mWord->SetTextBuf("Word Not Found");
   }
 M_recdata=recdata; strcpy(M_Key,RetKey);
}


Search First Record

void __fastcall TMainForm::First()
{
 int rc,recdata;
 char Key[MAX_KEY],RetKey[MAX_KEY];
 char buffer[BUF_LEN];

 char tmp[50];

 INDEX=0;

 mWord->Clear();
 rc = dict->ReadFirstKey(INDEX,RetKey,&recdata);
 RK->Caption=AnsiString(RetKey);
 eWord->Text=AnsiString(RetKey);
 if (rc==1)
   {

    rc=dict->ReadRecord(buffer,recdata);
    M_recdata=recdata; strcpy(M_Key,RetKey);
    if (rc) mWord->SetTextBuf(buffer);
   }
}

void __fastcall TMainForm::btFirstClick(TObject *Sender)
{
 First();
}
//---------------------------------------------------------------------------


Search Next Key

void __fastcall TMainForm::btNextClick(TObject *Sender)
{
 int rc,recdata;
 char Key[MAX_KEY],RetKey[MAX_KEY];
 char buffer[BUF_LEN];

 rc = dict->ReadNextKey(RetKey,&recdata);
 RK->Caption=AnsiString(RetKey);
 eWord->Text=AnsiString(RetKey);
  if (rc==1)
   {
    mWord->Clear();
    rc=dict->ReadRecord(buffer,recdata);
    M_recdata=recdata; strcpy(M_Key,RetKey);
    if (rc) mWord->SetTextBuf(buffer);
   }
}
//---------------------------------------------------------------------------


Search Last Key

void __fastcall TMainForm::btLastClick(TObject *Sender)
{
 int rc,recdata;
 char Key[MAX_KEY],RetKey[MAX_KEY];
 char buffer[BUF_LEN];

 rc = dict->ReadLastKey(INDEX,RetKey,&recdata);
 RK->Caption=AnsiString(RetKey);
 eWord->Text=AnsiString(RetKey);
 if (rc==1)
   {
    mWord->Clear();
    rc=dict->ReadRecord(buffer,recdata);
    M_recdata=recdata; strcpy(M_Key,RetKey);
    if (rc) mWord->SetTextBuf(buffer);
   }
}
//---------------------------------------------------------------------------


Search previous Key

void __fastcall TMainForm::btPrevClick(TObject *Sender)
{
int rc,recdata;
 char Key[MAX_KEY],RetKey[MAX_KEY];
 char buffer[BUF_LEN];

 rc = dict->ReadPrevKey(RetKey,&recdata);
 RK->Caption=AnsiString(RetKey);
 eWord->Text=AnsiString(RetKey);
 if (rc==1)
   {
    mWord->Clear();
    rc=dict->ReadRecord(buffer,recdata);
    M_recdata=recdata; strcpy(M_Key,RetKey);
    if (rc) mWord->SetTextBuf(buffer);
   }
}
//---------------------------------------------------------------------------


Exit Routine


void __fastcall TMainForm::Exit2Click(TObject *Sender)
{
 Close();
}
//---------------------------------------------------------------------------


Select a word from the definition displayed

void __fastcall TMainForm::mWordMouseUp(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
 char tmp[200];
 mWord->GetSelTextBuf(tmp,100);
 if (strlen(tmp)==0) return;
 eWord->Text=AnsiString(tmp);
 Search();

}
//---------------------------------------------------------------------------


Backup Isam Files in Text File

void __fastcall TMainForm::btBackupClick(TObject *Sender)
{
 int rc,recdata; char Key[MAX_KEY],RetKey[MAX_KEY];
 char buffer[BUF_LEN]; char html[BUF_LEN];
 char definition[BUF_LEN]; int nbseq,nbisam;
 struct time t; int nbsec1,nbsec2;
  TCursor oldCursor = Screen->Cursor;
 char tmp[250]; char *p,*p1;
 FILE *fp;

 strcpy(tmp,"Backup your Data in Text File Dict.txt ? ");
 if (Application->MessageBoxA(tmp,"Backup Dictionary",MB_YESNO)==IDNO) return;

 strcpy(tmp,dict_directory);
 strcat(tmp,"dict.txt");
 fp=fopen(tmp,"w+t");
 if (fp==NULL) { Application->MessageBoxA("Problem Opening Dict.Txt File",
                  "Backup Dictionary",MB_OK); return;
               }

 if (cb->Checked==true) multi=1; else multi=0;
 Screen->Cursor = crHourGlass;

 strcpy(tmp,lIndex->Caption.c_str());
 INDEX=atoi(tmp);

 DisableButtons();

 eWord->Text==""; mWord->Clear();
 gettime(&t);
  nbsec1 = t.ti_hour*3600+t.ti_min*60 + t.ti_sec;

 nbrecords=0; nbseq=0; nbisam=0;
 rc = dict->ReadFirstKey(INDEX,RetKey,&recdata);

 while (rc)
  {
    if (strlen(RetKey) > 30) Application->MessageBoxA(RetKey,"Key Length > 30",MB_OK);
    rc=dict->ReadRecord(buffer,recdata);
    if  (rc)
     {
       nbisam++;
       if (multi==1)
         { strcpy(html,"<P><B>"); strcat(html,RetKey); strcat(html,"</B> (<I></I>) ");
           strcat(html,buffer);
           strcat(html,"</P>\n");
           fputs(html,fp);  nbseq++;
         }
       else  // extract concatenated items
         {
          p1=buffer;
          p=strchr(p1,'\r');
          while (p)
            {
             *p=0; p++; *p=0;
             strcpy(html,"<P><B>"); strcat(html,RetKey); strcat(html,"</B> (<I></I>) ");
             
             strcat(html,p1);
             strcat(html,"</P>\n");
             fputs(html,fp); nbseq++;
             p1=p+1;
             p=strchr(p1,'\n');
            }
           strcpy(html,"<P><B>"); strcat(html,RetKey); strcat(html,"</B> (<I></I>) ");
           
           strcat(html,p1);
           strcat(html,"</P>\n");
           fputs(html,fp); nbseq++;

         }
     }

    rc=dict->ReadNextKey(RetKey,&recdata);
    Application->ProcessMessages();
 }
  fclose(fp);

  StatusBar1->SimpleText = "Number of Keys: " + AnsiString(nbisam);
  lRecords->Caption = AnsiString(nbseq);
  lKeys->Caption = AnsiString(nbisam);
  gettime(&t);
  nbsec2 = t.ti_hour*3600+t.ti_min*60 + t.ti_sec;
  int elapsed = nbsec2-nbsec1;
  lElap->Caption = AnsiString(elapsed);
  First();
  Screen->Cursor = oldCursor;
  Beep();
  EnableButtons();
  Application->MessageBoxA("Backup Done","RealIsam",MB_OK);

}
//---------------------------------------------------------------------------


Restore Isam Files from the text file


void __fastcall TMainForm::btRestoreClick(TObject *Sender)
{
 char tmp[250]; char name[250];
 FILE *fp;
 int rc,nbisam;
 char buffer[BUF_LEN];
 struct time t; int nbsec1,nbsec2;

 strcpy(tmp,"Restore Data from Dict.txt ? \r\n Isam Files will be deleted, and rebuilt");
 if (Application->MessageBoxA(tmp,"Restore Dictionary",MB_YESNO)==IDNO) return;

 TCursor oldCursor = Screen->Cursor;
 if (cb->Checked==true) multi=1; else multi=0;
 dict->CloseEngine();

 // delete isam files
 strcpy(name,dict_directory);strcat(name,"dict.ndx");
 rc = unlink (name);
 strcpy(name,dict_directory);strcat(name,"dict.dat");
 rc =unlink (name);
 Screen->Cursor = crHourGlass;

 DisableButtons();
 eWord->Text==""; mWord->Clear();

 gettime(&t);
 nbsec1 = t.ti_hour*3600+t.ti_min*60 + t.ti_sec;

 strcpy(tmp,lIndex->Caption.c_str());
 INDEX=atoi(tmp);
 if (INDEX <0 || INDEX>63)
  {
   Application->MessageBoxA("Index Number Not Correct (0-63)","RealIsam",MB_OK);
   return;
  }

 // create a new database
 strcpy(name,dict_directory);strcat(name,"dict");
 rc = dict->OpenEngine(name,120,"ndx","dat");   //120 = 128 - 8
 rc = dict->SetIndexMode(INDEX,multi); // if MULTI == 1 duplicate key allowed
 rc = dict->SetIndexMode(INDEX+1,multi);

 nbrecords=0;
 strcpy(name,dict_directory);strcat(name,"dict.txt");
 fp = fopen(name,"r");
 if (!fp) {Application->MessageBoxA("File DICT.txt not Found","File Not Found",MB_OK);
              EnableButtons();
              Screen->Cursor = oldCursor;
              return; }

 nbrecords=0; nbisam=0;
    // read sequential data
    while (!feof(fp))
     {
      buffer[0]=0;
      fgets(buffer,BUF_LEN,fp);
      if (strlen(buffer)>0)
        { nbisam++;  IndexBuffer(buffer); }
       else nbrecords=nbrecords;
      Application->ProcessMessages();

     }
    fclose(fp);

    int nbk = dict->NumberOfKeys(INDEX);
    StatusBar1->SimpleText = "Number of Keys: " + AnsiString(nbk);
    lRecords->Caption = AnsiString(nbisam);
    lKeys->Caption = AnsiString(nbk);

    gettime(&t);
    nbsec2 = t.ti_hour*3600+t.ti_min*60 + t.ti_sec;
    int elapsed = nbsec2-nbsec1;
    lElap->Caption = AnsiString(elapsed);
    First();
    Screen->Cursor = oldCursor;
    Beep();
    EnableButtons();
    Application->MessageBoxA("Restoration Done","RealIsam",MB_OK);
}
//---------------------------------------------------------------------------


Search Database from a keyed word


void __fastcall TMainForm::eWordKeyUp(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
 if (Key==13) Search();
}
//---------------------------------------------------------------------------


Update a definition record


void __fastcall TMainForm::btUpdateClick(TObject *Sender)
{
 char buffer[BUF_LEN]; int rc;
 // M_recdata is supposed to store the address of the data record
 mWord->GetTextBuf(buffer,BUF_LEN);
 rc = dict->RewriteRecord(buffer, strlen(buffer)+1,M_recdata);
  StatusBar1->SimpleText="Entry Updated";
}
//---------------------------------------------------------------------------


Delete an Entry

void __fastcall TMainForm::btDeleteClick(TObject *Sender)
{
  int rc;
  rc=dict->DeleteKey(INDEX,M_Key,M_recdata);
  rc=dict->DeleteRecord(M_recdata);

  First();
  StatusBar1->SimpleText="Entry Deleted";
}
//---------------------------------------------------------------------------


Duplicate Isam Files

void __fastcall TMainForm::btDuplClick(TObject *Sender)
{
 char name[MAX_PATH]; int rc, recdata,recdata_dupli;
 dupli = new realisam();   char RetKey[MAX_KEY];
 char buffer[BUF_LEN];   char tmp[250];

 strcpy(tmp,"Do you want to build a duplicate dictionnary : files Dupli.ndx and Dupli.dat ? ");
 if (Application->MessageBoxA(tmp,"Isam Dictionary",MB_YESNO)==IDNO) return;



  TCursor oldCursor = Screen->Cursor;

 strcpy(name,dict_directory);strcat(name,"dupli.ndx");
 rc = unlink (name);
 strcpy(name,dict_directory);strcat(name,"dupli.dat");
 rc =unlink (name);
 Screen->Cursor = crHourGlass;
 DisableButtons();
 strcpy(name,dict_directory);strcat(name,"dupli");

 rc = dupli->OpenEngine(name,120,"ndx","dat");   //120 = 128 - 8
 rc = dupli->SetIndexMode(INDEX,multi); // if MULTI == 1 duplicate key allowed

 // nbrecords=0; nbseq=0; nbisam=0;
 rc = dict->ReadFirstKey(INDEX,RetKey,&recdata);
 while (rc)
  {
    rc=dict->ReadRecord(buffer,recdata);

    recdata_dupli=dupli->GetNewRecordNumber();
    rc = dupli->WriteKey(INDEX,RetKey,recdata_dupli);
    rc = dupli->WriteRecord(buffer,strlen(buffer)+1);

    rc = dict->ReadNextKey(RetKey,&recdata);
  }

 dupli->CloseEngine();

 First();
 Screen->Cursor = oldCursor;
 EnableButtons();
 Application->MessageBoxA("Duplication Finished","RealIsam",MB_OK);
}
//---------------------------------------------------------------------------


Clear Search Field


void __fastcall TMainForm::btClearClick(TObject *Sender)
{
 eWord->Text="";
 mWord->Clear();
}
//---------------------------------------------------------------------------


Add an entry

void __fastcall TMainForm::btAddClick(TObject *Sender)
{
 char Key[MAX_KEY],RetKey[MAX_KEY];
 int rc, recdata;
 char buffer[BUF_LEN],str[BUF_LEN];

 strcpy(Key,eWord->Text.c_str());
 if (strlen(Key)==0)
   {
    Application->MessageBoxA("Key not provided","RealIsam",MB_OK);
    return;
   }

  strlwr(Key);
  mWord->GetTextBuf(buffer,BUF_LEN);

  rc = dict->ReadDirectKey(INDEX,Key,RetKey,&recdata);

  if (rc) // Exists if == 1
     {
      if (multi==0)   // Unique Keys  : Concatenate definitions
        {
         rc=dict->ReadRecord(str,recdata);
         strcat(str,"\r\n"); strcat(str,buffer);
         rc = dict->RewriteRecord(str, strlen(str)+1,recdata);
        }
        else
          { recdata=dict->GetNewRecordNumber();
            rc = dict->WriteKey(INDEX,Key,recdata);
            rc = dict->WriteRecord(buffer,strlen(buffer)+1);
          }

     }
     else  // Key does not exist
     { recdata=dict->GetNewRecordNumber();
       rc = dict->WriteKey(INDEX,Key,recdata);
       rc = dict->WriteRecord(buffer,strlen(buffer)+1);
     }
 StatusBar1->SimpleText="Entry Added";
}
//---------------------------------------------------------------------------


Enable Buttons


void __fastcall TMainForm::EnableButtons()
{
 btStart->Enabled = true;
 btFirst->Enabled = true;
 btLast->Enabled = true;
 btNext->Enabled = true;
 btPrev->Enabled = true;
 btSearch->Enabled = true;
 btBackup->Enabled=true;
 btRestore->Enabled=true;
 btDupl->Enabled=true;
 btClear->Enabled=true;
 btAdd->Enabled=true;
 btUpdate->Enabled=true;
 btDelete->Enabled=true;
}


Disable Buttons


void __fastcall TMainForm::DisableButtons()
{
 btStart->Enabled = false;
 btFirst->Enabled = false;
 btLast->Enabled = false;
 btNext->Enabled = false;
 btPrev->Enabled = false;
 btSearch->Enabled = false;
 btBackup->Enabled=false;
 btRestore->Enabled=false;
 btDupl->Enabled=false;
 btClear->Enabled=false;
 btAdd->Enabled=false;
 btUpdate->Enabled=false;
 btDelete->Enabled=false;
}


Current RealIsam Version

void __fastcall TMainForm::btVersionClick(TObject *Sender)
{
  char version[100];
  dict->Version(version);
  Application->MessageBoxA(version,"Version",MB_OK);
}
//---------------------------------------------------------------------------

Copyright Alpes Software - Documentation and HTML pages generated by Final Doc