cubicweb/server/repository.py
author Laurent Wouters <lwouters@cenotelie.fr>
Fri, 20 Mar 2020 14:34:07 +0100
changeset 12931 6eae252361e5
parent 12807 fb0936668535
child 12932 04bba74fc1fa
permissions -rw-r--r--
[rql] Store selected variables for RQL select queries in ResultSet (#17218476) By storing the name of the selected variables for RQL select queries in the ResultSet (within the "variables" attribute), the information can be passed down to specific protocols, e.g. rqlio that may wish to pass is down further to clients. In turn, clients can then choose to present the results of RQL select queries as symbolic bindings using the names used in the query's projection, instead of ordinal arrays.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
     1
# copyright 2003-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5376
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
"""Defines the central class for the CubicWeb RQL server: the repository.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
The repository is an abstraction allowing execution of rql queries against
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
data sources. Most of the work is actually done in helper classes. The
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
repository mainly:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
* brings these classes all together to provide a single access
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2473
diff changeset
    25
  point to a cubicweb instance.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
* handles session management
5587
72679e450f6d [web] dont attempt to update last login time on ldap users, avoiding spurious tb in logs (closes #914464)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    27
"""
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11763
diff changeset
    28
6390
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
    29
from itertools import chain
9113
af6efc15fc90 [repository] add an ``internal_cnx`` method to replace ``internal_session``
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9105
diff changeset
    30
from contextlib import contextmanager
11811
f09efeead7f9 Fix broken flake8 configuration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11774
diff changeset
    31
from logging import getLogger
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12542
diff changeset
    32
import queue
10608
7fc548d9dd8e [py3k] import queue using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10589
diff changeset
    33
6427
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
    34
from logilab.common.decorators import cached, clear_cache
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
from yams import BadSchemaDefinition
6390
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
    37
from rql.utils import rqlvar_maker
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
12054
d830ea048c97 [repo] Fix flake8 error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12051
diff changeset
    39
from cubicweb import (CW_MIGRATION_MAP,
2709
6ee816eb9f25 [hooksmanager] hooks should be reseted after vreg reload
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2708
diff changeset
    40
                      UnknownEid, AuthenticationError, ExecutionError,
12025
ba79f4a4f5d8 [session] Stop relying on _sessions to synchronize living session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12021
diff changeset
    41
                      UniqueTogetherError, ViolatedConstraint)
11811
f09efeead7f9 Fix broken flake8 configuration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11774
diff changeset
    42
from cubicweb import set_log_methods
2839
6419af16faa0 imports cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
    43
from cubicweb import cwvreg, schema, server
12021
cc8135ecfbb8 [repo] Drop _get_session method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12016
diff changeset
    44
from cubicweb.server import utils, hook, querier, sources
12043
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    45
from cubicweb.server.session import InternalManager, Connection
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
    47
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
    48
NO_CACHE_RELATIONS = set([
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
    49
    ('owned_by', 'object'),
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
    50
    ('created_by', 'object'),
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
    51
    ('cw_source', 'object'),
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
    52
])
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
    53
7134
01544b6d98fa allow CW to act as a Pyro Server without registering the server to a Pyro Nameserver (closes #1528533)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7085
diff changeset
    54
8456
c912d82f2166 [repository] drop unused argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8433
diff changeset
    55
def prefill_entity_caches(entity):
10368
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
    56
    cnx = entity._cw
6467
869813c2dd40 [entity, repo] move prefill_entity_cache function back to repository due to usage of del_existing_rel_if_needed function which is also defined there
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6466
diff changeset
    57
    # prefill entity relation caches
869813c2dd40 [entity, repo] move prefill_entity_cache function back to repository due to usage of del_existing_rel_if_needed function which is also defined there
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6466
diff changeset
    58
    for rschema in entity.e_schema.subject_relations():
869813c2dd40 [entity, repo] move prefill_entity_cache function back to repository due to usage of del_existing_rel_if_needed function which is also defined there
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6466
diff changeset
    59
        rtype = str(rschema)
7373
e5e6ef56cfb5 [repo cache] there are some relations we don't want to cache, they may cause memory leak
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7305
diff changeset
    60
        if rtype in schema.VIRTUAL_RTYPES or (rtype, 'subject') in NO_CACHE_RELATIONS:
6467
869813c2dd40 [entity, repo] move prefill_entity_cache function back to repository due to usage of del_existing_rel_if_needed function which is also defined there
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6466
diff changeset
    61
            continue
869813c2dd40 [entity, repo] move prefill_entity_cache function back to repository due to usage of del_existing_rel_if_needed function which is also defined there
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6466
diff changeset
    62
        if rschema.final:
869813c2dd40 [entity, repo] move prefill_entity_cache function back to repository due to usage of del_existing_rel_if_needed function which is also defined there
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6466
diff changeset
    63
            entity.cw_attr_cache.setdefault(rtype, None)
869813c2dd40 [entity, repo] move prefill_entity_cache function back to repository due to usage of del_existing_rel_if_needed function which is also defined there
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6466
diff changeset
    64
        else:
869813c2dd40 [entity, repo] move prefill_entity_cache function back to repository due to usage of del_existing_rel_if_needed function which is also defined there
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6466
diff changeset
    65
            entity.cw_set_relation_cache(rtype, 'subject',
10368
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
    66
                                         cnx.empty_rset())
6467
869813c2dd40 [entity, repo] move prefill_entity_cache function back to repository due to usage of del_existing_rel_if_needed function which is also defined there
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6466
diff changeset
    67
    for rschema in entity.e_schema.object_relations():
869813c2dd40 [entity, repo] move prefill_entity_cache function back to repository due to usage of del_existing_rel_if_needed function which is also defined there
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6466
diff changeset
    68
        rtype = str(rschema)
7373
e5e6ef56cfb5 [repo cache] there are some relations we don't want to cache, they may cause memory leak
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7305
diff changeset
    69
        if rtype in schema.VIRTUAL_RTYPES or (rtype, 'object') in NO_CACHE_RELATIONS:
6467
869813c2dd40 [entity, repo] move prefill_entity_cache function back to repository due to usage of del_existing_rel_if_needed function which is also defined there
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6466
diff changeset
    70
            continue
10368
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
    71
        entity.cw_set_relation_cache(rtype, 'object', cnx.empty_rset())
6467
869813c2dd40 [entity, repo] move prefill_entity_cache function back to repository due to usage of del_existing_rel_if_needed function which is also defined there
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6466
diff changeset
    72
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
    73
10368
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
    74
def del_existing_rel_if_needed(cnx, eidfrom, rtype, eidto):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
    """delete existing relation when adding a new one if card is 1 or ?
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
    have to be done once the new relation has been inserted to avoid having
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
    an entity without a relation for some time
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
    this kind of behaviour has to be done in the repository so we don't have
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
    hooks order hazardness
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
    """
7503
bc30c2faaadc [repository] refactor and optimize '?1' relation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7502
diff changeset
    83
    # skip that if integrity explicitly disabled
10368
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
    84
    if not cnx.is_hook_category_activated('activeintegrity'):
4687
082e66184f71 [integrity] skip auto-delete for internal sessions (but *not* for super session, see 4642:921737d2e3a8)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4686
diff changeset
    85
        return
10368
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
    86
    rdef = cnx.rtype_eids_rdef(rtype, eidfrom, eidto)
7502
e7190f7e850e [session] deprecates schema_rproperty in favor of more optimized rtype_eids_rdef which return the rdef (so reusable to gather other data)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7501
diff changeset
    87
    card = rdef.cardinality
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
    # one may be tented to check for neweids but this may cause more than one
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
    # relation even with '1?'  cardinality if thoses relations are added in the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
    # same transaction where the entity is being created. This never occurs from
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
    # the web interface but may occurs during test or dbapi connection (though
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
    # not expected for this).  So: don't do it, we pretend to ensure repository
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
    # consistency.
4673
6f8b925a29f4 auto-delete relation with single cardinality using execute, not unsafe_execute, so permissions are correctly checked
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4643
diff changeset
    94
    #
6189
9fa02f352c8c cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6188
diff changeset
    95
    # notes:
9fa02f352c8c cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6188
diff changeset
    96
    # * inlined relations will be implicitly deleted for the subject entity
9fa02f352c8c cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6188
diff changeset
    97
    # * we don't want read permissions to be applied but we want delete
9fa02f352c8c cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6188
diff changeset
    98
    #   permission to be checked
7503
bc30c2faaadc [repository] refactor and optimize '?1' relation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7502
diff changeset
    99
    if card[0] in '1?':
10368
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   100
        with cnx.security_enabled(read=False):
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   101
            cnx.execute('DELETE X %s Y WHERE X eid %%(x)s, '
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   102
                        'NOT Y eid %%(y)s' % rtype,
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   103
                        {'x': eidfrom, 'y': eidto})
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
    if card[1] in '1?':
10368
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   105
        with cnx.security_enabled(read=False):
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   106
            cnx.execute('DELETE X %s Y WHERE Y eid %%(y)s, '
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   107
                        'NOT X eid %%(x)s' % rtype,
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   108
                        {'x': eidfrom, 'y': eidto})
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   109
3694
33dbb1da1db9 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   110
10368
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   111
def preprocess_inlined_relations(cnx, entity):
8547
f23ac525ddd1 [datafeed] properly call hooks for inlined relations on entity creation. Closes #2481156
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8456
diff changeset
   112
    """when an entity is added, check if it has some inlined relation which
f23ac525ddd1 [datafeed] properly call hooks for inlined relations on entity creation. Closes #2481156
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8456
diff changeset
   113
    requires to be extrated for proper call hooks
f23ac525ddd1 [datafeed] properly call hooks for inlined relations on entity creation. Closes #2481156
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8456
diff changeset
   114
    """
f23ac525ddd1 [datafeed] properly call hooks for inlined relations on entity creation. Closes #2481156
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8456
diff changeset
   115
    relations = []
10368
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   116
    activeintegrity = cnx.is_hook_category_activated('activeintegrity')
8547
f23ac525ddd1 [datafeed] properly call hooks for inlined relations on entity creation. Closes #2481156
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8456
diff changeset
   117
    eschema = entity.e_schema
8696
0bb18407c053 [toward py3k] rewrite dict.keys() and dict.values() (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
   118
    for attr in entity.cw_edited:
8547
f23ac525ddd1 [datafeed] properly call hooks for inlined relations on entity creation. Closes #2481156
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8456
diff changeset
   119
        rschema = eschema.subjrels[attr]
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   120
        if not rschema.final:  # inlined relation
8547
f23ac525ddd1 [datafeed] properly call hooks for inlined relations on entity creation. Closes #2481156
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8456
diff changeset
   121
            value = entity.cw_edited[attr]
f23ac525ddd1 [datafeed] properly call hooks for inlined relations on entity creation. Closes #2481156
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8456
diff changeset
   122
            relations.append((attr, value))
10368
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   123
            cnx.update_rel_cache_add(entity.eid, attr, value)
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   124
            rdef = cnx.rtype_eids_rdef(attr, entity.eid, value)
8547
f23ac525ddd1 [datafeed] properly call hooks for inlined relations on entity creation. Closes #2481156
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8456
diff changeset
   125
            if rdef.cardinality[1] in '1?' and activeintegrity:
10368
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   126
                with cnx.security_enabled(read=False):
1691be295517 [repository] rename session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10365
diff changeset
   127
                    cnx.execute('DELETE X %s Y WHERE Y eid %%(y)s' % attr,
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   128
                                {'x': entity.eid, 'y': value})
8547
f23ac525ddd1 [datafeed] properly call hooks for inlined relations on entity creation. Closes #2481156
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8456
diff changeset
   129
    return relations
f23ac525ddd1 [datafeed] properly call hooks for inlined relations on entity creation. Closes #2481156
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8456
diff changeset
   130
8320
cd2d332b3063 [repo looping task] move looping task logic in a dedicated object (progress #2204047)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8280
diff changeset
   131
8211
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   132
class NullEventBus(object):
8214
ce9556358dbd [event bus] event has been renamed to publish
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8211
diff changeset
   133
    def publish(self, msg):
8211
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   134
        pass
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   135
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   136
    def add_subscription(self, topic, callback):
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   137
        pass
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   138
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   139
    def start(self):
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   140
        pass
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   141
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   142
    def stop(self):
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   143
        pass
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   144
11934
ec69125c03a8 [server] Add a blank line before _CnxSetPool to fix PEP8 error
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11931
diff changeset
   145
12804
6de3af773073 [refactoring] not needed anymore in python3
Laurent Peuch <cortex@worlddomination.be>
parents: 12803
diff changeset
   146
class _CnxSetPool:
11931
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   147
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   148
    def __init__(self, source, size):
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   149
        self._cnxsets = []
12805
8cf02773a6b3 [refactoring] blank lines to make core more readable
Laurent Peuch <cortex@worlddomination.be>
parents: 12804
diff changeset
   150
11950
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   151
        if size is not None:
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   152
            self._queue = queue.Queue()
12805
8cf02773a6b3 [refactoring] blank lines to make core more readable
Laurent Peuch <cortex@worlddomination.be>
parents: 12804
diff changeset
   153
11950
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   154
            for i in range(size):
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   155
                cnxset = source.wrapped_connection()
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   156
                self._cnxsets.append(cnxset)
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   157
                self._queue.put_nowait(cnxset)
12805
8cf02773a6b3 [refactoring] blank lines to make core more readable
Laurent Peuch <cortex@worlddomination.be>
parents: 12804
diff changeset
   158
11950
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   159
        else:
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   160
            self._queue = None
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   161
            self._source = source
11931
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   162
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   163
    def qsize(self):
12803
bf940d5416e5 [refactoring] inline useless variable
Laurent Peuch <cortex@worlddomination.be>
parents: 12749
diff changeset
   164
        if self._queue is None:
11950
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   165
            return None
12805
8cf02773a6b3 [refactoring] blank lines to make core more readable
Laurent Peuch <cortex@worlddomination.be>
parents: 12804
diff changeset
   166
12803
bf940d5416e5 [refactoring] inline useless variable
Laurent Peuch <cortex@worlddomination.be>
parents: 12749
diff changeset
   167
        return self._queue.qsize()
11931
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   168
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   169
    def get(self):
12803
bf940d5416e5 [refactoring] inline useless variable
Laurent Peuch <cortex@worlddomination.be>
parents: 12749
diff changeset
   170
        if self._queue is None:
11950
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   171
            return self._source.wrapped_connection()
12805
8cf02773a6b3 [refactoring] blank lines to make core more readable
Laurent Peuch <cortex@worlddomination.be>
parents: 12804
diff changeset
   172
11931
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   173
        try:
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   174
            return self._queue.get(True, timeout=5)
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   175
        except queue.Empty:
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   176
            raise Exception('no connections set available after 5 secs, probably either a '
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   177
                            'bug in code (too many uncommited/rolled back '
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   178
                            'connections) or too much load on the server (in '
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   179
                            'which case you can try to set a bigger '
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   180
                            'connections pool size)')
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   181
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   182
    def release(self, cnxset):
12803
bf940d5416e5 [refactoring] inline useless variable
Laurent Peuch <cortex@worlddomination.be>
parents: 12749
diff changeset
   183
        if self._queue is None:
11950
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   184
            cnxset.close(True)
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   185
        else:
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   186
            self._queue.put_nowait(cnxset)
11931
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   187
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   188
    def __iter__(self):
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   189
        for cnxset in self._cnxsets:
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   190
            yield cnxset
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   191
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   192
    def close(self):
12807
fb0936668535 [comment] add comment for maybe unhandled situation
Laurent Peuch <cortex@worlddomination.be>
parents: 12806
diff changeset
   193
        # XXX we don't close the connection when there is no queue?
12803
bf940d5416e5 [refactoring] inline useless variable
Laurent Peuch <cortex@worlddomination.be>
parents: 12749
diff changeset
   194
        if self._queue is not None:
bf940d5416e5 [refactoring] inline useless variable
Laurent Peuch <cortex@worlddomination.be>
parents: 12749
diff changeset
   195
            while not self._queue.empty():
bf940d5416e5 [refactoring] inline useless variable
Laurent Peuch <cortex@worlddomination.be>
parents: 12749
diff changeset
   196
                cnxset = self._queue.get_nowait()
12805
8cf02773a6b3 [refactoring] blank lines to make core more readable
Laurent Peuch <cortex@worlddomination.be>
parents: 12804
diff changeset
   197
11950
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   198
                try:
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   199
                    cnxset.close(True)
12806
91e262556573 [refactoring] don't hide exceptions
Laurent Peuch <cortex@worlddomination.be>
parents: 12805
diff changeset
   200
                except Exception as e:
91e262556573 [refactoring] don't hide exceptions
Laurent Peuch <cortex@worlddomination.be>
parents: 12805
diff changeset
   201
                    self.exception('error while closing %s, error: %s' % (cnxset, e))
11931
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   202
8211
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   203
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
class Repository(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
    """a repository provides access to a set of persistent storages for
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
    entities and relations
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
    """
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   208
12012
f7ff5217a02f [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11995
diff changeset
   209
    def __init__(self, config, scheduler=None, vreg=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
        self.config = config
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
        if vreg is None:
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8133
diff changeset
   212
            vreg = cwvreg.CWRegistryStore(config)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
        self.vreg = vreg
12012
f7ff5217a02f [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11995
diff changeset
   214
        self._scheduler = scheduler
8320
cd2d332b3063 [repo looping task] move looping task logic in a dedicated object (progress #2204047)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8280
diff changeset
   215
8211
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
   216
        self.app_instances_bus = NullEventBus()
8320
cd2d332b3063 [repo looping task] move looping task logic in a dedicated object (progress #2204047)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8280
diff changeset
   217
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
        # list of functions to be called at regular interval
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
        # list of running threads
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
        self._running_threads = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
        # initial schema, should be build or replaced latter
2839
6419af16faa0 imports cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   222
        self.schema = schema.CubicWebSchema(config.appid)
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   223
        self.vreg.schema = self.schema  # until actual schema is loaded...
5906
d40ced753291 [repository] fix so that when repository is shutting down, internal session in transaction are interrupted
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5813
diff changeset
   224
        # shutdown flag
11983
5de78b6fff2e [server] Separate repository bootstrap from initialization
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11981
diff changeset
   225
        self.shutting_down = None
6427
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
   226
        # sources (additional sources info in the system database)
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
   227
        self.system_source = self.get_source('native', 'system',
9460
a2a0bc984863 [config] cleanup/refactor server sources file values handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9458
diff changeset
   228
                                             config.system_source_config.copy())
6427
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
   229
        # querier helper, need to be created after sources initialization
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
   230
        self.querier = querier.QuerierHelper(self, self.schema)
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   231
        # cache eid -> type
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   232
        self._type_cache = {}
8946
fae2f561b0f5 [repo] minor cleanups to bootstrap sequence
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8943
diff changeset
   233
        # the hooks manager
fae2f561b0f5 [repo] minor cleanups to bootstrap sequence
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8943
diff changeset
   234
        self.hm = hook.HooksManager(self.vreg)
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   235
11981
56e99b59272f [server] Rename Repository's init_cnxset_pool method bootstrap
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11980
diff changeset
   236
    def bootstrap(self):
11977
6eb79532af12 [server] Move "starting repository..." message where this actually happens
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11975
diff changeset
   237
        self.info('starting repository from %s', self.config.apphome)
11983
5de78b6fff2e [server] Separate repository bootstrap from initialization
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11981
diff changeset
   238
        self.shutting_down = False
2959
daabb9bc5233 make db-restore command work even with no/corrupted database
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2929
diff changeset
   239
        config = self.config
11908
7904fe436e82 [repository] Fix connection-pool-size not set to 1 with quick_start enabled
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11821
diff changeset
   240
        # copy pool size here since config.init_cube() and config.load_schema()
7904fe436e82 [repository] Fix connection-pool-size not set to 1 with quick_start enabled
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11821
diff changeset
   241
        # reload configuration from file and could reset a manually set pool
7904fe436e82 [repository] Fix connection-pool-size not set to 1 with quick_start enabled
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11821
diff changeset
   242
        # size.
11950
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   243
        if config['connections-pooler-enabled']:
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   244
            pool_size, min_pool_size = config['connections-pool-size'], 1
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   245
        else:
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   246
            pool_size = min_pool_size = None
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   247
        # 0. init a cnxset that will be used to fetch bootstrap information from
8947
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   248
        #    the database
11950
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   249
        self.cnxsets = _CnxSetPool(self.system_source, min_pool_size)
8947
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   250
        # 1. set used cubes
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   251
        if config.creating or not config.read_instance_schema:
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   252
            config.bootstrap_cubes()
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   253
        else:
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   254
            self.set_schema(self.config.load_bootstrap_schema(), resetvreg=False)
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   255
            config.init_cubes(self.get_cubes())
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   256
        # 2. load schema
5043
fe52dd3936cf [repo config] cleanup read_instance_schema / bootstrap_schema / creating mess
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5032
diff changeset
   257
        if config.quick_start:
8946
fae2f561b0f5 [repo] minor cleanups to bootstrap sequence
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8943
diff changeset
   258
            # quick start: only to get a minimal repository to get cubes
5084
d8f491cb046c [repo] we want a hooks manager and hooks initialized event on quick start (we trigger events such as server_backup / server_restore for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5079
diff changeset
   259
            # information (eg dump/restore/...)
8947
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   260
            #
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   261
            # restrict appobject_path to only load hooks and entity classes in
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   262
            # the registry
8537
e30d0a7f0087 [config] turn internal configuration methods building appobjects search path into normal method rather than class method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8456
diff changeset
   263
            config.cube_appobject_path = set(('hooks', 'entities'))
e30d0a7f0087 [config] turn internal configuration methods building appobjects search path into normal method rather than class method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8456
diff changeset
   264
            config.cubicweb_appobject_path = set(('hooks', 'entities'))
11950
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   265
            # limit connections pool size
68766861debe [repository] possibility to disable connections pooling
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11934
diff changeset
   266
            pool_size = min_pool_size
8947
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   267
        if config.quick_start or config.creating or not config.read_instance_schema:
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   268
            # load schema from the file system
8580
d753d6a6798f [repository] move modification of appobject_path to repository initialization code so we can restore it later to avoid side effect on the config. Fix regression introduced in d32ab8570e5d
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8573
diff changeset
   269
            if not config.creating:
11975
248039d0e6b1 [server] Fix a typo in log message in Repository.init_cnxset_pool()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11962
diff changeset
   270
                self.info("set fs instance's schema")
9165
7ebf3b1cdb4c Use the list of cubes from the filesystem when reading the schema from the filesystem
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9132
diff changeset
   271
            self.set_schema(config.load_schema(expand_cubes=True))
11090
b4b854c25de5 [repository] set .eid on eschema when schema is loaded from the filesystem
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11008
diff changeset
   272
            if not config.creating:
b4b854c25de5 [repository] set .eid on eschema when schema is loaded from the filesystem
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11008
diff changeset
   273
                # set eids on entities schema
b4b854c25de5 [repository] set .eid on eschema when schema is loaded from the filesystem
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11008
diff changeset
   274
                with self.internal_cnx() as cnx:
b4b854c25de5 [repository] set .eid on eschema when schema is loaded from the filesystem
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11008
diff changeset
   275
                    for etype, eid in cnx.execute('Any XN,X WHERE X is CWEType, X name XN'):
11477
3b4d41566de3 [repo] Don't crash on start when fs schema is missing some db schema entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11348
diff changeset
   276
                        try:
3b4d41566de3 [repo] Don't crash on start when fs schema is missing some db schema entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11348
diff changeset
   277
                            self.schema.eschema(etype).eid = eid
3b4d41566de3 [repo] Don't crash on start when fs schema is missing some db schema entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11348
diff changeset
   278
                        except KeyError:
3b4d41566de3 [repo] Don't crash on start when fs schema is missing some db schema entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11348
diff changeset
   279
                            # etype in the database doesn't exist in the fs schema, this may occur
3b4d41566de3 [repo] Don't crash on start when fs schema is missing some db schema entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11348
diff changeset
   280
                            # during dev and we shouldn't crash
3b4d41566de3 [repo] Don't crash on start when fs schema is missing some db schema entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11348
diff changeset
   281
                            self.warning('No %s entity type in the file system schema', etype)
8592
df16bd045cae [server] fix repository initialisation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8580
diff changeset
   282
        else:
df16bd045cae [server] fix repository initialisation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8580
diff changeset
   283
            # normal start: load the instance schema from the database
8947
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   284
            self.info('loading schema from the repository')
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   285
            self.set_schema(self.deserialize_schema())
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   286
        # 3. initialize data sources
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   287
        if config.creating:
6128
fbb8398f80dc cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6126
diff changeset
   288
            # call init_creating so that for instance native source can
fbb8398f80dc cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6126
diff changeset
   289
            # configurate tsearch according to postgres version
9456
a79e88aad555 [multi-sources-removal] Kill repo.sources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9455
diff changeset
   290
            self.system_source.init_creating()
8947
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   291
        else:
12135
e814ba7e51dc [server] Move "system" source initialization into its own method
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12130
diff changeset
   292
            self._init_system_source()
8947
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   293
            if 'CWProperty' in self.schema:
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   294
                self.vreg.init_properties(self.properties())
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   295
        # 4. close initialization connection set and reopen fresh ones for
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   296
        #    proper initialization
11931
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   297
        self.cnxsets.close()
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   298
        self.cnxsets = _CnxSetPool(self.system_source, pool_size)
11988
ffde65347797 [server] Call 'server_startup' hooks at the end of repository "bootstrap"
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11985
diff changeset
   299
        # 5. call instance level initialisation hooks
ffde65347797 [server] Call 'server_startup' hooks at the end of repository "bootstrap"
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11985
diff changeset
   300
        self.hm.call_hooks('server_startup', repo=self)
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   301
12146
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   302
    def source_by_uri(self, uri):
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   303
        with self.internal_cnx() as cnx:
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   304
            rset = cnx.find('CWSource', name=uri)
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   305
            if not rset:
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   306
                raise ValueError('no source with uri %s found' % uri)
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   307
            return self._source_from_cwsource(rset.one())
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   308
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   309
    def source_by_eid(self, eid):
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   310
        with self.internal_cnx() as cnx:
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   311
            rset = cnx.find('CWSource', eid=eid)
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   312
            if not rset:
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   313
                raise ValueError('no source with eid %d found' % eid)
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   314
            return self._source_from_cwsource(rset.one())
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   315
12142
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   316
    @property
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   317
    def sources_by_uri(self):
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   318
        mapping = {'system': self.system_source}
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   319
        mapping.update((sourceent.name, source)
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   320
                       for sourceent, source in self._sources())
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   321
        return mapping
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   322
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   323
    def _sources(self):
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   324
        if self.config.quick_start:
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   325
            return
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   326
        with self.internal_cnx() as cnx:
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   327
            for sourceent in cnx.execute(
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   328
                    'Any S, SN, SA, SC WHERE S is_instance_of CWSource, '
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   329
                    'S name SN, S type SA, S config SC, S name != "system"').entities():
12146
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   330
                source = self._source_from_cwsource(sourceent)
12142
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   331
                yield sourceent, source
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   332
        self._clear_source_defs_caches()
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   333
12146
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   334
    def _source_from_cwsource(self, sourceent):
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   335
        source = self.get_source(sourceent.type, sourceent.name,
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   336
                                 sourceent.host_config, sourceent.eid)
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   337
        if self.config.source_enabled(source):
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   338
            # call source's init method to complete their initialisation if
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   339
            # needed (for instance looking for persistent configuration using an
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   340
            # internal session, which is not possible until connections sets have been
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   341
            # initialized)
12148
79160d54662e [sources] Simplify source's init method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12147
diff changeset
   342
            source.init(sourceent)
12146
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   343
        return source
d540defa0591 [server] Add source_by_eid and source_by_uri methods to repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12142
diff changeset
   344
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   345
    # internals ###############################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   346
12135
e814ba7e51dc [server] Move "system" source initialization into its own method
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12130
diff changeset
   347
    def _init_system_source(self):
e814ba7e51dc [server] Move "system" source initialization into its own method
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12130
diff changeset
   348
        if self.config.quick_start:
e814ba7e51dc [server] Move "system" source initialization into its own method
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12130
diff changeset
   349
            self.system_source.init_creating()
e814ba7e51dc [server] Move "system" source initialization into its own method
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12130
diff changeset
   350
            return
e814ba7e51dc [server] Move "system" source initialization into its own method
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12130
diff changeset
   351
        with self.internal_cnx() as cnx:
e814ba7e51dc [server] Move "system" source initialization into its own method
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12130
diff changeset
   352
            sourceent = cnx.execute(
e814ba7e51dc [server] Move "system" source initialization into its own method
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12130
diff changeset
   353
                'Any S, SA, SC WHERE S is_instance_of CWSource,'
e814ba7e51dc [server] Move "system" source initialization into its own method
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12130
diff changeset
   354
                ' S name "system", S type SA, S config SC'
e814ba7e51dc [server] Move "system" source initialization into its own method
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12130
diff changeset
   355
            ).one()
e814ba7e51dc [server] Move "system" source initialization into its own method
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12130
diff changeset
   356
            self.system_source.eid = sourceent.eid
12148
79160d54662e [sources] Simplify source's init method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12147
diff changeset
   357
            self.system_source.init(sourceent)
12135
e814ba7e51dc [server] Move "system" source initialization into its own method
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12130
diff changeset
   358
6945
28bf94d062a9 [sources] refactor source creation and options handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6941
diff changeset
   359
    def get_source(self, type, uri, source_config, eid=None):
6427
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
   360
        # set uri and type in source config so it's available through
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
   361
        # source_defs()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
        source_config['uri'] = uri
6427
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
   363
        source_config['type'] = type
6945
28bf94d062a9 [sources] refactor source creation and options handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6941
diff changeset
   364
        return sources.get_source(type, source_config, self, eid)
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   365
8943
58b3b2d9c965 [repo] kill rebuildinfered feature from Repository.set_schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8916
diff changeset
   366
    def set_schema(self, schema, resetvreg=True):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   367
        self.info('set schema %s %#x', schema.name, id(schema))
3240
8604a15995d1 refactor so that rql rewriter may be used outside the server. Enhance it to be usable for RRQLExpression as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3042
diff changeset
   368
        if resetvreg:
5447
f29dafba250a [vreg repo] shouldn't call init_registration in on hook registry bootstrap, already done before
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5442
diff changeset
   369
            # trigger full reload of all appobjects
3240
8604a15995d1 refactor so that rql rewriter may be used outside the server. Enhance it to be usable for RRQLExpression as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3042
diff changeset
   370
            self.vreg.set_schema(schema)
8604a15995d1 refactor so that rql rewriter may be used outside the server. Enhance it to be usable for RRQLExpression as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3042
diff changeset
   371
        else:
8604a15995d1 refactor so that rql rewriter may be used outside the server. Enhance it to be usable for RRQLExpression as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3042
diff changeset
   372
            self.vreg._set_schema(schema)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   373
        self.querier.set_schema(schema)
12142
db2fc87348ab [server] Make "sources_by_uri" and "sources_by_eid" properties of repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12135
diff changeset
   374
        self.system_source.set_schema(schema)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   375
        self.schema = schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   376
8947
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   377
    def deserialize_schema(self):
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   378
        """load schema from the database"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   379
        from cubicweb.server.schemaserial import deserialize_schema
2839
6419af16faa0 imports cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   380
        appschema = schema.CubicWebSchema(self.config.appid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   381
        self.debug('deserializing db schema into %s %#x', appschema.name, id(appschema))
9490
b3d2c4065e6a [server] use internal_cnx instead of internal_session in deserialize_schema
Julien Cristau <julien.cristau@logilab.fr>
parents: 9488
diff changeset
   382
        with self.internal_cnx() as cnx:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   383
            try:
9490
b3d2c4065e6a [server] use internal_cnx instead of internal_session in deserialize_schema
Julien Cristau <julien.cristau@logilab.fr>
parents: 9488
diff changeset
   384
                deserialize_schema(appschema, cnx)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   385
            except BadSchemaDefinition:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   386
                raise
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8694
diff changeset
   387
            except Exception as ex:
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1372
diff changeset
   388
                import traceback
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1372
diff changeset
   389
                traceback.print_exc()
10110
f601d2fdeff7 [repository] don't mangle the stack trace on exception
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10039
diff changeset
   390
                raise Exception('Is the database initialised ? (cause: %s)' % ex)
8947
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8946
diff changeset
   391
        return appschema
8321
b5d5a5630649 [repository] split repo initialization from starting looping task (closes #2204047)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8320
diff changeset
   392
12112
0a54f49314f6 [server] Introduce an `has_scheduler` method on Repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12111
diff changeset
   393
    def has_scheduler(self):
0a54f49314f6 [server] Introduce an `has_scheduler` method on Repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12111
diff changeset
   394
        """Return True if the repository has a scheduler attached and is able
0a54f49314f6 [server] Introduce an `has_scheduler` method on Repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12111
diff changeset
   395
        to register looping tasks.
0a54f49314f6 [server] Introduce an `has_scheduler` method on Repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12111
diff changeset
   396
        """
0a54f49314f6 [server] Introduce an `has_scheduler` method on Repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12111
diff changeset
   397
        return self._scheduler is not None
0a54f49314f6 [server] Introduce an `has_scheduler` method on Repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12111
diff changeset
   398
12012
f7ff5217a02f [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11995
diff changeset
   399
    def run_scheduler(self):
f7ff5217a02f [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11995
diff changeset
   400
        """Start repository scheduler after preparing the repository for that.
8321
b5d5a5630649 [repository] split repo initialization from starting looping task (closes #2204047)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8320
diff changeset
   401
b5d5a5630649 [repository] split repo initialization from starting looping task (closes #2204047)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8320
diff changeset
   402
        * trigger server startup hook,
12012
f7ff5217a02f [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11995
diff changeset
   403
        * start the scheduler *and block*.
8321
b5d5a5630649 [repository] split repo initialization from starting looping task (closes #2204047)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8320
diff changeset
   404
b5d5a5630649 [repository] split repo initialization from starting looping task (closes #2204047)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8320
diff changeset
   405
        XXX Other startup related stuffs are done elsewhere. In Repository
b5d5a5630649 [repository] split repo initialization from starting looping task (closes #2204047)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8320
diff changeset
   406
        XXX __init__ or in external codes (various server managers).
b5d5a5630649 [repository] split repo initialization from starting looping task (closes #2204047)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8320
diff changeset
   407
        """
12112
0a54f49314f6 [server] Introduce an `has_scheduler` method on Repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12111
diff changeset
   408
        assert self.has_scheduler(), \
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   409
            "This Repository is not intended to be used as a server"
12012
f7ff5217a02f [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11995
diff changeset
   410
        self.info(
f7ff5217a02f [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11995
diff changeset
   411
            'starting repository scheduler with tasks: %s',
f7ff5217a02f [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11995
diff changeset
   412
            ', '.join(e.action.__name__ for e in self._scheduler.queue))
f7ff5217a02f [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11995
diff changeset
   413
        self._scheduler.run()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   414
2708
60d728bdcba5 allow to specify arbitrary argument when recording a looping task func
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2667
diff changeset
   415
    def looping_task(self, interval, func, *args):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   416
        """register a function to be called every `interval` seconds.
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   417
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   418
        looping tasks can only be registered during repository initialization,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   419
        once done this method will fail.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   420
        """
12110
a9266a72f3e0 [server] Exit quickly when a looping task is registered in maintenance mode
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12062
diff changeset
   421
        if self.config.repairing:
a9266a72f3e0 [server] Exit quickly when a looping task is registered in maintenance mode
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12062
diff changeset
   422
            return
12112
0a54f49314f6 [server] Introduce an `has_scheduler` method on Repository
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12111
diff changeset
   423
        if not self.has_scheduler():
12111
cd069068a5ef [server] Warn instead of failing when a looping task is registered and repo has no scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12110
diff changeset
   424
            self.warning(
cd069068a5ef [server] Warn instead of failing when a looping task is registered and repo has no scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12110
diff changeset
   425
                'looping task %s will not run in this process where repository '
cd069068a5ef [server] Warn instead of failing when a looping task is registered and repo has no scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12110
diff changeset
   426
                'has no scheduler; use "cubicweb-ctl scheduler <appid>" to '
cd069068a5ef [server] Warn instead of failing when a looping task is registered and repo has no scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12110
diff changeset
   427
                'have it running', func)
cd069068a5ef [server] Warn instead of failing when a looping task is registered and repo has no scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12110
diff changeset
   428
            return
12012
f7ff5217a02f [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11995
diff changeset
   429
        event = utils.schedule_periodic_task(
f7ff5217a02f [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11995
diff changeset
   430
            self._scheduler, interval, func, *args)
f7ff5217a02f [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11995
diff changeset
   431
        self.info('scheduled periodic task %s (interval: %.2fs)',
f7ff5217a02f [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11995
diff changeset
   432
                  event.action.__name__, interval)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   433
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   434
    def threaded_task(self, func):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   435
        """start function in a separated thread"""
8320
cd2d332b3063 [repo looping task] move looping task logic in a dedicated object (progress #2204047)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8280
diff changeset
   436
        utils.RepoThread(func, self._running_threads).start()
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   437
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   438
    def shutdown(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   439
        """called on server stop event to properly close opened sessions and
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   440
        connections
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   441
        """
5906
d40ced753291 [repository] fix so that when repository is shutting down, internal session in transaction are interrupted
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5813
diff changeset
   442
        assert not self.shutting_down, 'already shutting down'
8393
77c7158916c1 [events] add a new before_shutdown event (closes #2345728)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8366
diff changeset
   443
        if not (self.config.creating or self.config.repairing
77c7158916c1 [events] add a new before_shutdown event (closes #2345728)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8366
diff changeset
   444
                or self.config.quick_start):
77c7158916c1 [events] add a new before_shutdown event (closes #2345728)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8366
diff changeset
   445
            # then, the system source is still available
77c7158916c1 [events] add a new before_shutdown event (closes #2345728)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8366
diff changeset
   446
            self.hm.call_hooks('before_server_shutdown', repo=self)
5906
d40ced753291 [repository] fix so that when repository is shutting down, internal session in transaction are interrupted
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5813
diff changeset
   447
        self.shutting_down = True
12016
88ed82a25f8a [server] Add a "scheduler" command to run repository scheduler
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12012
diff changeset
   448
        self.info('shutting down repository')
5749
b4393b681f7a [repo] on repository shutdown, we've to close the new eid creation connection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5747
diff changeset
   449
        self.system_source.shutdown()
8351
02f4f01375e8 [repository] fire 'server_shutdown' hooks before waiting for theads
David Douard <david.douard@logilab.fr>
parents: 8322
diff changeset
   450
        if not (self.config.creating or self.config.repairing
02f4f01375e8 [repository] fire 'server_shutdown' hooks before waiting for theads
David Douard <david.douard@logilab.fr>
parents: 8322
diff changeset
   451
                or self.config.quick_start):
02f4f01375e8 [repository] fire 'server_shutdown' hooks before waiting for theads
David Douard <david.douard@logilab.fr>
parents: 8322
diff changeset
   452
            self.hm.call_hooks('server_shutdown', repo=self)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   453
        for thread in self._running_threads:
5376
2c3f14bc2590 [python2.6] don't add a name property on Thread
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5292
diff changeset
   454
            self.info('waiting thread %s...', thread.getName())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   455
            thread.join()
5376
2c3f14bc2590 [python2.6] don't add a name property on Thread
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5292
diff changeset
   456
            self.info('thread %s finished', thread.getName())
11931
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11908
diff changeset
   457
        self.cnxsets.close()
12060
0cdf5fafd234 [repo] Extract rql cache handling to a dedicated class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12057
diff changeset
   458
        hits, misses = self.querier.rql_cache.cache_hit, self.querier.rql_cache.cache_miss
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   459
        try:
5747
d6ac0cd30fde [rset] do not filter rsets with __getstate__, ensure whatever flies with pyro has no .req attribute, also set the ._rqlst to None since it will be reconstructed later on demand
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5711
diff changeset
   460
            self.info('rql st cache hit/miss: %s/%s (%s%% hits)', hits, misses,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   461
                      (hits * 100) / (hits + misses))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   462
            hits, misses = self.system_source.cache_hit, self.system_source.cache_miss
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   463
            self.info('sql cache hit/miss: %s/%s (%s%% hits)', hits, misses,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   464
                      (hits * 100) / (hits + misses))
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   465
            nocache = self.system_source.no_cache
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   466
            self.info('sql cache usage: %s/%s (%s%%)', hits + misses, nocache,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   467
                      ((hits + misses) * 100) / (hits + misses + nocache))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   468
        except ZeroDivisionError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   469
            pass
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   470
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9510
diff changeset
   471
    def check_auth_info(self, cnx, login, authinfo):
6849
5a0c2cfc19bf [repository auth] cleanup email login by turning it into a proper repo-side authentication plugin
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6822
diff changeset
   472
        """validate authentication, raise AuthenticationError on failure, return
5a0c2cfc19bf [repository auth] cleanup email login by turning it into a proper repo-side authentication plugin
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6822
diff changeset
   473
        associated CWUser's eid on success.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   474
        """
8229
b7bc631816f7 [ldapfeed] make authentication actually working
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8214
diff changeset
   475
        # iter on sources_by_uri then check enabled source since sources doesn't
b7bc631816f7 [ldapfeed] make authentication actually working
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8214
diff changeset
   476
        # contain copy based sources
10663
54b8a1f249fb [py3k] dict.itervalues → dict.values
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
   477
        for source in self.sources_by_uri.values():
11750
18e7b9829471 [sources] Drop source support_entity / support_relation source API
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11699
diff changeset
   478
            if self.config.source_enabled(source):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   479
                try:
10365
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10354
diff changeset
   480
                    return source.authenticate(cnx, login, **authinfo)
11750
18e7b9829471 [sources] Drop source support_entity / support_relation source API
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11699
diff changeset
   481
                except (NotImplementedError, AuthenticationError):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   482
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   483
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   484
            raise AuthenticationError('authentication failed with all sources')
6849
5a0c2cfc19bf [repository auth] cleanup email login by turning it into a proper repo-side authentication plugin
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6822
diff changeset
   485
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9510
diff changeset
   486
    def authenticate_user(self, cnx, login, **authinfo):
6849
5a0c2cfc19bf [repository auth] cleanup email login by turning it into a proper repo-side authentication plugin
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6822
diff changeset
   487
        """validate login / password, raise AuthenticationError on failure
5a0c2cfc19bf [repository auth] cleanup email login by turning it into a proper repo-side authentication plugin
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6822
diff changeset
   488
        return associated CWUser instance on success
5a0c2cfc19bf [repository auth] cleanup email login by turning it into a proper repo-side authentication plugin
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6822
diff changeset
   489
        """
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9510
diff changeset
   490
        eid = self.check_auth_info(cnx, login, authinfo)
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9510
diff changeset
   491
        cwuser = self._build_user(cnx, eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   492
        if self.config.consider_user_state and \
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   493
           not cwuser.cw_adapt_to('IWorkflowable').state in cwuser.AUTHENTICABLE_STATES:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   494
            raise AuthenticationError('user is not in authenticable state')
2268
2f336fd5e040 euser->cwuser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2267
diff changeset
   495
        return cwuser
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   496
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9510
diff changeset
   497
    def _build_user(self, cnx, eid):
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1372
diff changeset
   498
        """return a CWUser entity for user with the given eid"""
10365
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10354
diff changeset
   499
        cls = self.vreg['etypes'].etype_class('CWUser')
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10354
diff changeset
   500
        st = cls.fetch_rqlst(cnx.user, ordermethod=None)
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10354
diff changeset
   501
        st.add_eid_restriction(st.get_variable('X'), 'x', 'Substitute')
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10354
diff changeset
   502
        rset = cnx.execute(st.as_string(), {'x': eid})
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10354
diff changeset
   503
        assert len(rset) == 1, rset
11699
b48020a80dc3 Store user groups and properties as session data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11477
diff changeset
   504
        return rset.get_entity(0, 0)
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   505
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   506
    # public (dbapi) interface ################################################
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   507
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   508
    def get_schema(self):
6256
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   509
        """Return the instance schema.
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   510
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   511
        This is a public method, not requiring a session id.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   512
        """
7723
badfd5524ab6 [repo] Stop setting hashmode on schema
Julien Cristau <julien.cristau@logilab.fr>
parents: 7716
diff changeset
   513
        return self.schema
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   514
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   515
    def get_cubes(self):
6256
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   516
        """Return the list of cubes used by this instance.
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   517
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   518
        This is a public method, not requiring a session id.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   519
        """
2473
490f88fb99b6 new distinguish repairing/creating from regular start.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2268
diff changeset
   520
        versions = self.get_versions(not (self.config.creating
4689
4eb1f4490538 [test] skipping versions checking during test is enough, no need for monkey patch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4687
diff changeset
   521
                                          or self.config.repairing
5043
fe52dd3936cf [repo config] cleanup read_instance_schema / bootstrap_schema / creating mess
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5032
diff changeset
   522
                                          or self.config.quick_start
4689
4eb1f4490538 [test] skipping versions checking during test is enough, no need for monkey patch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4687
diff changeset
   523
                                          or self.config.mode == 'test'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   524
        cubes = list(versions)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   525
        cubes.remove('cubicweb')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   526
        return cubes
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   527
12508
a8c1ea390400 Drop most of deprecated code
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12240
diff changeset
   528
    def get_option_value(self, option):
9458
e2dfdd313dfe [multi-sources-removal] Drop foreid argument of repo.get_option_value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9456
diff changeset
   529
        """Return the value for `option` in the configuration.
6257
7eb5f1aed728 [repo] new method on repo+dbapi.Connection to get a value from repository's configuration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6256
diff changeset
   530
7eb5f1aed728 [repo] new method on repo+dbapi.Connection to get a value from repository's configuration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6256
diff changeset
   531
        This is a public method, not requiring a session id.
7eb5f1aed728 [repo] new method on repo+dbapi.Connection to get a value from repository's configuration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6256
diff changeset
   532
        """
7eb5f1aed728 [repo] new method on repo+dbapi.Connection to get a value from repository's configuration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6256
diff changeset
   533
        # XXX we may want to check we don't give sensible information
9458
e2dfdd313dfe [multi-sources-removal] Drop foreid argument of repo.get_option_value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9456
diff changeset
   534
        return self.config[option]
6257
7eb5f1aed728 [repo] new method on repo+dbapi.Connection to get a value from repository's configuration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6256
diff changeset
   535
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   536
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   537
    def get_versions(self, checkversions=False):
6256
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   538
        """Return the a dictionary containing cubes used by this instance
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   539
        as key with their version as value, including cubicweb version.
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   540
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   541
        This is a public method, not requiring a session id.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   542
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   543
        from logilab.common.changelog import Version
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   544
        vcconf = {}
9505
53225f66e7ca [repo] Use a connection instead of a session for repo.get_versions()
Julien Cristau <julien.cristau@logilab.fr>
parents: 9496
diff changeset
   545
        with self.internal_cnx() as cnx:
53225f66e7ca [repo] Use a connection instead of a session for repo.get_versions()
Julien Cristau <julien.cristau@logilab.fr>
parents: 9496
diff changeset
   546
            for pk, version in cnx.execute(
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   547
                    'Any K,V WHERE P is CWProperty, P value V, P pkey K, '
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   548
                    'P pkey ~="system.version.%"', build_descr=False):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   549
                cube = pk.split('.')[-1]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   550
                # XXX cubicweb migration
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   551
                if cube in CW_MIGRATION_MAP:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   552
                    cube = CW_MIGRATION_MAP[cube]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   553
                version = Version(version)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   554
                vcconf[cube] = version
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   555
                if checkversions:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   556
                    if cube != 'cubicweb':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   557
                        fsversion = self.config.cube_version(cube)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   558
                    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   559
                        fsversion = self.config.cubicweb_version()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   560
                    if version < fsversion:
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2473
diff changeset
   561
                        msg = ('instance has %s version %s but %s '
12747
36d4a8ec1fb7 [ux] display instance name in suggested upgrade command
Laurent Peuch <cortex@worlddomination.be>
parents: 12240
diff changeset
   562
                               'is installed. Run "cubicweb-ctl upgrade %s".')
36d4a8ec1fb7 [ux] display instance name in suggested upgrade command
Laurent Peuch <cortex@worlddomination.be>
parents: 12240
diff changeset
   563
                        raise ExecutionError(msg % (cube, version, fsversion, self.config.appid))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   564
        return vcconf
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   565
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   566
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   567
    def source_defs(self):
6256
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   568
        """Return the a dictionary containing source uris as value and a
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   569
        dictionary describing each source as value.
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   570
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   571
        This is a public method, not requiring a session id.
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   572
        """
6427
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
   573
        sources = {}
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   574
        # remove sensitive information
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10609
diff changeset
   575
        for uri, source in self.sources_by_uri.items():
6722
3341521d857b [repo source] rename attribute so it's much easier to grasp its role
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6674
diff changeset
   576
            sources[uri] = source.public_config
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   577
        return sources
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   578
12057
90c40f229ab0 [repo] Move and rename repo._clear_planning_cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12054
diff changeset
   579
    def _clear_source_defs_caches(self):
90c40f229ab0 [repo] Move and rename repo._clear_planning_cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12054
diff changeset
   580
        clear_cache(self, 'source_defs')
90c40f229ab0 [repo] Move and rename repo._clear_planning_cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12054
diff changeset
   581
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   582
    def properties(self):
6256
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   583
        """Return a result set containing system wide properties.
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   584
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   585
        This is a public method, not requiring a session id.
da77d3f95079 [repo] docstring cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6211
diff changeset
   586
        """
9491
e82370a30018 [repo] restore python 2.6 compatibility
Julien Cristau <julien.cristau@logilab.fr>
parents: 9490
diff changeset
   587
        with self.internal_cnx() as cnx:
9685
0033aa71e077 [server] make internal_cnx get and keep a connection to the db
Julien Cristau <julien.cristau@logilab.fr>
parents: 9683
diff changeset
   588
            # don't use cnx.execute, we don't want rset.req set
0033aa71e077 [server] make internal_cnx get and keep a connection to the db
Julien Cristau <julien.cristau@logilab.fr>
parents: 9683
diff changeset
   589
            return self.querier.execute(cnx, 'Any K,V WHERE P is CWProperty,'
5747
d6ac0cd30fde [rset] do not filter rsets with __getstate__, ensure whatever flies with pyro has no .req attribute, also set the ._rqlst to None since it will be reconstructed later on demand
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5711
diff changeset
   590
                                        'P pkey K, P value V, NOT P for_user U',
d6ac0cd30fde [rset] do not filter rsets with __getstate__, ensure whatever flies with pyro has no .req attribute, also set the ._rqlst to None since it will be reconstructed later on demand
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5711
diff changeset
   591
                                        build_descr=False)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   592
6390
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   593
    def find_users(self, fetch_attrs, **query_attrs):
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   594
        """yield user attributes for cwusers matching the given query_attrs
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   595
        (the result set cannot survive this method call)
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   596
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   597
        This can be used by low-privileges account (anonymous comes to
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   598
        mind).
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   599
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   600
        `fetch_attrs`: tuple of attributes to be fetched
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   601
        `query_attrs`: dict of attr/values to restrict the query
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   602
        """
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   603
        assert query_attrs
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   604
        if not hasattr(self, '_cwuser_attrs'):
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   605
            cwuser = self.schema['CWUser']
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   606
            self._cwuser_attrs = set(str(rschema)
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   607
                                     for rschema, _eschema in cwuser.attribute_definitions()
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   608
                                     if not rschema.meta)
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   609
        cwuserattrs = self._cwuser_attrs
8696
0bb18407c053 [toward py3k] rewrite dict.keys() and dict.values() (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
   610
        for k in chain(fetch_attrs, query_attrs):
6390
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   611
            if k not in cwuserattrs:
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   612
                raise Exception('bad input for find_user')
10345
ef54ea75a642 [server] drop repo.internal_session and InternalSession
Julien Cristau <julien.cristau@logilab.fr>
parents: 10342
diff changeset
   613
        with self.internal_cnx() as cnx:
6390
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   614
            varmaker = rqlvar_maker()
10669
155c29e0ed1c [py3k] use next builtin instead of next method
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10663
diff changeset
   615
            vars = [(attr, next(varmaker)) for attr in fetch_attrs]
6390
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   616
            rql = 'Any %s WHERE X is CWUser, ' % ','.join(var[1] for var in vars)
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   617
            rql += ','.join('X %s %s' % (var[0], var[1]) for var in vars) + ','
10345
ef54ea75a642 [server] drop repo.internal_session and InternalSession
Julien Cristau <julien.cristau@logilab.fr>
parents: 10342
diff changeset
   618
            rset = cnx.execute(rql + ','.join('X %s %%(%s)s' % (attr, attr)
ef54ea75a642 [server] drop repo.internal_session and InternalSession
Julien Cristau <julien.cristau@logilab.fr>
parents: 10342
diff changeset
   619
                                              for attr in query_attrs),
ef54ea75a642 [server] drop repo.internal_session and InternalSession
Julien Cristau <julien.cristau@logilab.fr>
parents: 10342
diff changeset
   620
                               query_attrs)
6390
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   621
            return rset.rows
3766853656d7 [repo] add a find_users method for under-privileged accounts
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6368
diff changeset
   622
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   623
    # session handling ########################################################
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   624
9113
af6efc15fc90 [repository] add an ``internal_cnx`` method to replace ``internal_session``
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9105
diff changeset
   625
    @contextmanager
9127
aff75b69db92 [repository] drop safe attribute on ``internal_cnx``
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9113
diff changeset
   626
    def internal_cnx(self):
9747
10108d9f502a [repo] make it clear in internal_cnx that security is disabled
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9687
diff changeset
   627
        """Context manager returning a Connection using internal user which have
10108d9f502a [repo] make it clear in internal_cnx that security is disabled
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9687
diff changeset
   628
        every access rights on the repository.
9113
af6efc15fc90 [repository] add an ``internal_cnx`` method to replace ``internal_session``
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9105
diff changeset
   629
12034
e7e469d0539b [cleanup] Drop references to the old internal_session method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12030
diff changeset
   630
        Internal connections have all hooks beside security enabled.
9113
af6efc15fc90 [repository] add an ``internal_cnx`` method to replace ``internal_session``
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9105
diff changeset
   631
        """
12043
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
   632
        with Connection(self, InternalManager()) as cnx:
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   633
            cnx.user._cw = cnx  # XXX remove when "vreg = user._cw.vreg" hack in entity.py is gone
11204
71057a8bb19a [session] drop session-as-a-context-manager
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 11199
diff changeset
   634
            with cnx.security_enabled(read=False, write=False):
71057a8bb19a [session] drop session-as-a-context-manager
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 11199
diff changeset
   635
                yield cnx
9113
af6efc15fc90 [repository] add an ``internal_cnx`` method to replace ``internal_session``
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9105
diff changeset
   636
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   637
    # data sources handling ###################################################
11763
39df042f4ab4 [repository] Drop type_and_source_from_eid and rename related cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11756
diff changeset
   638
    # * correspondance between eid and type
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   639
    # * correspondance between eid and local id (i.e. specific to a given source)
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   640
12061
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   641
    def clear_caches(self, eids=None):
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   642
        if eids is None:
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   643
            self._type_cache = {}
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   644
            etypes = None
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   645
        else:
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   646
            etypes = []
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   647
            etcache = self._type_cache
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   648
            for eid in eids:
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   649
                try:
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   650
                    etype = etcache.pop(int(eid))  # may be a string in some cases
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   651
                except KeyError:
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   652
                    etype = None
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   653
                etypes.append(etype)
12062
601d65193619 [repo] Introduce a clear_caches method on the Querier class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12061
diff changeset
   654
        self.querier.clear_caches(eids, etypes)
12061
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12060
diff changeset
   655
        self.system_source.clear_caches(eids, etypes)
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   656
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   657
    def type_from_eid(self, eid, cnx):
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   658
        """Return the type of the entity with id `eid`"""
11763
39df042f4ab4 [repository] Drop type_and_source_from_eid and rename related cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11756
diff changeset
   659
        try:
39df042f4ab4 [repository] Drop type_and_source_from_eid and rename related cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11756
diff changeset
   660
            eid = int(eid)
39df042f4ab4 [repository] Drop type_and_source_from_eid and rename related cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11756
diff changeset
   661
        except ValueError:
39df042f4ab4 [repository] Drop type_and_source_from_eid and rename related cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11756
diff changeset
   662
            raise UnknownEid(eid)
39df042f4ab4 [repository] Drop type_and_source_from_eid and rename related cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11756
diff changeset
   663
        try:
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   664
            return self._type_cache[eid]
11763
39df042f4ab4 [repository] Drop type_and_source_from_eid and rename related cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11756
diff changeset
   665
        except KeyError:
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   666
            etype = self.system_source.eid_type(cnx, eid)
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   667
            self._type_cache[eid] = etype
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   668
            return etype
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   669
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   670
    def add_info(self, cnx, entity, source):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   671
        """add type and source info for an eid into the system table,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   672
        and index the entity with the full text index
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   673
        """
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   674
        # begin by inserting eid/type/source into the entities table
10315
0f3489d622ba [repository] replace session with cnx in a few places
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   675
        hook.CleanupNewEidsCacheOp.get_instance(cnx).add_data(entity.eid)
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   676
        self.system_source.add_info(cnx, entity, source)
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   677
10315
0f3489d622ba [repository] replace session with cnx in a few places
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   678
    def _delete_cascade_multi(self, cnx, entities):
10203
1443fe643a38 [server] change order of entities table modification vs entity creation/deletion
Julien Cristau <julien.cristau@logilab.fr>
parents: 10110
diff changeset
   679
        """same as _delete_cascade but accepts a list of entities with
1443fe643a38 [server] change order of entities table modification vs entity creation/deletion
Julien Cristau <julien.cristau@logilab.fr>
parents: 10110
diff changeset
   680
        the same etype and belonging to the same source.
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6801
diff changeset
   681
        """
10315
0f3489d622ba [repository] replace session with cnx in a few places
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   682
        pendingrtypes = cnx.transaction_data.get('pendingrtypes', ())
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6801
diff changeset
   683
        # delete remaining relations: if user can delete the entity, he can
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6801
diff changeset
   684
        # delete all its relations without security checking
10315
0f3489d622ba [repository] replace session with cnx in a few places
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   685
        with cnx.security_enabled(read=False, write=False):
7895
0a967180794b cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7887
diff changeset
   686
            in_eids = ','.join([str(_e.eid) for _e in entities])
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   687
            with cnx.running_hooks_ops():
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   688
                for rschema, _, role in entities[0].e_schema.relation_definitions():
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   689
                    if rschema.rule:
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   690
                        continue  # computed relation
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   691
                    rtype = rschema.type
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   692
                    if rtype in schema.VIRTUAL_RTYPES or rtype in pendingrtypes:
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   693
                        continue
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   694
                    if role == 'subject':
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   695
                        # don't skip inlined relation so they are regularly
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   696
                        # deleted and so hooks are correctly called
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   697
                        rql = 'DELETE X %s Y WHERE X eid IN (%s)' % (rtype, in_eids)
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   698
                    else:
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   699
                        rql = 'DELETE Y %s X WHERE X eid IN (%s)' % (rtype, in_eids)
11962
36851c8b6763 [server] Remove pseudo-handling of exceptions in Repository._delete_cascade_multi()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11950
diff changeset
   700
                    cnx.execute(rql, build_descr=False)
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6801
diff changeset
   701
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   702
    def init_entity_caches(self, cnx, entity, source):
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   703
        """Add entity to connection entities cache and repo's cache."""
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   704
        cnx.set_entity_cache(entity)
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   705
        self._type_cache[entity.eid] = entity.cw_etype
5068
10c3422d7419 [repo] on add entity, set cache as soon as possible + fill type/source cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5067
diff changeset
   706
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   707
    def glob_add_entity(self, cnx, edited):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   708
        """add an entity to the repository
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   709
10039
1d1afe3b5081 [server] typo fix
Julien Cristau <julien.cristau@logilab.fr>
parents: 10018
diff changeset
   710
        the entity eid should originally be None and a unique eid is assigned to
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   711
        the entity instance
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   712
        """
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   713
        entity = edited.entity
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   714
        entity._cw_is_saved = False  # entity has an eid but is not yet saved
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   715
        # init edited_attributes before calling before_add_entity hooks
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   716
        entity.cw_edited = edited
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   717
        source = self.system_source
5072
072ae171aeb0 [cleanup] style fixes, add nodes, 0.2 cents refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5068
diff changeset
   718
        # allocate an eid to the entity before calling hooks
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   719
        entity.eid = self.system_source.create_eid(cnx)
5068
10c3422d7419 [repo] on add entity, set cache as soon as possible + fill type/source cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5067
diff changeset
   720
        # set caches asap
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   721
        self.init_entity_caches(cnx, entity, source)
2600
6cd6c5d11b45 [F repo debugging] log repo event on DBG_REPO debug level
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2596
diff changeset
   722
        if server.DEBUG & server.DBG_REPO:
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 10579
diff changeset
   723
            print('ADD entity', self, entity.cw_etype, entity.eid, edited)
8456
c912d82f2166 [repository] drop unused argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8433
diff changeset
   724
        prefill_entity_caches(entity)
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   725
        self.hm.call_hooks('before_add_entity', cnx, entity=entity)
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   726
        relations = preprocess_inlined_relations(cnx, entity)
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   727
        edited.set_defaults()
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   728
        if cnx.is_hook_category_activated('integrity'):
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   729
            edited.check(creation=True)
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11767
diff changeset
   730
        self.add_info(cnx, entity, source)
6211
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6189
diff changeset
   731
        try:
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   732
            source.add_entity(cnx, entity)
10446
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10368
diff changeset
   733
        except (UniqueTogetherError, ViolatedConstraint) as exc:
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   734
            userhdlr = cnx.vreg['adapters'].select(
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   735
                'IUserFriendlyError', cnx, entity=entity, exc=exc)
6465
6401a9d0b5aa [architecture] introduce adapter to ease transformation of errors before display to the end user. Use it for UniqueTogetherError first
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6464
diff changeset
   736
            userhdlr.raise_user_exception()
6368
f907cc7f2875 [repo] properly mark object as saved once added to its source (code much probably gone during a merge...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6333
diff changeset
   737
        edited.saved = entity._cw_is_saved = True
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   738
        # trigger after_add_entity after after_add_relation
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   739
        self.hm.call_hooks('after_add_entity', cnx, entity=entity)
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   740
        # call hooks for inlined relations
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   741
        for attr, value in relations:
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   742
            self.hm.call_hooks('before_add_relation', cnx,
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   743
                               eidfrom=entity.eid, rtype=attr, eidto=value)
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   744
            self.hm.call_hooks('after_add_relation', cnx,
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   745
                               eidfrom=entity.eid, rtype=attr, eidto=value)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   746
        return entity.eid
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   747
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   748
    def glob_update_entity(self, cnx, edited):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   749
        """replace an entity in the repository
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   750
        the type and the eid of an entity must not be changed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   751
        """
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   752
        entity = edited.entity
2600
6cd6c5d11b45 [F repo debugging] log repo event on DBG_REPO debug level
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2596
diff changeset
   753
        if server.DEBUG & server.DBG_REPO:
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 10579
diff changeset
   754
            print('UPDATE entity', entity.cw_etype, entity.eid,
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 10579
diff changeset
   755
                  entity.cw_attr_cache, edited)
5115
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   756
        hm = self.hm
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   757
        eschema = entity.e_schema
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   758
        cnx.set_entity_cache(entity)
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   759
        orig_edited = getattr(entity, 'cw_edited', None)
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   760
        entity.cw_edited = edited
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   761
        source = self.system_source
5115
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   762
        try:
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   763
            only_inline_rels, need_fti_update = True, False
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   764
            relations = []
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   765
            for attr in list(edited):
5115
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   766
                if attr == 'eid':
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   767
                    continue
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   768
                rschema = eschema.subjrels[attr]
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   769
                if rschema.final:
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   770
                    if getattr(eschema.rdef(attr), 'fulltextindexed', False):
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   771
                        need_fti_update = True
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   772
                    only_inline_rels = False
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   773
                else:
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   774
                    # inlined relation
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   775
                    previous_value = entity.related(attr) or None
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   776
                    if previous_value is not None:
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   777
                        previous_value = previous_value[0][0]  # got a result set
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   778
                        if previous_value == entity.cw_attr_cache[attr]:
5115
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   779
                            previous_value = None
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   780
                        else:
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   781
                            hm.call_hooks('before_delete_relation', cnx,
5115
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   782
                                          eidfrom=entity.eid, rtype=attr,
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   783
                                          eidto=previous_value)
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   784
                    relations.append((attr, edited[attr], previous_value))
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   785
            # call hooks for inlined relations
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   786
            for attr, value, _t in relations:
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   787
                hm.call_hooks('before_add_relation', cnx,
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   788
                              eidfrom=entity.eid, rtype=attr, eidto=value)
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   789
            if not only_inline_rels:
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   790
                hm.call_hooks('before_update_entity', cnx, entity=entity)
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   791
            if cnx.is_hook_category_activated('integrity'):
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   792
                edited.check()
6211
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6189
diff changeset
   793
            try:
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   794
                source.update_entity(cnx, entity)
6225
a176e68b7d0d backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142 6211
diff changeset
   795
                edited.saved = True
10446
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10368
diff changeset
   796
            except (UniqueTogetherError, ViolatedConstraint) as exc:
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   797
                userhdlr = cnx.vreg['adapters'].select(
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   798
                    'IUserFriendlyError', cnx, entity=entity, exc=exc)
9226
653f1d4a1101 [repository] properly use IUserFriendlyError when UniqueTogetherError is raised during entity update. Closes #3096638
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9184
diff changeset
   799
                userhdlr.raise_user_exception()
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   800
            self.system_source.update_info(cnx, entity, need_fti_update)
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   801
            if not only_inline_rels:
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   802
                hm.call_hooks('after_update_entity', cnx, entity=entity)
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   803
            for attr, value, prevvalue in relations:
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   804
                # if the relation is already cached, update existant cache
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   805
                relcache = entity.cw_relation_cached(attr, 'subject')
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   806
                if prevvalue is not None:
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   807
                    hm.call_hooks('after_delete_relation', cnx,
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   808
                                  eidfrom=entity.eid, rtype=attr, eidto=prevvalue)
5115
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   809
                    if relcache is not None:
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   810
                        cnx.update_rel_cache_del(entity.eid, attr, prevvalue)
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   811
                del_existing_rel_if_needed(cnx, entity.eid, attr, value)
9770
112c884b2d8d merge 3.18.5 into 3.19 branch
Julien Cristau <julien.cristau@logilab.fr>
parents: 9757 9769
diff changeset
   812
                cnx.update_rel_cache_add(entity.eid, attr, value)
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   813
                hm.call_hooks('after_add_relation', cnx,
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   814
                              eidfrom=entity.eid, rtype=attr, eidto=value)
5115
2e43ef618d14 [repository] forbid usage of set_attributes() in before_add_entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   815
        finally:
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   816
            if orig_edited is not None:
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6139
diff changeset
   817
                entity.cw_edited = orig_edited
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   818
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   819
    def glob_delete_entities(self, cnx, eids):
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6801
diff changeset
   820
        """delete a list of  entities and all related entities from the repository"""
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   821
        # mark eids as being deleted in cnx info and setup cache update
7501
2983dd24494a [repository] refactor/cleanup entity deletion methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7373
diff changeset
   822
        # operation (register pending eids before actual deletion to avoid
2983dd24494a [repository] refactor/cleanup entity deletion methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7373
diff changeset
   823
        # multiple call to glob_delete_entities)
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   824
        op = hook.CleanupDeletedEidsCacheOp.get_instance(cnx)
7501
2983dd24494a [repository] refactor/cleanup entity deletion methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7373
diff changeset
   825
        eids = eids - op._container
2983dd24494a [repository] refactor/cleanup entity deletion methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7373
diff changeset
   826
        op._container |= eids
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   827
        data_by_etype = {}  # values are [list of entities]
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6801
diff changeset
   828
        #
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6801
diff changeset
   829
        # WARNING: the way this dictionary is populated is heavily optimized
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6801
diff changeset
   830
        # and does not use setdefault on purpose. Unless a new release
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6801
diff changeset
   831
        # of the Python interpreter advertises large perf improvements
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6801
diff changeset
   832
        # in setdefault, this should not be changed without profiling.
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6801
diff changeset
   833
        for eid in eids:
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   834
            etype = self.type_from_eid(eid, cnx)
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   835
            entity = cnx.entity_from_eid(eid, etype)
7501
2983dd24494a [repository] refactor/cleanup entity deletion methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7373
diff changeset
   836
            try:
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   837
                data_by_etype[etype].append(entity)
7501
2983dd24494a [repository] refactor/cleanup entity deletion methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7373
diff changeset
   838
            except KeyError:
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   839
                data_by_etype[etype] = [entity]
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   840
        source = self.system_source
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10609
diff changeset
   841
        for etype, entities in data_by_etype.items():
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6801
diff changeset
   842
            if server.DEBUG & server.DBG_REPO:
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11204
diff changeset
   843
                print('DELETE entities', etype, [e.eid for e in entities])
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   844
            self.hm.call_hooks('before_delete_entity', cnx, entities=entities)
10203
1443fe643a38 [server] change order of entities table modification vs entity creation/deletion
Julien Cristau <julien.cristau@logilab.fr>
parents: 10110
diff changeset
   845
            self._delete_cascade_multi(cnx, entities)
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   846
            source.delete_entities(cnx, entities)
10203
1443fe643a38 [server] change order of entities table modification vs entity creation/deletion
Julien Cristau <julien.cristau@logilab.fr>
parents: 10110
diff changeset
   847
            source.delete_info_multi(cnx, entities)
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   848
            self.hm.call_hooks('after_delete_entity', cnx, entities=entities)
7501
2983dd24494a [repository] refactor/cleanup entity deletion methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7373
diff changeset
   849
        # don't clear cache here, it is done in a hook on commit
1482
93c613913912 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   850
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   851
    def glob_add_relation(self, cnx, subject, rtype, object):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   852
        """add a relation to the repository"""
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   853
        self.glob_add_relations(cnx, {rtype: [(subject, object)]})
7237
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7134
diff changeset
   854
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   855
    def glob_add_relations(self, cnx, relations):
7237
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7134
diff changeset
   856
        """add several relations to the repository
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7134
diff changeset
   857
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7134
diff changeset
   858
        relations is a dictionary rtype: [(subj_eid, obj_eid), ...]
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7134
diff changeset
   859
        """
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   860
        source = self.system_source
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   861
        relations_by_rtype = {}
7513
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   862
        subjects_by_types = {}
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   863
        objects_by_types = {}
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   864
        activintegrity = cnx.is_hook_category_activated('activeintegrity')
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10609
diff changeset
   865
        for rtype, eids_subj_obj in relations.items():
7237
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7134
diff changeset
   866
            if server.DEBUG & server.DBG_REPO:
8548
eeabc752c32e [repo] fix debug code in DBG_REPO mode (closes #2469942)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8547
diff changeset
   867
                for subjeid, objeid in eids_subj_obj:
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 10579
diff changeset
   868
                    print('ADD relation', subjeid, rtype, objeid)
7513
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   869
            for subjeid, objeid in eids_subj_obj:
12240
8eb15566142f [server] Use dict.setdefault() instead of if/else in repo.glob_add_relations()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12148
diff changeset
   870
                relations_by_rtype.setdefault(rtype, []).append((subjeid, objeid))
7513
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   871
                if not activintegrity:
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   872
                    continue
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   873
                # take care to relation of cardinality '?1', as all eids will
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   874
                # be inserted later, we've remove duplicated eids since they
10510
51321946da37 Spelling fixes in comments and docstrings
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10488
diff changeset
   875
                # won't be caught by `del_existing_rel_if_needed`
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   876
                rdef = cnx.rtype_eids_rdef(rtype, subjeid, objeid)
7513
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   877
                card = rdef.cardinality
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   878
                if card[0] in '?1':
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   879
                    with cnx.security_enabled(read=False):
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   880
                        cnx.execute('DELETE X %s Y WHERE X eid %%(x)s, '
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   881
                                    'NOT Y eid %%(y)s' % rtype,
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   882
                                    {'x': subjeid, 'y': objeid})
7513
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   883
                    subjects = subjects_by_types.setdefault(rdef, {})
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   884
                    if subjeid in subjects:
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   885
                        del relations_by_rtype[rtype][subjects[subjeid]]
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   886
                        subjects[subjeid] = len(relations_by_rtype[rtype]) - 1
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   887
                        continue
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   888
                    subjects[subjeid] = len(relations_by_rtype[rtype]) - 1
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   889
                if card[1] in '?1':
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   890
                    with cnx.security_enabled(read=False):
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   891
                        cnx.execute('DELETE X %s Y WHERE Y eid %%(y)s, '
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   892
                                    'NOT X eid %%(x)s' % rtype,
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   893
                                    {'x': subjeid, 'y': objeid})
7513
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   894
                    objects = objects_by_types.setdefault(rdef, {})
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   895
                    if objeid in objects:
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   896
                        del relations_by_rtype[rtype][objects[objeid]]
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   897
                        objects[objeid] = len(relations_by_rtype[rtype])
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   898
                        continue
8f4422391e5a [repo integrity] test and fix glob add relation where several entities are added at once for a relation of 1? cardinality
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7507
diff changeset
   899
                    objects[objeid] = len(relations_by_rtype[rtype])
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10609
diff changeset
   900
        for rtype, source_relations in relations_by_rtype.items():
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   901
            self.hm.call_hooks('before_add_relation', cnx,
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   902
                               rtype=rtype, eids_from_to=source_relations)
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10609
diff changeset
   903
        for rtype, source_relations in relations_by_rtype.items():
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   904
            source.add_relations(cnx, rtype, source_relations)
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   905
            rschema = self.schema.rschema(rtype)
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   906
            for subjeid, objeid in source_relations:
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   907
                cnx.update_rel_cache_add(subjeid, rtype, objeid, rschema.symmetric)
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10609
diff changeset
   908
        for rtype, source_relations in relations_by_rtype.items():
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   909
            self.hm.call_hooks('after_add_relation', cnx,
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   910
                               rtype=rtype, eids_from_to=source_relations)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   911
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   912
    def glob_delete_relation(self, cnx, subject, rtype, object):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   913
        """delete a relation from the repository"""
2600
6cd6c5d11b45 [F repo debugging] log repo event on DBG_REPO debug level
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2596
diff changeset
   914
        if server.DEBUG & server.DBG_REPO:
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 10579
diff changeset
   915
            print('DELETE relation', subject, rtype, object)
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   916
        source = self.system_source
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   917
        self.hm.call_hooks('before_delete_relation', cnx,
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   918
                           eidfrom=subject, rtype=rtype, eidto=object)
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   919
        source.delete_relation(cnx, subject, rtype, object)
2647
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2641
diff changeset
   920
        rschema = self.schema.rschema(rtype)
9609
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   921
        cnx.update_rel_cache_del(subject, rtype, object, rschema.symmetric)
e7d38148799e [repository] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9607
diff changeset
   922
        self.hm.call_hooks('after_delete_relation', cnx,
9454
a173f9cf9f26 [multi-sources-removal] drop source location search on glob_*[entity|relation] methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   923
                           eidfrom=subject, rtype=rtype, eidto=object)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   924
7083
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7064
diff changeset
   925
    # these are overridden by set_log_methods below
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7064
diff changeset
   926
    # only defining here to prevent pylint from complaining
9468
39b7a91a3f4c [repo] pylint cleanup, mainly of imports, with a bit of style
Julien Cristau <julien.cristau@logilab.fr>
parents: 9467
diff changeset
   927
    info = warning = error = critical = exception = debug = lambda msg, *a, **kw: None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   928
11821
7534b32c45e3 Fix (new) flake8 errors
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11819
diff changeset
   929
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   930
set_log_methods(Repository, getLogger('cubicweb.repository'))