📜 ⬆️ ⬇️

DB. Directories. Globals. Nested structures. Living examples

Picture to attract attention showing an example of the upcoming "nesting" camera with a parachute in a satchel.

Part 1
Part 2
Part 3

Last time we stopped at the fact that we have a create () method, which, based on the global rule ^ RuleDictionary, creates directory elements. We have analyzed the example of creating elements of a simple, one-level directory. Today, we will look at how nested structures can be created using our globals and methods.

In the program code , the transparent variables t and map were used, which are not explicitly passed to the methods, but are available inside them. I was told that this is not the best way to demonstrate the work, especially given that for most, the syntax of Caché Object Script is new. Therefore, before proceeding to the nested structures, we make some changes to the program.


Macros


Macros allow you to set pseudonyms (other names) to constants, global and local variables, individual pieces of code, and more. The advantage of using macros is that if you change the actual location of your data (the name of the namespace, global, etc.), you don’t need to change anything in the program code, you just need to change one macro (in the inc file), recompile the project, and everything will work with new names. Also, the use of macros can reduce the recording without losing comprehension. The macro is declared the service word #define , then the name of the macro is transmitted through the space, another space is indicated by what this macro means. Macros can contain other macros within themselves, the main thing is that they are defined earlier. Parameters can be passed to macros (macro parameters start with a % ).
')
#define defNameSpace "MONTOLOGY"

This macro creates an alias, instead of “MONTOLOGY” - now we can write $$$ defNameSpace . Three dollars means that the macro was created by the developer (not system). Despite the fact that $$$ defNameSpace contains more characters and less clarity than “MONTOLOGY ”, this macro will be very useful to us, as it will be used in other macros, and in the program code it will practically not be encountered.

Suppose we have the following dictionary.inc file

#;     #define defNameSpace "MONTOLOGY" #;    #define dData ^|$$$defNameSpace|Dictionary #;    #define dName ^|$$$defNameSpace|NameDictionaryElement #;    #define dIndex ^|$$$defNameSpace|IndexDictionary #;   #define dRefs ^|$$$defNameSpace|RefsDictionary #;    #define dMaxID $increment($$$dData("MaxID")) #;   #define dRule ^|$$$defNameSpace|RuleDictionary #;      #define dDTO ^|$$$defNameSpace|tmwOntology #;        #define getDTOin(%param,%def) $get($$$dDTO($job,"in",%param),%def) #;        #define setDTOproc(%param,%val) set $$$dDTO($job,"proc",%param)=%val #;        #define getDTOproc(%param,%def) $get($$$dDTO($job,"proc",%param),%def) #;        #define setDTOout(%param,%val) set $$$dDTO($job,"out",%param)=%val #;        #define getDTOout(%param,%def) $get($$$dDTO($job,"out",%param),%def) #;          #define getDTOname(%lang) $get($$$dDTO($job,"in","nameList",%lang)) 

Now, in order to access the global: ^ | "MONTOLOGY" | IndexDictionary in the program code, you can write just $$$ dIndex . Pay attention to the $$$ dMaxID macro: it performs an increment operation. The compiler will simply go through the entire Dictionary program and replace all the macros with what they actually mean. Perform a normal text replacement. Macro $$$ dDTO (dictionary Data Transfer Object) - we will use instead of the transparent variable map to transfer parameters between subroutines. $ job is a system variable, inside which the current process number is stored. That is, we assume that the global ^ | "MONTOLOGY" | tmwOntology , available under the $$$ dDTO macro, can simultaneously run several processes. Each of them will refer to its $$$ dDTO ($ job) index, and further the following service branches will be used:


Our globals, from past articles, inside the program code are available in the following macros:

For example, let's rewrite the first method of the Dictionary program using macros

Was (without macros):
 #; -------------------------------------------------------------------------------------------------- #;   #; -------------------------------------------------------------------------------------------------- Dictionary #; -------------------------------------------------------------------------------------------------- #;   . #; -------------------------------------------------------------------------------------------------- retrieve(id,lang="ru",version=0) quit $get(^NameDictionaryElement(id,lang,version),"") #; -------------------------------------------------------------------------------------------------- 

It became (with macros):
 #; -------------------------------------------------------------------------------------------------- #;    Dictionary.inc,   (inc) -      #include Dictionary #; -------------------------------------------------------------------------------------------------- #;   #; -------------------------------------------------------------------------------------------------- Dictionary #; -------------------------------------------------------------------------------------------------- #;   . #; -------------------------------------------------------------------------------------------------- retrieve(id,lang="ru",version=0) quit $get($$$dName(id,lang,version),"") #; -------------------------------------------------------------------------------------------------- 

Let's transform all the code of our program taking into account the use of macros and without the use of transparent variables.

Reformed Dictionary Program
 #; -------------------------------------------------------------------------------------------------- #;    Dictionary.inc,   (inc) -      #include Dictionary #; -------------------------------------------------------------------------------------------------- #;   #; -------------------------------------------------------------------------------------------------- Dictionary #; -------------------------------------------------------------------------------------------------- #;   . #; -------------------------------------------------------------------------------------------------- retrieve(id,lang="ru",version=0) quit $get($$$dName(id,lang,version),"") #; -------------------------------------------------------------------------------------------------- #;      . #; -------------------------------------------------------------------------------------------------- retrieveListByIndex(ontology,type,index,value,str="",lang="ru") #;     ,       set str=$zconvert(str,"L") set id="" for { #;  ()    set id=$order($$$dIndex(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 $$$dDTO($job,"out") #;     t #;         create new t #;      set t("err")=$$check("create") #; ,    if t("err")<0 { quit t("err") } st("ontology")=$$$getDTOin("ontology","") st("type")=$$$getDTOin("type","") st("id")=$$$getDTOproc("id","") #;   "UpdateTime" do setProperty(t("ontology"),t("type"),"UpdateTime",$horolog,t("id"),"false") #;   "uid" do setProperty(t("ontology"),t("type"),"uid",$$$getDTOin("uid",888),t("id"),"true") set t("lang")="" for { #;    (     ) set t("lang")=$order($$$dDTO($job,"in","nameList",t("lang"))) #;   ,     quit:t("lang")="" #;      set t("name")=$get($$$dDTO($job,"in","nameList",t("lang")),"") #;      do setName(t("ontology"),t("type"),t("lang"),t("name"),t("id")) } #;          do saveOntoAndTypeID(t("id"),t("ontology"),t("type")) #;         do saveElementPath(t("id"),$$$getDTOproc("path","")) #;         $$$setDTOout("id",t("id")) #;     kill $$$dDTO($job,"in") #;     kill $$$dDTO($job,"porc") #;     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 #; ,      "check",        if $data($$$dRule($$$getDTOin("ontology",""),$$$getDTOin("type",""),action,"check")) { #;  check("map")        set check("map")=$name($$$dRule($$$getDTOin("ontology",""),$$$getDTOin("type",""),action,"check")) } else { #;  check("map")              set check("map")=$name($$$dRule("SimpleOntology","SimpleType",action,"check")) } set check("i")="" for { #;     set check("i")=$order(@check("map")@(check("i"))) #;   ,     quit:check("i")="" #;     xecute $get(@check("map")@(check("i"))) #;   ,     quit:check<0 } #;    quit check #; -------------------------------------------------------------------------------------------------- #;      . #; -------------------------------------------------------------------------------------------------- checkCreate()private new t #;       quit:$$$getDTOin("ontology","")="" -1 #;  ,      quit:$$$getDTOin("type","")="" -1 #;     set t("check")=$$checkNames() #;  ,     quit:t("check")<0 t("check") #;       $$$setDTOproc("id",$$$dMaxID) #;      ^Dictionary $$$setDTOproc("path",$name($$$dData($$$getDTOin("ontology",""),$$$getDTOin("type",""),$$$getDTOproc("id","")))) #;     quit 0 #; -------------------------------------------------------------------------------------------------- checkUpdate() quit 0 #; -------------------------------------------------------------------------------------------------- checkDelete() quit 0 #; -------------------------------------------------------------------------------------------------- #;     . #; -------------------------------------------------------------------------------------------------- checkNames()private new t #;   t("check")  #;         set t("check")=-1 set t("lang")="" for { #;    set t("lang")=$order($$$dDTO($job,"in","nameList",t("lang"))) #;   ,     quit:t("lang")="" #;      set t("name")=$get($$$dDTO($job,"in","nameList",t("lang")),"") #;    if t("name")="" { #;   t("check")  set t("check")=-1 #;    quit } else { #;  t("check")   ,     set t("check")=0 } } #;     quit t("check") #; -------------------------------------------------------------------------------------------------- #;    . #; -------------------------------------------------------------------------------------------------- processingNames(function) new t set t("lang")="" for { #;     set t("lang")=$order($$$dDTO($job,"in","nameList",t("lang"))) quit:t("lang")="" #;        xecute "set "_$name($$$dDTO($job,"in","nameList",t("lang")))_"=$$"_function_"("""_$$$getDTOname(t("lang"))_""")" } quit #; -------------------------------------------------------------------------------------------------- checkUniqueNameElementAllLang() new t set t("check")=0 st("ontology")=$$$getDTOin("ontology","") st("type")=$$$getDTOin("type","") set t("lang")="" for { #;     set t("lang")=$order($$$dDTO($job,"in","nameList",t("lang"))) quit:t("lang")="" #;    set t("name")=$get($$$dDTO($job,"in","nameList",t("lang")),"") #;   t("check")     (0 -  ) st("check")=$$checkUniqueNameElement(t("ontology"),t("type"),t("lang"),t("name"),$$$getDTOproc("id","")) #;     -    quit:t("check")<0 } quit t("check") #; -------------------------------------------------------------------------------------------------- #;         . #; -------------------------------------------------------------------------------------------------- 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") #; -------------------------------------------------------------------------------------------------- #; -------------------------------------------------------------------------------------------------- #;       . #;      . #;        (     ). #;      ,   "."   . #; -------------------------------------------------------------------------------------------------- specialClearStr(str) new t set t("str")="",t("flag")="start",t("delim")="" for t("i")=1:1:$L(str) { set t("ch")=$extract(str,t("i")) ;#     set:t("ch")=$char(9) t("ch")=" " continue:(t("ch")?1C) if (t("flag")="start")&&`(t("ch")?1P) { set t("str")=t("ch"),t("flag")="word" } elseif t("flag")="word" { if `(t("ch")?1P) { set t("str")=t("str")_t("ch") } else { set t("delim")=t("ch"),t("flag")="delim" } } elseif t("flag")="delim" { if (t("ch")?1P) { set:t("ch")`=" " t("delim")=t("ch") } else { set t("str")=t("str")_t("delim")_t("ch"),t("flag")="word",t("delim")="" } } } set:t("delim")="." t("str")=t("str")_t("delim") quit t("str") #; -------------------------------------------------------------------------------------------------- #; -------------------------------------------------------------------------------------------------- #;      ,   ,   . #;  ,   . #; -------------------------------------------------------------------------------------------------- checkUniqueNameElement(ontology,type,lang,name,id) new t #;    set t("q")=0 set t("uniqueId")="" for { #; ,         #;   , ,   (  ) set t("uniqueId")=$order($$$dIndex(ontology,type,"name",lang,$zconvert(name,"l"),t("uniqueId"))) #;     quit:t("uniqueId")="" #; ,      #;     update if (t("uniqueId")`=id) { #;  ,       set t("q")=-1 quit } } #;   quit t("q") #; -------------------------------------------------------------------------------------------------- #;  ,     . #;         . #; -------------------------------------------------------------------------------------------------- setProperty(ontology,type,property,value,id,index="true")private #;      ()    set $$$dData(ontology,type,id,0,property)=value #;    if index="true" { #;   set $$$dIndex(ontology,type,property,value,id)=1 #;      set $$$dRefs(id,$name($$$dIndex(ontology,type,property,value,id)))=1 } quit 0 #; -------------------------------------------------------------------------------------------------- #;   ,     . #;  (  )   . #; -------------------------------------------------------------------------------------------------- setName(ontology,type,lang,value,id)private #;         set $$$dName(id,lang,0)=value #;   / set $$$dName(id,lang,0,"UpdateTime")=$horolog #;     set $$$dIndex(ontology,type,"name",lang,$zconvert(value,"l"),id)=1 #;    set $$$dRefs(id,$name($$$dIndex(ontology,type,"name",lang,$zconvert(value,"l"),id)))=1 quit 0 #; -------------------------------------------------------------------------------------------------- saveOntoAndTypeID(id,ontology,type) set $$$dIndex("ID",id,"ontology")=ontology set $$$dRefs(id,$name($$$dIndex("ID",id,"ontology")))=1 set $$$dIndex("ID",id,"type")=type set $$$dRefs(id,$name($$$dIndex("ID",id,"type")))=1 quit #; -------------------------------------------------------------------------------------------------- saveElementPath(id,path) set $$$dIndex("ID",id,"path")=path set $$$dRefs(id,$name($$$dIndex("ID",id,"path")))=1 quit #; -------------------------------------------------------------------------------------------------- 

In the program listing, the symbol 'was replaced with the symbol ' - this is necessary for a more beautiful display of the code. In the case of copying the program code in Caché, it is necessary to make a reverse replacement: replace all the characters with

Converted global rules:

 MONTOLOGY>zwrite ^RuleDictionary("SimpleOntology") ^RuleDictionary("SimpleOntology","SimpleType","create","check",10)="do processingNames(""clearPunctuationAndControlChar"")" ^RuleDictionary("SimpleOntology","SimpleType","create","check",20)="s check=$$checkUniqueNameElementAllLang()" ^RuleDictionary("SimpleOntology","SimpleType","update","check",10)="do processingNames(""clearPunctuationAndControlChar"")" ^RuleDictionary("SimpleOntology","SimpleType","update","check",20)="s check=$$checkUniqueNameElementAllLang()" MONTOLOGY> 

Create Global Ctrl + C / V
 set ^RuleDictionary("SimpleOntology","SimpleType","create","check",10)="do processingNames(""clearPunctuationAndControlChar"")" set ^RuleDictionary("SimpleOntology","SimpleType","create","check",20)="s check=$$checkUniqueNameElementAllLang()" set ^RuleDictionary("SimpleOntology","SimpleType","update","check",10)="do processingNames(""clearPunctuationAndControlChar"")" set ^RuleDictionary("SimpleOntology","SimpleType","update","check",20)="s check=$$checkUniqueNameElementAllLang()" 


Perform global cleanup (except global rules) and insert the first two directory elements, like last time , to make sure that we never made any mistakes when switching to macros and avoiding transparent variables.

Check the converted program Dictionary
Remove all our globals, except the global rules ^ RuleDictionary :
 MONTOLOGY>kill ^Dictionary,^IndexDictionary,^NameDictionaryElement,^RefsDictionary MONTOLOGY> 

Create the first two elements of the directory:
 MONTOLOGY>kill ^tmwOntology($job) MONTOLOGY>set ^tmwOntology($job,"in","ontology")="Vehicle",^tmwOntology($job,"in","type")="TransmissionType" MONTOLOGY>set ^tmwOntology($job,"in","nameList","ru")=" ,",^tmwOntology($job,"in","nameList","partUri")="akp" MONTOLOGY>write $$create^Dictionary() 1 MONTOLOGY>kill ^tmwOntology($job) MONTOLOGY>set ^tmwOntology($job,"in","ontology")="Vehicle",^tmwOntology($job,"in","type")="TransmissionType" MONTOLOGY>set ^tmwOntology($job,"in","nameList","ru")="",^tmwOntology($job,"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")="62968,77638" ^Dictionary("Vehicle","TransmissionType",1,0,"uid")=888 ^Dictionary("Vehicle","TransmissionType",2,0,"UpdateTime")="62968,77664" ^Dictionary("Vehicle","TransmissionType",2,0,"uid")=888 ^IndexDictionary("ID",1,"ontology")="Vehicle" ^IndexDictionary("ID",1,"path")="^|""MONTOLOGY""|Dictionary(""Vehicle"",""TransmissionType"",1)" ^IndexDictionary("ID",1,"type")="TransmissionType" ^IndexDictionary("ID",2,"ontology")="Vehicle" ^IndexDictionary("ID",2,"path")="^|""MONTOLOGY""|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")="62968,77638" ^NameDictionaryElement(1,"ru",0)="" ^NameDictionaryElement(1,"ru",0,"UpdateTime")="62968,77638" ^NameDictionaryElement(2,"partUri",0)="meh" ^NameDictionaryElement(2,"partUri",0,"UpdateTime")="62968,77664" ^NameDictionaryElement(2,"ru",0)="" ^NameDictionaryElement(2,"ru",0,"UpdateTime")="62968,77664" ^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 

As you can see, these globals are different from these , only the value of "UpdateTime" . Changes to the Dictionary program can be considered successful.


Nested structures


Consider the simplest example of nested directory structures. Suppose that the ontology of the Vehicle contains the Make reference book, inside of which the Model reference book (vehicle makes and models) is contained. We describe these directories in our global rule ^ RuleDIctionary . For convenience, we will create a program InitRuleDic which will initialize our global rules. We also write the rules for reference books and ontology by default. Let me remind you that instead of ^ RuleDictionary , inside programs, the abbreviated $$$ dRule entry is now available to us .

 #; ------------------------------------------------------------------------------------------------------------ #include Dictionary #; ------------------------------------------------------------------------------------------------------------ InitRuleDic #; ------------------------------------------------------------------------------------------------------------ kill $$$dRule set $$$dRule("SimpleOntology","SimpleType","create","check",10)="do processingNames(""clearPunctuationAndControlChar"")" set $$$dRule("SimpleOntology","SimpleType","create","check",20)="s check=$$checkUniqueNameElementAllLang()" set $$$dRule("SimpleOntology","SimpleType","update","check",10)="do processingNames(""clearPunctuationAndControlChar"")" set $$$dRule("SimpleOntology","SimpleType","update","check",20)="s check=$$checkUniqueNameElementAllLang()" set $$$dRule("Vehicle","Make","property","lastId")="otherId" set $$$dRule("Vehicle","Make","property","lastId","index")="true" set $$$dRule("Vehicle","Make","create","check",10)="do processingNames(""specialClearStr"")" set $$$dRule("Vehicle","Make","create","check",20)="s check=$$checkUniqueNameElementAllLang()" set $$$dRule("Vehicle","Make","create","check",50)="s check=$$checkUniqueParamElement(""lastId"",""Vehicle"",""Make"")" set $$$dRule("Vehicle","Make","update","check",10)="do processingNames(""specialClearStr"")" set $$$dRule("Vehicle","Make","update","check",20)="s check=$$checkUniqueNameElementAllLang()" set $$$dRule("Vehicle","Make","update","check",50)="s check=$$checkUniqueParamElement(""lastId"",""Vehicle"",""Make"")" set $$$dRule("Vehicle","Model","parent")="Make" set $$$dRule("Vehicle","Model","property","parentId")="parent" set $$$dRule("Vehicle","Model","property","parentId","index")="true" set $$$dRule("Vehicle","Model","property","lastId")="otherId" set $$$dRule("Vehicle","Model","property","lastId","index")="true" set $$$dRule("Vehicle","Model","create","check",15)="do processingNames(""specialClearStr"")" set $$$dRule("Vehicle","Model","create","check",20)="s check=$$checkUniqueNameElementAllLang(""true"")" set $$$dRule("Vehicle","Model","create","check",50)="s check=$$checkUniqueParamElement(""lastId"",""Vehicle"",""Model"")" set $$$dRule("Vehicle","Model","update","check",15)="do processingNames(""specialClearStr"")" set $$$dRule("Vehicle","Model","update","check",20)="s check=$$checkUniqueNameElementAllLang(""true"")" set $$$dRule("Vehicle","Model","update","check",50)="s check=$$checkUniqueParamElement(""lastId"",""Vehicle"",""Model"")" zwrite $$$dRule quit #; ------------------------------------------------------------------------------------------------------------ 

Let's take a closer look at our global rules. In the Make directory, the lastId property appeared . This is the ID of the reference item in the old database (not globals). In some places, the last identifier can be used for binding, so it needs to be saved.The task of finding the correspondence between the elements of such reference books (in different systems) still remains one of the most relevant in the field of data migration. The type of property otherId is not processed in any way in the program, it is just a text reminder of what is inside. If necessary, nothing prevents the handler from hanging on this type of property in the methods of processing directories. The lastId property is indexable, as indicated by the index branch with the value “ture” . Next comes a set of three functions used to check when creating / updating an item. The checkUniqueParamElement () function for us is new - we will add it to the program.

checkUniqueParamElement ()
 #; -------------------------------------------------------------------------------------------------- #;      . #; -------------------------------------------------------------------------------------------------- checkUniqueParamElement(param,ontology,type) new t #;    set t("value")=$$$getDTOin(param,"") #;   ,     -    quit:t("value")="" 0 #;    set t("q")=0 set t("uniqueId")="" for { #; ,         #;   , ,    set t("uniqueId")=$o($$$dIndex(ontology,type,param,t("value"),t("uniqueId"))) #;     quit:t("uniqueId")="" #; ,      #;     update if (t("uniqueId")`=$$$getDTOproc("id","")) { #;  ,       set t("q")=-1 quit } } quit t("q") #; -------------------------------------------------------------------------------------------------- 


Extend the functionality of our create () method — add property handling to it:
  st("property")="" for { #;    st("property")=$o($$$dDTO($j,"in",t("property"))) #;   ,    quit:t("property")="" #;  ,              continue:$get($$$dRule(t("ontology"),t("type"),"property",t("property")),"")="" #;    set t("index")=$get($$$dRule(t("ontology"),t("type"),"property",t("property"),"index"),"false") #;    set t("value")=$get($$$dDTO($j,"in",t("property")),"") #;     -   if t("value")`="" { do setProperty(t("ontology"),t("type"),t("property"),t("value"),t("id"),t("index"),$$$getDTOproc("pathParent","")) } } 

Full version create
 #; -------------------------------------------------------------------------------------------------- #;   . #;         . #; -------------------------------------------------------------------------------------------------- create() #;     kill $$$dDTO($job,"out") #;     t #;         create new t #;      set t("err")=$$check("create") #; ,    if t("err")<0 { quit t("err") } st("ontology")=$$$getDTOin("ontology","") st("type")=$$$getDTOin("type","") st("id")=$$$getDTOproc("id","") #;   "UpdateTime" do setProperty(t("ontology"),t("type"),"UpdateTime",$horolog,t("id"),"false",$$$getDTOproc("pathParent","")) #;   "uid" do setProperty(t("ontology"),t("type"),"uid",$$$getDTOin("uid",888),t("id"),"true",$$$getDTOproc("pathParent","")) set t("lang")="" for { #;    (     ) set t("lang")=$order($$$dDTO($job,"in","nameList",t("lang"))) #;   ,     quit:t("lang")="" #;      set t("name")=$get($$$dDTO($job,"in","nameList",t("lang")),"") #;      do setName(t("ontology"),t("type"),t("lang"),t("name"),t("id")) } st("property")="" for { #;    st("property")=$o($$$dDTO($j,"in",t("property"))) #;   ,    quit:t("property")="" #;  ,              continue:$get($$$dRule(t("ontology"),t("type"),"property",t("property")),"")="" #;    set t("index")=$get($$$dRule(t("ontology"),t("type"),"property",t("property"),"index"),"false") #;    set t("value")=$get($$$dDTO($j,"in",t("property")),"") #;     -   if t("value")`="" { do setProperty(t("ontology"),t("type"),t("property"),t("value"),t("id"),t("index"),$$$getDTOproc("pathParent","")) } } #;          do saveOntoAndTypeID(t("id"),t("ontology"),t("type")) #;         do saveElementPath(t("id"),$$$getDTOproc("path","")) #;         $$$setDTOout("id",t("id")) #;     kill $$$dDTO($job,"in") #;     kill $$$dDTO($job,"porc") #;     quit t("id") #; -------------------------------------------------------------------------------------------------- 


Pay attention to the line:

do setProperty (t ("ontology"), t ("type"), t ("property"), t ("value"), t ("id"), t ("index"), $$$ getDTOproc ("pathParent", "")) One more pathParent parameter was added to the

call to the setProperty () method - it is needed to handle nesting.

Add a couple of car brands to our directory (the brands I chose at random - there is no advertising here).
 MONTOLOGY>kill ^tmwOntology($job) MONTOLOGY>set ^tmwOntology($job,"in","ontology")="Vehicle",^tmwOntology($job,"in","type")="Make" MONTOLOGY>set ^tmwOntology($job,"in","nameList","ru")="MAZDA",^tmwOntology($job,"in","nameList","partUri")="mazda" MONTOLOGY>set ^tmwOntology($job,"in","lastId")=122 MONTOLOGY>write $$create^Dictionary() 3 MONTOLOGY>kill ^tmwOntology($job) MONTOLOGY>set ^tmwOntology($job,"in","ontology")="Vehicle",^tmwOntology($job,"in","type")="Make" MONTOLOGY>set ^tmwOntology($job,"in","nameList","ru")="BMW",^tmwOntology($job,"in","nameList","partUri")="bmw" MONTOLOGY>set ^tmwOntology($job,"in","lastId")=1269 MONTOLOGY>write $$create^Dictionary() 4 MONTOLOGY> 


Carefully look at the rules for the Model . A parent branch appeared with the value “Make” - an indication that the parent for the Model directory is Make . Next, an indexable parentId property is declared , in which the parent ID is stored. Let the elements of the nested directory, in the global ^ Dictionary , be stored in the children branchparent element. We will not limit the number of nesting levels by software (only restrictions on the length of the index of the variable remain). We also assume that indexes and names for nested directories will be stored in the same way as for normal ones. Let's write the parent check function.

 #; -------------------------------------------------------------------------------------------------- #;   ,   . #;     . #; -------------------------------------------------------------------------------------------------- checkParent()private new t #;           (  ) st("parent")=$get($$$dRule($$$getDTOin("ontology",""),$$$getDTOin("type",""),"parent"),"") #;    if t("parent")`="" { #;    parentId      set t("parentId")=$$$getDTOin("parentId","") #;       if t("parentId")="" { quit -1 } #;       #;        if $get($$$dIndex("ID",t("parentId"),"ontology"),"")`=$$$getDTOin("ontology","") { quit -1 } #;       if $get($$$dIndex("ID",t("parentId"),"type"),"")`=t("parent") { quit -1 } #;     st("pathParent")=$get($$$dIndex("ID",t("parentId"),"path"),"") #;      if t("pathParent")="" { quit -1 } #;          $$$setDTOproc("pathParent",t("pathParent")) } #;      quit 0 #; -------------------------------------------------------------------------------------------------- 

As you can see, the function checks in the global rules whether the created element is nested, and if so, it checks the presence and correctness of the passed parent identifier. You will also have to make some changes to the checkCreate () method : add the call to the parent check to it, and change the rule for forming the path to the directory element in the global ^ Dictionary .

 #; -------------------------------------------------------------------------------------------------- #;      . #; -------------------------------------------------------------------------------------------------- checkCreate()private new t #;       quit:$$$getDTOin("ontology","")="" -1 #;  ,      quit:$$$getDTOin("type","")="" -1 #;     st("check")=$$checkParent() #;  ,     quit:t("check")<0 t("check") #;     set t("check")=$$checkNames() #;  ,     quit:t("check")<0 t("check") #;       $$$setDTOproc("id",$$$dMaxID) #;      ^Dictionary if $$$getDTOproc("pathParent","")="" { #;    -     ^Dictionary(ontology) set t("path")=$name($$$dData($$$getDTOin("ontology",""))) } else { #;      -         children set t("path")=$name(@($$$getDTOproc("pathParent",""))@(0,"children")) } #;           st("path")=$name(@(t("path"))@($$$getDTOin("type",""),$$$getDTOproc("id",""))) $$$setDTOproc("path",t("path")) #;     quit 0 #; -------------------------------------------------------------------------------------------------- 

Also note the following line in the global rules:

set $$$ dRule ("Vehicle", "Model", "create", "check", 20) = "s check = $$ checkUniqueNameElementAllLang (" "true" ")"

The method checkUniqueNameElement () , we added one parameter inparentwhich determines whether it is necessary to check for uniqueness within all directory elements or only within the parent. For our case it is easy to explain, there are many models of cars that are equally called, but they have different brands. We need to check that matches only within the parent - and in this case, produce an error. Similar requirements may arise, for example, when implementing an address directory. In one country there is a huge number of settlements with the same name. He himself was surprised by the far from single presence of such settlements in Ukraine as Nikolaev, Poltava, Cherkasy and others. Therefore, it is sometimes necessary to limit the domain within which the uniqueness is verified.

 #; -------------------------------------------------------------------------------------------------- #;      ,   ,   . #;  ,   . #; -------------------------------------------------------------------------------------------------- checkUniqueNameElement(ontology,type,lang,name,id,inparent="false") new t #;    set t("q")=0 set t("uniqueId")="" for { #; ,         #;   , ,   (  ) set t("uniqueId")=$order($$$dIndex(ontology,type,"name",lang,$zconvert(name,"l"),t("uniqueId"))) #;     quit:t("uniqueId")="" #; ,      #;     update if (t("uniqueId")`=id) { #;          if inparent="false" { #;  ,       set t("q")=-1 quit } else { #;        if $data($$$dIndex(ontology,type,"parentId",$$$getDTOin("parentId",""),t("uniqueId"))) { #;          #;    /  set t("q")=-1 quit } } } } #;   quit t("q") #; -------------------------------------------------------------------------------------------------- 

All Dictionary Code
 #; -------------------------------------------------------------------------------------------------- #;    Dictionary.inc,   (inc) -      #include Dictionary #; -------------------------------------------------------------------------------------------------- #;   #; -------------------------------------------------------------------------------------------------- Dictionary #; -------------------------------------------------------------------------------------------------- #;   . #; -------------------------------------------------------------------------------------------------- retrieve(id,lang="ru",version=0) quit $get($$$dName(id,lang,version),"") #; -------------------------------------------------------------------------------------------------- #;      . #; -------------------------------------------------------------------------------------------------- retrieveListByIndex(ontology,type,index,value,str="",lang="ru") #;     ,       set str=$zconvert(str,"L") set id="" for { #;  ()    set id=$order($$$dIndex(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 $$$dDTO($job,"out") #;     t #;         create new t #;      set t("err")=$$check("create") #; ,    if t("err")<0 { quit t("err") } st("ontology")=$$$getDTOin("ontology","") st("type")=$$$getDTOin("type","") st("id")=$$$getDTOproc("id","") #;   "UpdateTime" do setProperty(t("ontology"),t("type"),"UpdateTime",$horolog,t("id"),"false",$$$getDTOproc("pathParent","")) #;   "uid" do setProperty(t("ontology"),t("type"),"uid",$$$getDTOin("uid",888),t("id"),"true",$$$getDTOproc("pathParent","")) set t("lang")="" for { #;    (     ) set t("lang")=$order($$$dDTO($job,"in","nameList",t("lang"))) #;   ,     quit:t("lang")="" #;      set t("name")=$get($$$dDTO($job,"in","nameList",t("lang")),"") #;      do setName(t("ontology"),t("type"),t("lang"),t("name"),t("id")) } st("property")="" for { #;    st("property")=$order($$$dDTO($j,"in",t("property"))) #;   ,    quit:t("property")="" #;  ,              continue:$get($$$dRule(t("ontology"),t("type"),"property",t("property")),"")="" #;    set t("index")=$get($$$dRule(t("ontology"),t("type"),"property",t("property"),"index"),"false") #;    set t("value")=$get($$$dDTO($j,"in",t("property")),"") #;     -   if t("value")`="" { do setProperty(t("ontology"),t("type"),t("property"),t("value"),t("id"),t("index"),$$$getDTOproc("pathParent","")) } } #;          do saveOntoAndTypeID(t("id"),t("ontology"),t("type")) #;         do saveElementPath(t("id"),$$$getDTOproc("path","")) #;         $$$setDTOout("id",t("id")) #;     kill $$$dDTO($job,"in") #;     kill $$$dDTO($job,"porc") #;     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 #; ,      "check",        if $data($$$dRule($$$getDTOin("ontology",""),$$$getDTOin("type",""),action,"check")) { #;  check("map")        set check("map")=$name($$$dRule($$$getDTOin("ontology",""),$$$getDTOin("type",""),action,"check")) } else { #;  check("map")              set check("map")=$name($$$dRule("SimpleOntology","SimpleType",action,"check")) } set check("i")="" for { #;     set check("i")=$order(@check("map")@(check("i"))) #;   ,     quit:check("i")="" #;     xecute $get(@check("map")@(check("i"))) #;   ,     quit:check<0 } #;    quit check #; -------------------------------------------------------------------------------------------------- #;      . #; -------------------------------------------------------------------------------------------------- checkCreate()private new t #;       quit:$$$getDTOin("ontology","")="" -1 #;  ,      quit:$$$getDTOin("type","")="" -1 #;     st("check")=$$checkParent() #;  ,     quit:t("check")<0 t("check") #;     set t("check")=$$checkNames() #;  ,     quit:t("check")<0 t("check") #;       $$$setDTOproc("id",$$$dMaxID) #;      ^Dictionary if $$$getDTOproc("pathParent","")="" { #;    -     ^Dictionary(ontology) set t("path")=$name($$$dData($$$getDTOin("ontology",""))) } else { #;      -         children set t("path")=$name(@($$$getDTOproc("pathParent",""))@(0,"children")) } #;           st("path")=$name(@(t("path"))@($$$getDTOin("type",""),$$$getDTOproc("id",""))) $$$setDTOproc("path",t("path")) #;     quit 0 #; -------------------------------------------------------------------------------------------------- #;   ,   . #;     . #; -------------------------------------------------------------------------------------------------- checkParent()private new t #;           (  ) st("parent")=$get($$$dRule($$$getDTOin("ontology",""),$$$getDTOin("type",""),"parent"),"") #;    if t("parent")`="" { #;    parentId      set t("parentId")=$$$getDTOin("parentId","") #;       if t("parentId")="" { quit -1 } #;       #;        if $get($$$dIndex("ID",t("parentId"),"ontology"),"")`=$$$getDTOin("ontology","") { quit -1 } #;       if $get($$$dIndex("ID",t("parentId"),"type"),"")`=t("parent") { quit -1 } #;     st("pathParent")=$get($$$dIndex("ID",t("parentId"),"path"),"") #;      if t("pathParent")="" { quit -1 } #;          $$$setDTOproc("pathParent",t("pathParent")) } #;      quit 0 #; -------------------------------------------------------------------------------------------------- checkUpdate() quit 0 #; -------------------------------------------------------------------------------------------------- checkDelete() quit 0 #; -------------------------------------------------------------------------------------------------- #;     . #; -------------------------------------------------------------------------------------------------- checkNames()private new t #;   t("check")  #;         set t("check")=-1 set t("lang")="" for { #;    set t("lang")=$order($$$dDTO($job,"in","nameList",t("lang"))) #;   ,     quit:t("lang")="" #;      set t("name")=$get($$$dDTO($job,"in","nameList",t("lang")),"") #;    if t("name")="" { #;   t("check")  set t("check")=-1 #;    quit } else { #;  t("check")   ,     set t("check")=0 } } #;     quit t("check") #; -------------------------------------------------------------------------------------------------- #;    . #; -------------------------------------------------------------------------------------------------- processingNames(function) new t set t("lang")="" for { #;     set t("lang")=$order($$$dDTO($job,"in","nameList",t("lang"))) quit:t("lang")="" #;        xecute "set "_$name($$$dDTO($job,"in","nameList",t("lang")))_"=$$"_function_"("""_$$$getDTOname(t("lang"))_""")" } quit #; -------------------------------------------------------------------------------------------------- checkUniqueNameElementAllLang(inparent="false") new t set t("check")=0 st("ontology")=$$$getDTOin("ontology","") st("type")=$$$getDTOin("type","") set t("lang")="" for { #;     set t("lang")=$order($$$dDTO($job,"in","nameList",t("lang"))) quit:t("lang")="" #;    set t("name")=$get($$$dDTO($job,"in","nameList",t("lang")),"") #;   t("check")     (0 -  ) st("check")=$$checkUniqueNameElement(t("ontology"),t("type"),t("lang"),t("name"),$$$getDTOproc("id",""),inparent) #;     -    quit:t("check")<0 } quit t("check") #; -------------------------------------------------------------------------------------------------- #;         . #; -------------------------------------------------------------------------------------------------- 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") #; -------------------------------------------------------------------------------------------------- #; -------------------------------------------------------------------------------------------------- #;       . #;      . #;        (     ). #;      ,   "."   . #; -------------------------------------------------------------------------------------------------- specialClearStr(str) new t set t("str")="",t("flag")="start",t("delim")="" for t("i")=1:1:$length(str) { set t("ch")=$extract(str,t("i")) ;#     set:t("ch")=$char(9) t("ch")=" " continue:(t("ch")?1C) if (t("flag")="start")&&`(t("ch")?1P) { set t("str")=t("ch"),t("flag")="word" } elseif t("flag")="word" { if `(t("ch")?1P) { set t("str")=t("str")_t("ch") } else { set t("delim")=t("ch"),t("flag")="delim" } } elseif t("flag")="delim" { if (t("ch")?1P) { set:t("ch")`=" " t("delim")=t("ch") } else { set t("str")=t("str")_t("delim")_t("ch"),t("flag")="word",t("delim")="" } } } set:t("delim")="." t("str")=t("str")_t("delim") quit t("str") #; -------------------------------------------------------------------------------------------------- #;      . #; -------------------------------------------------------------------------------------------------- checkUniqueParamElement(param,ontology,type) new t #;    set t("value")=$$$getDTOin(param,"") #;   ,     -    quit:t("value")="" 0 #;    set t("q")=0 set t("uniqueId")="" for { #; ,         #;   , ,    set t("uniqueId")=$order($$$dIndex(ontology,type,param,t("value"),t("uniqueId"))) #;     quit:t("uniqueId")="" #; ,      #;     update if (t("uniqueId")`=$$$getDTOproc("id","")) { #;  ,       set t("q")=-1 quit } } quit t("q") #; -------------------------------------------------------------------------------------------------- #;      ,   ,   . #;  ,   . #; -------------------------------------------------------------------------------------------------- checkUniqueNameElement(ontology,type,lang,name,id,inparent="false") new t #;    set t("q")=0 set t("uniqueId")="" for { #; ,         #;   , ,   (  ) set t("uniqueId")=$order($$$dIndex(ontology,type,"name",lang,$zconvert(name,"l"),t("uniqueId"))) #;     quit:t("uniqueId")="" #; ,      #;     update if (t("uniqueId")`=id) { #;          if inparent="false" { #;  ,       set t("q")=-1 quit } else { #;        if $data($$$dIndex(ontology,type,"parentId",$$$getDTOin("parentId",""),t("uniqueId"))) { #;          #;    /  set t("q")=-1 quit } } } } #;   quit t("q") #; -------------------------------------------------------------------------------------------------- #;  ,     . #;         . #; -------------------------------------------------------------------------------------------------- setProperty(ontology,type,property,value,id,index="true",pathParent="")private #;      ()    if pathParent="" { #;    set $$$dData(ontology,type,id,0,property)=value } else { #;    set @(pathParent)@(0,"children",type,id,0,property)=value } #;    if index="true" { #;   set $$$dIndex(ontology,type,property,value,id)=1 #;      set $$$dRefs(id,$name($$$dIndex(ontology,type,property,value,id)))=1 } quit 0 #; -------------------------------------------------------------------------------------------------- #;   ,     . #;  (  )   . #; -------------------------------------------------------------------------------------------------- setName(ontology,type,lang,value,id)private #;         set $$$dName(id,lang,0)=value #;   / set $$$dName(id,lang,0,"UpdateTime")=$horolog #;     set $$$dIndex(ontology,type,"name",lang,$zconvert(value,"l"),id)=1 #;    set $$$dRefs(id,$name($$$dIndex(ontology,type,"name",lang,$zconvert(value,"l"),id)))=1 quit 0 #; -------------------------------------------------------------------------------------------------- saveOntoAndTypeID(id,ontology,type) set $$$dIndex("ID",id,"ontology")=ontology set $$$dRefs(id,$name($$$dIndex("ID",id,"ontology")))=1 set $$$dIndex("ID",id,"type")=type set $$$dRefs(id,$name($$$dIndex("ID",id,"type")))=1 quit #; -------------------------------------------------------------------------------------------------- saveElementPath(id,path) set $$$dIndex("ID",id,"path")=path set $$$dRefs(id,$name($$$dIndex("ID",id,"path")))=1 quit #; -------------------------------------------------------------------------------------------------- 

In the program listing, the symbol 'was replaced with the symbol ' - this is necessary for a more beautiful display of the code. In the case of copying the program code in Caché - it is necessary to make a reverse replacement: replace all the characters ` with '

Add a couple of models, print our globals and see what nesting in the global ^ Dictionary looks like .
 MONTOLOGY>kill ^tmwOntology($job) MONTOLOGY>set ^tmwOntology($job,"in","ontology")="Vehicle",^tmwOntology($job,"in","type")="Model" MONTOLOGY>set ^tmwOntology($job,"in","nameList","ru")=6,^tmwOntology($job,"in","nameList","partUri")=6 MONTOLOGY>set ^tmwOntology($job,"in","parentId")=3 MONTOLOGY>write $$create^Dictionary() 5 MONTOLOGY>kill ^tmwOntology($job) MONTOLOGY>set ^tmwOntology($job,"in","ontology")="Vehicle",^tmwOntology($job,"in","type")="Model" MONTOLOGY>set ^tmwOntology($job,"in","nameList","ru")="BMW",^tmwOntology($job,"in","nameList","partUri")="bmw" MONTOLOGY>^tmwOntology($job,"in","nameList","ru")=3,^tmwOntology($job,"in","nameList","partUri")=3 MONTOLOGY>write $$create^Dictionary() 6 MONTOLOGY>zw ^Dictionary ^Dictionary("MaxID")=6 ^Dictionary("Vehicle","Make",3,0,"UpdateTime")="62970,58071" ^Dictionary("Vehicle","Make",3,0,"children","Model",5,0,"UpdateTime")="62970,58071" ^Dictionary("Vehicle","Make",3,0,"children","Model",5,0,"parentId")=3 ^Dictionary("Vehicle","Make",3,0,"children","Model",5,0,"uid")=888 ^Dictionary("Vehicle","Make",3,0,"children","Model",6,0,"UpdateTime")="62970,58071" ^Dictionary("Vehicle","Make",3,0,"children","Model",6,0,"parentId")=3 ^Dictionary("Vehicle","Make",3,0,"children","Model",6,0,"uid")=888 ^Dictionary("Vehicle","Make",3,0,"lastId")=122 ^Dictionary("Vehicle","Make",3,0,"uid")=888 ^Dictionary("Vehicle","Make",4,0,"UpdateTime")="62970,58071" ^Dictionary("Vehicle","Make",4,0,"lastId")=1269 ^Dictionary("Vehicle","Make",4,0,"uid")=888 ^Dictionary("Vehicle","TransmissionType",1,0,"UpdateTime")="62970,58071" ^Dictionary("Vehicle","TransmissionType",1,0,"uid")=888 ^Dictionary("Vehicle","TransmissionType",2,0,"UpdateTime")="62970,58071" ^Dictionary("Vehicle","TransmissionType",2,0,"uid")=888 MONTOLOGY>zw ^IndexDictionary ^IndexDictionary("ID",1,"ontology")="Vehicle" ^IndexDictionary("ID",1,"path")="^|""MONTOLOGY""|Dictionary(""Vehicle"",""TransmissionType"",1)" ^IndexDictionary("ID",1,"type")="TransmissionType" ^IndexDictionary("ID",2,"ontology")="Vehicle" ^IndexDictionary("ID",2,"path")="^|""MONTOLOGY""|Dictionary(""Vehicle"",""TransmissionType"",2)" ^IndexDictionary("ID",2,"type")="TransmissionType" ^IndexDictionary("ID",3,"ontology")="Vehicle" ^IndexDictionary("ID",3,"path")="^|""MONTOLOGY""|Dictionary(""Vehicle"",""Make"",3)" ^IndexDictionary("ID",3,"type")="Make" ^IndexDictionary("ID",4,"ontology")="Vehicle" ^IndexDictionary("ID",4,"path")="^|""MONTOLOGY""|Dictionary(""Vehicle"",""Make"",4)" ^IndexDictionary("ID",4,"type")="Make" ^IndexDictionary("ID",5,"ontology")="Vehicle" ^IndexDictionary("ID",5,"path")="^|""MONTOLOGY""|Dictionary(""Vehicle"",""Make"",3,0,""children"",""Model"",5)" ^IndexDictionary("ID",5,"type")="Model" ^IndexDictionary("ID",6,"ontology")="Vehicle" ^IndexDictionary("ID",6,"path")="^|""MONTOLOGY""|Dictionary(""Vehicle"",""Make"",3,0,""children"",""Model"",6)" ^IndexDictionary("ID",6,"type")="Model" ^IndexDictionary("Vehicle","Make","lastId",122,3)=1 ^IndexDictionary("Vehicle","Make","lastId",1269,4)=1 ^IndexDictionary("Vehicle","Make","name","partUri","bmw",4)=1 ^IndexDictionary("Vehicle","Make","name","partUri","mazda",3)=1 ^IndexDictionary("Vehicle","Make","name","ru","bmw",4)=1 ^IndexDictionary("Vehicle","Make","name","ru","mazda",3)=1 ^IndexDictionary("Vehicle","Make","uid",888,3)=1 ^IndexDictionary("Vehicle","Make","uid",888,4)=1 ^IndexDictionary("Vehicle","Model","name","partUri",3,6)=1 ^IndexDictionary("Vehicle","Model","name","partUri",6,5)=1 ^IndexDictionary("Vehicle","Model","name","ru",3,6)=1 ^IndexDictionary("Vehicle","Model","name","ru",6,5)=1 ^IndexDictionary("Vehicle","Model","parentId",3,5)=1 ^IndexDictionary("Vehicle","Model","parentId",3,6)=1 ^IndexDictionary("Vehicle","Model","uid",888,5)=1 ^IndexDictionary("Vehicle","Model","uid",888,6)=1 ^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 MONTOLOGY> 

We have added two models of the brand MAZDA : 3 and 6 (the numbers are the names of the models).

All cleaning commands and creating directories in one place
  kill ^Dictionary,^IndexDictionary,^NameDictionaryElement,^RefsDictionary d ^InitRuleDic kill ^tmwOntology($job) set ^tmwOntology($job,"in","ontology")="Vehicle",^tmwOntology($job,"in","type")="TransmissionType" set ^tmwOntology($job,"in","nameList","ru")=" ,",^tmwOntology($job,"in","nameList","partUri")="akp" write $$create^Dictionary(),! kill ^tmwOntology($job) set ^tmwOntology($job,"in","ontology")="Vehicle",^tmwOntology($job,"in","type")="TransmissionType" set ^tmwOntology($job,"in","nameList","ru")="",^tmwOntology($job,"in","nameList","partUri")="meh" write $$create^Dictionary(),! kill ^tmwOntology($job) set ^tmwOntology($job,"in","ontology")="Vehicle",^tmwOntology($job,"in","type")="Make" set ^tmwOntology($job,"in","nameList","ru")="MAZDA",^tmwOntology($job,"in","nameList","partUri")="mazda" set ^tmwOntology($job,"in","lastId")=122 write $$create^Dictionary(),! kill ^tmwOntology($job) set ^tmwOntology($job,"in","ontology")="Vehicle",^tmwOntology($job,"in","type")="Make" set ^tmwOntology($job,"in","nameList","ru")="BMW",^tmwOntology($job,"in","nameList","partUri")="bmw" set ^tmwOntology($job,"in","lastId")=1269 write $$create^Dictionary(),! kill ^tmwOntology($job) set ^tmwOntology($job,"in","ontology")="Vehicle",^tmwOntology($job,"in","type")="Model" set ^tmwOntology($job,"in","nameList","ru")=6,^tmwOntology($job,"in","nameList","partUri")=6 set ^tmwOntology($job,"in","parentId")=3 write $$create^Dictionary(),! kill ^tmwOntology($job) set ^tmwOntology($job,"in","ontology")="Vehicle",^tmwOntology($job,"in","type")="Model" set ^tmwOntology($job,"in","nameList","ru")=3,^tmwOntology($job,"in","nameList","partUri")=3 set ^tmwOntology($job,"in","parentId")=3 write $$create^Dictionary(),! zwrite ^Dictionary,^IndexDictionary,^NameDictionaryElement,^RefsDictionary 


I think many of you paid attention to the fact that in these articles, issues of transactions, locks and error handling are completely unaffected (returning -1 in the case of any error is clearly not enough). These are the issues we will discuss in the next article, unless there are other wishes in the comments.

I remind you that globals and codes from these articles are used in a live project (although starting with this article, the identifiers of the created elements will differ from those used in the real system).

I would be happy to ask questions and comments, tell me how you are implementing this in your database (even if there are no globals, but there is SQL).

Thanks for attention.

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


All Articles