Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.

Public Report
Report From:    [ Add a report in this area ]  
Report #:  38957   Status: Closed
IVersionService VersionAtTime() returns incorrect value
Project:  C#Builder Build #:  10.0.2288.42451
Version:    10.0 Submitted By:   Andy Gray
Report Type:  Basic functionality failure Date Reported:  1/18/2007 3:22:38 PM
Severity:    Serious / Highly visible problem Last Updated: 3/20/2012 2:24:39 AM
Platform:    All platforms Internal Tracking #:   245091
Resolution: Inactive (Resolution Comments) Resolved in Build: : 11.0.2804.9245
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: None
Description
Unable to pick out a historical object for a given DateTime. Because VersionAtTime() returns the version at the end of the
interval rather than the beginning.



Also: It is not possible to determine when the Current object became valid. i.e. we do not know the time when the previous instance became invalid and the time when the Current version was created. Because TimeForVersion(CurrentVer) always returns Now().
TimeForVersion(CurrentVer +n) returns Now() too!

Also:
MaxSavedVersion always returns  -1. Until some data change on a Class instance and UpdateDB(thus new Version) after that the correct value is returned.
Steps to Reproduce:
Two Versioned Classes.
PersistenceMapper.SqlDatabaseConfig.UseTimeStampTable=true;
PersistenceMapper.SqlDatabaseConfig.UseTimeStampColumn=true;
PersistenceMapper.SqlDatabaseConfig.UseClockLog=true;
Generate Database
Manually edit the following two ECO tables to provide initial values (workaround for known bug)
Table ECO_LASTCLOCK {0 , 01.01.2007 00:00}
Table ECO_TIMESTAMP {0}

Set my system clock to 20/1/2007 0930
Create new object A, UpdateDatabase (0931)
Create new object B, UpdateDatabase (0932)
Set my system clock to 21/1/2007 0933
Edit object A, UpdateDatabase (0934)
Edit object B, UpdateDatabase (0935)
Set my system clock to 22/1/2007 0936
Edit object A, UpdateDatabase (0937)
Edit object B, UpdateDatabase (0938)

DateTime date = new DateTime(2007,01,20,17,00,0);
ClassA A_History = A.GetVersionForDateTime(A, date);
where:
Private ClassA GetVersionForDateTime(ClassA currentObj, DateTime someDateTime)
{
IVersionService ivs =(IVersionService)currentObj.AsIObject().ServiceProvider.GetEcoService(typeof(IVersionService));
int version = ivs.VersionAtTime(someDateTime);
IElement ie = ivs.GetVersion(version, currentObj.AsIObject());
return ie.AsObject as ClassA;
}

Likewise for ClassB.


ok, so the DateTime for which I attempt to retrieve historical objects is a few hours after the first two objects were created, but before the first edits took place. My system clock is now correctly set (24/1/2007).

VersionAtTime(20/1/2007 17:00) returns 3 for objects A and B. Actually I might have expected that to be a 2 as we have only created two objects so far and no edits? But it is consistent.
HOWEVER:
A.GetVersionForDateTime(A, date);
returns the version of A AFTER the first edit. I would expect it to return the original object as first created??!

B.GetVersionForDateTime(B, date);
returns object B as first created. This is what I would expect.

subsequently if date = 21/1/2007 17:00 the returned historical value of A is after the second edit, again, one version ahead of what I would expect. Version of B is correct. And so on...
Workarounds
Use the following workaround code in place of VerisonAtTime()

private int CorrectedVersionAtTime(IVersionService ivs, DateTime dt)
{
    int v = ivs.VersionAtTime(dt);

    // will return read-write version
    if(v == Int32.MaxValue) return v;

   // will return read-only version
   while ((ivs.TimeForVersion(v) > dt) && (v > 1))
   {

v--;
   }

   return v;
}
Attachment
None
Comments

None

Server Response from: ETNACODE01