vbdavie Posted August 23, 2015 Share Posted August 23, 2015 I've read as many posts as I could find and it seems that all the comments indicate to use the uniGUI version of the datamodule AND NOT the TDataModule that comes with standard Delphi apps. I have a delphi desktop app that does a LOT (hundreds of data manipulation functions) of DB functions on my DB. We need to create a Web version of the app and I thought that if I could "Re-Use" my datamodule, that would save so so so much time. It appears that in uniGUI EXE mode, I have NO ISSUES at all. I was estatic<happy>, and so I tested it in the DLL(ASAPI) mode and it just locks up or doesn't work at all. I tried creating the datamodule a few different ways: 1. Application.CreateForm(TFDataModule,FDataModule); 2. FDataModule:=TFDataModule.Create(Nil);Boths of these do not work in the DLL mode. What is it about the TDataModule that makes it not work ONLY IN DLL mode? It works in my Desktop app and in the UniGUI EXE mode. YET another difference between EXE and DLL mode Is there a good solution so that I can RE-USE my code between my desktop app and my uniGUI DLL? Thanks very much Davie P.S. What is the RTL property on forms? Link to comment Share on other sites More sharing options...
Ron Posted August 23, 2015 Share Posted August 23, 2015 Hi Davie, When I converted a Delphi app to web, using Unigui, I just moved all my data access components from the TDatamodule to the unigui Datamodule. Copy and paste...same with the code. Why do you need to re-use the Delphi version of the TDatamodule ? Kaj Link to comment Share on other sites More sharing options...
vbdavie Posted August 23, 2015 Author Share Posted August 23, 2015 Because I am NOT converting and getting RID of old app. I am creating a web "companion" that will utilize MANY of the functions that I have already created. The forms of course will all have to be re-created, but I wanted to keep as much core code as possible. Davie Link to comment Share on other sites More sharing options...
Ron Posted August 24, 2015 Share Posted August 24, 2015 OK, so you want to use one datamodule unit within two different projects, basically...without altering anything...can't you use some compiler directives to just alter the classname of the datamodule, depending on which project is compiled? Link to comment Share on other sites More sharing options...
vbdavie Posted August 24, 2015 Author Share Posted August 24, 2015 Actually, I was able to get the TDataModule to work properly. The problem was that I had kept the created object in a "GLOBAL" variable... which is BAD of course. BUT I have a ton of old working code that depends on that global object ;( SOOOooo, I decided to create a function that goes by the SAME NAME as the global name: For example: My global variable was... Var FDataModule:TDataModule; I replaced it with this..... Function FDataModule:TDataModule; And this function figures out what the correct pointer is Basically, I have a string list, and for every SESSIONID, I have the object of the stringlist pointing to the newly created TFDataModule object. That meant I had to create a "CreateFDataModule" function and a "FreeFDataModule" procedure that both utilize my SessionList string list of objects. That way depending on which session is trying to do database work, it will of course call my "FDataModule" function<which use to be a pointer> So, now my code utilizes the PROPER object <in respect to the sessionID> and I keep track of as many objects as I have sessions. It was easier to create my 3 little functions (about 60 EZ lines of code) and to modify my creation and freeing code (about 4 references) THAN to change literally hundreds of places where the static object pointer was being referenced So, now it works perfectly Davie P.S. Here's my 3 little functions in case you care. Var P_GetSessionID:TFunctionString; // points to function that gives me string representing the unique SessionID SessionList:TStringList; // needs to be initialized as a SORTED list Function FDataModule:TFDataModule; // Used to be a VARIABLEVar FDataModule_Instance:TFDataModule; //Use this if not in web mode - faster Function CreateFDataModule:TFDataModule; Procedure FreeFDataModule; Implementation Function FDataModule:TFDataModule;Var SessionID:String; Index:Integer; DataIndex:Integer;BeginIf G_WebMode Then Begin If Assigned(P_GetSessionID)=False Then Raise Exception.Create('Function FDataModule: P_GetSessionID is NOT initialized.'); SessionID:=P_GetSessionID; If SessionList.Find(SessionID,Index) Then Begin Result:=TFDataModule(SessionList.Objects[index]); End Else Result:=Nil; EndElse Result:=FDataModule_Instance;End;Function CreateFDataModule:TFDataModule;BeginIf G_WebMode Then Begin If Assigned(P_GetSessionID)=False Then Raise Exception.Create('Function FDataModule: P_GetSessionID is NOT initialized.'); Result:=TFDataModule.Create(Nil); SessionList.AddObject(P_GetSessionID,Result); EndElse Begin Application.CreateForm(TFDataModule,Result); FDataModule_Instance:=Result; End;End;Procedure FreeFDataModule;Var vObject:TFDataModule; SessionID:String; Index,DataIndex:Integer;BeginIf G_WebMode Then Begin If Assigned(P_GetSessionID)=False Then Raise Exception.Create('Function FDataModule: P_GetSessionID is NOT initialized.'); SessionID:=P_GetSessionID; If SessionList.Find(SessionID,Index) Then Begin vObject:=TFDataModule(SessionList.Objects[index]); vObject.Free; SessionList.Delete(Index); End; EndElse Begin FDataModule_Instance.Free; FDataModule_Instance:=Nil; End;End; Link to comment Share on other sites More sharing options...
Oliver Morsch Posted August 24, 2015 Share Posted August 24, 2015 This is not thread safe !!!. (session list ist a global var and there is no access control, ... ) Better you store a reference to your DataModule in a Field of TUniMainModule. That would be easy to read/write - no thoughts about sessions and threads, because thread safe and per session by default. Link to comment Share on other sites More sharing options...
vbdavie Posted August 24, 2015 Author Share Posted August 24, 2015 I had already thought about adding an EnterCriticalSection or some such thing, but you make a good point, under normal circumstances. My circumstance however, is that I have a ton of old code that refers to a global variable named FDataModule, and so that's why I chose the way I did. Many of these modules may or may not be linked into the Web version and may or may not be linked into the desktop version. Thoughts? Davie Link to comment Share on other sites More sharing options...
Oliver Morsch Posted August 25, 2015 Share Posted August 25, 2015 Additional you can use a (your) function "FDataModule" in your DataModule as follows: function FDataModule: TFDataModule; begin result := uniMainModule.FDataModule; end; Instead of "uniMainModule.FDataModule" you could you use a (String)List/Array/HashMap/... as UniMainModule field with containing all datamodules for the current session; so you have not to declare something for each of your modules in UniMainModule. Link to comment Share on other sites More sharing options...
Mohammed Nasman Posted August 26, 2015 Share Posted August 26, 2015 We have large VCL desktop application, when we started to add portal service for the customer, we use same source for both platforms (Desktop & web) for the DataModule I use it as following: on TUniGUIMainModule: type TMM = class(TUniGUIMainModule) ... public DM: TDM; end; ..... //------------------------------------------------------------------------------ procedure TMM.UniGUIMainModuleCreate(Sender: TObject); begin DM := TDM.Create(UniApplication); That's make it accessible and thread safe with UniGUi. var qry :TMyQuery ; begin qry := TMyQuery.Create(nil); try qry.Connection := {$IFDEF WebApp}MM.DM{$ELSE}DM{$ENDIF}.ConEMS; and you can change the code that shared between VCL & Uni to : P.S. What is the RTL property on forms? It's Related to set the aligment of form and controls on it to be from Right To Left to support RTL Languages such as Arabic and Farsi. Link to comment Share on other sites More sharing options...
maher Posted August 26, 2015 Share Posted August 26, 2015 On DM unit : {$IFNDEF WebApp} DM: TDM; {$ENDIF} Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now