You are not logged in.
Pages: 1
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
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
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
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
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
It's working! I'm so stupid)) Thanks a lot!
Offline
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
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
Pages: 1