From b98c532c9e98a4a12178fb32440960b9c066e725 Mon Sep 17 00:00:00 2001 From: Ansgar Becker Date: Tue, 5 Aug 2008 21:22:55 +0000 Subject: [PATCH] Fix bug #655: Export function failure with datatype double. Also applies for floats in WHERE clauses in grid editing. --- source/childwin.pas | 30 ++++++++++++++++++++++-------- source/helpers.pas | 27 ++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/source/childwin.pas b/source/childwin.pas index f12cc1db..dfdad06d 100644 --- a/source/childwin.pas +++ b/source/childwin.pas @@ -1285,10 +1285,15 @@ begin while not FSelectedTableColumns.Eof do begin if FSelectedTableColumns.FieldByName('Field').AsWideString = FieldName then begin rx := TRegExpr.Create; - rx.Expression := '^((tiny|small|medium|big)?int|float|double|decimal)\b'; + rx.Expression := '^(tiny|small|medium|big)?int\b'; if rx.Exec(FSelectedTableColumns.FieldByName('Type').AsWideString) then begin col.Alignment := taRightJustify; - FDataGridResult.Columns[i].IsNumeric := True; + FDataGridResult.Columns[i].IsInt := True; + end; + rx.Expression := '^(float|double|decimal)\b'; + if rx.Exec(FSelectedTableColumns.FieldByName('Type').AsWideString) then begin + col.Alignment := taRightJustify; + FDataGridResult.Columns[i].IsFloat := True; end; rx.Expression := '^(date|datetime|time(stamp)?)\b'; if rx.Exec(FSelectedTableColumns.FieldByName('Type').AsWideString) then @@ -2440,8 +2445,11 @@ begin col.Width := prefDefaultColWidth; col.Options := col.Options - [coAllowClick]; FQueryGridResult.Columns[i].Name := FieldName; - if ds.Fields[i].DataType in [ftSmallint, ftInteger, ftWord, ftFloat, ftLargeint] then begin - FQueryGridResult.Columns[i].IsNumeric := True; + if ds.Fields[i].DataType in [ftSmallint, ftInteger, ftWord, ftLargeint] then begin + FQueryGridResult.Columns[i].IsInt := True; + col.Alignment := taRightJustify; + end else if ds.Fields[i].DataType in [ftFloat] then begin + FQueryGridResult.Columns[i].IsFloat := True; col.Alignment := taRightJustify; end else if ds.Fields[i].DataType in [ftDate, ftTime, ftDateTime, ftTimeStamp] then FQueryGridResult.Columns[i].IsDate := True @@ -5479,7 +5487,7 @@ begin // NULL value isNull := r.Rows[Node.Index].Cells[Column].IsNull; // Numeric field - if r.Columns[Column].isNumeric then + if r.Columns[Column].isInt or r.Columns[Column].isFloat then if isNull then cl := $FF9090 else cl := clBlue // Date field else if r.Columns[Column].isDate then @@ -5643,7 +5651,9 @@ begin for i := 0 to Length(FDataGridResult.Columns) - 1 do begin if Row.Cells[i].Modified then begin Val := Row.Cells[i].NewText; - if Not FDataGridResult.Columns[i].IsNumeric then Val := esc(Val); + if FDataGridResult.Columns[i].IsInt then // don't quote or convert + else if FDataGridResult.Columns[i].IsFloat then Val := FloatStr(Val) + else Val := esc(Val); if Row.Cells[i].NewIsNull then Val := 'NULL'; sql := sql + ' ' + mask(FDataGridResult.Columns[i].Name) + '=' + Val + ', '; end; @@ -5730,7 +5740,9 @@ begin // Find old value of key column KeyVal := Row.Cells[j].Text; // Quote if needed - if Not Columns[j].IsNumeric then KeyVal := esc(KeyVal); + if FDataGridResult.Columns[j].IsInt then + else if FDataGridResult.Columns[j].IsFloat then KeyVal := FloatStr(KeyVal) + else KeyVal := esc(KeyVal); if Row.Cells[j].IsNull then KeyVal := ' IS NULL' else KeyVal := '=' + KeyVal; Result := Result + mask(KeyCols[i]) + KeyVal + ' AND '; @@ -5815,7 +5827,9 @@ begin if Row.Cells[i].Modified then begin Cols := Cols + mask(FDataGridResult.Columns[i].Name) + ', '; Val := Row.Cells[i].NewText; - if Not FDataGridResult.Columns[i].IsNumeric then Val := esc(Val); + if FDataGridResult.Columns[i].IsInt then + else if FDataGridResult.Columns[i].IsFloat then Val := FloatStr(Val) + else Val := esc(Val); if Row.Cells[i].NewIsNull then Val := 'NULL'; Vals := Vals + Val + ', '; end; diff --git a/source/helpers.pas b/source/helpers.pas index 664f7bd3..31770a42 100644 --- a/source/helpers.pas +++ b/source/helpers.pas @@ -51,7 +51,8 @@ type IsPK: Boolean; IsBlob: Boolean; IsMemo: Boolean; - IsNumeric: Boolean; + IsInt: Boolean; + IsFloat: Boolean; IsDate: Boolean; end; TGridColumns = Array of TGridColumn; @@ -94,6 +95,7 @@ type function Mince(PathToMince: String; InSpace: Integer): String; function MakeInt( Str: String ) : Int64; function MakeFloat( Str: String ): Extended; + function FloatStr(Val: String): String; function esc(Text: WideString; ProcessJokerChars: Boolean = false; sql_version: integer = 50000): WideString; function hasNullChar(Text: string): boolean; function hasIrregularChars(Text: string): boolean; @@ -854,7 +856,7 @@ end; function dataset2csv(ds: TGridResult; Separator, Encloser, Terminator: String; filename: String = ''): Boolean; var I, J : Integer; - Buffer, cbuffer : WideString; + Buffer, cbuffer, val : WideString; tofile : Boolean; begin separator := esc2ascii(separator); @@ -881,7 +883,9 @@ begin begin if j>0 then Buffer := Buffer + Separator; - Buffer := Buffer + Encloser + ds.Rows[i].Cells[j].Text + Encloser; + val := ds.Rows[i].Cells[j].Text; + if ds.Columns[j].IsFloat then val := FloatStr(val); + Buffer := Buffer + Encloser + val + Encloser; end; // write buffer: cbuffer := cbuffer + buffer; @@ -1309,6 +1313,23 @@ begin end; +{** + Unformat a formatted float value. Used for CSV export and composing WHERE clauses for grid editing. +} +function FloatStr(Val: String): String; +var + i: Integer; +begin + Result := ''; + for i:=1 to Length(Val) do begin + if Val[i] in ['0'..'9'] then + Result := Result + Val[i] + else if Val[i] = DecimalSeparator then + Result := Result + '.'; + end; +end; + + {*** Escape all kinds of characters: