Ultimately my goal is to be able to save an array of records data structure in a sqlite BLOB field, but in the interim I am trying to serialize an array of records and store it in a TMemoryStream. In case it may be relevant, I am using Tim Anderson’s sqlite wrapper (unicode) with Delphi 2010.
This is my array of record declaration:
type
TPerson = array of packed record
sCountry: string[50];
sFullName: string[100];
sAddress: string[100];
sCity: string[30];
sEmployer: string[100];
end;
var
MyPeople : TPerson;
And here is the code I am currently using to serialize this array of record to a TMemoryStream. The problem is that it doesn’t work:
var
i : integer;
ms : TMemoryStream:
ms2 : TMemoryStream;
TestPeople : TPerson;
sldb : TSQLiteDatabase;
begin
ms := TMemoryStream.Create;
ms2 := TMemoryStream.Create;
sldb := TSQLiteDatabase.Create(slDBPath); //sldBPath is a global variable with path to sqlite db
try
i := Length(MyPeople);
ms.Write(i, 4);
ms.Write(pointer(MyPeople)^, i * sizeOf(MyPeople));
///
ms2.Read(i, 4);
SetLength(ms2, i);
ms2.Read(pointer(TestPeople)^, i * sizeOf(TestPeople));
WriteLn('#############' + ms2[0].sFullName); //check if we can read data back
sQuery := 'UPDATE PersonDirectory SET fldPersonBlob = ? WHERE id = "' + 42 + '";';
sldb.UpdateBlob(sQuery, ms);
finally
ms.Free;
ms2.Free;
sqldb.Free;
end;
end;
Any ideas on either how to generally serialize an array of record to a TMemoryStream, or a better way to store an array of records in a sqlite BLOB field?
Make TPerson the packed record, and declare TPersons as array of TPerson.
This allows you to get SizeOf(TPerson) to get the right size of the record, while Length(MyPeople) will give you the length of the array. Multiply them to get the total byte size. That should get you started.
Also note that some read and write action start from the beginning of the stream, while others continue at the current
position. Settingpositionto 0 before copying the contents of a stream to another is sometimes needed. The documentation will mention this.