How to code a simple versioning system? How to code a simple versioning system? sql sql

How to code a simple versioning system?


For God's sake, don't. You really don't want to go down this road.

Stop and think about the bigger picture for a moment. You want to keep earlier versions of documents, which means that at some point, somebody is going to want to see some of those earlier versions, right? And then they are going to ask, "What's the difference between version 3 and version 7"? And then they are going to say, "I want to roll back to version 3, but keep some of the changes that I put in version 5, ummm, ok?"

Version control is non-trivial, and there's no need to reinvent the wheel-- there are lots of viable version control systems out there, some of them free, even.

In the long run, it will be much easier to learn the API of one of these systems, and code a web front-end that offers your users the subset of features they are looking for (now.)

You wouldn't code a text editor for your users, would you?


You may get inspiration from there.


Concerning your comment :

As for a database structure, you may try this kind of structure (MySQL sql) :

CREATE TABLE `Users` (       `UserID` INT NOT NULL AUTO_INCREMENT     , `UserName` CHAR(50) NOT NULL     , `UserLogin` CHAR(20) NOT NULL     , PRIMARY KEY (`UserID`));CREATE TABLE `Groups` (       `GroupID` INT NOT NULL AUTO_INCREMENT     , `GroupName` CHAR(20) NOT NULL     , PRIMARY KEY (`GroupID`));CREATE TABLE `Documents` (       `DocID` INT NOT NULL AUTO_INCREMENT     , `GroupID` INT NOT NULL     , `DocName` CHAR(50) NOT NULL     , `DocDateCreated` DATETIME NOT NULL     , PRIMARY KEY (`DocID`)     , INDEX (`GroupID`)     , CONSTRAINT `FK_Documents_1` FOREIGN KEY (`GroupID`)                  REFERENCES `Groups` (`GroupID`));CREATE TABLE `Revisions` (       `RevID` INT NOT NULL AUTO_INCREMENT     , `DocID` INT     , `RevUserFileName` CHAR(30) NOT NULL     , `RevServerFilePath` CHAR(255) NOT NULL     , `RevDateUpload` DATETIME NOT NULL     , `RevAccepted` BOOLEAN NOT NULL     , PRIMARY KEY (`RevID`)     , INDEX (`DocID`)     , CONSTRAINT `FK_Revisions_1` FOREIGN KEY (`DocID`)                  REFERENCES `Documents` (`DocID`));CREATE TABLE `M2M_UserRev` (       `UserID` INT NOT NULL     , `RevID` INT NOT NULL     , INDEX (`UserID`)     , CONSTRAINT `FK_M2M_UserRev_1` FOREIGN KEY (`UserID`)                  REFERENCES `Users` (`UserID`)     , INDEX (`RevID`)     , CONSTRAINT `FK_M2M_UserRev_2` FOREIGN KEY (`RevID`)                  REFERENCES `Revisions` (`RevID`));

Documents is a logical container, and Revisions contains actual links to the files.Whenever a person updates a new file, create an entry in each of these tables, the one in Revisions containing a link to the one inserted in Documents.

The table M2M_UserRev allows to associate several users to each revision of a document.

When you update a document, insert only in Revisions, with alink to the corresponding Document. To know which document to link to, you may use naming conventions, or asking the user to select the right document.

For the file system architecture of your files, it really doesn't matter. I would just rename my files to something unique before they are stored on the server, and keep the user file name in the database. Just store the files renamed in a folder anywhere, and keep the path to it in the database. This way, you know how to rename it when the user asks for it. You may as well keep the original name given by the user if you are sure it will be unique, but I wouldn't rely on it too much. You may soon see two different revisions having the same name and one overwriting the other on your file system.


Database schema


To keep it exremely simple, I would choose the following database design. I'm separating the "file" (same as a filesystem file) concept from the "document" (the gerarchic group of documents) concept.

User entity:

  • userId
  • userName

Group entity:

  • groupId
  • groupName

File entity:

  • fileId (a sequence)
  • fileName (the name the user gives to the file)
  • filesystemFullPath
  • uploadTime
  • uploaderId (id of the uploader User)
  • ownerGroupId

Document entity:

  • documentId
  • parentDocumentId
  • fileId
  • versionNumber
  • creationTime
  • isApproved

Every time a new file is uploaded, a "File" record is created, and also a new "Document". If it's the first time that file is uploaded, parentDocumentId for that document would be NULL. Otherwise, the new document record would point to the first version.

The "isApproved" field (boolean) would handle the document being a draft or an approved revision.
You get the latest draft of a document simply ordering descending by version number or upload time.

Hints


From how you describe the problem, you should analyze better those aspects, before moving to database schema design:

  • which is the role of the "group" entity?
  • how are groups/users/files related?
  • what if two users of different groups try to upload the same document?
  • will you need folders? (probably you will; my solution is still valid, giving a type, "folder" or "document", to the "document" entity)

Hope this helps.