瀏覽代碼

fcl-db: base: AsLongWord property + getter/setters for TField and TParam + TLongWordField class

git-svn-id: trunk@47219 -
lacak 4 年之前
父節點
當前提交
a8cd770b3c
共有 3 個文件被更改,包括 341 次插入87 次删除
  1. 75 27
      packages/fcl-db/src/base/db.pas
  2. 24 1
      packages/fcl-db/src/base/dsparams.inc
  3. 242 59
      packages/fcl-db/src/base/fields.inc

+ 75 - 27
packages/fcl-db/src/base/db.pas

@@ -341,6 +341,7 @@ type
     function GetAsDateTime: TDateTime; virtual;
     function GetAsFloat: Double; virtual;
     function GetAsLongint: Longint; virtual;
+    function GetAsLongWord: LongWord; virtual;
     function GetAsInteger: Longint; virtual;
     function GetAsVariant: variant; virtual;
     function GetOldValue: variant; virtual;
@@ -370,6 +371,7 @@ type
     procedure SetAsDateTime(AValue: TDateTime); virtual;
     procedure SetAsFloat(AValue: Double); virtual;
     procedure SetAsLongint(AValue: Longint); virtual;
+    procedure SetAsLongWord(AValue: LongWord); virtual;
     procedure SetAsInteger(AValue: Longint); virtual;
     procedure SetAsLargeInt(AValue: Largeint); virtual;
     procedure SetAsVariant(const AValue: variant); virtual;
@@ -408,6 +410,7 @@ type
     property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime;
     property AsFloat: Double read GetAsFloat write SetAsFloat;
     property AsLongint: Longint read GetAsLongint write SetAsLongint;
+    property AsLongWord: LongWord read GetAsLongWord write SetAsLongWord;
     property AsLargeInt: LargeInt read GetAsLargeInt write SetAsLargeInt;
     property AsInteger: Longint read GetAsInteger write SetAsInteger;
     property AsString: string read GetAsString write SetAsString;
@@ -482,6 +485,7 @@ type
     function GetAsFloat: Double; override;
     function GetAsInteger: Longint; override;
     function GetAsLargeInt: Largeint; override;
+    function GetAsLongWord: LongWord; override;
     function GetAsString: String; override;
     function GetAsAnsiString: AnsiString; override;
     function GetAsUTF8String: UTF8String; override;
@@ -495,6 +499,7 @@ type
     procedure SetAsFloat(AValue: Double); override;
     procedure SetAsInteger(AValue: Longint); override;
     procedure SetAsLargeInt(AValue: Largeint); override;
+    procedure SetAsLongWord(AValue: LongWord); override;
     procedure SetAsString(const AValue: String); override;
     procedure SetAsAnsiString(const AValue: AnsiString); override;
     procedure SetAsUTF8String(const AValue: UTF8String); override;
@@ -576,6 +581,7 @@ type
   protected
     function GetAsFloat: Double; override;
     function GetAsInteger: Longint; override;
+    function GetAsLongWord: LongWord; override;
     function GetAsString: string; override;
     function GetAsVariant: variant; override;
     function GetDataSize: Integer; override;
@@ -583,6 +589,7 @@ type
     function GetValue(var AValue: Longint): Boolean;
     procedure SetAsFloat(AValue: Double); override;
     procedure SetAsInteger(AValue: Longint); override;
+    procedure SetAsLongWord(AValue: LongWord); override;
     procedure SetAsString(const AValue: string); override;
     procedure SetVarValue(const AValue: Variant); override;
     function GetAsLargeInt: Largeint; override;
@@ -597,6 +604,66 @@ type
   end;
   TIntegerField = Class(TLongintField);
 
+{ TSmallintField }
+
+  TSmallintField = class(TLongintField)
+  protected
+    function GetDataSize: Integer; override;
+  public
+    constructor Create(AOwner: TComponent); override;
+  end;
+
+{ TWordField }
+
+  TWordField = class(TLongintField)
+  protected
+    function GetDataSize: Integer; override;
+  public
+    constructor Create(AOwner: TComponent); override;
+  end;
+
+{ TAutoIncField }
+
+  TAutoIncField = class(TLongintField)
+  Protected
+    procedure SetAsInteger(AValue: Longint); override;
+  public
+    constructor Create(AOwner: TComponent); override;
+  end;
+
+{ TLongWordField }
+
+  TLongWordField = class(TNumericField)
+  private
+    FMinValue,
+    FMaxValue : LongWord;
+    Procedure SetMinValue (AValue : LongWord);
+    Procedure SetMaxValue (AValue : LongWord);
+  protected
+    function GetAsFloat: Double; override;
+    function GetAsInteger: Longint; override;
+    function GetAsLargeInt: Largeint; override;
+    function GetAsLongWord: LongWord; override;
+    function GetAsString: string; override;
+    function GetAsVariant: variant; override;
+    function GetDataSize: Integer; override;
+    procedure GetText(var AText: string; ADisplayText: Boolean); override;
+    function GetValue(var AValue: LongWord): Boolean;
+    procedure SetAsFloat(AValue: Double); override;
+    procedure SetAsInteger(AValue: Longint); override;
+    procedure SetAsLargeInt(AValue: Largeint); override;
+    procedure SetAsLongWord(AValue: LongWord); override;
+    procedure SetAsString(const AValue: string); override;
+    procedure SetVarValue(const AValue: Variant); override;
+  public
+    constructor Create(AOwner: TComponent); override;
+    Function CheckRange(AValue : LargeInt) : Boolean;
+    property Value: LongWord read GetAsLongWord write SetAsLongWord;
+  published
+    property MaxValue: LongWord read FMaxValue write SetMaxValue default 0;
+    property MinValue: LongWord read FMinValue write SetMinValue default 0;
+  end;
+
 { TLargeintField }
 
   TLargeintField = class(TNumericField)
@@ -611,6 +678,7 @@ type
     function GetAsFloat: Double; override;
     function GetAsInteger: Longint; override;
     function GetAsLargeInt: Largeint; override;
+    function GetAsLongWord: LongWord; override;
     function GetAsString: string; override;
     function GetAsVariant: variant; override;
     function GetDataSize: Integer; override;
@@ -619,6 +687,7 @@ type
     procedure SetAsFloat(AValue: Double); override;
     procedure SetAsInteger(AValue: Longint); override;
     procedure SetAsLargeInt(AValue: Largeint); override;
+    procedure SetAsLongWord(AValue: LongWord); override;
     procedure SetAsString(const AValue: string); override;
     procedure SetVarValue(const AValue: Variant); override;
   public
@@ -630,33 +699,6 @@ type
     property MinValue: Largeint read FMinValue write SetMinValue default 0;
   end;
 
-{ TSmallintField }
-
-  TSmallintField = class(TLongintField)
-  protected
-    function GetDataSize: Integer; override;
-  public
-    constructor Create(AOwner: TComponent); override;
-  end;
-
-{ TWordField }
-
-  TWordField = class(TLongintField)
-  protected
-    function GetDataSize: Integer; override;
-  public
-    constructor Create(AOwner: TComponent); override;
-  end;
-
-{ TAutoIncField }
-
-  TAutoIncField = class(TLongintField)
-  Protected
-    procedure SetAsInteger(AValue: Longint); override;
-  public
-    constructor Create(AOwner: TComponent); override;
-  end;
-
 { TFloatField }
 
   TFloatField = class(TNumericField)
@@ -671,6 +713,7 @@ type
     function GetAsBCD: TBCD; override;
     function GetAsFloat: Double; override;
     function GetAsLargeInt: LargeInt; override;
+    function GetAsLongWord: LongWord; override;
     function GetAsInteger: Longint; override;
     function GetAsVariant: variant; override;
     function GetAsString: string; override;
@@ -679,6 +722,7 @@ type
     procedure SetAsBCD(const AValue: TBCD); override;
     procedure SetAsFloat(AValue: Double); override;
     procedure SetAsLargeInt(AValue: LargeInt); override;
+    procedure SetAsLongWord(AValue: LongWord); override;
     procedure SetAsInteger(AValue: Longint); override;
     procedure SetAsString(const AValue: string); override;
     procedure SetVarValue(const AValue: Variant); override;
@@ -1199,6 +1243,7 @@ type
     Function GetAsFloat: Double;
     Function GetAsInteger: Longint;
     Function GetAsLargeInt: LargeInt;
+    Function GetAsLongWord: LongWord;
     Function GetAsMemo: string;
     Function GetAsString: string;
     Function GetAsAnsiString: AnsiString;
@@ -1220,6 +1265,7 @@ type
     Procedure SetAsFloat(const AValue: Double);
     Procedure SetAsInteger(AValue: Longint);
     Procedure SetAsLargeInt(AValue: LargeInt);
+    Procedure SetAsLongWord(AValue: LongWord);
     Procedure SetAsMemo(const AValue: string);
     Procedure SetAsSmallInt(AValue: LongInt);
     Procedure SetAsString(const AValue: string);
@@ -1258,6 +1304,7 @@ type
     Property AsFloat : Double read GetAsFloat write SetAsFloat;
     Property AsInteger : LongInt read GetAsInteger write SetAsInteger;
     Property AsLargeInt : LargeInt read GetAsLargeInt write SetAsLargeInt;
+    Property AsLongWord: LongWord read GetAsLongWord write SetAsLongWord;
     Property AsMemo : string read GetAsMemo write SetAsMemo;
     Property AsSmallInt : LongInt read GetAsInteger write SetAsSmallInt;
     Property AsString : string read GetAsString write SetAsString;
@@ -2338,6 +2385,7 @@ end;
 
 
 { EUpdateError }
+
 constructor EUpdateError.Create(NativeError, Context : String;
                                 ErrCode, PrevError : integer; E: Exception);
                                 

+ 24 - 1
packages/fcl-db/src/base/dsparams.inc

@@ -626,6 +626,13 @@ begin
     Result:=FValue;
 end;
 
+function TParam.GetAsLongWord: LongWord;
+begin
+  If IsNull then
+    Result:=0
+  else
+    Result:=FValue;
+end;
 
 Function TParam.GetAsMemo: string;
 begin
@@ -783,6 +790,12 @@ begin
   Value:=AValue;
 end;
 
+Procedure TParam.SetAsLongWord(AValue: LongWord);
+begin
+  FDataType:=ftLongWord;
+  Value:=AValue;
+end;
+
 Procedure TParam.SetAsMemo(const AValue: string);
 begin
   FDataType:=ftMemo;
@@ -851,7 +864,7 @@ begin
       varWord,
       varInteger  : FDataType:=ftInteger;
       varCurrency : FDataType:=ftCurrency;
-      varLongWord,
+      varLongWord : FDataType:=ftLongWord;
       varSingle,
       varDouble   : FDataType:=ftFloat;
       varDate     : FDataType:=ftDateTime;
@@ -961,6 +974,8 @@ begin
       ftWord     : Field.AsInteger:=AsWord;
       ftInteger,
       ftAutoInc  : Field.AsInteger:=AsInteger;
+      ftLongWord : Field.AsLongWord:=AsLongword;
+      ftLargeInt : Field.AsLargeInt:=AsLargeInt;
       ftCurrency : Field.AsCurrency:=AsCurrency;
       ftFloat    : Field.AsFloat:=AsFloat;
       ftBoolean  : Field.AsBoolean:=AsBoolean;
@@ -1000,6 +1015,8 @@ begin
       ftWord     : AsWord:=Field.AsInteger;
       ftInteger,
       ftAutoInc  : AsInteger:=Field.AsInteger;
+      ftLargeInt : AsLargeInt:=Field.AsLargeInt;
+      ftLongWord : AsLongWord:=Field.AsLongWord;
       ftBCD,
       ftCurrency : AsCurrency:=Field.AsCurrency;
       ftFloat    : AsFloat:=Field.AsFloat;
@@ -1074,6 +1091,8 @@ begin
     ftWord     : PWord(Buffer)^:=AsWord;
     ftInteger,
     ftAutoInc  : PInteger(Buffer)^:=AsInteger;
+    ftLargeInt : PInt64(Buffer)^:=AsLargeInt;
+    ftLongWord : PLongWord(Buffer)^:=AsLongWord;
     ftCurrency : PDouble(Buffer)^:=AsCurrency;
     ftFloat    : PDouble(Buffer)^:=AsFloat;
     ftBoolean  : PWordBool(Buffer)^:=AsBoolean;
@@ -1134,6 +1153,8 @@ begin
     ftAutoInc  : Result:=SizeOf(Integer);
     ftSmallint : Result:=SizeOf(SmallInt);
     ftWord     : Result:=SizeOf(Word);
+    ftLongWord : Result:=SizeOf(LongWord);
+    ftLargeInt : Result:=SizeOf(Int64);
     ftTime,
     ftDate     : Result:=SizeOf(Integer);
     ftDateTime,
@@ -1223,6 +1244,8 @@ begin
     ftWord     : AsWord:=PWord(Buffer)^;
     ftInteger,
     ftAutoInc  : AsInteger:=PInteger(Buffer)^;
+    ftLargeInt : AsLargeInt:=PInt64(Buffer)^;
+    ftLongWord : AsLongWord:=PLongWord(Buffer)^;
     ftCurrency : AsCurrency:= PDouble(Buffer)^;
     ftFloat    : AsFloat:=PDouble(Buffer)^;
     ftBoolean  : AsBoolean:=PWordBool(Buffer)^;

+ 242 - 59
packages/fcl-db/src/base/fields.inc

@@ -340,6 +340,7 @@ Const
   SFloat = 'Float';
   SInteger = 'Integer';
   SLargeInt = 'LargeInt';
+  SLongWord = 'LongWord';
   SVariant = 'Variant';
   SString = 'String';
   SBytes = 'Bytes';
@@ -370,7 +371,7 @@ end;
 function TField.AccessError(const TypeName: string): EDatabaseError;
 
 begin
-  Result:=EDatabaseError.CreateFmt(SinvalidTypeConversion,[TypeName,FFieldName]);
+  Result:=EDatabaseError.CreateFmt(SInvalidTypeConversion,[TypeName,FFieldName]);
 end;
 
 procedure TField.Assign(Source: TPersistent);
@@ -533,6 +534,11 @@ begin
   Result:=GetAsInteger;
 end;
 
+function TField.GetAsLongWord: LongWord;
+begin
+  raise AccessError(SLongWord);
+end;
+
 function TField.GetAsInteger: Longint;
 
 begin
@@ -892,6 +898,11 @@ begin
   SetAsInteger(AValue);
 end;
 
+procedure TField.SetAsLongWord(AValue: LongWord);
+begin
+  raise AccessError(SLongWord);
+end;
+
 procedure TField.SetAsInteger(AValue: Longint);
 begin
   raise AccessError(SInteger);
@@ -1173,6 +1184,11 @@ begin
   Result:=StrToInt64(GetAsString);
 end;
 
+function TStringField.GetAsLongWord: LongWord;
+begin
+  Result:=StrToDWord(GetAsString);
+end;
+
 function TStringField.GetAsString: String;
 begin
 {$IFDEF UNICODE}
@@ -1311,6 +1327,11 @@ begin
   SetAsString(IntToStr(AValue));
 end;
 
+procedure TStringField.SetAsLongWord(AValue: LongWord);
+begin
+  SetAsString(IntToStr(AValue));
+end;
+
 procedure TStringField.SetValue(AValue: RawByteString);
 var Buf      : TStringFieldBuffer;
     DynBuf   : array of AnsiChar;
@@ -1587,6 +1608,11 @@ begin
     Result:=0;
 end;
 
+function TLongintField.GetAsLongWord: LongWord;
+begin
+  Result:=GetAsInteger;
+end;
+
 function TLongintField.GetAsVariant: Variant;
 
 var L : Longint;
@@ -1621,7 +1647,7 @@ var l : longint;
     fmt : string;
 
 begin
-  Atext:='';
+  AText:='';
   If Not GetValue(l) then exit;
   If ADisplayText or (FEditFormat='') then
     fmt:=FDisplayFormat
@@ -1675,6 +1701,11 @@ begin
       RangeError(AValue,FMinRange,FMaxRange);
 end;
 
+procedure TLongintField.SetAsLongWord(AValue: LongWord);
+begin
+  SetAsInteger(AValue);
+end;
+
 procedure TLongintField.SetVarValue(const AValue: Variant);
 begin
   SetAsInteger(AValue);
@@ -1724,10 +1755,198 @@ begin
     RangeError(AValue,FMinRange,FMaxRange);
 end;
 
+{ TSmallintField }
+
+function TSmallintField.GetDataSize: Integer;
+
+begin
+  Result:=SizeOf(SmallInt);
+end;
+
+constructor TSmallintField.Create(AOwner: TComponent);
+
+begin
+  inherited Create(AOwner);
+  SetDataType(ftSmallInt);
+  FMinRange:=-32768;
+  FMaxRange:=32767;
+end;
+
+
+{ TWordField }
+
+function TWordField.GetDataSize: Integer;
+
+begin
+  Result:=SizeOf(Word);
+end;
+
+constructor TWordField.Create(AOwner: TComponent);
+
+begin
+  inherited Create(AOwner);
+  SetDataType(ftWord);
+  FMinRange:=0;
+  FMaxRange:=65535;
+  FValidchars:=['+','0'..'9'];
+end;
+
+{ TAutoIncField }
+
+constructor TAutoIncField.Create(AOwner: TComponent);
+
+begin
+  Inherited Create(AOWner);
+  SetDataType(ftAutoInc);
+end;
+
+Procedure TAutoIncField.SetAsInteger(AValue: Longint);
+
+begin
+  // Some databases allows insertion of explicit values into identity columns
+  // (some of them also allows (some not) updating identity columns)
+  // So allow it at client side and leave check for server side
+  //if not(FDataSet.State in [dsFilter,dsSetKey,dsInsert]) then
+  //  DataBaseError(SCantSetAutoIncFields);
+  inherited;
+end;
+
 { ---------------------------------------------------------------------
-    TLargeintField
+    TLongWordField
   ---------------------------------------------------------------------}
 
+constructor TLongWordField.Create(AOwner: TComponent);
+begin
+  Inherited Create(AOwner);
+  SetDataType(ftLongWord);
+  FValidchars:=['+','-','0'..'9'];
+end;
+
+function TLongWordField.CheckRange(AValue: LargeInt): Boolean;
+begin
+  if (FMinValue<>0) or (FMaxValue<>0) then
+    Result := (AValue>=FMinValue) and (AValue<=FMaxValue)
+  else
+    Result := (AValue>=0) and (AValue<=High(LongWord));
+end;
+
+procedure TLongWordField.SetMinValue(AValue: LongWord);
+begin
+  FMinValue:=AValue
+end;
+
+procedure TLongWordField.SetMaxValue(AValue: LongWord);
+begin
+  FMaxValue:=AValue
+end;
+
+function TLongWordField.GetAsFloat: Double;
+begin
+  Result:=GetAsLongWord;
+end;
+
+function TLongWordField.GetAsInteger: Longint;
+begin
+  Result:=GetAsLongWord;
+end;
+
+function TLongWordField.GetAsLargeInt: Largeint;
+begin
+  Result:=GetAsLongWord;
+end;
+
+function TLongWordField.GetAsLongWord: LongWord;
+begin
+  if not GetValue(Result) then
+    Result:=0;
+end;
+
+function TLongWordField.GetAsString: string;
+begin
+  Result:=IntToStr(GetAsLongWord);
+end;
+
+function TLongWordField.GetAsVariant: variant;
+var L: LongWord;
+begin
+  If GetValue(L) then
+    Result:=L
+  else
+    Result:=Null;
+end;
+
+function TLongWordField.GetDataSize: Integer;
+begin
+  Result:=SizeOf(LongWord);
+end;
+
+procedure TLongWordField.GetText(var AText: string; ADisplayText: Boolean);
+var
+  L : LongWord;
+  fmt : string;
+begin
+  if GetValue(L) then
+    begin
+    if ADisplayText or (FEditFormat='') then
+      fmt:=FDisplayFormat
+    else
+      fmt:=FEditFormat;
+    if fmt<>'' then
+      AText:=FormatFloat(fmt,L)
+    else
+      Str(L,AText);
+    end
+  else
+    AText:='';
+end;
+
+function TLongWordField.GetValue(var AValue: LongWord): Boolean;
+begin
+  Result:=GetData(@AValue);
+end;
+
+procedure TLongWordField.SetAsFloat(AValue: Double);
+begin
+  SetAsLargeInt(Round(AValue));
+end;
+
+procedure TLongWordField.SetAsInteger(AValue: Longint);
+begin
+  SetAsLargeInt(AValue);
+end;
+
+procedure TLongWordField.SetAsLargeInt(AValue: Largeint);
+begin
+  if (AValue>=0) and (AValue<=High(LongWord)) then
+    SetAsLongWord(AValue)
+  else
+    RangeError(AValue,0,High(LongWord));
+end;
+
+procedure TLongWordField.SetAsLongWord(AValue: LongWord);
+begin
+  if CheckRange(AValue) then
+    SetData(@AValue)
+  else
+    RangeError(AValue,FMinValue,FMaxValue);
+end;
+
+procedure TLongWordField.SetAsString(const AValue: string);
+begin
+  if AValue='' then
+    Clear
+  else
+    SetAsLongWord(StrToDWord(AValue));
+end;
+
+procedure TLongWordField.SetVarValue(const AValue: Variant);
+begin
+  SetAsLongWord(AValue);
+end;
+
+{ ---------------------------------------------------------------------
+    TLargeintField
+  ---------------------------------------------------------------------}
 
 constructor TLargeintField.Create(AOwner: TComponent);
 
@@ -1752,6 +1971,11 @@ begin
     Result:=0;
 end;
 
+function TLargeintField.GetAsLongWord: LongWord;
+begin
+  Result:=GetAsLargeInt;
+end;
+
 function TLargeIntField.GetAsVariant: Variant;
 
 var L : Largeint;
@@ -1828,6 +2052,11 @@ begin
     RangeError(AValue,FMinValue,FMaxValue);
 end;
 
+procedure TLargeintField.SetAsLongWord(AValue: LongWord);
+begin
+  SetAsLargeInt(AValue);
+end;
+
 procedure TLargeintField.SetAsInteger(AValue: Longint);
 
 begin
@@ -1884,62 +2113,6 @@ begin
     RangeError(AValue,FMinRange,FMaxRange);
 end;
 
-{ TSmallintField }
-
-function TSmallintField.GetDataSize: Integer;
-
-begin
-  Result:=SizeOf(SmallInt);
-end;
-
-constructor TSmallintField.Create(AOwner: TComponent);
-
-begin
-  inherited Create(AOwner);
-  SetDataType(ftSmallInt);
-  FMinRange:=-32768;
-  FMaxRange:=32767;
-end;
-
-
-{ TWordField }
-
-function TWordField.GetDataSize: Integer;
-
-begin
-  Result:=SizeOf(Word);
-end;
-
-constructor TWordField.Create(AOwner: TComponent);
-
-begin
-  inherited Create(AOwner);
-  SetDataType(ftWord);
-  FMinRange:=0;
-  FMaxRange:=65535;
-  FValidchars:=['+','0'..'9'];
-end;
-
-{ TAutoIncField }
-
-constructor TAutoIncField.Create(AOwner: TComponent);
-
-begin
-  Inherited Create(AOWner);
-  SetDataType(ftAutoInc);
-end;
-
-Procedure TAutoIncField.SetAsInteger(AValue: Longint);
-
-begin
-  // Some databases allows insertion of explicit values into identity columns
-  // (some of them also allows (some not) updating identity columns)
-  // So allow it at client side and leave check for server side
-  //if not(FDataSet.State in [dsFilter,dsSetKey,dsInsert]) then
-  //  DataBaseError(SCantSetAutoIncFields);
-  inherited;
-end;
-
 { TFloatField }
 
 procedure TFloatField.SetCurrency(const AValue: Boolean);
@@ -1988,6 +2161,11 @@ begin
   Result:=Round(GetAsFloat);
 end;
 
+function TFloatField.GetAsLongWord: LongWord;
+begin
+  Result:=Round(GetAsFloat);
+end;
+
 function TFloatField.GetAsInteger: Longint;
 
 begin
@@ -2065,6 +2243,11 @@ begin
   SetAsFloat(AValue);
 end;
 
+procedure TFloatField.SetAsLongWord(AValue: LongWord);
+begin
+  SetAsFloat(AValue);
+end;
+
 procedure TFloatField.SetAsInteger(AValue: Longint);
 
 begin