DirectoryIndex default.rsp index.html
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.
In this article Barry Mavin, CEO and Chief Software Architect for Recital, details how to use the Client Drivers provided with the Recital Database Server to work with local or remote server-side OLE DB data sources.
Overview
The Recital Universal .NET Data Provider provides connectivity to the Recital Database Server running on any supported platform (Windows, Linux, Unix, OpenVMS) using the RecitalConnection object.
The Recital Universal JDBC Driver provides the same functionality for java applications.
The Recital Universal ODBC Driver provides the same functionality for applications that use ODBC.
Each of the above Client Drivers use a connection string to describe connections parameters.
The basic format of a connection string consists of a series of keyword/value pairs separated by semicolons. The equal sign (=) connects each keyword and its value.
The following table lists the valid names for keyword/values.
| Name | Default | Description |
|---|---|---|
|
Data Source
|
The name or network address of the instance of the Recital Database Server which to connect to. | |
| Directory | The target directory on the remote server where data to be accessed resides. This is ignored when a Database is specified. | |
|
Encrypt |
false | When true, DES3 encryption is used for all data sent between the client and server. |
| Initial Catalog -or- Database |
The name of the database on the remote server. | |
| Password -or- Pwd |
The password used to authenticate access to the remote server. | |
| User ID | The user name used to authenticate access to the remote server. | |
|
Connection Pooling |
false | Enable connection pooling to the server. This provides for one connection to be shared. |
| Logging | false | Provides for the ability to log all server requests for debugging purposes |
| Rowid | true | When Rowid is true (the default) a column will be post-fixed to each SELECT query that is a unique row identifier. This is used to provide optimised UPDATE and DELETE operations. If you use the RecitalSqlGrid, RecitalSqlForm, or RecitalSqlGridForm components then this column is not visible but is used to handle updates to the underlying data source. |
| Logfile | The name of the logfile for logging | |
| Gateway |
Opens an SQL gateway(Connection) to a foreign SQL data source on the remote server. Using Gateways, you can transparently access the following local or remote data sources:
The gateway can be specified in several formats: servertype@nodename:username/password-database e.g. oracle@nodename:username/password-database mysql@nodename:username/password-database postgresql@nodename:username/password-database -or- odbc:odbc_data_source_name_on_server oledb:oledb_connection_string_on_server jdbc:jdbc_driver_path_on_server;jdbc:Recital:args |
To connect to a server-side OLE DB data source, you use the gateway=value key/value pair in the following way.
gateway=oledb:oledb_connection_string_on_server
ImportantWhen specifying the connection string be sure to quote the gateway= with "...".
You can find examples of connection strings for most ODBC and OLE DB data sources by clicking here.
Example in C# using the Recital Universal .NET Data Provider:
////////////////////////////////////////////////////////////////////////
// include the references below
using System.Data;
using Recital.Data;
////////////////////////////////////////////////////////////////////////
// The following code example creates an instance of a DataAdapter that
// uses a Connection to the Recital Database Server, and a gateway to
// the SQL server Northwind database. It then populates a DataTable
// in a DataSet with the list of customers. The SQL statement and
// Connection arguments passed to the DataAdapter constructor are used
// to create the SelectCommand property of the DataAdapter.
public DataSet SelectCustomers()
{
string gateway = "oledb:Provider=sqloledb;Initial Catalog=Northwind;
Data Source=localhost;Integrated Security=SSPI";
RecitalConnection swindConn = new
RecitalConnection("Data Source=localhost;gateway=\""+gateway+"\");
RecitalCommand selectCMD = new
RecitalCommand("SELECT CustomerID, CompanyName FROM Customers", swindConn);
selectCMD.CommandTimeout = 30;
RecitalDataAdapter custDA = new RecitalDataAdapter();
custDA.SelectCommand = selectCMD;
swindConn.Open();
DataSet custDS = new DataSet();
custDA.Fill(custDS, "Customers");
swindConn.Close();
return custDS;
}
Example in Java using the Recital Universal JDBC Driver:
////////////////////////////////////////////////////////////////////////
// standard imports required by the JDBC driver
import java.sql.*;
import java.io.*;
import java.net.URL;
import java.math.BigDecimal;
import Recital.sql.*;
////////////////////////////////////////////////////////////////////////
// The following code example creates a Connection to the Recital
// Database Server, and a gateway to the SQL server Northwind database.
// It then retrieves all the customers.
public void SelectCustomers()
{
// setup the Connection URL for JDBC
String gateway = "oledb:Provider=sqloledb;Initial Catalog=Northwind;
Data Source=localhost;Integrated Security=SSPI";
String url = "jdbc:Recital:Data Source=localhost;gateway=\""+gateway+"\";
// load the Recital Universal JDBC Driver
new RecitalDriver();
// create the connection
Connection con = DriverManager.getConnection(url);
// create the statement
Statement stmt = con.createStatement();
// perform the SQL query
ResultSet rs = stmt.executeQuery("SELECT CustomerID, CompanyName FROM Customers");
// fetch the data
while (rs.next())
{
String CompanyID = rs.getString("CustomerID");
String CompanyName = rs.getString("CompanyName");
// do something with the data...
}
// Release the statement
stmt.close();
// Disconnect from the server
con.close();
} SE Linux is a feature of the Linux kernel that provides mandatory access control. This policy based access control system grants far greater control over the resources on a machine than standard Linux access controls such as permissions.
Many modern Linux distributions are shipping with SELinux enabled by default, Fedora 14 and Rhel 6 both install with it enabled.
When you run Recital Web on a SELinux enabled machine and navigate to the default.rsp page you will see something similar to the screen shot below.

If you launch the SELinux troubleshooter you will see the following problem.
SELinux is blocking the apache server from accessing the Recital server running on port 8001.

To manage you SELinux policy you must have the policycoreutils package group installed. The policycoreutils contains the policy core utilities that are required for basic operation of a SELinux system.
If you wish to use a GUI tool, you must install the policycoreutils-gui package.
At the command prompt execute the following:
As root
$ yum install policycoreutils
$ semanage port -a -t http_port_t -p tcp 8001
$ service recital restart
$ service httpd restart
We use the semanage command here to allow the http server access to port 8001. Once you have completed the steps detailed above you can go and navigate back to the default.rsp page in your borwser, where you will find the permission denied message is now replaced by the default.rsp page.

SELinux does a great job of restricting services and daemons so rather than simply disabling it, why not work with it!
When it comes to security, every little bit helps...
In this article Barry Mavin, CEO and Chief Software Architect for Recital details how to Build C Extension Libraries to use with Recital.
Overview
It is possible to extend the functionaliy of Recital products using "Extension libraries" that can be written in C. These extension libraries, written using the Recital/SDK API, are dynamically loadable from all Recital 9 products. This includes:
- Recital
- Recital Server
- Recital Web
Building C Extension Libraries
You can create C wrappers for virtually any native operating system function and access these from the Recital 4GL. Unlike traditional APIs which only handle the development of C functions that are callable from the 4GL, the Recital/SDK allows you to build Classes that are accessible from all Recital products. e.g. You could create a GUI framework for Linux that handles VFP system classes!
To deploy your C Extension Libraries, copy them to the following location:
Windows:
\Program Files\Recital\extensions
Linux/Unix:
/opt/recital/extensions
Please see the Recital/SDK API Reference documentation for further details.
Sample code
Listed below is the complete example of a C Extension Library.:
////////////////////////////////////////////////////////////////////////////////
#include "mirage_demo.h"
////////////////////////////////////////////////////////////////////////////////
// Declare your functions and classes below as follows:
//
// Recital Function Name, C Function Name, Type (Function or Class)
//
#define MAX_ELEMENTS 7
static struct API_SHARED_FUNCTION_TABLE api_function_table[MAX_ELEMENTS] = {
{"schar", "fnSamplesCharacter", API_FUNCTION},
{"stype", "fnSamplesType", API_FUNCTION},
{"slog", "fnSamplesLogical", API_FUNCTION},
{"snum", "fnSamplesNumeric", API_FUNCTION},
{"sopen", "fnSamplesOpen", API_FUNCTION},
{"myclass", "clsMyClass", API_CLASS},
{NULL, NULL, -1}
};
////////////////////////////////////////////////////////////////////////////////
// Recital API initialization. This should be in only ONE of your C files
// **IT SHOULD NEVER BE EDITED OR REMOVED**
INIT_API;
///////////////////////////////////////////////////////////////////////
// This is an example of passing a character parameter and returning one.
RECITAL_FUNCTION fnSamplesCharacter(void)
{
char *arg1;
if (!_parse_parameters(PCOUNT, "C", &arg1)) {
ERROR(-1, "Incorrect parameters");
}
_retc(arg1);
}
///////////////////////////////////////////////////////////////////////
// This is an example of passing a numeric parameter and returning one.
RECITAL_FUNCTION fnSamplesNumeric(void)
{
int arg1;
if (!_parse_parameters(PCOUNT, "N", &arg1)) {
ERROR(-1, "Incorrect parameters");
}
_retni(arg1);
}
///////////////////////////////////////////////////////////////////////
// This is an example returns the data type of the parameter passed.
RECITAL_FUNCTION fnSamplesType(void)
{
char result[10];
if (PCOUNT != 1) {
ERROR(-1, "Incorrect parameters");
}
switch (_parinfo(1)) {
case API_CTYPE:
strcpy(result, "Character");
break;
case API_NTYPE:
strcpy(result, "Numeric");
break;
case API_LTYPE:
strcpy(result, "Logical");
break;
case API_DTYPE:
strcpy(result, "Date");
break;
case API_TTYPE:
strcpy(result, "DateTime");
break;
case API_YTYPE:
strcpy(result, "Currency");
break;
case API_ATYPE:
strcpy(result, "Array");
break;
default:
strcpy(result, "Unkown");
break;
}
_retc(result);
}
///////////////////////////////////////////////////////////////////////
// This is an example returns "True" or False.
RECITAL_FUNCTION fnSamplesLogical(void)
{
char result[10];
int arg1;
if (!_parse_parameters(PCOUNT, "L", &arg1)) {
ERROR(-1, "Incorrect parameters");
}
if (arg1) strcpy(result, "True");
else strcpy(result, "False");
_retc(result);
}
///////////////////////////////////////////////////////////////////////
// This example opens a table.
RECITAL_FUNCTION fnSamplesOpen(void)
{
char *arg1;
if (!_parse_parameters(PCOUNT, "C", &arg1)) {
ERROR(-1, "Incorrect parameters");
}
if (_parinfo(1) == API_CTYPE) {
_retni(COMMAND(arg1));
} else {
_retni(-1);
}
}
///////////////////////////////////////////////////////////////////////
// Define the MyClass CLASS using the API macros
///////////////////////////////////////////////////////////////////////
RECITAL_EXPORT int DEFINE_CLASS(clsMyClass)
{
/*-------------------------------------*/
/* Dispatch factory methods and return */
/*-------------------------------------*/
DISPATCH_FACTORY();
/*---------------------------------*/
/* Dispatch constructor and return */
/*---------------------------------*/
DISPATCH_METHOD(clsMyClass, Constructor);
/*--------------------------------*/
/* Dispatch destructor and return */
/*--------------------------------*/
DISPATCH_METHOD(clsMyClass, Destructor);
/*-----------------------------------*/
/* Dispatch DEFINE method and return */
/*-----------------------------------*/
DISPATCH_METHOD(clsMyClass, Define);
/*------------------------------*/
/* Dispatch SET or GET PROPERTY */
/* method for property NumValue */
/* then return. */
/*------------------------------*/
DISPATCH_PROPSET(clsMyClass, NumValue);
DISPATCH_PROPGET(clsMyClass, NumValue);
/*------------------------------*/
/* Dispatch SET or GET PROPERTY */
/* method for property LogValue */
/* then return. */
/*------------------------------*/
DISPATCH_PROPSET(clsMyClass, LogValue);
DISPATCH_PROPGET(clsMyClass, LogValue);
/*-------------------------------*/
/* Dispatch SET or GET PROPERTY */
/* method for property DateValue */
/* then return. */
/*-------------------------------*/
DISPATCH_PROPSET(clsMyClass, DateValue);
DISPATCH_PROPGET(clsMyClass, DateValue);
/*-------------------------------*/
/* Dispatch SET or GET PROPERTY */
/* method for property TimeValue */
/* then return. */
/*-------------------------------*/
DISPATCH_PROPSET(clsMyClass, TimeValue);
DISPATCH_PROPGET(clsMyClass, TimeValue);
/*-------------------------------*/
/* Dispatch SET or GET PROPERTY */
/* method for property CurrValue */
/* then return. */
/*-------------------------------*/
DISPATCH_PROPSET(clsMyClass, CurrValue);
DISPATCH_PROPGET(clsMyClass, CurrValue);
/*-------------------------------*/
/* Dispatch SET or GET PROPERTY */
/* method for property CharValue */
/* then return. */
/*-------------------------------*/
DISPATCH_PROPSET(clsMyClass, CharValue);
DISPATCH_PROPGET(clsMyClass, CharValue);
/*------------------------------*/
/* Dispatch SET or GET PROPERTY */
/* method for property ObjValue */
/* then return. */
/*------------------------------*/
DISPATCH_PROPSET(clsMyClass, ObjValue);
DISPATCH_PROPGET(clsMyClass, ObjValue);
/*-----------------------------------*/
/* If message not found return error */
/*-----------------------------------*/
OBJECT_RETERROR("Unknown message type");
}
////////////////////////////////////////////////////////////////////////////////
// Define METHOD handlers
////////////////////////////////////////////////////////////////////////////////
DEFINE_METHOD(clsMyClass, Constructor)
{
struct example_data *objectDataArea;
/* Allocate memory for objects objectData area */
objectDataArea = (struct example_data *)
malloc(sizeof(struct example_data));
if (objectDataArea == NULL) return(-1);
/* Assign the default property values */
strcpy(objectDataArea->prop_charvalue, "Test API object");
objectDataArea->prop_numvalue = 15.2827;
objectDataArea->prop_logvalue = 'F';
strcpy(objectDataArea->prop_datevalue, DATE_DATE());
strcpy(objectDataArea->prop_timevalue, DATE_DATETIME());
strcpy(objectDataArea->prop_currvalue, "15.2827");
strcpy(objectDataArea->object_name, "APIobject");
objectDataArea->prop_objvalue
= OBJECT_NEW(objectDataArea->object_name, "exception", NULL);
/* Set the object objectData area */
OBJECT_SETDATA((char *)objectDataArea);
return(0);
}
DEFINE_METHOD(clsMyClass, Destructor)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
if (objectData != NULL) {
if (objectData->prop_objvalue != NULL)
OBJECT_DELETE(objectData->prop_objvalue);
free(objectData);
objectData = NULL;
}
return(0);
}
DEFINE_METHOD(clsMyClass, Define)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
struct API_EXPRESSION result;
char buffer[512];
int rc;
/* Check the object class */
OBJECT_GETPROPERTY(objectData->prop_objvalue, "class", buffer);
rc = OBJECT_GETARG(buffer, &result);
if (result.errno == 0 && result.type == 'C'
&& strcmp(result.character, "Exception") == 0) {
switch (OBJECT_GETARGC()) {
case 1:
rc = OBJECT_GETPARAMETER(1, &result);
if (result.errno == 0 && result.type == 'C') {
OBJECT_SETARG(buffer, &result);
rc = OBJECT_SETPROPERTY(objectData->prop_objvalue,
"message", buffer);
}
break;
case 2:
rc = OBJECT_GETPARAMETER(2, &result);
if (result.errno == 0 && result.type == 'N') {
OBJECT_SETARG(buffer, &result);
rc = OBJECT_SETPROPERTY(objectData->prop_objvalue,
"errorno", buffer);
}
}
}
result.type = 'L';
result.logical = (rc == 0 ? 'T' : 'F');
OBJECT_RETRESULT(&result);
}
////////////////////////////////////////////////////////////////////////////////
// Define GET property handlers
////////////////////////////////////////////////////////////////////////////////
DEFINE_PROPERTYGET(clsMyClass, NumValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
if (objectData == NULL) return(-1);
OBJECT_RETPROPERTY('N', objectData->prop_numvalue);
}
DEFINE_PROPERTYGET(clsMyClass, LogValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
if (objectData == NULL) return(-1);
OBJECT_RETPROPERTY('L', objectData->prop_logvalue);
}
DEFINE_PROPERTYGET(clsMyClass, DateValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
if (objectData == NULL) return(-1);
OBJECT_RETPROPERTY('D', objectData->prop_datevalue);
}
DEFINE_PROPERTYGET(clsMyClass, TimeValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
if (objectData == NULL) return(-1);
OBJECT_RETPROPERTY('T', objectData->prop_timevalue);
}
DEFINE_PROPERTYGET(clsMyClass, CurrValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
if (objectData == NULL) return(-1);
OBJECT_RETPROPERTY('Y', objectData->prop_currvalue);
}
DEFINE_PROPERTYGET(clsMyClass, CharValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
if (objectData == NULL) return(-1);
OBJECT_RETPROPERTY('C', objectData->prop_charvalue);
}
DEFINE_PROPERTYGET(clsMyClass, ObjValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
if (objectData == NULL) return(-1);
OBJECT_RETPROPERTY('O', objectData->prop_objvalue);
}
////////////////////////////////////////////////////////////////////////////////
// Define SET property handlers
////////////////////////////////////////////////////////////////////////////////
DEFINE_PROPERTYSET(clsMyClass, NumValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
struct API_EXPRESSION result;
int rc = OBJECT_ERROR;
OBJECT_GETVALUE(&result);
if (result.errno == 0 && result.type == 'N') {
objectData->prop_numvalue = result.number;
rc = OBJECT_SUCCESS;
}
return(rc);
}
DEFINE_PROPERTYSET(clsMyClass, LogValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
struct API_EXPRESSION result;
int rc = OBJECT_ERROR;
OBJECT_GETVALUE(&result);
if (result.errno == 0 && result.type == 'L') {
objectData->prop_logvalue = result.logical;
rc = OBJECT_SUCCESS;
}
return(rc);
}
DEFINE_PROPERTYSET(clsMyClass, DateValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
struct API_EXPRESSION result;
int rc = OBJECT_ERROR;
OBJECT_GETVALUE(&result);
if (result.errno == 0 && result.type == 'D') {
strcpy(objectData->prop_datevalue, DATE_DTOS(result.date));
rc = OBJECT_SUCCESS;
}
return(rc);
}
DEFINE_PROPERTYSET(clsMyClass, TimeValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
struct API_EXPRESSION result;
int rc = OBJECT_ERROR;
OBJECT_GETVALUE(&result);
if (result.errno == 0 && result.type == 'T') {
strcpy(objectData->prop_timevalue, DATE_TTOS(result.datetime));
rc = OBJECT_SUCCESS;
}
return(rc);
}
DEFINE_PROPERTYSET(clsMyClass, CurrValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
struct API_EXPRESSION result;
int rc = OBJECT_ERROR;
OBJECT_GETVALUE(&result);
if (result.errno == 0 && result.type == 'Y') {
strcpy(objectData->prop_currvalue, CURR_YTOS(result.currency));
rc = OBJECT_SUCCESS;
}
return(rc);
}
DEFINE_PROPERTYSET(clsMyClass, CharValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
struct API_EXPRESSION result;
int rc = OBJECT_ERROR;
OBJECT_GETVALUE(&result);
if (result.errno == 0 && result.type == 'C') {
strcpy(objectData->prop_currvalue, result.character);
rc = OBJECT_SUCCESS;
}
return(rc);
}
DEFINE_PROPERTYSET(clsMyClass, ObjValue)
{
struct example_data *objectData = (struct example_data *)OBJECT_GETDATA();
OBJECT objvalue;
int rc = OBJECT_ERROR;
if (OBJECT_GETTYPE() == 'O') {
objvalue = OBJECT_GETOBJECT();
objectData->prop_objvalue = OBJECT_ASSIGN(objvalue, objectData->object_name);
rc = OBJECT_SUCCESS;
}
return(rc);
} In this article Barry Mavin, CEO and Chief Software Architect for Recital provides details on how the Recital Database Server can be used to provide a solution for Universal Data Integration.
Overview
The Recital Database Server handles universal cross-platform data access to a wide range of data sources. The database server natively handles full remote SQL data access to Recital, Visual FoxPro, FoxPro, FoxBASE, Clipper and older dBase data. Using Bridges, it handles full remote SQL data access to C-ISAM and OpenVMS RMS. Using gateway connections, it handles full remote SQL data access to Oracle, MySQL, PostgreSQL, SQL Server, server-side ODBC, server-side JDBC and server-side OLE DB data sources. With its ability to access data using server-side ODBC, JDBC and OLE DB drivers from clients on all supported operating systems (Windows, Linux, Unix, OpenVMS), the Recital Database Server is an ideal Data Integration Solution for applications of all sizes and complexity.
Universal Data Integration Solutions
There are several ways in which data may be accessed by the Database Server.
Table 1:
Client Universal Data Access solutions for accessing local or remote data.
| Client | Solution |
|---|---|
| Recital | Use remote gateway connections |
| Visual FoxPro | Use the Universal ODBC Driver |
| Java (all platforms) | Use the Universal JDBC Driver |
| .NET Framework | Use the Universal .NET Data Provider |
| Microsoft Office | Use the Universal ODBC Driver |
| Windows Mobile | Use the Universal Compact Framework .NET Data Provider |
| PHP on Linux | Use the Universal ODBC Driver for Linux |
| Mono on Linux | Use the Universal .NET Data Provider |
| Others | If the data source you want to access is not in the list above, then you can use a remote ODBC, JDBC or OLE DB gateway. You can find examples of connection strings for most ODBC and OLE DB data sources by clicking here. |
Table 2:
Windows Server Universal Data Access solutions accessible from any remote client running on Windows, Linux, Unix or OpenVMS:
| Data Source | Solution |
|---|---|
| Recital | Native support (See table 1) |
| Visual FoxPro | Native support (See table 1) |
| FoxPro | Native support (See table 1) |
| FoxBASE | Native support (See table 1) |
| Clipper | Native support (See table 1) |
| dBase | Native support (See table 1) |
| C-ISAM | Use a bridge (See table 1) |
| Access | Use a gateway connection gateway="oledb:Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb;User Id=admin;Password=;" |
| Exchange | Use a gateway connection gateway="oledb:Provider=ExOLEDB.DataSource;Data Source=http://servername/publicstore" |
| Excel | Use a gateway connection gateway="oledb:Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyExcel.xls;" |
| Oracle | Use a gateway connection gateway="oledb:Provider=msdaora;Data Source=TheOracleDB;User Id=xxxxx;Password=xxxxx;" |
| SQL Server | Use a gateway connection gateway="oledb:Provider=sqloledb;Data Source=Aron1;Initial Catalog=pubs;User Id=sa;Password=asdasd;" |
| MySQL | Use a gateway connection gateway="oledb:Provider=MySQLProv;Data Source=mydb;User Id=xxxxx;Password=xxxxx;" |
| IBM DB2 | Use a gateway connection gateway="oledb:Provider=DB2OLEDB;Network Transport Library=TCPIP;Network Address=XXX.XXX.XXX.XXX;Initial Catalog=MyCtlg;Package Collection=MyPkgCol;Default Schema=Schema;User ID=MyUser;Password=MyPW" |
| Sybase ASA | Use a gateway connection gateway="oledb:Provider=ASAProv;Data source=myASA" |
| Sybase ASE | Use a gateway connection gateway="oledb:Provider=Sybase.ASEOLEDBProvider;Srvr=myASEserver,5000;Catalog=myDBname;User Id=username;Password=password" |
| IBM Informix | Use a gateway connection gateway="oledb:Provider=Ifxoledbc.2;password=myPw;User ID=myUser;Data Source=dbName@serverName;Persist Security Info=true" |
| Ingres | Use a gateway connection gateway="odbc:dsn=data_source_name" |
| Firebird | Use a gateway connection gateway="odbc:dsn=data_source_name" |
| IBM AS400 iSeries | Use a gateway connection gateway="oledb:PROVIDER=IBMDA400; DATA SOURCE=MY_SYSTEM_NAME;USER ID=myUserName;PASSWORD=myPwd" |
| Interbase | Use a gateway connection gateway="oledb:provider=sibprovider;location=localhost:;data source=c:\databases\gdbs\mygdb.gdb;user id=xxxxx;password=xxxxx" |
| Others |
If the data source you want to access is not in the list above, then you can use server-side ODBC, JDBC or OLE DB. |
Table 3:
Linux and Unix Server Universal Data Access solutions accessible from any remote client running on Windows, Linux, Unix or OpenVMS:
| Data Source | Solution |
|---|---|
| Recital | Native support (See table 1) |
| Visual FoxPro | Native support (See table 1) |
| FoxPro | Native support (See table 1) |
| FoxBASE | Native support (See table 1) |
| Clipper | Native support (See table 1) |
| dBase | Native support (See table 1) |
| C-ISAM | Use a bridge (See table 1) |
| Oracle | Use a gateway connection gateway="oracle:Connection_String" |
| MySQL | Use a gateway connection gateway="mysql:Connection_String" |
| IBM DB2 | Use a gateway connection gateway="db2:Connection_String" |
| PostgreSQL | Use a gateway connection gateway="postgres:Connection_String" |
| Others |
If the data source you want to access is not in the list above, then you can use a server-side JDBC driver. |
Table 4:
OpenVMS Server Universal Data Access solutions accessible from any remote client running on Windows, Linux, Unix or OpenVMS:
| Data Source | Solution |
|---|---|
| Recital | Native support (See table 1) |
| Visual FoxPro | Native support (See table 1) |
| FoxPro | Native support (See table 1) |
| FoxBASE | Native support (See table 1) |
| Clipper | Native support (See table 1) |
| dBase | Native support (See table 1) |
| RMS | Use a bridge (See table 1) |
| Others |
If the data source you want to access is not in the list above, then you can use a server-side JDBC driver. |
Supported Data Sources
Native Data Access
The Recital Database Server has native built-in support for the following data sources:
- Recital
- Visual FoxPro
- FoxPro
- FoxBASE
- Clipper
- dBase
You can setup tables to work with using the Database Administration Tool in Recital Enterprise Studio.
Bridges
Using Bridges, you can access the following data sources as if they were standard Recital/FoxPro tables:
- CISAM
- OpenVMS RMS
You can setup bridges using the Database Administration Tool in Recital Enterprise Studio.
Gateways/Connections
Using Gateways, you can transparently access the following local or remote data sources:
- Recital
- Oracle
- ODBC (Server-side ODBC data sources)
- JDBC (Server-side JDBC data sources)
- OLEDB Use this to connect to SQL Server and other Windows OLE DB data sources)
- MySQL
- PostgreSQL
Remote Data Object functions
Recital 10 includes a complete and robust set of data source independent functions for accession MySQL, Oracle, DB2 and Postgres. This article explains how to use them.
Client Data Access drivers
Included with the Recital Database Server are three Client drivers. These Client drivers can access any data sources supported by the Recital Database Server. They are not restricted to accessing only Recital data. They can be used to access server-side ODBC, JDBC and OLE DB data sources also.
Recital Universal .NET Data Provider
Use this client driver when building .NET applications with Visual Studio .NET. A data provider in the .NET Framework serves as a bridge between an application and a data source. A data provider is used to retrieve data from a data source and to reconcile changes to that data back to the data source.
Key features of the Recital Universal .NET Data Provider:
- Fully Internet enabled
The Recital Universal .NET Data Provider works across the internet providing access to a wide range of data sources located on remote servers running Windows, Linux, Unix and OpenVMS. - SQL Server compatible
The Recital Universal .NET Data Provider is plug compatible with the .NET Framework SQL Server Data Provider. - Cross-platform Data Integration
Using the Recital Universal .NET Data Provider, you can connect to remote Windows, Linux, Unix or OpenVMS servers and access any data source supported by the Recital Database Server. - Managed code
The Recital Universal .NET Data Adaptor written in C# is 100% .NET Framework managed code. - Runs on Windows Mobile
The Recital Universal .NET Data Adaptor runs under the .NET Compact Framework on Windows Mobile.
Recital Universal JDBC Driver
The JDBC API is the industry standard for database-independent connectivity between the Java programming language and a wide range of databases. The JDBC API provides a call-level API for SQL-based database access. JDBC technology allows you to use the Java programming language to exploit "Write Once, Run Anywhere" capabilities for applications that require access to enterprise data.
Key features of the Recital Universal JDBC Driver:
- Fully Internet enabled
The Recital Universal JDBC driver works across the internet providing access to a wide range of data sources located on remote servers running Windows, Linux, Unix and OpenVMS. - JDBC 3.0 API
The Recital Universal JDBC driver supports the JDBC 3.0 API. - Pure Java Type 3 Driver
The Recital Universal JDBC driver is a 100% pure Java Type 3 driver. - Full Access to Metadata
The JDBC API provides metadata access that enables the development of sophisticated applications that need to understand the underlying facilities and capabilities of a specific database connection. - Cross-platform Data Integration
Using the Recital Universal JDBC driver, you can connect to remote Windows, Linux, Unix or OpenVMS servers and access any data source supported by the Recital Database Server. - No Installation
A pure JDBC technology-based driver does not require special installation; it is automatically downloaded as part of the applet that makes the JDBC calls. The Recital Universal JDBC Driver is 100% java.
Recital Universal ODBC Driver
Connect to remote data from Microsoft Office or other applications that support ODBC data access. The Recital Universal ODBC Driver is also available for Linux and Unix.
Key features of the Recital Universal ODBC Driver:
- Fully Internet enabled
The Recital Universal ODBC driver works across the internet providing access to a wide range of data sources located on remote servers running Windows, Linux, Unix and OpenVMS. - Works with Crystal Reports
The Recital Universal ODBC driver supports the SQL syntax generated by Crystal Reports. - Works with Microsoft Office
The Recital Universal ODBC driver works with Microsoft Office products. - Works with PHP on Linux
The Recital Universal ODBC driver is available for Linux and works with PHP.
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 64bit port of Recital requires these libraries to allow access to 32bit Xbase and C-ISAM data files which are 32bit.
If you do not have these libraries installed you will either get a "can't find db.exe" or an "error loading shared libraries" when trying to run or license Recital.
Installing the ia32 shared libraries
Redhat EL 5 / Centos 5 / Fedora 10
-
Insert the Red Hat Enterprise Linux 5 Supplementary CD, which contains the ia32el package.
-
After the system has mounted the CD, change to the directory containing the Supplementary packages. For example:
cd /media/cdrom/Supplementary/
-
Install the ia32el package:
rpm -Uvh ia32el-<version>.ia64.rpm
yum install ia32el
Ubuntu / Debian
sudo apt-get install ia32-libs
$ lsof | grep db.exe | grep accounts db.exe 16897 john 6uw REG 253,0 20012 3413872 /usr/recital100/qa/accounts.dbf db.exe 16897 john 7u REG 253,0 4176 3413885 /usr/recital100/qa/accounts.dbxIf you want to check for locks you can use lslk, for example;
$ lslk | grep db.exe | grep accounts db.exe 16897 253,0 3413872 20012 w 0 0 0 12319 0 /usr/recital100/qa/accounts.dbfIf you don't have lslk installed you can install it with one of the updaters, for example on redhat linux:
$ yum update lslk