📜 ⬆️ ⬇️

DB. Directories. Live examples on globala 3


Part 1
Part 2

The word “Living,” in the title of the article, means that the mechanisms, code, and data from these articles are used in the working draft.

It may be interesting for you to look at some variants of database development solutions (structures, mechanisms).
')
The picture shows a piece of code that describes the global rules of the directory.

C R UD methods, in the course of their work, constantly refer to these rules to find out exactly what actions need to be performed.

Earlier, we stopped at the fact that we have the following globals:

View globals
^Dictionary("Vehicle","TransmissionType",1,0,"UpdateTime")="62086,66625" ^Dictionary("Vehicle","TransmissionType",1,0,"uid")=888 ^Dictionary("Vehicle","TransmissionType",2,0,"UpdateTime")="62086,66625" ^Dictionary("Vehicle","TransmissionType",2,0,"uid")=888 ^NameDictionaryElement(1,"partUri",0)="akp" ^NameDictionaryElement(1,"partUri",0,"UpdateTime")="62086,66625" ^NameDictionaryElement(1,"ru",0)="" ^NameDictionaryElement(1,"ru",0,"UpdateTime")="62086,66625" ^NameDictionaryElement(2,"partUri",0)="meh" ^NameDictionaryElement(2,"partUri",0,"UpdateTime")="62086,66625" ^NameDictionaryElement(2,"ru",0)="" ^NameDictionaryElement(2,"ru",0,"UpdateTime")="62086,66625" ^IndexDictionary("Vehicle","TransmissionType","name","partUri","akp",1)=1 ^IndexDictionary("Vehicle","TransmissionType","name","partUri","meh",2)=1 ^IndexDictionary("Vehicle","TransmissionType","name","ru","",1)=1 ^IndexDictionary("Vehicle","TransmissionType","name","ru","",2)=1 ^IndexDictionary("Vehicle","TransmissionType","uid",888,1)=1 ^IndexDictionary("Vehicle","TransmissionType","uid",888,2)=1 ^RefsDictionary(1,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""name"",""partUri"",""akp"",1)")=1 ^RefsDictionary(1,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""name"",""ru"","""",1)")=1 ^RefsDictionary(1,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""uid"",888,1)")=1 ^RefsDictionary(2,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""name"",""partUri"",""meh"",2)")=1 ^RefsDictionary(2,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""name"",""ru"","""",2)")=1 ^RefsDictionary(2,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""uid"",888,2)")=1 


Create global Ctrl + C / V
 set ^Dictionary("Vehicle","TransmissionType",1,0,"UpdateTime")="62086,66625" set ^Dictionary("Vehicle","TransmissionType",1,0,"uid")=888 set ^Dictionary("Vehicle","TransmissionType",2,0,"UpdateTime")="62086,66625" set ^Dictionary("Vehicle","TransmissionType",2,0,"uid")=888 set ^NameDictionaryElement(1,"partUri",0)="akp" set ^NameDictionaryElement(1,"partUri",0,"UpdateTime")="62086,66625" set ^NameDictionaryElement(1,"ru",0)="" set ^NameDictionaryElement(1,"ru",0,"UpdateTime")="62086,66625" set ^NameDictionaryElement(2,"partUri",0)="meh" set ^NameDictionaryElement(2,"partUri",0,"UpdateTime")="62086,66625" set ^NameDictionaryElement(2,"ru",0)="" set ^NameDictionaryElement(2,"ru",0,"UpdateTime")="62086,66625" set ^IndexDictionary("Vehicle","TransmissionType","name","partUri","akp",1)=1 set ^IndexDictionary("Vehicle","TransmissionType","name","partUri","meh",2)=1 set ^IndexDictionary("Vehicle","TransmissionType","name","ru","",1)=1 set ^IndexDictionary("Vehicle","TransmissionType","name","ru","",2)=1 set ^IndexDictionary("Vehicle","TransmissionType","uid",888,1)=1 set ^IndexDictionary("Vehicle","TransmissionType","uid",888,2)=1 set ^RefsDictionary(1,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""name"",""partUri"",""akp"",1)")=1 set ^RefsDictionary(1,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""name"",""ru"","""",1)")=1 set ^RefsDictionary(1,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""uid"",888,1)")=1 set ^RefsDictionary(2,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""name"",""partUri"",""meh"",2)")=1 set ^RefsDictionary(2,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""name"",""ru"","""",2)")=1 set ^RefsDictionary(2,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""uid"",888,2)")=1 




Global Directory Rules


Descriptions of all ontologies and types of reference books are stored in this global. Specific properties, characteristics, various types of indices are indicated. Calls for data verification functions are prescribed. A hierarchy of nested structures and so on. I will talk gradually and explain with examples. Over time, global rules will grow. The same thing happens in the process of project life: new types of reference books appear; new properties are added; service data processing functions change; programmed new functionality. The main purpose of this global is to keep in itself all the specifics of processing reference data .

Consider how the global rule ^ RuleDictionary works - let its indices mean the following:
  1. ontology
  2. directory type
  3. name of one of the CRUD methods
  4. indication of the type of action taken
  5. sequence of actions performed

I draw your attention to the fact that the indexes of the global rules, starting from the third, in other cases, may mean something else (when we come across this with an example - I will describe it in detail).

Print all the rules for ontology. SimpleOntology will execute the command:
zwrite ^ RuleDictionary ("SimpleOntology")
I remind you that “MONTOLOGY” is the name of the namespace.

 MONTOLOGY>zwrite ^RuleDictionary("SimpleOntology") ^RuleDictionary("SimpleOntology","SimpleType","create","check",10)="do clearPunctuationAndControlCharAllLang()" ^RuleDictionary("SimpleOntology","SimpleType","create","check",20)="do checkUniqueNameElementAllLang()" ^RuleDictionary("SimpleOntology","SimpleType","update","check",10)="do clearPunctuationAndControlCharAllLang()" ^RuleDictionary("SimpleOntology","SimpleType","update","check",20)="do checkUniqueNameElementAllLang()" MONTOLOGY> 

Create global Ctrl + C / V
 set ^RuleDictionary("SimpleOntology","SimpleType","create","check",10)="do clearPunctuationAndControlCharAllLang()" set ^RuleDictionary("SimpleOntology","SimpleType","create","check",20)="do checkUniqueNameElementAllLang()" set ^RuleDictionary("SimpleOntology","SimpleType","update","check",10)="do clearPunctuationAndControlCharAllLang()" set ^RuleDictionary("SimpleOntology","SimpleType","update","check",20)="do checkUniqueNameElementAllLang()" 


Let's take a closer look at what we brought out. As can be seen, there is one type of SimpleType in the ontology of SimpleOntology . There are no additional parameters in this directory (except default properties). The create method has two preprocessing and data validation functions. The same functions are defined for the update method. They are stored in global values. The sequence of actions (10, 20) may not necessarily be an integer. The sequence of execution goes from smaller to larger. The rules for SimpleOntology and SimpleType will be used for all simple default directories, in which there are only standard properties: names, update date and user uid .

Create


To understand how this works, consider the create method. For simplicity, we omit locks, transaction processing and various types of errors. Then we'll come back to this.

 #; -------------------------------------------------------------------------------------------------- #;   . #;         . #; -------------------------------------------------------------------------------------------------- create() #;     kill map("out") #;     t #;         create new t #;      set t("err")=$$check("create") #; ,    if t("err")<0 { quit t("err") } #;   "UpdateTime" do setProperty(t("ontology"),t("type"),"UpdateTime",$horolog,t("id"),"false") #;   "uid" do setProperty(t("ontology"),t("type"),"uid",t("uid"),t("id"),"true") set t("lang")="" for { #;    (     ) set t("lang")=$order(t("nameList",t("lang"))) #;   ,     quit:t("lang")="" #;      set t("name")=$get(t("nameList",t("lang"))) #;      do setName(t("ontology"),t("type"),t("lang"),t("name"),t("id")) } #;          do saveOntoAndTypeID #;         do saveElementPath #;         set map("out","id")=t("id") #;     kill map("in") #;     quit t("id") #; -------------------------------------------------------------------------------------------------- 

We see that no parameters are explicitly passed to the create () method. It is assumed that they are written to the local variable map , which must be defined before calling the method. In the variable map , we will use two main branches: map ("in") and map ("out") . A local variable differs from a global variable only in that it is not stored on disk and has a maximum size limit. In the rest - it is the same indexed as the global. It can be passed as a parameter to functions: $ order () , $ qsubscript () , $ qlength () , $ name () and others. In order not to produce many variables, and not to keep track of the scopes: it is enough to declare one variable new t . The variable t will be available anywhere in the create method, as well as in all other programs and subroutines that are called from it. The same can be said about the variable map . If inside some function called during the execution of create , new t is encountered - then this function will not have access to the variable t declared inside the create method. It will work with its variable t , which is inside its scope (elsewhere in the stack of variables). Perhaps the principles of the scope of variables in Caché I explained is not clear enough - ask questions in the comments.

check

Next, in t (“err”) we write the result of the $$ check (“create”) function. If all checks were successful, the function will return 0 , otherwise the result will be negative. Let's see how the $$ check () function and the methods called from it are arranged. I note that in these articles: method, function, subroutine - the words are synonyms. The private word private means that the method can be called only inside the Dictionary program.

 #; -------------------------------------------------------------------------------------------------- #;  . #;    ^RuleDictionary    . #; -------------------------------------------------------------------------------------------------- check(action)private #;     check new check #;        action set check=$case(action,"create":$$checkCreate(),"update":$$checkUpdate(),"delete":$$checkDelete(),:-1) #;   quit:check<0 check #;  "uid"      set t("uid")=$get(map("in","uid"),888) #; ,      "check",        if $data(^RuleDictionary(t("ontology"),t("type"),action,"check")) { #;  t("map")        set t("map")=$name(^RuleDictionary(t("ontology"),t("type"),action,"check")) } else { #;  t("map")              set t("map")=$name(^RuleDictionary("SimpleOntology","SimpleType",action,"check")) } set check("i")="" for { #;     set check("i")=$order(@t("map")@(check("i"))) #;   ,     quit:check("i")="" #;     xecute $get(@t("map")@(check("i"))) #;   ,     quit:check<0 } #;    quit check #; -------------------------------------------------------------------------------------------------- #;      . #;  id, ontology, type,   . #; -------------------------------------------------------------------------------------------------- checkCreate()private #;       st("ontology")=$get(map("in","ontology"),"") #;       quit:t("ontology")="" -1 #;        set t("type")=$get(map("in","type"),"") #;  ,      quit:t("type")="" -1 #;     set t("check")=$$checkNames() #;  ,     quit:t("check")<0 t("check") #;       set t("id")=$increment(^Dictionary("MaxID")) #;      ^Dictionary set t("path")=$name(^Dictionary(t("ontology"),t("type"),t("id"))) #;     quit 0 #; -------------------------------------------------------------------------------------------------- checkUpdate() quit 0 #; -------------------------------------------------------------------------------------------------- checkDelete() quit 0 #; -------------------------------------------------------------------------------------------------- #;     . #; -------------------------------------------------------------------------------------------------- checkNames()private #;          merge t("nameList")=map("in","nameList") #;   t("check")  #;         set t("check")=-1 set t("lang")="" for { #;    set t("lang")=$order(t("nameList",t("lang"))) #;   ,     quit:t("lang")="" #;      set t("name")=$get(t("nameList",t("lang")),"") #;    if t("name")="" { #;   t("check")  set t("check")=-1 #;    quit } else { #;  t("check")   ,     set t("check")=0 } } #;     quit t("check") #; -------------------------------------------------------------------------------------------------- 

At the very beginning of the check () method, we perform the mandatory check function for the current action. In our case, this is the checkCreate () function. Please note that the checkUpdate () and checkDelete () functions stubs are also present in the code — this is necessary for those who copy the Dictionary program themselves and compile it.

The checkCreate () subroutine checks for the ontology and directory type parameters in the input map. Inside checkNames () - the presence of names for each specified language is checked, with the obligatory condition of the presence of at least one language (it is impossible to create an element of the directory without a name in our system). In the same method, the identifier of the created directory element is generated by the safe function $ increment () . The current maximal element identifier of the directory (for any ontology and type) is stored in ^ Dictionary ("MaxID") .
all identifiers are unique, even within different reference books and ontologies
At the end of the checkCreate () method, we write the canonical name of the Global dictionary branch to the variable t (“path”) , in which the created directory element will be stored.

Pay attention to the term merge t ("nameList") = map ("in", "nameList") of the checkNames () method.
The merge command copies whole subtrees of indexed variables into each other, no matter whether they are defined as local or global.
The definition is taken from the book: Wolfgang Kirsten. Michael Iringer. Matthias Kühn Bernhard Rörig. Postrelational Caché DBMS 5. Object-oriented application development. Second edition. Moscow. Publisher BINOM . 2005. Translation by A. Maslov, K. Aristova. Page 116.

So, after running the checkCreate () method, the local variable t will contain the following important data:

Continue with the check () function. After checkCreate () is executed, we get the user's uid ( 888 is the default). Next, in the variable t (“map”) , we write the canonical name of the global rule thread containing the necessary verification functions for our ontology of the directory type and action. Since now, in the global ^ RuleDictionary , rules are defined only for ontology and the default type, the t ("map") will contain the canonical view of the ^ RuleDictionary ("SimpleOntology", "SimpleType", "create", "check" ) .

Let us examine in detail the line:
 set check("i")=$order(@t("map")@(check("i"))) 

I remind you that @ is an indirection operator. The initial value of the check ("i") = "" . So at the beginning of the loop, the string is equivalent to the following:
 set check("i")=$order(^RuleDictionary("SimpleOntology","SimpleType","create","check","")) 

That is, check (“i”) will be 10. If the syntax of the indirection operator causes questions, ask in the comments.

Now let's look at:
 xecute $get(@t("map")@(check("i"))) 

The xecute command executes a string of characters as a single-line subroutine.
Page 115, the same book.

That is, at the beginning of the cycle we will execute what is written in ^ RuleDictionary (“SimpleOntology”, “SimpleType”, “create”, “check”, 10) . And this:
 do clearPunctuationAndControlCharAllLang() 

After executing this subroutine, punctuation and service characters will be thrown from the names in all specified languages.

At the next loop iteration, we will execute the value ^ RuleDictionary (“SimpleOntology”, “SimpleType”, “create”, “check”, 20) . And this:
 do checkUniqueNameElementAllLang() 

This routine checks the uniqueness of the name for all specified languages. If at least one name is not unique, an error is written to the check variable defined in the check () method.

Subroutine code:
 #; -------------------------------------------------------------------------------------------------- clearPunctuationAndControlCharAllLang() set t("lang")="" for { #;     set t("lang")=$order(t("nameList",t("lang"))) quit:t("lang")="" #;           set t("nameList",t("lang"))=$$clearPunctuationAndControlChar($get(t("nameList",t("lang")),"")) } quit #; -------------------------------------------------------------------------------------------------- checkUniqueNameElementAllLang() set t("lang")="" for { #;     set t("lang")=$order(t("nameList",t("lang"))) quit:t("lang")="" #;    set t("name")=$get(t("nameList",t("lang")),"") #;   check     (0 -  ) set check=$$checkUniqueNameElement() #;     -    quit:check<0 } quit #; -------------------------------------------------------------------------------------------------- #;         . #; -------------------------------------------------------------------------------------------------- clearPunctuationAndControlChar(str) new t #;  t("str")     set t("str")="" #;      for t("i")=1:1:$length(str) { #;    set t("ch")=$extract(str,t("i")) if '((t("ch")?1P)||(t("ch")?1C)) { #;       set t("str")=t("str")_t("ch") } } #;    quit t("str") #; -------------------------------------------------------------------------------------------------- #; -------------------------------------------------------------------------------------------------- #;      ,   ,   . #;  ,   . #; -------------------------------------------------------------------------------------------------- checkUniqueNameElement() #;    set t("q")=0 set t("uniqueId")="" for { #; ,         #;   , ,   (  ) set t("uniqueId")=$order(^IndexDictionary(t("ontology"),t("type"),"name",t("lang"),$zconvert(t("name"),"l"),t("uniqueId"))) #;     quit:t("uniqueId")="" #; ,      #;     update if (t("uniqueId")'=t("id")) { #;  ,       set t("q")=-1 quit } } #;   quit t("q") #; -------------------------------------------------------------------------------------------------- 


Subroutines use new, for us, functions: $ zconvert () , $ length () , $ extract () ; as well as the pattern checking operator - the symbol "?" . Checking the presence of punctuation in the string and service characters can be done in another way, using built-in Kashev functions, but my project uses a character-by-character analysis method.

So, our method create () , successfully executed the line: set t ("err") = $$ check ("create") , and in the variable t - important service information is stored.

setProperty

Next, we set the “UpdateTime” and “uid” properties using the setProperty () function.

 #; -------------------------------------------------------------------------------------------------- #;  ,     . #;         . #; -------------------------------------------------------------------------------------------------- setProperty(ontology,type,property,value,id,index="true")private #;      ()    set ^Dictionary(ontology,type,id,0,property)=value #;    if index="true" { #;   set ^IndexDictionary(ontology,type,property,value,id)=1 #;      set ^RefsDictionary(id,$name(^|"MONTOLOGY"|IndexDictionary(ontology,type,property,value,id)))=1 } quit 0 #; -------------------------------------------------------------------------------------------------- 

$ horolog is the current date and time in Caché format. Please note that the “UpdateTime” property - we do not index (extreme parameter index = “false” ). In the same method for the first time appears global ^ RefsDictionary . The structure of its indices is simple:
  1. item id
  2. canonical name of the global index thread

That is, if necessary (for example, when deleting an element) - we will quickly get all the different sets of indices that contain the reference to this element.

setName

Next, we set the values ​​of the names using the setName () function.

 #; -------------------------------------------------------------------------------------------------- #;   ,     . #;  (  )   . #; -------------------------------------------------------------------------------------------------- setName(ontology,type,lang,value,id)private #;         set ^NameDictionaryElement(id,lang,0)=value #;   / set ^NameDictionaryElement(id,lang,0,"UpdateTime")=$horolog #;     set ^IndexDictionary(ontology,type,"name",lang,$zconvert(value,"l"),id)=1 #;    set ^RefsDictionary(id,$name(^|"MONTOLOGY"|IndexDictionary(ontology,type,"name",lang,$zconvert(value,"l"),id)))=1 quit 0 #; -------------------------------------------------------------------------------------------------- 

After that, we call the saveOntoAndTypeID function, which will write the ontology and the element type to the Global ^ IndexDictionary (“ID”, t (“id”)) branch. This is necessary in case, in the future, we need to find out by the reference element what type and ontology it belongs to. Next, the function saveElementPath in the same branch, write the path to the directory element.

 #; -------------------------------------------------------------------------------------------------- saveOntoAndTypeID set ^IndexDictionary("ID",t("id"),"ontology")=t("ontology") set ^RefsDictionary(t("id"),$name(^|"MONTOLOGY"|IndexDictionary("ID",t("id"),"ontology")))=1 set ^IndexDictionary("ID",t("id"),"type")=t("type") set ^RefsDictionary(t("id"),$name(^|"MONTOLOGY"|IndexDictionary("ID",t("id"),"type")))=1 quit #; -------------------------------------------------------------------------------------------------- saveElementPath set ^IndexDictionary("ID",t("id"),"path")=t("path") set ^RefsDictionary(t("id"),$name(^|"MONTOLOGY"|IndexDictionary("ID",t("id"),"path")))=1 quit #; -------------------------------------------------------------------------------------------------- 

Please note that all entries in the global RefsDictionary contain the explicit name of the namespace | "MONTOLOGY" | .If in the future, we will work with this global from another namespace, then we will always have the correct full path. Of course, even inside the Dictionary program itself , it is necessary to prescribe full paths (in case of calling methods from other namespaces). In my project, this is implemented by means of macros, however, for simplicity, for now I am providing simplified code.

All the code of the program Dictionary:
 #; -------------------------------------------------------------------------------------------------- #;   #; -------------------------------------------------------------------------------------------------- Dictionary #; -------------------------------------------------------------------------------------------------- #;   . #; -------------------------------------------------------------------------------------------------- retrieve(id,lang="ru",version=0) quit $get(^NameDictionaryElement(id,lang,version),"") #; -------------------------------------------------------------------------------------------------- #;      . #; -------------------------------------------------------------------------------------------------- retrieveListByIndex(ontology,type,index,value,str="",lang="ru") #;     ,       set str=$zconvert(str,"L") set id="" for { #;  ()    set id=$order(^IndexDictionary(ontology,type,index,value,id)) #;  ,        quit:id="" #;   set name=$$retrieve(id,lang) #;      str if $extract($zconvert(name,"L"),1,$length(str))=str { #;  (  ) write id_" "_name,! } } quit #; -------------------------------------------------------------------------------------------------- #;   . #;         . #; -------------------------------------------------------------------------------------------------- create() #;     kill map("out") #;     t #;         create new t #;      set t("err")=$$check("create") #; ,    if t("err")<0 { quit t("err") } #;   "UpdateTime" do setProperty(t("ontology"),t("type"),"UpdateTime",$horolog,t("id"),"false") #;   "uid" do setProperty(t("ontology"),t("type"),"uid",t("uid"),t("id"),"true") set t("lang")="" for { #;    (     ) set t("lang")=$order(t("nameList",t("lang"))) #;   ,     quit:t("lang")="" #;      set t("name")=$get(t("nameList",t("lang"))) #;      do setName(t("ontology"),t("type"),t("lang"),t("name"),t("id")) } #;          do saveOntoAndTypeID #;         do saveElementPath #;         set map("out","id")=t("id") #;     kill map("in") #;     quit t("id") #; -------------------------------------------------------------------------------------------------- #;  . #;    ^RuleDictionary    . #; -------------------------------------------------------------------------------------------------- check(action)private #;     check new check #;        action set check=$case(action,"create":$$checkCreate(),"update":$$checkUpdate(),"delete":$$checkDelete(),:-1) #;   quit:check<0 check #;  "uid"      set t("uid")=$get(map("in","uid"),888) #; ,      "check",        if $data(^RuleDictionary(t("ontology"),t("type"),action,"check")) { #;  t("map")        set t("map")=$name(^RuleDictionary(t("ontology"),t("type"),action,"check")) } else { #;  t("map")              set t("map")=$name(^RuleDictionary("SimpleOntology","SimpleType",action,"check")) } set check("i")="" for { #;     set check("i")=$order(@t("map")@(check("i"))) #;   ,     quit:check("i")="" #;     xecute $get(@t("map")@(check("i"))) #;   ,     quit:check<0 } #;    quit check #; -------------------------------------------------------------------------------------------------- #;      . #;  id, ontology, type,   . #; -------------------------------------------------------------------------------------------------- checkCreate()private #;       st("ontology")=$get(map("in","ontology"),"") #;       quit:t("ontology")="" -1 #;        set t("type")=$get(map("in","type"),"") #;  ,      quit:t("type")="" -1 #;     set t("check")=$$checkNames() #;  ,     quit:t("check")<0 t("check") #;       set t("id")=$increment(^Dictionary("MaxID")) #;      ^Dictionary set t("path")=$name(^Dictionary(t("ontology"),t("type"),t("id"))) #;     quit 0 #; -------------------------------------------------------------------------------------------------- checkUpdate() quit 0 #; -------------------------------------------------------------------------------------------------- checkDelete() quit 0 #; -------------------------------------------------------------------------------------------------- #;     . #; -------------------------------------------------------------------------------------------------- checkNames()private #;          merge t("nameList")=map("in","nameList") #;   t("check")  #;         set t("check")=-1 set t("lang")="" for { #;    set t("lang")=$order(t("nameList",t("lang"))) #;   ,     quit:t("lang")="" #;      set t("name")=$get(t("nameList",t("lang")),"") #;    if t("name")="" { #;   t("check")  set t("check")=-1 #;    quit } else { #;  t("check")   ,     set t("check")=0 } } #;     quit t("check") #; -------------------------------------------------------------------------------------------------- clearPunctuationAndControlCharAllLang() set t("lang")="" for { #;     set t("lang")=$order(t("nameList",t("lang"))) quit:t("lang")="" #;           set t("nameList",t("lang"))=$$clearPunctuationAndControlChar($get(t("nameList",t("lang")),"")) } quit #; -------------------------------------------------------------------------------------------------- checkUniqueNameElementAllLang() set t("lang")="" for { #;     set t("lang")=$order(t("nameList",t("lang"))) quit:t("lang")="" #;    set t("name")=$get(t("nameList",t("lang")),"") #;   check     (0 -  ) set check=$$checkUniqueNameElement() #;     -    quit:check<0 } quit #; -------------------------------------------------------------------------------------------------- #;         . #; -------------------------------------------------------------------------------------------------- clearPunctuationAndControlChar(str) new t #;  t("str")     set t("str")="" #;      for t("i")=1:1:$length(str) { #;    set t("ch")=$extract(str,t("i")) if '((t("ch")?1P)||(t("ch")?1C)) { #;       set t("str")=t("str")_t("ch") } } #;    quit t("str") #; -------------------------------------------------------------------------------------------------- #; -------------------------------------------------------------------------------------------------- #;      ,   ,   . #;  ,   . #; -------------------------------------------------------------------------------------------------- checkUniqueNameElement() #;    set t("q")=0 set t("uniqueId")="" for { #; ,         #;   , ,   (  ) set t("uniqueId")=$order(^IndexDictionary(t("ontology"),t("type"),"name",t("lang"),$zconvert(t("name"),"l"),t("uniqueId"))) #;     quit:t("uniqueId")="" #; ,      #;     update if (t("uniqueId")'=t("id")) { #;  ,       set t("q")=-1 quit } } #;   quit t("q") #; -------------------------------------------------------------------------------------------------- #;  ,     . #;         . #; -------------------------------------------------------------------------------------------------- setProperty(ontology,type,property,value,id,index="true")private #;      ()    set ^Dictionary(ontology,type,id,0,property)=value #;    if index="true" { #;   set ^IndexDictionary(ontology,type,property,value,id)=1 #;      set ^RefsDictionary(id,$name(^|"MONTOLOGY"|IndexDictionary(ontology,type,property,value,id)))=1 } quit 0 #; -------------------------------------------------------------------------------------------------- #;   ,     . #;  (  )   . #; -------------------------------------------------------------------------------------------------- setName(ontology,type,lang,value,id)private #;         set ^NameDictionaryElement(id,lang,0)=value #;   / set ^NameDictionaryElement(id,lang,0,"UpdateTime")=$horolog #;     set ^IndexDictionary(ontology,type,"name",lang,$zconvert(value,"l"),id)=1 #;    set ^RefsDictionary(id,$name(^|"MONTOLOGY"|IndexDictionary(ontology,type,"name",lang,$zconvert(value,"l"),id)))=1 quit 0 #; -------------------------------------------------------------------------------------------------- saveOntoAndTypeID set ^IndexDictionary("ID",t("id"),"ontology")=t("ontology") set ^RefsDictionary(t("id"),$name(^|"MONTOLOGY"|IndexDictionary("ID",t("id"),"ontology")))=1 set ^IndexDictionary("ID",t("id"),"type")=t("type") set ^RefsDictionary(t("id"),$name(^|"MONTOLOGY"|IndexDictionary("ID",t("id"),"type")))=1 quit #; -------------------------------------------------------------------------------------------------- saveElementPath set ^IndexDictionary("ID",t("id"),"path")=t("path") set ^RefsDictionary(t("id"),$name(^|"MONTOLOGY"|IndexDictionary("ID",t("id"),"path")))=1 quit #; -------------------------------------------------------------------------------------------------- 


Now we will delete all our globals, except the global rules ^ RuleDictionary :
 MONTOLOGY>kill ^Dictionary,^IndexDictionary,^NameDictionaryElement,^RefsDictionary MONTOLOGY> 

And create the first two elements of the directory:
 MONTOLOGY>kill map MONTOLOGY>set map("in","ontology")="Vehicle",map("in","type")="TransmissionType" MONTOLOGY>set map("in","nameList","ru")=" ,",map("in","nameList","partUri")="akp" MONTOLOGY>write $$create^Dictionary() 1 MONTOLOGY>kill map MONTOLOGY>set map("in","ontology")="Vehicle",map("in","type")="TransmissionType" MONTOLOGY>set map("in","nameList","ru")="",map("in","nameList","partUri")="meh" MONTOLOGY>write $$create^Dictionary() 2 MONTOLOGY> 

Print all our globals:
 MONTOLOGY>zwrite ^Dictionary,^IndexDictionary,^NameDictionaryElement,^RefsDictionary ^Dictionary("MaxID")=2 ^Dictionary("Vehicle","TransmissionType",1,0,"UpdateTime")="62948,47015" ^Dictionary("Vehicle","TransmissionType",1,0,"uid")=888 ^Dictionary("Vehicle","TransmissionType",2,0,"UpdateTime")="62948,47022" ^Dictionary("Vehicle","TransmissionType",2,0,"uid")=888 ^IndexDictionary("ID",1,"ontology")="Vehicle" ^IndexDictionary("ID",1,"path")="^Dictionary(""Vehicle"",""TransmissionType"",1)" ^IndexDictionary("ID",1,"type")="TransmissionType" ^IndexDictionary("ID",2,"ontology")="Vehicle" ^IndexDictionary("ID",2,"path")="^Dictionary(""Vehicle"",""TransmissionType"",2)" ^IndexDictionary("ID",2,"type")="TransmissionType" ^IndexDictionary("Vehicle","TransmissionType","name","partUri","akp",1)=1 ^IndexDictionary("Vehicle","TransmissionType","name","partUri","meh",2)=1 ^IndexDictionary("Vehicle","TransmissionType","name","ru","",1)=1 ^IndexDictionary("Vehicle","TransmissionType","name","ru","",2)=1 ^IndexDictionary("Vehicle","TransmissionType","uid",888,1)=1 ^IndexDictionary("Vehicle","TransmissionType","uid",888,2)=1 ^NameDictionaryElement(1,"partUri",0)="akp" ^NameDictionaryElement(1,"partUri",0,"UpdateTime")="62948,47015" ^NameDictionaryElement(1,"ru",0)="" ^NameDictionaryElement(1,"ru",0,"UpdateTime")="62948,47015" ^NameDictionaryElement(2,"partUri",0)="meh" ^NameDictionaryElement(2,"partUri",0,"UpdateTime")="62948,47022" ^NameDictionaryElement(2,"ru",0)="" ^NameDictionaryElement(2,"ru",0,"UpdateTime")="62948,47022" ^RefsDictionary(1,"^|""MONTOLOGY""|IndexDictionary(""ID"",1,""ontology"")")=1 ^RefsDictionary(1,"^|""MONTOLOGY""|IndexDictionary(""ID"",1,""path"")")=1 ^RefsDictionary(1,"^|""MONTOLOGY""|IndexDictionary(""ID"",1,""type"")")=1 ^RefsDictionary(1,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""name"",""partUri"",""akp"",1)")=1 ^RefsDictionary(1,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""name"",""ru"","""",1)")=1 ^RefsDictionary(1,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""uid"",888,1)")=1 ^RefsDictionary(2,"^|""MONTOLOGY""|IndexDictionary(""ID"",2,""ontology"")")=1 ^RefsDictionary(2,"^|""MONTOLOGY""|IndexDictionary(""ID"",2,""path"")")=1 ^RefsDictionary(2,"^|""MONTOLOGY""|IndexDictionary(""ID"",2,""type"")")=1 ^RefsDictionary(2,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""name"",""partUri"",""meh"",2)")=1 ^RefsDictionary(2,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""name"",""ru"","""",2)")=1 ^RefsDictionary(2,"^|""MONTOLOGY""|IndexDictionary(""Vehicle"",""TransmissionType"",""uid"",888,2)")=1 

, , , «UpdateTime» — — . ^IndexDictionary(«ID») ^RefsDictionary . ^Dictionary(«MaxID») .

Dictionary , , . - — - — .

. .

Thanks for attention.

I will be glad to questions, comments and suggestions.

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


All Articles