Jump to content

UniServerModule.GetSession - new powerfull feature


Tokay

Recommended Posts

I was constantly missing feature of find defined session. It very important in some cases. I show you idea (if I understand all properly):

unit Main;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics,
 Controls, Forms, Uni, uniGUITypes, uniGUIAbstractClasses,
 uniGUIClasses, uniGUIRegClasses, uniGUIForm;

//this case shows how to run a long query without stopping the interface
//additional thread for query
type
 THelpThread = class(TThread)
 private
  FQuery:       TUniQuery;
  FSessionName: string;
 protected
  procedure Execute; override;
 public
  property Query: TUniQuery Read FQuery Write FQuery;
  property SessionName: string Read FSessionName Write FSessionName;
 end;

type
 TMainForm = class(TUniForm)
  UniQuery1:      TUniQuery;
  UniDataSource1: TUniDataSource;
  UniDBGrid1:     TUniDBGrid;
 private
  FThread: THelpThread;
  procedure Thread1Finish(Sender: TObject);
  procedure StartCalcThread(const s: string);
  procedure AssignDataSet;
  { Private declarations }
 public
  { Public declarations }
 end;

function MainForm: TMainForm;

implementation

{$R *.dfm}

uses
 uniGUIVars, MainModule, uniGUIApplication;

function MainForm: TMainForm;
begin
 Result := TMainForm(UniMainModule.GetFormInstance(TMainForm));
end;

{ THelpThread }

procedure THelpThread.Execute;
begin
 inherited;
 if Query.State <> dsInactive then
  Query.Close;
 if not Query.Transaction.Active then
  Query.Transaction.StartTransaction;
 Query.Open;
end;

{ TMainForm }

procedure TMainForm.StartCalcThread(const s: string);
begin
 //startin of query thread
 if not Assigned(FThread) then
 begin
  //the query
  UniQuery1.SQL.Clear;
  UniQuery1.SQL.Add('select MAPS.MAPS_SOURCE,');
  UniQuery1.SQL.Add(s);
  UniQuery1.SQL.Add('from MAPS');
  UniQuery1.SQL.Add('group by MAPS_SOURCE');
  UniQuery1.SQL.Add('union');
  UniQuery1.SQL.Add('select "all",');
  UniQuery1.SQL.Add(s);
  UniQuery1.SQL.Add('from MAPS');
  //off the grid DataSource
  UniDBGrid1.DataSource := nil;
  FThread := THelpThread.Create(True);
  FThread.Query := UniQuery1;
  FThread.OnTerminate := Thread1Finish;
  FThread.FreeOnTerminate := True;
  //store the session ID {!!!!}
  FThread.SessionName := UniSession.SessionId;
  //start querying
  FThread.Start;
 end;
end;

procedure TMainForm.Thread1Finish(Sender: TObject);
begin
 //sync assigned of dataset with the grid
 TThread.Synchronize(nil, AssignDataSet);
 FThread := nil;
end;

procedure TMainForm.AssignDataSet;
var
 Session: TUniGUISession;
 lMainModule: TUniMainModule;
begin
 //find session by ID {!!!!}
 Session := UniServerModule.GetSession(FThread.SessionName);
 //get defined MainModule of session
 lMainModule := TUniMainModule(Session.UniApplication.UniMainModule);
 //get defined MainForm of session
 with TMainForm(lMainModule.GetFormInstance(TMainForm)) do
 //assigne dataset and DataSource with grid
  UniDBGrid1.DataSource := UniDataSource1;
end;

initialization
 RegisterAppFormClass(TMainForm);

end.

 

  • Like 2
Link to comment
Share on other sites

On 4/26/2020 at 6:38 PM, Tokay said:

I was constantly missing feature of find defined session. It very important in some cases. I show you idea (if I understand all properly):


unit Main;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics,
 Controls, Forms, Uni, uniGUITypes, uniGUIAbstractClasses,
 uniGUIClasses, uniGUIRegClasses, uniGUIForm;

//this case shows how to run a long query without stopping the interface
//additional thread for query
type
 THelpThread = class(TThread)
 private
  FQuery:       TUniQuery;
  FSessionName: string;
 protected
  procedure Execute; override;
 public
  property Query: TUniQuery Read FQuery Write FQuery;
  property SessionName: string Read FSessionName Write FSessionName;
 end;

type
 TMainForm = class(TUniForm)
  UniQuery1:      TUniQuery;
  UniDataSource1: TUniDataSource;
  UniDBGrid1:     TUniDBGrid;
 private
  FThread: THelpThread;
  procedure Thread1Finish(Sender: TObject);
  procedure StartCalcThread(const s: string);
  procedure AssignDataSet;
  { Private declarations }
 public
  { Public declarations }
 end;

function MainForm: TMainForm;

implementation

{$R *.dfm}

uses
 uniGUIVars, MainModule, uniGUIApplication;

function MainForm: TMainForm;
begin
 Result := TMainForm(UniMainModule.GetFormInstance(TMainForm));
end;

procedure TMainForm.StartCalcThread(const s: string);
begin
 //startin of query thread
 if not Assigned(FThread) then
 begin
  //the query
  UniQuery1.SQL.Clear;
  UniQuery1.SQL.Add('select MAPS.MAPS_SOURCE,');
  UniQuery1.SQL.Add(s);
  UniQuery1.SQL.Add('from MAPS');
  UniQuery1.SQL.Add('group by MAPS_SOURCE');
  UniQuery1.SQL.Add('union');
  UniQuery1.SQL.Add('select "all",');
  UniQuery1.SQL.Add(s);
  UniQuery1.SQL.Add('from MAPS');
  //off the grid DataSource
  UniDBGrid1.DataSource := nil;
  FThread := THelpThread.Create(True);
  FThread.Query := UniQuery1;
  FThread.OnTerminate := Thread1Finish;
  FThread.FreeOnTerminate := True;
  //store the session ID {!!!!}
  FThread.SessionName := UniSession.SessionId;
  //start querying
  FThread.Start;
 end;
end;

procedure TMainForm.Thread1Finish(Sender: TObject);
begin
 //sync assigned of dataset with the grid
 TThread.Synchronize(nil, AssignDataSet);
 FThread := nil;
end;

procedure TMainForm.AssignDataSet;
var
 Session: TUniGUISession;
 lMainModule: TUniMainModule;
begin
 //find session by ID {!!!!}
 Session := UniServerModule.GetSession(FThread.SessionName);
 //get defined MainModule of session
 lMainModule := TUniMainModule(Session.UniApplication.UniMainModule);
 //get defined MainForm of session
 with TMainForm(lMainModule.GetFormInstance(TMainForm)) do
 //assigne dataset and DataSource with grid
  UniDBGrid1.DataSource := UniDataSource1;
end;

initialization
 RegisterAppFormClass(TMainForm);

end.

 

I tried to simulate your example here, but I didn't find this TUniQuery component

Link to comment
Share on other sites

22 hours ago, eduardosuruagy said:

//find session by ID {!!!!} 
Session := UniServerModule.GetSession(FThread.SessionName); 
//get defined MainModule of session 
lMainModule := TUniMainModule(Session.UniApplication.UniMainModule);

 

You have enough info and access code. I'm not test yet.

Link to comment
Share on other sites

small test, in trail 1526

Not tested in hyperserver, but this will not work. 'cos node not access to another nodes, but if work on this, can work too. via db share. and next century :) server farm

procedure TMainForm.BTN_1Click(Sender: TObject);
var
 SS: TUniGUISession;
 lMainModule: TUniMainModule;
 SId : string;
 Hooked: TMainForm;
begin
//find session by ID {!!!!}
 SId := ClientDataSet1.FieldByName('sessionid').AsString;
 if (SId = '') or (SId = UniSession.SessionId) then Exit;

 SS := UniServerModule.GetSession(SId);
 //get defined MainModule of session
 lMainModule := TUniMainModule(SS.UniApplication.UniMainModule);
 //get defined MainForm of session
 Hooked:= TMainForm(lMainModule.GetFormInstance(TMainForm, False));
 if Hooked<>nil then Hooked._InComeMessage:= '[' +UniSession.SessionId +'  To: ' +SId +']-->' +EDT_1.Text;
end;

procedure TMainForm.Set_InComeMessage(const Value: string);
begin
  F_InComeMessage := Value;
  MEM_1.Lines.Add(FormatDateTime('hh:mm:ss',now) +'  InCome message : '+ F_InComeMessage);
//MEM_1: TUniMemo;  just screen not updated, son on screenshot, I moved form. just visual problem
end;

 

GetSession.gif

Link to comment
Share on other sites

  • 2 weeks later...

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...