--- ibx/trunk/runtime/IBCustomDataSet.pas 2013/12/28 19:22:24 18 +++ ibx/trunk/runtime/IBCustomDataSet.pas 2014/07/07 13:00:15 19 @@ -198,6 +198,7 @@ type TIBCustomDataSet = class(TDataset) private + FGenerateParamNames: Boolean; FGeneratorField: TIBGenerator; FNeedsRefresh: Boolean; FForcedRefresh: Boolean; @@ -250,6 +251,7 @@ type FBeforeTransactionEnd, FAfterTransactionEnd, FTransactionFree: TNotifyEvent; + FAliasNameMap: array of string; function GetSelectStmtHandle: TISC_STMT_HANDLE; procedure SetUpdateMode(const Value: TUpdateMode); @@ -321,6 +323,7 @@ type procedure DeactivateTransaction; procedure CheckDatasetClosed; procedure CheckDatasetOpen; + procedure FieldDefsFromQuery(SourceQuery: TIBSQL); function GetActiveBuf: PChar; procedure InternalBatchInput(InputObject: TIBBatchInput); virtual; procedure InternalBatchOutput(OutputObject: TIBBatchOutput); virtual; @@ -362,6 +365,8 @@ type function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override; function GetCanModify: Boolean; override; function GetDataSource: TDataSource; override; + function GetDBAliasName(FieldNo: integer): string; + function GetFieldDefFromAlias(aliasName: string): TFieldDef; function GetFieldClass(FieldType: TFieldType): TFieldClass; override; function GetRecNo: Integer; override; function GetRecord(Buffer: PChar; GetMode: TGetMode; @@ -390,6 +395,7 @@ type procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override; procedure SetCachedUpdates(Value: Boolean); procedure SetDataSource(Value: TDataSource); + procedure SetGenerateParamNames(AValue: Boolean); virtual; procedure SetFieldData(Field : TField; Buffer : Pointer); override; procedure SetFieldData(Field : TField; Buffer : Pointer; NativeFormat : Boolean); overload; override; @@ -456,6 +462,7 @@ type function GetFieldData(FieldNo: Integer; Buffer: Pointer): Boolean; overload; (*override;*) function GetFieldData(Field : TField; Buffer : Pointer; NativeFormat : Boolean) : Boolean; overload; override; + property GenerateParamNames: Boolean read FGenerateParamNames write SetGenerateParamNames; function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; override; function Lookup(const KeyFields: string; const KeyValues: Variant; @@ -543,6 +550,7 @@ type property SelectSQL; property ModifySQL; property GeneratorField; + property GenerateParamNames; property ParamCheck; property UniDirectional; property Filtered; @@ -859,6 +867,7 @@ begin FQModify.GoToFirstRecordOnExecute := False; FUpdateRecordTypes := [cusUnmodified, cusModified, cusInserted]; FParamCheck := True; + FGenerateParamNames := False; FForcedRefresh := False; {Bookmark Size is Integer for IBX} BookmarkSize := SizeOf(Integer); @@ -1895,15 +1904,20 @@ begin begin if not FQSelect.Prepared then begin + FQSelect.GenerateParamNames := FGenerateParamNames; FQSelect.ParamCheck := ParamCheck; FQSelect.Prepare; end; + FQDelete.GenerateParamNames := FGenerateParamNames; if (Trim(FQDelete.SQL.Text) <> '') and (not FQDelete.Prepared) then FQDelete.Prepare; + FQInsert.GenerateParamNames := FGenerateParamNames; if (Trim(FQInsert.SQL.Text) <> '') and (not FQInsert.Prepared) then FQInsert.Prepare; + FQRefresh.GenerateParamNames := FGenerateParamNames; if (Trim(FQRefresh.SQL.Text) <> '') and (not FQRefresh.Prepared) then FQRefresh.Prepare; + FQModify.GenerateParamNames := FGenerateParamNames; if (Trim(FQModify.SQL.Text) <> '') and (not FQModify.Prepared) then FQModify.Prepare; FInternalPrepared := True; @@ -2197,6 +2211,8 @@ begin InternalClose; if FInternalPrepared then InternalUnPrepare; + FieldDefs.Clear; + FieldDefs.Updated := false end; { I can "undelete" uninserted records (make them "inserted" again). @@ -2563,6 +2579,24 @@ begin result := FDataLink.DataSource; end; + function TIBCustomDataSet.GetDBAliasName(FieldNo: integer): string; +begin + Result := FAliasNameMap[FieldNo-1] +end; + + function TIBCustomDataSet.GetFieldDefFromAlias(aliasName: string): TFieldDef; + var + i: integer; + begin + Result := nil; + for i := 0 to Length(FAliasNameMap) - 1 do + if FAliasNameMap[i] = aliasName then + begin + Result := FieldDefs[i+1]; + Exit + end; + end; + function TIBCustomDataSet.GetFieldClass(FieldType: TFieldType): TFieldClass; begin Result := DefaultFieldClasses[FieldType]; @@ -2873,6 +2907,16 @@ begin end; procedure TIBCustomDataSet.InternalInitFieldDefs; +begin + if not InternalPrepared then + begin + InternalPrepare; + exit; + end; + FieldDefsFromQuery(FQSelect); + end; + +procedure TIBCustomDataSet.FieldDefsFromQuery(SourceQuery: TIBSQL); const DefaultSQL = 'Select F.RDB$COMPUTED_BLR, ' + {do not localize} 'F.RDB$DEFAULT_VALUE, R.RDB$FIELD_NAME ' + {do not localize} @@ -2886,7 +2930,7 @@ var FieldSize: Word; FieldNullable : Boolean; i, FieldPosition, FieldPrecision: Integer; - FieldAliasName: string; + FieldAliasName, DBAliasName: string; RelationName, FieldName: string; Query : TIBSQL; FieldIndex: Integer; @@ -2986,11 +3030,6 @@ var end; begin - if not InternalPrepared then - begin - InternalPrepare; - exit; - end; FRelationNodes := TRelationNode.Create; FNeedsRefresh := False; Database.InternalTransaction.StartTransaction; @@ -3001,20 +3040,22 @@ begin FieldDefs.BeginUpdate; FieldDefs.Clear; FieldIndex := 0; - if (Length(FMappedFieldPosition) < FQSelect.Current.Count) then - SetLength(FMappedFieldPosition, FQSelect.Current.Count); + if (Length(FMappedFieldPosition) < SourceQuery.Current.Count) then + SetLength(FMappedFieldPosition, SourceQuery.Current.Count); Query.SQL.Text := DefaultSQL; Query.Prepare; - for i := 0 to FQSelect.Current.Count - 1 do - with FQSelect.Current[i].Data^ do + SetLength(FAliasNameMap, SourceQuery.Current.Count); + for i := 0 to SourceQuery.Current.Count - 1 do + with SourceQuery.Current[i].Data^ do begin { Get the field name } - SetString(FieldAliasName, aliasname, aliasname_length); + FieldAliasName := SourceQuery.Current[i].Name; + SetString(DBAliasName, aliasname, aliasname_length); SetString(RelationName, relname, relname_length); SetString(FieldName, sqlname, sqlname_length); FieldSize := 0; FieldPrecision := 0; - FieldNullable := FQSelect.Current[i].IsNullable; + FieldNullable := SourceQuery.Current[i].IsNullable; case sqltype and not 1 of { All VARCHAR's must be converted to strings before recording their values } @@ -3100,7 +3141,7 @@ begin with FieldDefs.AddFieldDef do begin Name := FieldAliasName; - (* FieldNo := FieldPosition;*) + FAliasNameMap[FieldNo-1] := DBAliasName; DataType := FieldType; Size := FieldSize; Precision := FieldPrecision; @@ -3589,6 +3630,7 @@ begin begin CheckDatasetClosed; FieldDefs.Clear; + FieldDefs.Updated := false; FInternalPrepared := False; end; end; @@ -3628,6 +3670,13 @@ begin Result := FQSelect.Handle; end; + procedure TIBCustomDataSet.SetGenerateParamNames(AValue: Boolean); +begin + if FGenerateParamNames = AValue then Exit; + FGenerateParamNames := AValue; + Disconnect +end; + procedure TIBCustomDataSet.InitRecord(Buffer: PChar); begin inherited InitRecord(Buffer); @@ -4035,4 +4084,4 @@ begin Owner.FieldByName(FFieldName).AsInteger := GetNextValue(Owner.Database,Owner.Transaction); end; -end. +end. \ No newline at end of file