auth sufficient pam_krb5.so try_first_pass
auth sufficient pam_unix.so shadow nullok try_first_pass
account required pam_unix.so broken_shadow
account [default=bad success=ok user_unknown=ignore] pam_krb5.so
In this article Barry Mavin, CEO and Chief Software Architect for Recital, details Working with Stored Procedures in the Recital Database Server.
Overview
Stored procedures and user-defined functions are collections of SQL statements and optional control-of-flow statements written in the Recital 4GL (compatible with VFP) stored under a name and saved in a Database. Both stored procedures and user-defined functions are just-in-time compiled by the Recital database engine. Using the Database Administrator in Recital Enterprise Studio, you can easily create, view, modify, and test Stored Procedures, Triggers, and user-defined functions
Creating and Editing Stored Procedures
To create a new Stored Procedure, right-click the Procedures node in the Databases tree of the Project Explorer and choose Create. To modify an existing stored procedure select the Stored Procedure in the Databases Tree in the Project Explorer by double-clicking on it or selecting Modify from the context menu . By convertion we recommend that you name your Stored Procedures beginning with "sp_xxx_", user-defined functions with "f_xxx_", and Triggers with "dt_xxx_", where xxx is the name of the table that they are associated with.
Testing the Procedure
To test run the Stored Procedure, select the Stored Procedure in the Databases Tree in the Project Explorer by double-clicking on it. Once the Database Administrator is displayed, click the Run button to run the procedure.
Getting return values
Example Stored Procedure called "sp_myproc":
parameter arg1, arg2 return arg1 + arg2
Example calling the Stored Procedure from C# .NET:
//////////////////////////////////////////////////////////////////////// // include the references below using System.Data; using Recital.Data; //////////////////////////////////////////////////////////////////////// // sample code to call a Stored Procedure that adds to numeric values together public int CallStoredProcedure() { RecitalConnection conn = new RecitalConnection("Data Source=localhost;Database=southwind;uid=?;pwd=?"); RecitalCommand cmd = new RecitalCommand(); cmd.Connection = conn; cmd.CommandText = "sp_myproc(@arg1, @arg2)"; cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters["@arg1"].Value = 10; cmd.Parameters["@arg2"].Value = 20; conn.Open(); cmd.ExecuteNonQuery(); int result = (int)(cmd.Parameters["retvalue"].Value); // get the return value from the sp conn.Close(); return result; }
Writing Stored Procedures that return a Resultset
If you want to write a Stored Procedure that returns a ResultSet, you use the SETRESULTSET() function of the 4GL. Using the Universal .NET Data Provider, you can then execute the 4GL Stored Procedure and return the ResultSet to the client application for processing. ResultSets that are returned from Stored Procedures are read-only.
Example Stored Procedure called "sp_myproc":
parameter query select * from customers &query into cursor "mydata" return setresultset("mydata")
Example calling the Stored Procedure from C# .NET:
//////////////////////////////////////////////////////////////////////// // include the references below using System.Data; using Recital.Data; //////////////////////////////////////////////////////////////////////// // sample code to call a stored procedure that returns a ResultSet public void CallStoredProcedure() { RecitalConnection conn = new RecitalConnection("Data Source=localhost;Database=southwind;uid=?;pwd=?"); RecitalCommand cmd = new RecitalCommand(); cmd.Connection = conn; cmd.CommandText = "sp_myproc(@query)"; cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters["@query"].Value = "where not deleted()"; conn.Open(); RecitalDataReader dreader = cmd.ExecuteReader(); int sqlcnt = (int)(cmd.Parameters["sqlcnt"].Value); // returns number of affected rows while (dreader.Read()) { // read and process the data } dreader.Close(); conn.Close(); }
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)
STRERROR()
Syntax
STRERROR( [ <expN> ] )Description
The STRERROR() function returns a string describing the last operating system error message. If the optional error number is specified then the related operating system error message will be returned.Example
mqdes=mqcreate("/myqueue", 2) if (mqdes < 0) messagebox(strerror()+",errno="+alltrim(str(error()))) return endif rc = mqsend(mqdes, "Test message") if (rc < 0) messagebox(strerror()+",errno="+alltrim(str(error()))) return endif mqclose(mqdes)
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)
This is a good primer for getting familiar with using Infiniband with Redhat/Centos Linux.
http://people.redhat.com/dledford/infiniband_get_started.html
Getting Started with InfiniBand
The first step to using a new infiniband based network is to get the right packages installed. These are the infiniband related packages we ship and what they are there for (Note, the Fedora packages have not all been built or pushed to the repos yet, so their mention here is as a "Coming soon" variety, not an already done variety):
Here's how to set up field validation based on dynamic values from another table.
Using the products.dbf table from the southwind sample database, validation can be added to the categoryid field to ensure it matches an existing categoryid from the categories.dbf table.
open database southwindThe rlookup() function checks whether an expression exists in the index (master or specified) of the specified table . An attempt to update categoryid with a value not in the list will give an error: Validation on field 'CATEGORYID' failed.
alter table products add constraint;
(categoryid set check rlookup(products.categoryid,categories))
If you have access to the Recital Workbench, you can use the modify structure worksurface to add and alter your dictionary entries, including a customized error message if required.

Key features of the Recital database include:
- SQL-92 and a broad subset of ANSI SQL 99, as well as extensions
- Cross-platform support
- Stored procedures
- Triggers
- Cursors
- Updatable Views
- System Tables
- Query caching
- High-performance
- Single-User and Multi-User
- Multi-Process
- ACID Transactions
- Referential Integrity
- Cascading Updates and Deletes
- Multi-table Joins
- Row-level Locking
- BLOBs (Binary Large Objects)
- UDFs (User Defined Functions)
- OLTP (On-Line Transaction Processing)
- Drivers for ODBC, JDBC, and .NET
- Sub-SELECTs (i.e. nested SELECTs)
- Embedded database library
- Database timelines providing data undo functionality
- Fault tolerant clustering support
- Hot backup
// determine how many Recital users are on the system nusers = pipetostr("ps -ef | grep db.exe | wc -l")
After split brain has been detected, one node will always have the resource in a StandAlone connection state. The other might either also be in the StandAlone state (if both nodes detected the split brain simultaneously), or in WFConnection (if the peer tore down the connection before the other node had a chance to detect split brain).
At this point, unless you configured DRBD to automatically recover from split brain, you must manually intervene by selecting one node whose modifications will be discarded (this node is referred to as the split brain victim). This intervention is made with the following commands:
# drbdadm secondary resource
# drbdadm disconnect resource
# drbdadm -- --discard-my-data connect resource
On the other node (the split brain survivor), if its connection state is also StandAlone, you would enter:
# drbdadm connect resource
You may omit this step if the node is already in the WFConnection state; it will then reconnect automatically.
If all else fails and the machines are still in a split-brain condition then on the secondary (backup) machine issue:
drbdadm invalidate resource