Skip to main content
Version: Next

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
.clearAllRemoteContexts()
clears all the attributes for all the active contexts in the datastore
.dataclassName : 4D.DataClass
contains a description of the dataclass
.encryptionStatus(): Object
returns an object providing the encryption status for the current data file
.flushAndLock()
flushes the cache of the local datastore and prevents other processes from performing write operations on the database
.getAllRemoteContexts() : Collection
returns a collection of objects containing information on all the active optimization contexts in the datastore
.getGlobalStamp() : Real
returns the current value of the global modification stamp of the datastore
.getInfo(): Object
returns an object providing information about the datastore
.getRemoteContextInfo(contextName : Text) : Object
returns an object that holds information on the contextName optimization context in the datastore.
.getRequestLog() : Collection
returns the ORDA requests logged in memory on the client side
.locked() : Boolean
returns True if the local datastore is currently locked
.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
.setGlobalStamp( newStamp : Real)
sets newStamp as new value for the current global modification stamp for the datastore
.setRemoteContextInfo( contextName : Text ; dataClassName : Text ; attributes : Text {; contextType : Text { ; pageLength : Integer}})
.setRemoteContextInfo( contextName : Text ; dataClassName : Text; attributesColl : Collection {; contextType : Text { ; pageLength : Integer }} )
.setRemoteContextInfo( contextName : Text ; dataClassObject : 4D.DataClass ; attributes : Text {; contextType : Text { ; pageLength : Integer }})
.setRemoteContextInfo( contextName : Text ; dataClassObject : 4D.DataClass ; attributesColl : Collection {; contextType : Text { ; pageLength : Integer }} )

links the specified dataclass attributes to the contextName optimization context
.startRequestLog()
.startRequestLog( file : 4D.File )
.startRequestLog( file : 4D.File ; options : Integer )
.startRequestLog( reqNum : Integer )

starts the logging of ORDA requests on the client side or on the server 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 machine it is called (client or server)
.unlock()
removes the current lock on write operations in the datastore, if it has been set in the same process
.validateTransaction()
accepts the transaction

.dataclassName

History
ReleaseChanges
17Added

.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
ReleaseChanges
18Added

.cancelTransaction()

ParameterTypeDescription
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.

.clearAllRemoteContexts()

History
ReleaseChanges
19 R5Added

.clearAllRemoteContexts()

ParameterTypeDescription
Does not require any parameters

Description

The .clearAllRemoteContexts() function clears all the attributes for all the active contexts in the datastore.

This function is mainly used in the context of debugging. One thing to keep in mind is that when you open the debugger, it sends requests to the server and queries all the dataclass attributes to display them. This can overload your contexts with unnecessary data.

In such cases, you can use .clearAllRemoteContexts() to clear your contexts and keep them clean.

See also

.getRemoteContextInfo()
.getAllRemoteContexts()
.setRemoteContextInfo()

.encryptionStatus()

History
ReleaseChanges
17 R5Added

.encryptionStatus(): Object

ParameterTypeDescription
ResultObject<-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:

PropertyTypeDescription
isEncryptedBooleanTrue if the data file is encrypted
keyProvidedBooleanTrue if the encryption key matching the encrypted data file is provided(*).
tablesObjectObject containing as many properties as there are encryptable or encrypted tables.
tableNameObjectEncryptable or Encrypted table
nameTextName of the table
numNumberTable number
isEncryptableBooleanTrue if the table is declared encryptable in the structure file
isEncryptedBooleanTrue 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:=ds.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

.flushAndLock()

History
ReleaseChanges
20Added

.flushAndLock()

ParameterTypeDescription
Does not require any parameters

Description

The .flushAndLock() function flushes the cache of the local datastore and prevents other processes from performing write operations on the database. The datastore is set to a consistent, frozen state. Calling this function is necessary before executing an application snapshot, for example.

info

This function can only be called:

  • on the local datastore (ds).
  • in client/server environment, on the server machine.

Once this function is executed, write operations such as .save() or other .flushAndLock() calls are frozen in all other processes until the datastore is unlocked.

When multiple calls to .flushAndLock() have been done in the same process, the same number of .unlock() calls must be executed to actually unlock the datastore.

The datastore is unlocked when:

  • the .unlock() function is called in the same process, or
  • the process that called the .flushAndLock() function is killed.

If the datastore is already locked from another process, the .flushAndLock() call is frozen and will be executed when the datastore will be unlocked.

An error is triggered if the .flushAndLock() function cannot be executed (e.g. it is run on a remote 4D), .

caution

Other 4D features and services including backup, vss, and MSC can also lock the datastore. Before calling .flushAndLock(), make sure no other locking action is being used, in order to avoid any unexpected interaction.

Example

You want to create a copy of the data folder along with its current journal file:

$destination:=Folder(fk documents folder).folder("Archive")
$destination.create()

ds.flushAndLock() //Block write operations from other processes

$dataFolder:=Folder(fk data folder)
$dataFolder.copyTo($destination) //Copy the data folder

$oldJournalPath:=New log file //Close the journal and create a new one
$oldJournal:=File($oldJournalPath; fk platform path)
$oldJournal.moveTo($destination) //Save the old journal with data

ds.unlock() //Our copy is over, we can now unlock the datastore

See also

.locked()
.unlock()

.getAllRemoteContexts()

History
ReleaseChanges
19 R5Added

.getAllRemoteContexts() : Collection

ParameterTypeDescription
ResultCollection<-Collection of optimization context objects

Advanced mode: This function is intended for developers who need to customize ORDA default features for specific configurations. In most cases, you will not need to use it.

Description

The .getAllRemoteContexts() function returns a collection of objects containing information on all the active optimization contexts in the datastore.

For more information on how contexts can be created, see client/server optimization.

Each object in the returned collection has the properties listed in the .getRemoteContextInfo() section.

Example

The following code sets up two contexts and retrieves them using .getAllRemoteContexts():

var $ds : 4D.DataStoreImplementation
var $persons : cs.PersonsSelection
var $addresses : cs.AddressSelection
var $p : cs.PersonsEntity
var $a : cs.AddressEntity
var $contextA; $contextB : Object
var $info : Collection
var $text : Text

// Open remote datastore
$ds:=Open datastore(New object("hostname"; "www.myserver.com"); "myDS")

// Set context A
$contextA:=New object("context"; "contextA")
$persons:=$ds.Persons.all($contextA)
$text:=""
For each ($p; $persons)
$text:=$p.firstname+" lives in "+$p.address.city+" / "
End for each

// Set context B
$contextB:=New object("context"; "contextB")
$addresses:=$ds.Address.all($contextB)
$text:=""
For each ($a; $addresses)
$text:=$a.zipCode
End for each

// Get all remote contexts (in this case, contextA and contextB)
$info:=$ds.getAllRemoteContexts()
//$info = [{name:"contextB"; dataclass:"Address"; main:"zipCode"},
{name:"contextA";dataclass:"Persons";main:"firstname,address.city"}]

This example serves as a demonstration, it is not meant for real implementation.

See also

.getRemoteContextInfo()
.setRemoteContextInfo()
.clearAllRemoteContexts()

.getGlobalStamp()

History
ReleaseChanges
20 R3Added

.getGlobalStamp() : Real

ParameterTypeDescription
ResultReal<-Current value of the global modification stamp

Description

The .getGlobalStamp() function returns the current value of the global modification stamp of the datastore.

info

This function can only be called:

  • on the local datastore (ds).
  • in client/server environment, on the server machine.

For more information on global stamp and data change tracking, please refer to the Using the Global Stamp page.

Example

var $currentStamp : Real
var $hasModifications : Boolean

$currentStamp:=ds.getGlobalStamp()
methodWhichCouldModifyEmployees //call some code
$hasModifications:=($currentStamp # ds.getGlobalStamp())

See also

.setGlobalStamp()

.getInfo()

History
ReleaseChanges
17Added

.getInfo(): Object

ParameterTypeDescription
ResultObject<-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

PropertyTypeDescription
typestring
  • "4D": main datastore, available through ds
  • "4D Server": remote datastore, open with Open datastore
  • networkedboolean
  • True: the datastore is reached through a network connection.
  • False: the datastore is not reached through a network connection (local database)
  • localIDtextID of the datastore on the machine. Corresponds to the localId string given with the Open datastore command. Empty string ("") for main datastore.
    connectionobjectObject describing the remote datastore connection (not returned for main datastore). Available properties:
    PropertyTypeDescription
    hostnametextIP address or name of the remote datastore + ":" + port number
    tlsbooleanTrue if secured connection is used with the remote datastore
    idleTimeoutnumberSession inactivity timeout (in minutes)
    usertextUser authenticated on the remote datastore
    • 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"}}

    .getRemoteContextInfo()

    History
    ReleaseChanges
    19 R5Added

    .getRemoteContextInfo(contextName : Text) : Object

    ParameterTypeDescription
    contextNameText->Name of the context
    ResultObject<-Description of the optimization context

    Advanced mode: This function is intended for developers who need to customize ORDA default features for specific configurations. In most cases, you will not need to use it.

    Description

    The .getRemoteContextInfo() function returns an object that holds information on the contextName optimization context in the datastore..

    For more information on how optimization contexts can be created, see client/server optimization.

    Returned object

    The returned object has the following properties:

    PropertyTypeDescription
    nameTextName of the context
    mainTextAttribute(s) associated to the context (attribute names are separated by a comma)
    dataclassTextDataclass name
    currentItem (optional)TextThe attributes of the page mode if the context is linked to a list box. Returned as Null or empty text element if the context name is not used for a list box, or if there is no context for the currentItem

    Since contexts behave as filters for attributes, if main is returned empty, it means that no filter is applied, and that the server returns all the dataclass attributes.

    Example

    See the example from the .setRemoteContextInfo() section.

    See also

    .setRemoteContextInfo()
    .getAllRemoteContexts()
    .clearAllRemoteContexts()

    .getRequestLog()

    History
    ReleaseChanges
    17 R6Added

    .getRequestLog() : Collection

    ParameterTypeDescription
    ResultCollection<-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
    ReleaseChanges
    18 R6Added

    .isAdminProtected() : Boolean

    ParameterTypeDescription
    ResultBoolean<-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

    .setAdminProtection()

    .locked()

    History
    ReleaseChanges
    20Added

    .locked() : Boolean

    ParameterTypeDescription
    ResultBoolean<-True if locked

    Description

    The .locked() function returns True if the local datastore is currently locked.

    You can lock the datastore using the .flushAndLock() function before executing a snapshot of the data file, for example.

    caution

    The function will also return True if the datastore was locked by another administration feature such as backup or vss (see .flushAndLock()).

    See also

    .flushAndLock()
    .unlock()

    .makeSelectionsAlterable()

    History
    ReleaseChanges
    18 R5Added

    .makeSelectionsAlterable()

    ParameterTypeDescription
    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() or OB Copy when the explicit ck 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
    ReleaseChanges
    17 R5Added

    .provideDataKey( curPassPhrase : Text ) : Object
    .provideDataKey( curDataKey : Object ) : Object

    ParameterTypeDescription
    curPassPhraseText->Current encryption passphrase
    curDataKeyObject->Current data encryption key
    ResultObject<-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 the Data 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:

    PropertyTypeDescription
    successBooleanTrue if the provided encryption key matches the encrypted data, False otherwise
    Properties below are returned only if success is FALSE
    statusNumberError code (4 if the provided encryption key is wrong)
    statusTextTextError message
    errorsCollectionStack of errors. The first error has the highest index
    [ ].componentSignatureTextInternal component name
    [ ].errCodeNumberError number
    [ ].messageTextError 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
    ReleaseChanges
    18 R6Added

    .setAdminProtection( status : Boolean )

    ParameterTypeDescription
    statusBoolean->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

    .isAdminProtected()

    .setGlobalStamp()

    History
    ReleaseChanges
    20 R3Added

    .setGlobalStamp( newStamp : Real)

    ParameterTypeDescription
    newStampReal->New value of global modification stamp
    Advanced mode

    This function is intended for developers who need to modify the current global stamp value. It should be used with care.

    Description

    The .setGlobalStamp() function sets newStamp as new value for the current global modification stamp for the datastore.

    info

    This function can only be called:

    • on the local datastore (ds).
    • in client/server environment, on the server machine.

    For more information on global stamp and data change tracking, please refer to the Using the Global Stamp page.

    Example

    The following code sets the modification global stamp:

    var $newValue: Real
    $newValue:=ReadValueFrom //get a new value to assign
    ds.setGlobalStamp($newValue)

    See also

    .getGlobalStamp()

    .setRemoteContextInfo()

    History
    ReleaseChanges
    19 R5Added

    .setRemoteContextInfo( contextName : Text ; dataClassName : Text ; attributes : Text {; contextType : Text { ; pageLength : Integer}})
    .setRemoteContextInfo( contextName : Text ; dataClassName : Text; attributesColl : Collection {; contextType : Text { ; pageLength : Integer }} )
    .setRemoteContextInfo( contextName : Text ; dataClassObject : 4D.DataClass ; attributes : Text {; contextType : Text { ; pageLength : Integer }})
    .setRemoteContextInfo( contextName : Text ; dataClassObject : 4D.DataClass ; attributesColl : Collection {; contextType : Text { ; pageLength : Integer }} )

    ParameterTypeDescription
    contextNameText->Name of the context
    dataClassNameText->Name of the dataclass
    dataClassObject4D.DataClass->dataclass object (e.g datastore.Employee)
    attributesText->Attribute list separated by a comma
    attributesCollCollection->Collection of attribute names (text)
    contextTypeText->If provided, value must be "main" or "currentItem"
    pageLengthInteger->Page length of the entity selection linked to the context (default is 80)

    Advanced mode: This function is intended for developers who need to customize ORDA default features for specific configurations. In most cases, you will not need to use it.

    Description

    The .setRemoteContextInfo() function links the specified dataclass attributes to the contextName optimization context. If an optimization context already exists for the specified attributes, this command replaces it.

    When you pass a context to the ORDA class functions, the REST request optimization is triggered immediately:

    • the first entity is not fully loaded as done in automatic mode
    • pages of 80 entities (or pageLength entities) are immediately asked to the server with only the attributes in the context

    For more information on how optimization contexts are built, refer to the client/server optimization paragraph

    In contextName, pass the name of the optimization context to link to the dataclass attributes.

    To designate the dataclass that will receive the context, you can pass a dataClassName or a dataClassObject.

    To designate the attributes to link to the context, pass either a list of attributes separated by a comma in attributes (Text), or a collection of attribute names in attributesColl (collection of text).

    If attributes is an empty Text, or attributesColl is an empty collection, all the scalar attributes of the dataclass are put in the optimization context. If you pass an attribute that does not exist in the dataclass, the function ignores it and an error is thrown.

    You can pass a contextType to specify if the context is a standard context or the context of the current entity selection item displayed in a list box:

    • If set to "main" (default), the contextName designates a standard context.
    • If set to "currentItem", the attributes passed are put in the context of the current item. See Entity selection-based list box.

    In pageLength, specify the number of dataclass entities to request from the server.

    You can pass a pageLength for a relation attribute which is an entity selection (one to many). The syntax is relationAttributeName:pageLength (e.g employees:20).

    Example 1

    var $ds : 4D.DataStoreImplementation
    var $persons : cs.PersonsSelection
    var $p : cs.PersonsEntity
    var $contextA : Object
    var $info : Object
    var $text : Text

    // Open remote datastore
    $ds:=Open datastore(New object("hostname"; "www.myserver.com"); "myDS")

    // Set context info
    $contextA:=New object("context"; "contextA")
    $ds.setRemoteContextInfo("contextA"; $ds.Persons; "firstname, lastname")

    // Send requests to the server using a loop
    $persons:=$ds.Persons.all($contextA)
    $text:=""
    For each ($p; $persons)
    $text:=$p.firstname + " " + $p.lastname
    End for each

    // Check contents of the context
    $info:=$ds.getRemoteContextInfo("contextA")
    // $info = {name:"contextA";dataclass:"Persons";main:"firstname, lastname"}

    This example serves as a demonstration, it is not meant for real implementation.

    Example 2

    The following piece of code requests pages of 30 entities of the Address dataclass from the server. The returned entities only contain the zipCode attribute.

    For each Address entity, 20 Persons entities are returned, and they only contain the lastname and firstname attributes:

    var $ds : 4D.DataStoreImplementation

    $ds:=Open datastore(New object("hostname"; "www.myserver.com"); "myDS")

    $ds.setRemoteContextInfo("contextA"; $ds.Address; "zipCode, persons:20,\
    persons.lastname, persons.firstname"; "main"; 30)

    Example 3 - Listbox

    // When the form loads
    Case of
    : (Form event code=On Load)

    Form.ds:=Open datastore(New object("hostname"; "www.myserver.com"); "myDS")

    // Set the attributes of the page context
    Form.ds.setRemoteContextInfo("LB"; Form.ds.Persons; "age, gender,\
    children"; "currentItem")

    Form.settings:=New object("context"; "LB")
    Form.persons:=Form.ds.Persons.all(Form.settings)
    // Form.persons is displayed in a list box
    End case

    // When you get the attributes in the context of the current item:
    Form.currentItemLearntAttributes:=Form.selectedPerson.getRemoteContextAttributes()
    // Form.currentItemLearntAttributes = "age, gender, children"

    See also

    .getRemoteContextInfo()
    .getAllRemoteContexts()
    .clearAllRemoteContexts()

    .startRequestLog()

    History
    ReleaseChanges
    20Server side support, new options parameter
    17 R6Added

    .startRequestLog()
    .startRequestLog( file : 4D.File )
    .startRequestLog( file : 4D.File ; options : Integer )
    .startRequestLog( reqNum : Integer )

    ParameterTypeDescription
    file4D.File->File object
    optionsInteger->Log response option (server only)
    reqNumInteger->Number of requests to keep in memory (client only)

    Description

    The .startRequestLog() function starts the logging of ORDA requests on the client side or on the server side. It is designed for debugging purposes in client/server configurations.

    info

    For a description of the ORDA request log format, please refer to the ORDA requests section.

    Client-side

    To create a client-side ORDA request log, call this function on a remote machine. The 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.

    Server-side

    To create a server-side ORDA request log, call this function on the server machine. The log data is written in a file in .jsonl 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 you passed the file parameter, the log data is written in this file, at the requested location. - If you omit the file parameter or if it is null, the log data is written in a file named ordaRequests.jsonl and stored in the "/LOGS" folder.
    • The options parameter can be used to specify if the server response has to be logged, and if it should include the body. By default when the parameter is omitted, the full response is logged. The following constants can be used in this parameter:
    ConstantDescription
    srl log allLog the response entirely (default value)
    srl log no responseDisable the logging of the response
    srl log response without bodyLog the response without the body

    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")

    Example 3

    You want to log ORDA server requests in a specific file and enable the log sequence number and duration:

    SET DATABASE PARAMETER(4D Server Log Recording;1)

    $file:=Folder(fk logs folder).file("myOrdaLog.jsonl")
    ds.startRequestLog($file)
    ...
    ds.stopRequestLog()
    SET DATABASE PARAMETER(4D Server Log Recording;0)


    .startTransaction()

    History
    ReleaseChanges
    18Added

    .startTransaction()

    ParameterTypeDescription
    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
    ReleaseChanges
    20Server side support
    17 R6Added

    .stopRequestLog()

    ParameterTypeDescription
    Does not require any parameters

    Description

    The .stopRequestLog() function stops any logging of ORDA requests on the machine it is called (client or server).

    It actually closes the opened document on disk. On the client side, if the log was started in memory, it is stopped.

    This function does nothing if logging of ORDA requests was not started on the machine.

    Example

    See examples for .startRequestLog().

    .unlock()

    History
    ReleaseChanges
    20Added

    .unlock()

    ParameterTypeDescription
    Does not require any parameters

    Description

    The .unlock() function removes the current lock on write operations in the datastore, if it has been set in the same process. Write operations can be locked in the local datastore using the .flushAndLock() function.

    If the current lock was the only lock on the datastore, write operations are immediately enabled. If the .flushAndLock() function was called several times in the process, the same number of .unlock() must be called to actually unlock the datastore.

    The .unlock() function must be called from the process that called the corresponding .flushAndLock(), otherwise the function does nothing and the lock is not removed.

    If the .unlock() function is called in an unlocked datastore, it does nothing.

    See also

    .flushAndLock()
    .locked()

    .validateTransaction()

    History
    ReleaseChanges
    18Added

    .validateTransaction()

    ParameterTypeDescription
    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().