Hide keyboard shortcuts

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 

6 

7from pystratum_backend.RoutineWrapperGeneratorWorker import RoutineWrapperGeneratorWorker 

8from pystratum_backend.StratumStyle import StratumStyle 

9from pystratum_common.Util import Util 

10 

11 

12class CommonRoutineWrapperGeneratorWorker(RoutineWrapperGeneratorWorker): 

13 """ 

14 Class for generating a class with wrapper methods for calling stored routines in a MySQL database. 

15 """ 

16 

17 # ------------------------------------------------------------------------------------------------------------------ 

18 def __init__(self, io: StratumStyle, config: configparser.ConfigParser): 

19 """ 

20 Object constructor. 

21 

22 :param PyStratumStyle io: The output decorator. 

23 """ 

24 self._code: str = '' 

25 """ 

26 The generated Python code buffer. 

27 """ 

28 

29 self._lob_as_string_flag: bool = False 

30 """ 

31 If true BLOBs and CLOBs must be treated as strings. 

32 """ 

33 

34 self._metadata_filename: Optional[str] = None 

35 """ 

36 The filename of the file with the metadata of all stored procedures. 

37 """ 

38 

39 self._parent_class_name: Optional[str] = None 

40 """ 

41 The class name of the parent class of the routine wrapper. 

42 """ 

43 

44 self._parent_class_namespace: Optional[str] = None 

45 """ 

46 The namespace of the parent class of the routine wrapper. 

47 """ 

48 

49 self._wrapper_class_name: Optional[str] = None 

50 """ 

51 The class name of the routine wrapper. 

52 """ 

53 

54 self._wrapper_filename: Optional[str] = None 

55 """ 

56 The filename where the generated wrapper class must be stored. 

57 """ 

58 

59 self._io: StratumStyle = io 

60 """ 

61 The output decorator. 

62 """ 

63 

64 self._config = config 

65 """ 

66 The configuration object. 

67 

68 :type: ConfigParser  

69 """ 

70 

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. 

75 

76 :rtype: int 

77 """ 

78 self._read_configuration_file() 

79 

80 if self._wrapper_class_name: 

81 self._io.title('Wrapper') 

82 

83 self.__generate_wrapper_class() 

84 

85 self._io.writeln('') 

86 else: 

87 self._io.log_verbose('Wrapper not enabled') 

88 

89 return 0 

90 

91 # ------------------------------------------------------------------------------------------------------------------ 

92 def __generate_wrapper_class(self) -> None: 

93 """ 

94 Generates the wrapper class. 

95 """ 

96 routines = self._read_routine_metadata() 

97 

98 self._write_class_header() 

99 

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') 

106 

107 self._write_class_trailer() 

108 

109 Util.write_two_phases(self._wrapper_filename, self._code, self._io) 

110 

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')) 

122 

123 # ------------------------------------------------------------------------------------------------------------------ 

124 def _read_routine_metadata(self) -> Dict: 

125 """ 

126 Returns the metadata of stored routines. 

127 

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) 

134 

135 return metadata 

136 

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(' """') 

151 

152 # ------------------------------------------------------------------------------------------------------------------ 

153 def _write_line(self, text: str = '') -> None: 

154 """ 

155 Writes a line with Python code to the generate code buffer. 

156 

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" 

163 

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)) 

172 

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. 

178 

179 :param dict routine: The metadata of the stored routine. 

180 """ 

181 raise NotImplementedError() 

182 

183# ----------------------------------------------------------------------------------------------------------------------