misc/migration/3.11.0_Any.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 21 Jan 2014 17:34:31 +0100
changeset 9445 65d93a4fd11c
parent 8696 0bb18407c053
child 9450 af4b93bc38a5
permissions -rw-r--r--
[multi-sources-removal] Drop pyrorql and zmqrql sources After a few years experementing "true" multi-sources, we're now moving to "copy-based" source à la datafeed. As pyro and zmq sources have no more known customers and the related code is in the way of future refactoring of cubicweb's core, we decided to drop support for those sources without backward compatibility. If you're still using a zmqrql or pyrorql source and you want to upgrade, ask support to move it to datafeed using a pre-3.19 version first. Related to #2919300 (first step)

from datetime import datetime

for rtype in ('cw_support', 'cw_dont_cross', 'cw_may_cross'):
    drop_relation_type(rtype)

add_entity_type('CWSourceSchemaConfig')

if not 'url' in schema['CWSource'].subjrels:
    add_attribute('CWSource', 'url')
    add_attribute('CWSource', 'parser')
    add_attribute('CWSource', 'latest_retrieval')

try:
    from cubicweb.server.sources.pyrorql import PyroRQLSource
except ImportError:
    pass
else:

    from os.path import join
    # function to read old python mapping file
    def load_mapping_file(source):
        mappingfile = source.config['mapping-file']
        mappingfile = join(source.repo.config.apphome, mappingfile)
        mapping = {}
        execfile(mappingfile, mapping)
        for junk in ('__builtins__', '__doc__'):
            mapping.pop(junk, None)
        mapping.setdefault('support_relations', {})
        mapping.setdefault('dont_cross_relations', set())
        mapping.setdefault('cross_relations', set())
        # do some basic checks of the mapping content
        assert 'support_entities' in mapping, \
               'mapping file should at least define support_entities'
        assert isinstance(mapping['support_entities'], dict)
        assert isinstance(mapping['support_relations'], dict)
        assert isinstance(mapping['dont_cross_relations'], set)
        assert isinstance(mapping['cross_relations'], set)
        unknown = set(mapping) - set( ('support_entities', 'support_relations',
                                       'dont_cross_relations', 'cross_relations') )
        assert not unknown, 'unknown mapping attribute(s): %s' % unknown
        # relations that are necessarily not crossed
        for rtype in ('is', 'is_instance_of', 'cw_source'):
            assert rtype not in mapping['dont_cross_relations'], \
                   '%s relation should not be in dont_cross_relations' % rtype
            assert rtype not in mapping['support_relations'], \
                   '%s relation should not be in support_relations' % rtype
        return mapping
    # for now, only pyrorql sources have a mapping
    for source in repo.sources_by_uri.itervalues():
        if not isinstance(source, PyroRQLSource):
            continue
        sourceentity = session.entity_from_eid(source.eid)
        mapping = load_mapping_file(source)
        # write mapping as entities
        print 'migrating map for', source
        for etype, write in mapping['support_entities'].items():
            create_entity('CWSourceSchemaConfig',
                          cw_for_source=sourceentity,
                          cw_schema=session.entity_from_eid(schema[etype].eid),
                          options=write and u'write' or None,
                          ask_confirm=False)
        for rtype, write in mapping['support_relations'].items():
            options = []
            if write:
                options.append(u'write')
            if rtype in mapping['cross_relations']:
                options.append(u'maycross')
            create_entity('CWSourceSchemaConfig',
                          cw_for_source=sourceentity,
                          cw_schema=session.entity_from_eid(schema[rtype].eid),
                          options=u':'.join(options) or None,
                          ask_confirm=False)
        for rtype in mapping['dont_cross_relations']:
            create_entity('CWSourceSchemaConfig',
                          cw_for_source=source,
                          cw_schema=session.entity_from_eid(schema[rtype].eid),
                          options=u'dontcross',
                          ask_confirm=False)
        # latest update time cwproperty is now a source attribute (latest_retrieval)
        pkey = u'sources.%s.latest-update-time' % source.uri
        rset = session.execute('Any V WHERE X is CWProperty, X value V, X pkey %(k)s',
                               {'k': pkey})
        timestamp = int(rset[0][0])
        sourceentity.cw_set(latest_retrieval=datetime.fromtimestamp(timestamp))
        session.execute('DELETE CWProperty X WHERE X pkey %(k)s', {'k': pkey})