Эх, въедливый. Ну да это и не плохо. Что ж, будем писать объектную БД на дельфях. Чисто для обучения.
Для начала нам понадобится движок, можно конечно взять любой, но мы не ищем легких путей, поэтому напишем свой, простой до безобразия, зато все внутненности работы будут нам понятны.
Вот что получилось набросать за последний час рабочего дня
Код:
unit AbstractDB;
{
Модуль реализующий класс абстрактного движка БД
Эта БД ничего особого не умеет :)
Но для примера она нам пригодится
Работаем только со строками длинной в 250 символов - никаких других типов
Процедуры чтения и записи данных по индексу в БД
+ процедура пометки записи на удаление
}
interface
uses
Classes;
const
DeleteFlag = $FF; //признак того что данная запись в БД помечена на удаление
type
TMyRec = string[250]; //Это будет нашей записью
TAbstractDB = class //Это класс самого движка
protected
FFileName:string; //Тут имя файла с которым будем работать
FData:TFileStream; //Объект для работы с файлом (кстати, тут умное слово ИНКАПСУЛЯЦИЯ)
FBuffer:array [1..255] of byte; //Буффер чтения/записи (ПОЧЕМУ длинна буфера не равна длине данных - потому что первые 5 байт будем использовать для системных нужд)
function ReadData(i:integer):TMyRec; //Функция реализующая чтение
procedure WriteData(i:integer;data:TMyRec); //Процедура реализующая запись
public
constructor Create (aFileName:string); //Конструктор
destructor Destroy; override; //Деструктор
procedure Delete (index:integer); //Процедура ПОМЕТКИ на удаление
property data[index:integer]:TMyRec read ReadData write WriteData; //Единственное (пока??) свойство доступа к данным
end;
implementation
uses SysUtils;
{ TAbstractDB }
constructor TAbstractDB.Create(aFileName: string);
begin
inherited Create;
if FileExists(aFileName) then
FData:=TFileStream.Create(aFileName,fmOpenReadWrite)
else
FData:=TFileStream.Create(aFileName,fmCreate);
end;
procedure TAbstractDB.Delete(index: integer);
{
Пометка записи на удаление
i - номер записи которую хотим того :)
}
begin
if FData.Size>=(index-1)*255 then //проверим не вывалимся ли за границу файла
begin
FData.Seek((index-1)*255,soFromBeginning); //спозиционируем курсор в файле
FData.ReadBuffer(FBuffer[1],255); //читаем
FBuffer[1]:=DeleteFlag; //установили пометку
FData.WriteBuffer(FBuffer[1],255); //записали назад
end;
end;
destructor TAbstractDB.Destroy;
begin
FData.Destroy; //Файл не забыли грохнуть
inherited;
end;
function TAbstractDB.ReadData(i: integer): TMyRec;
{
Чтение данных из базы
i - номер читаемой записи
result - наши мега данные :)
}
begin
if FData.Size>=(i-1)*255 then //проверим не вывалимся ли за границу файла
begin
FData.Seek((i-1)*255,soFromBeginning); //спозиционируем курсор в файле
FData.ReadBuffer(FBuffer[1],255); //читаем
Move(FBuffer[6],result[1],250);
end;
end;
procedure TAbstractDB.WriteData(i: integer; data: TMyRec);
{
Запись данных в БД
i - номер записи по порядку (нумерация с нуля)
data - данные
}
begin
if FData.Size>=(i-1)*255 then //проверим не вывалимся ли за границу файла
begin
FillChar(FBuffer[1],255,#0); //очистим буффер
Move(data[1],FBuffer[6],250); //скопируем в него инфу
FData.Seek((i-1)*255,soFromBeginning); //спозиционируем курсор в файле
FData.WriteBuffer(FBuffer[1],255); //Запишем данные
end;
end;
end.
пример использования:
Код:
var
i:TAbstractDB;
begin
i:=TAbstractDB.Create('c:\data.ADB');
i.data[1]:='какой-то там текст';
i.data[2]:='другой текст';
ShowMessage(i.data[2]);
i.Free;
end;
т.к. рабочий день закончился продолжим чуть поздже (когда до дому доберусь). Пока можно задавать вопросы по "движку".