source: trunk/Packages/PersistentData/UPDClient.pas

Last change on this file was 149, checked in by chronos, 9 months ago
  • Modified: Update Common package.
  • Added: Project group.
  • Modified: Assign ModuleUser to modules which use it in later time.
File size: 10.8 KB
Line 
1unit UPDClient;
2
3interface
4
5uses
6 Classes, SysUtils, Generics.Collections, Generics;
7
8const
9 SystemVersionObject = 'SystemVersion';
10
11type
12 EClientNotSet = class(Exception);
13
14 TPDClient = class;
15 TPDType = class;
16
17 TOrderDirection = (odNone, odAscending, odDescending);
18
19 { TObjectProxy }
20
21 TObjectProxy = class
22 Id: Integer;
23 Properties: TDictionaryStringString;
24 Client: TPDClient;
25 ObjectName: string;
26 Path: string;
27 procedure Load;
28 procedure Save;
29 procedure Delete;
30 constructor Create;
31 destructor Destroy; override;
32 procedure Assign(Source: TObjectProxy);
33 end;
34
35 { TObjectProxies }
36
37 TObjectProxies = class(TObjectList<TObjectProxy>)
38 function AddProxy: TObjectProxy;
39 end;
40
41 TOperation = (opUndefined, opDefined, opEqual, opNotEqual,
42 opLess, opMore, opLessOrEqual, opMoreOrEqual);
43
44 TCondition = class
45 Column: string;
46 Operation: TOperation;
47 Value: string;
48 end;
49
50 { TListProxy }
51
52 TListProxy = class
53 Client: TPDClient;
54 OrderColumn: string;
55 OrderDirection: TOrderDirection;
56 OrderUse: Boolean;
57 PageItemFirst: Integer;
58 PageItemCount: Integer;
59 PageUse: Boolean;
60 ColumnsFilter: TListString;
61 ColummsFilterUse: Boolean;
62 Condition: string;
63 ObjectName: string;
64 Path: string;
65 Objects: TObjectList<TObjectProxy>;
66 procedure Clear;
67 constructor Create;
68 destructor Destroy; override;
69 procedure Load; virtual;
70 procedure Save; virtual;
71 end;
72
73 TPDTypeProperty = class
74 Name: string;
75 DbType: TPDType;
76 Unique: Boolean;
77 Index: Boolean;
78 end;
79
80 { TPDTypeProperties }
81
82 TPDTypeProperties = class(TObjectList<TPDTypeProperty>)
83 Client: TPDClient;
84 function AddSimple(Name: string; TypeName: string; Unique: Boolean = False;
85 Index: Boolean = False): TPDTypeProperty;
86 end;
87
88 { TPDType }
89
90 TPDType = class
91 private
92 FClient: TPDClient;
93 procedure SetClient(AValue: TPDClient);
94 public
95 Name: string;
96 DbType: string;
97 Properties: TPDTypeProperties;
98 function IsDefined: Boolean;
99 procedure Define;
100 procedure Undefine;
101 constructor Create;
102 destructor Destroy; override;
103 property Client: TPDClient read FClient write SetClient;
104 end;
105
106 { TPDTypes }
107
108 TPDTypes = class(TObjectList<TPDType>)
109 Client: TPDClient;
110 function AddType(Name: string; DbType: string = ''): TPDType;
111 function SearchByName(Name: string): TPDType;
112 end;
113
114 { TPDClient }
115
116 TPDClient = class(TComponent)
117 private
118 FSchema: string;
119 procedure SetConnected(AValue: Boolean);
120 protected
121 procedure InitSystemTypes; virtual;
122 procedure Init; virtual;
123 function GetConnected: Boolean; virtual;
124 function GetConnectionString: string; virtual;
125 procedure SetConnectionString(AValue: string); virtual;
126 public
127 Types: TPDTypes;
128 Version: string;
129 BackendName: string;
130 procedure ObjectLoad(AObject: TObjectProxy); virtual; abstract;
131 procedure ObjectSave(AObject: TObjectProxy); virtual; abstract;
132 procedure ObjectDelete(AObject: TObjectProxy); virtual; abstract;
133 procedure ListLoad(AList: TListProxy); virtual; abstract;
134 procedure ListSave(AList: TListProxy); virtual; abstract;
135 function TypeIsDefined(AType: TPDType): Boolean; virtual; abstract;
136 procedure TypeDefine(AType: TPDType); virtual; abstract;
137 procedure TypeUndefine(AType: TPDType); virtual; abstract;
138 procedure CheckTypes;
139 constructor Create(AOwner: TComponent); override;
140 destructor Destroy; override;
141 procedure Connect; virtual;
142 procedure Disconnect; virtual;
143 procedure Install; virtual;
144 procedure Uninstall; virtual;
145 procedure Update; virtual;
146 published
147 property Schema: string read FSchema write FSchema;
148 property Connected: Boolean read GetConnected write SetConnected;
149 property ConnectionString: string read GetConnectionString
150 write SetConnectionString;
151 end;
152
153 TPDClientClass = class of TPDClient;
154
155resourcestring
156 SClientNotSet = 'Client not set';
157 SNotSupported = 'Not supported';
158 SVersionMismatch = 'Version mismatch, client: %0:s, server: %1:s. Please upgrade database.';
159 SCantLoadObjectWithoutId = 'Can''t load object without id';
160
161
162implementation
163
164{ TObjectProxies }
165
166function TObjectProxies.AddProxy: TObjectProxy;
167begin
168 Result := TObjectProxy.Create;
169 Add(Result);
170end;
171
172{ TPDTypeProperties }
173
174function TPDTypeProperties.AddSimple(Name: string; TypeName: string;
175 Unique: Boolean = False; Index: Boolean = False): TPDTypeProperty;
176begin
177 Result := TPDTypeProperty.Create;
178 Result.Name := Name;
179 Result.DbType := Client.Types.SearchByName(TypeName);
180 Result.Unique := Unique;
181 Result.Index := Index;
182 Add(Result);
183end;
184
185{ TPDTypes }
186
187function TPDTypes.AddType(Name: string; DbType: string = ''): TPDType;
188begin
189 Result := TPDType.Create;
190 Result.Client := Client;
191 Result.Name := Name;
192 Result.DbType := DbType;
193 Add(Result);
194end;
195
196function TPDTypes.SearchByName(Name: string): TPDType;
197var
198 I: Integer;
199begin
200 I := 0;
201 while (I < Count) and (TPDType(Items[I]).Name <> Name) do Inc(I);
202 if I < Count then Result := TPDType(Items[I])
203 else Result := nil;
204end;
205
206procedure TPDType.SetClient(AValue: TPDClient);
207begin
208 if FClient = AValue then Exit;
209 FClient := AValue;
210 Properties.Client := AValue;
211end;
212
213function TPDType.IsDefined: Boolean;
214begin
215 if Assigned(Client) then Result := Client.TypeIsDefined(Self)
216 else raise EClientNotSet.Create(SClientNotSet);
217end;
218
219procedure TPDType.Define;
220begin
221 if Assigned(Client) then Client.TypeDefine(Self)
222 else raise EClientNotSet.Create(SClientNotSet);
223end;
224
225procedure TPDType.Undefine;
226begin
227 if Assigned(Client) then Client.TypeUndefine(Self)
228 else raise EClientNotSet.Create(SClientNotSet);
229end;
230
231constructor TPDType.Create;
232begin
233 Properties := TPDTypeProperties.Create;
234end;
235
236destructor TPDType.Destroy;
237begin
238 FreeAndNil(Properties);
239 inherited;
240end;
241
242{ TObjectProxy }
243
244procedure TObjectProxy.Load;
245begin
246 if Assigned(Client) then Client.ObjectLoad(Self)
247 else raise EClientNotSet.Create(SClientNotSet);
248end;
249
250procedure TObjectProxy.Save;
251begin
252 if Assigned(Client) then Client.ObjectSave(Self)
253 else raise EClientNotSet.Create(SClientNotSet);
254end;
255
256procedure TObjectProxy.Delete;
257begin
258 if Assigned(Client) then Client.ObjectDelete(Self)
259 else raise EClientNotSet.Create(SClientNotSet);
260end;
261
262constructor TObjectProxy.Create;
263begin
264 Properties := TDictionaryStringString.Create;
265end;
266
267destructor TObjectProxy.Destroy;
268begin
269 FreeAndNil(Properties);
270 inherited;
271end;
272
273procedure TObjectProxy.Assign(Source: TObjectProxy);
274begin
275 Path := Source.Path;
276 Client := Source.Client;
277 ObjectName := Source.ObjectName;
278 Id := Source.Id;
279 Properties.Assign(Source.Properties);
280end;
281
282{ TListProxy }
283
284procedure TListProxy.Clear;
285begin
286 PageUse := False;
287 ColummsFilterUse := False;
288 OrderUse := False;
289 Objects.Free;
290end;
291
292constructor TListProxy.Create;
293begin
294 ColumnsFilter := TListString.Create;
295 Objects := TObjectList<TObjectProxy>.Create;
296end;
297
298destructor TListProxy.Destroy;
299begin
300 FreeAndNil(Objects);
301 FreeAndNil(ColumnsFilter);
302 inherited;
303end;
304
305procedure TListProxy.Load;
306begin
307 if Assigned(Client) then Client.ListLoad(Self)
308 else raise EClientNotSet.Create(SClientNotSet);
309end;
310
311procedure TListProxy.Save;
312begin
313 if Assigned(Client) then Client.ListSave(Self)
314 else raise EClientNotSet.Create(SClientNotSet);
315end;
316
317{ TPDClient }
318
319function TPDClient.GetConnectionString: string;
320begin
321 Result := '';
322end;
323
324procedure TPDClient.SetConnectionString(AValue: string);
325begin
326end;
327
328procedure TPDClient.SetConnected(AValue: Boolean);
329begin
330 if AValue then Connect else Disconnect;
331end;
332
333procedure TPDClient.InitSystemTypes;
334begin
335end;
336
337procedure TPDClient.Init;
338var
339 NewProxy: TListProxy;
340 NewType: TPDType;
341 NewObject: TObjectProxy;
342 DbVersion: string;
343begin
344 NewProxy := TListProxy.Create;
345 NewProxy.Client := Self;
346 NewProxy.Path := 'information_schema';
347 NewProxy.ObjectName := 'TABLES';
348 NewProxy.Condition := '(TABLE_SCHEMA = "' + Schema +
349 '") AND (TABLE_NAME = "' + SystemVersionObject + '")';
350 NewProxy.Load;
351 if NewProxy.Objects.Count > 0 then begin
352 NewObject := TObjectProxy.Create;
353 NewObject.Client := Self;
354 NewObject.Path := Schema;
355 NewObject.ObjectName := SystemVersionObject;
356 NewObject.Id := 1;
357 NewObject.Load;
358
359 DbVersion := NewObject.Properties.Items['Version'];
360 if Version <> DbVersion then
361 raise Exception.Create(Format(SVersionMismatch, [Version, DbVersion]));
362 end else begin
363 NewType := TPDType.Create;
364 NewType.Client := Self;
365 NewType.Name := SystemVersionObject;
366 NewType.Properties.AddSimple('Version', 'String');
367 NewType.Properties.AddSimple('Time', 'DateTime');
368 NewType.Define;
369
370 NewObject := TObjectProxy.Create;
371 NewObject.Client := Self;
372 NewObject.Path := Schema;
373 NewObject.ObjectName := SystemVersionObject;
374 NewObject.Properties.Add('Version', Version);
375 NewObject.Properties.Add('Time', 'NOW()');
376 NewObject.Save;
377
378 Install;
379 end;
380end;
381
382function TPDClient.GetConnected: Boolean;
383begin
384 Result := False;
385end;
386
387procedure TPDClient.CheckTypes;
388var
389 StructureVersion: string;
390 Data: TDictionaryStringString;
391 ObjectId: Integer;
392 Tables: TListString;
393 I: Integer;
394 NewProxy: TListProxy;
395begin
396 try
397 Tables := TListString.Create;
398 Data := TDictionaryStringString.Create;
399
400 NewProxy := TListProxy.Create;
401 NewProxy.Client := Self;
402 NewProxy.Path := 'information_schema';
403 NewProxy.ObjectName := 'TABLES';
404 NewProxy.Condition := 'TABLE_SCHEMA = "' + Schema + '"';
405 NewProxy.Load;
406 //Database.Query(DbRows, 'SHOW TABLES');
407 Tables.Count := NewProxy.Objects.Count;
408 for I := 0 to NewProxy.Objects.Count - 1 do
409 Tables[I] := TObjectProxy(NewProxy.Objects[I]).Properties.Items['TABLE_NAME'];
410
411 for I := 0 to Types.Count - 1 do
412 with TPDType(Types[I]) do begin
413 if (DbType = '') and (Tables.IndexOf(Name) = -1) then begin
414 Define;
415 end;
416 end;
417 finally
418 NewProxy.Free;
419 Data.Free;
420 Tables.Free;
421 end;
422end;
423
424constructor TPDClient.Create(AOwner: TComponent);
425begin
426 inherited;
427 Types := TPDTypes.Create;
428 Types.Client := Self;
429 InitSystemTypes;
430end;
431
432destructor TPDClient.Destroy;
433begin
434 FreeAndNil(Types);
435 inherited;
436end;
437
438procedure TPDClient.Connect;
439begin
440end;
441
442procedure TPDClient.Disconnect;
443begin
444end;
445
446procedure TPDClient.Install;
447begin
448end;
449
450procedure TPDClient.Uninstall;
451begin
452 //Types.Uninstall;
453end;
454
455procedure TPDClient.Update;
456begin
457end;
458
459end.
460
Note: See TracBrowser for help on using the repository browser.