Strange experience with TJsonConfig.Clear

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Strange experience with TJsonConfig.Clear

Free Pascal - General mailing list
Hi,

I experienced some strange behaviour with TJSONConfig.Clear.
I'm using fpc 3.0.4 32-bit on Win10-64.
(While I do have fpc trunk as well, the program is a Lazaurs GUI
program and I don't like using Lazarus (trunk) in combination with fpc
trunk.)

I have a TJSONConfig that I use to store addresses.

var
  CFG: TJSONConfig
...
      Cfg.Filename:= Fn;
      Cfg.Clear;
      Cfg.Formatted := True;
      Cfg.JSONOptions := Cfg.JSONOptions + [joIgnoreTrailingComma];
...
   //write general info
      Cfg.SetValue(jpInfoCopyRight, Utf8Decode(ABook.Copyright));
   //write addresses, List is a TSTringList
     Cfg.SetValue(jpaPerson, List, True);


This creates a file like
  "AdresBoek" : {
    "Info" : {
      "CopyRight" : "Copyright (c) 2011 by Flying Sheep Inc. & Bart Broersma",
    },
    "Personen" : {
      "Persoon000" : {
        "Naam" : "Een",
        "Voornaam" : "äëï"
      },
  }
}

So far so good.

Now I simply run that code again and now I get:

  "AdresBoek" : {
    "Info" : {
      "CopyRight" : "Copyright (c) 2011 by Flying Sheep Inc. & Bart Broersma",
    },
    "Personen" : {
      "Persoon000" : {
        "Naam" : "Een",
        "Voornaam" : "äëï",
        "Naam" : "Een",
        "Voornaam" : "äëï"
    },
  }
}

It duplicates all entries for Persoon000 (and does that for all
following Keys in Personen) and will repeat that upon each run.
This of course sucks, because when I change e.g. "Naam", it still
writes the old value.
And since I don't write keys with empty values (if "Naam" is empty
string, it is not stored), I can no longer clear "Naam", because the
old value remains and will be read back.
Also the filesize grows to very huge very soon.


Now when I add a check in the code __after__ Cfg.Clear to see if I
still can read the entry with Cfg.GetValue, it is there.

   Cfg.Clear;
....
   //write general info
      if Cfg.GetValue(jpInfoCopyRight,'')<>'' then
writeln('Cfg.GetValue(jpInfoCopyRight) NOT empty');
     Cfg.SetValue(jpInfoCopyRight, Utf8Decode(ABook.Copyright));
   //write addresses, List,Persons,Def are TSTringList
          if Cfg.GetValue(jpaPerson, Persons, Def) then
            writeln('Cfg.GetValues ',jpaPerson,' = TRUE');
    Cfg.SetValue(jpaPerson, List, True);

Sure enough it ouputs:
Cfg.GetValue(jpInfoCopyRight) NOT empty
Cfg.GetValues /AdresBoek/Personen/Persoon000 = TRUE

Isn't TJSONConfig.Clear supposed to clear all contents?

The weirdness in this is:
- This only started to happen after unrelated code changes (the code
to save was not altered at all), before that I behaved as I expected.
- Why does it duplicate the values of Person0000, but not the value of
jpInfoCopyRight?
- When I move Cfg.Clear to the line below Cfg.JSONOptions :=
Cfg.JSONOptions + [joIgnoreTrailingComma], then it behaves normally
again.

The application is build with -Criot -gh -gt.
It raises no exceptions and no memory leaks are reported.

I was unable to reproduce the issue in a simple test program that just
writes values to a TJSONConfig.
(In fact I started out writing simple test programs reading and
writing TJSONConfig before trying to attempt to convince my
addressbook application to write to a TJSONConfig in the first place)

Before you ask: my app doesn't use threads.

Any thoughts on this?
--
Bart
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Strange experience with TJsonConfig.Clear

Michael Van Canneyt


On Sat, 23 Nov 2019, Bart via fpc-pascal wrote:

> Hi,
>
> I experienced some strange behaviour with TJSONConfig.Clear.
> I'm using fpc 3.0.4 32-bit on Win10-64.
> (While I do have fpc trunk as well, the program is a Lazaurs GUI
> program and I don't like using Lazarus (trunk) in combination with fpc
> trunk.)
>

[snip]

>
> I was unable to reproduce the issue in a simple test program that just
> writes values to a TJSONConfig.
> (In fact I started out writing simple test programs reading and
> writing TJSONConfig before trying to attempt to convince my
> addressbook application to write to a TJSONConfig in the first place)
>
> Before you ask: my app doesn't use threads.
>
> Any thoughts on this?

Without complet code hard to say.

Sounds like you don't clear the list with persons between runs, so persons
are added ?

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Strange experience with TJsonConfig.Clear

Free Pascal - General mailing list
In reply to this post by Free Pascal - General mailing list
On Sat, Nov 23, 2019 at 7:47 PM Bart <[hidden email]> wrote:

As I was afraid: User error!

Cfg.JSONOptions := Cfg.JSONOptions + [joIgnoreTrailingComma];
This forces a reload of the file (since Filename isn't empty at this point).

(B.t.w. fpc trunk raise an error :
An unhandled exception occurred at $00438A84:
EJSON: Duplicate object member: "Naam"
  $00438A84  TJSONDATA__DOERROR,  line 1388 of ./fcl-json/src/fpjson.pp
  $0043C593  TJSONOBJECT__DOADD,  line 3411 of ./fcl-json/src/fpjson.pp
  $0043C5CA  TJSONOBJECT__ADD,  line 3426 of ./fcl-json/src/fpjson.pp

That's better than screwing up the file ...
)

--
Bart
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal