Elementary data is tree
Mask
Elementary object, processable by language TML, is no a record, but a tree.
Trees is set of a records, placed in a different tables.
Record is mentioned in request of tree by specification of a table, in which it is stored
(we shall name such mention as a section).
Top table is specified first, then others tables in order of an enclosure.
Each surrounding table is separated from enclosed table by mark "point" (".") without blanks.
Each request is terminated by mark "semicolon" (";").
tablename1.tablename2.tablename3.tablename4;
Any sub-tree can be requested.
tablename2.tablename3.tablename4;
Sections can have the same names.
tablename1.tablename2.tablename3.tablename2;
It's interesting to compare purpose of words, listed through a slash in path to a file,
and words, listed through a point in TML.
In first case we have a list of values of one field
in different records of one table ("dir1/dir2/dir3"),
in second case - a list of names ("tab1.tab2.tab3").
Special-symbols (*, +, ?) and natural numbers
can be used for designation of several levels of hierarchy -
we shall name them in this capacity as repeaters.
It's necessary to remember, that name of a section can not be a number.
repeater | quantity of designated intermediate levels of hierarchy |
* | 0-∞ |
+ | 1-∞ |
? | 0-1 |
5 | 5 |
3~5 | 3-5 |
Some examples.
tablename.*.tabname;
tablename.+.tabname;
tablename.?.tabname;
tablename.5.tabname;
tablename.3~5.tabname;
tablename.0~5.tabname;
Rule for enclosed tables: it is not taken, what did not asked.
If "tabname" in example above have an enclosed tables,
then they will not be taken from a database.
It's interesting to compare purpose of special-symbols in "shell" and repeaters in TML.
A filename is unknown in first case, a depth of an enclosure - in second case.
For example, an asterisk means any quantity of a letters in a word in first case,
any quantity of sections - in second case.
We shall name several any consequent sections of request as sharer,
and we shall name combination of sharers, listed in parenthesis, as sharer.
Sharer of repeater
It's possible to select not all enclosed tables in request,
but only enclosed tables with certain names.
These names need to be put before a repeater.
If it's necessary to select by repeaters not all tables in example above,
but only table with name "tname" or "tcap", then expressions should look so
(comma between names in brackets means logic operation "or")
tablename.(tname,tcap)*.tabname;
tablename.(tname,tcap)+.tabname;
tablename.(tname,tcap)?.tabname;
tablename.(tname,tcap)5.tabname;
tablename.(tname,tcap)3~5.tabname;
Repeater can act to not one section, but to some sections.
tablename.(tname1.tname2.tname3)*.tabname;
tablename.(tname1.tname2.tname3)+.tabname;
tablename.(tname1.tname2.tname3)?.tabname;
tablename.(tname1.tname2.tname3)5.tabname;
tablename.(tname1.tname2.tname3)3~5.tabname;
For example, first expression in example above means repetition of
"tname1.tname2.tname3" any time, i.e.
tablename.tname1.tname2.tname3.tabname
tablename.tname1.tname2.tname3.tname1.tname2.tname3.tabname
tablename.tname1.tname2.tname3.tname1.tname2.tname3.tname1.tname2.tname3.tabname
We shall name part of request, which is under sign of repeater,
as sharer of repeater
(absence of any repeater after a closing parentheses means number one).
We shall name part of result of request, received by action of repeater
(emphasized by green) as nuntaku.
tablename.(tname).tabname;
Nuntaku always consists of maximum quantity of sharers,
this quantity is limited only by requirement of existence of sections after nuntaku
(including by requirement of existence of next nuntaku!).
So if the following tree is in a database
tablename.t1.t2.t1.t2.t1.t2.t1.t2
then nuntaku consists only of three sharers in the request below.
tablename.(t1.t2)*.t1.t2;
If repeaters "*", "+" is used,
then it's possible to specify a condition in square brackets after repeater.
If field of sharer satify this condition,
then further increasing of quantity of sharers in nuntaku is terminated.
We shall name such square brackets as finish brackets,
and we shall name sharer, satifing condition, as last sharer.
Request will give tree together with last sharer.
If no sharer satisfy to expression in finish brackets,
then nevertheless request has passed successfully and return tree with nuntaku.
tablename.*[fld=0].tabname;
tablename.tname*[fld=0].tabname;
tablename.(tname1.tname2)*[tname1.fld=0 tname2.fld=0].tabname;
Assignment in finish brackets are executed
only in last sharer and only after assignment in field brackets.
All, what can be in field bracket, can be in finish brackets,
and order of processing in finish brackets is similar
to order of processing in field brackets.
t.(t1[a11].t2[a22])*[t1.fld=0 t2.fld=0 t1.fld10 t2.fld10].t3;
Sharers of sub-tree
If two and more enclosed tables (several sub-trees) are in surrounding table,
then specify necessary sub-trees in parentheses through blank
for work with table together with sub-trees -
we shall name this listing of sub-trees as joint sharer.
Tree should have all specified sub-trees wholly to get in result of request.
tablename1.(tab21.tab31.tab41 tab22.tab32.tab42);
Listing through comma means,
that it's enough to have any of sub-trees, but wholly -
we shall name this listing of sub-trees as alternative sharer.
tablename1.(tab21.tab31.tab41, tab22.tab32.tab42);
Mark "blank" (one or several marks "blank" or "tabulation") everywhere in TML
means operation "and", and mark comma (",") means operation "or".
Operation "and" has a priority above operation "or" everywhere in TML.
There can be any repeater after listing sub-trees through a comma
(but not through a blank) -
this means, that listed sub-trees are equivalent during application of repeater
(including sub-trees can alternate).
tablename1.(tab21.tab31.tab41, tab22.tab32.tab42, tab23.tab33.tab43)*.tablename5;
Parentheses can be enclosed, for example
tablename1.(tab21.(tab31, tab32) tab22);
If any sections are listed after parentheses through a point,
then these sections are a part of request also and continues hierarchy of all sub-trees,
specified in parentheses.
Two following expressions are equivalent.
tablename1.(tab21.tab31.tab41 tab22.tab32).tablename5;
tablename1.(tab21.tab31.tab41.tablename5 tab22.tab32.tablename5);
Beheading
If request should give not whole tree "tab1.tab2.tab3.tab4",
but only sub-tree "tab3.tab4", then expression should be divided into parts by word "->"
(which we shall name further as axe).
tab1.tab2 -> tab2.tab3.tab4;
We shall name sections to the left of axe as address tree,
on the right - as data tree.
Last section of address tree is a field,
we shall name it as field of axe.
Name of field of axe can be not equal to name of top table of data tree.
tabname1.tabname2.field -> tablename1.tablename2.tablename3;
Address tree can contain sharers.
tabname1.(tabname2 tabname20).field -> tablename1.tablename2.tablename3;
tabname1.(tabname2)*.field -> tablename1.tablename2.tablename3;
Indexation of list
Some sections probably are a lists,
for example, section "tablename2" in example below.
If there are no any special instructions, then lists are taken wholly.
tablename1.tablename2.tablename3;
But it's possible to limit quantity of taken elements by
specifing of necessary indexes in braces
- we shall name further such indexes as list indexes).
Collection of specified list elements is list also,
order of following of elements is saved
(table "tablename3" in example above continues hierarchy of
each chosen list element "tablename2").
tablename1.tablename2{1,4,5}.tablename3;
Several values of index are listed through comma (for example, "1,3,5"),
range of index is specified by borders of range through mark tilda (for example, "10~15"),
triplet (range of index with step, which is different from one) is specified
by bottom border, step and top borders through marks tilda (for example, "30~33~90"),
combination of all ways is possible (for example, "1,3,5,10~15,30~33~90").
There can be in list indexes:
- serial numbers of list elements, counted from 1.
Overstep list border is not a mistake -
it's possible to specify number of element, which is greater, than exist in list.
tablename1.tablename2{5}.tablename3;
tablename1.tablename2{3,15,27}.tablename3;
tablename1.tablename2{3~27}.tablename3;
Serial numbers can be in column of some table.
tablename1.tablename2{tab.fld}.tablename3;
tablename1.tablename2{tab1.tab2.fld}.tablename3;
- sign "$", designating quantity of elements in list.
Writing into field of "$+1"-th element of means creating new element
tablename1.tablename2{$-3}.tablename3;
tablename1.tablename2{$+1}[fld1].tablename3;
tablename1.tablename2{$+2}[fld1].tablename3;
- sign "!", designating number of level of hierarchy of current section.
Levels of hierarchy are counted from 1, counting begins from first section of request.
All elements of list are on the same level of hierarchy.
tablename1.tablename2{!-3}.tablename3;
tablename1.tablename2{!+3}[fld1].tablename3;
tablename1[tablename2{!+3}[fld1].tablename2;
Use all they simultaneously is possible.
tablename1.tablename2{ 3,15,27,40~52,$-5, tab.fld,tab1.tab2.fld }.tablename3;
tablename1.tablename2{(3,15,27,40~52,$-5)(tab.fld,tab1.tab2.fld)}.tablename3;
Absence of any mark between round brackets inside index means operation "and",
mark comma (",") means operation "or".
Tree's and list's operations
Tree's operations
Tree's operations are written in field brackets -
so, as enclosed redords (sub-trees) are fields of current record.
It's possible to create a new record in enclosed table
(with simultaneous entering identical values into primary and foreign keys),
to delete existing record and to clean reference to existing record.
Creating of new record
(second example use determination):
tablename1[ tablename2<+>[field110 field120] ].tablename2;
tablename1[ tablename2/ref<+>[field110 field120] ].tablename2/ref;
It's possible to insert records
tablename1[ tablename2<+>tab.lnk->tablename2 ].tablename2;
At deleting record
it's necessary to specify, how many levels of hierarchy should be deleted:
3 level of hierarchy is deleted in the first example below,
so much, how many is specified in field "fld", in deleted the second example
(if enclosed records exist inside
deleted records of the most lower level of hierarchy (inside the "lowest" records),
then these enclosed records are saved in database),
all levels - in third example:
mark means,
that all enclosed records should be deleted in cascade.
tablename1[ tablename2<->3 ];
tablename1[ tablename2<->tab.fld ];
tablename1[ tablename2<-> ];
It's possible to delete only records, which have special values of fields
tablename1[ tablename2[field1<10 field2>20]<->3 ];
tablename1[ tablename2[field1<10 field2>20]<->tab.fld ];
tablename1[ tablename2[field1<10 field2>20]<-> ];
Throw is assignment value "null" to refering field
without deleting record (it's used at processing a count).
tablename1[ tablename2[field1<10 field2>20]<~>3 ];
tablename1[ tablename2[field1<10 field2>20]<~>tab.fld ];
tablename1[ tablename2[field1<10 field2>20]<~> ];
List's operations
Creating and inserting of new element of list is looks so
(we enter three new elements before 3,5-th and 7-th elements
in numeration before creation of new elements)
tablename1.tablename2{3,5<+>[field11 field12]}{7<+>[field110 field120]}.tablename3;
Similarly inserting of records into a list
it is executed before specified element and
means shift of next elements to appropriate quantity of positions,
and cutting is executed since specified element and
means shift in opposite direction.
Shift of list elements is executed by changing values of refering fields
(all records, got by sub-query, are inserted into list in example below).
tablename1.tablename2{5<+>tab.lnk->tablename2}.tablename3;
utting of list elements is change of values of refering fields and
deleting appropriate records,
if there are sub-trees in deleted records, then they are also deleted
(3 elements of list is deleted in the first example below,
and so much, how many is specified in field "fld", in the second example,
tail of list is deleted in third example).
tablename1.tablename2{5<->3 }.tablename3;
tablename1.tablename2{5<->tab.fld}.tablename3;
tablename1.tablename2{5<-> }.tablename3;
Throw of list elements is the same, as cutting,
but elements of list (records) are not deleted from database
(that is used for processing a count).
Value "null" is assigned to appropriate refering fields of thrown elements,
i.e. thrown elements are not joined with each other.
tablename1.tablename2{5<~>3 }.tablename3;
tablename1.tablename2{5<~>tab.fld}.tablename3;
tablename1.tablename2{5<~> }.tablename3;
Throw of all elements of list is spliting it into insulated elements
(two following expressions are equivalent)
tablename1.tablename2{1<~> }.tablename3;
tablename1.tablename2{ref_fieldnull}.tablename3;
It's possible to address to a field
- in field brackets
(at once after name of a section (or after list indexes - if they exist)
there can be square brackets named as field brackets)
table[subtable.field5];
-
as to an appropriate place in level of hierarchy
table.subtable.field5;
It's possible to assign into fields of section or fields of sub-trees in field brackets and
to compare they with a number, a text (in double inverted commas),
field of any table
(further we shall name it as
right field,
request, which give it - as right request,
and record, containing right field - as right record or
right list, if it is a list.
We shall name usual requests, including which contain right requests,
as left requests).
Fields always stand to the left of operator of comparison or assignment,
but number, text and right fields always to the right.
Usually data for right field goes from GUI,
so only one right record exist.
In case of right list, only first its element is used.
Comparison of fields is condition,
to which a section (and all tree) should satisfy
to get in result of request.
tablename1.tablename2[a1=1 a2>2, a1≠null a2≤tab.fld, a3="text"].tablename3;
Parentheses can be used inside field brackets for grouping requirements, showed to fields.
tablename1.tablename2[a1=1 (a2>2, a2<0)].tablename3;
Mark "blank" (one or several marks "blank" or "tabulation")
between comparisons inside the same field bracket means operation "and",
mark comma (",") means operation "or".
Any assignment in a field bracket is executed after all comparisons
in the same field bracket, and only if comparisons return true.
Assignments should be written after all comparisons.
tab1.tab2[a1=1 (a2>2, a2<0) a11 a2table.fld a3"text"].tab3;
It's possible to group assingments with comparisons by parentheses,
then assignment in parentheses is executed after all comparisons
in the same parentheses and at truly only in them.
Assingments in parentheses should be written after all comparisons
in the same parentheses.
Parentheses, listed through blank, are executed in order of following:
each next parentheses is executed after all assignments of previous brackets.
If comparison in a parentheses returns false,
then assignments in this and next parentheses are not executed,
and assignments in previous parentheses are not cancelled.
tab1.tab2[(a1=1 a12) (a2>2, a2<0 a2table.fld) a3"text"].tab3;
Parentheses, listed through comma, are executed independently of each other.
Assignment after them is executed at truly in any of them.
tab1.tab2[(a1=1 a12), (a2>2, a2<0 a2table.fld) a3"text"].tab3;
Assignments in enclosed bracket are executed,
only if operation of comparison in the same bracket returns true
(returned value of operation of comparison in above-bracket is unimportantly).
Assignments in above-bracket are executed,
only if operations of comparison in all enclosed brackets return true.
tab1.tab2[(a1=1 a12 (a2>2 a210) (a3<0 a3 -10) )].tab3;
Processing of field brackets of different sections goes in order of following of sections.
If comparison in a field bracket returns false,
then assingments in this and next brackets,
and also in continuing function are not executed
(but are executed in finishing function),
and assignments in previous brackets are not cancelled.
tabname1.tabname2[a1=1 a21].tabname3[b1=1 b21].tabname4[c1=1 c21].tabname5;
Operation "and" is executed between field brackets of different sections.
tablename1.tablename2[a1<100].tablename3[a2<100].tablename4;
Special value for assignment is "null".
tablename1.tablename2[a1null].tablename3;
If section, which is a list, has field brackets (section "tablename2" in example below),
then only those list elements will get into result of request, which satisfy field brackets.
Order of following of chosen elements of list is not broken
during copying into other list or during output.
tablename1.tablename2[a1=1 (a2>2, a2<0)].tablename3;
If section, which is a list, has both list indexes, and field brackets,
then list indexes always are written before field brackets,
and field brackets are applied only to those list elements,
which are specified in list indexes.
tablename1.tablename2{3~7}[a1=1 (a2>2, a2<0)].tablename3;
Permutation
Special operator of comparison with name permutation "<~" can be used
instead of mark of equality during comparison of left fields with right field.
If right list is used only one time,
then left field can be equal to any of value in right list.
tab1.tab2[a1<~table1.field1 a2<~table2.field2].tab3;
If identical right list is "permutated" with several left queries of
the same or different sections,
then left fields can be equal to any of values of right list,
but so, that to not be equal to each other.
tab1.tab2[a1<~table.field a2<~table.field].tab3;
Continuing and finishing functions can be left query.
tab1.tab2[a1<~table.field a2<~table.field].tab3 | a3<~table.field || a4<~table.field;
Quantity of using right query in left queries and
in continuing and finishing functions
should not exceed quantity of elements in right list.
If operator of permutation is used in nuntaku,
then quantity of sharer in result of query will be limited by
quantity of elements of right list.
tab1.tab2[a<~table.fld]*[a=10].tab3;
There exist several pseudo-fields, into which writing is impossible:
- "$" means quantity of elements in list and in set
tablename1.tablename2{3}[fld$].tablename3;
- "!" means number of level of hierarchy of current section.
Levels of hierarchy are counted from 1,
counting begins from first section of request.
Records-elements of list are on the same level of hierarchy.
tablename1.tablename2[a1!]*.tablename3;
tablename1.tablename2*[!=5].tablename3;
-
"^" means value of primary key of previous section
(if previous section is a list,
then it means value of primary key of so element of list,
which is parent of this section)
tablename1.tablename2[a1= ^]*.tablename3;
tablename1.tablename2[a1^]*.tablename3;
and previous section itself - when it anticipate name of a field
(i.e. it's possible to use a predicate for previous section in field brackets -
it's necessary to anticipate fields of previous section by sign "^")
tablename1.tablename2[^.a1= 10]*.tablename3;
tablename1.tablename2[^.a1 10]*.tablename3;
tablename1.tablename2[sum < ^.sum + ^.weight]*.tablename3;
tablename1.tablename2[sum ^.sum + ^.weight]*.tablename3;
-
"^^" means value of primary key of previous-previous section and previous-previous section itself,
"^^^" means value of primary key of previous-previous-previous section, etc
Sub-trees
List indexes of sub-tree can contain mark
,
which means, that section ("tab" in example lower),
having field brackets, satisfies to query,
if even one element of set or list ("x" in example lower)
satisfies to requirement.
tab[ x{}.tab2=^^ ];
Field brackets are easy for distinguishing from list indexes by their contents:
fields of section or sub-trees of section are inside field brackets.
Presence of a sub-tree without its fields means,
that section (and also all tree) satisfies to request,
only if it has specified sub-tree
(sub-tree is not written into result of request).
tab1.tab2[t1.t2.t3.t4.t5 table1.table2.table3].tab3;
If condition for several fields of different sections in one expression is necessary,
then put mark "vertical line" ("|")
and write comparison of fields of different sections,
we shall name expression after vertical line as continuing function.
tab1.tab2[a2<100].tab3[a3<100].tab4 | a2+a3>125;
If fields of different sections have identical names, but sections have not identical names,
then fields in continuing function are differed
by specifing names of one directly previous section
through a mark "point".
tab1.tab2[a1<100].tab3[a1<100].tab4 | tab2.a1+tab3.a1>125;
Use of continuing function for sections, which have the same name, is forbidden.
tab1.tab2[a2<100].tab3.tab2.tab3 | a2+a3>125;
tab1.tab2[a2<100]:10.tab3[a3<100] | a2+a3>125;
All, what can be in field bracket, can be in continuing function,
and order of processing in continuing function is similar
to order of processing in field brackets.
Continuing function is executed after
finish brackets (including after all assignments).
tab1.tab2[a1100].tab3[a1100].tab4 | tab2.a1+tab3.a1>125;
Operation "and" is executed between list indexes, field brackets and continuing function.
If logic multiplicands before finishing function already give value 'not',
then finishing function will not be executed.
It's can be a finishing function
after continuing function through "||" (without blank between marks "vertical line".
Continuing function can be absent before it -
thus finishing function is written at once after a tree).
A finishing function is completely similar to continuing function,
one difference is,
that finishing function always uses fields of last sharer or section.
tab1[a1≠0].tab2[a2<100].tab3.tab2.tab3.tab4[a4≠0] | a1+a4=0 || a2+a3>125;
tab1[a1≠0].tab2[a2<100]:10.tab3[a3<100].tab4[a4≠0] | a1+a4=0 || a2+a3>125;
Special operations
Deleting of all records of some table are executed by operator "~~"
(but deleting is not executed for enclosed records recursively, in cascade).
Operator of conditional executing is applied to requests, it's format
(first string is whole form, second and third strings are brief forms):
single braces are executed, if "request1" returns one or several trees;
double braces are executed in opposite case.
request1 ? { request2 } {{ request3 }};
request1 ? { request2 };
request1 ? {{ request2 }};
You can write constriction like below
request1 ? { }
request2 ? { }
request3 ? { }
request4 ? { }
request5 ? { }
{{ }};
Comment is all, what after two marks minus to end of a line,
and all, what is between marks /* */
-- comment
/*
comment
comment
comment
*/
Dmitry Turin
Сайт управляется системой
uCoz