CUBRID Engine  latest
load_error_handler.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * load_error_handler.hpp - Error handling class for loaddb functionality
21  */
22 
23 #ifndef _LOAD_ERROR_HANDLER_HPP_
24 #define _LOAD_ERROR_HANDLER_HPP_
25 
26 #include "load_common.hpp"
27 #include "porting.h"
28 #include "utility.h"
29 
30 #include <memory>
31 #include <string>
32 
33 namespace cubload
34 {
35 
36  class session;
37 
39  {
40  public:
41 #if defined (SERVER_MODE)
42  explicit error_handler (session &session);
43 #else
44  error_handler () = default;
45 #endif
46 
47  ~error_handler () = default; // Destructor
48 
49  template<typename... Args>
50  void on_error (MSGCAT_LOADDB_MSG msg_id, Args &&... args);
51 
52  // just log er_msg from error_manager and fail the session
53  void on_failure ();
54 
55  // In case of syntax check argument do nothing, else keep the behavior as on_failure
56  void on_syntax_failure (bool use_scanner_line = false);
57 
58  template<typename... Args>
59  void on_error_with_line (MSGCAT_LOADDB_MSG msg_id, Args &&... args);
60 
61  template<typename... Args>
62  void on_error_with_line (int lineno, MSGCAT_LOADDB_MSG msg_id, Args &&... args);
63 
64  template<typename... Args>
65  void on_failure (MSGCAT_LOADDB_MSG msg_id, Args &&... args);
66 
67  template<typename... Args>
68  void on_failure_with_line (MSGCAT_LOADDB_MSG msg_id, Args &&... args);
69 
70  template<typename... Args>
71  void log_date_time_conversion_error (Args &&... args);
72 
73  template<typename... Args>
74  static std::string format_log_msg (MSGCAT_LOADDB_MSG msg_id, Args &&... args);
75 
76  bool current_line_has_error ();
77  void set_error_on_current_line (bool has_error);
78 
79  /*
80  * This function will return the line number at the beginning of the record. We use this in case we encounter
81  * an error during the insert part of loading the row, since the lexer in this case would have already advanced
82  * to the next record.
83  */
84  int get_driver_lineno ();
85 
86  /*
87  * This function will return the line number at the current position in the record in the object file. We use
88  * this in case we encounter an error during the parsing of the row, and we report the line at which the lexer
89  * is currently situated. This proves useful in case of multi-lines records, using "+" at the end of the line
90  * and will get the current line, instead of the line where the record starts.
91  */
92  int get_scanner_lineno ();
93 
94  private:
95 
96  // Format string based on format string passed as input parameter. Check snprintf function for more details
97  template<typename... Args>
98  static std::string format (const char *fmt, Args &&... args);
99 
100  static char *get_message_from_catalog (MSGCAT_LOADDB_MSG msg_id);
101 
102  void log_error_message (std::string &err_msg, bool fail, bool is_syntax_error = false);
103  bool is_last_error_filtered ();
104 
106 
107 #if defined (SERVER_MODE)
108  session &m_session;
109  bool m_syntax_check;
110 
111  bool is_error_filtered (int err_id);
112 #endif
113  };
114 
115 }
116 
117 /************************************************************************/
118 /* Template implementation */
119 /************************************************************************/
120 
121 namespace cubload
122 {
123 
124  template<typename... Args>
125  void
126  error_handler::on_error (MSGCAT_LOADDB_MSG msg_id, Args &&... args)
127  {
128  std::string err_msg = format (get_message_from_catalog (msg_id), std::forward<Args> (args)...);
129  log_error_message (err_msg, false);
130  }
131 
132  template<typename... Args>
133  void
135  {
136  if (get_driver_lineno () == 0)
137  {
138  // Parsing has not started yet!
139  on_error (msg_id, std::forward<Args> (args)...);
140  return;
141  }
142 
143  on_error_with_line (get_driver_lineno (), msg_id, std::forward<Args> (args)...);
144  }
145 
146  template<typename... Args>
147  void
148  error_handler::on_error_with_line (int lineno, MSGCAT_LOADDB_MSG msg_id, Args &&... args)
149  {
150  std::string err_msg;
151 
152  err_msg.append (format (get_message_from_catalog (LOADDB_MSG_LINE), lineno));
153  err_msg.append (format (get_message_from_catalog (msg_id), std::forward<Args> (args)...));
154 
155  log_error_message (err_msg, false);
156  }
157 
158  template<typename... Args>
159  void
161  {
162  if (!is_last_error_filtered ())
163  {
164  std::string err_msg = format (get_message_from_catalog (msg_id), std::forward<Args> (args)...);
165  log_error_message (err_msg, true);
166  }
167  }
168 
169  template<typename... Args>
170  void
172  {
173  if (!is_last_error_filtered ())
174  {
175  std::string err_msg;
176 
177  if (get_driver_lineno () == 0)
178  {
179  // Parsing has not started yet!
180  on_failure (msg_id, std::forward<Args> (args)...);
181  return;
182  }
183 
185  err_msg.append (format (get_message_from_catalog (msg_id), std::forward<Args> (args)...));
186 
187  log_error_message (err_msg, true);
188  }
189  }
190 
191  template<typename... Args>
192  std::string
193  error_handler::format (const char *fmt, Args &&... args)
194  {
195  // Determine required size
196  int size = snprintf (NULL, 0, fmt, std::forward<Args> (args)...) + 1; // +1 for '\0'
197  std::unique_ptr<char[]> msg (new char[size]);
198 
199  snprintf (msg.get (), (size_t) size, fmt, std::forward<Args> (args)...);
200 
201  return std::string (msg.get (), msg.get () + size - 1);
202  }
203 
204  template<typename... Args>
205  void
207  {
208  std::string err_msg;
209 
211  err_msg.append (format (get_message_from_catalog (LOADDB_MSG_CONVERSION_ERROR), std::forward<Args> (args)...));
212 
213  log_error_message (err_msg, false);
214  }
215 
216  template<typename... Args>
217  std::string
219  {
220  std::string log_msg;
221 
222  log_msg.append (format (get_message_from_catalog (msg_id), std::forward<Args> (args)...));
223  return log_msg;
224  }
225 } // namespace cubload
226 
227 #endif /* _LOAD_ERROR_HANDLER_HPP_ */
void on_syntax_failure(bool use_scanner_line=false)
void log_date_time_conversion_error(Args &&...args)
static std::string format_log_msg(MSGCAT_LOADDB_MSG msg_id, Args &&...args)
static int fail(const char *message)
MSGCAT_LOADDB_MSG
Definition: utility.h:438
static char * get_message_from_catalog(MSGCAT_LOADDB_MSG msg_id)
#define NULL
Definition: freelistheap.h:34
void log_error_message(std::string &err_msg, bool fail, bool is_syntax_error=false)
void on_failure_with_line(MSGCAT_LOADDB_MSG msg_id, Args &&...args)
static std::string format(const char *fmt, Args &&...args)
void set_error_on_current_line(bool has_error)
void on_error_with_line(MSGCAT_LOADDB_MSG msg_id, Args &&...args)
void on_error(MSGCAT_LOADDB_MSG msg_id, Args &&...args)