Hi,

in TSqlitePassDatabaseDataTypeOptions.LoadFromDatabase you need to replace


if DbSettingsRecordset.RecordsCount = 0
  then Exit;

Try {1}
 Try {2}

[...]

 end; {Try 2 }
finally
StorageInfoStrings.Free;
MainPropertiesStrings.Free;
TranslationRulesStrings.Free;
CustomFieldDefsStrings.Free;
DbSettingsRecordset.Free;
end; {Try 1}

with

if DbSettingsRecordset.RecordsCount <> 0 then
Try {1}
 Try {2}

[...]

 end; {Try 2 }
finally

end; {Try 1}
StorageInfoStrings.Free;
MainPropertiesStrings.Free;
TranslationRulesStrings.Free;
CustomFieldDefsStrings.Free;
DbSettingsRecordset.Free;

2

(5 replies, posted in General)

Hi,

Sorry, I don't know anything about sorting smile

About the recordset thing, when you set it to nil, you lost some functionnality like:

Recordset.FDataset.FDatabase.FTranslator.
Recordset.FDataset.FDatabase.FEngine.

Maybe you planned to change the "TSqlitePassValueBufferToSqliteValue" declaration by adding the "Database" ?

{ Procedure to bind a FieldValue Buffer to a sqlite statement }
TSqlitePassValueBufferToSqliteValue = procedure
                                              ( Const Database: TSqlitePassDatabase;
                                                Const Recordset: TSqlitePassRecordset;
                                                Const FieldValueBuffer: PRecBuffer;
                                                Const PreparedStmt: Pointer;
                                                Const PreparedStmtFieldNo: Integer);

3

(5 replies, posted in General)

I made some changes
First, here's a fix for Delphi Unicode, you have to cast string to ansistring explicitly, we need to replace:

     ftString, ftFixedChar, ftMemo, FtFmtMemo:
       begin
       StrSize := Length(StrValue)+1;
       GetMem(Buffer, StrSize);
       StrCopy(Buffer, PAnsiChar(StrValue));
       end;

with

     ftString, ftFixedChar, ftMemo, FtFmtMemo:
       begin
       StrSize := Length(StrValue)+1;
       GetMem(Buffer, StrSize);
       StrCopy(Buffer, PAnsiChar(AnsiString(StrValue)));
       end;

And about params, I don't really understand why binding is made on Recordset data for strings as it's not the case for others types like integer or date and time. So I replaced all "Recordset.GetFieldAs"

in BindAnsiStringFieldValueBufferToSqliteValueAsUTF8

UTF8StrValue := SqlitePassUtils.AnsiToUTF8(PAnsiChar(FieldValueBuffer));

in BindUTF8AnsiStringFieldValueBufferToSqliteValueAsUTF8

UTF8StrValue := SqlitePassUtils.AnsiToUTF8(PAnsiChar(FieldValueBuffer));

in BindUTF8AnsiStringFieldValueBufferToSqliteValueAsUTF16

UTF16StrValue := SqlitePassUtils.UTF8Decode(PAnsiChar(FieldValueBuffer));

in BindWideStringFieldValueBufferToSqliteValueAsUTF16

UTF16StrValue := PWideChar(FieldValueBuffer);

What do you think about this ? It is the correct way ?

4

(5 replies, posted in General)

Hi,

Thank you for this library, I'm just starting to use it and I'm already happy with it!

I have an issue with parameters when using strings, see the code above. I'm not able to see where the bug happen.

  Dataset.Close;
  Dataset.Params.Clear;
  Dataset.ParamCheck := True;
  Dataset.SQL.Text := 'SELECT * FROM archive WHERE path=:PathAsString;';
  Dataset.Params.ParamByName('PathAsString').Value := ('path');
  Dataset.Open;

I'm getting an access violation in:

SqlitePassUtils.TSqlitePassAnsiStringList.Get(131184)
SqlitePassDbo.TSqlitePassRecordset.GetFieldAsAnsiString($91E0140)
SqlitePassDbo.BindUTF8AnsiStringFieldValueBufferToSqliteValueAsUTF16($F33290,$91E0140,$AE7098,1)
SqlitePassDbo.TSqlitePassParam.BindValue
SqlitePassDbo.TSqlitePassParams.BindValues
SqlitePassDbo.TSqlitePassDataset.InternalRefresh
SqlitePassDbo.TSqlitePassDataset.InternalOpen
:00657b3b TDataSet.DoInternalOpen + $1F
:006578f6 TDataSet.Open + $A

for the following reasons, FList is "nil" in TSqlitePassAnsiStringList.Get, and I can see that StrIndex is not valid (I'm getting a random value > 255)  in GetFieldAsAnsiString

If FList is "nil" it should mean that the parameter has not been stored correctly in the TSqlitePassAnsiStringList ?
Any help ?

You need to replace:

     ftWideString:
       begin
       // TODO - Check WideString Size...// Length
       StrSize := (Length(StrValue)*2)+1;

with

     ftWideString:
       begin
       // TODO - Check WideString Size...// Length
       StrSize := (Length(StrValue)+1)*2;

because #0 is also stored on 2 bytes

For unicode version of Delphi, you need to replace:

SqliteDbv3_bind_parameter_name:function(stmt:pointer; idx:integer):pChar; cdecl;

with

SqliteDbv3_bind_parameter_name:function(stmt:pointer; idx:integer):pAnsiChar; cdecl;