#1 2012-10-22 14:57:28

h.hasenack
Member
From: Nijmegen, Netherlands
Registered: 2012-08-01
Posts: 173
Website

TRecordReference - risky busyness?

I noticed this in SQLite3Commons.pas:

  /// a reference to another record in any table in the database Model
  // - stored as an 32 bits unsigned integer (i.e. a pointer=TObject)
  // - type cast any value of TRecordReference with the RecordRef object below
  // for easy access to its content
  // - use TSQLRest.Retrieve(Reference) to get a record value
  // - don't change associated TSQLModel tables order, since TRecordReference
  // depends on it to store the Table type in its highest bits
  TRecordReference = type PtrUInt;

So this means when I have another table added to my model (which might be inserted before or after the referred table, depending on it's name or the loaded plugins), my TRecordReference fields get to be invalid, simply because during downtime my table order may have changed. Using part of the integer as a table index is kind-a awkward IMO. hmm

Anyway, this is pretty bad when building a plugin-based data model, as I cannot (and do not want to) guarantee that my tables are registered in the same order, or for that matter that they will still all be there once the app has been shutdown and restarted. Plugins may be (un)installed during downtime, causing the datamodel to change between sessions. Anyway, this should definitely NOT break my datamodel. (Well, at least not when a table that is not "used" by any record reference is removed/added)

Wouldnt it be much more sensible to have a "combined" link, similar to TMethod (ObjectInstancePointer,ProcPointer), where the 1st pointer points to the targeted class (or table) and the 2nd pointer points to the actual target record, or contains the record ID? Wouldn't it be a lot safer if it's  something like this:

  TSQLRecordReference=record
  case type of
    Unresolved:
      TargetRecordID:TSQLRecordID;
      TargetTableClassName:UTF8string;
   Resolved:
      TargetRecord:TSQLRecord
   end;      

It is probably not as efficient as an int32, but is surely a lot safer. smile

(BTW I didnt check the syntax of the record, but I'm pretty sure you understand what I mean).

Offline

#2 2012-10-22 16:16:34

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: TRecordReference - risky busyness?

The restriction is clearly stated in the doc.
It works safely if your order is fixed.

Such a record property could be used... but issue is th at there is no rtti generated for it by the compiler!

Offline

#3 2012-10-22 18:34:19

h.hasenack
Member
From: Nijmegen, Netherlands
Registered: 2012-08-01
Posts: 173
Website

Re: TRecordReference - risky busyness?

tongue D7 again sad

I guess using a object instead of record (thus not a TObject class!, but the old thingy from turbo pascal) would not fix this either... sigh.

What about an Int64, of which the 1st 4 bytes are a hash of the classname? yes, there could be a collision between class names, but what are the odds... (1:4G). Would that be an escape route?

( hmm gnargnar, I going to install D7, just to try it., hmm)

Last edited by h.hasenack (2012-10-22 18:41:49)

Offline

#4 2012-10-22 21:38:42

h.hasenack
Member
From: Nijmegen, Netherlands
Registered: 2012-08-01
Posts: 173
Website

Re: TRecordReference - risky busyness?

I've downloaded and tested D7.

OMG... when adding a "record type" property, GetPropInfo() just returns nil, when examing the proplist returned by GetProplist it just isn't there, it is simply skipped. That's just plain stupid.
Thus: the only way to "stream" objects including  record type  properties is using the DefineProperties solution like the one defined in TCOmponent.
argh - that's just so.. f. Incomplete in the D7 rtti.

Let's just hope the new property framework will provide a solution for this one too. It would certainly be a great enhancement if the TSQLRecordReference could be resolved in a bit cleaner way. Another solution might be to define it as a class or interface and add some special handling for it as rtti will be generated for class based properties.

Offline

#5 2015-07-03 23:45:09

Leslie7
Member
Registered: 2015-06-25
Posts: 248

Re: TRecordReference - risky busyness?

TRecordReference is a great addition to mORMot. By now it is stored as 64bit integer,  but the implementation remained  tied to  the index which makes it unusable in many situations.

Adding  a Table_ID class field to the TSQLRecord class and using that instead of the index should be a safe implementation.  Having a system table in the database storing the name of the tables with the Table_ID could be used to check at model creation  if the  Table_ID in the class definition is the same as in the database. If not there could be several options to handle  the situation like using the Table_ID  value from the db ...

Offline

#6 2015-07-04 06:23:01

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: TRecordReference - risky busyness?

We may maintain a list at TSQLModel level.
But it would need to change some a lot of code lines, which use directly shl/shr bit manipulation to compute the table index.

Could you create a ticket for this feature request?

Offline

Board footer

Powered by FluxBB