#1 2011-07-27 15:04:22

jora
Member
Registered: 2011-07-27
Posts: 5

How to get Set variable?

Hello, I have some variable of set type (TSetInv = Set of TInv) in my base, and I can't get this variable from TSQLTableJSON field, can you help me?

Offline

#2 2011-07-27 15:32:58

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,661
Website

Re: How to get Set variable?

A set in a property should be stored as an Int64 in the database.
One bit per element in the set.

What is your exact problem?

Offline

#3 2011-07-28 07:03:44

jora
Member
Registered: 2011-07-27
Posts: 5

Re: How to get Set variable?

Yes, I know. But I think you have a function for "Integer->Set" transformation in framework.
Something like that, but universal

function IntegerToSetInvType(I: Integer): TSetInvType;
var
  Index: Integer;
begin
  Result := [];
  Index := 0;
  while (I <> 0) do
  begin
    if ((Byte(I) and 1) = 1) then
      Result := Result + [TInvType(Index)];
    Inc(Index);
    I := I shr 1;
  end;
end;
var
  lInvType: TSetInvType;
begin
... 
lInvType := IntegerToSetInvType(aJSONTable.GetAsInteger(I, FieldIndex)); 

Last edited by jora (2011-07-28 07:04:57)

Offline

#4 2011-07-28 09:29:41

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,661
Website

Re: How to get Set variable?

You don't need such complicated material, but just a type casting will do the work:

var
  lInvInteger: integer;
  lInvType: TSetInvType;
begin
  lInvInteger := aJSONTable.GetAsInteger(I, FieldIndex);
  lInvType := TSetInvType(lInvInteger);
  lInvInteger := integer(lInvType);

All is done at binary level, fast and safe.

Perhaps you'd need to change "integer" type into "byte" or "word", for small sets (up to 8 elements in byte, up to 16 elements in word, up to 32 elements in integer).

Offline

#5 2011-07-28 09:49:48

jora
Member
Registered: 2011-07-27
Posts: 5

Re: How to get Set variable?

I tried to do like you say before start topic, but there was "Invalid typecast" errors in TSetInvType(lInvInteger) and Integer(lInvType).
Thanks, I think my function is satisfy me.

Offline

#6 2011-07-28 12:39:53

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,661
Website

Re: How to get Set variable?

Did you try with byte(lInvType)? The invalid typecast occurs when the set size do not match.

If your set has up to 8 elements, typecast its set value into a byte, up to 16 elements into word, up to 32 elements into an integer.

I do this all day, and it works like a charm, much faster than your function.

Put more code, with type definition, and I'll show you.

Offline

#7 2011-07-28 13:02:12

jora
Member
Registered: 2011-07-27
Posts: 5

Re: How to get Set variable?

It's working! I'm so stupid)) Thanks a lot!

Offline

#8 2011-08-03 08:44:36

jora
Member
Registered: 2011-07-27
Posts: 5

Re: How to get Set variable?

One more question, how I can find all rows with some "enum" property if I have "set" field in database?

For example:

TTest = (tOne, tTwo, tThree, tFour, tFive);
TTestSet = Set of TTest;

T_Test = class(TSQLRecord)
private
  ...
  fTestSet: TTestSet;
published
   ...
  property TestSet: TTestSet read fTestSet write fTestSet;
end; 

procedure Smth(aTest: TTest);
var
  lJSON: TSQLTableJSON;
begin
  lJSON := Client.List([T_Test], 'T_Test.ID', 'T_Test.TestSet LIKE "' + aTest + '"'); // what should I write in SQLWhere?
end;

Or I need to delete "wrong" rows after I get lJSON ?

Offline

#9 2011-08-03 12:24:20

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,661
Website

Re: How to get Set variable?

You could use binary operation like:

procedure Smth(aTest: TTest);
var
  lJSON: TSQLTableJSON;
begin
  lJSON := Client.List([T_Test], 'T_Test.ID', FormatUTF8('(T_Test.TestSet & %)<>0',[1 shl ord(aTest)]));
  (...)
end;

I think SQLite do understand & as the "and" binary operator.
See http://www.sqlite.org/lang_expr.html

Offline

Board footer

Powered by FluxBB