#1 2011-02-14 20:18:41

newfedra
Member
Registered: 2010-08-31
Posts: 14

How to check if field exists?

Hi.
I want to create a table and and to write to it records. Each record contains a string and an integer:

  Table:= TSynBigTableRecord.Create('MyFirstDB.DB','Tabel1');       
  TRY
    fdBases   := Table.AddField ('Base'    , tftWinAnsi, [tfoIndex] ); 
    fdNoOfBas := Table.AddField( 'NoOfBase', tftInt32  , [tfoIndex, tfoUnique] ); 
    Table.AddFieldUpdate;     





Tomorrow I may add a boolean field also:

  procedure TForm1.WriteExtraFields;
  Table:= TSynBigTableRecord.Create('MyFirstDB.DB','Tabel1'); 
  TRY
    Table.AddField ('bool', tftBoolean);
    Table.AddFieldUpdate;       





But forget tomorrow. I want to read the table today, while the third field was not yet added. But the program crashes here:

      { Retrieve fields }
      aStr:= ReadRec.GetFieldValue(fdBases);
      aInt:= ReadRec.GetFieldValue(fdNoOfBas);
      bol := ReadRec.GetFieldValue(fdBoolean);                <-------- Crash here.


How do I test if a field exists before reading it. There is something like: "if Table.FieldExists then DoStuff" ?







----------------------
EDIT:


I also have problems updating the current records when adding the new column:

procedure TForm1.WriteExtraFields;
VAR
   i: Integer;
   Table: TSynBigTableRecord;
   CurRec: TSynTableData;
   NewField: TSynTableFieldProperties;
begin
  { Create table }
  Table:= TSynBigTableRecord.Create('MyFirstDB.DB','Tabel1');
  TRY
    { Define an extra fields/column to be added to the table }
    NewField:= Table.AddField ('bool', tftBoolean);
    Table.AddFieldUpdate;

    for i:= 1 to 10 DO
     begin
      { GET CUR RECORD }
      CurRec.Init(Table.Table);
      CurRec:= Table.RecordGet(i);

      { EDIT RECORD }
      CurRec.SetFieldValue(NewField, TRUE);

      { WRITE BACK RECORD }
      if NOT Table.RecordUpdate(CurRec)                       <-------- Error here. It returns false
      then Log.AddError('Error adding record');             
     end;

    Table.UpdateToFile;
  FINALLY
    FreeAndNil(Table);                                                       
  END;
end;

Last edited by newfedra (2011-02-14 20:55:32)

Offline

#2 2011-02-15 10:07:05

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,067
Website

Re: How to check if field exists?

newfedra wrote:

How do I test if a field exists before reading it. There is something like: "if Table.FieldExists then DoStuff" ?

The field logic is implemented in the TSynTable class, which is in the Table property.

So you can use:

 if Table.Table.FieldFromName['FieldName']=nil then TheFieldDoesNotExists;

or even shorter to code:

 if Table.Table['FieldName']=nil then TheFieldDoesNotExists;
newfedra wrote:
      { WRITE BACK RECORD }
      if NOT Table.RecordUpdate(CurRec)                       <-------- Error here. It returns false 
      then Log.AddError('Error adding record');             
     end;

There is indeed an issue with updating TSynBigTableRecord content.
I'll fix it ASAP.
Thanks for the feedback.

Offline

#3 2011-02-15 11:02:50

newfedra
Member
Registered: 2010-08-31
Posts: 14

Re: How to check if field exists?

Thanks.
Where (which page) will be the update released?

Offline

#4 2011-02-15 12:51:06

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,067
Website

Re: How to check if field exists?

I'll notify you here as soon as it's ready.

I've already fixed some issues.

Here will be the published modifications:
    - fixed issue with Packing with no deleted but only updated records
    - fixed issue with TSynBigTableMetaData/TSynBigTableRecord updating and packing (and added corresponding regression tests)
    - AddField methods now return a boolean and no TSynTableFieldProperties, because these instances may be modified after a later AddFieldUpdate call

Some features (like packing or updating) where not tested for TSynBigTableMetaData/TSynBigTableRecord (whereas TSynBigTable and TSynBigTableString did have full test coverage).
Adding the tests did show me some problems in the 1.12a code.
They will be fixed ASAP.

Version will then be upgraded to 1.12b.

Offline

#5 2011-02-15 13:01:24

newfedra
Member
Registered: 2010-08-31
Posts: 14

Re: How to check if field exists?

Thanks.

There might be another issue. This time in the example provided by you in your blog. The record obtained using the variant code is not 1 but 0. The ID obtained with the non-variant code is 1. Maybe I have done something wrong. Also maybe there is another bug. Just take a look.


...
    Table.UpdateToFile;

    { VERIFY - READ RECORD: }
    ReadRec:= Table.RecordGet(aRecID);
    assert(ReadRec.ID= aRecID);

    { a) CLASSIC }
    s:= ReadRec.GetFieldValue(fdBases);
    Form1.lblString.caption:= s;
    Assert(s= ctTestStr);

    { b) VARINAT }
    Vari:= Table.VariantGet(aRecID);
    vID:= vari.ID;
    assert(vari.Base= ctTestStr);
    Assert(vID= aRecID);                              // <-- this fails
...


------------------------

I have also a suggestion.
The example (TestBigTable) provided by you is EXTREMELY difficult to follow because it is a function that contina lots of other functions. It will be nice if the example will be provided in a separated file and without that function-in-function structure.
smile

Offline

#6 2011-02-15 15:11:22

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,067
Website

Re: How to check if field exists?

There was a bug in VariantGet: the ID was indeed not properly set!
I've fixed it and added the corresponding test.

About TestBigTable, it's mainly a benchmark and a regression test.
So it was not written to be didactic, only be fast and cover most testing.
Some more simple sample is needed...
Let's finish the debugging then write it right...

Offline

#7 2011-02-15 16:15:03

newfedra
Member
Registered: 2010-08-31
Posts: 14

Re: How to check if field exists?

> Some more simple sample is needed...
Yes. It took me quite a while until a figure out basic stuff (how to create/add/update records, etc).
smile

Anyway, now that I figured out most of these basic stuffs, the library is great.
I will continue to test it. If I find other strange stuff I let you know.

Last edited by newfedra (2011-02-15 16:16:24)

Offline

#8 2011-02-15 16:20:27

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,067
Website

Re: How to check if field exists?

Thanks for the precise feedback!

I'll post here some updates, when all my tests will pass...

Offline

#9 2011-02-16 09:41:01

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,067
Website

Re: How to check if field exists?

That's it!

All identified issues have been corrected.

Packing and field record update will work as expected now.
Test coverage has been enhanced a lot, in order to avoid any regression about the issues you identified.

See http://synopse.info/fossil/info/a9d1df1d24

This was a major code correction, with some kind of deep rewrite of the updating mechanism.

For the end-user, the only change is that the AddField method won't return any TSynTableFieldProperties.

You'll have to code like this:

procedure TForm1.WriteExtraFields;
VAR
   i: Integer;
   Table: TSynBigTableRecord;
   CurRec: TSynTableData;
   NewField: TSynTableFieldProperties;
begin
  { Create table }
  Table:= TSynBigTableRecord.Create('MyFirstDB.DB','Tabel1');
  TRY
    { Define an extra fields/column to be added to the table }
    Table.AddField ('bool', tftBoolean);
    Table.AddFieldUpdate;
    NewField:= Table.Table['bool'];
    for i:= 1 to 10 DO
     (....)

Not only update will work as expected, but it will be MUCH faster with a huge amount of records.
For the speed benchmark and regression tests, I always uses at least 1,000,000 records.

Offline

#10 2011-02-16 10:57:01

newfedra
Member
Registered: 2010-08-31
Posts: 14

Re: How to check if field exists?

Wow. This is great . Thanks.

Offline

#11 2011-02-16 20:04:04

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,067
Website

Re: How to check if field exists?

Version 1.12b has been published (accessible from the same link)
See http://synopse.info/files/SynBigTable.zip

Offline

Board footer

Powered by FluxBB