1 | unit UPDClient;
|
---|
2 |
|
---|
3 | interface
|
---|
4 |
|
---|
5 | uses
|
---|
6 | Classes, SysUtils, Generics.Collections, Generics;
|
---|
7 |
|
---|
8 | const
|
---|
9 | SystemVersionObject = 'SystemVersion';
|
---|
10 |
|
---|
11 | type
|
---|
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 |
|
---|
155 | resourcestring
|
---|
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 |
|
---|
162 | implementation
|
---|
163 |
|
---|
164 | { TObjectProxies }
|
---|
165 |
|
---|
166 | function TObjectProxies.AddProxy: TObjectProxy;
|
---|
167 | begin
|
---|
168 | Result := TObjectProxy.Create;
|
---|
169 | Add(Result);
|
---|
170 | end;
|
---|
171 |
|
---|
172 | { TPDTypeProperties }
|
---|
173 |
|
---|
174 | function TPDTypeProperties.AddSimple(Name: string; TypeName: string;
|
---|
175 | Unique: Boolean = False; Index: Boolean = False): TPDTypeProperty;
|
---|
176 | begin
|
---|
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);
|
---|
183 | end;
|
---|
184 |
|
---|
185 | { TPDTypes }
|
---|
186 |
|
---|
187 | function TPDTypes.AddType(Name: string; DbType: string = ''): TPDType;
|
---|
188 | begin
|
---|
189 | Result := TPDType.Create;
|
---|
190 | Result.Client := Client;
|
---|
191 | Result.Name := Name;
|
---|
192 | Result.DbType := DbType;
|
---|
193 | Add(Result);
|
---|
194 | end;
|
---|
195 |
|
---|
196 | function TPDTypes.SearchByName(Name: string): TPDType;
|
---|
197 | var
|
---|
198 | I: Integer;
|
---|
199 | begin
|
---|
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;
|
---|
204 | end;
|
---|
205 |
|
---|
206 | procedure TPDType.SetClient(AValue: TPDClient);
|
---|
207 | begin
|
---|
208 | if FClient = AValue then Exit;
|
---|
209 | FClient := AValue;
|
---|
210 | Properties.Client := AValue;
|
---|
211 | end;
|
---|
212 |
|
---|
213 | function TPDType.IsDefined: Boolean;
|
---|
214 | begin
|
---|
215 | if Assigned(Client) then Result := Client.TypeIsDefined(Self)
|
---|
216 | else raise EClientNotSet.Create(SClientNotSet);
|
---|
217 | end;
|
---|
218 |
|
---|
219 | procedure TPDType.Define;
|
---|
220 | begin
|
---|
221 | if Assigned(Client) then Client.TypeDefine(Self)
|
---|
222 | else raise EClientNotSet.Create(SClientNotSet);
|
---|
223 | end;
|
---|
224 |
|
---|
225 | procedure TPDType.Undefine;
|
---|
226 | begin
|
---|
227 | if Assigned(Client) then Client.TypeUndefine(Self)
|
---|
228 | else raise EClientNotSet.Create(SClientNotSet);
|
---|
229 | end;
|
---|
230 |
|
---|
231 | constructor TPDType.Create;
|
---|
232 | begin
|
---|
233 | Properties := TPDTypeProperties.Create;
|
---|
234 | end;
|
---|
235 |
|
---|
236 | destructor TPDType.Destroy;
|
---|
237 | begin
|
---|
238 | FreeAndNil(Properties);
|
---|
239 | inherited;
|
---|
240 | end;
|
---|
241 |
|
---|
242 | { TObjectProxy }
|
---|
243 |
|
---|
244 | procedure TObjectProxy.Load;
|
---|
245 | begin
|
---|
246 | if Assigned(Client) then Client.ObjectLoad(Self)
|
---|
247 | else raise EClientNotSet.Create(SClientNotSet);
|
---|
248 | end;
|
---|
249 |
|
---|
250 | procedure TObjectProxy.Save;
|
---|
251 | begin
|
---|
252 | if Assigned(Client) then Client.ObjectSave(Self)
|
---|
253 | else raise EClientNotSet.Create(SClientNotSet);
|
---|
254 | end;
|
---|
255 |
|
---|
256 | procedure TObjectProxy.Delete;
|
---|
257 | begin
|
---|
258 | if Assigned(Client) then Client.ObjectDelete(Self)
|
---|
259 | else raise EClientNotSet.Create(SClientNotSet);
|
---|
260 | end;
|
---|
261 |
|
---|
262 | constructor TObjectProxy.Create;
|
---|
263 | begin
|
---|
264 | Properties := TDictionaryStringString.Create;
|
---|
265 | end;
|
---|
266 |
|
---|
267 | destructor TObjectProxy.Destroy;
|
---|
268 | begin
|
---|
269 | FreeAndNil(Properties);
|
---|
270 | inherited;
|
---|
271 | end;
|
---|
272 |
|
---|
273 | procedure TObjectProxy.Assign(Source: TObjectProxy);
|
---|
274 | begin
|
---|
275 | Path := Source.Path;
|
---|
276 | Client := Source.Client;
|
---|
277 | ObjectName := Source.ObjectName;
|
---|
278 | Id := Source.Id;
|
---|
279 | Properties.Assign(Source.Properties);
|
---|
280 | end;
|
---|
281 |
|
---|
282 | { TListProxy }
|
---|
283 |
|
---|
284 | procedure TListProxy.Clear;
|
---|
285 | begin
|
---|
286 | PageUse := False;
|
---|
287 | ColummsFilterUse := False;
|
---|
288 | OrderUse := False;
|
---|
289 | Objects.Free;
|
---|
290 | end;
|
---|
291 |
|
---|
292 | constructor TListProxy.Create;
|
---|
293 | begin
|
---|
294 | ColumnsFilter := TListString.Create;
|
---|
295 | Objects := TObjectList<TObjectProxy>.Create;
|
---|
296 | end;
|
---|
297 |
|
---|
298 | destructor TListProxy.Destroy;
|
---|
299 | begin
|
---|
300 | FreeAndNil(Objects);
|
---|
301 | FreeAndNil(ColumnsFilter);
|
---|
302 | inherited;
|
---|
303 | end;
|
---|
304 |
|
---|
305 | procedure TListProxy.Load;
|
---|
306 | begin
|
---|
307 | if Assigned(Client) then Client.ListLoad(Self)
|
---|
308 | else raise EClientNotSet.Create(SClientNotSet);
|
---|
309 | end;
|
---|
310 |
|
---|
311 | procedure TListProxy.Save;
|
---|
312 | begin
|
---|
313 | if Assigned(Client) then Client.ListSave(Self)
|
---|
314 | else raise EClientNotSet.Create(SClientNotSet);
|
---|
315 | end;
|
---|
316 |
|
---|
317 | { TPDClient }
|
---|
318 |
|
---|
319 | function TPDClient.GetConnectionString: string;
|
---|
320 | begin
|
---|
321 | Result := '';
|
---|
322 | end;
|
---|
323 |
|
---|
324 | procedure TPDClient.SetConnectionString(AValue: string);
|
---|
325 | begin
|
---|
326 | end;
|
---|
327 |
|
---|
328 | procedure TPDClient.SetConnected(AValue: Boolean);
|
---|
329 | begin
|
---|
330 | if AValue then Connect else Disconnect;
|
---|
331 | end;
|
---|
332 |
|
---|
333 | procedure TPDClient.InitSystemTypes;
|
---|
334 | begin
|
---|
335 | end;
|
---|
336 |
|
---|
337 | procedure TPDClient.Init;
|
---|
338 | var
|
---|
339 | NewProxy: TListProxy;
|
---|
340 | NewType: TPDType;
|
---|
341 | NewObject: TObjectProxy;
|
---|
342 | DbVersion: string;
|
---|
343 | begin
|
---|
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;
|
---|
380 | end;
|
---|
381 |
|
---|
382 | function TPDClient.GetConnected: Boolean;
|
---|
383 | begin
|
---|
384 | Result := False;
|
---|
385 | end;
|
---|
386 |
|
---|
387 | procedure TPDClient.CheckTypes;
|
---|
388 | var
|
---|
389 | StructureVersion: string;
|
---|
390 | Data: TDictionaryStringString;
|
---|
391 | ObjectId: Integer;
|
---|
392 | Tables: TListString;
|
---|
393 | I: Integer;
|
---|
394 | NewProxy: TListProxy;
|
---|
395 | begin
|
---|
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;
|
---|
422 | end;
|
---|
423 |
|
---|
424 | constructor TPDClient.Create(AOwner: TComponent);
|
---|
425 | begin
|
---|
426 | inherited;
|
---|
427 | Types := TPDTypes.Create;
|
---|
428 | Types.Client := Self;
|
---|
429 | InitSystemTypes;
|
---|
430 | end;
|
---|
431 |
|
---|
432 | destructor TPDClient.Destroy;
|
---|
433 | begin
|
---|
434 | FreeAndNil(Types);
|
---|
435 | inherited;
|
---|
436 | end;
|
---|
437 |
|
---|
438 | procedure TPDClient.Connect;
|
---|
439 | begin
|
---|
440 | end;
|
---|
441 |
|
---|
442 | procedure TPDClient.Disconnect;
|
---|
443 | begin
|
---|
444 | end;
|
---|
445 |
|
---|
446 | procedure TPDClient.Install;
|
---|
447 | begin
|
---|
448 | end;
|
---|
449 |
|
---|
450 | procedure TPDClient.Uninstall;
|
---|
451 | begin
|
---|
452 | //Types.Uninstall;
|
---|
453 | end;
|
---|
454 |
|
---|
455 | procedure TPDClient.Update;
|
---|
456 | begin
|
---|
457 | end;
|
---|
458 |
|
---|
459 | end.
|
---|
460 |
|
---|