Project

General

Profile

« Previous | Next » 

Revision 48

Refactored db_xml.py's db insertion function to avoid extra nested functions

View differences:

scripts/lib/db_xml.py
31 31
                elif child_name == name: return child
32 32
    return None
33 33

  
34
def get(db, node, create=False, store_ids=False, row_ct_ref=None, pkeys=None):
34
def put(db, node, store_ids=False, row_ct_ref=None, pkeys=None, parent_id=None):
35 35
    # store_ids enables searching the tree for missing fields
36 36
    if pkeys == None: pkeys = {}
37 37
    def pkey(table):
38 38
        if table not in pkeys: pkeys[table] = sql.pkey(db, table)
39 39
        return pkeys[table]
40 40
    
41
    def obj(node, parent_id=None):
42
        table = name_of(node)
43
        pkey_ = pkey(table)
44
        row = {}
45
        children = []
46
        
47
        # Divide children into fields and children with fkeys to parent
48
        for child in xml_dom.NodeElemIter(node):
49
            child_name = name_of(child)
50
            if xml_dom.is_text(child): row[child_name] = xml_dom.value(child)
51
            elif is_ptr(child_name): row[child_name] = obj(ptr_target(child))
52
            else: children.append(child)
53
        try: del row[pkey_]
54
        except KeyError: pass
55
        
56
        # Add fkey to parent
57
        if parent_id != None: row[pkey(name_of(node.parentNode))] = parent_id
58
        
59
        # Insert node
60
        for try_num in range(2):
61
            try:
62
                id_ = sql.get(db, table, row, pkey_, create, row_ct_ref)
63
                if store_ids: xml_dom.set_id(node, id_)
64
                break
65
            except sql.NullValueException, ex:
66
                if try_num > 0: raise # exception still raised after retry
67
                # Search for required column in ancestors and their children
68
                target = find_by_name(node, ptr_type(ex.col))
69
                if target == None: raise
70
                row[ex.col] = xml_dom.get_id(target)
71
        
72
        # Insert children with fkeys to parent
73
        for child in children: obj(child, id_)
74
        
75
        return id_
41
    table = name_of(node)
42
    pkey_ = pkey(table)
43
    row = {}
44
    children = []
76 45
    
77
    return obj(node)
46
    # Divide children into fields and children with fkeys to parent
47
    for child in xml_dom.NodeElemIter(node):
48
        child_name = name_of(child)
49
        if xml_dom.is_text(child): row[child_name] = xml_dom.value(child)
50
        elif is_ptr(child_name): row[child_name] = put(db, ptr_target(child),
51
            store_ids, row_ct_ref, pkeys)
52
        else: children.append(child)
53
    try: del row[pkey_]
54
    except KeyError: pass
55
    
56
    # Add fkey to parent
57
    if parent_id != None: row[pkey(name_of(node.parentNode))] = parent_id
58
    
59
    # Insert node
60
    for try_num in range(2):
61
        try:
62
            id_ = sql.get(db, table, row, pkey_, True, row_ct_ref)
63
            if store_ids: xml_dom.set_id(node, id_)
64
            break
65
        except sql.NullValueException, ex:
66
            if try_num > 0: raise # exception still raised after retry
67
            # Search for required column in ancestors and their children
68
            target = find_by_name(node, ptr_type(ex.col))
69
            if target == None: raise
70
            row[ex.col] = xml_dom.get_id(target)
71
    
72
    # Insert children with fkeys to parent
73
    for child in children: put(db, child, store_ids, row_ct_ref, pkeys, id_)
74
    
75
    return id_
78 76

  
79 77
def xml2db(db, node, row_ct_ref=None):
80
    for child in xml_dom.NodeElemIter(node):
81
        if not xml_dom.is_text(child): # not XML metadata
82
            get(db, child, True, True, row_ct_ref)
78
    iter_ = xml_dom.NodeElemIter(node)
79
    while xml_dom.is_text(iter_.curr()): iter_.next() # skip metadata
80
    for child in iter_: put(db, child, True, row_ct_ref)

Also available in: Unified diff