From: <na...@us...> - 2008-02-27 09:03:34
|
Revision: 778 http://instantobjects.svn.sourceforge.net/instantobjects/revision/?rev=778&view=rev Author: nandod Date: 2008-02-27 01:03:37 -0800 (Wed, 27 Feb 2008) Log Message: ----------- + New "usenull" attribute parameter to have a zero value stored as null in DBs that support it (especially useful for dates) (WIP - design time support still not finished). Modified Paths: -------------- trunk/Source/Core/InstantBrokers.pas trunk/Source/Core/InstantCode.pas trunk/Source/Core/InstantMetadata.pas trunk/Source/Core/InstantPersistence.pas Modified: trunk/Source/Core/InstantBrokers.pas =================================================================== --- trunk/Source/Core/InstantBrokers.pas 2008-02-25 17:55:07 UTC (rev 777) +++ trunk/Source/Core/InstantBrokers.pas 2008-02-27 09:03:37 UTC (rev 778) @@ -417,9 +417,9 @@ FSelectExternalPartSQL: string; FDeleteExternalSQL: string; FInsertExternalSQL: string; - procedure AddIntegerParam(Params: TParams; const ParamName: string; - Value: Integer); - procedure AddStringParam(Params: TParams; const ParamName, Value: string); + function AddIntegerParam(Params: TParams; const ParamName: string; + Value: Integer): TParam; + function AddStringParam(Params: TParams; const ParamName, Value: string): TParam; // Adds an "Id" param, whose data type and size depends on connector // settings. procedure AddIdParam(Params: TParams; const ParamName, Value: string); @@ -2391,57 +2391,81 @@ procedure TInstantNavigationalResolver.WriteBlob(Attribute: TInstantBlob); begin - with Attribute do - FieldByName(Metadata.FieldName).AsString := Value; + with FieldByName(Attribute.Metadata.FieldName) do + if Attribute.IsNull then + Clear + else + AsString := Attribute.Value; end; procedure TInstantNavigationalResolver.WriteBoolean(Attribute: TInstantBoolean); begin - with Attribute do - FieldByName(Metadata.FieldName).AsBoolean := Value; + with FieldByName(Attribute.Metadata.FieldName) do + if Attribute.IsNull then + Clear + else + AsBoolean := Attribute.Value; end; procedure TInstantNavigationalResolver.WriteCurrency(Attribute: TInstantCurrency); begin - with Attribute do + with FieldByName(Attribute.Metadata.FieldName) do + if Attribute.IsNull then + Clear + else {$IFDEF FPC} - FieldByName(Metadata.FieldName).AsFloat := Value; + AsFloat := Value; {$ELSE} - FieldByName(Metadata.FieldName).AsCurrency := Value; + AsCurrency := Value; {$ENDIF} end; procedure TInstantNavigationalResolver.WriteDateTime( Attribute: TInstantDateTime); begin - with Attribute do - FieldByName(Metadata.FieldName).AsDateTime := Value; + with FieldByName(Attribute.Metadata.FieldName) do + if Attribute.IsNull then + Clear + else + AsDateTime := Attribute.Value; end; procedure TInstantNavigationalResolver.WriteDate( Attribute: TInstantDate); begin - with Attribute do - FieldByName(Metadata.FieldName).AsDateTime := Value; + with FieldByName(Attribute.Metadata.FieldName) do + if Attribute.IsNull then + Clear + else + AsDateTime := Attribute.Value; end; procedure TInstantNavigationalResolver.WriteTime( Attribute: TInstantTime); begin - with Attribute do - FieldByName(Metadata.FieldName).AsDateTime := Value; + with FieldByName(Attribute.Metadata.FieldName) do + if Attribute.IsNull then + Clear + else + AsDateTime := Attribute.Value; end; procedure TInstantNavigationalResolver.WriteFloat(Attribute: TInstantFloat); begin - with Attribute do - FieldByName(Metadata.FieldName).AsFloat := Value; + with FieldByName(Attribute.Metadata.FieldName) do + if Attribute.IsNull then + Clear + else + AsFloat := Attribute.Value; end; procedure TInstantNavigationalResolver.WriteInteger(Attribute: TInstantInteger); begin - with Attribute do - FieldByName(Metadata.FieldName).AsInteger := Value; + with FieldByName(Attribute.Metadata.FieldName) do + if Attribute.IsNull then + Clear + else + AsInteger := Attribute.Value; end; procedure TInstantNavigationalResolver.WriteMemo(Attribute: TInstantMemo); @@ -2563,8 +2587,11 @@ procedure TInstantNavigationalResolver.WriteString(Attribute: TInstantString); begin - with Attribute do - FieldByName(Metadata.FieldName).AsString := Value; + with FieldByName(Attribute.Metadata.FieldName) do + if Attribute.IsNull then + Clear + else + AsString := Attribute.Value; end; constructor TInstantSQLResolver.Create(ABroker: TInstantSQLBroker; @@ -2602,60 +2629,102 @@ end; procedure AddBlobAttributeParam; + var + LParam: TParam; begin - AddBlobParam(FieldName, (Attribute as TInstantBlob).Value); + LParam := AddParam(Params, FieldName, ftBlob); + if Attribute.IsNull then + LParam.Clear + else + LParam.AsBlob := (Attribute as TInstantBlob).Value; end; procedure AddBooleanAttributeParam; + var + LParam: TParam; begin - AddParam(Params, FieldName, ftBoolean).AsBoolean := - (Attribute as TInstantBoolean).Value; + LParam := AddParam(Params, FieldName, ftBoolean); + if Attribute.IsNull then + LParam.Clear + else + LParam.AsBoolean := (Attribute as TInstantBoolean).Value; end; procedure AddDateTimeAttributeParam; + var + LParam: TParam; begin - AddParam(Params, FieldName, ftDateTime).AsDateTime := - (Attribute as TInstantDateTime).Value; + LParam := AddParam(Params, FieldName, ftDateTime); + if Attribute.IsNull then + LParam.Clear + else + LParam.AsDateTime := (Attribute as TInstantDateTime).Value; end; procedure AddDateAttributeParam; + var + LParam: TParam; begin - AddParam(Params, FieldName, ftDate).AsDateTime := - (Attribute as TInstantDate).Value; + LParam := AddParam(Params, FieldName, ftDate); + if Attribute.IsNull then + LParam.Clear + else + LParam.AsDateTime := (Attribute as TInstantDate).Value; end; procedure AddTimeAttributeParam; + var + LParam: TParam; begin - AddParam(Params, FieldName, ftTime).AsDateTime := - (Attribute as TInstantTime).Value; + LParam := AddParam(Params, FieldName, ftTime); + if Attribute.IsNull then + LParam.Clear + else + LParam.AsDateTime := (Attribute as TInstantTime).Value; end; procedure AddFloatAttributeParam; + var + LParam: TParam; begin - AddParam(Params, FieldName, ftFloat).AsFloat := - (Attribute as TInstantFloat).Value; + LParam := AddParam(Params, FieldName, ftFloat); + if Attribute.IsNull then + LParam.Clear + else + LParam.AsFloat := (Attribute as TInstantFloat).Value; end; procedure AddCurrencyAttributeParam; + var + LParam: TParam; begin - AddParam(Params, FieldName, ftBCD).AsCurrency := - (Attribute as TInstantCurrency).Value; + LParam := AddParam(Params, FieldName, ftBCD); + if Attribute.IsNull then + LParam.Clear + else + LParam.AsCurrency := (Attribute as TInstantCurrency).Value; end; procedure AddIntegerAttributeParam; + var + LParam: TParam; begin - AddIntegerParam(Params, FieldName, (Attribute as TInstantInteger).Value); + LParam := AddIntegerParam(Params, FieldName, (Attribute as TInstantInteger).Value); + if Attribute.IsNull then + LParam.Clear; end; procedure AddMemoAttributeParam; var - Param: TParam; + LParam: TParam; MemoAttrib: TInstantMemo; begin - Param := AddParam(Params, FieldName, ftMemo); + LParam := AddParam(Params, FieldName, ftMemo); MemoAttrib := (Attribute as TInstantMemo); - if MemoAttrib.Size <> 0 then - Param.AsMemo := MemoAttrib.Value; + if (MemoAttrib.Size = 0) or Attribute.IsNull then + LParam.Clear + else + LParam.AsMemo := MemoAttrib.Value; end; procedure AddPartAttributeParam; @@ -2728,8 +2797,12 @@ end; procedure AddStringAttributeParam; + var + LParam: TParam; begin - AddStringParam(Params, FieldName, (Attribute as TInstantString).Value); + LParam := AddStringParam(Params, FieldName, (Attribute as TInstantString).Value); + if Attribute.IsNull then + LParam.Clear; end; begin @@ -2810,10 +2883,11 @@ Param.Value := Value; end; -procedure TInstantSQLResolver.AddIntegerParam(Params: TParams; - const ParamName: string; Value: Integer); +function TInstantSQLResolver.AddIntegerParam(Params: TParams; + const ParamName: string; Value: Integer): TParam; begin - AddParam(Params, ParamName, ftInteger).AsInteger := Value; + Result := AddParam(Params, ParamName, ftInteger); + Result.AsInteger := Value; end; function TInstantSQLResolver.AddParam(Params: TParams; @@ -2830,18 +2904,12 @@ AddIdParam(Params, PersistentIdParamName, APersistentId); end; -procedure TInstantSQLResolver.AddStringParam(Params: TParams; - const ParamName, Value: string); -var - Param: TParam; +function TInstantSQLResolver.AddStringParam(Params: TParams; + const ParamName, Value: string): TParam; begin - Param := AddParam(Params, ParamName, ftString); + Result := AddParam(Params, ParamName, ftString); if Value <> '' then - begin - Param.AsString := Value; - // Update the length string to avoid the MBCS Bug. -// Param.Size := Length(Value); - end; + Result.AsString := Value; end; procedure TInstantSQLResolver.CheckConflict(Info: PInstantOperationInfo; Modified: trunk/Source/Core/InstantCode.pas =================================================================== --- trunk/Source/Core/InstantCode.pas 2008-02-25 17:55:07 UTC (rev 777) +++ trunk/Source/Core/InstantCode.pas 2008-02-27 09:03:37 UTC (rev 778) @@ -625,6 +625,8 @@ procedure SetStorageKind(const Value: TInstantStorageKind); function GetCanHaveStorageName: boolean; function GetCanBeExternal: boolean; + function GetUseNull: Boolean; + procedure SetUseNull(const Value: Boolean); protected function GetIsDefault: Boolean; virtual; function GetMethodName(MethodType: TInstantCodeContainerMethodType): string; @@ -692,6 +694,7 @@ property IncludeRemoveMethod: Boolean read GetIncludeRemoveMethod write SetIncludeRemoveMethod; property IsDefault: Boolean read GetIsDefault write SetIsDefault; + property UseNull: Boolean read GetUseNull write SetUseNull; property StorageKind: TInstantStorageKind read GetStorageKind write SetStorageKind; property IsIndexed: Boolean read GetIsIndexed write SetIsIndexed; @@ -1548,6 +1551,7 @@ MetadataInfoID = 'IOMETADATA'; MetaKeyDefault = 'default'; + MetaKeyUseNull = 'usenull'; MetaKeyExternal = 'external'; MetaKeyFormat = 'format'; MetaKeyIndex = 'index'; @@ -3949,6 +3953,11 @@ Result := FTailor; end; +function TInstantCodeAttribute.GetUseNull: Boolean; +begin + Result := Metadata.UseNull; +end; + function TInstantCodeAttribute.GetValueGetterCode: string; begin Result := Tailor.ValueGetterCode; @@ -4002,6 +4011,8 @@ Metadata.StorageName := Reader.ReadStringValue else if Token = MetaKeyDefault then Metadata.DefaultValue := Reader.ReadStringValue + else if Token = MetaKeyUseNull then + Metadata.UseNull := True else if Token = MetaKeyIndex then IsIndexed := True else if Token = MetaKeyRequired then @@ -4055,6 +4066,8 @@ Writer.Write(' ' + MetaKeyIndex); if IsRequired then Writer.Write(' ' + MetaKeyRequired); + if Metadata.UseNull then + Writer.Write(' ' + MetaKeyUseNull); if IsDefault then Writer.Write(' ' + MetaKeyDefault); Writer.Write(';'); @@ -4205,6 +4218,11 @@ Metadata.FieldName := Value; end; +procedure TInstantCodeAttribute.SetUseNull(const Value: Boolean); +begin + Metadata.UseNull := Value; +end; + procedure TInstantCodeAttribute.SetVisibility( Value: TInstantCodeVisibility); begin Modified: trunk/Source/Core/InstantMetadata.pas =================================================================== --- trunk/Source/Core/InstantMetadata.pas 2008-02-25 17:55:07 UTC (rev 777) +++ trunk/Source/Core/InstantMetadata.pas 2008-02-27 09:03:37 UTC (rev 778) @@ -434,6 +434,7 @@ private FAttributeType: TInstantAttributeType; FDefaultValue: string; + FUseNull: Boolean; FDisplayWidth: Integer; FEditMask: string; FIsIndexed: Boolean; @@ -497,6 +498,7 @@ write SetAttributeTypeName stored False; property ClassMetadata: TInstantClassMetadata read GetClassMetadata; property DefaultValue: string read FDefaultValue write FDefaultValue; + property UseNull: Boolean read FUseNull write FUseNull; property DisplayWidth: Integer read FDisplayWidth write FDisplayWidth default 0; property EditMask: string read FEditMask write FEditMask; Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2008-02-25 17:55:07 UTC (rev 777) +++ trunk/Source/Core/InstantPersistence.pas 2008-02-27 09:03:37 UTC (rev 778) @@ -179,6 +179,7 @@ function GetDisplayText: string; virtual; function GetIsChanged: Boolean; virtual; function GetIsDefault: Boolean; virtual; + function GetIsNull: Boolean; virtual; function GetIsMandatory: Boolean; virtual; function GetOwner: TInstantObject; reintroduce; virtual; procedure Initialize; override; @@ -220,6 +221,7 @@ property IsIndexed: Boolean read GetIsIndexed; property IsMandatory: Boolean read GetIsMandatory; property IsRequired: Boolean read GetIsRequired; + property IsNull: Boolean read GetIsNull; property Name: string read GetName; property Metadata: TInstantAttributeMetadata read GetMetadata write SetMetadata; property Owner: TInstantObject read GetOwner; @@ -239,6 +241,7 @@ function GetAsDateTime: TDateTime; override; function GetDisplayText: string; override; function GetIsDefault: Boolean; override; + function GetIsNull: Boolean; override; procedure SetAsBoolean(AValue: Boolean); override; procedure SetAsDateTime(AValue: TDateTime); override; end; @@ -335,6 +338,7 @@ function GetAsString: string; override; function GetAsVariant: Variant; override; function GetIsDefault: Boolean; override; + function GetIsNull: Boolean; override; function GetValue: Boolean; virtual; procedure Initialize; override; procedure ReadObject(Reader: TInstantReader); override; @@ -393,6 +397,7 @@ function GetAsVariant: Variant; override; function GetDisplayText: string; override; function GetIsDefault: Boolean; override; + function GetIsNull: Boolean; override; function GetValue: TDateTime; virtual; procedure Initialize; override; procedure ReadObject(Reader: TInstantReader); override; @@ -507,6 +512,7 @@ function GetValue: TInstantObject; virtual; abstract; procedure SetAsObject(AValue: TInstantObject); override; procedure SetValue(AValue: TInstantObject); virtual; + function GetIsNull: Boolean; override; public function AttachObject(AObject: TInstantObject): Boolean; override; function DetachObject(AObject: TInstantObject): Boolean; override; @@ -2389,7 +2395,8 @@ //Result := CompareMem(@DefaultStr[1], @ValueStr[1], L); Result := CompareStr(DefaultStr, ValueStr) = 0; end; - end else + end + else Result := L = 0; end; @@ -2403,6 +2410,13 @@ Result := IsRequired or IsIndexed; end; +function TInstantAttribute.GetIsNull: Boolean; +begin + Result := False; + if Assigned(Metadata) then + Result := Metadata.UseNull and (AsString = ''); +end; + function TInstantAttribute.GetIsRequired: Boolean; begin Result := Assigned(Metadata) and Metadata.IsRequired; @@ -2568,12 +2582,20 @@ function TInstantNumeric.GetIsDefault: Boolean; begin - if Assigned(Metadata) and (Metadata.Defaultvalue <> '') then + if Assigned(Metadata) and (Metadata.DefaultValue <> '') then Result := inherited GetIsDefault else Result := AsFloat = 0; end; +function TInstantNumeric.GetIsNull: Boolean; +begin + if Assigned(Metadata) and (Metadata.UseNull) then + Result := AsFloat = 0 + else + Result := inherited GetIsNull; +end; + procedure TInstantNumeric.SetAsBoolean(AValue: Boolean); begin AsInteger := Integer(AValue); @@ -3005,6 +3027,14 @@ Result := False; end; +function TInstantBoolean.GetIsNull: Boolean; +begin + if Assigned(Metadata) and Metadata.UseNull then + Result := AsBoolean = False + else + Result := inherited GetIsNull; +end; + function TInstantBoolean.GetValue: Boolean; begin Result := FValue; @@ -3305,6 +3335,14 @@ Result := Value = DefaultValue; end; +function TInstantCustomDateTime.GetIsNull: Boolean; +begin + if Assigned(Metadata) and Metadata.UseNull then + Result := AsDateTime = 0 + else + Result := inherited GetIsNull; +end; + function TInstantCustomDateTime.GetValue: TDateTime; begin Result := FValue; @@ -3734,6 +3772,14 @@ Result := Value; end; +function TInstantElement.GetIsNull: Boolean; +begin + if Assigned(Metadata) and Metadata.UseNull then + Result := not HasValue + else + Result := inherited GetIsNull; +end; + function TInstantElement.HasValue: Boolean; begin Result := False; |