⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ffxquery.pas

📁 TxQuery is an SQL engine implemented in a TDataSet descendant component, that can parse SQL syntax,
💻 PAS
📖 第 1 页 / 共 2 页
字号:
Unit FFxQuery;

{
================================================================================
   (c) 2002 Alfonso moreno
   TFFxQuery class implementation
   Most of this code due (and thanks) to : David G. Stern (60% :-))
================================================================================
}
Interface

Uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, IniFiles, xquery, xqmiscel, xqbase;

//{$R FFxQUERY.DCR}

Type
  {-------------------------------------------------------------------------------}
  {                  forward declarations                                         }
  {-------------------------------------------------------------------------------}
  TDataList = Class;

  {-------------------------------------------------------------------------------}
  {                  Defines TDataItem                                            }
  {-------------------------------------------------------------------------------}

  TDataItem = Class
  Private
    FDataList: TDataList; { belongs to                                          }
    FDataSet: TDataSet; { the TFFxTable                                       }
    FDatabaseName: String;
    FTableName: String;
    FAlias: String; { the alias assigned (to be passed to TFFxQuery)      }
    Function GetFileName: String;
  Public
    Constructor Create( DataList: TDataList );
    Destructor Destroy; Override;
    Procedure Open;

    Property DatabaseName: String Read FDatabaseName Write FDatabaseName;
    Property TableName: String Read FTableName Write FTableName;
    Property Alias: String Read FAlias Write FAlias;
    Property DataSet: TDataSet Read FDataSet Write FDataSet;
    Property FileName: String Read GetFileName;
  End;

  {-------------------------------------------------------------------------------}
  {                  Defines TDataList                                            }
  {-------------------------------------------------------------------------------}

  TDataList = Class
  Private
    FItems: TList;
    FConfigFileName: String;
    FInMemResultSet: Boolean;
    FMapFileSize: Longint;
    FDateFormat: String;
    FUseDisplayLabel: Boolean;
    Function GetCount: Integer;
    Function GetItem( Index: Integer ): TDataItem;
  Public
    Constructor Create;
    Destructor Destroy; Override;
    Function Add( Const pDatabaseName, pTableName, pAlias: String ): TDataItem;
    Procedure Clear;
    Procedure Delete( Index: Integer );
    Procedure LoadFromFile( Const ConfigFileName: String );
    Procedure SaveToFile( Const ConfigFileName: String );
    Procedure OpenDataSets;
    Procedure CloseDataSets;

    Property Count: Integer Read GetCount;
    Property Items[Index: Integer]: TDataItem Read GetItem; Default;
    Property ConfigFileName: String Read FConfigFileName Write FConfigFileName;
    Property InMemResultSet: Boolean Read FInMemResultSet Write FInMemResultSet;
    Property MapFileSize: Longint Read FMapFileSize Write FMapFileSize;
    Property DateFormat: String Read FDateFormat Write FDateFormat;
    Property UseDisplayLabel: Boolean Read FUseDisplayLabel Write FUseDisplayLabel;
  End;

  TFFxQuery = Class( TCustomxQuery )
  Private
    fIndexList: Array[1..2] Of TStringList;
    fDatabaseName: String;
    { this is only a reference to a global object and must not be created }
    fDataList: TDataList;
    // for temporary saving events
    fSaveIndexNeededFor: TIndexNeededForEvent;
    fSaveSetRange: TSetRangeEvent;
    fSaveCancelRange: TCancelRangeEvent;
    fSaveSetFilter: TSetFilterEvent;
    fSaveCancelFilter: TCancelFilterEvent;
    FOldBeforeQuery: TNotifyEvent;
    FOldAfterQuery: TNotifyEvent;

    Procedure SetDataList( Value: TDataList );
    { overriden methods}
    Procedure IndexNeededFor( Sender: TObject;
      DataSet: TDataSet;
      Const FieldNames: String;
      ActivateIndex: Boolean;
      IsJoining: Boolean;
      Var Accept: Boolean );
    Procedure SetRange( Sender: TObject;
      RelOperator: TRelationalOperator;
      DataSet: TDataSet;
      Const FieldNames, StartValues, EndValues: String;
      IsJoining: Boolean );
    Procedure CancelRange( Sender: TObject;
      DataSet: TDataSet;
      IsJoining: Boolean );
    Procedure SetUserRange( Sender: TObject; Dataset: TDataset;
      Const UsingIndex: String;
      ForFields, StartValues, EndValues: TStrings );
    Procedure CancelUserRange( Sender: TObject; Dataset: TDataset );
  Protected

    { not overrides }
    Procedure CreateTable( Sender: TObject; CreateTable: TCreateTableItem );
    Procedure CreateIndex( Sender: TObject;
      Unique, Descending: Boolean;
      Const TableName, IndexName: String;
      ColumnExprList: TStringList );
    Procedure DropTable( Sender: TObject; Const TableName: String );
    Procedure DropIndex( Sender: TObject; Const TableName, IndexName: String );
  Public
    Constructor Create( AOwner: TComponent ); Override;
    Destructor Destroy; Override;
    Procedure Loaded; Override;
    Procedure BeforeQuery( Sender: TObject );
    Procedure AfterQuery( Sender: TObject );

    Property DataList: TDataList Read FDataList Write SetDataList;
  Published
    { inherited properties }
    Property OnBlobNeeded;
    Property DataSets;
    Property DatabaseName: String Read fDatabaseName Write fDatabaseName;
  End;

Procedure Register;

Implementation

Uses
  FFDB;

Procedure Register;
Begin
  RegisterComponents( 'FlashFiler', [TFFxQuery] );
End;

{-------------------------------------------------------------------------------}
{                  Implementes TDataItem                                        }
{-------------------------------------------------------------------------------}

Constructor TDataItem.Create( DataList: TDataList );
Begin
  Inherited Create;
  FDataList := DataList;
  { the dataset belong to the DataList }
  FDataSet := TffTable.Create( Nil );
End;

Destructor TDataItem.Destroy;
Begin
  FDataSet.Free;
  Inherited Destroy;
End;

Function TDataItem.GetFileName: String;
Begin
  Result := AddSlash( FDatabaseName ) + FTableName;
End;

Procedure TDataItem.Open;
Begin
  FDataSet.Close;
  With ( FDataSet As TffTable ) Do
  Begin
    DatabaseName := Self.FDatabaseName;
    Tablename := Self.FTableName;
    Open;
  End;
End;

{-------------------------------------------------------------------------------}
{                  Implement TDataList                                          }
{-------------------------------------------------------------------------------}

Constructor TDataList.Create;
Begin
  Inherited Create;
  FItems := TList.Create;
End;

Destructor TDataList.Destroy;
Begin
  Clear;
  FItems.Free;
  Inherited Destroy;
End;

Function TDataList.GetCount;
Begin
  Result := FItems.Count;
End;

Function TDataList.GetItem( Index: Integer ): TDataItem;
Begin
  Result := FItems[Index];
End;

Function TDataList.Add( Const pDatabaseName, pTableName, pAlias: String ): TDataItem;
Begin
  Result := TDataItem.Create( Self );
  Try
    With TDataItem( Result ) Do
    Begin
      DataSet.Close;
      TffTable( DataSet ).DatabaseName := pDatabaseName;
      TffTable( DataSet ).TableName := pTableName;
      If Length( pAlias ) > 0 Then
        Alias := pAlias
      Else
        Alias := ChangeFileExt( ExtractFileName( pTableName ), '' );
      DatabaseName := pDatabaseName;
      TableName := pTableName;
    End;
  Except
    Result.Free;
    Raise;
  End;
  FItems.Add( Result );
End;

Procedure TDataList.Clear;
Var
  I: Integer;
Begin
  For I := 0 To FItems.Count - 1 Do
    TDataItem( FItems[I] ).Free;
  FItems.Clear;
End;

Procedure TDataList.Delete( Index: Integer );
Begin
  TDataItem( FItems[Index] ).Free;
  FItems.Delete( Index );
End;

Procedure TDataList.LoadFromFile( Const ConfigFileName: String );
Var
  IniFile: TIniFile;
  NumFiles: Integer;
  I: Integer;
  DatabaseName: String;
  Tablename: String;
  Alias: String;
Begin
  Clear;
  IniFile := TIniFile.Create( ConfigFileName );
  Try
    { this is the configuration for the file :
    [General]
    NumFiles=3
    DatabaseName1=Examples
    Tablename1=ExCust
    DatabaseName2=Examples
    Tablename2=ExOrders
    Alias1=Customer
    Alias2=Orders
    ...
    FInMemResultSet : Boolean;
    FMapFileSize    : Longint;
    FDateFormat     : String;
    }
    NumFiles := IniFile.ReadInteger( 'General', 'NumFiles', 0 );
    FInMemResultSet := IniFile.ReadBool( 'General', 'InMemResultSet', True );
    FMapFileSize := IniFile.ReadInteger( 'General', 'MapFileSize', 2000000 );
    FDateFormat := IniFile.ReadString( 'General', 'DateFormat', 'm/d/yyyy' );

    For I := 1 To NumFiles Do
    Begin
      DatabaseName := IniFile.ReadString( 'General', 'DatabaseName' + IntToStr( I ), '' );
      TableName := IniFile.ReadString( 'General', 'TableName' + IntToStr( I ), '' );
      Alias := IniFile.ReadString( 'General', 'Alias' + IntToStr( I ), '' );
      Add( DatabaseName, TableName, Alias );
    End;
  Finally
    IniFile.Free;
  End;
  FConfigFileName := ConfigFileName;
End;

Procedure TDataList.SaveToFile( Const ConfigFileName: String );
Var
  IniFile: TIniFile;
  NumFiles, I: Integer;
  DatabaseName, TableName, Alias: String;
  Item: TDataItem;
Begin
  IniFile := TIniFile.Create( ConfigFileName );
  Try
    NumFiles := FItems.Count;
    IniFile.WriteInteger( 'General', 'NumFiles', NumFiles );
    IniFile.WriteBool( 'General', 'InMemResultSet', FInMemResultSet );
    IniFile.WriteInteger( 'General', 'MapFileSize', FMapFileSize );
    IniFile.WriteString( 'General', 'DateFormat', FDateFormat );
    For I := 0 To NumFiles - 1 Do
    Begin
      Item := Items[I];
      DatabaseName := Item.DatabaseName;
      TableName := Item.TableName;
      IniFile.writeString( 'General', 'DatabaseName' + IntToStr( I + 1 ), DatabaseName );
      IniFile.writeString( 'General', 'TableName' + IntToStr( I + 1 ), TableName );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -