home *** CD-ROM | disk | FTP | other *** search
- {$A+,B-,D+,F-,G+,I+,K+,L+,N+,P+,Q+,R+,S+,T-,V+,W-,X+,Y+}
- {$M 25600,4096}
-
- { Description:
- This unit holds all the filter code. It can be changed
- to work with any table. Expression types can also be changed.
- }
- unit Filter;
-
- interface
-
- uses WinProcs, WinTypes, DbiErrs, DbiTypes, DbiProcs, SysUtils, DB;
-
- const
- szField1: PChar = 'Species No'; { Name of the field for the third
- node of the tree }
-
- type
- tValues = array[1..2] of Double; { structure to pass filter values }
-
- { Exceptions for dbi calls }
- EFilterError = class(EDatabaseError);
- EFilterInvalidHndl = class(EFilterError);
- EFilterLocked = class(EFilterError);
- EFilterTblLockLimit = class(EFilterError);
- EFilterNoSuchFilter = class(EFilterError);
- EFilterNA = class(EFilterError);
-
- var
- hFilter: hDBIFilter; { Filter handle }
-
- function AddFilter(Values: tValues; hTable: hDBICur): DBIResult;
- function RemoveFilter(hTbl: hDbiCur; hFltr: hDBIFilter): DBIResult;
-
- implementation
-
- { METHOD: Chk
- PURPOSE: dbi error handling routine.
- }
- function Chk(rslt: DbiResult): DbiResult;
- var
- FErr: Array [0..dbiMaxMsgLen] of Char;
- FErrStr: String[dbiMaxMsgLen];
- FErrInfo: dbiErrInfo;
-
- begin
- if rslt <> dbiErr_None then
- begin
- { Look on the eror stack to see if there is any detailed information
- about the error that has just occurred }
- DbiGetErrorInfo(False, FErrInfo);
- { If so construct an error string }
- if FErrInfo.iError = rslt then
- begin
- FErrStr := Format('%s ', [FErrInfo.szErrCode]);
- { Add the string only if the string on the stack is not blank }
- if StrComp(FErrInfo.szContext[1], '') = 0 then
- FErrStr := Format('%s %s', [FErrStr, FErrInfo.szContext[1]]);
- if StrComp(FErrInfo.szContext[2], '') = 0 then
- FErrStr := Format('%s %s', [FErrStr, FErrInfo.szContext[2]]);
- if StrComp(FErrInfo.szContext[3], '') = 0 then
- FErrStr := Format('%s %s', [FErrStr, FErrInfo.szContext[3]]);
- if StrComp(FErrInfo.szContext[4], '') = 0 then
- FErrStr := Format('%s %s', [FErrStr, FErrInfo.szContext[4]]);
- end
- else
- begin
- { Get the generic error message if there is no error information
- on the stack }
- DbiGetErrorString(rslt, FErr);
- FErrStr := StrPas(FErr);
- end;
- FErrStr := Format('Filter Error: %d. %s', [rslt, FErrStr]);
- MessageBeep(mb_IconHand);
- { Raise the appropriate exception }
- case rslt of
- dbiErr_InvalidHndl:
- raise EFilterInvalidHndl.Create(FErrStr);
- dbiErr_Locked:
- raise EFilterLocked.Create(FErrStr);
- dbiErr_TblLockLimit:
- raise EFilterTblLockLimit.Create(FErrStr);
- dbiErr_NoSuchFilter:
- raise EFilterNoSuchFilter.Create(FErrStr);
- dbiErr_NA:
- raise EFilterNA.Create(FErrStr);
- else
- { If an unknown error occured, rais a generic exception }
- raise EFilterError.Create(FErrStr);
- end;
- end;
- end;
-
- { METHOD: AddFilter
- PURPOSE: Create and activate the filter on the Biolife.DB table.
- }
- function AddFilter(Values: tValues; hTable: hDBICur): DBIResult;
- var
- pcanExp: pBYTE; { Structure containing filter info }
- uSizeNodes: Word; { Size of the nodes in the tree }
- uSizeCanExpr: Word; { Size of the header information }
- uSizeLiterals: Word; { Size of the literals }
- uTotalSize: Word; { Total size of the filter expression }
- canExp: CANExpr; { Contains the header information }
- Nodes: array[0..29] of word;{ Filter expression }
-
- begin
- { Create the filter expression }
- { Offset 0 }
- Nodes[0] := Word(nodeBINARY); { nodeBINARY = 2 }
- Nodes[1] := Word(canAND); { canGT = 5}
- Nodes[2] := 8; { offset = 8 }
- Nodes[3] := 34; { canBinary.iOperand2
- Offsets in the Nodes array }
- { Offset 8 }
- Nodes[4] := Word(nodeBINARY); { nodeBINARY = 2}
- Nodes[5] := Word(canGE); { canGT = 5}
- Nodes[6] := 16; { offset = 8}
- Nodes[7] := 24; { canBinary.iOperand2
- Offsets in the Nodes array }
- { Offset 16 }
- Nodes[8] := Word(nodeFIELD); { canFIELD = 4}
- Nodes[9] := Word(canFIELD2); { canFIELD2 = 13 }
- Nodes[10]:= 1; { canField.iFieldNum }
- Nodes[11]:= 0; { canField.iNameOffset: szField1 is the
- literal at offset 0 }
- { Offset 24 }
- Nodes[12]:= Word(nodeCONST); { nodeCONST = 5 }
- Nodes[13]:= Word(canCONST2); { canCONST2 = 14 }
- Nodes[14]:= fldFLOAT; { canConst.iType }
- Nodes[15]:= 8; { canConst.iSize }
- Nodes[16]:= length(StrPas(szField1)) + 1;
- { canConst.iOffset: lConst is the
- literal at offset strlen(szField1) + 1 }
- { Offset 34 }
- Nodes[17]:= Word(nodeBINARY);
- Nodes[18]:= Word(canLE);
- Nodes[19]:= 42;
- Nodes[20]:= 50;
-
- { Offset 42 }
- Nodes[21]:= Word(nodeFIELD); { canFIELD = 4}
- Nodes[22]:= Word(canFIELD2); { canFIELD2 = 13 }
- Nodes[23]:= 1; { canField.iFieldNum }
- Nodes[24]:= 0; { canField.iNameOffset: szField1 is the
- literal at offset 0 }
- { Offset 50 }
- Nodes[25]:= Word(nodeCONST); { nodeCONST = 5 }
- Nodes[26]:= Word(canCONST2); { canCONST2 = 14 }
- Nodes[27]:= fldFLOAT; { canConst.iType }
- Nodes[28]:= 8; { canConst.iSize }
-
- Nodes[29]:= (length(StrPas(szField1)) + 1) + sizeof(Values[1]);
- { canConst.iOffset: lConst is the
- literal at offset strlen(szField1) + 1
- + sizeof(lConst1)}
-
- { Determine the values of certain constants Size of the nodes }
- uSizeNodes := sizeof(Nodes);
- { Size of the literals }
- uSizeLiterals := strlen(szField1) + 1 + sizeof(Values[1]) +
- sizeof(Values[2]);
- { Size of the header information }
- uSizeCanExpr := sizeof(CANExpr);
- { Total size of the filter }
- uTotalSize := uSizeCanExpr + uSizeNodes + uSizeLiterals;
- { Initialize the header information }
- canExp.iVer := 1; { Version is 1 }
- canExp.iTotalSize := uTotalSize; { Set the Total Size of the filter }
- canExp.iNodes := 7; { number of nodes }
- canExp.iNodeStart := uSizeCanExpr; { The offset in the buffer
- where the expression nodes start }
- { The offset in the buffer where the literals start }
- canExp.iLiteralStart := uSizeCanExpr + uSizeNodes;
- { Allocate space for the filter expression. }
- GetMem(pcanExp, uTotalSize * sizeof(BYTE));
- if not Assigned(pcanExp) then
- MessageBox(0, 'Could not allocate memory.', 'Windows error', mb_Ok);
-
- { Initialize the filter expression. }
- Move(canExp, pcanExp^, uSizeCanExpr);
- Inc(pcanExp, uSizeCanExpr);
-
- Move(Nodes, pcanExp^, uSizeNodes);
- Inc(pcanExp, uSizeNodes);
-
- Move(szField1^, pcanExp^, strlen(szField1)+1); { first literal }
- Inc(pcanExp, strlen(szField1)+1);
- Move(Values[1], pcanExp^, sizeof(Values[1])); { second literal }
- Inc(pcanExp, sizeof(Values[1]));
- Move(Values[2], pcanExp^, sizeof(Values[2])); { second literal }
-
- Dec(pCanExp, uSizeCanExpr + uSizeNodes + strlen(szField1) + 1 +
- sizeof(Values[1]));
-
- FreeMem(pcanExp, uTotalSize * sizeof(BYTE));
- { Add the filter }
- Chk(DbiAddFilter(hTable, 0, 0, FALSE, pCANExpr(pcanExp),
- nil, hFilter));
- { Activate the filter }
- Chk(DbiActivateFilter(hTable, hFilter));
- end;
-
- { METHOD: RemoveFilter
- PURPOSE: Deactivate and remove the filter on the Biolife.DB table.
- }
- function RemoveFilter(hTbl: hDbiCur; hFltr: hDBIFilter): DBIResult;
- begin
- { Deactivate the filter }
- Chk(DbiDeactivateFilter(hTbl, hFltr));
- { Drop the filter }
- Chk(DbiDropFilter(hTbl, hFltr));
- end;
-
- end.
-