Use the conditional expression parser/analyzer to evaluate application-specific expressions. The FairCom DB expression parser is a full standalone feature in and of itself, and can be used directly in your own applications for purposes other than data filters, conditional indexes, or partitioned files. Two core API functions provide a powerful interface into this advanced expression handling.
FairCom DB’s expression parser/analyzer requires two key steps:
For a complete sample program, see ctexpr.c in the ctree/source directory.
See also:
Parsing your expression involves three steps:
Sample code to perform these steps is shown below. This code assumes FairCom DB has been initialized prior to calling ctparsedoda().
Expression Parsing Example
#include "ctcndx.h" /* For PTREE type */
/* Define a DODA structure. */
DATOBJ doda[] = {
{"CustomerNumber", 0, CT_INT4U},
{"ZipCode", 4, CT_FSTRING, 9},
{"State", 13, CT_FSTRING, 2},
{"LastName", 15, CT_STRING, 37},
{"FirstName", 52, CT_STRING, 37},
{"Address", 89, CT_STRING, 49},
{"City", 138, CT_STRING, 37}
};
COUNT retval; /* Return code. */
pTEXT schema; /* Record schema. */
pTEXT names; /* Field name list. */
PTREE ptree; /* Expression tree. */
pTEXT expr; /* Expression string. */
/* Parse the DODA into a record schema and field name list. */
if ((retval = ctparsedoda(doda, 7, &schema, &names)) != 0)
printf("Error %d parsing DODA.\n", retval);
/* Parse your expression to produce an expression tree. */
expr = "stricmp(LastName, \"Smith\") == 0
&& CustomerNumber > 10000";
ptree = cndxparse(schema, names, expr, strlen(expr));
if (!ptree)
printf("Error: Unable to parse expression.\n");
else
printf("Successfully parsed expression.\n");
To invoke the expression parser to parse a string expression and produce an expression tree, call cndxparse(), which is declared as follows:
PTREE cndxparse(pConvMap Schema, pTEXT Names, pTEXT InputText,
NINT InputTextSize)
Schema is a pointer to a record schema derived from a DODA definition. Names is a pointer to a list of the field names from the DODA. InputText points to a NULL-terminated string expression, and InputTextSize is the length of InputText.
One of the most useful features of the expression parser is its ability to associate symbolic names in expressions with data in a buffer in memory. To use this ability, you must define a record schema, known as a DODA (Data Object Definition Array). A DODA is an array of field specifications, each of which contains a field name, field offset, field type, and a field length. By providing the expression parser with a DODA, you may include references to DODA field names in your expressions. See the sample code shown later in this section for an example of a DODA definition.
While a DODA is conveniently defined in your application using an array of DATOBJ structures, cndxparse() does not take a DODA in DATOBJ form, but instead accepts a record schema and a list of the field names from the DODA. In order to simplify converting your DODA into the required record schema and field name list, FairCom has written a utility function, ctparsedoda(). This function can be found in the sample file ctexpr.c.
ctparsedoda() is declared as follows:
COUNT ctparsedoda(pDATOBJ doda, UCOUNT numfld, ppTEXT ppschema,
ppTEXT ppnames)
Having produced an expression tree, you are ready to evaluate the expression using the expression analyzer. To evaluate your expression, call cndxeval(), which is declared as follows:
COUNT cndxeval(PTREE Tree, pVOID Recptr, pConvMap Schema)
Note: Before you call cndxeval() the first time, you must ensure that a run-time stack has been allocated for the expression analyzer.
To summarize, evaluating your expression involves three steps:
If you wish, you can repeat steps 2) and 3) multiple times. Sample code to perform these steps is shown below. It is assumed the Get_Buffer() routine allocates a record buffer and initializes it with data conforming to the field definitions specified in the DODA.
Expression Evaluation Example
COUNT retcidx; /* Result of expression evaluation. */
pTEXT recbuf; /* Record buffer. */
/* Allocate a run-time stack for the expression analyzer (first time only). */
if (!ctcidxStk) {
ctcidxStk = (pVOID) getcndxmem(CNDX_MAX_STACK * ctSIZE(PLEAF));
if (!ctcidxStk) {
printf("Unable to allocate memory for run-time stack.\n");
ctrt_exit(1);
}
}
/* Set up a buffer containing the field data used in the expression. */
Get_Buffer(&recbuf);
/* Evaluate the expression. */
retcidx = cndxeval(ptree, recbuf, (pConvMap)schema);
if (retcidx<0)
printf("The expression cannot be evaluated for this record
- error %d.\n", uerr_cod);
else if (retcidx)
printf("The expression evaluates to TRUE for this record.\n");
else
printf("The expression evaluates to FALSE for this record.\n");
Remember to always free any memory used by your record schema, field name list, and expression tree when you are finished with them. Use the following FairCom DB functions to do so: