OpenVAS Manager  7.0.3~git
sql.c
Go to the documentation of this file.
1 /* OpenVAS Manager
2  * $Id$
3  * Description: Manager Manage library: the SQL library.
4  *
5  * Authors:
6  * Matthew Mundell <matthew.mundell@greenbone.net>
7  *
8  * Copyright:
9  * Copyright (C) 2009,2010,2012 Greenbone Networks GmbH
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
26 #include "sql.h"
27 
28 #include <assert.h>
29 #include <errno.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #undef G_LOG_DOMAIN
34 
37 #define G_LOG_DOMAIN "md manage"
38 
39 
40 /* Headers of internal symbols defined in backend files. */
41 
42 int
43 sql_prepare_internal (int, int, const char*, va_list, sql_stmt_t **);
44 
45 int
47 
48 int
49 sql_explain_internal (const char*, va_list);
50 
51 int
52 sql_explain (const char*, ...);
53 
54 
55 /* Variables. */
56 
62 int log_errors = 1;
63 
64 
65 /* Helpers. */
66 
75 gchar*
76 sql_nquote (const char* string, size_t length)
77 {
78  gchar *new, *new_start;
79  const gchar *start, *end;
80  int count = 0;
81 
82  assert (string);
83 
84  /* Count number of apostrophes. */
85 
86  start = string;
87  while ((start = strchr (start, '\''))) start++, count++;
88 
89  /* Allocate new string. */
90 
91  new = new_start = g_malloc0 (length + count + 1);
92 
93  /* Copy string, replacing apostrophes with double apostrophes. */
94 
95  start = string;
96  end = string + length;
97  for (; start < end; start++, new++)
98  {
99  char ch = *start;
100  if (ch == '\'')
101  {
102  *new = '\'';
103  new++;
104  *new = '\'';
105  }
106  else
107  *new = ch;
108  }
109 
110  return new_start;
111 }
112 
120 gchar*
121 sql_quote (const char* string)
122 {
123  assert (string);
124  return sql_nquote (string, strlen (string));
125 }
126 
135 gchar *
136 sql_insert (const char *string)
137 {
138  if (string)
139  {
140  gchar *quoted_value = sql_quote (string);
141  gchar *insert = g_strdup_printf ("'%s'", quoted_value);
142  g_free (quoted_value);
143  return insert;
144  }
145  return g_strdup ("NULL");
146 }
147 
157 int
158 sqlv (int retry, char* sql, va_list args)
159 {
160  while (1)
161  {
162  int ret;
163  sql_stmt_t* stmt;
164  va_list args_copy;
165 
166  /* Prepare statement.
167  * Copy args for this because a va_list can only be used once.
168  */
169  va_copy (args_copy, args);
170  ret = sql_prepare_internal (retry, 1, sql, args_copy, &stmt);
171  va_end (args_copy);
172  if (ret == -1)
173  g_warning ("%s: sql_prepare_internal failed\n", __FUNCTION__);
174  if (ret)
175  return ret;
176 
177  /* Run statement. */
178 
179  while ((ret = sql_exec_internal (retry, stmt)) == 1);
180  if ((ret == -1) && log_errors)
181  g_warning ("%s: sql_exec_internal failed\n", __FUNCTION__);
182  sql_finalize (stmt);
183  if (ret == 2)
184  continue;
185  if (ret == -2)
186  return 1;
187  assert (ret == -1 || ret == 0);
188  return ret;
189  }
190 }
191 
198 void
199 sql (char* sql, ...)
200 {
201  while (1)
202  {
203  va_list args;
204  int ret;
205 
206  va_start (args, sql);
207  ret = sqlv (1, sql, args);
208  va_end (args);
209  if (ret == -1)
210  abort ();
211  if (ret == 1)
212  /* Gave up with statement reset. */
213  continue;
214  break;
215  }
216 }
217 
228 int
229 sql_error (char* sql, ...)
230 {
231  int ret;
232 
233  while (1)
234  {
235  va_list args;
236  va_start (args, sql);
237  ret = sqlv (1, sql, args);
238  va_end (args);
239  if (ret == 1)
240  /* Gave up with statement reset. */
241  continue;
242  break;
243  }
244 
245  return ret;
246 }
247 
256 int
257 sql_giveup (char* sql, ...)
258 {
259  int ret;
260  va_list args;
261 
262  va_start (args, sql);
263  ret = sqlv (0, sql, args);
264  va_end (args);
265  return ret;
266 }
267 
274 void
275 sql_quiet (char* sql, ...)
276 {
277  int ret;
278  sql_stmt_t *stmt;
279  va_list args;
280 
281  /* Prepare statement. */
282 
283  while (1)
284  {
285  va_start (args, sql);
286  ret = sql_prepare_internal (1, 0, sql, args, &stmt);
287  va_end (args);
288  if (ret)
289  {
290  g_warning ("%s: sql_prepare failed\n", __FUNCTION__);
291  abort ();
292  }
293 
294  /* Run statement. */
295 
296  while ((ret = sql_exec_internal (1, stmt)) == 1);
297  if (ret == -1)
298  {
299  if (log_errors)
300  g_warning ("%s: sql_exec_internal failed\n", __FUNCTION__);
301  abort ();
302  }
303  if (ret == -2 || ret == 2)
304  {
305  /* Busy or locked, with statement reset. Or schema changed. */
306  sql_finalize (stmt);
307  continue;
308  }
309  break;
310  }
311  sql_finalize (stmt);
312 }
313 
324 static int
325 sql_x_internal (int log, char* sql, va_list args, sql_stmt_t** stmt_return)
326 {
327  int ret;
328 
329  assert (stmt_return);
330 
331  while (1)
332  {
333  /* Prepare statement.
334  * Copy args for this because a va_list can only be used once.
335  */
336  va_list args_copy;
337  va_copy (args_copy, args);
338  ret = sql_prepare_internal (1, log, sql, args_copy, stmt_return);
339  va_end (args_copy);
340 
341  if (ret)
342  {
343  g_warning ("%s: sql_prepare failed\n", __FUNCTION__);
344  return -1;
345  }
346 
347  /* Run statement. */
348 
349  ret = sql_exec_internal (1, *stmt_return);
350  if (ret == -1)
351  {
352  if (log_errors)
353  g_warning ("%s: sql_exec_internal failed\n", __FUNCTION__);
354  return -1;
355  }
356  if (ret == 0)
357  /* Too few rows. */
358  return 1;
359  if (ret == -2 || ret == 2)
360  {
361  /* Busy or locked, with statement reset. Or schema changed. */
362  sql_finalize (*stmt_return);
363  continue;
364  }
365  break;
366  }
367  assert (ret == 1);
368  if (log)
369  g_debug (" sql_x end (%s)\n", sql);
370  return 0;
371 }
372 
384 int
385 sql_x (char* sql, va_list args, sql_stmt_t** stmt_return)
386 {
387  return sql_x_internal (1, sql, args, stmt_return);
388 }
389 
403 double
404 sql_double (char* sql, ...)
405 {
406  sql_stmt_t* stmt;
407  va_list args;
408  double ret;
409 
410  int sql_x_ret;
411  va_start (args, sql);
412  sql_x_ret = sql_x (sql, args, &stmt);
413  va_end (args);
414  if (sql_x_ret)
415  {
416  sql_finalize (stmt);
417  abort ();
418  }
419  ret = sql_column_double (stmt, 0);
420  sql_finalize (stmt);
421  return ret;
422 }
423 
437 int
438 sql_int (char* sql, ...)
439 {
440  sql_stmt_t* stmt;
441  va_list args;
442  int ret;
443 
444  int sql_x_ret;
445  va_start (args, sql);
446  sql_x_ret = sql_x (sql, args, &stmt);
447  va_end (args);
448  if (sql_x_ret)
449  {
450  sql_finalize (stmt);
451  abort ();
452  }
453  ret = sql_column_int (stmt, 0);
454  sql_finalize (stmt);
455  return ret;
456 }
457 
468 char*
469 sql_string (char* sql, ...)
470 {
471  sql_stmt_t* stmt;
472  const char* ret2;
473  char* ret;
474  int sql_x_ret;
475 
476  va_list args;
477  va_start (args, sql);
478  sql_x_ret = sql_x (sql, args, &stmt);
479  va_end (args);
480  if (sql_x_ret)
481  {
482  sql_finalize (stmt);
483  return NULL;
484  }
485  ret2 = sql_column_text (stmt, 0);
486  ret = g_strdup (ret2);
487  sql_finalize (stmt);
488  return ret;
489 }
490 
500 int
501 sql_int64 (long long int* ret, char* sql, ...)
502 {
503  sql_stmt_t* stmt;
504  int sql_x_ret;
505  va_list args;
506 
507  va_start (args, sql);
508  sql_x_ret = sql_x (sql, args, &stmt);
509  va_end (args);
510  switch (sql_x_ret)
511  {
512  case 0:
513  break;
514  case 1:
515  sql_finalize (stmt);
516  return 1;
517  break;
518  default:
519  assert (0);
520  /* Fall through. */
521  case -1:
522  sql_finalize (stmt);
523  return -1;
524  break;
525  }
526  *ret = sql_column_int64 (stmt, 0);
527  sql_finalize (stmt);
528  return 0;
529 }
530 
539 int
540 sql_explain (const char *sql, ...)
541 {
542  int ret;
543  va_list args;
544  va_start (args, sql);
545  ret = sql_explain_internal (sql, args);
546  va_end (args);
547 
548  return ret;
549 }
550 
551 
552 /* Iterators. */
553 
560 void
562 {
563  iterator->done = FALSE;
564  iterator->stmt = stmt;
565  iterator->prepared = 1;
566  iterator->crypt_ctx = NULL;
567  g_debug (" sql: init prepared %p\n", stmt);
568 }
569 
576 void
577 init_iterator (iterator_t* iterator, const char* sql, ...)
578 {
579  int ret;
580  sql_stmt_t* stmt;
581  va_list args;
582 
583  iterator->done = FALSE;
584  iterator->prepared = 0;
585  iterator->crypt_ctx = NULL;
586 
587  va_start (args, sql);
588  ret = sql_prepare_internal (1, 1, sql, args, &stmt);
589  va_end (args);
590  if (ret)
591  {
592  g_warning ("%s: sql_prepare failed\n", __FUNCTION__);
593  abort ();
594  }
595  iterator->stmt = stmt;
596 }
597 
606 double
608 {
609  if (iterator->done) abort ();
610  return sql_column_double (iterator->stmt, col);
611 }
612 
621 int
623 {
624  if (iterator->done) abort ();
625  return sql_column_int (iterator->stmt, col);
626 }
627 
636 long long int
638 {
639  if (iterator->done) abort ();
640  return sql_column_int64 (iterator->stmt, col);
641 }
642 
651 const char*
653 {
654  if (iterator->done) abort ();
655  return sql_column_text (iterator->stmt, col);
656 }
657 
663 void
665 {
666  if (iterator == NULL)
667  {
668  g_warning ("%s: null iterator pointer.\n", __FUNCTION__);
669  return;
670  }
671 
672  if (iterator->prepared == 0)
674  if (iterator->crypt_ctx)
675  {
677  iterator->crypt_ctx = NULL;
678  }
679 }
680 
688 gboolean
690 {
691  int ret;
692 
693  if (iterator->done) return FALSE;
694 
696  while (1)
697  {
698  ret = sql_exec_internal (1, iterator->stmt);
699  if (ret == 0)
700  {
701  iterator->done = TRUE;
702  return FALSE;
703  }
704  if (ret == -1)
705  {
706  if (log_errors)
707  g_warning ("%s: sql_exec_internal failed\n", __FUNCTION__);
708  abort ();
709  }
710  if (ret == -2)
711  {
712  /* Busy or locked, with statement reset. Just try step again like
713  * we used to do in sql_exec_internal. We're not supposed to do this
714  * for SQLite, but it would mean quite a bit of reworking in the
715  * callers to be able to handle this case. */
716  g_warning ("%s: stepping after reset\n", __FUNCTION__);
717  continue;
718  }
719  if (ret == 2)
720  {
721  /* Schema changed, for example an internal change due to a VACUUM.
722  * Retrying will result in the same error, so abort. We lock
723  * exclusively around the VACUUM in --optimize, so hopefully when
724  * using --optimize the schema error will happen earlier, in the
725  * the init function for the iterator.
726  *
727  * This only applies to SQLite3. */
728  g_warning ("%s: schema error.\n"
729  " This is possibly due to running VACUUM while Manager\n"
730  " is running. Restart Manager. In future use\n"
731  " --optimize=vacuum instead of running VACUUM"
732  " directly.\n",
733  __FUNCTION__);
734  abort ();
735  }
736  break;
737  }
738  assert (ret == 1);
739  return TRUE;
740 }
741 
742 
743 /* Prepared statements. */
744 
752 sql_stmt_t *
753 sql_prepare (const char* sql, ...)
754 {
755  int ret;
756  sql_stmt_t* stmt;
757  va_list args;
758 
759  va_start (args, sql);
760  ret = sql_prepare_internal (1, 1, sql, args, &stmt);
761  va_end (args);
762  if (ret)
763  return NULL;
764  return stmt;
765 }
766 
775 int
777 {
778  return sql_exec_internal (1, stmt);
779 }
double iterator_double(iterator_t *iterator, int col)
Get a double column from an iterator.
Definition: sql.c:607
int sql_prepare_internal(int, int, const char *, va_list, sql_stmt_t **)
Prepare a statement.
Definition: sql_pg.c:458
int sql_int(char *sql,...)
Get a particular cell from a SQL query, as an int.
Definition: sql.c:438
double sql_column_double(sql_stmt_t *, int)
Return a column as a double from a prepared statement.
Definition: sql_pg.c:868
int iterator_int(iterator_t *iterator, int col)
Get a int column from an iterator.
Definition: sql.c:622
int sql_explain_internal(const char *, va_list)
Write debug messages with the query plan for an SQL query to the log.
Definition: sql_pg.c:551
int sql_giveup(char *sql,...)
Perform an SQL statement, giving up if database is busy or locked.
Definition: sql.c:257
void sql_quiet(char *sql,...)
Perform an SQL statement, without logging.
Definition: sql.c:275
A generic SQL iterator.
Definition: iterator.h:52
int log_errors
Whether to log errors.
Definition: sql.c:62
void sql(char *sql,...)
Perform an SQL statement, retrying if database is busy or locked.
Definition: sql.c:199
lsc_crypt_ctx_t crypt_ctx
Encryption context.
Definition: iterator.h:57
gboolean done
End flag.
Definition: iterator.h:55
int sql_int64(long long int *ret, char *sql,...)
Get a particular cell from a SQL query, as an int64.
Definition: sql.c:501
int sql_exec(sql_stmt_t *stmt)
Execute a prepared statement.
Definition: sql.c:776
long long int sql_column_int64(sql_stmt_t *, int)
Return a column as an int64 from a prepared statement.
Definition: sql_pg.c:936
int sql_column_int(sql_stmt_t *, int)
Return a column as an integer from a prepared statement.
Definition: sql_pg.c:906
gchar * sql_quote(const char *string)
Quotes a string to be passed to sql statements.
Definition: sql.c:121
int sql_exec_internal(int, sql_stmt_t *)
Execute a prepared statement.
Definition: sql_pg.c:482
double sql_double(char *sql,...)
Get the first value from a SQL query, as a double.
Definition: sql.c:404
int sqlv(int retry, char *sql, va_list args)
Perform an SQL statement.
Definition: sql.c:158
void lsc_crypt_flush(lsc_crypt_ctx_t ctx)
Flush an LSC encryption context.
Definition: lsc_crypt.c:586
const char * sql_column_text(sql_stmt_t *, int)
Return a column as text from a prepared statement.
Definition: sql_pg.c:887
sql_stmt_t * stmt
SQL statement.
Definition: iterator.h:54
void init_prepared_iterator(iterator_t *iterator, sql_stmt_t *stmt)
Initialise an iterator.
Definition: sql.c:561
int prepared
Prepared flag.
Definition: iterator.h:56
int sql_error(char *sql,...)
Perform an SQL statement, retrying if database is busy or locked.
Definition: sql.c:229
const char * iterator_string(iterator_t *iterator, int col)
Get a string column from an iterator.
Definition: sql.c:652
sql_stmt_t * sql_prepare(const char *sql,...)
Prepare a statement.
Definition: sql.c:753
void cleanup_iterator(iterator_t *iterator)
Cleanup an iterator.
Definition: sql.c:664
char * sql_string(char *sql,...)
Get a particular cell from a SQL query, as an string.
Definition: sql.c:469
gboolean next(iterator_t *iterator)
Increment an iterator.
Definition: sql.c:689
gchar * sql_insert(const char *string)
Get the SQL insert expression for a string.
Definition: sql.c:136
int sql_explain(const char *,...)
Write debug messages with the query plan for an SQL query to the log.
Definition: sql.c:540
void lsc_crypt_release(lsc_crypt_ctx_t ctx)
Release an LSC encryption context.
Definition: lsc_crypt.c:528
void init_iterator(iterator_t *iterator, const char *sql,...)
Initialise an iterator.
Definition: sql.c:577
int sql_x(char *sql, va_list args, sql_stmt_t **stmt_return)
Get a particular cell from a SQL query.
Definition: sql.c:385
gchar * sql_nquote(const char *string, size_t length)
Quotes a string of a known length to be passed to sql statements.
Definition: sql.c:76
long long int iterator_int64(iterator_t *iterator, int col)
Get an integer column from an iterator.
Definition: sql.c:637
void sql_finalize(sql_stmt_t *)
Free a prepared statement.
Definition: sql_pg.c:824