modernc.org/cc@v1.0.1/v2/testdata/_sqlite/src/table.c (about)

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