extensions/sqlite/sqlite-source/table.c
author Scott Ehlert <ds@alliedmods.net>
Sun Mar 30 07:00:22 2008 +0000 (2008-03-30)
changeset 1952 b7aa2b626807
permissions -rw-r--r--
Spring Cleaning, Part Ichi (1)
Various minor things done to project files
Updated sample extension project file and updated makefile to the new unified version (more changes likely on the way)
Updated regex project file and makefile
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 */