adding backup SQLITE API
Posted: 22.08.2019, 11:29
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
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