From d4e0e6b5ea5255e5b28701677e84019ff773f0b8 Mon Sep 17 00:00:00 2001 From: Daniele Teti Date: Thu, 16 Jan 2025 22:37:27 +0100 Subject: [PATCH] Session engine realigned --- samples/sessions/AppControllerU.pas | 13 +++++++++++++ samples/sessions/SessionSample.dpr | 2 +- samples/sessions/SessionSample.dproj | 2 +- samples/sessions_on_database/WebModuleUnit1.pas | 11 ++++++++++- sources/MVCFramework.Serializer.HTML.pas | 2 +- sources/MVCFramework.Session.Database.pas | 13 ++++++------- sources/MVCFramework.Session.pas | 14 ++++++++------ 7 files changed, 40 insertions(+), 17 deletions(-) diff --git a/samples/sessions/AppControllerU.pas b/samples/sessions/AppControllerU.pas index 2cfa13a4..9a217fff 100644 --- a/samples/sessions/AppControllerU.pas +++ b/samples/sessions/AppControllerU.pas @@ -17,6 +17,10 @@ TApp1MainController = class(TMVCController) [MVCHTTPMethod([httpGET])] procedure Index; + [MVCPath('/inc')] + [MVCHTTPMethod([httpGET])] + function DoInc: String; + [MVCPath('/started')] [MVCHTTPMethod([httpGET])] function SessionStarted: Boolean; @@ -33,8 +37,17 @@ TApp1MainController = class(TMVCController) implementation +uses + System.SysUtils; + { TApp1MainController } +function TApp1MainController.DoInc: String; +begin + Session['value'] := (StrToIntDef(Session['value'], 0) + 1).ToString; + Result := Session['value']; +end; + procedure TApp1MainController.DoLogin(username: string); begin Session['username'] := username; diff --git a/samples/sessions/SessionSample.dpr b/samples/sessions/SessionSample.dpr index 7f357039..6162f65f 100644 --- a/samples/sessions/SessionSample.dpr +++ b/samples/sessions/SessionSample.dpr @@ -25,7 +25,7 @@ procedure RunServer(APort: Integer); var LServer: TIdHTTPWebBrokerBridge; begin - LogI(Format('Starting HTTP Server or port %d', [APort])); + LogI(Format('Listening on http://localhost:%d', [APort])); LServer := TIdHTTPWebBrokerBridge.Create(nil); try LServer.DefaultPort := APort; diff --git a/samples/sessions/SessionSample.dproj b/samples/sessions/SessionSample.dproj index e7b28c9a..59c85211 100644 --- a/samples/sessions/SessionSample.dproj +++ b/samples/sessions/SessionSample.dproj @@ -50,7 +50,7 @@ $(BDS)\bin\delphi_PROJECTICON.ico System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) .\$(Platform)\$(Config) - .\$(Platform)\$(Config) + bin false false false diff --git a/samples/sessions_on_database/WebModuleUnit1.pas b/samples/sessions_on_database/WebModuleUnit1.pas index ba3410f5..0e390aab 100644 --- a/samples/sessions_on_database/WebModuleUnit1.pas +++ b/samples/sessions_on_database/WebModuleUnit1.pas @@ -39,7 +39,16 @@ procedure TWebModule1.WebModuleCreate(Sender: TObject); Config[TMVCConfigKey.SessionType] := 'dbactiverecord'; end); MVC.AddController(TApp1MainController); - MVC.AddMiddleware(TMVCActiveRecordMiddleware.Create('mydb')) + + + { You need to have a running database engine and a correct configuration in the FDConnectionDefs.ini file. + Also you need to create a dmvc_sessions table using one of SQL DDL script available at } + + { Use the following line for MySQL database connection configured in FDConnectionDefs.ini} + //MVC.AddMiddleware(TMVCActiveRecordMiddleware.Create('mysqldb')); + + { Use the following line for FirebirdSQL database connection configured in FDConnectionDefs.ini} + MVC.AddMiddleware(TMVCActiveRecordMiddleware.Create('firebirddb')); end; end. diff --git a/sources/MVCFramework.Serializer.HTML.pas b/sources/MVCFramework.Serializer.HTML.pas index eb5bf35f..cbf6e1e3 100644 --- a/sources/MVCFramework.Serializer.HTML.pas +++ b/sources/MVCFramework.Serializer.HTML.pas @@ -264,7 +264,7 @@ procedure TMVCHTMLSerializer.DeserializeObject(const ASerializedObject: string; procedure TMVCHTMLSerializer.RaiseNotImplemented; begin - raise EMVCException.Create('Not Implemented'); + raise EMVCException.Create('Not Implemented for ' + ClassName); end; procedure TMVCHTMLSerializer.RegisterTypeSerializer(const ATypeInfo: PTypeInfo; diff --git a/sources/MVCFramework.Session.Database.pas b/sources/MVCFramework.Session.Database.pas index 49b1f43c..8798ec4f 100644 --- a/sources/MVCFramework.Session.Database.pas +++ b/sources/MVCFramework.Session.Database.pas @@ -139,7 +139,6 @@ procedure TMVCWebSessionDatabase.InsertIntoDB; begin MarkAsUsed; fSessionData.Insert; - LogW('InsertIntoDB'); end; procedure TMVCWebSessionDatabase.InternalApplyChanges; @@ -159,11 +158,12 @@ procedure TMVCWebSessionDatabase.MarkAsUsed; begin if fSessionData.SessionExpiration.HasValue then begin - lFutureExpiration := Now() + OneMinute * Timeout; - if FormatDateTime('yyyymmddhhnn', lFutureExpiration) > FormatDateTime('yyyymmddhhnn', fSessionData.SessionExpiration) then + lFutureExpiration := RecodeMillisecond(RecodeSecond(Now() + OneMinute * fTimeout, 0), 0); + if lFutureExpiration > fSessionData.SessionExpiration.Value then begin inherited; fSessionData.RefreshSessionExpiration; + ExpirationTimeStamp := fSessionData.SessionExpiration; end; end; end; @@ -171,7 +171,6 @@ procedure TMVCWebSessionDatabase.MarkAsUsed; procedure TMVCWebSessionDatabase.UpdateToDB; begin fSessionData.Update(True); - LogW('UpdateToDB'); end; procedure TMVCWebSessionDatabase.SetItems(const AKey, AValue: string); @@ -196,7 +195,6 @@ class function TMVCWebSessionDatabase.TryFindSessionID(const aSessionID: String) lSess: TMVCSessionActiveRecord; begin inherited; - LogW('ReadFromDB - EXISTS'); lSess := TMVCActiveRecord.SelectOneByRQL(Format('eq(session_id, "%s")', [aSessionID]), False); try Result := Assigned(lSess); @@ -234,7 +232,6 @@ class function TMVCWebSessionDatabase.CreateFromSessionID(const aSessionId: stri lSessDB: TMVCSessionActiveRecord; begin Result := nil; - LogW('ReadFromDB'); lSessDB := TMVCActiveRecord.GetByPK(aSessionId, False); if lSessDB <> nil then begin @@ -287,7 +284,9 @@ procedure TMVCSessionActiveRecord.RefreshSessionExpiration; if fTimeout = 0 then fSessionExpiration.Clear else - fSessionExpiration := RecodeSecond(Now() + OneMinute * fTimeout, 0); + begin + fSessionExpiration := RecodeMillisecond(RecodeSecond(Now() + OneMinute * fTimeout, 0), 0); + end; end; procedure TMVCSessionActiveRecord.SetTimeout(const Value: Cardinal); diff --git a/sources/MVCFramework.Session.pas b/sources/MVCFramework.Session.pas index 9f41670a..e2c3bdbd 100644 --- a/sources/MVCFramework.Session.pas +++ b/sources/MVCFramework.Session.pas @@ -47,7 +47,7 @@ EMVCSession = class(EMVCException) TMVCWebSession = class abstract strict private fChanged: Boolean; - fExpirationTimeStamp: TDateTime; + fExpirationTimeStamp: NullableTDateTime; protected fSessionId: string; fTimeout: UInt64; @@ -258,7 +258,7 @@ procedure TMVCWebSession.InternalApplyChanges; function TMVCWebSession.IsExpired: Boolean; begin if ExpirationTimeStamp.HasValue then - Result := ExpirationTimeStamp.Value < RecodeSecond(Now(), 0) + Result := ExpirationTimeStamp.Value < RecodeMilliSecond(RecodeSecond(Now(), 0), 0) else Result := False; end; @@ -297,10 +297,12 @@ procedure TMVCWebSession.StopSession; procedure TMVCWebSession.RefreshSessionExpiration; begin - fExpirationTimeStamp := RecodeSecond(Now() + OneMinute * fTimeout, 0); + if fTimeout > 0 then + fExpirationTimeStamp := RecodeMilliSecond(RecodeSecond(Now() + OneMinute * fTimeout, 0), 0) + else + fExpirationTimeStamp.Clear; end; - function TMVCWebSession.ToString: string; begin Result := String.Join(',', Keys); @@ -322,8 +324,8 @@ function TMVCWebSessionMemory.Clone: TMVCWebSession; begin lMemSess := TMVCWebSessionMemory.Create; try - lMemSess.FSessionId := Self.FSessionId; - lMemSess.FTimeout := Self.FTimeout; + lMemSess.fSessionId := SessionId; + lMemSess.Timeout := Timeout; for var lItem in Self.Data do begin lMemSess.Data.Add(lItem.Key, lItem.Value);