Coverage for pystratum_common/backend/CommonRoutineWrapperGeneratorWorker.py : 0%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import abc
2import configparser
3import json
4import os
5from typing import Any, Dict, Optional
7from pystratum_backend.RoutineWrapperGeneratorWorker import RoutineWrapperGeneratorWorker
8from pystratum_backend.StratumStyle import StratumStyle
9from pystratum_common.Util import Util
12class CommonRoutineWrapperGeneratorWorker(RoutineWrapperGeneratorWorker):
13 """
14 Class for generating a class with wrapper methods for calling stored routines in a MySQL database.
15 """
17 # ------------------------------------------------------------------------------------------------------------------
18 def __init__(self, io: StratumStyle, config: configparser.ConfigParser):
19 """
20 Object constructor.
22 :param PyStratumStyle io: The output decorator.
23 """
24 self._code: str = ''
25 """
26 The generated Python code buffer.
27 """
29 self._lob_as_string_flag: bool = False
30 """
31 If true BLOBs and CLOBs must be treated as strings.
32 """
34 self._metadata_filename: Optional[str] = None
35 """
36 The filename of the file with the metadata of all stored procedures.
37 """
39 self._parent_class_name: Optional[str] = None
40 """
41 The class name of the parent class of the routine wrapper.
42 """
44 self._parent_class_namespace: Optional[str] = None
45 """
46 The namespace of the parent class of the routine wrapper.
47 """
49 self._wrapper_class_name: Optional[str] = None
50 """
51 The class name of the routine wrapper.
52 """
54 self._wrapper_filename: Optional[str] = None
55 """
56 The filename where the generated wrapper class must be stored.
57 """
59 self._io: StratumStyle = io
60 """
61 The output decorator.
62 """
64 self._config = config
65 """
66 The configuration object.
68 :type: ConfigParser
69 """
71 # ------------------------------------------------------------------------------------------------------------------
72 def execute(self) -> int:
73 """
74 The "main" of the wrapper generator. Returns 0 on success, 1 if one or more errors occurred.
76 :rtype: int
77 """
78 self._read_configuration_file()
80 if self._wrapper_class_name:
81 self._io.title('Wrapper')
83 self.__generate_wrapper_class()
85 self._io.writeln('')
86 else:
87 self._io.log_verbose('Wrapper not enabled')
89 return 0
91 # ------------------------------------------------------------------------------------------------------------------
92 def __generate_wrapper_class(self) -> None:
93 """
94 Generates the wrapper class.
95 """
96 routines = self._read_routine_metadata()
98 self._write_class_header()
100 if routines:
101 for routine_name in sorted(routines):
102 if routines[routine_name]['designation'] != 'hidden':
103 self._write_routine_function(routines[routine_name])
104 else:
105 self._io.error('No files with stored routines found')
107 self._write_class_trailer()
109 Util.write_two_phases(self._wrapper_filename, self._code, self._io)
111 # ------------------------------------------------------------------------------------------------------------------
112 def _read_configuration_file(self) -> None:
113 """
114 Reads parameters from the configuration file.
115 """
116 self._parent_class_name = self._config.get('wrapper', 'parent_class')
117 self._parent_class_namespace = self._config.get('wrapper', 'parent_class_namespace')
118 self._wrapper_class_name = self._config.get('wrapper', 'wrapper_class')
119 self._wrapper_filename = self._config.get('wrapper', 'wrapper_file')
120 self._metadata_filename = self._config.get('wrapper', 'metadata')
121 self._lob_as_string_flag = bool(self._config.get('wrapper', 'lob_as_string'))
123 # ------------------------------------------------------------------------------------------------------------------
124 def _read_routine_metadata(self) -> Dict:
125 """
126 Returns the metadata of stored routines.
128 :rtype: dict
129 """
130 metadata = {}
131 if os.path.isfile(self._metadata_filename):
132 with open(self._metadata_filename, 'r') as file:
133 metadata = json.load(file)
135 return metadata
137 # ------------------------------------------------------------------------------------------------------------------
138 def _write_class_header(self) -> None:
139 """
140 Generate a class header for stored routine wrapper.
141 """
142 self._write_line('from typing import Any, Dict, List, Optional, Union')
143 self._write_line()
144 self._write_line('from {0!s} import {1!s}'.format(self._parent_class_namespace, self._parent_class_name))
145 self._write_line()
146 self._write_line()
147 self._write_line('class {0!s}({1!s}):'.format(self._wrapper_class_name, self._parent_class_name))
148 self._write_line(' """')
149 self._write_line(' The stored routines wrappers.')
150 self._write_line(' """')
152 # ------------------------------------------------------------------------------------------------------------------
153 def _write_line(self, text: str = '') -> None:
154 """
155 Writes a line with Python code to the generate code buffer.
157 :param str text: The line with Python code.
158 """
159 if text:
160 self._code += str(text) + "\n"
161 else:
162 self._code += "\n"
164 # ------------------------------------------------------------------------------------------------------------------
165 def _write_class_trailer(self) -> None:
166 """
167 Generate a class trailer for stored routine wrapper.
168 """
169 self._write_line()
170 self._write_line()
171 self._write_line('# ' + ('-' * 118))
173 # ------------------------------------------------------------------------------------------------------------------
174 @abc.abstractmethod
175 def _write_routine_function(self, routine: Dict[str, Any]) -> None:
176 """
177 Generates a complete wrapper method for a stored routine.
179 :param dict routine: The metadata of the stored routine.
180 """
181 raise NotImplementedError()
183# ----------------------------------------------------------------------------------------------------------------------