Changeset 20 for trunk/UDatabase.pas


Ignore:
Timestamp:
Mar 23, 2018, 1:59:25 PM (6 years ago)
Author:
chronos
Message:
  • Modified: Database classes reorganized. Now TDbConnectProfile is class which holds information about connection to database.
  • Modified: TDbManager is top most class for managing other database classes.
  • Modified: TDbConnectParams class contains client specific parameters for connect profile.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UDatabase.pas

    r15 r20  
    77uses
    88  Classes, SysUtils, Contnrs, ExtCtrls, StdCtrls, EditBtn, dialogs, USqlDatabase,
    9   SpecializedDictionary;
     9  SpecializedDictionary, URegistry;
    1010
    1111type
    1212  TTable = class;
    13   TDatabaseEngine = class;
    14   TDatabaseClient = class;
    15   TDatabase = class;
     13  TDbClientType = class;
     14  TDbClient = class;
    1615  TDataType = class;
     16  TDbManager = class;
    1717
    1818  TFieldType = (ftString, ftInteger, ftDateTime, ftBoolean, ftFloat, ftImage,
     
    104104    Records: TRecords;
    105105    Fields: TFields;
    106     Database: TDatabase;
     106    DbClient: TDbClient;
    107107    RecordsCount: Integer;
    108108    procedure LoadRecords;
     
    116116
    117117  TTables = class(TObjectList)
    118     Database: TDatabase;
     118    DbClient: TDbClient;
    119119    function SearchByName(Name: string): TTable;
    120120  end;
    121121
    122   // CSV, INI, WinRegistry, XML, sqlite, mysql
    123 
    124   { TDatabase }
    125 
    126   TDatabase = class
     122  { TDbConnectParams }
     123
     124  TDbConnectParams = class
     125  protected
     126    FConnectionString: string;
     127    function GetConnectionString: string; virtual;
     128    procedure SetConnectionString(AValue: string); virtual;
     129  public
     130    property ConnectionString: string read GetConnectionString
     131      write SetConnectionString;
     132  end;
     133
     134  TDbConnectParamsClass = class of TDbConnectParams;
     135
     136  { TDbConnectProfile }
     137
     138  TDbConnectProfile = class
    127139  private
    128     FEngine: TDatabaseEngine;
    129     procedure SetEngine(AValue: TDatabaseEngine);
     140    FClientType: TDbClientType;
     141    procedure SetClientType(AValue: TDbClientType);
    130142  public
    131143    Name: string;
    132     Tables: TTables;
    133     ConnectionString: string;
    134     Client: TDatabaseClient;
    135     constructor Create;
    136     destructor Destroy; override;
    137     procedure Load; virtual;
    138     procedure Save; virtual;
    139     procedure Clear;
    140     property Engine: TDatabaseEngine read FEngine write SetEngine;
    141   end;
    142 
    143   { TDatabases }
    144 
    145   TDatabases = class(TObjectList)
    146     function FindByName(Name: string): TDatabase;
    147   end;
    148 
    149   TDatabaseClass = class of TDatabase;
     144    Params: TDbConnectParams;
     145    property ClientType: TDbClientType read FClientType write SetClientType;
     146  end;
     147
     148  { TDbConnectProfiles }
     149
     150  TDbConnectProfiles = class(TObjectList)
     151    DbManager: TDbManager;
     152    procedure LoadFromRegistry(Context: TRegistryContext);
     153    procedure SaveToRegistry(Context: TRegistryContext);
     154    function FindByName(Name: string): TDbConnectProfile;
     155  end;
    150156
    151157  { TDataType }
     
    168174  end;
    169175
    170   { TDatabaseClient }
    171 
    172   TDatabaseClient = class
    173     Database: TDatabase;
     176  { TDbClient }
     177
     178  TDbClient = class
     179  private
     180    function GetClientType: TDbClientType;
     181  protected
     182    FConnectProfile: TDbConnectProfile;
     183    procedure SetConnectProfile(AValue: TDbConnectProfile); virtual;
     184  public
    174185    procedure Query(DbRows: TDbRows; Text: string); virtual;
     186    procedure LoadTables(Tables: TTables); virtual;
    175187    constructor Create; virtual;
    176188    procedure Load; virtual;
    177189    procedure Save; virtual;
    178   end;
    179 
    180   TDatabaseClientClass = class of TDatabaseClient;
     190    property ClientType: TDbClientType read GetClientType;
     191    property ConnectProfile: TDbConnectProfile read FConnectProfile
     192      write SetConnectProfile;
     193  end;
     194
     195  TDbClientClass = class of TDbClient;
    181196
    182197  TFieldTypeSet = set of TFieldType;
    183198
    184   { TDatabaseEngine }
    185 
    186   TDatabaseEngine = class
     199  { TDbClientType }
     200
     201  TDbClientType = class
    187202    Name: string;
    188203    DataTypes: TDataTypes;
    189     DatabaseClientClass: TDatabaseClientClass;
     204    DatabaseClientClass: TDbClientClass;
     205    ConnectParmasClass: TDbConnectParamsClass;
    190206    procedure UseTypes(ADataTypes: TDataTypes; Types: TFieldTypeSet);
    191207    constructor Create;
     
    193209  end;
    194210
    195   { TDatabaseEngines }
    196 
    197   TDatabaseEngines = class(TObjectList)
    198     function RegisterEngine(Name: string; DatabaseClass: TDatabaseClientClass): TDatabaseEngine;
    199     function FindByName(Name: string): TDatabaseEngine;
     211  { TDbClientTypes }
     212
     213  TDbClientTypes = class(TObjectList)
     214    function RegisterClientType(Name: string; DatabaseClass: TDbClientClass;
     215      ConnectParamsClass: TDbConnectParamsClass): TDbClientType;
     216    function FindByName(Name: string): TDbClientType;
    200217  end;
    201218
     
    205222  end;
    206223
     224  { TDbManager }
     225
     226  TDbManager = class
     227  private
     228    procedure InitClientTypes;
     229    procedure InitDataTypes;
     230  public
     231    ConnectProfiles: TDbConnectProfiles;
     232    ClientTypes: TDbClientTypes;
     233    DataTypes: TDataTypes;
     234    constructor Create;
     235    destructor Destroy; override;
     236  end;
     237
     238resourcestring
     239  STypeString = 'String';
     240  STypeInteger = 'Integer';
     241  STypeFloat = 'Float';
     242  STypeBoolean = 'Boolean';
     243  STypeMapPosition = 'Map position';
     244  STypeImage = 'Image';
     245  STypeDate = 'Date';
     246  STypeTime = 'Time';
     247  STypeDateTime = 'Date and time';
     248  STypeReference = 'Reference';
     249
    207250
    208251implementation
    209252
    210253uses
    211   UDataTypes;
     254  UDataTypes,
     255  UEngineXML, UEngineMySQL, UEngineSQLite, UDbClientRegistry;
     256
     257{ TDbManager }
     258
     259procedure TDbManager.InitClientTypes;
     260var
     261  ClientType: TDbClientType;
     262begin
     263  ClientTypes.Clear;
     264
     265  ClientType := ClientTypes.RegisterClientType('XML file', TDatabaseXML, TDbConnectParamsXml);
     266  ClientType.UseTypes(DataTypes, [ftString, ftInteger, ftDateTime, ftBoolean, ftFloat]);
     267
     268  ClientType := ClientTypes.RegisterClientType('MySQL', TDatabaseMySQL, TDbConnectParamsMySql);
     269  ClientType.UseTypes(DataTypes, [ftString, ftInteger, ftDateTime, ftBoolean, ftFloat,
     270    ftReference]);
     271
     272  ClientType := ClientTypes.RegisterClientType('SQLite', TDatabaseSQLite, TDbConnectParamsSqlite);
     273  ClientType.UseTypes(DataTypes, [ftString, ftInteger, ftDateTime, ftBoolean, ftFloat]);
     274
     275  ClientType := ClientTypes.RegisterClientType('Registry', TDbClientRegistry, TDbConnectParamsRegistry);
     276  ClientType.UseTypes(DataTypes, [ftString, ftInteger]);
     277end;
     278
     279procedure TDbManager.InitDataTypes;
     280begin
     281  DataTypes.Clear;
     282  with DataTypes do begin
     283    RegisterType(1, 'String', STypeString, ftString, TFieldString);
     284    RegisterType(2, 'Integer', STypeInteger, ftInteger, TFieldInteger);
     285    RegisterType(3, 'DateTime', STypeDateTime, ftDateTime, TFieldDateTime);
     286    RegisterType(4, 'Boolean', STypeBoolean, ftBoolean, TFieldBoolean);
     287    RegisterType(5, 'Float', STypeFloat, ftFloat, TFieldFloat);
     288    RegisterType(6, 'MapPosition', STypeMapPosition, ftMapPosition, TFieldMapPosition);
     289    RegisterType(7, 'Date', STypeDate, ftDate, TFieldDate);
     290    RegisterType(8, 'Time', STypeTime, ftTime, TFieldTime);
     291    RegisterType(9, 'Image', STypeImage, ftImage, TFieldImage);
     292    RegisterType(10, 'Reference', STypeReference, ftReference, TFieldReference);
     293  end;
     294end;
     295
     296constructor TDbManager.Create;
     297begin
     298  ConnectProfiles := TDbConnectProfiles.Create;
     299  ConnectProfiles.DbManager := Self;
     300  ClientTypes := TDbClientTypes.Create;
     301  DataTypes := TDataTypes.Create;
     302  InitDataTypes;
     303  InitClientTypes;
     304end;
     305
     306destructor TDbManager.Destroy;
     307begin
     308  DataTypes.Free;
     309  ClientTypes.Free;
     310  ConnectProfiles.Free;
     311  inherited Destroy;
     312end;
     313
     314{ TDbConnectParams }
     315
     316procedure TDbConnectParams.SetConnectionString(AValue: string);
     317begin
     318  if FConnectionString = AValue then Exit;
     319  FConnectionString := AValue;
     320end;
     321
     322function TDbConnectParams.GetConnectionString: string;
     323begin
     324  Result := FConnectionString;
     325end;
     326
     327{ TDbConnectProfiles }
     328
     329procedure TDbConnectProfiles.LoadFromRegistry(Context: TRegistryContext);
     330var
     331  I: Integer;
     332  ConnectProfile: TDbConnectProfile;
     333  ClientType: TDbClientType;
     334begin
     335  with TRegistryEx.Create do
     336  try
     337    CurrentContext := Context;
     338    Count := GetValue('Count', 0);
     339    for I := 0 to Count - 1 do begin
     340      OpenKey(Context.Key + '\Item' + IntToStr(I), True);
     341      ClientType := DbManager.ClientTypes.FindByName(GetValue('ClientType', ''));
     342      if not Assigned(ClientType) and (DbManager.ClientTypes.Count > 0) then
     343        ClientType := TDbClientType(DbManager.ClientTypes[0]);
     344
     345      ConnectProfile := TDbConnectProfile.Create;
     346      ConnectProfile.ClientType := ClientType;
     347      ConnectProfile.Name := GetValue('Name', '');
     348      ConnectProfile.Params.ConnectionString := GetValue('ConnectionString', '');
     349      Items[I] := ConnectProfile;
     350    end;
     351  finally
     352    Free;
     353  end;
     354end;
     355
     356procedure TDbConnectProfiles.SaveToRegistry(Context: TRegistryContext);
     357var
     358  I: Integer;
     359begin
     360  with TRegistryEx.Create do
     361  try
     362    CurrentContext := Context;
     363    SetValue('Count', Count);
     364    for I := 0 to Count - 1 do begin
     365      OpenKey(Context.Key + '\Item' + IntToStr(I), True);
     366      SetValue('Name', TDbConnectProfile(Items[I]).Name);
     367      SetValue('ConnectionString', TDbConnectProfile(Items[I]).Params.ConnectionString);
     368      SetValue('ClientType', TDbConnectProfile(Items[I]).ClientType.Name);
     369    end;
     370  finally
     371    Free;
     372  end;
     373end;
     374
     375function TDbConnectProfiles.FindByName(Name: string): TDbConnectProfile;
     376var
     377  I: Integer;
     378begin
     379  I := 0;
     380  while (I < Count) and (TDbConnectProfile(Items[I]).Name <> Name) do Inc(I);
     381  if (I < Count) then Result := TDbConnectProfile(Items[I])
     382    else Result := nil;
     383end;
     384
     385{ TDbConnectProfile }
     386
     387procedure TDbConnectProfile.SetClientType(AValue: TDbClientType);
     388begin
     389  if FClientType = AValue then Exit;
     390  if Assigned(FClientType) then begin
     391    Params.Free;
     392  end;
     393  FClientType := AValue;
     394  if Assigned(FClientType) then begin
     395    Params := FClientType.ConnectParmasClass.Create;
     396  end;
     397end;
    212398
    213399{ TTables }
     
    223409end;
    224410
    225 { TDatabases }
    226 
    227 function TDatabases.FindByName(Name: string): TDatabase;
    228 var
    229   I: Integer;
    230 begin
    231   I := 0;
    232   while (I < Count) and (TDatabase(Items[I]).Name <> Name) do Inc(I);
    233   if (I < Count) then Result := TDatabase(Items[I])
    234     else Result := nil;
    235 end;
    236 
    237 { TDatabaseClient }
    238 
    239 procedure TDatabaseClient.Query(DbRows: TDbRows; Text: string);
    240 begin
    241 end;
    242 
    243 constructor TDatabaseClient.Create;
    244 begin
    245 end;
    246 
    247 procedure TDatabaseClient.Load;
    248 begin
    249 
    250 end;
    251 
    252 procedure TDatabaseClient.Save;
    253 begin
    254 
    255 end;
    256 
    257 { TDatabaseEngines }
    258 
    259 function TDatabaseEngines.RegisterEngine(Name: string;
    260   DatabaseClass: TDatabaseClientClass): TDatabaseEngine;
    261 begin
    262   Result := TDatabaseEngine.Create;
     411{ TDbClient }
     412
     413function TDbClient.GetClientType: TDbClientType;
     414begin
     415  Result := FConnectProfile.ClientType;
     416end;
     417
     418procedure TDbClient.SetConnectProfile(AValue: TDbConnectProfile);
     419begin
     420  if FConnectProfile = AValue then Exit;
     421  FConnectProfile := AValue;
     422end;
     423
     424procedure TDbClient.Query(DbRows: TDbRows; Text: string);
     425begin
     426end;
     427
     428procedure TDbClient.LoadTables(Tables: TTables);
     429begin
     430  Tables.Clear;
     431end;
     432
     433constructor TDbClient.Create;
     434begin
     435  inherited;
     436end;
     437
     438procedure TDbClient.Load;
     439begin
     440
     441end;
     442
     443procedure TDbClient.Save;
     444begin
     445
     446end;
     447
     448{ TDbClientTypes }
     449
     450function TDbClientTypes.RegisterClientType(Name: string;
     451  DatabaseClass: TDbClientClass; ConnectParamsClass: TDbConnectParamsClass): TDbClientType;
     452begin
     453  Result := TDbClientType.Create;
    263454  Result.Name := Name;
    264455  Result.DatabaseClientClass := DatabaseClass;
     456  Result.ConnectParmasClass := ConnectParamsClass;
    265457  Add(Result);
    266458end;
    267459
    268 function TDatabaseEngines.FindByName(Name: string): TDatabaseEngine;
     460function TDbClientTypes.FindByName(Name: string): TDbClientType;
    269461var
    270462  I: Integer;
    271463begin
    272464  I := 0;
    273   while (I < Count) and (TDatabaseEngine(Items[I]).Name <> Name) do Inc(I);
    274   if I < Count then Result := TDatabaseEngine(Items[I])
     465  while (I < Count) and (TDbClientType(Items[I]).Name <> Name) do Inc(I);
     466  if I < Count then Result := TDbClientType(Items[I])
    275467    else Result := nil;
    276468end;
     
    310502end;
    311503
    312 { TDatabaseEngine }
    313 
    314 procedure TDatabaseEngine.UseTypes(ADataTypes: TDataTypes; Types: TFieldTypeSet);
     504{ TDbClientType }
     505
     506procedure TDbClientType.UseTypes(ADataTypes: TDataTypes; Types: TFieldTypeSet);
    315507var
    316508  I: TFieldType;
     
    321513end;
    322514
    323 constructor TDatabaseEngine.Create;
     515constructor TDbClientType.Create;
    324516begin
    325517  DataTypes := TDataTypes.Create;
     
    327519end;
    328520
    329 destructor TDatabaseEngine.Destroy;
     521destructor TDbClientType.Destroy;
    330522begin
    331523  DataTypes.Free;
     
    506698  Records.Clear;
    507699  DbRows := TDbRows.Create;
    508   Database.Client.Query(DbRows, 'SELECT * FROM ' + Name);
     700  DbClient.Query(DbRows, 'SELECT * FROM ' + Name);
    509701  for I := 0 to DbRows.Count - 1 do begin
    510702    NewRecord := TRecord.Create;
     
    531723  Records.Clear;
    532724  DbRows := TDbRows.Create;
    533   Database.Client.Query(DbRows, 'SELECT COUNT(*) FROM ' + Name);
     725  DbClient.Query(DbRows, 'SELECT COUNT(*) FROM ' + Name);
    534726  if DbRows.Count = 1 then begin
    535727    RecordsCount := StrToInt(TDictionaryStringString(DbRows[0]).Items[0].Value);
     
    561753end;
    562754
    563 { TDatabase }
    564 
    565 procedure TDatabase.SetEngine(AValue: TDatabaseEngine);
    566 begin
    567   if FEngine = AValue then Exit;
    568   if Assigned(Client) then
    569     Client.Free;
    570   FEngine := AValue;
    571   if Assigned(FEngine) then begin
    572     Client := Engine.DatabaseClientClass.Create;
    573     Client.Database := Self;
    574   end;
    575 end;
    576 
    577 constructor TDatabase.Create;
    578 begin
    579   Tables := TTables.Create;
    580   Tables.Database := Self;
    581   Engine := nil;
    582 end;
    583 
    584 destructor TDatabase.Destroy;
    585 begin
    586   Engine := nil;
    587   Tables.Free;
    588   inherited Destroy;
    589 end;
    590 
    591 procedure TDatabase.Load;
    592 begin
    593   if Assigned(Client) then Client.Load;
    594 end;
    595 
    596 procedure TDatabase.Save;
    597 begin
    598   if Assigned(Client) then Client.Save;
    599 end;
    600 
    601 procedure TDatabase.Clear;
    602 begin
    603   Tables.Clear;
    604 end;
    605 
    606755end.
    607756
Note: See TracChangeset for help on using the changeset viewer.