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

Comparing ibx/trunk/runtime/IBCustomDataSet.pas (file contents):
Revision 101 by tony, Thu Jan 18 14:37:18 2018 UTC vs.
Revision 106 by tony, Thu Jan 18 14:37:35 2018 UTC

# Line 315 | Line 315 | type
315      FFieldName: string;
316      FGeneratorName: string;
317      FIncrement: integer;
318 +    FQuery: TIBSQL;
319 +    function GetDatabase: TIBDatabase;
320 +    function GetTransaction: TIBTransaction;
321 +    procedure SetDatabase(AValue: TIBDatabase);
322 +    procedure SetGeneratorName(AValue: string);
323      procedure SetIncrement(const AValue: integer);
324 +    procedure SetTransaction(AValue: TIBTransaction);
325 +    procedure SetQuerySQL;
326    protected
327 <    function GetNextValue(ADatabase: TIBDatabase; ATransaction: TIBTransaction): integer;
327 >    function GetNextValue: integer;
328    public
329      constructor Create(Owner: TIBCustomDataSet);
330 +    destructor Destroy; override;
331      procedure Apply;
332      property Owner: TIBCustomDataSet read FOwner;
333 +    property Database: TIBDatabase read GetDatabase write SetDatabase;
334 +    property Transaction: TIBTransaction read GetTransaction write SetTransaction;
335    published
336 <    property Generator: string read FGeneratorName write FGeneratorName;
336 >    property Generator: string read FGeneratorName write SetGeneratorName;
337      property Field: string read FFieldName write FFieldName;
338      property Increment: integer read FIncrement write SetIncrement default 1;
339      property ApplyOnEvent: TIBGeneratorApplyOnEvent read FApplyOnEvent write FApplyOnEvent;
# Line 2064 | Line 2074 | procedure TIBCustomDataSet.ColumnDataToB
2074                 ColumnIndex, FieldIndex: integer; Buffer: PChar);
2075   var
2076    LocalData: PByte;
2077 <  LocalDate, LocalDouble: Double;
2077 >  LocalDate: TDateTime;
2078 >  LocalDouble: Double;
2079    LocalInt: Integer;
2080    LocalBool: wordBool;
2081    LocalInt64: Int64;
2082    LocalCurrency: Currency;
2072  p: PRecordData;
2083    ColData: ISQLData;
2084   begin
2075  p := PRecordData(Buffer);
2085    LocalData := nil;
2086 <  with p^.rdFields[FieldIndex], FFieldColumns^[FieldIndex] do
2086 >  with PRecordData(Buffer)^.rdFields[FieldIndex], FFieldColumns^[FieldIndex] do
2087    begin
2088      QryResults.GetData(ColumnIndex,fdIsNull,fdDataLength,LocalData);
2089      if not fdIsNull then
2090      begin
2091        ColData := QryResults[ColumnIndex];
2092        case fdDataType of  {Get Formatted data for column types that need formatting}
2093 +        SQL_TYPE_DATE,
2094 +        SQL_TYPE_TIME,
2095          SQL_TIMESTAMP:
2096          begin
2097 <          LocalDate := TimeStampToMSecs(DateTimeToTimeStamp(ColData.AsDateTime));
2097 >          {This is an IBX native format and not the TDataset approach. See also GetFieldData}
2098 >          LocalDate := ColData.AsDateTime;
2099            LocalData := PByte(@LocalDate);
2100          end;
2089        SQL_TYPE_DATE:
2090        begin
2091          LocalInt := DateTimeToTimeStamp(ColData.AsDateTime).Date;
2092          LocalData := PByte(@LocalInt);
2093        end;
2094        SQL_TYPE_TIME:
2095        begin
2096          LocalInt := DateTimeToTimeStamp(ColData.AsDateTime).Time;
2097          LocalData := PByte(@LocalInt);
2098        end;
2101          SQL_SHORT, SQL_LONG:
2102          begin
2103            if (fdDataScale = 0) then
# Line 2717 | Line 2719 | begin
2719      FQSelect.Database := Value;
2720      FQModify.Database := Value;
2721      FDatabaseInfo.Database := Value;
2722 +    FGeneratorField.Database := Value;
2723    end;
2724   end;
2725  
# Line 2820 | Line 2823 | begin
2823              end;
2824              SQL_BLOB, SQL_ARRAY, SQL_QUAD:
2825                Param.AsQuad := PISC_QUAD(data)^;
2826 <            SQL_TYPE_DATE:
2827 <            begin
2825 <              ts.Date := PInt(data)^;
2826 <              ts.Time := 0;
2827 <              Param.AsDate := TimeStampToDateTime(ts);
2828 <            end;
2829 <            SQL_TYPE_TIME:
2830 <            begin
2831 <              ts.Date := 0;
2832 <              ts.Time := PInt(data)^;
2833 <              Param.AsTime := TimeStampToDateTime(ts);
2834 <            end;
2826 >            SQL_TYPE_DATE,
2827 >            SQL_TYPE_TIME,
2828              SQL_TIMESTAMP:
2829 <              Param.AsDateTime :=
2830 <                       TimeStampToDateTime(MSecsToTimeStamp(trunc(PDouble(data)^)));
2829 >            {This is an IBX native format and not the TDataset approach. See also SetFieldData}
2830 >              Param.AsDateTime := PDateTime(data)^;
2831              SQL_BOOLEAN:
2832                Param.AsBoolean := PWordBool(data)^;
2833            end;
# Line 2885 | Line 2878 | begin
2878      FQRefresh.Transaction := Value;
2879      FQSelect.Transaction := Value;
2880      FQModify.Transaction := Value;
2881 +    FGeneratorField.Transaction := Value;
2882    end;
2883   end;
2884  
# Line 4160 | Line 4154 | begin
4154      for i := 0 to SQLParams.GetCount - 1 do
4155      begin
4156        cur_field := DataSource.DataSet.FindField(SQLParams[i].Name);
4157 <      cur_param := SQLParams[i];
4158 <      if (cur_field <> nil) then begin
4157 >      if (cur_field <> nil) then
4158 >      begin
4159 >        cur_param := SQLParams[i];
4160          if (cur_field.IsNull) then
4161            cur_param.IsNull := True
4162 <        else case cur_field.DataType of
4162 >        else
4163 >        case cur_field.DataType of
4164            ftString:
4165              cur_param.AsString := cur_field.AsString;
4166            ftBoolean:
# Line 4174 | Line 4170 | begin
4170            ftInteger:
4171              cur_param.AsLong := cur_field.AsInteger;
4172            ftLargeInt:
4173 <            cur_param.AsInt64 := TLargeIntField(cur_field).AsLargeInt;
4173 >            cur_param.AsInt64 := cur_field.AsLargeInt;
4174            ftFloat, ftCurrency:
4175             cur_param.AsDouble := cur_field.AsFloat;
4176            ftBCD:
# Line 4928 | Line 4924 | end;
4924   function TIBCustomDataSet.GetFieldData(Field: TField; Buffer: Pointer;
4925    NativeFormat: Boolean): Boolean;
4926   begin
4927 <  if (Field.DataType = ftBCD) and not NativeFormat then
4927 >  {These datatypes use IBX conventions and not TDataset conventions}
4928 >  if (Field.DataType in [ftBCD,ftDateTime,ftDate,ftTime]) and not NativeFormat then
4929      Result := InternalGetFieldData(Field, Buffer)
4930    else
4931      Result := inherited GetFieldData(Field, Buffer, NativeFormat);
# Line 4954 | Line 4951 | end;
4951   procedure TIBCustomDataSet.SetFieldData(Field: TField; Buffer: Pointer;
4952    NativeFormat: Boolean);
4953   begin
4954 <  if (not NativeFormat) and (Field.DataType = ftBCD) then
4954 >  {These datatypes use IBX conventions and not TDataset conventions}
4955 >  if (not NativeFormat) and (Field.DataType in [ftBCD,ftDateTime,ftDate,ftTime]) then
4956      InternalSetfieldData(Field, Buffer)
4957    else
4958      inherited SetFieldData(Field, buffer, NativeFormat);
# Line 5058 | Line 5056 | end;
5056  
5057   procedure TIBGenerator.SetIncrement(const AValue: integer);
5058   begin
5059 +  if FIncrement = AValue then Exit;
5060    if AValue < 0 then
5061 <     raise Exception.Create('A Generator Increment cannot be negative');
5062 <  FIncrement := AValue
5061 >    IBError(ibxeNegativeGenerator,[]);
5062 >  FIncrement := AValue;
5063 >  SetQuerySQL;
5064   end;
5065  
5066 < function TIBGenerator.GetNextValue(ADatabase: TIBDatabase;
5067 <  ATransaction: TIBTransaction): integer;
5066 > procedure TIBGenerator.SetTransaction(AValue: TIBTransaction);
5067   begin
5068 <  with TIBSQL.Create(nil) do
5069 <  try
5070 <    Database := ADatabase;
5071 <    Transaction := ATransaction;
5072 <    if not assigned(Database) then
5073 <       IBError(ibxeCannotSetDatabase,[]);
5074 <    if not assigned(Transaction) then
5075 <       IBError(ibxeCannotSetTransaction,[]);
5076 <    with Transaction do
5077 <      if not InTransaction then StartTransaction;
5078 <    SQL.Text := Format('Select Gen_ID(%s,%d) as ID From RDB$Database',[FGeneratorName,Increment]);
5079 <    Prepare;
5068 >  FQuery.Transaction := AValue;
5069 > end;
5070 >
5071 > procedure TIBGenerator.SetQuerySQL;
5072 > begin
5073 >  FQuery.SQL.Text := Format('Select Gen_ID(%s,%d) From RDB$Database',[FGeneratorName,Increment]);
5074 > end;
5075 >
5076 > function TIBGenerator.GetDatabase: TIBDatabase;
5077 > begin
5078 >  Result := FQuery.Database;
5079 > end;
5080 >
5081 > function TIBGenerator.GetTransaction: TIBTransaction;
5082 > begin
5083 >  Result := FQuery.Transaction;
5084 > end;
5085 >
5086 > procedure TIBGenerator.SetDatabase(AValue: TIBDatabase);
5087 > begin
5088 >  FQuery.Database := AValue;
5089 > end;
5090 >
5091 > procedure TIBGenerator.SetGeneratorName(AValue: string);
5092 > begin
5093 >  if FGeneratorName = AValue then Exit;
5094 >  FGeneratorName := AValue;
5095 >  SetQuerySQL;
5096 > end;
5097 >
5098 > function TIBGenerator.GetNextValue: integer;
5099 > begin
5100 >  with FQuery do
5101 >  begin
5102 >    Transaction.Active := true;
5103      ExecQuery;
5104      try
5105 <      Result := FieldByName('ID').AsInteger
5105 >      Result := Fields[0].AsInteger
5106      finally
5107        Close
5108      end;
5087  finally
5088    Free
5109    end;
5110   end;
5111  
# Line 5093 | Line 5113 | constructor TIBGenerator.Create(Owner: T
5113   begin
5114    FOwner := Owner;
5115    FIncrement := 1;
5116 +  FQuery := TIBSQL.Create(nil);
5117 + end;
5118 +
5119 + destructor TIBGenerator.Destroy;
5120 + begin
5121 +  if assigned(FQuery) then FQuery.Free;
5122 +  inherited Destroy;
5123   end;
5124  
5125  
5126   procedure TIBGenerator.Apply;
5127   begin
5128 <  if (FGeneratorName <> '') and (FFieldName <> '') and Owner.FieldByName(FFieldName).IsNull then
5129 <    Owner.FieldByName(FFieldName).AsInteger := GetNextValue(Owner.Database,Owner.Transaction);
5128 >  if assigned(Database) and assigned(Transaction) and
5129 >       (FGeneratorName <> '') and (FFieldName <> '') and Owner.FieldByName(FFieldName).IsNull then
5130 >    Owner.FieldByName(FFieldName).AsInteger := GetNextValue;
5131   end;
5132  
5133  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines