New function to read and save data to a remote DataEase Server and other Web Services.
Function::Internal
retval := Remote(commandstring)
retval := Remote(commandstring, input)
retval := Remote(commandstring, input, output)
Used to do commands on a remote web server or organize in memory structures.
commandstring : Text
This can be all from a sequence used to log in, a returned field that we already have fetched using a previous call to Remote or setting a value to a empty object or update existing object. All commands starts with a @commandname:. If not a @ if the first char in the command string, the meaning is either a data fetch and return or a data set. A data fetch is characterized bu being a string without any = in. A data set is a string with a = in. The name fetched or set can be a single name, an object where you use dot notation or an array where you use [index] notation. When you fetch data, you can also transform of fetch part of the data by using a filter. The filter is recognized by a |.
Remote("@cleanup") | This is a simple command with no parameters at all. It simply clean up all memory and connections done. |
Remote("@get:http://json.example.com/customer/1/") | This is a remote lookup command that has on parameter. In this case it read and return the json data from a web site that returns the data as json. This data can be read by fetch data calls later on. |
Remote("@imap:fetch 1") | This is a command with a sub command that has a parameter. In this case you read the mail with id 1 using the imap protocol. |
val:=Remote("mailcount") | This command returns the value from the data store named mailcount. This value is actually returned if you run the pop3 command. |
val:=Remote("customer.name") | This command returns a value inside a json object that previously are returned by an other command like the @get. |
val:=Remote("mails[0].Subject") | This command return the Subject found in the first object inside the mails array. The mails array is actually used to return data from both the @pop3 and the @imap command. |
val:=Remote("mails[0].Body|html") | This command returns the Body in the first ovject inside the mails array and runs this through a filter to transform of fetch a part of the data. In this case you actually returns the html data of a multipart mail body that was returned by a @pop3 or @imap command. |
val:=Remote("mails[0].Body|html",,MemoField) | This command set the returned data into a body field. As you might know, DfW can only return 256 characters of data to a variable like val. To over come this you can use a body as the third parameter. The memo field must be and active in memory field. How to do this will be explained in more details in the mail handling part of the documentation. |
val:=Remote("mails[0].Body|html",,"MemoField") | This is the same as the previous example except for this will set the data into the memofield in the active form. The difference are "" around the name means in the active form instead of the active memo field given by a dql for command. |
val:=Remote("myvar=My own string value") | This command set a value into myvar variable in the data store. The variable is created if it do not exist an overwritten if is does. |
val:=Remote("myvar=", "My own string value") | This command set the value form the second parameter into variable. This can be created by any valid formula or fields. |
val:=Remote("myvar=", concat("Re: ",Subject)) | Sets the result form the concat formula into myvar. |
val:=Remote("myob.myvar=My own string value") | This command set or create a variablein the object myob. If myob do not exist or are a other type of value, it will be created a new object and a variable in the created. |
val:=Remote("myarray[0]=My own string value") | This will set a value in the first position of a string array named myarray. If the array do not exist, it will be created. |
val:=Remote("myobarray[0].subject=My own string value") | This will set a value in the first position of an object array named myobarray. The value will be set in a object and the a variable named subject the object is created if it do not exist. If the array do not exist, it will be created. |
val:=Remote("mail.Body.html=","memo:EMailHtmlMemo") | Sets the in form memo to a special mail object that can be used to build mails for sending using the @smtp command. the "memo:FieldName" indicates to fetch the in memory memo field from GUI. |
String with asked for field, empty string or in error situation the error string.
@agent | Nothing | Set the user agent sent to the server. Default is "dataease-agent/1.0". Some server used this to serve different pages to different clients. So if you do not get the same result as in your browser, you can try to change this value to something like "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0" that is what Firefox 37 returns on Windows 7. |
@cleanup | Nothing | Closes all connections and removes all remote lookup memory uses for the current session. The session is left there to reuse. For removing it completely you have to use @remove instead. This can be done on all connections except default that only support @cleanup. |
@connect | Nothing | Used to set up a connection to a remote server using an url like http://www.dataease.com/getmydata/ |
@current | Nothing or Name | Set the current active remote lookup session or return the name if :Name is omitted. If no change is done, the one created by default the first time used is called "default". Ex. curentused := Remote("@current") returnes the name of currently used session, Dummy := Remove("@current:mysession") will switch to or create a session named mysession and switch to that one. |
@error | String | Last error reported. Ex a bad user name password. |
@errorclear | Nothing | Clear the last error message. |
@fieldnames | String | Return a list of fields found in an element. Ex. Remote("@fieldnames:mails[0]") list all fields found in the first mail. Remote("@fieldnames:") list all element names in the first level. All fields found are separated by a line feed. |
@filter | Nothing | Update values in the query string with these new values in the form of field1=value1&field2=value2. If a field is not already in the query string it will we added to it. |
@get | Nothing | Fetch a new set of data from the remote server using the query, the url and the login information set in previous commands. You can also set a url and a query direct in the get as a shortcut. |
@imap | String | Get imap mail form the server. See own document for commands and examples. |
@json | String | Returns the raw json from the data in the current session. You can use this to debug your data or see what's returned from the server by setting it to a memo field. A parameter will select the root of the json, no parameter will return all. |
@logbody | Nothing | Log the body returned from the function to a file given by parameter 1. Ex Remote("@logbody:C:\rlbody.txt") |
@logheader | Nothing | Log the header returned from the function to a file given by parameter 1. Ex Remote("@logheader:C:\rlheader.txt"). Mind that all mail handling commands logs all communication with the server using the header and processed data in the body. HTTP traffic separates header and body by leaving the server specific data to the headers and what the user see in the body. |
@login | Nothing | Login using user/password as parameter or previous set @username and @password. |
@logintype | Nothing | The type of login used. Defaut is dataease, but you can also use basic, digest, ntlm, negotiate, anybasic, post and django. The DataEase method used the default login method used on DG3 server. The anybasic method tests all of the basic methods from the strongest to basic and uses the best supported version. The negotiate method is not activated at the moment. |
@logout | Nothing | Logout using the login type set, |
@logupload | Nothing | Log the data posted to the server to a file given by parameter 1. Ex Remote("@logupload:C:\rlupload.txt"). At the moment it is only smt:send command that uploads data. |
@password | Nothing | Set the password used for login |
@processinfo | Nothing | Get a list of all processes the current user can see on the computer. The list of processes are returned as an array objects named "processes". The number of processes returned can be read from the value "processescount". You can use a string as filter of what to return. The format is either just a string that will filter on the process name, but you can also use the format fieldname=filtervalue. Filter value support * and ? for wildcard and letter. The object returns the following fields that also are the supported filter fields: pid, name, fullname, user and domain. Ex. Remote("@processinfo") will return all processes that you can see Ex 2.: Remote("@processinfo:DataEase.exe") will return all processes that have the name DataEase.exe Ex 3.: Remote("@processinfo:name=de*&user=administrator") will return all processes that have a name that starts with de and are started by the administrator user. |
@pop3 | String | Get pop3 mail form mail server. See own document for commands and examples. |
@post | Nothing | Post data to the server using a form post method. |
@put | Nothing | Update the data on the server by posting values set previously using the DataEase server method. |
@query | Nothing | Replace the query string with this one. The query string is everything added after a ? in a url. |
@raw | String | Return raw data from server by a GET call using the supplied url or the one set in previous connect. The raw data is returned to the caller. |
@remove | Nothing | Removes the session from the cached session list. This can be done on all sessions except default. The default session is always available, but you can clear your data by using @cleanup. |
@returncode | String | Returns the last result code from a http request. This is the codes returned by a web server. 200 is all ok, 30X is request for redirect, 40X is access denied of some sort and 50X is an internal server error. If the code is 0, no request has been done. The X is a number between 0-9 and describes the kind of error. |
@securitytype | Nothing | Set the type of security used on none http protocols like pop3. You can set none, any and secure. None do not set security, any the is the default tires any security type including none and use the strongest supported and secure tries any one except none and uses the strongest. |
@set | Nothing | Set a value in the locally cached data by using the form fieldname=Value. This is the same as using the direct fieldname=value. |
@setjson | Nothing | Takes a json string, encodes it en set it to the local cache. |
@timeout | Nothing | Set a time out value for the maximum time to be used for geting back a result including the time it takes to return the data. Default i 0 that means no timeout at all. You can use the form 10 for ten seconds or 10000ms to 10 thousand milliseconds. The form 10s for 10 seconds are also valid. |
@username | Nothing | Set the username used when login |
fieldname | String | returns the livetext stored in the server cache for the value fieldname. The fieldname can be in the form of a single name, a . separated name, an array of string or an array of object. Ex. single name: fildname, dot separated name: objectname.fieldname, string array: dataarray[10] and object array: objectarray[10].fieldname. These can be as deep as you need to represent the data. All values will be converted to a string when returned to caller, but any valid json value are supported. |
fieldname= | Nothing | Used to set a value to a field name. The field is added if it not is found in the current data and replaced if there are a current value. You can use any valid combination supported by get field to set a field as well. |
Filters that can be used when fetching values. At the moment most of the filters only work on mail data stored in the mime store in the variable mail or mails[]. All filters are set by using the | character before the filter value. A filter can also have parameters like the attachment and attachmentname. Then the the filter have the form |attacment 1 where the parameter is separated from the filter by a space.
attachment | Returns the attachment and store it a file. The filter can have 0 to three parameters where the meaning depends on the type and number of parameters. The first are the position in the Body if it is a number. It starts on 1 and count up to as many attachment there is in the mail. You can find the number of attachments by using the attachmentcount filter. The next parameter is the folder to save the attachment in. Make sure to use "" around the path if it contains space in the name. If no folder is uses or you add a "" the current app path is used. If the the path starts on \ or second character is : a global path is used. Mind that this might not be legal depending on the run time environment. If not this will be a relative path to the current app folder. Last parameter is used to override the file name. Ex.: |attachment will store the first attachment to the app folder using the filename given by the attachment. |attachment 2 upload will save the second attachment to a subfolder named upload in the app folder and using the file name given by the attachment |attachment "C:\User\Me\My Documetents" invoice0034.pdf will store the first attachment in the a fixed folder with spaces in the name to a specific file name. |
attachmentcount | Number of attachments found in the MIME body. Ex. mails[0].Body|attachmentcount will return the number of attachments in the first mail in the incoming mails store. The value returned is a string as for all remote lookup commands. |
attachmentext | Returns the file extension to the file name given by MIME. Can take zero or one parameters. When zero parameters it returns the extension of the first attachment, if one this indicates which attachment to fetch the extension from, and the first is 1. Extension are returned including the . so a pdf will return the extension .pdf and no extension will return nothing. |
attachmentname | The file name registered by the MIME attachment. Can take zero or one parameters. When zero parameters it returns the name of the first attachment, if one this indicates which attachment to fetch the name from, and the first is 1. |
html | The html part of a MIME body in an email. The filter can be used on both the mail.Body valriable and the mails[idx].Body variable. |
raw | Returns the value of a MIME part in raw MIME format. Ex. mails[0]|raw will return the first mail object in raw mime text as it is stored in the MIME mail array. |
text | The text part of a MIME body in an email. The filter can be used on both the mail.Body valriable and the mails[idx].Body variable. |
To understand how to use the Remote data store, we will do a few examples without calling a server in the first examples. First we will show how to set a named datastore. All settings done to a named data store is maintaned in memory until you close down DataEase or use the @cleanup command. To set up a new datastore, you use the @current:name command. This will switch to an existing datastore if it exist or create a new. In the next example we will create "mydata" datastore and create a field direct on the root object called "myvalue", an array called "data" with 10 objects, and 2 field in each object called "Name" and "Code". Then we pick the 6th element in the array and return it.
-- The DQL define temp "Dummy" text. define temp "telle" number. define temp "cname" text. define temp "ccode" text. Dummy := Remote("@current:mydata"). Dummy := Remote("myvalue=a value"). telle := 0 . while telle < 10 do Dummy := Remote(concat("data[", telle , "].Name=Name", telle)) . Dummy := Remote(concat("data[", telle , "].Code=C", telle)) . telle := telle + 1 . end cname := Remote("data[5].Name") . ccode := Remote("data[5].Code") . list records cname ; ccode . -- The body ***************************************************** Test of creating a json structure in memory only ***************************************************** .items Code: [{ccode}] Name: [{cname}] .end ***************************************************** -- The result ***************************************************** Test of creating a json structure in memory only ***************************************************** Code: C5 Name: Name5 *****************************************************
Create an string array and read values back form it. In this example we do not use field names inside the array, but just set a string value direct into the array. This is never used in the DataEase server, but can be useful when connecting to other kinds of server like mail server. We also added a @cleanup command to start on a fresh datastore. This is useful if you reuse your datastore name.
-- The DQL define temp "Dummy" text. define temp "telle" number. define temp "cname" text. define temp "ccode" text. Dummy := Remote("@current:mydata"). Dummy := Remote("@cleanup"). telle := 0 . while telle < 10 do Dummy := Remote(concat("data[", telle , "]=Name", telle)) . Dummy := Remote(concat("data2[", telle , "]=C", telle)) . telle := telle + 1 . end cname := Remote("data[5]") . ccode := Remote("data2[5]") . list records cname ; ccode . -- The body ***************************************************** Test of creating a json string array in memory ***************************************************** .items Code: [{ccode}] Name: [{cname}] .end ***************************************************** -- The result ***************************************************** Test of creating a json string array in memory ***************************************************** Code: C5 Name: Name5 *****************************************************
This concludes the section where you use the Remote command without calling a server. In the next section you will need a server to use.
For the examples I use a Contact table where you have a first_name, last_name, title, and email field. I have created a DG3 page that have a fixed filter
email=[{ user.email }] that connects the logged in user to the record data by the registered email. To use the page for Remote, you just add a query string q.action=getrecord to the url and sets the action to updaterecord when you save the changed data back to the server. Here are the example of how to do it.
Login and show the registered values on the contact.
-- The DQL define temp "Dummy" text. define temp "fname" text. define temp "lname" text. define temp "email" text. define temp "title" text. define temp "dob" text. Dummy := Remote("@current:mydata"). Dummy := Remote("@connect:127.0.0.1:8080/licensecheck/editcontact/"). Dummy := Remote( "@login:username/password"). Dummy := Remote("@query:q.action=getrecord"). Dummy := Remote( "@get") . fname := Remote( "recorddata.first_name") . lname := Remote( "recorddata.last_name") . email := Remote( "recorddata.email") . title := Remote( "recorddata.title") . dob := Remote( "recorddata.dob") . list records fname ; lname ; email ; title ; dob . -- The Body ***************************************************** Get my contact info ***************************************************** .items Name:[{fname}] [{lname}] EMail:[{email}] Title:[{title}] Day of birth:[{dob}] .end ***************************************************** -- The result if you have a valid login ***************************************************** Get my contact info ***************************************************** Name:Test User EMail:test@example.com Title: Day of birth:17.08.67 *****************************************************
Get a record and update it with new values. This routine simply toggles the title form blank to "The Master" each time it is called and return the result.
-- The DQL used define temp "Dummy" text. define temp "fname" text. define temp "lname" text. define temp "email" text. define temp "title" text. define temp "dob" text. Dummy := Remote("@current:mydata"). Dummy := Remote("@connect:127.0.0.1:8080/licensecheck/editcontact/"). Dummy := Remote( "@login:username/password"). Dummy := Remote("@query:q.action=getrecord"). Dummy := Remote( "@get") . fname := Remote( "recorddata.first_name") . lname := Remote( "recorddata.last_name") . email := Remote( "recorddata.email") . title := Remote( "recorddata.title") . dob := Remote( "recorddata.dob") . if title = blank then title := "The master" . else title := "" . end Dummy := Remote("@query:"). Dummy := Remote( "action=updaterecord") . Dummy := Remote( jointext("recorddata.title=",title)) . Dummy := Remote( "@put") . title := Remote( "recorddata.title") . list records fname ; lname ; email ; title ; dob . -- The body ***************************************************** Get and update my contact info ***************************************************** .items Name: [{fname}] [{lname}] EMail: [{email}] Title: [{title}] Day of birth: [{dob}] .end ***************************************************** -- The result if you have a valid login ***************************************************** Get my contact info ***************************************************** Name: Test User EMail: test@example.com Title: The master Day of birth: 17.08.67 *****************************************************
Delete record
For the examples I use a Contact table where you have a first_name, last_name, title, and email field. I have created a DG3 page that have a fixed filter
email=[{ user.email }] that connects the logged in user to the record data by the registered email. To use the page for RemoteLookup, you just add a query string q.action=getrecord to the url and sets the action to updaterecord when you save the changed data back to the server. Here are the example of how to do it.
Login and show the registered values on the contact.
-- The DQL
define temp "Dummy" text.
define temp "fname" text.
define temp "lname" text.
define temp "email" text.
define temp "title" text.
define temp "dob" text.
Dummy := RemoteLookup("@current:mydata").
Dummy := RemoteLookup("@connect:http://127.0.0.1:8080/licensecheck/editcontact/").
Dummy := RemoteLookup( "@login:username/password").
Dummy := RemoteLookup("@query:q.action=getrecord").
Dummy := RemoteLookup( "@get") .
fname := RemoteLookup( "recorddata.first_name") .
lname := RemoteLookup( "recorddata.last_name") .
email := RemoteLookup( "recorddata.email") .
title := RemoteLookup( "recorddata.title") .
dob := RemoteLookup( "recorddata.dob") .
list records
fname ;
lname ;
email ;
title ;
dob .
-- The Body
*****************************************************
Get my contact info
*****************************************************
.items
Name:[{fname}] [{lname}]
EMail:[{email}]
Title:[{title}]
Day of birth:[{dob}]
.end
*****************************************************
-- The result if you have a valid login
*****************************************************
Get my contact info
*****************************************************
Name:Test User
EMail:test@example.com
Title:
Day of birth:17.08.67
*****************************************************
Product: Dataease [{8}]FIVE. Written by Sehoh Kang 06/10/13 at 04:07:52
Product: Dataease [{8}]FIVE. Written by DataEase 07/10/13 at 15:11:24
Product: Dataease [{8}]FIVE. Written by richard keyter 07/04/14 at 11:20:31
Product: Dataease [{8}]FIVE. Written by DataEase Tech Sup 08/04/14 at 08:27:01
Product: Dataease [{8}]FIVE. Written by richard keyter 08/04/14 at 09:15:56
Product: Dataease [{8}]FIVE. Written by DataEase Tech Sup 16/04/14 at 09:27:05
Product: Dataease [{8}]FIVE. Written by richard keyter 17/04/14 at 04:40:36
Product: Dataease [{8}]FIVE. Written by DataEase 07/07/16 at 10:26:25
Product: Not product specific.. Written by Godfrey 20/11/18 at 13:18:49
Product: Not product specific.. Written by DataEase 22/11/18 at 17:53:21
Product: Dataease [{8}]FIVE. Written by DataEase 15/01/14 at 09:14:10