home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1997 May / Pcwk0597.iso / borland / cb / setup / cbuilder / data.z / BTSCLASS.PAS < prev    next >
Pascal/Delphi Source File  |  1997-02-28  |  19KB  |  741 lines

  1. //---------------------------------------------------------------------------
  2. // Borland C++Builder
  3. // Copyright (c) 1987, 1997 Borland International Inc.  All Rights Reserved.
  4. //---------------------------------------------------------------------------
  5. // BtsClass.pas
  6. //
  7. // VCL Class Browser
  8. //---------------------------------------------------------------------------
  9.  
  10. unit BtsClass;
  11.  
  12. interface
  13.  
  14. uses Windows, SysUtils, Classes, MIFiles, DB, DBTables, BtsConst, BDE;
  15.  
  16. const
  17.   fldnoNetName    = 3;  { USER table, Network Name field }
  18.  
  19. type
  20.  
  21. { Exceptions }
  22.  
  23.   EBts = class(Exception);
  24.   ENoRecords = class(EBts);
  25.   ESystemDown = class(EBts);
  26.   EInvalidField = class(EBts)
  27.   public
  28.     Field: TField;
  29.     constructor Create(AField: TField; const Msg: string);
  30.   end;
  31.   EMissingAttach = class(EInvalidField);
  32.  
  33. { Notifications }
  34.  
  35.   EDisplayOutline = class(Exception)
  36.   public
  37.     ItemCode: Double;
  38.     constructor Create(ACode: Double);
  39.   end;
  40.  
  41. { TLookupList }
  42.  
  43.   PStrItem = ^TStrItem;
  44.   TStrItem = record
  45.     FObject: TObject;
  46.     FCode: Integer;
  47.     FDesc: PChar;
  48.     FValue: string;
  49.     FString: string;
  50.   end;
  51.  
  52.   TLookupList = class(TStrings)
  53.   private
  54.     List: TList;
  55.     FCoded: Boolean;
  56.     FUseDesc: Boolean;
  57.     FTableName: string;
  58.   protected
  59.     CodeSep: string;
  60.     DescSep: string;
  61.     function NewStrItem(const S: string): PStrItem;
  62.     procedure DisposeStrItem(P: PStrItem);
  63.     function Get(Index: Integer): string; override;
  64.     function GetCount: Integer; override;
  65.     function GetObject(Index: Integer): TObject; override;
  66.     procedure Put(Index: Integer; const S: string); override;
  67.     procedure PutObject(Index: Integer; AObject: TObject); override;
  68.     function GetValue(Index: Integer): string;
  69.     function GetDesc(Index: Integer): string;
  70.     function GetCode(Index: Integer): Integer;
  71.     function GetItem(Index: Integer): string;
  72.   public
  73.     constructor Create;
  74.     destructor Destroy; override;
  75.     procedure Delete(Index: Integer); override;
  76.     procedure Insert(Index: Integer; const S: string); override;
  77.     procedure Clear; override;
  78.     function IndexOfValue(const S: string): Integer;
  79.     function IndexOfDesc(const S: string): Integer;
  80.     function IndexOfCode(ACode: Integer): Integer;
  81.     function IndexOfItem(const S: string): Integer;
  82.     function CodeToValue(ACode: Integer): string;
  83.     function ValueToCode(const AValue: string): Integer;
  84.     property Value[Index: Integer]: string read GetValue;
  85.     property Desc[Index: Integer]: string read GetDesc;
  86.     property Code[Index: Integer]: Integer read GetCode;
  87.     property Item[Index: Integer]: string read GetItem;
  88.     property UseDesc: Boolean read FUseDesc write FUseDesc;
  89.     property TableName: string read FTableName write FTableName;
  90.     property Coded: Boolean read FCoded;
  91.   end;
  92.  
  93. { TBtsUser }
  94.  
  95.   TBtsUser = class
  96.   private
  97.     FNetName: string;
  98.     FUserName: string;
  99.     FGroup: string;
  100.     FRights: TUserRights;
  101.     FRegistered: Boolean;
  102.   public
  103.     constructor Create(UserTab: TTable; GroupLook: TLookupList;
  104.       const DefRights: string);
  105.     procedure CheckRights(Value: TUserRights);
  106.     property Group: string read FGroup;
  107.     property NetName: string read FNetName;
  108.     property Rights: TUserRights read FRights;
  109.     property UserName: string read FUserName;
  110.     property Registered: Boolean read FRegistered write FRegistered;
  111.   end;
  112.  
  113. { TFieldMap }
  114.  
  115.   TFieldMap = class(TStringList)
  116.   private
  117.     function GetStatusValue(ResValue: Integer): Integer;
  118.   public
  119.     constructor Create(StatIni: TMemIniFile; const CfgSect: string);
  120.     property StatusValue[ResValue: Integer]: Integer read GetStatusValue;
  121.   end;
  122.  
  123. { TCloneDataset }
  124.  
  125.   TCloneDataset = class(TDBDataset)
  126.   private
  127.     FSourceHandle: HDBICur;
  128.     procedure SetSourceHandle(ASourceHandle: HDBICur);
  129.   protected
  130.     function CreateHandle: HDBICur; override;
  131.   public
  132.     property SourceHandle: HDBICur read FSourceHandle write SetSourceHandle;
  133.   end;
  134.  
  135. { TCloneTable }
  136.  
  137.   TCloneTable = class(TTable)
  138.   private
  139.     FSourceHandle: HDBICur;
  140.     procedure SetSourceHandle(ASourceHandle: HDBICur);
  141.   protected
  142.     function CreateHandle: HDBICur; override;
  143.   public
  144.     constructor CreateFromTable(AOwner: TComponent; Reset: Boolean);
  145.     procedure InitFromTable(SourceTable: TTable; Reset: Boolean);
  146.   end;
  147.  
  148. { TQueryField }
  149.  
  150.   TQueryField = class
  151.   protected
  152.     FQDType: TQueryDataType;
  153.     FFldNo: Integer;
  154.     FQRow: Integer;
  155.     FQText: string;
  156.     FFldName: string;
  157.     FLookupTableName: string;
  158.   public
  159.     LookupData: array[1..2] of TQueryField;
  160.     constructor Create(AQDType: TQueryDataType; AFldNo: Integer; AQText: string);
  161.     destructor Destroy; override;
  162.     procedure InitLookupData(LookupList: TLookupList;
  163.      const Example, CodeFldName, DescFldName: string; ARow, ACol: Integer);
  164.     property FldNo: Integer read FFldNo;
  165.     property FldName: string read FFldName write FFldName;
  166.     property QText: string read FQText write FQText;
  167.     property QRow: Integer read FQRow write FQRow;
  168.     property QDType: TQueryDataType read FQDType;
  169.     property LookupTableName: string read FLookupTableName write FLookupTableName;
  170.   end;
  171.  
  172. { TQueryData }
  173.  
  174.   TQueryData = class(TList)
  175.   private
  176.     function Get(Index: Integer): TQueryField;
  177.   public
  178.     procedure Empty;
  179.     destructor Destroy; override;
  180.     property Items[Index: Integer]: TQueryField read Get; default;
  181.   end;
  182.  
  183. { TQBEQuery }
  184.  
  185.   TCheckType = (ctNone, ctCheck, ctCheckPlus, ctCheckDesc, ctCheckGroup);
  186.  
  187.   TQBEQuery = class(TQuery)
  188.   private
  189.     hQry: hDBIQry;
  190.   protected
  191.     function CreateHandle: HDBICur; override;
  192.   public
  193.     constructor Create(AOwner: TComponent); override;
  194.     procedure AddExpr(const TabName, FldName: string; Row: Integer;
  195.       CheckType: TCheckType; Expr: string);
  196.   end;
  197.  
  198. { TOtlData }
  199.  
  200.   TOtlData = class(TObject)
  201.   public
  202.     ProgName: PChar;
  203.     Tester: PChar;
  204.     HasChildren: Boolean;
  205.     constructor Create(PName, TName: PChar; ChildFlag: Boolean);
  206.     destructor Destroy; override;
  207.   end;
  208.  
  209. implementation
  210.  
  211. uses DBConsts;
  212.  
  213. { EInvalidField }
  214.  
  215. constructor EInvalidField.Create(AField: TField; const Msg: string);
  216. begin
  217.   Field := AField;
  218.   inherited Create(Msg);
  219. end;
  220.  
  221. { TDisplayOutline }
  222.  
  223. constructor EDisplayOutline.Create(ACode: Double);
  224. begin
  225.   ItemCode := ACode;
  226. end;
  227.  
  228. { TLookupList }
  229.  
  230. constructor TLookupList.Create;
  231. const
  232.   SCodeSep = '|';
  233.   SDescSep = ' - ';
  234. begin
  235.   inherited Create;
  236.   List := TList.Create;
  237.   CodeSep := SCodeSep;
  238.   DescSep := SDescSep;
  239. end;
  240.  
  241. destructor TLookupList.Destroy;
  242. begin
  243.   if List <> nil then
  244.   begin
  245.     Clear;
  246.     List.Destroy;
  247.   end;
  248.   inherited Destroy;
  249. end;
  250.  
  251. function TLookupList.NewStrItem(const S: string): PStrItem;
  252. var
  253.   CodeSepPos: Integer;
  254.   ValLen: Integer;
  255. begin
  256.   CodeSepPos := Pos(CodeSep, S);
  257.   FCoded := CodeSepPos > 0;
  258.   ValLen := Pos(DescSep, S) - 1;
  259.   if (ValLen > 0) and (CodeSepPos > 0) then
  260.     Dec(ValLen, CodeSepPos - 1 + Length(CodeSep));
  261.   Result := New(PStrItem);
  262.   if FCoded then
  263.   begin
  264.     Result^.FString := Copy(S, CodeSepPos + Length(CodeSep), Length(S));
  265.     Result^.FCode := StrToInt(Copy(S, 1, CodeSepPos - 1));
  266.   end else
  267.   begin
  268.     Result^.FString := S;
  269.     Result^.FCode := -1;
  270.   end;
  271.   with Result^ do
  272.   begin
  273.     FObject := nil;
  274.     if ValLen > 0 then
  275.     begin
  276.       { Make a copy of the value part, so we can access it easily }
  277.       FValue := Copy(FString, 1 , ValLen);
  278.       { And a pointer to only the description }
  279.       FDesc := @FString[ValLen + Length(DescSep) + 1];
  280.     end else
  281.     begin
  282.       FValue := FString;
  283.       FDesc := nil;
  284.     end;
  285.   end;
  286. end;
  287.  
  288. procedure TLookupList.DisposeStrItem(P: PStrItem);
  289. begin
  290.   P.FObject.Free;
  291.   Dispose(P);
  292. end;
  293.  
  294. function TLookupList.Get(Index: Integer): string;
  295. begin
  296.   Result := PStrItem(List[Index]).FString;
  297. end;
  298.  
  299. function TLookupList.GetObject(Index: Integer): TObject;
  300. begin
  301.   Result := PStrItem(List[Index]).FObject;
  302. end;
  303.  
  304. function TLookupList.GetCount: Integer;
  305. begin
  306.   Result := List.Count;
  307. end;
  308.  
  309. procedure TLookupList.Put(Index: Integer; const S: string);
  310. var
  311.   P: PStrItem;
  312. begin
  313.   P := List[Index];
  314.   List[Index] := NewStrItem(S);
  315.   DisposeStrItem(P);
  316. end;
  317.  
  318. procedure TLookupList.PutObject(Index: Integer; AObject: TObject);
  319. begin
  320.   PStrItem(List[Index]).FObject := AObject;
  321. end;
  322.  
  323. procedure TLookupList.Insert(Index: Integer; const S: string);
  324. begin
  325.   List.Expand.Insert(Index, NewStrItem(S));
  326. end;
  327.  
  328. procedure TLookupList.Delete(Index: Integer);
  329. begin
  330.   DisposeStrItem(List[Index]);
  331.   List.Delete(Index);
  332. end;
  333.  
  334. procedure TLookupList.Clear;
  335. var
  336.   I: Integer;
  337. begin
  338.   for I := 0 to List.Count - 1 do DisposeStrItem(List[I]);
  339.   List.Clear;
  340. end;
  341.  
  342. function TLookupList.GetValue(Index: Integer): string;
  343. begin
  344.   if Index >= 0 then
  345.     with PStrItem(List[Index])^ do
  346.       Result := FValue
  347.   else
  348.       Result := '';
  349. end;
  350.  
  351. function TLookupList.GetDesc(Index: Integer): string;
  352. begin
  353.   with PStrItem(List[Index])^ do
  354.     if Assigned(FDesc) then
  355.       Result := FDesc else
  356.       Result := '';
  357. end;
  358.  
  359. function TLookupList.GetCode(Index: Integer): Integer;
  360. begin
  361.   with PStrItem(List[Index])^ do
  362.     Result := FCode;
  363. end;
  364.  
  365. function TLookupList.GetItem(Index: Integer): string;
  366. begin
  367.   if UseDesc then
  368.     Result := GetDesc(Index) else
  369.     Result := GetValue(Index);
  370. end;
  371.  
  372. function TLookupList.IndexOfValue(const S: string): Integer;
  373. begin
  374.   for Result := 0 to GetCount - 1 do
  375.     if CompareText(GetValue(Result), S) = 0 then Exit;
  376.   Result := -1;
  377. end;
  378.  
  379. function TLookupList.IndexOfDesc(const S: string): Integer;
  380. begin
  381.   for Result := 0 to GetCount - 1 do
  382.     if CompareText(GetDesc(Result), S) = 0 then Exit;
  383.   Result := -1;
  384. end;
  385.  
  386. function TLookupList.IndexOfCode(ACode: Integer): Integer;
  387. begin
  388.   for Result := 0 to GetCount - 1 do
  389.     if ACode = GetCode(Result) then Exit;
  390.   Result := -1;
  391. end;
  392.  
  393. function TLookupList.IndexOfItem(const S: string): Integer;
  394. begin
  395.   if UseDesc then
  396.     Result := IndexOfDesc(S) else
  397.     Result := IndexOfValue(S);
  398. end;
  399.  
  400. function TLookupList.CodeToValue(ACode: Integer): string;
  401. var
  402.   Index: Integer;
  403. begin
  404.   Index := IndexOfCode(ACode);
  405.   if Index >= 0 then
  406.     Result := Item[Index] else
  407.     Result := EmptyStr;
  408. end;
  409.  
  410. function TLookupList.ValueToCode(const AValue: string): Integer;
  411. begin
  412.   Result := IndexOfItem(AValue);
  413.   if Result > -1 then Result := Code[Result];
  414. end;
  415.  
  416.  
  417. { TBtsUser }
  418.  
  419. constructor TBtsUser.Create(UserTab: TTable; GroupLook: TLookupList;
  420.   const DefRights: string);
  421. var
  422.   RightsStr: string;
  423.   NameBuf: array[0..255] of Char;
  424.  
  425.   procedure Str2Rights;
  426.   var
  427.     X: Byte;
  428.     I: Integer;
  429.   begin
  430.     FRights := [];
  431.     for I := 1 to Length(RightsStr) do
  432.     begin
  433.       X := Pos(RightsStr[I], sRightsChars);
  434.       if X > 0 then
  435.         Include(FRights, TUserRightsElement(X-1));
  436.     end;
  437.     if urDirectEntry in FRights then Include(FRights, urEntry);
  438.   end;
  439.  
  440. begin
  441.   if (DbiGetNetUserName(NameBuf) = 0) and (NameBuf[0] <> #0) then
  442.     SetString(FNetName, NameBuf, StrLen(NameBuf)) else
  443.     raise EBts.Create(SUnknownUser);
  444.  
  445.   with UserTab do
  446.   try
  447.     Open;
  448.     try
  449.       IndexName := 'NetName';
  450.     except
  451.       Close;
  452.       Exclusive := True;
  453.       Open;
  454.       AddIndex('NetName', Fields[fldnoNetName].FieldName, [ixCaseInsensitive]);
  455.       IndexName := 'NetName';
  456.     end;
  457.     if FindKey([NetName]) then
  458.     begin
  459.       FUserName := FieldByName('User Name').AsString;
  460.       FGroup := GroupLook.CodeToValue(FieldByName('Group').AsInteger);
  461.       RightsStr := FieldByName('Rights').AsString;
  462.     end else
  463.     begin
  464.       FUserName := NetName;
  465.       RightsStr := DefRights;
  466.       FGroup := 'User';
  467.     end;
  468.     Str2Rights;
  469.   finally
  470.     Close
  471.   end;
  472. end;
  473.  
  474. procedure TBtsUser.CheckRights(Value: TUserRights);
  475. var
  476.   S: string;
  477.   X: TUserRightsElement;
  478. begin
  479.   if not (Value <= Rights)  then
  480.   begin
  481.     S := SRights1;
  482.     for X := Low(X) to High(X) do
  483.       if (X in Value) and not (X in Rights) then
  484.         S := Format('%s%s, ', [S, SRights[X]]);
  485.     SetLength(S, Length(S) - 1); { remove last ", " }
  486.     S := S + SRights2;
  487.     raise EBts.Create(S);
  488.   end;
  489. end;
  490.  
  491. { TFieldMap }
  492.  
  493. constructor TFieldMap.Create(StatIni: TMemIniFile; const CfgSect: string);
  494. var
  495.   I, Count, BarPos: Integer;
  496.   S: string;
  497. begin
  498.   Count := StatIni.ReadInteger(CfgSect, ckCount, 0);
  499.   for I := 1 to Count do
  500.   begin
  501.     S := StatIni.ReadString(CfgSect, IntToStr(I), '');
  502.     BarPos := Pos('|', S);
  503.     if BarPos > 0 then
  504.       AddObject(Copy(S, 1, BarPos-1), TObject(StrToInt(Copy(S, BarPos+1, 5))));
  505.   end;
  506. end;
  507.  
  508. function TFieldMap.GetStatusValue(ResValue: Integer): Integer;
  509. begin
  510.   Result := IndexOf(IntToStr(ResValue));
  511.   if Result <> -1 then
  512.     Result := Integer(Objects[Result]);
  513. end;
  514.  
  515. { TCloneDataset }
  516.  
  517. procedure TCloneDataset.SetSourceHandle(ASourceHandle: HDBICur);
  518. begin
  519.   if ASourceHandle <> FSourceHandle then
  520.   begin
  521.     Close;
  522.     FSourceHandle := ASourceHandle;
  523.     if FSourceHandle <> nil then Open;
  524.   end;
  525. end;
  526.  
  527. function TCloneDataset.CreateHandle: HDBICur;
  528. begin
  529.    Check(DbiCloneCursor(FSourceHandle, False, False, Result));
  530. end;
  531.  
  532. { TCloneTable }
  533.  
  534. constructor TCloneTable.CreateFromTable(AOwner: TComponent; Reset: Boolean);
  535. begin
  536.   inherited Create(AOwner);
  537.   InitFromTable(TTable(AOwner), Reset);
  538. end;
  539.  
  540. procedure TCloneTable.InitFromTable(SourceTable: TTable; Reset: Boolean);
  541. begin
  542.   with SourceTable do
  543.   begin
  544.     Self.TableName := TableName;
  545.     Self.DatabaseName := DatabaseName;
  546.     if IndexName <> '' then
  547.       Self.IndexName := IndexName
  548.     else if IndexFieldNames <> '' then
  549.       Self.IndexFieldNames := IndexFieldNames;
  550.     SetSourceHandle(Handle);
  551.     Self.Filter := Filter;
  552.     Self.OnFilterRecord := OnFilterRecord;
  553.     Self.Filtered := Filtered;
  554.   end;
  555.   if Reset then
  556.   begin
  557.     Filtered := False;
  558.     DbiResetRange(Handle);
  559.     IndexName := '';
  560.     First;
  561.   end;
  562. end;
  563.  
  564. procedure TCloneTable.SetSourceHandle(ASourceHandle: HDBICur);
  565. begin
  566.   if ASourceHandle <> FSourceHandle then
  567.   begin
  568.     Close;
  569.     FSourceHandle := ASourceHandle;
  570.     if FSourceHandle <> nil then Open;
  571.   end;
  572. end;
  573.  
  574. function TCloneTable.CreateHandle: HDBICur;
  575. begin
  576.    Check(DbiCloneCursor(FSourceHandle, False, False, Result));
  577. end;
  578.  
  579. { TQueryField }
  580.  
  581. constructor TQueryField.Create(AQDType: TQueryDataType; AFldNo: Integer;
  582.   AQText: string);
  583. begin
  584.   FQDType := AQDType;
  585.   FFldNo := AFldNo;
  586.   FQText := AQText;
  587.   FQRow := 1;
  588. end;
  589.  
  590. destructor TQueryField.Destroy;
  591. begin
  592.   LookupData[1].Free;
  593.   LookupData[2].Free;
  594. end;
  595.  
  596. procedure TQueryField.InitLookupData(LookupList: TLookupList;
  597.   const Example, CodeFldName, DescFldName: string; ARow, ACol: Integer);
  598. var
  599.   Code: Integer;
  600. begin
  601.   Code := LookupList.ValueToCode(QText);
  602.   if Code <> -1 then
  603.     QText := IntToStr(Code)
  604.   else if (CompareText(QText, 'BADLINK') = 0) then
  605.   begin
  606.     LookupData[1] := TQueryField.Create(qdLookup, 1, Example + ',count=0');
  607.     LookupData[1].FldName := CodeFldName;
  608.     LookupData[1].LookupTableName := LookupList.TableName;
  609.     LookupData[1].QRow := ARow;
  610.     QText := Example + #33',not blank'; {#33 = Exclamation point}
  611.   end
  612.   else if not (CompareText(QText, SBLANK) = 0) or
  613.               (CompareText(QText, SNOTBLANK) = 0) then
  614.   begin
  615.     LookupData[1] := TQueryField.Create(qdLookup, 1, Example);
  616.     LookupData[1].FldName := CodeFldName;
  617.     LookupData[1].LookupTableName := LookupList.TableName;
  618.     LookupData[1].QRow := ARow;
  619.     LookupData[2] := TQueryField.Create(qdLookup, ACol, QText);
  620.     LookupData[2].LookupTableName := LookupList.TableName;
  621.     LookupData[2].FldName := DescFldName;
  622.     LookupData[2].QRow := ARow;
  623.     QText := Example;
  624.   end;
  625. end;
  626.  
  627. { TQueryData }
  628.  
  629. procedure TQueryData.Empty;
  630. var
  631.   I: Integer;
  632. begin
  633.   for I := 0 to Count - 1 do TQueryField(Items[I]).Free;
  634.   Count := 0;
  635. end;
  636.  
  637. destructor TQueryData.Destroy;
  638. begin
  639.   Empty;
  640.   inherited Destroy;
  641. end;
  642.  
  643. function TQueryData.Get(Index: Integer): TQueryField;
  644. begin
  645.   Result := inherited Items[Index];
  646. end;
  647.  
  648. { TQBEQuery }
  649.  
  650. type
  651.   TDbiQryFree = function(var hQry: hDBIQry): DbiResult; stdcall;
  652.  
  653.   TDbiQLowStart = function (hDb: hDbiDb; pszQryName: PChar;
  654.     eQryType: DbiQryType; var hQry: hDbiQry): DbiResult;  stdcall;
  655.  
  656.   TDbiQLowBuild = function(hQry: hDbiQry; pszTableName: PChar;
  657.     pszTableType: PChar; pszFieldName: PChar; iRowNum: Word;
  658.     eCheck: TCheckType; pszExpr: PChar): DbiResult; stdcall;
  659.  
  660.   TDbiQLowPrepare = function(hQry: hDbiQry;
  661.     TableBits: PWord): DbiResult; stdcall;
  662.  
  663.   TDbiQryOpen = function(hQry: hDBIQry; bUniDirec: Bool;
  664.     var hCur: hDBICur): DbiResult; stdcall;
  665.  
  666. var
  667.   DbiQLowStart: TDbiQLowStart;
  668.   DbiQLowBuild: TDbiQLowBuild;
  669.   DbiQLowPrepare: TDbiQLowPrepare;
  670.   DbiQryFree: TDbiQryFree;
  671.   DbiQryOpen: TDbiQryOpen;
  672.  
  673. procedure InitializeQBEProcedures;
  674. var
  675.   HModule: THandle;
  676. begin
  677.   if not Assigned(DbiQLowStart) then
  678.   begin
  679.     HModule := LoadLibrary('IDAPI32.DLL');
  680.     if HModule <= 32 then SysUtils.Abort;
  681.     DbiQLowStart := GetProcAddress(HModule, 'DbiQLowStart');
  682.     DbiQLowBuild := GetProcAddress(HModule, 'DbiQLowBuild');
  683.     DbiQLowPrepare := GetProcAddress(HModule, 'DbiQLowPrepare');
  684.     DbiQryOpen := GetProcAddress(HModule, 'DbiQryOpen');
  685.     DbiQryFree := GetProcAddress(HModule, 'DbiQryFree');
  686.     FreeLibrary(HModule);
  687.   end;
  688. end;
  689.  
  690. constructor TQBEQuery.Create(AOwner: TComponent);
  691. begin
  692.   inherited Create(AOwner);
  693.   InitializeQBEProcedures;
  694. end;
  695.  
  696. procedure TQBEQuery.AddExpr(const TabName, FldName: string; Row: Integer;
  697.   CheckType: TCheckType; Expr: string);
  698. begin
  699.   CheckInactive;
  700.   SetDBFlag(dbfOpened, True);
  701.   if hQry = nil then
  702.     Check(DbiQLowStart(DBHandle, nil, dbiqryDIRTY, hQry));
  703.   UniqueString(Expr);
  704.   try
  705.     Check(DbiQLowBuild(hQry, PChar(TabName), nil, PChar(FldName),
  706.       Row, CheckType, PChar(Expr)));
  707.   except
  708.     DbiQryFree(hQry);
  709.     raise;
  710.   end;
  711. end;
  712.  
  713. function TQBEQuery.CreateHandle: HDBICur;
  714. begin
  715.   try
  716.     Check(DbiQLowPrepare(hQry, nil));
  717.     Check(DbiQryOpen(hQry, True, Result));
  718.   finally
  719.     DbiQryFree(hQry);
  720.   end;
  721. end;
  722.  
  723. { TOtlData }
  724.  
  725. constructor TOtlData.Create(PName, TName: PChar; ChildFlag: Boolean);
  726. begin
  727.   inherited Create;
  728.   ProgName := StrNew(PName);
  729.   Tester := StrNew(TName);
  730.   HasChildren := ChildFlag;
  731. end;
  732.  
  733. destructor TOtlData.Destroy;
  734. begin
  735.   StrDispose(ProgName);
  736.   StrDispose(Tester);
  737.   inherited Destroy;
  738. end;
  739.  
  740. end.
  741.