server/sources/native.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 29 Sep 2010 12:16:28 +0200
branchstable
changeset 6359 0bff5a05385c
parent 6297 23c1e50ff97b
child 6366 1806148d6ce8
permissions -rw-r--r--
[sync schema] take care rdef may not be final, in which case we want to use type of eid attribute
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
     1
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
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/>.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
"""Adapters for native cubicweb sources.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
1952
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
    20
Notes:
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
    21
* extid (aka external id, the primary key of an entity in the external source
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
    22
  from which it comes from) are stored in a varchar column encoded as a base64
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
    23
  string. This is because it should actually be Bytes but we want an index on
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
    24
  it for fast querying.
5824
de9b7e88660e cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5751
diff changeset
    25
"""
2056
57d287a2132a reminder
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    26
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    27
from __future__ import with_statement
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    28
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    31
from pickle import loads, dumps
4900
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4893
diff changeset
    32
from threading import Lock
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 973
diff changeset
    33
from datetime import datetime
1952
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
    34
from base64 import b64decode, b64encode
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
    35
from contextlib import contextmanager
5542
a8ad3df5a8a3 [test] absolute sqlite database names in source initialization, avoid pb when cwd is changed later
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5515
diff changeset
    36
from os.path import abspath
6211
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
    37
import re
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
    39
from logilab.common.compat import any
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
from logilab.common.cache import Cache
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
    41
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
    42
from logilab.common.configuration import Method
a191b3b9e455 more sensible default values to c-c "create" inputs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
    43
from logilab.common.shellutils import getlogin
4848
41f84eea63c9 rename logilab.db into logilab.database
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4845
diff changeset
    44
from logilab.database import get_db_helper
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
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
    46
from yams import schema2sql as y2sql
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
    47
6211
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
    48
from cubicweb import UnknownEid, AuthenticationError, ValidationError, Binary, UniqueTogetherError
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
    49
from cubicweb import transaction as tx, server, neg_role
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
    50
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
    51
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
    52
from cubicweb.server import hook
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
    53
from cubicweb.server.utils import crypt_password, eschema_eid
2759
23d7a75693f8 R refactor backup and use tar.gz to store all sources
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2638
diff changeset
    54
from cubicweb.server.sqlutils import SQL_PREFIX, SQLAdapterMixIn
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
from cubicweb.server.rqlannotation import 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
    56
from cubicweb.server.hook import CleanupDeletedEidsCacheOp
4943
7f5b83578fec disable security when undoing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4913
diff changeset
    57
from cubicweb.server.session import hooks_control, security_enabled
2625
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
    58
from cubicweb.server.sources import AbstractSource, dbg_st_search, dbg_results
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
from cubicweb.server.sources.rql2sql import SQLGenerator
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
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
    62
ATTR_MAP = {}
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
NONSYSTEM_ETYPES = set()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
NONSYSTEM_RELATIONS = set()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
class LogCursor(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
    def __init__(self, cursor):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
        self.cu = cursor
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    69
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
    def execute(self, query, args=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
        """Execute a query.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
        it's a function just so that it shows up in profiling
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
        """
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
    74
        if server.DEBUG & server.DBG_SQL:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
            print 'exec', query, args
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
            self.cu.execute(str(query), args)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
        except Exception, ex:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
            print "sql: %r\n args: %s\ndbms message: %r" % (
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
                query, args, ex.args[0])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
            raise
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    82
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
    def fetchall(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
        return self.cu.fetchall()
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    85
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
    def fetchone(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
        return self.cu.fetchone()
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
    88
2625
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
    89
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
def make_schema(selected, solution, table, typemap):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
    """return a sql schema to store RQL query result"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
    sql = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
    varmap = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
    for i, term in enumerate(selected):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
        name = 'C%s' % i
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
        key = term.as_string()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
        varmap[key] = '%s.%s' % (table, name)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
        ttype = term.get_type(solution)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
            sql.append('%s %s' % (name, typemap[ttype]))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
        except KeyError:
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3497
diff changeset
   102
            # assert not schema(ttype).final
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
            sql.append('%s %s' % (name, typemap['Int']))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
    return ','.join(sql), varmap
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
2625
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   106
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
def _modified_sql(table, etypes):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
    # XXX protect against sql injection
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
    if len(etypes) > 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
        restr = 'type IN (%s)' % ','.join("'%s'" % etype for etype in etypes)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
        restr = "type='%s'" % etypes[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
    if table == 'entities':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
        attr = 'mtime'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
        attr = 'dtime'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
    return 'SELECT type, eid FROM %s WHERE %s AND %s > %%(time)s' % (
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
        table, restr, attr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   121
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
   122
    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
   123
    restrclauses = restr.split(' AND ')
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   124
    for clause in clauses:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   125
        restrclauses.remove(clause)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   126
    if restrclauses:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   127
        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
   128
                                 ' OR '.join(clauses))
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   129
    else:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   130
        restr = '(%s)' % ' OR '.join(clauses)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   131
    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
   132
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
   133
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
   134
    """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
   135
    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
   136
    """
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
   137
    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
   138
            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
   139
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
   140
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
   141
    """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
   142
    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
   143
    """
6359
0bff5a05385c [sync schema] take care rdef may not be final, in which case we want to use type of eid attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6297
diff changeset
   144
    if rdef.object.final:
0bff5a05385c [sync schema] take care rdef may not be final, in which case we want to use type of eid attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6297
diff changeset
   145
        ttype = rdef.object
0bff5a05385c [sync schema] take care rdef may not be final, in which case we want to use type of eid attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6297
diff changeset
   146
    else:
0bff5a05385c [sync schema] take care rdef may not be final, in which case we want to use type of eid attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6297
diff changeset
   147
        ttype = 'Int' # eid type
0bff5a05385c [sync schema] take care rdef may not be final, in which case we want to use type of eid attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6297
diff changeset
   148
    coltype = y2sql.type_from_constraints(dbhelper, ttype,
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
   149
                                          rdef.constraints, creating=False)
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
   150
    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
   151
    return coltype, allownull
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   152
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   153
class UndoException(Exception):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   154
    """something went wrong during undoing"""
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   155
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   156
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   157
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
   158
    """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
   159
    card = rdef.role_cardinality(role)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   160
    if card in '?1' and tentity.related(rdef.rtype, role):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   161
        raise UndoException(tentity._cw._(
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   162
            "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
   163
            "is already linked using this relation.")
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   164
                            % {'role': neg_role(role),
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   165
                               'rtype': rdef.rtype,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   166
                               'eid': tentity.eid})
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   167
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   168
def _undo_rel_info(session, subj, rtype, obj):
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   169
    entities = []
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   170
    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
   171
        try:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   172
            entities.append(session.entity_from_eid(eid))
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   173
        except UnknownEid:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   174
            raise UndoException(session._(
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   175
                "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
   176
                " doesn't exist anymore.")
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   177
                                % {'role': session._(role),
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   178
                                   'rtype': session._(rtype),
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   179
                                   'eid': eid})
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   180
    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
   181
    try:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   182
        rschema = session.vreg.schema.rschema(rtype)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   183
        rdef = rschema.rdefs[(sentity.__regid__, oentity.__regid__)]
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   184
    except KeyError:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   185
        raise UndoException(session._(
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   186
            "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
   187
            "%(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
   188
            "schema.")
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   189
                            % {'rtype': session._(rtype),
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   190
                               'subj': subj,
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   191
                               'obj': obj})
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   192
    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
   193
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   194
def _undo_has_later_transaction(session, eid):
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   195
    return session.system_sql('''\
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   196
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
   197
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
   198
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
   199
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
   200
            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
   201
     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
   202
               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
   203
                   TRA.eid_from=%(eid)s OR TRA.eid_to=%(eid)s))
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   204
     )''' % {'txuuid': session.transaction_data['undoing_uuid'],
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   205
             '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
   206
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   207
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
class NativeSQLSource(SQLAdapterMixIn, AbstractSource):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
    """adapter for source using the native cubicweb schema (see below)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
    """
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
   211
    sqlgen_class = SQLGenerator
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
    options = (
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
        ('db-driver',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
         {'type' : 'string',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
          '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
   216
          # XXX use choice type
e15abfdcce38 backport default into stable: stable is now cw 3.8
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5397 5421
diff changeset
   217
          'help': 'database driver (postgres, mysql, sqlite, sqlserver2005)',
6201
cf445fcaf8fe [c-c create] ask for database driver by default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6128
diff changeset
   218
          'group': 'native-source', 'level': 0,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
          }),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
        ('db-host',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
         {'type' : 'string',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
          'default': '',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
          '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
   224
          'group': 'native-source', 'level': 1,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
          }),
2566
714a8743d423 missing db-port option to source's option definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2354
diff changeset
   226
        ('db-port',
714a8743d423 missing db-port option to source's option definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2354
diff changeset
   227
         {'type' : 'string',
714a8743d423 missing db-port option to source's option definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2354
diff changeset
   228
          'default': '',
714a8743d423 missing db-port option to source's option definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2354
diff changeset
   229
          '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
   230
          '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
   231
          }),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
        ('db-name',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
         {'type' : 'string',
3835
a191b3b9e455 more sensible default values to c-c "create" inputs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   234
          'default': Method('default_instance_id'),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
          '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
   236
          'group': 'native-source', 'level': 0,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
          }),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
        ('db-user',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
         {'type' : 'string',
3835
a191b3b9e455 more sensible default values to c-c "create" inputs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   240
          'default': CubicWebNoAppConfiguration.mode == 'user' and getlogin() or 'cubicweb',
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
          '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
   242
          'group': 'native-source', 'level': 0,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
          }),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
        ('db-password',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
         {'type' : 'password',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
          'default': '',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
          '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
   248
          'group': 'native-source', 'level': 0,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
          }),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
        ('db-encoding',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   251
         {'type' : 'string',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
          'default': 'utf8',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   253
          '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
   254
          'group': 'native-source', 'level': 1,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
          }),
5413
dc896e698ab0 added db-extra-arguments to configuration parameters for native source
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5410
diff changeset
   256
        ('db-extra-arguments',
dc896e698ab0 added db-extra-arguments to configuration parameters for native source
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5410
diff changeset
   257
         {'type' : 'string',
dc896e698ab0 added db-extra-arguments to configuration parameters for native source
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5410
diff changeset
   258
          'default': '',
dc896e698ab0 added db-extra-arguments to configuration parameters for native source
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5410
diff changeset
   259
          '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
   260
                  '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
   261
          '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
   262
          }),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
    )
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   264
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
    def __init__(self, repo, appschema, source_config, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
        SQLAdapterMixIn.__init__(self, source_config)
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
   267
        self.authentifiers = [LoginPasswordAuthentifier(self)]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
        AbstractSource.__init__(self, repo, appschema, source_config,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
                                *args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
        # sql generator
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
   271
        self._rql_sqlgen = self.sqlgen_class(appschema, self.dbhelper,
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
   272
                                             ATTR_MAP.copy())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
        # 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
   274
        self.do_fti = not repo.config['delay-full-text-indexation']
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   275
        # sql queries cache
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
        self._cache = Cache(repo.config['rql-cache-size'])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   277
        self._temp_table_data = {}
5061
cdab5220eac0 [cleanup]
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5059
diff changeset
   278
        # we need a lock to protect eid attribution function (XXX, really?
cdab5220eac0 [cleanup]
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5059
diff changeset
   279
        # explain)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   280
        self._eid_creation_lock = Lock()
5690
6de8437b06bd [source] don't create the eid_creation connection at source initiliaztion time
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5649
diff changeset
   281
        self._eid_creation_cnx = None
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   282
        # (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
   283
        self._storages = {}
5059
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   284
        # entity types that may be used by other multi-sources instances
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   285
        self.multisources_etypes = set(repo.config['multi-sources-etypes'])
2072
8008e8812d76 deactivate sqlite connection wrapping for unittest_multisources for now
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2066
diff changeset
   286
        # XXX no_sqlite_wrap trick since we've a sqlite locking pb when
8008e8812d76 deactivate sqlite connection wrapping for unittest_multisources for now
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2066
diff changeset
   287
        # running unittest_multisources with the wrapping below
8008e8812d76 deactivate sqlite connection wrapping for unittest_multisources for now
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2066
diff changeset
   288
        if self.dbdriver == 'sqlite' and \
8008e8812d76 deactivate sqlite connection wrapping for unittest_multisources for now
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2066
diff changeset
   289
               not getattr(repo.config, 'no_sqlite_wrap', False):
2064
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   290
            from cubicweb.server.sources.extlite import ConnectionWrapper
5542
a8ad3df5a8a3 [test] absolute sqlite database names in source initialization, avoid pb when cwd is changed later
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5515
diff changeset
   291
            self.dbhelper.dbname = abspath(self.dbhelper.dbname)
2064
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   292
            self.get_connection = lambda: ConnectionWrapper(self)
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   293
            self.check_connection = lambda cnx: cnx
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   294
            def pool_reset(cnx):
2620
de68f84b8f54 R [sql source] cnx._cnx checked in cnx.close, don't do it here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2619
diff changeset
   295
                cnx.close()
2064
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   296
            self.pool_reset = pool_reset
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
   297
        if self.dbdriver == 'sqlite':
a07dee204187 fix unit tests by not using the new create_eid implementation with sqlite
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5645
diff changeset
   298
            self._create_eid = None
a07dee204187 fix unit tests by not using the new create_eid implementation with sqlite
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5645
diff changeset
   299
            self.create_eid = self._create_eid_sqlite
5847
51636c991fb4 [migration] refactor schema migration fix introduced by 5833:d7256ae7c1d1
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5824
diff changeset
   300
        self.binary_to_str = self.dbhelper.dbapi_module.binary_to_str
51636c991fb4 [migration] refactor schema migration fix introduced by 5833:d7256ae7c1d1
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5824
diff changeset
   301
2064
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   302
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   303
    @property
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   304
    def _sqlcnx(self):
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   305
        # XXX: sqlite connections can only be used in the same thread, so
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   306
        #      create a new one each time necessary. If it appears to be time
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   307
        #      consuming, find another way
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   308
        return SQLAdapterMixIn.get_connection(self)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   309
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
   310
    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
   311
        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
   312
        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
   313
        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
   314
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   315
    def reset_caches(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   316
        """method called during test to reset potential source caches"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   317
        self._cache = Cache(self.repo.config['rql-cache-size'])
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   318
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   319
    def clear_eid_cache(self, eid, etype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   320
        """clear potential caches for the given eid"""
2610
2933cc6bf9ad [F native source] fix attempts to clear cache key
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2593
diff changeset
   321
        self._cache.pop('Any X WHERE X eid %s, X is %s' % (eid, etype), None)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   322
        self._cache.pop('Any X WHERE X eid %s' % eid, None)
2610
2933cc6bf9ad [F native source] fix attempts to clear cache key
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2593
diff changeset
   323
        self._cache.pop('Any %s' % eid, None)
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   324
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   325
    def sqlexec(self, session, sql, args=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   326
        """execute the query and return its result"""
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
   327
        return self.process_result(self.doexec(session, sql, args))
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   328
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   329
    def init_creating(self):
2064
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   330
        pool = self.repo._get_pool()
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   331
        pool.pool_set()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   332
        # 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
   333
        if self.do_fti:
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
   334
            if not self.dbhelper.has_fti_table(pool['system']):
4825
cdd979ae1b57 fix name error fixed in wrong branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4818
diff changeset
   335
                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
   336
                    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
   337
                self.do_fti = False
2064
a5cd3a92314a properly call [re]set_pool, fix connection handling so we have a change to get cw running on top of a sqlite dabase with threads activated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2056
diff changeset
   338
        pool.pool_reset()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   339
        self.repo._free_pool(pool)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   340
4893
15ae9a33a7f2 [db backup] fix name error in backup_to_file: we've to pass .confirm all along the chain as for restore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4836
diff changeset
   341
    def backup(self, backupfile, confirm):
2759
23d7a75693f8 R refactor backup and use tar.gz to store all sources
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2638
diff changeset
   342
        """method called to create a backup of the source's data"""
23d7a75693f8 R refactor backup and use tar.gz to store all sources
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2638
diff changeset
   343
        self.close_pool_connections()
23d7a75693f8 R refactor backup and use tar.gz to store all sources
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2638
diff changeset
   344
        try:
4893
15ae9a33a7f2 [db backup] fix name error in backup_to_file: we've to pass .confirm all along the chain as for restore
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4836
diff changeset
   345
            self.backup_to_file(backupfile, confirm)
2759
23d7a75693f8 R refactor backup and use tar.gz to store all sources
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2638
diff changeset
   346
        finally:
23d7a75693f8 R refactor backup and use tar.gz to store all sources
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2638
diff changeset
   347
            self.open_pool_connections()
2493
9806571ea790 major refactoring of database dump/restore:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   348
4195
86dcaf6bb92f closes #601987
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4185
diff changeset
   349
    def restore(self, backupfile, confirm, drop):
2493
9806571ea790 major refactoring of database dump/restore:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   350
        """method called to restore a backup of source's data"""
2959
daabb9bc5233 make db-restore command work even with no/corrupted database
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2759
diff changeset
   351
        if self.repo.config.open_connections_pools:
daabb9bc5233 make db-restore command work even with no/corrupted database
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2759
diff changeset
   352
            self.close_pool_connections()
2759
23d7a75693f8 R refactor backup and use tar.gz to store all sources
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2638
diff changeset
   353
        try:
4195
86dcaf6bb92f closes #601987
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4185
diff changeset
   354
            self.restore_from_file(backupfile, confirm, drop=drop)
2759
23d7a75693f8 R refactor backup and use tar.gz to store all sources
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2638
diff changeset
   355
        finally:
2959
daabb9bc5233 make db-restore command work even with no/corrupted database
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2759
diff changeset
   356
            if self.repo.config.open_connections_pools:
daabb9bc5233 make db-restore command work even with no/corrupted database
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2759
diff changeset
   357
                self.open_pool_connections()
2493
9806571ea790 major refactoring of database dump/restore:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   358
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   359
    def init(self):
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   360
        self.init_creating()
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   361
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
   362
    def shutdown(self):
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
   363
        if self._eid_creation_cnx:
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
   364
            self._eid_creation_cnx.close()
5751
1e5ef464cade [test] properly close connections during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5749
diff changeset
   365
            self._eid_creation_cnx = None
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
   366
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
   367
    # XXX deprecates [un]map_attribute ?
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
   368
    def map_attribute(self, etype, attr, cb, sourcedb=True):
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
   369
        self._rql_sqlgen.attr_map['%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
   370
4512
e7ac20bf3629 unset_attribute_storage, for testing purpose at least
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   371
    def unmap_attribute(self, etype, attr):
e7ac20bf3629 unset_attribute_storage, for testing purpose at least
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   372
        self._rql_sqlgen.attr_map.pop('%s.%s' % (etype, attr), None)
e7ac20bf3629 unset_attribute_storage, for testing purpose at least
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   373
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   374
    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
   375
        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
   376
        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
   377
        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
   378
                           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
   379
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   380
    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
   381
        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
   382
        # 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
   383
        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
   384
            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
   385
        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
   386
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
   387
    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
   388
        """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
   389
        """
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
   390
        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
   391
            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
   392
        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
   393
            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
   394
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   395
    # ISource interface #######################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   396
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
   397
    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
   398
        rqlst = self.repo.vreg.rqlhelper.parse(rql)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   399
        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
   400
        rqlst.children[0].solutions = sols
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   401
        self.repo.querier.sqlgen_annotate(rqlst)
438
69b79faefa94 need_intersect test and fixes
sylvain.thenault@logilab.fr
parents: 0
diff changeset
   402
        set_qdata(self.schema.rschema, rqlst, ())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   403
        return rqlst
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   404
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   405
    def set_schema(self, schema):
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2354
diff changeset
   406
        """set the instance'schema"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   407
        self._cache = Cache(self.repo.config['rql-cache-size'])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
        self.cache_hit, self.cache_miss, self.no_cache = 0, 0, 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   409
        self.schema = schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   410
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   411
            self._rql_sqlgen.schema = schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   412
        except AttributeError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   413
            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
   414
        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
   415
            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
   416
        clear_cache(self, 'need_fti_indexation')
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   417
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   418
    def support_entity(self, etype, write=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   419
        """return true if the given entity's type is handled by this adapter
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   420
        if write is true, return true only if it's a RW support
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   421
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   422
        return not etype in NONSYSTEM_ETYPES
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   423
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   424
    def support_relation(self, rtype, write=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   425
        """return true if the given relation's type is handled by this adapter
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   426
        if write is true, return true only if it's a RW support
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   427
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   428
        if write:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   429
            return not rtype in NONSYSTEM_RELATIONS
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   430
        # due to current multi-sources implementation, the system source
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   431
        # can't claim not supporting a relation
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   432
        return True #not rtype == 'content_for'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   433
3041
782fa7566a22 [multi-sources] new may_cross_relation method on sources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2967
diff changeset
   434
    def may_cross_relation(self, rtype):
782fa7566a22 [multi-sources] new may_cross_relation method on sources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2967
diff changeset
   435
        return True
782fa7566a22 [multi-sources] new may_cross_relation method on sources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2967
diff changeset
   436
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
   437
    def authenticate(self, session, login, **kwargs):
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
   438
        """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
   439
        information found in kwargs, else raise `AuthenticationError`
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   440
        """
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
   441
        for authentifier in self.authentifiers:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   442
            try:
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
   443
                return authentifier.authenticate(session, login, **kwargs)
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
   444
            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
   445
                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
   446
        raise AuthenticationError()
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   447
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   448
    def syntax_tree_search(self, session, union, args=None, cachekey=None,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   449
                           varmap=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   450
        """return result from this source for a rql query (actually from
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   451
        a rql syntax tree and a solution dictionary mapping each used
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   452
        variable to a possible type). If cachekey is given, the query
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   453
        necessary to fetch the results (but not the results themselves)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   454
        may be cached using this key.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   455
        """
2625
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   456
        assert dbg_st_search(self.uri, union, varmap, args, cachekey)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   457
        # remember number of actually selected term (sql generation may append some)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   458
        if cachekey is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   459
            self.no_cache += 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   460
            # generate sql query if we are able to do so (not supported types...)
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
   461
            sql, qargs, cbs = self._rql_sqlgen.generate(union, args, varmap)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   462
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   463
            # sql may be cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   464
            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
   465
                sql, qargs, cbs = self._cache[cachekey]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   466
                self.cache_hit += 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   467
            except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   468
                self.cache_miss += 1
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
   469
                sql, qargs, cbs = self._rql_sqlgen.generate(union, args, varmap)
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
   470
                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
   471
        args = self.merge_args(args, qargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   472
        assert isinstance(sql, basestring), repr(sql)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   473
        try:
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
   474
            cursor = self.doexec(session, sql, args)
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
   475
        except (self.OperationalError, self.InterfaceError):
5975
5120d97e2f7e [transaction] do not attempt to reconnect if there has been some write during the transaction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5847
diff changeset
   476
            if session.mode == 'write':
5120d97e2f7e [transaction] do not attempt to reconnect if there has been some write during the transaction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5847
diff changeset
   477
                # do not attempt to reconnect if there has been some write
5120d97e2f7e [transaction] do not attempt to reconnect if there has been some write during the transaction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5847
diff changeset
   478
                # during the transaction
5120d97e2f7e [transaction] do not attempt to reconnect if there has been some write during the transaction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5847
diff changeset
   479
                raise
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   480
            # FIXME: better detection of deconnection pb
5107
3694bd379513 [source] log attempt to reconnect using warning level. Also, don't relog failed sql (already logged)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5098
diff changeset
   481
            self.warning("trying to reconnect")
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   482
            session.pool.reconnect(self)
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
   483
            cursor = self.doexec(session, sql, args)
5605
2604545d7dd9 [win32 SQLServer] connection lost detection
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5515
diff changeset
   484
        except (self.DbapiError,), exc:
2604545d7dd9 [win32 SQLServer] connection lost detection
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5515
diff changeset
   485
            # We get this one with pyodbc and SQL Server when connection was reset
5975
5120d97e2f7e [transaction] do not attempt to reconnect if there has been some write during the transaction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5847
diff changeset
   486
            if exc.args[0] == '08S01' and session.mode != 'write':
5605
2604545d7dd9 [win32 SQLServer] connection lost detection
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5515
diff changeset
   487
                self.warning("trying to reconnect")
2604545d7dd9 [win32 SQLServer] connection lost detection
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5515
diff changeset
   488
                session.pool.reconnect(self)
2604545d7dd9 [win32 SQLServer] connection lost detection
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5515
diff changeset
   489
                cursor = self.doexec(session, sql, args)
2604545d7dd9 [win32 SQLServer] connection lost detection
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5515
diff changeset
   490
            else:
2604545d7dd9 [win32 SQLServer] connection lost detection
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5515
diff changeset
   491
                raise
5625
6ee2a7b6f194 [external storage] refactor to give session to storage's callback (needed by vcsfile storage)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5606
diff changeset
   492
        results = self.process_result(cursor, cbs, session=session)
2625
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   493
        assert dbg_results(results)
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   494
        return results
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   495
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   496
    def flying_insert(self, table, session, union, args=None, varmap=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   497
        """similar as .syntax_tree_search, but inserts data in the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   498
        temporary table (on-the-fly if possible, eg for the system
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   499
        source whose the given cursor come from). If not possible,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   500
        inserts all data by calling .executemany().
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   501
        """
2625
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   502
        assert dbg_st_search(
2638
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2627
diff changeset
   503
            self.uri, union, varmap, args,
2625
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   504
            prefix='ON THE FLY temp data insertion into %s from' % table)
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   505
        # generate sql queries if we are able to do so
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
   506
        sql, qargs, cbs = self._rql_sqlgen.generate(union, args, varmap)
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
   507
        query = 'INSERT INTO %s %s' % (table, sql.encode(self._dbencoding))
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
   508
        self.doexec(session, query, self.merge_args(args, qargs))
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   509
2627
d710278e0c1c manual_insert is a public method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2625
diff changeset
   510
    def manual_insert(self, results, table, session):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   511
        """insert given result into a temporary table on the system source"""
2625
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   512
        if server.DEBUG & server.DBG_RQL:
6128
fbb8398f80dc cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6019
diff changeset
   513
            print '  manual insertion of', len(results), 'results into', table
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   514
        if not results:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   515
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   516
        query_args = ['%%(%s)s' % i for i in xrange(len(results[0]))]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   517
        query = 'INSERT INTO %s VALUES(%s)' % (table, ','.join(query_args))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   518
        kwargs_list = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   519
        for row in results:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   520
            kwargs = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   521
            row = tuple(row)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   522
            for index, cell in enumerate(row):
2066
2c4bf4ee88a2 cleanup, stop encoding unicode string in manual_insert, no more necessary and make crash recent sqlite w/ 8bit string
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2064
diff changeset
   523
                if isinstance(cell, Binary):
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
   524
                    cell = self._binary(cell.getvalue())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   525
                kwargs[str(index)] = cell
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   526
            kwargs_list.append(kwargs)
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
   527
        self.doexecmany(session, query, kwargs_list)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   528
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   529
    def clean_temp_data(self, session, temptables):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   530
        """remove temporary data, usually associated to temporary tables"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   531
        if temptables:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   532
            for table in temptables:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   533
                try:
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
   534
                    self.doexec(session,'DROP TABLE %s' % table)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   535
                except:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   536
                    pass
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   537
                try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   538
                    del self._temp_table_data[table]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   539
                except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   540
                    continue
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   541
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   542
    @contextmanager
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   543
    def _storage_handler(self, entity, event):
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   544
        # 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
   545
        #    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
   546
        #    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
   547
        #    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
   548
        #    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
   549
        #    value once the SQL query will be executed
5131
88b5ca8da928 [storages] fix fs_importing side-effect on entity.data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5128
diff changeset
   550
        restore_values = {}
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   551
        etype = entity.__regid__
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   552
        for attr, storage in self._storages.get(etype, {}).items():
5011
57c4c6399b44 [source storage] on deletion, entity has no edited_attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4964
diff changeset
   553
            try:
5217
08e7fa906cdb [source] small refactoring to avoid being doomed by a wrong assertion message on buggy storage raising attribute error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5214
diff changeset
   554
                edited = entity.edited_attributes
08e7fa906cdb [source] small refactoring to avoid being doomed by a wrong assertion message on buggy storage raising attribute error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5214
diff changeset
   555
            except AttributeError:
08e7fa906cdb [source] small refactoring to avoid being doomed by a wrong assertion message on buggy storage raising attribute error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5214
diff changeset
   556
                assert event == 'deleted'
08e7fa906cdb [source] small refactoring to avoid being doomed by a wrong assertion message on buggy storage raising attribute error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5214
diff changeset
   557
                getattr(storage, 'entity_deleted')(entity, attr)
08e7fa906cdb [source] small refactoring to avoid being doomed by a wrong assertion message on buggy storage raising attribute error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5214
diff changeset
   558
            else:
08e7fa906cdb [source] small refactoring to avoid being doomed by a wrong assertion message on buggy storage raising attribute error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5214
diff changeset
   559
                if attr in edited:
5011
57c4c6399b44 [source storage] on deletion, entity has no edited_attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4964
diff changeset
   560
                    handler = getattr(storage, 'entity_%s' % event)
5131
88b5ca8da928 [storages] fix fs_importing side-effect on entity.data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5128
diff changeset
   561
                    real_value = handler(entity, attr)
88b5ca8da928 [storages] fix fs_importing side-effect on entity.data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5128
diff changeset
   562
                    restore_values[attr] = real_value
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
   563
        try:
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
   564
            yield # 2/ execute the source's instructions
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
   565
        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
   566
            # 3/ restore original values
5131
88b5ca8da928 [storages] fix fs_importing side-effect on entity.data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 5128
diff changeset
   567
            for attr, value in restore_values.items():
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
                entity[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
   569
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   570
    def add_entity(self, session, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   571
        """add a new entity to the source"""
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   572
        with self._storage_handler(entity, 'added'):
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   573
            attrs = self.preprocess_entity(entity)
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   574
            sql = self.sqlgen.insert(SQL_PREFIX + entity.__regid__, attrs)
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   575
            self.doexec(session, sql, attrs)
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   576
            if session.undoable_action('C', entity.__regid__):
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   577
                self._record_tx_action(session, 'tx_entity_actions', 'C',
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   578
                                       etype=entity.__regid__, eid=entity.eid)
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   579
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   580
    def update_entity(self, session, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   581
        """replace an entity in the source"""
4964
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   582
        with self._storage_handler(entity, 'updated'):
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   583
            attrs = self.preprocess_entity(entity)
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   584
            if session.undoable_action('U', entity.__regid__):
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   585
                changes = self._save_attrs(session, entity, attrs)
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   586
                self._record_tx_action(session, 'tx_entity_actions', 'U',
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   587
                                       etype=entity.__regid__, eid=entity.eid,
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   588
                                       changes=self._binary(dumps(changes)))
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   589
            sql = self.sqlgen.update(SQL_PREFIX + entity.__regid__, attrs,
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   590
                                     ['cw_eid'])
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   591
            self.doexec(session, sql, attrs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   592
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   593
    def delete_entity(self, session, entity):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   594
        """delete an entity from the source"""
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
        with self._storage_handler(entity, 'deleted'):
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   596
            if session.undoable_action('D', entity.__regid__):
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   597
                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
   598
                         for r in entity.e_schema.subject_relations()
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   599
                         if (r.final or r.inlined) and not r in VIRTUAL_RTYPES]
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   600
                changes = self._save_attrs(session, entity, attrs)
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   601
                self._record_tx_action(session, 'tx_entity_actions', 'D',
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   602
                                       etype=entity.__regid__, eid=entity.eid,
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   603
                                       changes=self._binary(dumps(changes)))
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   604
            attrs = {'cw_eid': entity.eid}
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   605
            sql = self.sqlgen.delete(SQL_PREFIX + entity.__regid__, attrs)
d9e8af8a7a42 [source] implement storages right in the source rather than in hooks
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4943
diff changeset
   606
            self.doexec(session, sql, attrs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   607
5072
072ae171aeb0 [cleanup] style fixes, add nodes, 0.2 cents refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5071
diff changeset
   608
    def add_relation(self, session, subject, rtype, object, inlined=False):
072ae171aeb0 [cleanup] style fixes, add nodes, 0.2 cents refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5071
diff changeset
   609
        """add a relation to the source"""
072ae171aeb0 [cleanup] style fixes, add nodes, 0.2 cents refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5071
diff changeset
   610
        self._add_relation(session, subject, rtype, object, inlined)
072ae171aeb0 [cleanup] style fixes, add nodes, 0.2 cents refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5071
diff changeset
   611
        if session.undoable_action('A', rtype):
072ae171aeb0 [cleanup] style fixes, add nodes, 0.2 cents refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5071
diff changeset
   612
            self._record_tx_action(session, 'tx_relation_actions', 'A',
072ae171aeb0 [cleanup] style fixes, add nodes, 0.2 cents refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5071
diff changeset
   613
                                   eid_from=subject, rtype=rtype, eid_to=object)
072ae171aeb0 [cleanup] style fixes, add nodes, 0.2 cents refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5071
diff changeset
   614
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   615
    def _add_relation(self, session, subject, rtype, object, inlined=False):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   616
        """add a relation to the source"""
4818
9f9bfbcdecfd le patch massiveimport a été importé
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4810
diff changeset
   617
        if inlined is False:
9f9bfbcdecfd le patch massiveimport a été importé
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4810
diff changeset
   618
            attrs = {'eid_from': subject, 'eid_to': object}
9f9bfbcdecfd le patch massiveimport a été importé
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4810
diff changeset
   619
            sql = self.sqlgen.insert('%s_relation' % rtype, attrs)
9f9bfbcdecfd le patch massiveimport a été importé
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4810
diff changeset
   620
        else: # used by data import
9f9bfbcdecfd le patch massiveimport a été importé
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4810
diff changeset
   621
            etype = session.describe(subject)[0]
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   622
            attrs = {'cw_eid': subject, SQL_PREFIX + rtype: object}
4818
9f9bfbcdecfd le patch massiveimport a été importé
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4810
diff changeset
   623
            sql = self.sqlgen.update(SQL_PREFIX + etype, attrs,
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   624
                                     ['cw_eid'])
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
   625
        self.doexec(session, sql, attrs)
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   626
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   627
    def delete_relation(self, session, subject, rtype, object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   628
        """delete a relation from the source"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   629
        rschema = self.schema.rschema(rtype)
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   630
        self._delete_relation(session, subject, rtype, object, rschema.inlined)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   631
        if session.undoable_action('R', rtype):
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   632
            self._record_tx_action(session, 'tx_relation_actions', 'R',
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   633
                                   eid_from=subject, rtype=rtype, eid_to=object)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   634
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   635
    def _delete_relation(self, session, subject, rtype, object, inlined=False):
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
   636
        """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
   637
        if inlined:
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
   638
            table = SQL_PREFIX + session.describe(subject)[0]
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
   639
            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
   640
            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
   641
                                                                  SQL_PREFIX)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   642
            attrs = {'eid' : subject}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   643
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   644
            attrs = {'eid_from': subject, 'eid_to': object}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   645
            sql = self.sqlgen.delete('%s_relation' % rtype, attrs)
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
   646
        self.doexec(session, sql, attrs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   647
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
   648
    def doexec(self, session, query, args=None, rollback=True):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   649
        """Execute a query.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   650
        it's a function just so that it shows up in profiling
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   651
        """
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
   652
        cursor = session.pool[self.uri]
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
   653
        if server.DEBUG & server.DBG_SQL:
2625
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   654
            cnx = session.pool.connection(self.uri)
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   655
            # getattr to get the actual connection if cnx is a ConnectionWrapper
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   656
            # instance
d6012db7b93e R [server debug] more server side debugging tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2620
diff changeset
   657
            print 'exec', query, args, getattr(cnx, '_cnx', cnx)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   658
        try:
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
   659
            # str(query) to avoid error if it's an unicode string
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   660
            cursor.execute(str(query), args)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   661
        except Exception, 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
   662
            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
   663
                # 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
   664
                # 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
   665
                self.critical("sql: %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
   666
                              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
   667
            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
   668
                try:
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
   669
                    session.pool.connection(self.uri).rollback()
4692
11a040e2601c [test] also hide this message during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4682
diff changeset
   670
                    if self.repo.config.mode != 'test':
11a040e2601c [test] also hide this message during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4682
diff changeset
   671
                        self.critical('transaction has been rollbacked')
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
   672
                except:
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
   673
                    pass
6211
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
   674
            if ex.__class__.__name__ == 'IntegrityError':
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
   675
                # 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
   676
                for arg in ex.args:
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
   677
                    mo = re.search('unique_cw_[^ ]+_idx', arg)
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
   678
                    if mo is not None:
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
   679
                        index_name = mo.group(0)
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
   680
                        elements = index_name.rstrip('_idx').split('_cw_')[1:]
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
   681
                        etype = elements[0]
6297
23c1e50ff97b [rql] fix bug with query like 'Any 1 WHERE NOT X in_group G': tables should be kept in EXISTS() even when there are no restriction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6247
diff changeset
   682
                        rtypes = elements[1:]
6211
e9d125fd1465 nicer error reporting for unique together constraints
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6201
diff changeset
   683
                        raise UniqueTogetherError(etype, rtypes)
6247
f7cb092d2296 unique_together: recast exception raised by sqlite
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6211
diff changeset
   684
                    mo = re.search('columns (.*) are not unique', arg)
f7cb092d2296 unique_together: recast exception raised by sqlite
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6211
diff changeset
   685
                    if mo is not None: # sqlite in use
f7cb092d2296 unique_together: recast exception raised by sqlite
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6211
diff changeset
   686
                        rtypes = [c.strip().lstrip('cw_') for c in mo.group(1).split(',')]
f7cb092d2296 unique_together: recast exception raised by sqlite
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6211
diff changeset
   687
                        etype = '???'
f7cb092d2296 unique_together: recast exception raised by sqlite
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6211
diff changeset
   688
                        raise UniqueTogetherError(etype, rtypes)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   689
            raise
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
   690
        return cursor
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   691
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
   692
    def doexecmany(self, session, query, args):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   693
        """Execute a query.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   694
        it's a function just so that it shows up in profiling
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   695
        """
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
   696
        if server.DEBUG & server.DBG_SQL:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   697
            print 'execmany', query, 'with', len(args), 'arguments'
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
   698
        cursor = session.pool[self.uri]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   699
        try:
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
   700
            # str(query) to avoid error if it's an unicode string
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   701
            cursor.executemany(str(query), args)
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
   702
        except Exception, 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
   703
            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
   704
                # 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
   705
                # 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
   706
                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
   707
                              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
   708
            try:
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
   709
                session.pool.connection(self.uri).rollback()
4692
11a040e2601c [test] also hide this message during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4682
diff changeset
   710
                if self.repo.config.mode != 'test':
11a040e2601c [test] also hide this message during test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4682
diff changeset
   711
                    self.critical('transaction has been rollbacked')
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
   712
            except:
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
   713
                pass
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   714
            raise
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   715
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   716
    # short cut to method requiring advanced db helper usage ##################
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   717
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
   718
    def update_rdef_column(self, session, 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
   719
        """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
   720
        """
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
   721
        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
   722
        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
   723
        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
   724
            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
   725
                       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
   726
            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
   727
        self.dbhelper.change_col_type(LogCursor(session.pool[self.uri]),
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
   728
                                      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
   729
        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
   730
                  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
   731
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
   732
    def update_rdef_null_allowed(self, session, 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
   733
        """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
   734
        (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
   735
        """
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
   736
        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
   737
            # 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
   738
            # 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
   739
            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
   740
        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
   741
        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
   742
        self.dbhelper.set_null_allowed(LogCursor(session.pool[self.uri]),
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
   743
                                       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
   744
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
   745
    def update_rdef_indexed(self, session, 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
   746
        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
   747
        if rdef.indexed:
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
   748
            self.create_index(session, table, column)
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
   749
        else:
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
   750
            self.drop_index(session, table, column)
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
   751
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
   752
    def update_rdef_unique(self, session, 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
   753
        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
   754
        if rdef.constraint_by_type('UniqueConstraint'):
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
   755
            self.create_index(session, table, column, unique=True)
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
   756
        else:
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
   757
            self.drop_index(session, table, column, unique=True)
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
   758
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   759
    def create_index(self, session, table, column, unique=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   760
        cursor = LogCursor(session.pool[self.uri])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   761
        self.dbhelper.create_index(cursor, table, column, unique)
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   762
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   763
    def drop_index(self, session, table, column, unique=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   764
        cursor = LogCursor(session.pool[self.uri])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   765
        self.dbhelper.drop_index(cursor, table, column, unique)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   766
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   767
    # system source interface #################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   768
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   769
    def eid_type_source(self, session, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   770
        """return a tuple (type, source, extid) for the entity with id <eid>"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   771
        sql = 'SELECT type, source, extid FROM entities WHERE eid=%s' % eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   772
        try:
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   773
            res = self.doexec(session, sql).fetchone()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   774
        except:
1079
452cb76fe07a backport typo fix
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 973
diff changeset
   775
            assert session.pool, 'session has no pool set'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   776
            raise UnknownEid(eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   777
        if res is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   778
            raise UnknownEid(eid)
1952
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
   779
        if res[-1] is not None:
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
   780
            if not isinstance(res, list):
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
   781
                res = list(res)
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
   782
            res[-1] = b64decode(res[-1])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   783
        return res
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   784
1952
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
   785
    def extid2eid(self, session, source, extid):
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
   786
        """get eid from an external id. Return None if no record found."""
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
   787
        assert isinstance(extid, str)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   788
        cursor = self.doexec(session,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   789
                             'SELECT eid FROM entities '
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   790
                             'WHERE extid=%(x)s AND source=%(s)s',
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   791
                             {'x': b64encode(extid), 's': source.uri})
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   792
        # XXX testing rowcount cause strange bug with sqlite, results are there
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   793
        #     but rowcount is 0
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   794
        #if cursor.rowcount > 0:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   795
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   796
            result = cursor.fetchone()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   797
            if result:
1954
9b20f3504af8 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1952
diff changeset
   798
                return result[0]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   799
        except:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   800
            pass
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   801
        return None
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   802
5168
1ab032df5ca3 SQL Server port: temporary table handling
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5131
diff changeset
   803
    def make_temp_table_name(self, table):
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
   804
        try: # XXX remove this once
5168
1ab032df5ca3 SQL Server port: temporary table handling
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5131
diff changeset
   805
            return self.dbhelper.temporary_table_name(table)
1ab032df5ca3 SQL Server port: temporary table handling
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5131
diff changeset
   806
        except AttributeError:
1ab032df5ca3 SQL Server port: temporary table handling
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5131
diff changeset
   807
            import warnings
1ab032df5ca3 SQL Server port: temporary table handling
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5131
diff changeset
   808
            warnings.warn('Please hg up logilab.database')
1ab032df5ca3 SQL Server port: temporary table handling
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5131
diff changeset
   809
            return table
1ab032df5ca3 SQL Server port: temporary table handling
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5131
diff changeset
   810
1ab032df5ca3 SQL Server port: temporary table handling
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5131
diff changeset
   811
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   812
    def temp_table_def(self, selected, sol, table):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   813
        return make_schema(selected, sol, table, self.dbhelper.TYPE_MAPPING)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   814
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   815
    def create_temp_table(self, session, table, schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   816
        # we don't want on commit drop, this may cause problem when
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   817
        # running with an ldap source, and table will be deleted manually any way
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   818
        # on commit
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   819
        sql = self.dbhelper.sql_temporary_table(table, schema, False)
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
   820
        self.doexec(session, sql)
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   821
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
   822
    def _create_eid_sqlite(self, session):
5644
73d8a757db80 fix create_eid for sqlite (and bring back tests)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5639
diff changeset
   823
        self._eid_creation_lock.acquire()
73d8a757db80 fix create_eid for sqlite (and bring back tests)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5639
diff changeset
   824
        try:
73d8a757db80 fix create_eid for sqlite (and bring back tests)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5639
diff changeset
   825
            for sql in self.dbhelper.sqls_increment_sequence('entities_id_seq'):
73d8a757db80 fix create_eid for sqlite (and bring back tests)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5639
diff changeset
   826
                cursor = self.doexec(session, sql)
73d8a757db80 fix create_eid for sqlite (and bring back tests)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5639
diff changeset
   827
            return cursor.fetchone()[0]
73d8a757db80 fix create_eid for sqlite (and bring back tests)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5639
diff changeset
   828
        finally:
73d8a757db80 fix create_eid for sqlite (and bring back tests)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5639
diff changeset
   829
            self._eid_creation_lock.release()
73d8a757db80 fix create_eid for sqlite (and bring back tests)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5639
diff changeset
   830
73d8a757db80 fix create_eid for sqlite (and bring back tests)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5639
diff changeset
   831
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   832
    def create_eid(self, session):
5639
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   833
        # lock needed to prevent 'Connection is busy with results for another command (0)' errors with SQLServer
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
   834
        self._eid_creation_lock.acquire()
5639
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   835
        try:
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
   836
            return self._create_eid()
5639
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   837
        finally:
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   838
            self._eid_creation_lock.release()
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
   839
a07dee204187 fix unit tests by not using the new create_eid implementation with sqlite
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5645
diff changeset
   840
    def _create_eid(self):
a07dee204187 fix unit tests by not using the new create_eid implementation with sqlite
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5645
diff changeset
   841
        # internal function doing the eid creation without locking.
a07dee204187 fix unit tests by not using the new create_eid implementation with sqlite
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5645
diff changeset
   842
        # needed for the recursive handling of disconnections (otherwise we
5639
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   843
        # deadlock on self._eid_creation_lock
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   844
        if self._eid_creation_cnx is None:
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   845
            self._eid_creation_cnx = self.get_connection()
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   846
        cnx = self._eid_creation_cnx
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   847
        cursor = cnx.cursor()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   848
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   849
            for sql in self.dbhelper.sqls_increment_sequence('entities_id_seq'):
5639
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   850
                cursor.execute(sql)
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   851
            eid = cursor.fetchone()[0]
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   852
        except (self.OperationalError, self.InterfaceError):
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   853
            # FIXME: better detection of deconnection pb
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   854
            self.warning("trying to reconnect create eid connection")
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   855
            self._eid_creation_cnx = None
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
   856
            return self._create_eid()
5639
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   857
        except (self.DbapiError,), exc:
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   858
            # We get this one with pyodbc and SQL Server when connection was reset
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   859
            if exc.args[0] == '08S01':
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   860
                self.warning("trying to reconnect create eid connection")
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   861
                self._eid_creation_cnx = None
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
   862
                return self._create_eid()
5639
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   863
            else:
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   864
                raise
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   865
        except: # WTF?
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   866
            cnx.rollback()
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   867
            self._eid_creation_cnx = None
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   868
            self.exception('create eid failed in an unforeseen way on SQL statement %s', sql)
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   869
            raise
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   870
        else:
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   871
            cnx.commit()
4acb860159e4 [win32] fix deadlock occuring on the sequence tables with SQLServer
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5605
diff changeset
   872
            return eid
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
   873
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   874
    def add_info(self, session, entity, source, extid, complete):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   875
        """add type and source info for an eid into the system table"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   876
        # begin by inserting eid/type/source/extid into the entities table
1952
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
   877
        if extid is not None:
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
   878
            assert isinstance(extid, str)
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
   879
            extid = b64encode(extid)
3399
2b84f4adb6f8 use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3240
diff changeset
   880
        attrs = {'type': entity.__regid__, 'eid': entity.eid, 'extid': extid,
1952
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1792
diff changeset
   881
                 'source': source.uri, 'mtime': datetime.now()}
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   882
        self.doexec(session, self.sqlgen.insert('entities', attrs), attrs)
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   883
        # now we can update the full text index
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   884
        if self.do_fti and self.need_fti_indexation(entity.__regid__):
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   885
            if complete:
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   886
                entity.complete(entity.e_schema.indexable_attributes())
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
   887
            self.index_entity(session, entity=entity)
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   888
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   889
    def update_info(self, session, entity, need_fti_update):
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   890
        """mark entity as being modified, fulltext reindex if needed"""
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   891
        if self.do_fti and need_fti_update:
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   892
            # 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
   893
            # one indexable attribute
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
   894
            self.index_entity(session, entity=entity)
5059
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   895
        # update entities.mtime.
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   896
        # XXX Only if entity.__regid__ in self.multisources_etypes?
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
   897
        attrs = {'eid': entity.eid, 'mtime': datetime.now()}
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   898
        self.doexec(session, self.sqlgen.update('entities', attrs, ['eid']), attrs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   899
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   900
    def delete_info(self, session, entity, uri, extid):
5059
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   901
        """delete system information on deletion of an entity:
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
   902
        * update the fti
5059
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   903
        * remove record from the entities table
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   904
        * transfer it to the deleted_entities table if the entity's type is
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   905
          multi-sources
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   906
        """
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
   907
        self.fti_unindex_entity(session, entity.eid)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   908
        attrs = {'eid': entity.eid}
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   909
        self.doexec(session, self.sqlgen.delete('entities', attrs), attrs)
5059
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   910
        if not entity.__regid__ in self.multisources_etypes:
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   911
            return
2955
6bb5025c9fc7 remove some pretty old deprecation code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2759
diff changeset
   912
        if extid is not None:
6bb5025c9fc7 remove some pretty old deprecation code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2759
diff changeset
   913
            assert isinstance(extid, str), type(extid)
6bb5025c9fc7 remove some pretty old deprecation code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2759
diff changeset
   914
            extid = b64encode(extid)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   915
        attrs = {'type': entity.__regid__, 'eid': entity.eid, 'extid': extid,
5061
cdab5220eac0 [cleanup]
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5059
diff changeset
   916
                 'source': uri, 'dtime': datetime.now()}
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   917
        self.doexec(session, self.sqlgen.insert('deleted_entities', attrs), attrs)
1792
9eadf34fd860 delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   918
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   919
    def modified_entities(self, session, etypes, mtime):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   920
        """return a 2-uple:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   921
        * list of (etype, eid) of entities of the given types which have been
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   922
          modified since the given timestamp (actually entities whose full text
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   923
          index content has changed)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   924
        * list of (etype, eid) of entities of the given types which have been
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   925
          deleted since the given timestamp
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   926
        """
5059
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   927
        for etype in etypes:
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   928
            if not etype in self.multisources_etypes:
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   929
                self.critical('%s not listed as a multi-sources entity types. '
5072
072ae171aeb0 [cleanup] style fixes, add nodes, 0.2 cents refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5071
diff changeset
   930
                              'Modify your configuration' % etype)
5059
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
   931
                self.multisources_etypes.add(etype)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   932
        modsql = _modified_sql('entities', etypes)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   933
        cursor = self.doexec(session, modsql, {'time': mtime})
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   934
        modentities = cursor.fetchall()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   935
        delsql = _modified_sql('deleted_entities', etypes)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   936
        cursor = self.doexec(session, delsql, {'time': mtime})
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   937
        delentities = cursor.fetchall()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   938
        return modentities, delentities
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   939
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   940
    # undo support #############################################################
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   941
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   942
    def undoable_transactions(self, session, ueid=None, **actionfilters):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   943
        """See :class:`cubicweb.dbapi.Connection.undoable_transactions`"""
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   944
        # force filtering to session's user if not a manager
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   945
        if not session.user.is_in_group('managers'):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   946
            ueid = session.user.eid
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   947
        restr = {}
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   948
        if ueid is not None:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   949
            restr['tx_user'] = ueid
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   950
        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
   951
        if actionfilters:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   952
            # 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
   953
            # actions done
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   954
            tearestr = {} # filters on the tx_entity_actions table
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   955
            trarestr = {} # filters on the tx_relation_actions table
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   956
            genrestr = {} # generic filters, appliyable to both table
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   957
            # 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
   958
            # actions
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   959
            if actionfilters.pop('public', True):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   960
                genrestr['txa_public'] = True
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   961
            # put additional filters in trarestr and/or tearestr
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   962
            for key, val in actionfilters.iteritems():
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   963
                if key == 'etype':
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   964
                    # 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
   965
                    # 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
   966
                    assert 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
   967
                    assert not 'eid' in actionfilters
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   968
                    tearestr['etype'] = val
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   969
                elif key == 'eid':
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   970
                    # 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
   971
                    # '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
   972
                    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
   973
                        tearestr['eid'] = val
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   974
                    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
   975
                        trarestr['eid_from'] = val
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   976
                        trarestr['eid_to'] = val
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   977
                elif key == 'action':
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   978
                    if val in 'CUD':
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   979
                        tearestr['txa_action'] = val
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   980
                    else:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   981
                        assert val in 'AR'
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   982
                        trarestr['txa_action'] = val
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   983
                else:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   984
                    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
   985
            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
   986
            subqsqls = []
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   987
            # 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
   988
            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
   989
                trarestr.update(genrestr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   990
                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
   991
                if 'eid_from' in trarestr:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   992
                    # 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
   993
                    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
   994
                                                     'eid_to = %(eid_to)s'])
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   995
                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
   996
                subqsqls.append('EXISTS(%s)' % trasql)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   997
            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
   998
                tearestr.update(genrestr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
   999
                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
  1000
                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
  1001
                subqsqls.append('EXISTS(%s)' % teasql)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1002
            if restr:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1003
                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
  1004
            else:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1005
                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
  1006
            restr.update(trarestr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1007
            restr.update(tearestr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1008
        # 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
  1009
        sql += ' ORDER BY tx_time DESC'
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1010
        cu = self.doexec(session, sql, restr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1011
        # turn results into transaction objects
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1012
        return [tx.Transaction(*args) for args in cu.fetchall()]
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1013
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1014
    def tx_info(self, session, txuuid):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1015
        """See :class:`cubicweb.dbapi.Connection.transaction_info`"""
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1016
        return tx.Transaction(txuuid, *self._tx_info(session, txuuid))
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1017
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1018
    def tx_actions(self, session, txuuid, public):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1019
        """See :class:`cubicweb.dbapi.Connection.transaction_actions`"""
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1020
        self._tx_info(session, txuuid)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1021
        restr = {'tx_uuid': txuuid}
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1022
        if public:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1023
            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
  1024
        # 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
  1025
        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
  1026
                                 ('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
  1027
                                  'etype', 'eid', 'changes'))
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1028
        cu = self.doexec(session, sql, restr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1029
        actions = [tx.EntityAction(a,p,o,et,e,c and loads(self.binary_to_str(c)))
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1030
                   for a,p,o,et,e,c in cu.fetchall()]
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1031
        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
  1032
                                 ('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
  1033
                                  'rtype', 'eid_from', 'eid_to'))
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1034
        cu = self.doexec(session, sql, restr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1035
        actions += [tx.RelationAction(*args) for args in cu.fetchall()]
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1036
        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
  1037
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1038
    def undo_transaction(self, session, txuuid):
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
  1039
        """See :class:`cubicweb.dbapi.Connection.undo_transaction`
8631bb9f6e73 [undo] during undoing, call hooks in the [active]integrity and undo categories
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5070
diff changeset
  1040
8631bb9f6e73 [undo] during undoing, call hooks in the [active]integrity and undo categories
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5070
diff changeset
  1041
        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
  1042
        '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
  1043
        """
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1044
        # set mode so pool isn't released subsquently until commit/rollback
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1045
        session.mode = 'write'
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1046
        errors = []
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
  1047
        session.transaction_data['undoing_uuid'] = txuuid
8631bb9f6e73 [undo] during undoing, call hooks in the [active]integrity and undo categories
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5070
diff changeset
  1048
        with hooks_control(session, session.HOOKS_DENY_ALL,
8631bb9f6e73 [undo] during undoing, call hooks in the [active]integrity and undo categories
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5070
diff changeset
  1049
                           'integrity', 'activeintegrity', 'undo'):
4943
7f5b83578fec disable security when undoing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4913
diff changeset
  1050
            with security_enabled(session, read=False):
7f5b83578fec disable security when undoing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4913
diff changeset
  1051
                for action in reversed(self.tx_actions(session, txuuid, False)):
7f5b83578fec disable security when undoing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4913
diff changeset
  1052
                    undomethod = getattr(self, '_undo_%s' % action.action.lower())
7f5b83578fec disable security when undoing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4913
diff changeset
  1053
                    errors += undomethod(session, action)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1054
        # remove the transactions record
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1055
        self.doexec(session,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1056
                    "DELETE FROM transactions WHERE tx_uuid='%s'" % txuuid)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1057
        return errors
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1058
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1059
    def start_undoable_transaction(self, session, uuid):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1060
        """session callback to insert a transaction record in the transactions
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1061
        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
  1062
        """
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1063
        ueid = session.user.eid
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1064
        attrs = {'tx_uuid': uuid, 'tx_user': ueid, 'tx_time': datetime.now()}
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1065
        self.doexec(session, self.sqlgen.insert('transactions', attrs), attrs)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1066
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1067
    def _save_attrs(self, session, entity, attrs):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1068
        """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
  1069
        attributes of the entity
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1070
        """
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1071
        restr = {'cw_eid': entity.eid}
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1072
        sql = self.sqlgen.select(SQL_PREFIX + entity.__regid__, restr, attrs)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1073
        cu = self.doexec(session, sql, restr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1074
        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
  1075
        # 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
  1076
        eschema = entity.e_schema
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1077
        for column in attrs:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1078
            # [3:] remove 'cw_' prefix
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1079
            attr = column[3:]
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1080
            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
  1081
                continue
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1082
            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
  1083
                value = values[column]
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1084
                if value is not None:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1085
                    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
  1086
        return values
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1087
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1088
    def _record_tx_action(self, session, table, action, **kwargs):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1089
        """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
  1090
        '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
  1091
        """
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1092
        kwargs['tx_uuid'] = session.transaction_uuid()
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1093
        kwargs['txa_action'] = action
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1094
        kwargs['txa_order'] = session.transaction_inc_action_counter()
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1095
        kwargs['txa_public'] = session.running_dbapi_query
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1096
        self.doexec(session, self.sqlgen.insert(table, kwargs), kwargs)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1097
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1098
    def _tx_info(self, session, txuuid):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1099
        """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
  1100
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1101
        raise `NoSuchTransaction` if there is no such transaction of if the
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1102
        session's user isn't allowed to see it.
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1103
        """
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1104
        restr = {'tx_uuid': txuuid}
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1105
        sql = self.sqlgen.select('transactions', restr, ('tx_time', 'tx_user'))
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1106
        cu = self.doexec(session, sql, restr)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1107
        try:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1108
            time, ueid = cu.fetchone()
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1109
        except TypeError:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1110
            raise tx.NoSuchTransaction()
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1111
        if not (session.user.is_in_group('managers')
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1112
                or session.user.eid == ueid):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1113
            raise tx.NoSuchTransaction()
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1114
        return time, ueid
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1115
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1116
    def _undo_d(self, session, action):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1117
        """undo an entity deletion"""
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1118
        errors = []
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1119
        err = errors.append
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1120
        eid = action.eid
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1121
        etype = action.etype
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1122
        _ = session._
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1123
        # get an entity instance
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1124
        try:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1125
            entity = self.repo.vreg['etypes'].etype_class(etype)(session)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1126
        except Exception:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1127
            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
  1128
                % (eid, etype))
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1129
            return errors
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1130
        # check for schema changes, entities linked through inlined relation
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1131
        # still exists, rewrap binary values
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1132
        eschema = entity.e_schema
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1133
        getrschema = eschema.subjrels
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1134
        for column, value in action.changes.items():
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1135
            rtype = column[3:] # remove cw_ prefix
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1136
            try:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1137
                rschema = getrschema[rtype]
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1138
            except KeyError:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1139
                err(_("Can't restore relation %(rtype)s of entity %(eid)s, "
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1140
                      "this relation does not exists anymore in the schema.")
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1141
                    % {'rtype': rtype, 'eid': eid})
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1142
            if not rschema.final:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1143
                assert value is None
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1144
            elif eschema.destination(rtype) in ('Bytes', 'Password'):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1145
                action.changes[column] = self._binary(value)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1146
                entity[rtype] = Binary(value)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1147
            elif isinstance(value, str):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1148
                entity[rtype] = unicode(value, session.encoding, 'replace')
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1149
            else:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1150
                entity[rtype] = value
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
  1151
        entity.eid = eid
5075
a4b735e76c66 [undo] init entity cache when undoing an entity deletion
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5074
diff changeset
  1152
        session.repo.init_entity_caches(session, entity, self)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1153
        entity.edited_attributes = set(entity)
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
  1154
        entity._cw_check()
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1155
        self.repo.hm.call_hooks('before_add_entity', session, entity=entity)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1156
        # restore the entity
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1157
        action.changes['cw_eid'] = eid
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1158
        sql = self.sqlgen.insert(SQL_PREFIX + etype, action.changes)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1159
        self.doexec(session, sql, action.changes)
5074
bc481dab93d4 [undo] consistent is/is_instance_of processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
  1160
        # add explicitly is / is_instance_of whose deletion is not recorded for
bc481dab93d4 [undo] consistent is/is_instance_of processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
  1161
        # consistency with addition (done by sql in hooks)
bc481dab93d4 [undo] consistent is/is_instance_of processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
  1162
        self.doexec(session, 'INSERT INTO is_relation(eid_from, eid_to) '
bc481dab93d4 [undo] consistent is/is_instance_of processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
  1163
                    'VALUES(%s, %s)' % (eid, eschema_eid(session, eschema)))
bc481dab93d4 [undo] consistent is/is_instance_of processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
  1164
        for eschema in entity.e_schema.ancestors() + [entity.e_schema]:
bc481dab93d4 [undo] consistent is/is_instance_of processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
  1165
            self.doexec(session, 'INSERT INTO is_instance_of_relation(eid_from,'
bc481dab93d4 [undo] consistent is/is_instance_of processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
  1166
                        'eid_to) VALUES(%s, %s)' % (eid, eschema_eid(session, eschema)))
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1167
        # restore record in entities (will update fti if needed)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1168
        self.add_info(session, entity, self, None, True)
5059
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
  1169
        # remove record from deleted_entities if entity's type is multi-sources
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
  1170
        if entity.__regid__ in self.multisources_etypes:
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
  1171
            self.doexec(session,
1d5c81588144 [repo] make etype which should go in deleted_entities configurable: we only need this for types imported from other multi-sources instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5013
diff changeset
  1172
                        'DELETE FROM deleted_entities WHERE eid=%s' % eid)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1173
        self.repo.hm.call_hooks('after_add_entity', session, entity=entity)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1174
        return errors
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1175
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1176
    def _undo_r(self, session, action):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1177
        """undo a relation removal"""
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1178
        errors = []
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1179
        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
  1180
        try:
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1181
            sentity, oentity, rdef = _undo_rel_info(session, subj, rtype, obj)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1182
        except UndoException, ex:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1183
            errors.append(unicode(ex))
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1184
        else:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1185
            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
  1186
                                 ('object', oentity)):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1187
                try:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1188
                    _undo_check_relation_target(entity, rdef, role)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1189
                except UndoException, ex:
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1190
                    errors.append(unicode(ex))
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1191
                    continue
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1192
        if not errors:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1193
            self.repo.hm.call_hooks('before_add_relation', session,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1194
                                    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
  1195
            # add relation in the database
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1196
            self._add_relation(session, subj, rtype, obj, rdef.rtype.inlined)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1197
            # set related cache
5076
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1198
            session.update_rel_cache_add(subj, rtype, obj, rdef.rtype.symmetric)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1199
            self.repo.hm.call_hooks('after_add_relation', session,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1200
                                    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
  1201
        return errors
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1202
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1203
    def _undo_c(self, session, action):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1204
        """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
  1205
        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
  1206
        # 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
  1207
        # 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
  1208
        # massive deletion performance)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1209
        if _undo_has_later_transaction(session, eid):
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1210
            msg = session._('some later transaction(s) touch entity, undo them '
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1211
                            'first')
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1212
            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
  1213
        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
  1214
        # 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
  1215
        try:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1216
            entity = self.repo.vreg['etypes'].etype_class(etype)(session)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1217
        except Exception:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1218
            return [session._(
5098
32b1adfb6b92 [i18n] use named substitution to avoid gettext warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5076
diff changeset
  1219
                "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
  1220
                "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
  1221
        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
  1222
        # for proper eid/type cache update
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1223
        hook.set_operation(session, 'pendingeids', eid,
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1224
                           CleanupDeletedEidsCacheOp)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1225
        self.repo.hm.call_hooks('before_delete_entity', session, entity=entity)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1226
        # 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
  1227
        # unvisible as transaction action
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1228
        self.doexec(session, 'DELETE FROM is_relation WHERE eid_from=%s' % eid)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1229
        self.doexec(session, 'DELETE FROM is_instance_of_relation WHERE eid_from=%s' % eid)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1230
        # 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
  1231
        # 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
  1232
        attrs = {'cw_eid': eid}
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1233
        sql = self.sqlgen.delete(SQL_PREFIX + entity.__regid__, attrs)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1234
        self.doexec(session, sql, attrs)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1235
        # remove record from entities (will update fti if needed)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1236
        self.delete_info(session, entity, self.uri, None)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1237
        self.repo.hm.call_hooks('after_delete_entity', session, entity=entity)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1238
        return ()
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1239
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1240
    def _undo_u(self, session, action):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1241
        """undo an entity update"""
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1242
        return ['undoing of entity updating not yet supported.']
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1243
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1244
    def _undo_a(self, session, action):
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1245
        """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
  1246
        errors = []
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1247
        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
  1248
        try:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1249
            sentity, oentity, rdef = _undo_rel_info(session, subj, rtype, obj)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1250
        except UndoException, ex:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1251
            errors.append(unicode(ex))
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1252
        else:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1253
            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
  1254
            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
  1255
                sql = 'SELECT 1 FROM cw_%s WHERE cw_eid=%s and cw_%s=%s'\
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1256
                      % (sentity.__regid__, subj, rtype, obj)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1257
            else:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1258
                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
  1259
                      % (rtype, subj, obj)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1260
            cu = self.doexec(session, sql)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1261
            if cu.fetchone() is None:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1262
                errors.append(session._(
5098
32b1adfb6b92 [i18n] use named substitution to avoid gettext warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5076
diff changeset
  1263
                    "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
  1264
                    " %(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
  1265
        if not errors:
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1266
            self.repo.hm.call_hooks('before_delete_relation', session,
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1267
                                    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
  1268
            # delete relation from the database
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1269
            self._delete_relation(session, subj, rtype, obj, rschema.inlined)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1270
            # set related cache
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1271
            session.update_rel_cache_del(subj, rtype, obj, rschema.symmetric)
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1272
            self.repo.hm.call_hooks('after_delete_relation', session,
b0e6134b4324 [undo] basic support for undoing of entity creation / relation addition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5075
diff changeset
  1273
                                    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
  1274
        return errors
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1275
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1276
    # full text index handling #################################################
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1277
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1278
    @cached
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1279
    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
  1280
        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
  1281
        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
  1282
            return True
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1283
        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
  1284
            return True
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1285
        return False
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1286
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1287
    def index_entity(self, session, entity):
4807
5642bfa43236 [cleanup] add index_entity to abstract source, add docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4806
diff changeset
  1288
        """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
  1289
        on commit
5642bfa43236 [cleanup] add index_entity to abstract source, add docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4806
diff changeset
  1290
        """
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
  1291
        hook.set_operation(session, 'ftindex', entity.eid, FTIndexEntityOp)
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1292
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1293
    def fti_unindex_entity(self, session, eid):
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1294
        """remove text content for entity with the given eid from the full text
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1295
        index
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1296
        """
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1297
        try:
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
  1298
            self.dbhelper.cursor_unindex_object(eid, session.pool['system'])
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1299
        except Exception: # let KeyboardInterrupt / SystemExit propagate
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1300
            self.exception('error while unindexing %s', eid)
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1301
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1302
    def fti_index_entity(self, session, entity):
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1303
        """add text content of a created/modified entity to the full text index
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1304
        """
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1305
        self.debug('reindexing %r', entity.eid)
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1306
        try:
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1307
            # 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
  1308
            # unindexing done in the FTIndexEntityOp
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5542
diff changeset
  1309
            self.dbhelper.cursor_index_object(entity.eid,
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5542
diff changeset
  1310
                                              entity.cw_adapt_to('IFTIndexable'),
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
  1311
                                              session.pool['system'])
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1312
        except Exception: # let KeyboardInterrupt / SystemExit propagate
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1313
            self.exception('error while reindexing %s', entity)
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1314
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1315
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1316
class FTIndexEntityOp(hook.LateOperation):
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1317
    """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
  1318
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1319
    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
  1320
    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
  1321
    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
  1322
    """
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
    def precommit_event(self):
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1325
        session = self.session
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1326
        source = session.repo.system_source
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
  1327
        pendingeids = session.transaction_data.get('pendingeids', ())
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
  1328
        done = session.transaction_data.setdefault('indexedeids', set())
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
  1329
        for eid in session.transaction_data.pop('ftindex', ()):
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
  1330
            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
  1331
                # 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
  1332
                # processed
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
  1333
                return
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
  1334
            done.add(eid)
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5542
diff changeset
  1335
            iftindexable = session.entity_from_eid(eid).cw_adapt_to('IFTIndexable')
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5542
diff changeset
  1336
            for container in iftindexable.fti_containers():
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
  1337
                source.fti_unindex_entity(session, container.eid)
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
                source.fti_index_entity(session, container)
4806
4f12f59b1a13 [fti] refactor and fix full text indexation handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4692
diff changeset
  1339
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1340
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1341
def sql_schema(driver):
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
  1342
    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
  1343
    typemap = helper.TYPE_MAPPING
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1344
    schema = """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1345
/* Create the repository's system database */
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1346
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1347
%s
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1348
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1349
CREATE TABLE entities (
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1350
  eid INTEGER PRIMARY KEY NOT NULL,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1351
  type VARCHAR(64) NOT NULL,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1352
  source VARCHAR(64) NOT NULL,
4113
986fc01be83c TIMESTAMP column type has a special meaning for SQLServer,
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 3958
diff changeset
  1353
  mtime %s NOT NULL,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1354
  extid VARCHAR(256)
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1355
);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1356
CREATE INDEX entities_type_idx ON entities(type);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1357
CREATE INDEX entities_mtime_idx ON entities(mtime);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1358
CREATE INDEX entities_extid_idx ON entities(extid);;
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1359
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1360
CREATE TABLE deleted_entities (
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1361
  eid INTEGER PRIMARY KEY NOT NULL,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1362
  type VARCHAR(64) NOT NULL,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1363
  source VARCHAR(64) NOT NULL,
4113
986fc01be83c TIMESTAMP column type has a special meaning for SQLServer,
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 3958
diff changeset
  1364
  dtime %s NOT NULL,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1365
  extid VARCHAR(256)
4913
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 deleted_entities_type_idx ON deleted_entities(type);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1368
CREATE INDEX deleted_entities_dtime_idx ON deleted_entities(dtime);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1369
CREATE INDEX deleted_entities_extid_idx ON deleted_entities(extid);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1370
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1371
CREATE TABLE transactions (
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1372
  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
  1373
  tx_user INTEGER NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1374
  tx_time %s NOT NULL
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1375
);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1376
CREATE INDEX transactions_tx_user_idx ON transactions(tx_user);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1377
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1378
CREATE TABLE tx_entity_actions (
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1379
  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
  1380
  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
  1381
  txa_public %s NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1382
  txa_order INTEGER,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1383
  eid INTEGER NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1384
  etype VARCHAR(64) NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1385
  changes %s
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1386
);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1387
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
  1388
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
  1389
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
  1390
CREATE INDEX tx_entity_actions_etype_idx ON tx_entity_actions(etype);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1391
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1392
CREATE TABLE tx_relation_actions (
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1393
  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
  1394
  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
  1395
  txa_public %s NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1396
  txa_order INTEGER,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1397
  eid_from INTEGER NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1398
  eid_to INTEGER NOT NULL,
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1399
  rtype VARCHAR(256) NOT NULL
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1400
);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1401
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
  1402
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
  1403
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
  1404
CREATE INDEX tx_relation_actions_eid_to_idx ON tx_relation_actions(eid_to);;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1405
""" % (helper.sql_create_sequence('entities_id_seq').replace(';', ';;'),
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1406
       typemap['Datetime'], typemap['Datetime'], typemap['Datetime'],
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1407
       typemap['Boolean'], typemap['Bytes'], typemap['Boolean'])
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1408
    if helper.backend_name == 'sqlite':
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1409
        # sqlite support the ON DELETE CASCADE syntax but do nothing
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1410
        schema += '''
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1411
CREATE TRIGGER fkd_transactions
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1412
BEFORE DELETE ON transactions
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1413
FOR EACH ROW BEGIN
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1414
    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
  1415
    DELETE FROM tx_relation_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
  1416
END;;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1417
'''
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1418
    return schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1419
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1420
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1421
def sql_drop_schema(driver):
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
  1422
    helper = get_db_helper(driver)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1423
    return """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1424
%s
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1425
DROP TABLE entities;
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1426
DROP TABLE deleted_entities;
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1427
DROP TABLE tx_entity_actions;
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1428
DROP TABLE tx_relation_actions;
5214
3285b6e3b930 fix cwctl db-init -d on SQL Server
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5168
diff changeset
  1429
DROP TABLE transactions;
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1430
""" % helper.sql_drop_sequence('entities_id_seq')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1431
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1432
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1433
def grant_schema(user, set_owner=True):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1434
    result = ''
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1435
    for table in ('entities', 'deleted_entities', 'entities_id_seq',
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1436
                  '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
  1437
        if set_owner:
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1438
            result = 'ALTER TABLE %s OWNER TO %s;\n' % (table, user)
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4902
diff changeset
  1439
        result += 'GRANT ALL ON %s TO %s;\n' % (table, user)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1440
    return result
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
  1441
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
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
  1443
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
  1444
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
    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
  1446
        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
  1447
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
  1448
    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
  1449
        """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
  1450
        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
  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
class LoginPasswordAuthentifier(BaseAuthentifier):
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
    passwd_rql = "Any P WHERE X is CWUser, X login %(login)s, X upassword P"
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
    auth_rql = "Any X WHERE X is CWUser, X login %(login)s, X upassword %(pwd)s"
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
  1455
    _sols = ({'X': 'CWUser', 'P': 'Password'},)
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
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
  1457
    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
  1458
        """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
  1459
        if 'CWUser' in schema: # probably an empty schema if not true...
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
            # 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
  1461
            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
  1462
            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
  1463
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
  1464
    def authenticate(self, session, login, password=None, **kwargs):
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
        """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
  1466
        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
  1467
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
  1468
        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
  1469
        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
  1470
        """
6018
f4d1d5d9ccbb [security] don't put uncrypted password in query parameters, else it may be logged on error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5975
diff changeset
  1471
        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
  1472
        if password is not 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
  1473
            rset = self.source.syntax_tree_search(session, self._passwd_rqlst, args)
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
  1474
            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
  1475
                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
  1476
            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
  1477
                raise AuthenticationError('bad login')
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
  1478
            # passwords are stored using the Bytes type, so we get a StringIO
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
  1479
            if pwd is not None:
4204
60256056bda6 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181 4198
diff changeset
  1480
                args['pwd'] = Binary(crypt_password(password, pwd.getvalue()[:2]))
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
  1481
        # get eid from login and (crypted) password
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
  1482
        rset = self.source.syntax_tree_search(session, self._auth_rqlst, args)
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
  1483
        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
  1484
            return 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
  1485
        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
  1486
            raise AuthenticationError('bad password')