logo

Saving New Versions on the Web

A project I worked on a while ago involved converting a client app to the web. One of the forms used Versioning to allow new versions to be saved.

Notes Versions Form Property

This doesn't work on the web. Instead I had to use a LotusScript WQS agent to mimic the feature. If a user pressed the Save New Version button a flag-field was set and the code saved a copy of the document as a response to itself, before going on to save as normal.

The code is something like this (where vThisDocument is the document context):

Dim vNewDocument as NotesDocument
Set vNewDocument = vThisDocument.CopyToDatabase( vThisDatabase )
Call vNewDocument.MakeResponse( vThisDocument )
Call vNewDocument.Save(True, True)

The strange part is that the behaviour is somewhat unexpected. Looking at this code you might expect it not to work. We're making a copy of the document context, so surely the prior version we save as a response is going to contain the current edits and new field values? Well, no. It seems that Domino actually makes a copy of the document that is held "on disk". Strange but true and a quirk by which this is made possible.

Anyway, I mention this because I thought it might be useful in dealing with yesterday's conundrum. Let's say we detect there's a possible conflict. How about we save the current document as a response, then set the SaveOptions field to "0" so as to abandon the save of the main document? A bit like a conflict, but not a conflict.

However, since I started writing this, I've realised something - it won't work. There's no way to save the current version of the document. You can't save it as a response for the same reason I mentioned above - it's the document held on disk that gets copied. Nor can you create a prior version response and then save the current document, as this will probably result in a save conflict anyway. Doh!

I thought about scrapping this entry when I realised (think before you blog Jake!) but thought I'd leave it here as a "how to create new version responses on the web". It took me a while to work it out, so it might save you some time one day.

The more I think about the problem of save conflicts the more confused I becoem and the more I think Notes has already got the best solution - try and merge the changes or create a response. The only trouble is dealing with the result. There are lots of things we can do to help, but they depend on the exact scenario. I don't think there's a one-size-fits-all solution to this.

Anyway, enjoy your weekends. If you get a minute give it a thought and see what you come up. Personally I won't get chance as I'm going to be on hands-n-knees all weekend laying hundreds of parquet tiles on my newly-dried concrete floor.

Comments

  1. Never ever use CopyToDatabase, it has bitten me so many times now. Create a new Document and use CopyAllItems. More info here:

    {Link}

    What is a real killer though:

    {Link}

    Apparently if you copy a document which was saved like 2 days ago to another database with CopyToDatabase, they modified datetime stays the same. So if you have a replication schedule on the target database of lets say every day, the document will not be replicated, because its too old.

    What is even better (happened here, took me 2 days to find it):

    Copy a document with copytodatabase to a target database in a cluster environment. Delete the copied document in the target database. The deletion stub is replicated immediately to the other cluster members. Now copy the same document again. It will get the same UNID in the target database again!!! But the modified date doesn't change, so the deletion stubs on the other cluster members are actually newer. Replicate and your document is gone.

    • avatar
    • Jake
    • Fri 10 Dec 2004 07:25

    So the fact that my original button works is due to a bug? Double doh!

    Never a dull day with Notes ;-)

  2. this is how it could work:

    dim s as New NotesSession

    Dim db1 as NotesDatabase

    Dim db2 as NotesDatabase

    Dim newDoc as NotesDocument

    Dim oldDoc as NotesDocument

    Dim newResponse as NotesDocument

    set db1 = s.currentdatabase

    set db2 = new NotesDatabase(db1.server, db1.filepath)

    set newDoc = s.documentcontext

    set oldDoc = db2.getdocumentbyuniqueid(newDoc.universalid)

    set newResponse = new NotesDocument(db2)

    call oldDoc.copyallitems(newResponse)

    call newResponse.makeresponse(oldDoc)

    call newResponse.save(true,true)

    set oldDoc = nothing

    set newResponse = nothing

    set db2 = nothing

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

    Typed that from memory, so syntax might not be accurate. The trick: Open the db twice and you can have two different handles. Worked in the compare changes db (see previous post). Feedback would be nice.

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

    Of course there is another way!!!!

    It includes to tweak with Domino's actions. You can do that with JS: Get the form element and change the action property to point to "?CreateDocument" instead of "?EditDocument&Sequ..."

    This way Domino would create a brand new document... If you have it's original UNID as a hidden field you then could easily do the trick since documentcontext and old document are 2 items. You would need to save the new document in code (to get the unid fixed) and use saveoptions=0 to avoid that the QS tries to save it a second time.

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

    Hth

    ;-) stw

  3. Hello Jake

    A word of advice about your parquet floor, you should put underlay before putting it down. It will save your parquet from moisture damage and splitting.I have worked construction since i was in my early teens before pursuing a career in programming and believe me i've seen the damage that can be caused by not using an underlay.If you should decide to use underlay here is the product i recommend I'm not sure if they sell it in the U.K . {Link}

  4. The only problem with Stephans code is that the most recent version contains the same values as the current version. Otherwise, it does the trick. If I resolve that one little issue, I'll post a response.

  5. I found something interesting and unexpected when trying to get Stephans code to work as expected.

    When the oldDoc above is created from the newDocs unid lookup, you would expect newDoc to be the modified document inbound from the browser and the oldDoc to be the document on disk. Not so. Testing with Version 6.5.0 with the above code running in a WQS agent, the following outputs produce identical values!

    <code>

    Set newDoc = s.documentcontext

    Messagebox(newdoc.plaintext(0))

    Set oldDoc = db2.GetDocumentByUNID(newDoc.universalid) ' despite what we would expect, oldDoc and newDoc are identical at this juncture.

    ' this leaves us seemingly no way to retrieve the original changes.

    Messagebox(olddoc.plaintext(0))

    </code>

    At this point, the only way I can see to preserve the prior version in its unedited state is to create a 'safe copy' on WQO, but I question whether that is even possible, and then if no changes are saved, you have a potentially unwanted document to deal with.

    As it stands, I'll take the little quirk if I get some degree of versioning over the web.

    • avatar
    • Tom
    • Tue 24 Jun 2008 09:53 AM

    It may be a long time since the last comment and it may be not straight to the discussion, but I found this page while searching for problems with CopyToDatabase.

    I have a database, where documents may get archived. I archived with CopyToDatabase. So far, everything went fine, since the original documents UNID was kept in a new document in the main database.

    Now, for a new type of document, I wanted to keep the UNID to avoid updating other documents too. So after using CopyToDatabase I changed the UniversalID. What happenend is, that the document became doubled. Instead of archiving 1 document, it created 2, one with the CopyToDatabase, the other after changing the UNID. I changed to code, using CopyAllItems, and it worked as expected.

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:


About This Page

Written by Jake Howlett on Fri 10 Dec 2004

Share This Page

# ( ) '

Comments

The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

More Content