LCOV - code coverage report
Current view: top level - g10 - sqlite.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 66 95 69.5 %
Date: 2015-11-05 17:10:59 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* sqlite.c - SQLite helper functions.
       2             :  * Copyright (C) 2015 g10 Code GmbH
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * GnuPG is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation; either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * GnuPG is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include <config.h>
      21             : #include <stdarg.h>
      22             : #include <stdlib.h>
      23             : #include <string.h>
      24             : #include <assert.h>
      25             : 
      26             : #include "gpg.h"
      27             : #include "util.h"
      28             : #include "logging.h"
      29             : 
      30             : #include "sqlite.h"
      31             : 
      32             : /* This is a convenience function that combines sqlite3_mprintf and
      33             :    sqlite3_exec.  */
      34             : int
      35          15 : sqlite3_exec_printf (sqlite3 *db,
      36             :                      int (*callback)(void*,int,char**,char**), void *cookie,
      37             :                      char **errmsg,
      38             :                      const char *sql, ...)
      39             : {
      40             :   va_list ap;
      41             :   int rc;
      42             :   char *sql2;
      43             : 
      44          15 :   va_start (ap, sql);
      45          15 :   sql2 = sqlite3_vmprintf (sql, ap);
      46          15 :   va_end (ap);
      47             : 
      48             : #if 0
      49             :   log_debug ("tofo db: executing: '%s'\n", sql2);
      50             : #endif
      51             : 
      52          15 :   rc = sqlite3_exec (db, sql2, callback, cookie, errmsg);
      53             : 
      54          15 :   sqlite3_free (sql2);
      55             : 
      56          15 :   return rc;
      57             : }
      58             : 
      59             : int
      60         351 : sqlite3_stepx (sqlite3 *db,
      61             :                sqlite3_stmt **stmtp,
      62             :                sqlite3_stepx_callback callback,
      63             :                void *cookie,
      64             :                char **errmsg,
      65             :                const char *sql, ...)
      66             : {
      67             :   int rc;
      68         351 :   int err = 0;
      69         351 :   sqlite3_stmt *stmt = NULL;
      70             : 
      71             :   va_list va;
      72             :   int args;
      73             :   enum sqlite_arg_type t;
      74             :   int i;
      75             : 
      76             :   int cols;
      77             :   /* Names of the columns.  We initialize this lazily to avoid the
      78             :      overhead in case the query doesn't return any results.  */
      79         351 :   const char **azColName = 0;
      80         351 :   int callback_initialized = 0;
      81             : 
      82         351 :   const char **azVals = 0;
      83             : 
      84         351 :   callback_initialized = 0;
      85             : 
      86         351 :   if (stmtp && *stmtp)
      87             :     {
      88         182 :       stmt = *stmtp;
      89             : 
      90             :       /* Make sure this statement is associated with the supplied db.  */
      91         182 :       assert (db == sqlite3_db_handle (stmt));
      92             : 
      93             : #if DEBUG_TOFU_CACHE
      94             :       prepares_saved ++;
      95             : #endif
      96             :     }
      97             :   else
      98             :     {
      99         169 :       const char *tail = NULL;
     100             : 
     101         169 :       rc = sqlite3_prepare_v2 (db, sql, -1, &stmt, &tail);
     102         169 :       if (rc)
     103           0 :         log_fatal ("failed to prepare SQL: %s", sql);
     104             : 
     105             :       /* We can only process a single statement.  */
     106         169 :       if (tail)
     107             :         {
     108         338 :           while (*tail == ' ' || *tail == ';' || *tail == '\n')
     109           0 :             tail ++;
     110             : 
     111         169 :           if (*tail)
     112           0 :             log_fatal
     113             :               ("sqlite3_stepx can only process a single SQL statement."
     114             :                "  Second statement starts with: '%s'\n",
     115             :                tail);
     116             :         }
     117             : 
     118         169 :       if (stmtp)
     119         169 :         *stmtp = stmt;
     120             :     }
     121             : 
     122             : #if DEBUG_TOFU_CACHE
     123             :   queries ++;
     124             : #endif
     125             : 
     126         351 :   args = sqlite3_bind_parameter_count (stmt);
     127         351 :   va_start (va, sql);
     128         351 :   if (args)
     129             :     {
     130        1034 :       for (i = 1; i <= args; i ++)
     131             :         {
     132         723 :           t = va_arg (va, enum sqlite_arg_type);
     133         723 :           switch (t)
     134             :             {
     135             :             case SQLITE_ARG_INT:
     136             :               {
     137          14 :                 int value = va_arg (va, int);
     138          14 :                 err = sqlite3_bind_int (stmt, i, value);
     139          14 :                 break;
     140             :               }
     141             :             case SQLITE_ARG_LONG_LONG:
     142             :               {
     143          12 :                 long long value = va_arg (va, long long);
     144          12 :                 err = sqlite3_bind_int64 (stmt, i, value);
     145          12 :                 break;
     146             :               }
     147             :             case SQLITE_ARG_STRING:
     148             :               {
     149         697 :                 char *text = va_arg (va, char *);
     150         697 :                 err = sqlite3_bind_text (stmt, i, text, -1, SQLITE_STATIC);
     151         697 :                 break;
     152             :               }
     153             :             case SQLITE_ARG_BLOB:
     154             :               {
     155           0 :                 char *blob = va_arg (va, void *);
     156           0 :                 long long length = va_arg (va, long long);
     157           0 :                 err = sqlite3_bind_blob (stmt, i, blob, length, SQLITE_STATIC);
     158           0 :                 break;
     159             :               }
     160             :             default:
     161             :               /* Internal error.  Likely corruption.  */
     162           0 :               log_fatal ("Bad value for parameter type %d.\n", t);
     163             :             }
     164             : 
     165         723 :           if (err)
     166             :             {
     167           0 :               log_fatal ("Error binding parameter %d\n", i);
     168             :               goto out;
     169             :             }
     170             :         }
     171             : 
     172             :     }
     173         351 :   t = va_arg (va, enum sqlite_arg_type);
     174         351 :   assert (t == SQLITE_ARG_END);
     175         351 :   va_end (va);
     176             : 
     177             :   for (;;)
     178             :     {
     179         629 :       rc = sqlite3_step (stmt);
     180             : 
     181         629 :       if (rc != SQLITE_ROW)
     182             :         /* No more data (SQLITE_DONE) or an error occured.  */
     183         351 :         break;
     184             : 
     185         278 :       if (! callback)
     186           0 :         continue;
     187             : 
     188         278 :       if (! callback_initialized)
     189             :         {
     190         276 :           cols = sqlite3_column_count (stmt);
     191         276 :           azColName = xmalloc (2 * cols * sizeof (const char *) + 1);
     192             : 
     193         810 :           for (i = 0; i < cols; i ++)
     194         534 :             azColName[i] = sqlite3_column_name (stmt, i);
     195             : 
     196         276 :           callback_initialized = 1;
     197             :         }
     198             : 
     199         278 :       azVals = &azColName[cols];
     200         814 :       for (i = 0; i < cols; i ++)
     201             :         {
     202         536 :           azVals[i] = sqlite3_column_text (stmt, i);
     203         536 :           if (! azVals[i] && sqlite3_column_type (stmt, i) != SQLITE_NULL)
     204             :             /* Out of memory.  */
     205             :             {
     206           0 :               err = SQLITE_NOMEM;
     207           0 :               break;
     208             :             }
     209             :         }
     210             : 
     211         278 :       if (callback (cookie, cols, (char **) azVals, (char **) azColName, stmt))
     212             :         /* A non-zero result means to abort.  */
     213             :         {
     214           0 :           err = SQLITE_ABORT;
     215           0 :           break;
     216             :         }
     217         278 :     }
     218             : 
     219             :  out:
     220         351 :   xfree (azColName);
     221             : 
     222         351 :   if (stmtp)
     223         351 :     rc = sqlite3_reset (stmt);
     224             :   else
     225           0 :     rc = sqlite3_finalize (stmt);
     226         351 :   if (rc == SQLITE_OK && err)
     227             :     /* Local error.  */
     228             :     {
     229           0 :       rc = err;
     230           0 :       if (errmsg)
     231             :         {
     232           0 :           const char *e = sqlite3_errstr (err);
     233           0 :           size_t l = strlen (e) + 1;
     234           0 :           *errmsg = sqlite3_malloc (l);
     235           0 :           if (! *errmsg)
     236           0 :             log_fatal ("Out of memory.\n");
     237           0 :           memcpy (*errmsg, e, l);
     238             :         }
     239             :     }
     240         351 :   else if (rc != SQLITE_OK && errmsg)
     241             :     /* Error reported by sqlite.  */
     242             :     {
     243           0 :       const char * e = sqlite3_errmsg (db);
     244           0 :       size_t l = strlen (e) + 1;
     245           0 :       *errmsg = sqlite3_malloc (l);
     246           0 :       if (! *errmsg)
     247           0 :         log_fatal ("Out of memory.\n");
     248           0 :       memcpy (*errmsg, e, l);
     249             :     }
     250             : 
     251         351 :   return rc;
     252             : }

Generated by: LCOV version 1.11