diff --git a/docs/API/SignalClass.md b/docs/API/SignalClass.md index b5b4ce8fffe945..e466bc9588088f 100644 --- a/docs/API/SignalClass.md +++ b/docs/API/SignalClass.md @@ -5,20 +5,16 @@ title: Signal Signals are tools provided by the 4D language to manage interactions and avoid conflicts between processes in a multiprocess application. Signals allow you to make sure one or more process(es) will wait for a specific task to be completed before continuing execution. Any process can wait and/or release a signal. -> Semaphores can also be used to manage interactions. Semaphores allow you to make sure that two or more processes do not modify the same resource (file, record...) at the same time. Only the process that sets the semaphore can remove it. +:::note +[Semaphores](../Develop/processes.md#semaphores) can also be used to manage interactions. Semaphores allow you to make sure that two or more processes do not modify the same resource (file, record...) at the same time. Only the process that sets the semaphore can remove it. + +::: ### Signal Object A signal is a shared object that must be passed as a parameter to commands that call or create workers or processes. -A `4D.Signal` object contains the following built-in methods and properties: - -- [`.wait()`](#wait) -- [`.trigger()`](#trigger) -- [`.signaled`](#signaled) -- [`.description`](#description). - Any worker/process calling the `.wait()` method will suspend its execution until the `.signaled` property is true. While waiting for a signal, the calling process does not use any CPU. This can be very interesting for performance in multiprocess applications. The `.signaled` property becomes true when any worker/process calls the `.trigger()` method. Note that to avoid blocking situations, the `.wait()` can also return after a defined timeout has been reached. diff --git a/docs/Concepts/dt_string.md b/docs/Concepts/dt_string.md index 7c999d4f48aae0..c1ac293ed35819 100644 --- a/docs/Concepts/dt_string.md +++ b/docs/Concepts/dt_string.md @@ -34,6 +34,15 @@ The following escape sequences can be used within strings: **Note:** The \ (backslash) character is used as a separator in pathnames under Windows. You must therefore use a double backslash \\\ in paths when you want to have a backslash in front of a character used in one of the escape sequences recognized by 4D (e.g. "C:\\\MyDocuments\\\New.txt"). + +### Automatic normalization of line endings + +In order to ensure multi-platform compatibility of texts handled in the database, 4D automatically normalizes line endings so that they occupy a single character: `\r` (carriage return). This normalization is carried out at the level of form objects (variables or fields) hosting plain or multi-style text. Line endings that are not native, or that use a mix of several characters (for example `\r\n`), are considered as a single `\r`. Note that in compliance with the XML standard (multi-style text format), the [multi-style text commands](../commands/theme/Styled_Text.md) also normalize line endings for text variables that are not associated with objects. + +This principle makes it easier to use multi-style text commands or commands such as [`HIGHLIGHT TEXT`](../commands/highlight-text) in a multi-platform context. However, you must take this into account in your processing when you work with texts from heterogeneous sources. + + + ## String operators |Operation |Syntax |Returns |Expression |Value| diff --git a/docs/Concepts/methods.md b/docs/Concepts/methods.md index 8c7ec211e2217e..a9ae6867c776f3 100644 --- a/docs/Concepts/methods.md +++ b/docs/Concepts/methods.md @@ -24,3 +24,57 @@ In the 4D Language, there are several categories of methods. The category depend |**Class**|Automatically called when an object of the class is instantiated or when a function of the class is executed on an object instance in any other methods or in a [database field](../Develop/field-properties.md#class).|yes (class functions)|A **Class** is used to declare and configure the class [constructor](./classes.md#class-constructor), [properties](./classes.md#property), and [functions](./classes.md#function) of objects. See [**Classes**](classes.md) and [**Function** class](../API/FunctionClass.md). | +## Language tokens + +4D's language includes a unique tokenization system for constants, commands, tables, fields and keywords names that are used in the code. Tokenizing these names means that as you type in the code editor they are stored internally as absolute references (numbers) and then restored as text during execution or display depending on the context. This allows you to guarantee that the code will always be interpreted correctly, even if you rename your tables or fields, or when 4D language commands are renamed over the course of different application versions. + +**Note:** This also ensures automatic translation of the code when you have enabled the ["Use regional system settings" preference](../Preferences/methods.md#4d-programming-language-use-regional-system-settings) and open your databases with 4D versions in different languages. + +Tokenisation is completely transparent for 4D developers when working in the [4D code editor](../code-editor/write-class-method.md), and you generally won't need to worry about it. However, there are two cases where you might need to take action regarding tokenization: if you want to disable it, and if you want to use tokenization in your formulas. + +### Disabling tokenization + +When your project is stored on a version control system (VCS) such as GitHub or GitLab, you may want to disable tokenization to make the code more readable on the external platform. To do this, you can deselect the [**Include tokens in project source files**](../Preferences/general.md#include-tokens-in-project-source-files) preference to prevent tokens from being stored in your **new projects**. + +You can configure your **existing projects** to save code without tokens by inserting the following key in the `.4DProject` file using a text editor: + +```json +"tokenizedText": false +``` + +This setting is only taken into account when methods are saved. Existing methods in your projects are left untouched, unless you resave them. + +### Using tokens in formulas + +A text-based 4D [formula](../commands/theme/Formulas.md) is a text that is interpreted at runtime, and not as it is typed. In fact, this is the case as soon as 4D code is expressed as raw text, more specifically when code is exported and then imported using the [`METHOD GET CODE`](../commands/method-get-code) and [`METHOD SET CODE`](../commands/method-set-code) commands, copied/pasted or [interpreted from 4D HTML tags](../Tags/transformation-tags.md). +To benefit from tokenization mechanisms in these contexts, you just need to use an explicit syntax which consists in preceding object names in the language by their token. + +### Token syntax + +For tokenizable named elements contained in expressions, 4D offers a special syntax you can use to reference the tokens directly: you just need to add a specific suffix after the element name to indicate its type (command, field, etc.), followed by its reference. The token syntax is detailed in this table: + +|Element|Example (standard syntax)|Suffix|Example (token syntax)|Comments| +|--|---|---|---|----| +|4D Command|String(a)|:Cxx|String:C10(a)|xx is the command number| +|4D Constant|Pi|:Kxx:yy|Pi:K30:1|xx is the ID of the constant group and yy is its index (position) within this group| +|Table|[Employees]|:xx|[Employees:1]|xx is the table number| +|Field|[Employees]Name|:xx|[Employees:1]Name:2|xx is the field number| +|4D Plugin|PV PRINT(area)|:Pxx:yy|PV PRINT:P13000:229(area)|xx is the plug-in ID and yy is the index of the command| + +**Note:** Uppercase letters (C, P) must be used in the suffixes; otherwise, they will not be interpreted correctly. + +When you use this syntax, you guarantee that your formulas will be interpreted correctly even in the case of renaming or when the database is executed in a different language. + +This syntax is accepted in all 4D formulas (or 4D expressions) regardless of the calling context: + +- 4D formulas executed using the Formula editor or using commands such as [`EXECUTE FORMULA`](../commands/execute-formula), [`APPLY TO SELECTION`](../commands/apply-to-selection), [`QUERY BY FORMULA`](../commands/query-by-formula), [`LISTBOX INSERT COLUMN FORMULA`](../commands/listbox-insert-column-formula), etc. +- expressions inserted in [multi-style text areas](../FormObjects/properties_Text.md#supported-tags) (see [`ST INSERT EXPRESSION`]()), +- expressions calculated in [transformation tags](../Tags/transformation-tags.md), +- expressions inserted in external areas such as [4D Write Pro areas](../WritePro/managing-formulas.md). + +#### Where to find the element numbers? + +The token syntax requires the addition of the reference numbers of various elements. The location of these references depends on the type of element. + +- **4D commands:** Command numbers can be found in the documentation ("Properties" area) as well as on the Commands page of the Explorer. +- **Tables and fields**: Table and field numbers can be obtained using the [`Table`](../commands/table) and [`Field`](../commands/field) commands. They are also displayed in the Inspector palette of the Structure editor. \ No newline at end of file diff --git a/docs/Desktop/drag-and-drop.md b/docs/Desktop/drag-and-drop.md new file mode 100644 index 00000000000000..4ce94a9056588f --- /dev/null +++ b/docs/Desktop/drag-and-drop.md @@ -0,0 +1,276 @@ +--- +id: drag-and-drop +title: Drag and drop +--- + +## Overview + +4D allows built-in drag and drop capability between objects in your forms and applications. You can drag and drop one object to another, in the same window or in another window. In other words, drag and drop can be performed within a process or from one process to another. + +You can also drag and drop objects between 4D forms and other applications, and vice versa. For example, it is possible to drag and drop a .png picture file onto a 4D picture field. It is also possible to select text in a word processing application and drop it onto a 4D text variable or a list box. + +Finally, it is possible to drop objects directly onto the application without necessarily having a form in the foreground. The [`On Drop` Database Method](../commands-legacy/on-drop-database-method.md) can be used to manage the drag and drop action in this case. This means, for example, that you can open a 4D Write Pro document by dropping it onto the 4D application icon. + +4D provides two drag-and-drop modes: + +- a **custom mode**, where the whole drag-and-drop operation is handled by the programmer. This mode lets you implement any interface based upon drag-on-drop, including interfaces that do not necessarily transport data, but can perform any action like opening files or triggering a calculation. +- an **automatic mode**, where a drag-and-drop operation automatically copies or moves data from an object to another. This mode is available to text-based objects and (partially) pictures, and can be enabled by simply selecting a property. + + +## Draggable and Droppable Objects + +Several form objects can be draggable and/or droppable, in custom and/or automatic mode (see below). By default, newly created form objects can be neither dragged nor dropped ("none" value). It is up to you to set these properties. + +To drag and drop an object to another object, you must set its [**Draggable** property](../FormObjects/properties_Action.md#draggable) to "Automatic" or "Custom". In a drag-and-drop operation, the object that you drag is the source object. + +To make an object the destination of a drag and drop operation, you must set its [**Droppable** property](../FormObjects/properties_Action.md#droppable) to "Automatic" or "Custom". In a drag-and-drop operation, the object that receives data is the destination object. + +The following table lists the available properties for draggable and/or droppable objects: + +|Form object|Draggable "Custom"|Droppable "Custom"|Draggable "Auto"|Droppable "Auto"| +|----|----|----|----|----| +|[4D Write Pro areas](writeProArea_overview.md)|x|x|x|x| +|[Combo Box](comboBox_overview.md)||x|x|x| +|[Input](input_overview.md)|x|x|x|x| +|[Hierarchical List](list_overview.md)|x|x||| +|[List Box](listbox_overview.md)|x|x||| +|[Plug-in Area](pluginArea_overview.md)|||x|x| +|[Button](button_overview.md)||x||| +|[Picture button](pictureButton_overview.md)||x||| + + +Items of a hierarchical list or rows in a list box can be dragged and dropped. Conversely, you can drag and drop an object onto an item of a hierarchical list or a list box row. However, you cannot drag and drop objects from the detail area of an output form. You can also manage dragging and dropping onto the application, outside of any form, using the [`On Drop` database method](../commands-legacy/on-drop-database-method.md). + +:::note Notes + +- By default, in the case of picture fields and variables, the picture and its reference are both dragged. If you only want to drag the reference, first hold down the **Alt** (Windows) or **Option** (macOS) key. +- When the "Custom" Draggable and ["Movable Rows"](../FormObjects/properties_Action.md#movable-rows) properties are both set for an array list box object, the "Movable Rows" property takes priority when a row is moved. Dragging is not possible in this case. +- An object that is capable of being both dragged and dropped can also be dropped onto itself, unless you reject the operation. + +::: + + +## Custom Drag and Drop + +Implementing a custom drag-and-drop interface means combining properties, events, and commands from the [*Pasteboard* theme](../commands/theme/Pasteboard.md). The following diagram illustrates the key points of a custom drag-and-drop sequence: + +![](../assets/en/Desktop/dragdrop1.png) + +Your implementation will be based upon the following scenario: + +1. In the [`On Begin Drag Over`](../Events/onBeginDragOver.md) event of the source object (with ["Custom" **Draggable** property](../FormObjects/properties_Action.md#draggable)), put appropriate data in the pasteboard using [`APPEND DATA TO PASTEBOARD`](../commands/append-data-to-pasteboard), [`SET FILE TO PASTEBOARD`](../commands/set-file-to-pasteboard) or other commands from the [Pasteboard theme](../commands/theme/Pasteboard.md). You can also define a specific cursor icon using [`SET DRAG ICON`](../commands/set-drag-icon) command. +2. In the [`On Drag Over`](../Events/onDragOver.md) event of the destination object (with ["Custom" **Droppable** property](../FormObjects/properties_Action.md#droppable)), get the data types or data signatures found in the pasteboard using [`GET PASTEBOARD DATA TYPE`](../commands/get-pasteboard-data-type) or [`GET PASTEBOARD DATA`](../commands/get-pasteboard-data) and check if they are compatible with the destination object. +The [`Drop position`](../commands/drop-position) command returns the element number or the item position of the target element or list item, if the destination object is an array (i.e., scrollable area), a hierarchical list, a text or a combo box, as well as the column number if the object is a list box. +3. The [object method](../Concepts/methods.md#method-types) of the destination object or element must return 0 or -1 to accept or reject the action: + - If it is compatible, return **0** to accept the drop and execute the [`On Drop`](../Events/onDrop.md) event when the mouse button is released. + - Otherwise, return **-1** to reject the drop. +4D automatically handles the interface aspect of this interaction by displaying a cursor depending on whether the drop is accepted or rejected. +4. In the [`On Drop`](../Events/onDrop.md) event of the destination object (with ["Custom" **Droppable** property](../FormObjects/properties_Action.md#droppable)), execute any action in response to the drop. If the drag-and-drop operation is intended to copy the dragged data, you simply assign the data to destination object. If the drag and drop is not intended to move data, but is instead a user interface metaphor for a particular operation, you can perform whatever you want, for example getting file paths using [`Get file from pasteboard`](../commands/get-file-from-pasteboard) command. + + +Note that the [`On Begin Drag Over`](../Events/onBeginDragOver.md) event is generated **in the context of the source object of the drag** while [`On Drag Over`](../Events/onDragOver.md) and [`On Drop`](../Events/onDrop.md) events are only sent to the destination object. + +In order for the application to process these events, they must be selected in an appropriate manner in the Property List for both the source and destination objects: + +![](../assets/en/Desktop/dragdrop2.png) + + +## Automatic Drag and Drop + +Automatic drag and drop is the movement or copy of a text or picture selection from one area to another by a single click. It can be used in the same 4D area, between two 4D areas, or between 4D and another application. + +:::note + +In the case of automatic drag and drop between two 4D areas, the data are moved, in other words, they are removed from the source area. If you want to copy the data, hold down the **Ctrl** (Windows) or **Option** (macOS) key during the action (under macOS, you need to hit the **Option** key *after* you start to drag the item(s)). + +::: + + +[Automatic Draggable](../FormObjects/properties_Action.md#draggable) property and [Automatic Droppable](../FormObjects/properties_Action.md#droppable) property can be configured separately for each form object. + +- **Draggable: Automatic**: When this option is selected, the automatic drag mode is activated for the object. In this mode, the [`On Begin Drag`](../Events/onBeginDragOver.md) form event is NOT generated. +If you want to "force" the use of the custom drag while automatic drag is enabled, hold down the **Alt** (Windows) or **Option** (macOS) key during the action (under macOS, you need to hit the **Option** key *before* you start to drag the item(s)). This option is not available for pictures. +- **Droppable: Automatic**: In this mode, 4D automatically manages — if possible — the insertion of dragged data of the text or picture type that is dropped onto the object (the data are pasted into the object). The [`On Drag Over`](../Events/onDragOver.md) and [`On Drop`](../Events/onDrop.md) form events are not generated in this case. On the other hand, the [`On After Edit`](../Events/onAfterEdit.md) (during a drop) and [`On Data Change`](../Events/onDataChange.md) (when the object loses the focus) events are generated. + +In the case of data other than text or pictures (another 4D object, file, etc.) or complex data being dropped, the application refers to the value of the "Droppable" option: if it is not "none", the [`On Drag Over`](../Events/onDragOver.md) and [`On Drop`](../Events/onDrop.md) form events are generated; otherwise, the drop is refused. + + +## Examples + +### Array based list box to input text area + + +In this simple example, we want to fill an input text area with data dragged from an array-based list box: + +![](../assets/en/Desktop/dragdrop3.png) + +The list box object method: + +```4d + //Object Method: ListBox + If(Form event code=On Begin Drag Over) + SET TEXT TO PASTEBOARD(arrFirstname{arrFirstname}+" "+arrLastname{arrFirstname}) + End if +``` + +The input text area object method contains: + +```4d + + // Object Method: label1 +If(Form event code=On Drop) //Requires Droppable Action enabled from Property List + ARRAY TEXT($signatures_at;0) + ARRAY TEXT($nativeTypes_at;0) + ARRAY TEXT($formatNames_at;0) + GET PASTEBOARD DATA TYPE($signatures_at;$nativeTypes_at;$formatNames_at) + If(Find in array($signatures_at;"com.4d.private.text.native")#-1) // there is 4D text in pasteboard + OBJECT Get pointer(Object current)->:=Get text from pasteboard + End if + End if +``` + + +### Selection based list box to input text area + +Combining custom and automatic drag and drop features allows simple and powerful interfaces. In this example, we want to fill an input text area with data dragged from a list box: + +![](../assets/en/Desktop/dragdrop4.png) + +- List box: "Custom" Draggable property and "On Begin Drag Over" event +- Input text area: "Automatic" Droppable property. + +```4d + //list box object method + Case of + :(Form event code=On Begin Drag Over) + LOAD RECORD([Clients]) + $label:=[Clients]Name+Char(CR ASCII code)+[Clients]Contact+Char(CR ASCII code)+\ + [Clients]Address1+Char(CR ASCII code)+[Clients]City+", "+[Clients]State+" "+[Clients]ZipCode) + SET TEXT TO PASTEBOARD($label) + End case +``` + + +Moving and formatting data is done through drag and drop: + +![](../assets/en/Desktop/dragdrop5.png) + + +### File path to text area + + +You want the user to select a file on the disk, then drag and drop it on an enterable variable (of type object) so that it displays a json description of the file. + +![](../assets/en/Desktop/dragdrop6.png) + +In the object method of the variable, you just write: + +```4d + #DECLARE -> $result : Integer + Case of + + :(Form event code=On Drag Over) + // Accept On Drop event only if the pasteboard contains files, reject otherwise. + If(Get file from pasteboard(1)="") //no file in pasteboard + $result:=-1 //reject drop + End if + + :(Form event code=On Drop) //Requires Droppable action enabled from Property List + var $path_t : Text + var path_o : Object + $path_t:=Get file from pasteboard(1) + If($path_t#"") + path_o:=Path to object($path_t) + End if + + End case +``` + + +### File paths to list box + +You want the user to select files on the disk, then drag and drop them on a list box so that it displays file paths. + +![](../assets/en/Desktop/dragdrop7.png) + + +In the list box object method, you just write: + +```4d + #DECLARE -> $result : Integer + Case of + + :(Form event code=On Drag Over) + // Accept On Drop event only if the pasteboard contains files, reject otherwise. + If(Get file from pasteboard(1)#"") //at least one file dropped + $result:=0 //accept drop + Else //no file in pasteboard + $result:=-1 //reject drop + End if + + :(Form event code=On Drop) //Requires Droppable action enabled from Property List + ARRAY TEXT(importedPath_at;0) + var $path_t :Text + var $index_l:=1 + Repeat + $path_t:=Get file from pasteboard($index_l) + If($path_t#"") + APPEND TO ARRAY(importedPath_at;$path_t) + End if + $index_l:=$index_l+1 + Until($path_t="") + End case +``` + + +## Pasteboard commands + +The [commands of the "Pasteboard" theme](../commands/theme/Pasteboard.md) can be used both for managing copy/paste actions (**Clipboard management**), as well as inter-application drag and drop actions. + +4D uses two data pasteboards: one for copied (or cut) data, which is the clipboard, and the other for data being dragged and dropped. +These two pasteboards are managed using the same commands. You access one or the other depending on the context: + +- The drag and drop pasteboard can only be accessed within the [`On Begin Drag Over`](../Events/onBeginDragOver.md), [`On Drag over`](../Events/onDragOver.md) or [`On Drop`](../Events/onDrop.md) form events and in the [**On Drop** database method](../commands-legacy/on-drop-database-method.md). Outside of these contexts, the drag and drop pasteboard is not available. +- The copy/paste pasteboard can be accessed in all other cases. Unlike the drag and drop pasteboard, it keeps the data that are placed in it during the entire session, so long as they are not cleared or reused. + +### Types of Data + +During drag and drop actions, different types of data can be placed on and read from the pasteboard. You can access a data type in several ways: + +- Via its 4D signature: The 4D signature is a character string indicating a data type referenced by the 4D application. The use of 4D signatures facilitates the development of multi-platform applications since these signatures are identical under Mac OS and Windows. You will find the list of 4D signatures below. +- Via a UTI (Uniform Type Identifier, macos only): The UTI standard, specified by Apple, associates a character string with each type of native object. For example, GIF pictures have the UTI type "com.apple.gif". UTI types are published in Apple documentations as well as by the editors concerned. +- Via its number or its format name (Windows only): Under Windows, each native data type is referenced by its number ("3", "12", and so on) and a name ("Rich Text Edit"). By default, Microsoft specifies several native types called standard data formats. In addition, third-party editors can "save" format names in the system, which then attributes them a number in return. For more information about this and about native types, please refer to the Microsoft developer documentation (more particularly at http://msdn2.microsoft.com/en-us/library/ms649013.aspx). + +:::note + +In 4D commands, the Windows format numbers are handled as text. + +::: + +All the [commands of the "Pasteboard" theme](../commands/theme/Pasteboard.md) can work with each one of these data types. You can find out which data types are present in the pasteboard in each of these formats using the [`GET PASTEBOARD DATA TYPE`](../commands/get-pasteboard-data-type) command. + +:::note + +4-character types (TEXT, PICT or custom types) are supported for compatibility with prior versions of 4D. + +::: + + +### 4D Signatures + +Here is the list of standard 4D signatures as well as their description: + +|Signature|Description| +|----|----| +|"com.4d.private.text.native"|Text in native character set| +|"com.4d.private.text.utf16"|Text in Unicode character set| +|"com.4d.private.text.rtf"|Enriched text| +|"com.4d.private.picture.pict"|PICT picture format| +|"com.4d.private.picture.png"|PNG picture format| +|"com.4d.private.picture.gif"|GIF picture format| +|"com.4d.private.picture.jfif"|JPEG picture format| +|"com.4d.private.picture.emf"|EMF picture format| +|"com.4d.private.picture.bitmap"|BITMAP picture format| +|"com.4d.private.picture.tiff"|TIFF picture format| +|"com.4d.private.picture.pdf"|PDF document| +|"com.4d.private.file.url"|File pathname| \ No newline at end of file diff --git a/docs/Develop-legacy/legacy-to-import.md b/docs/Develop-legacy/legacy-to-import.md new file mode 100644 index 00000000000000..89f9256f4f8c49 --- /dev/null +++ b/docs/Develop-legacy/legacy-to-import.md @@ -0,0 +1,91 @@ +--- +id: legacy-to-import +title: develop-legacy +draft: true +--- + + + + +## Semaphores + +Semaphores allow you to make sure that two or more processes do not modify the same resource (file, record...) at the same time. Only the process that sets the semaphore can remove it. + +:::info + +[Signals](../API/SignalClass.md) can also be used to manage interactions. Signals allow you to make sure one or more process(es) will wait for a specific task to be completed before continuing execution. Any process can wait and/or release a signal. + +::: + +### What is a semaphore? + +In a computer program, a semaphore is a tool used to protect actions that need to be performed by only one process or user at a time. + +In 4D, the conventional need for using semaphores is for modifying an interprocess array: if one process is modifying the values of the array, another process must not be able to do the same thing at the same time. The developer uses a semaphore to indicate to a process that it can only perform its sequence of operations if no other process is already performing the same tasks. When a process encounters a semaphore, there are three possibilities: + +- It immediately gets the right to pass +- It waits for its turn until it gets the right to pass +- It continues on its way, abandoning the idea of performing the tasks. + +The semaphore therefore protects parts of the code. It allows only one process through at a time and blocks access until the process currently holding the right of use relinquishes this right by releasing the semaphore. + +### Commands for working with semaphores + +In 4D, you set a semaphore by calling the [`Semaphore`](../commands/sempahore) command. To release a semaphore, you call the [`CLEAR SEMAPHORE`](../commands/clear-sempahore) command. + +The [`Semaphore`](../commands/sempahore) command has a very special behavior since it potentially performs two actions simultaneously: + +- If the semaphore is already assigned, the function returns **True** +- If the semaphore is not assigned, the function assigns it to the process and returns **False** at the same time. + +This double action performed by the same command ensures that no external operation can be inserted between the semaphore test and its assignment. + +You can use the [`Test semaphore`](../commands/test-semaphore) command to find out whether a semaphore is already assigned or not. This command is mainly used as part of long operations, such as the annual closing of accounts, where [`Test semaphore`](../commands/test-semaphore) lets you control the interface to prevent access to certain operations such as the addition of accounting data. + +### How to use semaphores + +Semaphores should be used according to the following principles: + +- A semaphore must be set and released in the same method, +- The execution of code protected by the semaphore must be as short as possible, +- The code must be timed by means of the tickCount parameter of the [`Semaphore`](../commands/sempahore) command to wait for the release of the semaphore. + +Here is typical code for using a semaphore: + +```4d + While(Semaphore("MySemaphore";300)) + IDLE + End while + // place code protected by semaphore here + CLEAR SEMAPHORE("MySemaphore") +``` + +A semaphore that is not released can block part of the database. Setting and releasing semaphores in the same method helps to eliminate this risk. + +Minimizing the code protected by the semaphore increases the fluidity of the application and avoids the semaphore acting as a bottleneck. + +Finally, using the optional *tickCount* parameter of the [`Semaphore`](../commands/sempahore) command is essential for optimizing the wait for the semaphore to be released. Using this parameter, the commands works as follows: + +- The process waits a maximum of the specified number of ticks (300 in the example) for the semaphore to be available, without the code execution moving on to the next line, +- If the semaphore is released before the end of this limit, it is immediately assigned to the process (Semaphore returns False) and code execution resumes, +- If the semaphore is not released before the end of this limit, then code execution resumes. + +The command also prioritizes requests by establishing a queue. This way, the first process requesting a semaphore will be the first to get one. Note that the wait time is set depending on the specifics of the application. + +### Local or global semaphores + +There are two types of semaphores in 4D: local semaphores and global semaphores. + +- A local semaphore is accessible by all processes on the same workstation and only on the workstation. A local semaphore can be created by prefixing the name of the semaphore with a dollar sign ($). You use local semaphores to monitor operations among processes executing on the same workstation. For example, a local semaphore can be used to monitor access to an interprocess array shared by all the processes in your single-user database or on the workstation. +- A global semaphore is accessible to all users and all their processes. You use global semaphores to monitor operations among users of a multi-user database. + +Global and local semaphores are identical in their logic. The difference resides in their scope. + +In client/server, global semaphores are shared among all the processes running on all clients and servers. A local semaphore is only shared among the processes running on the machine where it has been created. + +In single-user 4D applications, global or local semaphores have the same scope because you are the only user. However, if your database is being used in both setups, make sure to use global or local semaphores depending on what you want to do. + +**Note:** We recommend using local semaphores when you need a semaphore to manage a local aspect for a client of the application, such as the interface or an array of interprocess variables. If you use a global semaphores in this case, it would not only cause unnecessary network exchanges but could also affect other client machines unnecessarily. Using a local semaphore would avoid these undesirable side effects. + + + \ No newline at end of file diff --git a/docs/Develop-legacy/named-selections.md b/docs/Develop-legacy/named-selections.md new file mode 100644 index 00000000000000..ebe8817eccdbd2 --- /dev/null +++ b/docs/Develop-legacy/named-selections.md @@ -0,0 +1,75 @@ +--- +id: named-selections +title: Named Selections +slug: /Develop/named-selections +displayed_sidebar: docs +--- + + +## Overview + +Named selections provide an easy way to manipulate several selections simultaneously. A named selection is an ordered list of records for a table in a process. This ordered list can be given a name and kept in memory. Named selections offer a simple means to preserve in memory the order of the selection and the current record of the selection. + +The following commands enable you to work with named selections: + +- [`COPY NAMED SELECTION`](../commands/copy-named-selection) +- [`CUT NAMED SELECTION`](../commands/cut-named-selection) +- [`USE NAMED SELECTION`](../commands/use-named-selection) +- [`CLEAR NAMED SELECTION`](../commands/clear-named-selection) +- [`CREATE SELECTION FROM ARRAY`](../commands/create-selection-from-array) + + +Named selections are created with the [`COPY NAMED SELECTION`](../commands/copy-named-selection), [`CUT NAMED SELECTION`](../commands/cut-named-selection) and [`CREATE SELECTION FROM ARRAY`](../commands/create-selection-from-array). Named selections are generally used to work on one or more selections and to save and later restore an ordered selection. There can be many named selections for each table in a process. To reuse a named selection as the current selection, call [`USE NAMED SELECTION`](../commands/use-named-selection). When you are done with a named selection, use [`CLEAR NAMED SELECTION`](../commands/clear-named-selection). + +:::note + +Combining the statement `SET QUERY DESTINATION(Into named selection;namedselection)` with a search command (for example [`QUERY`](../commands/query)) can also be used to create a named selection. Refer to the description of the [`SET QUERY DESTINATION`](../commands/set-query-destination) command. + +::: + +Named selections can be local, process or interprocess in scope. + +A named selection is local when its name is preceded by a dollar sign. When its name is not preceded by any symbol, it is a process named selection and it is an interprocess named selection if its name is preceded by the symbols (<>) — a “less than” sign followed by a “greater than” sign. + +The scope of an interprocess named selection is identical to the scope of an interprocess variable (*deprecated*). An interprocess named selection can be accessed from any process. With 4D in remote mode and 4D Server, an interprocess named selection is available only to the processes of the client that created it. An interprocess named selection is not available to other client machines. +A process named selection is available only within the process in which it was created and on the server. +A local named selection is defined for the process that created it and is not visible on the server. + +:::note + +Creating a named selection requires access to the selection of the table. Since selections are kept on the server and a local process does not have access to server data, do not use named selections within local processes. + +::: + +## Visibility of Named Selections + +The following table indicates the principles concerning the visibility of named selections depending on their scope and where they were created: + + +||Client Process|Other processes on the same client|Other clients |Server process|Other processes on the server| +|---|---|---|---|---|---| +|Creation in a client process |||||| +|$test|X||||| +|test |X|||X(Trigger) || +|<>test| X| X |||| +|Creation in a server process |||||| +|$test||||X|| +|test|||| X || +|<>test |||| X|X| + + +## Named Selections and Sets + +The differences between [sets](./sets.md) and named selections are: + +- A named selection is an ordered list of records; a set is not. +- Sets are very memory efficient, because they require only one bit for each record in the file. Named selections require 4 bytes for each record in the selection. +- Unlike sets, named selections cannot be saved to disk. +- Sets have the standard [`INTERSECTION`](../commands/intersection), [`UNION`](../commands/union) and [`DIFFERENCE`](../commands/difference) operations; named selections cannot be combined with other named selections. + + +The similarities between named selections and sets are: + +- Like a set, a named selection exists in memory. +- A named selection and a set store references to a record. If records are modified or deleted, the named selection or the set can become invalid. +- Like a set, a named selection “remembers” the current record as of the time the named selection was created. \ No newline at end of file diff --git a/docs/Develop-legacy/records.md b/docs/Develop-legacy/records.md new file mode 100644 index 00000000000000..b854cb6dcac864 --- /dev/null +++ b/docs/Develop-legacy/records.md @@ -0,0 +1,370 @@ +--- +id: records +title: Records +slug: /Develop/records +displayed_sidebar: docs +--- + + +## Record numbers + +There are three numbers associated with a record: + +- Record number +- Selected record number +- Sequence number + +### Record Number + +The record number is the absolute/physical record number for a record. A record number is automatically assigned to each new record and remains constant for the record until the record is deleted. Record numbers start at zero. They are not unique because record numbers of deleted records are reused for new records. They also change when the database is [compacted](../MSC/compact.md) or [repaired](../MSC/repair.md). + +### Selected Record Number + +The selected record number is the position of the record in the current selection, and so depends on the current selection. If the selection is changed or sorted, the selected record number will probably change. Numbering for the selected record number starts at one (1). + +### Sequence Number + +The sequence number is a unique non-repeating number that may be assigned to a field of a record (via the Autoincrement property, the SQL AUTO_INCREMENT attribute or the [`Sequence number`](../commands/sequence-number) command). It is not automatically stored with each record. It starts by default at 1 and is incremented for each new record that is created. Unlike record numbers, a sequence number is not reused when a record is deleted or when a database is compacted or repaired. Sequence numbers provide a way to have unique ID numbers for records. If a sequence number is incremented during a transaction, the number is not decremented if the transaction is canceled. + +:::note Notes + +- 4D does not carry out any check when you modify the automatic number internal counter of a table using the [`SET DATABASE PARAMETER`](../commands/set-database-parameter) command. If you decrement this counter, the new records created may have numbers that have already been assigned. +- Sequence numbers are not recommended to fill unique ID primary key fields for records. To create unique record IDs, it is strongly recommended to use UUIDs. + +::: + +### Example + +The following tables illustrate the numbers that are associated with records. Each line in the table represents information about a record. The order of the lines is the order in which records would be displayed in an output form. + +- **Data**: The data from a field in each record. For our example, it contains a person’s name. +- **Record Number**: The record’s absolute record number. This is the number returned by the [`Record number`](../commands/record-number) command. +- **Selected Record Number**: The record’s position in the current selection. This is the number returned by the [`Selected record number`](../commands/selected-record-number) command. +- **Sequence Number**: The record’s unique sequence number. This is the number returned by the [`Sequence number`](../commands/sequence-number) command when the record was created. This number is stored in a field. + +#### After the Records Are Entered + +The first table shows the records after they are entered. + +- The default order for the records is by record number. +- The record number starts at 0. +- The selected record number and the sequence number start at 1. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Tess |0| 1| 1| +|Terri| 1 |2 |2| +|Sabra| 2|3| 3| +|Sam| 3 |4 |4| +|Lisa| 4| 5 |5| + +Note: The records remain in the default order after a command changes the current selection without reordering it; for example, after the **Show All** menu command is chosen in the Design environment, or after the [`ALL RECORDS`](../commands/all-records) command is executed. + +#### After the Records Are Sorted + +The next table shows the same records sorted by name. + +- The same record number remains associated with each record. +- The selected record numbers reflect the new position of the records in the sorted selection. +- The sequence numbers never change, since they were assigned when each record was created and are stored in the record. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Lisa| 4| 1 |5| +|Sabra| 2|2| 3| +|Sam| 3 |3 |4| +|Terri| 1 |4 |2| +|Tess |0| 5| 1| + + +#### After a Record Is Deleted + +The following table shows the records after Sam is deleted. + +- Only the selected record numbers have changed. Selected record numbers reflect the order in which the records are displayed. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Lisa| 4| 1 |5| +|Sabra| 2|2| 3| +|Terri| 1 |3 |2| +|Tess |0| 4| 1| + + +#### After a Record Is Added + +The next table shows the records after a new record has been added for Liz. + +- A new record is added to the end of the current selection. +- Sam’s record number is reused for the new record. +- The sequence number continues to increment. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Tess |0| 1| 1| +|Terri| 1 |2 |2| +|Sabra| 2|3| 3| +|Lisa| 4| 4 |5| +|Liz |3| 5| 6| + +#### After the Selection is Changed and Sorted + +The following table shows the records after the selection was reduced to three records and then sorted. + +- Only the selected record number associated with each record changes. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Sabra| 2|1| 3| +|Liz |3| 2| 6| +|Terri| 1 |3 |2| + +## Record Stack + +The [`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) commands allow you to put (“push”) records onto the record stack, and to remove (“pop”) them from the stack. + +Each process has its own record stack for each table. 4D maintains the record stacks for you. Each record stack is a last-in-first-out (LIFO) stack. Stack capacity is limited by memory. + +[`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) should be used with discretion. Each record that is pushed uses part of free memory. Pushing too many records can cause an out-of-memory or stack full condition. + +4D clears the stack of any unpopped records when you return to the menu at the end of execution of your method. + +[`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) are useful when you want to examine records in the same file during data entry. To do this, you push the record, search and examine records in the file (copy fields into variables, for example), and finally pop the record to restore the record. + +While entering a record, if you have to check a multiple field unique value, use the [`SET QUERY DESTINATION`](../commands/set-quer-destination) command. This will save you the calls to [`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) that you were making before and after the call to QUERY in order to preserve the data entered in the current record. [`SET QUERY DESTINATION`](../commands/set-quer-destination) allows you to make a query that does not change the selection nor the current record. + +## Record locking + +4D and 4D Server automatically manage databases by preventing multi-user or multi-process conflicts. Two users or two processes cannot modify the same record or object at the same time. However, the second user or process can have read-only access to the record or object at the same time. + +There are several reasons for using the multi-user commands: + +- Modifying records by using the language. +- Using a custom user interface for multi-user operations. +- Saving related modifications inside a transaction. + +There are three important concepts to be aware of when using commands in a multi-processing database: + +1. In a process, each table is in either a read-only or a read/write state. +2. Records become locked when they are loaded and unlocked when they are unloaded. +3. A locked record cannot be modified. + +As a convention in the following sections, the person performing an operation on the multi-user database is referred to as the **local user**. Other people using the database are referred to as the **other users**. The discussion is from the perspective of the local user. Also, from a multi-process perspective, the process executing an operation on the database is the **current process**. Any other executing process is referred to as **other processes**. The discussion is from the point of view of the current process. + +### Locked Records + +A locked record cannot be modified by the local user or the current process. A locked record can be loaded, but cannot be modified. A record is locked when one of the other users or processes has successfully loaded the record for modification, or when the record is stacked. Only the user who is modifying the record sees that record as unlocked. All other users and processes see the record as locked, and therefore unavailable for modification. A table must be in a read/write state for a record to be loaded unlocked. + +### Read-Only and Read/Write States + +Each table in a database is in either a read/write or a read-only state for each user and process of the database. **Read-only** means that records for the table can be loaded but not modified. **Read/write** means that records for the table can be loaded and modified if no other user has locked the record first. + +Note that if you change the status of a table, the change takes effect for the next record loaded. If there is a record currently loaded when you change the table’s status, that record is not affected by the status change. + +#### Read-Only State + +When a table is read-only and a record is loaded, this record is always locked. In other words, locked records can be displayed, printed, and otherwise used, but they cannot be modified. + +Note that the read-only state applies only to editing existing records. A read-only state does not affect the creation of new records. You can still add records to a read-only table using [`CREATE RECORD`](../commands/create-record) and [`ADD RECORD`](../commands/add-record), or the menu commands of the Design environment (in this case, the records being created are locked for all other users/processes). Note that the [`ARRAY TO SELECTION`](../commands/array-to-selection) command is not affected by the read-only state since it can both create and modify records. + +4D automatically sets a table to read-only for commands that do not require write access to records. These commands are: [`DISPLAY SELECTION`](../commands/display-selection), [`DISTINCT VALUES`](../commands/distinct-values), [`EXPORT DIF`](../commands/export-dif), [`EXPORT SYLK`](../commands/export-sylk), [`EXPORT TEXT`](../commands/export-text), [`PRINT SELECTION`](../commands/print-selection), [`PRINT LABEL`](../commands/print-label), [`QR REPORT`](../commands/qr-report), [`SELECTION TO ARRAY`](../commands/selection-to-array), [`SELECTION RANGE TO ARRAY`](../commands/selection-range-to-array). + +You can find out the state of a table at any time using the [`Read only state`](../commands/read-only-state) function. + +Before executing any of these commands, 4D saves the current state of the table (read-only or read/write) for the current process. After the command has executed, this state is restored. + +#### Read/Write State + +When a table is read/write and a record is loaded, the record will become unlocked if no other user has locked the record first. If the record is locked by another user, the record is loaded as a locked record that cannot be modified by the local user. + +A table must be set to read/write and the record loaded for it to become unlocked and thus modifiable. + +If a user loads a record from a table in read/write mode, no other users can load that record for modification. However, other users can add records to the table, either through the [`CREATE RECORD`](../commands/create-record) and [`ADD RECORD`](../commands/add-record) commands or manually in the Design environment. + +Read/write is the default state for all tables when a database is opened and a new process is started. + +#### Changing the Status of a Table + +You can use the [`READ ONLY`](../commands/read-only) and [`READ WRITE`](../commands/read-write) commands to change the state of a table. If you want to change the state of a table in order to make a record read-only or read/write, you must execute the command before this record is loaded. Any record that is already loaded is not affected by the [`READ ONLY`](../commands/read-only) and [`READ WRITE`](../commands/read-write) commands. + +Each process has its own state (read-only or read/write) for each table in the database. + +By default, if you do not use the READ ONLY command, all tables are in read/write mode. + +### Loading, Modifying and Unloading Records + +Before the local user can modify a record, the table must be in the read/write state and the record must be loaded and unlocked. + +Any of the commands that loads a current record (if there is one) — such as [`NEXT RECORD`](../commands/next-record), [`QUERY`](../commands/query), [`ORDER BY`](../commands/order-by), [`RELATE ONE`](../commands/relate-one), etc. — sets the record state as locked or unlocked. The record is loaded according to the current state of its table (read-only or read/write) and its availability. A record may also be loaded for a related table by any of the commands that cause an automatic relation to be established. + +If a table is in the read-only state for a process or a user, then this table's records are loaded in read-only mode, which means they cannot be modified or deleted by this process or user. This is recommended for viewing or retrieving data because it does not prevent other users or processes from accessing the records of this table in read/write mode if necessary. + +If a table is in the read/write state for a process or a user, then any record from this table is also loaded in read/write mode, but only if no other user or process has already locked this record. If a record is successfully loaded in read/write mode, it is unlocked for the current process or user (it can be modified and saved) and is locked for all other users or processes. A table must be put into the read/write state before loading a record for modification and then saving it. + +If the record is to be modified, you use the Locked function to test whether or not a record is locked by another user. If a record is locked (Locked returns True), load the record with the [`LOAD RECORD`](../commands/load-record) command and again test whether or not the record is locked. This sequence must be continued until the record becomes unlocked (Locked returns False). + +When modifications to be made to a record are finished, the record must be released (and therefore unlocked for the other users) with [`UNLOAD RECORD`](../commands/unload-record). If a record is not unloaded, it will remain locked for all other users until a different current record is selected. Changing the current record of a table automatically unlocks the previous current record. You need to explicitly call [`UNLOAD RECORD`](../commands/unload-record) if you do not change the current record. This discussion applies to existing records. When a new record is created, it can be saved regardless of the state of the table to which it belongs. + +:::note + +When it is used in a transaction, the [`UNLOAD RECORD`](../commands/unload-record) command unloads the current record only for the process that manages the transaction. For other processes, the record stays locked as long as the transaction has not been validated (or cancelled). + +::: + +Use the [`LOCKED BY`](../commands/locked-by) command to see which user and/or process have locked a record. + +::: + +A good practice is to place all tables in read-only mode when each process is started (using the syntax [`READ ONLY(*)`](../commands/read-only)) then put each table in read/write mode only when necessary. Access to tables in read-only mode is faster and more memory-efficient. Moreover, changing the state of a table is optimized in client/server mode because it does not cause any additional network traffic: information is only sent to the server when executing a command that requires adequate access to the table. + +::: + +### Loops to Load Unlocked Records + +The following example shows the simplest loop with which to load an unlocked record: + +```4d + READ WRITE([Customers])//Set the table’s state to read/write + Repeat//Loop until the record is unlocked + LOAD RECORD([Customers])//Load record and set locked status + Until(Not(Locked([Customers]))) + //Do something to the record here + READ ONLY([Customers])//Set the table’s state to read-only +``` + +The loop continues until the record is unlocked. + +A loop like this is used only if the record is unlikely to be locked by anyone else, since the user would have to wait for the loop to terminate. Thus, it is unlikely that the loop would be used as is unless the record could only be modified by means of a method. + +The following example uses the previous loop to load an unlocked record and modify the record: + +```4d + READ WRITE([Inventory]) + Repeat //Loop until the record is unlocked + LOAD RECORD([Inventory]) //Load record and set it to locked + Until(Not(Locked([Inventory]))) + [Inventory]Part Qty:=[Inventory]Part Qty 1 //Modify the record + SAVE RECORD([Inventory]) //Save the record + UNLOAD RECORD([Inventory]) //Let other users modfiy it + READ ONLY([Inventory]) +``` + + +The [`MODIFY RECORD`](../commands/modify-record) command automatically notifies the user if a record is locked, and prevents the record from being modified. The following example avoids this automatic notification by first testing the record with the Locked function. If the record is locked, the user can cancel. + +This example efficiently checks to see if the current record is locked for the table [Commands]. If it is locked, the process is delayed by the procedure for one second. This technique can be used both in a multi-user or multi-process situation: + +```4d + Repeat + READ ONLY([Commands])//You do not need read/write right now + QUERY([Commands]) + //If the search was completed and some records were returned + If((OK=1) & (Records in selection([Commands])>0)) + READ WRITE([Commands])//Set the table to read/write state + LOAD RECORD([Commands]) + While(Locked([Commands]) & (OK=1)) `If the record is locked, + //loop until the record is unlocked + //Who is the record locked by? + LOCKED BY([Commands];$Process;$User;$SessionUser;$Name) + If($Process=-1)//Has the record been deleted? + ALERT("The record has been deleted in the meantime.") + OK:=0 + Else + If($User="")//Are you in single-user mode + $User:="you" + End if + CONFIRM("The record is already used by "+$User+" in the "+$Name+" Process.") + If(OK=1)//If you want to wait for a few seconds + DELAY PROCESS(Current process;120)//Wait for a few seconds + LOAD RECORD([Commands])//Try to load the record + End if + End if + End while + If(OK=1)//The record is unlocked + MODIFY RECORD([Commands])//You can modify the record + UNLOAD RECORD([Commands]) + End if + READ ONLY([Commands])//Switch back to read-only + OK:=1 + End if + Until(OK=0) +``` + + +### Using Commands in Multi-user or Multi-process Environment + +A number of commands in the language perform specific actions when they encounter a locked record. They behave normally if they do not encounter a locked record. + +Here is a list of these commands and their actions when a locked record is encountered. + +- [`MODIFY RECORD`](../commands/modify-record): Displays a dialog box stating that the record is in use. The record is not displayed, therefore the user cannot modify the record. In the Design environment, the record is shown in read-only state. +- [`MODIFY SELECTION`](../commands/modify-selection): Behaves normally except when the user double-clicks a record to modify it. [`MODIFY SELECTION`](../commands/modify-selection) displays dialog box stating that the record is in use and then allows read-only access to the record. +- [`APPLY TO SELECTION`](../commands/apply-to-selection): Loads a locked record, but does not modify it. [`APPLY TO SELECTION`](../commands/apply-to-selection) can be used to read information from the table without special care. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`DELETE SELECTION`](../commands/delete-selection): Does not delete any locked records; it skips them. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`DELETE RECORD`](../commands/delete-record): This command is ignored if the record is locked. No error is returned. You must test that the record is unlocked before executing this command. +- [`SAVE RECORD`](../commands/save-record): This command is ignored if the record is locked. No error is returned. You must test that the record is unlocked before executing this command. +- [`ARRAY TO SELECTION`](../commands/array-to-selection): Does not save any locked records. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`GOTO RECORD`](../commands/goto-record): Records in a multi-user/multi-process database may be deleted and added by other users, therefore the record numbers may change. Use caution when directly referencing a record by number in a multi-user database. +- [**Sets**](./sets.md): Take special care with sets, as the information that the set was based on may be changed by another user or process. + + +## Records and Relations + +Commands in the [Relations theme](../commands/theme/Relations.md), in particular [`RELATE ONE`](../commands/relate-one) and [`RELATE MANY`](../commands/relate-many), establish and manage the automatic and non-automatic relations between tables. Before using any of the commands in this theme, refer to the 4D Design Reference manual for information about creating relations between tables. + +### Using Automatic Table Relations with Commands + +Two tables can be related with automatic table relations. In general, when an automatic table relation is established, it loads or selects the related records in a related table. Many operations cause the relation to be established. + +These operations include: + +- Data entry +- Listing records on the screen in output forms +- Reporting +- Operations on a selection of records, such as queries, sorts, and applying a formula + +To optimize performance, when 4D establishes automatic relations, only one record becomes the current record for a table. For each of the operations listed above, the related record is loaded according to the following principles: + +- If a relation selects only one record of a related table, that record is loaded from disk. +- If a relation selects more than one record of a related table, a new selection of records is created for that table, and the first record in that selection is loaded from disk. + +For example, using the database structure displayed here, if a record for the [Employees] table is loaded and displayed for data entry, the related record from the [Companies] table is selected and is loaded. Similarly, if a record for the [Companies] table is loaded and displayed for data entry, the related records from the [Employees] table are selected. + +![](../assets/en/Develop/relations.png) + + +In this database structure, the [Employees] table is referred to as the **Many table**, and the [Companies] table is referred to as the **One table**. To remember this concept, think of "there are many employees related to one company" and "each company has many employees". + +Similarly, the Company field in the [Employees] table is referred to as the **Many field**, and the Name field in the [Companies] table is referred to as the **One** field. It is not always possible to have the related field be unique. For example, the [Companies]Name field may have several company records containing the same value. This non-unique situation can be easily handled by creating a relation, which will always be unique, on another field in the related table. This field could be a company ID field. + +The following table lists commands that use automatic relations to load related records during operation of the command. All of the commands will use existing automatic Many-to-One relations. Only those commands with Yes in the One-to-Many established column below will use automatic One-to-Many relations. + +|Command|One-to-Many established| +|--|--| +|[`ADD RECORD`](../commands/add-record) |Yes| +|[`APPLY TO SELECTION`](../commands/apply-to-selection)| No| +|[`DISPLAY SELECTION`](../commands/display-selection)| No| +|[`EXPORT DIF`](../commands/export-dif)| No| +|[`EXPORT SYLK`](../commands/export-sylk)| No| +|[`EXPORT TEXT`](../commands/export-text)| No| +|[`EXPORT DATA`](../commands/export-data)| No| +|[`MODIFY RECORD`](../commands/modify-record)| Yes| +|[`MODIFY SELECTION`](../commands/modify-selection)| Yes (in data entry)| +|[`ORDER BY`](../commands/order-by)| No| +|[`ORDER BY FORMULA`](../commands/order-by-formula)| No| +|[`QUERY BY FORMULA`](../commands/query-by-formula)| Yes| +|[`QUERY SELECTION`](../commands/query-selection)| Yes| +|[`QUERY`](../commands/query)| Yes| +|[`PRINT LABEL`](../commands/print-label)| No| +|[`PRINT SELECTION`](../commands/print-selection)| Yes| +|[`QR REPORT`](../commands/qr-report)| No| +|[`SELECTION TO ARRAY`](../commands/selection-to-array)| No| +|[`SELECTION RANGE TO ARRAY`](../commands/selection-range-to-array)| No| + + +### Using Commands to Establish Table Relations + +Automatic relations do not mean that the related record or records for a table will be selected simply because a command loads a record. In some cases, after using a command that loads a record, you must explicitly select the related records by using [`RELATE ONE`](../commands/relate-one) or [`RELATE MANY`](../commands/relate-many) if you need to access the related data. + +Some of the commands listed in the previous table (such as the query commands) load a current record after the task is completed. In this case, the record that is loaded does not automatically select the records related to it. Again, if you need to access the related data, you must explicitly select the related records by using [`RELATE ONE`](../commands/relate-one) or [`RELATE MANY`](../commands/relate-many). + diff --git a/docs/Develop-legacy/sets.md b/docs/Develop-legacy/sets.md new file mode 100644 index 00000000000000..f1e42b3cc1c863 --- /dev/null +++ b/docs/Develop-legacy/sets.md @@ -0,0 +1,168 @@ +--- +id: sets +title: Sets +slug: /Develop/sets +displayed_sidebar: docs +--- + + +Sets offer you a powerful, swift means for manipulating record selections. Besides the ability to create sets, relate them to the current selection, and store, load, and clear sets, 4D offers three standard set operations: + +- Intersection +- Union +- Difference. + + +## Sets and the Current Selection + +A set is a compact representation of a selection of records. The idea of sets is closely bound to the idea of the current selection. Sets are generally used for the following purposes: + +- To save and later restore a selection when the order does not matter +- To access the selection a user made on screen (the `UserSet`) +- To perform a logical operation between selections. + +The current selection is a list of references that points to each record that is currently selected. The list exists in memory. Only currently selected records are in the list. A selection doesn’t actually contain the records, but only a list of references to the records. Each reference to a record takes 4 bytes in memory. When you work on a table, you always work with the records in the current selection. When a selection is sorted, only the list of references is rearranged. There is only one current selection for each table inside a process. + +Like a current selection, a set represents a selection of records. A set does this by using a very compact representation for each record. Each record is represented by one bit (one-eighth of a byte). Operations using sets are very fast, because computers can perform operations on bits very quickly. A set contains one bit for every record in the table, whether or not the record is included in the set. In fact, each bit is equal to 1 or 0, depending on whether or not the record is in the set. + +Sets are very economical in terms of RAM space. The size of a set, in bytes, is always equal to the total number of records in the table divided by 8. For example, if you create a set for a table containing 10,000 records, the set takes up 1,250 bytes, which is about 1.2K in RAM. + +There can be many sets for each table. In fact, sets can be saved to disk separately from the database. To change a record belonging to a set, first you must use the set as the current selection, then modify the record or records. + +A set is never in a sorted order—the records are simply indicated as belonging to the set or not. On the other hand, a named selection is in sorted order, but it requires more memory in most cases. For more information about named selections, see the Named Selections section. + +A set "remembers" which record was the current record at the time the set was created. The following table compares the concepts of the current selection and of sets: + +|Comparison|Current Selection|Sets| +|---|---|---| +|Number per table|1|0 to many| +|Sortable|Yes|No| +|Can be saved on disk|No|Yes| +|RAM per record(in bytes)|Number of selected records * 4|Total number of records/8| +|Combinable| No| Yes| +|Contains current record| Yes| Yes, as of the time the set was created| + +When you create a set, it belongs to the table from which you created it. Set operations can be performed only between sets belonging to the same table. + +Sets are independent from the data. This means that after changes are made to a file, a set may no longer be accurate. There are many operations that can cause a set to be inaccurate. For example, if you create a set of all the people from New York City, and then change the data in one of those records to “Boston” the set would not change, because the set is just a representation of a selection of records. Deleting records and replacing them with new ones also changes a set, as well as compacting the data. Sets can be guaranteed to be accurate only as long as the data in the original selection has not been changed. + +## Process and Interprocess Sets + +You can have the following three types of sets: + +- **Process sets**: A process set can only be accessed by the process in which it has been created. `LockedSet` is a process set. Process sets are cleared as soon as the process method ends. Process sets do not need any special prefix in the name. +- **Interprocess sets**: A set is an interprocess set if the name of the set is preceded by the symbols (<>) — a “less than” sign followed by a “greater than” sign. An interprocess set is “visible” to all the processes of the database. +In client/server mode, an interprocess set is “visible” to processes of the machine where it was created (client or server). +The name of an interprocess set must be unique in the database. +- **Local Sets/Client Sets**: Local/client sets are intended for use in client/server mode. The name of a local/client set is always preceded by the dollar sign ($) -- except for the UserSet system set. Unlike other types of sets, a local/client set is stored on the client machine. + +:::note Notes + +- The maximum size of a set name is 255 characters (excluding <> and $ symbols). +- For more information about the use of sets in client/server mode, please refer to 4D Server, Sets and Named Selections. + +::: + + +## Visibility of Sets + +The following table indicates the principles concerning the visibility of sets depending on their scope and where they were created: + + + +||Client Process|Other processes on the same client|Other clients|Server process|Other processes on the server| +|---|---|---|---|---|---| +|Creation in a client process |||||| +|$test|X ||||| +|test | X||| X(Trigger) || +|<>test | X|X |||| +|Creation in a server process|||||| +|$test|||| X|| +|test ||||X|| +|<>test||||X| X| + + +## Sets and Transactions + +A set can be created inside a [transaction](./transactions.md). It is possible to create a set of the records created inside a transaction and a set of records created or modified outside of a transaction. When the transaction ends, the set created during the transaction should be cleared, because it may not be an accurate representation of the records, especially if the transaction was canceled. + +## Example + +The following example deletes duplicate records from a table which contains information about people. A For...End for loop moves through all the records, comparing the current record to the previous record. If the name, address, and zip code are the same, then the record is added to a set. At the end of the loop, the set is made the current selection and the (old) current selection is deleted: + +```4d + CREATE EMPTY SET([People];"Duplicates") + // Create an empty set for duplicate records + ALL RECORDS([People]) + // Select all records + // Sort the records by ZIP, address, and name so + // that the duplicates will be next to each other + ORDER BY([People];[People]ZIP;>;[People]Address;>;[People]Name;>) + // Initialize variables that hold the fields from the previous record + $Name:=[People]Name + $Address:=[People]Address + $ZIP:=[People]ZIP + // Go to second record to compare with first + NEXT RECORD([People]) + For($i;2;Records in table([People])) + // Loop through records starting at 2 + // If the name, address, and ZIP are the same as the + // previous record then it is a duplicate record. + If(([People]Name=$Name) & ([People]Address=$Address) & ([People]ZIP=$ZIP)) + // Add current record (the duplicate) to set + ADD TO SET([People];"Duplicates") + Else + // Save this record’s name, address, and ZIP for comparison with the next record + $Name:=[People]Name + $Address:=[People]Address + $ZIP:=[People]ZIP + End if + // Move to the next record + NEXT RECORD([People]) + End for + // Use duplicate records that were found + USE SET("Duplicates") + // Delete the duplicate records + DELETE SELECTION([People]) + // Remove the set from memory + CLEAR SET("Duplicates") +``` + +As an alternative to immediately deleting records at the end of the method, you could display them on screen or print them, so that a more detailed comparison can be made. + + +## The UserSet System Set + +4D maintains a system set named `UserSet`, which automatically stores the most recent selection of records highlighted on screen by the user. Thus, you can display a group of records with [`MODIFY SELECTION`](../commands/modify-selection) or [`DISPLAY SELECTION`](../commands/display-selection), ask the user to select from among them and turn the results of that manual selection into a selection or into a set that you name. + +::info 4D Server + +Although its name does not begin with the character "$", the `UserSet` system set is a client set. So, when using [`INTERSECTION`](../commands/intersection), [`UNION`](../commands/union) and [`DIFFERENCE`](../commands/difference), make sure you compare `UserSet` only to client sets. + +::: + +There is only one `UserSet` for a [process](../Develop/processes.md). Each table does not have its own `UserSet`. `UserSet` becomes "owned" by a table when a selection of records is displayed for the table. + +4D manages the `UserSet` set for list forms displayed in Design mode or using the [`MODIFY SELECTION`](../commands/modify-selection) or [`DISPLAY SELECTION`](../commands/display-selection) commands. However, this mechanism is not active for [subforms](../FormObjects/subform_overview.md). + +The following method illustrates how you can display records, allow the user to select some of them, and then use UserSet to display the selected records: + +```4d + // Display all records and allow user to select any number of them. + // Then display this selection by using UserSet to change the current selection. + FORM SET OUTPUT([People];"Display") // Set the output layout + ALL RECORDS([People]) // Select all people + ALERT("Press Ctrl or Command and Click to select the people required.") + DISPLAY SELECTION([People]) // Display the people + USE SET("UserSet") // Use the people that were selected + ALERT("You chose the following people.") + DISPLAY SELECTION([People]) // Display the selected people +``` + +## The LockedSet System Set + +The [`APPLY TO SELECTION`](../commands/apply-to-selection), [`DELETE SELECTION`](../commands/delete-selection), [`ARRAY TO SELECTION`](../commands/array-to-selection) and [`JSON TO SELECTION`](../commands/json-to-selection) commands create a set named `LockedSet` when used in a multi-processing environment. + +Query commands also create a `LockedSet` system set when they find locked records in the 'query and lock' context (see the [`SET QUERY AND LOCK`](../commands/set-query-and-lock) command). + +`LockedSet` indicates which records were locked during the execution of the command. \ No newline at end of file diff --git a/docs/Develop-legacy/xml.md b/docs/Develop-legacy/xml.md new file mode 100644 index 00000000000000..6691cfcb0e545c --- /dev/null +++ b/docs/Develop-legacy/xml.md @@ -0,0 +1,157 @@ +--- +id: xml +title: XML Processing +slug: /Develop/XML +displayed_sidebar: docs +--- + + +## Overview of XML Commands + +### XML, DOM, and SAX + +The [**XML** theme](../commands/theme/XML.md) groups together the generic XML "utilities" commands of 4D. These are option- and error-management commands. + +4D also offers two separate sets of XML commands: [**DOM**](../commands/theme/XML_DOM.md) (Document Object Model) and [**SAX**](../commands/theme/XML_SAX.md) (Simple API XML) are two different parsing modes for XML documents. + +- The DOM mode parses an XML source and builds its structure (its "tree") in memory. Because of this, access to each element of the source is extremely fast. However, since the entire tree structure is stored in memory, the processing of large XML documents may lead to the memory capacity being exceeded and thus provoke errors. +- The SAX mode does not build a tree structure in memory. In this mode, "events" (such as the start and end of an element) are generated when parsing the source. This mode lets you parse XML documents of any size, regardless of the amount of memory available. + +### References + +http://www.saxproject.org/?selected=event
+http://www.w3schools.com/xml/ + +:::note + +For XML support, 4D uses the [Xerces.dll library](../Notes/updates.md#library-table) developed by the Apache Foundation company. + +::: + + +### Preemptive mode + +XML references created by a [preemptive process](../Develop/preemptive.md) can only be used in that specific process. Conversely, XML references created by a cooperative process can be used by any other cooperative process, but cannot be used by any preemptive process. + + +### Character Sets + +The following character sets are supported by the XML DOM and XML SAX commands of 4D: + +- ASCII +- UTF-8 +- UTF-16 (Big/Small Endian) +- UCS4 (Big/Small Endian) +- EBCDIC code pages IBM037, IBM1047 and IBM1140 encodings, +- ISO-8859-1 (or Latin1) +- Windows-1252. + + +### Glossary + +This non-exhaustive list details the main XML concepts used by the commands and functions of 4D. + +- **Attribute**: an XML sub-tag associated with an element. An attribute always contains a name and a value. +- **Child**: In an XML structure, an element in a level directly below another. +- **DTD**: *Document Type Declaration*. The DTD records the set of specific rules and properties that the XML must follow. These rules define, more particularly, the name and content of each tag as well as its context. This formalization of the elements can be used to check whether an XML document is in compliance (in which case, it is declared “valid”). The DTD may be included in the XML document (internal DTD) or in a separate document (external DTD). Note that the DTD is not mandatory. +- **Element**: an XML tag. An element always contains a name and a value. Optionally, an element may contain attributes. +- **ElementRef**: XML reference used by the 4D XML commands to specify an XML structure. This reference is made up of 8 coded characters in hexadecimal form, which means that its length is 32 characters on a 64-bit system. It is recommended to declare XML references as Text. +- **Parent**: In an XML structure, an element in a level directly above another. +- **Parsing, parser**: The act of analyzing the contents of a structured object in order to extract useful information. +- **Root**: An element located at the first level of an XML structure. +- **Sibling**: An element at the same level as another. +- **Structure**: structured XML object. This object can be a document, a variable, or an element. +- **Validation**: An XML document is “validated” by the parser when it is “well-formed” and in compliance with the DTD specifications. +- **Well-formed**: An XML document is declared “well-formed” by the parser when it complies with the generic XML specifications. +- **XML**: eXtensible Markup Language. A computerized data exchange standard enabling the transfer of data as well as their structure. The XML language is based on the use of tags and a specific syntax, in keeping with the HTML language. However, unlike the latter, the XML language allows the definition of customized tags. +- **XSL**: eXtensible Stylesheet Language. A language permitting the definition of style sheets used to process and display the contents of an XSL document. + + +## XML DOM Commands + +### Creating, opening and closing XML documents via DOM + +Objects created, modified or parsed by the [4D XML DOM commands](../commands/theme/XML_DOM.md) can be text, URLs, documents or BLOBs. The DOM commands used for opening XML objects in 4D are [`DOM Parse XML source`](../commands/dom-parse-xml-source) and [`DOM Parse XML variable`](../commands/dom-parse-xml-variable). + +Many commands then let you read, parse and write the elements and attributes. Errors are recovered using the [`XML GET ERROR`](../commands/xml-get-error) command. Do not forget to call the [`DOM CLOSE XML`](../commands/dom-close-xml) command to close the source in the end. + +Note about use of XML BLOB parameters: For historical reasons, XML commands such as [`DOM Parse XML variable`](../commands/dom-parse-xml-variable) accept BLOB type parameters. However, it is highly recommended to store XML structures as Text. The use of BLOBs is reserved for processing binary data. In conformity with XML specifications, binary data are automatically encoded in Base64, even when the BLOB contains text. + + +### Support of XPath notation + +Several XML DOM commands ([`DOM Create XML element`](../commands/dom-create-xml-element), [`DOM Find XML element`](../commands/dom-find-xml-element), [`DOM Create XML element arrays`](../commands/dom-create-xml-element-arrays) and [`DOM SET XML ELEMENT VALUE`](../commands/dom-set-xml-element-value)) support some XPath expressions for accessing XML elements. + +XPath notation comes from the XPath language, designed to navigate within XML structures. It allows the setting of elements directly within an XML structure via a "pathname" type syntax, without necessarily having to indicate the complete pathname in order to reach it. + +For example, given the following structure: + +```xml + + + + + + + +``` + +XPath notation allows you to access element 3 using the */RootElement/Elem1/Elem2/Elem3* syntax. + +4D also accepts indexed XPath elements using the *Element[ElementNum]* syntax. For example, given the following structure: + +```xml + + + aaa + bbb + ccc + + +``` + +XPath notation allows you to access the "ccc" value using the */RootElement/Elem1/Elem2[3]* syntax. + +For a comprehensive list of supported XPath expressions, refer to the [`DOM Find XML element`](../commands/dom-find-xml-element) command description. + +:::note Compatibility + +Starting with 4D 18 R3, the XPath implementation has been modified to be more compliant and to support a wider set of expressions. If you want to benefit from the extended features in your converted databases, you need to select the **Use standard XPath** option of the [Compatibility page](../settings/compatibility.md). + +::: + +### Error Handling + +Many functions in this theme return an XML element reference. If an error occurs during function execution (for example, if the root element reference is not valid), the *OK* variable is set to 0 and an error is generated. + +In addition, the reference returned in this case is a sequence of 32 zero "0" characters. + + +## XML SAX Commands + +### Creating, opening and closing XML documents via SAX + +The [XML SAX commands](../commands/theme/XML_SAX.md) work with the standard document references of 4D (**DocRef**, a Time type reference). It is therefore possible to use these commands jointly with the 4D commands used to manage documents, such as [`SEND PACKET`](../commands/send-packet) or [`Append document`](../commands/append-document). + +The creation and opening of XML documents by programming is carried out using the [`Create document`](../commands/create-document) and [`Open document`](../commands/open-document) commands. Subsequently, the use of an XML command with these documents will cause the automatic activation of XML mechanisms such as encoding. For instance, the `` header will be written automatically in the document. + +:::note + +Documents read by SAX commands must be opened in read-only mode by the [`Open document`](../commands/open-document) command. This avoids any conflict between 4D and the Xerces library when you open "regular" and XML documents simultaneously. If you execute a SAX parsing command with a document open in read-write mode, an alert message is displayed and parsing is impossible. + +::: + +Closing an XML document must be carried out using the [`CLOSE DOCUMENT`](../commands/close-document) command. If any XML elements were open, they will be closed automatically. + +### About end-of-line characters and BOM management + +When writing SAX documents, 4D uses the following default settings for end-of-line characters and BOM (byte order mask) usage: + +- CRLF characters on Windows and LF on macOS for end-of-line characters +- files are written without BOM. + +:::note Compatibility + +In projects created with 4D versions up to 19.x, by default 4D uses CRLF as end-of-line characters on macOS for SAX and a BOM. You can control the `XML line ending` and `XML BOM` management using the [`XML SET OPTIONS`](../commands/xml-set-options) command and a [Compatibility setting](../settings/compatibility.md). Important: Since SAX file lines are written directly at each statement, if you need to set the BOM and/or end-of-line options, you must call the [`XML SET OPTIONS`](../commands/xml-set-options) command before the first SAX writing command. + +::: diff --git a/docs/Develop/processes.md b/docs/Develop/processes.md index a4ed67f95058b1..6ae3a245c496ee 100644 --- a/docs/Develop/processes.md +++ b/docs/Develop/processes.md @@ -145,3 +145,5 @@ All worker processes, except the main process, have the process type `Worker pro For more information, please see [this blog post](https://blog.4d.com/4d-summit-2016-laurent-esnault-presents-workers-and-ui-in-preemptive-mode/) about how to use workers. + + diff --git a/docs/FormObjects/formObjects_overview.md b/docs/FormObjects/formObjects_overview.md index 88be6eabf58535..35efd5b543e55e 100644 --- a/docs/FormObjects/formObjects_overview.md +++ b/docs/FormObjects/formObjects_overview.md @@ -36,3 +36,35 @@ Example for a button object: "height": 20 } ``` + +### Accessing form objects using their name or their data source in the 4D language + +Many commands handling form objects such as commands from [Objects (Forms)](../commands/theme/Objects_Forms.md), [List Box](../commands/theme/List_Box.md), or [Styled Text](../commands/theme/Styled_Text.md) themes share the same generic syntaxes described here: + +```4d +COMMAND NAME( * ; *object* : Text { ; *additional parameters* } ) +//or +COMMAND NAME( *object* : Variable, Field { ; *additional parameters* }) +``` + +If you specify the \* parameter, you indicate that *object* is the [name of the object](./properties_Object.md#object-name) (a string). If you don't pass the \*, you indicate that *object* is a field or a variable, i.e. its [data source](./properties_Object.md#variable-or-expression). + +When using the [object name](./properties_Object.md#object-name), you can rely on the @ character within that name if you want to address several objects of the form in one call. The following table shows examples of object names you can specify to this command. + +|Object Names|Objects affected by the call| +|---|---| +|mainGroupBox|Only the object mainGroupBox.| +|main@|The objects whose name starts with “main”.| +|@GroupBox|The objects whose name ends with “GroupBox”.| +|@Group@|The objects whose name contains “Group”.| +|main@Btn|The objects whose name starts with “main” and ends with “Btn”.| +|@|All the objects present in the form.| + +Form object names can contain up 255 bytes, allowing you to define and apply custom naming rules, such as "xxxx_Button" or "xxx_Mac". + +:::warning + +You can [configure the way the @ character is interpreted](../settings/database.md#text-comparison) when it is included in a character string. This option affects the functioning of the form object commands. + +::: + diff --git a/docs/FormObjects/list_overview.md b/docs/FormObjects/list_overview.md index a0459ebfdb6eb3..afff2babd0d260 100644 --- a/docs/FormObjects/list_overview.md +++ b/docs/FormObjects/list_overview.md @@ -25,7 +25,7 @@ In both cases, you manage a hierarchical list at runtime through its *ListRef* r A hierarchical list is both a **language object** existing in memory and a **form object**. -The **language object** is referenced by an unique internal ID of the Longint type, designated by *ListRef* in the 4D Language Reference. This ID is returned by the commands that can be used to create lists: `New list`, `Copy list`, `Load list`, `BLOB to list`. There is only one instance of the language object in memory and any modification carried out on this object is immediately carried over to all the places where it is used. +The **language object** is referenced by an unique internal ID of the Longint type, designated by *ListRef* in the 4D Language Reference. This ID is returned by the commands that can be used to create lists: [`New list`](../commands/new-list), [`Copy list`](../commands/copy-list), [`Load list`](../commands/load-list), [`BLOB to list`](../commands/blob-to-list). There is only one instance of the language object in memory and any modification carried out on this object is immediately carried over to all the places where it is used. The **form object** is not necessarily unique: there may be several representations of the same hierarchical list in the same form or in different ones. As with other form objects, you specify the object in the language using the syntax (*;"ListName", etc.). @@ -42,7 +42,7 @@ Each representation of the list has its own specific characteristics and shares - The position of the scrolling cursor. The other characteristics (font, font size, style, entry control, color, list contents, icons, etc.) are common to all the representations and cannot be modified separately. -Consequently, when you use commands based on the expanded/collapsed configuration or the current item, for example `Count list items` (when the final `*` parameter is not passed), it is important to be able to specify the representation to be used without any ambiguity. +Consequently, when you use commands based on the expanded/collapsed configuration or the current item, for example [`Count list items`](../commands/count-list-items) (when the final `*` parameter is not passed), it is important to be able to specify the representation to be used without any ambiguity. You must use the `ListRef` ID with language commands when you want to specify the hierarchical list found in memory. On the other hand, if you want to specify the representation of a hierarchical list object at the form level, you must use the object name (string type) in the command, via the standard syntax (*;"ListName", etc.). @@ -57,45 +57,45 @@ SET LIST ITEM FONT(*;"mylist1";*;thefont) ### Support of @ -As with other object property management commands, it is possible to use the “@” character in the `ListName` parameter. As a rule, this syntax is used to designate a set of objects in the form. However, in the context of hierarchical list commands, this does not apply in every case. This syntax will have two different effects depending on the type of command: +As with [other object property management commands](../FormObjects/formObjects_overview.md#accessing-form-objects-using-their-name-or-their-data-source-in-the-4d-language), it is possible to use the “@” character in the `ListName` parameter. As a rule, this syntax is used to designate a set of objects in the form. However, in the context of hierarchical list commands, this does not apply in every case. This syntax will have two different effects depending on the type of command: - For commands that set properties, this syntax designates all the objects whose name corresponds (standard behavior). For example, the parameter "LH@" designates all objects of the hierarchical list type whose name begins with “LH.” - - `DELETE FROM LIST` - - `INSERT IN LIST` - - `SELECT LIST ITEMS BY POSITION` - - `SET LIST ITEM` - - `SET LIST ITEM FONT` - - `SET LIST ITEM ICON` - - `SET LIST ITEM PARAMETER` - - `SET LIST ITEM PROPERTIES` + - [`DELETE FROM LIST`](../commands/delete-from-list) + - [`INSERT IN LIST`](../commands/insert-in-list) + - [`SELECT LIST ITEMS BY POSITION`](../commands/select-list-items-by-position) + - [`SET LIST ITEM`](../commands/set-list-item) + - [`SET LIST ITEM FONT`](../commands/set-list-item-font) + - [`SET LIST ITEM ICON`](../commands/set-list-item-icon) + - [`SET LIST ITEM PARAMETER`](../commands/set-list-item-parameter) + - [`SET LIST ITEM PROPERTIES`](../commands/set-list-item-properties) - For commands retrieving properties, this syntax designates the first object whose name corresponds: - - `Count list items` - - `Find in list` - - `GET LIST ITEM` - - `Get list item font` - - `GET LIST ITEM ICON` - - `GET LIST ITEM PARAMETER` - - `GET LIST ITEM PROPERTIES` - - `List item parent` - - `List item position` - - `Selected list items` + - [`Count list items`](../commands/count-list-items) + - [`Find in list`](../commands/find-in-list) + - [`GET LIST ITEM`](../commands/get-list-item) + - [`Get list item font`](../commands/get-list-item-font) + - [`GET LIST ITEM ICON`](../commands/get-list-item-icon) + - [`GET LIST ITEM PARAMETER`](../commands/get-list-item-parameter) + - [`GET LIST ITEM PROPERTIES`](../commands/get-list-item-properties) + - [`List item parent`](../commands/list-item-parent) + - [`List item position`](../commands/list-item-position) + - [`Selected list items`](../commands/selected-list-items) ## Generic commands to use with hierarchical lists It is possible to modify the appearance of a hierarchical list form objects using several generic 4D commands. You can pass to these commands either the object name of the hierarchical list (using the * parameter), or its variable name (containing the ListRef value): -- `OBJECT SET FONT` -- `OBJECT SET FONT STYLE` -- `OBJECT SET FONT SIZE` -- `OBJECT SET FILTER` -- `OBJECT SET ENTERABLE` -- `OBJECT SET SCROLLBAR` -- `OBJECT SET SCROLL POSITION` -- `OBJECT SET RGB COLORS` +- [`OBJECT SET FONT`](../commands/object-set-font) +- [`OBJECT SET FONT STYLE`](../commands/object-set-font-style) +- [`OBJECT SET FONT SIZE`](../commands/object-set-font-size) +- [`OBJECT SET FILTER`](../commands/object-set-filter) +- [`OBJECT SET ENTERABLE`](../commands/object-set-enterable) +- [`OBJECT SET SCROLLBAR`](../commands/object-set-scrollbar) +- [`OBJECT SET SCROLL POSITION`](../commands/object-set-scroll-position) +- [`OBJECT SET RGB COLORS`](../commands/object-set-rgb-colors) -> Reminder: Except `OBJECT SET SCROLL POSITION`, these commands modify all the representations of the same list, even if you only specify a list via its object name. +> Reminder: Except [`OBJECT SET SCROLL POSITION`](../commands/object-set-scroll-position), these commands modify all the representations of the same list, even if you only specify a list via its object name. ## Priority of property commands @@ -105,7 +105,7 @@ Certain properties of hierarchical lists (for example, the **Enterable** attribu 2. Generic object property commands 3. Form property -This principle is applied regardless of the order in which the commands are called. If an item property is modified individually via a hierarchical list command, the equivalent object property command will have no effect on this item even if it is called subsequently. For example, if the color of an item is modified via the `SET LIST ITEM PROPERTIES` command, the `OBJECT SET COLOR` command will have no effect on this item. +This principle is applied regardless of the order in which the commands are called. If an item property is modified individually via a hierarchical list command, the equivalent object property command will have no effect on this item even if it is called subsequently. For example, if the color of an item is modified via the [`SET LIST ITEM PROPERTIES`](../commands/set-list-item-properties) command, the `OBJECT SET COLOR` command will have no effect on this item. ## Management of items by position or by reference @@ -127,19 +127,19 @@ Here are a few tips for using reference numbers: 1. You do not need to identify each item with a unique number (beginner level). - First example: you build a system of tabs by programming, for example, an address book. Since the system returns the number of the tab selected, you will probably not need more information than this. In this case, do not worry about item reference numbers: pass any value (except 0) in the *itemRef* parameter. Note that for an address book system, you can predefine a list A, B, ..., Z in Design mode. You can also create it by programming in order to eliminate any letters for which there are no records. - - Second example: while working with a database, you progressively build a list of keywords. You can save this list at the end of each session by using the `SAVE LIST` or `LIST TO BLOB` commands and reload it at the beginning of each new session using the `Load list` or `BLOB to list` commands. You can display this list in a floating palette; when each user clicks on a keyword in the list, the item chosen is inserted into the enterable area that is selected in the foreground process. The important thing is that you only process the item selected, because the `Selected list items` command returns the position of the item that you must process. When using this position value, you obtain the title of the item by means of the `GET LIST ITEM` command. Here again, you do not need to identify each item individually; you can pass any value (except 0) in the *itemRef* parameter. + - Second example: while working with a database, you progressively build a list of keywords. You can save this list at the end of each session by using the [`SAVE LIST`](../commands/save-list) or [`LIST TO BLOB`](../commands/list-to-blob) commands and reload it at the beginning of each new session using the [`Load list`](../commands/load-list) or [`BLOB to list`](../commands/blob-to-list) commands. You can display this list in a floating palette; when each user clicks on a keyword in the list, the item chosen is inserted into the enterable area that is selected in the foreground process. The important thing is that you only process the item selected, because the [`Selected list items`](../commands/selected-list-items) command returns the position of the item that you must process. When using this position value, you obtain the title of the item by means of the [`GET LIST ITEM`](../commands/get-list-item) command. Here again, you do not need to identify each item individually; you can pass any value (except 0) in the *itemRef* parameter. 2. You need to partially identify the list items (intermediary level). -You use the item reference number to store information needed when you must work with the item; this point is detailed in the example of the `APPEND TO LIST` command. In this example, we use the item reference numbers to store record numbers. However, we must be able to establish a distinction between items that correspond to the [Department] records and those that correspond to the [Employees] records. +You use the item reference number to store information needed when you must work with the item; this point is detailed in the example of the [`APPEND TO LIST`](../commands/append-to-list) command. In this example, we use the item reference numbers to store record numbers. However, we must be able to establish a distinction between items that correspond to the [Department] records and those that correspond to the [Employees] records. 3. You need to identify all the list items individually (advanced level). -You program an elaborate management of hierarchical lists in which you absolutely must be able to identify each item individually at every level of the list. A simple way of implementing this is to maintain a personal counter. Suppose that you create a *hlList* list using the `APPEND TO LIST` command. At this stage, you initialize a counter *vhlCounter* to 1. Each time you call `APPEND TO LIST` or `INSERT IN LIST`, you increment this counter `(vhlCounter:=vhlCounter+1)`, and you pass the counter number as the item reference number. The trick consists in never decrementing the counter when you delete items — the counter can only increase. In this way, you guarantee the uniqueness of the item reference numbers. Since these numbers are of the Longint type, you can add or insert more than two billion items in a list that has been reinitialized... (however if you are working with such a great number of items, this usually means that you should use a table rather than a list.) +You program an elaborate management of hierarchical lists in which you absolutely must be able to identify each item individually at every level of the list. A simple way of implementing this is to maintain a personal counter. Suppose that you create a *hlList* list using the [`APPEND TO LIST`](../commands/append-to-list) command. At this stage, you initialize a counter *vhlCounter* to 1. Each time you call [`APPEND TO LIST`](../commands/append-to-list) or [`INSERT IN LIST`](../commands/insert-in-list), you increment this counter `(vhlCounter:=vhlCounter+1)`, and you pass the counter number as the item reference number. The trick consists in never decrementing the counter when you delete items — the counter can only increase. In this way, you guarantee the uniqueness of the item reference numbers. Since these numbers are of the Longint type, you can add or insert more than two billion items in a list that has been reinitialized... (however if you are working with such a great number of items, this usually means that you should use a table rather than a list.) > If you use Bitwise Operators, you can also use item reference numbers for storing information that can be put into a Longint, i.e. 2 Integers, 4-byte values or, yet again, 32 Booleans. ### When do you need unique reference numbers? -In most cases, when using hierarchical lists for user interface purposes and when only dealing with the selected item (the one that was clicked or dragged), you will not need to use item reference numbers at all. Using `Selected list items` and `GET LIST ITEM` you have all you need to deal with the currently selected item. In addition, commands such as `INSERT IN LIST` and `DELETE FROM LIST` allow you to manipulate the list “relatively” with respect to the selected item. +In most cases, when using hierarchical lists for user interface purposes and when only dealing with the selected item (the one that was clicked or dragged), you will not need to use item reference numbers at all. Using [`Selected list items`](../commands/selected-list-items) and [`GET LIST ITEM`](../commands/get-list-item) you have all you need to deal with the currently selected item. In addition, commands such as [`INSERT IN LIST`](../commands/insert-in-list) and [`DELETE FROM LIST`](../commands/delete-from-list) allow you to manipulate the list “relatively” with respect to the selected item. Basically, you need to deal with item reference numbers when you want direct access to any item of the list programmatically and not necessarily the one currently selected in the list. diff --git a/docs/FormObjects/listbox_overview.md b/docs/FormObjects/listbox_overview.md index 825cf6cd4a9f1c..65febef27f4d3c 100644 --- a/docs/FormObjects/listbox_overview.md +++ b/docs/FormObjects/listbox_overview.md @@ -606,5 +606,183 @@ In this case, you must fill and empty arrays through the code. The principles to - When a user clicks on a collapse button, you can process the `On Collapse` event. The [`LISTBOX GET CELL POSITION`](../commands/listbox-get-cell-position) command returns the cell concerned: you remove as many rows as needed from the list box using the [`LISTBOX DELETE ROWS`](../commands/listbox-delete-rows) command. +## List boxes and the 4D language + +Many commands of the 4D language can be used with list boxes, from the [List box theme](../commands/theme/List_Box.md) but also from [Objects (Forms)](../commands/theme/Objects_Forms.md) and other themes. They can be used with list boxes, or [parts of list boxes](#list-box-parts) such as headers, footers, rows, or columns. Some of them can only be used with specific [list box types](#list-box-types). + +### List Box commands + +| Command | List Box Type | Supported Parts | +|--------|--------------|----------------| +| [`LISTBOX COLLAPSE`](../commands/listbox-collapse) | Hierarchical | List box, headers, footers, rows, columns | +| [`LISTBOX DELETE COLUMN`](../commands/listbox-delete-column) | All | Columns | +| [`LISTBOX DELETE ROWS`](../commands/listbox-delete-rows) | Array | List box, headers, footers, rows, columns | +| [`LISTBOX DUPLICATE COLUMN`](../commands/listbox-duplicate-column) | Array, Selection, Collection | Columns | +| [`LISTBOX EXPAND`](../commands/listbox-expand) | Hierarchical | List box, headers, footers, rows, columns | +| [`LISTBOX Get array`](../commands/listbox-get-array) | Array | List box, headers, footers, rows, columns | +| [`LISTBOX GET ARRAYS`](../commands/listbox-get-arrays) | All | List box, headers, footers, rows, columns | +| [`LISTBOX Get auto row height`](../commands/listbox-get-auto-row-height) | Array | List box, headers, footers, rows, columns | +| [`LISTBOX GET CELL COORDINATES`](../commands/listbox-get-cell-coordinates) | All | List box, headers, footers, rows, columns | +| [`LISTBOX GET CELL POSITION`](../commands/listbox-get-cell-position) | All | List box, headers, footers, rows, columns | +| [`LISTBOX Get column formula`](../commands/listbox-get-column-formula) | Selection, Collection | Columns | +| [`LISTBOX Get column width`](../commands/listbox-get-column-width) | All | Columns | +| [`LISTBOX Get footer calculation`](../commands/listbox-get-footer-calculation) | Array, Selection | Footers | +| [`LISTBOX Get footers height`](../commands/listbox-get-footers-height) | All | Footers | +| [`LISTBOX GET GRID`](../commands/listbox-get-grid) | All | List box, headers, footers, rows, columns | +| [`LISTBOX GET GRID COLORS`](../commands/listbox-get-grid-colors) | All | List box, headers, footers, rows, columns | +| [`LISTBOX Get headers height`](../commands/listbox-get-headers-height) | All | Headers | +| [`LISTBOX GET HIERARCHY`](../commands/listbox-get-hierarchy) | Array | List box, headers, footers, rows, columns | +| [`LISTBOX Get locked columns`](../commands/listbox-get-locked-columns) | All | List box | +| [`LISTBOX Get number of columns`](../commands/listbox-get-number-of-columns) | All | List box | +| [`LISTBOX GET OBJECTS`](../commands/listbox-get-objects) | All | List box | +| [`LISTBOX GET PRINT INFORMATION`](../commands/listbox-get-print-information) | All | List box, headers, footers, rows, columns | +| [`LISTBOX Get property`](../commands/listbox-get-property) | All | List box, columns | +| [`LISTBOX Get row color as number`](../commands/listbox-get-row-color-as-number) | Array | Rows | +| [`LISTBOX Get row font style`](../commands/listbox-get-row-font-style) | Array | Rows | +| [`LISTBOX Get row height`](../commands/listbox-get-row-height) | Array | Rows | +| [`LISTBOX Get rows height`](../commands/listbox-get-rows-height) | All | List box | +| [`LISTBOX Get static columns`](../commands/listbox-get-static-columns) | All | List box | +| [`LISTBOX GET TABLE SOURCE`](../commands/listbox-get-table-source) | All | List box | +| [`LISTBOX INSERT COLUMN`](../commands/listbox-insert-column) | All | List box | +| [`LISTBOX INSERT COLUMN FORMULA`](../commands/listbox-insert-column-formula) | All | List box | +| [`LISTBOX INSERT ROWS`](../commands/listbox-insert-rows) | Array | List box | +| [`LISTBOX MOVE COLUMN`](../commands/listbox-move-column) | All | Columns | +| [`LISTBOX MOVED COLUMN NUMBER`](../commands/listbox-moved-column-number) | All | Columns | +| [`LISTBOX MOVED ROW NUMBER`](../commands/listbox-moved-row-number) | Array | Rows | +| [`LISTBOX SELECT BREAK`](../commands/listbox-select-break) | Hierarchical | List box | +| [`LISTBOX SELECT ROW`](../commands/listbox-select-row) | All | Rows | +| [`LISTBOX SET ARRAY`](../commands/listbox-set-array) | Array | List box, columns | +| [`LISTBOX SET AUTO ROW HEIGHT`](../commands/listbox-set-auto-row-height) | Array | Rows | +| [`LISTBOX SET COLUMN FORMULA`](../commands/listbox-set-column-formula) | Selection, Collection | Columns | +| [`LISTBOX SET COLUMN WIDTH`](../commands/listbox-set-column-width) | All | Columns | +| [`LISTBOX SET FOOTER CALCULATION`](../commands/listbox-set-footer-calculation) | Array, Selection | Footers | +| [`LISTBOX SET FOOTERS HEIGHT`](../commands/listbox-set-footers-height) | All | Footers | +| [`LISTBOX SET GRID`](../commands/listbox-set-grid) | All | List box | +| [`LISTBOX SET GRID COLOR`](../commands/listbox-set-grid-color) | All | List box | +| [`LISTBOX SET HEADERS HEIGHT`](../commands/listbox-set-headers-height) | All | Headers | +| [`LISTBOX SET HIERARCHY`](../commands/listbox-set-hierarchy) | Array | List box | +| [`LISTBOX SET LOCKED COLUMNS`](../commands/listbox-set-locked-columns) | All | List box | +| [`LISTBOX SET PROPERTY`](../commands/listbox-set-property) | All | List box, columns | +| [`LISTBOX SET ROW COLOR`](../commands/listbox-set-row-color) | Array | Rows | +| [`LISTBOX SET ROW FONT STYLE`](../commands/listbox-set-row-font-style) | Array | Rows | +| [`LISTBOX SET ROW HEIGHT`](../commands/listbox-set-row-height) | Array | Rows | +| [`LISTBOX SET ROWS HEIGHT`](../commands/listbox-set-rows-height) | All | List box | +| [`LISTBOX SET STATIC COLUMNS`](../commands/listbox-set-static-columns) | All | List box | +| [`LISTBOX SET TABLE SOURCE`](../commands/listbox-set-table-source) | Selection | List box | +| [`LISTBOX SORT COLUMNS`](../commands/listbox-sort-columns) | All | Columns | + +### Miscellaneous commands + + +| Command | List Box Type | Supported Parts | Comments | +|--------|--------------|----------------|----------| +| [`EDIT ITEM`](../commands/edit-item) | All | Columns | Allows you to pass a cell of a list box object into edit mode | +| [`Get edited text`](../commands/get-edited-text) | All | List box, headers, footers, rows, columns | | +| [`REDRAW`](../commands/redraw) | Array, Selection | List box | When applied to a selection list box, triggers an update of the data displayed in the list box. Not supported with list box of the entity selection type. | +| [`Displayed line number`](../commands/displayed-line-number) | All | List box, headers, footers, rows, columns | Works in the context of the [`On Display Detail`](../Events/onDisplayDetail.md) form event for a list box object | +| [`Drop position`](../commands/drop-position) | All | List box, headers, footers, rows, columns | | +| [`Count in array`](../commands/count-in-array) | All | List box, headers, footers, rows, columns | | +| [`Print object`](../commands/print-object) | All | List box, headers, footers, rows, columns | | + + +### Object (forms) commands + +| Command | List Box Type | Supported Parts | +|--------|--------------|----------------| +| [`OBJECT DUPLICATE`](../commands/object-duplicate) | All | List box, headers, footers, rows, columns | +| [`OBJECT GET BEST SIZE`](../commands/object-get-best-size) | All | Columns | +| [`OBJECT Get border style`](../commands/object-get-border-style) | All | List box, headers, footers, rows, columns | +| [`OBJECT GET COORDINATES`](../commands/object-get-coordinates) | All | List box, headers, footers, rows, columns | +| [`OBJECT Get data source`](../commands/object-get-data-source) | Array | List box | +| [`OBJECT GET DRAG AND DROP OPTIONS`](../commands/object-get-drag-and-drop-options) | All | List box, headers, footers, rows, columns | +| [`OBJECT Get enterable`](../commands/object-get-enterable) | All | Columns | +| [`OBJECT Get filter`](../commands/object-get-filter) | All | Columns | +| [`OBJECT Get focus rectangle invisible`](../commands/object-get-focus-rectangle-invisible) | All | List box, headers, footers, rows, columns | +| [`OBJECT Get font`](../commands/object-get-font) | All | List box, headers, footers, rows, columns | +| [`OBJECT Get font size`](../commands/object-get-font-size) | All | List box, headers, footers, rows, columns | +| [`OBJECT Get font style`](../commands/object-get-font-style) | All | List box, headers, footers, rows, columns | +| [`OBJECT Get format`](../commands/object-get-format) | All | Headers | +| [`OBJECT Get help tip`](../commands/object-get-help-tip) | All | Headers, footers | +| [`OBJECT Get horizontal alignment`](../commands/object-get-horizontal-alignment) | All | List box, headers, footers, columns | +| [`OBJECT Get list reference`](../commands/object-get-list-reference) | All | Columns | +| [`OBJECT Get name`](../commands/object-get-name) | All | List box, headers, footers, rows, columns | +| [`OBJECT Get pointer`](../commands/object-get-pointer) | All | List box, headers, footers, rows, columns (see below)| +| [`OBJECT GET RESIZING OPTIONS`](../commands/object-get-resizing-options) | All | List box, headers, footers, rows, columns | +| [`OBJECT GET RGB COLORS`](../commands/object-get-rgb-colors) | All | List box, headers, footers, rows, columns | +| [`OBJECT GET SCROLL POSITION`](../commands/object-get-scroll-position) | All | List box | +| [`OBJECT GET SCROLLBAR`](../commands/object-get-scrollbar) | All | List box | +| [`OBJECT Get type`](../commands/object-get-type) | All | List box, headers, footers, columns | +| [`OBJECT Get vertical alignment`](../commands/object-get-vertical-alignment) | All | List box, headers, footers, columns | +| [`OBJECT MOVE`](../commands/object-move) | All | List box, headers, footers, rows, columns | +| [`OBJECT SET COLOR`](../commands/object-set-color) | All | List box, headers, footers, rows, columns | +| [`OBJECT SET COORDINATES`](../commands/object-set-coordinates) | All | List box | +| [`OBJECT SET DATA SOURCE`](../commands/object-set-data-source) | All | List box | +| [`OBJECT SET ENTERABLE`](../commands/object-set-enterable) | All | Columns | +| [`OBJECT SET EVENTS`](../commands/object-set-events) | All | List box | +| [`OBJECT SET FOCUS RECTANGLE INVISIBLE`](../commands/object-set-focus-rectangle-invisible) | All | List box, headers, footers, rows, columns | +| [`OBJECT SET FONT`](../commands/object-set-font) | All | List box, headers, footers, rows, columns | +| [`OBJECT SET FONT SIZE`](../commands/object-set-font-size) | All | List box, headers, footers, rows, columns | +| [`OBJECT SET FONT STYLE`](../commands/object-set-font-style) | All | List box, headers, footers, rows, columns | +| [`OBJECT SET FORMAT`](../commands/object-set-format) | All | List box, headers, footers, rows, columns | +| [`OBJECT SET HELP TIP`](../commands/object-set-help-tip) | All | Headers, footers | +| [`OBJECT SET HORIZONTAL ALIGNMENT`](../commands/object-set-horizontal-alignment) | All | List box, headers, footers, columns | +| [`OBJECT SET RESIZING OPTIONS`](../commands/object-set-resizing-options) | All | List box, headers, footers, rows, columns | +| [`OBJECT SET RGB COLORS`](../commands/object-set-rgb-colors) | All | List box, headers, footers, rows, columns | +| [`OBJECT SET SCROLL POSITION`](../commands/object-set-scroll-position) | All | List box | +| [`OBJECT SET SCROLLBAR`](../commands/object-set-scrollbar) | All | List box. Scrolls the list box rows so that the first selected row or a specified row is displayed| +| [`OBJECT SET TITLE`](../commands/object-set-title) | All | Headers | +| [`OBJECT SET VERTICAL ALIGNMENT`](../commands/object-set-vertical-alignment) | All | List box, headers, footers, columns | +| [`OBJECT SET VISIBLE`](../commands/object-set-visible) | All | List box, headers, footers | + +When [`OBJECT SET VISIBLE`](../commands/object-set-visible) is used with a header or footer, it is applied on all List box object headers or footers, regardless of the individual element set by the command. For example, the `OBJECT SET VISIBLE(*;"header3";False)` statement will hide all headers in the List box object to which *header3* belongs and not simply this header. Note that in order for you to be able to manage the visibility of these objects using the [`OBJECT SET VISIBLE`](../commands/object-set-visible) command, they must have been displayed in the list box properties. + +### OBJECT Get pointer + +The [`OBJECT Get pointer`](../commands/object-get-pointer) command used with the `Object with focus` or `Object current` constant can be used in the object method of a list box or a list box column. They return a pointer to the list box, the list box column (see note below) or the header variable depending on the type of [form event](../Events/overview.md). The following table details this functioning: + +| Event | Object with focus | Object current | +|------|------------------|----------------| +| [`On Clicked`](../Events/onClicked.md) | list box | column | +| [`On Double Clicked`](../Events/onDoubleClicked.md) | list box | column | +| [`On Before Keystroke`](../Events/onBeforeKeystroke.md) | column | column | +| [`On After Keystroke`](../Events/onAfterKeystroke.md) | column | column | +| [`On After Edit`](../Events/onAfterEdit.md) | column | column | +| [`On Getting Focus`](../Events/onGettingFocus.md) | column or list box (*) | column or list box (*) | +| [`On Losing Focus`](../Events/onLosingFocus.md) | column or list box (*) | column or list box (*) | +| [`On Drop`](../Events/onDrop.md) | list box (source) | list box (*) | +| [`On Drag Over`](../Events/onDragOver.md) | list box (source) | list box (*) | +| [`On Begin Drag Over`](../Events/onBeginDragOver.md) | list box | list box (*) | +| [`On Mouse Enter`](../Events/onMouseEnter.md) | list box (**) | list box (**) | +| [`On Mouse Move`](../Events/onMouseMove.md) | list box (**) | list box (**) | +| [`On Mouse Leave`](../Events/onMouseLeave.md) | list box (**) | list box (**) | +| [`On Data Change`](../Events/onDataChange.md) | column | column | +| [`On Selection Change`](../Events/onSelectionChange.md) | list box (**) | list box (**) | +| [`On Before Data Entry`](../Events/onBeforeDataEntry.md) | column | column | +| [`On Column Moved`](../Events/onColumnMoved.md) | list box | column | +| [`On Row Moved`](../Events/onRowMoved.md) | list box | list box | +| [`On Column Resize`](../Events/onColumnResize.md) | list box | column | +| [`On Open Detail`](../Events/onOpenDetail.md) | Nil | list box (**) | +| [`On Close Detail`](../Events/onCloseDetail.md) | Nil | list box (**) | +| [`On Header Click`](../Events/onHeaderClick.md) | list box | header | +| [`On Footer Click`](../Events/onFooterClick.md) | list box | footer | +| [`On After Sort`](../Events/onAfterSort.md) | list box | header | + +(\*) When the focus is modified within a list box, a pointer to the column is returned. When the focus is modified at the overall form level, a pointer to the list box is returned. In the context of a column object method, a pointer to the column is returned. +(\*\*) Not executed in the context of a column object method. + +:::note + +When a pointer to a column is returned, the object pointed to depends on the type of list box. With an array type list box, the `OBJECT Get pointer` command returns a pointer to the column of the list box with the focus (i.e. to an array). The 4D pointer mechanism allows you to see the item number of the modified array. For example, supposing a user modified the 5th line of the column col2: +```4d + $Column:=OBJECT Get pointer(Object with focus) + //$Column contains a pointer to col2 + $Row:=$Column-> //$Row equals 5 +``` +::: + +For a selection type list box, the `OBJECT Get pointer` command returns: +- For a column associated with a field, a pointer to the associated field, +- For a column associated with a variable, a pointer to the variable, +- For a column associated with an expression, the `Is nil pointer` pointer. diff --git a/docs/FormObjects/properties_Text.md b/docs/FormObjects/properties_Text.md index 4d0d7726e11f01..fddb8e84f72dee 100644 --- a/docs/FormObjects/properties_Text.md +++ b/docs/FormObjects/properties_Text.md @@ -440,7 +440,7 @@ By default, this option is not enabled. #### Commands -[LISTBOX Get property](../commands/listbox-get-property) - [LISTBOX SET PROPERTY](../commands/listbox-set-property) - [OBJECT Is styled text](../commands/object-is-styled-text) +[LISTBOX Get property](../commands/listbox-get-property) - [LISTBOX SET PROPERTY](../commands/listbox-set-property) - [OBJECT Is styled text](../commands/object-is-styled-text) - ["Styled Text" theme](../ommands/theme/Styled_Text.md) ### Supported tags @@ -520,6 +520,91 @@ For font color and background color attributes, the color value can be either th ![](../assets/en/FormObjects/colors2.png) +### Working with text handling commands + +#### User interface + +The commands that can be used to manipulate text objects by programming do not take any style tags integrated into the text into account. They act upon displayed text only. This concerns the following commands: + +- [User Interface](../commands/theme/User_Interface.md) theme commands +- [`HIGHLIGHT TEXT`](../commands/highlight-text) +- [`GET HIGHLIGHT`](../commands/get-highlight) + +When you use these commands with commands that manipulate character strings, it is necessary to filter the formatting characters using the [`ST Get plain text`](../commands/st-get-plain-text) command: + +```4d + HIGHLIGHT TEXT([Products]Notes;1;Length(ST Get plain text([Products]Notes))+1) +``` + +#### Objects (Forms) + +The commands that can be used to modify the style of objects (for example, [`OBJECT SET FONT`](../commands/object-set-font)) apply to the whole object and not to the selection. + +If the object does not have the focus when the command is executed, the modification is applied simultaneously to the object (the text area) and to its associated variable. If the object does have the focus, the modification is carried out on the object but not on the associated variable. The modification is only applied to the variable when the object loses the focus. Keep this principle in mind when programming text areas. + +:::note + +If the [**Store with default style tags**](#store-with-default-style-tags) option is checked for the object, the use of these commands will cause a modification of the tags saved with each object. + +::: + + +Note also that only default properties are affected by these commands (as well as any properties saved by means of default tags). Custom style tags remain as they are. For example, given a multi-style area where default tags were saved: + +![](../assets/en/FormObjects/multistyle-ex1.png) + +The plain text of the area is as follows: + +```html +This is the word red +``` + +If you execute the following code: + +```4d +OBJECT SET COLOR(*;"myArea";-(Blue+(256*Yellow))) +``` + +The red color remains: + +![](../assets/en/FormObjects/multistyle-ex2.png) + +and code is: + +```html +This is the word red +``` + +The following commands are concerned: + +- [`OBJECT SET RGB COLORS`](../commands/object-set-rgb-colors) +- [`OBJECT SET FONT`](../commands/object-set-font) +- [`OBJECT SET FONT STYLE`](../commands/object-set-font-style) +- [`OBJECT SET FONT SIZE`](../commands/object-set-font-size) + +In the context of multi-style areas, such commands should be used to set default styles only. To manage styles during database execution, we recommend using the [commands of the "Styled Text" theme](../commands/theme/Styled_Text.md). + +#### Get edited text + +When it is used with a rich text area, the [`Get edited text`](../commands/get-edited-text) command returns the text of the current area including any style tags. + +To retrieve the "plain" text (text without tags) being edited, you must use the [`ST Get plain text`](../commands/st-get-plain-text) command: + +```4d +ST Get plain text(Get edited text) +``` + +#### Query and order by commands + +Queries and sorts carried out among multi-style objects take into account any style tags saved in the object. If a style modification has been made within a word, searching for the word will not be successful. + +To be able to carry out valid searches and sorts, you must use the [`ST Get plain text`](../commands/st-get-plain-text) command. For example: + +```4d +QUERY BY FORMULA([MyTable];ST Get plain text([MyTable]MyFieldStyle)="very well") +``` + + --- diff --git a/docs/Preferences/general.md b/docs/Preferences/general.md index 300b63dc466aa8..6e193a06c800e4 100644 --- a/docs/Preferences/general.md +++ b/docs/Preferences/general.md @@ -96,7 +96,7 @@ Thanks to this principle, under macOS the database folders appear as packages ha ### Include tokens in project source files -When this option is checked, saved [method source files](../Project/architecture.md#sources) in new 4D projects will contain **tokens** for classic language and database objects (constants, commands, tables and fields). Tokens are additional characters such as `:C10` or `:5` inserted in the source code files, that allow renaming tables and fields and identifying elements whatever the 4D version (see [Using tokens in formulas](https://doc.4d.com/4Dv20/4D/20.6/Using-tokens-in-formulas.300-7487422.en.html)). +When this option is checked, saved [method source files](../Project/architecture.md#sources) in new 4D projects will contain [**tokens** for classic language and database objects (constants, commands, tables and fields)](../Concepts/methods.md#language-tokens). Tokens are additional characters such as `:C10` or `:5` inserted in the source code files, that allow renaming tables and fields and identifying elements whatever the 4D version. If you intend to use VCS or external code editors with your new projects, you might want to uncheck this option for a better readability of the code with these tools. diff --git a/docs/assets/en/API/signal.png b/docs/assets/en/API/signal.png index 60e7ac67d13398..2f84ccaadd6c54 100644 Binary files a/docs/assets/en/API/signal.png and b/docs/assets/en/API/signal.png differ diff --git a/docs/assets/en/Desktop/dragdrop1.png b/docs/assets/en/Desktop/dragdrop1.png new file mode 100644 index 00000000000000..69d86f478af2c8 Binary files /dev/null and b/docs/assets/en/Desktop/dragdrop1.png differ diff --git a/docs/assets/en/Desktop/dragdrop2.png b/docs/assets/en/Desktop/dragdrop2.png new file mode 100644 index 00000000000000..669e20441b7e5f Binary files /dev/null and b/docs/assets/en/Desktop/dragdrop2.png differ diff --git a/docs/assets/en/Desktop/dragdrop3.png b/docs/assets/en/Desktop/dragdrop3.png new file mode 100644 index 00000000000000..e3b622f42e4b17 Binary files /dev/null and b/docs/assets/en/Desktop/dragdrop3.png differ diff --git a/docs/assets/en/Desktop/dragdrop4.png b/docs/assets/en/Desktop/dragdrop4.png new file mode 100644 index 00000000000000..b398386d8f07bc Binary files /dev/null and b/docs/assets/en/Desktop/dragdrop4.png differ diff --git a/docs/assets/en/Desktop/dragdrop5.png b/docs/assets/en/Desktop/dragdrop5.png new file mode 100644 index 00000000000000..5dd212126556ee Binary files /dev/null and b/docs/assets/en/Desktop/dragdrop5.png differ diff --git a/docs/assets/en/Desktop/dragdrop6.png b/docs/assets/en/Desktop/dragdrop6.png new file mode 100644 index 00000000000000..4380a47cefc426 Binary files /dev/null and b/docs/assets/en/Desktop/dragdrop6.png differ diff --git a/docs/assets/en/Desktop/dragdrop7.png b/docs/assets/en/Desktop/dragdrop7.png new file mode 100644 index 00000000000000..7bed26ebeb1859 Binary files /dev/null and b/docs/assets/en/Desktop/dragdrop7.png differ diff --git a/docs/assets/en/Develop/relations.png b/docs/assets/en/Develop/relations.png new file mode 100644 index 00000000000000..cba02ce581035d Binary files /dev/null and b/docs/assets/en/Develop/relations.png differ diff --git a/docs/commands/theme/XML.md b/docs/commands/theme/XML.md index 2f4d31f420401e..8bc29ed3ca26ee 100644 --- a/docs/commands/theme/XML.md +++ b/docs/commands/theme/XML.md @@ -13,63 +13,3 @@ slug: /commands/theme/XML |[](../../commands/xml-set-options)
| -## Overview of XML Commands - -:::note - -For XML support, 4D uses the [Xerces.dll library](../../Notes/updates.md#library-table) developed by the Apache Foundation company. - -::: - - -### XML, DOM, and SAX - -The **XML** theme groups together the generic XML "utilities" commands of 4D. These are option- and error-management commands. - -4D also offers two separate sets of XML commands: [**DOM**](../theme/XML_DOM.md) (Document Object Model) and [**SAX**](../theme/XML_SAX.md) (Simple API XML) are two different parsing modes for XML documents. - -- The DOM mode parses an XML source and builds its structure (its "tree") in memory. Because of this, access to each element of the source is extremely fast. However, since the entire tree structure is stored in memory, the processing of large XML documents may lead to the memory capacity being exceeded and thus provoke errors. -- The SAX mode does not build a tree structure in memory. In this mode, "events" (such as the start and end of an element) are generated when parsing the source. This mode lets you parse XML documents of any size, regardless of the amount of memory available. - -#### See also - -http://www.saxproject.org/?selected=event
-http://www.w3schools.com/xml/ - -### Preemptive mode - -XML references created by a [preemptive process](../../Develop/preemptive.md) can only be used in that specific process. Conversely, XML references created by a cooperative process can be used by any other cooperative process, but cannot be used by any preemptive process. - - -### Character Sets - -The following character sets are supported by the XML DOM and XML SAX commands of 4D: - -- ASCII -- UTF-8 -- UTF-16 (Big/Small Endian) -- UCS4 (Big/Small Endian) -- EBCDIC code pages IBM037, IBM1047 and IBM1140 encodings, -- ISO-8859-1 (or Latin1) -- Windows-1252. - - -### Glossary - -This non-exhaustive list details the main XML concepts used by the commands and functions of 4D. - -- **Attribute**: an XML sub-tag associated with an element. An attribute always contains a name and a value. -- **Child**: In an XML structure, an element in a level directly below another. -- **DTD**: *Document Type Declaration*. The DTD records the set of specific rules and properties that the XML must follow. These rules define, more particularly, the name and content of each tag as well as its context. This formalization of the elements can be used to check whether an XML document is in compliance (in which case, it is declared “valid”). The DTD may be included in the XML document (internal DTD) or in a separate document (external DTD). Note that the DTD is not mandatory. -- **Element**: an XML tag. An element always contains a name and a value. Optionally, an element may contain attributes. -- **ElementRef**: XML reference used by the 4D XML commands to specify an XML structure. This reference is made up of 8 coded characters in hexadecimal form, which means that its length is 32 characters on a 64-bit system. It is recommended to declare XML references as Text. -- **Parent**: In an XML structure, an element in a level directly above another. -- **Parsing, parser**: The act of analyzing the contents of a structured object in order to extract useful information. -- **Root**: An element located at the first level of an XML structure. -- **Sibling**: An element at the same level as another. -- **Structure**: structured XML object. This object can be a document, a variable, or an element. -- **Validation**: An XML document is “validated” by the parser when it is “well-formed” and in compliance with the DTD specifications. -- **Well-formed**: An XML document is declared “well-formed” by the parser when it complies with the generic XML specifications. -- **XML**: eXtensible Markup Language. A computerized data exchange standard enabling the transfer of data as well as their structure. The XML language is based on the use of tags and a specific syntax, in keeping with the HTML language. However, unlike the latter, the XML language allows the definition of customized tags. -- **XSL**: eXtensible Stylesheet Language. A language permitting the definition of style sheets used to process and display the contents of an XSL document. - diff --git a/docs/commands/theme/XML_DOM.md b/docs/commands/theme/XML_DOM.md index 35952a7bf19560..a5417ee344c1c3 100644 --- a/docs/commands/theme/XML_DOM.md +++ b/docs/commands/theme/XML_DOM.md @@ -46,64 +46,3 @@ slug: /commands/theme/XML-DOM |[](../../commands/dom-set-xml-element-value)
| -## Overview of XML DOM Commands - -See [XML, DOM, and SAX](../theme/XML.md#xml-dom-and-sax) section for a definition of XML DOM. - -### Creating, opening and closing XML documents via DOM - -Objects created, modified or parsed by the 4D DOM commands can be text, URLs, documents or BLOBs. The DOM commands used for opening XML objects in 4D are [`DOM Parse XML source`](../../commands/dom-parse-xml-source) and [`DOM Parse XML variable`](../../commands/dom-parse-xml-variable). - -Many commands then let you read, parse and write the elements and attributes. Errors are recovered using the [`XML GET ERROR`](../../commands/xml-get-error) command. Do not forget to call the [`DOM CLOSE XML`](../../commands/dom-close-xml) command to close the source in the end. - -Note about use of XML BLOB parameters: For historical reasons, XML commands such as [`DOM Parse XML variable`](../../commands/dom-parse-xml-variable) accept BLOB type parameters. However, it is highly recommended to store XML structures as Text. The use of BLOBs is reserved for processing binary data. In conformity with XML specifications, binary data are automatically encoded in Base64, even when the BLOB contains text. - - -### Support of XPath notation - -Several XML DOM commands ([`DOM Create XML element`](../../commands/dom-create-xml-element), [`DOM Find XML element`](../../commands/dom-find-xml-element), [`DOM Create XML element arrays`](../../commands/dom-create-xml-element-arrays) and [`DOM SET XML ELEMENT VALUE`](../../commands/dom-set-xml-element-value)) support some XPath expressions for accessing XML elements. - -XPath notation comes from the XPath language, designed to navigate within XML structures. It allows the setting of elements directly within an XML structure via a "pathname" type syntax, without necessarily having to indicate the complete pathname in order to reach it. - -For example, given the following structure: - -```xml - - - - - - - -``` - -XPath notation allows you to access element 3 using the */RootElement/Elem1/Elem2/Elem3* syntax. - -4D also accepts indexed XPath elements using the *Element[ElementNum]* syntax. For example, given the following structure: - -```xml - - - aaa - bbb - ccc - - -``` - -XPath notation allows you to access the "ccc" value using the */RootElement/Elem1/Elem2[3]* syntax. - -For a comprehensive list of supported XPath expressions, refer to the [`DOM Find XML element`](../../commands/dom-find-xml-element) command description. - -:::note Compatibility - -Starting with 4D 18 R3, the XPath implementation has been modified to be more compliant and to support a wider set of expressions. If you want to benefit from the extended features in your converted databases, you need to select the **Use standard XPath** option of the [Compatibility page](../../settings/compatibility.md). - -::: - -### Error Handling - -Many functions in this theme return an XML element reference. If an error occurs during function execution (for example, if the root element reference is not valid), the *OK* variable is set to 0 and an error is generated. - -In addition, the reference returned in this case is a sequence of 32 zero "0" characters. - diff --git a/docs/commands/theme/XML_SAX.md b/docs/commands/theme/XML_SAX.md index de16e6c401d184..39ae1effae4e5b 100644 --- a/docs/commands/theme/XML_SAX.md +++ b/docs/commands/theme/XML_SAX.md @@ -27,33 +27,3 @@ slug: /commands/theme/XML-SAX |[](../../commands/sax-set-xml-declaration)
| -## Overview of XML SAX Commands - -See [XML, DOM, and SAX](../theme/XML.md#xml-dom-and-sax) section for a definition of XML SAX. - -### Creating, opening and closing XML documents via SAX - -The SAX commands work with the standard document references of 4D (**DocRef**, a Time type reference). It is therefore possible to use these commands jointly with the 4D commands used to manage documents, such as [`SEND PACKET`](../../commands/send-packet) or [`Append document`](../../commands/append-document). - -The creation and opening of XML documents by programming is carried out using the [`Create document`](../../commands/create-document) and [`Open document`](../../commands/open-document) commands. Subsequently, the use of an XML command with these documents will cause the automatic activation of XML mechanisms such as encoding. For instance, the `` header will be written automatically in the document. - -:::note - -Documents read by SAX commands must be opened in read-only mode by the [`Open document`](../../commands/open-document) command. This avoids any conflict between 4D and the Xerces library when you open "regular" and XML documents simultaneously. If you execute a SAX parsing command with a document open in read-write mode, an alert message is displayed and parsing is impossible. - -::: - -Closing an XML document must be carried out using the [`CLOSE DOCUMENT`](../../commands/close-document) command. If any XML elements were open, they will be closed automatically. - -### About end-of-line characters and BOM management - -When writing SAX documents, 4D uses the following default settings for end-of-line characters and BOM (byte order mask) usage: - -- CRLF characters on Windows and LF on macOS for end-of-line characters -- files are written without BOM. - -:::note Compatibility - -In projects created with 4D versions up to 19.x, by default 4D uses CRLF as end-of-line characters on macOS for SAX and a BOM. You can control the `XML line ending` and `XML BOM` management using the [`XML SET OPTIONS`](../../commands/xml-set-options) command and a [Compatibility setting](../../settings/compatibility.md). Important: Since SAX file lines are written directly at each statement, if you need to set the BOM and/or end-of-line options, you must call the [`XML SET OPTIONS`](../../commands/xml-set-options) command before the first SAX writing command. - -::: diff --git a/docs/language-legacy/4D Environment/get-database-parameter.md b/docs/language-legacy/4D Environment/get-database-parameter.md index d8665e3dd75a11..d8a02fd5dbde61 100644 --- a/docs/language-legacy/4D Environment/get-database-parameter.md +++ b/docs/language-legacy/4D Environment/get-database-parameter.md @@ -123,7 +123,7 @@ Three synchronization modes are then possible on the client side. The Auto Synch **Possible values**: longint > 1 (seconds) -**Description**: Gets or sets the current cache flush periodicity, expressed in seconds. Modifying this value overrides the **Flush Cache every X Seconds** option in the [XML DECODE](../commands/xml-decode) of the Database settings for the session (it is not stored in the Database settings). +**Description**: Gets or sets the current cache flush periodicity, expressed in seconds. Modifying this value overrides the **Flush Cache every X Seconds** option in the [Database page](../../settings/database.md) of the settings for the session (it is not stored in the settings). diff --git a/docs/language-legacy/4D Environment/set-database-parameter.md b/docs/language-legacy/4D Environment/set-database-parameter.md index 3a369b5d72548a..ce8f35d8c7192a 100644 --- a/docs/language-legacy/4D Environment/set-database-parameter.md +++ b/docs/language-legacy/4D Environment/set-database-parameter.md @@ -130,7 +130,7 @@ Three synchronization modes are then possible on the client side. The Auto Synch **Possible values**: longint > 1 (seconds) -**Description**: Gets or sets the current cache flush periodicity, expressed in seconds. Modifying this value overrides the **Flush Cache every X Seconds** option in the [XML DECODE](../commands/xml-decode) of the Database settings for the session (it is not stored in the Database settings). +**Description**: Gets or sets the current cache flush periodicity, expressed in seconds. Modifying this value overrides the **Flush Cache every X Seconds** option in the [Database page](../../settings/database.md) of the settings for the session (it is not stored in the settings). diff --git a/docs/language-legacy/LDAP/ldap-login.md b/docs/language-legacy/LDAP/ldap-login.md index 2723d57e3bb00f..bc8080729df50a 100644 --- a/docs/language-legacy/LDAP/ldap-login.md +++ b/docs/language-legacy/LDAP/ldap-login.md @@ -32,6 +32,12 @@ displayed_sidebar: docs The **LDAP LOGIN** command opens a read-only connection to the LDAP server specified in the *url* parameter with the *login* and *password* identifiers provided. If accepted by the server, this connection will be used for any LDAP searches executed subsequently in the current process until the [LDAP LOGOUT](../commands/ldap-logout) command is executed (or until the process is closed). +:::info + +LDAP or *Lightweight Directory Access Protocol* is an open standard for accessing and maintaining distributed information services. For more information, please refer to the [Wikipedia page on LDAP](http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol) or the [OpenLDAP Software](http://www.openldap.org/) main page. + +::: + In *url*, pass the full URL of the LDAP server you want to connect to, including the scheme and port (389 by default). This parameter should be compliant with [rfc2255](https://www.ietf.org/rfc/rfc2255.txt). You can open secure connections over TLS by using a *url* that starts with "ldaps" and uses a specific port number (for example "ldaps://svr.ldap.acme.com:1389"). The LDAP server must have an SSL Certificate (at least for Microsoft Active Directory). Using a TLS connection is highly recommended when the password is sent in plain text (see below). @@ -40,9 +46,9 @@ You can open secure connections over TLS by using a *url* that starts with "ldap In *login*, pass the user account on the LDAP server, and in *password*, pass the user password. By default, the *login* can be one of the following login strings, depending on the LDAP Server configuration: * a Distinguished Name (DN), for example "CN=John Smith,OU=users,DC=example,DC=com" -* the user name (CN), for example "CN=John Smith" +* the user name (CN for *Common Name*), for example "CN=John Smith" * an e-mail address, for example "johnsmith@4d.fr" -* an SAM-Account-Name, for example "jsmith". +* a SAM-Account-Name (*Security Account Manager*, logon name for Active Directory), for example "jsmith". Note that accepted values for the *login* are related to the password transmission mode as defined by the *digest* parameter. For example, in a default MS Active Directory configuration: @@ -105,7 +111,6 @@ This example tries to connect to an application: ## See also -*LDAP* [LDAP LOGOUT](../commands/ldap-logout) ## Properties diff --git a/docs/language-legacy/Objects (Forms)/object-is-styled-text.md b/docs/language-legacy/Objects (Forms)/object-is-styled-text.md index 71af510dbe98be..5b9d5047f5a7ad 100644 --- a/docs/language-legacy/Objects (Forms)/object-is-styled-text.md +++ b/docs/language-legacy/Objects (Forms)/object-is-styled-text.md @@ -31,13 +31,13 @@ displayed_sidebar: docs The **OBJECT Is styled text** command returns **True** when the "Multi-style" option is checked for the object(s) designated by the *object* and *\** parameters. -The "Multi-style" option lets you use rich test areas including individual style variations. For more information, refer to *Multi-style (Rich text area)* in the *Design Reference* manual. +The ["Multi-style" form object property](../../FormObjects/properties_Text.md#multi-style) lets you use rich text areas including individual style variations. -Multi-style objects can be managed by programming using the commands of the "*Styled Text*" theme. +Multi-style objects can be managed by programming using the [commands of the *Styled Text* theme](../../commands/theme/Styled_Text.md). Passing the optional *\** parameter indicates that the *object* parameter is an object name (string). If you do not pass this parameter, it indicates that the *object* parameter is a field or variable. In this case, you pass a field or variable reference instead of a string (field or variable object only). -**Note:** The **OBJECT Is styled text** command returns **True** when it is applied to a 4D Write Pro area. +**Note:** The **OBJECT Is styled text** command returns **True** when it is applied to a [4D Write Pro area](../../FormObjects/writeProArea_overview.md). ## Example @@ -53,7 +53,7 @@ A form contains a field represented by two different objects; one of the objects ## See also -*Styled Text* +[*Styled Text* commands](../../commands/theme/Styled_Text.md) ## Properties diff --git a/docs/language-legacy/On a Series/average.md b/docs/language-legacy/On a Series/average.md index e8f25cbba07a2b..b05efae1685f5d 100644 --- a/docs/language-legacy/On a Series/average.md +++ b/docs/language-legacy/On a Series/average.md @@ -32,21 +32,21 @@ displayed_sidebar: docs ## Description -**Average** returns the arithmetic mean (average) of *series*. If *series* is an indexed field, the index is used to find the average. +**Average** returns the arithmetic mean (average) of *series*. If *series* is a field, the command uses to current selection ot the parent table; if it is indexed, the index is used to find the average. You can pass an array (one or two dimensions) in *series*. In this case, the array must be of the Integer, Longint or Real type. This command accepts an optional *attributePath* parameter of the Text type, that you can use if *series* is an object field. It allows you to define the path of the attribute to compute. Use the standard dot notation to define paths to nested attributes, for example "company.address.number". Keep in mind that object attribute names are case-sensitive. Only numeric attribute values are computed. If there are values in the attribute path which are not of a numeric type, they are ignored. -If the command is correctly executed, the OK system variable is set to 1\. If it is interrupted (for example if the user clicks on the **Stop** button of the progress thermometer), the OK variable is set to 0. +If the command is correctly executed, the OK system variable is set to 1. If it is interrupted (for example if the user clicks on the **Stop** button of the progress thermometer), the OK variable is set to 0. ## Example 1 The following example sets the variable *vAverage* that is in the B0 Break area of an output form. The line of code is the object method for *vAverage*. The object method is not executed until the level 0 break: ```4d - vAverage:=Average([Employees] Salary) + vAverage:=Average([Employees]Salary) ``` The following method is called to print the records in the selection and to activate break processing: diff --git a/docs/language-legacy/On a Series/max.md b/docs/language-legacy/On a Series/max.md index fd05bd7b428461..9a5d594c974e79 100644 --- a/docs/language-legacy/On a Series/max.md +++ b/docs/language-legacy/On a Series/max.md @@ -32,7 +32,7 @@ displayed_sidebar: docs ## Description -**Max** returns the maximum value in *series*. If *series* is an indexed field, the index is used to find the maximum value. +**Max** returns the maximum value in *series*. If *series* is a field, the command uses to current selection ot the parent table; if it is indexed, the index is used to find the maximum value. You can pass an array (one or two dimensions) in *series*. In this case, the array must be of the Integer, Longint, Real, or Date type. diff --git a/docs/language-legacy/On a Series/min.md b/docs/language-legacy/On a Series/min.md index 068a3613c68e5d..2d0a12c5a3384d 100644 --- a/docs/language-legacy/On a Series/min.md +++ b/docs/language-legacy/On a Series/min.md @@ -32,7 +32,7 @@ displayed_sidebar: docs ## Description -**Min** returns the minimum value in *series*. If *series* is an indexed field, the index is used to find the minimum value. +**Min** returns the minimum value in *series*. If *series* is a field, the command uses to current selection ot the parent table; if it is indexed, the index is used to find the minimum value. If the *series* selection is empty, **Min** returns 0. diff --git a/docs/language-legacy/On a Series/std-deviation.md b/docs/language-legacy/On a Series/std-deviation.md index 38e3042e04f7c1..c30d43fc70b8fb 100644 --- a/docs/language-legacy/On a Series/std-deviation.md +++ b/docs/language-legacy/On a Series/std-deviation.md @@ -29,7 +29,7 @@ displayed_sidebar: docs ## Description -**Std deviation** returns the standard deviation of *series*. If *series* is an indexed field, the index is used to find the standard deviation. +**Std deviation** returns the standard deviation of *series*. If *series* is a field, the command uses to current selection ot the parent table; if it is indexed, the index is used to find the standard deviation. You can pass an array (one or two dimensions) in *series*. In this case, the array must be of the Integer, Longint or Real type. diff --git a/docs/language-legacy/On a Series/sum-squares.md b/docs/language-legacy/On a Series/sum-squares.md index 263958bf095e2c..49826260245bd6 100644 --- a/docs/language-legacy/On a Series/sum-squares.md +++ b/docs/language-legacy/On a Series/sum-squares.md @@ -29,7 +29,7 @@ displayed_sidebar: docs ## Description -**Sum squares** returns the sum of the squares of *series*. If *series* is an indexed field, the index is used to find the sum of the squares. +**Sum squares** returns the sum of the squares of *series*. If *series* is a field, the command uses to current selection ot the parent table; if it is indexed, the index is used to find the sum of the squares. You can pass an array (one or two dimensions) in *series*. In this case, the array must be of the Integer, Longint or Real type. diff --git a/docs/language-legacy/On a Series/sum.md b/docs/language-legacy/On a Series/sum.md index 947b5ca40ad66f..38d3c1a8238594 100644 --- a/docs/language-legacy/On a Series/sum.md +++ b/docs/language-legacy/On a Series/sum.md @@ -32,7 +32,7 @@ displayed_sidebar: docs ## Description -The **Sum** command returns the sum (total of all values) for *series*. If *series* is an indexed field, the index is used to total the values. +The **Sum** command returns the sum (total of all values) for *series*. If *series* is a field, the command uses to current selection ot the parent table; if it is indexed, the index is used to total the values. You can pass an array (one or two dimensions) in *series*. In this case, the array must be of the Integer, Longint or Real type. diff --git a/docs/language-legacy/On a Series/variance.md b/docs/language-legacy/On a Series/variance.md index 6f412fd6c0263c..1679d0fc60251c 100644 --- a/docs/language-legacy/On a Series/variance.md +++ b/docs/language-legacy/On a Series/variance.md @@ -29,7 +29,7 @@ displayed_sidebar: docs ## Description -**Variance** returns the variance for *series*. If *series* is an indexed field, the index is used to find the variance. +**Variance** returns the variance for *series*. If *series* is a field, the command uses to current selection ot the parent table; if it is indexed, the index is used to find the variance. You can pass an array (one or two dimensions) in *series*. In this case, the array must be of the Integer, Longint or Real type. diff --git a/docs/language-legacy/Printing/print-selection.md b/docs/language-legacy/Printing/print-selection.md index d334b4d7854d84..30d3811d2e512c 100644 --- a/docs/language-legacy/Printing/print-selection.md +++ b/docs/language-legacy/Printing/print-selection.md @@ -47,7 +47,19 @@ During printing, the output form method and/or the form’s object methods are e You can check whether **PRINT SELECTION** is printing the first header by testing [Before selection](../commands/before-selection) during an On Header event. You can also check for the last footer, by testing [End selection](../commands/end-selection) during an On Printing Footer event. For more information, see the description of these commands, as well as those of [Form event code](../commands/form-event-code) and [Level](../commands/level). -To print a sorted selection with subtotals or breaks using **PRINT SELECTION**, you must first sort the selection. Then, in each Break area of the report, include a variable with an object method that assigns the subtotal to the variable. You can also use statistical and arithmetical functions like [Sum](../commands/sum) and [Average](../commands/average) to assign values to variables. For more information, see the descriptions of [Subtotal](../commands/subtotal), [BREAK LEVEL](../commands/break-level) and [ACCUMULATE](../commands/accumulate). +To print a sorted selection with subtotals or breaks using **PRINT SELECTION**, you must first sort the selection. Then, in each Break area of the report, include a variable with an object method that assigns the subtotal to the variable. For more information, see the descriptions of [Subtotal](../commands/subtotal), [BREAK LEVEL](../commands/break-level) and [ACCUMULATE](../commands/accumulate). + + +:::note + +You can use [statistical commands](../../commands/theme/On_a_Series.md) like [Sum](../commands/sum) and [Average](../commands/average) to assign values to variables. When statistical functions are used in a report, they behave in a specific way because the report itself must load each record. When you use these functions in a report, the values that are returned are reliable only at break level 0, and only when break processing is turned on. This means that they are useful only at the end of a report, after all the records have been processed. You would use these functions only in an object method for a non-enterable area that is included in the B0 Break area. + + +::: + + + + :::warning diff --git a/docs/language-legacy/Structure Access/is-field-number-valid.md b/docs/language-legacy/Structure Access/is-field-number-valid.md index 7e503daec18c0b..b4b1bbb5d59dbc 100644 --- a/docs/language-legacy/Structure Access/is-field-number-valid.md +++ b/docs/language-legacy/Structure Access/is-field-number-valid.md @@ -34,6 +34,24 @@ displayed_sidebar: docs This command can be used to detect any field deletions, which create gaps in the sequence of field numbers. +## Example + +It is possible to delete 4D tables and fields. You must take this possibility into account in algorithms used for counting tables and fields. It is necessary to use algorithms combining the `Get last table number` and `Get last field number`, as well as `Is table number valid` and `Is field number valid` commands. The following is an example of this type of algorithm: + +```4d + var $thetable; $thefield : Integer + For($thetable;1;Get last table number) + If(Is table number valid($thetable)) + For($thefield;1;Get last field number($thetable)) + If(Is field number valid($thetable;$thefield)) + ... `The field exists and is valid + End if + End for + End if + End for +``` + + ## See also [Last table number](../commands/last-table-number) diff --git a/docs/language-legacy/Structure Access/is-table-number-valid.md b/docs/language-legacy/Structure Access/is-table-number-valid.md index ca12ed69fc9168..bf31d1a90a399b 100644 --- a/docs/language-legacy/Structure Access/is-table-number-valid.md +++ b/docs/language-legacy/Structure Access/is-table-number-valid.md @@ -28,10 +28,11 @@ displayed_sidebar: docs ## Description -The Is table number valid command returns True if the table whose number is passed in the *tableNum* parameter exists in the database and False otherwise. Keep in mind that the command returns False if the table is in the Trash of the Explorer. +The **Is table number valid** command returns True if the table whose number is passed in the *tableNum* parameter exists in the database and False otherwise. Keep in mind that the command returns False if the table is in the Trash of the Explorer. This command can be used to detect any table deletions, which create gaps in the sequence of table numbers. + ## See also [Last table number](../commands/last-table-number) diff --git a/docs/settings/database.md b/docs/settings/database.md index 0d74f51df9085c..9f45beac7dee28 100644 --- a/docs/settings/database.md +++ b/docs/settings/database.md @@ -114,15 +114,44 @@ You use the settings on this tab to configure the cache memory for the database. ![](../assets/en/settings/memory-maximum-size.png) -- **Calculation of adaptive cache not checked**: this mode, you set the size of the memory cache for the database yourself. 4D then displays an entry area that allows setting the memory cache to use as well as information related to the physical memory (RAM available on the machine), the current cache and cache after restart (taking your changes into account). +- **Calculation of adaptive cache not checked**: this mode, you set the size of the memory cache for the database yourself. 4D then displays an entry area that allows setting the memory cache to use as well as information related to the physical memory (RAM available on the machine), the current cache and cache after restart (taking your changes into account). - The size of the memory cache that you enter will be reserved for the 4D database, regardless of the state of machine resources. This setting can be used in certain specific configurations, or when the database is designed to be used on dissimilar systems in terms of memory. In most cases, the adaptive cache offers better performance. +The size of the memory cache that you enter will be reserved for the 4D database, regardless of the state of machine resources. This setting can be used in certain specific configurations, or when the database is designed to be used on dissimilar systems in terms of memory. In most cases, the adaptive cache offers better performance. -- **Flush Cache every ... Seconds/Minutes**: Specifies the time period between each automatic saving of the data cache, i.e., its writing to disk. - 4D saves the data placed in the cache at regular intervals. You can specify any time interval between 1 second and 500 minutes. By default, 4D saves your data every 20 seconds. The application also saves your data to disk each time you change to another environment or exit the application. You can also call the [FLUSH CACHE](../commands/flush-cache) command to trigger the flush at any moment. +- **Flush Cache every ... Seconds/Minutes**: Specifies the time period between each automatic saving of the data cache, i.e., its writing to disk. +4D saves the data placed in the cache at regular intervals. You can specify any time interval between 1 second and 500 minutes. By default, 4D saves your data every 20 seconds. The application also saves your data to disk each time you change to another environment or exit the application. You can also call the [`FLUSH CACHE`](../commands/flush-cache) command to trigger the flush at any moment. - When you anticipate heavy data entry, consider setting a short time interval between saves. In case of a power failure, you will only lose the data entered since the previous save (if the database is running without a log file). +When you anticipate heavy data entry, consider setting a short time interval between saves. In case of a power failure, you will only lose the data entered since the previous save (if the database is running without a log file). - If there is a noticeable slowing down of the database each time the cache is flushed, you need to adjust the frequency. This slowness means that a huge amount of records is being saved. A shorter period between saves would therefore be more efficient since each save would involve fewer records and hence be faster. - - By default, 4D displays a small window when the cache is flushed. If you do not want this visual reminder, you can uncheck the **Flushing progress** option on the [Interface page](./interface.md). +If there is a noticeable slowing down of the database each time the cache is flushed, you need to adjust the frequency. This slowness means that a huge amount of records is being saved. A shorter period between saves would therefore be more efficient since each save would involve fewer records and hence be faster. + +By default, 4D displays a small window when the cache is flushed. If you do not want this visual reminder, you can uncheck the **Flushing progress** option on the [Interface page](./interface.md). + +:::note + +You can modify temporary the cache flush frequency using the [`Cache flush periodicity` selector of the `SET DATABASE PARAMETER` command](../commands/set-database-parameter#cache-flush-periodicity-95). + +::: + + + + +### Managing priorities in database cache + +The 4D database cache includes an automatic priority management mechanism that provides a high level of efficiency and performance for data access. Thanks to this mechanism, when space is needed to load new data in the cache, low priority cached data are released first, while higher priority cached data remain loaded. + +This mechanism is fully automatic and usually, you will not have to worry about it. However, for specific cases it can be customized using a [set of dedicated commands from the "Cache Management" theme](../commands/theme/Cache_Management.md), which allow changing the priority of objects for the entire time the database is running, or temporarily for the current process. Note that these commands must be used carefully since they affect database performance. + +#### Priority management overview + +The Cache manager selects data to remove from the cache as necessary using a priority system. The three kinds of objects that can be loaded in the cache have a different priority: + +- **tables**: all standard field data (numeric, dates, etc.), excluding blobs (see below). Default priority is medium. +- **blobs**: all binary field data (text, picture, object and blobs) stored in the data file. Default priority is the lowest. +- **indexes**: all field indexes, including keyword indexes and composite indexes. Since indexes are frequently accessed, they have a special status in the cache. Default priority is the highest. + +Default priorities usually provide the best performances. However, for specific cases you can customize the cache priorities using two sets of 4D commands: + +- Commands that change the priorities for the whole session and all processes: [`SET TABLE CACHE PRIORITY`](../commands/set-table-cache-priority), [`SET INDEX CACHE PRIORITY`](../commands/set-index-cache-priority), and [`SET BLOBS CACHE PRIORITY`](../commands/set-blobs-cache-priority). These commands should be used in a startup database method. +- Commands that change the priorities only for the current process: [`ADJUST TABLE CACHE PRIORITY`](../commands/adjust-table-cache-priority), [`ADJUST INDEX CACHE PRIORITY`](../commands/adjust-index-cache-priority), and [`ADJUST BLOBS CACHE PRIORITY`](../commands/adjust-blobs-cache-priority). Use these commands to improve the performance of a temporary operation on your database and go back to initial priorities after the operation is finished. These commands are available only on 4D Server or 4D in local mode. + diff --git a/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/legacy-to-import.md b/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/legacy-to-import.md new file mode 100644 index 00000000000000..bada589d97d8f0 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/legacy-to-import.md @@ -0,0 +1,91 @@ +--- +id: legacy-to-import +title: develop-legacy +draft: true +--- + + + + +## Semáforos + +Los semáforos le permiten asegurarse de que dos o más procesos no modifiquen el mismo recurso (archivo, registro...) al mismo tiempo. Solo el proceso que coloca el semáforo puede eliminarlo. + +:::info + +Las [señales](../API/SignalClass.md) también pueden utilizarse para gestionar las interacciones. Las señales le permiten asegurarse de que uno o varios procesos esperarán a que se complete una tarea específica antes de continuar su ejecución. Cualquier proceso puede esperar y/o liberar una señal. + +::: + +### ¿Qué es un semáforo? + +En un programa informático, un semáforo es una herramienta utilizada para proteger acciones que solo deben ser ejecutadas por un único proceso o usuario a la vez. + +En 4D, la necesidad habitual de utilizar semáforos es para modificar un array interproceso: si un proceso está modificando los valores del array, otro proceso no debe poder hacer lo mismo al mismo tiempo. El desarrollador utiliza un semáforo para indicar a un proceso que solo puede ejecutar su secuencia de operaciones si ningún otro proceso está realizando ya las mismas tareas. Cuando un proceso encuentra un semáforo, existen tres posibilidades: + +- Obtiene de inmediato el derecho a pasar +- Espera su turno hasta que obtiene el derecho a pasar +- Continúa su camino, renunciando a ejecutar las tareas. + +Por lo tanto, el semáforo protege partes del código. Solo permite el paso de un proceso a la vez y bloquea el acceso hasta que el proceso que actualmente tiene el derecho de uso renuncia a este derecho liberando el semáforo. + +### Comandos para trabajar con semáforos + +En 4D, usted coloca un semáforo llamando al comando [`Semaphore`](../commands/sempahore). Para liberar un semáforo, llame al comando [`CLEAR SEMAPHORE`](../commands/clear-sempahore). + +El comando [`Semaphore`](../commands/sempahore) tiene un comportamiento muy particular ya que potencialmente realiza dos acciones simultáneamente: + +- Si el semáforo ya está asignado, la función devuelve **True** +- Si el semáforo no está asignado, la función lo asigna al proceso y devuelve **False** al mismo tiempo. + +Esta doble acción realizada por el mismo comando garantiza que ninguna operación externa pueda insertarse entre la prueba del semáforo y su asignación. + +Puede utilizar el comando [`Test semaphore`](../commands/test-semaphore) para saber si un semáforo ya está asignado o no. Este comando se utiliza principalmente como parte de operaciones largas, como el cierre anual de cuentas, donde [`Test semaphore`](../commands/test-semaphore) le permite controlar la interfaz para impedir el acceso a ciertas operaciones, como la adición de datos contables. + +### Cómo utilizar los semáforos + +Los semáforos deben utilizarse según los siguientes principios: + +- Un semáforo debe colocarse y liberarse en el mismo método, +- La ejecución del código protegido por el semáforo debe ser lo más corta posible, +- El código debe temporizarse mediante el parámetro tickCount del comando [`Semaphore`](../commands/sempahore) para esperar la liberación del semáforo. + +Aquí tiene un código típico para utilizar un semáforo: + +```4d + While(Semaphore("MySemaphore";300)) + IDLE + End while + // coloque aquí el código protegido por el semáforo + CLEAR SEMAPHORE("MySemaphore") +``` + +Un semáforo que no se libera puede bloquear parte de la base de datos. Colocar y liberar los semáforos en el mismo método ayuda a eliminar este riesgo. + +Minimizar el código protegido por el semáforo aumenta la fluidez de la aplicación y evita que el semáforo actúe como un cuello de botella. + +Por último, el uso del parámetro opcional *tickCount* del comando [`Semaphore`](../commands/sempahore) es esencial para optimizar la espera de la liberación del semáforo. Con este parámetro, el comando funciona de la siguiente manera: + +- El proceso espera como máximo el número de ticks especificado (300 en el ejemplo) a que el semáforo esté disponible, sin que la ejecución del código pase a la línea siguiente, +- Si el semáforo se libera antes del final de este límite, se asigna inmediatamente al proceso (Semaphore devuelve False) y la ejecución del código se reanuda, +- Si el semáforo no se libera antes del final de este límite, entonces la ejecución del código se reanuda. + +El comando también prioriza las solicitudes estableciendo una cola de espera. De esta manera, el primer proceso que solicite un semáforo será el primero en obtenerlo. Tenga en cuenta que el tiempo de espera se define en función de las particularidades de la aplicación. + +### Semáforos locales o globales + +Existen dos tipos de semáforos en 4D: los semáforos locales y los semáforos globales. + +- Un semáforo local es accesible por todos los procesos de la misma estación de trabajo y únicamente en esa estación. Un semáforo local puede crearse anteponiendo al nombre del semáforo un signo de dólar ($). Los semáforos locales se utilizan para supervisar operaciones entre procesos que se ejecutan en la misma estación de trabajo. Por ejemplo, un semáforo local puede utilizarse para supervisar el acceso a un array interproceso compartido por todos los procesos de su base de datos monousuario o de la estación de trabajo. +- Un semáforo global es accesible para todos los usuarios y todos sus procesos. Los semáforos globales se utilizan para supervisar operaciones entre los usuarios de una base de datos multiusuario. + +Los semáforos globales y locales son idénticos en su lógica. La diferencia reside en su alcance. + +En cliente/servidor, los semáforos globales se comparten entre todos los procesos que se ejecutan en todos los clientes y servidores. Un semáforo local solo se comparte entre los procesos que se ejecutan en la máquina donde se creó. + +En las aplicaciones 4D monousuario, los semáforos globales o locales tienen el mismo alcance porque usted es el único usuario. No obstante, si su base de datos se utiliza en ambas configuraciones, asegúrese de utilizar semáforos globales o locales según lo que desee hacer. + +**Nota:** Recomendamos utilizar semáforos locales cuando necesite un semáforo para gestionar un aspecto local de un cliente de la aplicación, como la interfaz o un array de variables interproceso. Si utiliza un semáforo global en este caso, no solo provocaría intercambios de red innecesarios, sino que también podría afectar innecesariamente a otras máquinas cliente. El uso de un semáforo local evitaría estos efectos secundarios indeseables. + + + \ No newline at end of file diff --git a/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/overview.md b/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/overview.md new file mode 100644 index 00000000000000..793f5e5c9dbd03 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/overview.md @@ -0,0 +1,7 @@ +--- +id: overview +title: 4D database overview +--- + +## Description + diff --git a/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/records.md b/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/records.md new file mode 100644 index 00000000000000..25e1705847e48e --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/records.md @@ -0,0 +1,308 @@ +--- +id: records +title: Records +slug: /Develop/records +displayed_sidebar: docs +--- + + +## Record numbers + +There are three numbers associated with a record: + +- Record number +- Selected record number +- Sequence number + +### Record Number + +The record number is the absolute/physical record number for a record. A record number is automatically assigned to each new record and remains constant for the record until the record is deleted. Record numbers start at zero. They are not unique because record numbers of deleted records are reused for new records. They also change when the database is [compacted](../MSC/compact.md) or [repaired](../MSC/repair.md). + +### Selected Record Number + +The selected record number is the position of the record in the current selection, and so depends on the current selection. If the selection is changed or sorted, the selected record number will probably change. Numbering for the selected record number starts at one (1). + +### Sequence Number + +The sequence number is a unique non-repeating number that may be assigned to a field of a record (via the Autoincrement property, the SQL AUTO_INCREMENT attribute or the [`Sequence number`](../commands/sequence-number) command). It is not automatically stored with each record. It starts by default at 1 and is incremented for each new record that is created. Unlike record numbers, a sequence number is not reused when a record is deleted or when a database is compacted or repaired. Sequence numbers provide a way to have unique ID numbers for records. If a sequence number is incremented during a transaction, the number is not decremented if the transaction is canceled. + +:::note Notes + +- 4D does not carry out any check when you modify the automatic number internal counter of a table using the [`SET DATABASE PARAMETER`](../commands/set-database-parameter) command. If you decrement this counter, the new records created may have numbers that have already been assigned. +- Sequence numbers are not recommended to fill unique ID primary key fields for records. To create unique record IDs, it is strongly recommended to use UUIDs. + +::: + +### Example + +The following tables illustrate the numbers that are associated with records. Each line in the table represents information about a record. The order of the lines is the order in which records would be displayed in an output form. + +- **Data**: The data from a field in each record. For our example, it contains a person’s name. +- **Record Number**: The record’s absolute record number. This is the number returned by the [`Record number`](../commands/record-number) command. +- **Selected Record Number**: The record’s position in the current selection. This is the number returned by the [`Selected record number`](../commands/selected-record-number) command. +- **Sequence Number**: The record’s unique sequence number. This is the number returned by the [`Sequence number`](../commands/sequence-number) command when the record was created. This number is stored in a field. + +#### After the Records Are Entered + +The first table shows the records after they are entered. + +- The default order for the records is by record number. +- The record number starts at 0. +- The selected record number and the sequence number start at 1. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Tess |0| 1| 1| +|Terri| 1 |2 |2| +|Sabra| 2|3| 3| +|Sam| 3 |4 |4| +|Lisa| 4| 5 |5| + +Note: The records remain in the default order after a command changes the current selection without reordering it; for example, after the **Show All** menu command is chosen in the Design environment, or after the [`ALL RECORDS`](../commands/all-records) command is executed. + +#### After the Records Are Sorted + +The next table shows the same records sorted by name. + +- The same record number remains associated with each record. +- The selected record numbers reflect the new position of the records in the sorted selection. +- The sequence numbers never change, since they were assigned when each record was created and are stored in the record. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Lisa| 4| 1 |5| +|Sabra| 2|2| 3| +|Sam| 3 |3 |4| +|Terri| 1 |4 |2| +|Tess |0| 5| 1| + + +#### After a Record Is Deleted + +The following table shows the records after Sam is deleted. + +- Only the selected record numbers have changed. Selected record numbers reflect the order in which the records are displayed. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Lisa| 4| 1 |5| +|Sabra| 2|2| 3| +|Terri| 1 |3 |2| +|Tess |0| 4| 1| + + +#### After a Record Is Added + +The next table shows the records after a new record has been added for Liz. + +- A new record is added to the end of the current selection. +- Sam’s record number is reused for the new record. +- The sequence number continues to increment. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Tess |0| 1| 1| +|Terri| 1 |2 |2| +|Sabra| 2|3| 3| +|Lisa| 4| 4 |5| +|Liz |3| 5| 6| + +#### After the Selection is Changed and Sorted + +The following table shows the records after the selection was reduced to three records and then sorted. + +- Only the selected record number associated with each record changes. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Sabra| 2|1| 3| +|Liz |3| 2| 6| +|Terri| 1 |3 |2| + +## Record Stack + +The [`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) commands allow you to put (“push”) records onto the record stack, and to remove (“pop”) them from the stack. + +Each process has its own record stack for each table. 4D maintains the record stacks for you. Each record stack is a last-in-first-out (LIFO) stack. Stack capacity is limited by memory. + +[`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) should be used with discretion. Each record that is pushed uses part of free memory. Pushing too many records can cause an out-of-memory or stack full condition. + +4D clears the stack of any unpopped records when you return to the menu at the end of execution of your method. + +[`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) are useful when you want to examine records in the same file during data entry. To do this, you push the record, search and examine records in the file (copy fields into variables, for example), and finally pop the record to restore the record. + +While entering a record, if you have to check a multiple field unique value, use the [`SET QUERY DESTINATION`](../commands/set-quer-destination) command. This will save you the calls to [`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) that you were making before and after the call to QUERY in order to preserve the data entered in the current record. [`SET QUERY DESTINATION`](../commands/set-quer-destination) allows you to make a query that does not change the selection nor the current record. + +## Record locking + +4D and 4D Server automatically manage databases by preventing multi-user or multi-process conflicts. Two users or two processes cannot modify the same record or object at the same time. However, the second user or process can have read-only access to the record or object at the same time. + +There are several reasons for using the multi-user commands: + +- Modifying records by using the language. +- Using a custom user interface for multi-user operations. +- Saving related modifications inside a transaction. + +There are three important concepts to be aware of when using commands in a multi-processing database: + +1. In a process, each table is in either a read-only or a read/write state. +2. Records become locked when they are loaded and unlocked when they are unloaded. +3. A locked record cannot be modified. + +As a convention in the following sections, the person performing an operation on the multi-user database is referred to as the **local user**. Other people using the database are referred to as the **other users**. The discussion is from the perspective of the local user. Also, from a multi-process perspective, the process executing an operation on the database is the **current process**. Any other executing process is referred to as **other processes**. The discussion is from the point of view of the current process. + +### Locked Records + +A locked record cannot be modified by the local user or the current process. A locked record can be loaded, but cannot be modified. A record is locked when one of the other users or processes has successfully loaded the record for modification, or when the record is stacked. Only the user who is modifying the record sees that record as unlocked. All other users and processes see the record as locked, and therefore unavailable for modification. A table must be in a read/write state for a record to be loaded unlocked. + +### Read-Only and Read/Write States + +Each table in a database is in either a read/write or a read-only state for each user and process of the database. **Read-only** means that records for the table can be loaded but not modified. **Read/write** means that records for the table can be loaded and modified if no other user has locked the record first. + +Note that if you change the status of a table, the change takes effect for the next record loaded. If there is a record currently loaded when you change the table’s status, that record is not affected by the status change. + +#### Read-Only State + +When a table is read-only and a record is loaded, this record is always locked. In other words, locked records can be displayed, printed, and otherwise used, but they cannot be modified. + +Note that the read-only state applies only to editing existing records. A read-only state does not affect the creation of new records. You can still add records to a read-only table using [`CREATE RECORD`](../commands/create-record) and [`ADD RECORD`](../commands/add-record), or the menu commands of the Design environment (in this case, the records being created are locked for all other users/processes). Note that the [`ARRAY TO SELECTION`](../commands/array-to-selection) command is not affected by the read-only state since it can both create and modify records. + +4D automatically sets a table to read-only for commands that do not require write access to records. These commands are: [`DISPLAY SELECTION`](../commands/display-selection), [`DISTINCT VALUES`](../commands/distinct-values), [`EXPORT DIF`](../commands/export-dif), [`EXPORT SYLK`](../commands/export-sylk), [`EXPORT TEXT`](../commands/export-text), [`PRINT SELECTION`](../commands/print-selection), [`PRINT LABEL`](../commands/print-label), [`QR REPORT`](../commands/qr-report), [`SELECTION TO ARRAY`](../commands/selection-to-array), [`SELECTION RANGE TO ARRAY`](../commands/selection-range-to-array). + +You can find out the state of a table at any time using the [`Read only state`](../commands/read-only-state) function. + +Before executing any of these commands, 4D saves the current state of the table (read-only or read/write) for the current process. After the command has executed, this state is restored. + +#### Read/Write State + +When a table is read/write and a record is loaded, the record will become unlocked if no other user has locked the record first. If the record is locked by another user, the record is loaded as a locked record that cannot be modified by the local user. + +A table must be set to read/write and the record loaded for it to become unlocked and thus modifiable. + +If a user loads a record from a table in read/write mode, no other users can load that record for modification. However, other users can add records to the table, either through the [`CREATE RECORD`](../commands/create-record) and [`ADD RECORD`](../commands/add-record) commands or manually in the Design environment. + +Read/write is the default state for all tables when a database is opened and a new process is started. + +#### Changing the Status of a Table + +You can use the [`READ ONLY`](../commands/read-only) and [`READ WRITE`](../commands/read-write) commands to change the state of a table. If you want to change the state of a table in order to make a record read-only or read/write, you must execute the command before this record is loaded. Any record that is already loaded is not affected by the [`READ ONLY`](../commands/read-only) and [`READ WRITE`](../commands/read-write) commands. + +Each process has its own state (read-only or read/write) for each table in the database. + +By default, if you do not use the READ ONLY command, all tables are in read/write mode. + +### Loading, Modifying and Unloading Records + +Before the local user can modify a record, the table must be in the read/write state and the record must be loaded and unlocked. + +Any of the commands that loads a current record (if there is one) — such as [`NEXT RECORD`](../commands/next-record), [`QUERY`](../commands/query), [`ORDER BY`](../commands/order-by), [`RELATE ONE`](../commands/relate-one), etc. — sets the record state as locked or unlocked. The record is loaded according to the current state of its table (read-only or read/write) and its availability. A record may also be loaded for a related table by any of the commands that cause an automatic relation to be established. + +If a table is in the read-only state for a process or a user, then this table's records are loaded in read-only mode, which means they cannot be modified or deleted by this process or user. This is recommended for viewing or retrieving data because it does not prevent other users or processes from accessing the records of this table in read/write mode if necessary. + +If a table is in the read/write state for a process or a user, then any record from this table is also loaded in read/write mode, but only if no other user or process has already locked this record. If a record is successfully loaded in read/write mode, it is unlocked for the current process or user (it can be modified and saved) and is locked for all other users or processes. A table must be put into the read/write state before loading a record for modification and then saving it. + +If the record is to be modified, you use the Locked function to test whether or not a record is locked by another user. If a record is locked (Locked returns True), load the record with the [`LOAD RECORD`](../commands/load-record) command and again test whether or not the record is locked. This sequence must be continued until the record becomes unlocked (Locked returns False). + +When modifications to be made to a record are finished, the record must be released (and therefore unlocked for the other users) with [`UNLOAD RECORD`](../commands/unload-record). If a record is not unloaded, it will remain locked for all other users until a different current record is selected. Changing the current record of a table automatically unlocks the previous current record. You need to explicitly call [`UNLOAD RECORD`](../commands/unload-record) if you do not change the current record. This discussion applies to existing records. When a new record is created, it can be saved regardless of the state of the table to which it belongs. + +:::note + +When it is used in a transaction, the [`UNLOAD RECORD`](../commands/unload-record) command unloads the current record only for the process that manages the transaction. For other processes, the record stays locked as long as the transaction has not been validated (or cancelled). + +::: + +Use the [`LOCKED BY`](../commands/locked-by) command to see which user and/or process have locked a record. + +::: + +A good practice is to place all tables in read-only mode when each process is started (using the syntax [`READ ONLY(*)`](../commands/read-only)) then put each table in read/write mode only when necessary. Access to tables in read-only mode is faster and more memory-efficient. Moreover, changing the state of a table is optimized in client/server mode because it does not cause any additional network traffic: information is only sent to the server when executing a command that requires adequate access to the table. + +::: + +### Loops to Load Unlocked Records + +The following example shows the simplest loop with which to load an unlocked record: + +```4d + READ WRITE([Customers])//Set the table’s state to read/write + Repeat//Loop until the record is unlocked + LOAD RECORD([Customers])//Load record and set locked status + Until(Not(Locked([Customers]))) + //Do something to the record here + READ ONLY([Customers])//Set the table’s state to read-only +``` + +The loop continues until the record is unlocked. + +A loop like this is used only if the record is unlikely to be locked by anyone else, since the user would have to wait for the loop to terminate. Thus, it is unlikely that the loop would be used as is unless the record could only be modified by means of a method. + +The following example uses the previous loop to load an unlocked record and modify the record: + +```4d + READ WRITE([Inventory]) + Repeat //Loop until the record is unlocked + LOAD RECORD([Inventory]) //Load record and set it to locked + Until(Not(Locked([Inventory]))) + [Inventory]Part Qty:=[Inventory]Part Qty 1 //Modify the record + SAVE RECORD([Inventory]) //Save the record + UNLOAD RECORD([Inventory]) //Let other users modfiy it + READ ONLY([Inventory]) +``` + + +The [`MODIFY RECORD`](../commands/modify-record) command automatically notifies the user if a record is locked, and prevents the record from being modified. The following example avoids this automatic notification by first testing the record with the Locked function. If the record is locked, the user can cancel. + +This example efficiently checks to see if the current record is locked for the table [Commands]. If it is locked, the process is delayed by the procedure for one second. This technique can be used both in a multi-user or multi-process situation: + +```4d + Repeat + READ ONLY([Commands])//You do not need read/write right now + QUERY([Commands]) + //If the search was completed and some records were returned + If((OK=1) & (Records in selection([Commands])>0)) + READ WRITE([Commands])//Set the table to read/write state + LOAD RECORD([Commands]) + While(Locked([Commands]) & (OK=1)) `If the record is locked, + //loop until the record is unlocked + //Who is the record locked by? + LOCKED BY([Commands];$Process;$User;$SessionUser;$Name) + If($Process=-1)//Has the record been deleted? + ALERT("The record has been deleted in the meantime.") + OK:=0 + Else + If($User="")//Are you in single-user mode + $User:="you" + End if + CONFIRM("The record is already used by "+$User+" in the "+$Name+" Process.") + If(OK=1)//If you want to wait for a few seconds + DELAY PROCESS(Current process;120)//Wait for a few seconds + LOAD RECORD([Commands])//Try to load the record + End if + End if + End while + If(OK=1)//The record is unlocked + MODIFY RECORD([Commands])//You can modify the record + UNLOAD RECORD([Commands]) + End if + READ ONLY([Commands])//Switch back to read-only + OK:=1 + End if + Until(OK=0) +``` + + +### Using Commands in Multi-user or Multi-process Environment + +A number of commands in the language perform specific actions when they encounter a locked record. They behave normally if they do not encounter a locked record. + +Here is a list of these commands and their actions when a locked record is encountered. + +- [`MODIFY RECORD`](../commands/modify-record): Displays a dialog box stating that the record is in use. The record is not displayed, therefore the user cannot modify the record. In the Design environment, the record is shown in read-only state. +- [`MODIFY SELECTION`](../commands/modify-selection): Behaves normally except when the user double-clicks a record to modify it. [`MODIFY SELECTION`](../commands/modify-selection) displays dialog box stating that the record is in use and then allows read-only access to the record. +- [`APPLY TO SELECTION`](../commands/apply-to-selection): Loads a locked record, but does not modify it. [`APPLY TO SELECTION`](../commands/apply-to-selection) can be used to read information from the table without special care. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`DELETE SELECTION`](../commands/delete-selection): Does not delete any locked records; it skips them. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`DELETE RECORD`](../commands/delete-record): This command is ignored if the record is locked. No error is returned. You must test that the record is unlocked before executing this command. +- [`SAVE RECORD`](../commands/save-record): This command is ignored if the record is locked. No error is returned. You must test that the record is unlocked before executing this command. +- [`ARRAY TO SELECTION`](../commands/array-to-selection): Does not save any locked records. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`GOTO RECORD`](../commands/goto-record): Records in a multi-user/multi-process database may be deleted and added by other users, therefore the record numbers may change. Use caution when directly referencing a record by number in a multi-user database. +- [**Sets**](./sets.md): Take special care with sets, as the information that the set was based on may be changed by another user or process. diff --git a/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/sets.md b/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/sets.md new file mode 100644 index 00000000000000..f1e42b3cc1c863 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/sets.md @@ -0,0 +1,168 @@ +--- +id: sets +title: Sets +slug: /Develop/sets +displayed_sidebar: docs +--- + + +Sets offer you a powerful, swift means for manipulating record selections. Besides the ability to create sets, relate them to the current selection, and store, load, and clear sets, 4D offers three standard set operations: + +- Intersection +- Union +- Difference. + + +## Sets and the Current Selection + +A set is a compact representation of a selection of records. The idea of sets is closely bound to the idea of the current selection. Sets are generally used for the following purposes: + +- To save and later restore a selection when the order does not matter +- To access the selection a user made on screen (the `UserSet`) +- To perform a logical operation between selections. + +The current selection is a list of references that points to each record that is currently selected. The list exists in memory. Only currently selected records are in the list. A selection doesn’t actually contain the records, but only a list of references to the records. Each reference to a record takes 4 bytes in memory. When you work on a table, you always work with the records in the current selection. When a selection is sorted, only the list of references is rearranged. There is only one current selection for each table inside a process. + +Like a current selection, a set represents a selection of records. A set does this by using a very compact representation for each record. Each record is represented by one bit (one-eighth of a byte). Operations using sets are very fast, because computers can perform operations on bits very quickly. A set contains one bit for every record in the table, whether or not the record is included in the set. In fact, each bit is equal to 1 or 0, depending on whether or not the record is in the set. + +Sets are very economical in terms of RAM space. The size of a set, in bytes, is always equal to the total number of records in the table divided by 8. For example, if you create a set for a table containing 10,000 records, the set takes up 1,250 bytes, which is about 1.2K in RAM. + +There can be many sets for each table. In fact, sets can be saved to disk separately from the database. To change a record belonging to a set, first you must use the set as the current selection, then modify the record or records. + +A set is never in a sorted order—the records are simply indicated as belonging to the set or not. On the other hand, a named selection is in sorted order, but it requires more memory in most cases. For more information about named selections, see the Named Selections section. + +A set "remembers" which record was the current record at the time the set was created. The following table compares the concepts of the current selection and of sets: + +|Comparison|Current Selection|Sets| +|---|---|---| +|Number per table|1|0 to many| +|Sortable|Yes|No| +|Can be saved on disk|No|Yes| +|RAM per record(in bytes)|Number of selected records * 4|Total number of records/8| +|Combinable| No| Yes| +|Contains current record| Yes| Yes, as of the time the set was created| + +When you create a set, it belongs to the table from which you created it. Set operations can be performed only between sets belonging to the same table. + +Sets are independent from the data. This means that after changes are made to a file, a set may no longer be accurate. There are many operations that can cause a set to be inaccurate. For example, if you create a set of all the people from New York City, and then change the data in one of those records to “Boston” the set would not change, because the set is just a representation of a selection of records. Deleting records and replacing them with new ones also changes a set, as well as compacting the data. Sets can be guaranteed to be accurate only as long as the data in the original selection has not been changed. + +## Process and Interprocess Sets + +You can have the following three types of sets: + +- **Process sets**: A process set can only be accessed by the process in which it has been created. `LockedSet` is a process set. Process sets are cleared as soon as the process method ends. Process sets do not need any special prefix in the name. +- **Interprocess sets**: A set is an interprocess set if the name of the set is preceded by the symbols (<>) — a “less than” sign followed by a “greater than” sign. An interprocess set is “visible” to all the processes of the database. +In client/server mode, an interprocess set is “visible” to processes of the machine where it was created (client or server). +The name of an interprocess set must be unique in the database. +- **Local Sets/Client Sets**: Local/client sets are intended for use in client/server mode. The name of a local/client set is always preceded by the dollar sign ($) -- except for the UserSet system set. Unlike other types of sets, a local/client set is stored on the client machine. + +:::note Notes + +- The maximum size of a set name is 255 characters (excluding <> and $ symbols). +- For more information about the use of sets in client/server mode, please refer to 4D Server, Sets and Named Selections. + +::: + + +## Visibility of Sets + +The following table indicates the principles concerning the visibility of sets depending on their scope and where they were created: + + + +||Client Process|Other processes on the same client|Other clients|Server process|Other processes on the server| +|---|---|---|---|---|---| +|Creation in a client process |||||| +|$test|X ||||| +|test | X||| X(Trigger) || +|<>test | X|X |||| +|Creation in a server process|||||| +|$test|||| X|| +|test ||||X|| +|<>test||||X| X| + + +## Sets and Transactions + +A set can be created inside a [transaction](./transactions.md). It is possible to create a set of the records created inside a transaction and a set of records created or modified outside of a transaction. When the transaction ends, the set created during the transaction should be cleared, because it may not be an accurate representation of the records, especially if the transaction was canceled. + +## Example + +The following example deletes duplicate records from a table which contains information about people. A For...End for loop moves through all the records, comparing the current record to the previous record. If the name, address, and zip code are the same, then the record is added to a set. At the end of the loop, the set is made the current selection and the (old) current selection is deleted: + +```4d + CREATE EMPTY SET([People];"Duplicates") + // Create an empty set for duplicate records + ALL RECORDS([People]) + // Select all records + // Sort the records by ZIP, address, and name so + // that the duplicates will be next to each other + ORDER BY([People];[People]ZIP;>;[People]Address;>;[People]Name;>) + // Initialize variables that hold the fields from the previous record + $Name:=[People]Name + $Address:=[People]Address + $ZIP:=[People]ZIP + // Go to second record to compare with first + NEXT RECORD([People]) + For($i;2;Records in table([People])) + // Loop through records starting at 2 + // If the name, address, and ZIP are the same as the + // previous record then it is a duplicate record. + If(([People]Name=$Name) & ([People]Address=$Address) & ([People]ZIP=$ZIP)) + // Add current record (the duplicate) to set + ADD TO SET([People];"Duplicates") + Else + // Save this record’s name, address, and ZIP for comparison with the next record + $Name:=[People]Name + $Address:=[People]Address + $ZIP:=[People]ZIP + End if + // Move to the next record + NEXT RECORD([People]) + End for + // Use duplicate records that were found + USE SET("Duplicates") + // Delete the duplicate records + DELETE SELECTION([People]) + // Remove the set from memory + CLEAR SET("Duplicates") +``` + +As an alternative to immediately deleting records at the end of the method, you could display them on screen or print them, so that a more detailed comparison can be made. + + +## The UserSet System Set + +4D maintains a system set named `UserSet`, which automatically stores the most recent selection of records highlighted on screen by the user. Thus, you can display a group of records with [`MODIFY SELECTION`](../commands/modify-selection) or [`DISPLAY SELECTION`](../commands/display-selection), ask the user to select from among them and turn the results of that manual selection into a selection or into a set that you name. + +::info 4D Server + +Although its name does not begin with the character "$", the `UserSet` system set is a client set. So, when using [`INTERSECTION`](../commands/intersection), [`UNION`](../commands/union) and [`DIFFERENCE`](../commands/difference), make sure you compare `UserSet` only to client sets. + +::: + +There is only one `UserSet` for a [process](../Develop/processes.md). Each table does not have its own `UserSet`. `UserSet` becomes "owned" by a table when a selection of records is displayed for the table. + +4D manages the `UserSet` set for list forms displayed in Design mode or using the [`MODIFY SELECTION`](../commands/modify-selection) or [`DISPLAY SELECTION`](../commands/display-selection) commands. However, this mechanism is not active for [subforms](../FormObjects/subform_overview.md). + +The following method illustrates how you can display records, allow the user to select some of them, and then use UserSet to display the selected records: + +```4d + // Display all records and allow user to select any number of them. + // Then display this selection by using UserSet to change the current selection. + FORM SET OUTPUT([People];"Display") // Set the output layout + ALL RECORDS([People]) // Select all people + ALERT("Press Ctrl or Command and Click to select the people required.") + DISPLAY SELECTION([People]) // Display the people + USE SET("UserSet") // Use the people that were selected + ALERT("You chose the following people.") + DISPLAY SELECTION([People]) // Display the selected people +``` + +## The LockedSet System Set + +The [`APPLY TO SELECTION`](../commands/apply-to-selection), [`DELETE SELECTION`](../commands/delete-selection), [`ARRAY TO SELECTION`](../commands/array-to-selection) and [`JSON TO SELECTION`](../commands/json-to-selection) commands create a set named `LockedSet` when used in a multi-processing environment. + +Query commands also create a `LockedSet` system set when they find locked records in the 'query and lock' context (see the [`SET QUERY AND LOCK`](../commands/set-query-and-lock) command). + +`LockedSet` indicates which records were locked during the execution of the command. \ No newline at end of file diff --git a/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/xml.md b/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/xml.md new file mode 100644 index 00000000000000..6691cfcb0e545c --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/Develop-legacy/xml.md @@ -0,0 +1,157 @@ +--- +id: xml +title: XML Processing +slug: /Develop/XML +displayed_sidebar: docs +--- + + +## Overview of XML Commands + +### XML, DOM, and SAX + +The [**XML** theme](../commands/theme/XML.md) groups together the generic XML "utilities" commands of 4D. These are option- and error-management commands. + +4D also offers two separate sets of XML commands: [**DOM**](../commands/theme/XML_DOM.md) (Document Object Model) and [**SAX**](../commands/theme/XML_SAX.md) (Simple API XML) are two different parsing modes for XML documents. + +- The DOM mode parses an XML source and builds its structure (its "tree") in memory. Because of this, access to each element of the source is extremely fast. However, since the entire tree structure is stored in memory, the processing of large XML documents may lead to the memory capacity being exceeded and thus provoke errors. +- The SAX mode does not build a tree structure in memory. In this mode, "events" (such as the start and end of an element) are generated when parsing the source. This mode lets you parse XML documents of any size, regardless of the amount of memory available. + +### References + +http://www.saxproject.org/?selected=event
+http://www.w3schools.com/xml/ + +:::note + +For XML support, 4D uses the [Xerces.dll library](../Notes/updates.md#library-table) developed by the Apache Foundation company. + +::: + + +### Preemptive mode + +XML references created by a [preemptive process](../Develop/preemptive.md) can only be used in that specific process. Conversely, XML references created by a cooperative process can be used by any other cooperative process, but cannot be used by any preemptive process. + + +### Character Sets + +The following character sets are supported by the XML DOM and XML SAX commands of 4D: + +- ASCII +- UTF-8 +- UTF-16 (Big/Small Endian) +- UCS4 (Big/Small Endian) +- EBCDIC code pages IBM037, IBM1047 and IBM1140 encodings, +- ISO-8859-1 (or Latin1) +- Windows-1252. + + +### Glossary + +This non-exhaustive list details the main XML concepts used by the commands and functions of 4D. + +- **Attribute**: an XML sub-tag associated with an element. An attribute always contains a name and a value. +- **Child**: In an XML structure, an element in a level directly below another. +- **DTD**: *Document Type Declaration*. The DTD records the set of specific rules and properties that the XML must follow. These rules define, more particularly, the name and content of each tag as well as its context. This formalization of the elements can be used to check whether an XML document is in compliance (in which case, it is declared “valid”). The DTD may be included in the XML document (internal DTD) or in a separate document (external DTD). Note that the DTD is not mandatory. +- **Element**: an XML tag. An element always contains a name and a value. Optionally, an element may contain attributes. +- **ElementRef**: XML reference used by the 4D XML commands to specify an XML structure. This reference is made up of 8 coded characters in hexadecimal form, which means that its length is 32 characters on a 64-bit system. It is recommended to declare XML references as Text. +- **Parent**: In an XML structure, an element in a level directly above another. +- **Parsing, parser**: The act of analyzing the contents of a structured object in order to extract useful information. +- **Root**: An element located at the first level of an XML structure. +- **Sibling**: An element at the same level as another. +- **Structure**: structured XML object. This object can be a document, a variable, or an element. +- **Validation**: An XML document is “validated” by the parser when it is “well-formed” and in compliance with the DTD specifications. +- **Well-formed**: An XML document is declared “well-formed” by the parser when it complies with the generic XML specifications. +- **XML**: eXtensible Markup Language. A computerized data exchange standard enabling the transfer of data as well as their structure. The XML language is based on the use of tags and a specific syntax, in keeping with the HTML language. However, unlike the latter, the XML language allows the definition of customized tags. +- **XSL**: eXtensible Stylesheet Language. A language permitting the definition of style sheets used to process and display the contents of an XSL document. + + +## XML DOM Commands + +### Creating, opening and closing XML documents via DOM + +Objects created, modified or parsed by the [4D XML DOM commands](../commands/theme/XML_DOM.md) can be text, URLs, documents or BLOBs. The DOM commands used for opening XML objects in 4D are [`DOM Parse XML source`](../commands/dom-parse-xml-source) and [`DOM Parse XML variable`](../commands/dom-parse-xml-variable). + +Many commands then let you read, parse and write the elements and attributes. Errors are recovered using the [`XML GET ERROR`](../commands/xml-get-error) command. Do not forget to call the [`DOM CLOSE XML`](../commands/dom-close-xml) command to close the source in the end. + +Note about use of XML BLOB parameters: For historical reasons, XML commands such as [`DOM Parse XML variable`](../commands/dom-parse-xml-variable) accept BLOB type parameters. However, it is highly recommended to store XML structures as Text. The use of BLOBs is reserved for processing binary data. In conformity with XML specifications, binary data are automatically encoded in Base64, even when the BLOB contains text. + + +### Support of XPath notation + +Several XML DOM commands ([`DOM Create XML element`](../commands/dom-create-xml-element), [`DOM Find XML element`](../commands/dom-find-xml-element), [`DOM Create XML element arrays`](../commands/dom-create-xml-element-arrays) and [`DOM SET XML ELEMENT VALUE`](../commands/dom-set-xml-element-value)) support some XPath expressions for accessing XML elements. + +XPath notation comes from the XPath language, designed to navigate within XML structures. It allows the setting of elements directly within an XML structure via a "pathname" type syntax, without necessarily having to indicate the complete pathname in order to reach it. + +For example, given the following structure: + +```xml + + + + + + + +``` + +XPath notation allows you to access element 3 using the */RootElement/Elem1/Elem2/Elem3* syntax. + +4D also accepts indexed XPath elements using the *Element[ElementNum]* syntax. For example, given the following structure: + +```xml + + + aaa + bbb + ccc + + +``` + +XPath notation allows you to access the "ccc" value using the */RootElement/Elem1/Elem2[3]* syntax. + +For a comprehensive list of supported XPath expressions, refer to the [`DOM Find XML element`](../commands/dom-find-xml-element) command description. + +:::note Compatibility + +Starting with 4D 18 R3, the XPath implementation has been modified to be more compliant and to support a wider set of expressions. If you want to benefit from the extended features in your converted databases, you need to select the **Use standard XPath** option of the [Compatibility page](../settings/compatibility.md). + +::: + +### Error Handling + +Many functions in this theme return an XML element reference. If an error occurs during function execution (for example, if the root element reference is not valid), the *OK* variable is set to 0 and an error is generated. + +In addition, the reference returned in this case is a sequence of 32 zero "0" characters. + + +## XML SAX Commands + +### Creating, opening and closing XML documents via SAX + +The [XML SAX commands](../commands/theme/XML_SAX.md) work with the standard document references of 4D (**DocRef**, a Time type reference). It is therefore possible to use these commands jointly with the 4D commands used to manage documents, such as [`SEND PACKET`](../commands/send-packet) or [`Append document`](../commands/append-document). + +The creation and opening of XML documents by programming is carried out using the [`Create document`](../commands/create-document) and [`Open document`](../commands/open-document) commands. Subsequently, the use of an XML command with these documents will cause the automatic activation of XML mechanisms such as encoding. For instance, the `` header will be written automatically in the document. + +:::note + +Documents read by SAX commands must be opened in read-only mode by the [`Open document`](../commands/open-document) command. This avoids any conflict between 4D and the Xerces library when you open "regular" and XML documents simultaneously. If you execute a SAX parsing command with a document open in read-write mode, an alert message is displayed and parsing is impossible. + +::: + +Closing an XML document must be carried out using the [`CLOSE DOCUMENT`](../commands/close-document) command. If any XML elements were open, they will be closed automatically. + +### About end-of-line characters and BOM management + +When writing SAX documents, 4D uses the following default settings for end-of-line characters and BOM (byte order mask) usage: + +- CRLF characters on Windows and LF on macOS for end-of-line characters +- files are written without BOM. + +:::note Compatibility + +In projects created with 4D versions up to 19.x, by default 4D uses CRLF as end-of-line characters on macOS for SAX and a BOM. You can control the `XML line ending` and `XML BOM` management using the [`XML SET OPTIONS`](../commands/xml-set-options) command and a [Compatibility setting](../settings/compatibility.md). Important: Since SAX file lines are written directly at each statement, if you need to set the BOM and/or end-of-line options, you must call the [`XML SET OPTIONS`](../commands/xml-set-options) command before the first SAX writing command. + +::: diff --git a/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md b/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md index 05786444cfe324..bb8e169addba59 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md @@ -124,7 +124,7 @@ Tres modos de sincronización son posibles del lado del cliente. El selector Aut **Valores posibles:** entero largo > 1 (segundos) -**Descripción**: obtiene o establece la periodicidad del vaciado de la caché, expresado en segundos. La modificación de este valor prevalece sobre la opción **Vaciar caché cada X segundos** en [XML DECODE](../commands/xml-decode) de la configuración de la base para la sesión (que no se almacena en las Propiedades de la base). +**Descripción**: obtiene o establece la periodicidad del vaciado de la caché, expresado en segundos. La modificación de este valor prevalece sobre la opción **Vaciar caché cada X segundos** en la [página Base de datos](../../settings/database.md) de la configuración para la sesión (que no se almacena en la configuración). diff --git a/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md b/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md index 07b3f6e3a089b9..dc7b582769f30c 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md @@ -130,7 +130,7 @@ Tres modos de sincronización son posibles del lado del cliente. El selector Aut **Valores posibles:** entero largo > 1 (segundos) -**Descripción**: obtiene o establece la periodicidad del vaciado de la caché, expresado en segundos. La modificación de este valor prevalece sobre la opción **Vaciar caché cada X segundos** en [XML DECODE](../commands/xml-decode) de la configuración de la base para la sesión (que no se almacena en las Propiedades de la base). +**Descripción**: obtiene o establece la periodicidad del vaciado de la caché, expresado en segundos. La modificación de este valor prevalece sobre la opción **Vaciar caché cada X segundos** en la [página Base de datos](../../settings/database.md) de la configuración para la sesión (que no se almacena en la configuración). diff --git a/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md b/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md index 14754cabd08c53..12a03ceb5c1683 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md @@ -32,6 +32,12 @@ displayed_sidebar: docs El comando **LDAP LOGIN** abre una conexión de sólo lectura en el servidor LDAP especificado por el parámetro *url* con los identificadores *login* y *contraseña* suministrados. Si es aceptado por el servidor, esta conexión se utiliza para todas las búsquedas LDAP efectuadas posteriormente en el proceso actual hasta que el comando *RuntimeVLWinFolder* se ejecute (o hasta que el proceso se cierre). +:::info + +LDAP o *Lightweight Directory Access Protocol* es un estándar abierto para acceder y mantener servicios de información distribuidos. Para más información, consulte la [página de Wikipedia sobre LDAP](http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol) o la página principal de [OpenLDAP Software](http://www.openldap.org/). + +::: + En *url*, pase el URL completo del servidor LDAP al cual conectarse, incluyendo el esquema y el puerto (389 por defecto). Este parámetro debe ser compatible con la [rfc2255](https://www.ietf.org/rfc/rfc2255.txt). Puede abrir conexiones seguras a través de TLS utilizando una mediante el uso de una *url* que empieza comience por "ldaps" y que utilice un número de puerto específico (por ejemplo "ldaps://svr.ldap.acme.com:1389"). El servidor LDAP debe tener un certificado SSL (al menos para Microsoft Active Directory). Es muy recomendable utilizar una conexión TLS cuando se envía la contraseña en texto plano (ver más abajo). @@ -41,9 +47,9 @@ Puede abrir conexiones seguras a través de TLS utilizando una mediante el uso d En *login*, pase la cuenta de usuario en el servidor LDAP, y en *contraseña*, pase la contraseña de usuario. Por defecto, el *login* puede ser una de las siguientes cadenas de inicio de sesión, dependiendo de la configuración del servidor LDAP: * un Distinguished Name (DN), por ejemplo "CN=John Smith,OU=users,DC=example,DC=com" -* un nombre de usuario (CN), por ejemplo "CN=John Smith" +* un nombre de usuario (CN para *Common Name*), por ejemplo "CN=John Smith" * una dirección de correo electrónico, por ejemplo "johnsmith@4d.fr" -* un SAM-Account-Name, por ejemplo "jsmith". +* un SAM-Account-Name (*Security Account Manager*, nombre de inicio de sesión para Active Directory), por ejemplo "jsmith". Tenga en cuenta que los valores aceptados para el *login* están relacionadas con el modo de transmisión de la contraseña definido por el parámetro *digest*. Por ejemplo, en una configuración por defecto de MS Active Directory: diff --git a/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md b/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md index d245f6771e7e2b..672645ff87dba0 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md @@ -49,6 +49,12 @@ Puede saber si PRINT SELECTION está imprimiendo el primer encabezado probando [ Para imprimir una selección ordenada con subtotales o rupturas utilizando PRINT SELECTION, debe primero ordenar la selección. Luego, en cada área de ruptura del informe, incluir una variable con un método de objeto que asigne el subtotal a la variable. Igualmente puede utilizar funciones estadísticas y aritméticas como [Sum](../commands/sum) y [Average](../commands/average) para asignar valores a las variables. Para mayor información, consulte las descripciones de [Subtotal](../commands/subtotal), [BREAK LEVEL](../commands/break-level) y [ACCUMULATE](../commands/accumulate). +:::note + +Puede utilizar [comandos estadísticos](../../commands/theme/On_a_Series.md) como [Sum](../commands/sum) y [Average](../commands/average) para asignar valores a las variables. Cuando se utilizan funciones estadísticas en un informe, se comportan de manera específica porque el propio informe debe cargar cada registro. Cuando utiliza estas funciones en un informe, los valores devueltos solo son fiables en el nivel de ruptura 0, y solo cuando el procesamiento de rupturas está activado. Esto significa que solo son útiles al final de un informe, después de que se hayan procesado todos los registros. Solo usaría estas funciones en un método de objeto para un área no editable incluida en el área de ruptura B0. + +::: + **Advertencia:** no utilice el comando [PAGE BREAK](../commands/page-break) con el comando PRINT SELECTION. [PAGE BREAK](../commands/page-break) está reservado para ser utilizado con el comando [Print form](../commands/print-form). Después de un llamado a PRINT SELECTION, la variable OK toma el valor 1 si la impresión se ha completado. Si la impresión fue interrumpida, la variable OK toma el valor 0 (cero) (por ejemplo si el usuario hizo clic en Cancelar en la caja de diálogo de impresión). diff --git a/i18n/es/docusaurus-plugin-content-docs/current/settings/database.md b/i18n/es/docusaurus-plugin-content-docs/current/settings/database.md index 749bbc81261bd2..266fc43fdc21df 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/settings/database.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/settings/database.md @@ -124,3 +124,31 @@ Utilice los parámetros de esta pestaña para configurar la memoria caché de la Si la base de datos se ralentiza notablemente cada vez que se vacía la caché, deberá ajustar la frecuencia. Esta lentitud significa que se está guardando una gran cantidad de registros. Por lo tanto, un periodo más corto entre guardados sería más eficaz, ya que cada guardado implicaría menos registros y, por lo tanto, sería más rápido. Por defecto, 4D muestra una pequeña ventana cuando se vacía la caché. Si no desea este recordatorio visual, puede deseleccionar la opción **Escritura de caché** en la [página Interfaz](./interface.md). + +:::note + +Puede modificar temporalmente la frecuencia de escritura de la caché utilizando el [selector `Cache flush periodicity` del comando `SET DATABASE PARAMETER`](../commands/set-database-parameter#cache-flush-periodicity-95). + +::: + + + + +### Gestión de las prioridades en la caché de la base de datos + +La caché de la base de datos 4D incluye un mecanismo automático de gestión de prioridades que ofrece un alto nivel de eficacia y rendimiento para el acceso a los datos. Gracias a este mecanismo, cuando se necesita espacio para cargar nuevos datos en la caché, los datos en caché de baja prioridad se liberan primero, mientras que los datos en caché de mayor prioridad permanecen cargados. + +Este mecanismo es totalmente automático y, por lo general, no tendrá que preocuparse por él. Sin embargo, para casos específicos puede personalizarse utilizando un [conjunto de comandos dedicados del tema "Gestión de caché"](../commands/theme/Cache_Management.md), que permiten cambiar la prioridad de los objetos durante todo el tiempo que la base de datos está en ejecución, o temporalmente para el proceso actual. Tenga en cuenta que estos comandos deben utilizarse con cuidado, ya que afectan al rendimiento de la base de datos. + +#### Descripción general de la gestión de prioridades + +El gestor de caché selecciona los datos a eliminar de la caché según sea necesario mediante un sistema de prioridades. Los tres tipos de objetos que se pueden cargar en la caché tienen una prioridad diferente: + +- **tablas**: todos los datos de campos estándar (numéricos, fechas, etc.), excluyendo los blobs (ver más abajo). La prioridad por defecto es media. +- **blobs**: todos los datos de campos binarios (texto, imagen, objeto y blobs) almacenados en el archivo de datos. La prioridad por defecto es la más baja. +- **índices**: todos los índices de campos, incluidos los índices de palabras clave y los índices compuestos. Dado que los índices se consultan con frecuencia, tienen un estatus especial en la caché. La prioridad por defecto es la más alta. + +Las prioridades por defecto suelen ofrecer el mejor rendimiento. Sin embargo, para casos específicos puede personalizar las prioridades de la caché utilizando dos conjuntos de comandos 4D: + +- Comandos que cambian las prioridades para toda la sesión y todos los procesos: [`SET TABLE CACHE PRIORITY`](../commands/set-table-cache-priority), [`SET INDEX CACHE PRIORITY`](../commands/set-index-cache-priority), y [`SET BLOBS CACHE PRIORITY`](../commands/set-blobs-cache-priority). Estos comandos deben utilizarse en un método base de inicio. +- Comandos que cambian las prioridades sólo para el proceso actual: [`ADJUST TABLE CACHE PRIORITY`](../commands/adjust-table-cache-priority), [`ADJUST INDEX CACHE PRIORITY`](../commands/adjust-index-cache-priority), y [`ADJUST BLOBS CACHE PRIORITY`](../commands/adjust-blobs-cache-priority). Utilice estos comandos para mejorar el rendimiento de una operación temporal en su base de datos y volver a las prioridades iniciales una vez finalizada la operación. Estos comandos sólo están disponibles en 4D Server o 4D en modo local. diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md index 1a3c66e0bf844a..37987c73de48aa 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md @@ -123,7 +123,7 @@ Tres modos de sincronización son posibles del lado del cliente. El selector Aut **Valores posibles:** entero largo > 1 (segundos) -**Descripción**: obtiene o establece la periodicidad del vaciado de la caché, expresado en segundos. La modificación de este valor prevalece sobre la opción **Vaciar caché cada X segundos** en [XML DECODE](../commands/xml-decode) de la configuración de la base para la sesión (que no se almacena en las Propiedades de la base). +**Descripción**: obtiene o establece la periodicidad del vaciado de la caché, expresado en segundos. La modificación de este valor prevalece sobre la opción **Vaciar caché cada X segundos** en la [página Base de datos](../../settings/database.md) de la configuración para la sesión (que no se almacena en la configuración). diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md index 3b8603ba23e79b..faf2a1537bfc0b 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md @@ -129,7 +129,7 @@ Tres modos de sincronización son posibles del lado del cliente. El selector Aut **Valores posibles:** entero largo > 1 (segundos) -**Descripción**: obtiene o establece la periodicidad del vaciado de la caché, expresado en segundos. La modificación de este valor prevalece sobre la opción **Vaciar caché cada X segundos** en [XML DECODE](../commands/xml-decode) de la configuración de la base para la sesión (que no se almacena en las Propiedades de la base). +**Descripción**: obtiene o establece la periodicidad del vaciado de la caché, expresado en segundos. La modificación de este valor prevalece sobre la opción **Vaciar caché cada X segundos** en la [página Base de datos](../../settings/database.md) de la configuración para la sesión (que no se almacena en la configuración). diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/legacy-to-import.md b/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/legacy-to-import.md new file mode 100644 index 00000000000000..4c033be35c91ad --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/legacy-to-import.md @@ -0,0 +1,91 @@ +--- +id: legacy-to-import +title: develop-legacy +draft: true +--- + + + + +## Sémaphores + +Les sémaphores vous permettent de vous assurer que deux processus ou plus ne modifient pas la même ressource (fichier, enregistrement...) en même temps. Seul le processus qui pose le sémaphore peut le retirer. + +:::info + +Les [signaux](../API/SignalClass.md) peuvent également être utilisés pour gérer les interactions. Les signaux vous permettent de vous assurer qu'un ou plusieurs processus attendront qu'une tâche spécifique soit terminée avant de poursuivre leur exécution. Tout processus peut attendre et/ou libérer un signal. + +::: + +### Qu'est-ce qu'un sémaphore ? + +Dans un programme informatique, un sémaphore est un outil utilisé pour protéger des actions qui ne doivent être exécutées que par un seul processus ou utilisateur à la fois. + +En 4D, le besoin classique d'utiliser des sémaphores concerne la modification d'un tableau interprocess : si un processus modifie les valeurs du tableau, un autre processus ne doit pas pouvoir faire la même chose en même temps. Le développeur utilise un sémaphore pour indiquer à un processus qu'il ne peut effectuer sa séquence d'opérations que si aucun autre processus n'effectue déjà les mêmes tâches. Lorsqu'un processus rencontre un sémaphore, trois possibilités se présentent : + +- Il obtient immédiatement le droit de passer +- Il attend son tour jusqu'à obtenir le droit de passer +- Il poursuit son chemin, renonçant à exécuter les tâches. + +Le sémaphore protège donc des parties du code. Il ne laisse passer qu'un seul processus à la fois et bloque l'accès jusqu'à ce que le processus détenant actuellement le droit d'utilisation abandonne ce droit en libérant le sémaphore. + +### Commandes pour travailler avec les sémaphores + +En 4D, vous posez un sémaphore en appelant la commande [`Semaphore`](../commands/sempahore). Pour libérer un sémaphore, vous appelez la commande [`CLEAR SEMAPHORE`](../commands/clear-sempahore). + +La commande [`Semaphore`](../commands/sempahore) a un comportement très particulier car elle effectue potentiellement deux actions simultanément : + +- Si le sémaphore est déjà attribué, la fonction retourne **True** +- Si le sémaphore n'est pas attribué, la fonction l'attribue au processus et retourne **False** en même temps. + +Cette double action effectuée par la même commande garantit qu'aucune opération externe ne peut s'insérer entre le test du sémaphore et son attribution. + +Vous pouvez utiliser la commande [`Test semaphore`](../commands/test-semaphore) pour savoir si un sémaphore est déjà attribué ou non. Cette commande est principalement utilisée dans le cadre d'opérations longues, telles que la clôture annuelle des comptes, où [`Test semaphore`](../commands/test-semaphore) vous permet de contrôler l'interface afin d'empêcher l'accès à certaines opérations, comme l'ajout de données comptables. + +### Comment utiliser les sémaphores + +Les sémaphores doivent être utilisés selon les principes suivants : + +- Un sémaphore doit être posé et libéré dans la même méthode, +- L'exécution du code protégé par le sémaphore doit être aussi courte que possible, +- Le code doit être temporisé au moyen du paramètre tickCount de la commande [`Semaphore`](../commands/sempahore) pour attendre la libération du sémaphore. + +Voici un code type pour utiliser un sémaphore : + +```4d + While(Semaphore("MySemaphore";300)) + IDLE + End while + // placer ici le code protégé par le sémaphore + CLEAR SEMAPHORE("MySemaphore") +``` + +Un sémaphore qui n'est pas libéré peut bloquer une partie de la base de données. Poser et libérer les sémaphores dans la même méthode permet d'éliminer ce risque. + +Minimiser le code protégé par le sémaphore augmente la fluidité de l'application et évite que le sémaphore ne devienne un goulot d'étranglement. + +Enfin, l'utilisation du paramètre optionnel *tickCount* de la commande [`Semaphore`](../commands/sempahore) est essentielle pour optimiser l'attente de la libération du sémaphore. Avec ce paramètre, la commande fonctionne de la manière suivante : + +- Le processus attend au maximum le nombre de ticks spécifié (300 dans l'exemple) que le sémaphore soit disponible, sans que l'exécution du code ne passe à la ligne suivante, +- Si le sémaphore est libéré avant la fin de cette limite, il est immédiatement attribué au processus (Semaphore retourne False) et l'exécution du code reprend, +- Si le sémaphore n'est pas libéré avant la fin de cette limite, alors l'exécution du code reprend. + +La commande priorise également les requêtes en établissant une file d'attente. Ainsi, le premier processus à demander un sémaphore sera le premier à l'obtenir. Notez que le temps d'attente est défini en fonction des spécificités de l'application. + +### Sémaphores locaux ou globaux + +Il existe deux types de sémaphores en 4D : les sémaphores locaux et les sémaphores globaux. + +- Un sémaphore local est accessible par tous les processus du même poste de travail et uniquement sur ce poste. Un sémaphore local peut être créé en préfixant le nom du sémaphore par un signe dollar ($). Vous utilisez les sémaphores locaux pour surveiller les opérations entre des processus s'exécutant sur le même poste de travail. Par exemple, un sémaphore local peut être utilisé pour surveiller l'accès à un tableau interprocess partagé par tous les processus de votre base de données mono-utilisateur ou du poste de travail. +- Un sémaphore global est accessible à tous les utilisateurs et à tous leurs processus. Vous utilisez les sémaphores globaux pour surveiller les opérations entre les utilisateurs d'une base de données multi-utilisateurs. + +Les sémaphores globaux et locaux sont identiques dans leur logique. La différence réside dans leur portée. + +En client/serveur, les sémaphores globaux sont partagés entre tous les processus s'exécutant sur tous les clients et serveurs. Un sémaphore local n'est partagé qu'entre les processus s'exécutant sur la machine où il a été créé. + +Dans les applications 4D mono-utilisateur, les sémaphores globaux ou locaux ont la même portée car vous êtes le seul utilisateur. Toutefois, si votre base de données est utilisée dans les deux configurations, veillez à utiliser des sémaphores globaux ou locaux selon ce que vous souhaitez faire. + +**Note :** Nous recommandons d'utiliser des sémaphores locaux lorsque vous avez besoin d'un sémaphore pour gérer un aspect local d'un client de l'application, tel que l'interface ou un tableau de variables interprocess. Si vous utilisez un sémaphore global dans ce cas, cela provoquerait non seulement des échanges réseau inutiles, mais pourrait aussi affecter inutilement d'autres machines clientes. L'utilisation d'un sémaphore local éviterait ces effets secondaires indésirables. + + + \ No newline at end of file diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/overview.md b/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/overview.md new file mode 100644 index 00000000000000..793f5e5c9dbd03 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/overview.md @@ -0,0 +1,7 @@ +--- +id: overview +title: 4D database overview +--- + +## Description + diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/records.md b/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/records.md new file mode 100644 index 00000000000000..25e1705847e48e --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/records.md @@ -0,0 +1,308 @@ +--- +id: records +title: Records +slug: /Develop/records +displayed_sidebar: docs +--- + + +## Record numbers + +There are three numbers associated with a record: + +- Record number +- Selected record number +- Sequence number + +### Record Number + +The record number is the absolute/physical record number for a record. A record number is automatically assigned to each new record and remains constant for the record until the record is deleted. Record numbers start at zero. They are not unique because record numbers of deleted records are reused for new records. They also change when the database is [compacted](../MSC/compact.md) or [repaired](../MSC/repair.md). + +### Selected Record Number + +The selected record number is the position of the record in the current selection, and so depends on the current selection. If the selection is changed or sorted, the selected record number will probably change. Numbering for the selected record number starts at one (1). + +### Sequence Number + +The sequence number is a unique non-repeating number that may be assigned to a field of a record (via the Autoincrement property, the SQL AUTO_INCREMENT attribute or the [`Sequence number`](../commands/sequence-number) command). It is not automatically stored with each record. It starts by default at 1 and is incremented for each new record that is created. Unlike record numbers, a sequence number is not reused when a record is deleted or when a database is compacted or repaired. Sequence numbers provide a way to have unique ID numbers for records. If a sequence number is incremented during a transaction, the number is not decremented if the transaction is canceled. + +:::note Notes + +- 4D does not carry out any check when you modify the automatic number internal counter of a table using the [`SET DATABASE PARAMETER`](../commands/set-database-parameter) command. If you decrement this counter, the new records created may have numbers that have already been assigned. +- Sequence numbers are not recommended to fill unique ID primary key fields for records. To create unique record IDs, it is strongly recommended to use UUIDs. + +::: + +### Example + +The following tables illustrate the numbers that are associated with records. Each line in the table represents information about a record. The order of the lines is the order in which records would be displayed in an output form. + +- **Data**: The data from a field in each record. For our example, it contains a person’s name. +- **Record Number**: The record’s absolute record number. This is the number returned by the [`Record number`](../commands/record-number) command. +- **Selected Record Number**: The record’s position in the current selection. This is the number returned by the [`Selected record number`](../commands/selected-record-number) command. +- **Sequence Number**: The record’s unique sequence number. This is the number returned by the [`Sequence number`](../commands/sequence-number) command when the record was created. This number is stored in a field. + +#### After the Records Are Entered + +The first table shows the records after they are entered. + +- The default order for the records is by record number. +- The record number starts at 0. +- The selected record number and the sequence number start at 1. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Tess |0| 1| 1| +|Terri| 1 |2 |2| +|Sabra| 2|3| 3| +|Sam| 3 |4 |4| +|Lisa| 4| 5 |5| + +Note: The records remain in the default order after a command changes the current selection without reordering it; for example, after the **Show All** menu command is chosen in the Design environment, or after the [`ALL RECORDS`](../commands/all-records) command is executed. + +#### After the Records Are Sorted + +The next table shows the same records sorted by name. + +- The same record number remains associated with each record. +- The selected record numbers reflect the new position of the records in the sorted selection. +- The sequence numbers never change, since they were assigned when each record was created and are stored in the record. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Lisa| 4| 1 |5| +|Sabra| 2|2| 3| +|Sam| 3 |3 |4| +|Terri| 1 |4 |2| +|Tess |0| 5| 1| + + +#### After a Record Is Deleted + +The following table shows the records after Sam is deleted. + +- Only the selected record numbers have changed. Selected record numbers reflect the order in which the records are displayed. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Lisa| 4| 1 |5| +|Sabra| 2|2| 3| +|Terri| 1 |3 |2| +|Tess |0| 4| 1| + + +#### After a Record Is Added + +The next table shows the records after a new record has been added for Liz. + +- A new record is added to the end of the current selection. +- Sam’s record number is reused for the new record. +- The sequence number continues to increment. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Tess |0| 1| 1| +|Terri| 1 |2 |2| +|Sabra| 2|3| 3| +|Lisa| 4| 4 |5| +|Liz |3| 5| 6| + +#### After the Selection is Changed and Sorted + +The following table shows the records after the selection was reduced to three records and then sorted. + +- Only the selected record number associated with each record changes. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Sabra| 2|1| 3| +|Liz |3| 2| 6| +|Terri| 1 |3 |2| + +## Record Stack + +The [`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) commands allow you to put (“push”) records onto the record stack, and to remove (“pop”) them from the stack. + +Each process has its own record stack for each table. 4D maintains the record stacks for you. Each record stack is a last-in-first-out (LIFO) stack. Stack capacity is limited by memory. + +[`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) should be used with discretion. Each record that is pushed uses part of free memory. Pushing too many records can cause an out-of-memory or stack full condition. + +4D clears the stack of any unpopped records when you return to the menu at the end of execution of your method. + +[`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) are useful when you want to examine records in the same file during data entry. To do this, you push the record, search and examine records in the file (copy fields into variables, for example), and finally pop the record to restore the record. + +While entering a record, if you have to check a multiple field unique value, use the [`SET QUERY DESTINATION`](../commands/set-quer-destination) command. This will save you the calls to [`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) that you were making before and after the call to QUERY in order to preserve the data entered in the current record. [`SET QUERY DESTINATION`](../commands/set-quer-destination) allows you to make a query that does not change the selection nor the current record. + +## Record locking + +4D and 4D Server automatically manage databases by preventing multi-user or multi-process conflicts. Two users or two processes cannot modify the same record or object at the same time. However, the second user or process can have read-only access to the record or object at the same time. + +There are several reasons for using the multi-user commands: + +- Modifying records by using the language. +- Using a custom user interface for multi-user operations. +- Saving related modifications inside a transaction. + +There are three important concepts to be aware of when using commands in a multi-processing database: + +1. In a process, each table is in either a read-only or a read/write state. +2. Records become locked when they are loaded and unlocked when they are unloaded. +3. A locked record cannot be modified. + +As a convention in the following sections, the person performing an operation on the multi-user database is referred to as the **local user**. Other people using the database are referred to as the **other users**. The discussion is from the perspective of the local user. Also, from a multi-process perspective, the process executing an operation on the database is the **current process**. Any other executing process is referred to as **other processes**. The discussion is from the point of view of the current process. + +### Locked Records + +A locked record cannot be modified by the local user or the current process. A locked record can be loaded, but cannot be modified. A record is locked when one of the other users or processes has successfully loaded the record for modification, or when the record is stacked. Only the user who is modifying the record sees that record as unlocked. All other users and processes see the record as locked, and therefore unavailable for modification. A table must be in a read/write state for a record to be loaded unlocked. + +### Read-Only and Read/Write States + +Each table in a database is in either a read/write or a read-only state for each user and process of the database. **Read-only** means that records for the table can be loaded but not modified. **Read/write** means that records for the table can be loaded and modified if no other user has locked the record first. + +Note that if you change the status of a table, the change takes effect for the next record loaded. If there is a record currently loaded when you change the table’s status, that record is not affected by the status change. + +#### Read-Only State + +When a table is read-only and a record is loaded, this record is always locked. In other words, locked records can be displayed, printed, and otherwise used, but they cannot be modified. + +Note that the read-only state applies only to editing existing records. A read-only state does not affect the creation of new records. You can still add records to a read-only table using [`CREATE RECORD`](../commands/create-record) and [`ADD RECORD`](../commands/add-record), or the menu commands of the Design environment (in this case, the records being created are locked for all other users/processes). Note that the [`ARRAY TO SELECTION`](../commands/array-to-selection) command is not affected by the read-only state since it can both create and modify records. + +4D automatically sets a table to read-only for commands that do not require write access to records. These commands are: [`DISPLAY SELECTION`](../commands/display-selection), [`DISTINCT VALUES`](../commands/distinct-values), [`EXPORT DIF`](../commands/export-dif), [`EXPORT SYLK`](../commands/export-sylk), [`EXPORT TEXT`](../commands/export-text), [`PRINT SELECTION`](../commands/print-selection), [`PRINT LABEL`](../commands/print-label), [`QR REPORT`](../commands/qr-report), [`SELECTION TO ARRAY`](../commands/selection-to-array), [`SELECTION RANGE TO ARRAY`](../commands/selection-range-to-array). + +You can find out the state of a table at any time using the [`Read only state`](../commands/read-only-state) function. + +Before executing any of these commands, 4D saves the current state of the table (read-only or read/write) for the current process. After the command has executed, this state is restored. + +#### Read/Write State + +When a table is read/write and a record is loaded, the record will become unlocked if no other user has locked the record first. If the record is locked by another user, the record is loaded as a locked record that cannot be modified by the local user. + +A table must be set to read/write and the record loaded for it to become unlocked and thus modifiable. + +If a user loads a record from a table in read/write mode, no other users can load that record for modification. However, other users can add records to the table, either through the [`CREATE RECORD`](../commands/create-record) and [`ADD RECORD`](../commands/add-record) commands or manually in the Design environment. + +Read/write is the default state for all tables when a database is opened and a new process is started. + +#### Changing the Status of a Table + +You can use the [`READ ONLY`](../commands/read-only) and [`READ WRITE`](../commands/read-write) commands to change the state of a table. If you want to change the state of a table in order to make a record read-only or read/write, you must execute the command before this record is loaded. Any record that is already loaded is not affected by the [`READ ONLY`](../commands/read-only) and [`READ WRITE`](../commands/read-write) commands. + +Each process has its own state (read-only or read/write) for each table in the database. + +By default, if you do not use the READ ONLY command, all tables are in read/write mode. + +### Loading, Modifying and Unloading Records + +Before the local user can modify a record, the table must be in the read/write state and the record must be loaded and unlocked. + +Any of the commands that loads a current record (if there is one) — such as [`NEXT RECORD`](../commands/next-record), [`QUERY`](../commands/query), [`ORDER BY`](../commands/order-by), [`RELATE ONE`](../commands/relate-one), etc. — sets the record state as locked or unlocked. The record is loaded according to the current state of its table (read-only or read/write) and its availability. A record may also be loaded for a related table by any of the commands that cause an automatic relation to be established. + +If a table is in the read-only state for a process or a user, then this table's records are loaded in read-only mode, which means they cannot be modified or deleted by this process or user. This is recommended for viewing or retrieving data because it does not prevent other users or processes from accessing the records of this table in read/write mode if necessary. + +If a table is in the read/write state for a process or a user, then any record from this table is also loaded in read/write mode, but only if no other user or process has already locked this record. If a record is successfully loaded in read/write mode, it is unlocked for the current process or user (it can be modified and saved) and is locked for all other users or processes. A table must be put into the read/write state before loading a record for modification and then saving it. + +If the record is to be modified, you use the Locked function to test whether or not a record is locked by another user. If a record is locked (Locked returns True), load the record with the [`LOAD RECORD`](../commands/load-record) command and again test whether or not the record is locked. This sequence must be continued until the record becomes unlocked (Locked returns False). + +When modifications to be made to a record are finished, the record must be released (and therefore unlocked for the other users) with [`UNLOAD RECORD`](../commands/unload-record). If a record is not unloaded, it will remain locked for all other users until a different current record is selected. Changing the current record of a table automatically unlocks the previous current record. You need to explicitly call [`UNLOAD RECORD`](../commands/unload-record) if you do not change the current record. This discussion applies to existing records. When a new record is created, it can be saved regardless of the state of the table to which it belongs. + +:::note + +When it is used in a transaction, the [`UNLOAD RECORD`](../commands/unload-record) command unloads the current record only for the process that manages the transaction. For other processes, the record stays locked as long as the transaction has not been validated (or cancelled). + +::: + +Use the [`LOCKED BY`](../commands/locked-by) command to see which user and/or process have locked a record. + +::: + +A good practice is to place all tables in read-only mode when each process is started (using the syntax [`READ ONLY(*)`](../commands/read-only)) then put each table in read/write mode only when necessary. Access to tables in read-only mode is faster and more memory-efficient. Moreover, changing the state of a table is optimized in client/server mode because it does not cause any additional network traffic: information is only sent to the server when executing a command that requires adequate access to the table. + +::: + +### Loops to Load Unlocked Records + +The following example shows the simplest loop with which to load an unlocked record: + +```4d + READ WRITE([Customers])//Set the table’s state to read/write + Repeat//Loop until the record is unlocked + LOAD RECORD([Customers])//Load record and set locked status + Until(Not(Locked([Customers]))) + //Do something to the record here + READ ONLY([Customers])//Set the table’s state to read-only +``` + +The loop continues until the record is unlocked. + +A loop like this is used only if the record is unlikely to be locked by anyone else, since the user would have to wait for the loop to terminate. Thus, it is unlikely that the loop would be used as is unless the record could only be modified by means of a method. + +The following example uses the previous loop to load an unlocked record and modify the record: + +```4d + READ WRITE([Inventory]) + Repeat //Loop until the record is unlocked + LOAD RECORD([Inventory]) //Load record and set it to locked + Until(Not(Locked([Inventory]))) + [Inventory]Part Qty:=[Inventory]Part Qty 1 //Modify the record + SAVE RECORD([Inventory]) //Save the record + UNLOAD RECORD([Inventory]) //Let other users modfiy it + READ ONLY([Inventory]) +``` + + +The [`MODIFY RECORD`](../commands/modify-record) command automatically notifies the user if a record is locked, and prevents the record from being modified. The following example avoids this automatic notification by first testing the record with the Locked function. If the record is locked, the user can cancel. + +This example efficiently checks to see if the current record is locked for the table [Commands]. If it is locked, the process is delayed by the procedure for one second. This technique can be used both in a multi-user or multi-process situation: + +```4d + Repeat + READ ONLY([Commands])//You do not need read/write right now + QUERY([Commands]) + //If the search was completed and some records were returned + If((OK=1) & (Records in selection([Commands])>0)) + READ WRITE([Commands])//Set the table to read/write state + LOAD RECORD([Commands]) + While(Locked([Commands]) & (OK=1)) `If the record is locked, + //loop until the record is unlocked + //Who is the record locked by? + LOCKED BY([Commands];$Process;$User;$SessionUser;$Name) + If($Process=-1)//Has the record been deleted? + ALERT("The record has been deleted in the meantime.") + OK:=0 + Else + If($User="")//Are you in single-user mode + $User:="you" + End if + CONFIRM("The record is already used by "+$User+" in the "+$Name+" Process.") + If(OK=1)//If you want to wait for a few seconds + DELAY PROCESS(Current process;120)//Wait for a few seconds + LOAD RECORD([Commands])//Try to load the record + End if + End if + End while + If(OK=1)//The record is unlocked + MODIFY RECORD([Commands])//You can modify the record + UNLOAD RECORD([Commands]) + End if + READ ONLY([Commands])//Switch back to read-only + OK:=1 + End if + Until(OK=0) +``` + + +### Using Commands in Multi-user or Multi-process Environment + +A number of commands in the language perform specific actions when they encounter a locked record. They behave normally if they do not encounter a locked record. + +Here is a list of these commands and their actions when a locked record is encountered. + +- [`MODIFY RECORD`](../commands/modify-record): Displays a dialog box stating that the record is in use. The record is not displayed, therefore the user cannot modify the record. In the Design environment, the record is shown in read-only state. +- [`MODIFY SELECTION`](../commands/modify-selection): Behaves normally except when the user double-clicks a record to modify it. [`MODIFY SELECTION`](../commands/modify-selection) displays dialog box stating that the record is in use and then allows read-only access to the record. +- [`APPLY TO SELECTION`](../commands/apply-to-selection): Loads a locked record, but does not modify it. [`APPLY TO SELECTION`](../commands/apply-to-selection) can be used to read information from the table without special care. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`DELETE SELECTION`](../commands/delete-selection): Does not delete any locked records; it skips them. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`DELETE RECORD`](../commands/delete-record): This command is ignored if the record is locked. No error is returned. You must test that the record is unlocked before executing this command. +- [`SAVE RECORD`](../commands/save-record): This command is ignored if the record is locked. No error is returned. You must test that the record is unlocked before executing this command. +- [`ARRAY TO SELECTION`](../commands/array-to-selection): Does not save any locked records. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`GOTO RECORD`](../commands/goto-record): Records in a multi-user/multi-process database may be deleted and added by other users, therefore the record numbers may change. Use caution when directly referencing a record by number in a multi-user database. +- [**Sets**](./sets.md): Take special care with sets, as the information that the set was based on may be changed by another user or process. diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/sets.md b/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/sets.md new file mode 100644 index 00000000000000..f1e42b3cc1c863 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/sets.md @@ -0,0 +1,168 @@ +--- +id: sets +title: Sets +slug: /Develop/sets +displayed_sidebar: docs +--- + + +Sets offer you a powerful, swift means for manipulating record selections. Besides the ability to create sets, relate them to the current selection, and store, load, and clear sets, 4D offers three standard set operations: + +- Intersection +- Union +- Difference. + + +## Sets and the Current Selection + +A set is a compact representation of a selection of records. The idea of sets is closely bound to the idea of the current selection. Sets are generally used for the following purposes: + +- To save and later restore a selection when the order does not matter +- To access the selection a user made on screen (the `UserSet`) +- To perform a logical operation between selections. + +The current selection is a list of references that points to each record that is currently selected. The list exists in memory. Only currently selected records are in the list. A selection doesn’t actually contain the records, but only a list of references to the records. Each reference to a record takes 4 bytes in memory. When you work on a table, you always work with the records in the current selection. When a selection is sorted, only the list of references is rearranged. There is only one current selection for each table inside a process. + +Like a current selection, a set represents a selection of records. A set does this by using a very compact representation for each record. Each record is represented by one bit (one-eighth of a byte). Operations using sets are very fast, because computers can perform operations on bits very quickly. A set contains one bit for every record in the table, whether or not the record is included in the set. In fact, each bit is equal to 1 or 0, depending on whether or not the record is in the set. + +Sets are very economical in terms of RAM space. The size of a set, in bytes, is always equal to the total number of records in the table divided by 8. For example, if you create a set for a table containing 10,000 records, the set takes up 1,250 bytes, which is about 1.2K in RAM. + +There can be many sets for each table. In fact, sets can be saved to disk separately from the database. To change a record belonging to a set, first you must use the set as the current selection, then modify the record or records. + +A set is never in a sorted order—the records are simply indicated as belonging to the set or not. On the other hand, a named selection is in sorted order, but it requires more memory in most cases. For more information about named selections, see the Named Selections section. + +A set "remembers" which record was the current record at the time the set was created. The following table compares the concepts of the current selection and of sets: + +|Comparison|Current Selection|Sets| +|---|---|---| +|Number per table|1|0 to many| +|Sortable|Yes|No| +|Can be saved on disk|No|Yes| +|RAM per record(in bytes)|Number of selected records * 4|Total number of records/8| +|Combinable| No| Yes| +|Contains current record| Yes| Yes, as of the time the set was created| + +When you create a set, it belongs to the table from which you created it. Set operations can be performed only between sets belonging to the same table. + +Sets are independent from the data. This means that after changes are made to a file, a set may no longer be accurate. There are many operations that can cause a set to be inaccurate. For example, if you create a set of all the people from New York City, and then change the data in one of those records to “Boston” the set would not change, because the set is just a representation of a selection of records. Deleting records and replacing them with new ones also changes a set, as well as compacting the data. Sets can be guaranteed to be accurate only as long as the data in the original selection has not been changed. + +## Process and Interprocess Sets + +You can have the following three types of sets: + +- **Process sets**: A process set can only be accessed by the process in which it has been created. `LockedSet` is a process set. Process sets are cleared as soon as the process method ends. Process sets do not need any special prefix in the name. +- **Interprocess sets**: A set is an interprocess set if the name of the set is preceded by the symbols (<>) — a “less than” sign followed by a “greater than” sign. An interprocess set is “visible” to all the processes of the database. +In client/server mode, an interprocess set is “visible” to processes of the machine where it was created (client or server). +The name of an interprocess set must be unique in the database. +- **Local Sets/Client Sets**: Local/client sets are intended for use in client/server mode. The name of a local/client set is always preceded by the dollar sign ($) -- except for the UserSet system set. Unlike other types of sets, a local/client set is stored on the client machine. + +:::note Notes + +- The maximum size of a set name is 255 characters (excluding <> and $ symbols). +- For more information about the use of sets in client/server mode, please refer to 4D Server, Sets and Named Selections. + +::: + + +## Visibility of Sets + +The following table indicates the principles concerning the visibility of sets depending on their scope and where they were created: + + + +||Client Process|Other processes on the same client|Other clients|Server process|Other processes on the server| +|---|---|---|---|---|---| +|Creation in a client process |||||| +|$test|X ||||| +|test | X||| X(Trigger) || +|<>test | X|X |||| +|Creation in a server process|||||| +|$test|||| X|| +|test ||||X|| +|<>test||||X| X| + + +## Sets and Transactions + +A set can be created inside a [transaction](./transactions.md). It is possible to create a set of the records created inside a transaction and a set of records created or modified outside of a transaction. When the transaction ends, the set created during the transaction should be cleared, because it may not be an accurate representation of the records, especially if the transaction was canceled. + +## Example + +The following example deletes duplicate records from a table which contains information about people. A For...End for loop moves through all the records, comparing the current record to the previous record. If the name, address, and zip code are the same, then the record is added to a set. At the end of the loop, the set is made the current selection and the (old) current selection is deleted: + +```4d + CREATE EMPTY SET([People];"Duplicates") + // Create an empty set for duplicate records + ALL RECORDS([People]) + // Select all records + // Sort the records by ZIP, address, and name so + // that the duplicates will be next to each other + ORDER BY([People];[People]ZIP;>;[People]Address;>;[People]Name;>) + // Initialize variables that hold the fields from the previous record + $Name:=[People]Name + $Address:=[People]Address + $ZIP:=[People]ZIP + // Go to second record to compare with first + NEXT RECORD([People]) + For($i;2;Records in table([People])) + // Loop through records starting at 2 + // If the name, address, and ZIP are the same as the + // previous record then it is a duplicate record. + If(([People]Name=$Name) & ([People]Address=$Address) & ([People]ZIP=$ZIP)) + // Add current record (the duplicate) to set + ADD TO SET([People];"Duplicates") + Else + // Save this record’s name, address, and ZIP for comparison with the next record + $Name:=[People]Name + $Address:=[People]Address + $ZIP:=[People]ZIP + End if + // Move to the next record + NEXT RECORD([People]) + End for + // Use duplicate records that were found + USE SET("Duplicates") + // Delete the duplicate records + DELETE SELECTION([People]) + // Remove the set from memory + CLEAR SET("Duplicates") +``` + +As an alternative to immediately deleting records at the end of the method, you could display them on screen or print them, so that a more detailed comparison can be made. + + +## The UserSet System Set + +4D maintains a system set named `UserSet`, which automatically stores the most recent selection of records highlighted on screen by the user. Thus, you can display a group of records with [`MODIFY SELECTION`](../commands/modify-selection) or [`DISPLAY SELECTION`](../commands/display-selection), ask the user to select from among them and turn the results of that manual selection into a selection or into a set that you name. + +::info 4D Server + +Although its name does not begin with the character "$", the `UserSet` system set is a client set. So, when using [`INTERSECTION`](../commands/intersection), [`UNION`](../commands/union) and [`DIFFERENCE`](../commands/difference), make sure you compare `UserSet` only to client sets. + +::: + +There is only one `UserSet` for a [process](../Develop/processes.md). Each table does not have its own `UserSet`. `UserSet` becomes "owned" by a table when a selection of records is displayed for the table. + +4D manages the `UserSet` set for list forms displayed in Design mode or using the [`MODIFY SELECTION`](../commands/modify-selection) or [`DISPLAY SELECTION`](../commands/display-selection) commands. However, this mechanism is not active for [subforms](../FormObjects/subform_overview.md). + +The following method illustrates how you can display records, allow the user to select some of them, and then use UserSet to display the selected records: + +```4d + // Display all records and allow user to select any number of them. + // Then display this selection by using UserSet to change the current selection. + FORM SET OUTPUT([People];"Display") // Set the output layout + ALL RECORDS([People]) // Select all people + ALERT("Press Ctrl or Command and Click to select the people required.") + DISPLAY SELECTION([People]) // Display the people + USE SET("UserSet") // Use the people that were selected + ALERT("You chose the following people.") + DISPLAY SELECTION([People]) // Display the selected people +``` + +## The LockedSet System Set + +The [`APPLY TO SELECTION`](../commands/apply-to-selection), [`DELETE SELECTION`](../commands/delete-selection), [`ARRAY TO SELECTION`](../commands/array-to-selection) and [`JSON TO SELECTION`](../commands/json-to-selection) commands create a set named `LockedSet` when used in a multi-processing environment. + +Query commands also create a `LockedSet` system set when they find locked records in the 'query and lock' context (see the [`SET QUERY AND LOCK`](../commands/set-query-and-lock) command). + +`LockedSet` indicates which records were locked during the execution of the command. \ No newline at end of file diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/xml.md b/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/xml.md new file mode 100644 index 00000000000000..6691cfcb0e545c --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/Develop-legacy/xml.md @@ -0,0 +1,157 @@ +--- +id: xml +title: XML Processing +slug: /Develop/XML +displayed_sidebar: docs +--- + + +## Overview of XML Commands + +### XML, DOM, and SAX + +The [**XML** theme](../commands/theme/XML.md) groups together the generic XML "utilities" commands of 4D. These are option- and error-management commands. + +4D also offers two separate sets of XML commands: [**DOM**](../commands/theme/XML_DOM.md) (Document Object Model) and [**SAX**](../commands/theme/XML_SAX.md) (Simple API XML) are two different parsing modes for XML documents. + +- The DOM mode parses an XML source and builds its structure (its "tree") in memory. Because of this, access to each element of the source is extremely fast. However, since the entire tree structure is stored in memory, the processing of large XML documents may lead to the memory capacity being exceeded and thus provoke errors. +- The SAX mode does not build a tree structure in memory. In this mode, "events" (such as the start and end of an element) are generated when parsing the source. This mode lets you parse XML documents of any size, regardless of the amount of memory available. + +### References + +http://www.saxproject.org/?selected=event
+http://www.w3schools.com/xml/ + +:::note + +For XML support, 4D uses the [Xerces.dll library](../Notes/updates.md#library-table) developed by the Apache Foundation company. + +::: + + +### Preemptive mode + +XML references created by a [preemptive process](../Develop/preemptive.md) can only be used in that specific process. Conversely, XML references created by a cooperative process can be used by any other cooperative process, but cannot be used by any preemptive process. + + +### Character Sets + +The following character sets are supported by the XML DOM and XML SAX commands of 4D: + +- ASCII +- UTF-8 +- UTF-16 (Big/Small Endian) +- UCS4 (Big/Small Endian) +- EBCDIC code pages IBM037, IBM1047 and IBM1140 encodings, +- ISO-8859-1 (or Latin1) +- Windows-1252. + + +### Glossary + +This non-exhaustive list details the main XML concepts used by the commands and functions of 4D. + +- **Attribute**: an XML sub-tag associated with an element. An attribute always contains a name and a value. +- **Child**: In an XML structure, an element in a level directly below another. +- **DTD**: *Document Type Declaration*. The DTD records the set of specific rules and properties that the XML must follow. These rules define, more particularly, the name and content of each tag as well as its context. This formalization of the elements can be used to check whether an XML document is in compliance (in which case, it is declared “valid”). The DTD may be included in the XML document (internal DTD) or in a separate document (external DTD). Note that the DTD is not mandatory. +- **Element**: an XML tag. An element always contains a name and a value. Optionally, an element may contain attributes. +- **ElementRef**: XML reference used by the 4D XML commands to specify an XML structure. This reference is made up of 8 coded characters in hexadecimal form, which means that its length is 32 characters on a 64-bit system. It is recommended to declare XML references as Text. +- **Parent**: In an XML structure, an element in a level directly above another. +- **Parsing, parser**: The act of analyzing the contents of a structured object in order to extract useful information. +- **Root**: An element located at the first level of an XML structure. +- **Sibling**: An element at the same level as another. +- **Structure**: structured XML object. This object can be a document, a variable, or an element. +- **Validation**: An XML document is “validated” by the parser when it is “well-formed” and in compliance with the DTD specifications. +- **Well-formed**: An XML document is declared “well-formed” by the parser when it complies with the generic XML specifications. +- **XML**: eXtensible Markup Language. A computerized data exchange standard enabling the transfer of data as well as their structure. The XML language is based on the use of tags and a specific syntax, in keeping with the HTML language. However, unlike the latter, the XML language allows the definition of customized tags. +- **XSL**: eXtensible Stylesheet Language. A language permitting the definition of style sheets used to process and display the contents of an XSL document. + + +## XML DOM Commands + +### Creating, opening and closing XML documents via DOM + +Objects created, modified or parsed by the [4D XML DOM commands](../commands/theme/XML_DOM.md) can be text, URLs, documents or BLOBs. The DOM commands used for opening XML objects in 4D are [`DOM Parse XML source`](../commands/dom-parse-xml-source) and [`DOM Parse XML variable`](../commands/dom-parse-xml-variable). + +Many commands then let you read, parse and write the elements and attributes. Errors are recovered using the [`XML GET ERROR`](../commands/xml-get-error) command. Do not forget to call the [`DOM CLOSE XML`](../commands/dom-close-xml) command to close the source in the end. + +Note about use of XML BLOB parameters: For historical reasons, XML commands such as [`DOM Parse XML variable`](../commands/dom-parse-xml-variable) accept BLOB type parameters. However, it is highly recommended to store XML structures as Text. The use of BLOBs is reserved for processing binary data. In conformity with XML specifications, binary data are automatically encoded in Base64, even when the BLOB contains text. + + +### Support of XPath notation + +Several XML DOM commands ([`DOM Create XML element`](../commands/dom-create-xml-element), [`DOM Find XML element`](../commands/dom-find-xml-element), [`DOM Create XML element arrays`](../commands/dom-create-xml-element-arrays) and [`DOM SET XML ELEMENT VALUE`](../commands/dom-set-xml-element-value)) support some XPath expressions for accessing XML elements. + +XPath notation comes from the XPath language, designed to navigate within XML structures. It allows the setting of elements directly within an XML structure via a "pathname" type syntax, without necessarily having to indicate the complete pathname in order to reach it. + +For example, given the following structure: + +```xml + + + + + + + +``` + +XPath notation allows you to access element 3 using the */RootElement/Elem1/Elem2/Elem3* syntax. + +4D also accepts indexed XPath elements using the *Element[ElementNum]* syntax. For example, given the following structure: + +```xml + + + aaa + bbb + ccc + + +``` + +XPath notation allows you to access the "ccc" value using the */RootElement/Elem1/Elem2[3]* syntax. + +For a comprehensive list of supported XPath expressions, refer to the [`DOM Find XML element`](../commands/dom-find-xml-element) command description. + +:::note Compatibility + +Starting with 4D 18 R3, the XPath implementation has been modified to be more compliant and to support a wider set of expressions. If you want to benefit from the extended features in your converted databases, you need to select the **Use standard XPath** option of the [Compatibility page](../settings/compatibility.md). + +::: + +### Error Handling + +Many functions in this theme return an XML element reference. If an error occurs during function execution (for example, if the root element reference is not valid), the *OK* variable is set to 0 and an error is generated. + +In addition, the reference returned in this case is a sequence of 32 zero "0" characters. + + +## XML SAX Commands + +### Creating, opening and closing XML documents via SAX + +The [XML SAX commands](../commands/theme/XML_SAX.md) work with the standard document references of 4D (**DocRef**, a Time type reference). It is therefore possible to use these commands jointly with the 4D commands used to manage documents, such as [`SEND PACKET`](../commands/send-packet) or [`Append document`](../commands/append-document). + +The creation and opening of XML documents by programming is carried out using the [`Create document`](../commands/create-document) and [`Open document`](../commands/open-document) commands. Subsequently, the use of an XML command with these documents will cause the automatic activation of XML mechanisms such as encoding. For instance, the `` header will be written automatically in the document. + +:::note + +Documents read by SAX commands must be opened in read-only mode by the [`Open document`](../commands/open-document) command. This avoids any conflict between 4D and the Xerces library when you open "regular" and XML documents simultaneously. If you execute a SAX parsing command with a document open in read-write mode, an alert message is displayed and parsing is impossible. + +::: + +Closing an XML document must be carried out using the [`CLOSE DOCUMENT`](../commands/close-document) command. If any XML elements were open, they will be closed automatically. + +### About end-of-line characters and BOM management + +When writing SAX documents, 4D uses the following default settings for end-of-line characters and BOM (byte order mask) usage: + +- CRLF characters on Windows and LF on macOS for end-of-line characters +- files are written without BOM. + +:::note Compatibility + +In projects created with 4D versions up to 19.x, by default 4D uses CRLF as end-of-line characters on macOS for SAX and a BOM. You can control the `XML line ending` and `XML BOM` management using the [`XML SET OPTIONS`](../commands/xml-set-options) command and a [Compatibility setting](../settings/compatibility.md). Important: Since SAX file lines are written directly at each statement, if you need to set the BOM and/or end-of-line options, you must call the [`XML SET OPTIONS`](../commands/xml-set-options) command before the first SAX writing command. + +::: diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md b/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md index 3ebf1e4039b0ae..2f81264281d6e4 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md @@ -124,7 +124,7 @@ Portée : 4D local, 4D Server **Valeurs possibles** : entier long > 1 (secondes) -**Description** : Permet de lire ou de fixer la valeur courante de périodicité de l'écriture du cache de données sur le disque, exprimée en secondes. Si elle est modifiée, cette valeur remplace la valeur définie par l'option **Ecriture cache toutes les secondes/minutes** dans la [XML DECODE](../commands/xml-decode) des Propriétés de la base durant la session courante (elle n'est pas stockée dans les Propriétés de la base). +**Description** : Permet de lire ou de fixer la valeur courante de périodicité de l'écriture du cache de données sur le disque, exprimée en secondes. Si elle est modifiée, cette valeur remplace la valeur définie par l'option **Ecriture cache toutes les secondes/minutes** dans la [page Base de données](../../settings/database.md) des paramètres durant la session courante (elle n'est pas stockée dans les paramètres). diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md b/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md index e13bd8f7bb314c..ec394e78e12f0f 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md @@ -129,7 +129,7 @@ Portée : 4D local, 4D Server **Valeurs possibles** : entier long > 1 (secondes) -**Description** : Permet de lire ou de fixer la valeur courante de périodicité de l'écriture du cache de données sur le disque, exprimée en secondes. Si elle est modifiée, cette valeur remplace la valeur définie par l'option **Ecriture cache toutes les secondes/minutes** dans la [XML DECODE](../commands/xml-decode) des Propriétés de la base durant la session courante (elle n'est pas stockée dans les Propriétés de la base). +**Description** : Permet de lire ou de fixer la valeur courante de périodicité de l'écriture du cache de données sur le disque, exprimée en secondes. Si elle est modifiée, cette valeur remplace la valeur définie par l'option **Ecriture cache toutes les secondes/minutes** dans la [page Base de données](../../settings/database.md) des paramètres durant la session courante (elle n'est pas stockée dans les paramètres). diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md b/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md index afd859d8c3ab20..2a57db00010f79 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md @@ -32,6 +32,12 @@ displayed_sidebar: docs La commande **LDAP LOGIN** ouvre une connexion en lecture seule sur le serveur LDAP désigné par le paramètre *url* avec les identifiants *login* et *motDePasse* fournis. Si elle est acceptée par le serveur, cette connexion sera utilisée pour toutes les recherches LDAP effectuées par la suite dans le process courant, jusqu'à ce que la commande [LDAP LOGOUT](../commands/ldap-logout) soit exécutée (ou que le process soit terminé). +:::info + +LDAP ou *Lightweight Directory Access Protocol* est un standard ouvert pour l'accès et la maintenance de services d'information distribués. Pour plus d'informations, veuillez consulter la [page Wikipedia sur LDAP](http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol) ou la page principale du logiciel [OpenLDAP Software](http://www.openldap.org/). + +::: + Dans *url*, passez l'URL complet du serveur LDAP auquel se connecter, incluant le *scheme* et le port (389 by default). Ce paramètre doit être conforme à la [rfc2255](https://www.ietf.org/rfc/rfc2255.txt). Vous pouvez ouvrir une connexion sécurisée via TLS en passant un *url* qui débute par "ldaps" et qui utilise un numéro de port spécifique (par exemple "ldaps://svr.ldap.acme.com:1389"). Le serveur LDAP doit généralement disposer d'un certificat SSL (c'est le cas pour MS Active Directory). Il est fortement recommandé d'utiliser une connexion TLS lorsque le mot de passe est transmis en texte brut (voir ci-dessous). @@ -40,9 +46,9 @@ Vous pouvez ouvrir une connexion sécurisée via TLS en passant un *url* qui dé Dans *login*, passez le compte utilisateur sur le serveur LDAP et dans *motDePasse*, passez le mot de passe du compte. Le *login* peut prendre l'une des formes suivantes, en fonction de la configuration du serveur LDAP : * un Distinguished Name (DN), par exemple "CN=John Smith,OU=users,DC=example,DC=com" -* un nom d'utilisateur (CN), par exemple "CN=John Smith" +* un nom d'utilisateur (CN pour *Common Name*), par exemple "CN=John Smith" * une adresse email, par exemple "johnsmith@4d.fr" -* un SAM-Account-Name, par exemple "jsmith". +* un SAM-Account-Name (*Security Account Manager*, identifiant de connexion pour Active Directory), par exemple "jsmith". Notez que les valeurs admises pour le *login* sont liées au mode de transmission du mot de passe, défini par le paramètre *digest*. Par exemple, dans une configuration par défaut de MS Active Directory : diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md b/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md index dc4a61e6e39b00..00d4227a1dbb4f 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md @@ -52,6 +52,12 @@ Si **PRINT SELECTION** est appelée au même moment par deux process différents Pour imprimer une sélection triée avec des sous-totaux ou des ruptures à l'aide de la commande **PRINT SELECTION**, vous devez d'abord trier la sélection. Puis vous devez inclure, dans chaque zone de rupture de l'état, une variable associée à une méthode objet assignant le sous-total à la variable. Vous pouvez aussi utiliser des fonctions statistiques ou arithmétiques telles que [Sum](../commands/sum) et [Average](../commands/average) pour assigner des valeurs aux variables. Pour plus d'informations, reportez-vous à la description des commandes [Subtotal](../commands/subtotal), [BREAK LEVEL](../commands/break-level) et [ACCUMULATE](../commands/accumulate). +:::note + +Vous pouvez utiliser des [commandes statistiques](../../commands/theme/On_a_Series.md) comme [Sum](../commands/sum) et [Average](../commands/average) pour assigner des valeurs aux variables. Lorsque des fonctions statistiques sont utilisées dans un état, elles se comportent de manière spécifique car l'état lui-même doit charger chaque enregistrement. Lorsque vous utilisez ces fonctions dans un état, les valeurs retournées ne sont fiables qu'au niveau de rupture 0, et uniquement lorsque le traitement des ruptures est activé. Cela signifie qu'elles ne sont utiles qu'à la fin d'un état, après que tous les enregistrements ont été traités. Vous utiliserez ces fonctions uniquement dans une méthode objet d'une zone non saisissable incluse dans la zone de rupture B0. + +::: + **Attention :** N'utilisez pas la commande [PAGE BREAK](../commands/page-break) avec **PRINT SELECTION**. [PAGE BREAK](../commands/page-break) est exclusivement réservée à une utilisation combinée avec la commande [Print form](../commands/print-form). Après un appel à **PRINT SELECTION**, la variable OK prend la valeur 1 si l'impression s'est déroulée correctement. Si l'impression a été interrompue (par exemple l'utilisateur a cliqué sur un bouton Annuler dans les boîtes de dialogue d'impression), la variable OK prend la valeur *0* (zéro). diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/settings/database.md b/i18n/fr/docusaurus-plugin-content-docs/current/settings/database.md index e5b16d1f91f96e..2385c4e76d50e3 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/settings/database.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/settings/database.md @@ -124,3 +124,31 @@ Utilisez les paramètres de cet onglet pour configurer la mémoire cache de la b Si chaque opération d’écriture du cache est accompagnée d’un fort ralentissement de la base de données, il faut ajuster la fréquence. Ce symptôme signifie une sauvegarde massive d’enregistrements. Dans ce cas, une fréquence d’écriture plus élevée, donc plus rapide, est plus efficace. Par défaut, 4D affiche une petite fenêtre lors de l'écriture du cache. Si vous ne voulez pas ce rappel visuel, vous pouvez désélectionner l'option **Ecriture du cache** dans la [Page Interface](./interface.md). + +:::note + +Vous pouvez modifier temporairement la fréquence d'écriture du cache à l'aide du [sélecteur `Cache flush periodicity` de la commande `SET DATABASE PARAMETER`](../commands/set-database-parameter#cache-flush-periodicity-95). + +::: + + + + +### Gestion des priorités dans le cache de la base de données + +Le cache de la base de données 4D inclut un mécanisme automatique de gestion des priorités qui offre un haut niveau d'efficacité et de performance pour l'accès aux données. Grâce à ce mécanisme, lorsque de l'espace est nécessaire pour charger de nouvelles données dans le cache, les données mises en cache de faible priorité sont libérées en premier, tandis que les données mises en cache de priorité plus élevée restent chargées. + +Ce mécanisme est entièrement automatique et, en général, vous n'aurez pas à vous en préoccuper. Toutefois, pour des cas spécifiques, il peut être personnalisé à l'aide d'un [ensemble de commandes dédiées du thème "Gestion du cache"](../commands/theme/Cache_Management.md), qui permettent de modifier la priorité des objets pendant toute la durée de fonctionnement de la base, ou temporairement pour le process courant. Notez que ces commandes doivent être utilisées avec précaution car elles affectent les performances de la base de données. + +#### Présentation de la gestion des priorités + +Le gestionnaire de cache sélectionne les données à retirer du cache si nécessaire à l'aide d'un système de priorités. Les trois types d'objets pouvant être chargés dans le cache ont une priorité différente : + +- **tables** : toutes les données de champs standard (numériques, dates, etc.), à l'exclusion des blobs (voir ci-dessous). La priorité par défaut est moyenne. +- **blobs** : toutes les données de champs binaires (texte, image, objet et blobs) stockées dans le fichier de données. La priorité par défaut est la plus basse. +- **index** : tous les index de champs, y compris les index par mots-clés et les index composites. Étant donné que les index sont fréquemment consultés, ils ont un statut spécial dans le cache. La priorité par défaut est la plus élevée. + +Les priorités par défaut offrent généralement les meilleures performances. Toutefois, pour des cas spécifiques, vous pouvez personnaliser les priorités du cache à l'aide de deux ensembles de commandes 4D : + +- Les commandes qui modifient les priorités pour toute la session et tous les process : [`SET TABLE CACHE PRIORITY`](../commands/set-table-cache-priority), [`SET INDEX CACHE PRIORITY`](../commands/set-index-cache-priority), et [`SET BLOBS CACHE PRIORITY`](../commands/set-blobs-cache-priority). Ces commandes doivent être utilisées dans une méthode base sur ouverture. +- Les commandes qui modifient les priorités uniquement pour le process courant : [`ADJUST TABLE CACHE PRIORITY`](../commands/adjust-table-cache-priority), [`ADJUST INDEX CACHE PRIORITY`](../commands/adjust-index-cache-priority), et [`ADJUST BLOBS CACHE PRIORITY`](../commands/adjust-blobs-cache-priority). Utilisez ces commandes pour améliorer les performances d'une opération temporaire sur votre base et revenir aux priorités initiales une fois l'opération terminée. Ces commandes sont disponibles uniquement sur 4D Server ou 4D en mode local. diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md index 3029942e49a485..c4a336453e54e6 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md @@ -123,7 +123,7 @@ Portée : 4D local, 4D Server **Valeurs possibles** : entier long > 1 (secondes) -**Description** : Permet de lire ou de fixer la valeur courante de périodicité de l'écriture du cache de données sur le disque, exprimée en secondes. Si elle est modifiée, cette valeur remplace la valeur définie par l'option **Ecriture cache toutes les secondes/minutes** dans la [XML DECODE](../commands/xml-decode) des Propriétés de la base durant la session courante (elle n'est pas stockée dans les Propriétés de la base). +**Description** : Permet de lire ou de fixer la valeur courante de périodicité de l'écriture du cache de données sur le disque, exprimée en secondes. Si elle est modifiée, cette valeur remplace la valeur définie par l'option **Ecriture cache toutes les secondes/minutes** dans la [page Base de données](../../settings/database.md) des paramètres durant la session courante (elle n'est pas stockée dans les paramètres). diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md index b419010fd3279f..3b21b7314ba0e9 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md @@ -128,7 +128,7 @@ Portée : 4D local, 4D Server **Valeurs possibles** : entier long > 1 (secondes) -**Description** : Permet de lire ou de fixer la valeur courante de périodicité de l'écriture du cache de données sur le disque, exprimée en secondes. Si elle est modifiée, cette valeur remplace la valeur définie par l'option **Ecriture cache toutes les secondes/minutes** dans la [XML DECODE](../commands/xml-decode) des Propriétés de la base durant la session courante (elle n'est pas stockée dans les Propriétés de la base). +**Description** : Permet de lire ou de fixer la valeur courante de périodicité de l'écriture du cache de données sur le disque, exprimée en secondes. Si elle est modifiée, cette valeur remplace la valeur définie par l'option **Ecriture cache toutes les secondes/minutes** dans la [page Base de données](../../settings/database.md) des paramètres durant la session courante (elle n'est pas stockée dans les paramètres). diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/legacy-to-import.md b/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/legacy-to-import.md new file mode 100644 index 00000000000000..f4c532758ef675 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/legacy-to-import.md @@ -0,0 +1,91 @@ +--- +id: legacy-to-import +title: develop-legacy +draft: true +--- + + + + +## セマフォ + +セマフォを使用すると、2つ以上のプロセスが同じリソース (ファイル、レコードなど) を同時に変更しないようにできます。セマフォを設定したプロセスのみが、それを解除できます。 + +:::info + +[シグナル](../API/SignalClass.md) もインタラクションの管理に使用できます。シグナルを使用すると、1つ以上のプロセスが特定のタスクの完了を待ってから実行を続行するようにできます。任意のプロセスがシグナルを待機したり、解放したりできます。 + +::: + +### セマフォとは何か? + +コンピュータープログラムにおいて、セマフォは、一度に1つのプロセスまたはユーザーのみが実行する必要のあるアクションを保護するために使用されるツールです。 + +4Dにおいてセマフォを使用する一般的なニーズは、プロセス間配列を変更することにあります。あるプロセスが配列の値を変更している場合、別のプロセスが同時に同じことをできてはなりません。開発者はセマフォを使用して、他のプロセスがすでに同じタスクを実行していない場合にのみ、プロセスが一連の処理を実行できることを示します。プロセスがセマフォに遭遇したとき、3つの可能性があります: + +- ただちに通過する権利を得る +- 通過する権利を得るまで順番を待つ +- タスクの実行をあきらめて、そのまま進む。 + +したがって、セマフォはコードの一部を保護します。一度に1つのプロセスのみを通過させ、現在使用権を保持しているプロセスがセマフォを解放してその権利を手放すまでアクセスをブロックします。 + +### セマフォを操作するためのコマンド + +4Dでは、[`Semaphore`](../commands/sempahore) コマンドを呼び出してセマフォを設定します。セマフォを解放するには、[`CLEAR SEMAPHORE`](../commands/clear-sempahore) コマンドを呼び出します。 + +[`Semaphore`](../commands/sempahore) コマンドは、潜在的に2つのアクションを同時に実行するため、非常に特殊な動作をします: + +- セマフォがすでに割り当てられている場合、関数は **True** を返します +- セマフォが割り当てられていない場合、関数はそれをプロセスに割り当て、同時に **False** を返します。 + +同じコマンドによっておこなわれるこの二重のアクションは、セマフォのテストとその割り当てのあいだに外部の操作が挿入されないことを保証します。 + +[`Test semaphore`](../commands/test-semaphore) コマンドを使用すると、セマフォがすでに割り当てられているかどうかを知ることができます。このコマンドは主に、年次の決算処理などの長時間にわたる操作の一環として使用され、[`Test semaphore`](../commands/test-semaphore) を使うことで、会計データの追加などの特定の操作へのアクセスを防ぐようにインターフェースを制御できます。 + +### セマフォの使用方法 + +セマフォは、次の原則に従って使用する必要があります: + +- セマフォは同じメソッド内で設定し、解放しなければなりません。 +- セマフォによって保護されるコードの実行は、できる限り短くしなければなりません。 +- セマフォの解放を待つために、コードは [`Semaphore`](../commands/sempahore) コマンドの tickCount 引数によってタイミングを設定しなければなりません。 + +セマフォを使用する典型的なコードは次のとおりです: + +```4d + While(Semaphore("MySemaphore";300)) + IDLE + End while + // セマフォによって保護されるコードをここに置く + CLEAR SEMAPHORE("MySemaphore") +``` + +解放されないセマフォは、データベースの一部をブロックする可能性があります。セマフォの設定と解放を同じメソッド内でおこなうことは、このリスクを排除するのに役立ちます。 + +セマフォによって保護されるコードを最小限に抑えることで、アプリケーションの流動性が高まり、セマフォがボトルネックとして機能するのを防ぎます。 + +最後に、[`Semaphore`](../commands/sempahore) コマンドのオプションの *tickCount* 引数を使用することは、セマフォの解放待ちを最適化するために不可欠です。この引数を使用すると、コマンドは次のように動作します: + +- プロセスは、コードの実行が次の行に進むことなく、セマフォが利用可能になるまで、指定された tick 数 (この例では300) を最大として待機します。 +- この制限の終了前にセマフォが解放された場合、それはただちにプロセスに割り当てられ (Semaphore は False を返します)、コードの実行が再開されます。 +- この制限の終了前にセマフォが解放されない場合、コードの実行が再開されます。 + +このコマンドは、待ち行列を確立することでリクエストに優先順位を付けることもします。このようにして、セマフォを最初にリクエストしたプロセスが最初にそれを取得します。待機時間は、アプリケーションの仕様に応じて設定されることに注意してください。 + +### ローカルセマフォまたはグローバルセマフォ + +4Dには2種類のセマフォがあります: ローカルセマフォとグローバルセマフォです。 + +- ローカルセマフォは、同じワークステーション上のすべてのプロセスからアクセス可能で、そのワークステーション上でのみアクセスできます。ローカルセマフォは、セマフォの名前にドル記号 ($) を接頭辞として付けることで作成できます。ローカルセマフォは、同じワークステーション上で実行されるプロセス間の操作を監視するために使用します。たとえば、ローカルセマフォは、シングルユーザーデータベースまたはワークステーション上のすべてのプロセスによって共有されるプロセス間配列へのアクセスを監視するために使用できます。 +- グローバルセマフォは、すべてのユーザーとそのすべてのプロセスからアクセス可能です。グローバルセマフォは、マルチユーザーデータベースのユーザー間の操作を監視するために使用します。 + +グローバルセマフォとローカルセマフォは、その論理においては同一です。違いはそのスコープにあります。 + +クライアント/サーバーにおいて、グローバルセマフォは、すべてのクライアントとサーバー上で実行されるすべてのプロセス間で共有されます。ローカルセマフォは、それが作成されたマシン上で実行されるプロセス間でのみ共有されます。 + +シングルユーザーの4Dアプリケーションでは、あなたが唯一のユーザーであるため、グローバルセマフォとローカルセマフォは同じスコープを持ちます。ただし、データベースが両方の構成で使用されている場合は、おこないたいことに応じてグローバルセマフォまたはローカルセマフォを使用するようにしてください。 + +**注:** インターフェースやプロセス間変数の配列など、アプリケーションのクライアントのローカルな側面を管理するためにセマフォが必要な場合は、ローカルセマフォの使用を推奨します。この場合にグローバルセマフォを使用すると、不要なネットワーク交換を引き起こすだけでなく、他のクライアントマシンに不必要に影響を与える可能性もあります。ローカルセマフォを使用すれば、これらの望ましくない副作用を回避できます。 + + + \ No newline at end of file diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/overview.md b/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/overview.md new file mode 100644 index 00000000000000..793f5e5c9dbd03 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/overview.md @@ -0,0 +1,7 @@ +--- +id: overview +title: 4D database overview +--- + +## Description + diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/records.md b/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/records.md new file mode 100644 index 00000000000000..25e1705847e48e --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/records.md @@ -0,0 +1,308 @@ +--- +id: records +title: Records +slug: /Develop/records +displayed_sidebar: docs +--- + + +## Record numbers + +There are three numbers associated with a record: + +- Record number +- Selected record number +- Sequence number + +### Record Number + +The record number is the absolute/physical record number for a record. A record number is automatically assigned to each new record and remains constant for the record until the record is deleted. Record numbers start at zero. They are not unique because record numbers of deleted records are reused for new records. They also change when the database is [compacted](../MSC/compact.md) or [repaired](../MSC/repair.md). + +### Selected Record Number + +The selected record number is the position of the record in the current selection, and so depends on the current selection. If the selection is changed or sorted, the selected record number will probably change. Numbering for the selected record number starts at one (1). + +### Sequence Number + +The sequence number is a unique non-repeating number that may be assigned to a field of a record (via the Autoincrement property, the SQL AUTO_INCREMENT attribute or the [`Sequence number`](../commands/sequence-number) command). It is not automatically stored with each record. It starts by default at 1 and is incremented for each new record that is created. Unlike record numbers, a sequence number is not reused when a record is deleted or when a database is compacted or repaired. Sequence numbers provide a way to have unique ID numbers for records. If a sequence number is incremented during a transaction, the number is not decremented if the transaction is canceled. + +:::note Notes + +- 4D does not carry out any check when you modify the automatic number internal counter of a table using the [`SET DATABASE PARAMETER`](../commands/set-database-parameter) command. If you decrement this counter, the new records created may have numbers that have already been assigned. +- Sequence numbers are not recommended to fill unique ID primary key fields for records. To create unique record IDs, it is strongly recommended to use UUIDs. + +::: + +### Example + +The following tables illustrate the numbers that are associated with records. Each line in the table represents information about a record. The order of the lines is the order in which records would be displayed in an output form. + +- **Data**: The data from a field in each record. For our example, it contains a person’s name. +- **Record Number**: The record’s absolute record number. This is the number returned by the [`Record number`](../commands/record-number) command. +- **Selected Record Number**: The record’s position in the current selection. This is the number returned by the [`Selected record number`](../commands/selected-record-number) command. +- **Sequence Number**: The record’s unique sequence number. This is the number returned by the [`Sequence number`](../commands/sequence-number) command when the record was created. This number is stored in a field. + +#### After the Records Are Entered + +The first table shows the records after they are entered. + +- The default order for the records is by record number. +- The record number starts at 0. +- The selected record number and the sequence number start at 1. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Tess |0| 1| 1| +|Terri| 1 |2 |2| +|Sabra| 2|3| 3| +|Sam| 3 |4 |4| +|Lisa| 4| 5 |5| + +Note: The records remain in the default order after a command changes the current selection without reordering it; for example, after the **Show All** menu command is chosen in the Design environment, or after the [`ALL RECORDS`](../commands/all-records) command is executed. + +#### After the Records Are Sorted + +The next table shows the same records sorted by name. + +- The same record number remains associated with each record. +- The selected record numbers reflect the new position of the records in the sorted selection. +- The sequence numbers never change, since they were assigned when each record was created and are stored in the record. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Lisa| 4| 1 |5| +|Sabra| 2|2| 3| +|Sam| 3 |3 |4| +|Terri| 1 |4 |2| +|Tess |0| 5| 1| + + +#### After a Record Is Deleted + +The following table shows the records after Sam is deleted. + +- Only the selected record numbers have changed. Selected record numbers reflect the order in which the records are displayed. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Lisa| 4| 1 |5| +|Sabra| 2|2| 3| +|Terri| 1 |3 |2| +|Tess |0| 4| 1| + + +#### After a Record Is Added + +The next table shows the records after a new record has been added for Liz. + +- A new record is added to the end of the current selection. +- Sam’s record number is reused for the new record. +- The sequence number continues to increment. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Tess |0| 1| 1| +|Terri| 1 |2 |2| +|Sabra| 2|3| 3| +|Lisa| 4| 4 |5| +|Liz |3| 5| 6| + +#### After the Selection is Changed and Sorted + +The following table shows the records after the selection was reduced to three records and then sorted. + +- Only the selected record number associated with each record changes. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Sabra| 2|1| 3| +|Liz |3| 2| 6| +|Terri| 1 |3 |2| + +## Record Stack + +The [`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) commands allow you to put (“push”) records onto the record stack, and to remove (“pop”) them from the stack. + +Each process has its own record stack for each table. 4D maintains the record stacks for you. Each record stack is a last-in-first-out (LIFO) stack. Stack capacity is limited by memory. + +[`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) should be used with discretion. Each record that is pushed uses part of free memory. Pushing too many records can cause an out-of-memory or stack full condition. + +4D clears the stack of any unpopped records when you return to the menu at the end of execution of your method. + +[`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) are useful when you want to examine records in the same file during data entry. To do this, you push the record, search and examine records in the file (copy fields into variables, for example), and finally pop the record to restore the record. + +While entering a record, if you have to check a multiple field unique value, use the [`SET QUERY DESTINATION`](../commands/set-quer-destination) command. This will save you the calls to [`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) that you were making before and after the call to QUERY in order to preserve the data entered in the current record. [`SET QUERY DESTINATION`](../commands/set-quer-destination) allows you to make a query that does not change the selection nor the current record. + +## Record locking + +4D and 4D Server automatically manage databases by preventing multi-user or multi-process conflicts. Two users or two processes cannot modify the same record or object at the same time. However, the second user or process can have read-only access to the record or object at the same time. + +There are several reasons for using the multi-user commands: + +- Modifying records by using the language. +- Using a custom user interface for multi-user operations. +- Saving related modifications inside a transaction. + +There are three important concepts to be aware of when using commands in a multi-processing database: + +1. In a process, each table is in either a read-only or a read/write state. +2. Records become locked when they are loaded and unlocked when they are unloaded. +3. A locked record cannot be modified. + +As a convention in the following sections, the person performing an operation on the multi-user database is referred to as the **local user**. Other people using the database are referred to as the **other users**. The discussion is from the perspective of the local user. Also, from a multi-process perspective, the process executing an operation on the database is the **current process**. Any other executing process is referred to as **other processes**. The discussion is from the point of view of the current process. + +### Locked Records + +A locked record cannot be modified by the local user or the current process. A locked record can be loaded, but cannot be modified. A record is locked when one of the other users or processes has successfully loaded the record for modification, or when the record is stacked. Only the user who is modifying the record sees that record as unlocked. All other users and processes see the record as locked, and therefore unavailable for modification. A table must be in a read/write state for a record to be loaded unlocked. + +### Read-Only and Read/Write States + +Each table in a database is in either a read/write or a read-only state for each user and process of the database. **Read-only** means that records for the table can be loaded but not modified. **Read/write** means that records for the table can be loaded and modified if no other user has locked the record first. + +Note that if you change the status of a table, the change takes effect for the next record loaded. If there is a record currently loaded when you change the table’s status, that record is not affected by the status change. + +#### Read-Only State + +When a table is read-only and a record is loaded, this record is always locked. In other words, locked records can be displayed, printed, and otherwise used, but they cannot be modified. + +Note that the read-only state applies only to editing existing records. A read-only state does not affect the creation of new records. You can still add records to a read-only table using [`CREATE RECORD`](../commands/create-record) and [`ADD RECORD`](../commands/add-record), or the menu commands of the Design environment (in this case, the records being created are locked for all other users/processes). Note that the [`ARRAY TO SELECTION`](../commands/array-to-selection) command is not affected by the read-only state since it can both create and modify records. + +4D automatically sets a table to read-only for commands that do not require write access to records. These commands are: [`DISPLAY SELECTION`](../commands/display-selection), [`DISTINCT VALUES`](../commands/distinct-values), [`EXPORT DIF`](../commands/export-dif), [`EXPORT SYLK`](../commands/export-sylk), [`EXPORT TEXT`](../commands/export-text), [`PRINT SELECTION`](../commands/print-selection), [`PRINT LABEL`](../commands/print-label), [`QR REPORT`](../commands/qr-report), [`SELECTION TO ARRAY`](../commands/selection-to-array), [`SELECTION RANGE TO ARRAY`](../commands/selection-range-to-array). + +You can find out the state of a table at any time using the [`Read only state`](../commands/read-only-state) function. + +Before executing any of these commands, 4D saves the current state of the table (read-only or read/write) for the current process. After the command has executed, this state is restored. + +#### Read/Write State + +When a table is read/write and a record is loaded, the record will become unlocked if no other user has locked the record first. If the record is locked by another user, the record is loaded as a locked record that cannot be modified by the local user. + +A table must be set to read/write and the record loaded for it to become unlocked and thus modifiable. + +If a user loads a record from a table in read/write mode, no other users can load that record for modification. However, other users can add records to the table, either through the [`CREATE RECORD`](../commands/create-record) and [`ADD RECORD`](../commands/add-record) commands or manually in the Design environment. + +Read/write is the default state for all tables when a database is opened and a new process is started. + +#### Changing the Status of a Table + +You can use the [`READ ONLY`](../commands/read-only) and [`READ WRITE`](../commands/read-write) commands to change the state of a table. If you want to change the state of a table in order to make a record read-only or read/write, you must execute the command before this record is loaded. Any record that is already loaded is not affected by the [`READ ONLY`](../commands/read-only) and [`READ WRITE`](../commands/read-write) commands. + +Each process has its own state (read-only or read/write) for each table in the database. + +By default, if you do not use the READ ONLY command, all tables are in read/write mode. + +### Loading, Modifying and Unloading Records + +Before the local user can modify a record, the table must be in the read/write state and the record must be loaded and unlocked. + +Any of the commands that loads a current record (if there is one) — such as [`NEXT RECORD`](../commands/next-record), [`QUERY`](../commands/query), [`ORDER BY`](../commands/order-by), [`RELATE ONE`](../commands/relate-one), etc. — sets the record state as locked or unlocked. The record is loaded according to the current state of its table (read-only or read/write) and its availability. A record may also be loaded for a related table by any of the commands that cause an automatic relation to be established. + +If a table is in the read-only state for a process or a user, then this table's records are loaded in read-only mode, which means they cannot be modified or deleted by this process or user. This is recommended for viewing or retrieving data because it does not prevent other users or processes from accessing the records of this table in read/write mode if necessary. + +If a table is in the read/write state for a process or a user, then any record from this table is also loaded in read/write mode, but only if no other user or process has already locked this record. If a record is successfully loaded in read/write mode, it is unlocked for the current process or user (it can be modified and saved) and is locked for all other users or processes. A table must be put into the read/write state before loading a record for modification and then saving it. + +If the record is to be modified, you use the Locked function to test whether or not a record is locked by another user. If a record is locked (Locked returns True), load the record with the [`LOAD RECORD`](../commands/load-record) command and again test whether or not the record is locked. This sequence must be continued until the record becomes unlocked (Locked returns False). + +When modifications to be made to a record are finished, the record must be released (and therefore unlocked for the other users) with [`UNLOAD RECORD`](../commands/unload-record). If a record is not unloaded, it will remain locked for all other users until a different current record is selected. Changing the current record of a table automatically unlocks the previous current record. You need to explicitly call [`UNLOAD RECORD`](../commands/unload-record) if you do not change the current record. This discussion applies to existing records. When a new record is created, it can be saved regardless of the state of the table to which it belongs. + +:::note + +When it is used in a transaction, the [`UNLOAD RECORD`](../commands/unload-record) command unloads the current record only for the process that manages the transaction. For other processes, the record stays locked as long as the transaction has not been validated (or cancelled). + +::: + +Use the [`LOCKED BY`](../commands/locked-by) command to see which user and/or process have locked a record. + +::: + +A good practice is to place all tables in read-only mode when each process is started (using the syntax [`READ ONLY(*)`](../commands/read-only)) then put each table in read/write mode only when necessary. Access to tables in read-only mode is faster and more memory-efficient. Moreover, changing the state of a table is optimized in client/server mode because it does not cause any additional network traffic: information is only sent to the server when executing a command that requires adequate access to the table. + +::: + +### Loops to Load Unlocked Records + +The following example shows the simplest loop with which to load an unlocked record: + +```4d + READ WRITE([Customers])//Set the table’s state to read/write + Repeat//Loop until the record is unlocked + LOAD RECORD([Customers])//Load record and set locked status + Until(Not(Locked([Customers]))) + //Do something to the record here + READ ONLY([Customers])//Set the table’s state to read-only +``` + +The loop continues until the record is unlocked. + +A loop like this is used only if the record is unlikely to be locked by anyone else, since the user would have to wait for the loop to terminate. Thus, it is unlikely that the loop would be used as is unless the record could only be modified by means of a method. + +The following example uses the previous loop to load an unlocked record and modify the record: + +```4d + READ WRITE([Inventory]) + Repeat //Loop until the record is unlocked + LOAD RECORD([Inventory]) //Load record and set it to locked + Until(Not(Locked([Inventory]))) + [Inventory]Part Qty:=[Inventory]Part Qty 1 //Modify the record + SAVE RECORD([Inventory]) //Save the record + UNLOAD RECORD([Inventory]) //Let other users modfiy it + READ ONLY([Inventory]) +``` + + +The [`MODIFY RECORD`](../commands/modify-record) command automatically notifies the user if a record is locked, and prevents the record from being modified. The following example avoids this automatic notification by first testing the record with the Locked function. If the record is locked, the user can cancel. + +This example efficiently checks to see if the current record is locked for the table [Commands]. If it is locked, the process is delayed by the procedure for one second. This technique can be used both in a multi-user or multi-process situation: + +```4d + Repeat + READ ONLY([Commands])//You do not need read/write right now + QUERY([Commands]) + //If the search was completed and some records were returned + If((OK=1) & (Records in selection([Commands])>0)) + READ WRITE([Commands])//Set the table to read/write state + LOAD RECORD([Commands]) + While(Locked([Commands]) & (OK=1)) `If the record is locked, + //loop until the record is unlocked + //Who is the record locked by? + LOCKED BY([Commands];$Process;$User;$SessionUser;$Name) + If($Process=-1)//Has the record been deleted? + ALERT("The record has been deleted in the meantime.") + OK:=0 + Else + If($User="")//Are you in single-user mode + $User:="you" + End if + CONFIRM("The record is already used by "+$User+" in the "+$Name+" Process.") + If(OK=1)//If you want to wait for a few seconds + DELAY PROCESS(Current process;120)//Wait for a few seconds + LOAD RECORD([Commands])//Try to load the record + End if + End if + End while + If(OK=1)//The record is unlocked + MODIFY RECORD([Commands])//You can modify the record + UNLOAD RECORD([Commands]) + End if + READ ONLY([Commands])//Switch back to read-only + OK:=1 + End if + Until(OK=0) +``` + + +### Using Commands in Multi-user or Multi-process Environment + +A number of commands in the language perform specific actions when they encounter a locked record. They behave normally if they do not encounter a locked record. + +Here is a list of these commands and their actions when a locked record is encountered. + +- [`MODIFY RECORD`](../commands/modify-record): Displays a dialog box stating that the record is in use. The record is not displayed, therefore the user cannot modify the record. In the Design environment, the record is shown in read-only state. +- [`MODIFY SELECTION`](../commands/modify-selection): Behaves normally except when the user double-clicks a record to modify it. [`MODIFY SELECTION`](../commands/modify-selection) displays dialog box stating that the record is in use and then allows read-only access to the record. +- [`APPLY TO SELECTION`](../commands/apply-to-selection): Loads a locked record, but does not modify it. [`APPLY TO SELECTION`](../commands/apply-to-selection) can be used to read information from the table without special care. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`DELETE SELECTION`](../commands/delete-selection): Does not delete any locked records; it skips them. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`DELETE RECORD`](../commands/delete-record): This command is ignored if the record is locked. No error is returned. You must test that the record is unlocked before executing this command. +- [`SAVE RECORD`](../commands/save-record): This command is ignored if the record is locked. No error is returned. You must test that the record is unlocked before executing this command. +- [`ARRAY TO SELECTION`](../commands/array-to-selection): Does not save any locked records. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`GOTO RECORD`](../commands/goto-record): Records in a multi-user/multi-process database may be deleted and added by other users, therefore the record numbers may change. Use caution when directly referencing a record by number in a multi-user database. +- [**Sets**](./sets.md): Take special care with sets, as the information that the set was based on may be changed by another user or process. diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/sets.md b/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/sets.md new file mode 100644 index 00000000000000..f1e42b3cc1c863 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/sets.md @@ -0,0 +1,168 @@ +--- +id: sets +title: Sets +slug: /Develop/sets +displayed_sidebar: docs +--- + + +Sets offer you a powerful, swift means for manipulating record selections. Besides the ability to create sets, relate them to the current selection, and store, load, and clear sets, 4D offers three standard set operations: + +- Intersection +- Union +- Difference. + + +## Sets and the Current Selection + +A set is a compact representation of a selection of records. The idea of sets is closely bound to the idea of the current selection. Sets are generally used for the following purposes: + +- To save and later restore a selection when the order does not matter +- To access the selection a user made on screen (the `UserSet`) +- To perform a logical operation between selections. + +The current selection is a list of references that points to each record that is currently selected. The list exists in memory. Only currently selected records are in the list. A selection doesn’t actually contain the records, but only a list of references to the records. Each reference to a record takes 4 bytes in memory. When you work on a table, you always work with the records in the current selection. When a selection is sorted, only the list of references is rearranged. There is only one current selection for each table inside a process. + +Like a current selection, a set represents a selection of records. A set does this by using a very compact representation for each record. Each record is represented by one bit (one-eighth of a byte). Operations using sets are very fast, because computers can perform operations on bits very quickly. A set contains one bit for every record in the table, whether or not the record is included in the set. In fact, each bit is equal to 1 or 0, depending on whether or not the record is in the set. + +Sets are very economical in terms of RAM space. The size of a set, in bytes, is always equal to the total number of records in the table divided by 8. For example, if you create a set for a table containing 10,000 records, the set takes up 1,250 bytes, which is about 1.2K in RAM. + +There can be many sets for each table. In fact, sets can be saved to disk separately from the database. To change a record belonging to a set, first you must use the set as the current selection, then modify the record or records. + +A set is never in a sorted order—the records are simply indicated as belonging to the set or not. On the other hand, a named selection is in sorted order, but it requires more memory in most cases. For more information about named selections, see the Named Selections section. + +A set "remembers" which record was the current record at the time the set was created. The following table compares the concepts of the current selection and of sets: + +|Comparison|Current Selection|Sets| +|---|---|---| +|Number per table|1|0 to many| +|Sortable|Yes|No| +|Can be saved on disk|No|Yes| +|RAM per record(in bytes)|Number of selected records * 4|Total number of records/8| +|Combinable| No| Yes| +|Contains current record| Yes| Yes, as of the time the set was created| + +When you create a set, it belongs to the table from which you created it. Set operations can be performed only between sets belonging to the same table. + +Sets are independent from the data. This means that after changes are made to a file, a set may no longer be accurate. There are many operations that can cause a set to be inaccurate. For example, if you create a set of all the people from New York City, and then change the data in one of those records to “Boston” the set would not change, because the set is just a representation of a selection of records. Deleting records and replacing them with new ones also changes a set, as well as compacting the data. Sets can be guaranteed to be accurate only as long as the data in the original selection has not been changed. + +## Process and Interprocess Sets + +You can have the following three types of sets: + +- **Process sets**: A process set can only be accessed by the process in which it has been created. `LockedSet` is a process set. Process sets are cleared as soon as the process method ends. Process sets do not need any special prefix in the name. +- **Interprocess sets**: A set is an interprocess set if the name of the set is preceded by the symbols (<>) — a “less than” sign followed by a “greater than” sign. An interprocess set is “visible” to all the processes of the database. +In client/server mode, an interprocess set is “visible” to processes of the machine where it was created (client or server). +The name of an interprocess set must be unique in the database. +- **Local Sets/Client Sets**: Local/client sets are intended for use in client/server mode. The name of a local/client set is always preceded by the dollar sign ($) -- except for the UserSet system set. Unlike other types of sets, a local/client set is stored on the client machine. + +:::note Notes + +- The maximum size of a set name is 255 characters (excluding <> and $ symbols). +- For more information about the use of sets in client/server mode, please refer to 4D Server, Sets and Named Selections. + +::: + + +## Visibility of Sets + +The following table indicates the principles concerning the visibility of sets depending on their scope and where they were created: + + + +||Client Process|Other processes on the same client|Other clients|Server process|Other processes on the server| +|---|---|---|---|---|---| +|Creation in a client process |||||| +|$test|X ||||| +|test | X||| X(Trigger) || +|<>test | X|X |||| +|Creation in a server process|||||| +|$test|||| X|| +|test ||||X|| +|<>test||||X| X| + + +## Sets and Transactions + +A set can be created inside a [transaction](./transactions.md). It is possible to create a set of the records created inside a transaction and a set of records created or modified outside of a transaction. When the transaction ends, the set created during the transaction should be cleared, because it may not be an accurate representation of the records, especially if the transaction was canceled. + +## Example + +The following example deletes duplicate records from a table which contains information about people. A For...End for loop moves through all the records, comparing the current record to the previous record. If the name, address, and zip code are the same, then the record is added to a set. At the end of the loop, the set is made the current selection and the (old) current selection is deleted: + +```4d + CREATE EMPTY SET([People];"Duplicates") + // Create an empty set for duplicate records + ALL RECORDS([People]) + // Select all records + // Sort the records by ZIP, address, and name so + // that the duplicates will be next to each other + ORDER BY([People];[People]ZIP;>;[People]Address;>;[People]Name;>) + // Initialize variables that hold the fields from the previous record + $Name:=[People]Name + $Address:=[People]Address + $ZIP:=[People]ZIP + // Go to second record to compare with first + NEXT RECORD([People]) + For($i;2;Records in table([People])) + // Loop through records starting at 2 + // If the name, address, and ZIP are the same as the + // previous record then it is a duplicate record. + If(([People]Name=$Name) & ([People]Address=$Address) & ([People]ZIP=$ZIP)) + // Add current record (the duplicate) to set + ADD TO SET([People];"Duplicates") + Else + // Save this record’s name, address, and ZIP for comparison with the next record + $Name:=[People]Name + $Address:=[People]Address + $ZIP:=[People]ZIP + End if + // Move to the next record + NEXT RECORD([People]) + End for + // Use duplicate records that were found + USE SET("Duplicates") + // Delete the duplicate records + DELETE SELECTION([People]) + // Remove the set from memory + CLEAR SET("Duplicates") +``` + +As an alternative to immediately deleting records at the end of the method, you could display them on screen or print them, so that a more detailed comparison can be made. + + +## The UserSet System Set + +4D maintains a system set named `UserSet`, which automatically stores the most recent selection of records highlighted on screen by the user. Thus, you can display a group of records with [`MODIFY SELECTION`](../commands/modify-selection) or [`DISPLAY SELECTION`](../commands/display-selection), ask the user to select from among them and turn the results of that manual selection into a selection or into a set that you name. + +::info 4D Server + +Although its name does not begin with the character "$", the `UserSet` system set is a client set. So, when using [`INTERSECTION`](../commands/intersection), [`UNION`](../commands/union) and [`DIFFERENCE`](../commands/difference), make sure you compare `UserSet` only to client sets. + +::: + +There is only one `UserSet` for a [process](../Develop/processes.md). Each table does not have its own `UserSet`. `UserSet` becomes "owned" by a table when a selection of records is displayed for the table. + +4D manages the `UserSet` set for list forms displayed in Design mode or using the [`MODIFY SELECTION`](../commands/modify-selection) or [`DISPLAY SELECTION`](../commands/display-selection) commands. However, this mechanism is not active for [subforms](../FormObjects/subform_overview.md). + +The following method illustrates how you can display records, allow the user to select some of them, and then use UserSet to display the selected records: + +```4d + // Display all records and allow user to select any number of them. + // Then display this selection by using UserSet to change the current selection. + FORM SET OUTPUT([People];"Display") // Set the output layout + ALL RECORDS([People]) // Select all people + ALERT("Press Ctrl or Command and Click to select the people required.") + DISPLAY SELECTION([People]) // Display the people + USE SET("UserSet") // Use the people that were selected + ALERT("You chose the following people.") + DISPLAY SELECTION([People]) // Display the selected people +``` + +## The LockedSet System Set + +The [`APPLY TO SELECTION`](../commands/apply-to-selection), [`DELETE SELECTION`](../commands/delete-selection), [`ARRAY TO SELECTION`](../commands/array-to-selection) and [`JSON TO SELECTION`](../commands/json-to-selection) commands create a set named `LockedSet` when used in a multi-processing environment. + +Query commands also create a `LockedSet` system set when they find locked records in the 'query and lock' context (see the [`SET QUERY AND LOCK`](../commands/set-query-and-lock) command). + +`LockedSet` indicates which records were locked during the execution of the command. \ No newline at end of file diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/xml.md b/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/xml.md new file mode 100644 index 00000000000000..6691cfcb0e545c --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/Develop-legacy/xml.md @@ -0,0 +1,157 @@ +--- +id: xml +title: XML Processing +slug: /Develop/XML +displayed_sidebar: docs +--- + + +## Overview of XML Commands + +### XML, DOM, and SAX + +The [**XML** theme](../commands/theme/XML.md) groups together the generic XML "utilities" commands of 4D. These are option- and error-management commands. + +4D also offers two separate sets of XML commands: [**DOM**](../commands/theme/XML_DOM.md) (Document Object Model) and [**SAX**](../commands/theme/XML_SAX.md) (Simple API XML) are two different parsing modes for XML documents. + +- The DOM mode parses an XML source and builds its structure (its "tree") in memory. Because of this, access to each element of the source is extremely fast. However, since the entire tree structure is stored in memory, the processing of large XML documents may lead to the memory capacity being exceeded and thus provoke errors. +- The SAX mode does not build a tree structure in memory. In this mode, "events" (such as the start and end of an element) are generated when parsing the source. This mode lets you parse XML documents of any size, regardless of the amount of memory available. + +### References + +http://www.saxproject.org/?selected=event
+http://www.w3schools.com/xml/ + +:::note + +For XML support, 4D uses the [Xerces.dll library](../Notes/updates.md#library-table) developed by the Apache Foundation company. + +::: + + +### Preemptive mode + +XML references created by a [preemptive process](../Develop/preemptive.md) can only be used in that specific process. Conversely, XML references created by a cooperative process can be used by any other cooperative process, but cannot be used by any preemptive process. + + +### Character Sets + +The following character sets are supported by the XML DOM and XML SAX commands of 4D: + +- ASCII +- UTF-8 +- UTF-16 (Big/Small Endian) +- UCS4 (Big/Small Endian) +- EBCDIC code pages IBM037, IBM1047 and IBM1140 encodings, +- ISO-8859-1 (or Latin1) +- Windows-1252. + + +### Glossary + +This non-exhaustive list details the main XML concepts used by the commands and functions of 4D. + +- **Attribute**: an XML sub-tag associated with an element. An attribute always contains a name and a value. +- **Child**: In an XML structure, an element in a level directly below another. +- **DTD**: *Document Type Declaration*. The DTD records the set of specific rules and properties that the XML must follow. These rules define, more particularly, the name and content of each tag as well as its context. This formalization of the elements can be used to check whether an XML document is in compliance (in which case, it is declared “valid”). The DTD may be included in the XML document (internal DTD) or in a separate document (external DTD). Note that the DTD is not mandatory. +- **Element**: an XML tag. An element always contains a name and a value. Optionally, an element may contain attributes. +- **ElementRef**: XML reference used by the 4D XML commands to specify an XML structure. This reference is made up of 8 coded characters in hexadecimal form, which means that its length is 32 characters on a 64-bit system. It is recommended to declare XML references as Text. +- **Parent**: In an XML structure, an element in a level directly above another. +- **Parsing, parser**: The act of analyzing the contents of a structured object in order to extract useful information. +- **Root**: An element located at the first level of an XML structure. +- **Sibling**: An element at the same level as another. +- **Structure**: structured XML object. This object can be a document, a variable, or an element. +- **Validation**: An XML document is “validated” by the parser when it is “well-formed” and in compliance with the DTD specifications. +- **Well-formed**: An XML document is declared “well-formed” by the parser when it complies with the generic XML specifications. +- **XML**: eXtensible Markup Language. A computerized data exchange standard enabling the transfer of data as well as their structure. The XML language is based on the use of tags and a specific syntax, in keeping with the HTML language. However, unlike the latter, the XML language allows the definition of customized tags. +- **XSL**: eXtensible Stylesheet Language. A language permitting the definition of style sheets used to process and display the contents of an XSL document. + + +## XML DOM Commands + +### Creating, opening and closing XML documents via DOM + +Objects created, modified or parsed by the [4D XML DOM commands](../commands/theme/XML_DOM.md) can be text, URLs, documents or BLOBs. The DOM commands used for opening XML objects in 4D are [`DOM Parse XML source`](../commands/dom-parse-xml-source) and [`DOM Parse XML variable`](../commands/dom-parse-xml-variable). + +Many commands then let you read, parse and write the elements and attributes. Errors are recovered using the [`XML GET ERROR`](../commands/xml-get-error) command. Do not forget to call the [`DOM CLOSE XML`](../commands/dom-close-xml) command to close the source in the end. + +Note about use of XML BLOB parameters: For historical reasons, XML commands such as [`DOM Parse XML variable`](../commands/dom-parse-xml-variable) accept BLOB type parameters. However, it is highly recommended to store XML structures as Text. The use of BLOBs is reserved for processing binary data. In conformity with XML specifications, binary data are automatically encoded in Base64, even when the BLOB contains text. + + +### Support of XPath notation + +Several XML DOM commands ([`DOM Create XML element`](../commands/dom-create-xml-element), [`DOM Find XML element`](../commands/dom-find-xml-element), [`DOM Create XML element arrays`](../commands/dom-create-xml-element-arrays) and [`DOM SET XML ELEMENT VALUE`](../commands/dom-set-xml-element-value)) support some XPath expressions for accessing XML elements. + +XPath notation comes from the XPath language, designed to navigate within XML structures. It allows the setting of elements directly within an XML structure via a "pathname" type syntax, without necessarily having to indicate the complete pathname in order to reach it. + +For example, given the following structure: + +```xml + + + + + + + +``` + +XPath notation allows you to access element 3 using the */RootElement/Elem1/Elem2/Elem3* syntax. + +4D also accepts indexed XPath elements using the *Element[ElementNum]* syntax. For example, given the following structure: + +```xml + + + aaa + bbb + ccc + + +``` + +XPath notation allows you to access the "ccc" value using the */RootElement/Elem1/Elem2[3]* syntax. + +For a comprehensive list of supported XPath expressions, refer to the [`DOM Find XML element`](../commands/dom-find-xml-element) command description. + +:::note Compatibility + +Starting with 4D 18 R3, the XPath implementation has been modified to be more compliant and to support a wider set of expressions. If you want to benefit from the extended features in your converted databases, you need to select the **Use standard XPath** option of the [Compatibility page](../settings/compatibility.md). + +::: + +### Error Handling + +Many functions in this theme return an XML element reference. If an error occurs during function execution (for example, if the root element reference is not valid), the *OK* variable is set to 0 and an error is generated. + +In addition, the reference returned in this case is a sequence of 32 zero "0" characters. + + +## XML SAX Commands + +### Creating, opening and closing XML documents via SAX + +The [XML SAX commands](../commands/theme/XML_SAX.md) work with the standard document references of 4D (**DocRef**, a Time type reference). It is therefore possible to use these commands jointly with the 4D commands used to manage documents, such as [`SEND PACKET`](../commands/send-packet) or [`Append document`](../commands/append-document). + +The creation and opening of XML documents by programming is carried out using the [`Create document`](../commands/create-document) and [`Open document`](../commands/open-document) commands. Subsequently, the use of an XML command with these documents will cause the automatic activation of XML mechanisms such as encoding. For instance, the `` header will be written automatically in the document. + +:::note + +Documents read by SAX commands must be opened in read-only mode by the [`Open document`](../commands/open-document) command. This avoids any conflict between 4D and the Xerces library when you open "regular" and XML documents simultaneously. If you execute a SAX parsing command with a document open in read-write mode, an alert message is displayed and parsing is impossible. + +::: + +Closing an XML document must be carried out using the [`CLOSE DOCUMENT`](../commands/close-document) command. If any XML elements were open, they will be closed automatically. + +### About end-of-line characters and BOM management + +When writing SAX documents, 4D uses the following default settings for end-of-line characters and BOM (byte order mask) usage: + +- CRLF characters on Windows and LF on macOS for end-of-line characters +- files are written without BOM. + +:::note Compatibility + +In projects created with 4D versions up to 19.x, by default 4D uses CRLF as end-of-line characters on macOS for SAX and a BOM. You can control the `XML line ending` and `XML BOM` management using the [`XML SET OPTIONS`](../commands/xml-set-options) command and a [Compatibility setting](../settings/compatibility.md). Important: Since SAX file lines are written directly at each statement, if you need to set the BOM and/or end-of-line options, you must call the [`XML SET OPTIONS`](../commands/xml-set-options) command before the first SAX writing command. + +::: diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md b/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md index 6a949c77247b94..8685d1626ffc5e 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md @@ -123,7 +123,7 @@ displayed_sidebar: docs **取りうる値**: 倍長整数 > 1 (秒) -**詳細**: 秒単位で指定された、キャッシュ保存頻度を取得あるいは設定します。この値を変更すると、データベース設定の[XML DECODE](../commands/xml-decode)内の**キャッシュを保存: X秒毎**オプションをセッション中の間上書きします(これはデータベース設定には保存されません)。 +**詳細**: 秒単位で指定された、キャッシュ保存頻度を取得あるいは設定します。この値を変更すると、設定の[データベースページ](../../settings/database.md)内の**キャッシュを保存: X秒毎**オプションをセッション中の間上書きします(これは設定には保存されません)。 diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md b/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md index 6b7034318b01e5..f36cfe74af4b51 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md @@ -128,7 +128,7 @@ displayed_sidebar: docs **取りうる値**: 倍長整数 > 1 (秒) -**詳細**: 秒単位で指定された、キャッシュ保存頻度を取得あるいは設定します。この値を変更すると、データベース設定の[XML DECODE](../commands/xml-decode)内の**キャッシュを保存: X秒毎**オプションをセッション中の間上書きします(これはデータベース設定には保存されません)。 +**詳細**: 秒単位で指定された、キャッシュ保存頻度を取得あるいは設定します。この値を変更すると、設定の[データベースページ](../../settings/database.md)内の**キャッシュを保存: X秒毎**オプションをセッション中の間上書きします(これは設定には保存されません)。 diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md b/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md index b177b3ce9cc689..ca8c1adf887ec7 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md @@ -32,6 +32,12 @@ displayed_sidebar: docs **LDAP LOGIN** コマンドは*url* 引数で指定したLDAPサーバーに対し、*login* 引数と *password* 引数に渡された識別子をもって読み込み専用の接続を開きます。サーバーに受け入れられた場合、[LDAP LOGOUT](../commands/ldap-logout) コマンドが実行されるまで(あるいはプロセスが閉じられるまで)、カレントプロセスにおいてその後に実行される全てのLDAP検索にはこの接続が使用されます。 +:::info + +LDAP (*Lightweight Directory Access Protocol*) は、分散情報サービスへのアクセスおよび維持管理のためのオープンスタンダードです。詳細については、[LDAPに関するWikipediaのページ](http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol) または [OpenLDAP Software](http://www.openldap.org/) のメインページを参照してください。 + +::: + *url* 引数には、スキームとポート(デフォルトでは389)を含め、接続するLDAPサーバーへの完全なURLを渡します。この引数は[rfc2255](https://www.ietf.org/rfc/rfc2255.txt)に準拠している必要があります。 *url* 引数に対し、"ldaps"で始まる、特定のポート番号(例: "ldaps://svr.ldap.acme.com:1389" 等)を使用した場合、TLS経由の安全な接続を開くことができます。LDAPサーバーは、(少なくともMicrosoft Active Directoryに対する)SSL証明書を持っている必要があります。パスワードが通常のテキストとして送信される場合にはTLS接続の使用が強く推奨 されます(以下を参照して下さい)。 @@ -40,9 +46,9 @@ displayed_sidebar: docs *login* 引数には、LDAPサーバー上のユーザーアカウントを渡し、*password* 引数にはパスワードを渡します。デフォルトで、*login* 引数にはLDAPサーバーの設定に応じて、以下の文字列のどれかを渡すことができます: * 識別名(DN)。例えば、"CN=John Smith,OU=users,DC=example,DC=com" -* ユーザー名(CN)。例えば、"CN=John Smith" +* ユーザー名(CN、*Common Name*)。例えば、"CN=John Smith" * メールアドレス。例えば、"johnsmith@4d.fr" -* SAM-アカウント名。例えば、"jsmith" +* SAM-アカウント名 (*Security Account Manager*、Active Directory のログオン名)。例えば、"jsmith" *login* 引数で受け入れ可能な値は、*digest* 引数で定義された送信モードと関係しているという点に注意して下さい。例えば、MS Active Directoryのデフォルトの設定においては、以下のようになっています: diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md b/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md index 85f7ed49d0e0c4..d6b4a82d6fd8fe 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md @@ -49,6 +49,12 @@ displayed_sidebar: docs **PRINT SELECTION** を使用し、小計やブレーク付きでセレクションを印刷するには、まずそのセレクションをソートしなければなりません。次に、レポートの各ブレークエリアに、小計を変数に代入するオブジェクトメソッドを持つ変数を配置します。変数に値を代入する、[Sum](../commands/sum) や [Average](../commands/average) のような統計関数と算術関数を使用することもできます。詳細は[Subtotal](../commands/subtotal)、[BREAK LEVEL](../commands/break-level)、[ACCUMULATE](../commands/accumulate) コマンドの説明を参照してください。 +:::note + +[Sum](../commands/sum) や [Average](../commands/average) のような[統計コマンド](../../commands/theme/On_a_Series.md)を使用して変数に値を代入することができます。統計関数をレポートで使用する場合、レポート自体が各レコードを読み込む必要があるため、特定の動作をします。これらの関数をレポートで使用すると、返される値が信頼できるのはブレークレベル0のみであり、ブレーク処理が有効になっている場合に限ります。つまり、すべてのレコードが処理された後のレポートの末尾でのみ有効です。これらの関数は、B0ブレークエリアに含まれる非入力エリアのオブジェクトメソッド内でのみ使用してください。 + +::: + **警告:** **PRINT SELECTION** のコンテキストで [PAGE BREAK](../commands/page-break) コマンドを使用してはいけません。[PAGE BREAK](../commands/page-break) は [Print form](../commands/print-form) のコンテキストで使用します。 **PRINT SELECTION** の呼び出し後、プリントが正常に終了するとシステム変数OKに1がセットされます。プリントが中断された場合には、システム変数OKには0がセットされます(例えばユーザが印刷ダイアログボックスでキャンセルをクリックした場合)。 diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/settings/database.md b/i18n/ja/docusaurus-plugin-content-docs/current/settings/database.md index 1cc0aace262db0..f745ffe4e62aac 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/settings/database.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/settings/database.md @@ -120,3 +120,31 @@ UUID バージョン7の詳細な情報については、 [こちらのblog記 キャッシュがフラッシュされるたびにデータベースの動作が遅くなる場合、周期を調整する必要があります。 動作が遅くなるのは、大量のレコードがディスクにフラッシュされるためです。 フラッシュ周期を短くすることで、各フラッシュ時に保存されるレコード数を減らすことができ、動作も速くなります。 デフォルトで 4D はキャッシュがフラッシュされていることを示す小さなウィンドウを表示します。 このウィンドウを表示したくない場合、[インターフェースページ](./interface.md) の **フラッシュの進捗状況** オプションの選択を解除します。 + +:::note + +[`SET DATABASE PARAMETER` コマンドの `Cache flush periodicity` セレクター](../commands/set-database-parameter#cache-flush-periodicity-95) を使用して、キャッシュのフラッシュ周期を一時的に変更できます。 + +::: + + + + +### データベースキャッシュにおける優先度の管理 + +4D データベースキャッシュには、データアクセスの高い効率性とパフォーマンスを提供する自動優先度管理メカニズムが含まれています。 このメカニズムにより、新しいデータをキャッシュにロードするためのスペースが必要になると、優先度の低いキャッシュデータが先に解放され、優先度の高いキャッシュデータはロードされたままになります。 + +このメカニズムは完全に自動化されており、通常は気にする必要はありません。 ただし、特定のケースでは、[「キャッシュ管理」テーマの専用コマンド群](../commands/theme/Cache_Management.md) を使用してカスタマイズできます。これらのコマンドを使うと、データベースの実行中ずっと、または現在のプロセスに対して一時的に、オブジェクトの優先度を変更できます。 これらのコマンドはデータベースのパフォーマンスに影響するため、注意して使用する必要があります。 + +#### 優先度管理の概要 + +キャッシュマネージャーは、必要に応じて優先度システムを使用してキャッシュから削除するデータを選択します。 キャッシュにロードできる 3 種類のオブジェクトは、それぞれ異なる優先度を持ちます: + +- **テーブル**: blob を除く、すべての標準フィールドデータ (数値、日付など) (以下参照)。 デフォルトの優先度は中です。 +- **blob**: データファイルに格納される、すべてのバイナリフィールドデータ (テキスト、ピクチャー、オブジェクト、blob)。 デフォルトの優先度は最も低いです。 +- **インデックス**: キーワードインデックスや複合インデックスを含む、すべてのフィールドインデックス。 インデックスは頻繁にアクセスされるため、キャッシュ内で特別なステータスを持ちます。 デフォルトの優先度は最も高いです。 + +デフォルトの優先度は通常、最良のパフォーマンスを提供します。 ただし、特定のケースでは、2 種類の 4D コマンド群を使用してキャッシュの優先度をカスタマイズできます: + +- セッション全体とすべてのプロセスの優先度を変更するコマンド: [`SET TABLE CACHE PRIORITY`](../commands/set-table-cache-priority)、[`SET INDEX CACHE PRIORITY`](../commands/set-index-cache-priority)、および [`SET BLOBS CACHE PRIORITY`](../commands/set-blobs-cache-priority)。 これらのコマンドは、起動時データベースメソッドで使用する必要があります。 +- 現在のプロセスの優先度のみを変更するコマンド: [`ADJUST TABLE CACHE PRIORITY`](../commands/adjust-table-cache-priority)、[`ADJUST INDEX CACHE PRIORITY`](../commands/adjust-index-cache-priority)、および [`ADJUST BLOBS CACHE PRIORITY`](../commands/adjust-blobs-cache-priority)。 一時的な操作のパフォーマンスを改善し、操作終了後に初期の優先度に戻すには、これらのコマンドを使用します。 これらのコマンドは 4D Server または ローカルモードの 4D でのみ使用できます。 diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md index d5eb985018e714..abc9adf3312943 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md @@ -122,7 +122,7 @@ displayed_sidebar: docs **取りうる値**: 倍長整数 > 1 (秒) -**詳細**: 秒単位で指定された、キャッシュ保存頻度を取得あるいは設定します。この値を変更すると、データベース設定の[XML DECODE](../commands/xml-decode)内の**キャッシュを保存: X秒毎**オプションをセッション中の間上書きします(これはデータベース設定には保存されません)。 +**詳細**: 秒単位で指定された、キャッシュ保存頻度を取得あるいは設定します。この値を変更すると、設定の[データベースページ](../../settings/database.md)内の**キャッシュを保存: X秒毎**オプションをセッション中の間上書きします(これは設定には保存されません)。 diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md index 6f84881c65367c..0e7ee5dfb1da61 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md @@ -127,7 +127,7 @@ displayed_sidebar: docs **取りうる値**: 倍長整数 > 1 (秒) -**詳細**: 秒単位で指定された、キャッシュ保存頻度を取得あるいは設定します。この値を変更すると、データベース設定の[XML DECODE](../commands/xml-decode)内の**キャッシュを保存: X秒毎**オプションをセッション中の間上書きします(これはデータベース設定には保存されません)。 +**詳細**: 秒単位で指定された、キャッシュ保存頻度を取得あるいは設定します。この値を変更すると、設定の[データベースページ](../../settings/database.md)内の**キャッシュを保存: X秒毎**オプションをセッション中の間上書きします(これは設定には保存されません)。 diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/legacy-to-import.md b/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/legacy-to-import.md new file mode 100644 index 00000000000000..bec7326945fb92 --- /dev/null +++ b/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/legacy-to-import.md @@ -0,0 +1,95 @@ +--- +id: legacy-to-import +title: develop-legacy +draft: true +--- + + + + +## Semáforos + +um semáforo lhe permite ter certeza de que dois ou mais processos não modifiquem o mesmo recurso ao mesmo tempo. Só o processo que define o semáforo pode eliminá-lo. + + +:::info + +[Signals](../API/SignalClass.md) can also be used to manage interactions. Signals allow you to make sure one or more process(es) will wait for a specific task to be completed before continuing execution. Any process can wait and/or release a signal. + +::: + +### O que é um semáforo? + +Em um programa de computador, um semáforo é uma ferramenta que é usada para proteger as ações que devem ser realizadas por um único processo ou usuário por vez. + +Em 4D, a necessidade convencional de uso de um semáforo é para modificar um array inter-processo: se um processo estiver modificando os valores do array, outro processo não deve poder fazer a mesma coisa ao mesmo tempo. O desenvolvedor utiliza um semáforo para indicar a um processo que só pode realizar sua sequência de operações se nenhum outro processo estiver realizando as mesmas tarefas. Quando um processo encontra com um semáforo, há três possibilidades: + +- Obtém imediatamente o direito a passar +- Espera seu turno até que obtém o direito a passar +- Continua seu caminho, abandonando a ideia de realizar as tarefas. + +Portanto, o semáforo protege partes do código. Se permite passar só um processo de cada vez e bloqueia o acesso até que o processo que possui atualmente o direito de uso renuncie a este direito, liberando o semáforo. + + +### Comandos para trabalhar com semáfoross + +Em 4D, um semáforo é estabelecido chamando a função Semaphore. Para liberar um semáforo, se chama o comando CLEAR SEMAPHORE. + +A função Semaphore tem um comportamento muito especial já que realiza potencialmente duas ações de cada vez: + +- Se o semáforo já estiver assignado, a função devolve True +- Se não for assignado o semáforo, a função o assigna ao processo e devolve False ao mesmo tempo. + +Esta ação dupla realizada pelo mesmo comando assegura que nenhuma operação externa pode ser inserida entre a proba do semáforo e sua atribuição. + +Pode utilizar o comando Test semaphore para saber se um semáforo já estiver assignado ou não. Este comando se utiliza principalmente como parte das operações longas, tais como o fechamento anual das contas onde Test semaphore lhe permite controlar a interface para evitar o acesso a certas operações tais como a adição dos dados contáveis. + +### Como usar semáforos + +Os semáforos devem ser utilizados respeitando os princípios a seguir: + +- um semáforo deve ser definido e lançado no mesmo método, +- a execução de código protegido pelo semáforo deve ser a mas curta possível, +- o código deve ser temporizado por meio do parâmetro contTics da função Semaphore para esperar a liberação do semáforo. + + +Este é o código típico para o uso de um semáforo: + +```4d + While(Semaphore("MySemaphore";300)) + IDLE + End while + // place code protected by semaphore here + CLEAR SEMAPHORE("MySemaphore") +``` + +Um semáforo que não se libera pode bloquear parte do banco de dados. Configurar e liberar o semáforo no mesmo método ajuda a eliminar este risco. + +Minimizar o código protegido pelo semáforo aumenta a fluidez da aplicação e evita que o semáforo seja um gargalo. + +Por último, utilizando o parâmetro opcional contTics do comando Semaphore é essencial para otimizar a espera do semáforo a liberar. Utilizando este parâmetro, os comandos funcionam da maneira abaixo: + +- O processo espera um número máximo especificado de tics (300 no exemplo) para que o semáforo esteja disponível, sem a execução de código passar para a próxima linha, +Se o semáforo for liberado antes do final deste limite, ele é atribuído imediatamente ao processo (Semaphore devolve False) e se reinicia a execução de código, +Se o semáforo não for liberado antes do final deste limite, a execução do código recomeça. +- O comando também dá prioridade às petições estabelecendo uma fila. Desta maneira, o primeiro processo que solicitar um semáforo será o primeiro em obter um. + +Lembre que o tempo de espera se estabelece em função das características específicas da aplicação. + +### Semáforos globais ou locais + +Há dois tipos de semáforos em 4D: semáforos locais e semáforos globais. + +- Um semáforo local é visível para todos os processos de um mesmo posto e só no posto. Um semáforo local pode ser criado ao adicionar um prefixo ao nome do semáforo um sinal de dólar ($). Se utilizar semáforos locais para supervisar as operações entre os diferentes processos que são executados na mesma máquina. Por exemplo, um semáforo local pode ser utilizado para controlar o acesso a um array interprocesso compartido por todos os processos de um banco de dados mono usuário ou de um equipo cliente. +- Um semáforo global é acessível a todos os usuários e todos seus processos. Os semáforos globais são utilizados para controlar as operações entre os usuários de um banco de dados multi-usuário. + +Os semáforos globais e locais são idênticos em sua lógica. A diferença está em seu alcance. + +No modo cliente-servidor, os semáforos globais são compartidos entre todos os processos que são executados em todos os clientes e servidores. Um semáforo local somente se comparte entre os processos que se executam na máquina onde foi criado. + +Em 4D, os semáforos globais ou locais têm o mesmo alcance, já que você é o único usuario. Entretanto, se seu banco de dados estiver sendo usado em ambas configurações, tenha certeza de usar semáforos globais ou locais, dependendo do que quiser fazer. + +Nota: é recomendado o uso de semáforos locais quando precisar de um semáforo para gerenciar um aspecto local para um cliente da aplicação, tais como a interface ou um conjunto de variáveis inter processo. Se usar um semáforo global neste caso, não apenas haveria intercâmbios de rede desnecessários, mas também poderia afetar a outras máquinas clientes desnecessariamente. O uso de um semáforo local evitaria estes efeitos secundários indesejáveis. + + + \ No newline at end of file diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/overview.md b/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/overview.md new file mode 100644 index 00000000000000..793f5e5c9dbd03 --- /dev/null +++ b/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/overview.md @@ -0,0 +1,7 @@ +--- +id: overview +title: 4D database overview +--- + +## Description + diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/records.md b/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/records.md new file mode 100644 index 00000000000000..25e1705847e48e --- /dev/null +++ b/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/records.md @@ -0,0 +1,308 @@ +--- +id: records +title: Records +slug: /Develop/records +displayed_sidebar: docs +--- + + +## Record numbers + +There are three numbers associated with a record: + +- Record number +- Selected record number +- Sequence number + +### Record Number + +The record number is the absolute/physical record number for a record. A record number is automatically assigned to each new record and remains constant for the record until the record is deleted. Record numbers start at zero. They are not unique because record numbers of deleted records are reused for new records. They also change when the database is [compacted](../MSC/compact.md) or [repaired](../MSC/repair.md). + +### Selected Record Number + +The selected record number is the position of the record in the current selection, and so depends on the current selection. If the selection is changed or sorted, the selected record number will probably change. Numbering for the selected record number starts at one (1). + +### Sequence Number + +The sequence number is a unique non-repeating number that may be assigned to a field of a record (via the Autoincrement property, the SQL AUTO_INCREMENT attribute or the [`Sequence number`](../commands/sequence-number) command). It is not automatically stored with each record. It starts by default at 1 and is incremented for each new record that is created. Unlike record numbers, a sequence number is not reused when a record is deleted or when a database is compacted or repaired. Sequence numbers provide a way to have unique ID numbers for records. If a sequence number is incremented during a transaction, the number is not decremented if the transaction is canceled. + +:::note Notes + +- 4D does not carry out any check when you modify the automatic number internal counter of a table using the [`SET DATABASE PARAMETER`](../commands/set-database-parameter) command. If you decrement this counter, the new records created may have numbers that have already been assigned. +- Sequence numbers are not recommended to fill unique ID primary key fields for records. To create unique record IDs, it is strongly recommended to use UUIDs. + +::: + +### Example + +The following tables illustrate the numbers that are associated with records. Each line in the table represents information about a record. The order of the lines is the order in which records would be displayed in an output form. + +- **Data**: The data from a field in each record. For our example, it contains a person’s name. +- **Record Number**: The record’s absolute record number. This is the number returned by the [`Record number`](../commands/record-number) command. +- **Selected Record Number**: The record’s position in the current selection. This is the number returned by the [`Selected record number`](../commands/selected-record-number) command. +- **Sequence Number**: The record’s unique sequence number. This is the number returned by the [`Sequence number`](../commands/sequence-number) command when the record was created. This number is stored in a field. + +#### After the Records Are Entered + +The first table shows the records after they are entered. + +- The default order for the records is by record number. +- The record number starts at 0. +- The selected record number and the sequence number start at 1. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Tess |0| 1| 1| +|Terri| 1 |2 |2| +|Sabra| 2|3| 3| +|Sam| 3 |4 |4| +|Lisa| 4| 5 |5| + +Note: The records remain in the default order after a command changes the current selection without reordering it; for example, after the **Show All** menu command is chosen in the Design environment, or after the [`ALL RECORDS`](../commands/all-records) command is executed. + +#### After the Records Are Sorted + +The next table shows the same records sorted by name. + +- The same record number remains associated with each record. +- The selected record numbers reflect the new position of the records in the sorted selection. +- The sequence numbers never change, since they were assigned when each record was created and are stored in the record. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Lisa| 4| 1 |5| +|Sabra| 2|2| 3| +|Sam| 3 |3 |4| +|Terri| 1 |4 |2| +|Tess |0| 5| 1| + + +#### After a Record Is Deleted + +The following table shows the records after Sam is deleted. + +- Only the selected record numbers have changed. Selected record numbers reflect the order in which the records are displayed. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Lisa| 4| 1 |5| +|Sabra| 2|2| 3| +|Terri| 1 |3 |2| +|Tess |0| 4| 1| + + +#### After a Record Is Added + +The next table shows the records after a new record has been added for Liz. + +- A new record is added to the end of the current selection. +- Sam’s record number is reused for the new record. +- The sequence number continues to increment. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Tess |0| 1| 1| +|Terri| 1 |2 |2| +|Sabra| 2|3| 3| +|Lisa| 4| 4 |5| +|Liz |3| 5| 6| + +#### After the Selection is Changed and Sorted + +The following table shows the records after the selection was reduced to three records and then sorted. + +- Only the selected record number associated with each record changes. + +|Data|Record Number|Selected Record Number|Sequence Number| +|---|---|---|----| +|Sabra| 2|1| 3| +|Liz |3| 2| 6| +|Terri| 1 |3 |2| + +## Record Stack + +The [`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) commands allow you to put (“push”) records onto the record stack, and to remove (“pop”) them from the stack. + +Each process has its own record stack for each table. 4D maintains the record stacks for you. Each record stack is a last-in-first-out (LIFO) stack. Stack capacity is limited by memory. + +[`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) should be used with discretion. Each record that is pushed uses part of free memory. Pushing too many records can cause an out-of-memory or stack full condition. + +4D clears the stack of any unpopped records when you return to the menu at the end of execution of your method. + +[`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) are useful when you want to examine records in the same file during data entry. To do this, you push the record, search and examine records in the file (copy fields into variables, for example), and finally pop the record to restore the record. + +While entering a record, if you have to check a multiple field unique value, use the [`SET QUERY DESTINATION`](../commands/set-quer-destination) command. This will save you the calls to [`PUSH RECORD`](../commands/push-record) and [`POP RECORD`](../commands/pop-record) that you were making before and after the call to QUERY in order to preserve the data entered in the current record. [`SET QUERY DESTINATION`](../commands/set-quer-destination) allows you to make a query that does not change the selection nor the current record. + +## Record locking + +4D and 4D Server automatically manage databases by preventing multi-user or multi-process conflicts. Two users or two processes cannot modify the same record or object at the same time. However, the second user or process can have read-only access to the record or object at the same time. + +There are several reasons for using the multi-user commands: + +- Modifying records by using the language. +- Using a custom user interface for multi-user operations. +- Saving related modifications inside a transaction. + +There are three important concepts to be aware of when using commands in a multi-processing database: + +1. In a process, each table is in either a read-only or a read/write state. +2. Records become locked when they are loaded and unlocked when they are unloaded. +3. A locked record cannot be modified. + +As a convention in the following sections, the person performing an operation on the multi-user database is referred to as the **local user**. Other people using the database are referred to as the **other users**. The discussion is from the perspective of the local user. Also, from a multi-process perspective, the process executing an operation on the database is the **current process**. Any other executing process is referred to as **other processes**. The discussion is from the point of view of the current process. + +### Locked Records + +A locked record cannot be modified by the local user or the current process. A locked record can be loaded, but cannot be modified. A record is locked when one of the other users or processes has successfully loaded the record for modification, or when the record is stacked. Only the user who is modifying the record sees that record as unlocked. All other users and processes see the record as locked, and therefore unavailable for modification. A table must be in a read/write state for a record to be loaded unlocked. + +### Read-Only and Read/Write States + +Each table in a database is in either a read/write or a read-only state for each user and process of the database. **Read-only** means that records for the table can be loaded but not modified. **Read/write** means that records for the table can be loaded and modified if no other user has locked the record first. + +Note that if you change the status of a table, the change takes effect for the next record loaded. If there is a record currently loaded when you change the table’s status, that record is not affected by the status change. + +#### Read-Only State + +When a table is read-only and a record is loaded, this record is always locked. In other words, locked records can be displayed, printed, and otherwise used, but they cannot be modified. + +Note that the read-only state applies only to editing existing records. A read-only state does not affect the creation of new records. You can still add records to a read-only table using [`CREATE RECORD`](../commands/create-record) and [`ADD RECORD`](../commands/add-record), or the menu commands of the Design environment (in this case, the records being created are locked for all other users/processes). Note that the [`ARRAY TO SELECTION`](../commands/array-to-selection) command is not affected by the read-only state since it can both create and modify records. + +4D automatically sets a table to read-only for commands that do not require write access to records. These commands are: [`DISPLAY SELECTION`](../commands/display-selection), [`DISTINCT VALUES`](../commands/distinct-values), [`EXPORT DIF`](../commands/export-dif), [`EXPORT SYLK`](../commands/export-sylk), [`EXPORT TEXT`](../commands/export-text), [`PRINT SELECTION`](../commands/print-selection), [`PRINT LABEL`](../commands/print-label), [`QR REPORT`](../commands/qr-report), [`SELECTION TO ARRAY`](../commands/selection-to-array), [`SELECTION RANGE TO ARRAY`](../commands/selection-range-to-array). + +You can find out the state of a table at any time using the [`Read only state`](../commands/read-only-state) function. + +Before executing any of these commands, 4D saves the current state of the table (read-only or read/write) for the current process. After the command has executed, this state is restored. + +#### Read/Write State + +When a table is read/write and a record is loaded, the record will become unlocked if no other user has locked the record first. If the record is locked by another user, the record is loaded as a locked record that cannot be modified by the local user. + +A table must be set to read/write and the record loaded for it to become unlocked and thus modifiable. + +If a user loads a record from a table in read/write mode, no other users can load that record for modification. However, other users can add records to the table, either through the [`CREATE RECORD`](../commands/create-record) and [`ADD RECORD`](../commands/add-record) commands or manually in the Design environment. + +Read/write is the default state for all tables when a database is opened and a new process is started. + +#### Changing the Status of a Table + +You can use the [`READ ONLY`](../commands/read-only) and [`READ WRITE`](../commands/read-write) commands to change the state of a table. If you want to change the state of a table in order to make a record read-only or read/write, you must execute the command before this record is loaded. Any record that is already loaded is not affected by the [`READ ONLY`](../commands/read-only) and [`READ WRITE`](../commands/read-write) commands. + +Each process has its own state (read-only or read/write) for each table in the database. + +By default, if you do not use the READ ONLY command, all tables are in read/write mode. + +### Loading, Modifying and Unloading Records + +Before the local user can modify a record, the table must be in the read/write state and the record must be loaded and unlocked. + +Any of the commands that loads a current record (if there is one) — such as [`NEXT RECORD`](../commands/next-record), [`QUERY`](../commands/query), [`ORDER BY`](../commands/order-by), [`RELATE ONE`](../commands/relate-one), etc. — sets the record state as locked or unlocked. The record is loaded according to the current state of its table (read-only or read/write) and its availability. A record may also be loaded for a related table by any of the commands that cause an automatic relation to be established. + +If a table is in the read-only state for a process or a user, then this table's records are loaded in read-only mode, which means they cannot be modified or deleted by this process or user. This is recommended for viewing or retrieving data because it does not prevent other users or processes from accessing the records of this table in read/write mode if necessary. + +If a table is in the read/write state for a process or a user, then any record from this table is also loaded in read/write mode, but only if no other user or process has already locked this record. If a record is successfully loaded in read/write mode, it is unlocked for the current process or user (it can be modified and saved) and is locked for all other users or processes. A table must be put into the read/write state before loading a record for modification and then saving it. + +If the record is to be modified, you use the Locked function to test whether or not a record is locked by another user. If a record is locked (Locked returns True), load the record with the [`LOAD RECORD`](../commands/load-record) command and again test whether or not the record is locked. This sequence must be continued until the record becomes unlocked (Locked returns False). + +When modifications to be made to a record are finished, the record must be released (and therefore unlocked for the other users) with [`UNLOAD RECORD`](../commands/unload-record). If a record is not unloaded, it will remain locked for all other users until a different current record is selected. Changing the current record of a table automatically unlocks the previous current record. You need to explicitly call [`UNLOAD RECORD`](../commands/unload-record) if you do not change the current record. This discussion applies to existing records. When a new record is created, it can be saved regardless of the state of the table to which it belongs. + +:::note + +When it is used in a transaction, the [`UNLOAD RECORD`](../commands/unload-record) command unloads the current record only for the process that manages the transaction. For other processes, the record stays locked as long as the transaction has not been validated (or cancelled). + +::: + +Use the [`LOCKED BY`](../commands/locked-by) command to see which user and/or process have locked a record. + +::: + +A good practice is to place all tables in read-only mode when each process is started (using the syntax [`READ ONLY(*)`](../commands/read-only)) then put each table in read/write mode only when necessary. Access to tables in read-only mode is faster and more memory-efficient. Moreover, changing the state of a table is optimized in client/server mode because it does not cause any additional network traffic: information is only sent to the server when executing a command that requires adequate access to the table. + +::: + +### Loops to Load Unlocked Records + +The following example shows the simplest loop with which to load an unlocked record: + +```4d + READ WRITE([Customers])//Set the table’s state to read/write + Repeat//Loop until the record is unlocked + LOAD RECORD([Customers])//Load record and set locked status + Until(Not(Locked([Customers]))) + //Do something to the record here + READ ONLY([Customers])//Set the table’s state to read-only +``` + +The loop continues until the record is unlocked. + +A loop like this is used only if the record is unlikely to be locked by anyone else, since the user would have to wait for the loop to terminate. Thus, it is unlikely that the loop would be used as is unless the record could only be modified by means of a method. + +The following example uses the previous loop to load an unlocked record and modify the record: + +```4d + READ WRITE([Inventory]) + Repeat //Loop until the record is unlocked + LOAD RECORD([Inventory]) //Load record and set it to locked + Until(Not(Locked([Inventory]))) + [Inventory]Part Qty:=[Inventory]Part Qty 1 //Modify the record + SAVE RECORD([Inventory]) //Save the record + UNLOAD RECORD([Inventory]) //Let other users modfiy it + READ ONLY([Inventory]) +``` + + +The [`MODIFY RECORD`](../commands/modify-record) command automatically notifies the user if a record is locked, and prevents the record from being modified. The following example avoids this automatic notification by first testing the record with the Locked function. If the record is locked, the user can cancel. + +This example efficiently checks to see if the current record is locked for the table [Commands]. If it is locked, the process is delayed by the procedure for one second. This technique can be used both in a multi-user or multi-process situation: + +```4d + Repeat + READ ONLY([Commands])//You do not need read/write right now + QUERY([Commands]) + //If the search was completed and some records were returned + If((OK=1) & (Records in selection([Commands])>0)) + READ WRITE([Commands])//Set the table to read/write state + LOAD RECORD([Commands]) + While(Locked([Commands]) & (OK=1)) `If the record is locked, + //loop until the record is unlocked + //Who is the record locked by? + LOCKED BY([Commands];$Process;$User;$SessionUser;$Name) + If($Process=-1)//Has the record been deleted? + ALERT("The record has been deleted in the meantime.") + OK:=0 + Else + If($User="")//Are you in single-user mode + $User:="you" + End if + CONFIRM("The record is already used by "+$User+" in the "+$Name+" Process.") + If(OK=1)//If you want to wait for a few seconds + DELAY PROCESS(Current process;120)//Wait for a few seconds + LOAD RECORD([Commands])//Try to load the record + End if + End if + End while + If(OK=1)//The record is unlocked + MODIFY RECORD([Commands])//You can modify the record + UNLOAD RECORD([Commands]) + End if + READ ONLY([Commands])//Switch back to read-only + OK:=1 + End if + Until(OK=0) +``` + + +### Using Commands in Multi-user or Multi-process Environment + +A number of commands in the language perform specific actions when they encounter a locked record. They behave normally if they do not encounter a locked record. + +Here is a list of these commands and their actions when a locked record is encountered. + +- [`MODIFY RECORD`](../commands/modify-record): Displays a dialog box stating that the record is in use. The record is not displayed, therefore the user cannot modify the record. In the Design environment, the record is shown in read-only state. +- [`MODIFY SELECTION`](../commands/modify-selection): Behaves normally except when the user double-clicks a record to modify it. [`MODIFY SELECTION`](../commands/modify-selection) displays dialog box stating that the record is in use and then allows read-only access to the record. +- [`APPLY TO SELECTION`](../commands/apply-to-selection): Loads a locked record, but does not modify it. [`APPLY TO SELECTION`](../commands/apply-to-selection) can be used to read information from the table without special care. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`DELETE SELECTION`](../commands/delete-selection): Does not delete any locked records; it skips them. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`DELETE RECORD`](../commands/delete-record): This command is ignored if the record is locked. No error is returned. You must test that the record is unlocked before executing this command. +- [`SAVE RECORD`](../commands/save-record): This command is ignored if the record is locked. No error is returned. You must test that the record is unlocked before executing this command. +- [`ARRAY TO SELECTION`](../commands/array-to-selection): Does not save any locked records. If the command encounters a locked record, the record is put into the [`LockedSet` system set](./sets.md#the-lockedset-system-set). +- [`GOTO RECORD`](../commands/goto-record): Records in a multi-user/multi-process database may be deleted and added by other users, therefore the record numbers may change. Use caution when directly referencing a record by number in a multi-user database. +- [**Sets**](./sets.md): Take special care with sets, as the information that the set was based on may be changed by another user or process. diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/sets.md b/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/sets.md new file mode 100644 index 00000000000000..f1e42b3cc1c863 --- /dev/null +++ b/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/sets.md @@ -0,0 +1,168 @@ +--- +id: sets +title: Sets +slug: /Develop/sets +displayed_sidebar: docs +--- + + +Sets offer you a powerful, swift means for manipulating record selections. Besides the ability to create sets, relate them to the current selection, and store, load, and clear sets, 4D offers three standard set operations: + +- Intersection +- Union +- Difference. + + +## Sets and the Current Selection + +A set is a compact representation of a selection of records. The idea of sets is closely bound to the idea of the current selection. Sets are generally used for the following purposes: + +- To save and later restore a selection when the order does not matter +- To access the selection a user made on screen (the `UserSet`) +- To perform a logical operation between selections. + +The current selection is a list of references that points to each record that is currently selected. The list exists in memory. Only currently selected records are in the list. A selection doesn’t actually contain the records, but only a list of references to the records. Each reference to a record takes 4 bytes in memory. When you work on a table, you always work with the records in the current selection. When a selection is sorted, only the list of references is rearranged. There is only one current selection for each table inside a process. + +Like a current selection, a set represents a selection of records. A set does this by using a very compact representation for each record. Each record is represented by one bit (one-eighth of a byte). Operations using sets are very fast, because computers can perform operations on bits very quickly. A set contains one bit for every record in the table, whether or not the record is included in the set. In fact, each bit is equal to 1 or 0, depending on whether or not the record is in the set. + +Sets are very economical in terms of RAM space. The size of a set, in bytes, is always equal to the total number of records in the table divided by 8. For example, if you create a set for a table containing 10,000 records, the set takes up 1,250 bytes, which is about 1.2K in RAM. + +There can be many sets for each table. In fact, sets can be saved to disk separately from the database. To change a record belonging to a set, first you must use the set as the current selection, then modify the record or records. + +A set is never in a sorted order—the records are simply indicated as belonging to the set or not. On the other hand, a named selection is in sorted order, but it requires more memory in most cases. For more information about named selections, see the Named Selections section. + +A set "remembers" which record was the current record at the time the set was created. The following table compares the concepts of the current selection and of sets: + +|Comparison|Current Selection|Sets| +|---|---|---| +|Number per table|1|0 to many| +|Sortable|Yes|No| +|Can be saved on disk|No|Yes| +|RAM per record(in bytes)|Number of selected records * 4|Total number of records/8| +|Combinable| No| Yes| +|Contains current record| Yes| Yes, as of the time the set was created| + +When you create a set, it belongs to the table from which you created it. Set operations can be performed only between sets belonging to the same table. + +Sets are independent from the data. This means that after changes are made to a file, a set may no longer be accurate. There are many operations that can cause a set to be inaccurate. For example, if you create a set of all the people from New York City, and then change the data in one of those records to “Boston” the set would not change, because the set is just a representation of a selection of records. Deleting records and replacing them with new ones also changes a set, as well as compacting the data. Sets can be guaranteed to be accurate only as long as the data in the original selection has not been changed. + +## Process and Interprocess Sets + +You can have the following three types of sets: + +- **Process sets**: A process set can only be accessed by the process in which it has been created. `LockedSet` is a process set. Process sets are cleared as soon as the process method ends. Process sets do not need any special prefix in the name. +- **Interprocess sets**: A set is an interprocess set if the name of the set is preceded by the symbols (<>) — a “less than” sign followed by a “greater than” sign. An interprocess set is “visible” to all the processes of the database. +In client/server mode, an interprocess set is “visible” to processes of the machine where it was created (client or server). +The name of an interprocess set must be unique in the database. +- **Local Sets/Client Sets**: Local/client sets are intended for use in client/server mode. The name of a local/client set is always preceded by the dollar sign ($) -- except for the UserSet system set. Unlike other types of sets, a local/client set is stored on the client machine. + +:::note Notes + +- The maximum size of a set name is 255 characters (excluding <> and $ symbols). +- For more information about the use of sets in client/server mode, please refer to 4D Server, Sets and Named Selections. + +::: + + +## Visibility of Sets + +The following table indicates the principles concerning the visibility of sets depending on their scope and where they were created: + + + +||Client Process|Other processes on the same client|Other clients|Server process|Other processes on the server| +|---|---|---|---|---|---| +|Creation in a client process |||||| +|$test|X ||||| +|test | X||| X(Trigger) || +|<>test | X|X |||| +|Creation in a server process|||||| +|$test|||| X|| +|test ||||X|| +|<>test||||X| X| + + +## Sets and Transactions + +A set can be created inside a [transaction](./transactions.md). It is possible to create a set of the records created inside a transaction and a set of records created or modified outside of a transaction. When the transaction ends, the set created during the transaction should be cleared, because it may not be an accurate representation of the records, especially if the transaction was canceled. + +## Example + +The following example deletes duplicate records from a table which contains information about people. A For...End for loop moves through all the records, comparing the current record to the previous record. If the name, address, and zip code are the same, then the record is added to a set. At the end of the loop, the set is made the current selection and the (old) current selection is deleted: + +```4d + CREATE EMPTY SET([People];"Duplicates") + // Create an empty set for duplicate records + ALL RECORDS([People]) + // Select all records + // Sort the records by ZIP, address, and name so + // that the duplicates will be next to each other + ORDER BY([People];[People]ZIP;>;[People]Address;>;[People]Name;>) + // Initialize variables that hold the fields from the previous record + $Name:=[People]Name + $Address:=[People]Address + $ZIP:=[People]ZIP + // Go to second record to compare with first + NEXT RECORD([People]) + For($i;2;Records in table([People])) + // Loop through records starting at 2 + // If the name, address, and ZIP are the same as the + // previous record then it is a duplicate record. + If(([People]Name=$Name) & ([People]Address=$Address) & ([People]ZIP=$ZIP)) + // Add current record (the duplicate) to set + ADD TO SET([People];"Duplicates") + Else + // Save this record’s name, address, and ZIP for comparison with the next record + $Name:=[People]Name + $Address:=[People]Address + $ZIP:=[People]ZIP + End if + // Move to the next record + NEXT RECORD([People]) + End for + // Use duplicate records that were found + USE SET("Duplicates") + // Delete the duplicate records + DELETE SELECTION([People]) + // Remove the set from memory + CLEAR SET("Duplicates") +``` + +As an alternative to immediately deleting records at the end of the method, you could display them on screen or print them, so that a more detailed comparison can be made. + + +## The UserSet System Set + +4D maintains a system set named `UserSet`, which automatically stores the most recent selection of records highlighted on screen by the user. Thus, you can display a group of records with [`MODIFY SELECTION`](../commands/modify-selection) or [`DISPLAY SELECTION`](../commands/display-selection), ask the user to select from among them and turn the results of that manual selection into a selection or into a set that you name. + +::info 4D Server + +Although its name does not begin with the character "$", the `UserSet` system set is a client set. So, when using [`INTERSECTION`](../commands/intersection), [`UNION`](../commands/union) and [`DIFFERENCE`](../commands/difference), make sure you compare `UserSet` only to client sets. + +::: + +There is only one `UserSet` for a [process](../Develop/processes.md). Each table does not have its own `UserSet`. `UserSet` becomes "owned" by a table when a selection of records is displayed for the table. + +4D manages the `UserSet` set for list forms displayed in Design mode or using the [`MODIFY SELECTION`](../commands/modify-selection) or [`DISPLAY SELECTION`](../commands/display-selection) commands. However, this mechanism is not active for [subforms](../FormObjects/subform_overview.md). + +The following method illustrates how you can display records, allow the user to select some of them, and then use UserSet to display the selected records: + +```4d + // Display all records and allow user to select any number of them. + // Then display this selection by using UserSet to change the current selection. + FORM SET OUTPUT([People];"Display") // Set the output layout + ALL RECORDS([People]) // Select all people + ALERT("Press Ctrl or Command and Click to select the people required.") + DISPLAY SELECTION([People]) // Display the people + USE SET("UserSet") // Use the people that were selected + ALERT("You chose the following people.") + DISPLAY SELECTION([People]) // Display the selected people +``` + +## The LockedSet System Set + +The [`APPLY TO SELECTION`](../commands/apply-to-selection), [`DELETE SELECTION`](../commands/delete-selection), [`ARRAY TO SELECTION`](../commands/array-to-selection) and [`JSON TO SELECTION`](../commands/json-to-selection) commands create a set named `LockedSet` when used in a multi-processing environment. + +Query commands also create a `LockedSet` system set when they find locked records in the 'query and lock' context (see the [`SET QUERY AND LOCK`](../commands/set-query-and-lock) command). + +`LockedSet` indicates which records were locked during the execution of the command. \ No newline at end of file diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/xml.md b/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/xml.md new file mode 100644 index 00000000000000..6691cfcb0e545c --- /dev/null +++ b/i18n/pt/docusaurus-plugin-content-docs/current/Develop-legacy/xml.md @@ -0,0 +1,157 @@ +--- +id: xml +title: XML Processing +slug: /Develop/XML +displayed_sidebar: docs +--- + + +## Overview of XML Commands + +### XML, DOM, and SAX + +The [**XML** theme](../commands/theme/XML.md) groups together the generic XML "utilities" commands of 4D. These are option- and error-management commands. + +4D also offers two separate sets of XML commands: [**DOM**](../commands/theme/XML_DOM.md) (Document Object Model) and [**SAX**](../commands/theme/XML_SAX.md) (Simple API XML) are two different parsing modes for XML documents. + +- The DOM mode parses an XML source and builds its structure (its "tree") in memory. Because of this, access to each element of the source is extremely fast. However, since the entire tree structure is stored in memory, the processing of large XML documents may lead to the memory capacity being exceeded and thus provoke errors. +- The SAX mode does not build a tree structure in memory. In this mode, "events" (such as the start and end of an element) are generated when parsing the source. This mode lets you parse XML documents of any size, regardless of the amount of memory available. + +### References + +http://www.saxproject.org/?selected=event
+http://www.w3schools.com/xml/ + +:::note + +For XML support, 4D uses the [Xerces.dll library](../Notes/updates.md#library-table) developed by the Apache Foundation company. + +::: + + +### Preemptive mode + +XML references created by a [preemptive process](../Develop/preemptive.md) can only be used in that specific process. Conversely, XML references created by a cooperative process can be used by any other cooperative process, but cannot be used by any preemptive process. + + +### Character Sets + +The following character sets are supported by the XML DOM and XML SAX commands of 4D: + +- ASCII +- UTF-8 +- UTF-16 (Big/Small Endian) +- UCS4 (Big/Small Endian) +- EBCDIC code pages IBM037, IBM1047 and IBM1140 encodings, +- ISO-8859-1 (or Latin1) +- Windows-1252. + + +### Glossary + +This non-exhaustive list details the main XML concepts used by the commands and functions of 4D. + +- **Attribute**: an XML sub-tag associated with an element. An attribute always contains a name and a value. +- **Child**: In an XML structure, an element in a level directly below another. +- **DTD**: *Document Type Declaration*. The DTD records the set of specific rules and properties that the XML must follow. These rules define, more particularly, the name and content of each tag as well as its context. This formalization of the elements can be used to check whether an XML document is in compliance (in which case, it is declared “valid”). The DTD may be included in the XML document (internal DTD) or in a separate document (external DTD). Note that the DTD is not mandatory. +- **Element**: an XML tag. An element always contains a name and a value. Optionally, an element may contain attributes. +- **ElementRef**: XML reference used by the 4D XML commands to specify an XML structure. This reference is made up of 8 coded characters in hexadecimal form, which means that its length is 32 characters on a 64-bit system. It is recommended to declare XML references as Text. +- **Parent**: In an XML structure, an element in a level directly above another. +- **Parsing, parser**: The act of analyzing the contents of a structured object in order to extract useful information. +- **Root**: An element located at the first level of an XML structure. +- **Sibling**: An element at the same level as another. +- **Structure**: structured XML object. This object can be a document, a variable, or an element. +- **Validation**: An XML document is “validated” by the parser when it is “well-formed” and in compliance with the DTD specifications. +- **Well-formed**: An XML document is declared “well-formed” by the parser when it complies with the generic XML specifications. +- **XML**: eXtensible Markup Language. A computerized data exchange standard enabling the transfer of data as well as their structure. The XML language is based on the use of tags and a specific syntax, in keeping with the HTML language. However, unlike the latter, the XML language allows the definition of customized tags. +- **XSL**: eXtensible Stylesheet Language. A language permitting the definition of style sheets used to process and display the contents of an XSL document. + + +## XML DOM Commands + +### Creating, opening and closing XML documents via DOM + +Objects created, modified or parsed by the [4D XML DOM commands](../commands/theme/XML_DOM.md) can be text, URLs, documents or BLOBs. The DOM commands used for opening XML objects in 4D are [`DOM Parse XML source`](../commands/dom-parse-xml-source) and [`DOM Parse XML variable`](../commands/dom-parse-xml-variable). + +Many commands then let you read, parse and write the elements and attributes. Errors are recovered using the [`XML GET ERROR`](../commands/xml-get-error) command. Do not forget to call the [`DOM CLOSE XML`](../commands/dom-close-xml) command to close the source in the end. + +Note about use of XML BLOB parameters: For historical reasons, XML commands such as [`DOM Parse XML variable`](../commands/dom-parse-xml-variable) accept BLOB type parameters. However, it is highly recommended to store XML structures as Text. The use of BLOBs is reserved for processing binary data. In conformity with XML specifications, binary data are automatically encoded in Base64, even when the BLOB contains text. + + +### Support of XPath notation + +Several XML DOM commands ([`DOM Create XML element`](../commands/dom-create-xml-element), [`DOM Find XML element`](../commands/dom-find-xml-element), [`DOM Create XML element arrays`](../commands/dom-create-xml-element-arrays) and [`DOM SET XML ELEMENT VALUE`](../commands/dom-set-xml-element-value)) support some XPath expressions for accessing XML elements. + +XPath notation comes from the XPath language, designed to navigate within XML structures. It allows the setting of elements directly within an XML structure via a "pathname" type syntax, without necessarily having to indicate the complete pathname in order to reach it. + +For example, given the following structure: + +```xml + + + + + + + +``` + +XPath notation allows you to access element 3 using the */RootElement/Elem1/Elem2/Elem3* syntax. + +4D also accepts indexed XPath elements using the *Element[ElementNum]* syntax. For example, given the following structure: + +```xml + + + aaa + bbb + ccc + + +``` + +XPath notation allows you to access the "ccc" value using the */RootElement/Elem1/Elem2[3]* syntax. + +For a comprehensive list of supported XPath expressions, refer to the [`DOM Find XML element`](../commands/dom-find-xml-element) command description. + +:::note Compatibility + +Starting with 4D 18 R3, the XPath implementation has been modified to be more compliant and to support a wider set of expressions. If you want to benefit from the extended features in your converted databases, you need to select the **Use standard XPath** option of the [Compatibility page](../settings/compatibility.md). + +::: + +### Error Handling + +Many functions in this theme return an XML element reference. If an error occurs during function execution (for example, if the root element reference is not valid), the *OK* variable is set to 0 and an error is generated. + +In addition, the reference returned in this case is a sequence of 32 zero "0" characters. + + +## XML SAX Commands + +### Creating, opening and closing XML documents via SAX + +The [XML SAX commands](../commands/theme/XML_SAX.md) work with the standard document references of 4D (**DocRef**, a Time type reference). It is therefore possible to use these commands jointly with the 4D commands used to manage documents, such as [`SEND PACKET`](../commands/send-packet) or [`Append document`](../commands/append-document). + +The creation and opening of XML documents by programming is carried out using the [`Create document`](../commands/create-document) and [`Open document`](../commands/open-document) commands. Subsequently, the use of an XML command with these documents will cause the automatic activation of XML mechanisms such as encoding. For instance, the `` header will be written automatically in the document. + +:::note + +Documents read by SAX commands must be opened in read-only mode by the [`Open document`](../commands/open-document) command. This avoids any conflict between 4D and the Xerces library when you open "regular" and XML documents simultaneously. If you execute a SAX parsing command with a document open in read-write mode, an alert message is displayed and parsing is impossible. + +::: + +Closing an XML document must be carried out using the [`CLOSE DOCUMENT`](../commands/close-document) command. If any XML elements were open, they will be closed automatically. + +### About end-of-line characters and BOM management + +When writing SAX documents, 4D uses the following default settings for end-of-line characters and BOM (byte order mask) usage: + +- CRLF characters on Windows and LF on macOS for end-of-line characters +- files are written without BOM. + +:::note Compatibility + +In projects created with 4D versions up to 19.x, by default 4D uses CRLF as end-of-line characters on macOS for SAX and a BOM. You can control the `XML line ending` and `XML BOM` management using the [`XML SET OPTIONS`](../commands/xml-set-options) command and a [Compatibility setting](../settings/compatibility.md). Important: Since SAX file lines are written directly at each statement, if you need to set the BOM and/or end-of-line options, you must call the [`XML SET OPTIONS`](../commands/xml-set-options) command before the first SAX writing command. + +::: diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md b/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md index 086cdbe555ff77..567949d81ccfd5 100644 --- a/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md +++ b/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/get-database-parameter.md @@ -745,7 +745,7 @@ Deverá reiniciar a aplicação para que este parâmetro seja levado em conta. N **Valores possíveis**: longint > 1 (segundos) -**Descrição**: Obtém ou estabelece a peridiocidade de esvaziamento da cache atual, expressa em segundos. Modificar este valor sobrepuja a opção **Flush Cache every X Seconds** em [XML DECODE](../commands/xml-decode) das configurações de Bancos de Dados para a sessão (não é armazenada nas configurações do Banco de Dados). +**Descrição**: Obtém ou estabelece a peridiocidade de esvaziamento da cache atual, expressa em segundos. Modificar este valor sobrepuja a opção **Flush Cache every X Seconds** na [página Banco de dados](../../settings/database.md) das configurações para a sessão (não é armazenada nas configurações). diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md b/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md index f7e00f5db5f2db..055def2d326588 100644 --- a/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md +++ b/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/4D Environment/set-database-parameter.md @@ -750,7 +750,7 @@ Deverá reiniciar a aplicação para que este parâmetro seja levado em conta. N **Valores possíveis**: longint > 1 (segundos) -**Descrição**: Obtém ou estabelece a peridiocidade de esvaziamento da cache atual, expressa em segundos. Modificar este valor sobrepuja a opção **Flush Cache every X Seconds** em [XML DECODE](../commands/xml-decode) das configurações de Bancos de Dados para a sessão (não é armazenada nas configurações do Banco de Dados). +**Descrição**: Obtém ou estabelece a peridiocidade de esvaziamento da cache atual, expressa em segundos. Modificar este valor sobrepuja a opção **Flush Cache every X Seconds** na [página Banco de dados](../../settings/database.md) das configurações para a sessão (não é armazenada nas configurações). diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md b/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md index 1ffa1ad4745c59..146e19ea9998d6 100644 --- a/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md +++ b/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/LDAP/ldap-login.md @@ -32,6 +32,12 @@ displayed_sidebar: docs O comando**LDAP LOGIN** abre uma conexão somente leitura no servidor LDAP especificado pelo parâmetro *url* com os identificadores de *login* e *senha*. Se for aceito pelo servidor, esta ligação é utilizada para todas as pesquisas de LDAP posteriormente introduzidas no processo atual até que o comando *RuntimeVLWinFolder* sejaé executado (ou até que o processo seja fechado). +:::info + +LDAP ou *Lightweight Directory Access Protocol* é um padrão aberto para acessar e manter serviços de informação distribuídos. Para mais informações, consulte a [página da Wikipedia sobre LDAP](http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol) ou a página principal do [OpenLDAP Software](http://www.openldap.org/). + +::: + Em *url*, passe a URL completa do servidor LDAP para se conectar, incluindo o esquema e o porto (389 por padrão). Este parâmetro tem de ser compatível com o [rfc2255](https://www.ietf.org/rfc/rfc2255.txt). Você pode abrir conexões seguras usando TLS usando uma *url* que começa com "ldaps" e usa um número de porta específico (por exemplo, "ldaps://svr.ldap.acme.com:1389") . O servidor LDAP deve ter um certificado SSL (pelo menos para Microsoft Active Directory). É altamente recomendável usar uma conexão TLS quando a senha for enviada em texto simples (veja abaixo). @@ -42,9 +48,9 @@ No *login*, passar a conta de usuário no servidor LDAP, e em *senha*, passe sen * um Distinguished Name (DN), por exemplo, "CN=John Smith,OU=users,DC=example,DC=com" -* um nome de usuário (CN), por exemplo, "CN = John Smith" +* um nome de usuário (CN para *Common Name*), por exemplo, "CN = John Smith" * endereço de e-mail, por exemplo "johnsmith@4d.fr" -* uma SAM-Account-Name, por exemplo "jsmith". +* uma SAM-Account-Name (*Security Account Manager*, nome de início de sessão para Active Directory), por exemplo "jsmith". Repare que os valores aceitos para o *login* estão relacionados com o modo de transmissão da senha definido pelo parâmetro *digest*. Por exemplo, em uma configuração padrão do MS Active Directory: * Quando o modo de transmissão for LDAP password MD5, o único valor aceito para um início de sessão é a SAM-Account-Name. diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md b/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md index 236008adcde2a6..e554553252ca0a 100644 --- a/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md +++ b/i18n/pt/docusaurus-plugin-content-docs/current/language-legacy/Printing/print-selection.md @@ -47,7 +47,13 @@ Durante a impressão, o método de formulário de saída e os métodos de objeto Pode saber se PRINT SELECTION está imprimindo o primeiro cabeçalho provando [Before selection](../commands/before-selection) durante um evento On Header. Igualmente pode verificar o último pé de página, provando End selection durante um evento On Printing Footer. Para maior informação, consulte a descrição destes comandos, como também dos comandos [Form event code](../commands/form-event-code) e [Level ](../commands/level). Para imprimir uma seleção ordenada com subtotais ou quebras utilizando PRINT SELECTION, deve primeiro ordenar a seleção. Depois, em cada área de quebra do relatório, incluir uma variável com um método de objeto que atribui o subtotal à variável . Igualmente pode utilizar funções estatísticas e aritméticas como [Sum](../commands/sum) e [Average](../commands/average) para atribuir valores às variáveis. Para maior informação, consulte as descrições de [Subtotal](../commands/subtotal), [BREAK LEVEL](../commands/break-level) e [ACCUMULATE](../commands/accumulate). - + +:::note + +Você pode usar [comandos estatísticos](../../commands/theme/On_a_Series.md) como [Sum](../commands/sum) e [Average](../commands/average) para atribuir valores às variáveis. Quando funções estatísticas são usadas em um relatório, elas se comportam de maneira específica porque o próprio relatório precisa carregar cada registro. Quando você usa essas funções em um relatório, os valores retornados são confiáveis apenas no nível de quebra 0, e somente quando o processamento de quebras está ativado. Isso significa que elas são úteis apenas no final de um relatório, após todos os registros terem sido processados. Você usaria essas funções apenas em um método de objeto para uma área não editável incluída na área de quebra B0. + +::: + **Aviso**: Não use [PAGE BREAK](../commands/page-break) com o comando PRINT SELECTION. [PAGE BREAK](../commands/page-break) é usada com o comando [Print form](../commands/print-form). Depois de um chamado a PRINT SELECTION, a variável OK toma o valor 1 se a impressão for completada. Se a impressão foi interrompida, a variável OK toma o valor 0 (zero) (por exemplo se o usuário clicar em Cancelar nas caixas de diálogo de impressão). diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/settings/database.md b/i18n/pt/docusaurus-plugin-content-docs/current/settings/database.md index 7fb4cb4393573a..ca9c97c07f007e 100644 --- a/i18n/pt/docusaurus-plugin-content-docs/current/settings/database.md +++ b/i18n/pt/docusaurus-plugin-content-docs/current/settings/database.md @@ -124,3 +124,31 @@ Você usa as configurações nesta aba para configurar a memória em cache para Se houver uma lentidão notável no banco de dados toda vez que o cache for liberado, você precisará ajustar a frequência. Essa lentidão significa que uma grande quantidade de registros está sendo salva. Um período mais curto entre as economias seria portanto mais eficaz, uma vez que cada poupança implicaria menos registos e, por conseguinte, mais rápido. Por padrão, 4D exibe uma pequena janela quando o cache é liberado. Si no desea este recordatorio visual, puede deseleccionar la opción **Escritura de caché** en la [página Interfaz](./interface.md). + +:::note + +Você pode modificar temporariamente a frequência de escrita do cache usando o [seletor `Cache flush periodicity` do comando `SET DATABASE PARAMETER`](../commands/set-database-parameter#cache-flush-periodicity-95). + +::: + + + + +### Gerenciamento de prioridades no cache do banco de dados + +O cache do banco de dados 4D inclui um mecanismo automático de gerenciamento de prioridades que oferece um alto nível de eficiência e desempenho para o acesso aos dados. Graças a esse mecanismo, quando é necessário espaço para carregar novos dados no cache, os dados em cache de baixa prioridade são liberados primeiro, enquanto os dados em cache de prioridade mais alta permanecem carregados. + +Esse mecanismo é totalmente automático e, geralmente, você não terá que se preocupar com ele. No entanto, para casos específicos, ele pode ser personalizado usando um [conjunto de comandos dedicados do tema "Cache Management"](../commands/theme/Cache_Management.md), que permitem alterar a prioridade dos objetos durante todo o tempo em que o banco de dados está em execução, ou temporariamente para o processo atual. Observe que esses comandos devem ser usados com cuidado, pois afetam o desempenho do banco de dados. + +#### Visão geral do gerenciamento de prioridades + +O gerenciador de cache seleciona os dados a serem removidos do cache conforme necessário usando um sistema de prioridades. Os três tipos de objetos que podem ser carregados no cache têm uma prioridade diferente: + +- **tabelas**: todos os dados de campos padrão (numéricos, datas, etc.), excluindo os blobs (ver abaixo). A prioridade padrão é média. +- **blobs**: todos os dados de campos binários (texto, imagem, objeto e blobs) armazenados no arquivo de dados. A prioridade padrão é a mais baixa. +- **índices**: todos os índices de campos, incluindo índices de palavras-chave e índices compostos. Como os índices são acessados com frequência, eles têm um status especial no cache. A prioridade padrão é a mais alta. + +As prioridades padrão geralmente oferecem o melhor desempenho. No entanto, para casos específicos, você pode personalizar as prioridades do cache usando dois conjuntos de comandos 4D: + +- Comandos que alteram as prioridades para toda a sessão e todos os processos: [`SET TABLE CACHE PRIORITY`](../commands/set-table-cache-priority), [`SET INDEX CACHE PRIORITY`](../commands/set-index-cache-priority), e [`SET BLOBS CACHE PRIORITY`](../commands/set-blobs-cache-priority). Esses comandos devem ser usados em um método de banco de dados de inicialização. +- Comandos que alteram as prioridades apenas para o processo atual: [`ADJUST TABLE CACHE PRIORITY`](../commands/adjust-table-cache-priority), [`ADJUST INDEX CACHE PRIORITY`](../commands/adjust-index-cache-priority), e [`ADJUST BLOBS CACHE PRIORITY`](../commands/adjust-blobs-cache-priority). Use esses comandos para melhorar o desempenho de uma operação temporária no seu banco de dados e retornar às prioridades iniciais após a conclusão da operação. Esses comandos estão disponíveis apenas no 4D Server ou no 4D em modo local. diff --git a/i18n/pt/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md b/i18n/pt/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md index e41be9a6dd70c7..9ea279e2240a72 100644 --- a/i18n/pt/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md +++ b/i18n/pt/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md @@ -744,7 +744,7 @@ Deverá reiniciar a aplicação para que este parâmetro seja levado em conta. N **Valores possíveis**: longint > 1 (segundos) -**Descrição**: Obtém ou estabelece a peridiocidade de esvaziamento da cache atual, expressa em segundos. Modificar este valor sobrepuja a opção **Flush Cache every X Seconds** em [XML DECODE](../commands/xml-decode) das configurações de Bancos de Dados para a sessão (não é armazenada nas configurações do Banco de Dados). +**Descrição**: Obtém ou estabelece a peridiocidade de esvaziamento da cache atual, expressa em segundos. Modificar este valor sobrepuja a opção **Flush Cache every X Seconds** na [página Banco de dados](../../settings/database.md) das configurações para a sessão (não é armazenada nas configurações). diff --git a/i18n/pt/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md b/i18n/pt/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md index 528528d3a6a8e9..aa7573b5074f3a 100644 --- a/i18n/pt/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md +++ b/i18n/pt/docusaurus-plugin-content-docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md @@ -749,7 +749,7 @@ Deverá reiniciar a aplicação para que este parâmetro seja levado em conta. N **Valores possíveis**: longint > 1 (segundos) -**Descrição**: Obtém ou estabelece a peridiocidade de esvaziamento da cache atual, expressa em segundos. Modificar este valor sobrepuja a opção **Flush Cache every X Seconds** em [XML DECODE](../commands/xml-decode) das configurações de Bancos de Dados para a sessão (não é armazenada nas configurações do Banco de Dados). +**Descrição**: Obtém ou estabelece a peridiocidade de esvaziamento da cache atual, expressa em segundos. Modificar este valor sobrepuja a opção **Flush Cache every X Seconds** na [página Banco de dados](../../settings/database.md) das configurações para a sessão (não é armazenada nas configurações). diff --git a/sidebars.js b/sidebars.js index ed410a26460040..33ecaeb4007ae2 100644 --- a/sidebars.js +++ b/sidebars.js @@ -334,7 +334,29 @@ module.exports = }, "Develop-legacy/transactions", "Tags/transformation-tags", - "Project/date-time-formats" + "Project/date-time-formats", + "Develop-legacy/xml" + /* + // not ready yet, needs imports from Design ref for records and selection concepts, + { + type: "category", + label: "Records & Selections (legacy data access)", + link: { + type: "generated-index", + title: "Records & Selections (legacy data access)", + description: "Legacy data access based upon records, selections, sets", + slug: "/category/records-selections", + keywords: [ + "records", + "selections" + ], + image: "/img/docusaurus.png" }, + items: [ + "Develop-legacy/records", + "Develop-legacy/sets", + "Develop-legacy/named-selections" + ] + } */ ] }, { @@ -723,6 +745,11 @@ module.exports = "Menus/sdi" ] }, + { + type: "doc", + label: "Drag and Drop", + id: "Desktop/drag-and-drop" + }, { type: "category", label: "Access Rights", diff --git a/versioned_docs/version-21-R2/commands-legacy/component-list.md b/versioned_docs/version-21-R2/commands-legacy/component-list.md index dbbb2aafd38d9c..d9223a125234a7 100644 --- a/versioned_docs/version-21-R2/commands-legacy/component-list.md +++ b/versioned_docs/version-21-R2/commands-legacy/component-list.md @@ -31,16 +31,16 @@ displayed_sidebar: docs When a project is opened, 4D loads the valid components: -* found in the [Components folder of your project](../../Project/architecture.md#components). -* declared in the [**dependencies.json** file of your project](../../Project/components.md#dependenciesjson-and-environment4djson). +* found in the [Components folder of your project](../Project/architecture.md#components). +* declared in the [**dependencies.json** file of your project](../Project/components.md#dependenciesjson-and-environment4djson). -**Reminder:** If the same component is installed at different locations, a [priority order](../../Project/components.md#priority) is applied. +**Reminder:** If the same component is installed at different locations, a [priority order](../Project/components.md#priority) is applied. This command can be called from the host project or from a component. If the project does not use any components, the *componentsArray* array is returned empty. The names of the components are the names of the structure files of the matrix databases (.4db, .4dc or .4dbase). This command can be used for setting up architectures and modular interfaces that offer additional functionalities according to the presence of components. -For more information about 4D components, please refer to [this page](../../Concepts/components.md). +For more information about 4D components, please refer to [this page](../Concepts/components.md). ## See also diff --git a/versioned_docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md b/versioned_docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md index ba62c8b1d69f1b..a4840a70f51671 100644 --- a/versioned_docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md +++ b/versioned_docs/version-21-R3/language-legacy/4D Environment/get-database-parameter.md @@ -123,7 +123,7 @@ Three synchronization modes are then possible on the client side. The Auto Synch **Possible values**: longint > 1 (seconds) -**Description**: Gets or sets the current cache flush periodicity, expressed in seconds. Modifying this value overrides the **Flush Cache every X Seconds** option in the [XML DECODE](../commands/xml-decode) of the Database settings for the session (it is not stored in the Database settings). +**Description**: Gets or sets the current cache flush periodicity, expressed in seconds. Modifying this value overrides the **Flush Cache every X Seconds** option in the [Database page](../../settings/database.md) of the settings for the session (it is not stored in the settings). diff --git a/versioned_docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md b/versioned_docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md index 0f6c8aa9e0e226..150036d1ec04e7 100644 --- a/versioned_docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md +++ b/versioned_docs/version-21-R3/language-legacy/4D Environment/set-database-parameter.md @@ -129,7 +129,7 @@ Three synchronization modes are then possible on the client side. The Auto Synch **Possible values**: longint > 1 (seconds) -**Description**: Gets or sets the current cache flush periodicity, expressed in seconds. Modifying this value overrides the **Flush Cache every X Seconds** option in the [XML DECODE](../commands/xml-decode) of the Database settings for the session (it is not stored in the Database settings). +**Description**: Gets or sets the current cache flush periodicity, expressed in seconds. Modifying this value overrides the **Flush Cache every X Seconds** option in the [Database page](../../settings/database.md) of the settings for the session (it is not stored in the settings). diff --git a/versioned_docs/version-21/commands-legacy/component-list.md b/versioned_docs/version-21/commands-legacy/component-list.md index 38a001a6ebdc5a..a163082d9b6c82 100644 --- a/versioned_docs/version-21/commands-legacy/component-list.md +++ b/versioned_docs/version-21/commands-legacy/component-list.md @@ -31,16 +31,16 @@ displayed_sidebar: docs When a project is opened, 4D loads the valid components: -* found in the [Components folder of your project](../../Project/architecture.md#components). -* declared in the [**dependencies.json** file of your project](../../Project/components.md#dependenciesjson-and-environment4djson). +* found in the [Components folder of your project](../Project/architecture.md#components). +* declared in the [**dependencies.json** file of your project](../Project/components.md#dependenciesjson-and-environment4djson). -**Reminder:** If the same component is installed at different locations, a [priority order](../../Project/components.md#priority) is applied. +**Reminder:** If the same component is installed at different locations, a [priority order](../Project/components.md#priority) is applied. This command can be called from the host project or from a component. If the project does not use any components, the *componentsArray* array is returned empty. The names of the components are the names of the structure files of the matrix databases (.4db, .4dc or .4dbase). This command can be used for setting up architectures and modular interfaces that offer additional functionalities according to the presence of components. -For more information about 4D components, please refer to [this page](../../Concepts/components.md). +For more information about 4D components, please refer to [this page](../Concepts/components.md). ## See also