Jump to content

Roger Cigol

Members
  • Content Count

    305
  • Joined

  • Last visited

  • Days Won

    4

Posts posted by Roger Cigol


  1. I thought I would add some code with "what doesn't work" and how to use the above two functions to make it work.

    Assume you have a postgreSQL database connected and that you have a query that returns a record that contains a date/time value and that the database stores this value as a "time stamp with time zone" format (PostgreSQL users can call this timestamptz).

    I would expect the following code to work - but after you run it AllOkA is true (showing it works for UTC local time) but AllOkB is false (showing it falls over for BST (British Summer Time)).

             TFDQuery *FDQuery = SampleFDQuery;  // a query which returns a record with a timestampwithoffset field
             FDQuery->Close();
             // work with the oldest record (any one would do)
             FDQuery->ParamByName(SSQP_PrimaryKey)->AsLargeInt = 1;
             FDQuery->OpenOrExecute();
             FDQuery->First(); // should only be one entry
             TField *Field = FDQuery->FieldByName(PG_Sensors_TimeDate);
             // try a winter time (January)  (this is UTC - works without special function calls
             TDateTime WinterLocalDateTime{2020, 1, 17, 9, 8, 7, 0};
             FDQuery->Edit();
             Field->AsDateTime = WinterLocalDateTime;   //=== 
             FDQuery->Post();
             FDQuery->Close();
             FDQuery->OpenOrExecute();
             Field = FDQuery->FieldByName(PG_Sensors_TimeDate);
             TDateTime Check = Field->AsDateTime;  //=== 
             FDQuery->Close();
             AllOkA = (WinterLocalDateTime == Check);
             if (AllOkA) {
                FDQuery->OpenOrExecute();
                Field = FDQuery->FieldByName(PG_Sensors_TimeDate);
                // try a summer time (June) (BST - one hour ahead of UTC)
                TDateTime SummerLocalDateTime{2020, 6, 17, 9, 8, 7, 0};
                FDQuery->Edit();
                Field->AsDateTime = SummerLocalDateTime;  //=== 
                FDQuery->Post();
                FDQuery->Close();
                FDQuery->OpenOrExecute();
                Field = FDQuery->FieldByName(PG_Sensors_TimeDate);
                Check = Field->AsDateTime;  //=== 
                FDQuery->Close();
                AllOkB = (SummerLocalDateTime == Check);
             }

    If I replace the lines with comments //=== with calls to the functions given in my previous posting I get code that works for both winter and BST summer times (ie both AllOkA and AllOkB are true at the end of the code).

             TFDQuery *FDQuery = SampleFDQuery;  // a query which returns a record with a timestampwithoffset field
             FDQuery->Close();
             // work with the oldest record (any one would do)
             FDQuery->ParamByName(SSQP_PrimaryKey)->AsLargeInt = 1;
             FDQuery->OpenOrExecute();
             FDQuery->First(); // should only be one entry
             TField *Field = FDQuery->FieldByName(PG_Sensors_TimeDate);
             // try a winter time (January)  (this is UTC - works without special function calls
             TDateTime WinterLocalDateTime{2020, 1, 17, 9, 8, 7, 0};
             FDQuery->Edit();
             UpdatePgSQLDataSetFieldIfNotDefaultDate(Field, WinterLocalDateTime); //===
              FDQuery->Post();
             FDQuery->Close();
             FDQuery->OpenOrExecute();
             Field = FDQuery->FieldByName(PG_Sensors_TimeDate);
             TDateTime Check = GetPgSQLDataSetFieldAsLocalTime(Field); //===
             FDQuery->Close();
             AllOkA = (WinterLocalDateTime == Check);
             if (AllOkA) {
                FDQuery->OpenOrExecute();
                Field = FDQuery->FieldByName(PG_Sensors_TimeDate);
                // try a summer time (June) (BST - one hour ahead of UTC)
                TDateTime SummerLocalDateTime{2020, 6, 17, 9, 8, 7, 0};
                FDQuery->Edit();
                UpdatePgSQLDataSetFieldIfNotDefaultDate(Field, SummerLocalDateTime);//===
                FDQuery->Post();
                FDQuery->Close();
                FDQuery->OpenOrExecute();
                Field = FDQuery->FieldByName(PG_Sensors_TimeDate);
                Check = GetPgSQLDataSetFieldAsLocalTime(Field); //===
                FDQuery->Close();
                AllOkB = (SummerLocalDateTime == Check);
             }

    I do not have a copy of Microsoft SQLServer but I would think it very likely that the same problem exists with this too.  (but am wise enough to wait for someone else to verity this !).


  2. Just posting this in case anyone else out there is wasting their time on this.....

    It seems that there is currently a problem with using the Clang compilers in RAD Studio 12.0 with the GoogleTest framework on getit. The version currently (Jan 2024) available does not build correctly.

    I will monitor this situation and blog here as soon as Embarcadero have a working GoogleTest framework on getit.

     


  3. It is very unusual to want to create an XML file and then at some later time set the values. What purpose does an XML file with no values in serve? How you create an XML file from data values that you have is (probably) your question. The answer to this may depend on where the values are coming from.

    The Embarcadero XML mapper tool (available on Getit - EXCEPT AT THIS MOMENT IN TIME (JAN 2024) GETIT IS BROKEN) allows you to take <at design time> an existing *.xsd schema and create a transofrmation that can then be used in your code so that <at run time> a TClientDataset can generate an XML file from the data it contains. 

    I am aware that I am not helping with the "using OmniXml" part of your question but I mention the above in case it helps.

    • Thanks 1

  4. I think I have found the area of my problem. If I put my breakpoint(s) in areas of code where "normal" code functions are happening then all is well. The opposite of "normal" is if I put a breakpoint in code that is interfacing with my postgreSQL (version 13 - 64 bit) database inside a database transaction then the debugger seems to hang / or do all sorts of bad things. I have my postgreSQL configured with various time outs. It makes debugging complicated database interaction (with several TFDQuery updates being used in one transaction) a bit tricky - but the IDE seems reliable if I avoid this - which is something that is workable.

     


  5. I am finding problems with RAD RAD Studio 12.0 - running C++ using Clang 64bit for a windows VCL project.

    If I insert a breakpoint it stops ok when the execution reaches the breakpoint.

    If I then try to single step sometimes it works. Most often I get a dialog appear (as per attached screen shot) but both "Wait" and "Terminate" buttons are frozen. Task manager shows RAD Studio is usage is "high" but everything is frozen. Only recovery is to shut down the entire RAD Studio using Task Manager.

    I get the same problems if I try to run it on a remote windows PC, deploying using PA Server.

    Anyone else seen this ?

    DebugLockUpDialog.JPG


  6. I am using C++ Builder (RAD Studio 12.0) compiling to a Win64 VCL project working with PostgreSQL 13 database.

    RAD Studio 12.0 includes the bug fix of RSP-28292 - use of SQLTimeStampOffset fields in FireDAC.

    I have fields in my postgreSQL tables that are type TimeStampWithTimeZone. When viewed using PgAdmin4 they display values such as

     

    2024-01-15 15:05:12+00   (for winter in the UK = UTC)

    or

    2016-06-09 15:13:03+01 (for summer in the UK = BTS - one hour ahead of UTC).

     

    I use fireDAC TFDQuery and obtain datasets with these fields in. If I use 

     

    // ToBeRead is the TField pointer within the dataset (typically obtained using FieldByName())
    TSQLTimeStampOffset UTC_O = ToBeRead->AsSQLTimeStampOffset;

    Then I get a value in UTC_0 which has a time offset figure of zero and the hours compensated for. Using the above two examples this

    would mean UTC_0 would be equal to

     

    {2024, 01, 15, 15, 05, 12, 0, 0, 0}

     

    or

     

    {2016, 06, 09, 14, 13, 03, 0, 0, 0}    // note: time offset is returned as zero and the hours value has been decremented by 1

     

    This is not the behaviour I expected. I thought I would get the value as local time and with the time offset value set to the

    same value as displayed by pgAdmin4, ie for the summer case, I would expect

    {2016, 06, 09, 15, 13, 03, 0, 1, 0}   // result in BST and time offset = 1 hour

     

    Users of my software want to see the time values displayed in local time (of course) so I have to convert this UTC value to

    BST for date/time values in the summer. 

     

    RAD Studio 12.0 doesn't seem to implement functions UTCToLoca() or LocalToUTC() for arguments of type TSQLTimeStampOffset.

    It DOES implement these functions for type TSQLTimeStamp. So I am forced to first convert my TSQLTimeStampOffset to

    a TSQLTimeStamp value and then convert it to local time. I use this code....

     

    TDateTime GetPgSQLDataSetFieldAsLocalTime(TField *ToBeRead)
    {
       TDateTime LocalDateTime;
       if (ToBeRead) {
          // Reading AsSQLTimeStampOffset seems to return UTC value
          // (ie TimeZone is Zero and hours (+days etc) have been compensated correctly)
          // This is not ideal !
          TSQLTimeStampOffset UTC_O = ToBeRead->AsSQLTimeStampOffset;
          TSQLTimeStamp UTC;
          UTC.Year = UTC_O.Year;
          UTC.Month = UTC_O.Month;
          UTC.Day = UTC_O.Day;
          UTC.Hour = UTC_O.Hour;
          UTC.Minute = UTC_O.Minute;
          UTC.Second = UTC_O.Second;
          UTC.Fractions = UTC_O.Fractions;
          TSQLTimeStamp Local = UTCToLocal(UTC);
          LocalDateTime = SQLTimeStampToDateTime(Local);
       }
       return LocalDateTime;
    }

    This all works but it all has the feel of being a "work around".

     

    To update the field from a local time I am now using this code.

     

    void UpdatePgSQLDataSetFieldFromLocalTime(TField *ToBeUpdated, TDateTime LocalDateTime)
    {
       if (ToBeUpdated) {
          TSQLTimeStamp Local = DateTimeToSQLTimeStamp(LocalDateTime);
          TSQLTimeStamp UTC = LocalToUTC(Local);
          TSQLTimeStampOffset UTC_O;
          UTC_O.Year = UTC.Year;
          UTC_O.Month = UTC.Month;
          UTC_O.Day = UTC.Day;
          UTC_O.Hour = UTC.Hour;
          UTC_O.Minute = UTC.Minute;
          UTC_O.Second = UTC.Second;
          UTC_O.Fractions = UTC.Fractions;
          UTC_O.TimeZoneHour = 0;
          UTC_O.TimeZoneMinute = 0;
          ToBeUpdated->AsSQLTimeStampOffset = UTC_O;
       }
    }

    Again, this all works. But it all seems fairly "hard work" to code.

     

    I post the code here in case it helps anyone out.

     

    I am interested to know if anyone has a better way of working with TimeStampWithTimeZone field types and local time values.


  7. ...and if you look in the sub directory __history you would find files *.pas.~1~   (and possibly *.pas.~2~ and  *.pas.~3~ etc). These are the backup copy(s) you need. (The one with the highest number is the most recent). 


  8. Clipboard history was removed. The argument (probably valid) was that the Windows clipboard history does the job just as well (or better). Use left hand "Windows icon" key combined with "V" to bring up clipboard history.

    • Like 1
    • Thanks 4

  9. This looks like standard compiler memory alignment to me and is entirely expected.

     

    I am pretty sure that the compiler writers would take (gentle) issue with your "really no good reason" statement.

     

    I am not sure why it makes static analysis difficult - memory alignment is a common feature of many (most?) compilers. What static analysis tool are you using and where do you find the problem?


  10. This is arguably one of the other significant benefits of designing code with Unit Testing in mind. It encourages you to write loosely coupled (or better entirely self standing) modules....

    52 minutes ago, David Champion said:

    Refactor the code to be loosely coupled; normally a huge amount of effort on a typical RAD created application

    If you are dealing with legacy code this might be the case - but that doesn't mean that it is not worth effort. If you intend to keep the code live and supported for the future it almost certainly IS worth refactoring.

    • Like 2

  11. Most of the basic editing functions and keyboard short cuts of the text editor apply equally to Delphi or C++.

    But IDE menu Tools | Options and then scroll down to User Interface | Editor | Key mappings and the list of "out of the box" configurations does NOT include VIM.


  12. On 11/9/2023 at 11:14 AM, Roger Cigol said:

    And if you ARE using C++ builder version 12.0 does not quite deliver as much as you'd think. The much anticipated new tool chain is only present if a very limited "preview" form.

    Actually, having said this before the webinar, I feel I should correct myself: the Visual Assist (including basic refactoring) looks like a HUGE step forward.


  13. I am interested in the library information passed to the linker.

    With my simple hide show project (source code zip already included above) if I compile for Win64 for debugging and have no entry in the Project | Options | C++ Shared Options | Library path for any of the available levels of the tree (ie nothing in All configuration all platforms, nothing in All configurations - Windows 64, nothing in Debug configuration, nothing Debug configuration - Windows 64 and nothing in Release configuration and nothing in release configuration Win 64) if I then look at the text in the Console Output tab following the TwineCompile full build I can see the paths passed to the ILinker as parameters of the -L switch. These are as follows:

     

    -L.\Win64\Debug;

    "d:\program files (x86)\embarcadero\studio\22.0\lib\win64\release";

    "d:\program files (x86)\embarcadero\studio\22.0\lib\win64\release\psdk";

    C:\Users\Public\Documents\Embarcadero\Studio\22.0\Dcp\Win64;

    C:\Users\Public\Documents\Embarcadero\Studio\22.0\DCP\Win64\Debug;C:\Users\Public\Documents\Embarcadero\Studio\22.0\Dcp\Win64

     

    I don't think the second and third in this list should be "release" - I think they should be "debug". 

     

    But how to fix this? where do these come from? 

     

    If I open up the project file with a text editor and search for "release" there is no entry that is related to library file specification. so I don't think it is a problem with the project file.

     


  14. On 11/4/2023 at 3:29 PM, Harry Bego said:

    Just a hunch, following Remy's suggestion: is the form auto created? If auto, and if you also create a dynamic instance, you could be looking at another form than you think.

     

     

    Hi Harry, thanks for this: All help appreciated. In my case the form is NOT autocreated (I've removed it from the list in project | options). By displaying the value of "this" in my debug TEdit box and hitting a breakpoint I can confirm that I am on the correct instance of the form. Also the TEdit box clearly indicates that the form visible property is false - yet I am reading the TEdit box contents as it IS visible on the screen. This should never happen.

×