program Main; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Math, System.Classes, ZConnection, ZDataset, DatabaseTestExecutor in 'DatabaseTestExecutor.pas', DataGenerator in 'DataGenerator.pas'; function GetStringArg(const ASwitch, ADefault: string): string; begin if not FindCmdLineSwitch(ASwitch, Result, True) then Result := ADefault; end; function GetIntArg(const ASwitch: string; ADefault: Integer): Integer; begin var LStrValue: string; if FindCmdLineSwitch(ASwitch, LStrValue, True) then Result := StrToIntDef(LStrValue, ADefault) else Result := ADefault; end; procedure WriteResultsToCSV(const AFileName, AActionType: string; const ATimes: TArray); begin var LFileExists: Boolean; LFileExists := FileExists(AFileName); var LWriter: TStreamWriter; LWriter := TStreamWriter.Create(AFileName, True); // True enables Append mode try if not LFileExists then LWriter.WriteLine('actiontype,value'); var LTime: Double; for LTime in ATimes do begin LWriter.WriteLine(AActionType + ',' + FloatToStr(LTime)); end; finally LWriter.Free; end; end; var LConnection: TZConnection; begin var LHost: string; LHost := GetStringArg('host', 'localhost'); var LPort: Integer; LPort := GetIntArg('port', 5433); var LDatabase: string; LDatabase := GetStringArg('db', 'test_db'); var LUser: string; LUser := GetStringArg('user', 'postgres'); var LPassword: string; LPassword := GetStringArg('pass', 'postgres'); var LSeed: Integer; LSeed := GetIntArg('seed', 1234); var LNumActions: Integer; LNumActions := GetIntArg('ops', 10000); var LOutputFileName: string; LOutputFileName := GetStringArg('out', ''); if LOutputFileName = '' then begin LOutputFileName := Format('test_results_%s.csv', [FormatDateTime('yyyymmdd_hhnnss_zzz', Now)]); end; Writeln('Test results will be saved to: ', LOutputFileName); Writeln('-------------------------'); LConnection := TZConnection.Create(nil); LConnection.LibraryLocation := ExtractFilePath(ParamStr(0)) + 'libpq.dll'; try LConnection.Protocol := 'postgresql'; LConnection.HostName := LHost; LConnection.Port := LPort; LConnection.Database := LDatabase; LConnection.User := LUser; LConnection.Password := LPassword; Writeln('Connecting to PostgreSQL...'); LConnection.Connect; Writeln('Connected successfully!'); Writeln('-------------------------'); var DatabaseManager: TDatabaseManager; DatabaseManager := TDatabaseManager.Create(LConnection, LSeed); try var SetupSuccess: Boolean; SetupSuccess := DatabaseManager.SetupDatabase(); if SetupSuccess then begin Writeln('Done setting up database!'); end else begin Writeln('Failed to setup database connection!'); end; Writeln('-------------------------'); WriteLn('Testing Database Inserts'); var LInsertTimes: TArray; LInsertTimes := DatabaseManager.TestInserts(LNumActions); WriteResultsToCSV(LOutputFileName, 'insert', LInsertTimes); var LMeanInsertTime: Double; LMeanInsertTime := Mean(LInsertTimes); if Length(LInsertTimes) <> LNumActions then begin WriteLn('All inserts did not complete, got=' + Length(LInsertTimes).ToString + ' expected=' + LNumActions.ToString); end else begin WriteLn(LNumActions.ToString + ' inserts completed, average time ' + LMeanInsertTime.ToString + 'ms'); end; Writeln('-------------------------'); WriteLn('Testing reading back each record by primary key'); var LReadTimes: TArray; LReadTimes := TArray.Create(); LReadTimes := DatabaseManager.TestReads(LNumActions); WriteResultsToCSV(LOutputFileName, 'read_pk', LReadTimes); var LMeanReadTime: Double; LMeanReadTime := Mean(LReadTimes); if Length(LReadTimes) <> LNumActions then begin WriteLn('All reads did not complete, got=' + Length(LReadTimes).ToString + ' expected=' + LNumActions.ToString); end else begin WriteLn(LNumActions.ToString + ' reads completed, average time ' + LMeanReadTime.ToString + 'ms'); end; Writeln('-------------------------'); WriteLn('Testing reading back each record by email'); var LReadByEmailTimes: TArray; LReadByEmailTimes := DatabaseManager.TestReadsByEmail(); WriteResultsToCSV(LOutputFileName, 'read_email', LReadByEmailTimes); var LMeanReadByEmailTime: Double; LMeanReadByEmailTime := Mean(LReadByEmailTimes); if Length(LReadByEmailTimes) <> LNumActions then begin WriteLn('All reads by email did not complete, got=' + Length(LReadByEmailTimes).ToString + ' expected=' + LNumActions.ToString); end else begin WriteLn(LNumActions.ToString + ' reads by email completed, average time ' + LMeanReadByEmailTime.ToString + 'ms'); end; Writeln('-------------------------'); WriteLn('Testing reading back each record by social security number'); var LReadBySocialTimes: TArray; LReadBySocialTimes := DatabaseManager.TestReadsBySocial(); WriteResultsToCSV(LOutputFileName, 'read_social', LReadBySocialTimes); var LMeanReadBySocialTime: Double; LMeanReadBySocialTime := Mean(LReadBySocialTimes); if Length(LReadBySocialTimes) <> LNumActions then begin WriteLn('All reads by social did not complete, got=' + Length(LReadBySocialTimes).ToString + ' expected=' + LNumActions.ToString); end else begin WriteLn(LNumActions.ToString + ' reads by social completed, average time ' + LMeanReadBySocialTime.ToString + 'ms'); end; finally DatabaseManager.Free; end; finally FreeAndNil(LConnection); end; Writeln('-------------------------'); Writeln('Press Enter to exit...'); Readln; end.