Revision 3647
Added by Aaron Marcuse-Kubitza over 12 years ago
db_xml.py | ||
---|---|---|
63 | 63 |
|
64 | 64 |
def put(db, node, row_ct_ref=None, on_error=exc.raise_, pool=None, |
65 | 65 |
store_ids=False, parent_id=None): |
66 |
'''store_ids enables searching the tree for missing fields''' |
|
67 |
def pkey(table): return sql.pkey(db, table, True) |
|
68 |
|
|
69 |
def put_(node, parent_id=None): |
|
70 |
args = (db, node, row_ct_ref, on_error, pool, store_ids, parent_id) |
|
71 |
if parent_id != None and pool != None: pool.apply_async(put, args) |
|
72 |
else: return put(*args) |
|
73 |
|
|
74 |
def on_error_(e): |
|
75 |
exc.add_msg(e, 'node:\n'+str(node)) |
|
76 |
on_error(e) |
|
77 |
|
|
78 |
table = name_of(node) |
|
79 |
try: pkey_ = pkey(table) |
|
80 |
except sql.DatabaseErrors, e: on_error_(e); return None |
|
81 |
row = {} |
|
82 |
children = [] |
|
83 |
|
|
84 |
# Divide children into fields and children with fkeys to parent |
|
85 |
for child in xml_dom.NodeElemIter(node): |
|
86 |
child_name = name_of(child) |
|
87 |
if xml_dom.is_empty(child): row[child_name] = None |
|
88 |
elif xml_dom.is_text(child): |
|
89 |
row[child_name] = strings.to_unicode(xml_dom.value(child)) |
|
90 |
elif is_ptr(child_name): row[child_name] = put_(ptr_target(child)) |
|
91 |
else: children.append(child) |
|
92 |
|
|
93 |
# Add fkey to parent |
|
94 |
if parent_id != None: |
|
95 |
parent_ptr = node.getAttribute('fkey') |
|
96 |
if parent_ptr == '': parent_ptr = pkey(name_of(node.parentNode)) |
|
97 |
row[parent_ptr] = parent_id |
|
98 |
|
|
99 |
# Insert node |
|
100 |
try: |
|
101 |
for try_num in xrange(2): |
|
102 |
try: |
|
103 |
id_ = sql_io.put(db, table, row, pkey_, row_ct_ref) |
|
104 |
if store_ids: xml_dom.set_id(node, id_) |
|
105 |
break |
|
106 |
except sql.NullValueException, e: |
|
107 |
col = e.cols[0] |
|
108 |
if try_num > 0: raise # exception still raised after retry |
|
109 |
if store_ids and is_ptr(col): |
|
110 |
# Search for required column in ancestors and their children |
|
111 |
target = find_by_name(node, ptr_type_guess(col)) |
|
112 |
if target == None: raise |
|
113 |
row[col] = xml_dom.get_id(target) |
|
114 |
else: raise |
|
115 |
except sql.DatabaseErrors, e: on_error_(e); return None |
|
116 |
|
|
117 |
# Insert children with fkeys to parent |
|
118 |
for child in children: put_(child, id_) |
|
119 |
|
|
120 |
return id_ |
|
66 |
return _put_table_part(db, node, None, row_ct_ref, on_error) |
|
121 | 67 |
|
122 | 68 |
class ColRef: |
123 | 69 |
'''A reference to a table column''' |
Also available in: Unified diff
db_xml.py: put(): Use _put_table_part(). This will ensure that all the put-related functionality is in one place, rather than duplicated.