DataStore
A Datastore is the interface object provided by ORDA to reference and access a database. Datastore
objects are returned by the following commands:
- ds: a shortcut to the main datastore
- Open datastore: to open any remote datastore
Summary
.cancelTransaction() cancels the transaction |
.dataclassName : 4D.DataClass contains a description of the dataclass |
.encryptionStatus(): Object returns an object providing the encryption status for the current data file |
.getInfo(): Object returns an object providing information about the datastore |
.getRequestLog() : Collection returns the ORDA requests logged in memory on the client side |
.makeSelectionsAlterable() sets all entity selections as alterable by default in the current application datastores |
.provideDataKey( curPassPhrase : Text ) : Object .provideDataKey( curDataKey : Object ) : Object allows providing a data encryption key for the current data file of the datastore and detects if the key matches the encrypted data |
.setAdminProtection( status : Boolean ) allows disabling any data access on the web admin port, including for the Data Explorer in WebAdmin sessions |
.startRequestLog() .startRequestLog( file : 4D.File ) .startRequestLog( reqNum : Integer ) starts the logging of ORDA requests on the client side |
.startTransaction() starts a transaction in the current process on the database matching the datastore to which it applies |
.stopRequestLog() stops any logging of ORDA requests on the client side |
.validateTransaction() accepts the transaction |
ds
History
Release | Changes |
---|---|
18 | Support of localID parameter |
17 | Added |
ds { ( localID : Text ) } : cs.DataStore
Parameter | Type | Description | |
---|---|---|---|
localID | Text | -> | Local ID of the remote datastore to return |
Result | cs.DataStore | <- | Reference to the datastore |
Description
The ds
command returns a reference to the datastore matching the current 4D database or the database designated by localID.
If you omit the localID parameter (or pass an empty string ""), the command returns a reference to the datastore matching the local 4D database (or the 4D Server database in case of opening a remote database on 4D Server). The datastore is opened automatically and available directly through ds
.
You can also get a reference on an open remote datastore by passing its local id in the localID parameter. The datastore must have been previously opened with the Open datastore
command by the current database (host or component). The local id is defined when using this command.
The scope of the local id is the database where the datastore has been opened.
If no localID datastore is found, the command returns Null.
Using ds
requires that the target database is compliant with ORDA, as specified in the ORDA prerequisites section. The following rules are applied:
- A datastore only references tables with a single primary key. Tables without a primary key or with composite primary keys are not referenced.
- BLOB type attributes are not managed in the datastore.
Example 1
Using the main datastore on the 4D database:
$result:=ds.Employee.query("firstName = :1";"S@")
Example 2
var $connectTo; $firstFrench; $firstForeign : Object
var $frenchStudents; $foreignStudents : cs.DataStore
$connectTo:=New object("type";"4D Server";"hostname";"192.168.18.11:8044")
$frenchStudents:=Open datastore($connectTo;"french")
$connectTo.hostname:="192.168.18.11:8050"
$foreignStudents:=Open datastore($connectTo;"foreign")
//...
//...
$firstFrench:=getFirst("french";"Students")
$firstForeign:=getFirst("foreign";"Students")
//getFirst method
//getFirst(localID;dataclass) -> entity
#DECLARE( $localId : Text; $dataClassName : Text ) -> $entity : 4D.Entity
$0:=ds($localId)[$dataClassName].all().first()
Open datastore
History
Release | Changes |
---|---|
18 | Added |
Open datastore( connectionInfo : Object ; localID : Text ) : cs.DataStore
Parameter | Type | Description | |
---|---|---|---|
connectionInfo | Object | -> | Connection properties used to reach the remote datastore |
localID | Text | -> | Id to assign to the opened datastore on the local application (mandatory) |
Result | cs.DataStore | <- | Datastore object |
Description
The Open datastore
command connects the application to the 4D database identified by the connectionInfo parameter and returns a matching cs.DataStore
object associated with the localID local alias.
The connectionInfo 4D database must be available as a remote datastore, i.e.:
- its web server must be launched with http and/or https enabled,
- its Expose as REST server option must be checked,
- at least one client license is available.
If no matching database is found, Open datastore
returns Null.
localID is a local alias for the session opened on remote datastore. If localID already exists on the application, it is used. Otherwise, a new localID session is created when the datastore object is used.
Once the session is opened, the following statements become equivalent and return a reference on the same datastore object:
$myds:=Open datastore(connectionInfo;"myLocalId")
$myds2:=ds("myLocalId")
//$myds and $myds2 are equivalent
Pass in connectionInfo an object describing the remote datastore you want to connect to. It can contain the following properties (all properties are optional except hostname):
Property | Type | Description |
---|---|---|
hostname | Text | Name or IP address of the remote database + ":" + port number (port number is mandatory) |
user | Text | User name |
password | Text | User password |
idleTimeout | Integer | Inactivity session timeout (in minutes), after which the session is automatically closed by 4D. If omitted, default value is 60 (1h). The value cannot be < 60 (if a lower value is passed, the timeout is set to 60). For more information, see Closing sessions. |
tls | Boolean | Use secured connection(*). If omitted, false by default. Using a secured connection is recommended whenever possible. |
type | Text | Must be "4D Server" |
(*) If tls is true, the HTTPS protocol is used if:
- HTTPS is enabled on the remote datastore
- the given port is the right HTTPS port configured in the database settings
- a valid certificate and private encryption key are installed in the database. Otherwise, error "1610 - A remote request to host xxx has failed" is raised
Example 1
Connection to a remote datastore without user / password:
var $connectTo : Object
var $remoteDS : cs.DataStore
$connectTo:=New object("type";"4D Server";"hostname";"192.168.18.11:8044")
$remoteDS:=Open datastore($connectTo;"students")
ALERT("This remote datastore contains "+String($remoteDS.Students.all().length)+" students")
Example 2
Connection to a remote datastore with user / password / timeout / tls:
var $connectTo : Object
var $remoteDS : cs.DataStore
$connectTo:=New object("type";"4D Server";"hostname";\"192.168.18.11:4443";\
"user";"marie";"password";$pwd;"idleTimeout";70;"tls";True)
$remoteDS:=Open datastore($connectTo;"students")
ALERT("This remote datastore contains "+String($remoteDS.Students.all().length)+" students")
Example 3
Working with several remote datastores:
var $connectTo : Object
var $frenchStudents; $foreignStudents : cs.DataStore
$connectTo:=New object("hostname";"192.168.18.11:8044")
$frenchStudents:=Open datastore($connectTo;"french")
$connectTo.hostname:="192.168.18.11:8050"
$foreignStudents:=Open datastore($connectTo;"foreign")
ALERT("They are "+String($frenchStudents.Students.all().length)+" French students")
ALERT("They are "+String($foreignStudents.Students.all().length)+" foreign students")
Error management
In case of error, the command returns Null. If the remote datastore cannot be reached (wrong address, web server not started, http and https not enabled...), error 1610 "A remote request to host XXX has failed" is raised. You can intercept this error with a method installed by ON ERR CALL
.
.dataclassName
History
Release | Changes |
---|---|
17 | Added |
.dataclassName : 4D.DataClass
Description
Each dataclass in a datastore is available as a property of the DataStore objectdata. The returned object contains a description of the dataclass.
Example
var $emp : cs.Employee
var $sel : cs.EmployeeSelection
$emp:=ds.Employee //$emp contains the Employee dataclass
$sel:=$emp.all() //gets an entity selection of all employees
//you could also write directly:
$sel:=ds.Employee.all()
.cancelTransaction()
History
Release | Changes |
---|---|
18 | Added |
.cancelTransaction()
Parameter | Type | Description | |
---|---|---|---|
Does not require any parameters |
Description
The .cancelTransaction()
function cancels the transaction opened by the .startTransaction()
function at the corresponding level in the current process for the specified datastore.
The .cancelTransaction()
function cancels any changes made to the data during the transaction.
You can nest several transactions (sub-transactions). If the main transaction is cancelled, all of its sub-transactions are also cancelled, even if they were validated individually using the .validateTransaction()
function.
Example
See example for the .startTransaction()
function.
.encryptionStatus()
History
Release | Changes |
---|---|
17 R5 | Added |
.encryptionStatus(): Object
Parameter | Type | Description | |
---|---|---|---|
Result | Object | <- | Information about the encryption of the current datastore and of each table |
Description
The .encryptionStatus()
function returns an object providing the encryption status for the current data file (i.e., the data file of the ds
datastore). The status for each table is also provided.
Use the
Data file encryption status
command to determine the encryption status of any other data file.
Returned value
The returned object contains the following properties:
Property | Type | Description | ||
---|---|---|---|---|
isEncrypted | Boolean | True if the data file is encrypted | ||
keyProvided | Boolean | True if the encryption key matching the encrypted data file is provided(*). | ||
tables | Object | Object containing as many properties as there are encryptable or encrypted tables. | ||
tableName | Object | Encryptable or Encrypted table | ||
name | Text | Name of the table | ||
num | Number | Table number | ||
isEncryptable | Boolean | True if the table is declared encryptable in the structure file | ||
isEncrypted | Boolean | True if the records of the table are encrypted in the data file |
(*) The encryption key can be provided:
- with the
.provideDataKey()
command, - at the root of a connected device before opening the datastore,
- with the
Discover data key
command.
Example
You want to know the number of encrypted tables in the current data file:
var $status : Object
$status:=dataStore.encryptionStatus()
If($status.isEncrypted) //the database is encrypted
C_LONGINT($vcount)
C_TEXT($tabName)
For each($tabName;$status.tables)
If($status.tables[$tabName].isEncrypted)
$vcount:=$vcount+1
End if
End for each
ALERT(String($vcount)+" encrypted table(s) in this datastore.")
Else
ALERT("This database is not encrypted.")
End if
.getInfo()
History
Release | Changes |
---|---|
17 | Added |
.getInfo(): Object
Parameter | Type | Description | |
---|---|---|---|
Result | Object | <- | Datastore properties |
Description
The .getInfo()
function returns an object providing information about the datastore. This function is useful for setting up generic code.
Returned object
Property | Type | Description | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
type | string | ||||||||||||||||
networked | boolean | ||||||||||||||||
localID | text | ID of the datastore on the machine. Corresponds to the localId string given with the Open datastore command. Empty string ("") for main datastore. | |||||||||||||||
connection | object | Object describing the remote datastore connection (not returned for main datastore). Available properties:
|
- If the
.getInfo()
function is executed on a 4D Server or 4D single-user,networked
is False. - If the
.getInfo()
function is executed on a remote 4D,networked
is True
Example 1
var $info : Object
$info:=ds.getInfo() //Executed on 4D Server or 4D
//{"type":"4D","networked":false,"localID":""}
$info:=ds.getInfo() // Executed on 4D remote
//{"type":"4D","networked":true,"localID":""}
Example 2
On a remote datastore:
var $remoteDS : cs.DataStore
var $info; $connectTo : Object
$connectTo:=New object("hostname";"111.222.33.44:8044";"user";"marie";"password";"aaaa")
$remoteDS:=Open datastore($connectTo;"students")
$info:=$remoteDS.getInfo()
//{"type":"4D Server",
//"localID":"students",
//"networked":true,
//"connection":{hostname:"111.222.33.44:8044","tls":false,"idleTimeout":2880,"user":"marie"}}
.getRequestLog()
History
Release | Changes |
---|---|
17 R6 | Added |
.getRequestLog() : Collection
Parameter | Type | Description | |
---|---|---|---|
Result | Collection | <- | Collection of objects, where each object describes a request |
Description
The .getRequestLog()
function returns the ORDA requests logged in memory on the client side. The ORDA request logging must have previously been enabled using the .startRequestLog()
function.
This function must be called on a remote 4D, otherwise it returns an empty collection. It is designed for debugging purposes in client/server configurations.
Returned value
Collection of stacked request objects. The most recent request has index 0.
For a description of the ORDA request log format, please refer to the ORDA client requests section.
Example
See Example 2 of .startRequestLog()
.
.isAdminProtected()
History
Release | Changes |
---|---|
18 R6 | Added |
.isAdminProtected() : Boolean
Parameter | Type | Description | |
---|---|---|---|
Result | Boolean | <- | True if the Data Explorer access is disabled, False if it is enabled (default) |
Description
The .isAdminProtected()
function returns True
if Data Explorer access has been disabled for the working session.
By default, the Data Explorer access is granted for webAdmin
sessions, but it can be disabled to prevent any data access from administrators (see the .setAdminProtection()
function).
See also
.makeSelectionsAlterable()
History
Release | Changes |
---|---|
18 R5 | Added |
.makeSelectionsAlterable()
Parameter | Type | Description | |
---|---|---|---|
Does not require any parameters |
Description
The .makeSelectionsAlterable()
function sets all entity selections as alterable by default in the current application datastores (including remote datastores). It is intended to be used once, for example in the On Startup
database method.
When this function is not called, new entity selections can be shareable, depending on the nature of their "parent", or how they are created.
This function does not modify entity selections created by
.copy()
orOB Copy
when the explicitck shared
option is used.
Compatibility: This function must only be used in projects converted from 4D versions prior to 4D v18 R5 and containing .add() calls. In this context, using
.makeSelectionsAlterable()
can save time by restoring instantaneously the previous 4D behavior in existing projects. On the other hand, using this method in new projects created in 4D v18 R5 and higher is not recommended, since it prevents entity selections to be shared, which provides greater performance and scalabitlity.
.provideDataKey()
History
Release | Changes |
---|---|
17 R5 | Added |
.provideDataKey( curPassPhrase : Text ) : Object
.provideDataKey( curDataKey : Object ) : Object
Parameter | Type | Description | |
---|---|---|---|
curPassPhrase | Text | -> | Current encryption passphrase |
curDataKey | Object | -> | Current data encryption key |
Result | Object | <- | Result of the encryption key matching |
Description
The .provideDataKey()
function allows providing a data encryption key for the current data file of the datastore and detects if the key matches the encrypted data. This function can be used when opening an encrypted database, or when executing any encryption operation that requires the encryption key, such as re-encrypting the data file.
- The
.provideDataKey()
function must be called in an encrypted database. If it is called in a non-encrypted database, the error 2003 (the encryption key does not match the data.) is returned. Use theData file encryption status
command to determine if the database is encrypted.- The
.provideDataKey()
function cannot be called from a remote 4D or an encrypted remote datastore.
If you use the curPassPhrase parameter, pass the string used to generate the data encryption key. When you use this parameter, an encryption key is generated.
If you use the curDataKey parameter, pass an object (with encodedKey property) that contains the data encryption key. This key may have been generated with the New data key
command.
If a valid data encryption key is provided, it is added to the keyChain in memory and the encryption mode is enabled:
- all data modifications in encryptable tables are encrypted on disk (.4DD, .journal. 4Dindx files)
- all data loaded from encryptable tables is decrypted in memory
Result
The result of the command is described in the returned object:
Property | Type | Description | |
---|---|---|---|
success | Boolean | True if the provided encryption key matches the encrypted data, False otherwise | |
Properties below are returned only if success is FALSE | |||
status | Number | Error code (4 if the provided encryption key is wrong) | |
statusText | Text | Error message | |
errors | Collection | Stack of errors. The first error has the highest index | |
[ ].componentSignature | Text | Internal component name | |
[ ].errCode | Number | Error number | |
[ ].message | Text | Error message |
If no curPassphrase or curDataKey is given, .provideDataKey()
returns null (no error is generated).
Example
var $keyStatus : Object
var $passphrase : Text
$passphrase:=Request("Enter the passphrase")
If(OK=1)
$keyStatus:=ds.provideDataKey($passphrase)
If($keyStatus.success)
ALERT("You have provided a valid encryption key")
Else
ALERT("You have provided an invalid encryption key, you will not be able to work with encrypted data")
End if
End if
.setAdminProtection()
History
Release | Changes |
---|---|
18 R6 | Added |
.setAdminProtection( status : Boolean )
Parameter | Type | Description | |
---|---|---|---|
status | Boolean | -> | True to disable Data Explorer access to data on the webAdmin port, False (default) to grant access |
Description
The .setAdminProtection()
function allows disabling any data access on the web admin port, including for the Data Explorer in WebAdmin
sessions.
By default when the function is not called, access to data is always granted on the web administration port for a session with WebAdmin
privilege using the Data Explorer. In some configurations, for example when the application server is hosted on a third-party machine, you might not want the administrator to be able to view your data, although they can edit the server configuration, including the access key settings.
In this case, you can call this function to disable the data access from Data Explorer on the web admin port of the machine, even if the user session has the WebAdmin
privilege. When this function is executed, the data file is immediately protected and the status is stored on disk: the data file will be protected even if the application is restarted.
Example
You create a protectDataFile project method to call before deployments for example:
ds.setAdminProtection(True) //Disables the Data Explorer data access
See also
.startRequestLog()
History
Release | Changes |
---|---|
17 R6 | Added |
.startRequestLog()
.startRequestLog( file : 4D.File )
.startRequestLog( reqNum : Integer )
Parameter | Type | Description | |
---|---|---|---|
file | 4D.File | -> | File object |
reqNum | Integer | -> | Number of requests to keep in memory |
Description
The .startRequestLog()
function starts the logging of ORDA requests on the client side.
This function must be called on a remote 4D, otherwise it does nothing. It is designed for debugging purposes in client/server configurations.
The ORDA request log can be sent to a file or to memory, depending on the parameter type:
- If you passed a file object created with the
File
command, the log data is written in this file as a collection of objects (JSON format). Each object represents a request.
If the file does not already exist, it is created. Otherwise if the file already exists, the new log data is appended to it. If.startRequestLog( )
is called with a file while a logging was previously started in memory, the memory log is stopped and emptied.
A ] character must be manually appended at the end of the file to perform a JSON validation
-
If you passed a reqNum integer, the log in memory is emptied (if any) and a new log is initialized. It will keep reqNum requests in memory until the number is reached, in which case the oldest entries are emptied (FIFO stack).
If.startRequestLog()
is called with a reqNum while a logging was previously started in a file, the file logging is stopped. -
If you did not pass any parameter, the log is started in memory. If
.startRequestLog()
was previously called with a reqNum (before a.stopRequestLog()
), the log data is stacked in memory until the next time the log is emptied or.stopRequestLog()
is called.
For a description of the ORDA request log format, please refer to the ORDA client requests section.
Example 1
You want to log ORDA client requests in a file and use the log sequence number:
var $file : 4D.File
var $e : cs.PersonsEntity
$file:=File("/LOGS/ORDARequests.txt") //logs folder
SET DATABASE PARAMETER(Client Log Recording;1) //to trigger the global log sequence number
ds.startRequestLog($file)
$e:=ds.Persons.get(30001) //send a request
ds.stopRequestLog()
SET DATABASE PARAMETER(Client Log Recording;0)
Example 2
You want to log ORDA client requests in memory:
var $es : cs.PersonsSelection
var $log : Collection
ds.startRequestLog(3) //keep 3 requests in memory
$es:=ds.Persons.query("name=:1";"Marie")
$es:=ds.Persons.query("name IN :1";New collection("Marie"))
$es:=ds.Persons.query("name=:1";"So@")
$log:=ds.getRequestLog()
ALERT("The longest request lasted: "+String($log.max("duration"))+" ms")
.startTransaction()
History
Release | Changes |
---|---|
18 | Added |
.startTransaction()
Parameter | Type | Description | |
---|---|---|---|
Does not require any parameters |
Description
The .startTransaction()
function starts a transaction in the current process on the database matching the datastore to which it applies. Any changes made to the datastore's entities in the transaction's process are temporarily stored until the transaction is either validated or cancelled.
If this method is called on the main datastore (i.e. the datastore returned by the
ds
command), the transaction is applied to all operations performed on the main datastore and on the underlying database, thus including ORDA and classic languages.
You can nest several transactions (sub-transactions). Each transaction or sub-transaction must eventually be cancelled or validated. Note that if the main transaction is cancelled, all of its sub-transactions are also cancelled even if they were validated individually using the .validateTransaction()
function.
Example
var $connect; $status : Object
var $person : cs.PersonsEntity
var $ds : cs.DataStore
var $choice : Text
var $error : Boolean
Case of
:($choice="local")
$ds:=ds
:($choice="remote")
$connect:=New object("hostname";"111.222.3.4:8044")
$ds:=Open datastore($connect;"myRemoteDS")
End case
$ds.startTransaction()
$person:=$ds.Persons.query("lastname=:1";"Peters").first()
If($person#Null)
$person.lastname:="Smith"
$status:=$person.save()
End if
...
...
If($error)
$ds.cancelTransaction()
Else
$ds.validateTransaction()
End if
.stopRequestLog()
History
Release | Changes |
---|---|
17 R6 | Added |
.stopRequestLog()
Parameter | Type | Description | |
---|---|---|---|
Does not require any parameters |
Description
The .stopRequestLog()
function stops any logging of ORDA requests on the client side (in file or in memory). It is particularly useful when logging in a file, since it actually closes the opened document on disk.
This function must be called on a remote 4D, otherwise it does nothing. It is designed for debugging purposes in client/server configurations.
Example
See examples for .startRequestLog()
.
.validateTransaction()
History
Release | Changes |
---|---|
18 | Added |
.validateTransaction()
Parameter | Type | Description | |
---|---|---|---|
Does not require any parameters |
Description
The .validateTransaction()
function accepts the transaction that was started with .startTransaction()
at the corresponding level on the specified datastore.
The function saves the changes to the data on the datastore that occurred during the transaction.
You can nest several transactions (sub-transactions). If the main transaction is cancelled, all of its sub-transactions are also cancelled, even if they were validated individually using this function.
Example
See example for .startTransaction()
.