Since SQLite v2 was 'typeless', one had to call atoi() and atof() on terms
of the array *azArg to convert the text strings returned by a query into
integers and doubles.

As I understand it SQLite v3 stores integers and doubles in their native
binary format so one should be able to get at the numeric data without
text string conversions via atoi()/atof().  Does anyone have C code that
demonstrates how this could be done?

Here's a sample database and corresponding query + callback I'm currently
using:

  create table people ( name text, age integer , lat float, lon float );
  insert into  people values ( 'Alice' , 43 , 1.1 , -3.4e-3 );
  insert into  people values ( 'Bob'   , 28 , 5.5 , -3.1e+3 );
  insert into  people values ( 'Cindy' , 21 , 8.8 ,  3.2e+5 );

The query:

  rc = sqlite3_exec_printf(sql_db,
                           "select * from people order by age asc "
                           , a1_i1_d2_cb, 
                          &sql_data,
                          &zErrMsg);

The callback:

  int a1_i1_d2_cb(void *pArg, int nFields, char **azArg, char **azCol) {
      /* return array of [string, integer, double, double] */
      callback_data *p = (callback_data*) pArg;

      if (!azArg)
          return 0;
      strncpy(p->a[p->nRows][0],       azArg[0], SQL_STR_SIZE);
              p->i[p->nRows][0] = atoi(azArg[1]);
              p->x[p->nRows][0] = atof(azArg[2]);
              p->x[p->nRows][1] = atof(azArg[3]);
      ++(p->row_index);
      ++(p->nRows);

      return 0;
  }

The callback variable 'sql_data' has type 'callback_data' defined like this:

  #define SQL_BLOCK_SIZE 1000
  #define SQL_STR_SIZE    200
  #define SQL_MAX_COLUMNS  20

  typedef struct {
    sqlite3 *db;                    /* database handle                   */
    FILE   *out;                    /* output file handle                */
    char    nullvalue[SQL_MAX_COLUMNS]; /* string to display for NULL's  */
    char    zDbFilename[SQL_STR_SIZE];  /* db filename                   */
    int     nRows;                  /* size of a[]/i[]/x[] with valid data */
    int     row_index;              /* pointer to current row within table */
    char    a[SQL_BLOCK_SIZE][SQL_MAX_COLUMNS][SQL_STR_SIZE];/* string   */
    int     i[SQL_BLOCK_SIZE][SQL_MAX_COLUMNS];              /* integer  */
    double  x[SQL_BLOCK_SIZE][SQL_MAX_COLUMNS];              /* double   */
  } callback_data;

My questions:
 How can I populate sql_data.i[] and sql_data.x[] without calling atoi()
 and atof() on terms of azArg[]?
 Is there example C code out there that demonstrates the technique?
    -- Al

Reply via email to