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.
This article discusses Recital database security: from operating system file permissions through file and field protection to DES3 encryption.
Overview
A company's data is extremely valuable and must be protected, both in operation and in physical file format. Recital products provide a range of ways to protect your data.
Operating System File Permissions
The most basic level of database security is provided by the operating system. Recital database tables and indexes are individual files with their own respective operating system file permissions. Read permission is required to open a table and write permission to update a table. If a user does not have read permission they are denied access. Without write permission, a table will be opened read-only.
Here the owner, root, and members of the recital group have write permission, so can update the example table unless additional protection applies. Other users can only open the example table read-only.
# ls -l example* -rwxrwxr-x 1 root recital 147 Nov 29 14:27 example.dbd -rwxrwxr-x 1 root recital 41580 Nov 29 14:27 example.dbf -rwxrwxr-x 1 root recital 13312 Nov 29 14:28 example.dbt -rwxrwxr-x 1 root recital 19456 Nov 29 14:28 example.dbx
Note: As in the example above, a table's associated files should have the same permissions as the table itself:
|
File Extension |
File Type |
|
.dbd |
Dictionary |
|
.dbf |
Table |
|
.dbt |
Memo |
|
.dbx |
Index |
Database Dictionary
Each Recital table may have a Database Dictionary. The Dictionary can be used both to protect the integrity of the data and to protect access to the data. This section covers Column Constraints, Triggers, Security and Protection.
Column Constraints: Data Integrity
The Dictionary attributes or constraints either prevent the entry of incorrect data, e.g. must_enter and validation or aid the entry of correct data, e.g. default, picture and choicelist. The Dictionary can be modified in the character mode CREATE/MODIFY STRUCTURE worksurface, via SQL statements, or in the Recital Enterprise Studio Database Administrator.
Click image to display full size
Fig 1: MODIFY STRUCTURE Worksurface: Dictionary.
The SQL Column Constraints are as follows:
|
Constraint |
Description |
|
AUTO_INCREMENT | AUTOINC |
Used to auto increment the value of a column. |
|
CALCULATED |
Used to calculate the value of a column. |
|
CHECK | SET CHECK |
Used to validate a change to the value of a column. |
|
DEFAULT |
Used to set a default value for the specified column. |
|
DESCRIPTION |
Used set the column description for the specified column. |
|
ERROR |
Used to define an error message to be displayed when a validation check fails. |
|
FOREIGN KEY |
Used to define a column as a Foreign Key for a parent table. |
|
NOCPTRANS |
Used to prevent code page translation for character and memo fields. |
|
NOT NULL | NULL |
Used to disallow/allow NULL values. |
|
PRIMARY KEY |
Used to define a tables Primary Key. |
|
RANGE |
Used to specify minimum and maximum values for a date or numerical column. |
|
RECALCULATE |
Used to force recalculation of calculated columns when a columns value changes. |
|
REFERENCES |
Used to create a relationship to an index key of another table. |
|
UNIQUE |
Used to define the column as a candidate index for the table |
These can be specified in CREATE TABLE or ALTER TABLE statements:
exec sql OPEN DATABASE southwind; exec sql ALTER TABLE customers ADD COLUMN timeref char(8) CHECK validtime(timeref) ERROR "Not a valid time string";
Click image to display full size
Fig 2: Database Administrator: Column Constraints and Attributes.
TRIGGERS
Table Level Triggers are event-driven procedures called before an I/O operation. These can be used to introduce another layer of checks before a particular operation is permitted to take place or to simply set up logging of those operations.
The CREATE/MODIFY STRUCTURE worksurface <TRIGGERS> menu bar option allows you to specify table level triggers. You may edit a trigger procedure from within the <TRIGGERS> menu by placing the cursor next to the procedure name and pressing the [HELP] key. A text window pops up for editing. If the table triggers are stored in separate <.prg> files, rather than in a procedure library, procedures need not be predefined (SET PROCEDURE) before using the table.
Click image to display full size
Fig 3: MODIFY STRUCTURE Worksurface: Triggers.
The following triggers can be selected and associated with a specified procedure name in the <TRIGGERS> menu.
|
Trigger |
Description |
|
UPDATE |
The specified procedure is called prior to an update operation on the table. If the procedure returns .F., then the UPDATE is canceled. |
|
DELETE |
The specified procedure is called prior to a delete operation on the table. If the procedure returns .F., then the DELETE is canceled. |
|
APPEND |
The specified procedure is called prior to an append operation on the table. If the procedure returns .F., then the APPEND is canceled. |
|
OPEN |
The specified procedure is called after an open operation on the table. |
|
CLOSE |
The specified procedure is called prior to a close operation on the table. |
|
ROLLBACK |
The specified procedure is called when a user presses the [ABANDON] key in a forms based operation. |
The Recital Enterprise Studio Database Administrator also allows you to associate existing programs as Table Trigger Procedures.
Click image to display full size
Fig 4: Database Administrator: Triggers.
Programmatically, Trigger Procedures can also be associated with a table using SQL. The following table constraints may be applied in the SQL CREATE TABLE and ALTER TABLE statements:
|
Trigger |
Description |
|
ONUPDATE |
The specified procedure is called prior to an update operation
on the table. If the procedure returns .F., then the UPDATE
is canceled. |
|
ONDELETE |
The specified procedure is called prior to a delete operation
on the table. If the procedure returns .F., then the DELETE
is canceled. |
|
ONINSERT |
The specified procedure is called prior to an insert operation
on the table. If the procedure returns .F., then the INSERT
is canceled. |
|
ONOPEN |
The specified procedure is called after an open operation
on the table. |
|
ONCLOSE |
The specified procedure is called prior to a close operation
on the table. |
|
ONROLLBACK |
The specified procedure is called when a user presses the
[ABANDON] key in a forms based operation. |
SECURITY
As mentioned above, all Recital files are subject to Operating System read and write permissions. These permissions can be further refined, while still using the Operating System user and group IDs, in the Security and Protection sections of the Dictionary. The Security section handles table based operations and the Protection section focuses on individual fields.
Security and Protection rules can be defined in the CREATE/MODIFY STRUCTURE worksurface of Recital Terminal Developer, via the SQL GRANT and REVOKE statements or in the Recital Enterprise Studio Database Administrator.
Click image to display full size
Fig 5: MODIFY STRUCTURE Worksurface: Security.
The Security section has table operations for which Access Control Strings can be specified. An Access Control String (ACS) is a range of valid user identification codes, and is used to restrict table operations to certain individuals or groups. Each user on the system is allocated a group number and a user number. The user identification code is the combination of group and user numbers. When constructing an Access Control String of linked user identification codes, wild card characters may be used.
|
Example ACS |
Description |
|
[1,2] |
In group 1, user 2 |
|
[100,*] |
In group 100, all users |
|
[2-7,*] |
In groups 2-7, all users |
|
[*,100-200] |
In all groups, users 100-200 |
|
[1,*]&[2-7,1-7] |
In group 1, all users, in groups 2-7, users 1-7 |
Please note that the maximum ACS length is 254 characters. OpenVMS group and user numbers are stored and specified in octal. On other Operating Systems, group and user numbers are stored and specified in decimal.
Access Control Strings may be associated with the following operations:
|
Operation |
Description |
|
READONLY |
Users specified in the ACS have read-only access to the table. All other users have update access. |
|
UPDATE |
Users specified in the ACS have update access to the table. All other users are restricted to read-only access. |
|
APPEND |
Users specified in the ACS can append records into the table. No other users can append. |
|
DELETE |
Users specified in the ACS can delete records from the table. No other users can delete. |
|
COPY |
Users specified in the ACS can copy records from the table. No other users can copy. |
|
ADMIN |
Users specified in the ACS can use the following commands: |
The corresponding SQL privileges are:
|
Operation |
Description |
|
SELECT |
Users specified in the ACS may name any column in a SELECT statement. All other users have update access. |
|
UPDATE |
Users specified in the ACS may name any column in an UPDATE statement. All other users are restricted to read-only access. |
|
INSERT |
Users specified in the ACS can INSERT rows into the table. No other users can INSERT. |
|
DELETE |
Users specified in the ACS can DELETE rows from the table. No other users can DELETE. |
|
ALTER |
Users specified in the ACS can use the ALTER TABLE statement on this table. |
|
READONLY |
Users specified in the ACS may read any column in a SELECT statement. All other users have update access. |
// Grant insert privilege for the customer table exec sql OPEN DATABASE southwind; exec sql GRANT UPDATE (lastname, firstname) INSERT ON customers TO '[20,100]'; // Grant all privileges to all users exec sql OPEN DATABASE southwind; exec sql GRANT ALL ON shippers TO PUBLIC;
PROTECTION
Security and Protection rules can be defined in the CREATE/MODIFY STRUCTURE worksurface of Recital Terminal Developer, via the SQL GRANT and REVOKE statements or in the Recital Enterprise Studio Database Administrator.
Click image to display full size
Fig 6: Database Administrator: Protection.
The format of the ACS is the same as in <SECURITY> above.
The following protection can be defined:
|
Operation |
Description |
|
READONLY |
Users specified in the ACS have read-only access to the field. All other users have update access. |
|
UPDATE |
Users specified in the ACS have update access to the field. All other users are restricted to read-only access. |
Recital Terminal Developer also has 'HIDDEN' Protection:
|
Operation |
Description |
|
HIDDEN |
Users specified in the ACS see the 'hiddenfield'character rather than the data in the field. All other users see the data. |
Hidden fields can be accessed and viewed on a work surface, but the field contains the hiddenfield character, ?. If the field is referenced in an expression, it will contain the following: blanks for character fields, F for logical fields, 00/00/0000 for date fields and blank for memo fields.
The corresponding SQL privileges are:
|
Operation |
Description |
|
SELECT |
Users specified in the ACS may name the column in a SELECT statement. All other users have update access. |
|
UPDATE |
Users specified in the ACS may name the column in an UPDATE statement. All other users are restricted to read-only access. |
|
READONLY |
Users specified in the ACS may read the column in a SELECT statement. All other users have update access. |
// Grant update privilege for columns lastname and firstname from the customer table exec sql OPEN DATABASE southwind; exec sql GRANT UPDATE (lastname, firstname) customers TO '[20,100]';
Encryption
From Recital 8.5 onwards, Recital installations that have the additional DES3 license option have the ability to encrypt the data held in Recital database tables. Once a database table has been encrypted, the data cannot be accessed unless the correct three-part encryption key is specified, providing additional security for sensitive data.
ENCRYPT
The ENCRYPT Recital 4GL command is used to encrypt the data in the specified table or tables matching a skeleton. If the skeleton syntax is used, then all matching tables will be given the same encryption key. The encryption key is a three part comma-separated key and may optionally be enclosed in angled brackets. Each part of the key can be a maximum of 8 characters. The key is DES3 encrypted and stored in a .dkf file with the same basename as the table. After encryption, the three parts of the key must be specified correctly before the table can be accessed.
// Encrypt individual tables encrypt customers key "key_1,key_2,key_3" encrypt employees key "<key_1,key_2,key_3>" // Encrypt all .dbf files in the directory encrypt *.dbf key "key_1,key_2,key_3"
SET ENCRYPTION
If a database table is encrypted, the correct three-part encryption key must be specified before the table's data or structure can be accessed. The SET ENCRYPTION TO set command can be used to specify a default encryption key to be used whenever an encrypted table is accessed without the key being specified. The encryption key is a three part comma-separated key.
If the command to access the table includes the key, either by appending it to the table filename specification or using an explicit clause, this will take precedence over the key defined by SET ENCRYPTION TO.
Issuing SET ENCRYPTION TO without a key causes any previous setting to be cleared. The key must then be specified for each individual encrypted table.
The default key defined by SET ENCRYPTION is only active when SET ENCRYPTION is ON. SET ENCRYPTION OFF can be used to temporarily disable the default key. The SET ENCRYPTION ON | OFF setting does not change the default key itself. SET ENCRYPTION is ON by default.
// Encrypt individual tables encrypt customers key "key_1,key_2,key_3" encrypt shippers key "key_2,key_3,key_4" // Specify a default encryption key set encryption to "key_1,key_2,key_3" // Open customers table using the default encryption key use customers // Specify shippers table's encryption key use shippers<key_2,key_3,key_4> // Disable the default encryption key set encryption to // Specify the individual encryption keys use customers encryption "key_1,key_2,key_3" use shippers<key_2,key_3,key_4>
DECRYPT
The DECRYPT command is used to decrypt the data in the specified table or tables matching a skeleton. The specified key must contain the three part comma-separated key used to previously encrypt the table and may optionally be enclosed in angled brackets. The skeleton syntax can only be used if all tables matching the skeletonhave the same key.
The DECRYPT command decrypts the data and removes the table’s .dkf file. After decryption, the key need no longer be specified to gain access to the table.
// Decrypt individual tables decrypt customers key "key_1,key_2,key_3" decrypt employees key "<key_1,key_2,key_3>" // Decrypt all .dbf files in the directory decrypt *.dbf key "key_1,key_2,key_3"
All of the following commands are affected when a table is encrypted:
- APPEND FROM
- COPY FILE
- COPY STRUCTURE
- COPY TO
- DIR
- USE
- SQL INSERT
- SQL SELECT
- SQL UPDATE
APPEND FROM
Used to append records to the active table from another table.// The key must be specified for an encrypted source table
use mycustomers append from customers encryption "key_1,key_2,key_3"; for country = "UK"
COPY FILE
Used to copy a file.// The key file must also be copied for an encrypted source table // as the target table will be encrypted
encrypt customers key "key_1,key_2,key_3" copy file customers.dbf to newcustomers.dbf copy file customers.dkf to newcustomers.dkf use newcustomers encryption "key_1,key_2,key_3"
COPY STRUCTURE
Used to copy a table's structure to a new table.// The key file is automatically copied for an encrypted source table // and the target table encrypted
encrypt customers key "key_1,key_2,key_3"
use customers encryption "key_1,key_2,key_3" copy structure to blankcust use blankcust encryption "key_1,key_2,key_3"
COPY TO
Used to copy a table.// By default, the key file is automatically copied for an encrypted // source table and the target table encrypted with the same key encrypt customers key "key_1,key_2,key_3" use customers encryption "key_1,key_2,key_3" copy to newcustomers use newcustomers encryption "key_1,key_2,key_3" // You can also create a copy with a different key encrypt customers key "key_1,key_2,key_3" use customers encryption "key_1,key_2,key_3" copy to newcustomers encrypt "newkey_1,newkey_2,newkey_3" use newcustomers encryption "newkey_1,newkey_2,newkey_3" // Or create a decrypted copy encrypt customers key "key_1,key_2,key_3" use customers encryption "key_1,key_2,key_3" copy to newcustomers decrypt use newcustomers // You can also create an encrypted copy of a non-encrypted source table use orders copy to encorders encrypt "newkey_1,newkey_2,newkey_3" use encorders encryption "newkey_1,newkey_2,newkey_3"
DIR
Used to display a directory listing of tables.// Encrypted tables are flagged as such with (DES3) > open database southwind > dir
Current database: southwind Tables # Records Last Update Size Dictionary Triggers Security categories.dbf 8 01/10/06 24576 None None None cisamdemo.dbf ---> CISAM/Bridge [cisamdemo] customers.dbf (DES3) 91 05/12/04 49600 None None None employees.dbf 9 05/12/04 25520 None None None example.dbf (DES3) 100 12/24/05 38080 Yes Yes None order_details.dbf 2155 05/12/04 296320 None None None orders.dbf 829 05/12/04 232704 None None None products.dbf 77 05/12/04 37112 None None None productsbyname.dbf 77 05/12/04 29104 None None None shippers.dbf (DES3) 3 05/12/04 20864 None None None suppliers.dbf 29 12/08/05 29992 Yes None None 0.765 MB in 11 files. 1.093 GB remaining on drive.
USE
Used to open a table.// The three part key must be specified to open an // encrypted table. All of the following are valid. // 1. Specifying a default encryption key before opening the table set encryption to "key_1,key_2,key_3" use customers // 2. Appending the key to the filename use customers<key_1,key_2,key_3> // 3. Using the ENCRYPTION clause, optionally specifying angled brackets use customers encryption "key_1,key_2,key_3" use customers encryption "<key_1,key_2,key_3>"
SQL INSERT
Used to add a row to a table via SQL.// The three part key can be specified using a
// default encryption key before opening the table
exec sql
OPEN DATABASE southwind;
exec sql
SET ENCRYPTION TO "key_1,key_2,key_3";
exec sql
INSERT INTO customers
(customerid, companyname)
VALUES
('RECIT','Recital Corporation');
// Or by appending the key to the filename
exec sql
OPEN DATABASE southwind;
exec sql
INSERT INTO customers<key_1,key_2,key_3>
(customerid, companyname)
VALUES
('RECIT','Recital Corporation');
SQL SELECT
Used to return data from a table via SQL.// The three part key can be specified using a // default encryption key before opening the table exec sql OPEN DATABASE southwind; exec sql SET ENCRYPTION TO "key_1,key_2,key_3"; exec sql SELECT * FROM customers; // Or by appending the key to the filename exec sql OPEN DATABASE southwind; exec sql SELECT * FROM customers<key_1,key_2,key_3>;
SQL UPDATE
Used to update data in a table via SQL.// The three part key can be specified using a // default encryption key before opening the table exec sql OPEN DATABASE southwind; exec sql SET ENCRYPTION TO "key_1,key_2,key_3"; exec sql UPDATE customers SET companyname='Recital Corporation Inc.' WHERE customerid='RECIT'; // Or by appending the key to the filename exec sql OPEN DATABASE southwind; exec sql UPDATE customers<key_1,key_2,key_3> SET companyname='Recital Corporation Inc.' WHERE customerid='RECIT';
Summary
Recital offers a range of ways to keep your data secure. These start with the Operating System read/write permissions, which can be further refined to the level of table I/O operations and then field access in the Dictionary based Security and Protection rules. The Dictionary also provides the means to protect the integrity of the data via data validation and to assist in correct data entry through the use of choicelists, help messages and picture clauses etc. A further role of the Dictionary is in the provision of Table Triggers, which can be used to enable a programmatic response to table operations to add in additional checks or audit trails. For the most sensitive data, DES3 encryption is the ultimate protection: encrypting the physical data on the disk and only permitting table access on the production of the three part encryption key.
We are pleased to announce the release of Recital 10.0.3.
Here is a brief list of features and functionality that you will find in the 10.0.3 release.
- New Commands:
- SET TMPNAMPATH ON|OFF
- REMOVE TABLE - New Functions:
- CURSORGETPROP()
- CURSORSETPROP()
- CURVAL()
- GETFLDSTATE()
- OLDVAL()
- TABLEREVERT()
- TABLEUPDATE()
- SETFLDSTATE() - Enhanced Functions:
- TMPNAM() - additional parameter to specify the return of basename only
- MAILATTACH() - parameter changed from array to filename to allow directory and file extension to be specified - Enhancements:
- DO level increased from 32 to 64. - Fixes:
- Delay exiting Recital after SYS(3) or SYS(2015)
- SET SOFTSEEK issue when search key above first record in index
- Compilation error with REPLACE command after UDF call
- FETCH INTO memvars error
- END TRANSACTION at command prompt error
- ROLLBACK locking error
- Linux ODBC Driver undefined symbol error
- RELEASE variable with same name as variable in calling program issue
- SQLCODE() issue on non-gateway data access
- Issuing two SQLEXEC() calls error
- LASTSEQNO() in workareas > 1 error
- SET RELATION to detail table in workarea 1 issue
- LIST STATUS on empty table delay
- SET AUTOCATALOG alias entries error
- ADD OBJECT in DEFINE CLASS error
- DEACTIVATE WINDOW error
- SORT error
- Other reported bugs
./configure CFLAGS='-arch x86_64' APXSLDFLAGS='-arch x86_64' --with-apxs=/usr/sbin/apxsThen you must pass the these additional flags to the apxs command in order to generate a Universal Binary shared module.
-Wl,-dynamic -Wl,'-arch ppc' -Wl,'-arch ppc64' -Wl,'-arch i386' -Wl,'-arch x86_64' -Wc,-dynamic -Wc,'-arch ppc' -Wc,'-arch ppc64' -Wc,'-arch i386' -Wc,'-arch x86_64'If you then do a file command on the shared module it should return;
$ file mod_recital.so mod_recital2.2.so: Mach-O universal binary with 4 architectures mod_recital2.2.so (for architecture ppc7400): Mach-O bundle ppc mod_recital2.2.so (for architecture ppc64): Mach-O 64-bit bundle ppc64 mod_recital2.2.so (for architecture i386): Mach-O bundle i386 mod_recital2.2.so (for architecture x86_64): Mach-O 64-bit bundle x86_64The apache module files are stored in the /usr/libexec/apache2/ directory on a default apache install on the Mac and the configuration file is /private/etc/apache2/httpd.conf
This article looks at the range of client access mechanisms for Windows that can be used with the Recital C-ISAM Bridge and details bridge configuration and usage.
Overview
Just because the format of data is regarded as 'legacy' does not make that data in any way obsolete. Modern client interfaces can not only extend the life of long-term data, but also provide different ways to analyse and gain advantage from that data.
Recital Corporation provides a range of solutions to interface to Informix compliant C-ISAM data on Linux or UNIX from Windows clients.
.NET
Click image to display full size
Fig 1: Recital Mirage .NET application accessing the C-ISAM Demo table.
Recital offers two alternative ways to access C-ISAM data using Microsoft .NET:
The Recital .NET Data Provider is a managed Data Provider written in C# that provides full compatibility with the Microsoft SQLserver and OLE DB data providers that ship with the .NET framework. It is fully integrated with the Visual Studio .NET IDE supporting data binding and automatic code generation using the form designer. The Recital .NET Data Provider works in conjunction with the Recital Database Server for Linux or UNIX to access C-ISAM data.
Recital Mirage .NET is a complete solution for migrating, developing and deploying 4GL database applications. Recital Mirage .NET works in conjunction with the Recital Mirage .NET Application Server for Linux or UNIX to access C-ISAM data.
JDBC
Click image to display full size
Fig 2: Java™ Swing JTable accessing the C-ISAM Demo table via the Recital JDBC Driver.
The Recital JDBC Driver is an all Java Type 4 JDBC 3.0 Driver, allowing you to access C-ISAM data from Java applets and applications. The Recital JDBC Driver works in conjunction with the Recital Database Server for Linux or UNIX to access C-ISAM data.
ODBC
Click image to display full size
Fig 3: Microsoft® Office Excel 2003 Pivot Chart and Pivot Table accessing the C-ISAM Demo table via the Recital ODBC Driver.
The Recital ODBC Driver is an ODBC 3.0 Driver, allowing you to access C-ISAM data from your preferred ODBC based Windows applications. You can develop your own applications in languages such as C++ or Visual Basic, manipulate the data in a spreadsheet package or word processor document and design charts, graphs and reports. The Recital ODBC Driver works in conjunction with the Recital Database Server for Linux or UNIX to access C-ISAM data.
Configuring the Recital C-ISAM Bridge
Data access is achieved through a C-ISAM Bridge. This requires the creation of an empty Recital table that has the same structure as the C-ISAM file and of a RecitalC-ISAM Bridge file.
On Linux and UNIX, Recital Terminal Developer and the Recital Database Server come complete with an example C-ISAM data file, C-ISAM index and Recital C-ISAM bridge that can be used for testing and as a template for configuring your own C-ISAM bridges. The Recital Database Server also includes a bridge creation ini file.
Step 1:
Create a Recital table with the same structure as the C-ISAM file. The fields/columns in the structure file must exactly match the data type and length of those in the C-ISAM file. The Recital table will have one byte more in total record length due to the Recital record deletion marker.
To create the table, use the SQL CREATE TABLE command or the Recital Terminal Developer CREATE worksurface. The SQL CREATE TABLE command can be called directly:
SQLExecDirect:
In: hstmt = 0x00761BE8,
szSqlStr = "CREATE TABLE cisamdemo.str (DD Char(4)
DESCRIPTION "Dd...", cbSqlStr = -3
Return: SQL_SUCCESS=0
or be included in a 4GL program:
// createtab.prg
CREATE TABLE cisamdemo.str;
(DD Char(4) DESCRIPTION "Dd",;
CONFIRM Char(6) DESCRIPTION "Confirm",;
PROCDATE Char(6) DESCRIPTION "Procdate",;
CONTROL Char(5) DESCRIPTION "Control",;
DOLLARS Decimal(13,2) DESCRIPTION "Dollars",;
DEALER Char(5) DESCRIPTION "Dealer",;
TERRITORY Char(2) DESCRIPTION "Territory",;
WOREP Char(12) DESCRIPTION "Worep",;
CURRTRAN Char(3) DESCRIPTION "Currtran",;
TRADDATE Char(6) DESCRIPTION "Traddate",;
CITY Char(10) DESCRIPTION "City",;
ACCOUNT Char(11) DESCRIPTION "Account",;
PRETRAN Char(2) DESCRIPTION "Pretran",;
AFSREP Char(14) DESCRIPTION "Afsrep",;
REPKEY Char(9) DESCRIPTION "Repkey",;
BRANCH Char(3) DESCRIPTION "Branch",;
WODEALER Char(5) DESCRIPTION "Wodealer",;
BANKCODE Char(2) DESCRIPTION "Bankcode",;
COMMRATE Decimal(6,4) DESCRIPTION "Commrate",;
NEWREP Char(1) DESCRIPTION "Newrep",;
SETTLE Char(1) DESCRIPTION "Settle",;
POSTDATE Char(6) DESCRIPTION "Postdate")
if file("cisamdemo.str")
return .T.
else
return .F.
endif
// end of createtab.prg
Server-side 4GL programs can be called by all clients, e.g. from a Java class with a JDBC connection:
//---------------------------------
//-- create_str.java --
//---------------------------------
import java.sql.*;
import java.io.*;
import Recital.sql.*;
public class create_str {
public static void main(String argv[]) {
try {
new RecitalDriver();
String url = "jdbc:Recital:" +
"SERVERNAME=cisamserver;" +
"DIRECTORY=/usr/recital/data/southwind;" +
"USERNAME=user;" +
"PASSWORD=password";
Connection con = DriverManager.getConnection(url, "user", "pass");
Statement stmt = con.createStatement();
CallableStatement sp = con.prepareCall("{call createtab}");
boolean res = sp.execute();
String outParam = sp.getString(1);
System.out.println("Returned "+outParam);
sp.close();
con.close();
} catch (Exception e) {
System.out.flush();
System.err.flush();
DriverManager.println("Driver exception: " + e.getMessage());
e.printStackTrace();
}
try {
System.out.println("Press any key to continue...");
System.in.read();
} catch(IOException ie) {
;
}
}
}
The table should be given a ‘.str’ file extension (rather than the default ‘.dbf’) to signify that this is a structure file only.
Please see the end of this article for information on matching Informix and Recital data types

Fig 4: Recital CREATE/MODIFY STRUCTURE worksurface for character mode table creation.
Step 2: Creating the Bridge File
If you have Recital installed on the server platform, the Bridge File can be created using the CREATE BRIDGE worksurface. The corresponding command to modify the bridge file is MODIFY BRIDGE <bridge file>. This is the cisamdemo.dbf bridge file in the CREATE/MODIFY BRIDGE WORKSURFACE:
> modify bridge cisamdemo.dbf

Fig 5: Recital CREATE BRIDGE/MODIFY BRIDGE worksurface for bridge creation.
For Recital Database Server clients, the Bridge File can be created using the Recital/SQL CREATE BRIDGE command:
Recital/SQL CREATE BRIDGE:
CREATE BRIDGE cisamdemo.dbf; TYPE "CISAM"; EXTERNAL "cisamdemo.dat"; METADATA "cisamdemo.str"; ALIAS "cisamdemo"
or:
CREATE BRIDGE cisamdemo.dbf; AS "type=CISAM;external=cisamdemo.dat;metadata=cisamdemo.str;alias=cisamdemo"
The examples above assume that the C-ISAM file, the bridge file and the Recital structure file are all in the current working directory. Full path information can be specified for the <externalname> and the <databasename>. For added flexibility, environment variables can be used to determine the path at the time the bridge is opened. Environment variables can be included for either or both the <externalname> and the <databasename>. A colon should be specified between the environment variable and the file name.
e.g.
CREATE BRIDGE cisamdemo.dbf; TYPE "CISAM"; EXTERNAL "DB_DATADIR:cisamdemo"; METADATA "DB_MIRAGE_PATH:cisamdemo.str"; ALIAS "cisamdemo"
Recital CREATE BRIDGE/MODIFY BRIDGE worksurface:

Fig 6: Recital CREATE BRIDGE/MODIFY BRIDGE worksurface - using environment variables.
Using the Bridge
The Bridge can now be used. To access the C-ISAM file, use the ‘alias’ specified in the Bridge definition.
SQL:
SELECT * FROM cisamdemo
Recital/4GL:
use cisamdemo
Indexes
The cisamdemo.dat file included in the Recital distributions for Linux and UNIX has three associated index keys in the cisamdemo.idx file:
Select area: 1 Database in use: cisamdemo Alias: cisamdemo Number of records: 4 Current record: 2 File Type: CISAM (C-ISAM) Master Index: [cisamdemo.idx key #1] Key: DD+CONFIRM+PROCDATE+CONTROL Type: Character Len: 21 (Unique) Index: [cisamdemo.idx key #2]
Key: DD+SUBSTR(CONFIRM,2,5)+TRADDATE+STR(DOLLARS,13,2) +CURRTRAN+ACCOUNT Type: Character Len: 42 Index: [cisamdemo.idx key #3] Key: DEALER+BRANCH+AFSREP+SUBSTR(PROCDATE,5,2) +SUBSTR(CONTROL,2,4) Type: Character Len: 28
The Recital C-ISAM bridge makes full use of the C-ISAM indexes. SQL SELECT statements with WHERE clauses are optimized based on any of the existing indexes when possible. The following ODBC SELECT call makes use of key #3 rather than sequentially searching through the data file.
SQLExecDirect:
In: hstmt = 0x00761BE8,
szSqlStr = "select * from cisamdemo
where dealer+branch+afsrep=' 00161 595-7912",
cbSqlStr = -3
Return: SQL_SUCCESS=0
Get Data All:
"DD", "CONFIRM", "PROCDATE", "CONTROL", "DOLLARS", "DEALER",
"TERRITORY", "WOREP", "CURRTRAN", "TRADDATE", "CITY", "ACCOUNT",
"PRETRAN", "AFSREP", "REPKEY", "BRANCH", "WODEALER", "BANKCODE",
"COMMRATE", "NEWREP", "SETTLE", "POSTDATE"
"0159", " 15522", "930312", "13356", 4992.60, "00161", "19",
"", "210", "930305", "", "70000100009", "", "595-7912",
"930315791", "", "", "59", 0.0000, "1", "", "930315"
1 row fetched from 22 columns.
Using the Recital/4GL, the primary index is set as the master index when the bridge is first opened. Any secondary indexes can be selected using the SET ORDER TO <expN> command. The Recital/4GL SEEK or FIND commands and SEEK() function can be used to search in the current master index.
> SET ORDER TO 3 Master index: [cisamdemo.idx key #3] > SEEK “00161 595-7912”
Appendix 1: Data Types
|
Informix |
Recital |
|
Byte |
Numeric |
|
Char |
Character |
|
Character |
Character |
|
Date |
Date |
|
Datetime |
Character |
|
Decimal |
Numeric |
|
Double Precision |
Float |
|
Float |
Real |
|
16 Bit Integer |
Short |
|
Integer |
Numeric |
|
Interval |
Character |
|
32 Bit Long |
Integer |
|
Money |
Numeric |
|
Numeric |
Numeric |
|
Real |
Numeric |
|
Smallfloat |
Numeric |
|
Smallint |
Numeric |
|
Text |
Unsupported |
|
Varchar |
Character |
Appendix 2: C-ISAM RDD Error Messages
The following errors relate to the use of the Recital CISAM Replaceable Database Driver (RDD). They can be received as an ‘errno <expN>’ on Recital error messages:
|
ERRNO() |
Error Description |
|
100 |
Duplicate record |
|
101 |
File not open |
|
102 |
Invalid argument |
|
103 |
Invalid key description |
|
104 |
Out of file descriptors |
|
105 |
Invalid ISAM file format |
|
106 |
Exclusive lock required |
|
107 |
Record claimed by another user |
|
108 |
Key already exists |
|
109 |
Primary key may not be used |
|
110 |
Beginning or end of file reached |
|
111 |
No match was found |
|
112 |
There is no “current” established |
|
113 |
Entire file locked by another user |
|
114 |
File name too long |
|
115 |
Cannot create lock file |
|
116 |
Memory allocation request failed |
|
117 |
Bad custom collating |
|
118 |
Duplicate primary key allowed |
|
119 |
Invalid transaction identifier |
|
120 |
Exclusively locked in a transaction |
|
121 |
Internal error in journaling |
|
122 |
Object not locked |
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.
// declare some simple procedures
proc display(cArg)
echo "display=" + cArg
endproc
proc show(cArg)
echo "show=" + cArg
endproc
// create an object based on an anonymous class
myobj = new object()
// add some properties
myobj["name"] = "barry"
myobj["company"] = "recital"
// now declare an anonymous method
myobj["mymethod"] = display
// call the method
myobj.mymethod("hello world") // displays "display=hello world"
// redeclare the method
myobj["mymethod"] = show
// call the method
myobj.mymethod("hello world") // displays "show=hello world"
Where this becomes particularly useful is when you have a procedure that calls anonymous methods in order to process data. This technique can be used to call anonymous procedures in your code.
proc processdata(oArg)
oArg.mymethod(oArg.name)
endproc
proc show(cArg)
echo "show=" + cArg
endproc
myobj = new object()
myobj["name"] = "barry"
myobj["mymethod"] = show
processdata(myobj) // displays "show=barry" Platforms supported
- Intel® / AMD™ 32 bit Linux
- Intel® / AMD™ 64 bit Linux
- HP PA-RISC HP-UX® 10.20 and above
- Sun® SPARC Solaris™ 8 and above
- HP Alpha OpenVMS 7.2-1 and above
- SCO® OpenServer 5.0.5 and above
- Sun® Intel® Solaris™ 10 and above
- IBM AIX® 4.3 and above
- HP Integrity OpenVMS 8.2-1 and above
- HP Intel® Itanium® HP-UX® 11.23 and above
- Mac OS X leopard 10.5 and above
Large File Support is available for Windows, Itanium HP-UX and Linux.