📜 ⬆️ ⬇️

Docsvision database structure. From developer to developer!

Docsvision is not just a program, it is a platform that allows you to create your own solutions for electronic document management. The article of our colleague, Docsvision developer Dima Leikin, is intended specifically for developers of such solutions, to which we include partners of our company and employees of IT departments of our customer companies.

The material is divided into 5 logical parts - basic information about how the system is Docsvision. In addition, for developers who want to get us a job, this knowledge will be an additional plus.

image
')

In general, Docsvision is a client-server system, and the development of its solution comes down to the development of a set of cards (that is, a library).

The card is a basic concept in the Docsvision system. From the client’s point of view, the card is the UI that it sees when working with a document or task. From the point of view of the client programmer, a card is an object model that allows you to save information to a server. From the point of view of the server programmer, a card is a set of tables and stored procedures for accessing them. From the point of view of the card developer, a card is, above all, metadata. These metadata generate tables and stored procedures of the card, they contain attributes responsible for security, the way the card data is loaded onto the client, and many others.

Directory is another important concept. Directory is a card that exists in a single copy. For example, a staff directory, a directory of saved searches, a directory of roles, etc.
With the system itself comes several already written library cards. These are the Platform, ManagedPlatform, Takeoffice, Workflow, Backoffice libraries.
The first series of articles devoted to the basis of the system - the database Docsvision. Of course, this is not a complete description. Basically, the information is devoted to the principles of the system, so many details had to be sacrificed for the sake of simplicity.

Part 1. Sectional tables


When developing your library of cards using the CardManager utility, xml files are created with descriptions of the metadata for the cards. Then, using this metadata, tables and stored procedures are generated in the database, which allow working with these cards. Metadata is essentially a description of the type of card.

Briefly about metadata

In terms of metadata, a card is a set of sections. Section can be imagined as a table in the database, so it will be clearer. A section is a collection of fields. A field can be imagined as a column of this table. Section can be collectible, wooden or type struct. A section can have child sections; I write about this in more detail below.

Each card has a unique identifier - a card type identifier. Similarly, sections and fields have unique identifiers. Section identifiers are very important because at the moment the names of the partitioned tables are generated as follows: [dbo]. [Dvtable_ {id}], where id is the identifier of the section.

Beginners are often confused with types and instances. For example, in the table [dbo]. [Dvsys_instances], where information about the card instances is stored, in the field InstanceID (card instance identifier) ​​they start looking for the card type identifier for the document card. And they are very surprised when they do not find him there. (It should be noted here that in recent versions of Docsvision for directories, the identifier of the card is equal to the identifier of the type).

Section in terms of storing information in the database

From the point of view of information storage, a section is a DB table. The section field in the database corresponds to the column of the table. In addition to the columns for the fields, in each "sectional" table there are so-called system columns (RowID, InstanceID, ParentRowID, ParentTreeRowID, etc.)

InstanceID and RowID columns
RowID - unique identifier (Guid) of the section table table (primary key).
InstanceID - identifier (Guid) of the instance of the card to which this line belongs. Corresponds to the ID of the card from the table [dbo]. [Dvsys_instances].

You can imagine a sectional table as follows:
InstanceIDRowid...
CardId1RowId1...
CardId1Rowowd2...
CardId2Rowowd3...
CardId2Rowowd4...

The same table stores information about the section lines for all copies of cards of this type.

Representation of sections of different types in the database
Section can be collectible, wooden and type struct. The name of the sections originated, apparently, from the data structures for which these types of sections are intended to be stored.

Collection sections
The collection section is designed to store a collection of objects. From the point of view of the database, this means that among the rows of a sectional table there may be rows with the same InstanceID.

Sections like struct
A struct section is intended to hold a data structure. In essence, this is the same collection section, but only a collection can have a maximum of one object. From the point of view of the database, this means that in a sectional table there cannot be two rows with the same InstanceID. The columns of the sectional table correspond to the structure fields.

Wooden sections
The wooden section is designed for storing trees. Trees are stored as follows: there is a system column ParentTreeRowID, in which for each line is recorded the identifier of the parent line in the tree, or Guid.Empty, if there is no parent line. In the wooden section you can store several trees for one copy of the card, there is no restriction here.
When deleting a line in the tree, all its child lines will be deleted, this is provided by the stored procedures for deleting lines.

Child sections
Wood sections allow you to store a collection of children of the same type for an object. But what if we want to store a collection of child objects of another type? For this are child sections. The “classic” example of the parent and child sections is the sections of divisions and employees in the employee reference book. Each unit is associated with a collection of employees. In the database, it looks like this: in the section table for employees in the system column ParentRowID (not to be confused with ParentTreeRowID) the identifier of the parent unit is indicated.
Rowid
CompanyID1
CompanyID2

RowidParentRowID
EmployeeID1CompanyID1
EmployeeID2CompanyID1

For a sectional table of a child section, a foreign key is generated on the parent table (with the ParentRowID child on the RowID of the parent table) with cascade deletion. That is, for example, when deleting a unit, all its employees will be deleted.

Practical work

How can this knowledge be used in practice? Suppose we have a Docsvision database, and we want to see which employees are registered in the employee reference book. First we need to know the ID of the employees section of the employee directory. The easiest way, of course, is to look in CardManager or in xml, but if they are not at hand, it does not matter:

Find the identifier of the directory of employees:
select * from [dbo].[dvsys_carddefs] where Alias like '%Staff%' 

We get a list of its sections:
 select * from [dbo].[dvsys_sectiondefs] where CardTypeID = '6710B92A-E148-4363-8A6F-1AA0EB18936C' 

We see in the SectionTypeID field for the section with the Employees alias, the employee section identifier 'DBC8AE9D-C1D2-4D5E-978B-339D22B32482'. We make a request from the sectional table of employees:
 select * from [dbo].[dvtable_{DBC8AE9D-C1D2-4D5E-978B-339D22B32482}] 

The list of employees is in front of us. Now let's say we want to see what kind of employees there are in the unit called Test. Similarly, we find out the identifier of the division section and write:
 select Emp.* from [dvtable_{DBC8AE9D-C1D2-4D5E-978B-339D22B32482}] Emp join [dvtable_{7473F07F-11ED-4762-9F1E-7FF10808DDD1}] Company ON Emp.ParentRowID = Company.RowID where Company.Name = 'Test' 

Here we used the fact that the staff section is a subsidiary of the division section. Now we will try to derive the Test subdivision and all its subsidiaries (in the tree):
 ;WITH Companies (RowID, ParentTreeRowID, Name) AS ( SELECT Company.RowID, Company.ParentTreeRowID, Company.Name FROM [dvtable_{7473F07F-11ED-4762-9F1E-7FF10808DDD1}] Company WHERE Company.Name = 'Test' UNION ALL SELECT Company.RowID, Company.ParentTreeRowID, Company.Name FROM [dvtable_{7473F07F-11ED-4762-9F1E-7FF10808DDD1}] Company JOIN Companies ON Company.ParentTreeRowID = Companies.RowID ) SELECT RowID, ParentTreeRowID, Name FROM Companies 

Here we used the fact that the divisions section is a wooden section.

Part 2. A little more about the metadata


Xml with card metadata is an xml file with the Platform Library VersionedFile card metadata:

image

Metadata is essentially a type definition for card instances. Very often, the card is called both metadata and copies of cards in the database, which is somewhat confusing. When we talk about metadata, a card will always mean a card type, a card identifier - a card type identifier, etc.
The metadata specifies the name and ID of the card, its attributes, and the section tree. For each section, the name and identifier of the section, its attributes and fields are specified. For each field, the name and identifier of the field are given, as well as its type.
Among the attributes of the card is, first of all, note the attribute responsible for whether the card is a reference. Among the attributes of a section, the most important attribute is the type of section (collection, wood, or type of struct).
Child sections are defined in the xml file as follows. The element has a child element where elements for the child sections are specified. The child section, in turn, may also have child sections. Thus, the tree of sections turns out.

CardManager utility

To work with metadata in Docsvision, the CardManager developer utility is used. The utility allows you to automate the creation and editing of card metadata.

image
The screenshot is the CardManager utility with the Backoffice library open.


On the screenshot - Backoffice library staff metadata. Open the wooden section AlternativeHierarchy, designed to store user groups. It shows the child sections of Group and GrpViewFields, as well as the Name, Comments, AccountName and other fields.

Part 3. Links




Fields can be of different types, including links to lines (refid) and links to copies of cards (refcardid).
RowidMyReference
RowidId1

Rowid...
Id1...

In the case of a link to a row in the table cell, the identifier of the row to which this string refers is entered. But in which table to search for a row by this identifier? This is determined by the metadata of the field that is intended to store the reference (in the case in the figure, by the metadata of the MyReference field).
When storing a link to a card in a table cell, the instance ID of the InstanceID card from the table [dbo]. [Dvsys_instances] is written. The metadata indicates which type of card the link is stored.
RowidMyCardReference
RowidId1

InstanceIDCardTypeID...
Id1Type id...

Link Types Hard, Weak, Auto

The link to the card can be of type Hard, Weak, Auto.
Hard , or hard link, means the following: when the last hard link to the card is deleted, the card will be deleted.
Weak , or weak link, does not affect the removal of the card.
Auto - the automatic link also does not affect the removal of the card, but when the card is removed, the link itself will be reset.

Table [dbo]. [Dvsys_links]

For storing links, the table [dbo]. [Dvsys_links] is used. In this table, the link information is scattered across different sectional tables. Rasynchronization cannot happen here, since adding / deleting records to the table provides the same stored procedures that work with sectional fields.

The table has the following useful columns:

What are links for?

Links make the card a reuse component. For example, if you want a card created by you to contain a collection of files that support versioning, then it is enough to make a field with a link to the FileList card of the Backoffice system library.

Part 4. System tables and libraries


Basic system tables

[dbo]. [dvsys_globalinfo] - the table contains information about the version of the Docsvision database. This table has a useful Version field containing the current version of the database.
Sometimes it is required to update versions for all libraries to match the version of the database, and I don’t feel like immersing new versions of libraries into the database. To do this, there is the following method: see the version in [dbo]. [Dvsys_globalinfo] and then call the stored procedure:
 exec [dbo].[dvsys_help_set_version] @Version =   

Metadata tables:

Other important tables

Two tables are important for storing files:

The dvsys_files table stores information about the file, and dvsys_binaries contains its contents.
It is also important to mention that for card fields there is a fileId type. This type of field will store the file ID from the dvsys_files table.

Platform Library

Directory of folders
If you have ever opened Docsvision Navigator, then the first thing you saw was a folder and grid tree with a view of the cards contained in the folder. In fact, the folder contains not the cards themselves, but the labels on them.

Folder directory is the Platform library's FoldersCard directory, where information about folders is stored, as well as the folder labels on the cards. Folders are stored in the wooden section Folders.

Labels are stored in the child section of Shortcuts. In this section there are HardCardID and CardID fields. And that, and another field is a link to the card. The only difference is that the HardCardID field is a hard link, and the CardID link is an Auto type. Thus, labels for the same card can be located in different folders, and the card will be deleted when the last label with a hard link to it is deleted.

Folders can be of the following types: normal folders, virtual folders, delegate folders and system folders. Virtual folders are different in that they use a search query to return information about the labels contained in them. Delegate folders are essentially pointers to other folders. System folders are usually some special folders, such as the search results folder or the trash folder. Many system folders are invisible to the user. You can view the system folders as follows:
 select Name from [dbo].[dvtable_{FE27631D-EEEA-4E2E-A04C-D4351282FB55}] Folders where [Type] = 16 -- System 

Version File Card
There is a VersionedFile card in the Platform library. This card is useful when you need to store multiple versions of the same file. The card has a wooden section of Versions, which allows you to store a tree of versions of the file. In the Versions section there is a FileID field of type fileID, where the link to the file is stored. In the MainInfo section there is a useful CurrentID field (of type refid) containing a link to a version that is considered to be current.

Numbering card
The numbering card is used to issue numbers to documents and other cards.

Card Saved Views
The card is used to store information about user views - those views that are shown by the Docsvision Navigator grid.

Card Saved Searches
The card is used to store information about user searches.

Backoffice library

Species Reference
It so happened that the creators of the Backoffice library considered the division of cards into types insufficient, and decided within the library to specify the type of the card, adding a view to it. Let's say there is a document, and there is an incoming document - this is a document type. A species may have child species that inherit some of its features, and some have their own. So it turned out tree species. All these species are stored in the species directory.

Cards of the document, tasks, groups of tasks, coordination
These are the main work cards of the Docsvision system. They correspond to the main entities of the workflow. They provide a large number of different services and participate in different scenarios of work.

State Reference
The state directory stores the state machine for card states. When moving from state to state, operations are performed.

Role directory
The role directory stores role-playing information. In essence, this is a three-dimensional matrix of the role - state - available operations. UI directory allows you to see the cross section of this three-dimensional matrix.

Markup Reference
In the markup directory, you can customize the appearance of the card, add controls to it, subscribe to their events, define dynamic fields, and associate them with controls.

Script reference
The scripts directory allows you to write your own scripts for the cards.

Employee Handbook
The employee reference book stores employees and departments, as well as groups and roles.

Counterparty Handbook
The counterparty directory stores organizations and employees - counterparties.

Part 5. Search and Subsystem


Search and submission is not much different from each other. The main idea: using UI or using code to create a description of the search / presentation. According to this description, the server will generate a stored procedure that will return a selection with the results. Description of the search is stored in the directory of search queries, and views - in the directory of saved views. The search / view must have an identifier so that when it is called again, an existing stored procedure is called, which affects performance.

The view is what the user sees in the navigator grid. First, there is a system view (digest), which is used by default. Also, conventional views and views with paginated output of information (so-called keyset views) are distinguished. Presentation as its data source can use a regular folder, or search results, or something else. Search and views support parameters that are set at the time of the call, either by the user via the UI or programmatically. Search parameters can be specified as parameters (Me, Today, My Deputies and many others). Collectible options are allowed.

The definition of search and representations is essentially a small language with the syntax of xml, and this language supports many different possibilities. The system for generating stored procedures on the server is a translator from Xml to Sql.

The search subsystem supports 2 types of search - attribute and full-text . Full-text search allows you to search for cards or files containing a specific string. An attribute search allows you to impose conditions on the values ​​of the fields of the displayed cards. The condition on the field value can use operations equal, not equal, more, less, and others, depending on the type of field. Conditions can be combined with AND or OR. Thus, the tree of conditions turns out. When the stored procedure is generated, conditions are generated in the WHERE.

A similar approach is used in the submissions, since they, too, should not generally display all the cards. Unlike search, views support so-called computed fields. Generating a calculated field can be thought of as adding another expression to the list of a SELECT statement of the resulting sample of a stored procedure. The expressions for the calculated field resemble the expressions for the condition tree. In essence, this is the same tree, but instead of comparison operations, it most often uses arithmetic operations, as well as CASE WHEN expressions (resembling a switch in C #).

For simplicity, the sampling scheme in the representations can be represented as follows:
 SELECT     FROM   JOIN    WHERE  

In fact, of course, everything is more complicated. First, a view can contain more than one such sample, but several, and these samples are combined using UNION ALL. This can be useful to display different types of cards into one view. Secondly, in the page views, reading all the data for all pages from the database would lead to a significant decrease in performance, so the generator uses the corresponding magic from one sample to generate several stored procedures.

Views also provide advanced features that include the use of aggregations, concatenations, and the opening of wooden sections. Supports sorting for views. And the grouping is already done on the client.

In more detail, the search and presentation model can be considered in one of the future articles, and this block outlines basic information.

Source: https://habr.com/ru/post/233897/


All Articles