unit DatabaseTestExecutor; interface uses System.SysUtils, System.Diagnostics, ZConnection, ZDataset, ZExceptions, DataGenerator; type TDatabaseManager = class private FConnection: TZConnection; FDataGenerator: TDataGenerator; FSeed: Integer; FStopwatch: TStopwatch; function PerformSingleInsert(APrimaryKey: Integer): Double; function PerformSingleRead(APrimaryKey: Integer): Double; public constructor Create(AConnection:TZConnection; ASeed:Integer); destructor Destroy; override; function SetupDatabase: Boolean; function TestInserts(ACount:Integer): TArray; function TestReads(ACount:Integer): TArray; end; implementation constructor TDatabaseManager.Create(AConnection:TZConnection; ASeed:Integer); begin FSeed := ASeed; FConnection := AConnection; FDataGenerator := TDataGenerator.Create(FSeed); FStopwatch := TStopwatch.Create; end; destructor TDatabaseManager.Destroy; begin FreeAndNil(FDataGenerator); end; function TDatabaseManager.SetupDatabase: Boolean; begin var Query: TZQuery; Query := TZQuery.Create(nil); Query.Connection := FConnection; Query.Sql.Add('DROP TABLE IF EXISTS users'); try Query.ExecSQL; except on E: EZSQLException do begin Exit(False); end; end; Query.SQL.Clear; Query.SQL.Add('CREATE TABLE IF NOT EXISTS users (id INT PRIMARY KEY, email VARCHAR(255), social_security_number VARCHAR(255), age INT);'); try try Query.ExecSQL; except on E: EZSQLException do begin Exit(False); end end; finally FreeAndNil(Query); end; Result := True; end; function TDatabaseManager.PerformSingleInsert(APrimaryKey: Integer): Double; begin var LEmail: string; LEmail := FDataGenerator.GenerateRandomEmail; var LSocial: string; LSocial := FDataGenerator.GenerateRandomSocial; var LAge: Integer; LAge := FDataGenerator.GenerateRandomAge; var LQuery: TZQuery; try LQuery := TZQuery.Create(nil); LQuery.Connection := FConnection; LQuery.SQL.Add('INSERT INTO users (id, email, social_security_number, age) ' + 'VALUES (:id, :email, :ssn, :age)'); LQuery.ParamByName('id').AsInteger := APrimaryKey; LQuery.ParamByName('email').AsString := LEmail; LQuery.ParamByName('ssn').AsString := LSocial; LQuery.ParamByName('age').AsInteger := LAge; FStopwatch := TStopwatch.StartNew; try LQuery.ExecSQL; except on E: EZSQLException do begin Exit(-1.0); end end; finally FreeAndNil(LQuery); end; FStopwatch.Stop; Result := FStopwatch.ElapsedMilliseconds; end; function TDatabaseManager.PerformSingleRead(APrimaryKey: Integer): Double; begin var LQuery: TZQuery; try LQuery := TZQuery.Create(nil); LQuery.Connection := FConnection; LQuery.SQL.Add('SELECT id, email, social_security_number, age FROM users WHERE id = :id'); LQuery.ParamByName('id').AsInteger := APrimaryKey; FStopwatch := TStopwatch.StartNew; try LQuery.Open; except on E: EZSQLException do begin Exit(-1.0); end end; finally FreeAndNil(LQuery); end; FStopwatch.Stop; Result := FStopwatch.ElapsedMilliseconds; end; function TDatabaseManager.TestReads(ACount: Integer):Tarray; begin Result := TArray.Create(); var LIndex: Integer; for LIndex := 1 to ACount do begin var LRunResult := PerformSingleRead(LIndex); if LRunResult <> -1.0 then Result := Result + [LRunResult]; end; end; function TDatabaseManager.TestInserts(ACount: Integer): TArray; begin Result := TArray.Create(); var Index: Integer; for Index := 1 to ACount do begin var RunResult := PerformSingleInsert(Index); if RunResult <> -1.0 then Result := Result + [RunResult]; end; end; end.