Although third-party vendors like GitHub sell wonderful version control software for Domino, for those of you strapped for cash, some of the new LotusScript classes added in ND6 provide a fairly easy way to design your own version control tool.
NotesNoteCollection allows you to obtain a handle on any notes in a database (data, design elements, ACL, etc.), based on specified criteria. NotesDXLExporter and NotesDXLImporter allow you to, respectively, export one or more notes to DXL and create notes by importing DXL into a database. Finally, the NotesStream class acts as temporary storage for the exported information. Combining these three classes, you can take periodic or on-demand snapshots of any design element and roll back to previous versions. NotesDXLExporter can also pipeline directly to NotesDXLImporter, which allows you to easily copy design elements from one database to another.
Create a database containing the following design elements.
- A script library to store version snapshot and rollback procedures, so that they can be called from anywhere in the database (code examples listed in the "See the code for this tip" link below).
- A design element record form to store information about the design elements under version control. The form should contain, at minimum, fields for the replica ID of the database containing the design element, the current note ID of the element, a name for the element (I recommend referencing the $Title item that all design elements contain) and the database's current server and file path. Other useful fields to track are the type of element (i.e., form, view, agent), names of current lock holders, the template from which the parent database inherits, the designer version most recently used to edit the element, etc. Add a button to this form that calls the CreateElementVersion procedure.
- A version record form to store the converted data for each version of a given design element. This form should contain the same fields as the first form, as well as fields to store the version number, documenter, timestamp and comment. To protect the stored versions, I recommend including a single "Continue = False" statement in the QueryOpen of the form; once a version document is created, it need never be opened. All necessary manipulation of version documents (i.e., rollback) can be performed from a view.
- An agent to populate design element records (code examples listed in the "See the code for this tip" link below).
- A view displaying documents created with the design element record form, sorted by the concatenation of the database replica ID field and note ID field. This view is used by the above agent to establish uniqueness.
- A view displaying documents created with the version record form with the same sorting. Embed this view on the design element record form, listing the above concatenation as the single category string, to display only the version history for the design element currently open. Include a button in this view to call the RollbackToVersion procedure.
- Additional views as desired sorting design element records by the various attributes you wish to track. I recommend including a button in all design element record views that allows a snapshot of multiple elements to be taken simultaneously. If you frequently have multiple developers working on the same project, I'd also recommend using this same approach to create check in/check out buttons that lock and unlock the design elements, in addition to just taking snapshots of them. This can be done by using the value of the Notes ID field to get a handle on the design element as a NotesDocument, then calling the Lock or UnLock method.
- You might also find it useful to add a checkbox field to the design element record form indicating whether periodic snapshots are enabled for a given element, and create an agent to grab, say, an hourly snapshot for each enabled element. Having the ability to roll back even when versions haven't been manually created can be a lifesaver, but will naturally eat up disk space in a hurry, so if you take this approach you may want to keep a distinction between on-demand snapshots and those periodically grabbed by the agent, and purge the latter at a regular interval.
I hope this information is useful for some of you. Enjoy!
Do you have comments on this tip? Let us know.