Lightweight, Component-based, and Database-oriented Web Application Framework

About | Overview | Documentation


Documentation > Modules and APIs > webman_db_item_update




Multi phases component-type module that provides dynamic control on database table items for update operation.



Webman-framework's Core Modules:

  • CGI_HTML_Map (Composition)
  • Data_HTML_Map (Composition)
  • DBI_HTML_Map (Composition)
  • HTML_DB_Map (Composition)

Webman-framework's Component-type Modules:
  • CGI_Component::webman_CGI_component (Inheritance)
  • webman_link_path_generator (Composition)


1. View Template

There are two view template files might be assigned to a single webman_db_item_update module. First is an update form page for item's field entries and the second is a confirmation page for displaying back fields and their values entered before proceed with the update operation. If there is no second view template assigned to the module the confirmation phase will be skipped.

1.1 Update Form Page

The DYNAMIC_CONTENT template-element (line 4) named link_path will be processed by webman_link_path_generator module inside process_DYNAMIC hook function. It's used as place-holder to render current application's link path when webman_db_item_update module is called. The next DYNAMIC_CONTENT template-element (line 7) named form_hidden_field is used as place-holder for HTML-form's hidden input-element. This hidden input-element is used as an entity to pass the parameter named link_id (via POST-method) which is the standard CGI parameter name used to refer nodes' IDs that construct the overall application's link structure. The logic is to use again node's link-id which is used to call webman_db_item_update module previously.

The DATAHTML template-element (lines 10-27) named form_db_field is passed to process_DATAHTML hook function and manipulated by Data_HTML_Map core module. The input-elements which will be later passed as CGI parameters are named in the form of $db_field_name_1, ..., till $db_field_name_n to adhere the naming convention requirements imposed by other core module (HTML_DB_Map) that is responsible for the real database update operation. Note that inside the DATAHTML template-element, $db_field_name_1 and $db_field_name_1_ are two different things. The former is an input-element name to be passed as CGI parameter representing item field name and value involved in the update operation. The later is template-element's word pattern, treated by Data_HTML_Map module as a place-holder to render the coresspond CGI parameter value.

CGI parameters mapped by the word patterns $db_field_name_1_, ..., $db_field_name_n_ are already made available at the first time the update form page was loaded for the purpose of displaying current field values from the database prior the update operation. It's done by injecting all item's field names and values involved as CGI parameters named in the form of aforementioned word patterns before start processing the DATAHTML template-element. Items's field names and values are retrieved from Table_List_Data instance, created by DBI_HTML_Map core module using SQL string command automatically or manually constructed via module's basic parameter settings that will be explained in the next main section (section 2, code lines 6-7 or line 12).

Other template's word patterns $fe_field_name_1_, ..., $fe_field_name_n_ are used as place-holders for highlighting errors on field values entered.

Two form's submit buttons (lines 33-34) with identical name button_submit but having two different values (Proceed and Cancel) are the default settings to provide users the options to proceed or cancel the submission of update form. In other word the module by default will check the input type element named button_submit and look at its value either Proceed or Cancel before decide to continue or cancel the update form submission.

  1 <html>                                                                                           
  2 <body>                                                                                           
  3 <!-- start_view_ //-->                                                                           
  4 <!-- dynamic_content_ name=link_path //--> &gt; Update Item                                      
  5 <p />                                                                                            
  6 <form method="POST" action="./index.cgi">                                                        
  7 <!-- dynamic_content_ name=form_hidden_field //-->                                               
  8 <table border="1">                                                                               
  9   <!-- start_datahtml_ name=form_db_field //-->                                                  
 10   <tr>                                                                                           
 11     <td>field_caption_1</td>                                                                     
 12     <td>                                                                                         
 13       <input name="$db_field_name_1" type="text" id="$db_field_name_1" value="$db_field_name_1_">
 14       </br>                                                                                      
 15       $fe_field_name_1_                                                                          
 16     </td>                                                                                        
 17   </tr>                                                                                          
 18   ...                                                                                            
 19   ...                                                                                            
 20   <tr>                                                                                           
 21     <td>field_caption_n</td>                                                                     
 22     <td>                                                                                         
 23       <input name="$db_field_name_n" type="text" id="$db_field_name_n" value="$db_field_name_n_">
 24       </br>                                                                                      
 25       $fe_field_name_n_                                                                          
 26     </td>                                                                                        
 27   </tr>                                                                                          
 28   <!-- end_datahtml_ //-->                                                                       
 30   <tr>                                                                                           
 31     <td>&nbsp;</td>                                                                              
 32     <td>                                                                                         
 33       <input name="button_submit" type="submit" id="button_submit" value="Proceed"/>             
 34       <input name="button_submit" type="submit" id="button_submit" value="Cancel"/>              
 35     </td>                                                                                        
 36   </tr>                                                                                          
 37 </table>                                                                                         
 38 </form>                                                                                          
 39 <!-- end_view_ //-->                                                                             
 40 </body>                                                                                          
 41 </html>                                                                                          

1.2 Confirmation Form Page

View template for confirmation form page also contains two DYNAMIC_CONTENT template-elements (lines 4 and 7) that play the same roles as explained in update form page above. The DATAHTML template-element (lines 10-14) is also the same but doesn't contain any form's input-elements and word patterns for highlighting field entries errors. At the time confirmation form page processed by the module, all CGI parameters passed from the previous update form page are already cached into the database. DATAHTML template-element is solely used to display back item's field values held by these cached CGI parameters for confirmation purpose.

Three form's submit buttons (lines 20-22) with identical name button_submit but having three different values (Confirm, Edit, and Cancel) are the default settings to provide users the options to confirm or cancel the update operation, or back to update form page to edit the field entries. In other word the module by default will check the input-element named button_submit and look at its value either Confirm, Edit, or Cancel before decide to continue or cancel the update operation, or going back to update form page to edit the previous data entries.

  1 <html>                                                                              
  2 <body>                                                                              
  3 <!-- start_view_ //-->                                                              
  4 <!-- dynamic_content_ name=link_path //--> &gt; Update Item                         
  6 <form method="POST" action="./index.cgi">                                           
  7 <!-- dynamic_content_ name=form_hidden_field //-->                                  
  9 <table border="1">                                                                  
 10   <!-- start_datahtml_ name=form_db_field //-->                                     
 11   <tr><td>field_caption_1</td><td>$db_field_name_1_</td></tr>                       
 12   ...                                                                               
 13   ...                                                                               
 14   <tr><td>field_caption_n</td><td>$db_field_name_n_</td></tr>                       
 15   <!-- end_datahtml_ //-->                                                          
 17   <tr>                                                                              
 18     <td>&nbsp;</td>                                                                 
 19     <td>                                                                            
 20       <input name="button_submit" type="submit" id="button_submit" value="Confirm"/>
 21       <input name="button_submit" type="submit" id="button_submit" value="Edit"/>   
 22       <input name="button_submit" type="submit" id="button_submit" value="Cancel"/> 
 23     </td>                                                                           
 24   </tr>                                                                             
 25 </table>                                                                            
 26 </form>                                                                             
 27 <!-- end_view_ //-->                                                                
 28 </body>                                                                             
 29 </html>                                                                             

2. Instantiation and Basic Parameter Setting

The most basic parameter settings are the table name and the SQL's update key string (lines 6-7). The update key string normally use table's primary-key information (name and value) as a main key-field to specify item to be updated. This main key-field passed to the module as a CGI parameter and mapped inside the update key string argument (line 7) in the form of $cgi_key_field_name_. Arguments from these basic parameter settings will also be used to automatically generate the SQL string command to retrieve involved item field names and their current values from the database. Item field names and values are later injected as CGI parameters so it can be mapped into DATAHTML template-element for the purpose, as already explained in section 1.1, paragraph 3. If involved item fields information retrieval requires more complex SQL command, the optional set_SQL_View function call (line 12) can be used.

Through the parameter settings (lines 17-19), the module will able to detect errors for blank field entries, field values duplication in current table, and field values existence in current table or other related tables. The string argument passed for blank field entries setting (line 17) are CGI parameters which used to represent item field names and values involved in the update operation. They are all separated by single spaces in single string argument. Duplicate field values errors detection (line 18) might based on combination of current table fields (field_name_2&field_name_3). String argument for field values existence (line 19) are one-to-one mappings of field name and its table (field_name=>table_name). As an example, field values existence error might happen if try to register student's course with course-code still not exist from inside the course table.

To exclude particular fields from being involved in the update operation, though they are already represented as a CGI parameters as explained in section 1, setting via set_Limit_On_Fields module's function (line 18) can be used.

The framework implements CGI parameters database cache through GMM_CGI core module implementations and webman_db_item_update module can automatically remove no longer required CGI parameters from the cache when the update operation last phase has been reached. Obviously, CGI parameters which used to represent field names and values involved in the update operation are among which will be automatically removed from the cache. Other specific CGI parameters can also be forced to be removed by passing the CGI parameter names to the set_Last_Phase_CGI_Data_Reset module's function (line 29).

After update operation has reach its last phase, it's normal in many web applications, to bring back the users to the previous page that point to the update page. It can simply be done by telling the module the previous page's URL (line 33) that make a link to current update page. Other options for doing this task can be done as explained in the next section (section 3, code line 59 or line 62);

  1 my $component = new webman_db_item_update;                                                                                                    
  3 $component->set_CGI($cgi);                                                                                                                    
  4 $component->set_DBI_Conn($db_conn);                                                                                                           
  6 $component->set_Table_Name($table_name);                                                                                                      
  7 $component->set_Update_Keys_Str("key_field_name='\$cgi_key_field_name_'");                                                                    
  9 ### The next function call is not necessary if the previous two function calls                                                                
 10 ### is completed and complex key-field or tables joint for viewing current                                                                    
 11 ### item to be updated is not required.                                                                                                       
 12 ### $component->set_SQL_View("select * from $table_name where key_field_1='\$cgi_key_field_1_' and ... and key_field_n='\$cgi_key_field_n_'");
 14 ### Option to debug SQL satement generated by the module.                                                                                     
 15 #$component->set_SQL_Debug(1);                                                                                                                
 17 $component->set_Check_On_CGI_Data("\$db_field_name_1 ... \$db_field_name_n");                                                                 
 18 $component->set_Check_On_Fields_Duplication("field_name_1 field_name_2&field_name_3 ... field_name_n");                                       
 19 $component->set_Check_On_Fields_Existence("field_name_1=>table_name_1, ..., field_name_n=>table_name_n");                                     
 21 #$component->set_Limit_On_Fields("field_name_1 ... field_name_n");                                                                            
 23 #$component->set_Submit_Button_Name($submit_button_name);  ### default is "button_submit"                                                     
 24 #$component->set_Proceed_On_Submit($proceed_button_value); ### default is "Proceed"                                                           
 25 #$component->set_Confirm_On_Submit($confirm_button_value); ### default is "Confirm"                                                           
 26 #$component->set_Edit_On_Submit($edit_button_value);       ### default is "Edit"                                                              
 27 #$component->set_Cancel_On_Submit($cancel_button_value);   ### default is "Cancel"                                                            
 29 #$component->set_Last_Phase_CGI_Data_Reset("param_name_1 param_name_2 ... param_name_n");                                                     
 31 ### Option to automatically change the current active page by going                                                                           
 32 ### to other URL when last phase has been reached.                                                                                            
 33 #$component->set_Last_Phase_URL_Redirect($url);                                                                                               
 35 ### Update form page template.                                                                                                                
 36 $component->set_Template_Default($template_file);                                                                                             
 38 ### Don't assign confirm view template if want to skip the confirmation phase.                                                                
 39 $component->set_Template_Default_Confirm($template_file_confirm);                                                                             

3. Component-type Generic Function Calls

The proposed implementations below are slightly different from the basic generic function calls of standard component-type modules since webman_db_item_update is categorized as multi phases component-type module. The main differences are:

  • Component's run_Task function (line 43) will return the status of true or false. It's true if the update operation is proceed and succeed. Other extra tasks for handling this status condition is now considerable (lines 45-48).
  • There are requirements to do other related tasks if update operation has reach its last phase (lines 56-63).
When last phase has been reached there are options to change the current active page by directly change the content (line 59) or just redirect the page to other URL (line 62). However, within the context of framework's sub-controller implementation using webman_component_selector module, these last phase tasks options is not really necessary since the module will automatically reset some related CGI parameters when last phase has been reached causing the sub-controller running other correspond module for its next recursive module's function call.
 41 if ($component->authenticate) {                                 
 42     ### $status == 1 if update operation is proceed and succeed.
 43     my $status = $component->run_Task;                          
 45     if ($status) {                                              
 46         ### Do other extra tasks if update operation is succeed.
 47         ### ...                                                 
 48     }                                                           
 50     $component->process_Content;                                
 51 }                                                               
 53 my $content = undef;                                            
 55 if ($component->last_Phase) {                                   
 56     $component->end_Task;                                       
 58     ### Set to other related content .                          
 59     #$content = "...";                                          
 61     ### Jump to other URL.                                      
 62     #$cgi->redirect_Page($url);                                 
 64 } else {                                                        
 65     $content = $component->get_Content;                         
 66 }                                                               

The next proposed implementations is the more simple version but requires internal customizations inside child module implementations such as shown in the next section (section 4).
 41 if ($component->authenticate) {       
 42     $component->run_Task;             
 43     $component->process_Content;      
 44 }                                     
 46 if ($component->last_Phase) {         
 47     $component->end_Task;             
 48 }                                     
 50 my $content = $component->get_Content;

4. Child Module for Customization

Most generic customization tasks are reflect to multi-phases character featured by the base module as already explained in the previous section (section 3). Customizations inside child modules provide more fine-grained control on each phases involved (lines 43-58). An equivalent tasks from previous example (section 3) for handling succeed update operation and last phase condition can be done internally inside the child module (lines 62-64 and lines 88-92). There is also customize_CGI_Data function to be overriden (lines 105-111) to manipulate the CGI parameters prior the execution of update operation.

  1 package child_module_name;                                                                                     
  3 use webman_db_item_update;                                                                                                       
  5 @ISA=("webman_db_item_update");                                                                                                  
  7 sub new {                                                                                                                        
  8     my $class = shift;                                                                                                           
 10     my $this = $class->SUPER::new();                                                                                             
 12     #$this->set_Debug_Mode(1, 1);                                                                                                
 14     bless $this, $class;                                                                                                         
 16     return $this;                                                                                                                
 17 }                                                                                                                                
 19 sub get_Name {                                                                                                                   
 20     my $this = shift @_;                                                                                                         
 22     return __PACKAGE__;                                                                                                          
 23 }                                                                                                                                
 25 sub get_Name_Full {                                                                                                              
 26     my $this = shift @_;                                                                                                         
 28     return $this->SUPER::get_Name_Full . "::" . __PACKAGE__;                                                                     
 29 }                                                                                                                                
 31 sub run_Task {                                                                                                                   
 32     my $this = shift @_;                                                                                                         
 34     my $cgi = $this->get_CGI;                                                                                                    
 35     my $dbu = $this->get_DBU;                                                                                                    
 36     my $db_conn = $this->get_DB_Conn;                                                                                            
 38     my $login_name = $this->get_User_Login;                                                                                      
 39     my @groups = $this->get_User_Groups;                                                                                         
 41     my $match_group = $this->match_Group($group_name_, @groups);                                                                 
 43     if ($this->init_Phase) {                                                                                                     
 44         ### init. phase extra tasks                                                                                              
 45         #$cgi->add_Debug_Text("init_Phase", __FILE__, __LINE__, "TRACING");                                                      
 47     } elsif ($this->confirm_Phase) {                                                                                             
 48         ### confirm phase extra tasks                                                                                            
 49         #$cgi->add_Debug_Text("confirm_Phase", __FILE__, __LINE__, "TRACING");                                                   
 51     } elsif ($this->edit_Phase) {                                                                                                
 52         ### edit phase extra tasks                                                                                               
 53         #$cgi->add_Debug_Text("edit_Phase", __FILE__, __LINE__, "TRACING");                                                      
 55     } elsif($this->last_Phase) {                                                                                                 
 56         ### last phase extra tasks                                                                                               
 57         #$cgi->add_Debug_Text("last_Phase", __FILE__, __LINE__, "TRACING");                                                      
 58     }                                                                                                                            
 60     my $status = $this->SUPER::run_Task();                                                                                       
 62     if ($status) {                                                                                                               
 63         ### extra tasks after update operation is succeed                                                                        
 64     }                                                                                                                            
 65 }                                                                                                                                
 67 sub end_Task {                                                                                                                   
 68     my $this = shift @_;                                                                                                         
 70     my $cgi = $this->get_CGI;                                                                                                    
 71     my $dbu = $this->get_DBU;                                                                                                    
 72     my $db_conn = $this->get_DB_Conn;                                                                                            
 74     my $login_name = $this->get_User_Login;                                                                                      
 75     my @groups = $this->get_User_Groups;                                                                                         
 77     ### Skeleton code to check if current user's groups are match with                                                           
 78     ### specific intended group name.                                                                                            
 79     #my $group_name = "???";                                                                                                     
 80     #my $match_group = $this->match_Group($group_name, @groups);                                                                 
 82     ### It's mandatory to call this for multi phases modules                                                                     
 83     ### to reset some of the no longer required CGI data.                                                                        
 84     $this->SUPER::end_Task();                                                                                                    
 86     ### Put other extra end-task jobs after this line.                                                                           
 88     ### Set to other related content.                                                                                            
 89     #$this->set_Content("...");                                                                                                  
 91     ### Jump to other URL.                                                                                                       
 92     #$cgi->redirect_Page($url);                                                                                                  
 93 }                                                                                                                                
 95 ### This function will be called just before the update                                                                          
 96 ### operation is implemented inside the run_Task function.                                                                       
 97 sub customize_CGI_Data { ### 11/10/2011                                                                                          
 98     my $this = shift @_;                                                                                                         
 99     my $te = shift @_;                                                                                                           
101     my $cgi = $this->get_CGI;                                                                                                    
102     my $dbu = $this->get_DBU;                                                                                                    
103     my $db_conn = $this->get_DB_Conn;                                                                                            
105     ### Example on how to add/update other linked table primary keys                                                             
106     ### (linked_table_PK) that act as a foreign keys inside current table                                                        
107     ### by refering to one of current table field that act as a unique keys                                                      
108     ### inside the linked table (linked_table_UK)                                                                                
109     #$dbu->set_Table("linked_table_name");                                                                                       
110     #my $linked_table_PK = $dbu->get_Item("linked_table_PK", "linked_table_UK", $cgi->param("\$db_linked_table_UK"));            
111     #$cgi->push_Param("\$db_linked_table_PK", $linked_table_PK);                                                                 
112 }                                                                                                                                
114 1;