diff --git a/README.md b/README.md index 7580d233..084f3eb4 100644 --- a/README.md +++ b/README.md @@ -435,6 +435,8 @@ This version introduced new features in many different areas (swagger, server si - ⚡Improved! MVCActiveRecord doeas a better job to handle TDate/TTime/TDateTime types for SQLite (it is automatic because SQLite doesn't support date/time types). - ⚡Improved! PostgreSQL, FirebirdSQL, Interbase and SQLite now support tablename and fields with spaces. - ⚡New! Mechanism to customize the JWT claims setup using the client request as suggested in [issue495](https://github.com/danieleteti/delphimvcframework/issues/495) +- ⚡New! Added `TMVCActiveRecord.Merge(CurrentListOfT, ChangesOfT)` to allow merge between two lists of `TMVCActiveRecord` descendants using `UnitOfWork` design pattern. Check the button "Merge" in demo "activerecord_showcase". +- ⚡New! Added new default parameter to `TMVCActiveRecord.RemoveDefaultConnection` and `TMVCActiveRecord.RemoveConnection` to avoid exceptions in case of not initialized connection. - ⚡New! `MVCFromBody` attribute, useful to automatically inject the request body as actual object in the action paramaters. For instance in the following action the body request is automatically deserialized as an object of class TPerson. ```delphi //interface @@ -532,6 +534,7 @@ This version introduced new features in many different areas (swagger, server si - Fix https://github.com/danieleteti/delphimvcframework/issues/493 (thanks to [DelphiMan68](https://github.com/DelphiMan68) for his initial analisys) - Fix for nil objects in lists during serialization - Uniformed behavior in `Update` and `Delete` method in `TMVCActiveRecord`. Now these methods raise an exception if the record doesn't exists anymore in the table (update or delete statements return `AffectedRows` = 0). The behavior can be altered using the new parameter in the call, which by default is `true`. WARNING! This change could raise some incompatibilities with the previous version, however this is the correct behavior. Consider the previous one a "incorrect behavior to fix". +- Fix https://github.com/danieleteti/delphimvcframework/issues/489 ## Older Releases diff --git a/samples/activerecord_showcase/EngineChoiceFormU.pas b/samples/activerecord_showcase/EngineChoiceFormU.pas index b3f56722..16ee1175 100644 --- a/samples/activerecord_showcase/EngineChoiceFormU.pas +++ b/samples/activerecord_showcase/EngineChoiceFormU.pas @@ -25,7 +25,7 @@ type fSelectedRDBMS: TRDBMSEngine; function SelectedRDBMS: TRDBMSEngine; public - class function Execute: TRDBMSEngine; + class function Execute(out Engine: TRDBMSEngine): Boolean; end; implementation @@ -39,20 +39,16 @@ begin ModalResult := mrOk; end; -class function TEngineChoiceForm.Execute: TRDBMSEngine; +class function TEngineChoiceForm.Execute(out Engine: TRDBMSEngine): Boolean; var lFrm: TEngineChoiceForm; begin - Result := TRDBMSEngine.PostgreSQL; lFrm := TEngineChoiceForm.Create(nil); try - if lFrm.ShowModal = mrOk then + Result := lFrm.ShowModal = mrOk; + if Result then begin - Result := lFrm.SelectedRDBMS; - end - else - begin - Application.Terminate; + Engine := lFrm.SelectedRDBMS; end; finally lFrm.Free; diff --git a/samples/activerecord_showcase/MainFormU.pas b/samples/activerecord_showcase/MainFormU.pas index 3a26daed..a178f3cd 100644 --- a/samples/activerecord_showcase/MainFormU.pas +++ b/samples/activerecord_showcase/MainFormU.pas @@ -438,7 +438,6 @@ var lCustomer: TCustomer; lCustomers: TObjectList; lCustomersChanges: TObjectList; - lMultiExecutor: IMVCMultiExecutor; begin Log('** IMVCMultiExecutor demo'); TMVCActiveRecord.DeleteAll(TCustomer); @@ -1276,12 +1275,19 @@ end; procedure TMainForm.FormDestroy(Sender: TObject); begin - ActiveRecordConnectionsRegistry.RemoveDefaultConnection; + ActiveRecordConnectionsRegistry.RemoveDefaultConnection(False); end; procedure TMainForm.FormShow(Sender: TObject); +var + lEngine: TRDBMSEngine; begin - case TEngineChoiceForm.Execute of + if not TEngineChoiceForm.Execute(lEngine) then + begin + Close; + Exit; + end; + case lEngine of TRDBMSEngine.PostgreSQL: begin FDConnectionConfigU.CreatePostgresqlPrivateConnDef(True); diff --git a/sources/MVCFramework.ActiveRecord.pas b/sources/MVCFramework.ActiveRecord.pas index 44ff1cb3..a4080123 100644 --- a/sources/MVCFramework.ActiveRecord.pas +++ b/sources/MVCFramework.ActiveRecord.pas @@ -440,8 +440,8 @@ type procedure AddConnection(const aName: string; const aConnection: TFDConnection; const Owns: Boolean = false); procedure AddDefaultConnection(const aConnection: TFDConnection; const Owns: Boolean = false); - procedure RemoveConnection(const aName: string); - procedure RemoveDefaultConnection; + procedure RemoveConnection(const aName: string; const RaiseExceptionIfNotAvailable: Boolean = True); + procedure RemoveDefaultConnection(const RaiseExceptionIfNotAvailable: Boolean = True); procedure SetCurrent(const aName: string); function GetCurrent(const RaiseExceptionIfNotAvailable: Boolean = True): TFDConnection; function GetCurrentBackend: string; @@ -468,8 +468,8 @@ type procedure AddConnection(const aName: string; const aConnection: TFDConnection; const aOwns: Boolean = false); procedure AddDefaultConnection(const aConnection: TFDConnection; const aOwns: Boolean = false); - procedure RemoveConnection(const aName: string); - procedure RemoveDefaultConnection; + procedure RemoveConnection(const aName: string; const RaiseExceptionIfNotAvailable: Boolean = True); + procedure RemoveDefaultConnection(const RaiseExceptionIfNotAvailable: Boolean = True); procedure SetCurrent(const aName: string); function GetCurrent(const RaiseExceptionIfNotAvailable: Boolean = True): TFDConnection; function GetByName(const aName: string): TFDConnection; @@ -787,7 +787,7 @@ begin Result := Format('%10.10d::%s', [TThread.CurrentThread.ThreadID, aName]); end; -procedure TMVCConnectionsRepository.RemoveConnection(const aName: string); +procedure TMVCConnectionsRepository.RemoveConnection(const aName: string; const RaiseExceptionIfNotAvailable: Boolean = True); var lName: string; lKeyName: string; @@ -799,7 +799,16 @@ begin fMREW.BeginWrite; try if not fConnectionsDict.TryGetValue(lKeyName, lConnHolder) then - raise Exception.CreateFmt('Unknown connection %s', [aName]); + begin + if RaiseExceptionIfNotAvailable then + begin + raise Exception.CreateFmt('Unknown connection %s', [aName]) + end + else + begin + Exit; + end; + end; fConnectionsDict.Remove(lKeyName); try FreeAndNil(lConnHolder); @@ -815,9 +824,9 @@ begin end; end; -procedure TMVCConnectionsRepository.RemoveDefaultConnection; +procedure TMVCConnectionsRepository.RemoveDefaultConnection(const RaiseExceptionIfNotAvailable: Boolean = True); begin - RemoveConnection('default'); + RemoveConnection('default', RaiseExceptionIfNotAvailable); end; procedure TMVCConnectionsRepository.SetCurrent(const aName: string);