Jump to content

Rafael Dipold

Members
  • Content Count

    19
  • Joined

  • Last visited

Posts posted by Rafael Dipold


  1. I'll try, but the disadvantage of Indy is that I would have to include the SSL libraries and control the version of that too..

     

    I believe it would be possible to implement this using THTTPClient by activating the option flag WINHTTP_OPTION_IPV6_FAST_FALLBACK

    https://learn.microsoft.com/en-us/windows/win32/winhttp/option-flags
     

    However, I believe that this could only be done by modifying Delphi's RTL by Embarcadero to include such an option...


  2. Enjoying the topic, is there any way to force the connection only via IPv4 in this example?

     

      LHTTPClient := THTTPClient.Create;
      try
        LHTTPResponse := LHTTPClient.Get(LURL); //Error sending data: 12002.Time limit exceed
        Result := LHTTPResponse.ContentAsString(TEncoding.UTF8);
      finally
        LHTTPClient.Free;
      end;

     

    Because in a few cases, my clients who use my software end up receiving the error message described in the comment, and when I manually disable the IPv6 protocol in the Windows network settings, the software starts working again. =/
    I understand that IPv6 must be misconfigured on the router or server on the client's network, however, by forcing the use of IPv4, I would no longer need to waste time with this type of problem that is not related to my software


  3. Hi, 

     

    I can consider now this problem solved.

    As you can read here: Currently, explicit transaction object assignment is supported only for InterBase and Firebird.

    I have always worked with Firebird and I was guided by the same logic to manage PostgreSQL transactions. And now I see that I will have to redesign my connection layer.

    Thanks


  4.  

    Here is a verifiable example, just enter a valid database and table.

     

    I don't see anything that could be wrong here, it seems to be a Firedac bug:

     

    program Project1;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      FireDAC.Comp.Client,
      FireDAC.DApt,
      FireDAC.Phys.PG,
      FireDAC.Phys.PGDef,
      FireDAC.Stan.Async,
      FireDAC.Stan.Def,
      FireDAC.Stan.Intf,
      System.SysUtils;
    
    var
      LConnectionDef: IFDStanConnectionDef;
      LQueryRO: TFDQuery;
      LQueryRW: TFDQuery;
      LTransactionRO: TFDTransaction;
      LTransactionRW: TFDTransaction;
    begin
      try
        FDManager.DriverDefFileAutoLoad := False;
        FDManager.ConnectionDefs.AutoLoad := False;
        FDManager.ConnectionDefs.Clear;
    
        FDManager.ConnectionDefs.BeginWrite;
        try
          LConnectionDef := FDManager.ConnectionDefs.AddConnectionDef;
          LConnectionDef.Name := 'MY_DB';
    
          with TFDPhysPGConnectionDefParams(LConnectionDef.Params) do
          begin
            DriverID := 'PG';
            CharacterSet := TFDPGCharacterSet.csUTF8;
            Server := '127.0.0.1';
            Database := 'MY_DB';
            Port  := 11786;
            UserName := 'myuser';
            Password := '123456';
          end;
        finally
          FDManager.ConnectionDefs.EndWrite;
        end;
    
        LTransactionRO := TFDTransaction.Create(nil);
        LQueryRO := TFDQuery.Create(nil);
        try
          LTransactionRO.Connection := FDManager.AcquireConnection('MY_DB', '');
          LTransactionRO.Options.ReadOnly := True;
    
          LQueryRO.Connection := FDManager.AcquireConnection('MY_DB', '');
          LQueryRO.Transaction := LTransactionRO;
    
          LQueryRO.Open('SELECT * FROM MY_TABLE');
        finally
          LQueryRO.Free;
          LTransactionRO.Free;
        end;
    
        LTransactionRW := TFDTransaction.Create(nil);
        LQueryRW := TFDQuery.Create(nil);
        try
          LTransactionRW.Connection := FDManager.AcquireConnection('MY_DB', '');
          LTransactionRW.Options.ReadOnly := False;
    
          LQueryRW.Connection := FDManager.AcquireConnection('MY_DB', '');
          LQueryRW.Transaction := LTransactionRW;
    
          //ERROR: cannot execute UPDATE in a read-only transaction.
          LQueryRW.ExecSQL('UPDATE MY_TABLE SET COLUMN_1 = COLUMN_1 WHERE 1=1');
        finally
          LQueryRW.Free;
          LTransactionRW.Free;
        end;
    
        Writeln('OK');
        Readln;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.

     


  5. Hello friends,

     

    Would anyone have a tip why the read-only error happens when I run the FireDAC commands in this order, like the MRE below?

     

        //READ ONLY TRANSACTION
        LTransactionRO := TFDTransaction.Create(nil);
        LQueryRO := TFDQuery.Create(nil);
        try
          LTransactionRO.Connection := FDManager.AcquireConnection('MY_DB', '');
          LTransactionRO.Options.ReadOnly := True;
    
          LQueryRO.Connection := FDManager.AcquireConnection('MY_DB', '');
          LQueryRO.Transaction := LTransactionRO;
          LQueryRO.Open('SELECT * FROM mY_TABLE'); //OK
        finally
          LQueryRO.Free;
          LTransactionRO.Free;
        end;
    
        //READ WRITE TRANSACTION
        LTransactionRW := TFDTransaction.Create(nil);
        LQueryRW := TFDQuery.Create(nil);
        try
          LTransactionRW.Connection := FDManager.AcquireConnection('MY_DB', '');
          LTransactionRW.Options.ReadOnly := False;
    
          LQueryRW.Connection := FDManager.AcquireConnection('MY_DB', '');
          LQueryRW.Transaction := LTransactionRW;
    
          //ERROR: cannot execute UPDATE in a read-only transaction.
          LQueryRW.ExecSQL('UPDATE MY_TABLE SET COLUM1 = COLUM1 WHERE 1 = 1');
        finally
          LQueryRW.Free;
          LTransactionRW.Free;
        end;

    if I comment the line `//LTransactionRO.Options.ReadOnly := True;`, the SQL UPDATE run without errors.

     

    Thanks for any tips!


  6. I updated Windows to 22H2, no programs running in the background, and even copying this string from notepad, my string has only memory garbage..

     

    Initially I thought it was a bug in Delphi, that's why I posted it here, but now I see that my computer has some glitch, as I tested it on another computer and the bug doesn't happen

     

    image.thumb.png.3b0a2e9a4871c1597b342a2eff2cb2d0.png


  7. 42    N    N    =DOLLAR(4967.32, 2)    =DOLLAR(1515.61, 2)    =DOLLAR(0, 2)    =DOLLAR(58054.89, 2)    =DOLLAR(4084.55, 2)
    42    N    N    =DOLLAR(4B8r3B4p7yhRXuBWLqsQ546WR43cqQwrbXMDFnBi6vSJBeif8tPW85a7r7DM961Jvk4hdryZoByEp8GC8HzsqJpRN4FxGM9, 2)

    For me, even if I copy and paste here on the Forum, it pastes garbage from memory... see second line above.


    I will try to install the latest windows updates.. seems to be a windows bug


  8.  

    Hi,

    Can anyone explain to me why this specific sequence of characters, when copying to clipboard and pasting to notepad, windows pastes memory garbage?

     

    If I change '42' to '32', for example, this issue not happen

    procedure TForm1.Button1Click(Sender: TObject);
    var
      C, R: TArray<String>;
    begin
      C := [];
      C := C + ['42'];
      C := C + ['N'];
      C := C + ['N'];
      C := C + ['=DOLLAR(4967.32, 2)'];
      C := C + ['=DOLLAR(1515.61, 2)'];
      C := C + ['=DOLLAR(0, 2)'];
      C := C + ['=DOLLAR(58054.89, 2)'];
      C := C + ['=DOLLAR(4084.55, 2)'];
    
      R := R + [''.Join(#9, C)];
    
      Clipboard.AsText := ''.Join(#13#10, R);
    
      ShowMessage('Copy to Clipboard!');
    end;

     


  9. Exactly. I did some workarounds to get around this problem.

    It works, but it's not an ideal code...

     

    type
      TForm1 = class(TForm)
        EdgeBrowser: TEdgeBrowser;
        procedure EdgeBrowserWebMessageReceived(Sender: TCustomEdgeBrowser; Args: TWebMessageReceivedEventArgs);
      private
        FQueue: TQueue<String>;
    
        FMyResult1: String;
        FMyResult2: String;
    
        procedure JSExec;
        procedure ShowResult;
      end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      FQueue.Enqueue('JSExec1');
      FQueue.Enqueue('JSExec2');
    
      JSExec;
    end;
    
    procedure TForm1.EdgeBrowserWebMessageReceived(Sender: TCustomEdgeBrowser; Args: TWebMessageReceivedEventArgs);
    begin
      if (JSON.messageType = 'R1') then //Get from Args (omitted for simplification)
        FMyResult1 := JSON.value; 
    
      if (JSON.messageType = 'R2') then
        FMyResult2 := JSON.value; 
    
      JSExec;
    end;
    
    procedure TForm1.JSExec;
    var
      LExec: String;
      LMyScript: String;
    begin
      if (FQueue.Count = 0) then
      begin
        ShowResult;
        Exit;
      end;
    
      LExec := FQueue.Dequeue();
    
      if (LExec = 'JSExec1') then
      begin
        LMyScript := 'window.chrome.webview.postMessage({messageType: "R1", value: "MyResult1"});';
        EdgeBrowser.ExecuteScript(LMyScript);
        Exit;
      end;
    
      if (LExec = 'JSExec2') then
      begin
        LMyScript := 'window.chrome.webview.postMessage({messageType: "R2", value: "MyResult2"});';
        EdgeBrowser.ExecuteScript(LMyScript);
        Exit;
      end;
    end;
    
    procedure TForm1.ShowResult;
    begin
      ShowMessage(FResult1);
      ShowMessage(FResult2);
    end;

     


  10. Hi, lay questions are accepted?

     

    I need to run some scripts in a sequence on a document, where the result of the previous script is used to the next script.

     

    I created a simplified example for better understanding:

    type
      TForm1 = class(TForm)
        EdgeBrowser: TEdgeBrowser;
        procedure EdgeBrowserWebMessageReceived(Sender: TCustomEdgeBrowser; Args: TWebMessageReceivedEventArgs);
      private
        FMyResult: String;
      end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      LMyScript: String;
    begin
      LMyScript := 'window.chrome.webview.postMessage("MyResult");';
      EdgeBrowser.ExecuteScript(LMyScript);
    
      //How wait for EdgeBrowserWebMessageReceived() to get FMyResult?
      ShowMessage(FMyResult);
    end;
    
    procedure TForm1.EdgeBrowserWebMessageReceived(Sender: TCustomEdgeBrowser; Args: TWebMessageReceivedEventArgs);
    begin
      FMyResult := '"MyResult"'; //Get from Args (omitted for simplification)
    end;

    The comment in the code shows my need.

     

    I tried several workarounds like run ExecuteScript() on a TTask.Future(), but EdgeBrowserWebMessageReceived() only executes when the thread finalize.


    Does anyone have any suggestions? It doesn't have to be an elegant solution, because this is for internal use.

     

    Thanks in advance


  11. FEvents.Options.Synchronize := True;

    I had already tried this option without success.

    I also tried to force the registration of the event on a Thread Synchronize, but if more than on event register or trigger in the same cycle, the software also freezes:

     

    TThread.CreateAnonymousThread(
    procedure
    begin
      TThread.Synchronize(nil,
      procedure
      begin
        FBEvents.Events.Add('EVENT_2');
      end);
    end).Start;

     

    @WillH PostMessage() happens the same as Thread.Synchronize() if more than one event trigger. Both only minimize the problem:

     

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      FConn.ExecSQL('EXECUTE BLOCK AS BEGIN POST_EVENT ''EVENT_1''; END');
      FConn.ExecSQL('EXECUTE BLOCK AS BEGIN POST_EVENT ''EVENT_1''; END');
    
      PostMessage(Handle, WM_EVENT_MESSAGE, Integer(PChar('EVENT_2')), 0);
    end;

     


  12. I've created an MCVE that simulates a problem that eventually happens in our software, where software freezes when it tries to register an event when a previously registered event triggers within the same cycle.

     

    In an internal test, we found that this also occurs using the TIB_Events component.

     

    Would this be a Firebird or FireDAC bug?

     

    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows,
      Winapi.Messages,
      System.Classes,
      System.SysUtils,
      Vcl.Controls,
      Vcl.Forms,
      Vcl.StdCtrls,
      FireDAC.Comp.Client,
      FireDAC.Comp.UI,
      FireDAC.Phys,
      FireDAC.Phys.FB,
      FireDAC.Phys.FBDef,
      FireDAC.Phys.IBBase,
      FireDAC.Stan.Async,
      FireDAC.Stan.Def,
      FireDAC.Stan.Intf,
      FireDAC.UI.Intf,
      FireDAC.VCLUI.Wait;
    
    type
      TForm1 = class(TForm)
        Button1: TButton;
    
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        FConn : TFDConnection;
        FEvents: TFDEventAlerter;
        procedure EventAlert(ASender: TFDCustomEventAlerter; const AEventName: String; const AArgument: Variant);
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      FConn.ExecSQL('EXECUTE BLOCK AS BEGIN POST_EVENT ''EVENT_1''; END');
    
      FEvents.Names.Add('EVENT_2');
    end;
    
    procedure TForm1.EventAlert(ASender: TFDCustomEventAlerter; const AEventName: String; const AArgument: Variant);
    begin
      Caption := AEventName + ' ' + DateTimeToStr(Now);
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      FConn := TFDConnection.Create(nil);
      FConn.LoginPrompt := False;
      FConn.DriverName                    := 'FB';
      FConn.Params.Values['DriverID']     := 'FB';
      FConn.Params.Values['CharacterSet'] := 'ISO8859_1';
      FConn.Params.Values['Server']    := '127.0.0.1';
      FConn.Params.Values['Database']  := 'c:\temp\whatever.fdb';
      FConn.Params.Values['User_Name'] := 'SYSDBA';
      FConn.Params.Values['Password']  := 'masterkey';
    
      FEvents := TFDEventAlerter.Create(nil);
      FEvents.Connection := FConn;
      FEvents.Names.Add('EVENT_1');
      FEvents.OnAlert := EventAlert;
      FEvents.Register;
    end;
    
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      FEvents.Free;
      FConn.Free;
    end;
    
    end.

     

×