Changeset 20 for trunk/UDatabase.pas
- Timestamp:
- Mar 23, 2018, 1:59:25 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UDatabase.pas
r15 r20 7 7 uses 8 8 Classes, SysUtils, Contnrs, ExtCtrls, StdCtrls, EditBtn, dialogs, USqlDatabase, 9 SpecializedDictionary ;9 SpecializedDictionary, URegistry; 10 10 11 11 type 12 12 TTable = class; 13 TDatabaseEngine = class; 14 TDatabaseClient = class; 15 TDatabase = class; 13 TDbClientType = class; 14 TDbClient = class; 16 15 TDataType = class; 16 TDbManager = class; 17 17 18 18 TFieldType = (ftString, ftInteger, ftDateTime, ftBoolean, ftFloat, ftImage, … … 104 104 Records: TRecords; 105 105 Fields: TFields; 106 D atabase: TDatabase;106 DbClient: TDbClient; 107 107 RecordsCount: Integer; 108 108 procedure LoadRecords; … … 116 116 117 117 TTables = class(TObjectList) 118 D atabase: TDatabase;118 DbClient: TDbClient; 119 119 function SearchByName(Name: string): TTable; 120 120 end; 121 121 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 127 139 private 128 F Engine: TDatabaseEngine;129 procedure Set Engine(AValue: TDatabaseEngine);140 FClientType: TDbClientType; 141 procedure SetClientType(AValue: TDbClientType); 130 142 public 131 143 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; 150 156 151 157 { TDataType } … … 168 174 end; 169 175 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 174 185 procedure Query(DbRows: TDbRows; Text: string); virtual; 186 procedure LoadTables(Tables: TTables); virtual; 175 187 constructor Create; virtual; 176 188 procedure Load; virtual; 177 189 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; 181 196 182 197 TFieldTypeSet = set of TFieldType; 183 198 184 { TD atabaseEngine }185 186 TD atabaseEngine = class199 { TDbClientType } 200 201 TDbClientType = class 187 202 Name: string; 188 203 DataTypes: TDataTypes; 189 DatabaseClientClass: TDatabaseClientClass; 204 DatabaseClientClass: TDbClientClass; 205 ConnectParmasClass: TDbConnectParamsClass; 190 206 procedure UseTypes(ADataTypes: TDataTypes; Types: TFieldTypeSet); 191 207 constructor Create; … … 193 209 end; 194 210 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; 200 217 end; 201 218 … … 205 222 end; 206 223 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 238 resourcestring 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 207 250 208 251 implementation 209 252 210 253 uses 211 UDataTypes; 254 UDataTypes, 255 UEngineXML, UEngineMySQL, UEngineSQLite, UDbClientRegistry; 256 257 { TDbManager } 258 259 procedure TDbManager.InitClientTypes; 260 var 261 ClientType: TDbClientType; 262 begin 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]); 277 end; 278 279 procedure TDbManager.InitDataTypes; 280 begin 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; 294 end; 295 296 constructor TDbManager.Create; 297 begin 298 ConnectProfiles := TDbConnectProfiles.Create; 299 ConnectProfiles.DbManager := Self; 300 ClientTypes := TDbClientTypes.Create; 301 DataTypes := TDataTypes.Create; 302 InitDataTypes; 303 InitClientTypes; 304 end; 305 306 destructor TDbManager.Destroy; 307 begin 308 DataTypes.Free; 309 ClientTypes.Free; 310 ConnectProfiles.Free; 311 inherited Destroy; 312 end; 313 314 { TDbConnectParams } 315 316 procedure TDbConnectParams.SetConnectionString(AValue: string); 317 begin 318 if FConnectionString = AValue then Exit; 319 FConnectionString := AValue; 320 end; 321 322 function TDbConnectParams.GetConnectionString: string; 323 begin 324 Result := FConnectionString; 325 end; 326 327 { TDbConnectProfiles } 328 329 procedure TDbConnectProfiles.LoadFromRegistry(Context: TRegistryContext); 330 var 331 I: Integer; 332 ConnectProfile: TDbConnectProfile; 333 ClientType: TDbClientType; 334 begin 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; 354 end; 355 356 procedure TDbConnectProfiles.SaveToRegistry(Context: TRegistryContext); 357 var 358 I: Integer; 359 begin 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; 373 end; 374 375 function TDbConnectProfiles.FindByName(Name: string): TDbConnectProfile; 376 var 377 I: Integer; 378 begin 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; 383 end; 384 385 { TDbConnectProfile } 386 387 procedure TDbConnectProfile.SetClientType(AValue: TDbClientType); 388 begin 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; 397 end; 212 398 213 399 { TTables } … … 223 409 end; 224 410 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 413 function TDbClient.GetClientType: TDbClientType; 414 begin 415 Result := FConnectProfile.ClientType; 416 end; 417 418 procedure TDbClient.SetConnectProfile(AValue: TDbConnectProfile); 419 begin 420 if FConnectProfile = AValue then Exit; 421 FConnectProfile := AValue; 422 end; 423 424 procedure TDbClient.Query(DbRows: TDbRows; Text: string); 425 begin 426 end; 427 428 procedure TDbClient.LoadTables(Tables: TTables); 429 begin 430 Tables.Clear; 431 end; 432 433 constructor TDbClient.Create; 434 begin 435 inherited; 436 end; 437 438 procedure TDbClient.Load; 439 begin 440 441 end; 442 443 procedure TDbClient.Save; 444 begin 445 446 end; 447 448 { TDbClientTypes } 449 450 function TDbClientTypes.RegisterClientType(Name: string; 451 DatabaseClass: TDbClientClass; ConnectParamsClass: TDbConnectParamsClass): TDbClientType; 452 begin 453 Result := TDbClientType.Create; 263 454 Result.Name := Name; 264 455 Result.DatabaseClientClass := DatabaseClass; 456 Result.ConnectParmasClass := ConnectParamsClass; 265 457 Add(Result); 266 458 end; 267 459 268 function TD atabaseEngines.FindByName(Name: string): TDatabaseEngine;460 function TDbClientTypes.FindByName(Name: string): TDbClientType; 269 461 var 270 462 I: Integer; 271 463 begin 272 464 I := 0; 273 while (I < Count) and (TD atabaseEngine(Items[I]).Name <> Name) do Inc(I);274 if I < Count then Result := TD atabaseEngine(Items[I])465 while (I < Count) and (TDbClientType(Items[I]).Name <> Name) do Inc(I); 466 if I < Count then Result := TDbClientType(Items[I]) 275 467 else Result := nil; 276 468 end; … … 310 502 end; 311 503 312 { TD atabaseEngine }313 314 procedure TD atabaseEngine.UseTypes(ADataTypes: TDataTypes; Types: TFieldTypeSet);504 { TDbClientType } 505 506 procedure TDbClientType.UseTypes(ADataTypes: TDataTypes; Types: TFieldTypeSet); 315 507 var 316 508 I: TFieldType; … … 321 513 end; 322 514 323 constructor TD atabaseEngine.Create;515 constructor TDbClientType.Create; 324 516 begin 325 517 DataTypes := TDataTypes.Create; … … 327 519 end; 328 520 329 destructor TD atabaseEngine.Destroy;521 destructor TDbClientType.Destroy; 330 522 begin 331 523 DataTypes.Free; … … 506 698 Records.Clear; 507 699 DbRows := TDbRows.Create; 508 D atabase.Client.Query(DbRows, 'SELECT * FROM ' + Name);700 DbClient.Query(DbRows, 'SELECT * FROM ' + Name); 509 701 for I := 0 to DbRows.Count - 1 do begin 510 702 NewRecord := TRecord.Create; … … 531 723 Records.Clear; 532 724 DbRows := TDbRows.Create; 533 D atabase.Client.Query(DbRows, 'SELECT COUNT(*) FROM ' + Name);725 DbClient.Query(DbRows, 'SELECT COUNT(*) FROM ' + Name); 534 726 if DbRows.Count = 1 then begin 535 727 RecordsCount := StrToInt(TDictionaryStringString(DbRows[0]).Items[0].Value); … … 561 753 end; 562 754 563 { TDatabase }564 565 procedure TDatabase.SetEngine(AValue: TDatabaseEngine);566 begin567 if FEngine = AValue then Exit;568 if Assigned(Client) then569 Client.Free;570 FEngine := AValue;571 if Assigned(FEngine) then begin572 Client := Engine.DatabaseClientClass.Create;573 Client.Database := Self;574 end;575 end;576 577 constructor TDatabase.Create;578 begin579 Tables := TTables.Create;580 Tables.Database := Self;581 Engine := nil;582 end;583 584 destructor TDatabase.Destroy;585 begin586 Engine := nil;587 Tables.Free;588 inherited Destroy;589 end;590 591 procedure TDatabase.Load;592 begin593 if Assigned(Client) then Client.Load;594 end;595 596 procedure TDatabase.Save;597 begin598 if Assigned(Client) then Client.Save;599 end;600 601 procedure TDatabase.Clear;602 begin603 Tables.Clear;604 end;605 606 755 end. 607 756
Note:
See TracChangeset
for help on using the changeset viewer.