Jump to content

Lars Fosdal

Administrators
  • Content Count

    3521
  • Joined

  • Last visited

  • Days Won

    116

Posts posted by Lars Fosdal


  1. There is nothing unusual with Explorer querying a registry entry that doesn't exist. In this case, it checks for Application Compatibility flags and finds none for bds.exe.

    Nor is there anything unusual about Explorer reading from the files to extract things like file information resources.

    In computing like in medicine - it is only when the patience appear sick that you start examining the symptoms in detail.


  2. There are many better alternatives to Sleep. 

    https://learn.microsoft.com/en-us/windows/win32/sync/wait-functions#multiple-object-wait-functions

     

    The downside of a single Sleep is that it blocks termination of the thread.

    The downside of multiple Sleep + time checks to allow termination, consumes more CPU.

     

    Signals, WaitForXXXX & Timeouts give you all the tools you need to have low cost and responsive threads - even if it requires a little more scaffolding code.

    • Like 2

  3. @JonRobertson I have no performance comparisons between the ODBC driver and the OLEDB driver, so I'll have to take that at face value.
    Devart did a a more nuanced comparison between the two.
     

    The OLEDB driver was deprecated by MS at one point, then undeprecated in 2018.

    Not sure why EMBT chose not to create a wrapper for it, but resources may have been an issue?

     

    As for ODBC vs Native - In case there are multiple drivers installed, I wrote the following simple code to pick my preferred driver, but these days we stick with the ODBC driver(s) due to the Native Client being too old for some of our databases.

    class function TPSDFireDatabasePoolMSSQL.FindBestDriver(const Link: TFDPhysMSSQLDriverLink): String;
    const // Constants copied from implementation section of FireDAC.Phys.MSSQL
      C_SQL_SERVER = 'SQL Server'; // DO NOT TRANSLATE
      C_2019_ODBC = 'ODBC DRIVER 19 FOR SQL SERVER'; // DO NOT TRANSLATE
      C_2018_ODBC = 'ODBC DRIVER 18 FOR SQL SERVER'; // DO NOT TRANSLATE
      C_2017_ODBC = 'ODBC DRIVER 17 FOR SQL SERVER'; // DO NOT TRANSLATE
      C_2016_ODBC = 'ODBC DRIVER 13 FOR SQL SERVER'; // DO NOT TRANSLATE
      C_2012_ODBC = 'ODBC DRIVER 11 FOR SQL SERVER'; // DO NOT TRANSLATE
    {$IFDEF POSIX}
      C_FreeTDS = 'FreeTDS';
    {$ENDIF}
    {$IFDEF MSWINDOWS}
      C_2012_NC = 'SQL SERVER NATIVE CLIENT 11.0'; // DO NOT TRANSLATE
    {$ENDIF}
    var
      DriverList : TStringList;
      WantedList : TArray<String>;
      Driver: string;
    begin
      Result := ''; // Blank = Default
    
      WantedList := {$IFDEF MSWINDOWS}
                      {$IFDEF SQLNative}
                        [C_2012_NC, C_2017_ODBC, C_2016_ODBC, C_2012_ODBC]
                      {$ELSE}
                        [C_2018_ODBC, C_2017_ODBC, C_2016_ODBC, C_2012_NC, C_2012_ODBC]
                     {$ENDIF}
                   {$ENDIF}
                   {$IFDEF POSIX}
                     [C_2018_ODBC, C_2017_ODBC, C_2016_ODBC, C_2012_ODBC, C_FreeTDS]
                   {$ENDIF};
    
      DriverList := TStringList.Create;
      try
        Link.GetDrivers(DriverList);
    
        DebugOut('Available SQL drivers'); // DO NOT TRANSLATE
        for Driver in DriverList
         do DebugOut(' "' + Driver + '"');
    
        for var Wanted in WantedList
         do for Driver in DriverList
          do begin
            if CompareText(Wanted , Driver) = 0
            then begin
              DebugOut('Selected driver: "' + Driver + '"'); // DO NOT TRANSLATE
              BestDriver := Driver;
              Exit(Driver);
            end;
          end;
      finally
        DriverList.Free;
      end;
    end;
    

     


  4. I think you missed the point of my suggested changes. The point was only to be able to read the 32-bit stream.

    I think you will need to rewrite the code that loads the data from the old-32 bit structures.

    I don't see a clean easy way to avoid that, f.x. by using my example record struct to read the old stream, and then move it to a 64-bit version with actual pointers..

     

    You say Element sequence is important - is the order of the loaded double linked list supposed to be different from the streamed order?

     

    I have a feeling that your records are more complex than your example, and I certainly don't understand the reason for the untyped pointer.

    Are the actual records fixed in size or do they vary in size?

     

    Are you writing new 32-bit and 64-bit apps, so this is not a transition thing - but a need for a future shared format?

    In that case, I would rethink the structure and replace the pointers with stream offsets.

×