A very basic tutorial on the LAZY hypertext view definition system

We will show how to construct hypertext views on a simple database which has the following tables:

  table emp(empno, ename, hiredate, deptno, mgr)
  table dept(deptno, dname)

A hypertext view definition consists of a set of node schemas.




Example 1. A simple node on emp

This first example defines a node that shows all the employees of a given department d. The part between '{' and '}' is generated for each tuple selected by the selection condition (deptno = d). The complete syntax is given at the end of this document.

node intro_emps_of_dept[d] 
  {
    <p>("No: " , empno, " => ", ename,
        " Hire date: ", hiredate
       )
  }
  from emp
  selected by deptno = d
  order by empno

The instance intro_emps_of_dept[10] of this node shows all the employees of department no. 10:

The syntax <p>(field, field, ...) indicates that a field or a list of fields forms an element of type <p>. By default, it will generate an HTML <p> tag, followed by the field values, and closed by a </p> tag.

 


Example 2. Introducing reference links

This node shows the characteristics of all the departments located in a given city. Each departement is presented with a reference link to emp_of_dept. Following this link will lead to the node that shows all the employees of this department.

node intro_dept_in[place] 
  <h2>("Departments in ",place) ,
  {
   <p>(deptno, ": ", dname, "  ",
       href intro_emps_of_dept [deptno] ("employees")
      ) 
  } ,
  <hr>()
  from dept
  selected by loc=place
  order by deptno	

Have a look at intro_dept_in["DALLAS"].

The general syntax of a reference link is "href" node_instance field, where field is then anchor text of the link and

node_instance =  nodeident [ "[" simple_expression < "," simple_expression > "]" ] .

Remark about node URLs

Normally URLs are automatically generated by the Lazy system when you write an href statement. However, if you want to refer to a Lazy node from a "standard" HTML page, or directly by entering a URL in the address field of the browser, you must use the following scheme:

http://hostname:8080/lazy/ns?a=project_name.node_name&u=first_parameter&u=second_parameter&u=...

For example, to refer to intro_dept_in["DALLAS"] on the cuisun1.unige.ch machine you must write

http://cuisun1.unige.ch:8080/lazy/ns?a=LAZYEX.dept_in&u=DALLAS




Example 3. A similar node with an inclusion link

node intro_dept_in_i[place] 
   <h2>("Departments in ",place) ,
  {
   <h3>(deptno, ": ", dname),
       include intro_emps_of_dept [deptno]
   
  }
  from dept
  selected by loc=place
  order by deptno	

Have a look at intro_dept_in_i[DALLAS].

The general syntax of an inclusion link is "include" node_instance


Example 3b. The same with an expand-in-place link

node intro_dept_in_e[place] 
   <h2>("Departments in ",place) ,
  {
   <h3>(deptno, ": ", dname), " ", 
       expand href intro_emps_of_dept [deptno] ("show employees")
      
  }
  from dept
  selected by loc=place
  order by deptno	

Have a look at intro_dept_in_e[DALLAS].

The general syntax of an expand-in-place link is "expand href" node_instance field


Example 4. Recursive inclusion

Inclusion links may refer to the same node (but with different parameters), as in the following example:

node intro_emp_with_mgr[e]
  { 
    "No: ", <b>(empno), " => ", <b>(ename), <br>() ,
    "Hire date: ", hiredate, <br>(),
    <blockquote>(include intro_emp_with_mgr [ mgr ])
  }
  from emp
  selected by empno = e
  order by empno

See all the hierarchy above employee no. 7369 in intro_emp_with_mgr[7369].


Example 5. "Decode" the department no.

Here we want to display information about employees, including the name of their department. In the emp table we only have the department no. (deptno), so we include a simple node intro_dept_name whose purpose is to display the name of a department. This example also shows a slightly more complex selection condition: sal >= minsal and sal <= maxsal.

node intro_dept_name [n]
  {
     dname
  }
  from dept
  selected by deptno = n order by deptno
  
node intro_emp_with_dept [minsal, maxsal]
  {
    "[", empno, "] ", <b>(ename) ,
    " works in ", <i>(include intro_dept_name [deptno]),
    " and earns ", sal, ".", <hr>()
  }
  from emp
  selected by sal >= minsal and sal <= maxsal
  order by sal

See intro_mp_with_dept[2000,10000] (shows all the employees with a salary between 2000 and 10000).

Remark. The same effect can be obtained (moe efficiently) by defining a node one the cartesian product of the two tables :

node intro_emp_with_dept [minsal, maxsal]
  {
    "[", empno, "] ", <b>(ename) ,
    " works in ", <i>(dept.deptno),
    " and earns ", sal, ".", 
    <hr>()
  }
  from emp, dept
  selected by sal >= minsal and sal <= maxsal and emp.deptno = dept.deptno
  order by sal

 


The syntax of a compilation unit defining node schemas is:

compilation_unit = "define" { node_def } "end".

node_def = "node" node_identifier parameters 
              field {","  field  }
	           from_part();         
              select_part();         
              order_part

parameters = [ "[" parameter { "," parameter  } "]" ]

parameter = identifier

field =    "href" link "(" field {"," field } ")"  
         | "include" link
         | content

link = (  "include" | ["expand"] "href") nodeident 
                   [ "[" simple_expression { "," simple_expression } "]" ]

content =   element_type [ "(" [  field { , field } ] ")" ]  
          | simple_expression
          | tuple_based_content .  

tuple_bsed_content = "{" field {"," field } "}"

element_type = "<" element_type_identifier { element_attribute_identifier "=" simple_expression } ">"

simple_expression  = term { "+"|"-" term }

term = factor { "*"|"/" factor }

factor =   stringconstant 
         | numberconstant 
         | function_identifier "(" simple_exression { ","  simple_exression } ")" 
         | [collection_ident '.'] attribute_ident 
         | parameter_ident 
         | '(' simple_expression ')'


from_part = "from" collection_id [alias_identifier] { ',' collection_identifier [alias_id] } .

select_part = "selected" "by" condition. 

condition = ["not"] logical_term { "or" logical_term }

logical_term = logical_factor { "and" logical_factor }

logical_factor =  "(" condition ")"
                | simple_expression (  comparision_op simple_expression
                                     | "is" ["not"] "null" )
                   
order_part =  "order" "by" simple_expression {',' simple_expression}