82
static unsigned char *quotify (const unsigned char *src, size_t srclen,
83
unsigned char *dst, size_t dstlen)
85
static void quotify(const string &src, string &dst)
85
87
static const char hexit[]= { '0', '1', '2', '3', '4', '5', '6', '7',
86
88
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
87
size_t dst_ndx; /* ndx down the dst */
88
size_t src_ndx; /* ndx down the src */
93
for (dst_ndx= 0,src_ndx= 0; src_ndx < srclen; src_ndx++)
89
string::const_iterator src_iter;
91
for (src_iter= src.begin(); src_iter < src.end(); ++src_iter)
96
/* Worst case, need 5 dst bytes for the next src byte.
97
backslash x hexit hexit null
98
so if not enough room, just terminate the string and return
100
if ((dstlen - dst_ndx) < 5)
102
dst[dst_ndx]= (unsigned char)0x00;
106
if (src[src_ndx] > 0x7f)
108
// pass thru high bit characters, they are non-ASCII UTF8 Unicode
109
dst[dst_ndx++]= src[src_ndx];
111
else if (src[src_ndx] == 0x00) // null
113
dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (unsigned char) '0';
115
else if (src[src_ndx] == 0x07) // bell
117
dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (unsigned char) 'a';
119
else if (src[src_ndx] == 0x08) // backspace
121
dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (unsigned char) 'b';
123
else if (src[src_ndx] == 0x09) // horiz tab
125
dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (unsigned char) 't';
127
else if (src[src_ndx] == 0x0a) // line feed
129
dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (unsigned char) 'n';
131
else if (src[src_ndx] == 0x0b) // vert tab
133
dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (unsigned char) 'v';
135
else if (src[src_ndx] == 0x0c) // formfeed
137
dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (unsigned char) 'f';
139
else if (src[src_ndx] == 0x0d) // carrage return
141
dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (unsigned char) 'r';
143
else if (src[src_ndx] == 0x1b) // escape
145
dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (unsigned char) 'e';
147
else if (src[src_ndx] == 0x22) // quotation mark
149
dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= 0x22;
151
else if (src[src_ndx] == 0x2C) // comma
153
dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= 0x2C;
155
else if (src[src_ndx] == 0x5C) // backslash
157
dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= 0x5C;
159
else if ((src[src_ndx] < 0x20) || (src[src_ndx] == 0x7F)) // other unprintable ASCII
161
dst[dst_ndx++]= 0x5C;
162
dst[dst_ndx++]= (unsigned char) 'x';
163
dst[dst_ndx++]= hexit[(src[src_ndx] >> 4) & 0x0f];
164
dst[dst_ndx++]= hexit[src[src_ndx] & 0x0f];
93
if (static_cast<unsigned char>(*src_iter) > 0x7f)
95
dst.push_back(*src_iter);
97
else if (*src_iter == 0x00) // null
99
dst.push_back(ESCAPE_CHAR); dst.push_back('0');
101
else if (*src_iter == 0x07) // bell
103
dst.push_back(ESCAPE_CHAR); dst.push_back('a');
105
else if (*src_iter == 0x08) // backspace
107
dst.push_back(ESCAPE_CHAR); dst.push_back('b');
109
else if (*src_iter == 0x09) // horiz tab
111
dst.push_back(ESCAPE_CHAR); dst.push_back('t');
113
else if (*src_iter == 0x0a) // line feed
115
dst.push_back(ESCAPE_CHAR); dst.push_back('n');
117
else if (*src_iter == 0x0b) // vert tab
119
dst.push_back(ESCAPE_CHAR); dst.push_back('v');
121
else if (*src_iter == 0x0c) // formfeed
123
dst.push_back(ESCAPE_CHAR); dst.push_back('f');
125
else if (*src_iter == 0x0d) // carrage return
127
dst.push_back(ESCAPE_CHAR); dst.push_back('r');
129
else if (*src_iter == 0x1b) // escape
131
dst.push_back(ESCAPE_CHAR); dst.push_back('e');
133
else if (*src_iter == 0x22) // quotation mark
135
dst.push_back(ESCAPE_CHAR); dst.push_back(0x22);
137
else if (*src_iter == SEPARATOR_CHAR)
139
dst.push_back(ESCAPE_CHAR); dst.push_back(SEPARATOR_CHAR);
141
else if (*src_iter == ESCAPE_CHAR)
143
dst.push_back(ESCAPE_CHAR); dst.push_back(ESCAPE_CHAR);
145
else if ((*src_iter < 0x20) || (*src_iter == 0x7F)) // other unprintable ASCII
147
dst.push_back(ESCAPE_CHAR);
149
dst.push_back(hexit[(*src_iter >> 4) & 0x0f]);
150
dst.push_back(hexit[*src_iter & 0x0f]);
166
152
else // everything else
168
dst[dst_ndx++]= src[src_ndx];
154
dst.push_back(*src_iter);
166
/** Format of the output string */
167
boost::format formatter;
185
172
: drizzled::plugin::Logging("Logging_query"),
186
fd(-1), re(NULL), pe(NULL)
173
fd(-1), re(NULL), pe(NULL),
174
formatter("%1%,%2%,%3%,\"%4%\",\"%5%\",\"%6%\",%7%,%8%,"
175
"%9%,%10%,%11%,%12%,%13%,%14%,\"%15%\"\n")
189
178
/* if there is no destination filename, dont bother doing anything */
279
257
int this_pcre_rc;
280
this_pcre_rc = pcre_exec(re, pe, session->query.c_str(), session->query.length(), 0, 0, NULL, 0);
258
this_pcre_rc= pcre_exec(re, pe, session->query.c_str(), session->query.length(), 0, 0, NULL, 0);
281
259
if (this_pcre_rc < 0)
285
263
// buffer to quotify the query
286
unsigned char qs[255];
266
// Since quotify() builds the quoted string incrementally, we can
267
// avoid some reallocating if we reserve some space up front.
268
qs.reserve(session->getQueryLength());
270
quotify(session->getQueryString(), qs);
288
272
// to avoid trying to printf %s something that is potentially NULL
289
273
const char *dbs= session->db.empty() ? "" : session->db.c_str();
292
snprintf(msgbuf, MAX_MSG_LEN,
293
"%"PRIu64",%"PRIu64",%"PRIu64",\"%.*s\",\"%s\",\"%.*s\","
294
"%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64","
295
"%"PRIu32",%"PRIu32",%"PRIu32",\"%s\"\n",
298
session->getQueryId(),
299
// dont need to quote the db name, always CSV safe
300
(int)session->db.length(), dbs,
301
// do need to quote the query
302
quotify((unsigned char *)session->getQueryString().c_str(),
303
session->getQueryLength(), qs, sizeof(qs)),
304
// command_name is defined in drizzled/sql_parse.cc
305
// dont need to quote the command name, always CSV safe
306
(int)command_name[session->command].length,
307
command_name[session->command].str,
308
// counters are at end, to make it easier to add more
309
(t_mark - session->getConnectMicroseconds()),
310
(t_mark - session->start_utime),
311
(t_mark - session->utime_after_lock),
312
session->sent_row_count,
313
session->examined_row_count,
315
session->total_warn_count,
316
session->getServerId(),
277
% session->getQueryId()
280
% command_name[session->command].str
281
% (t_mark - session->getConnectMicroseconds())
282
% (t_mark - session->start_utime)
283
% (t_mark - session->utime_after_lock)
284
% session->sent_row_count
285
% session->examined_row_count
287
% session->total_warn_count
288
% session->getServerId()
291
string msgbuf= formatter.str();
320
293
// a single write has a kernel thread lock, thus no need mutex guard this
321
wrv= write(fd, msgbuf, msgbuf_len);
322
assert(wrv == msgbuf_len);
294
wrv= write(fd, msgbuf.c_str(), msgbuf.length());
295
assert(wrv == msgbuf.length());