ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/runtime/IBUpdate.pas
Revision: 158
Committed: Thu Mar 1 11:23:33 2018 UTC (6 years, 8 months ago) by tony
Content type: text/x-pascal
File size: 12145 byte(s)
Log Message:
Repository resync

File Contents

# User Rev Content
1 tony 158 (*
2     * IBX For Lazarus (Firebird Express)
3     *
4     * The contents of this file are subject to the Initial Developer's
5     * Public License Version 1.0 (the "License"); you may not use this
6     * file except in compliance with the License. You may obtain a copy
7     * of the License here:
8     *
9     * http://www.firebirdsql.org/index.php?op=doc&id=idpl
10     *
11     * Software distributed under the License is distributed on an "AS
12     * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13     * implied. See the License for the specific language governing rights
14     * and limitations under the License.
15     *
16     * The Initial Developer of the Original Code is Tony Whyman.
17     *
18     * The Original Code is (C) 2015 Tony Whyman, MWA Software
19     * (http://www.mwasoftware.co.uk).
20     *
21     * All Rights Reserved.
22     *
23     * Contributor(s): ______________________________________.
24     *
25     *)
26    
27     unit IBUpdate;
28    
29     {$mode objfpc}{$H+}
30    
31     interface
32    
33     uses
34     Classes, SysUtils, IBCustomDataSet, DB, IB, IBDatabase, IBExternals, FBMessages;
35    
36     type
37    
38     TOnApplyUpdates = procedure(Sender: TObject; UpdateKind: TUpdateKind; Params: ISQLParams) of object;
39    
40     { TIBUpdate}
41    
42     TIBUpdate = class(TIBDataSetUpdateObject)
43     private
44     FDataSet: TIBCustomDataSet;
45     FDummySQL: TStrings;
46     FOnApplyUpdates: TOnApplyUpdates;
47     protected
48     function GetSQL(UpdateKind: TUpdateKind): TStrings; override;
49     function GetDataSet: TIBCustomDataSet; override;
50     procedure SetDataSet(ADataSet: TIBCustomDataSet); override;
51     procedure Apply(UpdateKind: TUpdateKind; buff: PChar); override;
52     public
53     constructor Create(AOwner: TComponent); override;
54     destructor Destroy; override;
55     property DataSet;
56     published
57     property OnApplyUpdates: TOnApplyUpdates read FOnApplyUpdates write FOnApplyUpdates;
58     end;
59    
60    
61     implementation
62    
63     uses variants;
64    
65     type
66    
67     { TParamListIntf }
68    
69     TParamListIntf = class(TInterfacedObject,ISQLParams)
70     private
71     type TParamRec = record
72     Name: string;
73     Value: variant;
74     Modified: boolean;
75     end;
76     private
77     FDatabase: TIBDatabase;
78     FModified: boolean;
79     FParams: array of TParamRec;
80     procedure SetParam(index: integer; aValue: variant);
81     public
82     constructor Create(aFields: TFields; aDatabase: TIBDatabase);
83     destructor Destroy; override;
84     property Database: TIBDatabase read FDatabase;
85     public
86     {ISQLParams}
87     function getCount: integer;
88     function getSQLParam(index: integer): ISQLParam;
89     function ByName(Idx: AnsiString): ISQLParam ;
90     function GetModified: Boolean;
91     end;
92    
93     { TParamIntf }
94    
95     TParamIntf = class(TInterfacedObject,ISQLParam)
96     private
97     FIndex: integer;
98     FOwner: TParamListIntf;
99     public
100     constructor Create(aOwner: TParamListIntf; aIndex: integer);
101     function GetIndex: integer;
102     function GetSQLType: cardinal;
103     function GetSQLTypeName: AnsiString;
104     function getSubtype: integer;
105     function getName: AnsiString;
106     function getScale: integer;
107     function getCharSetID: cardinal;
108     function getCodePage: TSystemCodePage;
109     function getIsNullable: boolean;
110     function GetSize: cardinal;
111     function GetAsBoolean: boolean;
112     function GetAsCurrency: Currency;
113     function GetAsInt64: Int64;
114     function GetAsDateTime: TDateTime;
115     function GetAsDouble: Double;
116     function GetAsFloat: Float;
117     function GetAsLong: Long;
118     function GetAsPointer: Pointer;
119     function GetAsQuad: TISC_QUAD;
120     function GetAsShort: short;
121     function GetAsString: AnsiString;
122     function GetIsNull: boolean;
123     function GetAsVariant: Variant;
124     function GetAsBlob: IBlob;
125     function GetAsArray: IArray;
126     procedure Clear;
127     function GetModified: boolean;
128     procedure SetAsBoolean(AValue: boolean);
129     procedure SetAsCurrency(aValue: Currency);
130     procedure SetAsInt64(aValue: Int64);
131     procedure SetAsDate(aValue: TDateTime);
132     procedure SetAsLong(aValue: Long);
133     procedure SetAsTime(aValue: TDateTime);
134     procedure SetAsDateTime(aValue: TDateTime);
135     procedure SetAsDouble(aValue: Double);
136     procedure SetAsFloat(aValue: Float);
137     procedure SetAsPointer(aValue: Pointer);
138     procedure SetAsShort(aValue: Short);
139     procedure SetAsString(aValue: AnsiString);
140     procedure SetAsVariant(aValue: Variant);
141     procedure SetIsNull(aValue: Boolean);
142     procedure SetAsBlob(aValue: IBlob);
143     procedure SetAsArray(anArray: IArray);
144     procedure SetAsQuad(aValue: TISC_QUAD);
145     procedure SetCharSetID(aValue: cardinal);
146     end;
147    
148     { TParamIntf }
149    
150     constructor TParamIntf.Create(aOwner: TParamListIntf; aIndex: integer);
151     begin
152     FOwner := aOwner;
153     FIndex := aIndex;
154     end;
155    
156     function TParamIntf.GetIndex: integer;
157     begin
158     Result := Findex;
159     end;
160    
161     function TParamIntf.GetSQLType: cardinal;
162     begin
163     IBError(ibxeNotSupported,[]);
164     end;
165    
166     function TParamIntf.GetSQLTypeName: AnsiString;
167     begin
168     IBError(ibxeNotSupported,[]);
169     end;
170    
171     function TParamIntf.getSubtype: integer;
172     begin
173     IBError(ibxeNotSupported,[]);
174     end;
175    
176     function TParamIntf.getName: AnsiString;
177     begin
178     Result := FOwner.FParams[FIndex].Name;
179     end;
180    
181     function TParamIntf.getScale: integer;
182     begin
183     IBError(ibxeNotSupported,[]);
184     end;
185    
186     function TParamIntf.getCharSetID: cardinal;
187     var id: integer;
188     begin
189     FOwner.Database.Attachment.CodePage2CharSetID(StringCodePage(FOwner.FParams[FIndex].Value),id);
190     Result := id;
191     end;
192    
193     function TParamIntf.getCodePage: TSystemCodePage;
194     begin
195     Result := StringCodePage(FOwner.FParams[FIndex].Value);
196     end;
197    
198     function TParamIntf.getIsNullable: boolean;
199     begin
200     Result := true;
201     end;
202    
203     function TParamIntf.GetSize: cardinal;
204     begin
205     IBError(ibxeNotSupported,[]);
206     end;
207    
208     function TParamIntf.GetAsBoolean: boolean;
209     begin
210     Result := FOwner.FParams[FIndex].Value;
211     end;
212    
213     function TParamIntf.GetAsCurrency: Currency;
214     begin
215     Result := FOwner.FParams[FIndex].Value;
216     end;
217    
218     function TParamIntf.GetAsInt64: Int64;
219     begin
220     Result := FOwner.FParams[FIndex].Value;
221     end;
222    
223     function TParamIntf.GetAsDateTime: TDateTime;
224     begin
225     Result := FOwner.FParams[FIndex].Value;
226     end;
227    
228     function TParamIntf.GetAsDouble: Double;
229     begin
230     Result := FOwner.FParams[FIndex].Value;
231     end;
232    
233     function TParamIntf.GetAsFloat: Float;
234     begin
235     Result := FOwner.FParams[FIndex].Value;
236     end;
237    
238     function TParamIntf.GetAsLong: Long;
239     begin
240     Result := FOwner.FParams[FIndex].Value;
241     end;
242    
243     function TParamIntf.GetAsPointer: Pointer;
244     begin
245     IBError(ibxeNotSupported,[]);
246     end;
247    
248     function TParamIntf.GetAsQuad: TISC_QUAD;
249     begin
250     IBError(ibxeNotSupported,[]);
251     end;
252    
253     function TParamIntf.GetAsShort: short;
254     begin
255     Result := FOwner.FParams[FIndex].Value;
256     end;
257    
258     function TParamIntf.GetAsString: AnsiString;
259     var v: variant;
260     begin
261     v := FOwner.FParams[FIndex].Value;
262     Case varType(v) of
263     varEmpty,
264     varNull:
265     Result := '';
266     varShortInt,
267     varSmallint,
268     varInteger,
269     varInt64,
270     varByte,
271     varWord,
272     varDecimal,
273     varLongWord,
274     varQWord,
275     varSingle:
276     Result := IntToStr(v);
277     varCurrency,
278     varDouble:
279     Result := FloatToStr(v);
280     varDate:
281     Result := DateTimeToStr(v);
282     varStrArg,
283     varString:
284     Result := v;
285     varBoolean:
286     if v then
287     Result := 'true'
288     else
289     Result := 'false';
290     varVariant:
291     Result := v;
292     else
293     Result := v;
294     end;
295     end;
296    
297     function TParamIntf.GetIsNull: boolean;
298     begin
299     Result := VarIsNull(FOwner.FParams[FIndex].Value);
300     end;
301    
302     function TParamIntf.GetAsVariant: Variant;
303     begin
304     Result := FOwner.FParams[FIndex].Value;
305     end;
306    
307     function TParamIntf.GetAsBlob: IBlob;
308     begin
309     IBError(ibxeNotSupported,[]);
310     end;
311    
312     function TParamIntf.GetAsArray: IArray;
313     begin
314     IBError(ibxeNotSupported,[]);
315     end;
316    
317     procedure TParamIntf.Clear;
318     begin
319     FOwner.SetParam(FIndex,NULL);
320     end;
321    
322     function TParamIntf.GetModified: boolean;
323     begin
324     Result := FOwner.FParams[FIndex].Modified;
325     end;
326    
327     procedure TParamIntf.SetAsBoolean(AValue: boolean);
328     begin
329     FOwner.SetParam(FIndex,AValue);
330     end;
331    
332     procedure TParamIntf.SetAsCurrency(aValue: Currency);
333     begin
334     FOwner.SetParam(FIndex,AValue);
335     end;
336    
337     procedure TParamIntf.SetAsInt64(aValue: Int64);
338     begin
339     FOwner.SetParam(FIndex,AValue);
340     end;
341    
342     procedure TParamIntf.SetAsDate(aValue: TDateTime);
343     begin
344     FOwner.SetParam(FIndex,AValue);
345     end;
346    
347     procedure TParamIntf.SetAsLong(aValue: Long);
348     begin
349     FOwner.SetParam(FIndex,AValue);
350     end;
351    
352     procedure TParamIntf.SetAsTime(aValue: TDateTime);
353     begin
354     FOwner.SetParam(FIndex,AValue);
355     end;
356    
357     procedure TParamIntf.SetAsDateTime(aValue: TDateTime);
358     begin
359     FOwner.SetParam(FIndex,AValue);
360     end;
361    
362     procedure TParamIntf.SetAsDouble(aValue: Double);
363     begin
364     FOwner.SetParam(FIndex,AValue);
365     end;
366    
367     procedure TParamIntf.SetAsFloat(aValue: Float);
368     begin
369     FOwner.SetParam(FIndex,AValue);
370     end;
371    
372     procedure TParamIntf.SetAsPointer(aValue: Pointer);
373     begin
374     IBError(ibxeNotSupported,[]);
375     end;
376    
377     procedure TParamIntf.SetAsShort(aValue: Short);
378     begin
379     FOwner.SetParam(FIndex,AValue);
380     end;
381    
382     procedure TParamIntf.SetAsString(aValue: AnsiString);
383     begin
384     FOwner.SetParam(FIndex,AValue);
385     end;
386    
387     procedure TParamIntf.SetAsVariant(aValue: Variant);
388     begin
389     FOwner.SetParam(FIndex,AValue);
390     end;
391    
392     procedure TParamIntf.SetIsNull(aValue: Boolean);
393     begin
394     if aValue then
395     FOwner.SetParam(FIndex,NULL)
396     end;
397    
398     procedure TParamIntf.SetAsBlob(aValue: IBlob);
399     begin
400     IBError(ibxeNotSupported,[]);
401     end;
402    
403     procedure TParamIntf.SetAsArray(anArray: IArray);
404     begin
405     IBError(ibxeNotSupported,[]);
406     end;
407    
408     procedure TParamIntf.SetAsQuad(aValue: TISC_QUAD);
409     begin
410     IBError(ibxeNotSupported,[]);
411     end;
412    
413     procedure TParamIntf.SetCharSetID(aValue: cardinal);
414     var s: RawByteString;
415     codepage: TSystemCodePage;
416     str: string;
417     begin
418     str := FOwner.FParams[FIndex].Value;
419     s := str;
420     if FOwner.Database.Attachment.CharSetID2CodePage(aValue,codepage) then
421     SetCodePage(s,codepage,codepage <> cp_none);
422     end;
423    
424     { TParamListIntf }
425    
426     procedure TParamListIntf.SetParam(index: integer; aValue: variant);
427     begin
428     FParams[index].Value := aValue;
429     FParams[index].Modified := true;
430     FModified := true;
431     end;
432    
433     constructor TParamListIntf.Create(aFields: TFields; aDatabase: TIBDatabase);
434     var i,j: integer;
435     begin
436     inherited Create;
437     FDatabase := aDatabase;
438     SetLength(FParams,aFields.Count*2);
439     j := 0;
440     {set up both current and "OLD" parameters from Field Names}
441     for i := 0 to aFields.Count - 1 do
442     if aFields[i].FieldKind = fkData then
443     begin
444     FParams[j].Name := aFields[i].FieldName;
445     FParams[j].Value := NULL;
446     FParams[j].Modified := false;
447     Inc(j);
448     FParams[j].Name := 'OLD_' + aFields[i].FieldName;
449     FParams[j].Value := NULL;
450     FParams[j].Modified := false;
451     Inc(j);
452     end;
453     SetLength(FParams,j);
454     end;
455    
456     destructor TParamListIntf.Destroy;
457     begin
458     SetLength(FParams,0);
459     inherited Destroy;
460     end;
461    
462     function TParamListIntf.getCount: integer;
463     begin
464     Result := Length(FParams);
465     end;
466    
467     function TParamListIntf.getSQLParam(index: integer): ISQLParam;
468     begin
469     if (index < 0) or (index >= getCount) then
470     IBError(ibxeInvalidColumnIndex,[nil]);
471     Result := TParamIntf.Create(self,index);
472     end;
473    
474     function TParamListIntf.ByName(Idx: AnsiString): ISQLParam;
475     var i: integer;
476     begin
477     Result := nil;
478     for i := 0 to getCount - 1 do
479     if CompareText(FParams[i].Name,Idx) = 0 then
480     begin
481     Result := getSQLParam(i);
482     Exit;
483     end;
484     end;
485    
486     function TParamListIntf.GetModified: Boolean;
487     begin
488     Result := FModified;
489     end;
490    
491     { TIBUpdate }
492    
493     function TIBUpdate.GetSQL(UpdateKind: TUpdateKind): TStrings;
494     begin
495     Result := FDummySQL; {non empty result}
496     end;
497    
498     function TIBUpdate.GetDataSet: TIBCustomDataSet;
499     begin
500     Result := FDataSet;
501     end;
502    
503     procedure TIBUpdate.SetDataSet(ADataSet: TIBCustomDataSet);
504     begin
505     FDataSet := ADataset;
506     end;
507    
508     procedure TIBUpdate.Apply(UpdateKind: TUpdateKind; buff: PChar);
509     var Params: ISQLParams;
510     begin
511     Params := TParamListIntf.Create(Dataset.Fields,(DataSet.Database as TIBDatabase));
512     InternalSetParams(Params,buff);
513     if assigned(FOnApplyUpdates) then
514     OnApplyUpdates(self,UpdateKind,Params);
515     end;
516    
517     constructor TIBUpdate.Create(AOwner: TComponent);
518     begin
519     inherited Create(AOwner);
520     FDummySQL := TStringList.Create;
521     FDummySQL.Text := '*';
522     end;
523    
524     destructor TIBUpdate.Destroy;
525     begin
526     if assigned(FDummySQL) then FDummySQL.Free;
527     inherited Destroy;
528     end;
529    
530     end.
531