summaryrefslogtreecommitdiff
path: root/html/xbc5.htm
diff options
context:
space:
mode:
Diffstat (limited to 'html/xbc5.htm')
-rwxr-xr-xhtml/xbc5.htm156
1 files changed, 156 insertions, 0 deletions
diff --git a/html/xbc5.htm b/html/xbc5.htm
new file mode 100755
index 0000000..377129f
--- /dev/null
+++ b/html/xbc5.htm
@@ -0,0 +1,156 @@
+<!DOCTYPE HTML PUBLIC>
+<html>
+<title>Xbase DBMS Chapter 5</title>
+<body bgcolor=#FFFFFF>
+<h1><p align="center">Expression Handling<br></h1>
+<p align="center">Chapter Updated 3/12/04</p><hr>
+
+<h3>Overview</h3>
+
+The main objective of this chapter is to provide information regarding the
+basic concepts of using the Xbase Expression module.<br><br>
+
+Beginning with release 1.7.4, the Xbase library includes an expression parsing
+routine which assists application programmers by providing a high level data
+manipulation tool and also allows for building complex index keys.
+
+The functions included were derived from dBASE III Plus, but not all
+dBASE III Plus functions have been implemented yet.
+<br><br>
+Release 3.0 brought some upgrades to the expression module of the library
+including bug fixes, additional operators and new functions. The expression
+module is usable and functional, but has some room for improvement.
+A future release of Xbase will include more comprehensive expresion logic.
+
+<br><br>
+
+<h3>Internal fuctioning</h3>
+The expression module works in two phases. Firstly, method
+<em>ParseExpression</em> is called and builds an expression tree from
+all the components of the expression. The tree is made up of indivdual
+nodes. The expression is checked for valid field names, literals,
+operands and functions. Any field references are resolved. If fields
+are used in an expression and the database name for the field is not
+included in the name with the -> operand, the routines assume the
+associated database has been successfully opened.
+<br><br>
+Secondly, method <em>ProcessExpression</em> is called to process the
+expression tree created by ParseExpression(). The routine parses each
+node in the expression tree, executing functions, processing operands
+and manipulating data to produce the desired result.<br><br>
+
+If an expression will be processed repeatedely, it is best to pre-parse the
+tree using <em>ParseExpression</em>, then for each new call to the expression,
+execute method <em>ProcessExpression</em> which processes the tree.
+
+
+<h3>Expression Return Types</h3>
+Expressions will return a type of CHAR *, NUMERIC or LOGICAL.<br><br>
+
+An expression return type can be determined with method <em>
+GetExpressionResultType</em> after parsing it.<br><br>
+
+Expressions returning a return type of CHAR are limited to a 200 byte internal
+buffer. There is also a 100 byte limit for NDX index key support. If
+the 200 byte limit is not large enough for your application, adjust field
+<em>enum { WorkBufMaxLen = 200 };</em> in file <em>exp.h</em>.
+
+<h3>Expression Functions</h3>
+Each expression function also has a corresponding C++ function. It is
+slightly more efficient to call the C++ functions directly, rather than
+execute the expression parsing routines.
+
+<h3>Expression Components</h3>
+Expressions are made up of one or more tokens. A token is one of literal,
+database field, operand or function. Literals are either numeric or character.
+Character literals are enclosed in 'single' or "double" quotes. numeric
+literals are a series of one or more contiguous numerals, ".", "+" or "-'".
+<br><br>
+A field is simply a field name in the default database, or is in the form
+of database->fieldname.
+
+<br><br>
+<hr>
+<h3>Sample Program Demonstrating Expression Processing</h3>
+<xmp>
+
+/* expressn.cpp */
+
+#ifdef DOS
+extern unsigned _stklen = 40000;
+#endif
+
+#include <xbase/xbase.h>
+xbSchema MyRecord[] =
+{
+ { "FIELD1", 'C', 20, 0 },
+ { "FIELD2", 'C', 20, 0 },
+ { "NAME", 'C', 10, 0 },
+ { "DOUB1", 'N', 7, 2 },
+ { "FLOAT1", 'F', 8, 3 },
+ { "DATE1", 'D', 8, 0 },
+};
+xbShort rc;
+xbXBase x;
+xbDbf d( &x );
+XB_EXPRESSION *e;
+
+/****************************************************************************/
+xbShort MyExpressionProcessor( char * Expression )
+{
+ xbShort rc;
+ char type;
+
+ if(( rc = x.ParseExpression( Expression, &d )) != 0 )
+ {
+ cout << "\nParse Error " << rc;
+ return rc;
+ }
+ e = x.GetExpressionHandle();
+
+ if(( rc = x.ProcessExpression( e )) != 0 )
+ {
+ cout << "\nError processing expression rc = " << rc;
+ return rc;
+ }
+ type = x.GetExpressionResultType( e );
+ cout << "\nExpression " << Expression << " produced result = ";
+ if( type == 'C' )
+ cout << x.GetStringResult();
+ else if( type == 'N' )
+ cout << x.GetDoubleResult();
+ else if( type == 'L' )
+ cout << x.GetIntResult();
+ else
+ cout << "\nUnknown result type " << type;
+ return 0;
+}
+/****************************************************************************/
+main()
+{
+ e = NULL;
+
+ d.CreateDatabase( "TEST", MyRecord, OVERLAY );
+ d.BlankRecord();
+ d.PutField( d.GetFieldNo( "FIELD1" ), "TESTA " );
+ d.PutField( d.GetFieldNo( "FIELD2" ), " testb" );
+ d.PutField( d.GetFieldNo( "DOUB1" ), "200.33" );
+ d.PutField( d.GetFieldNo( "FLOAT1" ), "100.00" );
+ d.PutField( d.GetFieldNo( "DATE1" ), "19980101" );
+ d.AppendRecord();
+
+ /* process 3 simple expressions */
+ MyExpressionProcessor( "FIELD1+FIELD2" );
+ MyExpressionProcessor( "FIELD1-UPPER(FIELD2)" );
+ MyExpressionProcessor( "5+TEST->DOUB1" );
+
+ d.CloseDatabase();
+ return 1;
+}
+
+</xmp>
+
+<hr>
+<p><img src="xbase.jpg"><br><hr>
+</BODY>
+</HTML>