// declare an empty dynamic array a = array() // declare a simple dynamic array a = array("barry", "recital", "boston") foreach a as value echo value endfor // declare an associative array a = array("name" => "barry", "company" => "recital", "location" => "boston") echo "length of a is " + len(a) foreach a as key => value echo "key=" + key + ", value=" + value endfor
After an extended period of intense software development, we are pleased to announce the release of Recital 10 which is a milestone in our development efforts.
The Recital 10 release notes can be found here.
- Recital
A powerful scripting language with an embedded database used for developing desktop database applications on Linux and Unix.
- Recital Server
A cross-platform SQL database and application server.
- Recital Web
A server-side scripting language with an embedded SQL database for creating web 2.0 web applications.
auth sufficient pam_krb5.so try_first_pass
auth sufficient pam_unix.so shadow nullok try_first_pass
account required pam_unix.so broken_shadow
account [default=bad success=ok user_unknown=ignore] pam_krb5.so
In this article Barry Mavin explains step by step how to setup a Linux HA (High Availability) cluster for the running of Recital applications on Redhat/Centos 5.3 although the general configuration should work for other linux versions with a few minor changes.
The REQUIRE() statement includes and executes the contents of the specified file at the current program execution level.
When a file is included, the code it contains inherits the variable scope of the line on which the include occurs. Any variables, procedures, functions or classes declared in the included file will be available at the current program execution level.
The REQUIRE_ONCE() statement is identical to the REQUIRE() statement except that Recital will check to see if the file as already been included and if so ignore the command.
The full syntax is:
REQUIRE( expC ) REQUIRE_ONCE( expC ) e.g. REQUIRE_ONCE( "myapp/myglobals.prg" )
To access the menu bar in Recital, press the / key.
Full details on Recital Function Keys can be found in the Key Assist section of the Help menu, or in our documentation wiki here.
Ext3 commits writes to disk within approximately 5 seconds - Ext4 can take from 40-150 seconds. In addition, if a system is using Ext3 and crashes before the commit takes place you will still have the previous contents of a file where under Ext4 the file will be empty. Theodore Tso feels that this is a failure at the application level and that the file system is behaving as designed and as specified by the POSIX spec (which apparently does not specify what is supposed to happen when a system is not shut down cleanly). His solution to the issue is to suggest proper use of fsync() and lists various scenarios/examples in post 54 of the bug report (linked above). In addition he wrote a patch that recognize the rename() situation mentioned in his post 54 yet retains the normal Ext4 behaviors and performance in the majority of cases. Also a more "proper" solution has been provided which allows the behavior of Ext3 to be retained under Ext4 by mounting it with alloc_on_commit.
A somewhat related topic is the use of on-board caching by hard drives. This behavior can be modified on most drives by using hdparm.
In this article Barry Mavin, CEO and Chief Software Architect for Recital, details how to work with Triggers in the Recital Database Server.
Overview
A trigger is a special kind of stored procedure that runs when you modify data in a specified table using one or more of the data modification operations: UPDATE, INSERT, or DELETE.
Triggers can query other tables and can include complex SQL statements. They are primarily useful for enforcing complex business rules or requirements. For example, you can control whether to allow a new order to be inserted based on a customer's current account status.
Triggers are also useful for enforcing referential and data integrity.
Triggers can be used with any data source that is handled natively by the Recital Database Engine. This includes Recital, FoxPro, FoxBASE, Clipper, dBase, CISAM, and RMS data,
Creating and Editing Triggers
To create a new Trigger, right-click the Procedures node in the Databases tree of the Project Explorer and choose Create. To modify an existing Trigger select the Trigger in the Databases Tree in the Project Explorer by double-clicking on it, or select Modify from the context menu. By convertion we recommend that you name your Stored Procedures beginning with "sp_xxx_", user-defined functions with "f_xxx_", and Triggers with "dt_xxx_", where xxx is the name of the table that they are associated with.
Associating Triggers with a Table
Once you have written your Triggers as detailed above you can associate them with the operations performed on a Table by selecting the Table tab.
The Tables tab allows you to select a Trigger procedure by clicking on the small button at the right of the Text field.
Types of Triggers
As can be seen from the Tables tab detailed below, The Recital Database Server handles 6 distinct types of Triggers.
Open Trigger
The Open Trigger is called after is a table is opened but before any operations are performed on it. You can use this trigger to record a log of table usage or provide a programmable means of checing security. If the Trigger procedure returns .F. (false), then the table is not opened. You can use a TRY...CATCH block around the associated command to inform the user.
Close Trigger
The Close Trigger is called just prior to a table being closed. In this trigger you may find it useful to get transaction counts by using the IOSTATS() built-in 4GL function, and record these values in a transaction log.
Update Trigger
The Update Trigger is called prior to a record update operation being performed. You can use this trigger to perform complex application or data specific validation. If the Trigger procedure returns .F. (false), then the record is not updated. You can use inform the user from within the Trigger procedure the reason that the data cannot be updated.
Delete Trigger
The Delete Trigger is called prior to a record delete operation being performed. You can use this trigger to perform complex application or data specific validation such as cross-table lookups e.g. attempting to delete a customer recortd when there are still open orders for that specific customer. If the Trigger procedure returns .F. (false), then the record is not deleted.
Insert Trigger
The Insert Trigger is called prior to a record insert (append) operation being performed. You can use this trigger to perform such tasks as setting up default values of columns within the record. If the Trigger procedure returns .F. (false), then the record is not inserted.
Rollback Trigger
The RollbackTrigger is called prior to a rollback operation being performed from within a form. If the Trigger procedure returns .F. (false), then the record is not rolled back to its original state.
Testing the Trigger
To test run the Trigger, select the Trigger in the Databases Tree in the Project Explorer by double-clicking on it. Once the Database Administrator is displayed, click the Run button to run the Trigger.
lslk lists information about locks held on files with local inodes on systems running linux.
Install it with:
yum install lslk