Unable to access field 'Active' as type Integer
Unable to access field 'Active' as type Integer
Hello,
We recently purchased UniDac to replace AnyDac/FireDac. As expected there are a couple of differences between the systems, one of them is that UniDac allow's a boolean field in the database to be only approached as Field.AsBoolean=True (while AnyDac did not and only allowed AsInteger=1). This is a problem since we would need to adjust hundreds of references to all boolean field. Is there any solution for this so we can let UniDac interpret booleans just like AnyDac (via integers) and is this solution applyable for ALL available database?
I noticed for example a fieldmapping (Connection.DataTypeMap) but was unable to make any progress in that direction. We have defined booleans in the database via a domain called a TBoolean but we don't know how to use that knowledge in the mappings. Is that possible??
Any other pointers or solutions for this problem?
MsSql: create type TBoolean from bit null
Firebird: CREATE DOMAIN TBOOLEAN AS SMALLINT;
etc..
Btw; For the moment we want AnyDac to be a fallback scenario. We would like UniDac to behave the same as much as is (technical) possible so we can interchange the two systems.
Thanks,
Marius
We recently purchased UniDac to replace AnyDac/FireDac. As expected there are a couple of differences between the systems, one of them is that UniDac allow's a boolean field in the database to be only approached as Field.AsBoolean=True (while AnyDac did not and only allowed AsInteger=1). This is a problem since we would need to adjust hundreds of references to all boolean field. Is there any solution for this so we can let UniDac interpret booleans just like AnyDac (via integers) and is this solution applyable for ALL available database?
I noticed for example a fieldmapping (Connection.DataTypeMap) but was unable to make any progress in that direction. We have defined booleans in the database via a domain called a TBoolean but we don't know how to use that knowledge in the mappings. Is that possible??
Any other pointers or solutions for this problem?
MsSql: create type TBoolean from bit null
Firebird: CREATE DOMAIN TBOOLEAN AS SMALLINT;
etc..
Btw; For the moment we want AnyDac to be a fallback scenario. We would like UniDac to behave the same as much as is (technical) possible so we can interchange the two systems.
Thanks,
Marius
Re: Unable to access field 'Active' as type Integer
When calling the TBooleanField.AsInteger property in AnyDAC, the GetAsInteger method of the TField basic class will be called, because the GetAsInteger method of the TBooleanField class is not covered. That in turn will cause the "Cannot access field 'Active' as type Integer" error.
The 'Database Type' combobox is generated not dynamically by retrieved server data, but statically using predefined DBMS data types. Therefore you can't get your predefined data types in this combobox.
You can map data of the DBMS types (Bit of SQL Server, SmallInt of Firebird) to Integer.
To map Bit data (SQL Server) and SmallInt (Firebird) to Integer, set the following Data Type Mapping rules before establishing connection:
These rules will be applied to data of Bit (SQL Server) and SmallInt (Firebird) types and to your predefined TBoolean data types. To use msBit, ibcSmallInt constants, you should add MSDataTypeMapUni, IBCDataTypeMapUni units to the uses section.
You can also map data with such types using 'Field Name' of the required columns.
Example:
More details about Data Type Mapping can be found in the UniDAC documentation: http://www.devart.com/unidac/docs/data_type_mapping.htm
The 'Database Type' combobox is generated not dynamically by retrieved server data, but statically using predefined DBMS data types. Therefore you can't get your predefined data types in this combobox.
You can map data of the DBMS types (Bit of SQL Server, SmallInt of Firebird) to Integer.
To map Bit data (SQL Server) and SmallInt (Firebird) to Integer, set the following Data Type Mapping rules before establishing connection:
Code: Select all
UniConnection.DataTypeMap.AddDBTypeRule(msBit, ftInteger);
UniConnection.DataTypeMap.AddDBTypeRule(ibcSmallInt, ftInteger);
You can also map data with such types using 'Field Name' of the required columns.
Example:
Code: Select all
UniTable.DataTypeMap.AddFieldNameRule(YourFieldName, ftInteger);
Re: Unable to access field 'Active' as type Integer
Thanks Victor,
We will investigate this a bit further..
We will investigate this a bit further..
Re: Unable to access field 'Active' as type Integer
Got it working now. Just curious, where does unidac actually recoqnize the bit/smallint and makes it a boolean? (have been searching and debuggign a lot, unable to find
)

Re: Unable to access field 'Active' as type Integer
Just make it a Boolean Domain, then map Boolean to Boolean in the "Connection Editor-> Data Type Mapping" and bingo. The UniDac Editor does not pull the Domains from the db nor does it allow entry of items not in the list.
In FB3 Boolean will be part of the built in types so hopefully all you'll need to do is delete the Domain.
In FB3 Boolean will be part of the built in types so hopefully all you'll need to do is delete the Domain.
Code: Select all
CREATE DOMAIN "BOOLEAN"
AS Smallint
DEFAULT 0
CHECK (value in (0, 1))
;
CREATE DOMAIN DWORD
AS Bigint
check ( value between 0 and 4294967295 )
;
Re: Unable to access field 'Active' as type Integer
Hi Fred,
In this case the whole point was to make it compatbile with AnyDac/FireDac and to remove the boolean 'detection' avoiding having to adjust ~750k lines of code.
However perhaps we will do this later on (first we have to prove unidac/multidatabase is working as good as AnYDac <Firebird/MsSql/PostGresSql/MySql>).
Thanks,
Marius
In this case the whole point was to make it compatbile with AnyDac/FireDac and to remove the boolean 'detection' avoiding having to adjust ~750k lines of code.
However perhaps we will do this later on (first we have to prove unidac/multidatabase is working as good as AnYDac <Firebird/MsSql/PostGresSql/MySql>).
Thanks,
Marius
Re: Unable to access field 'Active' as type Integer
Sorry I never played with AnyDac.
So its easy enough to have a Mapping as Boolean for FB which leaves you with a coding issue where you accessed a Boolean field as integer, correct?
If you are XE3+ then just write a class helper like this, only include the unit if you are using UniDac:
So its easy enough to have a Mapping as Boolean for FB which leaves you with a coding issue where you accessed a Boolean field as integer, correct?
If you are XE3+ then just write a class helper like this, only include the unit if you are using UniDac:
Code: Select all
//MMWIN:CLASSCOPY
unit _MM_Copy_Buffer_;
interface
type
TBooleanFieldHelper = class helper for TBooleanField
private
function GetAsInteger: Integer;
procedure SetAsInteger(const Value: Integer);
public
property AsInteger: Integer read GetAsInteger write SetAsInteger;
end;
implementation
function TBooleanFieldHelper.GetAsInteger: Integer;
begin
Result := Ord(Self.Value);
end;
procedure TBooleanFieldHelper.SetAsInteger(const Value: Integer);
begin
Self.Value := Value<>0;
end;
end.
Re: Unable to access field 'Active' as type Integer
Hi Fred,
That is a very clever trick, why didn't we think of that
Btw; class helpers also work in XE..
Thanks,
Marius
That is a very clever trick, why didn't we think of that

Btw; class helpers also work in XE..
Thanks,
Marius
Re: Unable to access field 'Active' as type Integer
Hmm, I read an article that said in XE3+ you can do this and that with Helpers..Marius2 wrote:Hi Fred,
Btw; class helpers also work in XE..
Assumed it was because they came in in XE3 but it turns out their role was expanded in XE3..
Well enough, appears what I do with them isn't supported in XE2..
thanks
Fred
Re: Unable to access field 'Active' as type Integer
When working with SQL Server, UniDAC creates a TBooleanField for fields of the Bit system type - and this behavior is correct.Marius2 wrote:Got it working now. Just curious, where does unidac actually recoqnize the bit/smallint and makes it a boolean? (have been searching and debuggign a lot, unable to find)
When using the InterBase provider, the TCustomUniDataSet.SpecificOptions option of BooleanDomainFields is used, that is True by default. This option will let you enable using TBooleanField objects for fields that have domain of the integer data type, and the domain name contains 'BOOLEAN'.
Re: Unable to access field 'Active' as type Integer
Hello Victor,
I just remember we also have enumerations fitting a ms-sql bit so i doubt that is alway's the case (at least there is 1 exception on that bit-rule in our case). But since we also use domains for ms-sql and that would be really the proper way to recognise booleans. It's ashame MySql does not use domains because its really a powerfull system, but voila...
Just being curious, could you point me in the unidac sources where this boolean recognition is happening? (or where to look for?)
Thanks,
Marius
I just remember we also have enumerations fitting a ms-sql bit so i doubt that is alway's the case (at least there is 1 exception on that bit-rule in our case). But since we also use domains for ms-sql and that would be really the proper way to recognise booleans. It's ashame MySql does not use domains because its really a powerfull system, but voila...
Just being curious, could you point me in the unidac sources where this boolean recognition is happening? (or where to look for?)
Thanks,
Marius
Re: Unable to access field 'Active' as type Integer
See the TMSConverterManager.GetDBType method in the MSDataTypeMap unit.