MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_bootstrap.cc
1 /* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 
17 #include <stdlib.h>
18 #include <errno.h>
19 #include <ctype.h>
20 #include <string.h>
21 #include "sql_bootstrap.h"
22 
23 int read_bootstrap_query(char *query, int *query_length,
24  fgets_input_t input, fgets_fn_t fgets_fn, int *error)
25 {
26  char line_buffer[MAX_BOOTSTRAP_LINE_SIZE];
27  const char *line;
28  int len;
29  int query_len= 0;
30  int fgets_error= 0;
31  *error= 0;
32 
33  for ( ; ; )
34  {
35  line= (*fgets_fn)(line_buffer, sizeof(line_buffer), input, &fgets_error);
36 
37  if (error)
38  *error= fgets_error;
39 
40  if (fgets_error != 0)
41  return READ_BOOTSTRAP_ERROR;
42 
43  if (line == NULL)
44  return (query_len == 0) ? READ_BOOTSTRAP_EOF : READ_BOOTSTRAP_ERROR;
45 
46  len= strlen(line);
47 
48  /*
49  Remove trailing whitespace characters.
50  This assumes:
51  - no multibyte encoded character can be found at the very end of a line,
52  - whitespace characters from the "C" locale only.
53  which is sufficient for the kind of queries found
54  in the bootstrap scripts.
55  */
56  while (len && (isspace(line[len - 1])))
57  len--;
58  /*
59  Cleanly end the string, so we don't have to test len > x
60  all the time before reading line[x], in the code below.
61  */
62  line_buffer[len]= '\0';
63 
64  /* Skip blank lines */
65  if (len == 0)
66  continue;
67 
68  /* Skip # comments */
69  if (line[0] == '#')
70  continue;
71 
72  /* Skip -- comments */
73  if ((line[0] == '-') && (line[1] == '-'))
74  continue;
75 
76  /* Skip delimiter, ignored. */
77  if (strncmp(line, "delimiter", 9) == 0)
78  continue;
79 
80  /* Append the current line to a multi line query. If the new line will make
81  the query too long, preserve the partial line to provide context for the
82  error message.
83  */
84  if (query_len + len + 1 >= MAX_BOOTSTRAP_QUERY_SIZE)
85  {
86  int new_len= MAX_BOOTSTRAP_QUERY_SIZE - query_len - 1;
87  if ((new_len > 0) && (query_len < MAX_BOOTSTRAP_QUERY_SIZE))
88  {
89  memcpy(query + query_len, line, new_len);
90  query_len+= new_len;
91  }
92  query[query_len]= '\0';
93  *query_length= query_len;
94  return READ_BOOTSTRAP_QUERY_SIZE;
95  }
96 
97  if (query_len != 0)
98  {
99  /*
100  Append a \n to the current line, if any,
101  to preserve the intended presentation.
102  */
103  query[query_len++]= '\n';
104  }
105  memcpy(query + query_len, line, len);
106  query_len+= len;
107 
108  if (line[len - 1] == ';')
109  {
110  /*
111  The last line is terminated by ';'.
112  Return the query found.
113  */
114  query[query_len]= '\0';
115  *query_length= query_len;
116  return READ_BOOTSTRAP_SUCCESS;
117  }
118  }
119 }
120