mytbo
Members-
Content Count
21 -
Joined
-
Last visited
Everything posted by mytbo
-
With this data structure for the VST, it would be easier to use a class as a record for the tree data. The VST should better not hold the data, but only display it. This article shows how easy it is to map a data structure in VST. Here is the translation into English with Google Translator. The result is not perfect (rather not so good), also some formatting is destroyed, but it is readable. With best regards Thomas
-
Download HTML from server, save it as a file and execute the following: procedure TfrmMain.FormShow(Sender: TObject); begin EdgeBrowser.CreateWebView; end; procedure TfrmMain.EdgeBrowserCreateWebViewCompleted(Sender: TCustomEdgeBrowser; AResult: HRESULT); begin btnLoadHtml.Enabled := (AResult = 0); end; procedure TfrmMain.btnLoadHtmlClick(Sender: TObject); begin // ... download HTML from server, save it as a file EdgeBrowser.Navigate('file:///C:/Ambar/Temp/loginRetorno.html'); end; With best regards Thomas
-
Current alternatives for SMTP with TLS 1.3
mytbo replied to LeusKapus's topic in Network, Cloud and Web
With curl. See the examples. You can read how curl is used in this forum post and the follow-up links. With best regards Thomas -
With mORMot it can be solved as follows (all tubes for all records, or tubes for record with index): uses mormot.core.base, mormot.core.text, mormot.core.os, mormot.core.variants, mormot.db.rad.ui; function ShowTubesForRecordIndex(pmGrid: TDBGrid; const pmcDBFileName: TFileName; pmDBRecIdx: Integer): Boolean; var docDB: TDocVariantData; begin Result := False; if pmGrid = Nil then Exit; //=> FreeAndNil(pmGrid.DataSource); if docDB.InitJsonFromFile(pmcDBFileName, JSON_FAST_FLOAT) then begin pmGrid.DataSource := TDataSource.Create(pmGrid); var docPath: PDocVariantData := docDB.A['records']._[pmDBRecIdx].O['coin_mech'].A['tubes']; pmGrid.DataSource.DataSet := DocVariantToDataSet(pmGrid.DataSource, Variant(docPath^)); Result := (pmGrid.DataSource.DataSet <> Nil); end; end; function ShowTubesOfAllRecords(pmGrid: TDBGrid; const pmcDBFileName: TFileName): Boolean; var docDB: TDocVariantData; tubes: TVariantDynArray; begin Result := False; if pmGrid = Nil then Exit; //=> FreeAndNil(pmGrid.DataSource); if docDB.InitJsonFromFile(pmcDBFileName, JSON_FAST_FLOAT) then begin var docTubesPath: PDocVariantData; var docRecordsPath: PDocVariantData := docDB.A['records']; for var i: Integer := 0 to docRecordsPath.Count - 1 do begin docTubesPath := docRecordsPath._[i].O['coin_mech'].A['tubes']; for var n: Integer := 0 to docTubesPath.Count - 1 do begin SetLength(tubes, Length(tubes) + 1); tubes[High(tubes)] := Variant(docTubesPath._[n]^); end; end; if Length(tubes) > 0 then begin pmGrid.DataSource := TDataSource.Create(pmGrid); pmGrid.DataSource.DataSet := VariantsToDataSet(pmGrid.DataSource, tubes, Length(tubes), [], []); Result := (pmGrid.DataSource.DataSet <> Nil); end; end; end; Used as follows: var fileName: TFileName := MakePath([Executable.ProgramFilePath, 'DocDB.json']); ShowTubesForRecordIndex(DBGrid, fileName, 0); // ShowTubesOfAllRecords(DBGrid, fileName); I have published an article on topic mORMot DocVariant here (forum Delphi-PRAXIS). Here is the translation into English with Google Translator. The result is not perfect (rather not so good), also some formatting is destroyed, but it is readable. With best regards Thomas
-
I asked Stefan this question a year ago. This was his answer. We can only hope that he will find the time to do this. With best regards Thomas
-
FastReports event signalling finalization of a report output
mytbo replied to TurboMagic's topic in Delphi Third-Party
The event OnAfterPrintReport is fired only after printing. It is not fired during export (unless frxDotMatrixExport). With best regards Thomas -
FastReports event signalling finalization of a report output
mytbo replied to TurboMagic's topic in Delphi Third-Party
Is the answer I gave you on May 21 in forum Delphi-PRAXIS (DE) not helpful? Both links point to an example with source code. With best regards Thomas -
Problem with JSON library "SuperObjects"
mytbo replied to chkaufmann's topic in Network, Cloud and Web
What problems did you have with nested objects? mORMot can serialize almost anything to JSON. And if you use class TSynAutoCreateFields, you don't have to create or destroy the child object(s) yourself. It is enough to write the following: type {$M+} TSubItem = class(TObject) private FSubValue: RawUtf8; published property SubValue: RawUtf8 read FSubValue write FSubValue; end; {$M-} TItem = class(TSynAutoCreateFields) private FValue: RawUtf8; FSubItem: TSubItem; published property Value: RawUtf8 read FValue write FValue; property SubItem: TSubItem read FSubItem; end; var item: TItem; list: TObjectList; begin list := TObjectList.Create; try for var i: Integer := 0 to 1000 do begin item := TItem.Create; item.Value := StringToUtf8('value' + i.ToString); item.SubItem.SubValue := StringToUtf8('subValue' + i.ToString); list.Add(item); end; ObjectToJsonFile(list, '_listData.json'); finally list.Free; end; With best regards Thomas -
Problem with JSON library "SuperObjects"
mytbo replied to chkaufmann's topic in Network, Cloud and Web
In mORMot there are many ways to process JSON. mORMot is at least factor 5 faster than your current solution and more than 20 times faster than Delphi's own classes. A few of several possibilities are: var v: Variant; begin v := _JsonFast('{"splash.annually": "normal"}'); ShowMessage(v.Value('splash.annually')); var doc: TDocVariantData; begin doc.InitJson('{"splash.annually": "normal"}'); ShowMessage(doc.S['splash.annually']); I have published an article on this topic here (forum Delphi-PRAXIS). Here is the translation into English with Google Translator. The result is not perfect (rather not so good), also some formatting is destroyed, but it is readable. With best regards Thomas -
Store a large number of images in the filesystem or in a DB?
mytbo replied to RaelB's topic in Databases
With your requirements I would prefer a SQLite database. There is an article with sample source code on this topic in the DP forum (German part). Here is the translation into English with Google Translator. The result is not perfect, also some formatting is destroyed, but it is readable. With best regards Thomas -
Unable to write array of integers to JSON
mytbo replied to Bart Verbakel's topic in Algorithms, Data Structures and Class Design
The problem is simple. The way you have defined the field in the record, no Rtti information is created. This can be illustrated with the following: var rttiType: TRttiType := TRttiContext.Create.GetType(TypeInfo(TMyRecord)); if rttiType <> Nil then begin var recFieldType: TRttiType; for var field: TRttiField in rttiType.GetFields do begin recFieldType := field.FieldType; if recFieldType <> Nil then ShowMessage(recFieldType.ClassType.ClassName) else ShowMessage('Nil'); end; end; Solution: Explicitly define your own type or use dynamic arrays. type TInt3Array = array[1..3] of Integer; With best regards Thomas -
How to modify the code for $R+
mytbo replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
You are right. Thanks for the explanation. I didn't realize how easy it is to bypass range-checking. With best regards Thomas -
How to modify the code for $R+
mytbo replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Question for the experts. Is there a reason not to write this way? function BuildDigits(_Digits: UInt16; _Invalids: UInt8): UInt16; var tmp: SmallInt absolute _Digits; begin Dec(tmp, 2048); tmp := tmp * 11; _Digits := (_Digits and $FFFC) or (_Invalids and $03); Result := Swap(_Digits); end; With best regards Thomas -
With mORMot you can do it very easy. uses mormot.core.base, mormot.core.json, mormot.net.client; type TDataRec = packed record Count: Integer; Message: RawUtf8; SearchCriteria: RawUtf8; Results: array of record Value: RawUtf8; ValueId: Integer; Variable: RawUtf8; VariableId: Integer; end; end; var url: RawUtf8 := 'https://vpic.nhtsa.dot.gov/api/vehicles/decodevin/1G1BE5SM8J7207504?format=json&modelyear'; var content: RawByteString := HttpGet(url); if content <> '' then begin var dataRec: TDataRec; if RecordLoadJson(dataRec, content, TypeInfo(TDataRec)) then begin ShowMessage(dataRec.Count.ToString); ShowMessage(Length(dataRec.Results).ToString); for var i: Integer := 0 to High(dataRec.Results) do begin if dataRec.Results[i].Variable = 'Crash Imminent Braking (CIB)' then ShowMessage(dataRec.Results[i].VariableId.ToString); end; end; end; Additional information can be found in this article in Delphi-PRAXIS forum. Here is the translation into English with Google Translator. The result is not perfect (rather not so good), also some formatting is destroyed, but it is readable. With best regards Thomas
-
Best practices for working with a DB accessed via REST API?
mytbo replied to David Schwartz's topic in Databases
You wrote a long text but probably didn't spend a second to follow my links. If you did, what are you missing? I'm happy to take suggestions for further articles. With best regards Thomas -
Best practices for working with a DB accessed via REST API?
mytbo replied to David Schwartz's topic in Databases
If you want to use mORMot for the implementation, you can find some suggestions in these articles with sourcecode. For the creation of a MVC Web Application you can find an example here. If you use the ORM, the update is done by calling function CreateMissingTables. With best regards Thomas -
I can't answer your question for ICS. I use Curl because it supports FTP/FTPS/SFTP. You can find all the information on how to use it in this forum thread. An example of a download function: function FTPDownloadFile(const pmcUrl, pmcUserName, pmcPassword: RawUtf8; var pmvContent: RawByteString): TCurlResult; var hnd: TCurl; begin Result := crFailedInit; if not CurlIsAvailable then Exit; //=> hnd := curl.easy_init; if hnd <> Nil then begin curl.easy_setopt(hnd, coURL, Pointer(pmcUrl)); curl.easy_setopt(hnd, coUserName, Pointer(pmcUserName)); curl.easy_setopt(hnd, coPassword, Pointer(pmcPassword)); curl.easy_setopt(hnd, coWriteFunction, @CurlWriteRawByteString); curl.easy_setopt(hnd, coWriteData, @pmvContent); Result := curl.easy_perform(hnd); if Result <> crOk then pmvContent := ''; curl.easy_cleanup(hnd); end; end; Use it like this (for an SFTP server): uses mormot.core.base, mormot.core.text, mormot.core.os, mormot.lib.curl; var url: RawUtf8; buffer: RawByteString; begin url := 'sftp://test.rebex.net:22/pub/example/readme.txt'; if FTPDownloadFile(url, 'demo', 'password', buffer) = crOk then begin FileFromString(buffer, MakePath([Executable.ProgramFilePath, 'readme.txt'])); ShowMessage(Format('Download completed: %s', [KB(Length(buffer))])); end; end; With best regards Thomas
-
No, you are using the wrong libcurl DLL. Please download the file only from the official site and do not use any other source. Here is the link to the Windows download. The file for curl for 32-bit has the name curl-7.87.0_4-win32-mingw.zip and SHA256: ef8730e31245ef138aba1e3f02ae02e3fce435ec89177d7c8b05de5ce3c07891. The libcurl DLL has the modification date: Wednesday, December 21, 2022, 07:05:38. File size is 4,405,320 bytes. With best regards Thomas
-
Your libcurl DLL version is out of date (12-Oct-16). Download the latest version for your OS from the official site. With best regards Thomas
-
The all-purpose solution is Curl. The curl.exe program is part of current Windows versions. Links: GitHub, Download, Manual, libcurl C API and libcurl C examples. An encapsulation for libcurl DLL can be found in the mORMot unit mormot.lib.curl. The mORMot library does not need to be installed. Download the current commit and the static binaries from the last tag directory. Set the appropriate library and search paths in Delphi. This pattern helps to create them: // Simply replace the colons with the save path ..\src;..\src\app;..\src\core;..\src\crypt;..\src\db;..\src\lib;..\src\misc;..\src\net;..\src\orm;..\src\rest;..\src\script;..\src\soa;..\src\tools\ecc;..\src\ui; For many use cases you can find a template in the libcurl C examples. The following Delphi example shows the implementation for a download: uses mormot.core.base, mormot.core.text, mormot.core.os, mormot.lib.curl; var hnd: TCurl; url: RawUtf8; res: TCurlResult; buffer: RawByteString; responseSize: Int64; begin if not CurlIsAvailable then Exit; //=> hnd := curl.easy_init; if hnd <> Nil then begin url := 'https://icons8.com/icons/set/home.html'; curl.easy_setopt(hnd, coURL, Pointer(url)); curl.easy_setopt(hnd, coSSLVerifyPeer, 0); curl.easy_setopt(hnd, coSSLVerifyHost, 0); curl.easy_setopt(hnd, coWriteFunction, @CurlWriteRawByteString); curl.easy_setopt(hnd, coWriteData, @buffer); res := curl.easy_perform(hnd); if res = crOk then begin FileFromString(buffer, MakePath([Executable.ProgramFilePath, 'home.html'])); curl.easy_getinfo(hnd, ciSizeDownloadT, responseSize); ShowMessage(Format('Download completed: %s', [KB(responseSize)])); end else ShowMessage(Format('Curl told us %d (%s)', [Ord(res), curl.easy_strerror(res)])); curl.easy_cleanup(hnd); end; end; An example to study is also the class TCurlHttp from the unit mormot.net.client. With best regards Thomas
-
With mORMot you can write it as follows: ShowMessage(Utf8ToString(VariantSaveJson( _Obj(['registration_ids', _Arr(['crX7c-...']), 'notification', _Obj(['title', 'Hi', 'body', 'Notification test'])])))); The function _Obj() uses name-value pairs. The description of _Obj() can be found in the help here and for _Arr() here. Information about TDocVariant documents can be found here. With best regards Thomas