namespace eval gen_c_t {

variable g_header 0
variable dbclass ""

variable g_direct {
 char uchar "unsigned char" 
 short ushort "unsigned short"
 int uint "unsigned int"
 long ulong "unsigned long"
}

	
	

# Autogenerated with DRAKON Editor 1.27

proc add { field this element indent } {
    #item 2309
    set field_name [ tab::get_field_name $field ]
    #item 2310
    a "obj_list_add\($this->$field_name, $element\);" $indent
}

proc add_collections { class } {
    #item 2364
    set fields [ tab::get_class_fields $class ]
    foreach field $fields {
        #item 2367
        set type2 [ tab::get_field2_type $field ]
        set field_name [ tab::get_field_name $field ]
        #item 2369
        if {$type2 == "collection"} {
            #item 2368
            a "    _record_->$field_name = obj_list_create\(0\);"
        } else {
            
        }
    }
}

proc add_to_index { item indent class } {
    #item 435
    set index [ dict get $item "index" ]
    #item 437
    set index_name [ index_name $index ]
    #item 438
    a "hashtable_put\(db->$index_name, _record_\);" $indent
}

proc assemble { item indent class } {
    #item 350
    set indexed [ dict get $item "indexed" ]
    #item 352
    set class_name [ tab::get_class_name $class ]
    #item 361
    a "_record_ = allocate_memory\(sizeof\($class_name\)\);" $indent
    #item 1269
    a "rec_id = array_table_insert\(&db->$class_name, _record_\);" $indent
    #item 1270
    a "_record_->_row.id = rec_id;" $indent
    a "_record_->_row.table = &db->$class_name;" $indent
    #item 353
    set fields [ dict get $indexed $class ]
    foreach field $fields {
        #item 359
        set field_name [ tab::get_field_name $field ]
        set link [ tab::get_field2_link $field ]
        #item 594
        set arg_name $field_name
        set uname $field_name
        #item 595
        a "_record_->$uname = $arg_name;" $indent
    }
}

proc build_argument { field } {
    #item 1674
    set type [ field_type $field ]
    set fname [ tab::get_field_name $field ]
    #item 1695
    lassign \
    [get_field_hints $field] \
    get set cget ctr own
    #item 1689
    if {[is_ptr $type]} {
        #item 1696
        if {$own} {
            #item 1699
            set com " /* own. null */"
        } else {
            #item 1693
            set com " /* null */"
        }
    } else {
        #item 1692
        set com ""
    }
    #item 1675
    return "$type $fname$com"
}

proc build_argument_find { field } {
    #item 2097
    set type [ field_type $field ]
    set fname [ tab::get_field_name $field ]
    #item 2099
    if {[is_ptr $type]} {
        #item 2103
        set com " /* null */"
    } else {
        #item 2102
        set com ""
    }
    #item 2106
    if {[const_find $field]} {
        #item 2098
        return "const $type $fname$com"
    } else {
        #item 2128
        return "$type $fname$com"
    }
}

proc can_delete { item indent class } {
    #item 384
    a "ensure_can_delete(record, deletion_list\);" $indent
}

proc check_change { item indent class } {
    #item 465
    set field [ dict get $item "field" ]
    set field_name [ tab::get_field_name $field ]
    set type [ field_type $field ]
    #item 1057
    a "if \(_record_->$field_name == new_value\) \{" $indent
    a "    return 1;" $indent
    a "\}" $indent
}

proc check_deleted { item indent class } {
    #item 405
    a "if \(obj_list_contains(deletion_list, record\)\) \{" $indent
    a "    return 1;" $indent
    a "\} else \{" $indent
    a "    obj_list_add\(deletion_list, record\);" $indent
    a "\}" $indent
}

proc check_id { item indent class } {
    
}

proc check_not_deleted { var indent } {
    #item 2420
    a "if \( !obj_list_contains\(deletion_list, $var\)\) \{" $indent
}

proc check_ref_count { item indent class } {
    #item 549
    set class [ dict get $item "class" ]
    set master [ dict get $item "master" ]
    #item 552
    if {$master} {
        #item 558
        a "if \(\(master && record->_ref_count > 1\) || " $indent
        a "  \(!master && record->_ref_count > 0 \)\) \{" $indent
    } else {
        #item 555
        a "if \( record->_ref_count > 0 \) \{" $indent
    }
    #item 556
    ref_count_error $class "    $indent"
    #item 557
    a "\}" $indent
}

proc check_self { item indent class } {
    #item 459
    ensure_exists $class "_record_" "_record_" 0 $indent
}

proc comment { type } {
    #item 1661
    if {[is_ptr $type]} {
        #item 1664
        return " /* null */"
    } else {
        #item 1665
        return ""
    }
}

proc compare { class field_name } {
    #item 2059
    set field [ tab::find_field $class $field_name ]
    set type [ field_type $field ]
    set link [ tab::get_field2_link $field ]
    #item 2067
    lassign \
    [get_field_hints $field] \
    get set cget ctr own
    #item 2072
    set type2 [ tab::get_field2_type $field ]
    #item 2068
    if {$own} {
        #item 2078
        set stype [ strip_star $type ]
        #item 2079
        a "    if \(!${stype}_equal\(left->$field_name, right->$field_name\)\) return 0;"
    } else {
        #item 2080
        a "    if \(left->$field_name != right->$field_name\) return 0;"
    }
}

proc connect { item indent class } {
    #item 532
    set field [ dict get $item "field" ]
    set op [ dict get $item "op" ]
    set link [ dict get $item "link" ]
    #item 539
    set field_name [ tab::get_field_name $field ]
    set uname $field_name
    #item 540
    a "if \(_record_->$uname != 0 \) \{" $indent
    #item 5330001
    if {$op == "ref_count"} {
        #item 541
        a "    _record_->$uname->_ref_count++;" $indent
    } else {
        #item 5330002
        if {$op == "collection"} {
            
        } else {
            #item 5330003
            error "Unexpected switch value: $op"
        }
        #item 543
        do_connect_col $link "_record_->$uname" "    $indent"
    }
    #item 531
    a "\}" $indent
}

proc const_find { field } {
    #item 2118
    lassign \
    [get_field_hints $field] \
    get set cget ctr own
    #item 2120
    if {$own} {
        #item 2126
        return 1
    } else {
        #item 2119
        set type2 [ tab::get_field2_type $field ]
        #item 2122
        if {$type2 == "reference"} {
            #item 2126
            return 1
        } else {
            #item 2127
            return 0
        }
    }
}

proc direct_hash { type } {
    #item 2024
    variable g_direct
    #item 2025
    return [ contains $g_direct $type ]
}

proc disconnect { item indent class } {
    #item 513
    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 520
    set field_name [ tab::get_field_name $field ]
    set target_name [ tab::get_class_name $target ]
    set indent2 "    $indent"
    set indent3 "    $indent2"
    #item 521
    a "if \(record->$field_name != 0 \) \{" $indent
    #item 523
    a "if \( !obj_list_contains\(deletion_list, record->$field_name\)\) \{" $indent2
    #item 5140001
    if {$op == "ref_count"} {
        #item 522
        a "record->$field_name->_ref_count--;" $indent3
    } else {
        #item 5140002
        if {$op == "collection"} {
            
        } else {
            #item 5140003
            error "Unexpected switch value: $op"
        }
        #item 1159
        do_disconnect_col $link "record->$field_name" "record" $indent3
    }
    #item 512
    a "\}" $indent2
    a "\}" $indent
}

proc disconnect_m2m { item indent class } {
    #item 590
    set field [ dict get $item "field" ]
    set target_field [ dict get $item "target_field" ]
    set target_class [ tab::get_field_class $target_field ]
    #item 2444
    set field_name [ tab::get_field_name $field ]
    #item 2445
    a "_that_$field_name = _that_;" $indent
    #item 592
    check_not_deleted "_that_$field_name" $indent
    #item 591
    remove $target_field "_that_$field_name" "record" "    $indent"
    #item 593
    a "\}" $indent
}

proc disconnect_old { item indent class } {
    #item 2186
    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 2193
    set field_name [ tab::get_field_name $field ]
    set uname $field_name
    set indent2 "    $indent"
    #item 2194
    
    a "if \(_record_->$uname != 0 \) \{" $indent
    #item 21870001
    if {$op == "ref_count"} {
        #item 2195
        a "_record_->$uname->_ref_count--;" $indent2
    } else {
        #item 21870002
        if {$op == "collection"} {
            
        } else {
            #item 21870003
            error "Unexpected switch value: $op"
        }
        #item 2196
        do_disconnect_col $link "_record_->$uname" "_record_" $indent2
    }
    #item 2185
    a "\}" $indent
}

proc do_connect_col { link that indent } {
    #item 2295
    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 2296
    add $many_field $that "_record_" $indent
}

proc do_delete { item indent class } {
    #item 390
    a "do_delete\(record, base, deletion_list\);" $indent
}

proc do_disconnect_col { link that element indent } {
    #item 2288
    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 2289
    remove $many_field $that $element $indent
}

proc ensure_deleted { item indent this_class } {
    #item 581
    set field [ dict get $item "field" ]
    set class [ dict get $item "class" ]
    set this_name [ tab::get_class_name $this_class ]
    #item 584
    a "if \(!obj_list_contains\(deletion_list, _that_\)\) \{" $indent
    a "    db->error_code = 2;" $indent
    a "    return 0;" $indent
    a "\}" $indent
}

proc ensure_exists { class var out_var 0 indent } {
    #item 1764
    variable dbclass
    #item 1756
    set class_name [ tab::get_class_name $class ]
    #item 1765
    set getter "${dbclass}_get_${class_name}"
    #item 1759
    if {$0} {
        #item 1757
        a "if \($var\) \{" $indent
        a "    ENSURE($var == $getter\(db, $var->_row.id\)\)" $indent
        a "\}" $indent
    } else {
        #item 1766
        a "ENSURE($var == $getter\(db, $var->_row.id\)\)" $indent
    }
}

proc fetch_field { item indent class } {
    
}

proc field_type { field } {
    #item 1441
    set field_name [ tab::get_field_name $field ]
    set properties [ tab::get_field_properties $field ]
    #item 2469
    set class [ tab::get_field_class $field ]
    set class_name [ tab::get_class_name $class ]
    #item 1442
    if {$properties == {}} {
        #item 1446
        tab::report_error_class $class_name \
        "Field '$field_name' has no type."
        #item 1448
        return {}
    } else {
        #item 1447
        set type [ lindex $properties 0 ]
        #item 1494
        lassign \
        [get_field_hints $field] \
        get set cget ctr own
        #item 1449
        if {$type == "link"} {
            #item 2470
            set type2 [ tab::get_field2_type $field ]
            set link [ tab::get_field2_link $field ]
            #item 2465
            if {$link == ""} {
                #item 2468
                tab::report_error_class $class_name \
                "No link definition found for link field '$field_name'."
                #item 1448
                return {}
            } else {
                #item 1454
                if {$type2 == "collection"} {
                    #item 1459
                    set target [ tab::get_collection_target $field $link ]
                } else {
                    #item 1452
                    set target [ tab::get_target $link ]
                }
                #item 1458
                set target_name [ tab::get_class_name $target ]
                #item 1453
                return "$target_name*"
            }
        } else {
            #item 1495
            if {$own} {
                #item 1498
                return "$type*"
            } else {
                #item 1451
                return $type
            }
        }
    }
}

proc first_lower { text } {
    #item 1685
    set first [ string index $text 0 ]
    set first_low [ string tolower $first ]
    #item 1686
    set rest [ string range $text 1 end ]
    #item 1687
    return "${first_low}${rest}"
}

proc foreign_check { item indent class } {
    #item 506
    set field [ dict get $item "field" ]
    set target [ dict get $item "class" ]
    set action [ dict get $item "action" ]
    set field_name [ tab::get_field_name $field ]
    set target_name [ tab::get_class_name $target ]
    #item 1142
    if {$action == "update"} {
        #item 505
        ensure_exists $target "new_value" "new_value" 1 $indent
    } else {
        #item 1147
        set arg_name $field_name
        set var_name "_${arg_name}_"
        #item 1145
        ensure_exists $target $arg_name $var_name 1 $indent
    }
}

proc gen_add_remove { db_name link add } {
    #item 1189
    set dst [ tab::get_link_dst_table $link ]
    set src [ tab::get_link_src_table $link ]
    set dst_field [ tab::get_link_dst_field $link ]
    set src_field [ tab::get_link_src_field $link ]
    set dst_name [ tab::get_class_name $dst ]
    set src_name [ tab::get_class_name $src ]
    set src_f [ tab::find_field $src $src_field ]
    set dst_f [ tab::find_field $dst $dst_field ]
    #item 1210
    if {$add} {
        #item 1213
        set action "add"
    } else {
        #item 1214
        set action "remove"
    }
    #item 1191
    set name "${db_name}_${action}_${src_name}_${src_field}"
    #item 1190
    set arguments [ list "$db_name* db" "$src_name* left" "$dst_name* right" ]
    set indent "    "
    #item 1194
    proc_head "void" $name $arguments
    #item 2411
    variable g_header
    #item 2412
    if {$g_header} {
        
    } else {
        #item 1205
        a "if \(left == 0 || right == 0\) return;" $indent
        #item 1206
        ensure_exists $src "left" "left" 0 $indent
        ensure_exists $dst "right" "right" 0 $indent
        #item 1215
        if {$add} {
            #item 1209
            add $src_f "left" "right" $indent
            add $dst_f "right" "left" $indent
        } else {
            #item 1218
            remove $src_f "left" "right" $indent
            remove $dst_f "right" "left" $indent
        }
        #item 1192
        a "\}"
    }
}

proc gen_can_delete { db_name class } {
    #item 1842
    set name [ tab::get_class_name $class ]
    #item 913
    set method [ tab::core_can_delete $class ]
    #item 914
    set body [ dict get $method "body" ]
    #item 941
    set arguments [ list "$db_name* db" \
     "$name* record" "obj_list* deletion_list" ]
    #item 1844
    variable g_header
    #item 940
    proc_head "static int" "${name}_ensure_can_delete" $arguments
    #item 1845
    if {$g_header} {
        
    } else {
        #item 2346
        if {[has_paw $class "none" 0]} {
            #item 2349
            a "    int length, i;"
            a "    void* _that_;"
        } else {
            
        }
        #item 918
        render_list $body "    " $class
        #item 917
        a "    return 1;"
        a "\}"
    }
}

proc gen_class_bodies { classes } {
    foreach class $classes {
        #item 1601
        set cname [ tab::get_class_name $class ]
        set fields [ tab::get_class_fields $class ]
        #item 1604
        a "struct $cname \{"
        a "    row_base _row;"
        #item 2231
        if {[has_arrow $class]} {
            #item 2234
            a "    int _ref_count;"
        } else {
            
        }
        foreach field $fields {
            #item 1606
            gen_field $field
        }
        #item 1605
        a "\};"
    }
}

proc gen_comparer { index } {
    #item 1983
    variable g_header
    #item 1991
    set iname [ index_name $index ]
    set class [ tab::get_index_class $index ]
    set cname [ tab::get_class_name $class ]
    set fields [ tab::get_index_fields $index ]
    #item 1999
    set args [ list "const void* vobj" ]
    #item 1997
    proc_head "static unsigned int" "${iname}_hash" $args
    #item 1995
    if {$g_header} {
        
    } else {
        #item 2036
        a "    const $cname* obj;"
        a "    unsigned int code;"
        a "    if \(!vobj\) return 0;"
        a "    obj = vobj;"
        #item 2005
        set first 1
        foreach field_name $fields {
            #item 2004
            hash $first $class $field_name
            #item 2006
            set first 0
        }
        #item 2001
        a "    return code;"
        a "\}"
    }
    #item 2041
    set args [ list "const void* lobj" "const void* robj" ]
    #item 2039
    proc_head "static int" "${iname}_eq" $args
    #item 2037
    if {$g_header} {
        
    } else {
        #item 2046
        a "    const $cname* left;"
        a "    const $cname* right;"
        #item 2047
        a "    left = lobj;"
        a "    right = robj;"
        foreach field_name $fields {
            #item 2045
            compare $class $field_name
        }
        #item 2042
        a "    return 1;"
        a "\}"
    }
}

proc gen_comparers { class } {
    #item 2086
    set indexes [ tab::get_class_indexes $class ]
    foreach index $indexes {
        #item 2089
        gen_comparer $index
    }
}

proc gen_complex_setter { db_name method } {
    #item 1039
    set field [ dict get $method "field" ]
    set class [ dict get $method "class" ]
    set body [ get_optional $method "body" ]
    #item 1041
    set type [ field_type $field ]
    set class_name [ tab::get_class_name $class ]
    set field_name [ tab::get_field_name $field ]
    set name "${db_name}_set_${class_name}_${field_name}"
    #item 2137
    set indexes [ tab::get_field2_indexes $field ]
    #item 2146
    if {[is_ptr $type]} {
        #item 2149
        lassign \
        [get_field_hints $field] \
        get set cget ctr own
        #item 2150
        if {$own} {
            #item 2155
            set com " /* own. null */"
        } else {
            #item 2154
            set com " /* null */"
        }
    } else {
        #item 2153
        set com ""
    }
    #item 1040
    set arguments [ list "$db_name* db" "$class_name* _record_" \
     "$type new_value$com" ]
    #item 1045
    proc_head "int" $name $arguments
    #item 2138
    variable g_header
    #item 2139
    if {$g_header} {
        
    } else {
        #item 2143
        if {$indexes == {}} {
            
        } else {
            #item 2142
            a "    $class_name* found;"
            a "    $class_name _key_;"
        }
        #item 1043
        render_list $body "    " $class
        #item 1042
        a "    return 1;"
        a "\}"
    }
}

proc gen_count { db_name class } {
    #item 813
    set name [ tab::get_class_name $class ]
    #item 1706
    set args [ list "const $db_name* db" ]
    #item 814
    proc_head "int" "${db_name}_${name}_count" $args
    #item 1702
    variable g_header
    #item 1703
    if {$g_header} {
        
    } else {
        #item 817
        a "    return db->$name.count;"
        #item 815
        a "\}"
    }
}

proc gen_ctr { name classes } {
    #item 1372
    variable g_header
    #item 1376
    proc_head "$name* /* own */" "${name}_create" {}
    #item 1373
    if {$g_header} {
        
    } else {
        #item 1366
        a "    $name* me = allocate_memory\(sizeof\($name\)\);"
        a "    me->base.type = &${name}_t;"
        foreach class $classes {
            #item 1370
            set cname [ tab::get_class_name $class ]
            #item 1371
            a "    array_table_init\(&me->$cname, \"$cname\"\);"
            a "    me->$cname.do_delete = \(dd_fun\)${cname}_do_delete;"
            a "    me->$cname.ensure_can_delete = \(ensure_cd_fun\)${cname}_ensure_can_delete;"
            #item 1959
            set indexes [ tab::get_class_indexes $class ]
            foreach index $indexes {
                #item 1962
                set iname [ index_name $index ]
                #item 1963
                a "    me->$iname = hashtable_create\(0, ${iname}_hash, ${iname}_eq\);"
            }
        }
        #item 1367
        a "    return me;"
        a "\}"
    }
}

proc gen_del_utils { name } {
    #item 1813
    variable g_header
    #item 1822
    set args [ list "$name* db" "void* record" \
     "obj_list* deletion_list" ]
    #item 1820
    proc_head "static int" "ensure_can_delete" $args
    #item 1814
    if {$g_header} {
        
    } else {
        #item 1823
        a "    row_base* row = record;"
        a "    return row->table->ensure_can_delete\("
        a "        db,"
        a "        record,"
        a "        deletion_list\);"
        #item 1829
        a "\}"
    }
    #item 1837
    set args [ list "$name* db" "void* record" \
     "obj_list* deletion_list" "int unlink"]
    #item 1838
    proc_head "static void" "do_delete" $args
    #item 1834
    if {$g_header} {
        
    } else {
        #item 1839
        a "    row_base* row = record;"
        a "    row->table->do_delete\("
        a "        db,"
        a "        record,"
        a "        deletion_list,"
        a "        unlink\);"
        #item 1840
        a "\}"
    }
    #item 1826
    set args [ list "void* record" "void* dbv" ]
    #item 1827
    proc_head "static int" "record_destructor" $args
    #item 1817
    if {$g_header} {
        
    } else {
        #item 1828
        a "    $name* db = dbv;"
        a "    do_delete\("
        a "        db,"
        a "        record,"
        a "        0,"
        a "        0\);"
        a "    return 0;"
        #item 1830
        a "\}"
    }
}

proc gen_delete { db_name class } {
    #item 841
    set name [ tab::get_class_name $class ]
    #item 833
    set method [ tab::core_delete $class ]
    #item 834
    set body [ dict get $method "body" ]
    #item 1742
    set args [ list "$db_name* db" "$name* record /* null */" ]
    #item 835
    proc_head "int" "${db_name}_delete_${name}" $args
    #item 1743
    variable g_header
    #item 1744
    if {$g_header} {
        
    } else {
        #item 1767
        a "    obj_list* deletion_list;"
        a "    int deleted = 0;"
        a "    if \(!record\) return 0;"
        a "    deletion_list = obj_list_create\(0\);"
        a "    ENSURE\(record == ${db_name}_get_${name}\(db, record->_row.id\)\)"
        a "    if \(${name}_pre_delete\(db, record, deletion_list, 0\)\) \{"
        a "        deleted = delete_generic\(db, deletion_list\);"
        a "    \}"
        a "    obj_list_destroy\(deletion_list\);"
        a "    return deleted;"
        a "\}"
    }
}

proc gen_delete_generic { db_name } {
    #item 1786
    set args [ list "$db_name* db" "obj_list* deletion_list" ]
    #item 1785
    proc_head "static int" "delete_generic" $args
    #item 1787
    variable g_header
    #item 1788
    if {$g_header} {
        
    } else {
        #item 1784
        a "    void* record;"
        a "    int i, n;"
        a "    n = obj_list_length\(deletion_list\);"
        a "    for \(i = 0; i < n; i++\) \{"
        a "        record = obj_list_get\(deletion_list, i\);"
        a "        if \(!ensure_can_delete\(db, record, deletion_list\)\) \{"
        a "            return 0;"
        a "        \}"
        a "    \}"
        a "    for \(i = 0; i < n; i++\) \{"
        a "        record = obj_list_get\(deletion_list, i\);"
        a "        do_delete\(db, record, deletion_list, 1\);"
        a "    \}"
        a "    return 1;"
        a "\}"
    }
}

proc gen_do_delete { db_name class } {
    #item 1849
    set name [ tab::get_class_name $class ]
    #item 924
    set method [ tab::core_do_delete $class ]
    #item 957
    set body [ dict get $method "body" ]
    #item 960
    set arguments [ list "$db_name* db" \
     "$name* record" \
     "obj_list* deletion_list" \
     "int unlink" ]
    #item 958
    proc_head "static void" "${name}_do_delete" $arguments
    #item 1850
    variable g_header
    #item 1851
    if {$g_header} {
        
    } else {
        #item 2429
        vars_m2m $class
        #item 1855
        a "    if \(unlink\) \{"
        #item 929
        set indent "        "
        render_list $body $indent $class
        #item 1870
        a "        array_table_delete\(&db->$name, record->_row.id\);"
        #item 1856
        a "    \}"
        #item 936
        set fields [ tab::get_class_fields $class ]
        foreach field $fields {
            #item 1867
            set field_name [ tab::get_field_name $field ]
            #item 1857
            lassign \
            [get_field_hints $field] \
            get set cget ctr own
            #item 1859
            set type [ field_type $field ]
            set type2 [ tab::get_field2_type $field ]
            #item 1865
            set type_ws [ strip_star $type ]
            #item 1858
            if {$type2 == "collection"} {
                #item 1864
                a "    obj_list_destroy\(record->$field_name\);"
            } else {
                #item 1860
                if {$own} {
                    #item 1866
                    a "    ${type_ws}_destroy\(record->$field_name\);"
                } else {
                    
                }
            }
        }
        #item 1868
        a "    free_memory\(record, sizeof\($name\)\);"
        #item 928
        a "\}"
    }
}

proc gen_dtr { name classes } {
    #item 1382
    variable g_header
    #item 1386
    proc_head "void" "${name}_destroy" [ list "$name* me /* own. null */" ]
    #item 1383
    if {$g_header} {
        
    } else {
        #item 1388
        a "    if \(!me\) return;"
        a "    ENSURE\(me->base.type == &${name}_t\)"
        foreach class $classes {
            #item 1964
            set indexes [ tab::get_class_indexes $class ]
            foreach index $indexes {
                #item 1967
                set iname [ index_name $index ]
                #item 1968
                a "    hashtable_destroy(\me->$iname\);"
            }
            #item 1393
            set cname [ tab::get_class_name $class ]
            #item 1841
            a "    ${name}_foreach_${cname}\("
            a "        me,"
            a "        \(${cname}_fun\)record_destructor,"
            a "        me\);"
            #item 1392
            a "    array_table_cleanup\(&me->$cname\);"
        }
        #item 1389
        a "    free_memory\(me, sizeof\($name\)\);"
        #item 1387
        a "\}"
    }
}

proc gen_error { db_name } {
    #item 1949
    set args [ list "const $db_name* db" ]
    #item 1950
    proc_head "int" "${db_name}_error" $args
    #item 1944
    variable g_header
    #item 1945
    if {$g_header} {
        
    } else {
        #item 1951
        a "    return db->error_code;"
        #item 1952
        a "\}"
    }
}

proc gen_field { field } {
    #item 1612
    set field_name [ tab::get_field_name $field ]
    set link [ tab::get_field2_link $field ]
    set indexes [ tab::get_field2_indexes $field ]
    set type [ tab::get_field2_type $field ]
    #item 16130001
    if {$type == "data"} {
        #item 1626
        set ftype [ field_type $field ]
    } else {
        #item 16130002
        if {$type == "reference"} {
            #item 1620
            set target [ tab::get_target $link ]
            #item 1621
            set target_name [ tab::get_class_name $target ]
            #item 1641
            set ftype "$target_name*"
        } else {
            #item 16130003
            if {$type == "collection"} {
                
            } else {
                #item 16130004
                error "Unexpected switch value: $type"
            }
            #item 1629
            set ftype "obj_list*"
        }
    }
    #item 1640
    a "    $ftype $field_name;"
}

proc gen_find { db_name class } {
    #item 969
    set indexes [ tab::get_class_indexes $class ]
    #item 982
    set class_name [ tab::get_class_name $class ]
    foreach index $indexes {
        #item 980
        set iname [ index_name $index ]
        set name "${db_name}_${iname}"
        set fields [ tab::index_fields $index ]
        #item 981
        set arguments [ map2 $fields gen_c_t::build_argument_find ]
        set arguments [ linsert $arguments 0 "$db_name* db" ]
        #item 983
        proc_head "$class_name* /* null */" $name $arguments
        #item 2176
        variable g_header
        #item 2177
        if {$g_header} {
            
        } else {
            #item 2239
            a "    $class_name _key_;"
            #item 2328
            gen_key_find "_key_" $fields "    "
            #item 989
            a "    return hashtable_get\(db->$iname, &_key_\);"
            a "\}"
        }
    }
}

proc gen_foreach { db_name class } {
    #item 1713
    set name [ tab::get_class_name $class ]
    #item 1714
    set args [ list "$db_name* db" "${name}_fun visitor" \
     "void* user_data /* null */" ]
    #item 1715
    proc_head "int" "${db_name}_foreach_${name}" $args
    #item 1709
    variable g_header
    #item 1710
    if {$g_header} {
        
    } else {
        #item 1716
        a "    int i, n;"
        a "    $name* current;"
        #item 1717
        a "    n = db->$name.next;"
        a "    for \(i = 0; i < n; i++\) \{"
        a "        current = db->$name.items\[i\];"
        a "        if \(current\) \{"
        a "            if \(visitor\(current, user_data\)\) return 1;"
        a "        \}"
        a "    \}"
        a "    return 0;"
        a "\}"
    }
}

proc gen_get { db_name class } {
    #item 1735
    set name [ tab::get_class_name $class ]
    #item 1736
    set args [ list "$db_name* db" "int rec_id" ]
    #item 1737
    proc_head "$name* /* null */" "${db_name}_get_${name}" $args
    #item 1731
    variable g_header
    #item 1732
    if {$g_header} {
        
    } else {
        #item 1738
        a "    if \(rec_id < 0\) return 0;"
        a "    if \(rec_id >= db->$name.next\) return 0;"
        a "    return db->$name.items\[rec_id\];"
        #item 1739
        a "\}"
    }
}

proc gen_get_id { cname } {
    #item 1584
    proc_head "int" "${cname}_id" [ list "const $cname* me" ]
    #item 1585
    variable g_header
    #item 1586
    if {$g_header} {
        
    } else {
        #item 1589
        a "    return me->_row.id;"
        #item 1590
        a "\}"
    }
}

proc gen_getter { cname field } {
    #item 1422
    set in "        "
    #item 1412
    set field_name [ tab::get_field_name $field ]
    set link [ tab::get_field2_link $field ]
    set indexes [ tab::get_field2_indexes $field ]
    set type [ tab::get_field2_type $field ]
    #item 1499
    lassign \
    [get_field_hints $field] \
    get set cget ctr own
    #item 14130001
    if {$type == "data"} {
        #item 1426
        set ftype [ field_type $field ]
        #item 1423
        if {$indexes == {}} {
            #item 1500
            gen_simple_getter $cname $field_name $ftype $get $own
            #item 1502
            gen_simple_cgetter $cname $field_name $ftype $cget $own
            #item 1501
            gen_simple_setter $cname $field_name $ftype $set $own
        } else {
            #item 1503
            if {$own} {
                #item 1507
                gen_simple_cgetter $cname $field_name $ftype $cget $own
            } else {
                #item 1506
                gen_simple_getter $cname $field_name $ftype $get $own
            }
        }
    } else {
        #item 14130002
        if {$type == "reference"} {
            #item 1420
            set target [ tab::get_target $link ]
            #item 1421
            set target_name [ tab::get_class_name $target ]
            #item 2240
            gen_simple_getter $cname $field_name "$target_name*" $get 1
            #item 1508
            gen_simple_cgetter $cname $field_name "$target_name*" $cget 1
        } else {
            #item 14130003
            if {$type == "collection"} {
                
            } else {
                #item 14130004
                error "Unexpected switch value: $type"
            }
            #item 1429
            lassign \
            [tab::get_other_side $field] \
            target target_field
            #item 1430
            set target_name [ tab::get_class_name $target ]
            #item 1435
            gen_many_count $cname $field_name
            #item 1428
            gen_many_getter $cname $field_name "$target_name*"
        }
    }
}

proc gen_insert { db_name class } {
    #item 775
    set method [ tab::core_insert $class gen_cs::has_ctr ]
    #item 776
    set args [ get_optional $method "args" ]
    set body [ get_optional $method "body" ]
    #item 777
    set init_fields [ map2 $args gen_c_t::build_argument ]
    set arguments [ linsert $init_fields 0 "$db_name* db" ]
    #item 779
    set name [ tab::get_class_name $class ]
    set returns "$name* /* null */"
    #item 778
    proc_head $returns "${db_name}_insert_${name}" $arguments
    #item 1676
    variable g_header
    #item 1677
    if {$g_header} {
        
    } else {
        #item 1688
        a "    $name* _record_;"
        a "    int rec_id;"
        #item 1934
        set indexes [ tab::get_class_indexes $class ]
        #item 1935
        if {$indexes == {}} {
            
        } else {
            #item 1938
            a "    $name _key_;"
            a "    $name* found;"
        }
        #item 2175
        a "    _record_ = 0;"
        #item 781
        render_list $body "    " $class
        #item 2235
        if {[has_arrow $class]} {
            #item 2238
            a "    _record_->_ref_count = 0;"
        } else {
            
        }
        #item 2358
        add_collections $class
        #item 780
        a "    return _record_;"
        a "\}"
    }
}

proc gen_key { fields changed indent } {
    #item 1884
    set first [ lindex $fields 0 ]
    set class [ tab::get_field_class $first ]
    set key_name "_key_"
    #item 1885
    if {$changed == ""} {
        #item 1883
        gen_key_insert $key_name $fields $indent
    } else {
        #item 1889
        set changed_name [ tab::get_field_name $changed ]
        #item 1888
        gen_key_update $key_name $fields $changed_name $indent
    }
}

proc gen_key_find { key_name fields indent } {
    foreach field $fields {
        #item 2321
        set fname [ tab::get_field_name $field ]
        set link [ tab::get_field2_link $field ]
        #item 2322
        set type [ field_type $field ]
        #item 2323
        lassign \
        [get_field_hints $field] \
        get set cget ctr own
        #item 2324
        if {$own} {
            #item 2327
            a "$key_name.$fname = \($type\)$fname;" $indent
        } else {
            #item 2329
            if {$link == {}} {
                #item 2320
                a "$key_name.$fname = $fname;" $indent
            } else {
                #item 2331
                a "$key_name.$fname = \(struct $type\)$fname;" $indent
            }
        }
    }
}

proc gen_key_insert { key_name fields indent } {
    foreach field $fields {
        #item 1899
        set fname [ tab::get_field_name $field ]
        set link [ tab::get_field2_link $field ]
        #item 2132
        set type [ field_type $field ]
        #item 1897
        a "$key_name.$fname = $fname;" $indent
    }
}

proc gen_key_record { class } {
    #item 1910
    set indexes [ tab::get_class_indexes $class ]
    set name [ tab::get_class_name $class ]
    set key [ key_name $class ]
    #item 1911
    if {$indexes == {}} {
        
    } else {
        #item 1914
        a "    private readonly $name $key = new $name\(0\);"
    }
}

proc gen_key_update { key_name fields changed_name indent } {
    foreach field $fields {
        #item 1923
        set field_name [ tab::get_field_name $field ]
        #item 1924
        if {$field_name == $changed_name} {
            #item 1927
            a "$key_name.$field_name = new_value;" $indent
        } else {
            #item 1922
            a "$key_name.$field_name = _record_->$field_name;" $indent
        }
    }
}

proc gen_many_count { cname field_name } {
    #item 2266
    set args [ list "const $cname* record" ]
    #item 2267
    proc_head "int" "${cname}_${field_name}_count" $args
    #item 2261
    variable g_header
    #item 2262
    if {$g_header} {
        
    } else {
        #item 2268
        a "    return obj_list_length\(record->$field_name);"
        #item 2269
        a "\}"
    }
}

proc gen_many_getter { cname field_name target_name } {
    #item 2279
    set args [ list "$cname* record" "int index" ]
    #item 2280
    proc_head $target_name "${cname}_${field_name}" $args
    #item 2275
    variable g_header
    #item 2276
    if {$g_header} {
        
    } else {
        #item 2281
        a "    return obj_list_get\(record->$field_name, index);"
        #item 2282
        a "\}"
    }
}

proc gen_pre_delete { db_class class } {
    #item 1778
    set name [ tab::get_class_name $class ]
    #item 876
    set method [ tab::core_pre_delete_inner $class ]
    #item 2243
    set method2 [ tab::core_pre_delete_outer $class ]
    #item 942
    set body [ dict get $method "body" ]
    #item 2245
    set body2 [ dict get $method2 "body" ]
    #item 946
    set arguments [ list "$db_class* db" \
      "$name* record" "obj_list* deletion_list" "int master"]
    #item 945
    proc_head "static int" "${name}_pre_delete" $arguments
    #item 1792
    variable g_header
    #item 1793
    if {$g_header} {
        
    } else {
        #item 2393
        if {[has_paw $class "src" 0]} {
            #item 2396
            a "    int length, i;"
            a "    void* _that_;"
        } else {
            
        }
        #item 1797
        render_list $body2 "    " $class
        #item 2244
        render_list $body "    " $class
        #item 943
        a "    return 1;"
        a "\}"
    }
}

proc gen_pre_delete_inner { class } {
    #item 902
    set method [ tab::core_pre_delete_inner $class ]
    set base [ tab::get_class2_base $class ]
    #item 947
    set body [ dict get $method "body" ]
    #item 951
    set arguments [ list "[del_list_name] deletion_list" ]
    #item 1238
    set modifier [ method_modifier $class ]
    #item 950
    proc_head "$modifier void" "PreDeleteInner" $arguments "        "
    #item 949
    render_list $body "            " $class
    #item 1240
    if {$base == {}} {
        
    } else {
        #item 1239
        a "base.PreDeleteInner\(deletion_list\);" "            "
    }
    #item 948
    a "        \}"
}

proc gen_pri_methods { name classes } {
    #item 1791
    gen_delete_generic $name
    #item 1798
    gen_del_utils $name
    foreach class $classes {
        #item 1775
        gen_pre_delete $name $class
        #item 1843
        gen_can_delete $name $class
        #item 1854
        gen_do_delete $name $class
        #item 2090
        gen_comparers $class
    }
}

proc gen_pub_methods { name classes } {
    #item 1953
    gen_error $name
    foreach class $classes {
        #item 1404
        set cname [ tab::get_class_name $class ]
        set fields [ tab::get_class_fields $class ]
        #item 1591
        gen_get_id $cname
        #item 1740
        gen_get $name $class
        foreach field $fields {
            #item 1400
            gen_getter $cname $field
        }
        #item 2136
        gen_setters $name $class
        #item 1668
        gen_insert $name $class
        #item 1748
        gen_delete $name $class
        #item 1700
        gen_count $name $class
        #item 1707
        gen_foreach $name $class
        #item 2091
        gen_find $name $class
    }
    #item 2410
    set links [ tab::link_type_keys ]
    foreach link $links {
        #item 2405
        set type [ tab::get_link_type $link ]
        #item 2406
        if {$type == "m2m"} {
            #item 2409
            gen_add_remove $name $link 1
            gen_add_remove $name $link 0
        } else {
            
        }
    }
}

proc gen_setters { db_name class } {
    #item 1014
    set class_name [ tab::get_class_name $class ]
    set fields [ tab::get_class_fields $class ]
    foreach field $fields {
        #item 1033
        set setter [ tab::core_update $field ]
        #item 1023
        if {$setter == {}} {
            
        } else {
            #item 1026
            set type [ dict get $setter "type" ]
            #item 1044
            if {$type == "complex"} {
                #item 2134
                lassign \
                [get_field_hints $field] \
                get set cget ctr own
                #item 2135
                if {$set} {
                    #item 1028
                    gen_complex_setter $db_name $setter
                } else {
                    
                }
            } else {
                
            }
        }
    }
}

proc gen_simple_cgetter { cname field_name type cget own } {
    #item 1534
    if {($cget) && ($own)} {
        #item 1540
        set me "const $cname* me"
        set returns "const $type /* null */"
        #item 1543
        set args [ list $me ]
        #item 1542
        proc_head $returns "${cname}_cget_${field_name}" $args
        #item 1544
        variable g_header
        #item 1545
        if {$g_header} {
            
        } else {
            #item 1546
            a "    return me->$field_name;"
            a "\}"
        }
    } else {
        
    }
}

proc gen_simple_getter { cname field_name type get own } {
    #item 1515
    if {$get} {
        #item 1518
        if {$own} {
            #item 1522
            set me "$cname* me"
        } else {
            #item 1521
            set me "const $cname* me"
        }
        #item 1524
        set args [ list $me ]
        #item 1666
        set com [ comment $type ]
        set returns "${type}$com"
        #item 1523
        proc_head $returns "${cname}_${field_name}" $args
        #item 1525
        variable g_header
        #item 1526
        if {$g_header} {
            
        } else {
            #item 1528
            a "    return me->$field_name;"
            a "\}"
        }
    } else {
        
    }
}

proc gen_simple_setter { cname field_name type set own } {
    #item 1552
    if {$set} {
        #item 1555
        if {$own} {
            #item 1565
            set value "$type value /* own. null */"
        } else {
            #item 1667
            set com [ comment $type ]
            #item 1558
            set value "$type value$com"
        }
        #item 1561
        set args [ list "$cname* me" $value ]
        #item 1560
        proc_head "void" "${cname}_set_${field_name}" $args
        #item 1562
        variable g_header
        #item 1563
        if {$g_header} {
            
        } else {
            #item 1566
            if {$own} {
                #item 1578
                set field_cname [ strip_star $type ]
                #item 1571
                a "    if \(me->$field_name == value\) return;"
                a "    if \(me->$field_name\) \{"
                a "        ${field_cname}_destroy\(me->$field_name\);"
                a "    \}"
            } else {
                
            }
            #item 1570
            a "    me->$field_name = value;"
            #item 1569
            a "\}"
        }
    } else {
        
    }
}

proc gen_visitor { class } {
    #item 1723
    set name [ tab::get_class_name $class ]
    #item 1724
    a "typedef int \(*${name}_fun\)\($name* item, void* user_data /* null */\);"
}

proc generate_cpp { db_class_name } {
    #item 1763
    variable dbclass
    set dbclass $db_class_name
    #item 4
    set classes [ tab::class_name_keys ]
    set links [ tab::link_type_keys ]
    #item 12
    if {$classes == {}} {
        
    } else {
        #item 1317
        variable g_header
        set g_header 1
        #item 1275
        generate_db_body $db_class_name $classes
        #item 1593
        gen_class_bodies $classes
        #item 1776
        gen_pri_methods $db_class_name $classes
        #item 1318
        set g_header 0
        #item 1304
        gen_ctr $db_class_name $classes
        #item 1316
        gen_dtr $db_class_name $classes
        #item 1592
        gen_pub_methods $db_class_name $classes
        #item 1777
        gen_pri_methods $db_class_name $classes
    }
}

proc generate_db_body { name classes } {
    #item 1282
    a "struct $name \{"
    a "    tobject base;"
    foreach class $classes {
        #item 1286
        set cname [ tab::get_class_name $class ]
        #item 1287
        a "    array_table $cname;"
        #item 1954
        set indexes [ tab::get_class_indexes $class ]
        foreach index $indexes {
            #item 1957
            set iname [ index_name $index ]
            #item 1958
            a "    hashtable* $iname;"
        }
    }
    #item 1283
    a "    int error_code;"
    a "\};"
    #item 1288
    a "static type_info_t ${name}_t = \{" 
    a "	OBJECT_SIGNATURE,"
    a "	\"$name\","
    a "	\(destructor_fun\)${name}_destroy"
    a "\};"
}

proc generate_h { db_class_name } {
    #item 1762
    variable dbclass
    set dbclass $db_class_name
    #item 1292
    set classes [ tab::class_name_keys ]
    set links [ tab::link_type_keys ]
    #item 1360
    variable g_header
    set g_header 1
    #item 1293
    if {$classes == {}} {
        
    } else {
        #item 1298
        a "typedef struct $db_class_name $db_class_name;"
        foreach class $classes {
            #item 1302
            set cname [ tab::get_class_name $class ]
            #item 1301
            a "typedef struct $cname $cname;"
            #item 1725
            gen_visitor $class
        }
        #item 1394
        gen_ctr $db_class_name $classes
        #item 1395
        gen_dtr $db_class_name $classes
        #item 1509
        gen_pub_methods $db_class_name $classes
    }
}

proc get_class_id { item indent class } {
    
}

proc get_field_hints { field } {
    #item 1466
    set properties [ tab::get_field_properties $field ]
    #item 1465
    set tail [ lrange $properties 1 end ]
    #item 1468
    if {[contains $tail "get"]} {
        #item 1472
        set get 1
    } else {
        #item 1471
        set get 0
    }
    #item 1473
    if {[contains $tail "set"]} {
        #item 1477
        set set 1
    } else {
        #item 1476
        set set 0
    }
    #item 1478
    if {[contains $tail "cget"]} {
        #item 1482
        set cget 1
    } else {
        #item 1481
        set cget 0
    }
    #item 1483
    if {[contains $tail "ctr"]} {
        #item 1487
        set ctr 1
    } else {
        #item 1486
        set ctr 0
    }
    #item 1489
    if {[contains $tail "own"]} {
        #item 1493
        set own 1
    } else {
        #item 1492
        set own 0
    }
    #item 1488
    return [ list $get $set $cget $ctr $own ]
}

proc has_arrow { class } {
    #item 2202
    set links [ tab::get_class_links $class ]
    
    set normal_2207 1
    foreach link $links {
        #item 2209
        set type [ tab::get_link_type $link ]
        set dst  [ tab::get_link_dst_table $link ]
        #item 2214
        if {($type == "arrow") && ($dst == $class)} {
            #item 2220
            set result 1
            set normal_2207 0
            break
        } else {
            
        }
    }
    if {$normal_2207 == 1} {
        #item 2222
        set derived [ tab::get_class2_derived $class ]
        
        set normal_2223 1
        foreach cls $derived {
            #item 2225
            if {[has_arrow $cls]} {
                #item 2227
                set result 1
                set normal_2223 0
                break
            } else {
                
            }
        }
        if {$normal_2223 == 1} {
            #item 2228
            set result 0
        }
    }
    #item 2230
    return $result
}

proc has_paw { class exp_own for_m2m } {
    #item 2337
    set fields [ tab::get_class_fields $class ]
    foreach field $fields {
        #item 2344
        set link [ tab::get_field2_link $field ]
        set link_type [ tab::get_link_type $link ]
        set own [ tab::get_link_ownership $link ]
        #item 2354
        set type2 [ tab::get_field2_type $field ]
        #item 2338
        if {(($own == $exp_own) && ($link_type == "paw")) && ($type2 == "collection")} {
            #item 2353
            return 1
        } else {
            
        }
    }
    #item 2343
    return 0
}

proc hash { first class field_name } {
    #item 2015
    set value [ hash_value $class $field_name ]
    #item 2012
    if {$first} {
        #item 2016
        a "    code = $value;"
    } else {
        #item 2017
        a "    code = \(code * 397\) ^ \($value\);"
    }
}

proc hash_value { class field_name } {
    #item 117
    set field [ tab::find_field $class $field_name ]
    set type [ field_type $field ]
    set link [ tab::get_field2_link $field ]
    #item 2026
    lassign \
    [get_field_hints $field] \
    get set cget ctr own
    #item 2031
    set type2 [ tab::get_field2_type $field ]
    #item 20320001
    if {$type2 == "data"} {
        #item 1272
        if {[direct_hash $type]} {
            #item 134
            return "\(unsigned int\)obj->$field_name"
        } else {
            #item 2027
            if {$own} {
                #item 2029
                set stype [ strip_star $type ]
                #item 1274
                return "${stype}_hash\(obj->$field_name\)"
            } else {
                #item 2030
                return "qhashmurmur3_32\(&obj->$field_name, sizeof\($type\)\)"
            }
        }
    } else {
        #item 20320002
        if {$type2 == "reference"} {
            
        } else {
            #item 20320003
            error "Unexpected switch value: $type2"
        }
        #item 139
        return "\(obj->$field_name\) ? \(unsigned int\)obj->$field_name->_row.id : 0"
    }
}

proc index_name { index } {
    #item 1876
    set class [ tab::get_index_class $index ]
    set fields [ tab::get_index_fields $index ]
    set class_name [ tab::get_class_name $class ]
    set fields_str [ join $fields "_" ]
    #item 1877
    set name "${class_name}_by_${fields_str}"
}

proc index_not_exists { item indent class } {
    #item 424
    set index [ dict get $item "index" ]
    set fields [ dict get $item "fields" ]
    set changed [ dict get $item "changed" ]
    #item 676
    set fnames [ map2 $fields tab::get_field_name ]
    #item 427
    set index_name [ index_name $index ]
    set class [ tab::get_index_class $index ]
    set class_name [ tab::get_class_name $index ]
    #item 429
    gen_key $fields $changed "    "
    #item 426
    a "found = hashtable_get\(db->$index_name, &_key_\);" $indent
    a "if \(found && found != _record_\) \{" $indent
    a "    db->error_code = 1;" $indent
    a "    return 0;" $indent
    a "\}" $indent
}

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

proc is_ptr { type } {
    #item 1648
    set chars [ split $type "" ]
    foreach char $chars {
        #item 1651
        if {$char == "*"} {
            #item 1655
            return 1
        } else {
            
        }
    }
    #item 1654
    return 0
}

proc pre_delete_inner { item indent class } {
    
}

proc pre_delete_middle { item indent class } {
    
}

proc pre_delete_outer { item indent class } {
    #item 366
    set cls [ dict get $item "class" ]
    set field_name [ dict get $item "field_name" ]
    set master [ dict get $item "master" ]
    #item 857
    if {$field_name == "_id"} {
        #item 860
        set target "_record_"
    } else {
        #item 1160
        if {$field_name == "that"} {
            #item 1162
            set target "_that_"
        } else {
            #item 861
            set target "record->$field_name"
        }
    }
    #item 863
    if {($master == "none") || ($master == "false")} {
        #item 377
        set master "0"
    } else {
        #item 2255
        set master "1"
    }
    #item 2253
    set cname [ tab::get_class_name $cls ]
    #item 862
    a "if \(!${cname}_pre_delete\(db, $target, deletion_list, $master\)\) return 0;" $indent
}

proc proc_head { returns name arguments } {
    #item 1329
    variable g_header
    #item 1330
    if {$g_header} {
        #item 1333
        set end ";"
    } else {
        #item 1334
        set end " \{"
    }
    #item 1335
    if {$arguments == {}} {
        #item 1338
        set arg_str "void"
    } else {
        #item 1339
        set arg_str [ join $arguments ",\n    " ]
    }
    #item 1340
    a "\n"
    a $returns
    a "$name\($arg_str\)$end"
}

proc ref_count_error { class indent } {
    #item 2252
    a "db->error_code = 2;" $indent
    a "return 0;" $indent
}

proc remove { field this element indent } {
    #item 2311
    set field_name [ tab::get_field_name $field ]
    #item 2312
    a "obj_list_remove\($this->$field_name, $element\);" $indent
}

proc remove_from_index { item indent class } {
    #item 445
    set index [ dict get $item "index" ]
    set fields [ dict get $item "fields" ]
    #item 447
    set index_name [ index_name $index ]
    #item 760
    a "hashtable_remove\(db->$index_name, record\);" $indent
}

proc remove_from_index_old { item indent class } {
    #item 2161
    set index [ dict get $item "index" ]
    #item 2164
    set index_name [ index_name $index ]
    #item 2165
    a "hashtable_remove\(db->$index_name, _record_\);" $indent
}

proc render_action { items indent class } {
    #item 700
    set name [ lindex $items 1 ]
    set handler "gen_c_t::$name"
    #item 702
    $handler $items $indent $class
}

proc render_foreach { items indent class } {
    #item 724
    set condition [ dict get $items "foreach" ]
    set body [ dict get $items "do" ]
    #item 725
    if {[dict exists $condition "variable"]} {
        #item 728
        set var [ dict get $condition "variable" ]
        #item 729
        if {$var == "del_list"} {
            #item 731
            a "foreach \(IDelRecord item in deletion_list\) \{" $indent
            #item 733
            render_action $body "    $indent" $class
            #item 732
            a "\}" $indent
        } else {
            
        }
    } else {
        #item 734
        if {[dict exists $condition "field"]} {
            #item 737
            set field [ dict get $condition "field" ]
            set field_name [ tab::get_field_name $field ]
            set type [ field_type $field ]
            #item 741
            a "length = obj_list_length\(record->$field_name\);" $indent
            a "for \(i = 0; i < length; i++\) \{" $indent
            a "    _that_ = obj_list_get\(record->$field_name, i\);" $indent
            #item 740
            render_action $body "    $indent" $class
            #item 739
            a "\}" $indent
        } else {
            
        }
    }
}

proc render_if { items indent class } {
    #item 708
    set condition [ dict get $items "if" ]
    set then [ dict get $items "then" ]
    #item 709
    if {[dict exists $condition "is_not_deleted"]} {
        #item 713
        set field [ dict get $condition "is_not_deleted" ]
        set target [ dict get $condition "target" ]
        check_target_not_deleted $field $target $indent
    } else {
        #item 716
        if {[dict exists $condition "field_not_null"]} {
            #item 718
            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 \( record->$field_name != 0 \) \{" $indent
        } else {
            #item 712
            error "Unexpected condition: $condition"
        }
    }
    #item 714
    render_action $then "    $indent" $class
    #item 715
    a "\}" $indent
}

proc render_list { items indent class } {
    foreach item $items {
        #item 684
        set type [ lindex $item 0 ]
        #item 6850001
        if {$type == "action"} {
            #item 693
            render_action $item $indent $class
        } else {
            #item 6850002
            if {$type == "if"} {
                #item 694
                render_if $item $indent $class
            } else {
                #item 6850003
                if {$type == "foreach"} {
                    
                } else {
                    #item 6850004
                    error "Unexpected switch value: $type"
                }
                #item 695
                render_foreach $item $indent $class
            }
        }
    }
}

proc replace { item indent class } {
    #item 496
    set class [ dict get $item "class" ]
    set field [ dict get $item "field" ]
    #item 499
    set field_name [ tab::get_field_name $field ]
    set link [ tab::get_field2_link $field ]
    #item 2166
    lassign \
    [get_field_hints $field] \
    get set cget ctr own
    #item 2168
    set that "new_value"
    #item 2169
    if {$own} {
        #item 2174
        set type [ field_type $field ]
        set stype [ strip_star $type ]
        #item 2173
        a "if \(_record_->$field_name\) \{" $indent
        a "    ${stype}_destroy\(_record_->$field_name\);" $indent
        a "\}" $indent
    } else {
        
    }
    #item 2172
    a "_record_->$field_name = $that;" $indent
}

proc strip_star { type } {
    #item 1577
    return [ string map { "*" "" } $type ]
}

proc vars_m2m { class } {
    #item 2446
    set vars {}
    #item 2435
    set fields [ tab::get_class_fields $class ]
    foreach field $fields {
        #item 2439
        set link [ tab::get_field2_link $field ]
        set link_type [ tab::get_link_type $link ]
        set own [ tab::get_link_ownership $link ]
        #item 2442
        if {$link_type == "m2m"} {
            #item 2453
            lappend vars $field
        } else {
            
        }
    }
    #item 2457
    if {$vars == {}} {
        
    } else {
        #item 2460
        a "    int i, length;"
        a "    void* _that_;"
        foreach field $vars {
            #item 2463
            set type [ field_type $field ]
            set field_name [ tab::get_field_name $field ]
            #item 2464
            a "    $type _that_$field_name;"
        }
    }
}

}
