Browse Source

+ Initial implementation of params

michael 20 years ago
parent
commit
5e0bc4b8ad
3 changed files with 852 additions and 3 deletions
  1. 139 2
      fcl/db/db.pp
  2. 7 1
      fcl/db/dbconst.pp
  3. 706 0
      fcl/db/dsparams.inc

+ 139 - 2
fcl/db/db.pp

@@ -22,7 +22,7 @@ unit db;
 
 interface
 
-uses Classes,Sysutils;
+uses Classes,Sysutils,Variants;
 
 const
 
@@ -1387,6 +1387,139 @@ type
     destructor Destroy; override;
   end;
 
+  { TParam }
+
+  TBlobData = string;
+
+  TParamType = (ptUnknown, ptInput, ptOutput, ptInputOutput, ptResult);
+  TParamTypes = set of TParamType;
+
+  TParams = class;
+
+  TParam = class(TCollectionItem)
+  private
+    FNativeStr: string;
+    FValue: Variant;
+    FPrecision: Integer;
+    FNumericScale: Integer;
+    FNull: Boolean;
+    FName: string;
+    FDataType: TFieldType;
+    FBound: Boolean;
+    FParamType: TParamType;
+    FSize: Integer;
+    Function GetDataSet: TDataSet;
+    Function IsParamStored: Boolean;
+  protected
+    Procedure AssignParam(Param: TParam);
+    Procedure AssignTo(Dest: TPersistent); override;
+    Function GetAsBoolean: Boolean;
+    Function GetAsCurrency: Currency;
+    Function GetAsDateTime: TDateTime;
+    Function GetAsFloat: Double;
+    Function GetAsInteger: Longint;
+    Function GetAsMemo: string;
+    Function GetAsString: string;
+    Function GetAsVariant: Variant;
+    Function GetDisplayName: string; override;
+    Function GetIsNull: Boolean;
+    Function IsEqual(AValue: TParam): Boolean;
+    Procedure SetAsBlob(const AValue: TBlobData);
+    Procedure SetAsBoolean(AValue: Boolean);
+    Procedure SetAsCurrency(const AValue: Currency);
+    Procedure SetAsDate(const AValue: TDateTime);
+    Procedure SetAsDateTime(const AValue: TDateTime);
+    Procedure SetAsFloat(const AValue: Double);
+    Procedure SetAsInteger(AValue: Longint);
+    Procedure SetAsMemo(const AValue: string);
+    Procedure SetAsSmallInt(AValue: LongInt);
+    Procedure SetAsString(const AValue: string);
+    Procedure SetAsTime(const AValue: TDateTime);
+    Procedure SetAsVariant(const AValue: Variant);
+    Procedure SetAsWord(AValue: LongInt);
+    Procedure SetDataType(AValue: TFieldType);
+    Procedure SetText(const AValue: string);
+  public
+    constructor Create(ACollection: TCollection); overload; override;
+    constructor Create(AParams: TParams; AParamType: TParamType); reintroduce; overload;
+    Procedure Assign(Source: TPersistent); override;
+    Procedure AssignField(Field: TField);
+    Procedure AssignToField(Field: TField);
+    Procedure AssignFieldValue(Field: TField; const AValue: Variant);
+    Procedure Clear;
+    Procedure GetData(Buffer: Pointer);
+    Function  GetDataSize: Integer;
+    Procedure LoadFromFile(const FileName: string; BlobType: TBlobType);
+    Procedure LoadFromStream(Stream: TStream; BlobType: TBlobType);
+    Procedure SetBlobData(Buffer: Pointer; Size: Integer);
+    Procedure SetData(Buffer: Pointer);
+    Property AsBlob : TBlobData read GetAsString write SetAsBlob;
+    Property AsBoolean : Boolean read GetAsBoolean write SetAsBoolean;
+    Property AsCurrency : Currency read GetAsCurrency write SetAsCurrency;
+    Property AsDate : TDateTime read GetAsDateTime write SetAsDate;
+    Property AsDateTime : TDateTime read GetAsDateTime write SetAsDateTime;
+    Property AsFloat : Double read GetAsFloat write SetAsFloat;
+    Property AsInteger : LongInt read GetAsInteger write SetAsInteger;
+    Property AsMemo : string read GetAsMemo write SetAsMemo;
+    Property AsSmallInt : LongInt read GetAsInteger write SetAsSmallInt;
+    Property AsString : string read GetAsString write SetAsString;
+    Property AsTime : TDateTime read GetAsDateTime write SetAsTime;
+    Property AsWord : LongInt read GetAsInteger write SetAsWord;
+    Property Bound : Boolean read FBound write FBound;
+    Property Dataset : TDataset Read GetDataset;
+    Property IsNull : Boolean read GetIsNull;
+    Property NativeStr : string read FNativeStr write FNativeStr;
+    Property Text : string read GetAsString write SetText;
+    Property Value : Variant read GetAsVariant write SetAsVariant stored IsParamStored;
+  published
+    Property DataType : TFieldType read FDataType write SetDataType;
+    Property Name : string read FName write FName;
+    Property NumericScale : Integer read FNumericScale write FNumericScale default 0;
+    Property ParamType : TParamType read FParamType write FParamType;
+    Property Precision : Integer read FPrecision write FPrecision default 0;
+    Property Size : Integer read FSize write FSize default 0;
+  end;
+  
+
+  { TParams }
+
+  TParams = class(TCollection)
+  private
+    FOwner: TPersistent;
+    Function  GetItem(Index: Integer): TParam;
+    Function  GetParamValue(const ParamName: string): Variant;
+    Procedure SetItem(Index: Integer; Value: TParam);
+    Procedure SetParamValue(const ParamName: string; const Value: Variant);
+  protected
+    Procedure AssignTo(Dest: TPersistent); override;
+    Function  GetDataSet: TDataSet;
+    Function  GetOwner: TPersistent; override;
+  public
+    Constructor Create(AOwner: TPersistent); overload;
+    Constructor Create; overload;
+    Procedure AddParam(Value: TParam);
+    Procedure AssignValues(Value: TParams);
+    Function  CreateParam(FldType: TFieldType; const ParamName: string; ParamType: TParamType): TParam;
+    Function  FindParam(const Value: string): TParam;
+    Procedure GetParamList(List: TList; const ParamNames: string);
+    Function  IsEqual(Value: TParams): Boolean;
+    Function  ParamByName(const Value: string): TParam;
+    Function  ParseSQL(SQL: String; DoCreate: Boolean): String;
+    Procedure RemoveParam(Value: TParam);
+    Property Dataset : TDataset Read GetDataset;
+    Property Items[Index: Integer] : TParam read GetItem write SetItem; default;
+    Property ParamValues[const ParamName: string] : Variant read GetParamValue write SetParamValue;
+  end;
+
+const
+  FieldTypetoVariantMap : array[TFieldType] of Integer = (varError, varOleStr, varSmallint,
+    varInteger, varSmallint, varBoolean, varDouble, varCurrency, varCurrency,
+    varDate, varDate, varDate, varOleStr, varOleStr, varInteger, varOleStr,
+    varOleStr, varOleStr, varOleStr, varOleStr, varOleStr, varOleStr, varError,
+    varOleStr, varOleStr, varError, varError, varError, varError, varError,
+    varOleStr, varOleStr, varVariant, varUnknown, varDispatch, varOleStr, varOleStr,varOleStr);
+
+
 Const
   Fieldtypenames : Array [TFieldType] of String[15] =
     (
@@ -1641,12 +1774,16 @@ end;
 {$i datasource.inc}
 {$i database.inc}
 {$i BufDataset.inc}
+{$i dsparams.inc}
 
 end.
 
 {
   $Log$
-  Revision 1.31  2004-12-13 19:20:12  michael
+  Revision 1.32  2004-12-13 20:19:49  michael
+  + Initial implementation of params
+
+  Revision 1.31  2004/12/13 19:20:12  michael
     * Patch from Joost van der Sluis
     - moved IsCursorOpen from TSQLQuery to tbufdataset
     - moved SetFieldData from TSQLQuery to TBufDataset

+ 7 - 1
fcl/db/dbconst.pp

@@ -21,6 +21,7 @@ Interface
 
 Const
   SActiveDataset           = 'Operation cannot be performed on an active dataset';
+  SBadParamFieldType       = 'Bad fieldtype for parameter "%s".';
   SCantSetAutoIncFields    = 'AutoInc Fields are read-only';
   SConnected               = 'Operation cannot be performed on an connected database';
   SDatasetReadOnly         = 'Dataset is read-only.';
@@ -55,12 +56,14 @@ Const
   SNotAninteger            = '"%s" is not a valid integer';
   SNotConnected            = 'Operation cannot be performed on an disconnected database';
   SNotInEditState          = 'Operation not allowed, dataset "%s" is not in an edit state.';
+  SParameterNotFound       = 'Parameter "%s" not found';
   SRangeError              = '%f is not between %f and %f for %s';
   SReadOnlyField           = 'Field %s cannot be modified, it is read-only.';
   STransactionRegistered   = 'Transaction already registered : "%s"';
   SUniDirectional          = 'Operation cannot be performed on an unidirectional dataset';
   SUnknownField            = 'No field named "%s" was found in dataset "%s"';
   SUnknownFieldType        = 'Unknown field type : %s';
+  SUnknownParamFieldType   = 'Unknown fieldtype for parameter "%s".';
 
 Implementation
 
@@ -68,7 +71,10 @@ end.
 
 {
   $Log$
-  Revision 1.4  2004-11-05 08:32:02  michael
+  Revision 1.5  2004-12-13 20:19:49  michael
+  + Initial implementation of params
+
+  Revision 1.4  2004/11/05 08:32:02  michael
   TBufDataset.inc:
     - replaced Freemem by Reallocmem, Free by FreeAndNil
 

+ 706 - 0
fcl/db/dsparams.inc

@@ -0,0 +1,706 @@
+
+{ TParams }
+
+Function TParams.GetItem(Index: Integer): TParam;
+begin
+  Result:=(Inherited GetItem(Index)) as TParam;
+end;
+
+Function TParams.GetParamValue(const ParamName: string): Variant;
+begin
+  Result:=ParamByName(ParamName).Value;
+end;
+
+Procedure TParams.SetItem(Index: Integer; Value: TParam);
+begin
+  Inherited SetItem(Index,Value);
+end;
+
+Procedure TParams.SetParamValue(const ParamName: string; const Value: Variant);
+begin
+  ParamByName(ParamName).Value:=Value;
+end;
+
+Procedure TParams.AssignTo(Dest: TPersistent);
+begin
+ if (Dest is TParams) then
+   TParams(Dest).Assign(Self)
+ else
+   inherited AssignTo(Dest);
+end;
+
+Function TParams.GetDataSet: TDataSet;
+begin
+  If (FOwner is TDataset) Then
+    Result:=TDataset(FOwner)
+  else
+    Result:=Nil;
+end;
+
+Function TParams.GetOwner: TPersistent;
+begin
+  Result:=FOwner;
+end;
+
+
+constructor TParams.Create(AOwner: TPersistent);
+begin
+  Inherited Create(TParam);
+  Fowner:=AOwner;
+end;
+
+constructor TParams.Create;
+begin
+  Create(TPersistent(Nil));
+end;
+
+Procedure TParams.AddParam(Value: TParam);
+begin
+  Value.Collection:=Self;
+end;
+
+Procedure TParams.AssignValues(Value: TParams);
+
+Var
+  I : Integer;
+  P,PS : TParam;
+  
+begin
+  For I:=0 to Value.Count-1 do
+    begin
+    PS:=Value[i];
+    P:=FindParam(PS.Name);
+    If Assigned(P) then
+      P.Assign(PS);
+    end;
+end;
+
+Function TParams.CreateParam(FldType: TFieldType; const ParamName: string;
+  ParamType: TParamType): TParam;
+
+begin
+  Result:=Add as TParam;
+  With Result do
+    begin
+    Name:=ParamName;
+    DataType:=FldType;
+    ParamType:=ParamType;
+    end;
+end;
+
+Function TParams.FindParam(const Value: string): TParam;
+
+Var
+  I : Integer;
+
+begin
+  Result:=Nil;
+  I:=Count-1;
+  While (Result=Nil) and (I>=0) do
+    If (CompareText(Value,Items[i].Name)=0) then
+      Result:=Items[i]
+    else
+      Dec(i);
+end;
+
+Procedure TParams.GetParamList(List: TList; const ParamNames: string);
+
+  Function NextName(Var S : String) : String;
+  Var
+    P : Integer;
+  begin
+    P:=Pos(';',S);
+    If (P=0) then
+      P:=Length(S)+1;
+    Result:=Copy(S,1,P-1);
+    Delete(S,1,P);
+  end;
+
+Var
+  L,N : String;
+  
+begin
+  L:=ParamNames;
+  While (Length(L)>0) do
+    begin
+    N:=NextName(L);
+    List.Add(ParamByName(N));
+    end;
+end;
+
+Function TParams.IsEqual(Value: TParams): Boolean;
+
+Var
+  I : Integer;
+
+begin
+  Result:=(Value.Count=Count);
+  I:=Count-1;
+  While Result and (I>=0) do
+    begin
+    Result:=Items[I].IsEqual(Value[i]);
+    Dec(I);
+    end;
+end;
+
+Function TParams.ParamByName(const Value: string): TParam;
+begin
+  Result:=FindParam(Value);
+  If (Result=Nil) then
+    DatabaseErrorFmt(SParameterNotFound,[Value],Dataset);
+end;
+
+Function TParams.ParseSQL(SQL: String; DoCreate: Boolean): String;
+begin
+
+end;
+
+Procedure TParams.RemoveParam(Value: TParam);
+begin
+   Value.Collection:=Nil;
+end;
+
+{ TParam }
+
+Function TParam.GetDataSet: TDataSet;
+begin
+  If Assigned(Collection) and (Collection is TParams) then
+    Result:=TParams(Collection).GetDataset
+  else
+    Result:=Nil;
+end;
+
+Function TParam.IsParamStored: Boolean;
+begin
+  Result:=Bound;
+end;
+
+Procedure TParam.AssignParam(Param: TParam);
+begin
+  if Not Assigned(Param) then
+    begin
+    Clear;
+    FDataType:=ftunknown;
+    FParamType:=ptUnknown;
+    Name:='';
+    Size:=0;
+    Precision:=0;
+    NumericScale:=0;
+    end
+  else
+    begin
+    FDataType:=Param.DataType;
+    if Param.IsNull then
+      Clear
+    else
+      FValue:=Param.FValue;
+    FBound:=Param.Bound;
+    Name:=Param.Name;
+    if (ParamType=ptUnknown) then
+      ParamType:=Param.ParamType;
+    Size:=Param.Size;
+    Precision:=Param.Precision;
+    NumericScale:=Param.NumericScale;
+    end;
+end;
+
+Procedure TParam.AssignTo(Dest: TPersistent);
+begin
+  if (Dest is TField) then
+    AssignToField(TField(Dest))
+  else
+    inherited AssignTo(Dest);
+end;
+
+Function TParam.GetAsBoolean: Boolean;
+begin
+  If IsNull then
+    Result:=False
+  else
+    Result:=FValue;
+end;
+
+Function TParam.GetAsCurrency: Currency;
+begin
+  If IsNull then
+    Result:=0.0
+  else
+    Result:=FValue;
+end;
+
+Function TParam.GetAsDateTime: TDateTime;
+begin
+  If IsNull then
+    Result:=0.0
+  else
+    Result:=FValue;
+end;
+
+Function TParam.GetAsFloat: Double;
+begin
+  If IsNull then
+    Result:=0.0
+  else
+    Result:=FValue;
+end;
+
+Function TParam.GetAsInteger: Longint;
+begin
+  If IsNull then
+    Result:=0
+  else
+    Result:=FValue;
+end;
+
+Function TParam.GetAsMemo: string;
+begin
+  If IsNull then
+    Result:=''
+  else
+    Result:=FValue;
+end;
+
+Function TParam.GetAsString: string;
+begin
+  If IsNull then
+    Result:=''
+  else
+    Result:=FValue;
+end;
+
+Function TParam.GetAsVariant: Variant;
+begin
+  if IsNull then
+    Result:=Null
+  else
+    Result:=FValue;
+end;
+
+Function TParam.GetDisplayName: string;
+begin
+  if (FName<>'') then
+    Result:=FName
+  else
+    Result:=inherited GetDisplayName
+end;
+
+Function TParam.GetIsNull: Boolean;
+begin
+  Result:=FNull or VarIsNull(FValue) or VarIsClear(FValue);
+end;
+
+Function TParam.IsEqual(AValue: TParam): Boolean;
+begin
+  Result:=(Name=AValue.Name)
+          and (IsNull=AValue.IsNull)
+          and (Bound=AValue.Bound)
+          and (DataType=AValue.DataType)
+          and (ParamType=AValue.ParamType)
+          and (VarType(FValue)=VarType(AValue.FValue))
+          and (FValue=AValue.FValue);
+end;
+
+Procedure TParam.SetAsBlob(const AValue: TBlobData);
+begin
+  FValue:=AValue;
+  FDataType:=ftBlob;
+end;
+
+Procedure TParam.SetAsBoolean(AValue: Boolean);
+begin
+  FValue:=AValue;
+  FDataType:=ftBoolean;
+end;
+
+Procedure TParam.SetAsCurrency(const AValue: Currency);
+begin
+  FValue:=Avalue;
+  FDataType:=ftCurrency;
+end;
+
+Procedure TParam.SetAsDate(const AValue: TDateTime);
+begin
+  FValue:=Avalue;
+  FDataType:=ftDate;
+end;
+
+Procedure TParam.SetAsDateTime(const AValue: TDateTime);
+begin
+  FValue:=AValue;
+  FDataType:=ftDateTime;
+end;
+
+Procedure TParam.SetAsFloat(const AValue: Double);
+begin
+  FValue:=AValue;
+  FDataType:=ftFloat;
+end;
+
+Procedure TParam.SetAsInteger(AValue: Longint);
+begin
+  FValue:=AValue;
+  FDataType:=ftInteger;
+end;
+
+Procedure TParam.SetAsMemo(const AValue: string);
+begin
+  FValue:=AValue;
+  FDataType:=ftMemo;
+end;
+
+
+Procedure TParam.SetAsSmallInt(AValue: LongInt);
+begin
+  FValue:=AValue;
+  FDataType:=ftSmallInt;
+end;
+
+Procedure TParam.SetAsString(const AValue: string);
+begin
+  FValue:=AValue;
+  FDataType:=ftString;
+end;
+
+Procedure TParam.SetAsTime(const AValue: TDateTime);
+begin
+  FValue:=AValue;
+  FDataType:=ftTime;
+end;
+
+Procedure TParam.SetAsVariant(const AValue: Variant);
+begin
+  FValue:=AValue;
+  FBound:=not VarIsClear(Value);
+  FNull:=VarIsClear(Value) or VarIsNull(Value);
+  if FDataType = ftUnknown then
+    case VarType(Value) of
+      varBoolean  : FDataType:=ftBoolean;
+      varSmallint,
+      varShortInt,
+      varByte     : FDataType:=ftSmallInt;
+      varWord,
+      varInteger  : FDataType:=ftInteger;
+      varCurrency : FDataType:=ftCurrency;
+      varLongWord,
+      varSingle,
+      varDouble   : FDataType:=ftFloat;
+      varDate     : FDataType:=ftDateTime;
+      varString,
+      varOleStr   : if (FDataType<>ftFixedChar) then
+                      FDataType:=ftString;
+      varInt64    : FDataType:=ftLargeInt;
+    else
+      FDataType:=ftUnknown;
+    end;
+end;
+
+Procedure TParam.SetAsWord(AValue: LongInt);
+begin
+  FValue:=AValue;
+  FDataType:=ftWord;
+end;
+
+
+Procedure TParam.SetDataType(AValue: TFieldType);
+
+Var
+  VT : Integer;
+
+begin
+  FDataType:=AValue;
+  VT:=FieldTypetoVariantMap[AValue];
+  If (VT=varError) then
+    clear
+  else
+    Try
+      FValue:=VarAsType(AValue,VT)
+    except
+      Clear;
+    end;
+end;
+
+Procedure TParam.SetText(const AValue: string);
+begin
+  Value:=AValue;
+end;
+
+constructor TParam.Create(ACollection: TCollection);
+begin
+  inherited Create(Collection);
+  ParamType:=ptUnknown;
+  DataType:=ftUnknown;
+  FValue:=Unassigned;
+  FNull:=True;
+end;
+
+constructor TParam.Create(AParams: TParams; AParamType: TParamType);
+begin
+  Create(AParams);
+  ParamType:=AParamType;
+end;
+
+Procedure TParam.Assign(Source: TPersistent);
+begin
+  if (Source is TParam) then
+    AssignParam(TParam(Source))
+  else if (Source is TField) then
+    AssignField(TField(Source))
+  else if (source is TStrings) then
+    AsMemo:=TStrings(Source).Text
+  else
+    inherited Assign(Source);
+end;
+
+Procedure TParam.AssignField(Field: TField);
+begin
+  if Assigned(Field) then
+    begin
+    // Need TField.Value
+    // AssignFieldValue(Field,Field.Value);
+    Name:=Field.FieldName;
+    end
+  else
+    begin
+    Clear;
+    Name:='';
+    end
+end;
+
+procedure TParam.AssignToField(Field : TField);
+
+begin
+  if Assigned(Field) then
+    case FDataType of
+      ftUnknown  : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet);
+      // Need TField.AsSmallInt
+      ftSmallint : Field.AsInteger:=AsSmallInt;
+      // Need TField.AsWord
+      ftWord     : Field.AsInteger:=AsWord;
+      ftInteger,
+      ftAutoInc  : Field.AsInteger:=AsInteger;
+      // Need TField.AsCurrency
+      ftCurrency : Field.asFloat:=AsCurrency;
+      ftFloat    : Field.asFloat:=AsFloat;
+      ftBoolean  : Field.AsBoolean:=AsBoolean;
+      ftBlob,
+      ftGraphic..ftTypedBinary,
+      ftOraBlob,
+      ftOraClob,
+      ftString,
+      ftMemo,
+      ftAdt,
+      ftFixedChar: Field.AsString:=AsString;
+      ftTime,
+      ftDate,
+      ftDateTime : Field.AsDateTime:=AsDateTime;
+      ftBytes,
+      ftVarBytes : ; // Todo.
+    else
+      If not (DataType in [ftCursor, ftArray, ftDataset,ftReference]) then
+        DatabaseErrorFmt(SBadParamFieldType, [Name], DataSet);
+    end;
+end;
+
+Procedure TParam.AssignFieldValue(Field: TField; const AValue: Variant);
+begin
+  If Assigned(Field) then
+    begin
+    // Need TField.FixedChar property.
+    if (Field.DataType = ftString) {and TStringField(Field).FixedChar} then
+      DataType:=ftFixedChar
+    else if (Field.DataType = ftMemo) and (Field.Size > 255) then
+      DataType:=ftString
+    else
+      DataType:=Field.DataType;
+    if VarIsNull(AValue) then
+      Clear
+    else
+      Value:=AValue;
+    Size:=Field.DataSize;
+    FBound:=True;
+    end;
+end;
+
+Procedure TParam.Clear;
+begin
+  FValue:=UnAssigned;
+  FNull:=True;
+end;
+
+Procedure TParam.GetData(Buffer: Pointer);
+
+Var
+  P : Pointer;
+  S : String;
+
+begin
+  case FDataType of
+    ftUnknown  : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet);
+    ftSmallint : PSmallint(Buffer)^:=AsSmallInt;
+    ftWord     : PWord(Buffer)^:=AsWord;
+    ftInteger,
+    ftAutoInc  : PInteger(Buffer)^:=AsInteger;
+    ftCurrency : PDouble(Buffer)^:=AsCurrency;
+    ftFloat    : PDouble(Buffer)^:=AsFloat;
+    ftBoolean  : PWordBool(Buffer)^:=AsBoolean;
+    ftString,
+    ftMemo,
+    ftAdt,
+    ftFixedChar:
+      begin
+      S:=AsString;
+      StrMove(PChar(Buffer),Pchar(S),Length(S)+1);
+      end;
+    ftTime     : PInteger(Buffer)^:=DateTimeToTimeStamp(AsTime).Time;
+    ftDate     : PInteger(Buffer)^:=DateTimeToTimeStamp(AsTime).Date;
+    ftDateTime : PDouble(Buffer)^:=TimeStampToMSecs(DateTimeToTimeStamp(AsDateTime));
+    ftBlob,
+    ftGraphic..ftTypedBinary,
+    ftOraBlob,
+    ftOraClob  :
+      begin
+      S:=GetAsString;
+      Move(PChar(S)^, Buffer^, Length(S));
+      end;
+    ftBytes, ftVarBytes:
+      begin
+      if VarIsArray(FValue) then
+        begin
+        P:=VarArrayLock(FValue);
+        try
+          Move(P^, Buffer^, VarArrayHighBound(FValue, 1) + 1);
+        finally
+          VarArrayUnlock(FValue);
+        end;
+        end;
+      end;
+  else
+    If not (DataType in [ftCursor, ftArray, ftDataset,ftReference]) then
+      DatabaseErrorFmt(SBadParamFieldType, [Name], DataSet);
+  end;
+end;
+
+Function TParam.GetDataSize: Integer;
+begin
+  Result:=0;
+  case DataType of
+    ftUnknown  : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet);
+    ftBoolean  : Result:=SizeOf(WordBool);
+    ftInteger,
+    ftAutoInc  : Result:=SizeOf(Integer);
+    ftSmallint : Result:=SizeOf(SmallInt);
+    ftWord     : Result:=SizeOf(Word);
+    ftTime,
+    ftDate     : Result:=SizeOf(Integer);
+    ftDateTime,
+    ftCurrency,
+    ftFloat    : Result:=SizeOf(Double);
+    ftString,
+    ftFixedChar,
+    ftMemo,
+    ftADT      : Result:=Length(AsString)+1;
+    ftBytes,
+    ftVarBytes : if VarIsArray(FValue) then
+                   Result:=VarArrayHighBound(FValue,1)+1
+                 else
+                   Result:=0;
+    ftBlob,
+    ftGraphic..ftTypedBinary,
+    ftOraClob,
+    ftOraBlob  : Result:=Length(AsString);
+    ftArray,
+    ftDataSet,
+    ftReference,
+    ftCursor   : Result:=0;
+  else
+    DatabaseErrorFmt(SBadParamFieldType,[Name],DataSet);
+  end;
+
+
+end;
+
+Procedure TParam.LoadFromFile(const FileName: string; BlobType: TBlobType);
+
+Var
+  S : TFileStream;
+
+begin
+  S:=TFileStream.Create(FileName,fmOpenRead);
+  Try
+    LoadFromStream(S,BlobType);
+  Finally
+    FreeAndNil(S);
+  end;
+end;
+
+Procedure TParam.LoadFromStream(Stream: TStream; BlobType: TBlobType);
+
+Var
+  Temp : String;
+
+begin
+  FDataType:=BlobType;
+  With Stream do
+    begin
+    Position:=0;
+    SetLength(Temp,Size);
+    ReadBuffer(Pointer(Temp)^,Size);
+    FValue:=Temp;
+    end;
+end;
+
+Procedure TParam.SetBlobData(Buffer: Pointer; Size: Integer);
+
+Var
+  Temp : String;
+
+begin
+  SetLength(Temp,Size);
+  Move(Buffer^,Temp,Size);
+  AsBlob:=Temp;
+end;
+
+Procedure TParam.SetData(Buffer: Pointer);
+
+  Function FromTimeStamp(T,D : Integer) : TDateTime;
+  
+  Var TS : TTimeStamp;
+  
+  begin
+    TS.Time:=T;
+    TS.Date:=D;
+    Result:=TimeStampToDateTime(TS);
+  end;
+  
+begin
+  case FDataType of
+    ftUnknown  : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet);
+    ftSmallint : AsSmallInt:=PSmallint(Buffer)^;
+    ftWord     : AsWord:=PWord(Buffer)^;
+    ftInteger,
+    ftAutoInc  : AsInteger:=PInteger(Buffer)^;
+    ftCurrency : AsCurrency:= PDouble(Buffer)^;
+    ftFloat    : AsFloat:=PDouble(Buffer)^;
+    ftBoolean  : AsBoolean:=PWordBool(Buffer)^;
+    ftString,
+    ftFixedChar: AsString:=StrPas(Buffer);
+    ftMemo     : AsMemo:=StrPas(Buffer);
+    ftTime     : AsTime:=FromTimeStamp(PInteger(Buffer)^,DateDelta);
+    ftDate     : Asdate:=FromTimeStamp(0,PInteger(Buffer)^);
+    ftDateTime : AsDateTime:=TimeStampToDateTime(MSecsToTimeStamp(PDouble(Buffer)^));
+    ftCursor   : FValue:=0;
+    ftBlob,
+    ftGraphic..ftTypedBinary,
+    ftOraBlob,
+    ftOraClob  : SetBlobData(Buffer, StrLen(PChar(Buffer)));
+  else
+    DatabaseErrorFmt(SBadParamFieldType,[Name],DataSet);
+  end;
+end;
+
+{
+  $Log$
+  Revision 1.1  2004-12-13 20:19:49  michael
+  + Initial implementation of params
+
+}