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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines