Borland®
Shop
Products Downloads Services Support Partners News & Events Company Community

BDE API Examples (DbiReadBlock, DbiWriteBlock, DbiSetFieldMap)

(DbiReadBlock)Reads a specified number of records (starting from the next position of the cursor) into a buffer.
(DbiSetFieldMap)Sets a field map of the table associated with the given cursor.
(DbiWriteBlock)Writes a block of records to the table associated with the cursor.

Move data from one table to another table with a different structure in the fastest way possible.

This example uses the following input:
MoveFast(STable, DTable, [2, 3, 5], [4, 1, 7], 1024000);
NOTE: This procedure will take two tables of the same type and move data between the two even if they have a different structure. The above input example maps source table fields 2, 3 and 5 to 4, 1 and 7 respectively. The matching fields must be of same type and size because no field level translation is being done. Changing the BlockSize parameter can have an effect of speed. If you are moving massive amounts of data and have plenty of RAM in the machine, experiment with increasing the BlockSize parameter.
procedure MoveFast(SourceTable, DestTable: TTable; const SourceMap,

             DestMap: array of word; BlockSize: longint);

var

  pRecBuffs: pBYTE;

  TotalSize, Records, RecordsToRead, RecordsProcessed: longint;

  pSMapFields, pSFields, pDMapFields, pDFields, pD, pS: pFLDDesc;

  MapFieldCount, B: byte;

  Props: CURProps;





begin

  if sizeof(SourceMap) <> sizeof(DestMap) then

    raise EDatabaseError.Create('Source and destination field mappings must be same in size');



  pRecBuffs := nil;  pSFields := nil; pSMapFields := nil;

  pDFields := nil; pDMapFields := nil; RecordsProcessed := 0;

  try

    Check(DbiSetToBegin(SourceTable.Handle));



    MapFieldCount := sizeof(SourceMap) div sizeof(WORD);

    pSMapFields := AllocMem(MapFieldCount * sizeof(FLDDesc));



    pSFields := AllocMem(SourceTable.FieldCount * sizeof(FLDDesc));

    Check(DbiGetFieldDescs(SourceTable.Handle, pSFields));

    // Create the source field mappings...

    for B := 0 to MapFieldCount - 1 do

    begin

      Inc(pSFields, SourceMap[B] - 1);

      Move(pSFields^, pSMapFields^, sizeof(FLDDesc));

      Inc(pSMapFields);

      Dec(pSFields, SourceMap[B] - 1);

    end;

    Dec(pSMapFields, MapFieldCount);



    pDMapFields := AllocMem(MapFieldCount * sizeof(FLDDesc));



    pDFields := AllocMem(DestTable.FieldCount * sizeof(FLDDesc));

    Check(DbiGetFieldDescs(DestTable.Handle, pDFields));

    // Create the destination field mappings...

    for B := 0 to MapFieldCount - 1 do

    begin

      Inc(pDFields, DestMap[B] - 1);

      Move(pDFields^, pDMapFields^, sizeof(FLDDesc));

      Inc(pDMapFields);

      Dec(pDFields, DestMap[B] - 1);

    end;

    Dec(pDMapFields, MapFieldCount);

    // Check all fields to make sure they are comparable types and sizes...

    pS := pSMapFields;

    pD := pDMapFields;

    for B := 1 to MapFieldCount do

    begin

      if pS^.iFldType <> pD^.iFldType then

         raise EDatabaseError.Create('Source field: ' + pS^.szName + ' Type (' +

            IntToStr(pS^.iFldType) + ') is not the same base type as the ' +

            'destination field: ' + pD^.szName + ' Type (' +

            IntToStr(pD^.iFldType) + ')');

      if (pS^.iUnits1 <> pD^.iUnits1) or  (pS^.iUnits1 <> pD^.iUnits1) then

         raise EDatabaseError.Create('Source field size: ' + pS^.szName + ' Size (' +

            IntToStr(pS^.iUnits1) + ', ' + IntToStr(pS^.iUnits1) +

            ') is not the same base type as the destination size: ' + pD^.szName + ' Size (' +

            IntToStr(pD^.iUnits1) + ', ' + IntToStr(pD^.iUnits1) + ')');

      Inc(pS);

      Inc(pD);

    end;

    // Set the field maps on the tables...

    Check(DbiSetFieldMap(SourceTable.Handle, MapFieldCount, pSMapFields));

    Check(DbiSetFieldMap(DestTable.Handle, MapFieldCount, pDMapFields));



    Check(DbiGetCursorProps(DestTable.Handle, Props));



    // Determine the amount of records that can be move in the block size given...

    Check(DbiGetRecordCount(SourceTable.Handle, Records));

    TotalSize := Props.iRecBufSize * Records;

    if TotalSize < BlockSize then

      BlockSize := TotalSize;

    RecordsToRead := BlockSize div Props.iRecBufSize;

    pRecBuffs := AllocMem(BlockSize * sizeof(BYTE));

    // Read and write the data...

    while RecordsToRead > 0 do

    begin

      Check(DbiReadBlock(SourceTable.Handle, RecordsToRead, pRecBuffs));

      Check(DbiWriteBlock(DestTable.Handle, RecordsToRead, pRecBuffs));

      Inc(RecordsProcessed, RecordsToRead);

      if RecordsToRead > (Records - RecordsProcessed) then

        RecordsToRead := (Records - RecordsProcessed);

    end;



  finally

    if pRecBuffs <> nil then

      FreeMem(pRecBuffs);

    if pSFields <> nil then

      FreeMem(pSFields);

    if pSMapFields <> nil then

      FreeMem(pSMapFields);

    if pDFields <> nil then

      FreeMem(pDFields);

    if pDMapFields <> nil then

      FreeMem(pDMapFields);



    Check(DbiSetFieldMap(SourceTable.Handle, 0, pSFields));

    Check(DbiSetFieldMap(DestTable.Handle, 0, pDFields));    

  end;

end;

Back to BDE API Reference Page


DISCLAIMER: You have the right to use this technical information subject to the terms of the No-Nonsense License Statement that you received with the Borland product to which this information pertains.
 
Site Map Search Contact