You are not logged in.
Pages: 1
Thanks, ab.
I understood it.
I have to use InterfaceArrayAdd and InterfaceArrayDelete each time I add or delete the interface into the database
Thanks, ab
You can't persist an interface pointer.
It is depending on the execution context.
This is just what I need.
I need to save an interface pointer within the execution context into the FullInMemory database
Thanks
That's how it works
...
TSQLProviders = class(TSQLRecord)
private
FIntf: UIntPtr; {What type of interface variable?}
published
property Intf: UIntPtr read FIntf write FIntf;
end;
....
Intf := TSomeProvider.Create;
Rec.Intf := UIntPtr(Intf); {how to convert interface variable to store in database?}
FRest.Add(Rec,True);
....
Provider := ISomeInterface(Rec.Intf).GetProvider; {how to call the interface method from database?}
Did the IInterface type variable is not a pointer?
Hi, ab
Help me please
How correctly to convert IInterface type to store in ORM database?
unit Unit1;
interface
type
ISomeInterface = interface
['{0A799B7B-3BBB-4159-B59F-BD3B03AA654F}']
function GetProvider: RawUTF8;
end;
TSQLProviders = class(TSQLRecord)
private
FIntf: ISomeInterface; {What type of interface variable?}
published
property Intf: ISomeInterface read FIntf write FIntf;
end;
TSomeObject = class
protected
FIntf: ISomeInterface;
FRest: TSQLRest;
public
constructor Create;
end;
implementation
constructor TSomeObject.Create;
var
Rec: TSQLProviders;
Provider: RawUTF8;
begin
FRest := TSQLRestServerFullMemory.CreateWithOwnModel([TSQLProviders]);
FRest.CreateMissingTables;
TSQLProviders.AutoFree(Rec);
Intf := TSomeProvider.Create;
Rec.Intf := Intf; {how to convert interface variable to store in database?}
FRest.Add(Rec,'',True);
Provider := Rec.Intf.GetProvider; {how to call the interface method from database?}
end;
end.
Thank you, WesleyAlves.
I could not understand for a long time why the way to create a self-signed SSL certificate,
described in the blog, does not work in Windows 10
It turns out that SSL certificates in Windows 10 must be created via PowerShell :-)
Hello everyone!
I decided this problem myself.
I had to edit the SynDBVCL.pas module code, as shown below.
Now it is possible to explicitly determine the length of dataset's text fields before the open dataset.
In this case, the visual components of TDBEDIT or TDBGRID will not cut more the length of the editable field along the length of the maximum value
procedure TSynBinaryDataSet.InternalInitFieldDefs;
var F: integer;
DBType: TFieldType;
FieldList: TStringList;
i: Integer;
begin
(*
If before opening a TSynDBDataset, the field structure (Dataset.FieldDefs)
was previously defined, we use the length of the fields from this structure
so as not to cut the length of the text fields TDBedit.Text
*)
FieldList := TStringList.Create;
try
for i := 0 to FieldDefs.Count - 1 do
if FieldDefs.Items[i].DataType = ftString then
FieldList.AddPair(FieldDefs.Items[i].Name, FieldDefs.Items[i].Size.ToString);
FieldDefs.Clear;
if fDataAccess=nil then
exit;
for F := 0 to fDataAccess.ColumnCount-1 do
with fDataAccess.Columns[F] do begin
case ColumnType of
SynTable.ftInt64:
DBType := ftLargeint;
SynTable.ftDate:
DBType := ftDateTime;
SynTable.ftUTF8:
begin
if ColumnDataSize=0 then
DBType := ftDefaultMemo
else
DBType := ftWideString; // means UnicodeString for Delphi 2009+
end;
SynTable.ftBlob:
DBType := ftBlob;
SynTable.ftDouble, SynTable.ftCurrency:
DBType := ftFloat;
else
raise EDatabaseError.CreateFmt(
'GetFieldData ColumnType=%s',[TSQLDBFieldTypeToString(ColumnType)]);
end;
if ToInteger(FieldList.Values[ColumnName], i) then
FieldDefs.Add(UTF8ToString(ColumnName),DBType, i)
else
FieldDefs.Add(UTF8ToString(ColumnName),DBType,ColumnDataSize);
end;
finally
FieldList.Free;
end;
end;
Modification code in mORMotVCLUnit.pas from "17 - TClientDataset use"
8: // test TSynDBSQLDataSet / TSynDBDataSet
if chkViaTClientDataSet.Checked then begin
ds1.DataSet := TSynDBDataSet.Create(self);
// ++++ Pre-determine the length of text fields
TSynDBDataSet(ds1.DataSet).DataSet.FieldDefs.Clear;
TSynDBDataSet(ds1.DataSet).DataSet.FieldDefs.Add('FirstName', ftString, 30);
TSynDBDataSet(ds1.DataSet).DataSet.FieldDefs.Add('LastName', ftString, 30);
// ++++
TSynDBDataSet(ds1.DataSet).Connection := fProps;
TSynDBDataSet(ds1.DataSet).CommandText := SQL_PEOPLE;
//--- Does not affect
TSynDBDataSet(ds1.DataSet).IgnoreColumnDataSize := true;
ds1.DataSet.Open;
end else begin
ds1.DataSet := TSynDBSQLDataSet.Create(self);
TSynDBSQLDataSet(ds1.DataSet).Connection := fProps;
TSynDBSQLDataSet(ds1.DataSet).CommandText := SQL_PEOPLE;
ds1.DataSet.Open;
end;
end;
Many thanks to everyone who responded.
Hello everyone and ask for help.
I am working in Delphi 10.4 Sydney
I am using the TSynDBDataSet to edit table values through the TDBEdit and TDBGrid components, and I found an unpleasant feature when doing this.
When editing the dataset, I cannot enter the longest string value for the ftUTF8 field, which is longer than the longest value from the table.
It turns out that the length of any ftUTF8 field is limited to the longest value in the table.
See example "17 - Using TClientDataset"
If you create a dataset, as in the example, then TSynDBDataSet.IgnoreColumnDataSize does not work.
8: // test TSynDBSQLDataSet / TSynDBDataSet
if chkViaTClientDataSet.Checked then begin
ds1.DataSet := TSynDBDataSet.Create(self);
TSynDBDataSet(ds1.DataSet).Connection := fProps;
TSynDBDataSet(ds1.DataSet).CommandText := SQL_PEOPLE;
TSynDBDataSet(ds1.DataSet).IgnoreColumnDataSize := true;
If you create a dataset in such a way as shown below, then the limitation on the field length is removed, but the display of the dataset is distorted with words (WIDEMEMO)
8: // test TSynDBSQLDataSet / TSynDBDataSet
if chkViaTClientDataSet.Checked then begin
ds1.DataSet := TSynDBDataSet.Create(self);
TSynDBDataSet(ds1.DataSet).IgnoreColumnDataSize := true;
var Rows := fProps.ExecuteInlined(StringToUTF8('select * from People'), True);
TSynDBDataSet(ds1.DataSet).From(Rows.Instance);
Please help me solve this problem.
I would be very grateful.
Thanks
I may add a Win1251 explicit collation... since there is already a Win1252 dedicated version...
Thank you, Arnaud. It will be very good.
In addition, I do not plan to move the database between systems with different locales.
I just started learning mORMot framework yesterday and I plan to transfer one my simple project implemented on Datasnap to mORMot.
If all goes well, I will use mORMot for new projects.
Many thanks for the help.
Setting WIN32NOCASE mode solved my issue.
IMPORTANT!
It is necessary to set the Collation columns mode ONLY before creating a new database
procedure TForm1.FormCreate(Sender: TObject);
begin
Model := CreateSampleModel;
// It is necessary to set the Collation columns mode ONLY before creating a new database
Model.SetCustomCollationForAll(sftUTF8Text, 'WIN32NOCASE');
Database := TSQLRestServerDB.Create(Model,ChangeFileExt(ExeVersion.ProgramFileName,'.db3'));
TSQLRestServerDB(Database).CreateMissingTables;
end;
Hi.
I always use the default codepage Win-1251 for my projects.
In the Example 02, if field "Name" uses the Latin alphabet, then the search is made case-insensitive, and if the Cyrillic alphabet, then the search is only case-sensitive.
Help me please. How can I ensure that the Cyrillic alphabet is also compared case-insensitively?
Thanks.
Example 02 - Embedded SQLite3 ORM
procedure TForm1.FindButtonClick(Sender: TObject);
var
Rec: TSQLSampleRecord;
SearchStr: RawUTF8;
begin
SearchString := StringToUTF8(NameEdit.Text);
Rec := TSQLSampleRecord.Create(Database,'Name=?',[SearchString]);
try
if Rec.ID=0 then
QuestionMemo.Lines.Add('Not found')
else
begin
Created.Text := Rec.CreationString;
QuestionMemo.Lines.Add(UTF8ToString(Rec.Question));
end;
finally
Rec.Free;
end;
end;
Pages: 1