cubicweb/dataimport/stores.py
author Denis Laxalde <denis.laxalde@logilab.fr>
Thu, 21 Mar 2019 14:33:54 +0100
changeset 12530 9d88e1177c35
parent 12504 362fdb399ff5
child 12542 85194bd49119
permissions -rw-r--r--
Remove Twisted web server Twisted web server is not used anymore and has been superseded by pyramid many years ago. Furthermore, our usage is not compatible with Python 3. So we drop the "etwist" sub-package. As a consequence, "all-in-one" configuration type gets dropped as it was Twisted-specific. We resurrect it in cubicweb/pyramid/config.py by only keeping options used by the "pyramid". Similarly, we introduce a AllInOneCreateHandler in cubicweb/pyramid/pyramidctl.py that is basically the one that lived in cubicweb/etwist/twctl.py and is used to create the "all-in-one" instance. Added a TODO here about "pyramid.ini" that could be generated at the end of bootstrap() method. In cubicweb/devtools/httptest.py, CubicWebServerTC is now equivalent to CubicWebWsgiTC and the latter is dropped.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11140
fabcd1c6dcd1 [dataimport] cleanup a bit nohook store, mostly protecting some attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
     1
# copyright 2003-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     3
#
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     4
# This file is part of CubicWeb.
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     5
#
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     9
# any later version.
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    10
#
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    14
# details.
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    15
#
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    18
"""
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    19
Stores are responsible to insert properly formatted entities and relations into the database. They
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    20
have the following API::
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    21
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    22
    >>> user_eid = store.prepare_insert_entity('CWUser', login=u'johndoe')
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    23
    >>> group_eid = store.prepare_insert_entity('CWUser', name=u'unknown')
10794
0b4d6beec132 [dataimport] Update doc to reflect new API
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
    24
    >>> store.prepare_insert_relation(user_eid, 'in_group', group_eid)
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    25
    >>> store.flush()
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    26
    >>> store.commit()
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    27
    >>> store.finish()
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    28
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    29
Some store **requires a flush** to copy data in the database, so if you want to have store
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    30
independant code you should explicitly call it. (There may be multiple flushes during the
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    31
process, or only one at the end if there is no memory issue). This is different from the
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    32
commit which validates the database transaction. At last, the `finish()` method should be called in
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    33
case the store requires additional work once everything is done.
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    34
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    35
* ``prepare_insert_entity(<entity type>, **kwargs) -> eid``: given an entity
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    36
  type, attributes and inlined relations, return the eid of the entity to be
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    37
  inserted, *with no guarantee that anything has been inserted in database*,
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    38
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    39
* ``prepare_update_entity(<entity type>, eid, **kwargs) -> None``: given an
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    40
  entity type and eid, promise for update given attributes and inlined
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    41
  relations *with no guarantee that anything has been inserted in database*,
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    42
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    43
* ``prepare_insert_relation(eid_from, rtype, eid_to) -> None``: indicate that a
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    44
  relation ``rtype`` should be added between entities with eids ``eid_from``
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    45
  and ``eid_to``. Similar to ``prepare_insert_entity()``, *there is no
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    46
  guarantee that the relation will be inserted in database*,
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    47
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    48
* ``flush() -> None``: flush any temporary data to database. May be called
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    49
  several times during an import,
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    50
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    51
* ``commit() -> None``: commit the database transaction,
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    52
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    53
* ``finish() -> None``: additional stuff to do after import is terminated.
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    54
11749
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    55
.. autoclass:: cubicweb.dataimport.stores.NullStore
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    56
.. autoclass:: cubicweb.dataimport.stores.RQLObjectStore
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    57
.. autoclass:: cubicweb.dataimport.stores.NoHookRQLObjectStore
11309
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
    58
.. autoclass:: cubicweb.dataimport.stores.MetadataGenerator
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    59
"""
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    60
import inspect
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    61
import warnings
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    62
from datetime import datetime
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    63
from copy import copy
11749
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    64
from itertools import count
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    65
11811
f09efeead7f9 Fix broken flake8 configuration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11780
diff changeset
    66
from six import add_metaclass
10809
359cbdf3a515 [dataimport] extid must be a bytes object
Julien Cristau <julien.cristau@logilab.fr>
parents: 10794
diff changeset
    67
11308
df75fe529ba8 [dataimport] Prefer now(pytz.utc) to utcnow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11307
diff changeset
    68
import pytz
df75fe529ba8 [dataimport] Prefer now(pytz.utc) to utcnow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11307
diff changeset
    69
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    70
from logilab.common.decorators import cached
12504
362fdb399ff5 Drop deprecated code in cubicweb.dataimport
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12021
diff changeset
    71
from logilab.common.deprecation import class_deprecated
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    72
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    73
from cubicweb.schema import META_RTYPES, VIRTUAL_RTYPES
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    74
from cubicweb.server.edition import EditedEntity
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    75
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    76
11749
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    77
class NullStore(object):
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    78
    """Store that mainly describe the store API.
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    79
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    80
    It may be handy to test input data files or to measure time taken by steps above the store
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    81
    (e.g. data parsing, importer, etc.): simply give a :class:`NullStore` instance instead of the
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    82
    actual store.
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    83
    """
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    84
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    85
    def __init__(self):
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    86
        self._eid_gen = count()
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    87
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    88
    def prepare_insert_entity(self, *args, **kwargs):
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    89
        """Given an entity type, attributes and inlined relations, return the inserted entity's
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    90
        eid.
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    91
        """
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    92
        return next(self._eid_gen)
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    93
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    94
    def prepare_update_entity(self, etype, eid, **kwargs):
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    95
        """Given an entity type and eid, update the corresponding entity with specified attributes
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    96
        and inlined relations.
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    97
        """
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    98
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
    99
    def prepare_insert_relation(self, eid_from, rtype, eid_to, **kwargs):
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   100
        """Insert into the database a  relation ``rtype`` between entities with eids ``eid_from``
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   101
        and ``eid_to``.
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   102
        """
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   103
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   104
    def flush(self):
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   105
        """Flush internal data structures."""
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   106
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   107
    def commit(self):
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   108
        """Commit the database transaction."""
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   109
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   110
    def finish(self):
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   111
        """Import is terminated, do necessary cleanup."""
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   112
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   113
ae9789d77ea0 [dataimport] Add a new NullStore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11309
diff changeset
   114
class RQLObjectStore(NullStore):
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   115
    """Store that works by making RQL queries, hence with all the cubicweb's machinery activated.
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   116
    """
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   117
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   118
    def __init__(self, cnx, commit=None):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   119
        if commit is not None:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   120
            warnings.warn('[3.19] commit argument should not be specified '
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   121
                          'as the cnx object already provides it.',
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   122
                          DeprecationWarning, stacklevel=2)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   123
        self._cnx = cnx
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   124
        self._commit = commit or cnx.commit
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   125
        # XXX 3.21 deprecated attributes
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   126
        self.eids = {}
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   127
        self.types = {}
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   128
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   129
    def rql(self, *args):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   130
        """Execute a RQL query. This is NOT part of the store API."""
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   131
        return self._cnx.execute(*args)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   132
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   133
    def prepare_insert_entity(self, *args, **kwargs):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   134
        entity = self._cnx.create_entity(*args, **kwargs)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   135
        self.eids[entity.eid] = entity
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   136
        self.types.setdefault(args[0], []).append(entity.eid)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   137
        return entity.eid
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   138
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   139
    def prepare_update_entity(self, etype, eid, **kwargs):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   140
        entity = self._cnx.entity_from_eid(eid)
10939
b30c2f49da57 [dataimport] Format strings with % instead of .format()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 10907
diff changeset
   141
        assert entity.cw_etype == etype, 'Trying to update with wrong type %s' % etype
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   142
        # XXX some inlined relations may already exists
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   143
        entity.cw_set(**kwargs)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   144
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   145
    def prepare_insert_relation(self, eid_from, rtype, eid_to, **kwargs):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   146
        self.rql('SET X %s Y WHERE X eid %%(x)s, Y eid %%(y)s' % rtype,
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   147
                 {'x': int(eid_from), 'y': int(eid_to)})
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   148
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   149
    def commit(self):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   150
        return self._commit()
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   151
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   152
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   153
class NoHookRQLObjectStore(RQLObjectStore):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   154
    """Store that works by accessing low-level CubicWeb's source API, with all hooks deactivated. It
11307
74f5814ecdf0 [dataimport] rename nohook store .source attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11304
diff changeset
   155
    may be given a metadata generator object to handle metadata which are usually handled by hooks.
74f5814ecdf0 [dataimport] rename nohook store .source attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11304
diff changeset
   156
74f5814ecdf0 [dataimport] rename nohook store .source attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11304
diff changeset
   157
    Arguments:
74f5814ecdf0 [dataimport] rename nohook store .source attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11304
diff changeset
   158
    - `cnx`, a connection to the repository
11309
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   159
    - `metagen`, optional :class:`MetadataGenerator` instance
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   160
    """
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   161
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   162
    def __init__(self, cnx, metagen=None):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   163
        super(NoHookRQLObjectStore, self).__init__(cnx)
11309
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   164
        if metagen is None:
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   165
            metagen = MetadataGenerator(cnx)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   166
        if isinstance(metagen, MetadataGenerator):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   167
            metagen = _MetaGeneratorBWCompatWrapper(metagen)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   168
        self.metagen = metagen
11307
74f5814ecdf0 [dataimport] rename nohook store .source attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11304
diff changeset
   169
        self._system_source = cnx.repo.system_source
11140
fabcd1c6dcd1 [dataimport] cleanup a bit nohook store, mostly protecting some attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   170
        self._rschema = cnx.repo.schema.rschema
11309
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   171
        self._create_eid = self._system_source.create_eid
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   172
        self._add_relation = self._system_source.add_relation
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   173
        self._nb_inserted_entities = 0
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   174
        self._nb_inserted_types = 0
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   175
        self._nb_inserted_relations = 0
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   176
        # deactivate security
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   177
        cnx.read_security = False
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   178
        cnx.write_security = False
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   179
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   180
    def prepare_insert_entity(self, etype, **kwargs):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   181
        """Given an entity type, attributes and inlined relations, returns the inserted entity's
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   182
        eid.
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   183
        """
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10513
diff changeset
   184
        for k, v in kwargs.items():
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   185
            kwargs[k] = getattr(v, 'eid', v)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   186
        entity, rels = self.metagen.base_etype_dicts(etype)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   187
        # make a copy to keep cached entity pristine
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   188
        entity = copy(entity)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   189
        entity.cw_edited = copy(entity.cw_edited)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   190
        entity.cw_clear_relation_cache()
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   191
        entity.cw_edited.update(kwargs, skipsec=False)
11304
1dad60d54dfb [dataimport] move eid attribution from the metagenerator back to the nohook store
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11303
diff changeset
   192
        cnx = self._cnx
1dad60d54dfb [dataimport] move eid attribution from the metagenerator back to the nohook store
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11303
diff changeset
   193
        entity.eid = self._create_eid(cnx)
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11749
diff changeset
   194
        entity_source = self.metagen.init_entity(entity)
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11749
diff changeset
   195
        self._system_source.add_info(cnx, entity, entity_source)
11307
74f5814ecdf0 [dataimport] rename nohook store .source attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11304
diff changeset
   196
        self._system_source.add_entity(cnx, entity)
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   197
        kwargs = dict()
11140
fabcd1c6dcd1 [dataimport] cleanup a bit nohook store, mostly protecting some attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   198
        if inspect.getargspec(self._add_relation).keywords:
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   199
            kwargs['subjtype'] = entity.cw_etype
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10513
diff changeset
   200
        for rtype, targeteids in rels.items():
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   201
            # targeteids may be a single eid or a list of eids
11140
fabcd1c6dcd1 [dataimport] cleanup a bit nohook store, mostly protecting some attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   202
            inlined = self._rschema(rtype).inlined
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   203
            try:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   204
                for targeteid in targeteids:
11140
fabcd1c6dcd1 [dataimport] cleanup a bit nohook store, mostly protecting some attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   205
                    self._add_relation(cnx, entity.eid, rtype, targeteid,
fabcd1c6dcd1 [dataimport] cleanup a bit nohook store, mostly protecting some attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   206
                                       inlined, **kwargs)
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   207
            except TypeError:
11140
fabcd1c6dcd1 [dataimport] cleanup a bit nohook store, mostly protecting some attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   208
                self._add_relation(cnx, entity.eid, rtype, targeteids,
fabcd1c6dcd1 [dataimport] cleanup a bit nohook store, mostly protecting some attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   209
                                   inlined, **kwargs)
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   210
        self._nb_inserted_entities += 1
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   211
        return entity.eid
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   212
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   213
    # XXX: prepare_update_entity is inherited from RQLObjectStore, it should be reimplemented to
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   214
    # actually skip hooks as prepare_insert_entity
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   215
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   216
    def prepare_insert_relation(self, eid_from, rtype, eid_to, **kwargs):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   217
        """Insert into the database a  relation ``rtype`` between entities with eids ``eid_from``
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   218
        and ``eid_to``.
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   219
        """
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   220
        assert not rtype.startswith('reverse_')
11140
fabcd1c6dcd1 [dataimport] cleanup a bit nohook store, mostly protecting some attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   221
        rschema = self._rschema(rtype)
fabcd1c6dcd1 [dataimport] cleanup a bit nohook store, mostly protecting some attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   222
        self._add_relation(self._cnx, eid_from, rtype, eid_to, rschema.inlined)
fabcd1c6dcd1 [dataimport] cleanup a bit nohook store, mostly protecting some attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   223
        if rschema.symmetric:
fabcd1c6dcd1 [dataimport] cleanup a bit nohook store, mostly protecting some attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   224
            self._add_relation(self._cnx, eid_to, rtype, eid_from, rschema.inlined)
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   225
        self._nb_inserted_relations += 1
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   226
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   227
11309
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   228
class MetadataGenerator(object):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   229
    """Class responsible for generating standard metadata for imported entities. You may want to
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   230
    derive it to add application specific's metadata. This class (or a subclass) may either be
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   231
    given to a nohook or massive store.
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   232
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   233
    Parameters:
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   234
    * `cnx`: connection to the repository
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   235
    * `baseurl`: optional base URL to be used for `cwuri` generation - default to config['base-url']
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   236
    * `source`: optional source to be used as `cw_source` for imported entities
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   237
    """
11779
9a3663ec4ead [dataimport] make MetadataGenerator.META_RELATIONS customizable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 11774
diff changeset
   238
    META_RELATIONS = frozenset(META_RTYPES
9a3663ec4ead [dataimport] make MetadataGenerator.META_RELATIONS customizable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 11774
diff changeset
   239
                               - VIRTUAL_RTYPES
9a3663ec4ead [dataimport] make MetadataGenerator.META_RELATIONS customizable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 11774
diff changeset
   240
                               - set(('eid', 'cwuri',
9a3663ec4ead [dataimport] make MetadataGenerator.META_RELATIONS customizable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 11774
diff changeset
   241
                                      'is', 'is_instance_of', 'cw_source')))
11309
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   242
11779
9a3663ec4ead [dataimport] make MetadataGenerator.META_RELATIONS customizable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 11774
diff changeset
   243
    def __init__(self, cnx, baseurl=None, source=None, meta_skipped=()):
11309
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   244
        self._cnx = cnx
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   245
        if baseurl is None:
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   246
            config = cnx.vreg.config
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   247
            baseurl = config['base-url'] or config.default_base_url()
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   248
        if not baseurl[-1] == '/':
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   249
            baseurl += '/'
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   250
        self._baseurl = baseurl
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   251
        if source is None:
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   252
            source = cnx.repo.system_source
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   253
        self.source = source
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   254
        self._now = datetime.now(pytz.utc)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   255
        # attributes/relations shared by all entities of the same type
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   256
        self._etype_attrs = []
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   257
        self._etype_rels = []
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   258
        # attributes/relations specific to each entity
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   259
        self._entity_attrs = ['cwuri']
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   260
        rschema = cnx.vreg.schema.rschema
11779
9a3663ec4ead [dataimport] make MetadataGenerator.META_RELATIONS customizable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 11774
diff changeset
   261
        self.meta_relations = self.META_RELATIONS - set(meta_skipped)
9a3663ec4ead [dataimport] make MetadataGenerator.META_RELATIONS customizable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 11774
diff changeset
   262
        for rtype in self.meta_relations:
11309
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   263
            # skip owned_by / created_by if user is the internal manager
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   264
            if cnx.user.eid == -1 and rtype in ('owned_by', 'created_by'):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   265
                continue
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   266
            if rschema(rtype).final:
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   267
                self._etype_attrs.append(rtype)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   268
            else:
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   269
                self._etype_rels.append(rtype)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   270
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   271
    # etype is provided in the 3 methods below as proven useful to custom implementation but not
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   272
    # used by the default implementation
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   273
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   274
    def etype_attrs(self, etype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   275
        """Return the list of attributes to be set for all entities of the given type."""
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   276
        return self._etype_attrs[:]
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   277
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   278
    def etype_rels(self, etype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   279
        """Return the list of relations to be set for all entities of the given type."""
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   280
        return self._etype_rels[:]
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   281
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   282
    def entity_attrs(self, etype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   283
        """Return the list of attributes whose value is set per instance, not per type, for the
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   284
        given type.
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   285
        """
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   286
        return self._entity_attrs[:]
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   287
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   288
    @cached
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   289
    def base_etype_attrs(self, etype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   290
        """Return a dictionary of attributes to be set for all entities of the given type."""
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   291
        attrs = {}
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   292
        for attr in self.etype_attrs(etype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   293
            genfunc = self._generator(attr)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   294
            if genfunc:
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   295
                attrs[attr] = genfunc(etype)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   296
        return attrs
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   297
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   298
    @cached
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   299
    def base_etype_rels(self, etype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   300
        """Return a dictionary of relations to be set for all entities of the given type."""
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   301
        rels = {}
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   302
        for rel in self.etype_rels(etype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   303
            genfunc = self._generator(rel)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   304
            if genfunc:
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   305
                rels[rel] = genfunc(etype)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   306
        return rels
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   307
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   308
    def init_entity_attrs(self, etype, eid, attrs):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   309
        """Insert into an entity attrs dictionary attributes whose value is set per instance, not per
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   310
        type.
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   311
        """
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   312
        for attr in self.entity_attrs(etype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   313
            if attr in attrs:
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   314
                # already set, skip this attribute
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   315
                continue
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   316
            genfunc = self._generator(attr)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   317
            if genfunc:
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   318
                attrs[attr] = genfunc(etype, eid, attrs)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   319
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   320
    def _generator(self, rtype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   321
        return getattr(self, 'gen_%s' % rtype, None)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   322
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   323
    def gen_cwuri(self, etype, eid, attrs):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   324
        assert self._baseurl, 'baseurl is None while generating cwuri'
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   325
        return u'%s%s' % (self._baseurl, eid)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   326
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   327
    def gen_creation_date(self, etype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   328
        return self._now
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   329
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   330
    def gen_modification_date(self, etype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   331
        return self._now
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   332
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   333
    def gen_created_by(self, etype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   334
        return self._cnx.user.eid
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   335
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   336
    def gen_owned_by(self, etype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   337
        return self._cnx.user.eid
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   338
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   339
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   340
class _MetaGeneratorBWCompatWrapper(object):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   341
    """Class wrapping a MetadataGenerator to adapt it to the MetaGenerator interface.
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   342
    """
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   343
    META_RELATIONS = (META_RTYPES
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   344
                      - VIRTUAL_RTYPES
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   345
                      - set(('eid', 'cwuri',
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   346
                             'is', 'is_instance_of', 'cw_source')))
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   347
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   348
    def __init__(self, mdgenerator):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   349
        self._mdgen = mdgenerator
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   350
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   351
    @cached
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   352
    def base_etype_dicts(self, etype):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   353
        cnx = self._mdgen._cnx
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   354
        entity = cnx.vreg['etypes'].etype_class(etype)(cnx)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   355
        # entity are "surface" copied, avoid shared dict between copies
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   356
        del entity.cw_extra_kwargs
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   357
        entity.cw_edited = EditedEntity(entity)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   358
        attrs = self._mdgen.base_etype_attrs(etype)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   359
        entity.cw_edited.update(attrs, skipsec=False)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   360
        rels = self._mdgen.base_etype_rels(etype)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   361
        return entity, rels
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   362
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   363
    def init_entity(self, entity):
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   364
        attrs = dict(entity.cw_edited)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   365
        self._mdgen.init_entity_attrs(entity.cw_etype, entity.eid, attrs)
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   366
        entity.cw_edited.update(attrs, skipsec=False)
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11749
diff changeset
   367
        return self._mdgen.source
11309
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   368
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   369
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   370
@add_metaclass(class_deprecated)
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   371
class MetaGenerator(object):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   372
    """Class responsible for generating standard metadata for imported entities. You may want to
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   373
    derive it to add application specific's metadata.
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   374
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   375
    Parameters:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   376
    * `cnx`: connection to the repository
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   377
    * `baseurl`: optional base URL to be used for `cwuri` generation - default to config['base-url']
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   378
    * `source`: optional source to be used as `cw_source` for imported entities
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   379
    """
11309
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   380
    __deprecation_warning__ = '[3.23] this class is deprecated, use MetadataGenerator instead'
31bf3254be69 [dataimport] introduce a new MetadataGenerator to replace former MetaGenerator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11308
diff changeset
   381
11780
307d96c0ab5a [massive store] Follow configuration of the metadata generator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11779
diff changeset
   382
    META_RELATIONS = MetadataGenerator.META_RELATIONS
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   383
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   384
    def __init__(self, cnx, baseurl=None, source=None):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   385
        self._cnx = cnx
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   386
        if baseurl is None:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   387
            config = cnx.vreg.config
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   388
            baseurl = config['base-url'] or config.default_base_url()
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   389
        if not baseurl[-1] == '/':
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   390
            baseurl += '/'
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   391
        self.baseurl = baseurl
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   392
        if source is None:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   393
            source = cnx.repo.system_source
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   394
        self.source = source
11308
df75fe529ba8 [dataimport] Prefer now(pytz.utc) to utcnow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11307
diff changeset
   395
        self._now = datetime.now(pytz.utc)
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   396
        # attributes/relations shared by all entities of the same type
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   397
        self.etype_attrs = []
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   398
        self.etype_rels = []
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   399
        # attributes/relations specific to each entity
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   400
        self.entity_attrs = ['cwuri']
11303
891f3ecdbf7f [dataimport] rephrase minor bits of the meta generator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11142
diff changeset
   401
        rschema = cnx.vreg.schema.rschema
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   402
        for rtype in self.META_RELATIONS:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   403
            # skip owned_by / created_by if user is the internal manager
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   404
            if cnx.user.eid == -1 and rtype in ('owned_by', 'created_by'):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   405
                continue
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   406
            if rschema(rtype).final:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   407
                self.etype_attrs.append(rtype)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   408
            else:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   409
                self.etype_rels.append(rtype)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   410
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   411
    @cached
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   412
    def base_etype_dicts(self, etype):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   413
        entity = self._cnx.vreg['etypes'].etype_class(etype)(self._cnx)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   414
        # entity are "surface" copied, avoid shared dict between copies
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   415
        del entity.cw_extra_kwargs
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   416
        entity.cw_edited = EditedEntity(entity)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   417
        for attr in self.etype_attrs:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   418
            genfunc = self.generate(attr)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   419
            if genfunc:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   420
                entity.cw_edited.edited_attribute(attr, genfunc(entity))
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   421
        rels = {}
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   422
        for rel in self.etype_rels:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   423
            genfunc = self.generate(rel)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   424
            if genfunc:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   425
                rels[rel] = genfunc(entity)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   426
        return entity, rels
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   427
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   428
    def init_entity(self, entity):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   429
        for attr in self.entity_attrs:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   430
            if attr in entity.cw_edited:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   431
                # already set, skip this attribute
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   432
                continue
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   433
            genfunc = self.generate(attr)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   434
            if genfunc:
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   435
                entity.cw_edited.edited_attribute(attr, genfunc(entity))
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11749
diff changeset
   436
        return self.source
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   437
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   438
    def generate(self, rtype):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   439
        return getattr(self, 'gen_%s' % rtype, None)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   440
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   441
    def gen_cwuri(self, entity):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   442
        assert self.baseurl, 'baseurl is None while generating cwuri'
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   443
        return u'%s%s' % (self.baseurl, entity.eid)
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   444
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   445
    def gen_creation_date(self, entity):
11142
45f738a634e5 [dataimport] rename .time to .now attribute of meta generator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11140
diff changeset
   446
        return self._now
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   447
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   448
    def gen_modification_date(self, entity):
11142
45f738a634e5 [dataimport] rename .time to .now attribute of meta generator
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11140
diff changeset
   449
        return self._now
10513
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   450
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   451
    def gen_created_by(self, entity):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   452
        return self._cnx.user.eid
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   453
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   454
    def gen_owned_by(self, entity):
7bec01a59f92 [dataimport] dispatch and deprecate old code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   455
        return self._cnx.user.eid