Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [CDO] CDO version/history/revision functionality([CDO] CDO version/history/revision functionality)
[CDO] CDO version/history/revision functionality [message #1002602] Fri, 18 January 2013 18:15 Go to next message
Andrew Whelan is currently offline Andrew Whelan
Messages: 69
Registered: October 2012
Location: Syracuse NY
Member
Hello,

I have some questions about the versioning/history functionality that comes with CDO. I am using a DBStore store with a MySQL database. What we are looking for is being able to recover a history of a certain object (CDOObject). We'll use a Company object for the sake of demonstration (the code below is for demonstration, it's not something that I'm running so if you see something that looks a little off....).

CDOTransaction transaction = cdoSession.openTransaction();
CDOResource resource = transaction
					.getOrCreateResource("/repo1"); 
Company company = CompanyFactory.eINSTANCE.createCompany();
Company.setName("Andrew's 1st company");
Company.setCity("Paris");
resource.getContents().add(company);
transaction.commit();



....the below code in some other function retrieves it and updates....

CDOTransaction transaction = cdoSession.openTransaction();
CDOResource resource = transaction.getOrCreateResource("/repo1");
EList<EObject> list = resource.getContents();
			
for(EObject e : list)
{
    CompanyImpl company = (CompanyImpl)e;
    If(company.getName().equals("Andrew's 1st company"))
    {
        company.setCity("Berlin");
    }
}
transaction.commit();


So now we should have 2 versions of this Company object in the database.
Say we make a couple of more updates to this Company record's city (2 more would make 4 versions). The CDOID will be the same and uniquely identifiers it (please let me know if this is not the case. I'm fairly certain I read that a CDOID is unique for a repository ("/repo1" in this case)).

At some time in the future when I am working with the latest version of the Company object (named in our example above "Andrew's 1st company"), I would like to get a list of the Company objects so I can display the historical information for each version in a separate screen. I looked through the CDORevision and CDOView documentation as well as the test code and am having a difficult time determining how to do this.
One of the things I did try was using the CDOQuery functionality:

CDOID cdoID = company.cdoID();
id = CDOIDUtil.getLong(cdoID);

//NOTE: I was able to retrieve a list of cdo_version values that were associated with 
//cdo_id = id. Looping through the cdo_version values, storing them in an int version
//variable, we have the following code snippet

       CDOQuery query = 
                transaction.createQuery("sql", 
                        "select cdo_id from <repository name>.company_model_company where cdo_version=:version and cdo_id=:id");
        query.setParameter("version", version);
        query.setParameter("id",id);

List<Company> companies = query.getResult(Company.class);    


Doing this I do get a company/CDOObject object back but it is always the latest version. The cdo_version value in the above query seems to have no effect. I think part of the problem would be that the past versions are not available through a read/write object view?
So the question I need answered is, how do I do what I am trying to do with CDO in the dialog above?

Thanks
-Andrew

PS: The correct way to go from a CDOObject to the deltas of the revisions would be good to know also. Again I saw that there was delta functionality but am not sure how to get there from a CDOObject that I have obtained from the database.

Re: [CDO] CDO version/history/revision functionality [message #1002699 is a reply to message #1002602] Sat, 19 January 2013 01:24 Go to previous messageGo to next message
Eike Stepper is currently offline Eike Stepper
Messages: 5481
Registered: July 2009
Senior Member
Am 19.01.2013 00:15, schrieb Andrew Whelan:
> Hello,
>
> I have some questions about the versioning/history functionality that comes with CDO. I am using a DBStore store with
> a MySQL database. What we are looking for is being able to recover a history of a certain object (CDOObject).
If by "recover" you mean "revert a certain object to a certain historical state" that can be problematic because
referential integrity is not easy to ensure. A former committer has left this controversial enhancement request:

260036: Provide "revert to the history revision" operation
https://bugs.eclipse.org/bugs/show_bug.cgi?id=260036

> We'll use a Company object for the sake of demonstration (the code below is for demonstration, it's not something that
> I'm running so if you see something that looks a little off....).
>
>
> CDOTransaction transaction = cdoSession.openTransaction();
> CDOResource resource = transaction
> .getOrCreateResource("/repo1"); Company company = CompanyFactory.eINSTANCE.createCompany();
> Company.setName("Andrew's 1st company");
> Company.setCity("Paris");
> resource.getContents().add(company);
> transaction.commit();
>
>
>
> ...the below code in some other function retrieves it and updates....
>
> CDOTransaction transaction = cdoSession.openTransaction();
> CDOResource resource = transaction.getOrCreateResource("/repo1");
> EList<EObject> list = resource.getContents();
>
> for(EObject e : list)
> {
> CompanyImpl company = (CompanyImpl)e;
> If(company.getName().equals("Andrew's 1st company"))
> {
> company.setCity("Berlin");
> }
> }
> transaction.commit();
>
>
> So now we should have 2 versions of this Company object in the database.
> Say we make a couple of more updates to this Company record's city (2 more would make 4 versions). The CDOID will be
> the same and uniquely identifiers it (please let me know if this is not the case. I'm fairly certain I read that a
> CDOID is unique for a repository ("/repo1" in this case)).
Totally correct. The CDOID is unique for a CDOObject in an IRepository. All CDORevisions (in both time and branch
dimensions) of this CDOObject share the same CDOID.

> At some time in the future when I am working with the latest version of the Company object (named in our example above
> "Andrew's 1st company"), I would like to get a list of the Company objects so I can display the historical information
> for each version in a separate screen.
That's possible but let's see if that (historical *CDOObjects* ) is really what you want...

> I looked through the CDORevision and CDOView documentation as well as the test code and am having a difficult time
> determining how to do this. One of the things I did try was using the CDOQuery functionality:
>
>
> CDOID cdoID = company.cdoID();
> id = CDOIDUtil.getLong(cdoID);
Note that this last statement makes your code kind of depend on the DBStore. The same is true for your SQL query below.

> //NOTE: I was able to retrieve a list of cdo_version values that were associated with //cdo_id = id. Looping through
> the cdo_version values, storing them in an int version
> //variable, we have the following code snippet
>
> CDOQuery query = transaction.createQuery("sql", "select cdo_id from <repository
> name>.company_model_company where cdo_version=:version and cdo_id=:id");
That looks like a NOOP: "select id where id=123"

> query.setParameter("version", version);
> query.setParameter("id",id);
>
> List<Company> companies = query.getResult(Company.class);
This query is bound to your transaction that you opened the query upon. It can only return CDOObjects that are valid in
this transaction (i.e. the latest state of the transaction's branch).

> Doing this I do get a company/CDOObject object back but it is always the latest version. The cdo_version value in the
> above query seems to have no effect.
Of course not, as we've seen above.

> I think part of the problem would be that the past versions are not available through a read/write object view?
Yes, that's part of the problem. A CDOTransaction (and all CDOQueries from this transaction) always return CDOObjects
that are "wired" with the latest CDORevisions from the transaction's branch.

> So the question I need answered is, how do I do what I am trying to do with CDO in the dialog above?
What dialog?

Let's clarify a few core concepts:

A CDOView or CDOTransaction provides *consistent* access to the CDOObject *graph* at a certain point in time in a
certain branch (e.g. the MAIN branch). You can navigate this graph through EMF API and will never leave this
time/branch. A CDOTransaction always "looks" at the latest time in its branch, while a pure CDOView can "wind back
time". Views and transactions are *revision selectors* , where a revision is the state of a *single* object for a
certain period of time in a certain branch.

With a transaction you can modify the object graph atomically. The transitions between two consecutive commits are
described by CDOCommitInfos. They're returned from transaction.commit() and can later be recreated, e.g., through
session.getCommitInfoManager() methods. It's often more convenient to use the newer CDOCommitHistory or CDOObjectHistory
APIs as returned by implementations of CDOCommitHistory.Provider. A commit history is an ordered collection of
CDOCommitInfos (also used by our CDOHistoryPage contribution to the Eclipse "History" view part). The availablity of
historical commit infos and the cost to recreate them may depend on the used IStore.

CDOCommitInfos contain/provide the *deltas* between two consecutive sets of CDORevisions (the *states* of relevant
objects before and after a commit). They know nothing about CDOViews, CDOTransactions or CDOObjects (other than their
CDOIDs). But you can always turn a CDOID into a CDOObject (and the associated object graph) by opening a CDOView at the
time and branch that's associated with the CDOCommitInfo (and all its deltas and resulting revisions). That's what we do
in our EMF Compare integration as you can see by double clicking a commit info in the CDOHistoryPage.

Sounds complex? Maybe others can put it simpler ;-)

>
> Thanks
> -Andrew
>
> PS: The correct way to go from a CDOObject to the deltas of the revisions would be good to know also.
In CDO 4.2:

CDOObjectHistory history = cdoObject.cdoHistory();

Note that a history is an IContainer<CDOCommitInfo>.


> Again I saw that there was delta functionality but am not sure how to get there from a CDOObject that I have obtained
> from the database.
See above. No need to depend on the/a database.

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Re: [CDO] CDO version/history/revision functionality [message #1003702 is a reply to message #1002699] Mon, 21 January 2013 15:42 Go to previous messageGo to next message
Andrew Whelan is currently offline Andrew Whelan
Messages: 69
Registered: October 2012
Location: Syracuse NY
Member
>> CDOQuery query = transaction.createQuery("sql", "select cdo_id from <repository
>> name>.company_model_company where cdo_version=:version and cdo_id=:id");
>That looks like a NOOP: "select id where id=123"

This looked kind of funky to me too. I was just basing it on the first two lines of code that I saw on the http://wiki.eclipse.org/Query_DB_Store_by_using_SQL

CDOQuery cdoQuery = transaction.createQuery("sql", "SELECT CDO_ID FROM CUSTOMER");

final List<Product1> products = cdoQuery.getResult(Product1.class);




I was assuming that the Company/Product1 discrepency was a mistake.
It was something to try.


So its seems that using timestamps to list versions of a CDOObject makes more sense than using cdo_version with this API?

In this case I would be looking to get all the timestamps associated with a CDOID for a resource I think?

I am using 4.1 now, so It looks like I am stuck with CDOCommitInfo objects (better than nothing).
Thanks for all of your help!
Re: [CDO] CDO version/history/revision functionality [message #1003835 is a reply to message #1003702] Mon, 21 January 2013 23:48 Go to previous messageGo to next message
Eike Stepper is currently offline Eike Stepper
Messages: 5481
Registered: July 2009
Senior Member
Am 21.01.2013 21:42, schrieb Andrew Whelan:
>>> CDOQuery query = transaction.createQuery("sql", "select cdo_id from <repository name>.company_model_company where
>>> cdo_version=:version and cdo_id=:id");
>> That looks like a NOOP: "select id where id=123"
>
> This looked kind of funky to me too. I was just basing it on the first two lines of code that I saw on the
> http://wiki.eclipse.org/Query_DB_Store_by_using_SQL
Thanks for the hint. I've changed the wiki page accordingly.

> So its seems that using timestamps to list versions of a CDOObject makes more sense than using cdo_version with this API?
That just depends on what you're trying to achieve.

> In this case I would be looking to get all the timestamps associated with a CDOID for a resource I think?
In order to do what?

> I am using 4.1 now, so It looks like I am stuck with CDOCommitInfo objects (better than nothing).
You could try to upgrade early ;-)

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Re: [CDO] CDO version/history/revision functionality [message #1005342 is a reply to message #1003835] Thu, 24 January 2013 18:01 Go to previous messageGo to next message
Andrew Whelan is currently offline Andrew Whelan
Messages: 69
Registered: October 2012
Location: Syracuse NY
Member
Please see the following code. Reference extends CDOObject. We have an Ecore model. We generate our code from the ecore model.
We use the CDO reflective migration to insert the CDO layer (CDOObject) between Reference and EObject.

The "id" parameter in the getReference method below is obtained in a call like the following:

 long id = CDOIDUtil.getLong(reference.cdoID());

where reference is an instance of a Reference object. Now I need to figure out how to get the correct timestamp value for original and subsequent records in the database so I can look at historical versions.

So lets say we use a CDOTransaction to commit a certain Reference object to the database. For a new object, what is the best way to obtain the correct timestamp to reflect when the object is created in the database. Would it be using cdo_created from the database? Or reference.cdoRevision().getTimeStamp()? Which value is this last one returning? reference.cdo_created or reference.cdo_revised?

How do I get the correct timestamp value to, in the future, return the correct Reference (CDOObject) from the following method for the originally created record? How do I get the correct value for a subsequent version that may not be the current version.

We do need a CDOObject even if we shouldn't be editing it. We just won't edit it. We need a CDOObject because Reference extends CDOObject.


 public Reference getReference(long id, long timestamp)
  {
      Reference ret = null;
              try
              {
                  CDOView audit = session.openView(timestamp);
                  CDOResource auditResource = audit.getResource("/repo1");
                  
                  if((auditResource!=null) && (auditResource.getContents()!=null))
                  {   
                      for(EObject e : auditResource.getContents())
                      {
                         Reference o = (Reference)e;   
                         if(id == CDOIDUtil.getLong(o.cdoID())){
                             ret = o;
                             break;
                         }
                      }
                  }
                 
              }
              catch(Exception e)
              {
                  e.printStackTrace();
              }
              return ret;
  }

Thanks! Sorry for being such a newbie.
Re: [CDO] CDO version/history/revision functionality [message #1005356 is a reply to message #1005342] Thu, 24 January 2013 23:35 Go to previous messageGo to next message
Eike Stepper is currently offline Eike Stepper
Messages: 5481
Registered: July 2009
Senior Member
Am 25.01.2013 00:01, schrieb Andrew Whelan:
> Please see the following code. Reference extends CDOObject. We have an Ecore model. We generate our code from the
> ecore model.
> We use the CDO reflective migration to insert the CDO layer (CDOObject) between Reference and EObject.
Ok. In case you don't generate your models for CDO you can get the CDOObject for a "legacy" EObject with
CDOUtil.getCDOObject(eObject).

>
> The "id" parameter in the getReference method below is obtained in a call like the following:
>
>
> long id = CDOIDUtil.getLong(reference.cdoID());
I already told you that something in your implementation is likely "not so good" if you feel the need to convert a CDOID
to a long integer value. You lose (storage) portability by doing so. All client-side (and the generic server-side) APIs
take/use CDOIDs directly. Only store implementations and their tests make assumptions about the internal CDOID format.

> where reference is an instance of a Reference object. Now I need to figure out how to get the correct timestamp value
> for original and subsequent records in the database so I can look at historical versions.
>
> So lets say we use a CDOTransaction to commit a certain Reference object to the database. For a new object, what is
> the best way to obtain the correct timestamp to reflect when the object is created in the database.
Directly after committing:

transaction.commit().getTimeStamp();

or at any time later:

object.cdoRevision().getTimeStamp();

The latter call gives you the time of the revision that's currently valid/visible in the view was created/committed.

> Would it be using cdo_created from the database?
Accessing the database directly should be the last resort only.

> Or reference.cdoRevision().getTimeStamp()? Which value is this last one returning? reference.cdo_created or
> reference.cdo_revised?
cdo_created.

> How do I get the correct timestamp value to, in the future, return the correct Reference (CDOObject) from the
> following method for the originally created record?
I don't seem to understand this question. For a given *CDOObject* (and with auduting enabled in the server) you can
access any *revision* with these methods:

CDOUtil.getRevisionByVersion(CDOObject, int)
CDOUtil.getRevisionByVersion(CDOObject, CDOBranch, int)

If you need the "CDOObjects" for these *revisions* you must open audit views for the time stamps of these revisions:

int version = 1;
CDOView audit = object.cdoView().getSession.openView(CDOUtil.getRevision(object, version).getTimeStamp());
CDOObject oldObject = audit.getObject(object);

> How do I get the correct value for a subsequent version that may not be the current version.

int version = 1 + i;
...

> We do need a CDOObject even if we shouldn't be editing it. We just won't edit it. We need a CDOObject because
> Reference extends CDOObject.
>
>
>
> public Reference getReference(long id, long timestamp)
> {
> Reference ret = null;
> try
> {
> CDOView audit = session.openView(timestamp);
> CDOResource auditResource = audit.getResource("/repo1");
> if((auditResource!=null) && (auditResource.getContents()!=null))
> { for(EObject e : auditResource.getContents())
No, that's bad.

> {
> Reference o = (Reference)e; if(id == CDOIDUtil.getLong(o.cdoID())){
That's worse ;-)

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper



> ret = o;
> break;
> }
> }
> }
> }
> catch(Exception e)
> {
> e.printStackTrace();
> }
> return ret;
> }
>
> Thanks! Sorry for being such a newbie.
Re: [CDO] CDO version/history/revision functionality [message #1007368 is a reply to message #1002602] Tue, 05 February 2013 11:14 Go to previous messageGo to next message
Andrew Whelan is currently offline Andrew Whelan
Messages: 69
Registered: October 2012
Location: Syracuse NY
Member
What is the best way to deterime how many revisions there are for a particular CDOID?

The following is not portable, as Eike has stated. Is there a portable way to do what I am trying to do here?
    long id = CDOIDUtil.getLong(referenceObject.cdoID());
    CDOQuery query = transaction.createQuery("sql",
                    "select count(*) from project_schema.reference_reference where cdo_id=:id");
    query.setParameter("id", id);
    query.setParameter("cdoObjectQuery", false);
    List<Long> count = query.getResult(Long.class);
Re: [CDO] CDO version/history/revision functionality [message #1007421 is a reply to message #1007368] Tue, 05 February 2013 14:17 Go to previous message
Eike Stepper is currently offline Eike Stepper
Messages: 5481
Registered: July 2009
Senior Member
Am 05.02.2013 17:14, schrieb Andrew Whelan:
> What is the best way to deterime how many revisions there are for a particular CDOID?
>
> The following is not portable, as Eike has stated. Is there a portable way to do what I am trying to do here?
> long id = CDOIDUtil.getLong(referenceObject.cdoID());
> CDOQuery query = transaction.createQuery("sql",
> "select count(*) from project_schema.reference_reference where cdo_id=:id");
> query.setParameter("id", id);
> query.setParameter("cdoObjectQuery", false);
> List<Long> count = query.getResult(Long.class);
You can ask for the version of the latest revision of an object by

a) If you have a view/transaction open: view.getObject(id).cdoRevision().getVersion() or

b) by using the revision manager: session.getRevisionManager().getRevision(id, mainBranch.getHead(), ...).getVersion()

If you only use one branch (the main branch) that version is equal to the number of revisions of that object.

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Previous Topic:EMF Ecore
Next Topic:[CDO] NPE exporting from CDO
Goto Forum:
  


Current Time: Fri Jul 25 16:00:14 EDT 2014

Powered by FUDForum. Page generated in 0.01857 seconds