home *** CD-ROM | disk | FTP | other *** search
/ PC World 1998 October / PCWorld_1998-10_cd.bin / software / prehled / komix / DATA.Z / gen_db_fnc.tcl < prev    next >
Text File  |  1997-06-12  |  51KB  |  1,679 lines

  1. #---------------------------------------------------------------------------
  2. #
  3. # Copyright (c) 1994 by Westmount Technology B.V., Delft, The Netherlands.
  4. #
  5. # This software is furnished under a license and may be used only in
  6. # accordance with the terms of such license and with the inclusion of
  7. # the above copyright notice. This software or any other copies thereof
  8. # may not be provided or otherwise made available to any other person.
  9. # No title to and ownership of the software is hereby transferred.
  10. #
  11. # The information in this software is subject to change without notice
  12. # and should not be construed as a commitment by Westmount Technology B.V.
  13. #
  14. #---------------------------------------------------------------------------
  15. #
  16. #    File        : @(#)gen_db_fnc.tcl    /main/titanic/6
  17. #    Original date    : 15-12-1994
  18. #    Description    : NewEra generator functions, database dependent
  19. #
  20. #---------------------------------------------------------------------------
  21. #
  22.  
  23. require serial_utl.tcl
  24. require ne_serial.tcl
  25.  
  26. proc db_class::gen_class_decl {class} {
  27.     if [lempty [$class genNodeSet]] {
  28.         add_hdr_inc_name DBObject
  29.         set sect $ne_sections(h_class_nm_sect)
  30.         $sect append "CLASS [$class getName] "
  31.         $sect append "DERIVED FROM DBObject\n"
  32.     } else {
  33.         class::gen_class_decl $class
  34.     }
  35.  
  36. }
  37.  
  38. proc db_qual_assoc_attrib::generate {attrib class} {
  39.     gen_for_db_assoc $attrib $class
  40. }
  41.  
  42. proc db_qual_assoc_attrib::any_set {attrib class prefix} {
  43.     set type [[$attrib ooplType] getName]
  44.     set name [$attrib getName]
  45.     set cl_name [$class getName]
  46.     set class_data [uncap $cl_name]Data
  47.     set key [get_qualifier_name $attrib]
  48.     set qual [$attrib qualifier]
  49.     set q_type [generate_ixval [$qual ooplType] fwd]
  50.     set sect [get_assoc_hdr_sect $attrib w]
  51.     set access [get_access_mode [get_assoc_access $attrib] w]
  52.     $sect append "${access}FUNCTION $prefix[cap $name]($key "
  53.     $sect append "$q_type, new_$name $type) RETURNING INTEGER\n"
  54.     set sect [get_assoc_src_sect $attrib w]
  55.     $sect append "FUNCTION $cl_name::$prefix[cap $name]($key "
  56.     $sect append "$q_type, new_$name $type) RETURNING INTEGER\n"
  57.     $sect indent +
  58.     set link [$attrib link]
  59.     set opp_link [$attrib oppositeLink]
  60.     set my_tab [$class table]
  61.     set my_tab_nm [$my_tab getUniqueName]
  62.     set dt_tab [$link detail]
  63.     set dt_tab_nm [$dt_tab getUniqueName]
  64.     set op_tab [$opp_link master]
  65.     set op_tab_nm [$op_tab getUniqueName]
  66.     set q_col [[$attrib qualifier] column]
  67.     set param_nr 2
  68.     expand_text $sect {
  69.         VARIABLE stmt ixSQLStmt(getConnection())
  70.         VARIABLE ~${op_tab_nm}_data ixRow =\
  71.             new_~$name.~[uncap $type]Data
  72.  
  73.         CALL stmt.prepare("EXECUTE PROCEDURE pins_~${dt_tab_nm}(" ||
  74.             "p_~[$q_col getUniqueName] = ?, " ||
  75.             "~[gen_dyn_compare_cl $sect $link p_ "" \
  76.                 ", \" ||\n\""], " ||
  77.             "~[gen_dyn_compare_cl $sect $opp_link p_ "" \
  78.                 ", \" ||\n\""])")
  79.         CALL stmt.setParam(1, ~$key)
  80.         ~[gen_setparam_cl $sect $link param_nr $class_data]
  81.         ~[gen_setparam_cl $sect $opp_link param_nr ${op_tab_nm}_data]
  82.         CALL stmt.execute()
  83.  
  84.         IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  85.             RETURN 0
  86.         END IF
  87.         RETURN -1
  88.     }
  89.     $sect indent -
  90.     $sect append "END FUNCTION\n\n"
  91. }
  92.  
  93. proc db_qual_assoc_attrib::one_set {attrib class} {
  94.     db_qual_assoc_attrib::any_set $attrib $class "set"
  95. }
  96.  
  97. proc db_qual_assoc_attrib::one_remove {attrib class} {
  98.     set type [[$attrib ooplType] getName]
  99.     set name [$attrib getName]
  100.     set cl_name [$class getName]
  101.     set class_data [uncap $cl_name]Data
  102.     set key [get_qualifier_name $attrib]
  103.     set qual [$attrib qualifier]
  104.     set q_type [generate_ixval [$qual ooplType] fwd]
  105.     set sect [get_assoc_hdr_sect $attrib w]
  106.     set access [get_access_mode [get_assoc_access $attrib] w]
  107.     $sect append "${access}FUNCTION remove[cap $name]($key $q_type)\
  108.             RETURNING INTEGER\n"
  109.     set link [$attrib link]
  110.     set my_tab_nm [[$class table] getUniqueName]
  111.     set dt_tab_nm [[$link detail] getUniqueName]
  112.     set q_col [$qual column]
  113.     set sect [get_assoc_src_sect $attrib w]
  114.     set param_nr 1
  115.     expand_text $sect {
  116.     FUNCTION ~$cl_name::remove~[cap $name](~$key ~$q_type)\
  117.             RETURNING INTEGER
  118.         VARIABLE stmt ixSQLStmt(getConnection())
  119.  
  120.         CALL stmt.prepare("EXECUTE PROCEDURE pdel_~${dt_tab_nm}(" ||
  121.             "~[gen_dyn_compare_cl $sect $link p_ "" \
  122.                 ", \" ||\n\""], " ||
  123.             "p_~$key = ?)")
  124.         ~[gen_setparam_cl $sect $link param_nr $class_data]
  125.         CALL stmt.setParam(~$param_nr, ~$key)
  126.         CALL stmt.execute()
  127.  
  128.         IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  129.             RETURN 0
  130.         END IF
  131.         RETURN -1
  132.     END FUNCTION
  133.  
  134.     }
  135. }
  136.  
  137. proc db_qual_assoc_attrib::one_get {attrib class} {
  138.     set type [[$attrib ooplType] getName]
  139.     set name [$attrib getName]
  140.     set cl_name [$class getName]
  141.     set class_data [uncap $cl_name]Data
  142.     set key [get_qualifier_name $attrib]
  143.     set qual [$attrib qualifier]
  144.     set q_type [generate_ixval [$qual ooplType] fwd]
  145.     set sect [get_assoc_hdr_sect $attrib r]
  146.     set access [get_access_mode [get_assoc_access $attrib] r]
  147.     $sect append "${access}FUNCTION get[cap $name]($key $q_type)\
  148.             RETURNING $type\n"
  149.     set link [$attrib link]
  150.     set opp_link [$attrib oppositeLink]
  151.     set my_tab_nm [[$class table] getUniqueName]
  152.     set dt_tab_nm [[$link detail] getUniqueName]
  153.     set q_col [$qual column]
  154.     set sect [get_assoc_src_sect $attrib r]
  155.     set param_nr 1
  156.     expand_text $sect {
  157.     FUNCTION ~$cl_name::get~[cap $name](~$key ~$q_type) RETURNING ~$type
  158.         VARIABLE stmt ixSQLStmt(getConnection())
  159.         VARIABLE ~${dt_tab_nm}_datai ixRow
  160.         
  161.         CALL stmt.prepare("SELECT ~[gen_col_listl $sect $opp_link] " ||
  162.             "FROM ~$dt_tab_nm " ||
  163.             "WHERE ~[gen_dyn_compare_cl $sect $link "" "" \
  164.                 " AND \" ||\n\""] AND " ||
  165.                 "~$key = ?")
  166.         ~[gen_setparam_cl $sect $link param_nr $class_data]
  167.         CALL stmt.setParam(~$param_nr, ~$key)
  168.  
  169.         CALL stmt.execute()
  170.         LET ~${dt_tab_nm}_datai = stmt.fetch()
  171.         IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  172.             RETURN NULL
  173.         END IF
  174.         RETURN ~$type::findInDBByType(~[gen_rowgetvalinc_l $sect \
  175.                 $opp_link ${dt_tab_nm}_datai "" ",\n"])
  176.             CAST ~$type
  177.     END FUNCTION
  178.  
  179.     }
  180. }
  181.  
  182. proc db_qual_assoc_attrib::many_set {attrib class} {
  183.     db_qual_assoc_attrib::any_set $attrib $class "add"
  184. }
  185.  
  186. proc db_qual_assoc_attrib::many_remove {attrib class} {
  187.     set type [[$attrib ooplType] getName]
  188.     set name [$attrib getName]
  189.     set cl_name [$class getName]
  190.     set class_data [uncap $cl_name]Data
  191.     set key [get_qualifier_name $attrib]
  192.     set qual [$attrib qualifier]
  193.     set q_type [generate_ixval [$qual ooplType] fwd]
  194.     set sect [get_assoc_hdr_sect $attrib w]
  195.     set access [get_access_mode [get_assoc_access $attrib] w]
  196.     $sect append "${access}FUNCTION remove[cap $name]($key $q_type,\
  197.             toRemove $type) RETURNING INTEGER\n"
  198.     set link [$attrib link]
  199.     set opp_link [$attrib oppositeLink]
  200.     set my_tab_nm [[$class table] getUniqueName]
  201.     set dt_tab_nm [[$link detail] getUniqueName]
  202.     set ot_tab_nm [[$opp_link master] getUniqueName]
  203.     set q_col [$qual column]
  204.     set sect [get_assoc_src_sect $attrib w]
  205.     set param_nr 1
  206.     expand_text $sect {
  207.     FUNCTION ~$cl_name::remove~[cap $name](~$key ~$q_type, toRemove ~$type)\
  208.             RETURNING INTEGER
  209.         VARIABLE stmt ixSQLStmt(getConnection())
  210.         VARIABLE ~${ot_tab_nm}_data ixRow =\
  211.             toRemove.~[uncap $type]Data
  212.  
  213.         CALL stmt.prepare("EXECUTE PROCEDURE pdel_~${dt_tab_nm}(" ||
  214.             "~[gen_dyn_compare_cl $sect $link "p_" \
  215.                 ", \" ||\n\""], " ||
  216.             "~[gen_dyn_compare_cl $sect $opp_link "p_" \
  217.                 ", \" ||\n\""], " ||
  218.             "p_~$key = ?)")
  219.         ~[gen_setparam_cl $sect $link param_nr $class_data]
  220.         ~[gen_setparam_cl $sect $opp_link param_nr ${ot_tab_nm}_data]
  221.         CALL stmt.setParam(~$param_nr, ~$key)
  222.         CALL stmt.execute()
  223.  
  224.         IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  225.             RETURN -1
  226.         END IF
  227.         RETURN 0
  228.     END FUNCTION
  229.  
  230.     }
  231. }
  232.  
  233. proc db_qual_assoc_attrib::many_get {attrib class} {
  234.     set setpfx [set_prefix $attrib]
  235.     set type [[$attrib ooplType] getName]
  236.     set type_of_set [${setpfx}set_type_name [$attrib ooplType]]
  237.     set name [$attrib getName]
  238.     set name_of_set [${setpfx}set_name $name]
  239.     set add_func [set ${setpfx}set::add]
  240.     set class_nm [$class getName]
  241.     set class_data [uncap $class_nm]Data
  242.     set key [get_qualifier_name $attrib]
  243.     set qual [$attrib qualifier]
  244.     set q_type [generate_ixval [$qual ooplType] fwd]
  245.     set func_name get[cap $name]Set
  246.     set sect [get_assoc_hdr_sect $attrib r]
  247.     set access [get_access_mode [get_assoc_access $attrib] r]
  248.     $sect append "${access}FUNCTION ${func_name}($name_of_set $type_of_set, $key $q_type) RETURNING INTEGER\n"
  249.     set link [$attrib link]
  250.     set opp_link [$attrib oppositeLink]
  251.     set my_tab_nm [[$class table] getUniqueName]
  252.     set dt_tab_nm [[$link detail] getUniqueName]
  253.     set q_col [$qual column]
  254.     set sect [get_assoc_src_sect $attrib r]
  255.     set param_nr 1
  256.     expand_text $sect {
  257.     FUNCTION ~$class_nm::~${func_name}(~$name_of_set ~$type_of_set,\
  258.             ~$key ~$q_type) RETURNING INTEGER
  259.         VARIABLE stmt ixSQLStmt(getConnection())
  260.         VARIABLE ~${dt_tab_nm}_datai ixRow
  261.         VARIABLE ~${type}Ref ~$type
  262.         VARIABLE addOk INTEGER
  263.  
  264.         CALL stmt.prepare("SELECT ~[
  265.                 gen_col_listl $sect $opp_link] " ||
  266.             "FROM ~$dt_tab_nm " ||
  267.             "WHERE ~[gen_dyn_compare_cl $sect $link \
  268.                 "" "" " AND \" ||\n\""] AND " ||
  269.             "~$key = ?")
  270.         ~[gen_setparam_cl $sect $link param_nr $class_data]
  271.         CALL stmt.setParam(~$param_nr, ~$key)
  272.         CALL stmt.execute()
  273.  
  274.         LET ~${dt_tab_nm}_datai = stmt.fetch()
  275.         WHILE stmt.getODBCErrorCode() == stmt.SQL_Success
  276.             LET ~${type}Ref = ~$type::findInDBByType(~[
  277.                 gen_rowgetvalinc_l $sect $opp_link \
  278.                     ${dt_tab_nm}_datai "" ",\n"])
  279.                 CAST ~$type
  280.             IF ~${type}Ref IS NOT NULL THEN
  281.                 LET addOk = ~$name_of_set.~${add_func}(~${type}Ref)
  282.             END IF
  283.             LET ~${dt_tab_nm}_datai = stmt.fetch()
  284.         END WHILE
  285.         CALL stmt.free(stmt.SQL_Close)
  286.  
  287.         IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  288.             RETURN -1
  289.         END IF
  290.         RETURN 0
  291.     END FUNCTION
  292.  
  293.     }
  294. }
  295.  
  296. proc db_link_attrib::generate {attrib class} {
  297.     set type [$attrib ooplType]
  298.     add_src_inc $type
  299.     add_forward $type
  300.     db_link_attrib::[$attrib getMultiplicity]_generate $attrib $class
  301. }
  302.  
  303. proc db_link_attrib::one_generate {attrib class} {
  304.     set type [[$attrib ooplType] getName]
  305.     set name [$attrib getName]
  306.     set cl_name [$class getName]
  307.     set class_data [uncap $cl_name]Data
  308.     set sect [get_assoc_hdr_sect $attrib r]
  309.     set access [get_access_mode [get_assoc_access $attrib] r]
  310.     set func_name get[cap "${type}Of[cap $name]"]
  311.     $sect append "${access}FUNCTION ${func_name}() RETURNING $type\n\n"
  312.     set link [$attrib link]
  313.     set dt_tab [$link detail]
  314.     set dt_tab_nm [$dt_tab getUniqueName]
  315.     set my_tab_nm [[$class table] getUniqueName]
  316.     set sect [get_assoc_src_sect $attrib r]
  317.     set param_nr 1
  318.     expand_text $sect {
  319.         FUNCTION ~$cl_name::~${func_name}() RETURNING ~$type
  320.             VARIABLE stmt ixSQLStmt(getConnection())
  321.             VARIABLE ~${dt_tab_nm}_datai ixRow
  322.  
  323.             CALL stmt.prepare("SELECT ~[gen_col_list $sect $dt_tab\
  324.                     KEYS] " ||
  325.                 "FROM ~$dt_tab_nm " ||
  326.                 "WHERE ~[gen_dyn_compare_cl $sect $link "" "" \
  327.                     " AND \" ||\n\""]")
  328.             ~[gen_setparam_cl $sect $link param_nr $class_data]
  329.             CALL stmt.execute()
  330.  
  331.             LET ~${dt_tab_nm}_datai= stmt.fetch()
  332.             IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  333.                 RETURN NULL
  334.             END IF
  335.  
  336.             RETURN ~$type::findInDBByType(~[gen_rowgetvalinc $sect \
  337.                 $dt_tab KEYS ${dt_tab_nm}_datai "" ",\n"])
  338.                 CAST ~$type
  339.         END FUNCTION
  340.  
  341.     }
  342. }
  343.  
  344. proc db_link_attrib::many_generate {attrib class} {
  345.     set setpfx [set_prefix $attrib]
  346.     set type [[$attrib ooplType] getName]
  347.     set type_of_set [${setpfx}set_type_name [$attrib ooplType]]
  348.     set name [$attrib getName]
  349.     set func_name get[cap [${setpfx}set_name "${type}Of[cap $name]"]]
  350.     set name_of_set [cap [${setpfx}set_name $name]]
  351.     set add_func [set ${setpfx}set::add]
  352.     set class_nm [$class getName]
  353.     set class_data [uncap $class_nm]Data
  354.     set sect [get_assoc_hdr_sect $attrib r]
  355.     set access [get_access_mode [get_assoc_access $attrib] r]
  356.     $sect append "${access}FUNCTION ${func_name}($name_of_set $type_of_set) RETURNING INTEGER\n"
  357.     set tab_nm [[$class table] getUniqueName]
  358.     set link [$attrib link]
  359.     set dt_table [$link detail]
  360.     set dt_tab_nm [$dt_table getUniqueName]
  361.     set sect [get_assoc_src_sect $attrib r]
  362.     set param_nr 1
  363.     expand_text $sect {
  364.     FUNCTION ~$class_nm::~${func_name}(~$name_of_set ~$type_of_set)\
  365.             RETURNING INTEGER
  366.         VARIABLE stmt ixSQLStmt(getConnection())
  367.         VARIABLE ~${dt_tab_nm}_datai ixRow
  368.         VARIABLE ~${type}Ref ~$type
  369.         VARIABLE addOk INTEGER
  370.  
  371.         CALL stmt.prepare("SELECT ~[
  372.                 gen_col_list $sect $dt_table KEYS] " ||
  373.             "FROM ~$dt_tab_nm " ||
  374.             "WHERE ~[gen_dyn_compare_cl $sect $link \
  375.                 "" "" " AND \" ||\n\""]")
  376.         ~[gen_setparam_cl $sect $link param_nr $class_data]
  377.         CALL stmt.execute()
  378.  
  379.         LET ~${dt_tab_nm}_datai = stmt.fetch()
  380.         WHILE stmt.getODBCErrorCode() == stmt.SQL_Success
  381.             LET ~${type}Ref = ~$type::findInDBByType(~[ \
  382.                 gen_rowgetvalinc $sect $dt_table KEYS \
  383.                 ${dt_tab_nm}_datai "" ",\n"])
  384.                 CAST ~$type
  385.             IF ~${type}Ref IS NOT NULL THEN
  386.                 LET addOk = ~$name_of_set.~${add_func}(~${type}Ref)
  387.             END IF
  388.             LET ~${dt_tab_nm}_datai = stmt.fetch()
  389.         END WHILE
  390.         CALL stmt.free(stmt.SQL_Close)
  391.  
  392.         IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  393.             RETURN -1
  394.         END IF
  395.         RETURN 0
  396.     END FUNCTION
  397.  
  398.     }
  399. }
  400.  
  401. proc db_qual_link_attrib::generate {attrib class} {
  402.     # Only "get" is implemented for link attribs: the link is
  403.     # maintained through the link class itself
  404.     set type [$attrib ooplType]
  405.     add_forward $type
  406.     add_src_inc $type
  407.     db_qual_link_attrib::[$attrib getMultiplicity]_generate $attrib $class
  408. }
  409.  
  410. proc db_qual_link_attrib::one_generate {attrib class} {
  411.     set type [[$attrib ooplType] getName]
  412.     set name [$attrib getName]
  413.     set func_name get[cap "${type}Of[cap $name]"]
  414.     set cl_name [$class getName]
  415.     set class_data [uncap $cl_name]Data
  416.     set key [get_qualifier_name $attrib]
  417.     set qual [$attrib qualifier]
  418.     set q_type [generate_ixval [$qual ooplType] fwd]
  419.     set sect [get_assoc_hdr_sect $attrib r]
  420.     set access [get_access_mode [get_assoc_access $attrib] r]
  421.     $sect append "${access}FUNCTION ${func_name}($key $q_type) RETURNING $type\n"
  422.     set link [$attrib link]
  423.     set sect [get_assoc_src_sect $attrib r]
  424.     expand_text $sect {
  425.     FUNCTION ~$cl_name::~${func_name}(~$key ~$q_type) RETURNING ~$type
  426.         RETURN ~$type::findInDBByType(~[
  427.                 gen_rowgetval_l $sect $link $class_data], ~$key)
  428.             CAST ~$type
  429.     END FUNCTION
  430.  
  431.     }
  432. }
  433.  
  434. proc db_qual_link_attrib::many_generate {attrib class} {
  435.     set setpfx [set_prefix $attrib]
  436.     set type [[$attrib ooplType] getName]
  437.     set type_of_set [${setpfx}set_type_name [$attrib ooplType]]
  438.     set name [$attrib getName]
  439.     set name_of_set [${setpfx}set_name $name]
  440.     set add_func [set ${setpfx}set::add]
  441.     set class_nm [$class getName]
  442.     set class_data [uncap $class_nm]Data
  443.     set key [get_qualifier_name $attrib]
  444.     set qual [$attrib qualifier]
  445.     set q_type [generate_ixval [$qual ooplType] fwd]
  446.     set func_name get[cap "${type}Of[cap $name]"]Set
  447.     set sect [get_assoc_hdr_sect $attrib r]
  448.     set access [get_access_mode [get_assoc_access $attrib] r]
  449.     $sect append "${access}FUNCTION ${func_name}($name_of_set $type_of_set, $key $q_type) RETURNING INTEGER\n"
  450.     set link [$attrib link]
  451.     set opp_link [$attrib oppositeLink]
  452.     set my_tab_nm [[$class table] getUniqueName]
  453.     set dt_tab [$link detail]
  454.     set dt_tab_nm [$dt_tab getUniqueName]
  455.     set q_col [$qual column]
  456.     set sect [get_assoc_src_sect $attrib r]
  457.     set param_nr 1
  458.     expand_text $sect {
  459.     FUNCTION ~$class_nm::~${func_name}(~$name_of_set ~$type_of_set,\
  460.             ~$key ~$q_type) RETURNING INTEGER
  461.         VARIABLE stmt ixSQLStmt(getConnection())
  462.         VARIABLE ~${dt_tab_nm}_datai ixRow
  463.         VARIABLE ~${type}Ref ~$type
  464.         VARIABLE addOk INTEGER
  465.  
  466.         CALL stmt.prepare("SELECT ~[
  467.                 gen_col_list $sect $dt_tab KEYS] " ||
  468.             "FROM ~$dt_tab_nm " ||
  469.             "WHERE ~[gen_dyn_compare_cl $sect $link \
  470.                 "" "" " AND \" ||\n\""] AND " ||
  471.                 "~$key = ?")
  472.         ~[gen_setparam_cl $sect $link param_nr $class_data]
  473.         CALL stmt.setParam(~$param_nr, ~$key)
  474.         CALL stmt.execute()
  475.  
  476.         LET ~${dt_tab_nm}_datai = stmt.fetch()
  477.         WHILE stmt.getODBCErrorCode() == stmt.SQL_Success
  478.             LET ~${type}Ref = ~$type::findInDBByType(~[ \
  479.                 gen_rowgetvalinc $sect $dt_tab KEYS \
  480.                 ${dt_tab_nm}_datai "" ",\n"])
  481.                 CAST ~$type
  482.             IF ~${type}Ref IS NOT NULL THEN
  483.                 LET addOk = ~$name_of_set.~${add_func}(~${type}Ref)
  484.             END IF
  485.             LET ~${dt_tab_nm}_datai = stmt.fetch()
  486.         END WHILE
  487.         CALL stmt.free(stmt.SQL_Close)
  488.  
  489.         IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  490.             RETURN -1
  491.         END IF
  492.         RETURN 0
  493.     END FUNCTION
  494.  
  495.     }
  496. }
  497.  
  498. proc db_rv_link_attrib::generate {attrib class} {
  499.     set type [[$attrib ooplType] getName]
  500.     add_src_inc [$attrib ooplType]
  501.     add_forward [$attrib ooplType]
  502.     set name [$attrib getName]
  503.     set cl_name [$class getName]
  504.     set class_data [uncap $cl_name]Data
  505.     set sect $ne_sections(h_pub_func_sect)
  506.     $sect append "PUBLIC FUNCTION get[cap $name]() RETURNING $type\n\n"
  507.     set link [$attrib link]
  508.     set sect $ne_sections(c_impl_no_regen_sect)
  509.     expand_text $sect {
  510.         FUNCTION ~$cl_name::get~[cap $name]() RETURNING ~$type
  511.             RETURN ~$type::findInDBByType(~[
  512.                 gen_rowgetval_l $sect $link $class_data])
  513.                 CAST ~$type
  514.         END FUNCTION
  515.  
  516.     }
  517. }
  518.  
  519. proc db_rv_link_attrib::gen_initializer {attrib init decl_s body_s class} {
  520.     set name [$init getName]
  521.     set type [$attrib ooplType]
  522.     set class_data [uncap [$class getName]]Data
  523.     gen_assign_cl $body_s [$attrib link] $class_data ""\
  524.         $name.[uncap [$type getName]]Data ""
  525. }
  526.  
  527. proc db_link_class::generate {class} {
  528.     db_class::generate $class
  529. }
  530.  
  531. proc db_class::generate {class} {
  532.     add_hdr_sys_inc_name ixrow
  533.     add_src_sys_inc_name ixstmt
  534.  
  535.     class::generate $class
  536. }
  537.  
  538.  
  539. # for db classes db_constructor::generate generates a function called init
  540. # i.s.o. a real constructor;
  541. #
  542. proc db_constructor::generate {ctor class} {
  543.     global exists_ctor
  544.     set exists_ctor 1
  545.     if [is_eq_db_ctor $ctor $class] {
  546.         # it wil be generated later
  547.         global db_ctor_is_unique
  548.         set db_ctor_is_unique 1
  549.         return
  550.     }
  551.     # we have a double 'ctor' !
  552.     set class_nm [$class getName]
  553.         set class_data [uncap $class_nm]Data
  554.     set sect $ne_sections(h_pub_func_sect)
  555.     $sect append "FUNCTION init[cap $class_nm]"
  556.     set with_default 1
  557.     set with_types 1
  558.     gen_db_ctor_params $class $sect $with_default $with_types
  559.     $sect append " RETURNING INTEGER\n"
  560.     set sect $ne_sections(c_impl_no_regen_sect)
  561.     $sect append "FUNCTION $class_nm::init[cap $class_nm]"
  562.     set with_default 0
  563.     gen_db_ctor_params $class $sect $with_default $with_types
  564.     $sect append " RETURNING INTEGER\n"
  565.     $sect indent +
  566.     $sect append "VARIABLE retVal ixValue\n\n"
  567.     set table [$class table]
  568.     gen_assign_null $sect $table NULL_AND_NO_INIT $class_data
  569.     set TYPE_ID_NM_col_nr [get_column_nr [lindex \
  570.         [get_col_list $table TYPE] 0]]
  571.     $sect append "LET retVal =\
  572.         $class_data.setVal(getClassName(), $TYPE_ID_NM_col_nr)\n"
  573.     foreach init [$ctor initializerSet] {
  574.         generate $init $sect $sect $sect $class
  575.     }
  576.     $sect append "\nRETURN 0\n"
  577.     $sect indent -
  578.     $sect append "END FUNCTION\n\n"
  579.  
  580.     set with_default 1
  581.     set with_types 1
  582.     expand_text $ne_sections(h_pub_func_sect) {
  583.         SHARED FUNCTION NEW~${class_nm}~[gen_db_ctor_params \
  584.         $class $current_section $with_default $with_types \
  585.         ] RETURNING ~${class_nm}
  586.     }
  587.     expand_text $ne_sections(c_impl_no_regen_sect) {
  588.         FUNCTION ~${class_nm}::NEW~${class_nm}~[
  589.             gen_db_ctor_params $class $current_section \
  590.             $with_default $with_types]\
  591.             RETURNING ~${class_nm}
  592.             VARIABLE tmp ~${class_nm} = NEW ~${class_nm}()
  593.  
  594.             IF tmp.init~[cap $class_nm]~[gen_db_ctor_params \
  595.                 $class $current_section 0 0] < 0 THEN
  596.                 RETURN NULL
  597.             END IF
  598.             RETURN tmp
  599.         END FUNCTION
  600.  
  601.     }
  602. }
  603.  
  604. # used by db_constructor::generate
  605. #
  606. proc gen_db_ctor_params {class sect with_default with_types} {
  607.     if $with_default {
  608.         set decl fwd
  609.     } else {
  610.         set decl inc
  611.     }
  612.  
  613.     $sect append "("
  614.     set first 1
  615.     set is_db 1
  616.     foreach param [$class creationParamSet] {
  617.         parameter::generate $param $sect first $decl $is_db $with_types
  618.         set default [get_default_value $param]
  619.         if {$with_default && $default != ""} {
  620.             $sect append " : $default"
  621.         }
  622.     }
  623.     $sect append ")"
  624. }
  625.  
  626.  
  627. proc db_class_before {class} {
  628.     set class_nm [$class getName]
  629.     $ne_sections(h_priv_data_sect) append "SHARED PRIVATE VARIABLE\
  630.         [uncap $class_nm]RowSchema ixRow\n"
  631.     $ne_sections(c_static_sect) append "VARIABLE\
  632.         ${class_nm}::[uncap $class_nm]RowSchema ixRow = NULL\n"
  633.     $ne_sections(c_static_sect) append \
  634.         "CONSTANT ${class_nm}Str = \"$class_nm\"\n"
  635. }
  636.  
  637. proc db_class_after {class} {
  638.     set class_nm [$class getName]
  639.     set uclass_nm [uncap $class_nm]
  640.     set class_data ${uclass_nm}Data
  641.     global db_ctor_is_unique
  642.     global exists_ctor
  643.     if {! $exists_ctor} {
  644.         set db_ctor_is_unique 1
  645.         set exists_ctor 1
  646.     }
  647.     if [lempty [$class genNodeSet]] {
  648.         db_class::gen_for_base $class
  649.     }
  650.     db_class::gen_for_derived $class
  651.  
  652.     set table [$class table]
  653.     set tab_nm [$table getUniqueName]
  654.     expand_text $ne_sections(h_pub_data_sect) {
  655.         PUBLIC VARIABLE ~$class_data ixRow
  656.     }
  657.     if $db_ctor_is_unique {
  658.         set bykeys ""
  659.     } else {
  660.         set bykeys "ByKeys"
  661.     }
  662.     expand_text $ne_sections(h_ctor_sect) {
  663.         FUNCTION ~${class_nm}()
  664.     }
  665.     set sect $ne_sections(h_pub_func_sect)
  666.     expand_text $sect {
  667.         SHARED FUNCTION NEW~${class_nm}~${bykeys}(~[gen_param_decl_ne \
  668.             $sect $table KEYS_NO_TYPE fwd]) RETURNING ~${class_nm}
  669.     }
  670.     set genByRow 0
  671.     if {$genByRow} {
  672.         expand_text $sect {
  673.             SHARED FUNCTION NEW~${class_nm}ByRow(initRow ixRow)\
  674.                 RETURNING ~${class_nm}
  675.         }
  676.     }
  677.  
  678.     set sect $ne_sections(h_pub_func_sect)
  679.     expand_text $sect {
  680.         FUNCTION init~[cap $class_nm]~${bykeys}(~[gen_param_decl_ne \
  681.             $sect $table KEYS_NO_TYPE fwd]) RETURNING INTEGER
  682.     }
  683.     if {$genByRow} {
  684.         expand_text $sect {
  685.             FUNCTION init~[cap $class_nm]ByRow(initRow ixRow)\
  686.                 RETURNING INTEGER
  687.         }
  688.     }
  689.  
  690.     set sect $ne_sections(h_pub_func_sect)
  691.     expand_text $sect {
  692.         PUBLIC FUNCTION insertInDB() RETURNING INTEGER
  693.         PUBLIC FUNCTION readFromDB() RETURNING INTEGER
  694.         PUBLIC FUNCTION deleteFromDB() RETURNING INTEGER
  695.         PUBLIC FUNCTION updateInDB() RETURNING INTEGER
  696.  
  697.     }
  698.  
  699.     regen_unset ${class_nm} "()"
  700.     set sect $ne_sections(c_ctor_init_sect)
  701.     $sect append "FUNCTION $class_nm::${class_nm}()\n"
  702.     set sect $ne_sections(c_ctor_body_sect)
  703.     expand_text $sect {
  704.         VARIABLE stmt ixSQLStmt
  705.  
  706.         LET className = NEW ixString(~${class_nm}Str)
  707.         IF ~${uclass_nm}RowSchema IS NULL THEN
  708.             LET stmt = NEW ixSQLStmt(getConnection())
  709.             CALL stmt.prepare("~[padString "SELECT " \
  710.                 [gen_col_list_str $table ALL] \
  711.                 " " "\" || \""]" ||
  712.                 "FROM ~$tab_nm")
  713.             LET ~${uclass_nm}RowSchema = stmt.allocateRow()
  714.         END IF
  715.         LET ~$class_data = COPY ~${uclass_nm}RowSchema
  716.  
  717.     }
  718.     set sect $ne_sections(c_impl_no_regen_sect)
  719.     expand_text $sect {
  720.         FUNCTION ~${class_nm}::NEW~${class_nm}~${bykeys}(~[gen_param_decl_ne $sect $table KEYS_NO_TYPE inc]) RETURNING ~${class_nm}
  721.             VARIABLE tmp ~${class_nm} = NEW ~${class_nm}()
  722.  
  723.             IF tmp.init~[cap $class_nm]~${bykeys}(~[gen_col_list \
  724.                 $sect $table KEYS_NO_TYPE]) < 0 THEN
  725.                 RETURN NULL
  726.             END IF
  727.             RETURN tmp
  728.         END FUNCTION
  729.  
  730.     }
  731.     if {$genByRow} {
  732.         expand_text $sect {
  733.         FUNCTION ~${class_nm}::NEW~${class_nm}ByRow(initRow ixRow) RETURNING ~${class_nm}
  734.             VARIABLE tmp ~${class_nm} = NEW ~${class_nm}()
  735.             VARIABLE copyRow ixRow = COPY initRow
  736.             LET copyRow.isCountLocked = FALSE
  737.  
  738.             IF tmp.init~[cap $class_nm]ByRow(copyRow) < 0 THEN
  739.                 RETURN NULL
  740.             END IF
  741.             RETURN tmp
  742.         END FUNCTION
  743.  
  744.         }
  745.     }
  746.  
  747.     set TYPE_ID_NM_col_nr [get_column_nr [lindex [get_col_list $table TYPE] 0]]
  748.  
  749.     expand_text $sect {
  750.         FUNCTION ~$class_nm::init~[cap $class_nm]~${bykeys}(~[\
  751.             gen_param_decl_ne $sect $table KEYS_NO_TYPE inc])\
  752.             RETURNING INTEGER
  753.             VARIABLE retVal ixValue
  754.  
  755.             IF ~$class_data IS NULL THEN
  756.                 RETURN -1
  757.             END IF
  758.             ~[db_class::init_bases_bykeys $sect $class $bykeys]
  759.             ~[gen_assign_null $sect $table NONKEYS $class_data]
  760.             LET retVal = ~$class_data.setVal(getClassName(),\
  761.                 ~$TYPE_ID_NM_col_nr)
  762.             ~[gen_assign $sect $table KEYS_NO_TYPE $class_data]
  763.             RETURN 0
  764.         END FUNCTION
  765.  
  766.     }
  767.     if {$genByRow} {
  768.         expand_text $sect {
  769.         FUNCTION ~$class_nm::init~[cap $class_nm]ByRow(initRow ixRow)\
  770.             RETURNING INTEGER
  771.             VARIABLE retVal ixObject
  772.  
  773.             IF ~$class_data IS NULL THEN
  774.                 RETURN -1
  775.             END IF
  776.             ~[db_class::init_bases_byrow $sect $class]
  777.             ~[gen_assign_initrow $sect $table KEYS_FIELDS \
  778.                 $class_data initRow]
  779.             RETURN 0
  780.         END FUNCTION
  781.  
  782.         }
  783.     }
  784.     set serial_nr [get_serial_column_nr $table]
  785.     if {$serial_nr != 0} {
  786.         expand_text $sect {
  787.             FUNCTION ~$class_nm::insertInDB() RETURNING INTEGER
  788.                 VARIABLE stmt ixSQLStmt(getConnection())
  789.                 VARIABLE theSerial ixInteger
  790.  
  791.             ~[    call_for_all_bases $class $sect insertInDB
  792.             ]    
  793.                 CALL stmt.prepare("INSERT INTO ~$tab_nm " ||
  794.                     "VALUES (~[gen_dyn_place_holders $sect\
  795.                         $table ALL])")
  796.                 CALL stmt.setParams(~$class_data)
  797.                 CALL stmt.execute()
  798.  
  799.                 LET theSerial =\
  800.                     ~$class_data.getVal(~$serial_nr)\
  801.                     CAST ixInteger
  802.                 IF theSerial.value == 0 THEN
  803.                     LET theSerial.value = SQLCA.SQLERRD[2]
  804.                 END IF
  805.                 RETURN processSqlStatus(stmt)
  806.             END FUNCTION
  807.  
  808.         }
  809.     } else {
  810.         expand_text $sect {
  811.             FUNCTION ~$class_nm::insertInDB() RETURNING INTEGER
  812.                 VARIABLE stmt ixSQLStmt(getConnection())
  813.  
  814.             ~[    call_for_all_bases $class $sect insertInDB
  815.             ]~[    call_for_all_bases_set_serial $class $sect
  816.             ]
  817.                 CALL stmt.prepare("EXECUTE PROCEDURE\
  818.                     pins_~${tab_nm}(~[gen_dyn_place_holders\
  819.                         $sect $table ALL])")
  820.                 CALL stmt.setParams(~$class_data)
  821.                 CALL stmt.execute()
  822.                 RETURN processSqlStatus(stmt)
  823.             END FUNCTION
  824.  
  825.         }
  826.     }
  827.     set param_nr 1
  828.     expand_text $sect {
  829.         FUNCTION ~$class_nm::readFromDB() RETURNING INTEGER
  830.             VARIABLE stmt ixSQLStmt(getConnection())
  831.  
  832.             CALL stmt.prepare("~[padString "SELECT " \
  833.                 [gen_col_list_str $table ALL] \
  834.                 " " "\" || \""]" ||
  835.                 "FROM ~$tab_nm " ||
  836.                 "WHERE ~[gen_dyn_compare $sect $table KEYS \
  837.                     "" "" " AND \" ||\n\""]")
  838.             ~[gen_setparamc $sect $table param_nr KEYS $class_data]
  839.             CALL stmt.execute()
  840.             CALL stmt.fetchInto(~$class_data)
  841.             IF processSqlStatus(stmt) < 0 THEN
  842.                 RETURN -1
  843.             END IF~[
  844.             call_for_all_bases $class $sect readFromDB]
  845.             RETURN 0
  846.         END FUNCTION
  847.  
  848.     }
  849.     set param_nr 1
  850.     expand_text $sect {
  851.         FUNCTION ~$class_nm::deleteFromDB() RETURNING INTEGER
  852.             VARIABLE stmt ixSQLStmt(getConnection())
  853.  
  854.             CALL stmt.prepare("EXECUTE PROCEDURE pdel_~${tab_nm}(~[\
  855.                 gen_dyn_place_holders $sect $table KEYS])")
  856.             ~[gen_setparamc $sect $table param_nr KEYS $class_data]
  857.             CALL stmt.execute()
  858.             IF processSqlStatus(stmt) < 0 THEN
  859.                 RETURN -1
  860.             END IF~[
  861.             call_for_all_bases $class $sect deleteFromDB]
  862.             RETURN 0
  863.         END FUNCTION
  864.  
  865.     }
  866.     if {![lempty [get_col_list $table NONKEYFIELDS]]} {
  867.         set param_nr 1
  868.         expand_text $sect {
  869.             FUNCTION ~$class_nm::updateInDB() RETURNING INTEGER
  870.                 VARIABLE stmt ixSQLStmt(getConnection())
  871.  
  872.                 CALL stmt.prepare("UPDATE ~$tab_nm " ||
  873.                     "SET ~[gen_dyn_compare $sect $table \
  874.                     NONKEYFIELDS "" "" ", \" ||\n\""] " ||
  875.                     "WHERE ~[gen_dyn_compare $sect $table \
  876.                     KEYS "" "" " AND \" ||\n\""]")
  877.                 ~[gen_setparamc $sect $table param_nr \
  878.                     "NONKEYFIELDS KEYS" $class_data]
  879.                 CALL stmt.execute()
  880.                 IF processSqlStatus(stmt) < 0 THEN
  881.                     RETURN -1
  882.                 END IF~[
  883.                 call_for_all_bases $class $sect updateInDB]
  884.                 RETURN 0
  885.             END FUNCTION
  886.         }
  887.     } else {
  888.         expand_text $sect {
  889.             FUNCTION ~$class_nm::updateInDB() RETURNING INTEGER
  890.                 ~[call_for_all_bases $class $sect updateInDB]
  891.                 RETURN 0
  892.             END FUNCTION
  893.         }
  894.     }
  895.  
  896. }
  897.  
  898. proc db_class::init_bases_bykeys {sect class bykeys} {
  899.     $sect pushIndent
  900.     set table [$class table]
  901.     foreach gen_node [$class genNodeSet] {
  902.         set super_name [$gen_node getSuperClassName]
  903.         set superClass [$gen_node superClass]
  904.         if ![$superClass isPersistent] {
  905.             continue
  906.         }
  907.         set super_table [$superClass table]
  908.         expand_text $sect {
  909.             IF init~[cap $super_name]~${bykeys}(~[
  910.                 gen_col_list $sect $table IMPKEYS_NO_TYPE \
  911.                     "" "" ", " "" $super_table]) < 0 THEN
  912.                 RETURN -1
  913.             END IF
  914.         }
  915.     }
  916.     $sect popIndent
  917. }
  918.  
  919. proc db_class::init_bases_byrow {sect class} {
  920.         $sect pushIndent
  921.         set table [$class table]
  922.         foreach gen_node [$class genNodeSet] {
  923.         set super_name [$gen_node getSuperClassName]
  924.         set superClass [$gen_node superClass]
  925.         if ![$superClass isPersistent] {
  926.             continue
  927.         }
  928.         set super_table [$superClass table]
  929.         expand_text $sect {
  930.             IF init~[cap $super_name]ByRow(initRow) < 0 THEN
  931.                 RETURN -1
  932.             END IF
  933.         }
  934.     }
  935.     $sect popIndent
  936. }
  937.  
  938. proc db_class::gen_for_base {class} {
  939.     set class_nm [$class getName]
  940.     set table [$class table]
  941.     set setpfx ""
  942.     set type_of_set [${setpfx}set_type_name $class]
  943.     set name_of_set [uncap [${setpfx}set_name $class_nm]]
  944.     set add_func [set ${setpfx}set::add]
  945.     expand_text $ne_sections(h_pub_func_sect) {
  946.         SHARED FUNCTION findInDBByType(~[gen_param_decl_ne $current_section \
  947.             $table KEYS fwd]) RETURNING ~$class_nm
  948.         SHARED FUNCTION findInDB(~[gen_param_decl_ne $current_section \
  949.             $table KEYS_NO_TYPE fwd]) RETURNING ~$class_nm
  950.         SHARED FUNCTION searchInDB(~$name_of_set ~$type_of_set,\
  951.             whereClause ixString : NULL) RETURNING INTEGER
  952.     }
  953.     set sect $ne_sections(c_impl_no_regen_sect)
  954.     expand_text $sect {
  955.         FUNCTION ~$class_nm::searchInDB(~$name_of_set ~$type_of_set,\
  956.             whereClause ixString) RETURNING INTEGER
  957.             VARIABLE stmt ixSQLStmt(DBObject::getConnection())
  958.             VARIABLE ~${class_nm}Ref ~$class_nm
  959.             VARIABLE prepareStr ixString("")
  960.             VARIABLE db_data ixRow
  961.             VARIABLE addOk INTEGER
  962.  
  963.             CALL prepareStr.concat(NEW ixString("SELECT ~[
  964.                 gen_col_list $sect $table KEYS] FROM ~[
  965.                 $table getUniqueName]"))
  966.             IF whereClause IS NOT NULL THEN
  967.                 IF whereClause.getLength() > 0 THEN
  968.                     CALL prepareStr.concat(NEW ixString(" WHERE "))
  969.                     CALL prepareStr.concat(whereClause)
  970.                 END IF
  971.             END IF
  972.  
  973.             CALL stmt.prepare(prepareStr.getValueStr())
  974.             IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  975.                 RETURN -1
  976.             END IF
  977.             CALL stmt.execute()
  978.             IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  979.                 RETURN -1
  980.             END IF
  981.  
  982.             LET db_data = stmt.fetch()
  983.             WHILE stmt.getODBCErrorCode() == stmt.SQL_Success
  984.                 LET ~${class_nm}Ref = findInDBByType(~[ \
  985.                     gen_rowgetvalinc \
  986.                     $sect $table KEYS db_data "" ",\n"])
  987.                 IF ~${class_nm}Ref IS NOT NULL THEN
  988.                     LET addOk = ~$name_of_set.~${add_func}(~${class_nm}Ref)
  989.                 END IF
  990.                 LET db_data = stmt.fetch()
  991.             END WHILE
  992.             CALL stmt.free(stmt.SQL_Close)
  993.  
  994.             IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  995.                 RETURN -1
  996.             END IF
  997.             RETURN 0
  998.         END FUNCTION
  999.  
  1000.         FUNCTION ~$class_nm::findInDBByType(~[gen_param_decl_ne \
  1001.                 $sect $table KEYS inc]) RETURNING ~$class_nm
  1002.             VARIABLE instantiator ~${class_nm}Instantiator
  1003.             VARIABLE actualInstantiator ixString
  1004.  
  1005.             IF ~$TYPE_ID_NM IS NULL THEN
  1006.                 RETURN NULL
  1007.             END IF
  1008.             LET actualInstantiator = COPY ~$TYPE_ID_NM
  1009.             CALL actualInstantiator.concat(NEW\
  1010.                 ixString("Instantiator"))
  1011.             LET instantiator = NEW ~${class_nm}Instantiator() AS\
  1012.                 actualInstantiator.getValueStr()
  1013.             RETURN instantiator.instantiate(~[ \
  1014.                 gen_col_list $sect $table KEYS_NO_TYPE])
  1015.         END FUNCTION
  1016.  
  1017.     }
  1018.     db_class::gen_generic_find $class $table
  1019. }
  1020.  
  1021. proc db_class::gen_generic_find {class table} {
  1022.     set class_nm [$class getName]
  1023.     set sect $ne_sections(c_impl_no_regen_sect)
  1024.     if {[lempty [$class specNodeSet]] && ([$class get_obj_type] != "db_link_class")} {
  1025.         # Simple case: no sub classes
  1026.         expand_text $sect  {
  1027.             FUNCTION ~$class_nm::findInDB(~[gen_param_decl_ne \
  1028.                 $sect $table KEYS_NO_TYPE inc]) RETURNING ~$class_nm
  1029.                 VARIABLE ~$TYPE_ID_NM ixString =\
  1030.                     NEW ixString("~$class_nm")
  1031.                 RETURN findInDBByType(~[
  1032.                     gen_col_list $sect $table KEYS])
  1033.             END FUNCTION
  1034.  
  1035.         }
  1036.         return
  1037.     }
  1038.     # Sub (or link) classes exist. Look up the class type in the database
  1039.     expand_text $sect {
  1040.         FUNCTION ~$class_nm::findInDB(~[gen_param_decl_ne $sect \
  1041.             $table KEYS_NO_TYPE inc]) RETURNING ~$class_nm
  1042.             ~[gen_col_list $sect $table KEYS_TYPE "VARIABLE " " ixString" "" "\n"]
  1043.             VARIABLE ~${TYPE_ID_NM}Row ixRow
  1044.             VARIABLE stmt ixSQLStmt(DBObject::getConnection())
  1045.  
  1046.                         CALL stmt.prepare("SELECT ~[gen_col_list $sect $table KEYS_TYPE] " ||
  1047.                                 "FROM ~[$table getUniqueName] " ||
  1048.                                 "WHERE ~[gen_dyn_compare $sect $table \
  1049.                     KEYS_NO_TYPE "" "" " AND \" ||\n\""]")
  1050.                         ~[gen_setparamc_name $sect $table KEYS_NO_TYPE]
  1051.                         CALL stmt.execute()
  1052.                         LET ~${TYPE_ID_NM}Row = stmt.fetch()
  1053.  
  1054.             IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  1055.                 RETURN NULL
  1056.             END IF
  1057.  
  1058.             ~[set colnr 0
  1059.               $sect pushIndent
  1060.               foreach column [get_col_list $table KEYS_TYPE] {
  1061.                 incr colnr
  1062.                 $sect append "LET [$column getUniqueName] = ${TYPE_ID_NM}Row.getVal($colnr) CAST ixString\n"
  1063.               }
  1064.               $sect popIndent]
  1065.             RETURN findInDBByType(~[gen_col_list $sect $table KEYS])
  1066.         END FUNCTION
  1067.  
  1068.     }
  1069. }
  1070.  
  1071. proc db_class::gen_for_derived {class} {
  1072.     set class_nm [$class getName]
  1073.     set root_nm [[get_root_class $class] getName]
  1074.     set table [$class table]
  1075.     set sect $ne_sections(h_help_class_sect)
  1076.     if {$class_nm != $root_nm} {
  1077.         expand_text $sect {
  1078.  
  1079.         CLASS ~${class_nm}Instantiator DERIVED FROM\
  1080.                 ~${root_nm}Instantiator
  1081.             FUNCTION instantiate(~[gen_param_decl_ne $sect \
  1082.                 $table KEYS_NO_TYPE fwd]) RETURNING ~$root_nm
  1083.         END CLASS
  1084.  
  1085.         }
  1086.     } else {
  1087.         expand_text $sect {
  1088.  
  1089.         FORWARD ~$root_nm
  1090.         CLASS ~${class_nm}Instantiator
  1091.             FUNCTION instantiate(~[gen_param_decl_ne $sect \
  1092.                 $table KEYS_NO_TYPE fwd]) RETURNING ~$root_nm
  1093.         END CLASS
  1094.  
  1095.         }
  1096.     }
  1097.     set sect $ne_sections(c_impl_no_regen_sect)
  1098.     expand_text $sect {
  1099.         FUNCTION ~${class_nm}Instantiator::instantiate(~[ \
  1100.             gen_param_decl_ne $sect $table KEYS_NO_TYPE inc])\
  1101.                 RETURNING ~$root_nm
  1102.             RETURN ~$class_nm::instantiate(~[gen_col_list \
  1103.                 $sect $table KEYS_NO_TYPE])
  1104.         END FUNCTION
  1105.  
  1106.     }
  1107.     set sect $ne_sections(h_pub_func_sect)
  1108.     expand_text $sect {
  1109.         SHARED FUNCTION instantiate(~[gen_param_decl_ne $sect \
  1110.             $table KEYS_NO_TYPE fwd]) RETURNING ~$root_nm
  1111.     }
  1112.     set sect $ne_sections(c_impl_no_regen_sect)
  1113.     global db_ctor_is_unique
  1114.     if $db_ctor_is_unique {
  1115.         set bykeys ""
  1116.     } else {
  1117.         set bykeys "ByKeys"
  1118.     }
  1119.     expand_text $sect {
  1120.         FUNCTION ~$class_nm::instantiate(~[gen_param_decl_ne $sect \
  1121.             $table KEYS_NO_TYPE inc]) RETURNING ~$root_nm
  1122.             VARIABLE tmp ~$class_nm = NEW~${class_nm}~${bykeys}(~[
  1123.                 gen_col_list $sect $table KEYS_NO_TYPE])
  1124.  
  1125.             IF tmp IS NULL THEN
  1126.                 RETURN NULL
  1127.             END IF
  1128.             IF tmp.readFromDB() < 0 THEN
  1129.                 RETURN NULL
  1130.             END IF
  1131.             RETURN tmp
  1132.         END FUNCTION
  1133.  
  1134.     }
  1135. }
  1136.  
  1137. proc db_data_attrib_initial_value {attrib} {
  1138.     set sect $ne_sections(c_ctor_body_iv_sect)
  1139.     set attr_nm [$attrib getName]
  1140.     set iv [$attrib getPropertyValue initial_value]
  1141.     if {$iv == ""} {
  1142.         return
  1143.     }
  1144.     $sect append "CALL set[cap $attr_nm]($iv)\n"
  1145. }
  1146.  
  1147. proc db_data_attrib::generate {attrib class} {
  1148.     set attr_nm [$attrib getName]
  1149.     if {$attr_nm == $TYPE_ID_NM} {
  1150.         return
  1151.     }
  1152.     set col [$attrib column]
  1153.     set col_nr [get_column_nr $col]
  1154.     set class_nm [$class getName]
  1155.     set class_data [uncap $class_nm]Data
  1156.     set is_field [expr {[$col getColumnType] == "field"}]
  1157.         set obj_type [[$attrib ooplType] get_obj_type]
  1158.     set t_par [generate [$attrib ooplType] fwd]
  1159.     if {$t_par == "TEXT" || $t_par == "BYTE"} {
  1160.         set bytetext 1
  1161.     } else {
  1162.         set bytetext 0
  1163.     }
  1164.     set ixval [map_fgl2ixval ${t_par}]
  1165.     set sect [get_attrib_hdr_sect $attrib r]
  1166.     # put db_data_attrib free text
  1167.     # before the access funcs
  1168.     feature::gen_description $attrib $sect
  1169.     add_hdr_sys_inc_name [ixval2hdr $ixval]
  1170.     $sect append "FUNCTION get[cap $attr_nm]() RETURNING ${t_par}\n"
  1171.     $sect append "FUNCTION get[cap $attr_nm]Val()\
  1172.         RETURNING $ixval\n"
  1173.  
  1174.     set sect [get_attrib_hdr_sect $attrib w]
  1175.     if $is_field {
  1176.         if !$bytetext {
  1177.             $sect append \
  1178.             "FUNCTION set[cap $attr_nm](new[cap $attr_nm] ${t_par})\
  1179.                 RETURNING VOID\n"
  1180.         }
  1181.         $sect append \
  1182.             "FUNCTION set[cap $attr_nm]Val(new[\
  1183.                 cap $attr_nm] $ixval) RETURNING VOID\n"
  1184.     }
  1185.     set sect [get_attrib_src_sect $attrib r]
  1186.     expand_text $sect {
  1187.         FUNCTION ~$class_nm::get~[cap $attr_nm]() RETURNING ~${t_par}
  1188.             VARIABLE val ~$ixval = ~$class_data.getVal(~${col_nr})\
  1189.                 CAST ~$ixval
  1190.             RETURN ~[getixvalvalue $ixval val]
  1191.         END FUNCTION
  1192.  
  1193.     }
  1194.     expand_text $sect {
  1195.         FUNCTION ~$class_nm::get~[cap $attr_nm]Val() RETURNING ~$ixval
  1196.             RETURN ~$class_data.getVal(~${col_nr}) CAST ~$ixval
  1197.         END FUNCTION
  1198.  
  1199.     }
  1200.     db_data_attrib_initial_value $attrib
  1201.     if {!$is_field} {
  1202.         return
  1203.     }
  1204.     set sect [get_attrib_src_sect $attrib w]
  1205.     if !$bytetext {
  1206.         expand_text $sect {
  1207.         FUNCTION ~$class_nm::set~[cap $attr_nm](new~[\
  1208.                 cap $attr_nm] ~${t_par}) RETURNING VOID
  1209.             VARIABLE val ~$ixval = ~$class_data.getVal(~${col_nr})\
  1210.                 CAST ~$ixval
  1211.             ~[setixvalvalue $ixval val new[cap $attr_nm]]
  1212.         END FUNCTION
  1213.  
  1214.         }
  1215.     }
  1216.     expand_text $sect {
  1217.         FUNCTION ~$class_nm::set~[cap $attr_nm]Val(new~[\
  1218.                 cap $attr_nm] ~$ixval) RETURNING VOID
  1219.             VARIABLE oldVal ixValue =\
  1220.             ~$class_data.setVal(new~[cap $attr_nm], ~${col_nr})
  1221.         END FUNCTION
  1222.  
  1223.     }
  1224. }
  1225.  
  1226. proc db_assoc_attrib::generate {attrib class} {
  1227.     gen_for_db_assoc $attrib $class
  1228. }
  1229.  
  1230. proc db_assoc_attrib::one_set {attrib class} {
  1231.     set opp [$attrib opposite]
  1232.     if {$opp != "" && [$opp get_obj_type] == "db_qual_assoc_attrib"} {
  1233.         # Can't supply the key for a qualified assoc
  1234.         return
  1235.     }
  1236.     if {$opp != "" && [$opp isMandatory] && 
  1237.             [$opp getMultiplicity] == "one"} {
  1238.         return
  1239.     }
  1240.     set type [[$attrib ooplType] getName]
  1241.     set name [cap [$attrib getName]]
  1242.     set cl_name [$class getName]
  1243.     set sect [get_assoc_hdr_sect $attrib w]
  1244.     set access [get_access_mode [get_assoc_access $attrib] w]
  1245.     $sect append "${access}FUNCTION set${name}(new$name $type)\
  1246.             RETURNING INTEGER\n"
  1247.     set sect [get_assoc_src_sect $attrib w]
  1248.     $sect append "FUNCTION $cl_name::set${name}(new$name $type)\
  1249.             RETURNING INTEGER\n"
  1250.     set link [$attrib link]
  1251.     set table [$link detail]
  1252.     set tab_nm [$table getUniqueName]
  1253.     $sect indent +
  1254.     if {$table == [$class table]} {
  1255.         set master_data [uncap $cl_name]Data
  1256.         set detail_data [uncap $type]_data
  1257.     } else {
  1258.         set master_data [uncap $type]_data
  1259.         set detail_data [uncap $cl_name]Data
  1260.     }
  1261.     set param_nr 1
  1262.     expand_text $sect {
  1263.         VARIABLE stmt ixSQLStmt(getConnection())
  1264.         VARIABLE ~[uncap $type]_data ixRow = new~$name.~[uncap $type]Data
  1265.  
  1266.         CALL stmt.prepare("UPDATE ~$tab_nm " ||
  1267.             "SET ~[gen_dyn_compare_cl $sect $link] " ||
  1268.             "WHERE ~[gen_dyn_compare $sect $table \
  1269.                 KEYS "" "" " AND \" ||\n\""]")
  1270.         ~[gen_setparam_cl $sect $link param_nr $detail_data
  1271.         ]~[gen_setparamc $sect $table param_nr KEYS $master_data ]
  1272.         CALL stmt.execute()
  1273.         IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  1274.             RETURN -1
  1275.         END IF
  1276.         RETURN 0
  1277.     }
  1278.     $sect indent -
  1279.     $sect append "END FUNCTION\n\n"
  1280. }
  1281.  
  1282. proc db_assoc_attrib::one_remove {attrib class} {
  1283.     if [$attrib isMandatory] {
  1284.         return
  1285.     }
  1286.     set opp [$attrib opposite]
  1287.     if {$opp != "" && [$opp get_obj_type] == "db_qual_assoc_attrib"} {
  1288.         return
  1289.     }
  1290.     if {$opp != "" && [$opp isMandatory] && 
  1291.             [$opp getMultiplicity] == "one"} {
  1292.         return
  1293.     }
  1294.     set name [cap [$attrib getName]]
  1295.     set cl_name [$class getName]
  1296.     set class_data [uncap $cl_name]Data
  1297.     set sect [get_assoc_hdr_sect $attrib w]
  1298.     set access [get_access_mode [get_assoc_access $attrib] w]
  1299.     $sect append "${access}FUNCTION remove${name}()\
  1300.         RETURNING INTEGER\n"
  1301.     set sect [get_assoc_src_sect $attrib w]
  1302.     $sect append "FUNCTION $cl_name::remove${name}()\
  1303.         RETURNING INTEGER\n"
  1304.     $sect indent +
  1305.     set link [$attrib link]
  1306.     set table [$link detail]
  1307.     expand_text $sect {
  1308.         VARIABLE stmt ixSQLStmt(getConnection())
  1309.  
  1310.         CALL stmt.prepare("UPDATE ~[$table getUniqueName] " ||
  1311.             "SET ~[gen_col_listl $sect $link "" " = NULL"] " ||
  1312.             "WHERE }
  1313.     set param_nr 1
  1314.     if {$table == [$class table]} {
  1315.         gen_dyn_compare $sect $table KEYS "" "" " AND \" ||\n\""
  1316.         $sect append "\")\n"
  1317.         gen_setparamc $sect $table param_nr KEYS $class_data
  1318.     } else {
  1319.         gen_dyn_compare_cl $sect $link "" "" " AND \" ||\n\""
  1320.         $sect append "\")\n"
  1321.         gen_setparam_cl $sect $link param_nr $class_data
  1322.     }
  1323.     expand_text $sect {
  1324.         CALL stmt.execute()
  1325.         IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  1326.             RETURN -1
  1327.         END IF
  1328.         RETURN 0
  1329.     }
  1330.     $sect indent -
  1331.     $sect append "END FUNCTION\n\n"
  1332. }
  1333.  
  1334. proc db_assoc_attrib::one_get {attrib class} {
  1335.     set type [[$attrib ooplType] getName]
  1336.     set name [cap [$attrib getName]]
  1337.     set cl_name [$class getName]
  1338.     set class_data [uncap $cl_name]Data
  1339.     set sect $ne_sections(h_pub_func_sect)
  1340.     $sect append "PUBLIC FUNCTION get${name}() RETURNING $type\n"
  1341.     set sect $ne_sections(c_impl_no_regen_sect)
  1342.     $sect append "FUNCTION $cl_name::get${name}() RETURNING $type\n"
  1343.     $sect indent +
  1344.     set link [$attrib link]
  1345.     set opp_link [$attrib oppositeLink]
  1346.     set table [$link detail]
  1347.     set tab_nm [$table getUniqueName]
  1348.     set my_row_nm [[$class table] getUniqueName]Row
  1349.     set param_nr 1
  1350.     if {$link != $opp_link} {
  1351.         # opposite side of qual assoc
  1352.         expand_text $sect {
  1353.             VARIABLE stmt ixSQLStmt(getConnection())
  1354.             VARIABLE ~${tab_nm}_datai ixRow
  1355.  
  1356.             CALL stmt.prepare("SELECT ~[gen_col_listl $sect\
  1357.                 $opp_link] " ||
  1358.                 "FROM ~$tab_nm " ||
  1359.                 "WHERE ~[gen_dyn_compare_cl $sect $link "" "" \
  1360.                     " AND \" ||\n\""]")
  1361.             ~[gen_setparam_cl $sect $link param_nr $class_data]
  1362.  
  1363.             CALL stmt.execute()
  1364.                         LET ~${tab_nm}_datai = stmt.fetch()
  1365.             IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  1366.                 RETURN NULL
  1367.             END IF
  1368.             RETURN ~$type::findInDBByType(~[gen_rowgetvalinc_l \
  1369.                 $sect $opp_link ${tab_nm}_datai "" ",\n"])
  1370.                 CAST ~$type
  1371.         }
  1372.         $sect indent -
  1373.         $sect append "END FUNCTION\n\n"
  1374.         return
  1375.     }
  1376.     if {$table == [$class table]} {
  1377.         expand_text $sect {
  1378.             VARIABLE val ixValue
  1379.  
  1380.             ~[gen_null_check $sect $link $class_data NULL]
  1381.             RETURN ~$type::findInDBByType(~[gen_rowgetval_l $sect \
  1382.                     $link $class_data "" ",\n"])
  1383.                 CAST ~$type
  1384.         }
  1385.     } else {
  1386.         expand_text $sect {
  1387.             VARIABLE stmt ixSQLStmt(getConnection())
  1388.             VARIABLE ~${tab_nm}_datai ixRow
  1389.             VARIABLE val ixValue
  1390.  
  1391.             CALL stmt.prepare("SELECT ~[
  1392.                 gen_col_list $sect $table KEYS] " ||
  1393.                 "FROM ~$tab_nm " ||
  1394.                 "WHERE ~[gen_dyn_compare_cl $sect $link "" "" \
  1395.                     " AND \" ||\n\""]")
  1396.             ~[gen_setparam_cl $sect $link param_nr $class_data]
  1397.  
  1398.             CALL stmt.execute()
  1399.             LET ~${tab_nm}_datai = stmt.fetch()
  1400.             IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  1401.                 RETURN NULL
  1402.             END IF
  1403.             ~[gen_null_check $sect $table ${tab_nm}_datai NULL]
  1404.             RETURN ~$type::findInDBByType(~[gen_rowgetvalinc $sect \
  1405.                     $table KEYS ${tab_nm}_datai "" ",\n"])
  1406.                 CAST ~$type
  1407.         }
  1408.     }
  1409.     $sect indent -
  1410.     $sect append "END FUNCTION\n\n"
  1411. }
  1412.  
  1413. proc db_assoc_attrib::many_set {attrib class} {
  1414.     if {[set opp [$attrib opposite]] != "" &&
  1415.         [$opp get_obj_type] == "db_qual_assoc_attrib"} {
  1416.         # Can't supply the key for a qualified assoc
  1417.         return
  1418.     }
  1419.     set type [[$attrib ooplType] getName]
  1420.     set name [cap [$attrib getName]]
  1421.     set cl_name [$class getName]
  1422.     set class_data [uncap $cl_name]Data
  1423.     set sect [get_assoc_hdr_sect $attrib w]
  1424.     set access [get_access_mode [get_assoc_access $attrib] w]
  1425.     $sect append "${access}FUNCTION add${name}(new$name $type)\
  1426.             RETURNING INTEGER\n"
  1427.     set my_tab [$class table]
  1428.     set my_tab_nm [$my_tab getUniqueName]
  1429.     set link [$attrib link]
  1430.     set opp_link [$attrib oppositeLink]
  1431.     set dt_tab [$link detail]
  1432.     set dt_tab_nm [$dt_tab getUniqueName]
  1433.     set sect [get_assoc_src_sect $attrib w]
  1434.     set param_nr 1
  1435.     if {$link == $opp_link} {
  1436.         expand_text $sect {
  1437.         FUNCTION ~$cl_name::add~${name}(new~$name ~$type)\
  1438.                 RETURNING INTEGER
  1439.             VARIABLE stmt ixSQLStmt(getConnection())
  1440.             VARIABLE ~${dt_tab_nm}_data ixRow =\
  1441.                 new~$name.~[uncap $type]Data
  1442.  
  1443.             CALL stmt.prepare("UPDATE ~$dt_tab_nm " ||
  1444.                 "SET ~[gen_dyn_compare_cl $sect $link] " ||
  1445.                 "WHERE ~[gen_dyn_compare $sect $dt_tab KEYS \
  1446.                     "" "" " AND \" ||\n\""]")
  1447.             ~[gen_setparam_cl $sect $link param_nr $class_data]
  1448.             ~[gen_setparamc $sect $dt_tab param_nr KEYS ${dt_tab_nm}_data]
  1449.             CALL stmt.execute()
  1450.  
  1451.             IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  1452.                 RETURN -1
  1453.             END IF
  1454.             RETURN 0
  1455.         END FUNCTION
  1456.  
  1457.         }
  1458.     } else {
  1459.         set op_tab [$opp_link master]
  1460.         set op_tab_nm [$op_tab getUniqueName]
  1461.         expand_text $sect {
  1462.         FUNCTION ~$cl_name::add~${name}(new~$name ~$type)\
  1463.                 RETURNING INTEGER
  1464.             VARIABLE stmt ixSQLStmt(getConnection())
  1465.             VARIABLE ~${op_tab_nm}_data ixRow =\
  1466.                 new~$name.~[uncap $type]Data
  1467.  
  1468.             CALL stmt.prepare("EXECUTE PROCEDURE \
  1469.                     pins_~${dt_tab_nm}(" ||
  1470.                 "~[gen_dyn_compare_cl $sect $link p_ "" \
  1471.                     ", \" ||\n\""], " ||
  1472.                 "~[gen_dyn_compare_cl $sect $opp_link p_ "" \
  1473.                     ", \" ||\n\""])")
  1474.             ~[gen_setparam_cl $sect $link param_nr $class_data]
  1475.             ~[gen_setparam_cl $sect $opp_link param_nr \
  1476.                 ${op_tab_nm}_data]
  1477.             CALL stmt.execute()
  1478.  
  1479.             IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  1480.                 RETURN -1
  1481.             END IF
  1482.             RETURN 0
  1483.         END FUNCTION
  1484.  
  1485.         }
  1486.     }
  1487. }
  1488.  
  1489. proc db_assoc_attrib::many_remove {attrib class} {
  1490.     if {[set opp [$attrib opposite]] != "" &&
  1491.         [$opp get_obj_type] == "db_qual_assoc_attrib"} {
  1492.         return
  1493.     }
  1494.     set type [[$attrib ooplType] getName]
  1495.     set name [cap [$attrib getName]]
  1496.     set sect [get_assoc_hdr_sect $attrib w]
  1497.     set access [get_access_mode [get_assoc_access $attrib] w]
  1498.     $sect append "${access}FUNCTION remove${name}(old${name} $type)\
  1499.             RETURNING INTEGER\n"
  1500.     set cl_name [$class getName]
  1501.     set class_data [uncap $cl_name]Data
  1502.     set my_tab_nm [[$class table] getUniqueName]
  1503.     set link [$attrib link]
  1504.     set opp_link [$attrib oppositeLink]
  1505.     set dt_tab [$link detail]
  1506.     set dt_tab_nm [$dt_tab getUniqueName]
  1507.     set sect [get_assoc_src_sect $attrib w]
  1508.     set param_nr 1
  1509.     if {$link == $opp_link} {
  1510.         expand_text $sect {
  1511.         FUNCTION ~$cl_name::remove~${name}(old~${name} ~$type)\
  1512.                 RETURNING INTEGER
  1513.             VARIABLE stmt ixSQLStmt(getConnection())
  1514.             VARIABLE ~${dt_tab_nm}_data ixRow =\
  1515.                 old~${name}.~[uncap $type]Data
  1516.  
  1517.             CALL stmt.prepare("UPDATE ~$dt_tab_nm " ||
  1518.                 "SET ~[gen_col_listl $sect $link ""\
  1519.                     " = NULL"] " ||
  1520.                 "WHERE ~[gen_dyn_compare $sect $dt_tab KEYS \
  1521.                     "" "" " AND \" ||\n\""]")
  1522.             ~[gen_setparamc $sect $dt_tab param_nr KEYS \
  1523.                 ${dt_tab_nm}_data]
  1524.             CALL stmt.execute()
  1525.  
  1526.             IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  1527.                 RETURN -1
  1528.             END IF
  1529.             RETURN 0
  1530.         END FUNCTION
  1531.  
  1532.         }
  1533.     } else {
  1534.         set op_tab_nm [[$opp_link master] getUniqueName]
  1535.         expand_text $sect {
  1536.         FUNCTION ~$cl_name::remove~${name}(old~${name} ~$type)\
  1537.                 RETURNING INTEGER
  1538.             VARIABLE stmt ixSQLStmt(getConnection())
  1539.             VARIABLE ~${op_tab_nm}_data ixRow =\
  1540.                 old~${name}.~[uncap $type]Data
  1541.  
  1542.             CALL stmt.prepare("EXECUTE PROCEDURE \
  1543.                     pdel_~${dt_tab_nm}(" ||
  1544.                 "~[gen_dyn_compare_cl $sect $link p_ "" \
  1545.                     ", \" ||\n\""], " ||
  1546.                 "~[gen_dyn_compare_cl $sect $opp_link p_ "" \
  1547.                     ", \" ||\n\""])")
  1548.             ~[gen_setparam_cl $sect $link param_nr $class_data]
  1549.             ~[gen_setparam_cl $sect $opp_link param_nr \
  1550.                 ${op_tab_nm}_data]
  1551.             CALL stmt.execute()
  1552.  
  1553.             IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  1554.                 RETURN -1
  1555.             END IF
  1556.             RETURN 0
  1557.         END FUNCTION
  1558.  
  1559.         }
  1560.     }
  1561. }
  1562.  
  1563. # "template" for get function of the one side of a one-many assoc
  1564. #
  1565. global db_assoc_attrib_one_many_get
  1566. set db_assoc_attrib_one_many_get {
  1567.     FUNCTION ~$class_nm::get~${name_of_set}(~${name_of_set} ~$type_of_set)\
  1568.             RETURNING INTEGER
  1569.         VARIABLE stmt ixSQLStmt(getConnection())
  1570.         VARIABLE ~${dt_tab_nm}_datai ixRow
  1571.         VARIABLE ~${type}Ref ~$type
  1572.         VARIABLE addOk INTEGER
  1573.  
  1574.         CALL stmt.prepare("SELECT ~[
  1575.                 gen_col_list $sect $dt_table KEYS] " ||
  1576.             "FROM ~$dt_tab_nm " ||
  1577.               "WHERE ~[gen_dyn_compare_cl $sect $link \
  1578.                 "" "" " AND \" ||\n\""]")
  1579.         ~[gen_setparam_cl $sect $link param_nr $class_data]
  1580.         CALL stmt.execute()
  1581.  
  1582.         LET ~${dt_tab_nm}_datai = stmt.fetch()
  1583.         WHILE stmt.getODBCErrorCode() == stmt.SQL_Success
  1584.             LET ~${type}Ref = ~$type::findInDBByType(~[
  1585.                     gen_rowgetvalinc $sect $dt_table KEYS \
  1586.                     ${dt_tab_nm}_datai "" ",\n"])
  1587.                 CAST ~$type
  1588.             IF ~${type}Ref IS NOT NULL THEN
  1589.                 LET addOk = ~$name_of_set.~${add_func}(~${type}Ref)
  1590.             END IF
  1591.             LET ~${dt_tab_nm}_datai = stmt.fetch()
  1592.         END WHILE
  1593.         CALL stmt.free(stmt.SQL_Close)
  1594.  
  1595.         IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  1596.             RETURN -1
  1597.         END IF
  1598.         RETURN 0
  1599.     END FUNCTION
  1600.  
  1601. }
  1602.  
  1603. # "template" for get function of a many-many assoc
  1604. #
  1605. global db_assoc_attrib_many_many_get
  1606. set db_assoc_attrib_many_many_get {
  1607.     FUNCTION ~$class_nm::get~${name_of_set}(~${name_of_set} ~$type_of_set)\
  1608.             RETURNING INTEGER
  1609.         VARIABLE stmt ixSQLStmt(getConnection())
  1610.         VARIABLE ~${dt_tab_nm}_datai ixRow
  1611.         VARIABLE ~${type}Ref ~$type
  1612.         VARIABLE addOk INTEGER
  1613.  
  1614.         CALL stmt.prepare("SELECT ~[
  1615.                 gen_col_listl $sect $opp_link] " ||
  1616.             "FROM ~$dt_tab_nm " ||
  1617.             "WHERE ~[gen_dyn_compare_cl $sect $link \
  1618.                 "" "" " AND \" ||\n\""]")
  1619.         ~[gen_setparam_cl $sect $link param_nr $class_data]
  1620.         CALL stmt.execute()
  1621.  
  1622.         LET ~${dt_tab_nm}_datai = stmt.fetch()
  1623.         WHILE stmt.getODBCErrorCode() == stmt.SQL_Success
  1624.             LET ~${type}Ref = ~$type::findInDBByType(~[
  1625.                     gen_rowgetvalinc_l $sect $opp_link \
  1626.                     ${dt_tab_nm}_datai "" ",\n"])
  1627.                 CAST ~$type
  1628.             IF ~${type}Ref IS NOT NULL THEN
  1629.                 LET addOk = ~$name_of_set.~${add_func}(~${type}Ref)
  1630.             END IF
  1631.             LET ~${dt_tab_nm}_datai = stmt.fetch()
  1632.         END WHILE
  1633.         CALL stmt.free(stmt.SQL_Close)
  1634.  
  1635.         IF stmt.getODBCErrorCode() != stmt.SQL_Success THEN
  1636.             RETURN -1
  1637.         END IF
  1638.         RETURN 0
  1639.     END FUNCTION
  1640. }
  1641.  
  1642. proc db_assoc_attrib::many_get {attrib class} {
  1643.     set setpfx [set_prefix $attrib]
  1644.     set type [[$attrib ooplType] getName]
  1645.     set type_of_set [${setpfx}set_type_name [$attrib ooplType]]
  1646.     set name [$attrib getName]
  1647.     set name_of_set [cap [${setpfx}set_name $name]]
  1648.     set add_func [set ${setpfx}set::add]
  1649.     set class_nm [$class getName]
  1650.     set class_data [uncap $class_nm]Data
  1651.     set sect $ne_sections(h_pub_func_sect)
  1652.     $sect append "PUBLIC FUNCTION get${name_of_set}(${name_of_set} $type_of_set) RETURNING INTEGER\n"
  1653.     set tab_nm [[$class table] getUniqueName]
  1654.     set link [$attrib link]
  1655.     set opp_link [$attrib oppositeLink]
  1656.     set dt_table [$link detail]
  1657.     set dt_tab_nm [$dt_table getUniqueName]
  1658.     set sect $ne_sections(c_impl_no_regen_sect)
  1659.     set param_nr 1
  1660.     if {$link == $opp_link} {
  1661.         expand_text $sect $db_assoc_attrib_one_many_get
  1662.     } else {
  1663.         expand_text $sect $db_assoc_attrib_many_many_get
  1664.     }
  1665. }
  1666.  
  1667. proc db_assoc_attrib::gen_initializer {attrib init decl_s body_s class} {
  1668.     set name [$init getName]
  1669.     set type_nm [[$attrib ooplType] getName]
  1670.     set class_data [uncap [$class getName]]Data
  1671.     gen_assign_cl $body_s [$attrib link] $class_data ""\
  1672.         $name.[uncap $type_nm]Data ""
  1673. }
  1674.  
  1675. proc db_link_class::gen_class_decl {class} {
  1676.     db_class::gen_class_decl $class
  1677. }
  1678.  
  1679.