Project

General

Profile

« Previous | Next » 

Revision 2177

db_xml.py: put_table(): Support children with fkeys to parent

View differences:

lib/db_xml.py
125 125
    
126 126
    def __str__(self): return self.name
127 127

  
128
input_col_prefix = '$'
129

  
128 130
def put_table(db, node, in_table, in_schema=None, commit=False,
129
    row_ct_ref=None):
131
    row_ct_ref=None, parent_ids_loc=None):
130 132
    '''
131 133
    @param node The XML tree that transforms the input to the output. Similar to
132
        put()'s node param, but with the input column name prefixed by "$" in
133
        place of the column value.
134
        put()'s node param, but with the input column name prefixed by
135
        input_col_prefix in place of the column value.
134 136
    @param commit Whether to commit after each query
135 137
    @return (table, col) Where the pkeys (from INSERT RETURNING) are made
136 138
        available
......
139 141
    def qual_name(table): return sql.qual_name(db, in_schema, table)
140 142
    def pkey(table): return sql.pkey(db, table, True)
141 143
    
142
    def put_table_(node):
143
        return put_table(db, node, in_table, in_schema, commit, row_ct_ref)
144
    def put_table_(node, parent_ids_loc=None):
145
        return put_table(db, node, in_table, in_schema, commit, row_ct_ref,
146
            parent_ids_loc)
144 147
    
145 148
    out_table = name_of(node)
146 149
    row = {}
147 150
    children = []
148
    in_tables = [qual_name(in_table)]
149 151
    
150 152
    # Divide children into fields and children with fkeys to parent
151 153
    for child in xml_dom.NodeElemIter(node):
......
161 163
    try: del row[pkey(out_table)]
162 164
    except KeyError: pass
163 165
    
166
    # Add fkey to parent
167
    if parent_ids_loc != None:
168
        parent_ptr = node.getAttribute('fkey')
169
        if parent_ptr == '': parent_ptr = pkey(name_of(node.parentNode))
170
        row[parent_ptr] = parent_ids_loc
171
    
164 172
    # Divide fields into input columns and literal values
173
    in_tables = [qual_name(in_table)]
165 174
    for out_col, value in row.iteritems():
166
        if isinstance(value, tuple): in_tables.append(value[0])
167
        else:
168
            in_col = strings.remove_prefix('$', value)
169
            if in_col != value: row[out_col] = in_col # value is input column
170
            else: row[out_col] = (value,) # value is literal value
175
        if isinstance(value, tuple): # value is temp table column
176
            in_tables.append(value[0])
177
        elif util.is_str(value) and value.startswith(input_col_prefix):
178
            # value is input column
179
            row[out_col] = strings.remove_prefix(input_col_prefix, value)
180
        else: # value is literal value; should only be string or None
181
            assert util.is_str(value) or value == None
182
            row[out_col] = (value,) # value is literal value
171 183
    
172 184
    # Insert node
173 185
    pkeys_loc = sql.put_table(db, esc_name(out_table), in_tables, row,
174 186
        row_ct_ref=row_ct_ref, table_is_esc=True)
175 187
    
188
    # Insert children with fkeys to parent
189
    for child in children: put_table_(child, pkeys_loc)
190
    
176 191
    if commit: db.db.commit()
177 192
    return pkeys_loc

Also available in: Unified diff