Page 1 of 1

UniDAC 3.60.0.16 and SQLite Blob Fields typecast error

Posted: Tue 19 Apr 2011 14:50
by willianjhonnes
Hi...

I'm inserting data on a SQLite blob field with this code:

Code: Select all

function TFaceDetect.EnrollUser(const ALogin, APassword: String;
  const ATemplates: TFaceTemplates): Boolean;
const
  K_STR_INS_USER          = 'INSERT INTO Users (Login, Password, Active)' +
                                      ' VALUES (%s, %s, 1)';

  K_STR_INS_FACE_TEMPLATE = 'INSERT INTO FaceTemplates (Login, FaceTemplate)' +
                                              ' VALUES (:LOGIN, :TEMPLATE)';

var
  ucConnection: TUniConnection;
  i, j: Integer;
  bufTemplate: TArray;
  qryTemplate: TUniQuery;
begin
  try
    try
      ucConnection := CreateConnection('SETUP');
      ucConnection.StartTransaction;
      Result := LSQL('SETUP', Format(K_STR_INS_USER, [QuotedStr(ALogin),
                                                      QuotedStr(Encrypt('1234567890', APassword))]));

      if Result then
      begin
        qryTemplate := TUniQuery.Create(nil);
        qryTemplate.Connection := ucConnection;
        qryTemplate.SQL.Text := K_STR_INS_FACE_TEMPLATE;
        qryTemplate.Params.CreateParam(ftString, 'LOGIN', ptInput);
        qryTemplate.Params.CreateParam(ftBytes, 'TEMPLATE', ptInput);
        SetLength(bufTemplate, 16384);

        for i := 0 to Pred(Length(ATemplates)) do
        begin
          for j := 0 to 16383 do
            bufTemplate[j] := ATemplates[i].ftemplate[j];

          qryTemplate.Params[0].AsString := ALogin;
          qryTemplate.Params[1].AsBytes := bufTemplate;
          qryTemplate.ExecSQL;
        end;

        ucConnection.Commit;
      end;
    except
      ucConnection.Rollback;
      Result := False;
    end;
  finally
    FreeAndNil(ucConnection);
  end;
end;
The insertion works fine. But, when I try to read the stored data with this code [1], system shows me an "Invalid typecast" exception.

[1]

Code: Select all

function TFaceDetect.LoadUsers: TUsers;
const
  K_STR_SEL_USERS     = 'SELECT Login' +
                         ' FROM Users';

  K_STR_SEL_TEMPLATES = 'SELECT FaceTemplate' +
                         ' FROM FaceTemplates' +
                        ' WHERE Login = %s';
var
  qryUsers, qryTemplates: TUniQuery;
  i, j, k, intLength: Integer;
begin
  try
    try
      qryUsers := LQuery('SETUP', K_STR_SEL_USERS);

      if not qryUsers.IsEmpty then
      begin
        qryUsers.First;
        SetLength(Result, qryUsers.RecordCount);
        intLength := 0;
        i := 0;

        while not qryUsers.Eof do
        begin
          qryTemplates := LQuery('SETUP', Format(K_STR_SEL_TEMPLATES, [QuotedStr(qryUsers.Fields[0].AsString)]));
          intLength := qryTemplates.RecordCount;
          SetLength(Result[i].Templates, intLength);
          Result[i].Login := qryUsers.Fields[0].AsString;
          SetLength(bufTemplate, 16384);
          j := 0;

          if not qryTemplates.IsEmpty then
          begin
            while not qryTemplates.Eof do
            begin
              for k := 0 to 16383 do
                Result[i].Templates[j].ftemplate[k] := qryTemplates.Fields[0].AsBytes[k];{I have problems in this line}

              qryTemplates.Next;
              Inc(j);
            end;
          end;

          if Assigned(qryTemplates) then
            FreeAndNil(qryTemplates);

          qryUsers.Next;
          Inc(i);
        end;
      end;
    except
      raise;
    end;
  finally
    if Assigned(qryUsers) then
      FreeAndNil(qryUsers);

    if Assigned(qryTemplates) then
      FreeAndNil(qryTemplates);
  end;
end;
Am I doing something wrong?

I'm working with UniDAC 3.60.0.16 on Delphi XE (15.0.3890.34076) and SQLite 3.6.5.[/code]

Posted: Wed 20 Apr 2011 09:56
by AlexP
Hello,

I could not reproduce the problem.
Please specify type of TUsers.Templates.ftemplate and the script to create a table.
Also please try to execute the following code:

Code: Select all

function TFaceDetect.LoadUsers: TUsers; 
const 
  K_STR_SEL_USERS     = 'SELECT Login' + 
                         ' FROM Users'; 

  K_STR_SEL_TEMPLATES = 'SELECT FaceTemplate' + 
                         ' FROM FaceTemplates' + 
                        ' WHERE Login = %s'; 
var 
  qryUsers, qryTemplates: TUniQuery; 
  i, j, k, intLength: Integer;
  bufTemplate: TArray;  
begin 
  try 
    try 
      qryUsers := LQuery('SETUP', K_STR_SEL_USERS); 

      if not qryUsers.IsEmpty then 
      begin 
        qryUsers.First; 
        SetLength(Result, qryUsers.RecordCount); 
        intLength := 0; 
        i := 0; 

        while not qryUsers.Eof do 
        begin 
          qryTemplates := LQuery('SETUP', Format(K_STR_SEL_TEMPLATES, [QuotedStr(qryUsers.Fields[0].AsString)])); 
          intLength := qryTemplates.RecordCount; 
          SetLength(Result.Templates, intLength); 
          Result.Login := qryUsers.Fields[0].AsString; 
          SetLength(bufTemplate, 16384); 
          j := 0; 

          if not qryTemplates.IsEmpty then 
          begin 
            while not qryTemplates.Eof do 
            begin 
               SetLength(bufTemplate, 16384); 
               for k := 0 to 16383 do
                  bufTemplate[k] := qryTemplates.Fields[0].AsBytes[k];
               Result.Templates[j].ftemplate :=  bufTemplate;

              qryTemplates.Next; 
              Inc(j); 
            end; 
          end; 

          if Assigned(qryTemplates) then 
            FreeAndNil(qryTemplates); 

          qryUsers.Next; 
          Inc(i); 
        end; 
      end; 
    except 
      raise; 
    end; 
  finally 
    if Assigned(qryUsers) then 
      FreeAndNil(qryUsers); 

    if Assigned(qryTemplates) then 
      FreeAndNil(qryTemplates); 
  end;