ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/runtime/IBQuery.pas
(Generate patch)

Comparing ibx/trunk/runtime/IBQuery.pas (file contents):
Revision 23 by tony, Fri Mar 13 10:26:52 2015 UTC vs.
Revision 45 by tony, Tue Dec 6 10:33:46 2016 UTC

# Line 1 | Line 1
1 < {************************************************************************}
2 < {                                                                        }
3 < {       Borland Delphi Visual Component Library                          }
4 < {       InterBase Express core components                                }
5 < {                                                                        }
6 < {       Copyright (c) 1998-2000 Inprise Corporation                      }
7 < {                                                                        }
8 < {    InterBase Express is based in part on the product                   }
9 < {    Free IB Components, written by Gregory H. Deatz for                 }
10 < {    Hoagland, Longo, Moran, Dunst & Doukas Company.                     }
11 < {    Free IB Components is used under license.                           }
12 < {                                                                        }
13 < {    The contents of this file are subject to the InterBase              }
14 < {    Public License Version 1.0 (the "License"); you may not             }
15 < {    use this file except in compliance with the License. You            }
16 < {    may obtain a copy of the License at http://www.Inprise.com/IPL.html }
17 < {    Software distributed under the License is distributed on            }
18 < {    an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either              }
19 < {    express or implied. See the License for the specific language       }
20 < {    governing rights and limitations under the License.                 }
21 < {    The Original Code was created by InterBase Software Corporation     }
22 < {       and its successors.                                              }
23 < {    Portions created by Inprise Corporation are Copyright (C) Inprise   }
24 < {       Corporation. All Rights Reserved.                                }
25 < {    Contributor(s): Jeff Overcash                                       }
26 < {                                                                        }
27 < {    IBX For Lazarus (Firebird Express)                                  }
28 < {    Contributor: Tony Whyman, MWA Software http://www.mwasoftware.co.uk }
29 < {    Portions created by MWA Software are copyright McCallum Whyman      }
30 < {    Associates Ltd 2011                                                 }
31 < {                                                                        }
32 < {************************************************************************}
33 <
34 < unit IBQuery;
35 <
36 < interface
37 <
38 < {$Mode Delphi}
39 <
40 < uses
41 < {$IFDEF WINDOWS }
42 <  Windows,
43 < {$ELSE}
44 <  unix,
45 < {$ENDIF}
46 < SysUtils, Graphics, Classes, Controls, Db,
47 <     IBHeader, IB, IBCustomDataSet, IBSQL, IBSQLParser;
48 <
49 < type
50 <
51 < { TIBQuery }
52 <
53 <  TIBQuery = class(TIBParserDataSet)
54 <  private
55 <    FSQL: TStrings;
56 <    FPrepared: Boolean;
57 <    FParams: TParams;
58 <    FText: string;
59 <    FRowsAffected: Integer;
60 <    FCheckRowsAffected: Boolean;
61 <    FSQLUpdating: boolean;
62 <    function GetRowsAffected: Integer;
63 <    procedure PrepareSQL(Value: PChar);
64 <    procedure QueryChanged(Sender: TObject);
65 <    procedure ReadParamData(Reader: TReader);
66 <    procedure SetQuery(Value: TStrings);
67 <    procedure SetParamsList(Value: TParams);
68 <    procedure SetParams;
69 <    procedure SetParamsFromCursor;
70 <    procedure SetPrepared(Value: Boolean);
71 <    procedure SetPrepare(Value: Boolean);
72 <    procedure WriteParamData(Writer: TWriter);
73 <    function GetStmtHandle: TISC_STMT_HANDLE;
74 <
75 <  protected
76 <    { IProviderSupport }
77 < (*    procedure PSExecute; override;
78 <    function PSGetParams: TParams; override;
79 <    function PSGetTableName: string; override;
80 <    procedure PSSetCommandText(const CommandText: string); override;
81 <    procedure PSSetParams(AParams: TParams); override;  *)
82 <
83 <    function CreateParser: TSelectSQLParser; override;
84 <    procedure DefineProperties(Filer: TFiler); override;
85 <    procedure InitFieldDefs; override;
86 <    procedure InternalOpen; override;
87 <    procedure Disconnect; override;
88 <    function GetParamsCount: Word;
89 <    function GenerateQueryForLiveUpdate : Boolean;
90 <    procedure SetFiltered(Value: Boolean); override;
91 <
92 <  public
93 <    constructor Create(AOwner: TComponent); override;
94 <    destructor Destroy; override;
95 <    procedure BatchInput(InputObject: TIBBatchInput);
96 <    procedure BatchOutput(OutputObject: TIBBatchOutput);
97 <    procedure ExecSQL;
98 <    procedure GetDetailLinkFields(MasterFields, DetailFields: TList);(* override;*)
99 <    function ParamByName(const Value: string): TParam;
100 <    procedure Prepare;
101 <    procedure UnPrepare;
102 <    property Prepared: Boolean read FPrepared write SetPrepare;
103 <    property ParamCount: Word read GetParamsCount;
104 <    property StmtHandle: TISC_STMT_HANDLE read GetStmtHandle;
105 <    property StatementType;
106 <    property Text: string read FText;
107 <    property RowsAffected: Integer read GetRowsAffected;
108 < //   property Params: TParams read FParams write SetParamsList;
109 <    property BaseSQLSelect;
110 <
111 <  published
112 <    property Active;
113 <    property AutoCommit;
114 <    property BufferChunks;
115 <    property CachedUpdates;
116 <    property DataSource read GetDataSource write SetDataSource;
117 <    property GenerateParamNames;
118 < //   property Constraints stored ConstraintsStored;
119 <    property GeneratorField;
120 <    property ParamCheck;
121 <    property SQL: TStrings read FSQL write SetQuery;
122 <    property Params: TParams read FParams write SetParamsList;
123 <    property UniDirectional default False;
124 <    property UpdateObject;
125 <    property Filtered;
126 <
127 <    property BeforeDatabaseDisconnect;
128 <    property AfterDatabaseDisconnect;
129 <    property DatabaseFree;
130 <    property BeforeTransactionEnd;
131 <    property AfterTransactionEnd;
132 <    property TransactionFree;
133 <    property OnFilterRecord;
134 < end;
135 <
136 < implementation
137 <
138 < { TIBQuery }
139 <
140 < constructor TIBQuery.Create(AOwner: TComponent);
141 < begin
142 <  inherited Create(AOwner);
143 <  FSQL := TStringList.Create;
144 <  TStringList(SQL).OnChange := QueryChanged;
145 <  FParams := TParams.Create(Self);
146 <  ParamCheck := True;
147 <  FRowsAffected := -1;
148 < end;
149 <
150 < destructor TIBQuery.Destroy;
151 < begin
152 <  Destroying;
153 <  Disconnect;
154 <  SQL.Free;
155 <  FParams.Free;
156 <  inherited Destroy;
157 < end;
158 <
159 < procedure TIBQuery.InitFieldDefs;
160 < begin
161 <  inherited InitFieldDefs;
162 < end;
163 <
164 < procedure TIBQuery.InternalOpen;
165 < begin
166 <  ActivateConnection();
167 <  ActivateTransaction;
168 <  QSelect.GenerateParamNames := GenerateParamNames;
169 <  SetPrepared(True);
170 <  if DataSource <> nil then
171 <    SetParamsFromCursor;
172 <  SetParams;
173 <  inherited InternalOpen;
174 < end;
175 <
176 < procedure TIBQuery.Disconnect;
177 < begin
178 <  Close;
179 <  UnPrepare;
180 < end;
181 <
182 < procedure TIBQuery.SetPrepare(Value: Boolean);
183 < begin
184 <  if Value then
185 <    Prepare
186 <  else
187 <    UnPrepare;
188 < end;
189 <
190 < procedure TIBQuery.Prepare;
191 < begin
192 <  SetPrepared(True);
193 < end;
194 <
195 < procedure TIBQuery.UnPrepare;
196 < begin
197 <  SetPrepared(False);
198 < end;
199 <
200 < procedure TIBQuery.SetQuery(Value: TStrings);
201 < begin
202 <  if SQL.Text <> Value.Text then
203 <  begin
204 <    Disconnect;
205 <    SQL.BeginUpdate;
206 <    try
207 <      SQL.Assign(Value);
208 <    finally
209 <      SQL.EndUpdate;
210 <    end;
211 <  end;
212 < end;
213 <
214 < procedure TIBQuery.QueryChanged(Sender: TObject);
215 < var
216 <  List: TParams;
217 < begin
218 <  if not (csReading in ComponentState) then
219 <  begin
220 <    Disconnect;
221 <    if HasParser and not FSQLUpdating then
222 <    begin
223 <      FSQLUpdating := true;
224 <      try
225 <        SQL.Text := Parser.SQLText;
226 <      finally
227 <        FSQLUpdating := false
228 <      end;
229 <    end;
230 <    if ParamCheck or (csDesigning in ComponentState) then
231 <    begin
232 <      List := TParams.Create(Self);
233 <      try
234 <        FText := List.ParseSQL(SQL.Text, True);
235 <        List.AssignValues(FParams);
236 <        FParams.Clear;
237 <        FParams.Assign(List);
238 <      finally
239 <        List.Free;
240 <      end;
241 <    end else
242 <      FText := SQL.Text;
243 <    DataEvent(dePropertyChange, 0);
244 <  end else
245 <    FText := FParams.ParseSQL(SQL.Text, true);
246 <  SelectSQL.Assign(SQL);
247 < end;
248 <
249 < procedure TIBQuery.SetParamsList(Value: TParams);
250 < begin
251 <  FParams.AssignValues(Value);
252 < end;
253 <
254 < function TIBQuery.GetParamsCount: Word;
255 < begin
256 <  Result := FParams.Count;
257 < end;
258 <
259 < procedure TIBQuery.DefineProperties(Filer: TFiler);
260 <
261 <  function WriteData: Boolean;
262 <  begin
263 <  {The following results in a stream read error with nested frames. Hence commented out until
264 <   someone fixes the LCL }
265 < {    if Filer.Ancestor <> nil then
266 <      Result := not FParams.IsEqual(TIBQuery(Filer.Ancestor).FParams) else}
267 <      Result := FParams.Count > 0;
268 <  end;
269 <
270 < begin
271 <  inherited DefineProperties(Filer);
272 <  Filer.DefineProperty('ParamData', ReadParamData, WriteParamData, WriteData); {do not localize}
273 < end;
274 <
275 <
276 < procedure TIBQuery.ReadParamData(Reader: TReader);
277 < begin
278 <  FParams.Clear;
279 <  Reader.ReadValue;
280 <  Reader.ReadCollection(FParams);
281 < end;
282 <
283 < procedure TIBQuery.WriteParamData(Writer: TWriter);
284 < begin
285 <  Writer.WriteCollection(Params);
286 < end;
287 <
288 < procedure TIBQuery.SetPrepared(Value: Boolean);
289 < begin
290 <  CheckDatasetClosed;
291 <  if Value <> Prepared then
292 <  begin
293 <    if Value then
294 <    begin
295 <      FRowsAffected := -1;
296 <      FCheckRowsAffected := True;
297 <      if Length(Text) > 1 then PrepareSQL(PChar(Text))
298 <      else IBError(ibxeEmptySQLStatement, [nil]);
299 <    end
300 <    else
301 <    begin
302 <      if FCheckRowsAffected then
303 <        FRowsAffected := RowsAffected;
304 <      InternalUnPrepare;
305 <    end;
306 <    FPrepared := Value;
307 <  end;
308 < end;
309 <
310 < procedure TIBQuery.SetParamsFromCursor;
311 < var
312 <  I: Integer;
313 <  DataSet: TDataSet;
314 <  Field: TField;
315 <
316 <  procedure CheckRequiredParams;
317 <  var
318 <    I: Integer;
319 <  begin
320 <    for I := 0 to FParams.Count - 1 do
321 <    with FParams[I] do
322 <      if not Bound then
323 <        IBError(ibxeRequiredParamNotSet, [nil]);
324 <  end;
325 <
326 < begin
327 <  if DataSource <> nil then
328 <  begin
329 <    DataSet := DataSource.DataSet;
330 <    if DataSet <> nil then
331 <    begin
332 <      DataSet.FieldDefs.Update;
333 <      for I := 0 to FParams.Count - 1 do
334 <      if not FParams[I].Bound then
335 <      begin
336 <        Field := DataSet.FindField(FParams[I].Name);
337 <        if assigned(Field) then
338 <        begin
339 <            FParams[I].AssignField(Field);
340 <            FParams[I].Bound := False;
341 <        end;
342 <      end;
343 <    end
344 <    else
345 <      CheckRequiredParams;
346 <  end
347 <  else
348 <    CheckRequiredParams;
349 < end;
350 <
351 <
352 < function TIBQuery.ParamByName(const Value: string): TParam;
353 < begin
354 <  Result := FParams.ParamByName(Value);
355 < end;
356 <
357 < procedure TIBQuery.BatchInput(InputObject: TIBBatchInput);
358 < begin
359 <  InternalBatchInput(InputObject);
360 < end;
361 <
362 < procedure TIBQuery.BatchOutput(OutputObject: TIBBatchOutput);
363 < begin
364 <  InternalBatchOutput(OutputObject);
365 < end;
366 <
367 < procedure TIBQuery.ExecSQL;
368 < var
369 <  DidActivate: Boolean;
370 < begin
371 <  CheckInActive;
372 <  if SQL.Count <= 0 then
373 <  begin
374 <    FCheckRowsAffected := False;
375 <    IBError(ibxeEmptySQLStatement, [nil]);
376 <  end;
377 <  ActivateConnection();
378 <  DidActivate := ActivateTransaction;
379 <  try
380 <    SetPrepared(True);
381 <    if DataSource <> nil then SetParamsFromCursor;
382 <    if FParams.Count > 0 then SetParams;
383 <    InternalExecQuery;
384 <  finally
385 <    if DidActivate then
386 <      DeactivateTransaction;
387 <    FCheckRowsAffected := True;
388 <  end;
389 < end;
390 <
391 < procedure TIBQuery.SetParams;
392 <
393 < var
394 < i : integer;
395 < Buffer: Pointer;
396 < SQLParam: TIBXSQLVAR;
397 <
398 < begin
399 <  for I := 0 to FParams.Count - 1 do
400 <  begin
401 <    SQLParam :=  SQLParams.ByName(Params[i].Name);
402 <    if Params[i].IsNull then
403 <      SQLParam.IsNull := True
404 <    else begin
405 <      SQLParam.IsNull := False;
406 <      case Params[i].DataType of
407 <        ftBytes:
408 <        begin
409 <          GetMem(Buffer,Params[i].GetDataSize);
410 <          try
411 <            Params[i].GetData(Buffer);
412 <            SQLParam.AsPointer := Buffer;
413 <          finally
414 <            FreeMem(Buffer);
415 <          end;
416 <        end;
417 <        ftString:
418 <          SQLParam.AsString := Params[i].AsString;
419 <        ftBoolean:
420 <          SQLParam.AsBoolean := Params[i].AsBoolean;
421 <        ftSmallint, ftWord:
422 <          SQLParam.AsShort := Params[i].AsSmallInt;
423 <        ftInteger:
424 <          SQLParam.AsLong := Params[i].AsInteger;
425 <        ftLargeInt:
426 <          SQLParam.AsInt64 := Params[i].AsLargeInt;
427 <        ftFloat:
428 <         SQLParam.AsDouble := Params[i].AsFloat;
429 <        ftBCD, ftCurrency:
430 <          SQLParam.AsCurrency := Params[i].AsCurrency;
431 <        ftDate:
432 <          SQLParam.AsDate := Params[i].AsDateTime;
433 <        ftTime:
434 <          SQLParam.AsTime := Params[i].AsDateTime;
435 <        ftDateTime:
436 <          SQLParam.AsDateTime := Params[i].AsDateTime;
437 <        ftBlob, ftMemo:
438 <          SQLParam.AsString := Params[i].AsString;
439 <        else
440 <          IBError(ibxeNotSupported, [nil]);
441 <      end;
442 <    end;
443 <  end;
444 < end;
445 <
446 < procedure TIBQuery.PrepareSQL(Value: PChar);
447 < begin
448 <  QSelect.GenerateParamNames := GenerateParamNames;
449 <  InternalPrepare;
450 < end;
451 <
452 <
453 < function TIBQuery.GetRowsAffected: Integer;
454 < begin
455 <  Result := -1;
456 <  if Prepared then
457 <   Result := QSelect.RowsAffected
458 < end;
459 <
460 <
461 < procedure TIBQuery.GetDetailLinkFields(MasterFields, DetailFields: TList);
462 <
463 <  function AddFieldToList(const FieldName: string; DataSet: TDataSet;
464 <    List: TList): Boolean;
465 <  var
466 <    Field: TField;
467 <  begin
468 <    Field := DataSet.FindField(FieldName);
469 <    if (Field <> nil) then
470 <      List.Add(Field);
471 <    Result := Field <> nil;
472 <  end;
473 <
474 < var
475 <  i: Integer;
476 < begin
477 <  MasterFields.Clear;
478 <  DetailFields.Clear;
479 <  if (DataSource <> nil) and (DataSource.DataSet <> nil) then
480 <    for i := 0 to Params.Count - 1 do
481 <      if AddFieldToList(Params[i].Name, DataSource.DataSet, MasterFields) then
482 <        AddFieldToList(Params[i].Name, Self, DetailFields);
483 < end;
484 <
485 < function TIBQuery.GetStmtHandle: TISC_STMT_HANDLE;
486 < begin
487 <  Result := SelectStmtHandle;
488 < end;
489 <
490 < function TIBQuery.CreateParser: TSelectSQLParser;
491 < begin
492 <  Result := inherited CreateParser;
493 <  Result.OnSQLChanging := QueryChanged;
494 < end;
495 <
496 < function TIBQuery.GenerateQueryForLiveUpdate : Boolean;
497 < begin
498 <  Result := False;
499 < end;
500 <
501 < procedure TIBQuery.SetFiltered(Value: Boolean);
502 < begin
503 <  if(Filtered <> Value) then
504 <  begin
505 <    inherited SetFiltered(value);
506 <    if Active then
507 <    begin
508 <      Close;
509 <      Open;
510 <    end;
511 <  end
512 <  else
513 <    inherited SetFiltered(value);
514 < end;
515 <
516 < { TIBQuery IProviderSupport }
517 < (*
518 < function TIBQuery.PSGetParams: TParams;
519 < begin
520 <  Result := Params;
521 < end;
522 <
523 < procedure TIBQuery.PSSetParams(AParams: TParams);
524 < begin
525 <  if AParams.Count <> 0 then
526 <    Params.Assign(AParams);
527 <  Close;
528 < end;
529 <
530 < function TIBQuery.PSGetTableName: string;
531 < begin
532 <  Result := inherited PSGetTableName;
533 < end;
534 <
535 < procedure TIBQuery.PSExecute;
536 < begin
537 <  ExecSQL;
538 < end;
539 <
540 < procedure TIBQuery.PSSetCommandText(const CommandText: string);
541 < begin
542 <  if CommandText <> '' then
543 <    SQL.Text := CommandText;
544 < end;
545 < *)
546 < end.
547 <
1 > {************************************************************************}
2 > {                                                                        }
3 > {       Borland Delphi Visual Component Library                          }
4 > {       InterBase Express core components                                }
5 > {                                                                        }
6 > {       Copyright (c) 1998-2000 Inprise Corporation                      }
7 > {                                                                        }
8 > {    InterBase Express is based in part on the product                   }
9 > {    Free IB Components, written by Gregory H. Deatz for                 }
10 > {    Hoagland, Longo, Moran, Dunst & Doukas Company.                     }
11 > {    Free IB Components is used under license.                           }
12 > {                                                                        }
13 > {    The contents of this file are subject to the InterBase              }
14 > {    Public License Version 1.0 (the "License"); you may not             }
15 > {    use this file except in compliance with the License. You            }
16 > {    may obtain a copy of the License at http://www.Inprise.com/IPL.html }
17 > {    Software distributed under the License is distributed on            }
18 > {    an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either              }
19 > {    express or implied. See the License for the specific language       }
20 > {    governing rights and limitations under the License.                 }
21 > {    The Original Code was created by InterBase Software Corporation     }
22 > {       and its successors.                                              }
23 > {    Portions created by Inprise Corporation are Copyright (C) Inprise   }
24 > {       Corporation. All Rights Reserved.                                }
25 > {    Contributor(s): Jeff Overcash                                       }
26 > {                                                                        }
27 > {    IBX For Lazarus (Firebird Express)                                  }
28 > {    Contributor: Tony Whyman, MWA Software http://www.mwasoftware.co.uk }
29 > {    Portions created by MWA Software are copyright McCallum Whyman      }
30 > {    Associates Ltd 2011                                                 }
31 > {                                                                        }
32 > {************************************************************************}
33 >
34 > unit IBQuery;
35 >
36 > interface
37 >
38 > {$Mode Delphi}
39 >
40 > uses
41 > {$IFDEF WINDOWS }
42 >  Windows,
43 > {$ELSE}
44 >  unix,
45 > {$ENDIF}
46 > SysUtils, Classes,  Db,
47 >     IBHeader, IB, IBCustomDataSet, IBSQL, IBSQLParser;
48 >
49 > type
50 >
51 > { TIBQuery }
52 >
53 >  TIBQuery = class(TIBParserDataSet)
54 >  private
55 >    FSQL: TStrings;
56 >    FPrepared: Boolean;
57 >    FParams: TParams;
58 >    FText: string;
59 >    FRowsAffected: Integer;
60 >    FCheckRowsAffected: Boolean;
61 >    FSQLUpdating: boolean;
62 >    FInQueryChanged: boolean;
63 >    function GetRowsAffected: Integer;
64 >    procedure PrepareSQL;
65 >    procedure QueryChanged(Sender: TObject);
66 >    procedure ReadParamData(Reader: TReader);
67 >    procedure SetQuery(Value: TStrings);
68 >    procedure SetParamsList(Value: TParams);
69 >    procedure SetParams;
70 >    procedure SetParamsFromCursor;
71 >    procedure SetPrepared(Value: Boolean);
72 >    procedure SetPrepare(Value: Boolean);
73 >    procedure WriteParamData(Writer: TWriter);
74 >    function GetStmtHandle: IStatement;
75 >    procedure UpdateSQL;
76 >
77 >  protected
78 >    { IProviderSupport }
79 > (*    procedure PSExecute; override;
80 >    function PSGetParams: TParams; override;
81 >    function PSGetTableName: string; override;
82 >    procedure PSSetCommandText(const CommandText: string); override;
83 >    procedure PSSetParams(AParams: TParams); override;  *)
84 >
85 >    procedure DefineProperties(Filer: TFiler); override;
86 >    procedure InitFieldDefs; override;
87 >    procedure InternalOpen; override;
88 >    procedure Disconnect; override;
89 >    function GetParamsCount: Word;
90 >    function GenerateQueryForLiveUpdate : Boolean;
91 >    procedure SetFiltered(Value: Boolean); override;
92 >    procedure SQLChanged(Sender: TObject); override;
93 >    procedure SQLChanging(Sender: TObject); override;
94 >
95 >  public
96 >    constructor Create(AOwner: TComponent); override;
97 >    destructor Destroy; override;
98 >    procedure BatchInput(InputObject: TIBBatchInput);
99 >    procedure BatchOutput(OutputObject: TIBBatchOutput);
100 >    procedure ExecSQL;
101 >    procedure GetDetailLinkFields(MasterFields, DetailFields: TList);(* override;*)
102 >    function ParamByName(const Value: string): TParam;
103 >    procedure Prepare;
104 >    procedure UnPrepare;
105 >    procedure ResetParser; override;
106 >    property Prepared: Boolean read FPrepared write SetPrepare;
107 >    property ParamCount: Word read GetParamsCount;
108 >    property StmtHandle: IStatement read GetStmtHandle;
109 >    property StatementType;
110 >    property Text: string read FText;
111 >    property RowsAffected: Integer read GetRowsAffected;
112 > //   property Params: TParams read FParams write SetParamsList;
113 >    property BaseSQLSelect;
114 >
115 >  published
116 >    property Active;
117 >    property AutoCommit;
118 >    property BufferChunks;
119 >    property CachedUpdates;
120 >    property DataSource read GetDataSource write SetDataSource;
121 >    property GenerateParamNames;
122 > //   property Constraints stored ConstraintsStored;
123 >    property GeneratorField;
124 >    property ParamCheck;
125 >    property SQL: TStrings read FSQL write SetQuery;
126 >    property Params: TParams read FParams write SetParamsList;
127 >    property UniDirectional default False;
128 >    property UpdateObject;
129 >    property Filtered;
130 >    property DataSetCloseAction;
131 >
132 >    property BeforeDatabaseDisconnect;
133 >    property AfterDatabaseDisconnect;
134 >    property DatabaseFree;
135 >    property BeforeTransactionEnd;
136 >    property AfterTransactionEnd;
137 >    property TransactionFree;
138 >    property OnFilterRecord;
139 >    property OnValidatePost;
140 > end;
141 >
142 > implementation
143 >
144 > uses FBMessages;
145 >
146 > { TIBQuery }
147 >
148 > constructor TIBQuery.Create(AOwner: TComponent);
149 > begin
150 >  inherited Create(AOwner);
151 >  FSQL := TStringList.Create;
152 >  TStringList(SQL).OnChange := QueryChanged;
153 >  FParams := TParams.Create(Self);
154 >  ParamCheck := True;
155 >  FRowsAffected := -1;
156 > end;
157 >
158 > destructor TIBQuery.Destroy;
159 > begin
160 >  Destroying;
161 >  Disconnect;
162 >  SQL.Free;
163 >  FParams.Free;
164 >  inherited Destroy;
165 > end;
166 >
167 > procedure TIBQuery.InitFieldDefs;
168 > begin
169 >  inherited InitFieldDefs;
170 > end;
171 >
172 > procedure TIBQuery.InternalOpen;
173 > begin
174 >  ActivateConnection();
175 >  ActivateTransaction;
176 >  QSelect.GenerateParamNames := GenerateParamNames;
177 >  SetPrepared(True);
178 >  if DataSource <> nil then
179 >    SetParamsFromCursor;
180 >  SetParams;
181 >  inherited InternalOpen;
182 > end;
183 >
184 > procedure TIBQuery.Disconnect;
185 > begin
186 >  Close;
187 >  UnPrepare;
188 > end;
189 >
190 > procedure TIBQuery.SetPrepare(Value: Boolean);
191 > begin
192 >  if Value then
193 >    Prepare
194 >  else
195 >    UnPrepare;
196 > end;
197 >
198 > procedure TIBQuery.Prepare;
199 > begin
200 >  SetPrepared(True);
201 > end;
202 >
203 > procedure TIBQuery.UnPrepare;
204 > begin
205 >  SetPrepared(False);
206 > end;
207 >
208 > procedure TIBQuery.ResetParser;
209 > begin
210 >  inherited ResetParser;
211 >  UpdateSQL;
212 > end;
213 >
214 > procedure TIBQuery.SetQuery(Value: TStrings);
215 > begin
216 >  if SQL.Text <> Value.Text then
217 >  begin
218 >    Disconnect;
219 >    SQL.BeginUpdate;
220 >    try
221 >      SQL.Assign(Value);
222 >    finally
223 >      SQL.EndUpdate;
224 >    end;
225 >  end;
226 > end;
227 >
228 > procedure TIBQuery.QueryChanged(Sender: TObject);
229 > begin
230 >  if FInQueryChanged then Exit;
231 >  FInQueryChanged := true;
232 >  try
233 >    if not (csReading in ComponentState) then
234 >    begin
235 >      Disconnect;
236 >      if csDesigning in ComponentState then
237 >        FText := FParams.ParseSQL(SQL.Text, true)
238 >      else
239 >        FText := SQL.Text;
240 >      DataEvent(dePropertyChange, 0);
241 >    end else
242 >      FText := FParams.ParseSQL(SQL.Text, true);
243 >
244 >    if not FSQLUpdating then
245 >    begin
246 >      Prepared := false;
247 >      SelectSQL.Assign(SQL);
248 >    end;
249 >  finally
250 >    FInQueryChanged := false;
251 >  end;
252 > end;
253 >
254 > procedure TIBQuery.SetParamsList(Value: TParams);
255 > begin
256 >  FParams.AssignValues(Value);
257 > end;
258 >
259 > function TIBQuery.GetParamsCount: Word;
260 > begin
261 >  Result := FParams.Count;
262 > end;
263 >
264 > procedure TIBQuery.DefineProperties(Filer: TFiler);
265 >
266 >  function WriteData: Boolean;
267 >  begin
268 >  {The following results in a stream read error with nested frames. Hence commented out until
269 >   someone fixes the LCL }
270 > {    if Filer.Ancestor <> nil then
271 >      Result := not FParams.IsEqual(TIBQuery(Filer.Ancestor).FParams) else}
272 >      Result := FParams.Count > 0;
273 >  end;
274 >
275 > begin
276 >  inherited DefineProperties(Filer);
277 >  Filer.DefineProperty('ParamData', ReadParamData, WriteParamData, WriteData); {do not localize}
278 > end;
279 >
280 >
281 > procedure TIBQuery.ReadParamData(Reader: TReader);
282 > begin
283 >  FParams.Clear;
284 >  Reader.ReadValue;
285 >  Reader.ReadCollection(FParams);
286 > end;
287 >
288 > procedure TIBQuery.WriteParamData(Writer: TWriter);
289 > begin
290 >  Writer.WriteCollection(Params);
291 > end;
292 >
293 > procedure TIBQuery.SetPrepared(Value: Boolean);
294 > begin
295 >  CheckDatasetClosed;
296 >  if Value <> Prepared then
297 >  begin
298 >    if Value then
299 >    begin
300 >      FRowsAffected := -1;
301 >      FCheckRowsAffected := True;
302 >      if Length(Text) > 1 then PrepareSQL
303 >      else IBError(ibxeEmptySQLStatement, [nil]);
304 >    end
305 >    else
306 >    begin
307 >      if FCheckRowsAffected then
308 >        FRowsAffected := RowsAffected;
309 >      InternalUnPrepare;
310 >      FParams.Clear;
311 >    end;
312 >    FPrepared := Value;
313 >  end;
314 > end;
315 >
316 > procedure TIBQuery.SetParamsFromCursor;
317 > var
318 >  I: Integer;
319 >  DataSet: TDataSet;
320 >  Field: TField;
321 >
322 >  procedure CheckRequiredParams;
323 >  var
324 >    I: Integer;
325 >  begin
326 >    for I := 0 to FParams.Count - 1 do
327 >    with FParams[I] do
328 >      if not Bound then
329 >        IBError(ibxeRequiredParamNotSet, [FParams[I].Name]);
330 >  end;
331 >
332 > begin
333 >  if DataSource <> nil then
334 >  begin
335 >    DataSet := DataSource.DataSet;
336 >    if DataSet <> nil then
337 >    begin
338 >      DataSet.FieldDefs.Update;
339 >      for I := 0 to FParams.Count - 1 do
340 >      if not FParams[I].Bound then
341 >      begin
342 >        Field := DataSet.FindField(FParams[I].Name);
343 >        if assigned(Field) then
344 >        begin
345 >            FParams[I].AssignField(Field);
346 >            FParams[I].Bound := False;
347 >        end;
348 >      end;
349 >    end
350 >    else
351 >      CheckRequiredParams;
352 >  end
353 >  else
354 >    CheckRequiredParams;
355 > end;
356 >
357 >
358 > function TIBQuery.ParamByName(const Value: string): TParam;
359 > begin
360 >  if not Prepared then
361 >    Prepare;
362 >  Result := FParams.ParamByName(Value);
363 > end;
364 >
365 > procedure TIBQuery.BatchInput(InputObject: TIBBatchInput);
366 > begin
367 >  InternalBatchInput(InputObject);
368 > end;
369 >
370 > procedure TIBQuery.BatchOutput(OutputObject: TIBBatchOutput);
371 > begin
372 >  InternalBatchOutput(OutputObject);
373 > end;
374 >
375 > procedure TIBQuery.ExecSQL;
376 > var
377 >  DidActivate: Boolean;
378 > begin
379 >  CheckInActive;
380 >  if SQL.Count <= 0 then
381 >  begin
382 >    FCheckRowsAffected := False;
383 >    IBError(ibxeEmptySQLStatement, [nil]);
384 >  end;
385 >  ActivateConnection();
386 >  DidActivate := ActivateTransaction;
387 >  try
388 >    SetPrepared(True);
389 >    if DataSource <> nil then SetParamsFromCursor;
390 >    if FParams.Count > 0 then SetParams;
391 >    InternalExecQuery;
392 >  finally
393 >    if DidActivate then
394 >      DeactivateTransaction;
395 >    FCheckRowsAffected := True;
396 >  end;
397 > end;
398 >
399 > procedure TIBQuery.SetParams;
400 >
401 > var
402 > i : integer;
403 > Buffer: Pointer;
404 > SQLParam: ISQLParam;
405 >
406 > begin
407 >  for I := 0 to FParams.Count - 1 do
408 >  begin
409 >    SQLParam :=  SQLParams.ByName(Params[i].Name);
410 >    if Params[i].IsNull then
411 >      SQLParam.IsNull := True
412 >    else begin
413 >      SQLParam.IsNull := False;
414 >      case Params[i].DataType of
415 >        ftBytes:
416 >        begin
417 >          GetMem(Buffer,Params[i].GetDataSize);
418 >          try
419 >            Params[i].GetData(Buffer);
420 >            SQLParam.AsPointer := Buffer;
421 >          finally
422 >            FreeMem(Buffer);
423 >          end;
424 >        end;
425 >        ftString:
426 >          SQLParam.AsString := Params[i].AsString;
427 >        ftBoolean:
428 >          SQLParam.AsBoolean := Params[i].AsBoolean;
429 >        ftSmallint, ftWord:
430 >          SQLParam.AsShort := Params[i].AsSmallInt;
431 >        ftInteger:
432 >          SQLParam.AsLong := Params[i].AsInteger;
433 >        ftLargeInt:
434 >          SQLParam.AsInt64 := Params[i].AsLargeInt;
435 >        ftFloat:
436 >         SQLParam.AsDouble := Params[i].AsFloat;
437 >        ftBCD, ftCurrency:
438 >          SQLParam.AsCurrency := Params[i].AsCurrency;
439 >        ftDate:
440 >          SQLParam.AsDate := Params[i].AsDateTime;
441 >        ftTime:
442 >          SQLParam.AsTime := Params[i].AsDateTime;
443 >        ftDateTime:
444 >          SQLParam.AsDateTime := Params[i].AsDateTime;
445 >        ftBlob, ftMemo:
446 >          SQLParam.AsString := Params[i].AsString;
447 >        else
448 >          IBError(ibxeNotSupported, [nil]);
449 >      end;
450 >    end;
451 >  end;
452 > end;
453 >
454 > procedure TIBQuery.PrepareSQL;
455 > var List: TParams;
456 > begin
457 >  QSelect.GenerateParamNames := GenerateParamNames;
458 >  InternalPrepare;
459 >  UpdateSQL;
460 >  if ParamCheck  then
461 >  begin
462 >    List := TParams.Create(Self);
463 >    try
464 >      FText := List.ParseSQL(SQL.Text, True);
465 >      List.AssignValues(FParams);
466 >      FParams.Clear;
467 >      FParams.Assign(List);
468 >    finally
469 >      List.Free;
470 >    end;
471 >  end;
472 > end;
473 >
474 >
475 > function TIBQuery.GetRowsAffected: Integer;
476 > begin
477 >  Result := -1;
478 >  if Prepared then
479 >   Result := QSelect.RowsAffected
480 > end;
481 >
482 >
483 > procedure TIBQuery.GetDetailLinkFields(MasterFields, DetailFields: TList);
484 >
485 >  function AddFieldToList(const FieldName: string; DataSet: TDataSet;
486 >    List: TList): Boolean;
487 >  var
488 >    Field: TField;
489 >  begin
490 >    Field := DataSet.FindField(FieldName);
491 >    if (Field <> nil) then
492 >      List.Add(Field);
493 >    Result := Field <> nil;
494 >  end;
495 >
496 > var
497 >  i: Integer;
498 > begin
499 >  MasterFields.Clear;
500 >  DetailFields.Clear;
501 >  if (DataSource <> nil) and (DataSource.DataSet <> nil) then
502 >    for i := 0 to Params.Count - 1 do
503 >      if AddFieldToList(Params[i].Name, DataSource.DataSet, MasterFields) then
504 >        AddFieldToList(Params[i].Name, Self, DetailFields);
505 > end;
506 >
507 > function TIBQuery.GetStmtHandle: IStatement;
508 > begin
509 >  Result := SelectStmtHandle;
510 > end;
511 >
512 > procedure TIBQuery.UpdateSQL;
513 > begin
514 >  if not FSQLUpdating and not FInQueryChanged and (SQL.Text <> SelectSQL.Text) then
515 >  begin
516 >    FSQLUpdating := true;
517 >    try
518 >      SQL.Text := SelectSQL.Text;
519 >    finally
520 >      FSQLUpdating := false
521 >    end;
522 >  end;
523 > end;
524 >
525 > function TIBQuery.GenerateQueryForLiveUpdate : Boolean;
526 > begin
527 >  Result := False;
528 > end;
529 >
530 > procedure TIBQuery.SetFiltered(Value: Boolean);
531 > begin
532 >  if(Filtered <> Value) then
533 >  begin
534 >    inherited SetFiltered(value);
535 >    if Active then
536 >    begin
537 >      Close;
538 >      Open;
539 >    end;
540 >  end
541 >  else
542 >    inherited SetFiltered(value);
543 > end;
544 >
545 > procedure TIBQuery.SQLChanged(Sender: TObject);
546 > begin
547 >  inherited SQLChanged(Sender);
548 >  UpdateSQL;
549 > end;
550 >
551 > procedure TIBQuery.SQLChanging(Sender: TObject);
552 > begin
553 >  inherited SQLChanging(Sender);
554 >  Prepared := false;
555 > end;
556 >
557 > { TIBQuery IProviderSupport }
558 > (*
559 > function TIBQuery.PSGetParams: TParams;
560 > begin
561 >  Result := Params;
562 > end;
563 >
564 > procedure TIBQuery.PSSetParams(AParams: TParams);
565 > begin
566 >  if AParams.Count <> 0 then
567 >    Params.Assign(AParams);
568 >  Close;
569 > end;
570 >
571 > function TIBQuery.PSGetTableName: string;
572 > begin
573 >  Result := inherited PSGetTableName;
574 > end;
575 >
576 > procedure TIBQuery.PSExecute;
577 > begin
578 >  ExecSQL;
579 > end;
580 >
581 > procedure TIBQuery.PSSetCommandText(const CommandText: string);
582 > begin
583 >  if CommandText <> '' then
584 >    SQL.Text := CommandText;
585 > end;
586 > *)
587 > end.
588 >

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines