Projet

Général

Profil

0001-add-support-for-string-columns-fixes-29768.patch

Benjamin Dauvergne, 15 janvier 2019 17:04

Télécharger (11 ko)

Voir les différences:

Subject: [PATCH] add support for string columns (fixes #29768)

 bijoe/schemas.py                      | 12 ++++++---
 bijoe/templates/bijoe/cube_table.html |  2 +-
 bijoe/visualization/forms.py          | 20 ++++++++++++--
 bijoe/visualization/utils.py          | 17 +++++++++++-
 tests/fixtures/schema1/01_schema.json |  6 +++++
 tests/fixtures/schema1/01_schema.sql  | 39 ++++++++++++++-------------
 tests/test_schema1.py                 | 15 +++++++++++
 tox.ini                               |  1 +
 8 files changed, 86 insertions(+), 26 deletions(-)
bijoe/schemas.py
254 254
                filter_values = [filter_values]
255 255
            if not filter_values:
256 256
                return '', []
257
            is_none = None in filter_values
258
            filter_values = [v for v in filter_values if v is not None]
257 259
            if self.type == 'integer':
258
                values = map(int, filter_values)
260
                values = [int(v) for v in filter_values]
259 261
            else:
260 262
                values = filter_values
261 263
            s = ', '.join(['%s'] * len(values))
262 264
            if self.filter_expression:
263
                return self.filter_expression % s, values
264
            return '%s IN (%s)' % (value, s), values
265
                expression = self.filter_expression % s
266
            else:
267
                expression = '%s IN (%s)' % (value, s)
268
            if is_none:
269
                expression = '((%s) OR (%s IS NULL))' % (expression, value)
270
            return expression, values
265 271

  
266 272

  
267 273
def join_kind(kind):
bijoe/templates/bijoe/cube_table.html
13 13
        <tr>
14 14
          {% for value in row %}
15 15
          {% comment %}Only django 1.10 allow is None/True/False{% endcomment %}
16
          <td>{% if value|stringformat:"r" == "None" %}0{% elif value|stringformat:"r" == "True" %}{% trans "Oui" %}{% elif value|stringformat:"r" == "False" %}{% trans "Non" %}{% else %}{{ value }}{% endif %}</td>
16
          <td>{{ value }}</td>
17 17
          {% endfor %}
18 18
        </tr>
19 19
      {% endfor %}
bijoe/visualization/forms.py
15 15
# You should have received a copy of the GNU Affero General Public License
16 16
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 17

  
18
import six
19

  
18 20
from django import forms
19 21
from django.core.exceptions import ValidationError
20 22
from django.utils.translation import ugettext as _
......
183 185
                self.base_fields[field_name] = NullBooleanField(
184 186
                    label=dimension.label.capitalize(), required=False)
185 187
            else:
186
                self.base_fields[field_name] = forms.MultipleChoiceField(
188
                members = []
189
                for _id, label in dimension.members:
190
                    members.append((_id, six.text_type(_id), label))
191
                members.append((None, '__none__', _('None')))
192

  
193
                def coercion_function(members):
194
                    def f(v):
195
                        for value, s, label in members:
196
                            if v == s:
197
                                return value
198
                        return None
199
                    return f
200

  
201
                self.base_fields[field_name] = forms.TypedMultipleChoiceField(
187 202
                    label=dimension.label.capitalize(),
188
                    choices=dimension.members,
203
                    choices=[(s, label) for v, s, label in members],
204
                    coerce=coercion_function(members),
189 205
                    required=False,
190 206
                    widget=build_select2_multiple_widget())
191 207

  
bijoe/visualization/utils.py
159 159
                    if not s:
160 160
                        s = 'moins d\'1 heure'
161 161
                    value = s
162
                elif value is not None and cell['type'] == 'bool':
163
                    value = _('Yes') if value else _('No')
164
                elif value is None and cell['type'] in ('duration','integer'):
165
                    value = 0
166
                elif value is None and cell['type'] != 'integer':
167
                    value = _('None')
162 168
                cell['value'] = value
163 169
        return data
164 170

  
......
179 185
    def table(self):
180 186
        table = []
181 187
        if len(self.drilldown) == 2:
188
            if self.measure.type == 'integer':
189
                default = 0
190
            elif self.measure.type == 'duration':
191
                default = '0 s'
192
            elif self.measure.type == 'percent':
193
                default = '0 %'
194
            else:
195
                raise NotImplementedError(self.measure.type)
196

  
182 197
            x_labels = [x.label for x in self.drilldown_x.members]
183 198
            y_labels = [y.label for y in self.drilldown_y.members]
184 199
            used_x_label = set()
185 200
            used_y_label = set()
186 201

  
187
            grid = {(x, y): None for x in x_labels for y in y_labels}
202
            grid = {(x, y): default for x in x_labels for y in y_labels}
188 203

  
189 204
            for row in self.stringified():
190 205
                x_label = unicode(row[0]['value'])
tests/fixtures/schema1/01_schema.json
157 157
                    "value": "outercategory.id",
158 158
                    "order_by": "outercategory.ord",
159 159
                    "value_label": "outercategory.label"
160
                },
161
                {
162
                    "name": "string",
163
                    "label": "String",
164
                    "type": "string",
165
                    "value": "string"
160 166
                }
161 167
            ],
162 168
            "measures": [
tests/fixtures/schema1/01_schema.sql
25 25
    innersubcategory_id integer references schema1.subcategory(id),
26 26
    leftsubcategory_id integer references schema1.subcategory(id),
27 27
    rightsubcategory_id integer references schema1.subcategory(id),
28
    outersubcategory_id integer references schema1.subcategory(id)
28
    outersubcategory_id integer references schema1.subcategory(id),
29
    string varchar
29 30
);
30 31

  
31 32
INSERT INTO category (ord, label) VALUES
......
45 46
   (3, 0, 'subé9');
46 47

  
47 48

  
48
INSERT INTO facts (date, datetime, integer, boolean, cnt, innersubcategory_id, leftsubcategory_id, rightsubcategory_id, outersubcategory_id) VALUES
49
   ('2017-01-01', '2017-01-01 10:00', 1, FALSE, 10, 1, 1, 1, 1),
50
   ('2017-01-02', '2017-01-02 10:00', 1, TRUE, 10, 3, 3, 3, 3),
51
   ('2017-01-03', '2017-01-03 10:00', 1, FALSE, 10, NULL, NULL, NULL, NULL),
52
   ('2017-01-04', '2017-01-04 10:00', 1, FALSE, 10, 1, 1, 1, 1),
53
   ('2017-01-05', '2017-01-05 10:00', 1, TRUE, 10, 1, 1, 1, 1),
54
   ('2017-01-06', '2017-01-06 10:00', 1, FALSE, 10, 1, 1, 1, 1),
55
   ('2017-01-07', '2017-01-07 10:00', 1, TRUE, 10, 1, 1, 1, 1),
56
   ('2017-01-08', '2017-01-08 10:00', 1, FALSE, 10, 1, 1, 1, 1),
57
   ('2017-01-09', '2017-01-09 10:00', 1, TRUE, 10, 1, 1, 1, 1),
58
   ('2017-01-10', '2017-01-10 10:00', 1, FALSE, 10, 1, 1, 1, 1),
59
   ('2017-02-01', '2017-02-01 10:00', 1, TRUE, 10, 1, 1, 1, 1),
60
   ('2017-03-01', '2017-03-01 10:00', 1, FALSE, 10, 1, 1, 1, 1),
61
   ('2017-04-01', '2017-04-01 10:00', 1, TRUE, 10, 1, 1, 1, 1),
62
   ('2017-05-01', '2017-05-01 10:00', 1, FALSE, 10, 1, 1, 1, 1),
63
   ('2017-06-01', '2017-06-01 10:00', 1, TRUE, 10, 1, 1, 1, 1),
64
   ('2017-07-01', '2017-07-01 10:00', 1, FALSE, 10, 1, 1, 1, 1),
65
   ('2017-08-01', '2017-08-01 10:00', 1, TRUE, 10, 1, 1, 1, 1);
49
INSERT INTO facts (date, datetime, integer, boolean, cnt, innersubcategory_id, leftsubcategory_id, rightsubcategory_id, outersubcategory_id, string) VALUES
50
   ('2017-01-01', '2017-01-01 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'a'),
51
   ('2017-01-02', '2017-01-02 10:00', 1, TRUE, 10, 3, 3, 3, 3, 'b'),
52
   ('2017-01-03', '2017-01-03 10:00', 1, FALSE, 10, NULL, NULL, NULL, NULL, 'a'),
53
   ('2017-01-04', '2017-01-04 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'a'),
54
   ('2017-01-05', '2017-01-05 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'c'),
55
   ('2017-01-06', '2017-01-06 10:00', 1, FALSE, 10, 1, 1, 1, 1, NULL),
56
   ('2017-01-07', '2017-01-07 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'a'),
57
   ('2017-01-08', '2017-01-08 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'a'),
58
   ('2017-01-09', '2017-01-09 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'a'),
59
   ('2017-01-10', '2017-01-10 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'a'),
60
   ('2017-02-01', '2017-02-01 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'a'),
61
   ('2017-03-01', '2017-03-01 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'c'),
62
   ('2017-04-01', '2017-04-01 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'a'),
63
   ('2017-05-01', '2017-05-01 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'a'),
64
   ('2017-06-01', '2017-06-01 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'c'),
65
   ('2017-07-01', '2017-07-01 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'a'),
66
   ('2017-08-01', '2017-08-01 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'b');
tests/test_schema1.py
68 68
    form.set('filter__boolean', [o[0] for o in form.fields['filter__boolean'][0].options if o[2] == 'Oui'][0])
69 69
    response = form.submit('visualize')
70 70
    assert get_table(response) == [['Boolean', 'Oui'], ['number of rows', '8']]
71

  
72

  
73
def test_string_dimension(schema1, app, admin):
74
    login(app, admin)
75
    response = app.get('/').follow()
76
    response = response.click('Facts 1')
77
    form = response.form
78
    form.set('representation', 'table')
79
    form.set('measure', 'simple_count')
80
    form.set('drilldown_x', 'string')
81
    response = form.submit('visualize')
82
    assert get_table(response) == [['String', 'a', 'b', 'c', 'Aucun(e)'], ['number of rows', '11', '2', '3', '1']]
83
    form.set('filter__string', ['a', 'b', '__none__'])
84
    response = form.submit('visualize')
85
    assert get_table(response) == [['String', 'a', 'b', 'Aucun(e)'], ['number of rows', '11', '2', '1']]
tox.ini
25 25
	pytest-cov
26 26
	pytest-django
27 27
	pytest-freezegun
28
	pytest-random
28 29
	WebTest
29 30
	django-webtest<1.9.3
30 31
	pyquery
31
-