/*===================================== * llrpt_writefam -- Write family to database * usage: writefam(FAM) -> BOOLEAN *===================================*/ PVALUE llrpt_writefam (PNODE node, SYMTAB stab, BOOLEAN *eflg) { NODE fam1; NODE fam2 = eval_fam(iargs(node), stab, eflg, NULL); STRING rawrec=0, msg; INT len, cnt; BOOLEAN rtn=FALSE; if (*eflg) return NULL; /* make a copy, so we can delete it */ fam2 = copy_node_subtree(fam2); /* get existing record */ rawrec = retrieve_raw_record(rmvat(nxref(fam2)), &len); if (!rawrec) { /* TODO: What do we do here ? Are they adding a new fam ? or did they get the xref wrong ? */ goto end_writefam; } ASSERT(fam1 = string_to_node(rawrec)); cnt = resolve_refn_links(fam2); /* validate for showstopper errors */ if (!valid_fam_tree(fam2, &msg, fam1)) { /* TODO: What to do with msg ? */ goto end_writefam; } if (cnt > 0) { /* unresolvable refn links */ /* TODO: optional argument to make this fatal ? */ } if (equal_tree(fam1, fam2)) { /* optimization :) */ rtn = TRUE; goto end_writefam; } if (readonly) { /* TODO: database is read only error message */ goto end_writefam; } replace_fam(fam1, fam2); strfree(&rawrec); rtn = TRUE; end_writefam: return create_pvalue_from_bool(rtn); }
/*===================================== * process_fam -- process indi record * checking in pass 1, fixing in pass 2 *===================================*/ static void process_fam (RECORD rec) { NODE fam0, fam1; NODE fref1, husb1, wife1, chil1, rest1; NODE node1; INT members = 0; BOOLEAN altered=FALSE; BOOLEAN needfix=FALSE; CNSTRING key = nzkey(rec); fam0 = nztop(rec); if (todo.pass==1) { fam1 = fam0; } else { fam1 = copy_node_subtree(fam0); } split_fam(fam1, &fref1, &husb1, &wife1, &chil1, &rest1); /* check refns */ for (node1 = fref1; node1; node1 = nsibling(node1)) { /* STRING refn=nval(node1); */ /* TO DO: verify that refn is in db */ } /* check husbs */ for (node1 = husb1; node1; node1 = nsibling(node1)) { STRING husbkey=rmvat(nval(node1)); NODE husb = qkey_to_indi(husbkey); members++; if (!husb) { if (todo.pass == 1) { report_error(ERR_BADHUSBREF , _("Bad HUSB reference (%s) in family %s") , husbkey, key); needfix=TRUE; } else { if (fix_bad_pointer(key, rec, node1)) { report_fix(ERR_BADHUSBREF , _("Fixed Bad HUSB reference (%s) in family %s") , husbkey, key); altered=TRUE; } } } else { /* look for family (key) in husb */ if (!find_xref(key, husb, "FAMS", NULL)) { report_error(ERR_EXTRAHUSB , _("Improper HUSB (%s) in family (%s)") , husbkey, key); } } } /* check wives */ for (node1 = wife1; node1; node1 = nsibling(node1)) { STRING wifekey=rmvat(nval(node1)); NODE wife = qkey_to_indi(wifekey); members++; if (!wife) { if (todo.pass == 1) { report_error(ERR_BADWIFEREF , _("Bad wife reference (%s) in family %s") , wifekey, key); needfix=TRUE; } else { if (fix_bad_pointer(key, rec, node1)) { report_fix(ERR_BADWIFEREF , _("Fixed Bad wife reference (%s) in family %s") , printkey(wifekey), key); altered=TRUE; } } } else { /* look for family (key) in wife */ if (!find_xref(key, wife, "FAMS", NULL)) { report_error(ERR_EXTRAWIFE , _("Improper wife (%s) in family (%s)") , printkey(wifekey), key); } } } /* check children */ for (node1 = chil1; node1; node1 = nsibling(node1)) { STRING chilkey=rmvat(nval(node1)); NODE child = qkey_to_indi(chilkey); members++; if (!child) { if (todo.pass == 1) { report_error(ERR_BADCHILDREF , _("Bad child reference (%s) in family %s") , printkey(chilkey), key); needfix=TRUE; } else { if (fix_bad_pointer(key, rec, node1)) { report_fix(ERR_BADCHILDREF , _("Fixed bad child reference (%s) in family %s") , printkey(chilkey), key); altered=TRUE; } } } else { /* look for family (key) in child */ if (!find_xref(key, child, "FAMC", NULL)) { report_error(ERR_EXTRACHILD , _("Improper child: Child (%s) without FAMC reference to family (%s)") , printkey(chilkey), key); } } } join_fam(fam1, fref1, husb1, wife1, chil1, rest1); /* check for undersized family */ if (!members) { report_error(ERR_EMPTYFAM, _("Empty family (%s)"), key); } else if (members == 1) { report_error(ERR_SOLOFAM, _("Single person family (%s)"), key); } if (altered) { /* must normalize, as some lineage references may have been altered to non-lineage tags to fix broken pointers */ normalize_fam(fam1); /* write to database */ replace_fam(fam0, fam1); } else if (needfix) { enqueue_list(tofix, strsave(key)); } }