try open database southwind catch die("Cannot open database, please try later.") endtry
On exit of an .rsp page.
SAVE DATASESSION TO m_state
_SESSION["state"] = m_state
On entry to an .rsp page.
IF type( _session["state"] ) != "U"
m_state = _session["state"]
RESTORE DATASESSION FROM m_state
ENDIF
[data] oplocks = False level2 oplocks = False
veto oplock files = /*.dbf/*.DBF/*.ndx/*.NDX/*.dbx/*.DBX/*.dbt/*.DBT/
You can further tune samba by following this guide.
mount -t cifs {mount-point} -o username=name,pass=pass,directioThe directio option is used to not do inode data caching on files opened on this mount. This precludes mmaping files on this mount. In some cases with fast networks and little or no caching benefits on the client (e.g. when the application is doing large sequential reads bigger than page size without rereading the same data) this can provide better performance than the default behavior which caches reads (readahead) and writes (writebehind) through the local Linux client pagecache if oplock (caching token) is granted and held. Note that direct allows write operations larger than page size to be sent to the server.
Apr 22 16:57:39 bailey kernel: Status code returned 0xc000006d NT_STATUS_LOGON_FAILURE Apr 22 16:57:39 bailey kernel: CIFS VFS: Send error in SessSetup = -13 Apr 22 16:57:39 bailey kernel: CIFS VFS: cifs_mount failed w/return code = -13The you need to create the Samba user specified on the mount command
smbpasswd -a usernameFYI - Make sure you umount all the Samba {mount-point(s)} before shutting down Samba.
MQCURMSGS()
Syntax
MQCURMSGS( <expN> )Description
The MQCURMSGS() function returns the current number of unread messages in the queue specified by <expN>Example
mqdes=mqopen("/myqueue") if (mqdes < 0) messagebox(strerror()+",errno="+alltrim(str(error()))) return endif do while (mqcurmsgs(mqdes) > 0) mstr=mqreceive(mqdes) if (empty(mstr)) messagebox(strerror()+",errno="+alltrim(str(error()))) return endif messagebox(mstr) end do mqclose(mqdes)
Recital is a dynamic programming language with an integrated high performance database particularly well suited for the development and deployment of high transaction throughput applications. Recital 10 further enhances Recital with extensive features and functionality to facilitate its use in fault tolerant high availability systems. Much of the development of Recital 10 was concentrated on performance optimizations and cluster aware functionality to provide an application platform that can be scaled as needed without any application changes.
Key features of Recital 10 include:
- Cluster aware database engine that works transparently with drbd, heartbeat, glusterfs and samba
- High degree of fault tolerance with self healing indexes
- Massive performance improvements
- Extensive internals overall and modernization with superior object-oriented capabilities
- Chronological data versioning with database timelines
- SmartQuery caching
- Database Administration Tools
- Code and Data Profiling
- Better integration with unix/linux command shell
- Incorporates a range of new built-in functions compatible with those in the PHP core libraries
- Built-in support for outputting data in HTML, XML, and JSON format
- Seamless SQL command integration into the Recital scripting language
- Much improved Microsoft FoxPRO language compatibility
- Numerous extensions and improvements (see below for details)
- Very large file support (2^63)
Opening SSH to the outside world is a security risk. Here is how to restrict SSH access to certain IP addresses on a machine.
- Edit the /etc/hosts.allow file to include these lines, assuming your machine is on the 192.168.2.x nonrouting IP block, and you want to enable an external address of 217.40.111.121 IP block: Remember to add the period on the end of each incomplete IP number. If you have another complete IP address or range, add a space and that range on the end.
sshd,sshdfwd-X11: 192.168.2. 217.40.111.121
- Edit your /etc/hosts.deny file to include this line:
sshd,sshdfwd-X11:ALL
- These lines refuse SSH connections from anyone not in the IP address blocks listed.
Additionally you can restrict SSH access by username.
- Edit the /etc/ssh/sshd_config file and add the following lines
PermitRootLogin no
AllowUsers user1 user2 user3 etc
PasswordAuthentication yes
Now restart the ssh daemon for these changes to take effect
service sshd restart
http://www.the-art-of-web.com/css/border-radius/
APPEND FROM <table-name>Before when appending into a shared Recital table each new row was locked along with the table header, then unlocked after it was inserted. This operation has now been enhanced to lock the table once, complete inserting all the rows from the table and then unlock the table. The performance of this operation has been increased by using this method. All the database and table constraints are still enforced.
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, details on how to use the Client Drivers provided with the Recital Database Server to work with local or remote server-side JDBC 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 equals 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.
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 JDBC data source, you ue the gateway=value key/value pair in the following way.
gateway=jdbc:jdbc_driver_path_on_server;jdbc:Recital:args
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 // Recital Southwind database. It then populates a DataTable // in a DataSet with the list of customers via the JDBC driver. // 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 = "jdbc:/usr/java/lib/RecitalJDBC/Recital/sql/RecitalDriver;"+ "jdbc:Recital:Data Source=localhost;database=southwind"; 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 Recital Southwind database. // It then retrieves all the customers via the JDBC driver. public void SelectCustomers() { // setup the Connection URL for JDBC String gateway = "jdbc:/usr/java/lib/RecitalJDBC/Recital/sql/RecitalDriver;"+ "jdbc:Recital:Data Source=localhost;database=southwind"; 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(); }