Page 1 of 1

adding backup SQLITE API

Posted: 22.08.2019, 11:29
by Seba12
so on quickly,
adding backup SQLite API to ZEOS

file : ZPlainSqLiteDriver.pas

IZSQLitePlainDriver = interface (IZPlainDriver)
....
function backup_init(pDest: Psqlite; const zDestName: PAnsiChar; pSource: Psqlite; const zSourceName: PAnsiChar):Pointer;
function backup_step(p: Psqlite; nPage: Integer): Integer;
function backup_finish(p: Psqlite): Integer;
function backup_remaining(p: Psqlite): Integer;
function backup_pagecount(p: Psqlite): Integer;

TZSQLiteBaseDriver = class (TZAbstractPlainDriver, IZPlainDriver, IZSQLitePlainDriver)
....
private
....
sqlite3_backup_init: function(pDest: Psqlite; const zDestName: PAnsiChar; pSource: Psqlite; const zSourceName: PAnsiChar):Pointer; cdecl;
sqlite3_backup_step: function(p: Psqlite; nPage: Integer): Integer; cdecl;
sqlite3_backup_finish: function(p: Psqlite): Integer; cdecl;
sqlite3_backup_remaining: function(p: Psqlite): Integer; cdecl;
sqlite3_backup_pagecount: function(p: Psqlite): Integer; cdecl;

public
....
function backup_init(pDest: Psqlite; const zDestName: PAnsiChar; pSource: Psqlite; const zSourceName: PAnsiChar):Pointer;
function backup_step(p: Psqlite; nPage: Integer): Integer;
function backup_finish(p: Psqlite): Integer;
function backup_remaining(p: Psqlite): Integer;
function backup_pagecount(p: Psqlite): Integer;
....

function TZSQLiteBaseDriver.backup_init(pDest: Psqlite; const zDestName: PAnsiChar; pSource: Psqlite; const zSourceName: PAnsiChar):Pointer;
begin
Result := sqlite3_backup_init(pDest, zDestName, pSource,zSourceName);
end;
function TZSQLiteBaseDriver.backup_step(p: Psqlite; nPage: Integer): Integer;
begin
Result := sqlite3_backup_step(p, nPage);
end;
function TZSQLiteBaseDriver.backup_finish(p: Psqlite): Integer;
begin
Result := sqlite3_backup_finish(p);
end;
function TZSQLiteBaseDriver.backup_remaining(p: Psqlite): Integer;
begin
Result := sqlite3_backup_remaining(p);
end;
function TZSQLiteBaseDriver.backup_pagecount(p: Psqlite): Integer;
begin
Result := sqlite3_backup_pagecount(p);
end;

procedure TZSQLite3PlainDriver.LoadApi;
....
@sqlite3_backup_init := GetAddress('sqlite3_backup_init');
@sqlite3_backup_step := GetAddress('sqlite3_backup_step');
@sqlite3_backup_finish := GetAddress('sqlite3_backup_finish');
@sqlite3_backup_remaining := GetAddress('sqlite3_backup_remaining');
@sqlite3_backup_pagecount := GetAddress('sqlite3_backup_pagecount');



Procedure in your program

procedure TForm1.Backup;
var
ConA,ConB: TZConnection;
ConnA,ConnB: IZSQLiteConnection;
i,w:Integer;
p:Pointer;
begin
ConA:=TZConnection.Create(self);
ConA.LibraryLocation:=ExtractFilePath(Application.ExeName)+'sqlite3.dll';
ConA.Protocol:='sqlite-3';
ConA.Database:=ExtractFilePath(Application.ExeName)+'source.db';
ConA.TransactIsolationLevel:=tiReadCommitted;
ConA.Connect;
ConnA:=(ConA.DbcConnection as IZSQLiteConnection);

ConB:=TZConnection.Create(self);
ConB.LibraryLocation:=ExtractFilePath(Application.ExeName)+'sqlite3.dll';
ConB.Protocol:='sqlite-3';
ConB.Database:=ExtractFilePath(Application.ExeName)+'backup.db';
ConB.TransactIsolationLevel:=tiReadCommitted;
ConB.Connect;
ConnB:=(ConB.DbcConnection as IZSQLiteConnection);

p:=ConnA.GetPlainDriver.backup_init(ConnB.GetConnectionHandle,'main',ConnA.GetConnectionHandle,'main');
if p=nil then
begin
//error
end;

i:=ConnA.GetPlainDriver.backup_step(p, 0);
if not i in [SQLITE_BUSY, SQLITE_LOCKED, SQLITE_OK] then ConnA.GetPlainDriver.ErrorString(ConnA.GetConnectionHandle, i);

repeat
i:=ConnA.GetPlainDriver.backup_step(p, -1);
if i in [SQLITE_BUSY, SQLITE_LOCKED] then sleep(10);
until not (i in [SQLITE_BUSY, SQLITE_LOCKED]);
i:=ConnA.GetPlainDriver.backup_finish(p);
if i <> SQLITE_OK then ConnA.GetPlainDriver.ErrorString(ConnA.GetConnectionHandle, i);

ConB.Disconnect;
ConA.Disconnect;
end;


for a quick outline of the solution (maybe it was already but I didn't find it),
greetings

Re: adding backup SQLITE API

Posted: 26.08.2019, 06:54
by marsupilami
Hello,

we added the API to Zeos. Thank you for your support.

Best regards,

Jan