На главную
Подписка
Новости


Рейтинг@Mail.ru











Главная / DELPHI / Часто задаваемые вопросы и ответы на них / Разработка баз данных / Таблицы в памяти Сделать домашней страницей Добавить в избранное Написать писмо

Таблицы в памяти


Автор: grisha@mira.com

4 Mb - это не память. Это склероз

Вот пример InMemoryTable. Свободен для использования, модификации и всего остального. Ну и как в отношении других вещей: я не даю никаких гарантий. Я не несу никакой ответственности за ущерб, который может причинить код. Позвольте, я повторю это:

ВНИМАНИЕ! ДАННЫЙ КОД НЕ ПРЕДУСМАТРИВАЕТ НИКАКИХ ГАРАНТИЙ!

ИСПОЛЬЗУЙТЕ ЕГО НА СВОЙ СТРАХ И РИСК - ВЫ ЕДИНСТВЕННЫЙ ЧЕЛОВЕК, ОТВЕТСТВЕННЫЙ ЗА ЛЮБОЙ УЩЕРБ, КОТОРЫЙ МОЖЕТ ПОВЛЕЧЬ ЗА СОБОЙ ИСПОЛЬЗОВАНИЕ ДАННОГО КОДА - - Я ВАС ПРЕДУПРЕДИЛ!

Благодарю Steve Garland за предоставленную помощь. Он создал свой собственный "in-memory" табличный компонент, который послужил мне толчком для написания сего кода.

InMemory-таблицы являются характеристикой Borland Database Engine (BDE). InMemory-таблицы создаются в RAM и удаляются при их закрытии. Работают они значительно быстрее и очень полезны в случае, если вам нужны быстрые операции в небольших таблицах. Данный пример использует вызов функции BDE DbiCreateInMemoryTable. Данный объект должен работать наподобии простой регулярной таблицы, за исключением того, что InMemory-таблицы не поддерживают некоторые характеристики (типа проверка целостности, вторичные индексы и BLOB-поля), и в настоящее время данный код не содержит механизма обработки ошибок. Вероятно, вы получите ошибку при попытке создания memo-поля. Если у вас есть любые замечания, шлите их по адресу grisha@mira.com.


unit Inmem;

interface

uses DBTables, WinTypes, WinProcs, DBITypes, DBIProcs, DB, SysUtils;

type
  TInMemoryTable = class(TTable)

  private
    hCursor: hDBICur;
    procedure EncodeFieldDesc(var FieldDesc: FLDDesc;
      const Name: string; DataType: TFieldType; Size: Word);
    function CreateHandle: HDBICur; override;
  public
    procedure CreateTable;
  end;

implementation

{ Эта функция виртуальная, так что я смог перекрыть ее.
В оригинальном VCL-коде для TTable эта функция реально
открывает таблицу, но, поскольку мы уже имеем дескриптор
таблицы, то мы просто возвращаем его }

function TInMemoryTable.CreateHandle;
begin

  Result := hCursor;
end;

{ Эта функция получена ее простым копированием из исходного
кода VCL. Я должен был это сделать, поскольку это было
объявлено в секции private компонента TTable, поэтому отсюда
у меня не было к этому досупа. }

procedure TInMemoryTable.EncodeFieldDesc(var FieldDesc: FLDDesc;

  const Name: string; DataType: TFieldType; Size: Word);
const

  TypeMap: array[TFieldType] of Byte = (
    fldUNKNOWN, fldZSTRING, fldINT16, fldINT32, fldUINT16, fldBOOL,
    fldFLOAT, fldFLOAT, fldBCD, fldDATE, fldTIME, fldTIMESTAMP, fldBYTES,
    fldVARBYTES, fldBLOB, fldBLOB, fldBLOB);
begin

  with FieldDesc do
  begin
    AnsiToNative(Locale, Name, szName, SizeOf(szName) - 1);
    iFldType := TypeMap[DataType];
    case DataType of
      ftString, ftBytes, ftVarBytes, ftBlob, ftMemo, ftGraphic:
        iUnits1 := Size;
      ftBCD:
        begin
          iUnits1 := 32;
          iUnits2 := Size;
        end;
    end;
    case DataType of
      ftCurrency:
        iSubType := fldstMONEY;
      ftBlob:
        iSubType := fldstBINARY;
      ftMemo:
        iSubType := fldstMEMO;
      ftGraphic:
        iSubType := fldstGRAPHIC;
    end;
  end;
end;

{ Вот кухня, где все это происходит. Я скопировал эту
функцию из исходников VCL и затем изменил ее для
использования DbiCreateInMemoryTable вместо DbiCreateTable.
Поскольку InMemory-таблицы не поддерживают индексы,
я удалил весь соответствующий код. }

procedure TInMemoryTable.CreateTable;
var

  I: Integer;
  pFieldDesc: pFLDDesc;
  szTblName: DBITBLNAME;
  iFields: Word;
  Dogs: pfldDesc;
begin

  CheckInactive;
  if FieldDefs.Count = 0 then
    for I := 0 to FieldCount - 1 do
      with Fields[I] do
        if not Calculated then
          FieldDefs.Add(FieldName, DataType, Size, Required);
  pFieldDesc := nil;
  SetDBFlag(dbfTable, True);
  try
    AnsiToNative(Locale, TableName, szTblName, SizeOf(szTblName) - 1);
    iFields := FieldDefs.Count;
    pFieldDesc := AllocMem(iFields * SizeOf(FLDDesc));
    for I := 0 to FieldDefs.Count - 1 do
      with FieldDefs[I] do
      begin
        EncodeFieldDesc(PFieldDescList(pFieldDesc)^[I], Name,
          DataType, Size);
      end;
    { тип драйвера nil, т.к. поля логические }
    Check(DbiTranslateRecordStructure(nil, iFields, pFieldDesc,
      nil, nil, pFieldDesc));
    { здесь hCursor получает свое значение }
    Check(DbiCreateInMemTable(DBHandle, szTblName, iFields, pFieldDesc,
      hCursor));

  finally
    if pFieldDesc <> nil then
      FreeMem(pFieldDesc, iFields *
        SizeOf(FLDDesc));

    SetDBFlag(dbfTable, False);
  end;
end;

end.

{Данный код взят из файлов помощи Ллойда!}


Copyright ©   "DELPHI WORLD"   E-mail:   delphiworld@mail.ru  http://www.delphiworld.narod.ru
Источник получения информации: http://www.delphiworld.narod.ru
Hosted by uCoz