extensions/sqlite/sqlite-source/table.c
author Asher Baker <asherkin@gmail.com>
Thu Apr 26 16:58:18 2012 +0100 (2012-04-26)
changeset 3488 bee90c8ef6c3
parent 1952 b7aa2b626807
permissions -rw-r--r--
Fixed client serials not being unique on Windows (bug 5285, r=psychonic).
ds@1952
     1
/*
ds@1952
     2
** 2001 September 15
ds@1952
     3
**
ds@1952
     4
** The author disclaims copyright to this source code.  In place of
ds@1952
     5
** a legal notice, here is a blessing:
ds@1952
     6
**
ds@1952
     7
**    May you do good and not evil.
ds@1952
     8
**    May you find forgiveness for yourself and forgive others.
ds@1952
     9
**    May you share freely, never taking more than you give.
ds@1952
    10
**
ds@1952
    11
*************************************************************************
ds@1952
    12
** This file contains the sqlite3_get_table() and sqlite3_free_table()
ds@1952
    13
** interface routines.  These are just wrappers around the main
ds@1952
    14
** interface routine of sqlite3_exec().
ds@1952
    15
**
ds@1952
    16
** These routines are in a separate files so that they will not be linked
ds@1952
    17
** if they are not used.
ds@1952
    18
*/
ds@1952
    19
#include "sqliteInt.h"
ds@1952
    20
#include <stdlib.h>
ds@1952
    21
#include <string.h>
ds@1952
    22
ds@1952
    23
#ifndef SQLITE_OMIT_GET_TABLE
ds@1952
    24
ds@1952
    25
/*
ds@1952
    26
** This structure is used to pass data from sqlite3_get_table() through
ds@1952
    27
** to the callback function is uses to build the result.
ds@1952
    28
*/
ds@1952
    29
typedef struct TabResult {
ds@1952
    30
  char **azResult;
ds@1952
    31
  char *zErrMsg;
ds@1952
    32
  int nResult;
ds@1952
    33
  int nAlloc;
ds@1952
    34
  int nRow;
ds@1952
    35
  int nColumn;
ds@1952
    36
  int nData;
ds@1952
    37
  int rc;
ds@1952
    38
} TabResult;
ds@1952
    39
ds@1952
    40
/*
ds@1952
    41
** This routine is called once for each row in the result table.  Its job
ds@1952
    42
** is to fill in the TabResult structure appropriately, allocating new
ds@1952
    43
** memory as necessary.
ds@1952
    44
*/
ds@1952
    45
static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
ds@1952
    46
  TabResult *p = (TabResult*)pArg;
ds@1952
    47
  int need;
ds@1952
    48
  int i;
ds@1952
    49
  char *z;
ds@1952
    50
ds@1952
    51
  /* Make sure there is enough space in p->azResult to hold everything
ds@1952
    52
  ** we need to remember from this invocation of the callback.
ds@1952
    53
  */
ds@1952
    54
  if( p->nRow==0 && argv!=0 ){
ds@1952
    55
    need = nCol*2;
ds@1952
    56
  }else{
ds@1952
    57
    need = nCol;
ds@1952
    58
  }
ds@1952
    59
  if( p->nData + need >= p->nAlloc ){
ds@1952
    60
    char **azNew;
ds@1952
    61
    p->nAlloc = p->nAlloc*2 + need + 1;
ds@1952
    62
    azNew = sqlite3_realloc( p->azResult, sizeof(char*)*p->nAlloc );
ds@1952
    63
    if( azNew==0 ) goto malloc_failed;
ds@1952
    64
    p->azResult = azNew;
ds@1952
    65
  }
ds@1952
    66
ds@1952
    67
  /* If this is the first row, then generate an extra row containing
ds@1952
    68
  ** the names of all columns.
ds@1952
    69
  */
ds@1952
    70
  if( p->nRow==0 ){
ds@1952
    71
    p->nColumn = nCol;
ds@1952
    72
    for(i=0; i<nCol; i++){
ds@1952
    73
      if( colv[i]==0 ){
ds@1952
    74
        z = sqlite3_mprintf("");
ds@1952
    75
      }else{
ds@1952
    76
        z = sqlite3_mprintf("%s", colv[i]);
ds@1952
    77
      }
ds@1952
    78
      p->azResult[p->nData++] = z;
ds@1952
    79
    }
ds@1952
    80
  }else if( p->nColumn!=nCol ){
ds@1952
    81
    sqlite3SetString(&p->zErrMsg,
ds@1952
    82
       "sqlite3_get_table() called with two or more incompatible queries",
ds@1952
    83
       (char*)0);
ds@1952
    84
    p->rc = SQLITE_ERROR;
ds@1952
    85
    return 1;
ds@1952
    86
  }
ds@1952
    87
ds@1952
    88
  /* Copy over the row data
ds@1952
    89
  */
ds@1952
    90
  if( argv!=0 ){
ds@1952
    91
    for(i=0; i<nCol; i++){
ds@1952
    92
      if( argv[i]==0 ){
ds@1952
    93
        z = 0;
ds@1952
    94
      }else{
ds@1952
    95
        int n = strlen(argv[i])+1;
ds@1952
    96
        z = sqlite3_malloc( n );
ds@1952
    97
        if( z==0 ) goto malloc_failed;
ds@1952
    98
        memcpy(z, argv[i], n);
ds@1952
    99
      }
ds@1952
   100
      p->azResult[p->nData++] = z;
ds@1952
   101
    }
ds@1952
   102
    p->nRow++;
ds@1952
   103
  }
ds@1952
   104
  return 0;
ds@1952
   105
ds@1952
   106
malloc_failed:
ds@1952
   107
  p->rc = SQLITE_NOMEM;
ds@1952
   108
  return 1;
ds@1952
   109
}
ds@1952
   110
ds@1952
   111
/*
ds@1952
   112
** Query the database.  But instead of invoking a callback for each row,
ds@1952
   113
** malloc() for space to hold the result and return the entire results
ds@1952
   114
** at the conclusion of the call.
ds@1952
   115
**
ds@1952
   116
** The result that is written to ***pazResult is held in memory obtained
ds@1952
   117
** from malloc().  But the caller cannot free this memory directly.  
ds@1952
   118
** Instead, the entire table should be passed to sqlite3_free_table() when
ds@1952
   119
** the calling procedure is finished using it.
ds@1952
   120
*/
ds@1952
   121
int sqlite3_get_table(
ds@1952
   122
  sqlite3 *db,                /* The database on which the SQL executes */
ds@1952
   123
  const char *zSql,           /* The SQL to be executed */
ds@1952
   124
  char ***pazResult,          /* Write the result table here */
ds@1952
   125
  int *pnRow,                 /* Write the number of rows in the result here */
ds@1952
   126
  int *pnColumn,              /* Write the number of columns of result here */
ds@1952
   127
  char **pzErrMsg             /* Write error messages here */
ds@1952
   128
){
ds@1952
   129
  int rc;
ds@1952
   130
  TabResult res;
ds@1952
   131
  if( pazResult==0 ){ return SQLITE_ERROR; }
ds@1952
   132
  *pazResult = 0;
ds@1952
   133
  if( pnColumn ) *pnColumn = 0;
ds@1952
   134
  if( pnRow ) *pnRow = 0;
ds@1952
   135
  res.zErrMsg = 0;
ds@1952
   136
  res.nResult = 0;
ds@1952
   137
  res.nRow = 0;
ds@1952
   138
  res.nColumn = 0;
ds@1952
   139
  res.nData = 1;
ds@1952
   140
  res.nAlloc = 20;
ds@1952
   141
  res.rc = SQLITE_OK;
ds@1952
   142
  res.azResult = sqlite3_malloc( sizeof(char*)*res.nAlloc );
ds@1952
   143
  if( res.azResult==0 ) return SQLITE_NOMEM;
ds@1952
   144
  res.azResult[0] = 0;
ds@1952
   145
  rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
ds@1952
   146
#ifndef NDEBUG
ds@1952
   147
  sqlite3_mutex_enter(db->mutex);
ds@1952
   148
  assert((rc&db->errMask)==rc && (res.rc&db->errMask)==res.rc);
ds@1952
   149
  sqlite3_mutex_leave(db->mutex);
ds@1952
   150
#endif
ds@1952
   151
  if( res.azResult ){
ds@1952
   152
    assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
ds@1952
   153
    res.azResult[0] = (char*)res.nData;
ds@1952
   154
  }
ds@1952
   155
  if( (rc&0xff)==SQLITE_ABORT ){
ds@1952
   156
    sqlite3_free_table(&res.azResult[1]);
ds@1952
   157
    if( res.zErrMsg ){
ds@1952
   158
      if( pzErrMsg ){
ds@1952
   159
        sqlite3_free(*pzErrMsg);
ds@1952
   160
        *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg);
ds@1952
   161
      }
ds@1952
   162
      sqlite3_free(res.zErrMsg);
ds@1952
   163
    }
ds@1952
   164
    sqlite3_mutex_enter(db->mutex);
ds@1952
   165
    db->errCode = res.rc;
ds@1952
   166
    sqlite3_mutex_leave(db->mutex);
ds@1952
   167
    return res.rc;
ds@1952
   168
  }
ds@1952
   169
  sqlite3_free(res.zErrMsg);
ds@1952
   170
  if( rc!=SQLITE_OK ){
ds@1952
   171
    sqlite3_free_table(&res.azResult[1]);
ds@1952
   172
    return rc;
ds@1952
   173
  }
ds@1952
   174
  if( res.nAlloc>res.nData ){
ds@1952
   175
    char **azNew;
ds@1952
   176
    azNew = sqlite3_realloc( res.azResult, sizeof(char*)*(res.nData+1) );
ds@1952
   177
    if( azNew==0 ){
ds@1952
   178
      sqlite3_free_table(&res.azResult[1]);
ds@1952
   179
      return SQLITE_NOMEM;
ds@1952
   180
    }
ds@1952
   181
    res.nAlloc = res.nData+1;
ds@1952
   182
    res.azResult = azNew;
ds@1952
   183
  }
ds@1952
   184
  *pazResult = &res.azResult[1];
ds@1952
   185
  if( pnColumn ) *pnColumn = res.nColumn;
ds@1952
   186
  if( pnRow ) *pnRow = res.nRow;
ds@1952
   187
  return rc;
ds@1952
   188
}
ds@1952
   189
ds@1952
   190
/*
ds@1952
   191
** This routine frees the space the sqlite3_get_table() malloced.
ds@1952
   192
*/
ds@1952
   193
void sqlite3_free_table(
ds@1952
   194
  char **azResult            /* Result returned from from sqlite3_get_table() */
ds@1952
   195
){
ds@1952
   196
  if( azResult ){
ds@1952
   197
    int i, n;
ds@1952
   198
    azResult--;
ds@1952
   199
    if( azResult==0 ) return;
ds@1952
   200
    n = (int)azResult[0];
ds@1952
   201
    for(i=1; i<n; i++){ if( azResult[i] ) sqlite3_free(azResult[i]); }
ds@1952
   202
    sqlite3_free(azResult);
ds@1952
   203
  }
ds@1952
   204
}
ds@1952
   205
ds@1952
   206
#endif /* SQLITE_OMIT_GET_TABLE */