File: xbase_c5.html

package info (click to toggle)
xdb 1.2.0-5
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 1,676 kB
  • ctags: 1,055
  • sloc: cpp: 14,001; sh: 6,343; makefile: 150
file content (155 lines) | stat: -rw-r--r-- 5,155 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
<!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 2/1/98</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 are derived from dBASE III Plus, but not all 
dBASE III Plus functions have been implemented yet.

<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 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 which was already created.  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 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, you can adjust the
the <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. All functions which return CHAR * 
are returning a pointer to a static buffer which is overlaid by the next
call to any function which also returns CHAR *.

<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.GetCharResult();
   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>
<A HREF="mailto:xbase@startech.keller.tx.us">
Send me mail - xbase@startech.keller.tx.us</A><br>
<p>(c)1997 StarTech
<p><img src="xbase.jpg"><br><hr>
</BODY>
</HTML>