View Issue Details

IDProjectCategoryView StatusLast Update
0004159JEDI VCL00 JVCL Componentspublic2008-10-29 06:20
ReporterOlegAssigned Toobones 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionunable to reproduce 
Product Version3.30 
Target VersionFixed in Version 
Summary0004159: TJvAppDBStorage does not allow to use section with empty name (i.e. to store data in "root" section of storage)
DescriptionFor TJvAppDBStorage in methods Read.../Write... if empty line specified for name of "section" (i.e. parameter "Path" does not contains characters '\' at all, or contains only one character '\' and at the very first poition of string), then TJvAppDBStorage component does not find (not capable to read) data from such "section". It is because TJvAppDBStorage (TJvCustomAppDBStorage) uses method DataSet.Locate(';some_key') to find the corresponding database record (for section='', key='some_key') - but it is a wrong way to search for record, which containing NULL in one of fields.

(though, TJvAppDBStorage successfully writes data to such a "section" - thereafter this data cannot be read).

The problem solved by the following changes in file "JvAppDBStorage.pas":
--------------------------------

function TJvCustomAppDBStorage.SectionExists(const Path: string; RestorePosition: Boolean): Boolean;
.....
  Result := DataSource.DataSet.Locate(SectionField, Path, [loCaseInsensitive]);
replaced with
  if (Path = '') then
    Result := DataSource.DataSet.Locate(SectionField, Variants.Null(), [loCaseInsensitive])
    else
    Result := DataSource.DataSet.Locate(SectionField, Path, [loCaseInsensitive]);


function TJvCustomAppDBStorage.ValueExists(const Section, Key: string; RestorePosition: Boolean): Boolean;
.....
  Result := DataSource.DataSet.Locate(Format('%s;%s', [SectionField, KeyField]), VarArrayOf([Section, Key]),
    [loCaseInsensitive]);
replaced with
  if (Section = '') then
    Result := DataSource.DataSet.Locate(Format('%s;%s', [SectionField, KeyField]), VarArrayOf([Variants.Null(), Key]),
      [loCaseInsensitive])
    else
    Result := DataSource.DataSet.Locate(Format('%s;%s', [SectionField, KeyField]), VarArrayOf([Section, Key]),
      [loCaseInsensitive]);
Additional InformationIt is represented correct that empty line can be specified for section name - it is implied that data stored in current ("root") section of storage. For example, component TJvAppRegistryStorage correctly reads and writes data in "root" (current) section (section with empty name).

Also it seems that name of a key always should be nonempty (though, for example, registry has a "default" value - which can be used for data with an empty name of key).
TagsNo tags attached.

Activities

obones

2007-06-20 03:24

administrator   ~0013494

Isn't this because your database automatically converts an empty string to 'NULL'?
I seem to remember some databases that make no difference between NULL and an empty string, and some others do.
I'm asking because your patch does not include the change to the WriteValue so that an empty string is changed to a NULL value.

Oleg

2007-06-20 05:49

reporter   ~0013498

Last edited: 2007-06-20 05:52

It is really that in my case "empty" and "NULL" strings are equivalent (when using Oracle + ODAC components). Patch described by me is tested and enough (for use section with empty name) only in this case.

If NULL and empty-strings are not equivalent (at database-fields level) - i do not exclude, that still any completions can be demanded.
After superficial acquaintance with TJvCustomAppDBStorage.WriteValue I have found that possibly
----------------------------------
  FSectionLink.Field.AsString := Section;
*** need to be replaced with ***
  if(Section.IsEmpty())
    FSectionLink.Field.Clear()
    else
    FSectionLink.Field.AsString := Section;
----------------------------------


hmmm... But now I am not assured, that all changes (described by me in this issue) will be enough.
Considering the last patch - possibly it will be enough for use a NULL field value for section with empty name.
But if it required to use for section with empty name a field with empty string (instead of NULL) the code should be remained in its present state.

Probably, for different cases (databases ...or database access components?) will be better to specify obviously necessity of use of empty strings or NULL (for example, through any additional property in TJvCustomAppDBStorage/TJvAppDBStorage); certainly if such check cannot be performed automatically (programmatically).

Oleg

2007-08-03 03:54

reporter   ~0013608

Is there other components or functions in which the designated problem (equivalence "empty string" and NULL) also matters? How the problem is solved in that cases?

Is it will be good such decision - add additional property like:
EmptyStrAsNull: Boolean, "interpret empty lines as NULL"?

If I correctly understand, the designated problem can appear in any JVCL + Oracle application, irrespective of used database access components (including BDE) - because "empty string" and NULL are considered identical at a database layer.

jfudickar

2007-08-06 14:09

developer   ~0013615

Could you create a small sample using your odac components.

I will have a look for it and your fix.

Greetings
Jens

obones

2007-10-12 07:15

administrator   ~0013925

Oleg, can you act on Jens' request?

obones

2008-02-21 06:30

administrator   ~0014247

Any news?

obones

2008-10-29 06:19

administrator   ~0014927

No answers, we cannot do anything.

Issue History

Date Modified Username Field Change
2007-06-19 23:28 Oleg New Issue
2007-06-20 03:24 obones Note Added: 0013494
2007-06-20 03:24 obones Status new => feedback
2007-06-20 05:49 Oleg Note Added: 0013498
2007-06-20 05:51 Oleg Note Edited: 0013498
2007-06-20 05:52 Oleg Note Edited: 0013498
2007-08-03 03:54 Oleg Note Added: 0013608
2007-08-06 14:09 jfudickar Note Added: 0013615
2007-10-12 07:15 obones Note Added: 0013925
2008-02-21 06:30 obones Note Added: 0014247
2008-10-29 06:19 obones Status feedback => resolved
2008-10-29 06:19 obones Resolution open => unable to reproduce
2008-10-29 06:19 obones Assigned To => obones
2008-10-29 06:19 obones Note Added: 0014927