7. Embedded QUEL for Pascal : Sample Applications : The Professor-Student Mixed Form Application
 
Share this page                  
The Professor-Student Mixed Form Application
This EQUEL/FORMS application lets the user browse and update information about graduate students who report to a specific professor. The program is structured in a master/detail fashion, with the professor being the master entry, and the students the detail entries. The application uses two forms--one to contain general professor information and another for detailed student information.
The objects used in this application are:
Object
Description
personnel
The program's database environment.
professor
A database table with two columns:
pname (c(25))
pdept (c(10))
See its create statement below for a full description.
student
A database table with seven columns:
sname (c(25))
sage (i1)
sbdate (c(25))
sgpa (f4)
sidno (i1)
scomment (text(200))
sadvisor (c(25))
See the create statement below for a full description. The sadvisor column is the join field with the pname column in the Professor table.
masterfrm
The main form has the pname and pdept fields, which correspond to the information in the Professor table, and the studenttbl table field. The pdept field is display-only. "Masterfrm" is a compiled form.
studenttbl
A table field in "masterfrm" with the sname and sage columns. When initialized, it also has five hidden columns corresponding to information in the Student table.
studentfrm
The detail form, with seven fields, which correspond to information in the Student table. Only the fields sgpa, scomment, and sadvisor are updatable. All other fields are display-only. "Studentfrm" is a compiled form.
grad
A global structure, whose members correspond in name and type to the columns of the Student database table, the "studentfrm" form and the studenttbl table field.
The program uses the "masterfrm" as the general-level master entry, in which data can only be retrieved and browsed, and the "studentfrm" as the detailed screen, in which specific student information can be updated.
The runtime user enters a name in the pname (professor name) field and then selects the Students menu operation. The operation fills the displayed and hidden columns or table field "studenttbl" with detailed information of the students reporting to the named professor. The user can then browse the table field (in read mode), which displays only the names and ages of the students. More information about a specific student can be requested by selecting the Zoom menu operation. This operation displays the form "studentfrm." The fields of "studentfrm" are filled with values stored in the hidden columns of "studenttbl." The user can make changes to three fields (sgpa, scomment, and sadvisor). If validated, these changes will be written back to the database table (based on the unique student id), and to the table field's data set. This process can be repeated for different professor names.
##   create student  { Graduate Student table }
##      (sname          = c25,          { Name }
##       sage           = i1,           { Age }
##       sbdate         = c25,          { Birth date }
##       sgpa           = f4,           { Grade point average}
##       sidno          = i4,           { Unique student number }
##       scomment       = text(200),    { General comments }
##       sadvisor       = c25)          { Advisor's name}

##  create professor   {Professor table}
##      (pname  = c25,  {Professor's name}
##       pdept  = c10)  {Department}

##  program University;

##  const
##
##       shortstrlen = 10;
##       mediumstrlen = 25;
##       longstrlen = 100;
    type
##       StrShort       = packed array [1..SHORTSTRLEN] of Char;
##       StrMedium      = packed array [1..MEDIUMSTRLEN] of Char;
##       StrLong        = packed array [1..LONGSTRLEN] of Char;
##       NatTiny        = [byte] 0..255; {A one-byte unsigned integer}
##  var
##       {Master and student compiled forms}
##       masterfrm,studentfrm: [external] Integer;

##  declare
##  {
##  | Procedure: Prof_Student
##  | Purpose:  Main body of "Professor/Student"
##  | Master-Detail Application.
##  }

##  procedure Prof_Student;

##  type
##      {Grad student record maps to "student" DB table}
##      Student_Rec = record
##          sname: StrMedium;
##          sage: NatTiny;
##          sbdate: StrMedium;
##          sgpa: Real;
##          sidno: Integer;
##          scomment: StrMedium;
##          sadvisor: StrMedium;
##      end;

##      {Professor record maps to "professor" DB table}
##      Prof_Rec = record
##          pname: StrMedium;
##          pdept: StrShort;
##      end;

##  var
##      grad: Student_Rec;
##      prof: Prof_Rec;
##      old_advisor: StrMedium;   {Advisor before ZOOM}

##      {Useful forms runtime information}
##      lastrow,                  {Lastrow in table field}
##      istable: Integer;         {Is a table field?}

##      {Utility buffers}
##      msgbuf: StrLong:          {Message buffer}
##      respbuf: Char;            {Response buffer}
##      {
##      | Function: Student_Infor_Changed
##      | Purpose: Allow the user to zoom into the details
##      | of a selected student. Some of the data can be
##      | updated by the user. If any updates were made,
##      | then reflect these back into the database table.
##      | The procedure returns TRUE if any changes were made. 
##      | Parameters:
##      | None.
##      | Returns: 
##      | TRUE/FALSE - Changes were made to the database.
##      | Sets the global "grad" record with the new data.
##      }
##      function Student_Info_Changed : Boolean;

##      var
##          changed: Integer; {Changes made to the form?}
##          valid_advisor: Integer; {Is the advisor a professor?}

##      begin {Student_Info_Changed}

##              {Display the detailed student information}
##              display #studentfrm update

##              initialize (sname = grad.sname,
##                      sage       = grad.sage,
##                      sbdate     = grad.sbate,
##                      sgpa       = grad.sgpa,
##                      sidno      = grad.sidno,
##                      scomment   = grad.scomment,
##                      sadvisor   = grad.sadvisor)

##              activate menuitem 'Write'
##              begin
##                      {
##                      | If changes were made then update the
##                      | database table. Only bother with the 
##                      | fields that are not read-only.
##                      }
##                      inquire_frs form (changed = change)

                        if (changed = 1) then
                        begin
##                              validate
##                              getform (grad.sgpa = sgpa,
##                                       grad.scomment = scomment,
##                                       grad.sadvisor = sadvisor)

##                              {
##                              | Enforce referential integrity.
##                              | If there aren't any professors
##                              | matching the advisor's name then
##                              | don't change it -- user would never
##                              | be able to access it again to fix it.
##                              }
##              retrieve (valid_advisor =
##                    count(p.pname 
##                        where p.pname =
##                            grad.sadvisor))

                if (valid_advisor <= 0) then
                begin
##                    message 'Not a valid professor'
##                    sleep 2
##                    resume field sadvisor
                end else
                begin
##                    message 'Writing to database...'
##                    replace s(sgpa = grad.sgpa,
##                              scomment = grad.scomment,
##                              sadvisor = grad.sadvisor)
##                    where s.sidno = grad.sidno)
##                    breakdisplay
                end; {Valid advisor}
            end; {Form was changed}
##      end {write}

##      activate menuitem 'End', frskey3
##      begin
                {Quit without submitting changes}
                changed :=0;
##              breakdisplay
##      end {End}

##      finalize
        Student_Info_Changed := (changed =1);

##      end; {Student_Info_Changed}
##  begin {Prof_Student}

##      {Start up Ingres and the Forms system}
##      forms
##      message 'Initializing Student Administrator...'

##      ingres personnel

##      range of p IS professor, s is student

##      addform masterfrm
##      addform studentfrm

##      {
##      | Initialize "studenttbl" with a data set in READ mode.
##      | Declare hidden columns for all the extra fields that
##      | the program will display when more information is 
##      | requested about a student. Columns "sname" and "sage"
##      | are displayed, all other columns are hidden, to be
##      | used in the student information form.
##      }

##      inittable #masterfrm studenttbl read
##          (sbdate      = char(25),
##           sgpa        = float4,
##           sidno       = integer4,
##           scomment    = char(200),
##           sadvisor    = char(20))

##      {
##      | Drive the application, by running "masterfrm", and 
##      | allowing the user to "zoom" into a selected student.
##      }
##      display #masterfrm update

##      initialize
##      begin
##          message 'Enter an Advisor name...'
##          sleep 2
##      end {Initialize}

##      activate menutiem 'Students',field 'pname'
##      begin
##          {Load the students of the specified professor}
##          getform (prof.pname = pname)
 
##          {If no professor name is given then resume}
            if (prof.pname[1] = ' ') then
##              resume field pname
##      {
##      | Verify that the professor exists. If not
##      | print a message, and continue. We assume that
##      | each professor has exactly one department.
##      }
            prof.pdept :=' ';
##      retrieve (prof.pdept = p.pdept)
##      where p.pname = prof.pname

##      {If no professor report error}
        if (prof.pdetp[1] = ' ') then
        begin
            msgbuf := 'No professor with name '''+
                       prof.pname + ''' [RETURN]';
##          prompt noecho (msgbuf, respbuf)
##          clear field all
##          resume field pname
        end;

##      {Fill the department field and load students}
##      message 'Retrieving Student Information...'

##      putform (pdept = prof.pdept)
##      clear field studenttbl
##      redisplay     {Refresh for query}
##      {
##      | With the advisor name, load into the "studenttbl'
##      | table field all the graduate students who report
##      | to the professor with that name.
##      | Columns "sname" and "sage" will be displayed, and
##      | all other columns will be hidden.
##      }
##      retrieve (grad.sname = s.sname,
##              grad.sage = s.sage,
##              grad.sbdate = s.sbdate,
##              grad.sgpa = s.sgpa,
##              grad.sidno = s.sidno,
##              grad.scomment = s.scomment,
##              grad.sadvisor = s.sadvisor)
##              where s.advisor = prof.pname
##      begin
##              loadtable #masterfrm studenttbl
##              (sname = grad.sname,
##               sage = grad.sage,
##               sbdate = grad.sbdate,
##               sgpa = grad.sbdate,
##               sidno = grad.sidno,
##               scomment = grad.scomment,
##               sadvisor = grad.sadvisor)
##          end {Retrieve}
##          resume field studenttbl
##      end {Students}
##      activate menuitem 'Zoom'
##      begin
##          {
##          | Confirm that user is on "studenttbl", and that
##          | the table field is not empty. Collect data from
##          | the row and zoom for browsing and updating.
##          }
##          inquire_frs field #masterfrm (istable =table)
                if (istable = 0) then
                begin
##                  prompt noecho
##                      ('Select from the student table [RETURN]',
##                       respbuf)
##                  resume field studenttbl
                end;

##              inquire_frs table #masterfrm (lastrow = lastrow)
                if (lastrow = 0) then
                begin
##                  prompt noecho
##                      ('There are no students [RETURN]',
##                      respbuf)
##                  resume field pname
                end;

##              {Collect all data on student into graduate record}
##              getrow #masterfrm studenttbl
##                  (grad.sname = sname,
##                   grad.sage = sage,
##                   grad.sbdate = sbdate,
##                   grad.sgpa = sgpa,
##                   grad.sidno = sidno,
##                   grad.scomment = scomment,
##                   grad.sadvisor = sadvisor)
##          {
##          | Display "studentfrm", and if any changes were made
##          | make the updates to the local table field row.
##          | Only make updates to the columns corresponding to
##          | writable fields in "studentfrm".
##          | If the student changed advisors then delete this row
##          | from the current display -- it no longer belongs here.
##          }
                old_advisor := grad.sadvisor;
                if (Student_Infor_Changed) then 
                begin
                    if (grad.sadvisor <> old_advisor) then
                    begin
##                      deleterow #masterfrm studenttbl
                    end else
                    begin
##                      putrow #masterfrm studenttbl
##                          (sgpa = grad.sgpa,
##                           scomment = grad;scomment,
##                           sadvisor = grad.sadvisor)
                    end;
                end; {If student info changed}
##          end {Zoom}
##      activate menuitem 'QUIT', frskey2
##      begin
##          breakdisplay
##      end {Quit}

##      finalize

##      clear screen
##      endforms
##      exit
##  end; {Prof_Student}

##  begin {University}
        Prof_Student;
##  end. {University}