pystratum_pgsql.wrapper.PgSqlWrapper   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Test Coverage

Coverage 92.68%

Importance

Changes 0
Metric Value
eloc 71
dl 0
loc 123
ccs 38
cts 41
cp 0.9268
rs 10
c 0
b 0
f 0
wmc 13

4 Methods

Rating   Name   Duplication   Size   Complexity  
A PgSqlWrapper.is_lob_parameter() 0 35 4
A PgSqlWrapper._get_parameter_format_specifier() 0 29 2
B PgSqlWrapper._generate_command() 0 32 6
A PgSqlWrapper._write_result_handler() 0 8 1
1 1
import abc
2 1
from typing import Any, Dict
3
4 1
from pystratum_common.wrapper.Wrapper import Wrapper
5
6
7 1
class PgSqlWrapper(Wrapper):
8
    """
9
    Parent class for wrapper method generators for stored functions.
10
    """
11
12
    # ------------------------------------------------------------------------------------------------------------------
13 1
    def is_lob_parameter(self, parameters):
14
        """
15
        Returns True if one of the parameters is a BLOB or CLOB. Otherwise, returns False.
16
17
        :param list[dict[str,str]] parameters: The parameters of a stored routine.
18
19
        :rtype: bool
20
        """
21 1
        has_lob = False
22
23 1
        lookup = {'bigint':                      False,
24
                  'integer':                     False,
25
                  'bit':                         False,
26
                  'smallint':                    False,
27
                  'money':                       False,
28
                  'numeric':                     False,
29
                  'real':                        False,
30
                  'character':                   False,
31
                  'character varying':           False,
32
                  'timestamp without time zone': False,
33
                  'time without time zone':      False,
34
                  'date':                        False,
35
                  'boolean':                     False,
36
37
                  'bytea':                       True,
38
                  'text':                        True}
39
40 1
        if parameters:
41 1
            for parameter_info in parameters:
42 1
                if parameter_info['data_type'] in lookup:
43 1
                    has_lob = lookup[parameter_info['data_type']]
44
                else:
45
                    raise Exception("Unexpected date type '{0!s}'.".format(parameter_info['data_type']))
46
47 1
        return has_lob
48
49
    # ------------------------------------------------------------------------------------------------------------------
50 1
    @abc.abstractmethod
51 1
    def _write_result_handler(self, routine: Dict[str, Any]) -> None:
52
        """
53
        Generates code of the return statement of the wrapper method for invoking a stored routine.
54
55
        :param dict routine: Metadata of the stored routine.
56
        """
57
        raise NotImplementedError()
58
59
    # ------------------------------------------------------------------------------------------------------------------
60 1
    def _generate_command(self, routine: Dict[str, Any]) -> str:
61
        """
62
        Returns a SQL-statement for calling a stored routine.
63
64
        :param dict routine: Metadata of the stored routine.
65
66
        :rtype: str
67
        """
68 1
        parameters = ''
69 1
        placeholders = ''
70
71 1
        execute = 'select'
72
73 1
        parameter_count = 0
74 1
        for parameter in routine['parameters']:
75 1
            re_type = self._get_parameter_format_specifier(parameter['data_type'])
76 1
            if parameters:
77 1
                parameters += ', '
78 1
                placeholders += ', '
79 1
            parameters += parameter['name']
80 1
            placeholders += re_type
81 1
            if not re_type == '?':
82 1
                parameter_count += 1
83
84 1
        if parameter_count == 0:
85 1
            line = '"{0!s} {1!s}()"'.format(execute, routine['routine_name'])
86 1
        elif parameter_count >= 1:
87 1
            line = '"{0!s} {1!s}({2!s})", {3!s}'.format(execute, routine['routine_name'], placeholders, parameters)
88
        else:
89
            raise Exception('Internal error.')
90
91 1
        return line
92
93
    # ------------------------------------------------------------------------------------------------------------------
94 1
    @staticmethod
95 1
    def _get_parameter_format_specifier(data_type: str) -> str:
96
        """
97
        Returns the appropriate format specifier for a parameter type.
98
99
        :param str data_type: The parameter type.
100
101
        :rtype: str
102
        """
103 1
        lookup = {'bigint':                      '%s::bigint',
104
                  'integer':                     '%s::int',
105
                  'bit':                         '%s::bit(4)',
106
                  'smallint':                    '%s::smallint',
107
                  'money':                       '%s::money',
108
                  'numeric':                     '%s::numeric',
109
                  'real':                        '%s::real',
110
                  'character':                   '%s::char',
111
                  'character varying':           '%s::varchar',
112
                  'timestamp without time zone': '%s::timestamp',
113
                  'time without time zone':      '%s::timestamp',
114
                  'boolean':                     '%s::bool',
115
                  'date':                        '%s::date',
116
                  'bytea':                       '%s::bytea',
117
                  'text':                        '%s::text'}
118
119 1
        if data_type in lookup:
120 1
            return lookup[data_type]
121
122
        raise Exception('Unexpected data type {0!s}.'.format(data_type))
123
124
# ---------------------------------------------------------------------------------------------------------------------
125