home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / sql / sqldd2.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  50.6 KB  |  1,835 lines

  1. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2. --token.ada
  3. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4. with TEXT_IO;
  5.   use TEXT_IO;
  6.  
  7. package TOKEN_INPUT is
  8.  
  9.   type INPUT_STREAM is private;
  10.  
  11.   package INTEGER_IO is new TEXT_IO.INTEGER_IO(INTEGER);
  12.     use INTEGER_IO;
  13.  
  14.   function CREATE_STREAM(CARD_LENGTH : POSITIVE) return INPUT_STREAM;
  15.  
  16.   procedure SET_STREAM(STREAM : INPUT_STREAM);
  17.  
  18.   procedure OPEN_INPUT(STREAM : INPUT_STREAM;
  19.                        NAME   : STRING);
  20.  
  21.   procedure OPEN_INPUT(NAME : STRING);
  22.  
  23.   procedure CLOSE_INPUT(STREAM : INPUT_STREAM);
  24.  
  25.   procedure CLOSE_INPUT;
  26.  
  27.   procedure GET_STRING(STREAM : in  INPUT_STREAM;
  28.                        STR    : out STRING;
  29.                        LAST   : out NATURAL);
  30.  
  31.   procedure GET_STRING(STR  : out STRING;
  32.                        LAST : out NATURAL);
  33.  
  34.   function GET_INTEGER(STREAM : INPUT_STREAM) return INTEGER;
  35.  
  36.   function GET_INTEGER return INTEGER;
  37.  
  38.   procedure GOBBLE(STREAM : INPUT_STREAM;
  39.                    STR    : STRING);
  40.  
  41.   procedure GOBBLE(STR : STRING);
  42.  
  43. private
  44.  
  45.   type INPUT_RECORD(CARD_LENGTH : POSITIVE) is
  46.     record
  47.       BUFFER : STRING(1..CARD_LENGTH);
  48.       FILE   : FILE_TYPE;
  49.       NEXT   : POSITIVE := 1;
  50.       LAST   : NATURAL := 0;
  51.     end record;
  52.  
  53.   type INPUT_STREAM is access INPUT_RECORD;
  54.  
  55. end TOKEN_INPUT;
  56.  
  57. package body TOKEN_INPUT is
  58.  
  59.   DEFAULT_STREAM : INPUT_STREAM;
  60.  
  61.   function CREATE_STREAM(CARD_LENGTH : POSITIVE) return INPUT_STREAM is
  62.   begin
  63.     return new INPUT_RECORD(CARD_LENGTH);
  64.   end CREATE_STREAM;
  65.  
  66.   procedure SET_STREAM(STREAM : INPUT_STREAM) is
  67.   begin
  68.     DEFAULT_STREAM := STREAM;
  69.   end SET_STREAM;
  70.  
  71.   procedure OPEN_INPUT(STREAM : INPUT_STREAM;
  72.                        NAME   : STRING) is
  73.   begin
  74.     OPEN(STREAM.FILE,IN_FILE,NAME);
  75.   end OPEN_INPUT;
  76.  
  77.   procedure OPEN_INPUT(NAME : STRING) is
  78.   begin
  79.     OPEN_INPUT(DEFAULT_STREAM,NAME);
  80.   end OPEN_INPUT;
  81.  
  82.   procedure CLOSE_INPUT(STREAM : INPUT_STREAM) is
  83.   begin
  84.     CLOSE(STREAM.FILE);
  85.   end CLOSE_INPUT;
  86.  
  87.   procedure CLOSE_INPUT is
  88.   begin
  89.     CLOSE_INPUT(DEFAULT_STREAM);
  90.   end CLOSE_INPUT;
  91.  
  92.   function ALPHABETIC(C : CHARACTER) return BOOLEAN is
  93.   begin
  94.     return C in 'A'..'Z' or else C in 'a'..'z' or else C = '_';
  95.   end ALPHABETIC;
  96.  
  97.   function NUMERIC(C : CHARACTER) return BOOLEAN is
  98.   begin
  99.     return C in '0'..'9' or else C = '_';
  100.   end NUMERIC;
  101.  
  102.   function WHITESPACE(C : CHARACTER) return BOOLEAN is
  103.   begin
  104.     return C = ' ' or else C = ASCII.HT;
  105.   end WHITESPACE;
  106.  
  107.   procedure NEXT_LINE(STREAM : INPUT_STREAM) is
  108.   begin
  109.     loop
  110.       GET_LINE(STREAM.FILE,STREAM.BUFFER,STREAM.LAST);
  111.       exit when STREAM.LAST >= 2 and then STREAM.BUFFER(1..2) /= "--";
  112.       exit when STREAM.LAST = 1;
  113.     end loop;
  114.     STREAM.NEXT := 1;
  115.   end NEXT_LINE;
  116.  
  117.   procedure NEXT_TOKEN(STREAM : INPUT_STREAM) is
  118.   begin
  119.     loop
  120.       if STREAM.NEXT > STREAM.LAST then
  121.         NEXT_LINE(STREAM);
  122.       end if;
  123.       if STREAM.BUFFER(STREAM.NEXT) = '-' and then
  124.           STREAM.NEXT < STREAM.LAST and then
  125.           STREAM.BUFFER(STREAM.NEXT+1) = '-' then
  126.         NEXT_LINE(STREAM);
  127.       end if;
  128.       exit when not WHITESPACE(STREAM.BUFFER(STREAM.NEXT));
  129.       STREAM.NEXT := STREAM.NEXT + 1;
  130.     end loop;
  131.   end NEXT_TOKEN;
  132.  
  133.   function TOKEN_END(STREAM : INPUT_STREAM) return POSITIVE is
  134.     C   : CHARACTER;
  135.     PTR : POSITIVE;
  136.   begin
  137.     NEXT_TOKEN(STREAM);
  138.     PTR := STREAM.NEXT;
  139.     while PTR <= STREAM.LAST loop
  140.       C := STREAM.BUFFER(PTR);
  141.       exit when WHITESPACE(C);
  142.       case STREAM.BUFFER(STREAM.NEXT) is
  143.         when 'A'..'Z' | 'a'..'z' =>
  144.           exit when not ALPHABETIC(C) and then not NUMERIC(C);
  145.         when '0'..'9' | '-' | '+' =>
  146.           exit when not NUMERIC(C);
  147.         when others =>
  148.           exit when ALPHABETIC(C) or else NUMERIC(C);
  149.       end case;
  150.       PTR := PTR + 1;
  151.     end loop;
  152.     return PTR - 1;
  153.   end TOKEN_END;
  154.  
  155.   procedure GET_STRING(STREAM : in  INPUT_STREAM;
  156.                        STR    : out STRING;
  157.                        LAST   : out NATURAL) is
  158.     TOKEND,
  159.     TLAST : POSITIVE;
  160.   begin
  161.     TOKEND := TOKEN_END(STREAM);
  162.     TLAST := STR'FIRST + TOKEND - STREAM.NEXT;
  163.     STR(STR'FIRST..TLAST) := STREAM.BUFFER(STREAM.NEXT..TOKEND);
  164.     LAST := TLAST;
  165.     STREAM.NEXT := TOKEND + 1;
  166.   end GET_STRING;
  167.  
  168.   procedure GET_STRING(STR  : out STRING;
  169.                        LAST : out NATURAL) is
  170.   begin
  171.     GET_STRING(DEFAULT_STREAM,STR,LAST);
  172.   end GET_STRING;
  173.  
  174.   function GET_INTEGER(STREAM : INPUT_STREAM) return INTEGER is
  175.     TOKEND : POSITIVE;
  176.     INT,
  177.     LAST   : INTEGER;
  178.   begin
  179.     TOKEND := TOKEN_END(STREAM);
  180.     GET(STREAM.BUFFER(STREAM.NEXT..TOKEND),INT,LAST);
  181.     STREAM.NEXT := TOKEND + 1;
  182.     return INT;
  183.   end GET_INTEGER;
  184.  
  185.   function GET_INTEGER return INTEGER is
  186.   begin
  187.     return GET_INTEGER(DEFAULT_STREAM);
  188.   end GET_INTEGER;
  189.  
  190.   procedure GOBBLE(STREAM : INPUT_STREAM;
  191.                    STR    : STRING) is
  192.     S    : STRING(1..STREAM.CARD_LENGTH);
  193.     LAST : INTEGER;
  194.   begin
  195.     GET_STRING(STREAM,S,LAST);
  196.     if S(1..LAST) /= STR then
  197.       raise CONSTRAINT_ERROR;
  198.     end if;
  199.   end GOBBLE;
  200.  
  201.   procedure GOBBLE(STR : STRING) is
  202.   begin
  203.     GOBBLE(DEFAULT_STREAM,STR);
  204.   end GOBBLE;
  205.  
  206. end TOKEN_INPUT;
  207. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  208. --ddldefs.ada
  209. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  210. package DDL_DEFINITIONS is
  211.  
  212.   type TYPE_TYPE is (SUB_TYPE, REC_ORD, ENUMERATION, INT_EGER, FL_OAT,
  213.       STR_ING);
  214.  
  215.   type TYPE_NAME_STRING is new STRING;
  216.   type TYPE_NAME        is access TYPE_NAME_STRING;
  217.  
  218.   type TYPE_DESCRIPTOR(TY_PE : TYPE_TYPE);
  219.   type ACCESS_TYPE_DESCRIPTOR is access TYPE_DESCRIPTOR;
  220.  
  221.   subtype ACCESS_SUBTYPE_DESCRIPTOR     is ACCESS_TYPE_DESCRIPTOR(SUB_TYPE);
  222.   subtype ACCESS_RECORD_DESCRIPTOR      is ACCESS_TYPE_DESCRIPTOR(REC_ORD);
  223.   subtype ACCESS_ENUMERATION_DESCRIPTOR is ACCESS_TYPE_DESCRIPTOR(ENUMERATION);
  224.   subtype ACCESS_INTEGER_DESCRIPTOR     is ACCESS_TYPE_DESCRIPTOR(INT_EGER);
  225.   subtype ACCESS_FLOAT_DESCRIPTOR       is ACCESS_TYPE_DESCRIPTOR(FL_OAT);
  226.   subtype ACCESS_STRING_DESCRIPTOR      is ACCESS_TYPE_DESCRIPTOR(STR_ING);
  227.  
  228.   type COMPONENT_NAME_STRING is new STRING;
  229.   type COMPONENT_NAME        is access COMPONENT_NAME_STRING;
  230.  
  231.   type COMPONENT_DESCRIPTOR;
  232.   type ACCESS_COMPONENT_DESCRIPTOR is access COMPONENT_DESCRIPTOR;
  233.  
  234.   type COMPONENT_DESCRIPTOR is
  235.     record
  236.       NEXT_COMPONENT,
  237.       PREVIOUS_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  238.       NAME               : COMPONENT_NAME;
  239.       TY_PE,
  240.       PARENT_RECORD      : ACCESS_TYPE_DESCRIPTOR;
  241.     end record;
  242.  
  243.   type SUBRECORD_INDICATOR is new BOOLEAN;
  244.  
  245.   type LITERAL_DESCRIPTOR;
  246.   type ACCESS_LITERAL_DESCRIPTOR is access LITERAL_DESCRIPTOR;
  247.  
  248.   type ENUMERATION_NAME_STRING is new STRING;
  249.   type ENUMERATION_NAME        is access ENUMERATION_NAME_STRING;
  250.  
  251.   type ENUMERATION_POS is new NATURAL;
  252.  
  253.   type LITERAL_DESCRIPTOR is
  254.     record
  255.       NEXT_LITERAL,
  256.       PREVIOUS_LITERAL : ACCESS_LITERAL_DESCRIPTOR;
  257.       NAME             : ENUMERATION_NAME;
  258.       POS              : ENUMERATION_POS;
  259.       PARENT_TYPE      : ACCESS_TYPE_DESCRIPTOR;
  260.     end record;
  261.  
  262.   type STRING_LENGTH is new NATURAL;
  263.  
  264.   type TYPE_DESCRIPTOR(TY_PE : TYPE_TYPE) is
  265.     record
  266.       NAME         : TYPE_NAME;
  267.       NEXT_TYPE,
  268.       PREVIOUS_TYPE,
  269.       FIRST_SUBTYPE,
  270.       LAST_SUBTYPE : ACCESS_TYPE_DESCRIPTOR;
  271.       case TY_PE is
  272.         when SUB_TYPE =>
  273.           PARENT_TYPE,
  274.           TOP_TYPE,
  275.           NEXT_SUBTYPE,
  276.           PREVIOUS_SUBTYPE : ACCESS_TYPE_DESCRIPTOR;
  277.         when REC_ORD =>
  278.           FIRST_COMPONENT,
  279.           LAST_COMPONENT   : ACCESS_COMPONENT_DESCRIPTOR;
  280.           IS_SUBRECORD     : SUBRECORD_INDICATOR := FALSE;
  281.         when ENUMERATION =>
  282.           FIRST_LITERAL,
  283.           LAST_LITERAL     : ACCESS_LITERAL_DESCRIPTOR;
  284.           LAST_POS         : ENUMERATION_POS := 0;
  285.           MAX_LENGTH       : NATURAL := 0;
  286.         when INT_EGER | FL_OAT =>
  287.           null;
  288.         when STR_ING =>
  289.           LENGTH : STRING_LENGTH;
  290.       end case;
  291.     end record;
  292.  
  293. end DDL_DEFINITIONS;
  294. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  295. --listutil.ada
  296. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  297. with DDL_DEFINITIONS;
  298.   use DDL_DEFINITIONS;
  299.  
  300. package LIST_UTILITIES is
  301.  
  302.   function FIRST_TYPE_DESCRIPTOR return ACCESS_TYPE_DESCRIPTOR;
  303.  
  304.   function FIND_TYPE_DESCRIPTOR(NAME : TYPE_NAME_STRING)
  305.       return ACCESS_TYPE_DESCRIPTOR;
  306.  
  307.   procedure ADD_TYPE(T : ACCESS_TYPE_DESCRIPTOR);
  308.  
  309.   procedure ADD_SUBTYPE(PARENT : ACCESS_TYPE_DESCRIPTOR;
  310.                         CHILD  : ACCESS_SUBTYPE_DESCRIPTOR);
  311.  
  312.   procedure ADD_LITERAL(PARENT : ACCESS_ENUMERATION_DESCRIPTOR;
  313.                         CHILD  : ACCESS_LITERAL_DESCRIPTOR);
  314.  
  315.   procedure ADD_COMPONENT(PARENT : ACCESS_RECORD_DESCRIPTOR;
  316.                           CHILD  : ACCESS_COMPONENT_DESCRIPTOR);
  317.  
  318. end LIST_UTILITIES;
  319.  
  320. package body LIST_UTILITIES is
  321.  
  322.   TYPE_DESCRIPTOR_0,                          -- type listhead -- first & last
  323.   TYPE_DESCRIPTOR_9 : ACCESS_TYPE_DESCRIPTOR; --  type descriptors
  324.  
  325.   function FIRST_TYPE_DESCRIPTOR return ACCESS_TYPE_DESCRIPTOR is
  326.   begin
  327.     return TYPE_DESCRIPTOR_0;
  328.   end FIRST_TYPE_DESCRIPTOR;
  329.  
  330.   function FIND_TYPE_DESCRIPTOR(NAME : TYPE_NAME_STRING)
  331.       return ACCESS_TYPE_DESCRIPTOR is
  332.     T : ACCESS_TYPE_DESCRIPTOR := TYPE_DESCRIPTOR_0;
  333.   begin
  334.     while T.NAME.all /= NAME loop
  335.       T := T.NEXT_TYPE; -- CONSTRAINT_ERROR if non-existent type name
  336.     end loop;
  337.     return T;
  338.   end FIND_TYPE_DESCRIPTOR;
  339.  
  340.   procedure ADD_TYPE(T : ACCESS_TYPE_DESCRIPTOR) is
  341.   begin
  342.     if TYPE_DESCRIPTOR_9 = null then
  343.       TYPE_DESCRIPTOR_0 := T;
  344.     else
  345.       TYPE_DESCRIPTOR_9.NEXT_TYPE := T;
  346.     end if;
  347.     T.PREVIOUS_TYPE := TYPE_DESCRIPTOR_9;
  348.     TYPE_DESCRIPTOR_9 := T;
  349.     T.NEXT_TYPE := null;
  350.   end ADD_TYPE;
  351.  
  352.   procedure ADD_SUBTYPE(PARENT : ACCESS_TYPE_DESCRIPTOR;
  353.                         CHILD  : ACCESS_SUBTYPE_DESCRIPTOR) is
  354.   begin
  355.     if PARENT.LAST_SUBTYPE = null then
  356.       PARENT.FIRST_SUBTYPE := CHILD;
  357.     else
  358.       PARENT.LAST_SUBTYPE.NEXT_SUBTYPE := CHILD;
  359.     end if;
  360.     CHILD.PREVIOUS_SUBTYPE := PARENT.LAST_SUBTYPE;
  361.     PARENT.LAST_SUBTYPE := CHILD;
  362.     CHILD.NEXT_SUBTYPE := null;
  363.     CHILD.PARENT_TYPE := PARENT;
  364.   end ADD_SUBTYPE;
  365.  
  366.   procedure ADD_LITERAL(PARENT : ACCESS_ENUMERATION_DESCRIPTOR;
  367.                         CHILD  : ACCESS_LITERAL_DESCRIPTOR) is
  368.   begin
  369.     if PARENT.LAST_LITERAL = null then
  370.       PARENT.FIRST_LITERAL := CHILD;
  371.     else
  372.       PARENT.LAST_LITERAL.NEXT_LITERAL := CHILD;
  373.     end if;
  374.     CHILD.PREVIOUS_LITERAL := PARENT.LAST_LITERAL;
  375.     PARENT.LAST_LITERAL := CHILD;
  376.     CHILD.NEXT_LITERAL := null;
  377.     CHILD.PARENT_TYPE := PARENT;
  378.   end ADD_LITERAL;
  379.  
  380.   procedure ADD_COMPONENT(PARENT : ACCESS_RECORD_DESCRIPTOR;
  381.                           CHILD  : ACCESS_COMPONENT_DESCRIPTOR) is
  382.   begin
  383.     if PARENT.LAST_COMPONENT = null then
  384.       PARENT.FIRST_COMPONENT := CHILD;
  385.     else
  386.       PARENT.LAST_COMPONENT.NEXT_COMPONENT := CHILD;
  387.     end if;
  388.     CHILD.PREVIOUS_COMPONENT := PARENT.LAST_COMPONENT;
  389.     PARENT.LAST_COMPONENT := CHILD;
  390.     CHILD.NEXT_COMPONENT := null;
  391.     CHILD.PARENT_RECORD := PARENT;
  392.   end ADD_COMPONENT;
  393.  
  394. end LIST_UTILITIES;
  395. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  396. --readddl.ada
  397. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  398. with DDL_DEFINITIONS, LIST_UTILITIES, TOKEN_INPUT;
  399.   use DDL_DEFINITIONS, LIST_UTILITIES, TOKEN_INPUT;
  400.  
  401. package READ_DDL is
  402.  
  403.   procedure SCAN_DDL(PACKAGE_NAME : out STRING;
  404.                      LAST         : out POSITIVE);
  405.  
  406. end READ_DDL;
  407.  
  408. package body READ_DDL is
  409.  
  410.   procedure PROCESS_DERIVED_TYPE(NEW_NAME : TYPE_NAME) is
  411.     KEYWORD  : STRING(1..7);
  412.     LAST     : POSITIVE;
  413.     STR_LAST : STRING_LENGTH;
  414.   begin
  415.     GET_STRING(KEYWORD,LAST);
  416.     if KEYWORD(1..LAST) = "INTEGER" then
  417.       ADD_TYPE ( new TYPE_DESCRIPTOR'(TY_PE => INT_EGER, NAME => NEW_NAME,
  418.           others => null) );
  419.       GOBBLE(";");
  420.     elsif KEYWORD(1..LAST) = "FLOAT" then
  421.       ADD_TYPE ( new TYPE_DESCRIPTOR'(TY_PE => FL_OAT,   NAME => NEW_NAME,
  422.           others => null) );
  423.       GOBBLE(";");
  424.     elsif KEYWORD(1..LAST) = "STRING" then
  425.       GOBBLE("("); GOBBLE("1"); GOBBLE("..");
  426.       STR_LAST := STRING_LENGTH(GET_INTEGER);
  427.       ADD_TYPE ( new TYPE_DESCRIPTOR'(TY_PE => STR_ING,  NAME => NEW_NAME,
  428.           LENGTH => STR_LAST, others => null) );
  429.       GOBBLE(");");
  430.     else
  431.       raise CONSTRAINT_ERROR; -- unrecognized type keyword
  432.     end if;
  433.   end PROCESS_DERIVED_TYPE;
  434.  
  435.   procedure PROCESS_ENUMERATION_TYPE(NEW_NAME : TYPE_NAME) is
  436.     PARENT    : ACCESS_ENUMERATION_DESCRIPTOR;
  437.     LITERAL   : ENUMERATION_NAME_STRING(1..80);
  438.     LAST      : POSITIVE;
  439.     DELIMITER : STRING(1..2);
  440.   begin
  441.     PARENT := new TYPE_DESCRIPTOR'(TY_PE => ENUMERATION, NAME => NEW_NAME,
  442.         LAST_POS => 0, MAX_LENGTH => 0, FIRST_LITERAL | LAST_LITERAL => null,
  443.         others => null);
  444.     ADD_TYPE(PARENT);
  445.     loop
  446.       GET_STRING(STRING(LITERAL),LAST);
  447.       PARENT.LAST_POS := PARENT.LAST_POS + 1;
  448.       if LAST > PARENT.MAX_LENGTH then
  449.         PARENT.MAX_LENGTH := LAST;
  450.       end if;
  451.       ADD_LITERAL ( PARENT, new LITERAL_DESCRIPTOR'(
  452.           NAME => new ENUMERATION_NAME_STRING'(LITERAL(1..LAST)),
  453.           POS  => PARENT.LAST_POS, PARENT_TYPE => PARENT, others => null) );
  454.       GET_STRING(DELIMITER,LAST);
  455.       if DELIMITER(1..LAST) = ");" then
  456.         exit;
  457.       elsif DELIMITER(1..LAST) /= "," then
  458.         raise CONSTRAINT_ERROR; -- invalid enumeration literal list
  459.       end if;
  460.     end loop;
  461.   end PROCESS_ENUMERATION_TYPE;
  462.  
  463.   procedure PROCESS_RECORD_TYPE(NEW_NAME : TYPE_NAME) is
  464.     FIELD_TYPE_NAME : TYPE_NAME_STRING(1..80);
  465.     FIELD_NAME      : COMPONENT_NAME_STRING(1..80);
  466.     FIELD_TYPE      : ACCESS_TYPE_DESCRIPTOR;
  467.     PARENT          : ACCESS_RECORD_DESCRIPTOR;
  468.     FIELD_TYPE_LAST,
  469.     FIELD_LAST      : POSITIVE;
  470.   begin
  471.     PARENT := new TYPE_DESCRIPTOR'(TY_PE => REC_ORD, NAME => NEW_NAME,
  472.         IS_SUBRECORD => FALSE, FIRST_COMPONENT | LAST_COMPONENT => null,
  473.         others => null);
  474.     ADD_TYPE(PARENT);
  475.     loop
  476.       GET_STRING(STRING(FIELD_NAME),FIELD_LAST);
  477.       if FIELD_NAME(1..FIELD_LAST) = "end" then
  478.         GOBBLE("record"); GOBBLE(";");
  479.         exit;
  480.       end if;
  481.       GOBBLE(":");
  482.       GET_STRING(STRING(FIELD_TYPE_NAME),FIELD_TYPE_LAST);
  483.       FIELD_TYPE := FIND_TYPE_DESCRIPTOR(FIELD_TYPE_NAME(1..FIELD_TYPE_LAST));
  484.       if FIELD_TYPE.TY_PE = REC_ORD then
  485.         FIELD_TYPE.IS_SUBRECORD := TRUE;
  486.       end if;
  487.       ADD_COMPONENT ( PARENT, new COMPONENT_DESCRIPTOR' (
  488.           NAME  => new COMPONENT_NAME_STRING'(FIELD_NAME(1..FIELD_LAST)),
  489.           TY_PE => FIELD_TYPE, PARENT_RECORD => PARENT, others => null ) );
  490.       GOBBLE(";");
  491.     end loop;
  492.   end PROCESS_RECORD_TYPE;
  493.  
  494.   procedure PROCESS_TYPE is
  495.     NAME_STRING    : TYPE_NAME_STRING(1..80);
  496.     NAME           : TYPE_NAME;
  497.     LAST           : POSITIVE;
  498.     TYPE_INDICATOR : STRING(1..6);
  499.   begin
  500.     GET_STRING(STRING(NAME_STRING),LAST);
  501.     NAME := new TYPE_NAME_STRING'(NAME_STRING(1..LAST));
  502.     GOBBLE("is");
  503.     GET_STRING(TYPE_INDICATOR,LAST);
  504.     if TYPE_INDICATOR(1..LAST) = "(" then
  505.       PROCESS_ENUMERATION_TYPE(NAME);
  506.     elsif TYPE_INDICATOR(1..LAST) = "new" then
  507.       PROCESS_DERIVED_TYPE(NAME);
  508.     elsif TYPE_INDICATOR(1..LAST) = "record" then
  509.       PROCESS_RECORD_TYPE(NAME);
  510.     else
  511.       raise CONSTRAINT_ERROR; -- unrecognized type keyword/indicator
  512.     end if;
  513.   end PROCESS_TYPE;
  514.  
  515.   procedure PROCESS_SUBTYPE is
  516.     CHILD_NAME,
  517.     PARENT_NAME       : TYPE_NAME_STRING(1..80);
  518.     CHILD_LAST,
  519.     PARENT_LAST       : POSITIVE;
  520.     PARENT_DESCRIPTOR : ACCESS_TYPE_DESCRIPTOR;
  521.     CHILD_DESCRIPTOR  : ACCESS_SUBTYPE_DESCRIPTOR;
  522.   begin
  523.     GET_STRING(STRING(CHILD_NAME),CHILD_LAST);
  524.     GOBBLE("is");
  525.     GET_STRING(STRING(PARENT_NAME),PARENT_LAST);
  526.     GOBBLE(";");
  527.     PARENT_DESCRIPTOR := FIND_TYPE_DESCRIPTOR(PARENT_NAME(1..PARENT_LAST));
  528.     CHILD_DESCRIPTOR := new TYPE_DESCRIPTOR' (
  529.         TY_PE  => SUB_TYPE,
  530.         NAME   => new TYPE_NAME_STRING'(CHILD_NAME(1..CHILD_LAST)),
  531.         others => null );
  532.     ADD_TYPE(CHILD_DESCRIPTOR);
  533.     ADD_SUBTYPE(PARENT_DESCRIPTOR, CHILD_DESCRIPTOR);
  534.     if PARENT_DESCRIPTOR.TY_PE = SUB_TYPE then
  535.       CHILD_DESCRIPTOR.TOP_TYPE := PARENT_DESCRIPTOR.TOP_TYPE;
  536.     else
  537.       CHILD_DESCRIPTOR.TOP_TYPE := PARENT_DESCRIPTOR;
  538.     end if;
  539.   end PROCESS_SUBTYPE;
  540.  
  541.   procedure SCAN_DDL(PACKAGE_NAME : out STRING;
  542.                      LAST         : out POSITIVE) is
  543.     KEYWORD : STRING(1..7);
  544.     KLAST   : POSITIVE;
  545.   begin
  546.     GOBBLE("package");
  547.     GET_STRING(PACKAGE_NAME,LAST);
  548.     GOBBLE("is");
  549.     loop
  550.       GET_STRING(KEYWORD,KLAST);
  551.       if KEYWORD(1..KLAST) = "type" then
  552.         PROCESS_TYPE;
  553.       elsif KEYWORD(1..KLAST) = "subtype" then
  554.         PROCESS_SUBTYPE;
  555.       elsif KEYWORD(1..KLAST) = "end" then
  556.         exit;
  557.       else
  558.         raise CONSTRAINT_ERROR; -- unrecognized keyword
  559.       end if;
  560.     end loop;
  561.   end SCAN_DDL;
  562.  
  563. end READ_DDL;
  564. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  565. --sqlddl.ada
  566. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  567. with DDL_DEFINITIONS;
  568. use DDL_DEFINITIONS;
  569.  
  570. with LIST_UTILITIES;
  571. use LIST_UTILITIES;
  572.  
  573. with TEXT_IO;
  574. use TEXT_IO;
  575.  
  576. package SQL_DDL is
  577.  
  578. procedure GENERATE_SQL_DDL (DATABASE_NAME : STRING);
  579.  
  580. end SQL_DDL;
  581.  
  582. package body SQL_DDL is
  583.  
  584. procedure GENERATE_SQL_DDL (DATABASE_NAME : STRING) is
  585.  
  586.     package INT_IO is new INTEGER_IO (INTEGER);
  587.  
  588.     MAX_LINE_LENGTH : constant INTEGER := 120;
  589.  
  590.     INDENT_COLUMN_POSITION : constant INTEGER := 40;
  591.  
  592.     type FIELD_NODE;
  593.  
  594.     type ACCESS_FIELD_NODE is access FIELD_NODE;
  595.  
  596.     type FIELD_NODE is
  597.  
  598.       record
  599.     NEXT_FIELD : ACCESS_FIELD_NODE;
  600.     NAME       : STRING (1 .. 80);
  601.  
  602.       end record;
  603.  
  604.     DEFINITION_FILE      : FILE_TYPE;
  605.     UNDERLYING_FILE      : FILE_TYPE;
  606.  
  607.     DEFINITION_FILE_NAME : STRING (1 .. 20);
  608.     UNDERLYING_FILE_NAME : STRING (1 .. 20);
  609.  
  610.     LINE                 : STRING (1 .. MAX_LINE_LENGTH) :=
  611.                (1 .. MAX_LINE_LENGTH => ' ');
  612.  
  613.     BLANK_CARD           : STRING (1 .. MAX_LINE_LENGTH) :=
  614.                (1 .. MAX_LINE_LENGTH => ' ');
  615.  
  616.     LENGTH               : NATURAL;
  617.  
  618.     FIRST_FIELD_NODE     : ACCESS_FIELD_NODE;
  619.  
  620.     function LAST_FUNCTIONAL_POS (LINE : STRING) return INTEGER is
  621.  
  622.       POSITION    : NATURAL;
  623.       INPUT_FIRST : NATURAL := LINE'FIRST;
  624.  
  625.     begin
  626.  
  627.       POSITION := LINE'LAST;
  628.  
  629.       while (POSITION > INPUT_FIRST) and then
  630.         (CHARACTER'POS (LINE (POSITION)) <= CHARACTER'POS (' ')) loop
  631.  
  632.     POSITION := POSITION - 1;
  633.  
  634.       end loop;
  635.  
  636.       if POSITION < INPUT_FIRST then
  637.     -- compensate for null input
  638.     POSITION := INPUT_FIRST;   -- string
  639.  
  640.       end if;
  641.  
  642.       return POSITION;
  643.  
  644.     end LAST_FUNCTIONAL_POS;
  645.  
  646.     procedure INSERT_SLICE (LINE   : in out STRING;
  647.                 INSERT : STRING;
  648.                 POS    : INTEGER) is
  649.  
  650.       LINE_LAST                : INTEGER := LINE'LAST;
  651.       INSERT_LENGTH            : INTEGER := INSERT'LENGTH;
  652.       INSERT_POSITION          : INTEGER := POS;
  653.       NUMBER_OF_OVERFLOW_CHARS : INTEGER;
  654.  
  655.     begin
  656.  
  657.       if LINE'LENGTH > 0 and INSERT_LENGTH > 0 then
  658.  
  659. -- compensate for bad position request
  660.  
  661.     if INSERT_POSITION > LINE_LAST then
  662.       INSERT_POSITION := LINE_LAST;
  663.     end if;
  664.  
  665.     if INSERT_POSITION < 1 then
  666.       INSERT_POSITION := 1;
  667.     end if;
  668.  
  669.     NUMBER_OF_OVERFLOW_CHARS :=
  670.       INSERT_POSITION - LINE_LAST + INSERT_LENGTH - 1;
  671.  
  672.     if NUMBER_OF_OVERFLOW_CHARS > 0 then
  673.       INSERT_LENGTH := INSERT_LENGTH - NUMBER_OF_OVERFLOW_CHARS;
  674.     end if;
  675.  
  676.     LINE (INSERT_POSITION .. (INSERT_POSITION + INSERT_LENGTH - 1)) :=
  677.       INSERT (INSERT'FIRST .. (INSERT'FIRST + INSERT_LENGTH - 1));
  678.  
  679.       end if;
  680.  
  681.     end INSERT_SLICE;
  682.  
  683.  
  684.     procedure INSERT_LINE (LINE    : in out STRING;
  685.                LITERAL : STRING;
  686.                POS     : POSITIVE) is
  687.  
  688.     begin
  689.  
  690.       if LINE (POS - 1) = ' ' then
  691.  
  692.     INSERT_SLICE (LINE, LITERAL, POS);
  693.  
  694.       else
  695.  
  696.     INSERT_SLICE (LINE, LITERAL, LAST_FUNCTIONAL_POS (LINE) + 2);
  697.  
  698.       end if;
  699.  
  700.     end INSERT_LINE;
  701.  
  702.     procedure CREATE_FIELD_LIST (FIRST_FIELD_NODE : in out ACCESS_FIELD_NODE) is
  703.  
  704.       CURRENT_FIELD     : ACCESS_FIELD_NODE;
  705.       CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  706.       CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  707.       LITERAL           : STRING (1 .. 80);
  708.  
  709.     begin
  710.  
  711.       FIRST_FIELD_NODE := new FIELD_NODE;
  712.       CURRENT_FIELD := new FIELD_NODE;
  713.       FIRST_FIELD_NODE.NEXT_FIELD := CURRENT_FIELD;
  714.  
  715.       loop
  716.  
  717.     if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  718.        (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  719.  
  720.       CURRENT_COMPONENT := CURRENT_TYPE.FIRST_COMPONENT;
  721.  
  722.           loop
  723.  
  724.         CURRENT_FIELD.NAME := BLANK_CARD (1 .. 80);
  725.         LITERAL := BLANK_CARD (1 .. 80);
  726.         INSERT_SLICE (LITERAL, STRING (CURRENT_COMPONENT.NAME.all), 1);
  727.         CURRENT_FIELD.NAME := LITERAL;
  728.  
  729.         CURRENT_FIELD.NEXT_FIELD := new FIELD_NODE;
  730.         CURRENT_FIELD := CURRENT_FIELD.NEXT_FIELD;
  731.  
  732.         exit when CURRENT_COMPONENT.NEXT_COMPONENT = null;
  733.  
  734.         CURRENT_COMPONENT := CURRENT_COMPONENT.NEXT_COMPONENT;
  735.  
  736.       end loop;
  737.  
  738.     end if;
  739.  
  740.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  741.  
  742.     CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  743.  
  744.       end loop;
  745.  
  746.     end CREATE_FIELD_LIST;
  747.  
  748.  
  749.     procedure CREATE_UNDERLYING_PACKAGE
  750.          (FIRST_FIELD_NODE : ACCESS_FIELD_NODE;
  751.           DATABASE_NAME    : STRING;
  752.           UNDERLYING_FILE  : in out FILE_TYPE) is
  753.  
  754.       procedure GENERATE_TYPE_DEFINITIONS
  755.            (UNDERLYING_FILE : in out FILE_TYPE) is
  756.  
  757.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  758.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  759.  
  760.       begin
  761.  
  762.     loop
  763.  
  764.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  765.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  766.  
  767.         NEW_LINE (UNDERLYING_FILE);
  768.         PUT (UNDERLYING_FILE, "  TYPE ");
  769.         PUT (UNDERLYING_FILE, STRING (CURRENT_TYPE.NAME.all));
  770.         PUT_LINE (UNDERLYING_FILE, "_TYPE is ");
  771.         PUT_LINE (UNDERLYING_FILE, "     record");
  772.  
  773.         PUT (UNDERLYING_FILE, "         STAR");
  774.  
  775.         CURRENT_COMPONENT := CURRENT_TYPE.FIRST_COMPONENT;
  776.  
  777.         loop
  778.  
  779.           PUT (UNDERLYING_FILE, ", ");
  780.           PUT (UNDERLYING_FILE, STRING (CURRENT_COMPONENT.NAME.all));
  781.  
  782.           if COL (UNDERLYING_FILE) > 70 then
  783.  
  784.         NEW_LINE (UNDERLYING_FILE);
  785.         PUT (UNDERLYING_FILE, "         ");
  786.  
  787.           end if;
  788.  
  789.           exit when CURRENT_COMPONENT.NEXT_COMPONENT = null;
  790.  
  791.           CURRENT_COMPONENT := CURRENT_COMPONENT.NEXT_COMPONENT;
  792.  
  793.         end loop;
  794.  
  795.         PUT_LINE (UNDERLYING_FILE, " : FIELD;");
  796.         PUT_LINE (UNDERLYING_FILE, "     end record;");
  797.  
  798.       end if;
  799.  
  800.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  801.  
  802.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  803.  
  804.     end loop;
  805.  
  806.       end GENERATE_TYPE_DEFINITIONS;
  807.  
  808.  
  809.       procedure GENERATE_TABLE_ACCESS_DEFINITIONS
  810.            (UNDERLYING_FILE : in out FILE_TYPE) is
  811.  
  812.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  813.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  814.  
  815.       begin
  816.  
  817.     NEW_LINE (UNDERLYING_FILE);
  818.  
  819.     loop
  820.  
  821.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  822.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  823.  
  824.         LINE := BLANK_CARD;
  825.  
  826.         INSERT_SLICE (LINE, "type", 3);
  827.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 8);
  828.         INSERT_SLICE (LINE, "_TABLE", (LAST_FUNCTIONAL_POS (LINE) + 1));
  829.  
  830.         INSERT_LINE (LINE, "is access", INDENT_COLUMN_POSITION);
  831.  
  832.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  833.               (LAST_FUNCTIONAL_POS (LINE) + 2));
  834.         INSERT_SLICE (LINE, "_TYPE;", (LAST_FUNCTIONAL_POS (LINE) + 1));
  835.  
  836.         PUT_LINE (UNDERLYING_FILE, LINE);
  837.       end if;
  838.  
  839.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  840.  
  841.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  842.  
  843.     end loop;
  844.  
  845.     NEW_LINE (UNDERLYING_FILE);
  846.  
  847.  
  848.       end GENERATE_TABLE_ACCESS_DEFINITIONS;
  849.  
  850.  
  851.       procedure GENERATE_FIELD_CONSTANT_DEFINITIONS
  852.            (FIRST_FIELD_NODE : ACCESS_FIELD_NODE;
  853.             UNDERLYING_FILE  : in out FILE_TYPE) is
  854.  
  855.     FIELD_IS_UNIQUE : BOOLEAN;
  856.  
  857.     CURRENT_FIELD   : ACCESS_FIELD_NODE := FIRST_FIELD_NODE;
  858.  
  859.  
  860.     procedure SEARCH_FIELD_LIST_FOR_DUPLICITY
  861.              (FIELD_ELEMENT   : ACCESS_FIELD_NODE;
  862.               FIELD_IS_UNIQUE : out BOOLEAN) is
  863.  
  864.       FIELD_NODE           : ACCESS_FIELD_NODE := FIELD_ELEMENT;
  865.       NUMBER_OF_OCCURANCES : INTEGER := 0;
  866.  
  867.     begin
  868.  
  869.       FIELD_NODE := FIELD_NODE.NEXT_FIELD;
  870.  
  871.          if FIELD_NODE /= null then
  872.  
  873.            loop
  874.  
  875.         if FIELD_NODE.NAME = FIELD_ELEMENT.NAME then
  876.  
  877.           NUMBER_OF_OCCURANCES := NUMBER_OF_OCCURANCES + 1;
  878.  
  879.         end if;
  880.  
  881.         exit when FIELD_NODE.NEXT_FIELD = null;
  882.  
  883.         FIELD_NODE := FIELD_NODE.NEXT_FIELD;
  884.  
  885.       end loop;
  886.  
  887.           end if;
  888.  
  889.       if NUMBER_OF_OCCURANCES > 0 then
  890.  
  891.         FIELD_IS_UNIQUE := FALSE;
  892.  
  893.       else
  894.  
  895.         FIELD_IS_UNIQUE := TRUE;
  896.  
  897.       end if;
  898.  
  899.     end SEARCH_FIELD_LIST_FOR_DUPLICITY;
  900.  
  901.       begin
  902.  
  903.     CURRENT_FIELD := CURRENT_FIELD.NEXT_FIELD;
  904.  
  905.     loop
  906.  
  907.       LINE := BLANK_CARD;
  908.  
  909.       SEARCH_FIELD_LIST_FOR_DUPLICITY (CURRENT_FIELD, FIELD_IS_UNIQUE);
  910.  
  911.       if FIELD_IS_UNIQUE then
  912.  
  913.         INSERT_SLICE (LINE, "F_", 3);
  914.         INSERT_SLICE (LINE, CURRENT_FIELD.NAME, 5);
  915.         INSERT_LINE (LINE, ": constant FIELD := MAKE_FIELD(""", INDENT_COLUMN_POSITION);
  916.         INSERT_SLICE (LINE, CURRENT_FIELD.NAME,
  917.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  918.         INSERT_SLICE (LINE, """);", (LAST_FUNCTIONAL_POS (LINE) + 1));
  919.         PUT_LINE (UNDERLYING_FILE, LINE);
  920.  
  921.       end if;
  922.  
  923.       CURRENT_FIELD := CURRENT_FIELD.NEXT_FIELD;
  924.  
  925.       exit when CURRENT_FIELD.NEXT_FIELD = null;
  926.  
  927.     end loop;
  928.  
  929.     NEW_LINE (UNDERLYING_FILE);
  930.  
  931.       end GENERATE_FIELD_CONSTANT_DEFINITIONS;
  932.  
  933.  
  934.       procedure GENERATE_DATA_DEFINITIONS
  935.            (UNDERLYING_FILE : in out FILE_TYPE) is
  936.  
  937.  
  938.     CURRENT_FIELD     : ACCESS_FIELD_NODE;
  939.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  940.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  941.  
  942.       begin
  943.  
  944.     loop
  945.  
  946.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  947.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  948.  
  949.         LINE := BLANK_CARD;
  950.  
  951.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 3);
  952.         INSERT_SLICE (LINE, "_DATA", (LAST_FUNCTIONAL_POS (LINE) + 1));
  953.  
  954.         INSERT_LINE (LINE, ": ", INDENT_COLUMN_POSITION);
  955.  
  956.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  957.               (LAST_FUNCTIONAL_POS (LINE) + 2));
  958.         INSERT_SLICE (LINE, "_TABLE;", (LAST_FUNCTIONAL_POS (LINE) + 1));
  959.  
  960.         PUT_LINE (UNDERLYING_FILE, LINE);
  961.  
  962.       end if;
  963.  
  964.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  965.  
  966.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  967.  
  968.     end loop;
  969.  
  970.     NEW_LINE (UNDERLYING_FILE);
  971.  
  972.       end GENERATE_DATA_DEFINITIONS;
  973.  
  974.  
  975.       procedure GENERATE_PROCEDURE_SPECIFICATION_DEFINITIONS
  976.            (UNDERLYING_FILE : in out FILE_TYPE) is
  977.  
  978.  
  979.     CURRENT_FIELD     : ACCESS_FIELD_NODE;
  980.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  981.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  982.  
  983.       begin
  984.  
  985.     NEW_LINE (UNDERLYING_FILE);
  986.  
  987.     loop
  988.  
  989.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  990.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  991.  
  992.         LINE := BLANK_CARD;
  993.  
  994.         INSERT_SLICE (LINE, "procedure", 3);
  995.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 13);
  996.         INSERT_SLICE (LINE, "(X : in out", INDENT_COLUMN_POSITION);
  997.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  998.               (LAST_FUNCTIONAL_POS (LINE) + 2));
  999.         INSERT_SLICE (LINE, "_TABLE);", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1000.  
  1001.         PUT_LINE (UNDERLYING_FILE, LINE);
  1002.  
  1003.       end if;
  1004.  
  1005.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  1006.  
  1007.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1008.  
  1009.     end loop;
  1010.  
  1011.     NEW_LINE (UNDERLYING_FILE);
  1012.  
  1013.       end GENERATE_PROCEDURE_SPECIFICATION_DEFINITIONS;
  1014.  
  1015.  
  1016.       procedure GENERATE_PROCEDURE_BODY_DECLARATIONS
  1017.            (UNDERLYING_FILE : in out FILE_TYPE) is
  1018.  
  1019.  
  1020.     CURRENT_FIELD     : ACCESS_FIELD_NODE;
  1021.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1022.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  1023.  
  1024.       begin
  1025.  
  1026.     loop
  1027.  
  1028.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  1029.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  1030.  
  1031.         LINE := BLANK_CARD;
  1032.  
  1033.         INSERT_SLICE (LINE, "procedure", 3);
  1034.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 13);
  1035.         INSERT_SLICE (LINE, "(X : in out",
  1036.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1037.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  1038.               (LAST_FUNCTIONAL_POS (LINE) + 2));
  1039.         INSERT_SLICE (LINE, "_TABLE) is", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1040.         PUT_LINE (UNDERLYING_FILE, LINE);
  1041.  
  1042.         NEW_LINE (UNDERLYING_FILE);
  1043.         PUT_LINE (UNDERLYING_FILE, "     T : TABLE_NAME;");
  1044.         NEW_LINE (UNDERLYING_FILE);
  1045.         PUT_LINE (UNDERLYING_FILE, "   begin");
  1046.         NEW_LINE (UNDERLYING_FILE);
  1047.         PUT_LINE (UNDERLYING_FILE, "     if X = null then");
  1048.         NEW_LINE (UNDERLYING_FILE);
  1049.  
  1050.         LINE := BLANK_CARD;
  1051.  
  1052.         INSERT_SLICE (LINE, "T := MAKE_TABLE_NAME(""", 9);
  1053.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  1054.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1055.         INSERT_SLICE (LINE, """);", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1056.  
  1057.         PUT_LINE (UNDERLYING_FILE, LINE);
  1058.  
  1059.         LINE := BLANK_CARD;
  1060.  
  1061.         INSERT_SLICE (LINE, "X := new", 9);
  1062.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  1063.               (LAST_FUNCTIONAL_POS (LINE) + 2));
  1064.         INSERT_SLICE (LINE, "_TYPE'(", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1065.  
  1066.         PUT_LINE (UNDERLYING_FILE, LINE);
  1067.         PUT_LINE (UNDERLYING_FILE, "        MAKE_FIELD(T, STAR),");
  1068.         LINE := BLANK_CARD;
  1069.  
  1070.         CURRENT_COMPONENT := CURRENT_TYPE.FIRST_COMPONENT;
  1071.  
  1072.         loop
  1073.  
  1074.           LINE := BLANK_CARD;
  1075.  
  1076.           INSERT_SLICE (LINE, "MAKE_FIELD(T, F_", 9);
  1077.           INSERT_SLICE (LINE, STRING (CURRENT_COMPONENT.NAME.all),
  1078.                 (LAST_FUNCTIONAL_POS (LINE) + 1));
  1079.  
  1080.           if CURRENT_COMPONENT.NEXT_COMPONENT /= null then
  1081.  
  1082.         INSERT_SLICE (LINE, "),", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1083.           else
  1084.         INSERT_SLICE (LINE, ") );", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1085.           end if;
  1086.  
  1087.           PUT_LINE (UNDERLYING_FILE, LINE);
  1088.  
  1089.           exit when CURRENT_COMPONENT.NEXT_COMPONENT = null;
  1090.  
  1091.           CURRENT_COMPONENT := CURRENT_COMPONENT.NEXT_COMPONENT;
  1092.  
  1093.         end loop;
  1094.  
  1095.         NEW_LINE (UNDERLYING_FILE);
  1096.         PUT_LINE (UNDERLYING_FILE, "      end if;");
  1097.         NEW_LINE (UNDERLYING_FILE);
  1098.         PUT (UNDERLYING_FILE, "   end ");
  1099.         PUT (UNDERLYING_FILE, STRING (CURRENT_TYPE.NAME.all));
  1100.         PUT_LINE (UNDERLYING_FILE, "; ");
  1101.         NEW_LINE (UNDERLYING_FILE);
  1102.  
  1103.       end if;
  1104.  
  1105.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  1106.  
  1107.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1108.  
  1109.     end loop;
  1110.  
  1111.  
  1112.     NEW_LINE (UNDERLYING_FILE);
  1113.  
  1114.       end GENERATE_PROCEDURE_BODY_DECLARATIONS;
  1115.  
  1116.  
  1117.       procedure GENERATE_TABLE_INITIALIZATION
  1118.            (UNDERLYING_FILE : in out FILE_TYPE) is
  1119.  
  1120.     CURRENT_FIELD     : ACCESS_FIELD_NODE;
  1121.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1122.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  1123.  
  1124.       begin
  1125.  
  1126.     loop
  1127.  
  1128.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  1129.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  1130.  
  1131.         LINE := BLANK_CARD;
  1132.  
  1133.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 6);
  1134.         INSERT_LINE (LINE, " (", INDENT_COLUMN_POSITION);
  1135.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  1136.               LAST_FUNCTIONAL_POS (LINE) + 2);
  1137.         INSERT_SLICE (LINE, "_DATA);", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1138.  
  1139.         PUT_LINE (UNDERLYING_FILE, LINE);
  1140.  
  1141.       end if;
  1142.  
  1143.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  1144.  
  1145.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1146.  
  1147.     end loop;
  1148.  
  1149.       end GENERATE_TABLE_INITIALIZATION;
  1150.  
  1151.     begin
  1152.  
  1153.       NEW_LINE (UNDERLYING_FILE);
  1154.       PUT_LINE (UNDERLYING_FILE, "with SQL_DEFINITIONS;");
  1155.       PUT_LINE (UNDERLYING_FILE, "use  SQL_DEFINITIONS;");
  1156.       NEW_LINE (UNDERLYING_FILE);
  1157.  
  1158.       LINE := BLANK_CARD;
  1159.       INSERT_SLICE (LINE, "package ", 1);
  1160.       INSERT_SLICE (LINE, DATABASE_NAME, 9);
  1161.       INSERT_SLICE (LINE, "_UNDERLYING is ", LAST_FUNCTIONAL_POS (LINE) + 1);
  1162.       PUT_LINE (UNDERLYING_FILE, LINE);
  1163.       NEW_LINE (UNDERLYING_FILE);
  1164.  
  1165.       GENERATE_TYPE_DEFINITIONS (UNDERLYING_FILE);
  1166.  
  1167.       GENERATE_TABLE_ACCESS_DEFINITIONS (UNDERLYING_FILE);
  1168.  
  1169.       GENERATE_FIELD_CONSTANT_DEFINITIONS (FIRST_FIELD_NODE, UNDERLYING_FILE);
  1170.  
  1171.       GENERATE_DATA_DEFINITIONS (UNDERLYING_FILE);
  1172.  
  1173.       GENERATE_PROCEDURE_SPECIFICATION_DEFINITIONS (UNDERLYING_FILE);
  1174.  
  1175.       NEW_LINE (UNDERLYING_FILE);
  1176.       LINE := BLANK_CARD;
  1177.       INSERT_SLICE (LINE, "end ", 1);
  1178.       INSERT_SLICE (LINE, DATABASE_NAME, 5);
  1179.       INSERT_SLICE (LINE, "_UNDERLYING", LAST_FUNCTIONAL_POS (LINE) + 1);
  1180.       INSERT_SLICE (LINE, "; ", LAST_FUNCTIONAL_POS (LINE) + 1);
  1181.       PUT_LINE (UNDERLYING_FILE, LINE);
  1182.  
  1183.       NEW_LINE (UNDERLYING_FILE);
  1184.       PUT_LINE (UNDERLYING_FILE, "with SQL_DEFINITIONS;");
  1185.       PUT_LINE (UNDERLYING_FILE, "use  SQL_DEFINITIONS;");
  1186.       NEW_LINE (UNDERLYING_FILE);
  1187.  
  1188.       LINE := BLANK_CARD;
  1189.       INSERT_SLICE (LINE, "package body ", 1);
  1190.       INSERT_SLICE (LINE, DATABASE_NAME, 14);
  1191.       INSERT_SLICE (LINE, "_UNDERLYING is ", LAST_FUNCTIONAL_POS (LINE) + 1);
  1192.       PUT_LINE (UNDERLYING_FILE, LINE);
  1193.       NEW_LINE (UNDERLYING_FILE);
  1194.  
  1195.       GENERATE_PROCEDURE_BODY_DECLARATIONS (UNDERLYING_FILE);
  1196.  
  1197.       NEW_LINE (UNDERLYING_FILE);
  1198.       PUT_LINE (UNDERLYING_FILE, "    begin");
  1199.       NEW_LINE (UNDERLYING_FILE);
  1200.  
  1201.       GENERATE_TABLE_INITIALIZATION (UNDERLYING_FILE);
  1202.  
  1203.       NEW_LINE (UNDERLYING_FILE);
  1204.       LINE := BLANK_CARD;
  1205.       INSERT_SLICE (LINE, " end ", 1);
  1206.       INSERT_SLICE (LINE, DATABASE_NAME, 6);
  1207.       INSERT_SLICE (LINE, "_UNDERLYING", LAST_FUNCTIONAL_POS (LINE) + 1);
  1208.       INSERT_SLICE (LINE, "; ", LAST_FUNCTIONAL_POS (LINE) + 1);
  1209.       PUT_LINE (UNDERLYING_FILE, LINE);
  1210.  
  1211.     end CREATE_UNDERLYING_PACKAGE;
  1212.  
  1213.     procedure CREATE_DATABASE_DEFINITIONS_FILE
  1214.          (FIRST_FIELD_NODE : ACCESS_FIELD_NODE;
  1215.           DATABASE_NAME    : STRING;
  1216.           DEFINITION_FILE  : in out FILE_TYPE) is
  1217.  
  1218.  
  1219.       procedure GENERATE_TYPE_SUBTYPE_DECLARATIONS
  1220.            (DEFINITION_FILE : in out FILE_TYPE) is
  1221.  
  1222.     CURRENT_FIELD     : ACCESS_FIELD_NODE;
  1223.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1224.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  1225.  
  1226.       begin
  1227.  
  1228.     NEW_LINE (DEFINITION_FILE);
  1229.  
  1230.     loop
  1231.  
  1232.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  1233.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  1234.  
  1235.         LINE := BLANK_CARD;
  1236.  
  1237.         INSERT_SLICE (LINE, "subtype", 3);
  1238.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 11);
  1239.         INSERT_SLICE (LINE, "_TYPE", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1240.         INSERT_LINE (LINE, "is", INDENT_COLUMN_POSITION);
  1241.         INSERT_SLICE (LINE, DATABASE_NAME, LAST_FUNCTIONAL_POS (LINE) + 2);
  1242.         INSERT_SLICE (LINE, "_UNDERLYING.",
  1243.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1244.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  1245.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1246.         INSERT_SLICE (LINE, "_TYPE;", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1247.         PUT_LINE (DEFINITION_FILE, LINE);
  1248.  
  1249.       end if;
  1250.  
  1251.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  1252.  
  1253.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1254.  
  1255.     end loop;
  1256.  
  1257.     NEW_LINE (DEFINITION_FILE);
  1258.  
  1259.       end GENERATE_TYPE_SUBTYPE_DECLARATIONS;
  1260.  
  1261.  
  1262.       procedure GENERATE_TABLE_SUBTYPE_DEFINITIONS
  1263.            (DEFINITION_FILE : in out FILE_TYPE) is
  1264.  
  1265.  
  1266.     CURRENT_FIELD     : ACCESS_FIELD_NODE;
  1267.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1268.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  1269.  
  1270.  
  1271.       begin
  1272.  
  1273.     NEW_LINE (DEFINITION_FILE);
  1274.  
  1275.     loop
  1276.  
  1277.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  1278.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  1279.  
  1280.         LINE := BLANK_CARD;
  1281.  
  1282.         INSERT_SLICE (LINE, "subtype", 3);
  1283.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 11);
  1284.         INSERT_SLICE (LINE, "_TABLE", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1285.         INSERT_LINE (LINE, "is", INDENT_COLUMN_POSITION);
  1286.         INSERT_SLICE (LINE, DATABASE_NAME,
  1287.               (LAST_FUNCTIONAL_POS (LINE) + 2));
  1288.         INSERT_SLICE (LINE, "_UNDERLYING.",
  1289.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1290.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  1291.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1292.         INSERT_SLICE (LINE, "_TABLE;", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1293.  
  1294.         PUT_LINE (DEFINITION_FILE, LINE);
  1295.  
  1296.       end if;
  1297.  
  1298.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  1299.  
  1300.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1301.  
  1302.     end loop;
  1303.  
  1304.     NEW_LINE (DEFINITION_FILE);
  1305.  
  1306.       end GENERATE_TABLE_SUBTYPE_DEFINITIONS;
  1307.  
  1308.  
  1309.       procedure GENERATE_FIELD_SUBTYPE_REDEFINITIONS
  1310.            (FIRST_FIELD_NODE : ACCESS_FIELD_NODE;
  1311.             UNDERLYING_FILE  : in out FILE_TYPE) is
  1312.  
  1313.     FIELD_IS_UNIQUE : BOOLEAN;
  1314.  
  1315.     CURRENT_FIELD   : ACCESS_FIELD_NODE := FIRST_FIELD_NODE;
  1316.  
  1317.  
  1318.     procedure SEARCH_FIELD_LIST_FOR_DUPLICITY
  1319.              (FIELD_ELEMENT   : ACCESS_FIELD_NODE;
  1320.               FIELD_IS_UNIQUE : out BOOLEAN) is
  1321.  
  1322.       FIELD_NODE           : ACCESS_FIELD_NODE := FIELD_ELEMENT;
  1323.       NUMBER_OF_OCCURANCES : INTEGER := 0;
  1324.  
  1325.     begin
  1326.  
  1327.       FIELD_NODE := FIELD_NODE.NEXT_FIELD;
  1328.  
  1329.           if FIELD_NODE /= null then
  1330.  
  1331.             loop
  1332.  
  1333.         if FIELD_NODE.NAME = FIELD_ELEMENT.NAME then
  1334.  
  1335.           NUMBER_OF_OCCURANCES := NUMBER_OF_OCCURANCES + 1;
  1336.  
  1337.         end if;
  1338.  
  1339.         exit when FIELD_NODE.NEXT_FIELD = null;
  1340.  
  1341.         FIELD_NODE := FIELD_NODE.NEXT_FIELD;
  1342.  
  1343.       end loop;
  1344.  
  1345.           end if;
  1346.  
  1347.       if NUMBER_OF_OCCURANCES > 0 then
  1348.  
  1349.         FIELD_IS_UNIQUE := FALSE;
  1350.  
  1351.       else
  1352.  
  1353.         FIELD_IS_UNIQUE := TRUE;
  1354.  
  1355.       end if;
  1356.  
  1357.     end SEARCH_FIELD_LIST_FOR_DUPLICITY;
  1358.  
  1359.       begin
  1360.  
  1361.     CURRENT_FIELD := CURRENT_FIELD.NEXT_FIELD;
  1362.  
  1363.     loop
  1364.  
  1365.       LINE := BLANK_CARD;
  1366.  
  1367.       SEARCH_FIELD_LIST_FOR_DUPLICITY (CURRENT_FIELD, FIELD_IS_UNIQUE);
  1368.  
  1369.       if FIELD_IS_UNIQUE then
  1370.  
  1371.         LINE := BLANK_CARD;
  1372.         INSERT_SLICE (LINE, "function", 3);
  1373.         INSERT_SLICE (LINE, CURRENT_FIELD.NAME, 12);
  1374.         INSERT_LINE (LINE, "is new GET_FIELD_NAME(", INDENT_COLUMN_POSITION);
  1375.         INSERT_SLICE (LINE, DATABASE_NAME,
  1376.               (LAST_FUNCTIONAL_POS (LINE) + 2));
  1377.         INSERT_SLICE (LINE, "_UNDERLYING.F_",
  1378.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1379.         INSERT_SLICE (LINE, CURRENT_FIELD.NAME,
  1380.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1381.         INSERT_SLICE (LINE, "); ", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1382.  
  1383.         PUT_LINE (DEFINITION_FILE, LINE);
  1384.  
  1385.       end if;
  1386.  
  1387.  
  1388.       CURRENT_FIELD := CURRENT_FIELD.NEXT_FIELD;
  1389.  
  1390.       exit when CURRENT_FIELD.NEXT_FIELD = null;
  1391.  
  1392.     end loop;
  1393.  
  1394.       end GENERATE_FIELD_SUBTYPE_REDEFINITIONS;
  1395.  
  1396.  
  1397.       procedure GENERATE_TABLE_FUNCTION_REINSTANTIATIONS
  1398.            (DEFINITION_FILE : in out FILE_TYPE) is
  1399.  
  1400.     CURRENT_FIELD     : ACCESS_FIELD_NODE;
  1401.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1402.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  1403.  
  1404.       begin
  1405.  
  1406.     NEW_LINE (DEFINITION_FILE);
  1407.  
  1408.     loop
  1409.  
  1410.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  1411.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  1412.  
  1413.         LINE := BLANK_CARD;
  1414.  
  1415.         INSERT_SLICE (LINE, "function", 3);
  1416.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 12);
  1417.         INSERT_LINE (LINE, "is new GET_TABLE(", INDENT_COLUMN_POSITION);
  1418.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  1419.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1420.         INSERT_SLICE (LINE, "_DATA.STAR);",
  1421.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1422.  
  1423.         PUT_LINE (DEFINITION_FILE, LINE);
  1424.  
  1425.       end if;
  1426.  
  1427.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  1428.  
  1429.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1430.  
  1431.     end loop;
  1432.  
  1433.     NEW_LINE (DEFINITION_FILE);
  1434.  
  1435.       end GENERATE_TABLE_FUNCTION_REINSTANTIATIONS;
  1436.  
  1437.  
  1438.       procedure GENERATE_GET_FIELD_FUNCTION_INSTANTIATIONS
  1439.            (DEFINITION_FILE : in out FILE_TYPE) is
  1440.  
  1441.     CURRENT_FIELD     : ACCESS_FIELD_NODE;
  1442.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1443.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  1444.  
  1445.  
  1446.       begin
  1447.  
  1448.     NEW_LINE (DEFINITION_FILE);
  1449.  
  1450.     loop
  1451.  
  1452.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  1453.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  1454.  
  1455.         LINE := BLANK_CARD;
  1456.  
  1457.         INSERT_SLICE (LINE, "function", 3);
  1458.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 12);
  1459.         INSERT_SLICE (LINE, "is", (LAST_FUNCTIONAL_POS (LINE) + 2));
  1460.  
  1461.         PUT_LINE (DEFINITION_FILE, LINE);
  1462.         LINE := BLANK_CARD;
  1463.  
  1464.         INSERT_SLICE (LINE, "new GET_FIELDS(", 5);
  1465.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 20);
  1466.         INSERT_SLICE (LINE, "_TABLE,", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1467.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  1468.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1469.         INSERT_SLICE (LINE, "_DATA);", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1470.  
  1471.         PUT_LINE (DEFINITION_FILE, LINE);
  1472.  
  1473.       end if;
  1474.  
  1475.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  1476.  
  1477.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1478.  
  1479.     end loop;
  1480.  
  1481.     NEW_LINE (DEFINITION_FILE);
  1482.  
  1483.       end GENERATE_GET_FIELD_FUNCTION_INSTANTIATIONS;
  1484.  
  1485.  
  1486.       procedure GENERATE_INSERT_FIELD_FUNCTION_INSTANTIATIONS
  1487.            (DEFINITION_FILE : in out FILE_TYPE) is
  1488.  
  1489.  
  1490.     CURRENT_FIELD     : ACCESS_FIELD_NODE;
  1491.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1492.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  1493.  
  1494.       begin
  1495.  
  1496.     NEW_LINE (DEFINITION_FILE);
  1497.  
  1498.     loop
  1499.  
  1500.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  1501.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  1502.  
  1503.         LINE := BLANK_CARD;
  1504.  
  1505.         INSERT_SLICE (LINE, "function", 3);
  1506.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 12);
  1507.         INSERT_LINE (LINE, "is new INSERT_FIELDS(", INDENT_COLUMN_POSITION);
  1508.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  1509.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1510.         INSERT_SLICE (LINE, "_DATA.STAR);",
  1511.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1512.  
  1513.         PUT_LINE (DEFINITION_FILE, LINE);
  1514.  
  1515.       end if;
  1516.  
  1517.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  1518.  
  1519.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1520.  
  1521.     end loop;
  1522.  
  1523.     NEW_LINE (DEFINITION_FILE);
  1524.  
  1525.       end GENERATE_INSERT_FIELD_FUNCTION_INSTANTIATIONS;
  1526.  
  1527.  
  1528.       procedure GENERATE_TABLE_PROCEDURE_REDEFINITIONS
  1529.            (DEFINITION_FILE : in out FILE_TYPE) is
  1530.  
  1531.     CURRENT_FIELD     : ACCESS_FIELD_NODE;
  1532.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1533.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  1534.  
  1535.       begin
  1536.  
  1537.     NEW_LINE (DEFINITION_FILE);
  1538.  
  1539.     loop
  1540.  
  1541.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  1542.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  1543.  
  1544.         LINE := BLANK_CARD;
  1545.  
  1546.         INSERT_SLICE (LINE, "procedure", 3);
  1547.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 13);
  1548.         INSERT_SLICE (LINE, "(X : in out",
  1549.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1550.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  1551.               (LAST_FUNCTIONAL_POS (LINE) + 2));
  1552.         INSERT_SLICE (LINE, "_TABLE", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1553.         INSERT_SLICE (LINE, ") ", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1554.  
  1555.         PUT_LINE (DEFINITION_FILE, LINE);
  1556.         LINE := BLANK_CARD;
  1557.  
  1558.         INSERT_SLICE (LINE, "renames", 13);
  1559.         INSERT_SLICE (LINE, DATABASE_NAME,
  1560.               (LAST_FUNCTIONAL_POS (LINE) + 2));
  1561.         INSERT_SLICE (LINE, "_UNDERLYING.",
  1562.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1563.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  1564.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1565.         INSERT_SLICE (LINE, "; ", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1566.  
  1567.         PUT_LINE (DEFINITION_FILE, LINE);
  1568.         NEW_LINE (DEFINITION_FILE);
  1569.  
  1570.       end if;
  1571.  
  1572.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  1573.  
  1574.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1575.  
  1576.     end loop;
  1577.  
  1578.     NEW_LINE (DEFINITION_FILE);
  1579.  
  1580.       end GENERATE_TABLE_PROCEDURE_REDEFINITIONS;
  1581.  
  1582.       procedure GENERATE_TABLE_FUNCTION_DECLARATIONS
  1583.            (DEFINITION_FILE : in out FILE_TYPE) is
  1584.  
  1585.     CURRENT_FIELD     : ACCESS_FIELD_NODE;
  1586.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1587.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  1588.  
  1589.       begin
  1590.  
  1591.     NEW_LINE (DEFINITION_FILE);
  1592.  
  1593.     loop
  1594.  
  1595.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  1596.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  1597.  
  1598.         LINE := BLANK_CARD;
  1599.  
  1600.         NEW_LINE (DEFINITION_FILE);
  1601.         INSERT_SLICE (LINE, "function", 2);
  1602.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 12);
  1603.         INSERT_LINE (LINE, "(X : ", INDENT_COLUMN_POSITION);
  1604.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  1605.               LAST_FUNCTIONAL_POS (LINE) + 2);
  1606.         INSERT_SLICE (LINE, "_TABLE", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1607.         INSERT_SLICE (LINE, ") ", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1608.         INSERT_LINE (LINE, "return TABLE;", 65);
  1609.  
  1610.         PUT_LINE (DEFINITION_FILE, LINE);
  1611.  
  1612.       end if;
  1613.  
  1614.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  1615.  
  1616.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1617.  
  1618.     end loop;
  1619.  
  1620.     NEW_LINE (DEFINITION_FILE);
  1621.  
  1622.       end GENERATE_TABLE_FUNCTION_DECLARATIONS;
  1623.  
  1624.       procedure GENERATE_FUNCTION_BODY_DECLARATIONS
  1625.            (DEFINITION_FILE : in out FILE_TYPE) is
  1626.  
  1627.     CURRENT_FIELD     : ACCESS_FIELD_NODE;
  1628.     CURRENT_TYPE      : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1629.     CURRENT_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  1630.  
  1631.       begin
  1632.  
  1633.     NEW_LINE (DEFINITION_FILE);
  1634.  
  1635.     loop
  1636.  
  1637.       if (CURRENT_TYPE.TY_PE = REC_ORD) and then
  1638.          (CURRENT_TYPE.IS_SUBRECORD = FALSE) then
  1639.  
  1640.         LINE := BLANK_CARD;
  1641.  
  1642.         INSERT_SLICE (LINE, "function", 3);
  1643.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 12);
  1644.         INSERT_SLICE (LINE, "(X : in", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1645.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all),
  1646.               (LAST_FUNCTIONAL_POS (LINE) + 2));
  1647.         INSERT_SLICE (LINE, "_TABLE) return TABLE is",
  1648.               (LAST_FUNCTIONAL_POS (LINE) + 1));
  1649.  
  1650.         PUT_LINE (DEFINITION_FILE, LINE);
  1651.         PUT_LINE (DEFINITION_FILE, "   begin");
  1652.         NEW_LINE (DEFINITION_FILE);
  1653.         PUT_LINE (DEFINITION_FILE, "     return TABLEIFY(X.STAR);");
  1654.         NEW_LINE (DEFINITION_FILE);
  1655.  
  1656.         LINE := BLANK_CARD;
  1657.  
  1658.         INSERT_SLICE (LINE, "end", 3);
  1659.         INSERT_SLICE (LINE, STRING (CURRENT_TYPE.NAME.all), 7);
  1660.         INSERT_SLICE (LINE, "; ", (LAST_FUNCTIONAL_POS (LINE) + 1));
  1661.  
  1662.         PUT_LINE (DEFINITION_FILE, LINE);
  1663.         NEW_LINE (DEFINITION_FILE);
  1664.  
  1665.       end if;
  1666.  
  1667.       exit when CURRENT_TYPE.NEXT_TYPE = null;
  1668.  
  1669.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1670.  
  1671.     end loop;
  1672.  
  1673.     NEW_LINE (DEFINITION_FILE);
  1674.  
  1675.       end GENERATE_FUNCTION_BODY_DECLARATIONS;
  1676.  
  1677.     begin
  1678.  
  1679.       NEW_LINE (DEFINITION_FILE);
  1680.       PUT_LINE (DEFINITION_FILE, "with SQL_DEFINITIONS;");
  1681.       PUT_LINE (DEFINITION_FILE, "use  SQL_DEFINITIONS;");
  1682.       NEW_LINE (DEFINITION_FILE);
  1683.  
  1684.       LINE := BLANK_CARD;
  1685.  
  1686.       INSERT_SLICE (LINE, "with ", 1);
  1687.       INSERT_SLICE (LINE, DATABASE_NAME, LAST_FUNCTIONAL_POS (LINE) + 2);
  1688.       INSERT_SLICE (LINE, "_UNDERLYING;", LAST_FUNCTIONAL_POS (LINE) + 1);
  1689.       PUT_LINE (DEFINITION_FILE, LINE);
  1690.       NEW_LINE (DEFINITION_FILE);
  1691.  
  1692.       LINE := BLANK_CARD;
  1693.       INSERT_SLICE (LINE, "use ", 1);
  1694.       INSERT_SLICE (LINE, DATABASE_NAME, 5);
  1695.       INSERT_SLICE (LINE, "_UNDERLYING;", LAST_FUNCTIONAL_POS (LINE) + 1);
  1696.       PUT_LINE (DEFINITION_FILE, LINE);
  1697.       NEW_LINE (DEFINITION_FILE);
  1698.  
  1699.       LINE := BLANK_CARD;
  1700.       INSERT_SLICE (LINE, "package ", 1);
  1701.       INSERT_SLICE (LINE, DATABASE_NAME, 9);
  1702.       INSERT_SLICE (LINE, "_DATABASE is ", LAST_FUNCTIONAL_POS (LINE) + 1);
  1703.       PUT_LINE (DEFINITION_FILE, LINE);
  1704.       NEW_LINE (DEFINITION_FILE);
  1705.  
  1706.       GENERATE_TYPE_SUBTYPE_DECLARATIONS (DEFINITION_FILE);
  1707.  
  1708.       GENERATE_TABLE_SUBTYPE_DEFINITIONS (DEFINITION_FILE);
  1709.  
  1710.       GENERATE_FIELD_SUBTYPE_REDEFINITIONS (FIRST_FIELD_NODE, DEFINITION_FILE);
  1711.  
  1712.       GENERATE_TABLE_FUNCTION_REINSTANTIATIONS (DEFINITION_FILE);
  1713.  
  1714.       GENERATE_GET_FIELD_FUNCTION_INSTANTIATIONS (DEFINITION_FILE);
  1715.  
  1716.       GENERATE_INSERT_FIELD_FUNCTION_INSTANTIATIONS (DEFINITION_FILE);
  1717.  
  1718.       GENERATE_TABLE_PROCEDURE_REDEFINITIONS (DEFINITION_FILE);
  1719.  
  1720.  
  1721.       GENERATE_TABLE_FUNCTION_DECLARATIONS (DEFINITION_FILE);
  1722.  
  1723.       NEW_LINE (DEFINITION_FILE);
  1724.       LINE := BLANK_CARD;
  1725.       INSERT_SLICE (LINE, " end ", 1);
  1726.       INSERT_SLICE (LINE, DATABASE_NAME, 6);
  1727.       INSERT_SLICE (LINE, "_DATABASE", LAST_FUNCTIONAL_POS (LINE) + 1);
  1728.       INSERT_SLICE (LINE, "; ", LAST_FUNCTIONAL_POS (LINE) + 1);
  1729.       PUT_LINE (DEFINITION_FILE, LINE);
  1730.  
  1731.       NEW_LINE (DEFINITION_FILE);
  1732.       PUT_LINE (DEFINITION_FILE, "with SQL_DEFINITIONS;");
  1733.       PUT_LINE (DEFINITION_FILE, "use  SQL_DEFINITIONS;");
  1734.       NEW_LINE (DEFINITION_FILE);
  1735.  
  1736.       LINE := BLANK_CARD;
  1737.       INSERT_SLICE (LINE, "with ", 1);
  1738.       INSERT_SLICE (LINE, DATABASE_NAME, 6);
  1739.       INSERT_SLICE (LINE, "_UNDERLYING;", LAST_FUNCTIONAL_POS (LINE) + 1);
  1740.       PUT_LINE (DEFINITION_FILE, LINE);
  1741.  
  1742.       LINE := BLANK_CARD;
  1743.       INSERT_SLICE (LINE, "use  ", 1);
  1744.       INSERT_SLICE (LINE, DATABASE_NAME, 5);
  1745.       INSERT_SLICE (LINE, "_UNDERLYING;", LAST_FUNCTIONAL_POS (LINE) + 1);
  1746.       PUT_LINE (DEFINITION_FILE, LINE);
  1747.  
  1748.       NEW_LINE (DEFINITION_FILE);
  1749.       LINE := BLANK_CARD;
  1750.       INSERT_SLICE (LINE, "package body ", 1);
  1751.       INSERT_SLICE (LINE, DATABASE_NAME, 14);
  1752.       INSERT_SLICE (LINE, "_DATABASE is ", LAST_FUNCTIONAL_POS (LINE) + 1);
  1753.       PUT_LINE (DEFINITION_FILE, LINE);
  1754.       NEW_LINE (DEFINITION_FILE);
  1755.  
  1756.       GENERATE_FUNCTION_BODY_DECLARATIONS (DEFINITION_FILE);
  1757.  
  1758.       NEW_LINE (DEFINITION_FILE);
  1759.       LINE := BLANK_CARD;
  1760.       INSERT_SLICE (LINE, " end ", 1);
  1761.       INSERT_SLICE (LINE, DATABASE_NAME, 6);
  1762.       INSERT_SLICE (LINE, "_DATABASE", LAST_FUNCTIONAL_POS (LINE) + 1);
  1763.       INSERT_SLICE (LINE, "; ", LAST_FUNCTIONAL_POS (LINE) + 1);
  1764.       PUT_LINE (DEFINITION_FILE, LINE);
  1765.  
  1766.     end CREATE_DATABASE_DEFINITIONS_FILE;
  1767.  
  1768.   begin
  1769.  
  1770.     CREATE_FIELD_LIST (FIRST_FIELD_NODE);
  1771.  
  1772.     PUT ("Input physical name of underlying package: ");
  1773.  
  1774.     GET_LINE (UNDERLYING_FILE_NAME, LENGTH);
  1775.     CREATE (UNDERLYING_FILE, OUT_FILE, UNDERLYING_FILE_NAME (1 .. LENGTH));
  1776.  
  1777.     NEW_LINE;
  1778.  
  1779.     CREATE_UNDERLYING_PACKAGE (FIRST_FIELD_NODE, DATABASE_NAME,
  1780.                    UNDERLYING_FILE);
  1781.  
  1782.     CLOSE (UNDERLYING_FILE);
  1783.  
  1784.     PUT ("Input physical name of database definitions package: ");
  1785.  
  1786.     GET_LINE (DEFINITION_FILE_NAME, LENGTH);
  1787.     CREATE (DEFINITION_FILE, OUT_FILE, DEFINITION_FILE_NAME (1 .. LENGTH));
  1788.  
  1789.     CREATE_DATABASE_DEFINITIONS_FILE
  1790.        (FIRST_FIELD_NODE, DATABASE_NAME, DEFINITION_FILE);
  1791.  
  1792.     CLOSE (DEFINITION_FILE);
  1793.  
  1794.     PUT_LINE ("End of Ada/SQL generator procedure.");
  1795.  
  1796. end GENERATE_SQL_DDL;
  1797.  
  1798.  
  1799. end SQL_DDL;
  1800. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1801. --driver.ada
  1802. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1803. with READ_DDL;
  1804.  use READ_DDL;
  1805.  
  1806. with TOKEN_INPUT;
  1807.  use TOKEN_INPUT;
  1808.  
  1809. with SQL_DDL;
  1810.  use SQL_DDL;
  1811.  
  1812. with TEXT_IO;
  1813.  use TEXT_IO;
  1814.  
  1815. procedure DRIVER is
  1816.  
  1817.   INPUT        : INPUT_STREAM;
  1818.   PACKAGE_NAME : STRING (1..80);
  1819.   DDL_FILE     : STRING (1..80);
  1820.   LAST         : POSITIVE;
  1821.   LENGTH       : NATURAL;
  1822.  
  1823. begin
  1824.  
  1825.   INPUT := CREATE_STREAM (80);
  1826.   SET_STREAM (INPUT);
  1827.   PUT ("Input the name of the Ada DDL file: ");
  1828.   GET_LINE (DDL_FILE, LENGTH);
  1829.   OPEN_INPUT (INPUT, DDL_FILE (1..LENGTH));
  1830.   SCAN_DDL (PACKAGE_NAME, LAST);
  1831.   GENERATE_SQL_DDL (PACKAGE_NAME (1..LAST));
  1832.   CLOSE_INPUT (INPUT);
  1833.  
  1834. end DRIVER;
  1835.