devtools/fill.py
author Alexandre Fayolle <alexandre.fayolle@logilab.fr>
Wed, 02 Jun 2010 16:12:18 +0000
branchstable
changeset 5639 4acb860159e4
parent 5424 8ecbcbff9777
child 5575 8a531340c3ef
child 5786 7c16a4e7a592
permissions -rw-r--r--
[win32] fix deadlock occuring on the sequence tables with SQLServer actually, this deadlock would occur with any db backend other that PostgreSQL as the previous code was heavily relying on PG's SEQUENCE facility, not available elsewhere. Deadlock description: Thread1 starts creating entities (and therefore calls create_eid): -> this creates a DB-level lock on the entities_id_seq table, which will last until end of transaction Thread2 calls create_eid, which acquires the Python lock object, but updating the entities_id_seq is held by the DB lock Thread1 wants to create a new entity, calls create_eid, and is stuck by the Python lock object held by Thread2. Solution: use a separate connection to read and write the entities_id_seq table.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
# -*- coding: iso-8859-1 -*-
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4651
diff changeset
     2
# 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: 4651
diff changeset
     3
# 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: 4651
diff changeset
     4
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4651
diff changeset
     5
# 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: 4651
diff changeset
     6
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4651
diff changeset
     7
# 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: 4651
diff changeset
     8
# 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: 4651
diff changeset
     9
# 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: 4651
diff changeset
    10
# 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: 4651
diff changeset
    11
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    12
# 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: 4651
diff changeset
    13
# 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: 4651
diff changeset
    14
# 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: 4651
diff changeset
    15
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4651
diff changeset
    16
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4651
diff changeset
    17
# 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: 4651
diff changeset
    18
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
"""This modules defines func / methods for creating test repositories
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
from random import randint, choice
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
from copy import deepcopy
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    26
from datetime import datetime, date, time, timedelta
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 428
diff changeset
    27
from decimal import Decimal
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    29
from logilab.common import attrdict
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
from yams.constraints import (SizeConstraint, StaticVocabularyConstraint,
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    31
                              IntervalBoundConstraint, BoundConstraint,
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    32
                              Attribute, actual_value)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
from rql.utils import decompose_b26 as base_decompose_b26
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
from cubicweb import Binary
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
from cubicweb.schema import RQLConstraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    38
def custom_range(start, stop, step):
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    39
    while start < stop:
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    40
        yield start
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    41
        start += step
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    42
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
def decompose_b26(index, ascii=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
    """return a letter (base-26) decomposition of index"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
    if ascii:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
        return base_decompose_b26(index)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
    return base_decompose_b26(index, u'ïż½abcdefghijklmnopqrstuvwxyz')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
def get_max_length(eschema, attrname):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
    """returns the maximum length allowed for 'attrname'"""
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3749
diff changeset
    51
    for cst in eschema.rdef(attrname).constraints:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
        if isinstance(cst, SizeConstraint) and cst.max:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
            return cst.max
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
    return 300
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
    #raise AttributeError('No Size constraint on attribute "%s"' % attrname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
_GENERATED_VALUES = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
class _ValueGenerator(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
    """generates integers / dates / strings / etc. to fill a DB table"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
    def __init__(self, eschema, choice_func=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
        """<choice_func> is a function that returns a list of possible
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
        choices for a given entity type and an attribute name. It should
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
        looks like :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
            def values_for(etype, attrname):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
                # some stuff ...
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
                return alist_of_acceptable_values # or None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
        self.choice_func = choice_func
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    71
        self.eschema = eschema
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    73
    def generate_attribute_value(self, entity, attrname, index=1, **kwargs):
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    74
        if attrname in entity:
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    75
            return entity[attrname]
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    76
        eschema = self.eschema
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    77
        if not eschema.has_unique_values(attrname):
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    78
            value = self.__generate_value(entity, attrname, index, **kwargs)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    79
        else:
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    80
            value = self.__generate_value(entity, attrname, index, **kwargs)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    81
            while value in _GENERATED_VALUES.get((eschema, attrname), ()):
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    82
                index += 1
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    83
                value = self.__generate_value(entity, attrname, index, **kwargs)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    84
            _GENERATED_VALUES.setdefault((eschema, attrname), set()).add(value)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    85
        entity[attrname] = value
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
        return value
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
    87
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    88
    def __generate_value(self, entity, attrname, index, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
        """generates a consistent value for 'attrname'"""
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    90
        eschema = self.eschema
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    91
        attrtype = str(eschema.destination(attrname)).lower()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
        # Before calling generate_%s functions, try to find values domain
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
        if self.choice_func is not None:
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    94
            values_domain = self.choice_func(eschema, attrname)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
            if values_domain is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
                return choice(values_domain)
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    97
        gen_func = getattr(self, 'generate_%s_%s' % (eschema, attrname),
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    98
                           getattr(self, 'generate_Any_%s' % attrname, None))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
        if gen_func is not None:
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   100
            return gen_func(entity, index, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
        # If no specific values domain, then generate a dummy value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
        gen_func = getattr(self, 'generate_%s' % (attrtype))
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   103
        return gen_func(entity, attrname, index, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   105
    def generate_string(self, entity, attrname, index, format=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
        """generates a consistent value for 'attrname' if it's a string"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
        # First try to get choices
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   108
        choosed = self.get_choice(entity, attrname)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
        if choosed is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
            return choosed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
        # All other case, generate a default string
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   112
        attrlength = get_max_length(self.eschema, attrname)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
        num_len = numlen(index)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
        if num_len >= attrlength:
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   115
            ascii = self.eschema.rdef(attrname).internationalizable
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
            return ('&'+decompose_b26(index, ascii))[:attrlength]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
        # always use plain text when no format is specified
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
        attrprefix = attrname[:max(attrlength-num_len-1, 0)]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
        if format == 'text/html':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
            value = u'<span>ïż½%s<b>%d</b></span>' % (attrprefix, index)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
        elif format == 'text/rest':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
            value = u"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
title
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
-----
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
* %s
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
* %d
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
* ïż½&
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
""" % (attrprefix, index)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
            value = u'ïż½&%s%d' % (attrprefix, index)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
        return value[:attrlength]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   134
    def generate_password(self, entity, attrname, index):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
        """generates a consistent value for 'attrname' if it's a password"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
        return u'toto'
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   137
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   138
    def generate_integer(self, entity, attrname, index):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
        """generates a consistent value for 'attrname' if it's an integer"""
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   140
        return self._constrained_generate(entity, attrname, 0, 1, index)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
    generate_int = generate_integer
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   142
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   143
    def generate_float(self, entity, attrname, index):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
        """generates a consistent value for 'attrname' if it's a float"""
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   145
        return self._constrained_generate(entity, attrname, 0.0, 1.0, index)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   146
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   147
    def generate_decimal(self, entity, attrname, index):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
        """generates a consistent value for 'attrname' if it's a float"""
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   149
        return Decimal(str(self.generate_float(entity, attrname, index)))
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   150
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   151
    def generate_datetime(self, entity, attrname, index):
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   152
        """generates a random date (format is 'yyyy-mm-dd HH:MM')"""
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   153
        base = datetime(randint(2000, 2004), randint(1, 12), randint(1, 28), 11, index%60)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   154
        return self._constrained_generate(entity, attrname, base, timedelta(hours=1), index)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   155
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   156
    def generate_date(self, entity, attrname, index):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   157
        """generates a random date (format is 'yyyy-mm-dd')"""
4651
f9cd35dece09 [devtools/fill] fix date generation and its test
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 4513
diff changeset
   158
        base = date(randint(2000, 2010), 1, 1) + timedelta(randint(1, 365))
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   159
        return self._constrained_generate(entity, attrname, base, timedelta(days=1), index)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   161
    def generate_time(self, entity, attrname, index):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
        """generates a random time (format is ' HH:MM')"""
2118
0012d997b992 should use time here, not timedelta
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   163
        return time(11, index%60) #'11:%02d' % (index % 60)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   164
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   165
    def generate_bytes(self, entity, attrname, index, format=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
        fakefile = Binary("%s%s" % (attrname, index))
3541
63ba0a669c4f unicode file name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   167
        fakefile.filename = u"file_%s" % attrname
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
        return fakefile
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   169
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   170
    def generate_boolean(self, entity, attrname, index):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
        """generates a consistent value for 'attrname' if it's a boolean"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
        return index % 2 == 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   174
    def _constrained_generate(self, entity, attrname, base, step, index):
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   175
        choosed = self.get_choice(entity, attrname)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   176
        if choosed is not None:
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   177
            return choosed
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   178
        # ensure index > 0
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   179
        index += 1
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   180
        minvalue, maxvalue = self.get_bounds(entity, attrname)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   181
        if maxvalue is None:
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   182
            if minvalue is not None:
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   183
                base = max(minvalue, base)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   184
            maxvalue = base + index * step
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   185
        if minvalue is None:
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   186
            minvalue = maxvalue - (index * step) # i.e. randint(-index, 0)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   187
        return choice(list(custom_range(minvalue, maxvalue, step)))
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   188
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   189
    def _actual_boundary(self, entity, boundary):
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   190
        if isinstance(boundary, Attribute):
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   191
            # ensure we've a value for this attribute
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   192
            self.generate_attribute_value(entity, boundary.attr)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   193
            boundary = actual_value(boundary, entity)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   194
        return boundary
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   195
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   196
    def get_bounds(self, entity, attrname):
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   197
        minvalue = maxvalue = None
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   198
        for cst in self.eschema.rdef(attrname).constraints:
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   199
            if isinstance(cst, IntervalBoundConstraint):
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   200
                minvalue = self._actual_boundary(entity, cst.minvalue)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   201
                maxvalue = self._actual_boundary(entity, cst.maxvalue)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   202
            elif isinstance(cst, BoundConstraint):
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   203
                if cst.operator[0] == '<':
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   204
                    maxvalue = self._actual_boundary(entity, cst.boundary)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   205
                else:
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   206
                    minvalue = self._actual_boundary(entity, cst.boundary)
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   207
        return minvalue, maxvalue
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   208
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   209
    def get_choice(self, entity, attrname):
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   210
        """generates a consistent value for 'attrname' if it has some static
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   211
        vocabulary set, else return None.
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   212
        """
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   213
        for cst in self.eschema.rdef(attrname).constraints:
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   214
            if isinstance(cst, StaticVocabularyConstraint):
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   215
                return unicode(choice(cst.vocabulary()))
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   216
        return None
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   217
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   218
    # XXX nothing to do here
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   219
    def generate_Any_data_format(self, entity, index, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
        # data_format attribute of Image/File has no vocabulary constraint, we
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
        # need this method else stupid values will be set which make mtconverter
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
        # raise exception
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
        return u'application/octet-stream'
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   224
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   225
    def generate_Any_content_format(self, entity, index, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
        # content_format attribute of EmailPart has no vocabulary constraint, we
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
        # need this method else stupid values will be set which make mtconverter
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
        # raise exception
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
        return u'text/plain'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   231
    def generate_Image_data_format(self, entity, index, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
        # data_format attribute of Image/File has no vocabulary constraint, we
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
        # need this method else stupid values will be set which make mtconverter
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
        # raise exception
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
        return u'image/png'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
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
class autoextend(type):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
    def __new__(mcs, name, bases, classdict):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
        for attrname, attrvalue in classdict.items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
            if callable(attrvalue):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
                if attrname.startswith('generate_') and \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
                       attrvalue.func_code.co_argcount < 2:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
                    raise TypeError('generate_xxx must accept at least 1 argument')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
                setattr(_ValueGenerator, attrname, attrvalue)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
        return type.__new__(mcs, name, bases, classdict)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
class ValueGenerator(_ValueGenerator):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
    __metaclass__ = autoextend
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   251
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
def _default_choice_func(etype, attrname):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   253
    """default choice_func for insert_entity_queries"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
    return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   256
def insert_entity_queries(etype, schema, vreg, entity_num,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
                          choice_func=_default_choice_func):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   258
    """returns a list of 'add entity' queries (couples query, args)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   259
    :type etype: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
    :param etype: the entity's type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
    :type schema: cubicweb.schema.Schema
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2118
diff changeset
   263
    :param schema: the instance schema
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   264
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
    :type entity_num: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
    :param entity_num: the number of entities to insert
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
    XXX FIXME: choice_func is here for *historical* reasons, it should
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
               probably replaced by a nicer way to specify choices
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
    :type choice_func: function
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   271
    :param choice_func: a function that takes an entity type, an attrname and
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   272
                        returns acceptable values for this attribute
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   274
    # XXX HACK, remove or fix asap
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   275
    if etype in set(('String', 'Int', 'Float', 'Boolean', 'Date', 'CWGroup', 'CWUser')):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
        return []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   277
    queries = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   278
    for index in xrange(entity_num):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   279
        restrictions = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   280
        args = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
        for attrname, value in make_entity(etype, schema, vreg, index, choice_func).items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   282
            restrictions.append('X %s %%(%s)s' % (attrname, attrname))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   283
            args[attrname] = value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   284
        if restrictions:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   285
            queries.append(('INSERT %s X: %s' % (etype, ', '.join(restrictions)),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   286
                            args))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   287
            assert not 'eid' in args, args
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   288
        else:
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   289
            queries.append(('INSERT %s X' % etype, {}))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   290
    return queries
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   291
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   292
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   293
def make_entity(etype, schema, vreg, index=0, choice_func=_default_choice_func,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   294
                form=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   295
    """generates a random entity and returns it as a dict
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   296
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   297
    by default, generate an entity to be inserted in the repository
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   298
    elif form, generate an form dictionnary to be given to a web controller
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   299
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   300
    eschema = schema.eschema(etype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   301
    valgen = ValueGenerator(eschema, choice_func)
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   302
    entity = attrdict()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   303
    # preprocessing to deal with _format fields
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   304
    attributes = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   305
    relatedfields = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   306
    for rschema, attrschema in eschema.attribute_definitions():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   307
        attrname = rschema.type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   308
        if attrname == 'eid':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   309
            # don't specify eids !
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   310
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   311
        if attrname.endswith('_format') and attrname[:-7] in eschema.subject_relations():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   312
            relatedfields[attrname[:-7]] = attrschema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   313
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   314
            attributes.append((attrname, attrschema))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   315
    for attrname, attrschema in attributes:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   316
        if attrname in relatedfields:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   317
            # first generate a format and record it
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   318
            format = valgen.generate_attribute_value(entity, attrname + '_format', index)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   319
            # then a value coherent with this format
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   320
            value = valgen.generate_attribute_value(entity, attrname, index, format=format)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   321
        else:
4337
27ea69e2cfea refactor attributes'value generator to deal with yams special
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   322
            value = valgen.generate_attribute_value(entity, attrname, index)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   323
        if form: # need to encode values
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   324
            if attrschema.type == 'Bytes':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   325
                # twisted way
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   326
                fakefile = value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   327
                filename = value.filename
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   328
                value = (filename, u"text/plain", fakefile)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   329
            elif attrschema.type == 'Date':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   330
                value = value.strftime(vreg.property_value('ui.date-format'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   331
            elif attrschema.type == 'Datetime':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   332
                value = value.strftime(vreg.property_value('ui.datetime-format'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   333
            elif attrschema.type == 'Time':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   334
                value = value.strftime(vreg.property_value('ui.time-format'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   335
            elif attrschema.type == 'Float':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   336
                fmt = vreg.property_value('ui.float-format')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   337
                value = fmt % value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   338
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   339
                value = unicode(value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   340
    return entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   341
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   342
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   343
3742
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   344
def select(constraints, cursor, selectvar='O', objtype=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   345
    """returns list of eids matching <constraints>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   346
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   347
    <selectvar> should be either 'O' or 'S' to match schema definitions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   348
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   349
    try:
3742
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   350
        rql = 'Any %s WHERE %s' % (selectvar, constraints)
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   351
        if objtype:
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   352
            rql += ', %s is %s' % (selectvar, objtype)
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   353
        rset = cursor.execute(rql)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   354
    except:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   355
        print "could restrict eid_list with given constraints (%r)" % constraints
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   356
        return []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   357
    return set(eid for eid, in rset.rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   358
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   359
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   360
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   361
def make_relations_queries(schema, edict, cursor, ignored_relations=(),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
                           existingrels=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   363
    """returns a list of generated RQL queries for relations
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2118
diff changeset
   364
    :param schema: The instance schema
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   365
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   366
    :param e_dict: mapping between etypes and eids
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   367
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   368
    :param ignored_relations: list of relations to ignore (i.e. don't try
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   369
                              to generate insert queries for these relations)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   370
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   371
    gen = RelationsQueriesGenerator(schema, cursor, existingrels)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   372
    return gen.compute_queries(edict, ignored_relations)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   373
3742
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   374
def composite_relation(rschema):
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   375
    for obj in rschema.objects():
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3749
diff changeset
   376
        if obj.rdef(rschema, 'object').composite == 'subject':
3742
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   377
            return True
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   378
    for obj in rschema.subjects():
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3749
diff changeset
   379
        if obj.rdef(rschema, 'subject').composite == 'object':
3742
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   380
            return True
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   381
    return False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   382
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   383
class RelationsQueriesGenerator(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   384
    rql_tmpl = 'SET S %s O WHERE S eid %%(subjeid)s, O eid %%(objeid)s'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   385
    def __init__(self, schema, cursor, existing=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   386
        self.schema = schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   387
        self.cursor = cursor
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   388
        self.existingrels = existing or {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   389
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   390
    def compute_queries(self, edict, ignored_relations):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   391
        queries = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   392
        #   1/ skip final relations and explictly ignored relations
3742
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   393
        rels = sorted([rschema for rschema in self.schema.relations()
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   394
                       if not (rschema.final or rschema in ignored_relations)],
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   395
                      key=lambda x:not composite_relation(x))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   396
        # for each relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   397
        #   2/ take each possible couple (subj, obj)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   398
        #   3/ analyze cardinality of relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   399
        #      a/ if relation is mandatory, insert one relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   400
        #      b/ else insert N relations where N is the mininum
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   401
        #         of 20 and the number of existing targetable entities
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   402
        for rschema in rels:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   403
            sym = set()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   404
            sedict = deepcopy(edict)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   405
            oedict = deepcopy(edict)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   406
            delayed = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   407
            # for each couple (subjschema, objschema), insert relations
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3749
diff changeset
   408
            for subj, obj in rschema.rdefs:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   409
                sym.add( (subj, obj) )
4467
0e73d299730a fix long-waiting symetric typo: should be spelled symmetric. Add auto database migration on schema deserialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4337
diff changeset
   410
                if rschema.symmetric and (obj, subj) in sym:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   411
                    continue
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3749
diff changeset
   412
                subjcard, objcard = rschema.rdef(subj, obj).cardinality
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   413
                # process mandatory relations first
3742
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   414
                if subjcard in '1+' or objcard in '1+' or composite_relation(rschema):
3749
a84e798b99f6 turn make_relations_query into a true generator (this allows interleaving of actual entities linking and query generation)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3747
diff changeset
   415
                    for query, args in self.make_relation_queries(sedict, oedict,
a84e798b99f6 turn make_relations_query into a true generator (this allows interleaving of actual entities linking and query generation)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3747
diff changeset
   416
                                                          rschema, subj, obj):
a84e798b99f6 turn make_relations_query into a true generator (this allows interleaving of actual entities linking and query generation)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3747
diff changeset
   417
                        yield query, args
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   418
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   419
                    delayed.append( (subj, obj) )
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   420
            for subj, obj in delayed:
3749
a84e798b99f6 turn make_relations_query into a true generator (this allows interleaving of actual entities linking and query generation)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3747
diff changeset
   421
                for query, args in self.make_relation_queries(sedict, oedict, rschema,
a84e798b99f6 turn make_relations_query into a true generator (this allows interleaving of actual entities linking and query generation)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3747
diff changeset
   422
                                                              subj, obj):
a84e798b99f6 turn make_relations_query into a true generator (this allows interleaving of actual entities linking and query generation)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3747
diff changeset
   423
                    yield query, args
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   424
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   425
    def qargs(self, subjeids, objeids, subjcard, objcard, subjeid, objeid):
4513
8abf464d2ffe fix and begin to document autofill algorithm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4467
diff changeset
   426
        if subjcard in '?1+':
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   427
            subjeids.remove(subjeid)
4513
8abf464d2ffe fix and begin to document autofill algorithm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4467
diff changeset
   428
        if objcard in '?1+':
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   429
            objeids.remove(objeid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   430
        return {'subjeid' : subjeid, 'objeid' : objeid}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   431
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   432
    def make_relation_queries(self, sedict, oedict, rschema, subj, obj):
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3749
diff changeset
   433
        rdef = rschema.rdef(subj, obj)
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3749
diff changeset
   434
        subjcard, objcard = rdef.cardinality
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   435
        subjeids = sedict.get(subj, frozenset())
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   436
        used = self.existingrels[rschema.type]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   437
        preexisting_subjrels = set(subj for subj, obj in used)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   438
        preexisting_objrels = set(obj for subj, obj in used)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   439
        # if there are constraints, only select appropriate objeids
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   440
        q = self.rql_tmpl % rschema.type
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3749
diff changeset
   441
        constraints = [c for c in rdef.constraints
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   442
                       if isinstance(c, RQLConstraint)]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   443
        if constraints:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   444
            restrictions = ', '.join(c.restriction for c in constraints)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   445
            q += ', %s' % restrictions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   446
            # restrict object eids if possible
3711
486a29d66f2a work around a problem in constraint application
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 3689
diff changeset
   447
            # XXX the attempt to restrict below in completely wrong
486a29d66f2a work around a problem in constraint application
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 3689
diff changeset
   448
            # disabling it for now
3742
20f429eb5f46 kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3712
diff changeset
   449
            objeids = select(restrictions, self.cursor, objtype=obj)
3712
4b8d7838d74d revert change, but there's something fishy here
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 3711
diff changeset
   450
        else:
4b8d7838d74d revert change, but there's something fishy here
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 3711
diff changeset
   451
            objeids = oedict.get(obj, frozenset())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   452
        if subjcard in '?1' or objcard in '?1':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   453
            for subjeid, objeid in used:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   454
                if subjcard in '?1' and subjeid in subjeids:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   455
                    subjeids.remove(subjeid)
3673
9342e6783bd2 [testlib] hummm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3541
diff changeset
   456
                    # XXX why?
9342e6783bd2 [testlib] hummm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3541
diff changeset
   457
                    #if objeid in objeids:
9342e6783bd2 [testlib] hummm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3541
diff changeset
   458
                    #    objeids.remove(objeid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   459
                if objcard in '?1' and objeid in objeids:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   460
                    objeids.remove(objeid)
3673
9342e6783bd2 [testlib] hummm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3541
diff changeset
   461
                    # XXX why?
9342e6783bd2 [testlib] hummm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3541
diff changeset
   462
                    #if subjeid in subjeids:
9342e6783bd2 [testlib] hummm
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3541
diff changeset
   463
                    #    subjeids.remove(subjeid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   464
        if not subjeids:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   465
            check_card_satisfied(objcard, objeids, subj, rschema, obj)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   466
            return
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   467
        if not objeids:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   468
            check_card_satisfied(subjcard, subjeids, subj, rschema, obj)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   469
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   470
        if subjcard in '?1+':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   471
            for subjeid in tuple(subjeids):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   472
                # do not insert relation if this entity already has a relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   473
                if subjeid in preexisting_subjrels:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   474
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   475
                objeid = choose_eid(objeids, subjeid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   476
                if objeid is None or (subjeid, objeid) in used:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   477
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   478
                yield q, self.qargs(subjeids, objeids, subjcard, objcard,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   479
                                    subjeid, objeid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   480
                used.add( (subjeid, objeid) )
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   481
                if not objeids:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   482
                    check_card_satisfied(subjcard, subjeids, subj, rschema, obj)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   483
                    break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   484
        elif objcard in '?1+':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   485
            for objeid in tuple(objeids):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   486
                # do not insert relation if this entity already has a relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   487
                if objeid in preexisting_objrels:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   488
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   489
                subjeid = choose_eid(subjeids, objeid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   490
                if subjeid is None or (subjeid, objeid) in used:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   491
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   492
                yield q, self.qargs(subjeids, objeids, subjcard, objcard,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   493
                                    subjeid, objeid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   494
                used.add( (subjeid, objeid) )
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   495
                if not subjeids:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   496
                    check_card_satisfied(objcard, objeids, subj, rschema, obj)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   497
                    break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   498
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   499
            # FIXME: 20 should be read from config
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   500
            subjeidsiter = [choice(tuple(subjeids)) for i in xrange(min(len(subjeids), 20))]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   501
            objeidsiter = [choice(tuple(objeids)) for i in xrange(min(len(objeids), 20))]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   502
            for subjeid, objeid in zip(subjeidsiter, objeidsiter):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   503
                if subjeid != objeid and not (subjeid, objeid) in used:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   504
                    used.add( (subjeid, objeid) )
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   505
                    yield q, self.qargs(subjeids, objeids, subjcard, objcard,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   506
                                        subjeid, objeid)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   507
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   508
def check_card_satisfied(card, remaining, subj, rschema, obj):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   509
    if card in '1+' and remaining:
3749
a84e798b99f6 turn make_relations_query into a true generator (this allows interleaving of actual entities linking and query generation)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3747
diff changeset
   510
        raise Exception("can't satisfy cardinality %s for relation %s %s %s" %
a84e798b99f6 turn make_relations_query into a true generator (this allows interleaving of actual entities linking and query generation)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3747
diff changeset
   511
                        (card, subj, rschema, obj))
a84e798b99f6 turn make_relations_query into a true generator (this allows interleaving of actual entities linking and query generation)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3747
diff changeset
   512
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   513
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   514
def choose_eid(values, avoid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   515
    values = tuple(values)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   516
    if len(values) == 1 and values[0] == avoid:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   517
        return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   518
    objeid = choice(values)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   519
    while objeid == avoid: # avoid infinite recursion like in X comment X
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   520
        objeid = choice(values)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   521
    return objeid
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   522
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   523
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   524
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   525
# UTILITIES FUNCS ##############################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   526
def make_tel(num_tel):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   527
    """takes an integer, converts is as a string and inserts
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   528
    white spaces each 2 chars (french notation)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   529
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   530
    num_list = list(str(num_tel))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   531
    for index in (6, 4, 2):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   532
        num_list.insert(index, ' ')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   533
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   534
    return ''.join(num_list)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   535
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   536
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   537
def numlen(number):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   538
    """returns the number's length"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   539
    return len(str(number))