![]() |
![]() |
|
![]() |
Alternate to Handlerequest Methodology as Presented in the Hercules Example © 2002 Tony McGuire Download sample files demonstrating the methodology presented below. The Hercules example/model is wonderful. It gives us incredible flexibility to handle incoming requests. And using server.db allows us to automatically open/reference the correct library to handle the incoming request, through the 'handlerequest' method. My only issue has been all those case... statements. Likely, though, if you have that many case statements you need to create a new library for handling additional methods. However, this just bugged me. So I went looking for an alternative. Thus the recent thread on the pnews news server on execMethod(). In a library, you cannot use execMethod() to execute an internal method, unless the construct that has the library open (i.e., a form or script) 'knows about' that method. This would normally be done in that script/form's Uses clause. However, Tom Krieg discovered that the library can open a copy of itself, and that copy can be used by the one opening it; at this point, execMethod() works just fine. So, I went looking for a way to put this to use: the idea was to simplify the methodology presented in the Hercules example further. While initially complicating understanding of how it all works, perhaps, the below removes all necessity for a switch...case...endSwitch construct in your 'server' library. In server.lsl, we set some global variables.
var jsLib library loLib logical loTrueFalse logical dyIncoming dynarray[] string stReturnValue string stPath string arVersion array[] string endVar method open(var eventInfo Event) var arPath array[] string endvar loLib=False ; break apart the version of Paradox ; so the correct version of the JSI Library ; will be opened. This way one copy of this ; client library can be created, and distributed ; to multiple client versions of Paradox without special ; recoding breakapart(version(),arVersion,".") ; get the path to this library, and use that path to ; reference a copy of server.lsl library breakapart(getfilename(),arPath,"\\") stPath=arPath[1] if arPath.size()>=3 then for x from 2 to arPath.size()-1 stPath=stPath+"\\"+arPath[x] endfor endif endMethod method jsParseRequest(var olRequest oleAuto, var olResponse oleAuto) logical var liOne, liTwo longint endVar ; retrieve the incoming field data into a Global dynarray ; so it is available to all methods/procs in this library ; and thus also available in the new copy of the library liTwo = olRequest.NFields - 1 if liTwo<0 then dyIncoming.empty() dyIncoming["ErrorMessage"]="Error: No data received" return false endif for liOne from 0 to liTwo dyIncoming[olRequest.GetFieldName(liOne)]=olRequest.GetFieldByIndex(liOne) endFor ; add some incoming request variables to the global array dyIncoming["IpAddress"]=olRequest.ipAddress dyIncoming["URI"]=olRequest.uri return True endMethod ; replacement for handlerequest; this version uses the new methodology method handlerequest(strHandler String, var Request OleAuto, var Response OleAuto) Logical ; these vars are for handling errors in the try...onFail...endTry block below var siErrors, liErrors longint arErrors array[30] string stClock string endvar ; create a global dynarray from the incoming data, ; which can be used by both the original copy of the library ; and the jsLib copy of the library ; There must be a connection established to new global ; variables, since there can be no parameters passed with execMethod() if not jsParseRequest(request,response) then response.resultstring=dyIncoming["ErrorMessage"] return True endif ; if a copy of server.lsl isn't open, open it with jsLib variable if not loLib then jsLib.open(stPath+"\\Server") loLib=True endif ; set default for 'errormessage' element ; It can then just be added to, rather than ; figure out later whether it has been initialized dyIncoming["ErrorMessage"]="" ; run execMethod based on the incoming 'handler' identified in server.db ; you *could* bypass server.db at this point. But it is just too handy and flexible to ; abandon. Especially with proxying, where you can watch for /paradox/ACTION and pass ; ACTION here as the execMethod parameter. try jsLib.execmethod(strHandler) if loTrueFalse then response.resultstring=stReturnValue else response.resultstring=dyIncoming["ErrorMessage"] endif onFail arErrors[1]=errormessage() liErrors=1 while errorpop() liErrors=liErrors+1 arErrors[liErrors]=errormessage() endwhile stClock=string(cpuclocktime()) for siErrors from 1 to liErrors if arErrors[siErrors].search(chr(10))=arErrors[siErrors].size() then arErrors[siErrors]=arErrors[siErrors].substr(1,arErrors[siErrors].size()-1) endif if arErrors[siErrors].search(chr(13))=arErrors[siErrors].size() then arErrors[siErrors]=arErrors[siErrors].substr(1,arErrors[siErrors].size()-1) endif ; you can build on 'ErrorMessage' element since you create default blank value near top ; of this method dyIncoming["ErrorMessage"]=dyIncoming["ErrorMessage"]+arErrors[siErrors]+"\n" writeprofilestring(stPath+"\\errors.ini", stClock, string(siErrors), arErrors[siErrors]) endfor errorclear() sleep(1) response.resultstring=dyIncoming["ErrorMessage"] endTry ; empty the incoming dynarray so any ; values set during this operation won't also be in the next request dyIncoming.empty() return True endMethod ; getresponse is the 'action' in the html form included in this sample. ; it is as simplistic as it gets, and is included solely so that you can see that ; execMethod(strHandler) works. strHandler is the incoming 'Action' (getresponse), ; and therefore is the method that automatically executes by calling execMethod(strHandler) ; in handlerequest, above. method getresponse() ; a VERY simplistic use ; but shows that the connection has been ; initialize between jsRequest/jsResponse and ; the incoming request from the outside stReturnValue=dyIncoming["ipAddress"] ; all your normal processing of this request ; would take place here ; set a global variable that is a flag indicating whether this operation was successful loTrueFalse=True { ; if your operation fails, you could use dyIncoming["ErrorMessage"]="Message for user to see when operation fails" loTrueFalse=False } endMethod Inspect server.lsl for how the handlerequest method connects an internal dynArray to the incoming request data, then uses execMethod() to process the incoming request without using a switch..case..endSwitch construct. The execMethod() is based on 'strHandler', which is the ACTION set in the html file (or, rather, the handler identified in server.db). Again, I am not suggesting that this alternate is better than the version that comes with Paradox. I use that version myself. However, I will be experimenting with this to determine any potential speed enhancements (or decreases). And it does simplify your coding of this. The ACTION in the form (or one you change it to in server.db) becomes the method to execute automatically, removing the need for those switch...case...endSwitch statements. Discussion of this article |
![]() Feedback | Paradox Day | Who Uses Paradox | I Use Paradox | Downloads ![]() |
|
![]() The information provided on this Web site is not in any way sponsored or endorsed by Corel Corporation. Paradox is a registered trademark of Corel Corporation. ![]() |
|
![]() Modified: 15 May 2003 Terms of Use / Legal Disclaimer ![]() |
![]() Copyright © 2001- 2003 Paradox Community. All rights reserved. Company and product names are trademarks or registered trademarks of their respective companies. Authors hold the copyrights to their own works. Please contact the author of any article for details. ![]() |
![]() |
|