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