示例#1
0
/*=====================================
 * 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);
}
示例#2
0
/*=====================================
 * 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));
    }
}