SQLite Unicode Support
Posted: 23.03.2007, 17:28
Hi, my first Zeos Hack.
This hack allows the use of UTF8 reading from queries and tables in SQLite.
There is a drawback nontheless as one will be forced to use "WIDECHAR(XXX)" as datatype in the SQLite DB.
This is possible, as SQLite always considers a fieldtype to be text whenever the Keyelement "TEXT" or "CHAR" is contained in the fielddef (see SQLite doc).
Now I use a custom format "WIDECHAR", which gets interpreted by ZEOS as UnicodeString and properly decoded from UTF8.
I tested this only with SQLite3 but it works nice.
Note that this is only a hack and not very elegant, I only post it here as it might be some starting point for someone.
It would be better to check the content of the field but fieldtype is made up before content is available.
Another solution would be to restrict all sqlite3 strings to be UTF8 as they are always stored as UTF8 in the SQLite.
Anyway, this approach below works for me just fine and now for the patch:
in ZDbcSqLiteResultSet.pas
in ZDbcSqLiteUtils.pas:
This hack allows the use of UTF8 reading from queries and tables in SQLite.
There is a drawback nontheless as one will be forced to use "WIDECHAR(XXX)" as datatype in the SQLite DB.
This is possible, as SQLite always considers a fieldtype to be text whenever the Keyelement "TEXT" or "CHAR" is contained in the fielddef (see SQLite doc).
Now I use a custom format "WIDECHAR", which gets interpreted by ZEOS as UnicodeString and properly decoded from UTF8.
I tested this only with SQLite3 but it works nice.
Note that this is only a hack and not very elegant, I only post it here as it might be some starting point for someone.
It would be better to check the content of the field but fieldtype is made up before content is available.
Another solution would be to restrict all sqlite3 strings to be UTF8 as they are always stored as UTF8 in the SQLite.
Anyway, this approach below works for me just fine and now for the patch:
in ZDbcSqLiteResultSet.pas
Code: Select all
TZSQLiteResultSet = class(TZAbstractResultSet)
[...]
// BEGIN UNICODE HACK c.schiffler
function GetUnicodeString(ColumnIndex: Integer): WideString; override;
// END UNICODE HACK c.schiffler
[...]
// BEGIN UNICODE HACK c.schiffler
{**
Gets the value of the designated column in the current row
of this <code>ResultSet</code> object as
a <code>WideString</code> in the Java programming language.
@param columnIndex the first column is 1, the second is 2, ...
@return the column value; if the value is SQL <code>NULL</code>, the
value returned is <code>null</code>
}
function TZSQLiteResultSet.GetUnicodeString(ColumnIndex: Integer): WideString;
var
Buffer : PChar;
begin
Buffer := GetPChar(ColumnIndex);
if Buffer <> nil then
Result := UTF8Decode(Buffer)
else
Result := '';
end;
// END UNICODE HACK c.schiffler
Code: Select all
function ConvertSQLiteTypeToSQLType(TypeName: string; var Precision: Integer;
var Decimals: Integer): TZSQLType;
var
P1, P2: Integer;
Temp: string;
begin
TypeName := UpperCase(TypeName);
Result := stString;
Precision := 0;
Decimals := 0;
P1 := Pos('(', TypeName);
P2 := Pos(')', TypeName);
if (P1 > 0) and (P2 > 0) then
begin
Temp := Copy(TypeName, P1 + 1, P2 - P1 - 1);
TypeName := Copy(TypeName, 1, P1 - 1);
P1 := Pos(',', Temp);
if P1 > 0 then
begin
Precision := StrToIntDef(Copy(Temp, 1, P1 - 1), 0);
Decimals := StrToIntDef(Copy(Temp, P1 + 1, Length(Temp) - P1), 0);
end else
Precision := StrToIntDef(Temp, 0);
end;
if StartsWith(TypeName, 'BOOL') then
Result := stBoolean
[...]
// BEGIN UNICODE HACK c.schiffler
else if TypeName = 'WIDECHAR' then
Result := stUnicodeString
// END UNICODE HACK c.schiffler
[...]
end;