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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines