namespace eval gen_tcl {

# Autogenerated with DRAKON Editor 1.27

proc add { field id element indent } {
    #item 1214
    set array [ field_array_name $field ]
    #item 1213
    a "variable $array" $indent
    a "if \{ \[ info exists $array\(\$$id\) \] \} \{" $indent
    a "    set _col_ \$$array\(\$$id\)" $indent
    a "\} else \{" $indent
    a "    set _col_ \{\}" $indent
    a "\}" $indent
    a "lappend _col_ \$$element" $indent
    a "set $array\(\$$id\) \$_col_" $indent
}

proc add_name { field } {
    #item 1183
    set class [ tab::get_field_class $field ]
    set class_name [ tab::get_class_name $class ]
    set field_name [ tab::get_field_name $field ]
    #item 1184
    return "${class_name}_${field_name}_add"
}

proc add_to_index { item indent class } {
    #item 862
    set index [ dict get $item "index" ]
    set fields [ dict get $item "fields" ]
    #item 865
    set index_name [ index_array_name $index ]
    #item 866
    a "variable $index_name" $indent
    #item 867
    gen_key $fields "    "
    #item 864
    a "set $index_name\(\$_key_\) \$id" $indent
}

proc assemble { item indent class } {
    #item 409
    set indexed [ dict get $item "indexed" ]
    #item 411
    set classes [ dict keys $indexed ]
    set base [ lindex $classes 0 ]
    set class_name [ tab::get_class_name $class ]
    #item 428
    set type_id [ type_id_name $base ]
    a "variable $type_id" $indent
    a "set $type_id\(\$id\) \"$class_name\"" $indent
    foreach class $classes {
        #item 427
        set id_array [ id_array_name $class ]
        a "variable $id_array" $indent
        a "set $id_array\(\$id\) 0" $indent
        #item 412
        set fields [ dict get $indexed $class ]
        foreach field $fields {
            #item 425
            set field_name [ tab::get_field_name $field ]
            set array [ field_array_name $field ]
            #item 424
            a "variable $array" $indent
            a "set $array\(\$id\) \$$field_name" $indent
        }
    }
}

proc can_delete { item indent class } {
    #item 540
    a "set proc_name \"\$\{type\}_can_delete\"" $indent
    a "\$proc_name \$pk" $indent
}

proc check_change { item indent class } {
    #item 923
    set field [ dict get $item "field" ]
    set getter [ getter_name $field ]
    set field_name [ tab::get_field_name $field ]
    #item 928
    a "set old \[ $getter \$id \]" $indent
    a "if \{ \$old == \$$field_name \} \{" $indent
    a "    return" $indent
    a "\}" $indent
}

proc check_deleted { item indent class } {
    #item 761
    a "variable g_del_list" $indent
    a "set key \"\$id,\$type\"" $indent
    a "if \{ \[ info exists g_del_list\(\$key\) \] \} \{" $indent
    a "    return" $indent
    a "\} else \{" $indent
    a "    set g_del_list\(\$key\) 1" $indent
    a "\}" $indent
}

proc check_id { item indent class } {
    #item 313
    set class [ dict get $item "class" ]
    set name [ tab::get_class_name $class ]
    set next [ next_id_name $class ]
    set method [ get_type_id_name $class ]
    #item 314
    a "if \{ \$id == \{\} \} \{" $indent
    a "    set id \$$next" $indent
    a "\} else \{" $indent
    a "    if \{ \[ ${name}_exists \$id \] \} \{" $indent
    a "        set class_name \[ $method \$id \]" $indent
    a "        error \"'\$class_name' with id \$id already exists.\"" $indent
    a "    \}" $indent
    a "\}" $indent
    a "if \{ \$id >= \$$next \} \{" $indent
    a "    set $next \[ expr \{ \$id + 1 \} \]" $indent
    a "\}" $indent
}

proc check_not_deleted { class var indent } {
    #item 1283
    set method [ get_type_id_name $class ]
    #item 1282
    a "variable g_del_list" $indent
    a "set _type_ \[ $method \$$var \]" $indent
    a "set _key_ \"\$$var,\$_type_\"" $indent
    a "if \{ !\[ info exists g_del_list\(\$_key_\) \] \} \{" $indent
}

proc check_ref_count { item indent class } {
    #item 1027
    set class [ dict get $item "class" ]
    set master [ dict get $item "master" ]
    #item 1028
    set array [ id_array_name $class ]
    #item 1029
    a "variable $array" $indent
    a "set _ref_count_ \$$array\(\$id\)" $indent
    #item 1030
    if {$master} {
        #item 1045
        a "if \{ \$master && \$_ref_count_ > 1 || " $indent
        a "  !\$master && \$_ref_count_ > 0 \} \{" $indent
    } else {
        #item 1033
        a "if \{ \$_ref_count_ > 0 \} \{" $indent
    }
    #item 1041
    ref_count_error $class "    $indent"
    #item 1042
    a "\}" $indent
}

proc check_self { item indent class } {
    #item 917
    ensure_exists $class "id" 0 $indent
}

proc check_target_not_deleted { field target indent } {
    #item 1058
    set getter [ getter_name $field ]
    set field_name [ tab::get_field_name $field ]
    #item 1059
    a "set $field_name \[ $getter \$id \]" $indent
    #item 1284
    check_not_deleted $target $field_name $indent
}

proc connect { item indent class } {
    #item 1007
    set field [ dict get $item "field" ]
    set op [ dict get $item "op" ]
    set link [ dict get $item "link" ]
    #item 1018
    set field_name [ tab::get_field_name $field ]
    #item 1019
    a "if \{ \$$field_name != \{\} \} \{" $indent
    #item 10080001
    if {$op == "ref_count"} {
        #item 1020
        set dst [ tab::get_link_dst_table $link ]
        set array [ id_array_name $dst ]
        #item 1021
        a "    variable $array" $indent
        a "    set _ref_count \$$array\(\$$field_name\)" $indent
        a "    incr _ref_count" $indent
        a "    set $array\($$field_name\) \$_ref_count" $indent
    } else {
        #item 10080002
        if {$op == "collection"} {
            
        } else {
            #item 10080003
            error "Unexpected switch value: $op"
        }
        #item 1147
        do_connect_col $link $field_name "    $indent"
    }
    #item 1006
    a "\}" $indent
}

proc declare_array { name } {
    #item 345
    a "variable $name"
    a "array set $name \{\}"
}

proc disconnect { item indent class } {
    #item 984
    set field [ dict get $item "field" ]
    set op [ dict get $item "op" ]
    set link [ dict get $item "link" ]
    set target [ dict get $item "target" ]
    set method [ get_type_id_name $target ]
    #item 997
    set field_name [ tab::get_field_name $field ]
    set target_name [ tab::get_class_name $target ]
    set getter [ getter_name $field ]
    set indent2 "    $indent"
    set indent3 "    $indent2"
    #item 998
    a "set $field_name \[ $getter $\id \]" $indent
    a "if \{ \$$field_name != \{\} \} \{" $indent
    #item 1089
    a "variable g_del_list" $indent2
    a "set _type_ \[ $method \$$field_name \]" $indent2
    a "set _key_ \"\$$field_name,\$_type_\"" $indent2
    a "if \{ !\[ info exists g_del_list\(\$_key_\) \] \} \{" $indent2
    #item 9850001
    if {$op == "ref_count"} {
        #item 999
        set dst [ tab::get_link_dst_table $link ]
        set array [ id_array_name $dst ]
        #item 1090
        do_disconnect $array $field_name $indent3
    } else {
        #item 9850002
        if {$op == "collection"} {
            
        } else {
            #item 9850003
            error "Unexpected switch value: $op"
        }
        #item 1141
        do_disconnect_col $link $field_name $indent3
    }
    #item 983
    a "\}" $indent2
    a "\}" $indent
}

proc disconnect_m2m { item indent class } {
    #item 1261
    set field [ dict get $item "field" ]
    set target_field [ dict get $item "target_field" ]
    set target_class [ tab::get_field_class $target_field ]
    #item 1276
    check_not_deleted $target_class "that" $indent
    #item 1275
    remove $target_field "that" "id" "    $indent"
    #item 1285
    a "\}" $indent
}

proc disconnect_old { item indent class } {
    #item 1097
    set field [ dict get $item "field" ]
    set op [ dict get $item "op" ]
    set link [ dict get $item "link" ]
    set target [ dict get $item "target" ]
    #item 1104
    set field_name [ tab::get_field_name $field ]
    set indent2 "    $indent"
    #item 1105
    
    a "if \{ \$old != \{\} \} \{" $indent
    #item 10980001
    if {$op == "ref_count"} {
        #item 1106
        set dst [ tab::get_link_dst_table $link ]
        set array [ id_array_name $dst ]
        #item 1108
        do_disconnect $array "old" $indent2
    } else {
        #item 10980002
        if {$op == "collection"} {
            
        } else {
            #item 10980003
            error "Unexpected switch value: $op"
        }
        #item 1146
        do_disconnect_col $link "old" $indent2
    }
    #item 1096
    a "\}" $indent
}

proc do_connect_col { link that indent } {
    #item 1145
    set src_class [ tab::get_link_src_table $link ]
    set many_field_name [ tab::get_link_src_field $link ]
    set many_field [ tab::find_field $src_class $many_field_name ]
    #item 1139
    set array [ field_array_name $many_field ]
    #item 1216
    add $many_field $that "id" $indent
}

proc do_delete { item indent class } {
    #item 546
    a "set proc_name \"\$\{type\}_do_delete\"" $indent
    a "\$proc_name \$pk" $indent
}

proc do_disconnect { array var indent } {
    #item 1088
    a "variable $array" $indent
    a "set _ref_count \$$array\(\$$var\)" $indent
    a "incr _ref_count -1" $indent
    a "set $array\($$var\) \$_ref_count" $indent
}

proc do_disconnect_col { link that indent } {
    #item 1144
    set src_class [ tab::get_link_src_table $link ]
    set many_field_name [ tab::get_link_src_field $link ]
    set many_field [ tab::find_field $src_class $many_field_name ]
    #item 1254
    remove $many_field $that "id" $indent
}

proc ensure_deleted { item indent this_class } {
    #item 1161
    set field [ dict get $item "field" ]
    set class [ dict get $item "class" ]
    set this_name [ tab::get_class_name $this_class ]
    #item 1163
    set get_type_id [ get_type_id_name $class ]
    #item 1164
    a "variable g_del_list" $indent
    a "set _type_ \[ $get_type_id \$that \]" $indent
    a "set _key_ \"\$that,\$_type_\"" $indent
    a "if \{ !\[ info exists g_del_list\(\$_key_\) \] \} \{" $indent
    a "    error \"'$this_name' with id '\$id' is referenced by other record.\"" $indent
    a "\}" $indent
}

proc ensure_exists { class var null indent } {
    #item 492
    set class_name [ tab::get_class_name $class ]
    #item 1111
    if {$null} {
        #item 1109
        a "if \{ \$$var != \{\} && !\[ ${class_name}_exists \$$var \] \} \{" $indent
    } else {
        #item 1110
        a "if \{ !\[ ${class_name}_exists \$$var \] \} \{" $indent
    }
    #item 491
    a "    error \"'$class_name' with id '\$$var' does not exist.\"" $indent
    a "\}" $indent
}

proc fetch_field { item indent class } {
    #item 934
    set field [ dict get $item "field" ]
    set getter [ getter_name $field ]
    set field_name [ tab::get_field_name $field ]
    #item 935
    a "set $field_name \[ $getter \$id \]" $indent
}

proc field_array_name { field } {
    #item 471
    set class [ tab::get_field_class $field ]
    #item 323
    set class_name [ tab::get_class_name $class ]
    #item 324
    set field_name [ tab::get_field_name $field ]
    #item 322
    return "f_${class_name}_${field_name}"
}

proc foreign_check { item indent class } {
    #item 977
    set field [ dict get $item "field" ]
    set target [ dict get $item "class" ]
    set field_name [ tab::get_field_name $field ]
    #item 976
    ensure_exists $target $field_name 1 $indent
}

proc gen_add { field } {
    #item 1174
    set name [ add_name $field ]
    set array [ field_array_name $field ]
    set field_name [ tab::get_field_name $field ]
    set class [ tab::get_field_class $field ]
    set indent "    "
    #item 1175
    proc_head $name [ list "id" "element" ]
    #item 1192
    ensure_exists $class "id" 0 $indent
    #item 1193
    a "if \{ \$element == \{\} \} \{ return \}" $indent
    #item 1207
    lassign \
    [tab::get_other_side $field] \
    other_class other_field
    #item 1194
    ensure_exists $other_class "element" 0 $indent
    #item 1230
    add $other_field "element" "id" $indent
    #item 1231
    add $field "id" "element" $indent
    #item 1176
    a "\}"
}

proc gen_can_delete { class } {
    #item 813
    set method [ tab::core_can_delete $class ]
    #item 814
    set body [ dict get $method "body" ]
    set name [ tab::get_class_name $class ]
    #item 816
    set method_name "${name}_can_delete"
    #item 815
    proc_head $method_name {id}
    #item 818
    render_list $body "    " $class
    #item 817
    a "\}"
}

proc gen_complex_setter { method } {
    #item 904
    set field [ dict get $method "field" ]
    set class [ dict get $method "class" ]
    set body [ get_optional $method "body" ]
    #item 907
    set name [ setter_name $field ]
    set field_name [ tab::get_field_name $field ]
    #item 906
    proc_head $name [ list "id" $field_name ]
    #item 909
    render_list $body "    " $class
    #item 908
    a "\}"
}

proc gen_count { class } {
    #item 679
    set name [ tab::get_class_name $class ]
    #item 678
    proc_head "${name}_count" {}
    #item 677
    set id_array [ id_array_name $class ]
    #item 681
    a "    variable $id_array"
    a "    set names \[ array names $id_array \]"
    a "    return \[ llength \$names \]"
    #item 680
    a "\}"
}

proc gen_delete { class } {
    #item 653
    set method [ tab::core_delete $class ]
    #item 654
    set body [ dict get $method "body" ]
    #item 656
    set name [ tab::get_class_name $class ]
    #item 655
    proc_head "${name}_delete" {id}
    #item 660
    reset_array "g_del_list"
    #item 659
    render_list $body "    " $class
    #item 661
    set base [ get_base $class ]
    set type_id [ type_id_name $base ]
    a "    variable $type_id"
    a "    unset $type_id\(\$id\)"
    #item 657
    a "\}"
}

proc gen_do_delete { class } {
    #item 824
    set method [ tab::core_do_delete $class ]
    #item 825
    set body [ dict get $method "body" ]
    set name [ tab::get_class_name $class ]
    #item 827
    set method_name "${name}_do_delete"
    #item 826
    proc_head $method_name {id}
    #item 829
    render_list $body "    " $class
    #item 1286
    set chain [ tab::inheritance_chain $class ]
    set chain [ lreverse $chain ]
    foreach cls $chain {
        #item 830
        set fields [ tab::get_class_fields $cls ]
        foreach field $fields {
            #item 833
            set array [ field_array_name $field ]
            #item 834
            a "    variable $array"
            a "    if \{ \[ info exists $array\(\$id\) \] \} \{"
            a "        unset $array\(\$id\)"
            a "    \}"
        }
        #item 835
        set id_array [ id_array_name $cls ]
        a "    variable $id_array"
        a "    unset $id_array\(\$id\)"
    }
    #item 828
    a "\}"
}

proc gen_exists { class } {
    #item 669
    set name [ tab::get_class_name $class ]
    #item 668
    proc_head "${name}_exists" {id}
    #item 667
    set id_array [ id_array_name $class ]
    #item 671
    a "    variable $id_array"
    a "    return \[ info exists $id_array\(\$id\) \]"
    #item 670
    a "\}"
}

proc gen_field_arrays { classes } {
    #item 569
    declare_array "g_del_list"
    foreach class $classes {
        #item 566
        set id_array [ id_array_name $class ]
        declare_array $id_array
        set type_id_array [ type_id_name $class ]
        declare_array $type_id_array
        #item 568
        set next [ next_id_name $class ]
        a "variable $next 1"
        #item 565
        set fields [ tab::get_class_fields $class ]
        foreach field $fields {
            #item 567
            set f_array [ field_array_name $field ]
            declare_array $f_array
        }
    }
}

proc gen_get_type_id { class } {
    #item 729
    set base [ get_base $class ]
    set base_name [ tab::get_class_name $base ]
    set array "f_${base_name}_type_id"
    set class_name [ tab::get_class_name $class ]
    set proc_name "get_${class_name}_type_id"
    #item 730
    proc_head $proc_name { id }
    #item 732
    a "    variable $array"
    a "    if \{ \[ info exists $array\(\$id\) \] \} \{"
    a "        return \$$array\(\$id\)"
    a "    \} else \{"
    a "        return \{\}"
    a "    \}"
    #item 731
    a "\}"
}

proc gen_getter { field } {
    #item 711
    set name [ getter_name $field ]
    set array [ field_array_name $field ]
    #item 712
    proc_head $name { id }
    #item 714
    a "    variable $array"
    a "    if \{ \[ info exists $array\(\$id\) \] \} \{"
    a "        return \$$array\(\$id\)"
    a "    \} else \{"
    a "        return \{\}"
    a "    \}"
    #item 713
    a "\}"
}

proc gen_index_arrays { classes } {
    foreach class $classes {
        #item 577
        set indexes [ tab::get_class_indexes $class ]
        foreach index $indexes {
            #item 580
            set i_array [ index_array_name $index ]
            declare_array $i_array
        }
    }
}

proc gen_index_find { classes } {
    foreach class $classes {
        #item 875
        set indexes [ tab::get_class_indexes $class ]
        set class_name [ tab::get_class_name $class ]
        foreach index $indexes {
            #item 878
            set i_array [ index_array_name $index ]
            set fields [ tab::get_index_fields $index ]
            set fields_u [ join $fields "_" ]
            #item 879
            proc_head "find_${class_name}_by_${fields_u}" $fields
            #item 881
            a "    variable $i_array"
            #item 882
            set field_ids [ tab::index_fields $index ]
            gen_key $field_ids "    "
            #item 883
            a "    if \{ \[ info exists $i_array\(\$_key_\) \] \} \{"
            a "        return \$$i_array\(\$_key_\)"
            a "    \} else \{"
            a "        return \{\}"
            a "    \}"
            #item 880
            a "\}"
        }
    }
}

proc gen_insert { class } {
    #item 697
    set method [ tab::core_insert $class "" ]
    #item 698
    set args [ get_optional $method "args" ]
    set body [ get_optional $method "body" ]
    #item 699
    set init_fields [ map2 $args tab::get_field_name ]
    set arguments [ linsert $init_fields 0 "id" ]
    #item 701
    set name [ tab::get_class_name $class ]
    #item 704
    set chain [ tab::inheritance_chain $class ]
    set base [ lindex $chain 0 ]
    set next [ next_id_name $base ]
    #item 700
    proc_head "${name}_insert" $arguments
    #item 705
    a "    variable $next"
    #item 703
    render_list $body "    " $class
    #item 702
    a "    return \$id"
    a "\}"
}

proc gen_key { fields indent } {
    #item 854
    set fnames [ map2 $fields tab::get_field_name ]
    gen_key_core $fnames $indent
}

proc gen_key_core { fnames indent } {
    #item 959
    set key_value [ join $fnames ",|,\$" ]
    #item 960
    a "set _key_ \"\$$key_value\"" $indent
}

proc gen_keys { class } {
    #item 689
    set name [ tab::get_class_name $class ]
    #item 688
    proc_head "${name}_keys" {}
    #item 687
    set id_array [ id_array_name $class ]
    #item 691
    a "    variable $id_array"
    a "    set names \[ array names $id_array \]"
    a "    return \$names"
    #item 690
    a "\}"
}

proc gen_methods { classes } {
    foreach class $classes {
        #item 623
        gen_pre_delete $class
        gen_pre_delete_middle $class
        gen_pre_delete_inner $class
        gen_can_delete $class
        gen_do_delete $class
    }
}

proc gen_pre_delete { class } {
    #item 738
    set method [ tab::core_pre_delete_outer $class ]
    #item 739
    set body [ dict get $method "body" ]
    set master [ dict get $method "master" ]
    #item 741
    set name [ pre_delete_name $class ]
    #item 742
    if {$master} {
        #item 745
        proc_head $name {id master}
    } else {
        #item 740
        proc_head $name {id}
    }
    #item 747
    render_list $body "    " $class
    #item 746
    a "\}"
}

proc gen_pre_delete_inner { class } {
    #item 796
    set method [ tab::core_pre_delete_inner $class ]
    #item 797
    set body [ dict get $method "body" ]
    set name [ tab::get_class_name $class ]
    #item 799
    set method_name "${name}_pre_delete_inner"
    #item 798
    proc_head $method_name {id}
    #item 801
    render_list $body "    " $class
    #item 800
    a "\}"
}

proc gen_pre_delete_middle { class } {
    #item 774
    set method [ tab::core_pre_delete_middle $class ]
    #item 775
    set body [ dict get $method "body" ]
    set name [ tab::get_class_name $class ]
    #item 777
    set method_name "${name}_pre_delete_middle"
    #item 776
    proc_head $method_name {id}
    #item 783
    render_list $body "    " $class
    #item 782
    a "\}"
}

proc gen_public_methods { classes } {
    foreach class $classes {
        #item 1301
        gen_keys $class
        #item 1299
        gen_count $class
        #item 1300
        gen_exists $class
        #item 1302
        gen_insert $class
        gen_get_type_id $class
        gen_delete $class
        gen_index_find $class
        #item 1303
        set fields [ tab::get_class_fields $class ]
        foreach field $fields {
            #item 1307
            gen_getter $field
            #item 1306
            set setter [ tab::core_update $field ]
            #item 1313
            if {$setter == {}} {
                #item 1319
                if {[tab::is_m2m_field $field]} {
                    #item 1322
                    gen_add $field
                    gen_remove $field
                } else {
                    
                }
            } else {
                #item 1316
                set type [ dict get $setter "type" ]
                #item 13080001
                if {$type == "simple"} {
                    #item 1317
                    gen_simple_setter $field
                } else {
                    #item 13080002
                    if {$type == "complex"} {
                        
                    } else {
                        #item 13080003
                        error "Unexpected switch value: $type"
                    }
                    #item 1318
                    gen_complex_setter $setter
                }
            }
        }
    }
}

proc gen_remove { field } {
    #item 1237
    set name [ remove_name $field ]
    set array [ field_array_name $field ]
    set field_name [ tab::get_field_name $field ]
    set class [ tab::get_field_class $field ]
    set indent "    "
    #item 1238
    proc_head $name [ list "id" "element" ]
    #item 1240
    ensure_exists $class "id" 0 $indent
    #item 1241
    a "if \{ \$element == \{\} \} \{ return \}" $indent
    #item 1243
    lassign \
    [tab::get_other_side $field] \
    other_class other_field
    #item 1242
    ensure_exists $other_class "element" 0 $indent
    #item 1244
    remove $other_field "element" "id" $indent
    #item 1245
    remove $field "id" "element" $indent
    #item 1239
    a "\}"
}

proc gen_reset { classes } {
    #item 611
    proc_head "reset_db" {}
    foreach class $classes {
        #item 600
        set id_array [ id_array_name $class ]
        reset_array $id_array
        set type_id_array [ type_id_name $class ]
        reset_array $type_id_array
        #item 599
        set fields [ tab::get_class_fields $class ]
        foreach field $fields {
            #item 601
            set f_array [ field_array_name $field ]
            reset_array $f_array
        }
    }
    foreach class $classes {
        #item 607
        set indexes [ tab::get_class_indexes $class ]
        foreach index $indexes {
            #item 610
            set i_array [ index_array_name $index ]
            reset_array $i_array
        }
    }
    foreach class $classes {
        #item 602
        set next [ next_id_name $class ]
        a "    variable $next"
        a "    set $next 1"
    }
    #item 612
    a "\}"
}

proc gen_simple_setter { field } {
    #item 720
    set name [ setter_name $field ]
    set array [ field_array_name $field ]
    set field_name [ tab::get_field_name $field ]
    #item 721
    proc_head $name [ list "id" $field_name ]
    #item 723
    a "    variable $array"
    a "    set $array\(\$id\) \$$field_name"
    #item 722
    a "\}"
}

proc generate_data_struct { } {
    #item 19
    set classes [ tab::class_name_keys ]
    #item 1325
    if {$classes == {}} {
        
    } else {
        #item 1290
        a "######### Public #########"
        #item 24
        gen_reset $classes
        #item 1289
        gen_public_methods $classes
        #item 1291
        a "######### Private #########"
        #item 22
        gen_field_arrays $classes
        #item 25
        gen_index_arrays $classes
        #item 26
        gen_methods $classes
    }
}

proc get_base { class } {
    #item 554
    set chain [ tab::inheritance_chain $class ]
    set base [ lindex $chain 0 ]
    #item 555
    return $base
}

proc get_class_id { item indent class } {
    #item 753
    set class [ dict get $item "class" ]
    #item 754
    set method [ get_type_id_name $class ]
    #item 755
    a "set type \[ $method \$id \]" $indent
}

proc get_type_id_name { class } {
    #item 1120
    set name [ tab::get_class_name $class ]
    #item 1119
    set method "get_${name}_type_id"
    #item 1121
    return $method
}

proc getter_name { field } {
    #item 457
    set class [ tab::get_field_class $field ]
    set class_name [ tab::get_class_name $class ]
    set field_name [ tab::get_field_name $field ]
    #item 458
    return "get_${class_name}_${field_name}"
}

proc id_array_name { class } {
    #item 338
    set name [ tab::get_class_name $class ]
    #item 339
    return "f_${name}_rcount"
}

proc index_array_name { index } {
    #item 848
    set class [ tab::get_index_class $index ]
    #item 330
    set class_name [ tab::get_class_name $class ]
    #item 331
    set fields [ tab::get_index_fields $index ]
    set fields_str [ join $fields "_" ]
    #item 332
    return "i_${class_name}_${fields_str}"
}

proc index_not_exists { item indent class } {
    #item 843
    set index [ dict get $item "index" ]
    set fields [ dict get $item "fields" ]
    #item 844
    set fnames [ map2 $fields tab::get_field_name ]
    #item 846
    set index_name [ index_array_name $index ]
    set class [ tab::get_index_class $index ]
    set class_name [ tab::get_class_name $class ]
    #item 847
    a "variable $index_name" $indent
    #item 856
    gen_key $fields "    "
    #item 845
    a "if \{ \[ info exists $index_name\(\$_key_\) \] \} \{" $indent
    a "    error \"Fields '$fnames' are not unique for '$class_name'.\"" $indent
    a "\}" $indent
}

proc indexed_fields { class } {
    #item 372
    set result {}
    #item 371
    set fields [ tab::get_class_fields $class ]
    foreach field $fields {
        #item 376
        set indexes [ tab::get_field_indexes $field ]
        #item 377
        if {$indexes == {}} {
            
        } else {
            #item 380
            lappend result $field
        }
    }
    #item 373
    return $result
}

proc insert_possible { item indent class } {
    #item 402
    set method [ tab::core_insert_possible $class "" ]
    set body [ get_optional $method "body" ]
    #item 404
    render_list $body $indent $class
}

proc is_m2m_field { field } {
    #item 1222
    set link [ tab::get_field2_link $field ]
    #item 1223
    if {$link == {}} {
        #item 1229
        return 0
    } else {
        #item 1226
        set type [ tab::get_link_type $link ]
        #item 1227
        if {$type == "m2m"} {
            #item 1228
            return 1
        } else {
            #item 1229
            return 0
        }
    }
}

proc next_id_name { class } {
    #item 351
    set class_name [ tab::get_class_name $class ]
    #item 352
    return "g_${class_name}_next"
}

proc pre_delete_inner { item indent class } {
    #item 790
    set cls [ dict get $item "class" ]
    set name [ tab::get_class_name $cls ]
    #item 788
    a "${name}_pre_delete_inner \$id" $indent
}

proc pre_delete_middle { item indent class } {
    #item 766
    a "\$\{type\}_pre_delete_middle \$id" $indent
}

proc pre_delete_name { class } {
    #item 509
    set name [ tab::get_class_name $class ]
    #item 510
    return "${name}_pre_delete"
}

proc pre_delete_outer { item indent class } {
    #item 501
    set cls [ dict get $item "class" ]
    set field_name [ dict get $item "field_name" ]
    set master [ dict get $item "master" ]
    #item 503
    set name [ pre_delete_name $cls ]
    #item 5110001
    if {$master == "none"} {
        #item 524
        a "$name \$$field_name" $indent
    } else {
        #item 5110002
        if {$master == "true"} {
            #item 525
            a "$name \$$field_name 1" $indent
        } else {
            #item 5110003
            if {$master == "false"} {
                
            } else {
                #item 5110004
                error "Unexpected switch value: $master"
            }
            #item 526
            a "$name \$$field_name 0" $indent
        }
    }
}

proc proc_head { name arguments } {
    #item 364
    set arg_str [ join $arguments " " ]
    #item 365
    a "proc $name \{ $arg_str \} \{"
}

proc ref_count_error { class indent } {
    #item 1039
    set class_name [ tab::get_class_name $class ]
    set method [ get_type_id_name $class ]
    #item 1040
    a "set _type_id_ \[ $method \$id \]" $indent
    a "error \"'\$_type_id_' with id '\$id' is referenced by other record.\"" $indent
}

proc remove { field id element indent } {
    #item 1252
    set array [ field_array_name $field ]
    #item 1253
    a "variable $array" $indent
    a "if \{ \[ info exists $array\(\$$id\) \] \} \{" $indent
    a "    set _col_ \$$array\(\$$id\)" $indent
    a "    set _index_ \[ lsearch \$_col_ \$$element \]" $indent
    a "    if \{ \$_index_ != -1 \} \{" $indent
    a "        set _col_2 \[ lreplace \$_col_ \$_index_ \$_index_ \]" $indent
    a "        set $array\(\$$id\) \$_col_2" $indent
    a "    \}" $indent
    a "\}" $indent
}

proc remove_from_index { item indent class } {
    #item 889
    set index [ dict get $item "index" ]
    set fields [ dict get $item "fields" ]
    foreach field $fields {
        #item 896
        set field_name [ tab::get_field_name $field ]
        set getter [ getter_name $field ]
        #item 897
        a "set $field_name \[ $getter \$id \]" $indent
    }
    #item 891
    set index_name [ index_array_name $index ]
    #item 892
    a "variable $index_name" $indent
    #item 893
    gen_key $fields "    "
    #item 890
    a "unset $index_name\(\$_key_\)" $indent
}

proc remove_from_index_old { item indent class } {
    #item 941
    set index [ dict get $item "index" ]
    set fields [ dict get $item "fields" ]
    set old [ dict get $item "old" ]
    #item 953
    set fnames {}
    foreach field $fields {
        #item 950
        if {$field == $old} {
            #item 961
            lappend fnames "old"
        } else {
            #item 948
            set field_name [ tab::get_field_name $field ]
            #item 949
            lappend fnames $field_name
        }
    }
    #item 943
    set index_name [ index_array_name $index ]
    #item 945
    gen_key_core $fnames "    "
    #item 942
    a "unset $index_name\(\$_key_\)" $indent
}

proc remove_name { field } {
    #item 1190
    set class [ tab::get_field_class $field ]
    set class_name [ tab::get_class_name $class ]
    set field_name [ tab::get_field_name $field ]
    #item 1191
    return "${class_name}_${field_name}_remove"
}

proc render_action { items indent class } {
    #item 291
    set name [ lindex $items 1 ]
    set handler "gen_tcl::$name"
    #item 293
    $handler $items $indent $class
}

proc render_foreach { items indent class } {
    #item 311
    set condition [ dict get $items "foreach" ]
    set body [ dict get $items "do" ]
    #item 527
    if {[dict exists $condition "variable"]} {
        #item 530
        set var [ dict get $condition "variable" ]
        #item 531
        if {$var == "del_list"} {
            #item 533
            a "foreach item \[ array names g_del_list \] \{" $indent
            a "    lassign \[ split \$item \",\" \] pk type" $indent
            #item 535
            render_action $body "    $indent" $class
            #item 534
            a "\}" $indent
        } else {
            
        }
    } else {
        #item 1149
        if {[dict exists $condition "field"]} {
            #item 1152
            set field [ dict get $condition "field" ]
            set field_name [ tab::get_field_name $field ]
            #item 1153
            fetch_field [ list "field" $field ] $indent $class
            #item 1156
            a "foreach that \$$field_name \{" $indent
            #item 1155
            render_action $body "    $indent" $class
            #item 1154
            a "\}" $indent
        } else {
            
        }
    }
}

proc render_if { items indent class } {
    #item 304
    set condition [ dict get $items "if" ]
    set then [ dict get $items "then" ]
    #item 1046
    if {[dict exists $condition "is_not_deleted"]} {
        #item 1050
        set field [ dict get $condition "is_not_deleted" ]
        set target [ dict get $condition "target" ]
        check_target_not_deleted $field $target $indent
    } else {
        #item 1122
        if {[dict exists $condition "field_not_null"]} {
            #item 1124
            set field [ dict get $condition "field_not_null" ]
            fetch_field [ list "field" $field ] $indent $class
            set field_name [ tab::get_field_name $field ]
            a "if \{ \$$field_name != \{\} \} \{" $indent
        } else {
            #item 1049
            error "Unexpected condition: $condition"
        }
    }
    #item 1051
    render_action $then "    $indent" $class
    #item 1052
    a "\}" $indent
}

proc render_list { items indent class } {
    foreach item $items {
        #item 275
        set type [ lindex $item 0 ]
        #item 2760001
        if {$type == "action"} {
            #item 284
            render_action $item $indent $class
        } else {
            #item 2760002
            if {$type == "if"} {
                #item 285
                render_if $item $indent $class
            } else {
                #item 2760003
                if {$type == "foreach"} {
                    
                } else {
                    #item 2760004
                    error "Unexpected switch value: $type"
                }
                #item 286
                render_foreach $item $indent $class
            }
        }
    }
}

proc replace { item indent class } {
    #item 966
    set class [ dict get $item "class" ]
    set field [ dict get $item "field" ]
    #item 970
    set field_name [ tab::get_field_name $field ]
    set array [ field_array_name $field ]
    #item 969
    a "variable $array" $indent
    a "set $array\(\$id\) \$$field_name" $indent
}

proc reset_array { name } {
    #item 358
    a "    variable $name"
    a "    array unset $name"
    a "    array set $name \{\}"
    a ""
}

proc setter_name { field } {
    #item 422
    set class [ tab::get_field_class $field ]
    set class_name [ tab::get_class_name $class ]
    set field_name [ tab::get_field_name $field ]
    #item 423
    return "set_${class_name}_${field_name}"
}

proc type_id_name { class } {
    #item 397
    set class_name [ tab::get_class_name $class ]
    #item 396
    return "f_${class_name}_type_id"
}

}
