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...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...