Passed
Push — main ( 7e9c56...8b0189 )
by Jochen
03:34
created

_check_for_unknown_subject_ids()   A

Complexity

Conditions 2

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.1481

Importance

Changes 0
Metric Value
cc 2
eloc 8
nop 2
dl 0
loc 10
ccs 4
cts 6
cp 0.6667
crap 2.1481
rs 10
c 0
b 0
f 0
1
"""
2
byceps.services.consent.subject_service
3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5
:Copyright: 2006-2020 Jochen Kupperschmidt
6
:License: Modified BSD, see LICENSE for details.
7
"""
8
9 1
from typing import Dict, Optional, Set
10
11 1
from ...database import db
12
13 1
from .models.consent import Consent as DbConsent
14 1
from .models.subject import Subject as DbSubject
15 1
from .transfer.models import Subject, SubjectID
16
17
18 1
class UnknownSubjectId(ValueError):
19 1
    pass
20
21
22 1
def create_subject(
23
    name: str,
24
    title: str,
25
    type_: str,
26
    checkbox_label: str,
27
    checkbox_link_target: Optional[str],
28
) -> SubjectID:
29
    """Create a new subject."""
30 1
    subject = DbSubject(
31
        name, title, type_, checkbox_label, checkbox_link_target
32
    )
33
34 1
    db.session.add(subject)
35 1
    db.session.commit()
36
37 1
    return _db_entity_to_subject(subject)
38
39
40 1
def get_subjects(subject_ids: Set[SubjectID]) -> Set[Subject]:
41
    """Return the subjects."""
42 1
    rows = DbSubject.query \
43
        .filter(DbSubject.id.in_(subject_ids)) \
44
        .all()
45
46 1
    subjects = {_db_entity_to_subject(row) for row in rows}
47
48 1
    _check_for_unknown_subject_ids(subject_ids, subjects)
49
50 1
    return subjects
51
52
53 1
def _check_for_unknown_subject_ids(
54
    subject_ids: Set[SubjectID], subjects: Set[Subject]
55
) -> None:
56
    """Raise exception on unknown IDs."""
57 1
    found_subject_ids = {subject.id for subject in subjects}
58 1
    unknown_subject_ids = subject_ids.difference(found_subject_ids)
59 1
    if unknown_subject_ids:
60
        unknown_subject_ids_str = ', '.join(map(str, unknown_subject_ids))
61
        raise UnknownSubjectId(
62
            f'Unknown subject IDs: {unknown_subject_ids_str}'
63
        )
64
65
66 1
def get_subjects_with_consent_counts() -> Dict[Subject, int]:
67
    """Return all subjects."""
68
    rows = db.session \
69
        .query(
70
            DbSubject,
71
            db.func.count(DbConsent.user_id)
72
        ) \
73
        .outerjoin(DbConsent) \
74
        .group_by(DbSubject.id) \
75
        .all()
76
77
    return {
78
        _db_entity_to_subject(subject): consent_count
79
        for subject, consent_count in rows
80
    }
81
82
83 1
def _db_entity_to_subject(subject: DbSubject) -> Subject:
84 1
    return Subject(
85
        subject.id,
86
        subject.name,
87
        subject.title,
88
        subject.type_,
89
        subject.checkbox_label,
90
        subject.checkbox_link_target,
91
    )
92