program project1;
uses
cthreads,Classes, SysUtils, sqlite3conn, sqldb, FileUtil, syncobjs;
var
sync: TCriticalSection;
identifier: Integer;
gotit: Boolean;
ended: Integer;
procedure Insert(dbIdentifier: Integer; cycle: Integer);
var
connection: TSQLite3Connection;
transaction: TSQLTransaction;
q: TSQLQuery;
step: Integer;
begin
step := 0;
try
connection := TSQLite3Connection.Create(nil);
Inc(step);
try
connection.DatabaseName := 'sqlite_db_' + IntToStr(dbIdentifier);
Inc(step);
transaction := TSQLTransaction.Create(nil);
Inc(step);
try
transaction.SQLConnection := connection;
Inc(step);
transaction.StartTransaction();
Inc(step);
q := TSQLQuery.Create(nil);
Inc(step);
try
q.SQLConnection := connection;
Inc(step);
q.Transaction := transaction;
Inc(step);
q.SQL.Add('insert into Table1 (id, v1) values ('+ IntToStr(dbIdentifier) + ', ''value' + IntToStr(dbIdentifier) + ''')');
Inc(step);
try
q.ExecSQL();
Inc(step);
transaction.Commit();
Inc(step);
Sleep(1); // INNER LOOP SLEEP
except
on E: Exception do
begin
transaction.Rollback();
Writeln('Internal error ' + IntToStr(dbIdentifier) + ' ' + E.Message)
end;
end;
finally
FreeAndNil(q);
end;
finally
FreeAndNil(transaction);
end;
finally
FreeAndNil(connection);
end;
except
on E: Exception do
begin
Writeln('Internal error unhandled ' + IntToStr(dbIdentifier) + ' cycle ' + IntToStr(cycle) + 'step ' + IntToStr(step) + ' ' + E.Message);
raise;
end;
end;
end;
function TExec(parameter : pointer) : ptrint;
var
localIdentifier: Integer;
i: Integer;
begin
if parameter <> nil then
Result := 0
else
Result := 0;
try
localIdentifier := identifier;
gotit := True;
// Make sure databases are reset to original empty status
if FileExists('sqlite_db_' + IntToStr(localIdentifier)) then DeleteFile('sqlite_db_' + IntToStr(localIdentifier));
if FileExists('sqlite_db_' + IntToStr(localIdentifier) + '-journal') then DeleteFile('sqlite_db_' + IntToStr(localIdentifier) + '-journal');
CopyFile('template-sqlite_db_' + IntToStr(localIdentifier), 'sqlite_db_' + IntToStr(localIdentifier));
i := 0;
repeat
Insert(localIdentifier, i);
Inc(i);
until i > 1000; // NUMBER OF REPETITIONS
except
on E: Exception do
begin
Writeln('External error on ' + IntToStr(localIdentifier) + ' ' + E.Message)
end;
end;
sync.Acquire();
try
Inc(ended);
finally
sync.Release();
end;
EndThread(0);
end;
begin
sync := TCriticalSection.Create();
// Threads do not exist yet, so no need of semaphore to init ended
ended := 0;
identifier := 1 ; gotit := False; BeginThread(@TExec); while (not gotit) do Sleep(100);
identifier := 2 ; gotit := False; BeginThread(@TExec); while (not gotit) do Sleep(100);
identifier := 3 ; gotit := False; BeginThread(@TExec); while (not gotit) do Sleep(100);
identifier := 4 ; gotit := False; BeginThread(@TExec); while (not gotit) do Sleep(100);
identifier := 5 ; gotit := False; BeginThread(@TExec); while (not gotit) do Sleep(100);
identifier := 6 ; gotit := False; BeginThread(@TExec); while (not gotit) do Sleep(100);
identifier := 7 ; gotit := False; BeginThread(@TExec); while (not gotit) do Sleep(100);
identifier := 8 ; gotit := False; BeginThread(@TExec); while (not gotit) do Sleep(100);
identifier := 9 ; gotit := False; BeginThread(@TExec); while (not gotit) do Sleep(100);
identifier := 10; gotit := False; BeginThread(@TExec); while (not gotit) do Sleep(100);
while True do
begin
sync.Acquire();
try
if ended >= 10 then
Exit;
finally
sync.Release();
end;
Sleep(1);
end;
Writeln('ended');
Sleep(100);
sync.Destroy();
end.