--********************************************************************************** -- This template represents the basic procedure needed to automatically -- generate the abstract interface packages. All fragments in uppercase type -- are replaced by application specific variables, types, etc. as noted in -- comments near the fragment. All lower case fragments are constant within the -- actual procedure and can be used directly as shown here. A version -- of this template without explanatory comments is supplied at the -- end of this file --********************************************************************************** -- STEP 1 ************************************************************************** with base_specific_domains; use base_specific_domains; -- a package automatically generated by abstract_domain_generator. with abstract_interface_generator; -- package containing all interface generator generics to instantiate. with generator_support; use generator_support; -- package containing all constants, types, etc. -- STEP 2 ************************************************************************** procedure INTERFACE_VIEW is -- can name procedure any valid Ada variable name -- STEP 3 ************************************************************************** -- Define an enumeration type representing the record names to be included -- in the interface. type RECORD_NAMES is (REC_NAME1, REC_NAME2, REC_NAME3.. EX-> A_Rec, Business_Rec); -- type name can be any valid Ada type name -- STEP 4 ************************************************************************** -- Define an enumeration type representing the procedure names to be included -- in the interface. type PROCEDURE_NAMES is (PROC_NAME1, PROC_NAME2, PROC_NAME3.. EX-> Fetch_Rec, Close_Cursor, Update_Rec); -- type name can be any valid Ada type name -- STEP 5 ************************************************************************** -- Define an enumeration types representing and those errors allowed -- (expected) from the database during application program execution type OK_ERRORS is (ERROR1, ERROR2, ERROR3.. EX-> Not_Found, Bad_Rec, Cursor_Not_Opened); -- type name can be any valid Ada type name -- STEP 6 ************************************************************************** -- Next, instantiate abstract_interface_generator with eight parameters. -- (1) A string representing the name to be given to the concrete module. -- (2) A string representing the name to be given to the abstract interface. -- (3) A string representing the name to be given to the Dbms_Specific text file. -- (4) An array of domain package names that will be used by this interface. -- Invalid domain names will be caught at compilation. -- (5) The previously declared enumeration type representing the names of the records -- to be included in the specification. -- (6) The enumeration type representing the procedures included in the abstract -- interface. -- (7) The enumeration type representing those errors expected from the database. -- (8) The final parameter is an array of integer values which correspond with -- the errors expected from the database. package MY_INTERFACE is new abstract_interface_generator ("CONCRETE_INTERFACE_NAME", "ABSTRACT_INTERFACE_NAME", "DBMS_SPECIFIC_FILE_NAME",(DOMAIN_PKG_ARRAY), RECORD_NAMES, PROCEDURE_NAMES, OK_ERRORS, (ERROR_INTEGER_VALUE_ARRAY).. EX-> "Conc_Interface","Abs_Interface","Dbms_File", (1 => Domain_Def_Pkg_1, 2=> Domain_Def_Pkg_2), RECORD_NAMES, PROCEDURE_NAMES, OK_ERRORS, (1=> -100, 2=> -25, 3=> -501)); use MY_INTERFACE; -- not required, however, use clause suggested for clarity in subsequent package instantiations -- STEP 7 *********************************************************************** -- Perform steps 7-10 for each record name declared above. -- These steps instantiate the second level generic -- package, Generate_Record, with names of all record components belonging -- to this record and the name (from the list of valid record -- names) of this record. Note that from now on, only these component -- names and this specific record name will be recognized during -- elaboration subsequent generic packages. -- Important note: Both record names and component names can only be used -- once. begin declare -- The first stage of the process for generating record descriptions is to declare an enumeration type representing -- the components of the first record declared in the previously defined -- enumeration type representing records names. The components must be valid Ada identifiers. type REC_COMPONENTS is (COMPONENT_NAME1, COMPONENT_NAME2, COMPONENT_NAME3.. EX -> Name, Soc_Num, Status); -- STEP 8 ********************************************************************** -- The next stage is to instantiate the record_generator generic with the enumeration type -- representing the record components, the name of the record and a boolean value which tells whether -- this record is used for returning indicator values to the application (true) or if -- it is used to store or fetch a row record (false). The record name must be a valid one defined -- previously in the RECORD_NAMES enumeration type. Note any invalid values used as -- parameters will be caught at compile time. The previous 'use clause' for MY_INTERFACE -- allowed direct use of record_generator generic (without MY_INTERFACE.record_generator). The -- package name is left to the user but must be used consistently throughout the rest of the procedure. package REC1 is new record_generator (REC_COMPONENTS, REC_NAME1, TRUE/FALSE.. EX-> REC_COMPONENTS, A_Rec, false); -- STEP 9 ********************************************************************** -- Perform step 9 once for each component defined in the REC_COMPONENTS -- enumeration type. Instantiate the component_generator generic with -- two parameters. The first parameter is the record component name (an -- invalid name will be caught at compile time). The second parameter is -- the domain type from the previously defined domain packages. If this -- record is used to keep track of string truncation, then this -- generic is instantiated with only the component name and the domain type -- is left blank. REC2 provides an example of a record of string truncation -- indicators. package COM_11 is new REC1.component_generator(COMP_NAME1, DOMAIN_TYPE.. EX_> Name, Name_Not_Null); package COM_12 is new REC1.component_generator(COMP_NAME2, DOMAIN_TYPE.. EX-> Soc_Num, Sno_Type); package COM_13 is new REC1.component_generator(COMP_NAME3, DOMAIN_TYPE.. EX-> Status, Status_Not_null); -- STEP 10 ********************************************************************** -- The next step is to call the procedure to actually generate the records. begin REC1.generate_records; end; -- Example of record definition when record is used to track string truncation. declare type REC2_COMPONENTS is (COMP_NAME1, COMP_NAME2.. EX-> Title, Salary); package REC2 is new record_generator(REC2_COMPONENTS, REC_NAME2, TRUE/FALSE.. EX-> REC2_COMPONENTS,Business_Rec,true); package COM_21 is new REC2.component_generator(COMP_NAME1.. EX->Title); package COM_22 is new REC2.component_generator(COMP_NAME2.. EX-> Salary); begin REC2.generate_records; end; -- STEP 11 ********************************************************************** -- Perform step 11 once for each procedure represented by the PROCEDURE_NAMES -- enumeration type. There are two choices of procedure types to be -- included within the abstract interface: procedures with parameters and -- procedures without parameters. The first example for PROC_NAME1 -- is an example of a procedure with parameters and the second, PROC_NAME2, -- is a procedure without parameters. Each procedure defined above must be -- described as one or the other procedure types. -- ***************To describe a procedure with parameters*********************** -- First declare an enumeration type to represent the parameters of the -- abstract procedure. Second, declare an enumeration type to represent -- the parameters to the concrete procedure. The abstract parameters -- will be some subset of the following: -- (1) A single parameter of a valild domain type. -- (2) A parameter of valid record type -- (3) A boolean result information type OR -- (4) A error condition parameter name to represent this procedure's subset -- of expected errors. -- The concrete parameters will be some corresponding subset of: -- (1) A single parameter of a valild domain type. -- (2) A component of the record that has been used as an abstract -- procedure parameter. (Note indicator parameters are not declared -- here but generated automatically. -- (3) A boolean result information type OR -- (4) A error condition parameter name to represent this procedure's subset -- of expected errors. -- A boolean result parameter and an error condition result parameter may -- not be used in the same procedure. declare type PROC1_ABSTRACT_PARAMS is (ABS_PARAM1, ABS_PARAM2.. EX-> Sno, Personnel_Rec, Exists); type PROC1_CONCRETE_PARAMS is (CON_PARAM1, CON_PARAM2.. EX-> Sno, Name, Soc_Num, Status, Exists); -- Note that Sno and Exisits are parameters to the abstract procedure -- and Name, Soc_Num, and Status are components of the A_Rec record type. -- Next, instantiate the procedure_generator generic for the procedure -- and its parameters. It is instantiated with six parameters. -- (1) The first parameter must be a valid procedure name as declared above. -- (2) The second is the enumeration type representing this procedure's -- abstract paramaters. -- (3) The third is the type of sql statement this procedure will be calling. -- Choices for this are given in the enumeration type -- sql_statement_types declared in generator_support package. -- (4) The fourth is a string representing the concrete procedure name called by this -- procedure as during generation the concrete specification is also being generated. -- (5) The fifth parameter is the enumeration type representing the parameters to the -- concrete procedure. -- (6) The last parameter is an array of errors expected from the database. -- Each value must be valid as defined in the enumeration type used in -- the instantiation of abstract_interface_generator. -- Note that if a boolean reuslt parameter is used for this procedure, -- then this array can contain at most only one error or can be left -- blank for no errors. package PROCEDURE1 is new procedure_with_parameters_generator (PROC_NAME1, PROC1_ABSTRACT_PARAMS, SQL_PROC_TYPE, "CONCRETE_PROC_NAME", PROC1_CONCRETE_PARAMS, (1=> ERROR1, 2=> ERROR2).. EX-> Fetch_Rec, PROC1_ABSTRACT_PARAMS, fetch, "ConcreteFetch", PROC1_CONCRETE_PARAMS, (Not_Found, Bad_Rec)); -- Next, instantiate the paramter generic appropriate for each abstract -- paramter for this procedure. Which generic is instantiated depends upon -- the type of the parameter. -- Choices are: -- (1) params_of_domain_type_generator -- Used when the parameter is of some domain type. -- (2) params_of_record_type_generator -- Used when the parameter is a record type. -- (3) params_of_boolean_type_generator -- Used when the parameter is a boolean result information parameter. -- (4) params_of_error_condition_generator -- Used when the parameter is of some enumeration type -- which represents the expected errors from the database -- See abstract_interface_generator specification for a more through description of each. -- Each generic is instantiated with the parameter name. In addition, the -- domain_type generic and the record_type generic also take a parameter -- representing the type of the parameter. package PARAM1 is new PROCEDURE1.params_of_domain_type_generator (ABS_PARAM1, DOMAIN_TYPE.. EX-> Sno, Sno_Not_Null); package PARAM2 is new PROCEDURE1.params_of_record_type_generator (ABS_PARAM2, RECORD_TYPE.. EX-> Personnel_Rec, A_Rec); package PARAM3 is new PROCEDURE1.params_of_error_condition_generator (ABS_PARAM3.. EX-> Exists); -- Finally, call the procedure that generate the procedure declarations. begin PROCEDURE1.generate_procedures; end; -- ***************To describe a procedure without parameters******************** -- Instantiate the procedure_without_parameters_generator generic with -- the corresponding procedure name (PROC_NAME2 in this example), -- the sql_statement type, and a string representing the name of the concrete -- procedure to call. Then call the procedure that generates the -- procedure declarations. declare package PROCEDURE2 is new procedure_without_parameters_generator (PROC_NAME2, SQL_PROC_TYPE, "CONCRETE_PROC_NAME".. EX-> Close_Cursor, close, "ConcreteClose"); begin PROCEDURE2.generate_prodedure; end; -- STEP 1 ************************************************************************** -- The final step when generating the abstract interface is to call the procedure -- which finishes up the entire process by closing files, performing final error checks, etc MY_INTERFACE.generate_interface; -- Note use of dot notation. This is not necessary since we 'used' the -- generic instantiation package "MY_INTERFACE". end INTERFACE_VIEW; -- ****************************************************************************** -- Template without explanatory comments -- ****************************************************************************** with base_specific_domains; use base_specific_domains; with abstract_interface_generator; with generator_support; use generator_support; procedure INTERFACE_VIEW is type RECORD_NAMES is (REC_NAME1, REC_NAME2, REC_NAME3); type PROCEDURE_NAMES is (PROC_NAME1, PROC_NAME2, PROC_NAME3); type OK_ERRORS is (ERROR1, ERROR2, ERROR3); package MY_INTERFACE is new abstract_interface_generator ("CONCRETE_INTERFACE_NAME", "ABSTRACT_INTERFACE_NAME", "DBMS_SPECIFIC_FILE_NAME",(DOMAIN_PKG_ARRAY), RECORD_NAMES, PROCEDURE_NAMES, OK_ERRORS, (ERROR_INTEGER_VALUE_ARRAY)); use MY_INTERFACE; begin declare type REC_COMPONENTS is (COMP_NAME1, COMP_NAME2, COMP_NAME3); package REC1 is new record_generator (REC_COMPONENTS, REC_NAME1, FALSE); package COM_11 is new REC1.component_generator(COMP_NAME1, DOMAIN_TYPE); package COM_12 is new REC1.component_generator(COMP_NAME2, DOMAIN_TYPE); package COM_13 is new REC1.component_generator(COMP_NAME3, DOMAIN_TYPE); -- Addtional component definitions here... begin REC1.generate_records; end; declare type REC2_COMPONENTS is (COMPONENT_NAME1, COMPONENT_NAME2) package REC2 is new record_generator(REC2_COMPONENTS, REC_NAME2, TRUE); package COM_21 is new REC2.component_generator(COMP1); package COM_22 is new REC2.component_generator(COMP2); begin REC2.generate_records; end; -- Addtional record definitions here... declare type PROC1_ABSTRACT_PARAMS is (ABS_PARAM1, ABS_PARAM2); type PROC1_CONCRETE_PARAMS is ((CON_PARAM1, CON_PARAM2); package PROCEDURE1 is new procedure_with_parameters_generator (PROC_NAME1, PROC1_ABSTRACT_PARAMS, SQL_PROC_TYPE, "CONCRETE_PROC_NAME", PROC1_CONCRETE_PARAMS, (1=> ERROR1, 2=> ERROR2)); package PARAM1 is new PROCEDURE1.params_of_domain_type_generator (ABS_PARAM1, DOMAIN_TYPE); package PARAM2 is new PROCEDURE1.params_of_record_type_generator (ABS_PARAM2, RECORD_TYPE); package PARAM3 is new PROCEDURE1.params_of_error_condition_generator (ABS_PARAM3); -- Additonal parameter definitions here... begin PROCEDURE1.generate_procedures; end; declare package PROCEDURE2 is new procedure_without_parameters_generator (PROC_NAME2, SQL_PROC_TYPE, "CONCRETE_PROC_NAME"); begin PROCEDURE2.generate_prodedure; end; -- Additional procedure definitions here... MY_INTERFACE.generate_interface; end INTERFACE_VIEW;