Tech Note: File Transfers using Execute on Server
PRODUCT: 4D | VERSION: 11.2 | PLATFORM: Mac & Win
Published On: February 11, 2009
Execute on Server has always been powerful, but now with 4D Server v11 SQL Execute on Server has been revamped and is even easier to use then before. This technical note discusses the new way that developers can execute methods on 4D Server v11 SQL as well as some ideas of how this can be useful. A sample database is provided.
Download Complete Tech Note and Example: Windows | Mac
The SD goes through the extra effort of packing information about the file in each blob (or chuck) of the file that is transmitted. Parameters are supported as well as pointers in parameters to get information back from the routine. If you want to pass information it is MUCH simpler to just pass it as a parameter. Here is a sample of the code I ended up using (modified for Foundations dialogs):
C_BOOLEAN($0;$Success_vb)
$Success_vb:=False
C_TEXT($1;$ServerFullDocPath_vt)
$ServerFullDocPath_vt:=$1
C_TEXT($2;$LocalFullDocPath_vt)
$LocalFullDocPath_vt:=$2
C_POINTER($3;$ReturnMessage_vt_ptr)
$ReturnMessage_vt_ptr:=$3
C_BOOLEAN($Continue_vb)
$Continue_vb:=True
C_BOOLEAN($UseCompression_vb)
$UseCompression_vb:=(UT_PrefsGet ("SFS-TRN_CompressFilesDuringTransfer")="yes")
C_LONGINT($FileSizeLimit_vl)
$FileSizeLimit_vl:=Num(UT_PrefsGet ("SFS-TRN_FileChunkSize"))
C_TIME(vhDoc)
If (Test path name($LocalFullDocPath_vt)=1)
Fnd_Wnd_Position (Fnd_Wnd_CenterOnWindow )
Fnd_Dlg_Confirm ("A file requested already exists at: "+$LocalFullDocPath_vt+"\n\nWould you like to overwrite this file?")
$Continue_vb:=(OK=1)
End if
If ($Continue_vb)
C_REAL($docSize_r)
$docSize_r:=SFS_s_getDocSize ($ServerFullDocPath_vt)
If ($docSize_r>0)
C_LONGINT($TotalPartsNeeded_vl)
If (Dec($docSize_r/$FileSizeLimit_vl)=0)
$TotalPartsNeeded_vl:=$docSize_r/$FileSizeLimit_vl
Else
$TotalPartsNeeded_vl:=Int($docSize_r/$FileSizeLimit_vl)+1
End if
C_BLOB($FileChunkReceived_blob)
SET BLOB SIZE($FileChunkReceived_blob;0)
Case of
: ($docSize_r>(2048*1024*1024))
C_TEXT($alert_t)
$alert_t:="This method cannot transfer a file larger than "+UT_formatByteSize (2048*1024*1024)+"\n\n"
$alert_t:=$alert_t+"The file you are trying to transfer is "+UT_formatByteSize ($docSize_r)+"\n\n"
$alert_t:=$alert_t+"This operation cannot be completed\n\nThe process will be terminated"
ALERT($alert_t)
: ($TotalPartsNeeded_vl=1)
SET BLOB SIZE($FileChunkReceived_blob;0)
If (SFS_s_getDocument (->$FileChunkReceived_blob;$ServerFullDocPath_vt;1;$ReturnMessage_vt_ptr))
If ($UseCompression_vb)
EXPAND BLOB($FileChunkReceived_blob)
End if
BLOB TO DOCUMENT($LocalFullDocPath_vt;$FileChunkReceived_blob)
$Success_vb:=(OK=1)
If ($Success_vb)
UT_FileWipeCreatorCodes ($LocalFullDocPath_vt)
End if
End if
Else
Fnd_Dlg_SetProgress ($TotalPartsNeeded_vl)
Fnd_Dlg_SetText ("Retreiving "+UT_ShortName ($LocalFullDocPath_vt)+" ...")
Fnd_Dlg_SetCancelable (True)
Fnd_Dlg_MessageOpen
C_LONGINT($PartNumber_vl)
For ($PartNumber_vl;1;$TotalPartsNeeded_vl)
Fnd_Dlg_MessageUpdate ($PartNumber_vl)
SET BLOB SIZE($FileChunkReceived_blob;0)
If (SFS_s_getDocument (->$FileChunkReceived_blob;$ServerFullDocPath_vt;$PartNumber_vl;$ReturnMessage_vt_ptr))
If ($UseCompression_vb)
EXPAND BLOB($FileChunkReceived_blob)
End if
If ($PartNumber_vl=1)
vhDoc:=Create document($LocalFullDocPath_vt)
Else
vhDoc:=Open document($LocalFullDocPath_vt)
End if
$Cursor_vl:=(($PartNumber_vl-1)*$FileSizeLimit_vl)
SET DOCUMENT POSITION(vhDoc;$Cursor_vl;1)
SEND PACKET(vhDoc;$FileChunkReceived_blob)
$Success_vb:=(ok=1)
CLOSE DOCUMENT(vhDoc)
Else
`Something went wrong. Stop the process
$Success_vb:=False
$PartNumber_vl:=$TotalPartsNeeded_vl+1
End if
If (Fnd_Dlg_MessageCanceled )
$PartNumber_vl:=$TotalPartsNeeded_vl+1
$ReturnMessage_vt_ptr->:="User cancelled transfer of file."
End if
End for
Fnd_Dlg_MessageClose
UT_FileWipeCreatorCodes ($LocalFullDocPath_vt)
End case
Else
$ReturnMessage_vt_ptr->:="File not found on server."
End if
End if `Continue
$0:=$Success_vb