Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program TestMasterDetail;
- {$APPTYPE CONSOLE}
- // comment this line to switch to TSQLRestServerFullMemory
- // or we will use TSQLRestServerDB.
- {$DEFINE USE_SQLITE3}
- uses
- SysUtils,
- SynCommons,
- {$IFDEF USE_SQLITE3}SynSQLite3Static,{$ENDIF}
- SynTests,
- mORMot
- {$IFDEF USE_SQLITE3},mORMotSQLite3{$ENDIF};
- type
- // some DTO
- TMaster = packed record
- MasterName: String;
- end;
- TMasters = array of TMaster;
- TDetail = packed record
- Master: TMaster;
- DetailName: String;
- end;
- TDetails = array of TDetail;
- // first class - to be referenced.
- TSQLRecordMaster=class(TSQLRecord)
- private
- fDummyName: RawUTF8;
- published
- property DummyName: RawUTF8 read fDummyName write fDummyName;
- end;
- // second class - references first one.
- TSQLRecordDetail=class(TSQLRecord)
- private
- fMaster: TID;
- fDummyName: RawUTF8;
- published
- property Master: TID read fMaster write fMaster;
- property DummyName: RawUTF8 read fDummyName write fDummyName;
- end;
- TDummyService=class
- private
- fModel: TSQLModel;
- fRest: TSQLRestServer;
- public
- constructor Create;
- destructor Destroy; override;
- procedure MasterAdd(aMaster: TMaster);
- procedure MasterRemove(aMaster: TMaster);
- function MasterGet(out aMasters: TMasters): Integer;
- procedure DetailAdd(aMaster: TMaster; aDetail: TDetail);
- procedure DetailRemove(aMaster: TMaster; aDetail: TDetail);
- function DetailGet(aMaster: TMaster; out aDetails: TDetails): Integer;
- procedure ClearAll;
- end;
- TTestDummyService=class(TSynTestCase)
- private
- fService: TDummyService;
- published
- procedure SetupAll;
- procedure TestMasterAddGetRemove;
- procedure TestDetailAddGetRemove;
- procedure TeardownAll;
- end;
- TTestMasterDetailMode=class(TSynTests)
- published
- procedure TestAll;
- end;
- { TDummyService }
- procedure TDummyService.ClearAll;
- begin
- fRest.Delete(TSQLRecordDetail, '');
- fRest.Delete(TSQLRecordMaster, '');
- end;
- constructor TDummyService.Create;
- begin
- inherited;
- fModel := TSQLModel.Create([TSQLRecordMaster, TSQLRecordDetail]);
- {$IFDEF USE_SQLITE3}
- fRest := TSQLRestServerDB.Create(fModel);
- {$ELSE}
- fRest := TSQLRestServerFullMemory.Create(fModel,
- ChangeFileExt(ExeVersion.ProgramName, '.json'));
- {$ENDIF}
- fRest.CreateMissingTables;
- end;
- destructor TDummyService.Destroy;
- begin
- fRest.Free;
- fModel.Free;
- inherited;
- end;
- procedure TDummyService.DetailAdd(aMaster: TMaster; aDetail: TDetail);
- var
- qMaster: TSQLRecordMaster;
- qDetail: TSQLRecordDetail;
- begin
- with TSQLRecordMaster.AutoFree(qMaster,fRest,'DummyName=?',
- [aMaster.MasterName]) do
- if qMaster.FillOne then
- with TSQLRecordDetail.AutoFree(qDetail,fRest,'Master=? and DummyName=?',
- [qMaster.ID,aDetail.DetailName]) do
- if not qDetail.FillOne then
- begin
- qDetail.Master := qMaster.ID;
- qDetail.DummyName := aDetail.DetailName;
- fRest.Add(qDetail, True);
- end;
- end;
- function TDummyService.DetailGet(aMaster: TMaster; out aDetails: TDetails):
- Integer;
- var
- qMaster: TSQLRecordMaster;
- qDetail: TSQLRecordDetail;
- begin
- Result := 0;
- with TSQLRecordMaster.AutoFree(qMaster,fRest,'DummyName=?',
- [aMaster.MasterName]) do
- if qMaster.FillOne then
- with TSQLRecordDetail.AutoFree(qDetail,fRest,'Master=?',
- [qMaster.ID]) do
- while qDetail.FillOne do // always jump to the end
- begin
- SetLength(aDetails, Result+1);
- aDetails[Result].Master := aMaster;
- aDetails[Result].DetailName := qDetail.DummyName;
- Inc(Result);
- end;
- end;
- procedure TDummyService.DetailRemove(aMaster: TMaster; aDetail: TDetail);
- var
- qMaster: TSQLRecordMaster;
- qDetail: TSQLRecordDetail;
- begin
- with TSQLRecordMaster.AutoFree(qMaster,fRest,'DummyName=?',
- [aMaster.MasterName]) do
- if qMaster.FillOne then
- with TSQLRecordDetail.AutoFree(qDetail,fRest,'Master=? and DummyName=?',
- [qMaster.ID,aDetail.DetailName]) do
- if qDetail.FillOne then
- fRest.Delete(TSQLRecordDetail, qDetail.ID);
- end;
- procedure TDummyService.MasterAdd(aMaster: TMaster);
- var
- qMaster: TSQLRecordMaster;
- begin
- with TSQLRecordMaster.AutoFree(qMaster, fRest, 'DummyName=?',
- [aMaster.MasterName]) do
- if not qMaster.FillOne then
- begin
- qMaster.DummyName := aMaster.MasterName;
- fRest.Add(qMaster, True);
- end;
- end;
- function TDummyService.MasterGet(out aMasters: TMasters): Integer;
- var
- qMaster: TSQLRecordMaster;
- begin
- Result := 0;
- with TSQLRecordMaster.AutoFree(qMaster, fRest, '', []) do
- while qMaster.FillOne do
- begin
- SetLength(aMasters, Result + 1);
- aMasters[Result].MasterName := qMaster.DummyName;
- Inc(Result);
- end;
- end;
- procedure TDummyService.MasterRemove(aMaster: TMaster);
- var
- qMaster: TSQLRecordMaster;
- begin
- with TSQLRecordMaster.AutoFree(qMaster, fRest, 'DummyName=?',
- [aMaster.MasterName]) do
- if qMaster.FillOne then
- fRest.Delete(TSQLRecordMaster, qMaster.ID);
- end;
- { TTestDummyService }
- procedure TTestDummyService.SetupAll;
- begin
- fService := TDummyService.Create;
- end;
- procedure TTestDummyService.TeardownAll;
- begin
- fService.ClearAll;
- fService.Free;
- end;
- procedure TTestDummyService.TestDetailAddGetRemove;
- const
- TestMasterName='This is Master';
- TestDetailName1='This is detail No.1';
- TestDetailName2='This is detail No.2';
- TestDetailNameNotExist='I''m not here.';
- var
- oMaster: TMaster;
- oMastersGot: TMasters;
- oDetail: TDetail;
- oDetailsGot: TDetails;
- begin
- if CheckFailed(nil <> fService) then Exit;
- oMaster.MasterName := TestMasterName;
- fService.MasterAdd(oMaster);
- Check(1=fService.MasterGet(oMastersGot));
- Check(0=fService.DetailGet(oMaster, oDetailsGot));
- oDetail.Master := oMaster;
- oDetail.DetailName := TestDetailName1;
- fService.DetailAdd(oMaster, oDetail);
- Check(1=fService.DetailGet(oMaster, oDetailsGot));
- oDetail.DetailName := TestDetailName2;
- fService.DetailAdd(oMaster, oDetail);
- Check(2=fService.DetailGet(oMaster, oDetailsGot));
- oDetail.DetailName:=TestDetailNameNotExist;
- fService.DetailRemove(oMaster, oDetail);
- Check(2=fService.DetailGet(oMaster, oDetailsGot));
- oDetail.DetailName := TestDetailName1;
- fService.DetailRemove(oMaster, oDetail);
- Check(1=fService.DetailGet(oMaster, oDetailsGot));
- end;
- procedure TTestDummyService.TestMasterAddGetRemove;
- const
- TestMasterName1='Hello,world';
- TestMasterName2='Hello,world,again';
- TestMasterNameError='error';
- var
- oMaster: TMaster;
- oMastersGot: TMasters;
- begin
- if CheckFailed(nil <> fService) then Exit;
- Check(0=fService.MasterGet(oMastersGot));
- oMaster.MasterName:=TestMasterName1;
- fService.MasterAdd(oMaster);
- Check(1=fService.MasterGet(oMastersGot));
- Check(TestMasterName1=oMastersGot[0].MasterName);
- oMaster.MasterName:=TestMasterName2;
- fService.MasterAdd(oMaster);
- Check(2=fService.MasterGet(oMastersGot));
- oMaster.MasterName:=TestMasterName1;
- fService.MasterRemove(oMaster);
- Check(1=fService.MasterGet(oMastersGot));
- oMaster.MasterName:=TestMasterNameError;
- fService.MasterRemove(oMaster);
- Check(1=fService.MasterGet(oMastersGot));
- oMaster.MasterName:=TestMasterName2;
- fService.MasterRemove(oMaster);
- Check(0=fService.MasterGet(oMastersGot));
- end;
- { TTestMasterDetailMode }
- procedure TTestMasterDetailMode.TestAll;
- begin
- AddCase([TTestDummyService]);
- end;
- begin
- with TTestMasterDetailMode.Create() do
- try
- Run;
- ReadLn;
- finally
- Free;
- end;
- // try
- // { TODO -oUser -cConsole Main : Insert code here }
- // except
- // on E: Exception do
- // Writeln(E.ClassName, ': ', E.Message);
- // end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement