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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines