mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-15 07:45:54 +01:00
TransactionContext (WIP)
This commit is contained in:
parent
b41e245bbc
commit
4349f20d95
@ -120,13 +120,16 @@ resourcestring
|
||||
' end);' + sLineBreak +
|
||||
'' + sLineBreak +
|
||||
' WebRequestHandlerProc.MaxConnections := dotEnv.Env(''dmvc.handler.max_connections'', 1024);' + sLineBreak +
|
||||
'' + sLineBreak +
|
||||
' if dotEnv.Env(''dmvc.profiler.enabled'', false) then' + sLineBreak +
|
||||
' begin' + sLineBreak +
|
||||
' Profiler.ProfileLogger := Log;' + sLineBreak +
|
||||
' Profiler.WarningThreshold := dotEnv.Env(''dmvc.profiler.warning_threshold'', 2000);' + sLineBreak +
|
||||
' end;' + sLineBreak +
|
||||
'' + sLineBreak +
|
||||
'' + sLineBreak +
|
||||
'' + sLineBreak +
|
||||
'{$IF CompilerVersion >= 34}' + sLineBreak +
|
||||
' if dotEnv.Env(''dmvc.profiler.enabled'', false) then' + sLineBreak +
|
||||
' begin' + sLineBreak +
|
||||
' Profiler.ProfileLogger := Log;' + sLineBreak +
|
||||
' Profiler.WarningThreshold := dotEnv.Env(''dmvc.profiler.warning_threshold'', 2000);' + sLineBreak +
|
||||
' end;' + sLineBreak +
|
||||
'{$ENDIF}' + sLineBreak +
|
||||
'' + sLineBreak +
|
||||
' RunServer(dotEnv.Env(''dmvc.server.port'', %1:d));' + sLineBreak +
|
||||
' except' + sLineBreak +
|
||||
' on E: Exception do' + sLineBreak +
|
||||
|
@ -116,7 +116,8 @@ contains
|
||||
MVCFramework.DotEnv in '..\..\sources\MVCFramework.DotEnv.pas',
|
||||
MVCFramework.Serializer.URLEncoded in '..\..\sources\MVCFramework.Serializer.URLEncoded.pas',
|
||||
MVCFramework.Signal in '..\..\sources\MVCFramework.Signal.pas',
|
||||
MVCFramework.Serializer.Text in '..\..\sources\MVCFramework.Serializer.Text.pas';
|
||||
MVCFramework.Serializer.Text in '..\..\sources\MVCFramework.Serializer.Text.pas',
|
||||
MVCFramework.Container in '..\..\sources\MVCFramework.Container.pas';
|
||||
|
||||
end.
|
||||
|
||||
|
@ -208,6 +208,7 @@
|
||||
<DCCReference Include="..\..\sources\MVCFramework.Serializer.URLEncoded.pas"/>
|
||||
<DCCReference Include="..\..\sources\MVCFramework.Signal.pas"/>
|
||||
<DCCReference Include="..\..\sources\MVCFramework.Serializer.Text.pas"/>
|
||||
<DCCReference Include="..\..\sources\MVCFramework.Container.pas"/>
|
||||
<BuildConfiguration Include="Base">
|
||||
<Key>Base</Key>
|
||||
</BuildConfiguration>
|
||||
|
@ -319,6 +319,15 @@ object MainForm: TMainForm
|
||||
TabOrder = 31
|
||||
OnClick = btnCRUDWithOptionsClick
|
||||
end
|
||||
object btnTransaction: TButton
|
||||
Left = 144
|
||||
Top = 602
|
||||
Width = 121
|
||||
Height = 35
|
||||
Caption = 'Automatic Transactions'
|
||||
TabOrder = 32
|
||||
OnClick = btnTransactionClick
|
||||
end
|
||||
object FDConnection1: TFDConnection
|
||||
Left = 312
|
||||
Top = 40
|
||||
|
@ -27,6 +27,8 @@ uses
|
||||
FireDAC.Comp.Client,
|
||||
MVCFramework.Nullables,
|
||||
MVCFramework.ActiveRecord,
|
||||
MVCFramework.Logger,
|
||||
|
||||
System.Generics.Collections, System.Diagnostics;
|
||||
|
||||
type
|
||||
@ -64,6 +66,7 @@ type
|
||||
btnObjectVersion: TButton;
|
||||
btnCustomTable: TButton;
|
||||
btnCRUDWithOptions: TButton;
|
||||
btnTransaction: TButton;
|
||||
procedure btnCRUDClick(Sender: TObject);
|
||||
procedure btnInheritanceClick(Sender: TObject);
|
||||
procedure btnMultiThreadingClick(Sender: TObject);
|
||||
@ -98,6 +101,7 @@ type
|
||||
procedure btnObjectVersionClick(Sender: TObject);
|
||||
procedure btnCustomTableClick(Sender: TObject);
|
||||
procedure btnCRUDWithOptionsClick(Sender: TObject);
|
||||
procedure btnTransactionClick(Sender: TObject);
|
||||
private
|
||||
procedure Log(const Value: string);
|
||||
procedure LoadCustomers(const HowManyCustomers: Integer = 50);
|
||||
@ -1896,6 +1900,33 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.btnTransactionClick(Sender: TObject);
|
||||
begin
|
||||
Log('# TransactionContext');
|
||||
try
|
||||
begin var Ctx := TMVCActiveRecord.UseTransactionContext;
|
||||
TMVCActiveRecord.GetByPK<TCustomer>(-1); // will raise EMVCActiveRecordNotFound
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
Log('#1 - TransactionContext caught the exception (doing an automatic rollback)');
|
||||
end;
|
||||
end;
|
||||
|
||||
begin var Ctx := TMVCActiveRecord.UseTransactionContext;
|
||||
var lCustomer := TCustomer.Create;
|
||||
try
|
||||
lCustomer.CompanyName := 'Transaction Inc.';
|
||||
lCustomer.LastContact := Now();
|
||||
lCustomer.Insert;
|
||||
finally
|
||||
lCustomer.Free;
|
||||
end;
|
||||
Log('#2 - TransactionContext automatically committed changes (because no exceptions have been raised within the TransactionContext)');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.btnReadOnlyFieldsClick(Sender: TObject);
|
||||
var
|
||||
lCustomer: TCustomerWithReadOnlyFields;
|
||||
|
@ -26,6 +26,7 @@ unit MVCFramework.ActiveRecord;
|
||||
|
||||
{$I dmvcframework.inc}
|
||||
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
@ -65,6 +66,16 @@ type
|
||||
TMVCActiveRecordClass = class of TMVCActiveRecord;
|
||||
TMVCActiveRecord = class;
|
||||
|
||||
{$IF Defined(CUSTOM_MANAGED_RECORDS)}
|
||||
TMVCTransactionContext = record
|
||||
private
|
||||
fConnection: TFDConnection;
|
||||
public
|
||||
class operator Finalize(var Dest: TMVCTransactionContext);
|
||||
class operator Assign (var Dest: TMVCTransactionContext; const [ref] Src: TMVCTransactionContext);
|
||||
constructor Create(Connection: TFDConnection); overload;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
TMVCActiveRecordFieldOption = (
|
||||
/// <summary>
|
||||
@ -588,6 +599,9 @@ type
|
||||
class function All<T: TMVCActiveRecord, constructor>: TObjectList<T>; overload;
|
||||
class function DeleteRQL<T: TMVCActiveRecord>(const RQL: string = ''): Int64; overload;
|
||||
class function Count<T: TMVCActiveRecord>(const RQL: string = ''): Int64; overload;
|
||||
{$IF Defined(CUSTOM_MANAGED_RECORDS)}
|
||||
class function UseTransactionContext: TMVCTransactionContext;
|
||||
{$ENDIF}
|
||||
|
||||
{ Where }
|
||||
class function Where<T: TMVCActiveRecord, constructor>(const SQLWhere: string;
|
||||
@ -2216,6 +2230,13 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{$IF Defined(CUSTOM_MANAGED_RECORDS)}
|
||||
class function TMVCActiveRecordHelper.UseTransactionContext: TMVCTransactionContext;
|
||||
begin
|
||||
Result := TMVCTransactionContext.Create(TMVCActiveRecord.CurrentConnection);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
class function TMVCActiveRecordHelper.TryGetRQLQuery<T>(
|
||||
const QueryName: String; out NamedRQLQuery: TRQLQueryWithName): Boolean;
|
||||
var
|
||||
@ -4759,6 +4780,38 @@ begin
|
||||
Create(True);
|
||||
end;
|
||||
|
||||
{ TMVCTransactionContext }
|
||||
|
||||
{$IF Defined(CUSTOM_MANAGED_RECORDS)}
|
||||
|
||||
constructor TMVCTransactionContext.Create(Connection: TFDConnection);
|
||||
begin
|
||||
fConnection := nil;
|
||||
end;
|
||||
|
||||
class operator TMVCTransactionContext.Assign(var Dest: TMVCTransactionContext; const [ref] Src: TMVCTransactionContext);
|
||||
begin
|
||||
Dest.fConnection := TMVCActiveRecord.CurrentConnection;
|
||||
Dest.fConnection.StartTransaction;
|
||||
end;
|
||||
|
||||
class operator TMVCTransactionContext.Finalize(var Dest: TMVCTransactionContext);
|
||||
begin
|
||||
if Dest.fConnection <> nil then
|
||||
begin
|
||||
if ExceptAddr <> nil then
|
||||
begin
|
||||
Dest.fConnection.Rollback;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Dest.fConnection.Commit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{$ENDIF}
|
||||
|
||||
initialization
|
||||
|
||||
gConnectionsLock := TObject.Create;
|
||||
|
@ -47,6 +47,7 @@ type
|
||||
end;
|
||||
|
||||
TRegistration = class
|
||||
public
|
||||
Intf: TGUID;
|
||||
Clazz: TClassOfInterfacedObject;
|
||||
RttiType: TRttiType;
|
||||
|
@ -100,3 +100,7 @@ DelphiMVCFramework is compatible with Delphi version XE7 or better
|
||||
{$ENDIF}
|
||||
{$DEFINE USEFIREDAC}
|
||||
|
||||
{$IF Defined(SYDNEYORBETTER)}
|
||||
{$DEFINE CUSTOM_MANAGED_RECORDS}
|
||||
{$ENDIF}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user