cubicweb/server/sources/native.py
author Nicolas Chauvat <nicolas.chauvat@logilab.fr>
Wed, 13 Mar 2019 11:02:39 +0100
changeset 12887 11953d585a55
parent 12885 194e9ae964ed
permissions -rw-r--r--
[server.querier] remove useless indirection Querier.rqlannotator
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11413
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
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: 5413
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: 5413
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: 5413
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: 5413
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: 5413
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: 5413
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: 5413
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: 5413
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: 5413
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: 5413
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: 5413
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: 5413
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: 5413
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: 5413
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: 5413
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11773
diff changeset
    18
"""Adapters for native cubicweb sources."""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
4900
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4893
diff changeset
    20
from threading import Lock
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 973
diff changeset
    21
from datetime import datetime
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
    22
from contextlib import contextmanager
9468
39b7a91a3f4c [repo] pylint cleanup, mainly of imports, with a bit of style
Julien Cristau <julien.cristau@logilab.fr>
parents: 9467
diff changeset
    23
from os.path import basename
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
    24
import pickle
6211
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
    25
import re
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
    26
import itertools
12765
771c99f16780 [debug-toolbar] add sql panel
Laurent Peuch <cortex@worlddomination.be>
parents: 12761
diff changeset
    27
import traceback
12761
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
    28
import time
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
    29
import zipfile
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
    30
import logging
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
    31
import sys
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
    33
from logilab.common.decorators import cached, clear_cache
3835
a191b3b9e455 more sensible default values to c-c "create" inputs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
    34
from logilab.common.configuration import Method
11060
3699fca78836 [sources/native] ask permission to continue restoring even if metadata do not match (closes #7771864)
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 10623
diff changeset
    35
from logilab.common.shellutils import getlogin, ASK
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
    36
from logilab.database import get_db_helper, sqlgen
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
6945
28bf94d062a9 [sources] refactor source creation and options handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6931
diff changeset
    38
from yams.schema import role_name
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
    39
6945
28bf94d062a9 [sources] refactor source creation and options handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6931
diff changeset
    40
from cubicweb import (UnknownEid, AuthenticationError, ValidationError, Binary,
10446
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10411
diff changeset
    41
                      UniqueTogetherError, UndoTransactionException, ViolatedConstraint)
12149
649100470733 [sources] Stop translating validation error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12148
diff changeset
    42
from cubicweb import transaction as tx, server, neg_role, _
7954
a3d3220669d6 [cache] replace lgc.cache with something more appropriate (closes #1921713)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7922
diff changeset
    43
from cubicweb.utils import QueryCache
12761
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
    44
from cubicweb.debug import emit_to_debug_channel
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    45
from cubicweb.schema import VIRTUAL_RTYPES
3835
a191b3b9e455 more sensible default values to c-c "create" inputs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
    46
from cubicweb.cwconfig import CubicWebNoAppConfiguration
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
    47
from cubicweb.server import hook
10200
cceb2c7c02f4 Use our version of schema2sql
Julien Cristau <julien.cristau@logilab.fr>
parents: 10187
diff changeset
    48
from cubicweb.server import schema2sql as y2sql
11091
29aebc1edd29 [repository] drop usage of no more necessary eschema_eid function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11005
diff changeset
    49
from cubicweb.server.utils import crypt_password, verify_and_update
2759
23d7a75693f8 R refactor backup and use tar.gz to store all sources
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2638
diff changeset
    50
from cubicweb.server.sqlutils import SQL_PREFIX, SQLAdapterMixIn
12887
11953d585a55 [server.querier] remove useless indirection Querier.rqlannotator
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12885
diff changeset
    51
from cubicweb.server.rqlannotation import RQLAnnotator, set_qdata
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
    52
from cubicweb.server.hook import CleanupDeletedEidsCacheOp
7118
e094b3d4eb95 [server] move EditedEntity class to its own module, to avoid cyclic dependency when needed from e.g. session.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6957
diff changeset
    53
from cubicweb.server.edition import EditedEntity
12883
d5bbf030f967 [server/sources/native] refactor to remove useless injection
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12842
diff changeset
    54
from cubicweb.server.sources import AbstractSource, dbg_st_search, dbg_results, rql2sql
12758
db95a417a5ec [debug/source_highlight] rename highlight to highlight_terminal
Laurent Peuch <cortex@worlddomination.be>
parents: 12756
diff changeset
    55
from cubicweb.misc.source_highlight import highlight_terminal
10477
ee21c559f94f implement a simple statsd logger (closes #5488711)
David Douard <david.douard@logilab.fr>
parents: 10473
diff changeset
    56
from cubicweb.statsd_logger import statsd_timeit
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
2354
9b4bac626977 ability to map attributes to something else than usual cw mapping on sql generation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2310
diff changeset
    59
ATTR_MAP = {}
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
NONSYSTEM_ETYPES = set()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
NONSYSTEM_RELATIONS = set()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
    63
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
class LogCursor(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
    def __init__(self, cursor):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
        self.cu = cursor
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    67
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
    def execute(self, query, args=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
        """Execute a query.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
        it's a function just so that it shows up in profiling
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
        """
2593
16d9419a4a79 F: start to handle binary debug log level on the server side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
    72
        if server.DEBUG & server.DBG_SQL:
12758
db95a417a5ec [debug/source_highlight] rename highlight to highlight_terminal
Laurent Peuch <cortex@worlddomination.be>
parents: 12756
diff changeset
    73
            print('exec', highlight_terminal(query, "SQL"), args)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
            self.cu.execute(str(query), args)
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8694
diff changeset
    76
        except Exception as ex:
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 10580
diff changeset
    77
            print("sql: %r\n args: %s\ndbms message: %r" % (
12758
db95a417a5ec [debug/source_highlight] rename highlight to highlight_terminal
Laurent Peuch <cortex@worlddomination.be>
parents: 12756
diff changeset
    78
                highlight_terminal(query, "SQL"), args, ex.args[0]))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
            raise
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    80
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
    def fetchall(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
        return self.cu.fetchall()
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    83
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
    def fetchone(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
        return self.cu.fetchone()
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    86
2625
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
    87
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    88
def sql_or_clauses(sql, clauses):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    89
    select, restr = sql.split(' WHERE ', 1)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    90
    restrclauses = restr.split(' AND ')
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    91
    for clause in clauses:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    92
        restrclauses.remove(clause)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    93
    if restrclauses:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    94
        restr = '%s AND (%s)' % (' AND '.join(restrclauses),
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    95
                                 ' OR '.join(clauses))
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    96
    else:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    97
        restr = '(%s)' % ' OR '.join(clauses)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    98
    return '%s WHERE %s' % (select, restr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    99
9450
af4b93bc38a5 [multi-sources-removal] Drop deleted_entities system table and entities.mtime column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9448
diff changeset
   100
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   101
def rdef_table_column(rdef):
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   102
    """return table and column used to store the given relation definition in
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   103
    the database
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   104
    """
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   105
    return (SQL_PREFIX + str(rdef.subject),
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   106
            SQL_PREFIX + str(rdef.rtype))
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   107
9450
af4b93bc38a5 [multi-sources-removal] Drop deleted_entities system table and entities.mtime column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9448
diff changeset
   108
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   109
def rdef_physical_info(dbhelper, rdef):
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   110
    """return backend type and a boolean flag if NULL values should be allowed
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   111
    for a given relation definition
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   112
    """
11005
f8417bd135ed [server, hooks] allow callable in dbh.TYPE_MAPPING
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10915
diff changeset
   113
    if not rdef.object.final:
f8417bd135ed [server, hooks] allow callable in dbh.TYPE_MAPPING
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10915
diff changeset
   114
        return dbhelper.TYPE_MAPPING['Int']
11359
2da2dd60331c [sql gen] Explicitly name unique index
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11351
diff changeset
   115
    coltype = y2sql.type_from_rdef(dbhelper, rdef)
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   116
    allownull = rdef.cardinality[0] != '1'
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   117
    return coltype, allownull
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   118
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
   119
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
   120
class _UndoException(Exception):
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   121
    """something went wrong during undoing"""
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   122
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   123
    def __str__(self):
7530
15178bf89fb6 [server] fix unicode conversion capability in UndoException
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 7507
diff changeset
   124
        """Called by the unicode builtin; should return a Unicode object
15178bf89fb6 [server] fix unicode conversion capability in UndoException
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 7507
diff changeset
   125
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
   126
        Type of _UndoException message must be `unicode` by design in CubicWeb.
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
   127
        """
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
   128
        return self.args[0]
7530
15178bf89fb6 [server] fix unicode conversion capability in UndoException
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 7507
diff changeset
   129
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   130
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   131
def _undo_check_relation_target(tentity, rdef, role):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   132
    """check linked entity has not been redirected for this relation"""
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   133
    card = rdef.role_cardinality(role)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   134
    if card in '?1' and tentity.related(rdef.rtype, role):
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   135
        msg = tentity._cw._(
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   136
            "Can't restore %(role)s relation %(rtype)s to entity %(eid)s which "
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   137
            "is already linked using this relation.")
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   138
        raise _UndoException(msg % {'role': neg_role(role),
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   139
                                    'rtype': rdef.rtype,
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   140
                                    'eid': tentity.eid})
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   141
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   142
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   143
def _undo_rel_info(cnx, subj, rtype, obj):
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   144
    entities = []
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   145
    for role, eid in (('subject', subj), ('object', obj)):
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   146
        try:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   147
            entities.append(cnx.entity_from_eid(eid))
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   148
        except UnknownEid:
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   149
            msg = cnx._(
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   150
                "Can't restore relation %(rtype)s, %(role)s entity %(eid)s"
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   151
                " doesn't exist anymore.")
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   152
            raise _UndoException(msg % {'role': cnx._(role),
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   153
                                        'rtype': cnx._(rtype),
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   154
                                        'eid': eid})
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   155
    sentity, oentity = entities
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   156
    try:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   157
        rschema = cnx.vreg.schema.rschema(rtype)
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8821
diff changeset
   158
        rdef = rschema.rdefs[(sentity.cw_etype, oentity.cw_etype)]
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   159
    except KeyError:
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   160
        msg = cnx._(
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   161
            "Can't restore relation %(rtype)s between %(subj)s and "
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   162
            "%(obj)s, that relation does not exists anymore in the "
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   163
            "schema.")
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   164
        raise _UndoException(msg % {'rtype': cnx._(rtype),
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   165
                                    'subj': subj,
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   166
                                    'obj': obj})
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   167
    return sentity, oentity, rdef
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   168
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   169
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   170
def _undo_has_later_transaction(cnx, eid):
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   171
    return cnx.system_sql('''\
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   172
SELECT T.tx_uuid FROM transactions AS TREF, transactions AS T
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   173
WHERE TREF.tx_uuid='%(txuuid)s' AND T.tx_uuid!='%(txuuid)s'
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   174
AND T.tx_time>=TREF.tx_time
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   175
AND (EXISTS(SELECT 1 FROM tx_entity_actions AS TEA
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   176
            WHERE TEA.tx_uuid=T.tx_uuid AND TEA.eid=%(eid)s)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   177
     OR EXISTS(SELECT 1 FROM tx_relation_actions as TRA
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   178
               WHERE TRA.tx_uuid=T.tx_uuid AND (
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   179
                   TRA.eid_from=%(eid)s OR TRA.eid_to=%(eid)s))
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   180
     )''' % {'txuuid': cnx.transaction_data['undoing_uuid'],
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   181
             'eid': eid}).fetchone()
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   182
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   183
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   184
class DefaultEidGenerator(object):
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   185
    __slots__ = ('source', 'cnx', 'lock')
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   186
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   187
    def __init__(self, source):
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   188
        self.source = source
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   189
        self.cnx = None
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   190
        self.lock = Lock()
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   191
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   192
    def close(self):
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   193
        if self.cnx:
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   194
            self.cnx.close()
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   195
        self.cnx = None
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   196
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   197
    def create_eid(self, _cnx, count=1):
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   198
        # lock needed to prevent 'Connection is busy with results for another
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   199
        # command (0)' errors with SQLServer
9585
3f5b59527d31 [source/native] allow many eid creation per .create_eid call (closes #3526594)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9583
diff changeset
   200
        assert count > 0
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   201
        with self.lock:
9585
3f5b59527d31 [source/native] allow many eid creation per .create_eid call (closes #3526594)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9583
diff changeset
   202
            return self._create_eid(count)
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   203
9585
3f5b59527d31 [source/native] allow many eid creation per .create_eid call (closes #3526594)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9583
diff changeset
   204
    def _create_eid(self, count):
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   205
        # internal function doing the eid creation without locking.
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   206
        # needed for the recursive handling of disconnections (otherwise we
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   207
        # deadlock on self._eid_cnx_lock
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   208
        source = self.source
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   209
        if self.cnx is None:
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   210
            self.cnx = source.get_connection()
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   211
        cnx = self.cnx
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   212
        try:
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   213
            cursor = cnx.cursor()
9585
3f5b59527d31 [source/native] allow many eid creation per .create_eid call (closes #3526594)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9583
diff changeset
   214
            for sql in source.dbhelper.sqls_increment_numrange('entities_id_seq', count):
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   215
                cursor.execute(sql)
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   216
            eid = cursor.fetchone()[0]
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   217
        except (source.OperationalError, source.InterfaceError):
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   218
            # FIXME: better detection of deconnection pb
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   219
            source.warning("trying to reconnect create eid connection")
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   220
            self.cnx = None
9585
3f5b59527d31 [source/native] allow many eid creation per .create_eid call (closes #3526594)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9583
diff changeset
   221
            return self._create_eid(count)
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   222
        except source.DbapiError as exc:
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   223
            # We get this one with pyodbc and SQL Server when connection was reset
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   224
            if exc.args[0] == '08S01':
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   225
                source.warning("trying to reconnect create eid connection")
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   226
                self.cnx = None
9585
3f5b59527d31 [source/native] allow many eid creation per .create_eid call (closes #3526594)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9583
diff changeset
   227
                return self._create_eid(count)
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   228
            else:
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   229
                raise
12156
0d1d22a3a48b Fix some flake8 errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12153
diff changeset
   230
        except Exception:  # WTF?
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   231
            cnx.rollback()
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   232
            self.cnx = None
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   233
            source.exception('create eid failed in an unforeseen way on SQL statement %s', sql)
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   234
            raise
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   235
        else:
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   236
            cnx.commit()
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   237
            return eid
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   238
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   239
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   240
class SQLITEEidGenerator(object):
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   241
    __slots__ = ('source', 'lock')
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   242
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   243
    def __init__(self, source):
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   244
        self.source = source
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   245
        self.lock = Lock()
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   246
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   247
    def close(self):
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   248
        pass
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   249
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   250
    def create_eid(self, cnx, count=1):
9585
3f5b59527d31 [source/native] allow many eid creation per .create_eid call (closes #3526594)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9583
diff changeset
   251
        assert count > 0
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   252
        source = self.source
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   253
        with self.lock:
9585
3f5b59527d31 [source/native] allow many eid creation per .create_eid call (closes #3526594)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9583
diff changeset
   254
            for sql in source.dbhelper.sqls_increment_numrange('entities_id_seq', count):
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   255
                cursor = source.doexec(cnx, sql)
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   256
            return cursor.fetchone()[0]
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   257
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   258
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   259
class NativeSQLSource(SQLAdapterMixIn, AbstractSource):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
    """adapter for source using the native cubicweb schema (see below)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
    """
12883
d5bbf030f967 [server/sources/native] refactor to remove useless injection
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12842
diff changeset
   262
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
    options = (
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   264
        ('db-driver',
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   265
         {'type': 'string',
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
          'default': 'postgres',
5423
e15abfdcce38 backport default into stable: stable is now cw 3.8
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5397 5421
diff changeset
   267
          # XXX use choice type
10221
17ad882a211f [doc] Don't pretend we know cubicweb runs on mysql
Julien Cristau <julien.cristau@logilab.fr>
parents: 10209
diff changeset
   268
          'help': 'database driver (postgres, sqlite, sqlserver2005)',
6201
cf445fcaf8fe [c-c create] ask for database driver by default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6128
diff changeset
   269
          'group': 'native-source', 'level': 0,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
          }),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   271
        ('db-host',
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   272
         {'type': 'string',
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
          'default': '',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   274
          'help': 'database host',
5323
329b4f6d18b4 [config] with lgc >= 0.50, option's dict inputlevel becomes level
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5217
diff changeset
   275
          'group': 'native-source', 'level': 1,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
          }),
2566
714a8743d423 missing db-port option to source's option definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2354
diff changeset
   277
        ('db-port',
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   278
         {'type': 'string',
2566
714a8743d423 missing db-port option to source's option definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2354
diff changeset
   279
          'default': '',
714a8743d423 missing db-port option to source's option definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2354
diff changeset
   280
          'help': 'database port',
5323
329b4f6d18b4 [config] with lgc >= 0.50, option's dict inputlevel becomes level
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5217
diff changeset
   281
          'group': 'native-source', 'level': 1,
2566
714a8743d423 missing db-port option to source's option definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2354
diff changeset
   282
          }),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   283
        ('db-name',
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   284
         {'type': 'string',
3835
a191b3b9e455 more sensible default values to c-c "create" inputs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   285
          'default': Method('default_instance_id'),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   286
          'help': 'database name',
5323
329b4f6d18b4 [config] with lgc >= 0.50, option's dict inputlevel becomes level
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5217
diff changeset
   287
          'group': 'native-source', 'level': 0,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   288
          }),
10125
bc6461a7d2da [server] add a db-namespace option in source definition (closes #1631339)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10095
diff changeset
   289
        ('db-namespace',
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   290
         {'type': 'string',
10125
bc6461a7d2da [server] add a db-namespace option in source definition (closes #1631339)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10095
diff changeset
   291
          'default': '',
bc6461a7d2da [server] add a db-namespace option in source definition (closes #1631339)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10095
diff changeset
   292
          'help': 'database namespace (schema) name',
bc6461a7d2da [server] add a db-namespace option in source definition (closes #1631339)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10095
diff changeset
   293
          'group': 'native-source', 'level': 1,
bc6461a7d2da [server] add a db-namespace option in source definition (closes #1631339)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10095
diff changeset
   294
          }),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   295
        ('db-user',
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   296
         {'type': 'string',
3835
a191b3b9e455 more sensible default values to c-c "create" inputs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   297
          'default': CubicWebNoAppConfiguration.mode == 'user' and getlogin() or 'cubicweb',
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   298
          'help': 'database user',
5323
329b4f6d18b4 [config] with lgc >= 0.50, option's dict inputlevel becomes level
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5217
diff changeset
   299
          'group': 'native-source', 'level': 0,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   300
          }),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   301
        ('db-password',
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   302
         {'type': 'password',
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   303
          'default': '',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   304
          'help': 'database password',
5323
329b4f6d18b4 [config] with lgc >= 0.50, option's dict inputlevel becomes level
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5217
diff changeset
   305
          'group': 'native-source', 'level': 0,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   306
          }),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   307
        ('db-encoding',
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   308
         {'type': 'string',
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   309
          'default': 'utf8',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   310
          'help': 'database encoding',
5323
329b4f6d18b4 [config] with lgc >= 0.50, option's dict inputlevel becomes level
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5217
diff changeset
   311
          'group': 'native-source', 'level': 1,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   312
          }),
5413
dc896e698ab0 added db-extra-arguments to configuration parameters for native source
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5410
diff changeset
   313
        ('db-extra-arguments',
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   314
         {'type': 'string',
5413
dc896e698ab0 added db-extra-arguments to configuration parameters for native source
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5410
diff changeset
   315
          'default': '',
dc896e698ab0 added db-extra-arguments to configuration parameters for native source
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5410
diff changeset
   316
          'help': 'set to "Trusted_Connection" if you are using SQLServer and '
dc896e698ab0 added db-extra-arguments to configuration parameters for native source
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5410
diff changeset
   317
                  'want trusted authentication for the database connection',
5515
513af9be9e37 [config] rename remaining inputlevel to level in option definitions, as expected by lgc >= 0.50
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   318
          'group': 'native-source', 'level': 2,
5413
dc896e698ab0 added db-extra-arguments to configuration parameters for native source
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5410
diff changeset
   319
          }),
9724
e45bf9baa7b7 Add a db-statement-timeout option for postgresql sources
Julien Cristau <julien.cristau@logilab.fr>
parents: 9664
diff changeset
   320
        ('db-statement-timeout',
e45bf9baa7b7 Add a db-statement-timeout option for postgresql sources
Julien Cristau <julien.cristau@logilab.fr>
parents: 9664
diff changeset
   321
         {'type': 'int',
e45bf9baa7b7 Add a db-statement-timeout option for postgresql sources
Julien Cristau <julien.cristau@logilab.fr>
parents: 9664
diff changeset
   322
          'default': 0,
e45bf9baa7b7 Add a db-statement-timeout option for postgresql sources
Julien Cristau <julien.cristau@logilab.fr>
parents: 9664
diff changeset
   323
          'help': 'sql statement timeout, in milliseconds (postgres only)',
e45bf9baa7b7 Add a db-statement-timeout option for postgresql sources
Julien Cristau <julien.cristau@logilab.fr>
parents: 9664
diff changeset
   324
          'group': 'native-source', 'level': 2,
e45bf9baa7b7 Add a db-statement-timeout option for postgresql sources
Julien Cristau <julien.cristau@logilab.fr>
parents: 9664
diff changeset
   325
          }),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   326
    )
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   327
6427
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
   328
    def __init__(self, repo, source_config, *args, **kwargs):
9724
e45bf9baa7b7 Add a db-statement-timeout option for postgresql sources
Julien Cristau <julien.cristau@logilab.fr>
parents: 9664
diff changeset
   329
        SQLAdapterMixIn.__init__(self, source_config, repairing=repo.config.repairing)
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   330
        self.authentifiers = [LoginPasswordAuthentifier(self)]
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: 6724
diff changeset
   331
        if repo.config['allow-email-login']:
5a0c2cfc19bf [repository auth] cleanup email login by turning it into a proper repo-side authentication plugin
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6724
diff changeset
   332
            self.authentifiers.insert(0, EmailPasswordAuthentifier(self))
6427
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
   333
        AbstractSource.__init__(self, repo, source_config, *args, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   334
        # sql generator
12883
d5bbf030f967 [server/sources/native] refactor to remove useless injection
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12842
diff changeset
   335
        self._rql_sqlgen = rql2sql.SQLGenerator(self.schema, self.dbhelper,
d5bbf030f967 [server/sources/native] refactor to remove useless injection
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12842
diff changeset
   336
                                                ATTR_MAP.copy())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   337
        # full text index helper
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   338
        self.do_fti = not repo.config['delay-full-text-indexation']
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   339
        # sql queries cache
7954
a3d3220669d6 [cache] replace lgc.cache with something more appropriate (closes #1921713)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7922
diff changeset
   340
        self._cache = QueryCache(repo.config['rql-cache-size'])
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   341
        # (etype, attr) / storage mapping
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   342
        self._storages = {}
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   343
        self.binary_to_str = self.dbhelper.dbapi_module.binary_to_str
5649
a07dee204187 fix unit tests by not using the new create_eid implementation with sqlite
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5645
diff changeset
   344
        if self.dbdriver == 'sqlite':
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   345
            self.eid_generator = SQLITEEidGenerator(self)
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   346
        else:
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   347
            self.eid_generator = DefaultEidGenerator(self)
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   348
        self.create_eid = self.eid_generator.create_eid
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   349
6945
28bf94d062a9 [sources] refactor source creation and options handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6931
diff changeset
   350
    def check_config(self, source_entity):
12152
f34d18d0603f [sources] Check sources configuration is fine on creation/modification
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12149
diff changeset
   351
        if source_entity.config:
f34d18d0603f [sources] Check sources configuration is fine on creation/modification
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12149
diff changeset
   352
            msg = _("Configuration of the system source goes to "
f34d18d0603f [sources] Check sources configuration is fine on creation/modification
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12149
diff changeset
   353
                    "the 'sources' file, not in the database")
6945
28bf94d062a9 [sources] refactor source creation and options handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6931
diff changeset
   354
            raise ValidationError(source_entity.eid, {role_name('config', 'subject'): msg})
28bf94d062a9 [sources] refactor source creation and options handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6931
diff changeset
   355
12153
0ff0aff4413d [sources] Check source's url attribute value on creation/modification
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12152
diff changeset
   356
    def check_urls(self, source_entity):
0ff0aff4413d [sources] Check source's url attribute value on creation/modification
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12152
diff changeset
   357
        if source_entity.url:
0ff0aff4413d [sources] Check source's url attribute value on creation/modification
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12152
diff changeset
   358
            msg = _("Configuration of the system source goes to "
0ff0aff4413d [sources] Check source's url attribute value on creation/modification
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12152
diff changeset
   359
                    "the 'sources' file, not in the database")
0ff0aff4413d [sources] Check source's url attribute value on creation/modification
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12152
diff changeset
   360
            raise ValidationError(source_entity.eid, {role_name('config', 'subject'): msg})
0ff0aff4413d [sources] Check source's url attribute value on creation/modification
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12152
diff changeset
   361
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   362
    def add_authentifier(self, authentifier):
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   363
        self.authentifiers.append(authentifier)
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   364
        authentifier.source = self
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   365
        authentifier.set_schema(self.schema)
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   366
12061
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11979
diff changeset
   367
    def clear_caches(self, eids, etypes):
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11979
diff changeset
   368
        """Clear potential source caches."""
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11979
diff changeset
   369
        if eids is None:
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11979
diff changeset
   370
            self._cache = QueryCache(self.repo.config['rql-cache-size'])
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11979
diff changeset
   371
        else:
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11979
diff changeset
   372
            cache = self._cache
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11979
diff changeset
   373
            for eid, etype in zip(eids, etypes):
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11979
diff changeset
   374
                cache.pop('Any X WHERE X eid %s' % eid, None)
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11979
diff changeset
   375
                cache.pop('Any %s' % eid, None)
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11979
diff changeset
   376
                if etype is not None:
94ae25593c38 [repo] Consistent API for cache clearing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11979
diff changeset
   377
                    cache.pop('Any X WHERE X eid %s, X is %s' % (eid, etype), None)
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   378
10477
ee21c559f94f implement a simple statsd logger (closes #5488711)
David Douard <david.douard@logilab.fr>
parents: 10473
diff changeset
   379
    @statsd_timeit
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   380
    def sqlexec(self, cnx, sql, args=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   381
        """execute the query and return its result"""
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   382
        return self.process_result(self.doexec(cnx, sql, args))
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   383
7398
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7342
diff changeset
   384
    def init_creating(self, cnxset=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   385
        # check full text index availibility
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   386
        if self.do_fti:
7398
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7342
diff changeset
   387
            if cnxset is None:
11931
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11926
diff changeset
   388
                _cnxset = self.repo.cnxsets.get()
6724
24bf6f181d0e [pyro source] store pyro source mapping file into the database
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6427
diff changeset
   389
            else:
7398
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7342
diff changeset
   390
                _cnxset = cnxset
9463
d62e13eba033 [multi-sources-removal] Simplify ConnectionsSet internal structures and public methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9452
diff changeset
   391
            if not self.dbhelper.has_fti_table(_cnxset.cu):
4825
cdd979ae1b57 fix name error fixed in wrong branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4818
diff changeset
   392
                if not self.repo.config.creating:
4810
3055dc7a7c88 don't issue critical warning about missing text index when we're creating the instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4807
diff changeset
   393
                    self.critical('no text index table')
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   394
                self.do_fti = False
7398
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7342
diff changeset
   395
            if cnxset is None:
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7342
diff changeset
   396
                _cnxset.cnxset_freed()
11931
ad7796dabeaa [repository] move cnxset pool handling to a helper class
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11926
diff changeset
   397
                self.repo.cnxsets.release(_cnxset)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   398
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
   399
    def backup(self, backupfile, confirm, format='native'):
2759
23d7a75693f8 R refactor backup and use tar.gz to store all sources
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2638
diff changeset
   400
        """method called to create a backup of the source's data"""
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
   401
        if format == 'portable':
8947
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8916
diff changeset
   402
            # ensure the schema is the one stored in the database: if repository
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8916
diff changeset
   403
            # started in quick_start mode, the file system's one has been loaded
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8916
diff changeset
   404
            # so force reload
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8916
diff changeset
   405
            if self.repo.config.quick_start:
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8916
diff changeset
   406
                self.repo.set_schema(self.repo.deserialize_schema(),
3bbd416b09ec [repo] straightforward bootstrap sequence. Closes #2841188
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8916
diff changeset
   407
                                     resetvreg=False)
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
   408
            helper = DatabaseIndependentBackupRestore(self)
7398
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7342
diff changeset
   409
            self.close_source_connections()
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
   410
            try:
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
   411
                helper.backup(backupfile)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
   412
            finally:
7398
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7342
diff changeset
   413
                self.open_source_connections()
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
   414
        elif format == 'native':
7398
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7342
diff changeset
   415
            self.close_source_connections()
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
   416
            try:
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
   417
                self.backup_to_file(backupfile, confirm)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
   418
            finally:
7398
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7342
diff changeset
   419
                self.open_source_connections()
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
   420
        else:
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
   421
            raise ValueError('Unknown format %r' % format)
2493
9806571ea790 major refactoring of database dump/restore:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   422
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
   423
    def restore(self, backupfile, confirm, drop, format='native'):
2493
9806571ea790 major refactoring of database dump/restore:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   424
        """method called to restore a backup of source's data"""
11979
c93b47ba0093 [server] Drop close/open steps in NativeSQLSource.restore()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11931
diff changeset
   425
        if format == 'portable':
c93b47ba0093 [server] Drop close/open steps in NativeSQLSource.restore()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11931
diff changeset
   426
            helper = DatabaseIndependentBackupRestore(self)
c93b47ba0093 [server] Drop close/open steps in NativeSQLSource.restore()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11931
diff changeset
   427
            helper.restore(backupfile)
c93b47ba0093 [server] Drop close/open steps in NativeSQLSource.restore()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11931
diff changeset
   428
        elif format == 'native':
c93b47ba0093 [server] Drop close/open steps in NativeSQLSource.restore()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11931
diff changeset
   429
            self.restore_from_file(backupfile, confirm, drop=drop)
c93b47ba0093 [server] Drop close/open steps in NativeSQLSource.restore()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11931
diff changeset
   430
        else:
c93b47ba0093 [server] Drop close/open steps in NativeSQLSource.restore()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11931
diff changeset
   431
            raise ValueError('Unknown format %r' % format)
2493
9806571ea790 major refactoring of database dump/restore:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   432
12148
79160d54662e [sources] Simplify source's init method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12061
diff changeset
   433
    def init(self, source_entity):
79160d54662e [sources] Simplify source's init method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12061
diff changeset
   434
        super(NativeSQLSource, self).init(source_entity)
9131
b3ad80aa645f fix migration from pre-3.13.1 versions (closes #2846978)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9130
diff changeset
   435
        self.init_creating(source_entity._cw.cnxset)
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   436
5749
b4393b681f7a [repo] on repository shutdown, we've to close the new eid creation connection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5729
diff changeset
   437
    def shutdown(self):
9583
e337a9f658e0 [source/native] refactor eid generation code
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9574
diff changeset
   438
        self.eid_generator.close()
5749
b4393b681f7a [repo] on repository shutdown, we've to close the new eid creation connection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5729
diff changeset
   439
9492
c7fc56eecd1a English typography
Dimitri Papadopoulos <dimitri.papadopoulos@cea.fr>
parents: 9375
diff changeset
   440
    # XXX deprecates [un]map_attribute?
5013
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5011
diff changeset
   441
    def map_attribute(self, etype, attr, cb, sourcedb=True):
10095
200bd6a601dc [warnings] put an end to warnings in the sqlite driver over `str` being sent instead of unicode strings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10086
diff changeset
   442
        self._rql_sqlgen.attr_map[u'%s.%s' % (etype, attr)] = (cb, sourcedb)
2493
9806571ea790 major refactoring of database dump/restore:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   443
4512
e7ac20bf3629 unset_attribute_storage, for testing purpose at least
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   444
    def unmap_attribute(self, etype, attr):
10095
200bd6a601dc [warnings] put an end to warnings in the sqlite driver over `str` being sent instead of unicode strings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10086
diff changeset
   445
        self._rql_sqlgen.attr_map.pop(u'%s.%s' % (etype, attr), None)
4512
e7ac20bf3629 unset_attribute_storage, for testing purpose at least
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   446
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   447
    def set_storage(self, etype, attr, storage):
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   448
        storage_dict = self._storages.setdefault(etype, {})
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   449
        storage_dict[attr] = storage
5013
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5011
diff changeset
   450
        self.map_attribute(etype, attr,
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5011
diff changeset
   451
                           storage.callback, storage.is_source_callback)
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   452
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   453
    def unset_storage(self, etype, attr):
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   454
        self._storages[etype].pop(attr)
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   455
        # if etype has no storage left, remove the entry
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   456
        if not self._storages[etype]:
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   457
            del self._storages[etype]
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   458
        self.unmap_attribute(etype, attr)
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   459
5397
cdbf823450aa [bfss] new storage_changed migration action to move an attribute to a custom storage. Closes #893941
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5323
diff changeset
   460
    def storage(self, etype, attr):
cdbf823450aa [bfss] new storage_changed migration action to move an attribute to a custom storage. Closes #893941
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5323
diff changeset
   461
        """return the storage for the given entity type / attribute
cdbf823450aa [bfss] new storage_changed migration action to move an attribute to a custom storage. Closes #893941
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5323
diff changeset
   462
        """
cdbf823450aa [bfss] new storage_changed migration action to move an attribute to a custom storage. Closes #893941
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5323
diff changeset
   463
        try:
cdbf823450aa [bfss] new storage_changed migration action to move an attribute to a custom storage. Closes #893941
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5323
diff changeset
   464
            return self._storages[etype][attr]
cdbf823450aa [bfss] new storage_changed migration action to move an attribute to a custom storage. Closes #893941
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5323
diff changeset
   465
        except KeyError:
cdbf823450aa [bfss] new storage_changed migration action to move an attribute to a custom storage. Closes #893941
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5323
diff changeset
   466
            raise Exception('no custom storage set for %s.%s' % (etype, attr))
cdbf823450aa [bfss] new storage_changed migration action to move an attribute to a custom storage. Closes #893941
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5323
diff changeset
   467
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   468
    # ISource interface #######################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   469
10477
ee21c559f94f implement a simple statsd logger (closes #5488711)
David Douard <david.douard@logilab.fr>
parents: 10473
diff changeset
   470
    @statsd_timeit
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   471
    def compile_rql(self, rql, sols):
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: 3041
diff changeset
   472
        rqlst = self.repo.vreg.rqlhelper.parse(rql)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   473
        rqlst.restricted_vars = ()
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   474
        rqlst.children[0].solutions = sols
12887
11953d585a55 [server.querier] remove useless indirection Querier.rqlannotator
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12885
diff changeset
   475
        RQLAnnotator(self.repo.querier.schema).annotate(rqlst)
438
69b79faefa94 need_intersect test and fixes
sylvain.thenault@logilab.fr
parents: 0
diff changeset
   476
        set_qdata(self.schema.rschema, rqlst, ())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   477
        return rqlst
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   478
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   479
    def set_schema(self, schema):
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2354
diff changeset
   480
        """set the instance'schema"""
7954
a3d3220669d6 [cache] replace lgc.cache with something more appropriate (closes #1921713)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7922
diff changeset
   481
        self._cache = QueryCache(self.repo.config['rql-cache-size'])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   482
        self.cache_hit, self.cache_miss, self.no_cache = 0, 0, 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   483
        self.schema = schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   484
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   485
            self._rql_sqlgen.schema = schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   486
        except AttributeError:
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   487
            pass  # __init__
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   488
        for authentifier in self.authentifiers:
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   489
            authentifier.set_schema(self.schema)
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   490
        clear_cache(self, 'need_fti_indexation')
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   491
10477
ee21c559f94f implement a simple statsd logger (closes #5488711)
David Douard <david.douard@logilab.fr>
parents: 10473
diff changeset
   492
    @statsd_timeit
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9487
diff changeset
   493
    def authenticate(self, cnx, login, **kwargs):
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   494
        """return CWUser eid for the given login and other authentication
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   495
        information found in kwargs, else raise `AuthenticationError`
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   496
        """
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   497
        for authentifier in self.authentifiers:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   498
            try:
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9487
diff changeset
   499
                return authentifier.authenticate(cnx, login, **kwargs)
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   500
            except AuthenticationError:
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   501
                continue
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   502
        raise AuthenticationError()
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   503
12782
ea8801f10a72 Fix flake8 issues
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12765
diff changeset
   504
    def syntax_tree_search(self, cnx, union, args=None, cachekey=None,
ea8801f10a72 Fix flake8 issues
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12765
diff changeset
   505
                           rql_query_tracing_token=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   506
        """return result from this source for a rql query (actually from
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   507
        a rql syntax tree and a solution dictionary mapping each used
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   508
        variable to a possible type). If cachekey is given, the query
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   509
        necessary to fetch the results (but not the results themselves)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   510
        may be cached using this key.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   511
        """
11237
f32134dd0067 [repository] drop remanescence of old multi-sources code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11135
diff changeset
   512
        assert dbg_st_search(self.uri, union, args, cachekey)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   513
        # remember number of actually selected term (sql generation may append some)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   514
        if cachekey is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   515
            self.no_cache += 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   516
            # generate sql query if we are able to do so (not supported types...)
11237
f32134dd0067 [repository] drop remanescence of old multi-sources code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11135
diff changeset
   517
            sql, qargs, cbs = self._rql_sqlgen.generate(union, args)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   518
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   519
            # sql may be cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   520
            try:
5013
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5011
diff changeset
   521
                sql, qargs, cbs = self._cache[cachekey]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   522
                self.cache_hit += 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   523
            except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   524
                self.cache_miss += 1
11237
f32134dd0067 [repository] drop remanescence of old multi-sources code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11135
diff changeset
   525
                sql, qargs, cbs = self._rql_sqlgen.generate(union, args)
5013
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5011
diff changeset
   526
                self._cache[cachekey] = sql, qargs, cbs
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5011
diff changeset
   527
        args = self.merge_args(args, qargs)
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   528
        assert isinstance(sql, str), repr(sql)
12756
d91c229de97f [debug/rql] bind a uniq token per rql to trace its decomposition
Laurent Peuch <cortex@worlddomination.be>
parents: 12739
diff changeset
   529
        cursor = cnx.system_sql(sql, args, rql_query_tracing_token=rql_query_tracing_token)
10086
98bc2ca1a816 [source/native] session -> cnx
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10074
diff changeset
   530
        results = self.process_result(cursor, cnx, cbs)
2625
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   531
        assert dbg_results(results)
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   532
        return results
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   533
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   534
    @contextmanager
10550
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   535
    def _fixup_cw(self, cnx, entity):
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   536
        _cw = entity._cw
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   537
        entity._cw = cnx
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   538
        try:
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   539
            yield
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   540
        finally:
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   541
            entity._cw = _cw
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   542
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   543
    @contextmanager
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   544
    def _storage_handler(self, cnx, entity, event):
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   545
        # 1/ memorize values as they are before the storage is called.
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   546
        #    For instance, the BFSStorage will replace the `data`
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   547
        #    binary value with a Binary containing the destination path
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   548
        #    on the filesystem. To make the entity.data usage absolutely
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   549
        #    transparent, we'll have to reset entity.data to its binary
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   550
        #    value once the SQL query will be executed
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
   551
        restore_values = []
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
   552
        if isinstance(entity, list):
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
   553
            entities = entity
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
   554
        else:
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
   555
            entities = [entity]
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
   556
        etype = entities[0].__regid__
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   557
        for attr, storage in self._storages.get(etype, {}).items():
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
   558
            for entity in entities:
10550
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   559
                with self._fixup_cw(cnx, entity):
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   560
                    if event == 'deleted':
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   561
                        storage.entity_deleted(entity, attr)
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   562
                    else:
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   563
                        edited = entity.cw_edited
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   564
                        if attr in edited:
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   565
                            handler = getattr(storage, 'entity_%s' % event)
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   566
                            to_restore = handler(entity, attr)
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   567
                            restore_values.append((entity, attr, to_restore))
5128
e5d300d75519 [python] take care to this detail of @contextmanager: if an unhandled exception occurs in the block, it is reraised inside the generator at the point where the yield occurred
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5107
diff changeset
   568
        try:
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   569
            yield  # 2/ execute the source's instructions
5128
e5d300d75519 [python] take care to this detail of @contextmanager: if an unhandled exception occurs in the block, it is reraised inside the generator at the point where the yield occurred
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5107
diff changeset
   570
        finally:
e5d300d75519 [python] take care to this detail of @contextmanager: if an unhandled exception occurs in the block, it is reraised inside the generator at the point where the yield occurred
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5107
diff changeset
   571
            # 3/ restore original values
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
   572
            for entity, attr, value in restore_values:
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6128
diff changeset
   573
                entity.cw_edited.edited_attribute(attr, value)
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   574
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   575
    def add_entity(self, cnx, entity):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   576
        """add a new entity to the source"""
10550
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   577
        with self._storage_handler(cnx, entity, 'added'):
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   578
            attrs = self.preprocess_entity(entity)
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8821
diff changeset
   579
            sql = self.sqlgen.insert(SQL_PREFIX + entity.cw_etype, attrs)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   580
            self.doexec(cnx, sql, attrs)
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   581
            if cnx.ertype_supports_undo(entity.cw_etype):
10264
d5403de0792b [server] use unicode wherever appropriate in transaction/undo related methods
Julien Cristau <julien.cristau@logilab.fr>
parents: 10221
diff changeset
   582
                self._record_tx_action(cnx, 'tx_entity_actions', u'C',
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   583
                                       etype=entity.cw_etype, eid=entity.eid)
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   584
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   585
    def update_entity(self, cnx, entity):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   586
        """replace an entity in the source"""
10550
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   587
        with self._storage_handler(cnx, entity, 'updated'):
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   588
            attrs = self.preprocess_entity(entity)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   589
            if cnx.ertype_supports_undo(entity.cw_etype):
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   590
                changes = self._save_attrs(cnx, entity, attrs)
10264
d5403de0792b [server] use unicode wherever appropriate in transaction/undo related methods
Julien Cristau <julien.cristau@logilab.fr>
parents: 10221
diff changeset
   591
                self._record_tx_action(cnx, 'tx_entity_actions', u'U',
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   592
                                       etype=entity.cw_etype, eid=entity.eid,
10602
4845012cfc8e [py3k] import 'pickle' using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10589
diff changeset
   593
                                       changes=self._binary(pickle.dumps(changes)))
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8821
diff changeset
   594
            sql = self.sqlgen.update(SQL_PREFIX + entity.cw_etype, attrs,
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   595
                                     ['cw_eid'])
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   596
            self.doexec(cnx, sql, attrs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   597
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   598
    def delete_entity(self, cnx, entity):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   599
        """delete an entity from the source"""
10550
d4bd28d5fca8 [server/sources] make sure entity._cw is a Connection before calling Storages
Julien Cristau <julien.cristau@logilab.fr>
parents: 10477
diff changeset
   600
        with self._storage_handler(cnx, entity, 'deleted'):
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   601
            if cnx.ertype_supports_undo(entity.cw_etype):
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   602
                attrs = [SQL_PREFIX + r.type
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   603
                         for r in entity.e_schema.subject_relations()
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   604
                         if (r.final or r.inlined) and r not in VIRTUAL_RTYPES]
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   605
                changes = self._save_attrs(cnx, entity, attrs)
10264
d5403de0792b [server] use unicode wherever appropriate in transaction/undo related methods
Julien Cristau <julien.cristau@logilab.fr>
parents: 10221
diff changeset
   606
                self._record_tx_action(cnx, 'tx_entity_actions', u'D',
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   607
                                       etype=entity.cw_etype, eid=entity.eid,
10602
4845012cfc8e [py3k] import 'pickle' using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10589
diff changeset
   608
                                       changes=self._binary(pickle.dumps(changes)))
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   609
            attrs = {'cw_eid': entity.eid}
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8821
diff changeset
   610
            sql = self.sqlgen.delete(SQL_PREFIX + entity.cw_etype, attrs)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   611
            self.doexec(cnx, sql, attrs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   612
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   613
    def add_relation(self, cnx, subject, rtype, object, inlined=False):
5072
072ae171aeb0 [cleanup] style fixes, add nodes, 0.2 cents refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5071
diff changeset
   614
        """add a relation to the source"""
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   615
        self._add_relations(cnx, rtype, [(subject, object)], inlined)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   616
        if cnx.ertype_supports_undo(rtype):
10264
d5403de0792b [server] use unicode wherever appropriate in transaction/undo related methods
Julien Cristau <julien.cristau@logilab.fr>
parents: 10221
diff changeset
   617
            self._record_tx_action(cnx, 'tx_relation_actions', u'A',
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   618
                                   eid_from=subject, rtype=rtype, eid_to=object)
5072
072ae171aeb0 [cleanup] style fixes, add nodes, 0.2 cents refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5071
diff changeset
   619
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   620
    def add_relations(self, cnx, rtype, subj_obj_list, inlined=False):
7237
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7202
diff changeset
   621
        """add a relations to the source"""
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   622
        self._add_relations(cnx, rtype, subj_obj_list, inlined)
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   623
        if cnx.ertype_supports_undo(rtype):
7237
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7202
diff changeset
   624
            for subject, object in subj_obj_list:
10264
d5403de0792b [server] use unicode wherever appropriate in transaction/undo related methods
Julien Cristau <julien.cristau@logilab.fr>
parents: 10221
diff changeset
   625
                self._record_tx_action(cnx, 'tx_relation_actions', u'A',
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   626
                                       eid_from=subject, rtype=rtype, eid_to=object)
7551
2d4ba5b984dc cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7530
diff changeset
   627
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   628
    def _add_relations(self, cnx, rtype, subj_obj_list, inlined=False):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   629
        """add a relation to the source"""
7243
9ab01bf84eac fix bad handling of inlined relations when entities of different etypes are passed as subject to add_relations
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7237
diff changeset
   630
        sql = []
4818
9f9bfbcdecfd le patch massiveimport a été importé
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4810
diff changeset
   631
        if inlined is False:
7237
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7202
diff changeset
   632
            attrs = [{'eid_from': subject, 'eid_to': object}
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7202
diff changeset
   633
                     for subject, object in subj_obj_list]
7243
9ab01bf84eac fix bad handling of inlined relations when entities of different etypes are passed as subject to add_relations
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7237
diff changeset
   634
            sql.append((self.sqlgen.insert('%s_relation' % rtype, attrs[0]), attrs))
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   635
        else:  # used by data import
7243
9ab01bf84eac fix bad handling of inlined relations when entities of different etypes are passed as subject to add_relations
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7237
diff changeset
   636
            etypes = {}
9ab01bf84eac fix bad handling of inlined relations when entities of different etypes are passed as subject to add_relations
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7237
diff changeset
   637
            for subject, object in subj_obj_list:
11765
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11763
diff changeset
   638
                etype = cnx.entity_type(subject)
7243
9ab01bf84eac fix bad handling of inlined relations when entities of different etypes are passed as subject to add_relations
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7237
diff changeset
   639
                if etype in etypes:
9ab01bf84eac fix bad handling of inlined relations when entities of different etypes are passed as subject to add_relations
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7237
diff changeset
   640
                    etypes[etype].append((subject, object))
9ab01bf84eac fix bad handling of inlined relations when entities of different etypes are passed as subject to add_relations
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7237
diff changeset
   641
                else:
9ab01bf84eac fix bad handling of inlined relations when entities of different etypes are passed as subject to add_relations
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7237
diff changeset
   642
                    etypes[etype] = [(subject, object)]
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10651
diff changeset
   643
            for subj_etype, subj_obj_list in etypes.items():
7243
9ab01bf84eac fix bad handling of inlined relations when entities of different etypes are passed as subject to add_relations
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7237
diff changeset
   644
                attrs = [{'cw_eid': subject, SQL_PREFIX + rtype: object}
9ab01bf84eac fix bad handling of inlined relations when entities of different etypes are passed as subject to add_relations
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7237
diff changeset
   645
                         for subject, object in subj_obj_list]
9ab01bf84eac fix bad handling of inlined relations when entities of different etypes are passed as subject to add_relations
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7237
diff changeset
   646
                sql.append((self.sqlgen.update(SQL_PREFIX + etype, attrs[0],
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   647
                                               ['cw_eid']),
7243
9ab01bf84eac fix bad handling of inlined relations when entities of different etypes are passed as subject to add_relations
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7237
diff changeset
   648
                            attrs))
9ab01bf84eac fix bad handling of inlined relations when entities of different etypes are passed as subject to add_relations
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7237
diff changeset
   649
        for statement, attrs in sql:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   650
            self.doexecmany(cnx, statement, attrs)
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   651
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   652
    def delete_relation(self, cnx, subject, rtype, object):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   653
        """delete a relation from the source"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   654
        rschema = self.schema.rschema(rtype)
12726
1a2c7d6397ec Avoid to update inlined relation column to NULL when deleting entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12586
diff changeset
   655
        # we should not issue UPDATE on inlined relations when subject is going
1a2c7d6397ec Avoid to update inlined relation column to NULL when deleting entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12586
diff changeset
   656
        # to be deleted.
1a2c7d6397ec Avoid to update inlined relation column to NULL when deleting entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12586
diff changeset
   657
        # Unless object is also going to be deleted and is not equal to the
1a2c7d6397ec Avoid to update inlined relation column to NULL when deleting entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12586
diff changeset
   658
        # subject, in this case DELETE should occur in a order which cubicweb
1a2c7d6397ec Avoid to update inlined relation column to NULL when deleting entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12586
diff changeset
   659
        # doesn't handle (yet). For example
1a2c7d6397ec Avoid to update inlined relation column to NULL when deleting entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12586
diff changeset
   660
        # cubicweb/server/test/unittest_migractions.py::MigrationCommandsTC::test_add_drop_entity_type
1a2c7d6397ec Avoid to update inlined relation column to NULL when deleting entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12586
diff changeset
   661
        # trigger such case.
1a2c7d6397ec Avoid to update inlined relation column to NULL when deleting entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12586
diff changeset
   662
        if (
1a2c7d6397ec Avoid to update inlined relation column to NULL when deleting entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12586
diff changeset
   663
            rschema.inlined and cnx.deleted_in_transaction(subject)
1a2c7d6397ec Avoid to update inlined relation column to NULL when deleting entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12586
diff changeset
   664
            and (subject == object or not cnx.deleted_in_transaction(object))
1a2c7d6397ec Avoid to update inlined relation column to NULL when deleting entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12586
diff changeset
   665
        ):
1a2c7d6397ec Avoid to update inlined relation column to NULL when deleting entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12586
diff changeset
   666
            return
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   667
        self._delete_relation(cnx, subject, rtype, object, rschema.inlined)
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   668
        if cnx.ertype_supports_undo(rtype):
10264
d5403de0792b [server] use unicode wherever appropriate in transaction/undo related methods
Julien Cristau <julien.cristau@logilab.fr>
parents: 10221
diff changeset
   669
            self._record_tx_action(cnx, 'tx_relation_actions', u'R',
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   670
                                   eid_from=subject, rtype=rtype, eid_to=object)
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   671
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   672
    def _delete_relation(self, cnx, subject, rtype, object, inlined=False):
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   673
        """delete a relation from the source"""
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   674
        if inlined:
11765
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11763
diff changeset
   675
            table = SQL_PREFIX + cnx.entity_type(subject)
1251
af40e615dc89 introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents: 1079
diff changeset
   676
            column = SQL_PREFIX + rtype
af40e615dc89 introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents: 1079
diff changeset
   677
            sql = 'UPDATE %s SET %s=NULL WHERE %seid=%%(eid)s' % (table, column,
af40e615dc89 introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents: 1079
diff changeset
   678
                                                                  SQL_PREFIX)
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   679
            attrs = {'eid': subject}
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   680
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   681
            attrs = {'eid_from': subject, 'eid_to': object}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   682
            sql = self.sqlgen.delete('%s_relation' % rtype, attrs)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   683
        self.doexec(cnx, sql, attrs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   684
10477
ee21c559f94f implement a simple statsd logger (closes #5488711)
David Douard <david.douard@logilab.fr>
parents: 10473
diff changeset
   685
    @statsd_timeit
12756
d91c229de97f [debug/rql] bind a uniq token per rql to trace its decomposition
Laurent Peuch <cortex@worlddomination.be>
parents: 12739
diff changeset
   686
    def doexec(self, cnx, query, args=None, rollback=True, rql_query_tracing_token=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   687
        """Execute a query.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   688
        it's a function just so that it shows up in profiling
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   689
        """
12761
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   690
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   691
        query_debug_informations = {
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   692
            "sql": query,
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   693
            "args": args,
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   694
            "rollback": False,
12765
771c99f16780 [debug-toolbar] add sql panel
Laurent Peuch <cortex@worlddomination.be>
parents: 12761
diff changeset
   695
            "callstack": "".join(traceback.format_stack()[:-1]),
12761
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   696
            "rql_query_tracing_token": rql_query_tracing_token,
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   697
        }
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   698
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   699
        start = time.time()
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   700
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   701
        cursor = cnx.cnxset.cu
2593
16d9419a4a79 F: start to handle binary debug log level on the server side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   702
        if server.DEBUG & server.DBG_SQL:
12758
db95a417a5ec [debug/source_highlight] rename highlight to highlight_terminal
Laurent Peuch <cortex@worlddomination.be>
parents: 12756
diff changeset
   703
            print('exec', highlight_terminal(query, "SQL"), args, cnx.cnxset.cnx)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   704
        try:
9701
46c8d8701240 an unicode string -> a unicode string
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9492
diff changeset
   705
            # str(query) to avoid error if it's a unicode string
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   706
            cursor.execute(str(query), args)
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8694
diff changeset
   707
        except Exception as ex:
4682
4994901b7379 don't issue critical message when trying to alter sqlite db during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4517
diff changeset
   708
            if self.repo.config.mode != 'test':
4994901b7379 don't issue critical message when trying to alter sqlite db during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4517
diff changeset
   709
                # during test we get those message when trying to alter sqlite
4994901b7379 don't issue critical message when trying to alter sqlite db during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4517
diff changeset
   710
                # db schema
10178
4b33246cb43c [native] Change SQL errors log level.
Christophe de Vienne <christophe@unlish.com>
parents: 10076
diff changeset
   711
                self.info("sql: %r\n args: %s\ndbms message: %r",
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   712
                          query, args, ex.args[0])
2618
ff9b0d5bd884 [F repo sqlite schema changes] don't rollback on potentially expected schema changes failure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2611
diff changeset
   713
            if rollback:
ff9b0d5bd884 [F repo sqlite schema changes] don't rollback on potentially expected schema changes failure
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2611
diff changeset
   714
                try:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   715
                    cnx.cnxset.rollback()
12761
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   716
                    query_debug_informations["rollback"] = True
4692
11a040e2601c [test] also hide this message during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4682
diff changeset
   717
                    if self.repo.config.mode != 'test':
10178
4b33246cb43c [native] Change SQL errors log level.
Christophe de Vienne <christophe@unlish.com>
parents: 10076
diff changeset
   718
                        self.debug('transaction has been rolled back')
12842
e150ed316dfc [server.source.native] exceptions should never pass silently
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12782
diff changeset
   719
                except Exception as rollback_exc:
e150ed316dfc [server.source.native] exceptions should never pass silently
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12782
diff changeset
   720
                    self.warning('exception raised and ignored during rollback %s:\n%s',
e150ed316dfc [server.source.native] exceptions should never pass silently
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12782
diff changeset
   721
                                 rollback_exc, traceback.format_exc(limit=2))
12586
afafc8fd9a45 Account for new psycopg2 exception classes mapping
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   722
            if any(cls.__name__ for cls in ex.__class__.__mro__
afafc8fd9a45 Account for new psycopg2 exception classes mapping
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   723
                   if cls.__name__ == 'IntegrityError'):
6211
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
   724
                # need string comparison because of various backends
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
   725
                for arg in ex.args:
9375
8e88576787c3 [schema] fix unique together index handling
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9336
diff changeset
   726
                    # postgres, sqlserver
8e88576787c3 [schema] fix unique together index handling
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9336
diff changeset
   727
                    mo = re.search("unique_[a-z0-9]{32}", arg)
6211
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
   728
                    if mo is not None:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   729
                        raise UniqueTogetherError(cnx, cstrname=mo.group(0))
10053
079b5279a2cd [server] Handle unique constraint violations under recent sqlite
Julien Cristau <julien.cristau@logilab.fr>
parents: 10052
diff changeset
   730
                    # old sqlite
10329
f92823a66f18 [sqlite] Fix integrity error parsing
Christophe de Vienne <christophe@unlish.com>
parents: 10272
diff changeset
   731
                    mo = re.search('columns? (.*) (?:is|are) not unique', arg)
12156
0d1d22a3a48b Fix some flake8 errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12153
diff changeset
   732
                    if mo is not None:  # sqlite in use
8820
dbffb6959564 server/source/native: fix wrong usage of .lstrip that produce garbled error messages (closes #2777641)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8546
diff changeset
   733
                        # we left chop the 'cw_' prefix of attribute names
dbffb6959564 server/source/native: fix wrong usage of .lstrip that produce garbled error messages (closes #2777641)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8546
diff changeset
   734
                        rtypes = [c.strip()[3:]
dbffb6959564 server/source/native: fix wrong usage of .lstrip that produce garbled error messages (closes #2777641)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8546
diff changeset
   735
                                  for c in mo.group(1).split(',')]
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   736
                        raise UniqueTogetherError(cnx, rtypes=rtypes)
10053
079b5279a2cd [server] Handle unique constraint violations under recent sqlite
Julien Cristau <julien.cristau@logilab.fr>
parents: 10052
diff changeset
   737
                    # sqlite after http://www.sqlite.org/cgi/src/info/c80e229dd9c1230a
079b5279a2cd [server] Handle unique constraint violations under recent sqlite
Julien Cristau <julien.cristau@logilab.fr>
parents: 10052
diff changeset
   738
                    if arg.startswith('UNIQUE constraint failed:'):
079b5279a2cd [server] Handle unique constraint violations under recent sqlite
Julien Cristau <julien.cristau@logilab.fr>
parents: 10052
diff changeset
   739
                        # message looks like: "UNIQUE constraint failed: foo.cw_bar, foo.cw_baz"
079b5279a2cd [server] Handle unique constraint violations under recent sqlite
Julien Cristau <julien.cristau@logilab.fr>
parents: 10052
diff changeset
   740
                        # so drop the prefix, split on comma, drop the tablenames, and drop "cw_"
079b5279a2cd [server] Handle unique constraint violations under recent sqlite
Julien Cristau <julien.cristau@logilab.fr>
parents: 10052
diff changeset
   741
                        columns = arg.split(':', 1)[1].split(',')
079b5279a2cd [server] Handle unique constraint violations under recent sqlite
Julien Cristau <julien.cristau@logilab.fr>
parents: 10052
diff changeset
   742
                        rtypes = [c.split('.', 1)[1].strip()[3:] for c in columns]
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   743
                        raise UniqueTogetherError(cnx, rtypes=rtypes)
10446
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10411
diff changeset
   744
11926
2deb9f6cbb7b [source,native] Generalize the IntegrityError constraint parsing regex
Florent Cayré <florent.cayre@gmail.com>
parents: 11776
diff changeset
   745
                    mo = re.search(r'\bcstr[a-f0-9]{32}\b', arg)
10446
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10411
diff changeset
   746
                    if mo is not None:
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10411
diff changeset
   747
                        # postgresql
12614
8ac9ac8d9143 [mod] make ViolatedConstraint actually display useful information
Laurent Peuch <cortex@worlddomination.be>
parents: 12591
diff changeset
   748
                        raise ViolatedConstraint(cnx, cstrname=mo.group(0),
8ac9ac8d9143 [mod] make ViolatedConstraint actually display useful information
Laurent Peuch <cortex@worlddomination.be>
parents: 12591
diff changeset
   749
                                                 query=query)
10446
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10411
diff changeset
   750
                    if arg.startswith('CHECK constraint failed:'):
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10411
diff changeset
   751
                        # sqlite3 (new)
12614
8ac9ac8d9143 [mod] make ViolatedConstraint actually display useful information
Laurent Peuch <cortex@worlddomination.be>
parents: 12591
diff changeset
   752
                        raise ViolatedConstraint(cnx, cstrname=arg.split(':', 1)[1].strip(),
8ac9ac8d9143 [mod] make ViolatedConstraint actually display useful information
Laurent Peuch <cortex@worlddomination.be>
parents: 12591
diff changeset
   753
                                                 query=query)
10446
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10411
diff changeset
   754
                    mo = re.match('^constraint (cstr.*) failed$', arg)
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10411
diff changeset
   755
                    if mo is not None:
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10411
diff changeset
   756
                        # sqlite3 (old)
12614
8ac9ac8d9143 [mod] make ViolatedConstraint actually display useful information
Laurent Peuch <cortex@worlddomination.be>
parents: 12591
diff changeset
   757
                        raise ViolatedConstraint(cnx, cstrname=mo.group(1),
8ac9ac8d9143 [mod] make ViolatedConstraint actually display useful information
Laurent Peuch <cortex@worlddomination.be>
parents: 12591
diff changeset
   758
                                                 query=query)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   759
            raise
12761
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   760
        finally:
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   761
            query_debug_informations["time"] = (time.time() - start) * 1000
10b8352b0208 [debug-toolbar/rql] display sql queries generated by rql ones
Laurent Peuch <cortex@worlddomination.be>
parents: 12758
diff changeset
   762
            emit_to_debug_channel("sql", query_debug_informations)
2306
95da5d9f0870 give session to doexec so it's able to rollback the connection on unexpected error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2072
diff changeset
   763
        return cursor
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   764
10477
ee21c559f94f implement a simple statsd logger (closes #5488711)
David Douard <david.douard@logilab.fr>
parents: 10473
diff changeset
   765
    @statsd_timeit
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   766
    def doexecmany(self, cnx, query, args):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   767
        """Execute a query.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   768
        it's a function just so that it shows up in profiling
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   769
        """
2593
16d9419a4a79 F: start to handle binary debug log level on the server side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   770
        if server.DEBUG & server.DBG_SQL:
12758
db95a417a5ec [debug/source_highlight] rename highlight to highlight_terminal
Laurent Peuch <cortex@worlddomination.be>
parents: 12756
diff changeset
   771
            print('execmany', highlight_terminal(query, "SQL"), 'with', len(args), 'arguments',
12739
c6f8ca03718f [debug] syntax highlight SQL and RQL debug output
Laurent Peuch <cortex@worlddomination.be>
parents: 12731
diff changeset
   772
                  cnx.cnxset.cnx)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   773
        cursor = cnx.cnxset.cu
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   774
        try:
9701
46c8d8701240 an unicode string -> a unicode string
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9492
diff changeset
   775
            # str(query) to avoid error if it's a unicode string
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   776
            cursor.executemany(str(query), args)
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8694
diff changeset
   777
        except Exception as ex:
4682
4994901b7379 don't issue critical message when trying to alter sqlite db during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4517
diff changeset
   778
            if self.repo.config.mode != 'test':
4994901b7379 don't issue critical message when trying to alter sqlite db during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4517
diff changeset
   779
                # during test we get those message when trying to alter sqlite
4994901b7379 don't issue critical message when trying to alter sqlite db during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4517
diff changeset
   780
                # db schema
4994901b7379 don't issue critical message when trying to alter sqlite db during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4517
diff changeset
   781
                self.critical("sql many: %r\n args: %s\ndbms message: %r",
4994901b7379 don't issue critical message when trying to alter sqlite db during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4517
diff changeset
   782
                              query, args, ex.args[0])
2306
95da5d9f0870 give session to doexec so it's able to rollback the connection on unexpected error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2072
diff changeset
   783
            try:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   784
                cnx.cnxset.rollback()
4692
11a040e2601c [test] also hide this message during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4682
diff changeset
   785
                if self.repo.config.mode != 'test':
9267
24d9b86dfa54 spelling: rollbacked -> rolled back
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9131
diff changeset
   786
                    self.critical('transaction has been rolled back')
7645
cb2459aaa7d7 [source] closes #1816412: try to reconnect to dbms if connection is reset in eid_type_source()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7562
diff changeset
   787
            except Exception:
2306
95da5d9f0870 give session to doexec so it's able to rollback the connection on unexpected error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2072
diff changeset
   788
                pass
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   789
            raise
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   790
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   791
    # short cut to method requiring advanced db helper usage ##################
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   792
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   793
    def update_rdef_column(self, cnx, rdef):
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   794
        """update physical column for a relation definition (final or inlined)
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   795
        """
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   796
        table, column = rdef_table_column(rdef)
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   797
        coltype, allownull = rdef_physical_info(self.dbhelper, rdef)
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   798
        if not self.dbhelper.alter_column_support:
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   799
            self.error("backend can't alter %s.%s to %s%s", table, column, coltype,
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   800
                       not allownull and 'NOT NULL' or '')
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   801
            return
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   802
        self.dbhelper.change_col_type(LogCursor(cnx.cnxset.cu),
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   803
                                      table, column, coltype, allownull)
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   804
        self.info('altered %s.%s: now %s%s', table, column, coltype,
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   805
                  not allownull and 'NOT NULL' or '')
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   806
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   807
    def update_rdef_null_allowed(self, cnx, rdef):
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   808
        """update NULL / NOT NULL of physical column for a relation definition
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   809
        (final or inlined)
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   810
        """
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   811
        if not self.dbhelper.alter_column_support:
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   812
            # not supported (and NOT NULL not set by yams in that case, so no
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   813
            # worry)
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   814
            return
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   815
        table, column = rdef_table_column(rdef)
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   816
        coltype, allownull = rdef_physical_info(self.dbhelper, rdef)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   817
        self.dbhelper.set_null_allowed(LogCursor(cnx.cnxset.cu),
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   818
                                       table, column, coltype, allownull)
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   819
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   820
    def update_rdef_indexed(self, cnx, rdef):
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   821
        table, column = rdef_table_column(rdef)
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   822
        if rdef.indexed:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   823
            self.create_index(cnx, table, column)
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   824
        else:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   825
            self.drop_index(cnx, table, column)
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   826
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   827
    def update_rdef_unique(self, cnx, rdef):
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   828
        table, column = rdef_table_column(rdef)
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   829
        if rdef.constraint_by_type('UniqueConstraint'):
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   830
            self.create_index(cnx, table, column, unique=True)
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   831
        else:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   832
            self.drop_index(cnx, table, column, unique=True)
5891
99024ad59223 [schema migration] import refactoring to fix #1109558 and enhances things on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   833
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   834
    def create_index(self, cnx, table, column, unique=False):
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   835
        cursor = LogCursor(cnx.cnxset.cu)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   836
        self.dbhelper.create_index(cursor, table, column, unique)
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   837
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   838
    def drop_index(self, cnx, table, column, unique=False):
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   839
        cursor = LogCursor(cnx.cnxset.cu)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   840
        self.dbhelper.drop_index(cursor, table, column, unique)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   841
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   842
    # system source interface #################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   843
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11773
diff changeset
   844
    def eid_type(self, cnx, eid):  # pylint: disable=E0202
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11773
diff changeset
   845
        """Return the entity's type for `eid`."""
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11773
diff changeset
   846
        sql = 'SELECT type FROM entities WHERE eid=%s' % eid
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   847
        try:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   848
            res = self.doexec(cnx, sql).fetchone()
7646
91a984ba420f [native source] fix bug introduced in 7645:cb2459aaa7d7: fetchone() may return None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7645
diff changeset
   849
            if res is not None:
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11773
diff changeset
   850
                return res[0]
7645
cb2459aaa7d7 [source] closes #1816412: try to reconnect to dbms if connection is reset in eid_type_source()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7562
diff changeset
   851
        except Exception:
cb2459aaa7d7 [source] closes #1816412: try to reconnect to dbms if connection is reset in eid_type_source()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7562
diff changeset
   852
            self.exception('failed to query entities table for eid %s', eid)
cb2459aaa7d7 [source] closes #1816412: try to reconnect to dbms if connection is reset in eid_type_source()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7562
diff changeset
   853
        raise UnknownEid(eid)
cb2459aaa7d7 [source] closes #1816412: try to reconnect to dbms if connection is reset in eid_type_source()
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7562
diff changeset
   854
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   855
    def _handle_is_relation_sql(self, cnx, sql, attrs):
8625
7ee0752178e5 [dataimport] Add SQL Store for faster import - works ONLY with Postgres for now, as it requires "copy from" command - closes #2410822
Vincent Michel <vincent.michel@logilab.fr>
parents: 8573
diff changeset
   856
        """ Handler for specific is_relation sql that may be
7ee0752178e5 [dataimport] Add SQL Store for faster import - works ONLY with Postgres for now, as it requires "copy from" command - closes #2410822
Vincent Michel <vincent.michel@logilab.fr>
parents: 8573
diff changeset
   857
        overwritten in some stores"""
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   858
        self.doexec(cnx, sql % attrs)
8625
7ee0752178e5 [dataimport] Add SQL Store for faster import - works ONLY with Postgres for now, as it requires "copy from" command - closes #2410822
Vincent Michel <vincent.michel@logilab.fr>
parents: 8573
diff changeset
   859
7ee0752178e5 [dataimport] Add SQL Store for faster import - works ONLY with Postgres for now, as it requires "copy from" command - closes #2410822
Vincent Michel <vincent.michel@logilab.fr>
parents: 8573
diff changeset
   860
    _handle_insert_entity_sql = doexec
7ee0752178e5 [dataimport] Add SQL Store for faster import - works ONLY with Postgres for now, as it requires "copy from" command - closes #2410822
Vincent Michel <vincent.michel@logilab.fr>
parents: 8573
diff changeset
   861
    _handle_is_instance_of_sql = _handle_source_relation_sql = _handle_is_relation_sql
7ee0752178e5 [dataimport] Add SQL Store for faster import - works ONLY with Postgres for now, as it requires "copy from" command - closes #2410822
Vincent Michel <vincent.michel@logilab.fr>
parents: 8573
diff changeset
   862
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11773
diff changeset
   863
    def add_info(self, cnx, entity, source):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   864
        """add type and source info for an eid into the system table"""
9802
9f815b1f2516 [repository,tests] use the new connection api (part 1/2)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9770
diff changeset
   865
        assert cnx.cnxset is not None
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11773
diff changeset
   866
        # begin by inserting eid/type/source into the entities table
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   867
        attrs = {'type': entity.cw_etype, 'eid': entity.eid}
9802
9f815b1f2516 [repository,tests] use the new connection api (part 1/2)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9770
diff changeset
   868
        self._handle_insert_entity_sql(cnx, self.sqlgen.insert('entities', attrs), attrs)
6427
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6426
diff changeset
   869
        # insert core relations: is, is_instance_of and cw_source
11091
29aebc1edd29 [repository] drop usage of no more necessary eschema_eid function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11005
diff changeset
   870
29aebc1edd29 [repository] drop usage of no more necessary eschema_eid function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11005
diff changeset
   871
        if entity.e_schema.eid is not None:  # else schema has not yet been serialized
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   872
            self._handle_is_relation_sql(
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   873
                cnx, 'INSERT INTO is_relation(eid_from,eid_to) VALUES (%s,%s)',
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   874
                (entity.eid, entity.e_schema.eid))
6851
824d5b6eae7f [repo] kill no more needed 'recreate' feature
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6849
diff changeset
   875
            for eschema in entity.e_schema.ancestors() + [entity.e_schema]:
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   876
                self._handle_is_relation_sql(
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   877
                    cnx,
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   878
                    'INSERT INTO is_instance_of_relation(eid_from,eid_to) VALUES (%s,%s)',
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   879
                    (entity.eid, eschema.eid))
11135
421520f4d516 [server] remove some pre 3.10 compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11129
diff changeset
   880
        if source.eid is not None:  # else the source has not yet been inserted
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   881
            self._handle_is_relation_sql(
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   882
                cnx, 'INSERT INTO cw_source_relation(eid_from,eid_to) VALUES (%s,%s)',
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   883
                (entity.eid, source.eid))
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   884
        # now we can update the full text index
10631
1ab79c435fae consider .do_fti flag in index_entity method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10329
diff changeset
   885
        if self.need_fti_indexation(entity.cw_etype):
9802
9f815b1f2516 [repository,tests] use the new connection api (part 1/2)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9770
diff changeset
   886
            self.index_entity(cnx, entity=entity)
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   887
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   888
    def update_info(self, cnx, entity, need_fti_update):
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   889
        """mark entity as being modified, fulltext reindex if needed"""
10631
1ab79c435fae consider .do_fti flag in index_entity method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10329
diff changeset
   890
        if need_fti_update:
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   891
            # reindex the entity only if this query is updating at least
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   892
            # one indexable attribute
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   893
            self.index_entity(cnx, entity=entity)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   894
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   895
    def delete_info_multi(self, cnx, entities):
7501
2983dd24494a [repository] refactor/cleanup entity deletion methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7342
diff changeset
   896
        """delete system information on deletion of a list of entities with the
2983dd24494a [repository] refactor/cleanup entity deletion methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7342
diff changeset
   897
        same etype and belinging to the same source
2983dd24494a [repository] refactor/cleanup entity deletion methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7342
diff changeset
   898
5067
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
   899
        * update the fti
7501
2983dd24494a [repository] refactor/cleanup entity deletion methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7342
diff changeset
   900
        * remove record from the `entities` table
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
   901
        """
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   902
        self.fti_unindex_entities(cnx, entities)
11351
97882e99138d [server] Improve massive deletion of entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11279
diff changeset
   903
97882e99138d [server] Improve massive deletion of entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11279
diff changeset
   904
        # sqlserver is limited on the array size, the limit can occur starting
97882e99138d [server] Improve massive deletion of entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11279
diff changeset
   905
        # from > 10000 item, so we process by batch of 10000
97882e99138d [server] Improve massive deletion of entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11279
diff changeset
   906
        count = len(entities)
97882e99138d [server] Improve massive deletion of entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11279
diff changeset
   907
        batch_size = 10000
97882e99138d [server] Improve massive deletion of entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11279
diff changeset
   908
        for i in range(0, count, batch_size):
97882e99138d [server] Improve massive deletion of entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11279
diff changeset
   909
            in_eid = ",".join(str(entities[index].eid)
97882e99138d [server] Improve massive deletion of entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11279
diff changeset
   910
                              for index in range(i, min(i + batch_size, count)))
97882e99138d [server] Improve massive deletion of entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11279
diff changeset
   911
            attrs = {'eid': '(%s)' % (in_eid,)}
97882e99138d [server] Improve massive deletion of entities
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11279
diff changeset
   912
            self.doexec(cnx, self.sqlgen.delete_many('entities', attrs), attrs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   913
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   914
    # undo support #############################################################
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   915
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   916
    def undoable_transactions(self, cnx, ueid=None, **actionfilters):
10356
a009a31fb1ea [connection] eliminate ClientConnection leftovers
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   917
        """See :class:`cubicweb.repoapi.Connection.undoable_transactions`"""
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   918
        # force filtering to connection's user if not a manager
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   919
        if not cnx.user.is_in_group('managers'):
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   920
            ueid = cnx.user.eid
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   921
        restr = {}
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   922
        if ueid is not None:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   923
            restr['tx_user'] = ueid
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   924
        sql = self.sqlgen.select('transactions', restr, ('tx_uuid', 'tx_time', 'tx_user'))
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   925
        if actionfilters:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   926
            # we will need subqueries to filter transactions according to
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   927
            # actions done
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   928
            tearestr = {}  # filters on the tx_entity_actions table
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   929
            trarestr = {}  # filters on the tx_relation_actions table
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   930
            genrestr = {}  # generic filters, appliyable to both table
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   931
            # unless public explicitly set to false, we only consider public
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   932
            # actions
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   933
            if actionfilters.pop('public', True):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   934
                genrestr['txa_public'] = True
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   935
            # put additional filters in trarestr and/or tearestr
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10651
diff changeset
   936
            for key, val in actionfilters.items():
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   937
                if key == 'etype':
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   938
                    # filtering on etype implies filtering on entity actions
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   939
                    # only, and with no eid specified
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   940
                    assert actionfilters.get('action', 'C') in 'CUD'
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
   941
                    assert 'eid' not in actionfilters
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   942
                    tearestr['etype'] = val
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   943
                elif key == 'eid':
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   944
                    # eid filter may apply to 'eid' of tx_entity_actions or to
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   945
                    # 'eid_from' OR 'eid_to' of tx_relation_actions
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   946
                    if actionfilters.get('action', 'C') in 'CUD':
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   947
                        tearestr['eid'] = val
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   948
                    if actionfilters.get('action', 'A') in 'AR':
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   949
                        trarestr['eid_from'] = val
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   950
                        trarestr['eid_to'] = val
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   951
                elif key == 'action':
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   952
                    if val in 'CUD':
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   953
                        tearestr['txa_action'] = val
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   954
                    else:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   955
                        assert val in 'AR'
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   956
                        trarestr['txa_action'] = val
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   957
                else:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   958
                    raise AssertionError('unknow filter %s' % key)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   959
            assert trarestr or tearestr, "can't only filter on 'public'"
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   960
            subqsqls = []
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   961
            # append subqueries to the original query, using EXISTS()
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   962
            if trarestr or (genrestr and not tearestr):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   963
                trarestr.update(genrestr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   964
                trasql = self.sqlgen.select('tx_relation_actions', trarestr, ('1',))
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   965
                if 'eid_from' in trarestr:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   966
                    # replace AND by OR between eid_from/eid_to restriction
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   967
                    trasql = sql_or_clauses(trasql, ['eid_from = %(eid_from)s',
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   968
                                                     'eid_to = %(eid_to)s'])
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   969
                trasql += ' AND transactions.tx_uuid=tx_relation_actions.tx_uuid'
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   970
                subqsqls.append('EXISTS(%s)' % trasql)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   971
            if tearestr or (genrestr and not trarestr):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   972
                tearestr.update(genrestr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   973
                teasql = self.sqlgen.select('tx_entity_actions', tearestr, ('1',))
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   974
                teasql += ' AND transactions.tx_uuid=tx_entity_actions.tx_uuid'
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   975
                subqsqls.append('EXISTS(%s)' % teasql)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   976
            if restr:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   977
                sql += ' AND %s' % ' OR '.join(subqsqls)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   978
            else:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   979
                sql += ' WHERE %s' % ' OR '.join(subqsqls)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   980
            restr.update(trarestr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   981
            restr.update(tearestr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   982
        # we want results ordered by transaction's time descendant
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   983
        sql += ' ORDER BY tx_time DESC'
10365
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
   984
        cu = self.doexec(cnx, sql, restr)
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
   985
        # turn results into transaction objects
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
   986
        return [tx.Transaction(cnx, *args) for args in cu.fetchall()]
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   987
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   988
    def tx_info(self, cnx, txuuid):
10356
a009a31fb1ea [connection] eliminate ClientConnection leftovers
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   989
        """See :class:`cubicweb.repoapi.Connection.transaction_info`"""
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
   990
        return tx.Transaction(cnx, txuuid, *self._tx_info(cnx, txuuid))
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   991
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   992
    def tx_actions(self, cnx, txuuid, public):
10356
a009a31fb1ea [connection] eliminate ClientConnection leftovers
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   993
        """See :class:`cubicweb.repoapi.Connection.transaction_actions`"""
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
   994
        self._tx_info(cnx, txuuid)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   995
        restr = {'tx_uuid': txuuid}
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   996
        if public:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   997
            restr['txa_public'] = True
5072
072ae171aeb0 [cleanup] style fixes, add nodes, 0.2 cents refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5071
diff changeset
   998
        # XXX use generator to avoid loading everything in memory?
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   999
        sql = self.sqlgen.select('tx_entity_actions', restr,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1000
                                 ('txa_action', 'txa_public', 'txa_order',
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1001
                                  'etype', 'eid', 'changes'))
11429
6a9a9ea1e9b9 Remove usage of cnx.ensure_cnx_set context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11417
diff changeset
  1002
        cu = self.doexec(cnx, sql, restr)
6a9a9ea1e9b9 Remove usage of cnx.ensure_cnx_set context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11417
diff changeset
  1003
        actions = [tx.EntityAction(a, p, o, et, e, c and pickle.loads(self.binary_to_str(c)))
6a9a9ea1e9b9 Remove usage of cnx.ensure_cnx_set context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11417
diff changeset
  1004
                   for a, p, o, et, e, c in cu.fetchall()]
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1005
        sql = self.sqlgen.select('tx_relation_actions', restr,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1006
                                 ('txa_action', 'txa_public', 'txa_order',
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1007
                                  'rtype', 'eid_from', 'eid_to'))
11429
6a9a9ea1e9b9 Remove usage of cnx.ensure_cnx_set context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11417
diff changeset
  1008
        cu = self.doexec(cnx, sql, restr)
6a9a9ea1e9b9 Remove usage of cnx.ensure_cnx_set context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11417
diff changeset
  1009
        actions += [tx.RelationAction(*args) for args in cu.fetchall()]
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1010
        return sorted(actions, key=lambda x: x.order)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1011
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1012
    def undo_transaction(self, cnx, txuuid):
10356
a009a31fb1ea [connection] eliminate ClientConnection leftovers
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
  1013
        """See :class:`cubicweb.repoapi.Connection.undo_transaction`
5071
8631bb9f6e73 [undo] during undoing, call hooks in the [active]integrity and undo categories
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5070
diff changeset
  1014
8631bb9f6e73 [undo] during undoing, call hooks in the [active]integrity and undo categories
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5070
diff changeset
  1015
        important note: while undoing of a transaction, only hooks in the
8631bb9f6e73 [undo] during undoing, call hooks in the [active]integrity and undo categories
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5070
diff changeset
  1016
        'integrity', 'activeintegrity' and 'undo' categories are called.
8631bb9f6e73 [undo] during undoing, call hooks in the [active]integrity and undo categories
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5070
diff changeset
  1017
        """
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1018
        errors = []
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1019
        cnx.transaction_data['undoing_uuid'] = txuuid
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1020
        with cnx.deny_all_hooks_but('integrity', 'activeintegrity', 'undo'):
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1021
            with cnx.security_enabled(read=False):
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1022
                for action in reversed(self.tx_actions(cnx, txuuid, False)):
4943
7f5b83578fec disable security when undoing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4913
diff changeset
  1023
                    undomethod = getattr(self, '_undo_%s' % action.action.lower())
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1024
                    errors += undomethod(cnx, action)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1025
        # remove the transactions record
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1026
        self.doexec(cnx,
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1027
                    "DELETE FROM transactions WHERE tx_uuid='%s'" % txuuid)
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1028
        if errors:
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1029
            raise UndoTransactionException(txuuid, errors)
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1030
        else:
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1031
            return
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1032
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1033
    def start_undoable_transaction(self, cnx, uuid):
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1034
        """connection callback to insert a transaction record in the transactions
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1035
        table when some undoable transaction is started
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1036
        """
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1037
        ueid = cnx.user.eid
7922
d307c3817782 [repository] use utcnow instead of now for some internal timetamps (closes #1988458)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1038
        attrs = {'tx_uuid': uuid, 'tx_user': ueid, 'tx_time': datetime.utcnow()}
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1039
        self.doexec(cnx, self.sqlgen.insert('transactions', attrs), attrs)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1040
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1041
    def _save_attrs(self, cnx, entity, attrs):
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1042
        """return a pickleable dictionary containing current values for given
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1043
        attributes of the entity
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1044
        """
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1045
        restr = {'cw_eid': entity.eid}
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8821
diff changeset
  1046
        sql = self.sqlgen.select(SQL_PREFIX + entity.cw_etype, restr, attrs)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1047
        cu = self.doexec(cnx, sql, restr)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1048
        values = dict(zip(attrs, cu.fetchone()))
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1049
        # ensure backend specific binary are converted back to string
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1050
        eschema = entity.e_schema
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1051
        for column in attrs:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1052
            # [3:] remove 'cw_' prefix
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1053
            attr = column[3:]
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1054
            if not eschema.subjrels[attr].final:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1055
                continue
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1056
            if eschema.destination(attr) in ('Password', 'Bytes'):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1057
                value = values[column]
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1058
                if value is not None:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1059
                    values[column] = self.binary_to_str(value)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1060
        return values
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1061
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1062
    def _record_tx_action(self, cnx, table, action, **kwargs):
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1063
        """record a transaction action in the given table (either
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1064
        'tx_entity_actions' or 'tx_relation_action')
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1065
        """
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1066
        kwargs['tx_uuid'] = cnx.transaction_uuid()
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1067
        kwargs['txa_action'] = action
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1068
        kwargs['txa_order'] = cnx.transaction_inc_action_counter()
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10301
diff changeset
  1069
        kwargs['txa_public'] = not cnx.hooks_in_progress
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1070
        self.doexec(cnx, self.sqlgen.insert(table, kwargs), kwargs)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1071
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1072
    def _tx_info(self, cnx, txuuid):
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1073
        """return transaction's time and user of the transaction with the given uuid.
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1074
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1075
        raise `NoSuchTransaction` if there is no such transaction of if the
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1076
        connection's user isn't allowed to see it.
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1077
        """
10365
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
  1078
        restr = {'tx_uuid': txuuid}
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
  1079
        sql = self.sqlgen.select('transactions', restr,
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
  1080
                                 ('tx_time', 'tx_user'))
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
  1081
        cu = self.doexec(cnx, sql, restr)
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
  1082
        try:
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
  1083
            time, ueid = cu.fetchone()
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
  1084
        except TypeError:
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
  1085
            raise tx.NoSuchTransaction(txuuid)
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
  1086
        if not (cnx.user.is_in_group('managers')
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
  1087
                or cnx.user.eid == ueid):
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
  1088
            raise tx.NoSuchTransaction(txuuid)
21461f80f348 [connection] remove ensure_cnx_set context manager uses
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10364
diff changeset
  1089
        return time, ueid
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1090
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1091
    def _reedit_entity(self, entity, changes, err):
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1092
        cnx = entity._cw
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1093
        eid = entity.eid
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1094
        entity.cw_edited = edited = EditedEntity(entity)
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1095
        # check for schema changes, entities linked through inlined relation
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1096
        # still exists, rewrap binary values
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1097
        eschema = entity.e_schema
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1098
        getrschema = eschema.subjrels
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1099
        for column, value in changes.items():
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1100
            rtype = column[len(SQL_PREFIX):]
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1101
            if rtype == "eid":
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1102
                continue  # XXX should even `eid` be stored in action changes?
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1103
            try:
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1104
                rschema = getrschema[rtype]
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1105
            except KeyError:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1106
                err(cnx._("can't restore relation %(rtype)s of entity %(eid)s, "
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1107
                          "this relation does not exist in the schema anymore.")
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1108
                    % {'rtype': rtype, 'eid': eid})
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1109
            if not rschema.final:
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1110
                if not rschema.inlined:
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1111
                    assert value is None
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1112
                # rschema is an inlined relation
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1113
                elif value is not None:
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1114
                    # not a deletion: we must put something in edited
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1115
                    try:
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1116
                        entity._cw.entity_from_eid(value)  # check target exists
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1117
                        edited[rtype] = value
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1118
                    except UnknownEid:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1119
                        err(cnx._("can't restore entity %(eid)s of type %(eschema)s, "
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1120
                                  "target of %(rtype)s (eid %(value)s) does not exist any longer")
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1121
                            % locals())
10206
0ecd61f4bd37 [undo] when we can't undo an inlined relation change, point at None, not a broken eid
Julien Cristau <julien.cristau@logilab.fr>
parents: 10203
diff changeset
  1122
                        changes[column] = None
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1123
            elif eschema.destination(rtype) in ('Bytes', 'Password'):
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1124
                changes[column] = self._binary(value)
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1125
                edited[rtype] = Binary(value)
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1126
            else:
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1127
                edited[rtype] = value
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1128
        # This must only be done after init_entitiy_caches : defered in calling functions
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1129
        # edited.check()
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1130
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1131
    def _undo_d(self, cnx, action):
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1132
        """undo an entity deletion"""
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1133
        errors = []
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1134
        err = errors.append
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1135
        eid = action.eid
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1136
        etype = action.etype
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1137
        # get an entity instance
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1138
        try:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1139
            entity = self.repo.vreg['etypes'].etype_class(etype)(cnx)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1140
        except Exception:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1141
            err("can't restore entity %s of type %s, type no more supported"
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1142
                % (eid, etype))
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1143
            return errors
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1144
        self._reedit_entity(entity, action.changes, err)
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
  1145
        entity.eid = eid
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1146
        cnx.repo.init_entity_caches(cnx, entity, self)
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1147
        entity.cw_edited.check()
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1148
        self.repo.hm.call_hooks('before_add_entity', cnx, entity=entity)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1149
        # restore the entity
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1150
        action.changes['cw_eid'] = eid
10203
1443fe643a38 [server] change order of entities table modification vs entity creation/deletion
Julien Cristau <julien.cristau@logilab.fr>
parents: 10200
diff changeset
  1151
        # restore record in entities (will update fti if needed)
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11773
diff changeset
  1152
        self.add_info(cnx, entity, self)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1153
        sql = self.sqlgen.insert(SQL_PREFIX + etype, action.changes)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1154
        self.doexec(cnx, sql, action.changes)
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1155
        self.repo.hm.call_hooks('after_add_entity', cnx, entity=entity)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1156
        return errors
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1157
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1158
    def _undo_r(self, cnx, action):
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1159
        """undo a relation removal"""
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1160
        errors = []
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1161
        subj, rtype, obj = action.eid_from, action.rtype, action.eid_to
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1162
        try:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1163
            sentity, oentity, rdef = _undo_rel_info(cnx, subj, rtype, obj)
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8694
diff changeset
  1164
        except _UndoException as ex:
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
  1165
            errors.append(str(ex))
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1166
        else:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1167
            for role, entity in (('subject', sentity),
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1168
                                 ('object', oentity)):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1169
                try:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1170
                    _undo_check_relation_target(entity, rdef, role)
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8694
diff changeset
  1171
                except _UndoException as ex:
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
  1172
                    errors.append(str(ex))
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1173
                    continue
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1174
        if not errors:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1175
            self.repo.hm.call_hooks('before_add_relation', cnx,
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1176
                                    eidfrom=subj, rtype=rtype, eidto=obj)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1177
            # add relation in the database
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1178
            self._add_relations(cnx, rtype, [(subj, obj)], rdef.rtype.inlined)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1179
            # set related cache
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1180
            cnx.update_rel_cache_add(subj, rtype, obj, rdef.rtype.symmetric)
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1181
            self.repo.hm.call_hooks('after_add_relation', cnx,
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1182
                                    eidfrom=subj, rtype=rtype, eidto=obj)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1183
        return errors
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1184
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1185
    def _undo_c(self, cnx, action):
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1186
        """undo an entity creation"""
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1187
        eid = action.eid
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1188
        # XXX done to avoid fetching all remaining relation for the entity
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1189
        # we should find an efficient way to do this (keeping current veolidf
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1190
        # massive deletion performance)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1191
        if _undo_has_later_transaction(cnx, eid):
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1192
            msg = cnx._('some later transaction(s) touch entity, undo them first')
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1193
            raise ValidationError(eid, {None: msg})
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1194
        etype = action.etype
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1195
        # get an entity instance
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1196
        try:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1197
            entity = self.repo.vreg['etypes'].etype_class(etype)(cnx)
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1198
        except Exception:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1199
            return [cnx._(
5098
32b1adfb6b92 [i18n] use named substitution to avoid gettext warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5076
diff changeset
  1200
                "Can't undo creation of entity %(eid)s of type %(etype)s, type "
32b1adfb6b92 [i18n] use named substitution to avoid gettext warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5076
diff changeset
  1201
                "no more supported" % {'eid': eid, 'etype': etype})]
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
  1202
        entity.eid = eid
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1203
        # for proper eid/type cache update
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1204
        CleanupDeletedEidsCacheOp.get_instance(cnx).add_data(eid)
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1205
        self.repo.hm.call_hooks('before_delete_entity', cnx, entity=entity)
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1206
        # remove is / is_instance_of which are added using sql by hooks, hence
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1207
        # unvisible as transaction action
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1208
        self.doexec(cnx, 'DELETE FROM is_relation WHERE eid_from=%s' % eid)
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1209
        self.doexec(cnx, 'DELETE FROM is_instance_of_relation WHERE eid_from=%s' % eid)
10183
ff93dad2ae3a [undo] fix deletion of cw_source relation
Julien Cristau <julien.cristau@logilab.fr>
parents: 10178
diff changeset
  1210
        self.doexec(cnx, 'DELETE FROM cw_source_relation WHERE eid_from=%s' % eid)
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1211
        # XXX check removal of inlined relation?
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1212
        # delete the entity
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1213
        attrs = {'cw_eid': eid}
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8821
diff changeset
  1214
        sql = self.sqlgen.delete(SQL_PREFIX + entity.cw_etype, attrs)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1215
        self.doexec(cnx, sql, attrs)
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1216
        # remove record from entities (will update fti if needed)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1217
        self.delete_info_multi(cnx, [entity])
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1218
        self.repo.hm.call_hooks('after_delete_entity', cnx, entity=entity)
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1219
        return ()
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1220
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1221
    def _undo_u(self, cnx, action):
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1222
        """undo an entity update"""
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1223
        errors = []
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1224
        err = errors.append
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1225
        try:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1226
            entity = cnx.entity_from_eid(action.eid)
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1227
        except UnknownEid:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1228
            err(cnx._("can't restore state of entity %s, it has been "
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1229
                      "deleted inbetween") % action.eid)
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1230
            return errors
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1231
        self._reedit_entity(entity, action.changes, err)
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1232
        entity.cw_edited.check()
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1233
        self.repo.hm.call_hooks('before_update_entity', cnx, entity=entity)
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8821
diff changeset
  1234
        sql = self.sqlgen.update(SQL_PREFIX + entity.cw_etype, action.changes,
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1235
                                 ['cw_eid'])
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1236
        self.doexec(cnx, sql, action.changes)
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1237
        self.repo.hm.call_hooks('after_update_entity', cnx, entity=entity)
8265
9747ab9230ad [repo, undo] Finish repository-side implementation of the undo feature (closes #893940)
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8235
diff changeset
  1238
        return errors
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1239
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1240
    def _undo_a(self, cnx, action):
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1241
        """undo a relation addition"""
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1242
        errors = []
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1243
        subj, rtype, obj = action.eid_from, action.rtype, action.eid_to
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1244
        try:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1245
            sentity, oentity, rdef = _undo_rel_info(cnx, subj, rtype, obj)
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8694
diff changeset
  1246
        except _UndoException as ex:
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12355
diff changeset
  1247
            errors.append(str(ex))
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1248
        else:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1249
            rschema = rdef.rtype
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1250
            if rschema.inlined:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1251
                sql = 'SELECT 1 FROM cw_%s WHERE cw_eid=%s and cw_%s=%s'\
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8821
diff changeset
  1252
                      % (sentity.cw_etype, subj, rtype, obj)
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1253
            else:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1254
                sql = 'SELECT 1 FROM %s_relation WHERE eid_from=%s and eid_to=%s'\
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1255
                      % (rtype, subj, obj)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1256
            cu = self.doexec(cnx, sql)
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1257
            if cu.fetchone() is None:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1258
                errors.append(cnx._(
5098
32b1adfb6b92 [i18n] use named substitution to avoid gettext warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5076
diff changeset
  1259
                    "Can't undo addition of relation %(rtype)s from %(subj)s to"
32b1adfb6b92 [i18n] use named substitution to avoid gettext warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5076
diff changeset
  1260
                    " %(obj)s, doesn't exist anymore" % locals()))
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1261
        if not errors:
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1262
            self.repo.hm.call_hooks('before_delete_relation', cnx,
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1263
                                    eidfrom=subj, rtype=rtype, eidto=obj)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1264
            # delete relation from the database
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1265
            self._delete_relation(cnx, subj, rtype, obj, rschema.inlined)
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1266
            # set related cache
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1267
            cnx.update_rel_cache_del(subj, rtype, obj, rschema.symmetric)
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1268
            self.repo.hm.call_hooks('after_delete_relation', cnx,
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1269
                                    eidfrom=subj, rtype=rtype, eidto=obj)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1270
        return errors
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1271
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1272
    # full text index handling #################################################
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1273
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1274
    @cached
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1275
    def need_fti_indexation(self, etype):
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1276
        eschema = self.schema.eschema(etype)
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1277
        if any(eschema.indexable_attributes()):
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1278
            return True
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1279
        if any(eschema.fulltext_containers()):
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1280
            return True
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1281
        return False
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1282
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1283
    def index_entity(self, cnx, entity):
4807
5642bfa43236 [cleanup] add index_entity to abstract source, add docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4806
diff changeset
  1284
        """create an operation to [re]index textual content of the given entity
5642bfa43236 [cleanup] add index_entity to abstract source, add docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4806
diff changeset
  1285
        on commit
5642bfa43236 [cleanup] add index_entity to abstract source, add docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4806
diff changeset
  1286
        """
10631
1ab79c435fae consider .do_fti flag in index_entity method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10329
diff changeset
  1287
        if self.do_fti:
1ab79c435fae consider .do_fti flag in index_entity method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10329
diff changeset
  1288
            FTIndexEntityOp.get_instance(cnx).add_data(entity.eid)
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1289
9574
2d4c4842bd04 [server] some s/session/cnx/
Julien Cristau <julien.cristau@logilab.fr>
parents: 9546
diff changeset
  1290
    def fti_unindex_entities(self, cnx, entities):
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1291
        """remove text content for entities from the full text index
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1292
        """
12290
2b049c9fcec5 [source/native] do NOT do anything with fti if do_fti is False
David Douard <david.douard@logilab.fr>
parents: 12156
diff changeset
  1293
        if not cnx.repo.system_source.do_fti:
2b049c9fcec5 [source/native] do NOT do anything with fti if do_fti is False
David Douard <david.douard@logilab.fr>
parents: 12156
diff changeset
  1294
            return
9574
2d4c4842bd04 [server] some s/session/cnx/
Julien Cristau <julien.cristau@logilab.fr>
parents: 9546
diff changeset
  1295
        cursor = cnx.cnxset.cu
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1296
        cursor_unindex_object = self.dbhelper.cursor_unindex_object
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1297
        try:
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1298
            for entity in entities:
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1299
                cursor_unindex_object(entity.eid, cursor)
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1300
        except Exception:  # let KeyboardInterrupt / SystemExit propagate
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1301
            self.exception('error while unindexing %s', entity)
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1302
9574
2d4c4842bd04 [server] some s/session/cnx/
Julien Cristau <julien.cristau@logilab.fr>
parents: 9546
diff changeset
  1303
    def fti_index_entities(self, cnx, entities):
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1304
        """add text content of created/modified entities to the full text index
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1305
        """
12290
2b049c9fcec5 [source/native] do NOT do anything with fti if do_fti is False
David Douard <david.douard@logilab.fr>
parents: 12156
diff changeset
  1306
        if not cnx.repo.system_source.do_fti:
2b049c9fcec5 [source/native] do NOT do anything with fti if do_fti is False
David Douard <david.douard@logilab.fr>
parents: 12156
diff changeset
  1307
            return
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1308
        cursor_index_object = self.dbhelper.cursor_index_object
9574
2d4c4842bd04 [server] some s/session/cnx/
Julien Cristau <julien.cristau@logilab.fr>
parents: 9546
diff changeset
  1309
        cursor = cnx.cnxset.cu
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1310
        try:
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1311
            # use cursor_index_object, not cursor_reindex_object since
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1312
            # unindexing done in the FTIndexEntityOp
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1313
            for entity in entities:
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1314
                cursor_index_object(entity.eid,
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1315
                                    entity.cw_adapt_to('IFTIndexable'),
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1316
                                    cursor)
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1317
        except Exception:  # let KeyboardInterrupt / SystemExit propagate
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1318
            self.exception('error while indexing %s', entity)
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1319
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1320
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
  1321
class FTIndexEntityOp(hook.DataOperationMixIn, hook.LateOperation):
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1322
    """operation to delay entity full text indexation to commit
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1323
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1324
    since fti indexing may trigger discovery of other entities, it should be
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1325
    triggered on precommit, not commit, and this should be done after other
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1326
    precommit operation which may add relations to the entity
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1327
    """
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1328
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1329
    def precommit_event(self):
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1330
        cnx = self.cnx
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1331
        source = cnx.repo.system_source
12290
2b049c9fcec5 [source/native] do NOT do anything with fti if do_fti is False
David Douard <david.douard@logilab.fr>
parents: 12156
diff changeset
  1332
        if not source.do_fti:
2b049c9fcec5 [source/native] do NOT do anything with fti if do_fti is False
David Douard <david.douard@logilab.fr>
parents: 12156
diff changeset
  1333
            return
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1334
        pendingeids = cnx.transaction_data.get('pendingeids', ())
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1335
        done = cnx.transaction_data.setdefault('indexedeids', set())
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1336
        to_reindex = set()
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
  1337
        for eid in self.get_data():
5070
b1f80ccadda3 [repo] refactor fti operation to use set_operation and a single operation whatever the number of entities to ft index
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5067
diff changeset
  1338
            if eid in pendingeids or eid in done:
b1f80ccadda3 [repo] refactor fti operation to use set_operation and a single operation whatever the number of entities to ft index
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5067
diff changeset
  1339
                # entity added and deleted in the same transaction or already
b1f80ccadda3 [repo] refactor fti operation to use set_operation and a single operation whatever the number of entities to ft index
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5067
diff changeset
  1340
                # processed
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1341
                continue
5070
b1f80ccadda3 [repo] refactor fti operation to use set_operation and a single operation whatever the number of entities to ft index
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5067
diff changeset
  1342
            done.add(eid)
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1343
            iftindexable = cnx.entity_from_eid(eid).cw_adapt_to('IFTIndexable')
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6850
diff changeset
  1344
            to_reindex |= set(iftindexable.fti_containers())
9611
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1345
        source.fti_unindex_entities(cnx, to_reindex)
ca853478aaa8 [server/sources/native] deal with connections, not sessions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9605
diff changeset
  1346
        source.fti_index_entities(cnx, to_reindex)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1347
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1348
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1349
def sql_schema(driver):
11413
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1350
    """Yield SQL statements to create system tables in the database."""
4831
c5aec27c1bf7 [repo] use logilab.db instead of lgc.adbh/lgc.db/lgc.sqlgen/indexer, test new date extranction functions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4829
diff changeset
  1351
    helper = get_db_helper(driver)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1352
    typemap = helper.TYPE_MAPPING
11413
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1353
    # XXX should return a list of sql statements rather than ';' joined statements
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1354
    for sql in helper.sql_create_numrange('entities_id_seq').split(';'):
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1355
        yield sql
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1356
    for sql in ("""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1357
CREATE TABLE entities (
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1358
  eid INTEGER PRIMARY KEY NOT NULL,
11774
51c160677afe [repository] Drop the entities.extid column and associated cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11773
diff changeset
  1359
  type VARCHAR(64) NOT NULL
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1360
);;
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1361
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1362
CREATE TABLE transactions (
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1363
  tx_uuid CHAR(32) PRIMARY KEY NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1364
  tx_user INTEGER NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1365
  tx_time %s NOT NULL
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1366
);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1367
CREATE INDEX transactions_tx_user_idx ON transactions(tx_user);;
9336
722635e530a0 [server] Add missing indices for undo support (closes #3259691)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9298
diff changeset
  1368
CREATE INDEX transactions_tx_time_idx ON transactions(tx_time);;
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1369
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1370
CREATE TABLE tx_entity_actions (
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1371
  tx_uuid CHAR(32) REFERENCES transactions(tx_uuid) ON DELETE CASCADE,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1372
  txa_action CHAR(1) NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1373
  txa_public %s NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1374
  txa_order INTEGER,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1375
  eid INTEGER NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1376
  etype VARCHAR(64) NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1377
  changes %s
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1378
);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1379
CREATE INDEX tx_entity_actions_txa_action_idx ON tx_entity_actions(txa_action);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1380
CREATE INDEX tx_entity_actions_txa_public_idx ON tx_entity_actions(txa_public);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1381
CREATE INDEX tx_entity_actions_eid_idx ON tx_entity_actions(eid);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1382
CREATE INDEX tx_entity_actions_etype_idx ON tx_entity_actions(etype);;
9336
722635e530a0 [server] Add missing indices for undo support (closes #3259691)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9298
diff changeset
  1383
CREATE INDEX tx_entity_actions_tx_uuid_idx ON tx_entity_actions(tx_uuid);;
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1384
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1385
CREATE TABLE tx_relation_actions (
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1386
  tx_uuid CHAR(32) REFERENCES transactions(tx_uuid) ON DELETE CASCADE,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1387
  txa_action CHAR(1) NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1388
  txa_public %s NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1389
  txa_order INTEGER,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1390
  eid_from INTEGER NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1391
  eid_to INTEGER NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1392
  rtype VARCHAR(256) NOT NULL
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1393
);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1394
CREATE INDEX tx_relation_actions_txa_action_idx ON tx_relation_actions(txa_action);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1395
CREATE INDEX tx_relation_actions_txa_public_idx ON tx_relation_actions(txa_public);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1396
CREATE INDEX tx_relation_actions_eid_from_idx ON tx_relation_actions(eid_from);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1397
CREATE INDEX tx_relation_actions_eid_to_idx ON tx_relation_actions(eid_to);;
11413
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1398
CREATE INDEX tx_relation_actions_tx_uuid_idx ON tx_relation_actions(tx_uuid)
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1399
""" % (typemap['Datetime'],
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1400
       typemap['Boolean'], typemap['Bytes'], typemap['Boolean'])).split(';'):
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1401
        yield sql
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1402
    if helper.backend_name == 'sqlite':
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1403
        # sqlite support the ON DELETE CASCADE syntax but do nothing
11413
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1404
        yield '''
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1405
CREATE TRIGGER fkd_transactions
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1406
BEFORE DELETE ON transactions
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1407
FOR EACH ROW BEGIN
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1408
    DELETE FROM tx_entity_actions WHERE tx_uuid=OLD.tx_uuid;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1409
    DELETE FROM tx_relation_actions WHERE tx_uuid=OLD.tx_uuid;
11413
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1410
END;
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1411
'''
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1412
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1413
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1414
def grant_schema(user, set_owner=True):
11413
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1415
    """Yield SQL statements to give all access (and ownership if `set_owner` is True) on the
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1416
    database system tables to `user`.
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1417
    """
9450
af4b93bc38a5 [multi-sources-removal] Drop deleted_entities system table and entities.mtime column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9448
diff changeset
  1418
    for table in ('entities', 'entities_id_seq',
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1419
                  'transactions', 'tx_entity_actions', 'tx_relation_actions'):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1420
        if set_owner:
11413
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1421
            yield 'ALTER TABLE %s OWNER TO %s;' % (table, user)
c172fa18565e [schema2sql] Avoid "parsing" SQL statements for database initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11412
diff changeset
  1422
        yield 'GRANT ALL ON %s TO %s;' % (table, user)
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1423
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1424
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1425
class BaseAuthentifier(object):
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1426
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1427
    def __init__(self, source=None):
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1428
        self.source = source
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1429
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1430
    def set_schema(self, schema):
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1431
        """set the instance'schema"""
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1432
        pass
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1433
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1434
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1435
class LoginPasswordAuthentifier(BaseAuthentifier):
8520
fcd048fa6e6d [source/native] only system source users should be authenticated by the native source (closes #2465883)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8508
diff changeset
  1436
    passwd_rql = 'Any P WHERE X is CWUser, X login %(login)s, X upassword P'
10095
200bd6a601dc [warnings] put an end to warnings in the sqlite driver over `str` being sent instead of unicode strings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10086
diff changeset
  1437
    auth_rql = (u'Any X WHERE X is CWUser, X login %(login)s, X upassword %(pwd)s, '
8520
fcd048fa6e6d [source/native] only system source users should be authenticated by the native source (closes #2465883)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8508
diff changeset
  1438
                'X cw_source S, S name "system"')
fcd048fa6e6d [source/native] only system source users should be authenticated by the native source (closes #2465883)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8508
diff changeset
  1439
    _sols = ({'X': 'CWUser', 'P': 'Password', 'S': 'CWSource'},)
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1440
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1441
    def set_schema(self, schema):
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1442
        """set the instance'schema"""
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1443
        if 'CWUser' in schema:  # probably an empty schema if not true...
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1444
            # rql syntax trees used to authenticate users
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1445
            self._passwd_rqlst = self.source.compile_rql(self.passwd_rql, self._sols)
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1446
            self._auth_rqlst = self.source.compile_rql(self.auth_rql, self._sols)
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1447
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9487
diff changeset
  1448
    def authenticate(self, cnx, login, password=None, **kwargs):
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1449
        """return CWUser eid for the given login/password if this account is
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1450
        defined in this source, else raise `AuthenticationError`
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1451
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1452
        two queries are needed since passwords are stored crypted, so we have
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1453
        to fetch the salt first
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1454
        """
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1455
        args = {'login': login, 'pwd': None}
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1456
        if password is not None:
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9487
diff changeset
  1457
            rset = self.source.syntax_tree_search(cnx, self._passwd_rqlst, args)
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1458
            try:
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1459
                pwd = rset[0][0]
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1460
            except IndexError:
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1461
                raise AuthenticationError('bad login')
8235
c2a91d6639d8 [system source] fix authentication: don't allow login whatever the given password if user password is NULL in database. Closes #2186099
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8205
diff changeset
  1462
            if pwd is None:
c2a91d6639d8 [system source] fix authentication: don't allow login whatever the given password if user password is NULL in database. Closes #2186099
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8205
diff changeset
  1463
                # if pwd is None but a password is provided, something is wrong
c2a91d6639d8 [system source] fix authentication: don't allow login whatever the given password if user password is NULL in database. Closes #2186099
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8205
diff changeset
  1464
                raise AuthenticationError('bad password')
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1465
            # passwords are stored using the Bytes type, so we get a StringIO
8317
9c59258e7798 [security] use a stronger encryption algorythm for password, keeping bw compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8235
diff changeset
  1466
            args['pwd'] = Binary(crypt_password(password, pwd.getvalue()))
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1467
        # get eid from login and (crypted) password
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9487
diff changeset
  1468
        rset = self.source.syntax_tree_search(cnx, self._auth_rqlst, args)
10037
6b83ceda8323 [server] fix LoginPasswordAuthentifier.authenticate
David Douard <david.douard@logilab.fr>
parents: 9996
diff changeset
  1469
        pwd = args['pwd']
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1470
        try:
8546
3d2038d6f20d [sources/native] automatically update passwords using deprecated hashes on login
Julien Cristau <julien.cristau@logilab.fr>
parents: 8520
diff changeset
  1471
            user = rset[0][0]
3d2038d6f20d [sources/native] automatically update passwords using deprecated hashes on login
Julien Cristau <julien.cristau@logilab.fr>
parents: 8520
diff changeset
  1472
            # If the stored hash uses a deprecated scheme (e.g. DES or MD5 used
3d2038d6f20d [sources/native] automatically update passwords using deprecated hashes on login
Julien Cristau <julien.cristau@logilab.fr>
parents: 8520
diff changeset
  1473
            # before 3.14.7), update with a fresh one
10037
6b83ceda8323 [server] fix LoginPasswordAuthentifier.authenticate
David Douard <david.douard@logilab.fr>
parents: 9996
diff changeset
  1474
            if pwd is not None and pwd.getvalue():
8546
3d2038d6f20d [sources/native] automatically update passwords using deprecated hashes on login
Julien Cristau <julien.cristau@logilab.fr>
parents: 8520
diff changeset
  1475
                verify, newhash = verify_and_update(password, pwd.getvalue())
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1476
                if not verify:  # should not happen, but...
8546
3d2038d6f20d [sources/native] automatically update passwords using deprecated hashes on login
Julien Cristau <julien.cristau@logilab.fr>
parents: 8520
diff changeset
  1477
                    raise AuthenticationError('bad password')
3d2038d6f20d [sources/native] automatically update passwords using deprecated hashes on login
Julien Cristau <julien.cristau@logilab.fr>
parents: 8520
diff changeset
  1478
                if newhash:
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1479
                    cnx.system_sql("UPDATE %s SET %s=%%(newhash)s WHERE %s=%%(login)s"
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1480
                                   % (SQL_PREFIX + 'CWUser',
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1481
                                      SQL_PREFIX + 'upassword',
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1482
                                      SQL_PREFIX + 'login'),
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1483
                                   {'newhash': self.source._binary(newhash.encode('ascii')),
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1484
                                    'login': login})
10364
8b35a898b334 [server] remove cnxset tracking, it is now unneeded
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10360
diff changeset
  1485
                    cnx.commit()
8546
3d2038d6f20d [sources/native] automatically update passwords using deprecated hashes on login
Julien Cristau <julien.cristau@logilab.fr>
parents: 8520
diff changeset
  1486
            return user
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1487
        except IndexError:
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
  1488
            raise AuthenticationError('bad password')
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: 6724
diff changeset
  1489
5a0c2cfc19bf [repository auth] cleanup email login by turning it into a proper repo-side authentication plugin
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6724
diff changeset
  1490
5a0c2cfc19bf [repository auth] cleanup email login by turning it into a proper repo-side authentication plugin
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6724
diff changeset
  1491
class EmailPasswordAuthentifier(BaseAuthentifier):
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9487
diff changeset
  1492
    def authenticate(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: 6724
diff changeset
  1493
        # email_auth flag prevent from infinite recursion (call to
5a0c2cfc19bf [repository auth] cleanup email login by turning it into a proper repo-side authentication plugin
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6724
diff changeset
  1494
        # repo.check_auth_info at the end of this method may lead us here again)
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1495
        if '@' not in login or authinfo.pop('email_auth', None):
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: 6724
diff changeset
  1496
            raise AuthenticationError('not an email')
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9487
diff changeset
  1497
        rset = cnx.execute('Any L WHERE U login L, U primary_email M, '
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1498
                           'M address %(login)s', {'login': login},
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1499
                           build_descr=False)
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: 6724
diff changeset
  1500
        if rset.rowcount != 1:
5a0c2cfc19bf [repository auth] cleanup email login by turning it into a proper repo-side authentication plugin
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6724
diff changeset
  1501
            raise AuthenticationError('unexisting email')
5a0c2cfc19bf [repository auth] cleanup email login by turning it into a proper repo-side authentication plugin
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6724
diff changeset
  1502
        login = rset.rows[0][0]
5a0c2cfc19bf [repository auth] cleanup email login by turning it into a proper repo-side authentication plugin
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6724
diff changeset
  1503
        authinfo['email_auth'] = True
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9487
diff changeset
  1504
        return self.source.repo.check_auth_info(cnx, login, authinfo)
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1505
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1506
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1507
class DatabaseIndependentBackupRestore(object):
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1508
    """Helper class to perform db backend agnostic backup and restore
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1509
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1510
    The backup and restore methods are used to dump / restore the
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1511
    system database in a database independent format. The file is a
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1512
    Zip archive containing the following files:
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1513
10197
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1514
    * format.txt: the format of the archive. Currently '1.1'
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1515
    * tables.txt: list of filenames in the archive tables/ directory
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1516
    * sequences.txt: list of filenames in the archive sequences/ directory
10197
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1517
    * numranges.txt: list of filenames in the archive numrange/ directory
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1518
    * versions.txt: the list of cube versions from CWProperty
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1519
    * tables/<tablename>.<chunkno>: pickled data
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1520
    * sequences/<sequencename>: pickled data
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1521
10197
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1522
    The pickled data format for tables, numranges and sequences is a tuple of 3 elements:
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1523
    * the table name
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1524
    * a tuple of column names
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1525
    * a list of rows (as tuples with one element per column)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1526
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1527
    Tables are saved in chunks in different files in order to prevent
7551
2d4ba5b984dc cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7530
diff changeset
  1528
    a too high memory consumption.
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1529
    """
10048
7d9256aab337 [source/native/backup_restore] have a unique tunable blocksize for the dump phase
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9336
diff changeset
  1530
    blocksize = 100
7d9256aab337 [source/native/backup_restore] have a unique tunable blocksize for the dump phase
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9336
diff changeset
  1531
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1532
    def __init__(self, source):
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1533
        """
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1534
        :param: source an instance of the system source
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1535
        """
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1536
        self._source = source
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1537
        self.logger = logging.getLogger('cubicweb.ctl')
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1538
        self.logger.setLevel(logging.INFO)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1539
        self.logger.addHandler(logging.StreamHandler(sys.stdout))
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1540
        self.schema = self._source.schema
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1541
        self.dbhelper = self._source.dbhelper
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1542
        self.cnx = None
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1543
        self.cursor = None
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1544
        self.sql_generator = sqlgen.SQLGenerator()
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1545
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1546
    def get_connection(self):
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1547
        return self._source.get_connection()
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1548
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1549
    def backup(self, backupfile):
8910
7652c3d46ba3 [portable dump] skip virtual relations, they have no table associated. Closes #2841199
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8821
diff changeset
  1550
        archive = zipfile.ZipFile(backupfile, 'w', allowZip64=True)
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1551
        self.cnx = self.get_connection()
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1552
        try:
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1553
            self.cursor = self.cnx.cursor()
9468
39b7a91a3f4c [repo] pylint cleanup, mainly of imports, with a bit of style
Julien Cristau <julien.cristau@logilab.fr>
parents: 9467
diff changeset
  1554
            self.cursor.arraysize = 100
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1555
            self.logger.info('writing metadata')
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1556
            self.write_metadata(archive)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1557
            for seq in self.get_sequences():
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1558
                self.logger.info('processing sequence %s', seq)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1559
                self.write_sequence(archive, seq)
10196
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1560
            for numrange in self.get_numranges():
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1561
                self.logger.info('processing numrange %s', numrange)
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1562
                self.write_numrange(archive, numrange)
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1563
            for table in self.get_tables():
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1564
                self.logger.info('processing table %s', table)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1565
                self.write_table(archive, table)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1566
        finally:
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1567
            archive.close()
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1568
            self.cnx.close()
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1569
        self.logger.info('done')
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1570
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1571
    def get_tables(self):
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1572
        non_entity_tables = ['entities',
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1573
                             'transactions',
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1574
                             'tx_entity_actions',
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1575
                             'tx_relation_actions',
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1576
                             ]
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1577
        etype_tables = []
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1578
        relation_tables = []
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1579
        prefix = 'cw_'
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1580
        for etype in self.schema.entities():
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1581
            eschema = self.schema.eschema(etype)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1582
            if eschema.final:
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1583
                continue
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1584
            etype_tables.append('%s%s' % (prefix, etype))
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1585
        for rtype in self.schema.relations():
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1586
            rschema = self.schema.rschema(rtype)
8910
7652c3d46ba3 [portable dump] skip virtual relations, they have no table associated. Closes #2841199
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8821
diff changeset
  1587
            if rschema.final or rschema.inlined or rschema in VIRTUAL_RTYPES:
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1588
                continue
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1589
            relation_tables.append('%s_relation' % rtype)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1590
        return non_entity_tables + etype_tables + relation_tables
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1591
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1592
    def get_sequences(self):
10196
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1593
        return []
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1594
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1595
    def get_numranges(self):
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1596
        return ['entities_id_seq']
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1597
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1598
    def write_metadata(self, archive):
10196
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1599
        archive.writestr('format.txt', '1.1')
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1600
        archive.writestr('tables.txt', '\n'.join(self.get_tables()))
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1601
        archive.writestr('sequences.txt', '\n'.join(self.get_sequences()))
10196
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1602
        archive.writestr('numranges.txt', '\n'.join(self.get_numranges()))
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1603
        versions = self._get_versions()
9468
39b7a91a3f4c [repo] pylint cleanup, mainly of imports, with a bit of style
Julien Cristau <julien.cristau@logilab.fr>
parents: 9467
diff changeset
  1604
        versions_str = '\n'.join('%s %s' % (k, v)
39b7a91a3f4c [repo] pylint cleanup, mainly of imports, with a bit of style
Julien Cristau <julien.cristau@logilab.fr>
parents: 9467
diff changeset
  1605
                                 for k, v in versions)
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1606
        archive.writestr('versions.txt', versions_str)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1607
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1608
    def write_sequence(self, archive, seq):
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1609
        sql = self.dbhelper.sql_sequence_current_state(seq)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1610
        columns, rows_iterator = self._get_cols_and_rows(sql)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1611
        rows = list(rows_iterator)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1612
        serialized = self._serialize(seq, columns, rows)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1613
        archive.writestr('sequences/%s' % seq, serialized)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1614
10196
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1615
    def write_numrange(self, archive, numrange):
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1616
        sql = self.dbhelper.sql_numrange_current_state(numrange)
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1617
        columns, rows_iterator = self._get_cols_and_rows(sql)
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1618
        rows = list(rows_iterator)
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1619
        serialized = self._serialize(numrange, columns, rows)
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1620
        archive.writestr('numrange/%s' % numrange, serialized)
20d56b1f035e [backup/portable] properly write the eid numrange generator (the eid is no more a sequence)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10183
diff changeset
  1621
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1622
    def write_table(self, archive, table):
7753
681ef2a664dd work around cursor.rowcount not returning anything useful before 1st fetch with mssql (closes #1910869)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7551
diff changeset
  1623
        nb_lines_sql = 'SELECT COUNT(*) FROM %s' % table
681ef2a664dd work around cursor.rowcount not returning anything useful before 1st fetch with mssql (closes #1910869)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7551
diff changeset
  1624
        self.cursor.execute(nb_lines_sql)
681ef2a664dd work around cursor.rowcount not returning anything useful before 1st fetch with mssql (closes #1910869)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7551
diff changeset
  1625
        rowcount = self.cursor.fetchone()[0]
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1626
        sql = 'SELECT * FROM %s' % table
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1627
        columns, rows_iterator = self._get_cols_and_rows(sql)
7753
681ef2a664dd work around cursor.rowcount not returning anything useful before 1st fetch with mssql (closes #1910869)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7551
diff changeset
  1628
        self.logger.info('number of rows: %d', rowcount)
10048
7d9256aab337 [source/native/backup_restore] have a unique tunable blocksize for the dump phase
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9336
diff changeset
  1629
        blocksize = self.blocksize
7753
681ef2a664dd work around cursor.rowcount not returning anything useful before 1st fetch with mssql (closes #1910869)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7551
diff changeset
  1630
        if rowcount > 0:
10609
e2d8e81bfe68 [py3k] import range using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10602
diff changeset
  1631
            for i, start in enumerate(range(0, rowcount, blocksize)):
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1632
                rows = list(itertools.islice(rows_iterator, blocksize))
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1633
                serialized = self._serialize(table, columns, rows)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1634
                archive.writestr('tables/%s.%04d' % (table, i), serialized)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1635
                self.logger.debug('wrote rows %d to %d (out of %d) to %s.%04d',
11417
5e5e224239c3 pep8 bits
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11413
diff changeset
  1636
                                  start, start + len(rows) - 1,
7753
681ef2a664dd work around cursor.rowcount not returning anything useful before 1st fetch with mssql (closes #1910869)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7551
diff changeset
  1637
                                  rowcount,
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1638
                                  table, i)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1639
        else:
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1640
            rows = []
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1641
            serialized = self._serialize(table, columns, rows)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1642
            archive.writestr('tables/%s.%04d' % (table, 0), serialized)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1643
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1644
    def _get_cols_and_rows(self, sql):
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1645
        process_result = self._source.iter_process_result
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1646
        self.cursor.execute(sql)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1647
        columns = (d[0] for d in self.cursor.description)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1648
        rows = process_result(self.cursor)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1649
        return tuple(columns), rows
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1650
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1651
    def _serialize(self, name, columns, rows):
10602
4845012cfc8e [py3k] import 'pickle' using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10589
diff changeset
  1652
        return pickle.dumps((name, columns, rows), pickle.HIGHEST_PROTOCOL)
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1653
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1654
    def restore(self, backupfile):
7787
d9607ae447d2 [server] portable dump format supports now ZIP64 extensions by default (closes #1912535)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7786
diff changeset
  1655
        archive = zipfile.ZipFile(backupfile, 'r', allowZip64=True)
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1656
        self.cnx = self.get_connection()
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1657
        self.cursor = self.cnx.cursor()
10197
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1658
        sequences, numranges, tables, table_chunks = self.read_metadata(archive, backupfile)
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1659
        for seq in sequences:
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1660
            self.logger.info('restoring sequence %s', seq)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1661
            self.read_sequence(archive, seq)
10197
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1662
        for numrange in numranges:
10623
b9322cc17d7e [sources/native] fix potential NameError (closes #7364249)
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 10270
diff changeset
  1663
            self.logger.info('restoring numrange %s', numrange)
10197
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1664
            self.read_numrange(archive, numrange)
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1665
        for table in tables:
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1666
            self.logger.info('restoring table %s', table)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1667
            self.read_table(archive, table, sorted(table_chunks[table]))
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1668
        self.cnx.close()
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1669
        archive.close()
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1670
        self.logger.info('done')
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1671
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1672
    def read_metadata(self, archive, backupfile):
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1673
        formatinfo = archive.read('format.txt')
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1674
        self.logger.info('checking metadata')
10197
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1675
        if formatinfo.strip() != "1.1":
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1676
            self.logger.critical('Unsupported format in archive: %s', formatinfo)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1677
            raise ValueError('Unknown format in %s: %s' % (backupfile, formatinfo))
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1678
        tables = archive.read('tables.txt').splitlines()
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1679
        sequences = archive.read('sequences.txt').splitlines()
10197
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1680
        numranges = archive.read('numranges.txt').splitlines()
11060
3699fca78836 [sources/native] ask permission to continue restoring even if metadata do not match (closes #7771864)
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 10623
diff changeset
  1681
        archive_versions = self._parse_versions(archive.read('versions.txt'))
3699fca78836 [sources/native] ask permission to continue restoring even if metadata do not match (closes #7771864)
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 10623
diff changeset
  1682
        db_versions = set(self._get_versions())
3699fca78836 [sources/native] ask permission to continue restoring even if metadata do not match (closes #7771864)
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 10623
diff changeset
  1683
        if archive_versions != db_versions:
11115
a385bd146178 [sources/native] remove extra space before colon
Julien Cristau <julien.cristau@logilab.fr>
parents: 11060
diff changeset
  1684
            self.logger.critical('Restore warning: versions do not match')
11060
3699fca78836 [sources/native] ask permission to continue restoring even if metadata do not match (closes #7771864)
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 10623
diff changeset
  1685
            new_cubes = db_versions - archive_versions
3699fca78836 [sources/native] ask permission to continue restoring even if metadata do not match (closes #7771864)
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 10623
diff changeset
  1686
            if new_cubes:
12156
0d1d22a3a48b Fix some flake8 errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12153
diff changeset
  1687
                self.logger.critical('In the db:\n%s', '\n'.join(
0d1d22a3a48b Fix some flake8 errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12153
diff changeset
  1688
                    '%s: %s' % (cube, ver) for cube, ver in sorted(new_cubes)))
11060
3699fca78836 [sources/native] ask permission to continue restoring even if metadata do not match (closes #7771864)
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 10623
diff changeset
  1689
            old_cubes = archive_versions - db_versions
3699fca78836 [sources/native] ask permission to continue restoring even if metadata do not match (closes #7771864)
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 10623
diff changeset
  1690
            if old_cubes:
12156
0d1d22a3a48b Fix some flake8 errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12153
diff changeset
  1691
                self.logger.critical('In the archive:\n%s', '\n'.join(
0d1d22a3a48b Fix some flake8 errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12153
diff changeset
  1692
                    '%s: %s' % (cube, ver) for cube, ver in sorted(old_cubes)))
11060
3699fca78836 [sources/native] ask permission to continue restoring even if metadata do not match (closes #7771864)
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 10623
diff changeset
  1693
            if not ASK.confirm('Versions mismatch: continue anyway ?', False):
11115
a385bd146178 [sources/native] remove extra space before colon
Julien Cristau <julien.cristau@logilab.fr>
parents: 11060
diff changeset
  1694
                raise ValueError('Unable to restore: versions do not match')
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1695
        table_chunks = {}
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1696
        for name in archive.namelist():
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1697
            if not name.startswith('tables/'):
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1698
                continue
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1699
            filename = basename(name)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1700
            tablename, _ext = filename.rsplit('.', 1)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1701
            table_chunks.setdefault(tablename, []).append(name)
10197
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1702
        return sequences, numranges, tables, table_chunks
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1703
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1704
    def read_sequence(self, archive, seq):
10602
4845012cfc8e [py3k] import 'pickle' using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10589
diff changeset
  1705
        seqname, columns, rows = pickle.loads(archive.read('sequences/%s' % seq))
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1706
        assert seqname == seq
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1707
        assert len(rows) == 1
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1708
        assert len(rows[0]) == 1
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1709
        value = rows[0][0]
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1710
        sql = self.dbhelper.sql_restart_sequence(seq, value)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1711
        self.cursor.execute(sql)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1712
        self.cnx.commit()
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1713
10197
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1714
    def read_numrange(self, archive, numrange):
10602
4845012cfc8e [py3k] import 'pickle' using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10589
diff changeset
  1715
        rangename, columns, rows = pickle.loads(archive.read('numrange/%s' % numrange))
10197
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1716
        assert rangename == numrange
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1717
        assert len(rows) == 1
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1718
        assert len(rows[0]) == 1
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1719
        value = rows[0][0]
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1720
        sql = self.dbhelper.sql_restart_numrange(numrange, value)
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1721
        self.cursor.execute(sql)
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1722
        self.cnx.commit()
7c732d2abbc1 [restore/portable] properly restore the numrange generator
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10196
diff changeset
  1723
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1724
    def read_table(self, archive, table, filenames):
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1725
        merge_args = self._source.merge_args
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1726
        self.cursor.execute('DELETE FROM %s' % table)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1727
        self.cnx.commit()
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1728
        row_count = 0
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1729
        for filename in filenames:
10602
4845012cfc8e [py3k] import 'pickle' using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10589
diff changeset
  1730
            tablename, columns, rows = pickle.loads(archive.read(filename))
7342
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1731
            assert tablename == table
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1732
            if not rows:
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1733
                continue
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1734
            insert = self.sql_generator.insert(table,
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1735
                                               dict(zip(columns, rows[0])))
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1736
            for row in rows:
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1737
                self.cursor.execute(insert, merge_args(dict(zip(columns, row)), {}))
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1738
            row_count += len(rows)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1739
            self.cnx.commit()
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1740
        self.logger.info('inserted %d rows', row_count)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1741
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1742
    def _parse_versions(self, version_str):
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1743
        versions = set()
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1744
        for line in version_str.splitlines():
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1745
            versions.add(tuple(line.split()))
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1746
        return versions
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1747
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1748
    def _get_versions(self):
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1749
        version_sql = 'SELECT cw_pkey, cw_value FROM cw_CWProperty'
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1750
        versions = []
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1751
        self.cursor.execute(version_sql)
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1752
        for pkey, value in self.cursor.fetchall():
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1753
            if pkey.startswith(u'system.version'):
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1754
                versions.append((pkey, value))
d1c8b5b3531c adds support for a portable db import/export format (closes: #1521112)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7243
diff changeset
  1755
        return versions