Completed
Push — master ( 5353c7...9e0b1e )
by P.R.
02:05
created

pre_call_stored_procedure()   A

Complexity

Conditions 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
ccs 0
cts 2
cp 0
rs 9.6666
cc 1
crap 2
1
"""
2
ETLT
3
4
Copyright 2016 Set Based IT Consultancy
5
6
Licence MIT
7
"""
8
import abc
9
import datetime
10
11
12
class Type2ReferenceDimension(metaclass=abc.ABCMeta):
13
    """
14
    Abstract class for type2 dimensions for which the reference data is supplied with date intervals.
15
    """
16
17
    # ------------------------------------------------------------------------------------------------------------------
18
    def __init__(self):
19
        """
20
        Object constructor.
21
        """
22
23
        self._key_key = ''
24
        """
25
        The key in the dict returned by call_stored_procedure holding the technical ID.
26
27
        :type: str
28
        """
29
30
        self._key_date_start = ''
31
        """
32
        The key in the dict returned by call_stored_procedure holding the start date.
33
34
        :type: str
35
        """
36
37
        self._key_date_end = ''
38
        """
39
        The key in the dict returned by call_stored_procedure holding the end date.
40
41
        :type: str
42
        """
43
44
        self._map = {}
45
        """
46
        The map from natural keys to lists of tuples with start date, end date, and technical keys. The dates must be in
47
        ISO 8601 (YYYY-MM-DD) format.
48
49
        :type: dict[T, list[(str,str,int|None)]]
50
        """
51
52
        # Pre-load look up data in to the map.
53
        self.pre_load_data()
54
55
    # ------------------------------------------------------------------------------------------------------------------
56
    def get_id(self, natural_key, date, enhancement=None):
57
        """
58
        Returns the technical ID for a natural key at a date or None if the given natural key is not valid.
59
60
        :param T natural_key: The natural key.
61
        :param str date: The date in ISO 8601 (YYYY-MM-DD) format.
62
        :param T enhancement: Enhancement data of the dimension row.
63
64
        :rtype: int|None
65
        """
66
        if not date:
67
            return None
68
69
        # If the natural key is known return the technical ID immediately.
70
        if natural_key in self._map:
71
            for row in self._map[natural_key]:
72
                if row[0] <= date <= row[1]:
73
                    return row[2]
74
75
        # The natural key is not in the map of this dimension. Call a stored procedure for translating the natural key
76
        # to a technical key.
77
        self.pre_call_stored_procedure()
78
        success = False
79
        try:
80
            row = self.call_stored_procedure(natural_key, date, enhancement)
81
            # Convert dates to strings in ISO 8601 format.
82
            if isinstance(row[self._key_date_start], datetime.date):
83
                row[self._key_date_start] = row[self._key_date_start].isoformat()
84
            if isinstance(row[self._key_date_end], datetime.date):
85
                row[self._key_date_end] = row[self._key_date_end].isoformat()
86
            success = True
87
        finally:
88
            self.post_call_stored_procedure(success)
89
90
        # Make sure the natural key is in the map.
91
        if natural_key not in self._map:
92
            self._map[natural_key] = []
93
94
        if row[self._key_key]:
95
            self._map[natural_key].append((row[self._key_date_start],
96
                                           row[self._key_date_end],
97
                                           row[self._key_key]))
98
        else:
99
            self._map[natural_key].append((date, date, None))
100
101
        return row[self._key_key]
102
103
    # ------------------------------------------------------------------------------------------------------------------
104
    @abc.abstractmethod
105
    def call_stored_procedure(self, natural_key, date, enhancement):
106
        """
107
        Call a stored procedure for getting the technical key of a natural key at a date. Returns the technical ID or
108
        None if the given natural key is not valid.
109
110
        :param T natural_key: The natural key.
111
        :param str date: The date in ISO 8601 (YYYY-MM-DD) format.
112
        :param T enhancement: Enhancement data of the dimension row.
113
114
        :rtype: dict
115
        """
116
        raise NotImplementedError()
117
118
    # ------------------------------------------------------------------------------------------------------------------
119
    def pre_load_data(self):
120
        """
121
        Can be overridden to pre-load lookup data from a dimension table.
122
123
        :rtype: None
124
        """
125
        pass
126
127
    # ------------------------------------------------------------------------------------------------------------------
128
    def pre_call_stored_procedure(self):
129
        """
130
        This method is invoked before call the stored procedure for getting the technical key of a natural key.
131
132
        In a concurrent environment override this method to acquire a lock on the dimension or dimension hierarchy.
133
134
        :rtype: None
135
        """
136
        pass
137
138
    # ------------------------------------------------------------------------------------------------------------------
139
    def post_call_stored_procedure(self, success):
140
        """
141
        This method is invoked after calling the stored procedure for getting the technical key of a natural key.
142
143
        In a concurrent environment override this method to release a lock on the dimension or dimension hierarchy and
144
        to commit or rollback the transaction.
145
146
        :param bool success: If True the stored procedure is executed successfully. If an exception has occurred.
147
148
        :rtype: None
149
        """
150
        pass
151
152
# ----------------------------------------------------------------------------------------------------------------------
153