def migrate_measures(site):
    migrated = 0
    all_count = 0
    prior_incomplete = premigrate_incomplete_measures(site)  # UIDs incomplete
    q = {'portal_type': MEASURE_DEFINITION_TYPE}
    for brain in _search(site, q):
        measure = _get(brain)
        group = measure.__parent__
        if group.source_type == 'uu.formlibrary.simpleform':
            continue  # ignore SimpleForm-based measure, no queries to migrate
        migrated += migrate_measure(measure)
        all_count += 1
    print 'Migrated %s measures from legacy RecordFilter(s), of %s' % (
        migrated,
        all_count,
        )
    print 'Cleaning up remaining legacy RecordFilter entries from catalog'
    incomplete_cleanups(site)
    # VERIFY / assertions:
    # 1. NO RecordFilter content cataloged any more:
    q = {'portal_type': 'uu.formlibrary.recordfilter'}
    assert len(_search(site, q)) == 0
    # 2. For all measures, things look good:
    q = {'portal_type': MEASURE_DEFINITION_TYPE}
    for brain in _search(site, q):
        measure = _get(brain)
        schema = IFormDefinition(measure).schema
        group = measure.__parent__
        if group.source_type == 'uu.formlibrary.simpleform':
            continue  # ignore SimpleForm-based measure, no queries to migrate
        # 2.a. NO _tree; since MeasureDefinition
        # is not subclasing plone.dexterity.content.Container any more
        # in favor of Item, we need to directly access tree:
        try:
            assert getattr(aq_base(measure), '_tree', None) is None
        except AssertionError:
            # likely a tree with no filters, so clean up here:
            assert len(aq_base(measure)._tree) == 0
            delattr(aq_base(measure), '_tree')
        # 2.b. IComposedQuery for measure configuration looks okay, for
        # numerator, denominator as configured.
        if group.source_type == 'uu.formlibrary.simpleform':
            continue  # ignore SimpleForm-based measures, no queries!
        else:
            # get whether num, den...
            # build query for each:
            # assert is_query_complete(q.build())
            adapter = lambda name: queryAdapter(measure, IComposedQuery, name)
            if IUUID(measure) not in prior_incomplete:
                if measure.numerator_type == 'multi_filter':
                    composed = adapter(u'numerator')
                    assert is_query_complete(composed.build(schema))
                if measure.denominator_type == 'multi_filter':
                    composed = adapter(u'denominator')
                    assert is_query_complete(composed.build(schema))
def prior_incomplete_measure(measure):
    group = measure.__parent__
    schema = IFormDefinition(measure).schema
    if group.source_type == 'uu.formlibrary.simpleform':
        return False  # ignore SimpleForm-based measures, no queries!
    if measure.numerator_type == 'multi_filter':
        rfilter = premigrate_filter(measure, 'numerator')
        if rfilter is None or not is_query_complete(rfilter.build(schema)):
            return True
    if measure.denominator_type == 'multi_filter':
        rfilter = premigrate_filter(measure, 'denominator')
        if rfilter is None or not is_query_complete(rfilter.build(schema)):
            return True
    return False
def verify_filter(source, destination, schema):
    assert is_query_complete(destination.build(schema))
    assert len(source) == len(destination)
    for fieldname in source.keys():
        q1, q2 = source[fieldname], destination[fieldname]
        assert q1.fieldname == q1.fieldname
        assert q1.comparator == q2.comparator
        assert q1.value == q2.value
        assert source.operator == destination.operator