Esempio n. 1
0
/*
** Retrieve a column of data.
*/
static int schemaColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
  schema_cursor *pCur = (schema_cursor *)cur;
  switch( i ){
    case 0:
      sqlite3_result_value(ctx, sqlite3_column_value(pCur->pDbList, 1));
      break;
    case 1:
      sqlite3_result_value(ctx, sqlite3_column_value(pCur->pTableList, 0));
      break;
    default:
      sqlite3_result_value(ctx, sqlite3_column_value(pCur->pColumnList, i-2));
      break;
  }
  return SQLITE_OK;
}
Esempio n. 2
0
SQLValue SQLiteStatement::getColumnValue(int col)
{
    ASSERT(col >= 0);
    if (!m_statement)
        if (prepareAndStep() != SQLITE_ROW)
            return SQLValue();
    if (columnCount() <= col)
        return SQLValue();

    // SQLite is typed per value. optional column types are
    // "(mostly) ignored"
    sqlite3_value* value = sqlite3_column_value(m_statement, col);
    switch (sqlite3_value_type(value)) {
        case SQLITE_INTEGER:    // SQLValue and JS don't represent integers, so use FLOAT -case
        case SQLITE_FLOAT:
            return SQLValue(sqlite3_value_double(value));
        case SQLITE_BLOB:       // SQLValue and JS don't represent blobs, so use TEXT -case
        case SQLITE_TEXT: {
            const UChar* string = reinterpret_cast<const UChar*>(sqlite3_value_text16(value));
            unsigned length = WTF::lengthOfNullTerminatedString(string);
            return SQLValue(StringImpl::create8BitIfPossible(string, length));
        }
        case SQLITE_NULL:
            return SQLValue();
        default:
            break;
    }
    ASSERT_NOT_REACHED();
    return SQLValue();
}
Esempio n. 3
0
static JSVAL sqlite_column_value(JSARGS args) {
    HandleScope scope;
    Local<External>wrap = Local<External>::Cast(args[0]);
    sqlite3_stmt *stmt = (sqlite3_stmt *)wrap->Value();
    int iCol = args[1]->IntegerValue();
    return scope.Close(External::New(sqlite3_column_value(stmt, iCol)));
}
Esempio n. 4
0
static int sesqlite_column(sqlite3_vtab_cursor *cur, sqlite3_context *ctx,
		int cidx) {
	sesqlite_cursor *c = (sesqlite_cursor*) cur;
	sqlite3_result_value(ctx, sqlite3_column_value(c->stmt, cidx));

	return SQLITE_OK;
}
Esempio n. 5
0
/*
** Invoke an SQL statement recursively.  The function result is the 
** first column of the first row of the result set.
*/
static void test_eval(
  sqlite3_context *pCtx, 
  int nArg,
  sqlite3_value **argv
){
  sqlite3_stmt *pStmt;
  int rc;
  sqlite3 *db = sqlite3_context_db_handle(pCtx);
  const char *zSql;

  zSql = (char*)sqlite3_value_text(argv[0]);
  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_step(pStmt);
    if( rc==SQLITE_ROW ){
      sqlite3_result_value(pCtx, sqlite3_column_value(pStmt, 0));
    }
    rc = sqlite3_finalize(pStmt);
  }
  if( rc ){
    char *zErr;
    assert( pStmt==0 );
    zErr = sqlite3_mprintf("sqlite3_prepare_v2() error: %s",sqlite3_errmsg(db));
    sqlite3_result_text(pCtx, zErr, -1, sqlite3_free);
    sqlite3_result_error_code(pCtx, rc);
  }
}
Esempio n. 6
0
/*
 * Returns value for the column at position iCol (starting from 0).
 * Reads column data from ref-values table, filtered by ObjectID and sorted by PropertyID
 * For the sake of better performance, fetches required columns on demand, sequentially.
 *
 */
static int _column(sqlite3_vtab_cursor *pCursor, sqlite3_context *pContext, int iCol)
{
    int result = SQLITE_OK;
    struct flexi_VTabCursor *cur = (void *) pCursor;

    if (iCol == -1)
    {
        sqlite3_result_int64(pContext, cur->lObjectID);
        goto EXIT;
    }

    struct flexi_ClassDef_t *vtab = (void *) cur->base.pVtab;

    // First, check if column has been already loaded
    while (cur->iReadCol < iCol)
    {
        int colResult = sqlite3_step(cur->pPropertyIterator);
        if (colResult == SQLITE_DONE)
            break;
        if (colResult != SQLITE_ROW)
        {
            result = colResult;
            goto ONERROR;
        }
        sqlite3_int64 lPropID = sqlite3_column_int64(cur->pPropertyIterator, 1);
        if (lPropID < vtab->pProps[cur->iReadCol + 1].iPropID)
            continue;

        cur->iReadCol++;
        if (lPropID == vtab->pProps[cur->iReadCol].iPropID)
        {
            sqlite3_int64 lPropIdx = sqlite3_column_int64(cur->pPropertyIterator, 2);

            /*
             * No need in any special verification as we expect columns are sorted by property IDs, so
             * we just assume that once column index is OK, we can process this property data
             */

            cur->pCols[cur->iReadCol] = sqlite3_value_dup(sqlite3_column_value(cur->pPropertyIterator, 4));
        }
    }

    if (cur->pCols[iCol] == NULL || sqlite3_value_type(cur->pCols[iCol]) == SQLITE_NULL)
    {
        sqlite3_result_value(pContext, vtab->pProps[iCol].defaultValue);
    }
    else
    {
        sqlite3_result_value(pContext, cur->pCols[iCol]);
    }

    result = SQLITE_OK;
    goto EXIT;
    ONERROR:

    EXIT:
    // Map column number to property ID
    return result;
}
unsigned long int
device_get_symbol_address(device_symbol_t symbol)
{
  device_id_t device_id;
  sqlite3_stmt *st;
  int rc;
  unsigned long int value;

  device_id = detect_device();
  if (device_id == DEVICE_NOT_SUPPORTED) {
    return 0;
  }

  value = 0;

  rc = sqlite3_prepare(db, SQL_QUERY_DEVICE_ADDRESS, -1, &st, NULL);

  if (!IS_SQL_ERROR(rc)) {
    rc = sqlite3_reset(st);
  }

  if (!IS_SQL_ERROR(rc)) {
    rc = sqlite3_bind_int(st, 1, device_id);
  }

  if (!IS_SQL_ERROR(rc)) {
    rc = sqlite3_bind_text(st, 2, symbol, -1, SQLITE_STATIC);
  }

  if (!IS_SQL_ERROR(rc)) {
    rc = execute_sql(st);
  }

  if (!IS_SQL_ERROR(rc)) {
    sqlite3_value *value_object;
    int value_type;
    value_object = sqlite3_column_value(st, 0);
    value_type = sqlite3_value_type(value_object);
    if (value_type == SQLITE_INTEGER) {
      value = sqlite3_value_int(value_object);
    } else {
      const unsigned char *value_text;
      value_text = sqlite3_value_text(value_object);
      if (value_text) {
        sscanf(value_text, "%lx", &value);
      }
    }
  }

  if (IS_SQL_ERROR(rc)) {
    printf("%s(%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db));
  }

  sqlite3_finalize(st);

  return value;
}
Esempio n. 8
0
/*
** Return values of columns for the row at which the explain_cursor
** is currently pointing.
*/
static int explainColumn(
  sqlite3_vtab_cursor *cur,   /* The cursor */
  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
  int i                       /* Which column to return */
){
  explain_cursor *pCur = (explain_cursor*)cur;
  if( i==EXPLN_COLUMN_SQL ){
    sqlite3_result_text(ctx, pCur->zSql, -1, SQLITE_TRANSIENT);
  }else{
    sqlite3_result_value(ctx, sqlite3_column_value(pCur->pExplain, i));
  }
  return SQLITE_OK;
}
Esempio n. 9
0
/*
** Load the contents of the %_config table into memory.
*/
int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
  const char *zSelect = "SELECT k, v FROM %Q.'%q_config'";
  char *zSql;
  sqlite3_stmt *p = 0;
  int rc = SQLITE_OK;
  int iVersion = 0;

  /* Set default values */
  pConfig->pgsz = FTS5_DEFAULT_PAGE_SIZE;
  pConfig->nAutomerge = FTS5_DEFAULT_AUTOMERGE;
  pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE;
  pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
  pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE;

  zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName);
  if( zSql ){
    rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &p, 0);
    sqlite3_free(zSql);
  }

  assert( rc==SQLITE_OK || p==0 );
  if( rc==SQLITE_OK ){
    while( SQLITE_ROW==sqlite3_step(p) ){
      const char *zK = (const char*)sqlite3_column_text(p, 0);
      sqlite3_value *pVal = sqlite3_column_value(p, 1);
      if( 0==sqlite3_stricmp(zK, "version") ){
        iVersion = sqlite3_value_int(pVal);
      }else{
        int bDummy = 0;
        sqlite3Fts5ConfigSetValue(pConfig, zK, pVal, &bDummy);
      }
    }
    rc = sqlite3_finalize(p);
  }
  
  if( rc==SQLITE_OK && iVersion!=FTS5_CURRENT_VERSION ){
    rc = SQLITE_ERROR;
    if( pConfig->pzErrmsg ){
      assert( 0==*pConfig->pzErrmsg );
      *pConfig->pzErrmsg = sqlite3_mprintf(
          "invalid fts5 file format (found %d, expected %d) - run 'rebuild'",
          iVersion, FTS5_CURRENT_VERSION
      );
    }
  }

  if( rc==SQLITE_OK ){
    pConfig->iCookie = iCookie;
  }
  return rc;
}
Esempio n. 10
0
MHStoreEntry* MHLabelsStore::readEntry(sqlite3_stmt *stmt) const
{
    if (!stmt) {
        LOG.error("%s: null sql statement", __FUNCTION__);
        return NULL;
    }
    
    sqlite3_value* oid = sqlite3_column_value(stmt, 0);
    unsigned long luid = static_cast<unsigned long>(sqlite3_value_int64(oid));
    const char* name = (const char*)sqlite3_column_text(stmt, 1);
    uint32_t guid = (uint32_t)sqlite3_column_int(stmt, 2);
    
    MHLabelInfo* itemInfo = new MHLabelInfo(guid, luid, name);
    return itemInfo;
}
Esempio n. 11
0
static int echoColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
  int iCol = i + 1;
  sqlite3_stmt *pStmt = ((echo_cursor *)cur)->pStmt;

  if( simulateVtabError((echo_vtab *)(cur->pVtab), "xColumn") ){
    return SQLITE_ERROR;
  }

  if( !pStmt ){
    sqlite3_result_null(ctx);
  }else{
    assert( sqlite3_data_count(pStmt)>iCol );
    sqlite3_result_value(ctx, sqlite3_column_value(pStmt, iCol));
  }
  return SQLITE_OK;
}
Esempio n. 12
0
DLL_FUNCTION(sqlite3_value*) BU_SQLite_Column_Value(sqlite3_stmt* pStmt, int32_t iCol) {
#pragma comment(linker, "/EXPORT:BU_SQLite_Column_Value=_BU_SQLite_Column_Value@8")
	return sqlite3_column_value(pStmt, iCol);
}
Esempio n. 13
0
 void nextField(const RtlFieldInfo * field)
 {
     val = sqlite3_column_value(stmt, colIdx++);
 }
Esempio n. 14
0
        column sqlite3_row::column(size_t nPosition) const
        {
            assert(nPosition < size());

            return db::column(make_shared<sqlite3_column>( sqlite3_column_value(stmt_, nPosition ) ) );
        }
Esempio n. 15
0
static VALUE db_execute(int argc, VALUE *argv, VALUE self)
{
	sqlite3 * db = NULL;
	void **ppDB = NULL;		
	sqlite3_stmt *statement = NULL;
	const char* sql = NULL;
	VALUE arRes = rb_ary_new();
    VALUE* colNames = NULL;
	int nRes = 0;
    char * szErrMsg = 0;
    int is_batch = 0;

	if ((argc < 2) || (argc > 3))
		rb_raise(rb_eArgError, "wrong # of arguments(%d for 3)",argc);
	
	Data_Get_Struct(self, void *, ppDB);
	db = (sqlite3 *)rho_db_get_handle(*ppDB);
	sql = RSTRING_PTR(argv[0]);
    is_batch = argv[1] == Qtrue ? 1 : 0;

    RAWTRACE1("db_execute: %s", sql);

    PROF_START_CREATED("SQLITE");
    if ( is_batch )
    {
        PROF_START_CREATED("SQLITE_EXEC");

        rho_db_lock(*ppDB);
        nRes = sqlite3_exec(db, sql,  NULL, NULL, &szErrMsg);
        rho_db_unlock(*ppDB);

        PROF_STOP("SQLITE_EXEC");
    }
    else
    {
        rho_db_lock(*ppDB);
        PROF_START_CREATED("SQLITE_PREPARE");
        nRes = rho_db_prepare_statement(*ppDB, sql, -1, &statement);
        PROF_STOP("SQLITE_PREPARE");
        //nRes = sqlite3_prepare_v2(db, sql, -1, &statement, NULL);
        if ( nRes != SQLITE_OK)
        {
            szErrMsg = (char *)sqlite3_errmsg(db);
            rho_db_unlock(*ppDB);

            rb_raise(rb_eArgError, "could not prepare statement: %d; Message: %s",nRes, (szErrMsg?szErrMsg:""));
        }

        if ( argc > 2 )
        {
            int i = 0;
            VALUE args = argv[2];
            if ( RARRAY_LEN(args) > 0 && TYPE(RARRAY_PTR(args)[0]) == T_ARRAY )
                args = RARRAY_PTR(args)[0];

            for( ; i < RARRAY_LEN(args); i++ )
            {
                VALUE arg = RARRAY_PTR(args)[i];
                if (NIL_P(arg))
                {
                    sqlite3_bind_null(statement, i+1);
                    continue;
                }

                switch( TYPE(arg) )
                {
                case T_STRING:
                    sqlite3_bind_text(statement, i+1, RSTRING_PTR(arg), RSTRING_LEN(arg), SQLITE_TRANSIENT);
                    break;
                case T_FLOAT:
                    sqlite3_bind_double(statement, i+1, NUM2DBL(arg));
                    break;
                case T_FIXNUM:
                case T_BIGNUM:
                    sqlite3_bind_int64(statement, i+1, NUM2LL(arg));
                    break;
                default:
					{
						VALUE strVal = rb_funcall(arg, rb_intern("to_s"), 0);	
	                    sqlite3_bind_text(statement, i+1, RSTRING_PTR(strVal), -1, SQLITE_TRANSIENT);	
					}
					break;
                }
            }
        }

        PROF_START_CREATED("SQLITE_EXEC");
        nRes = sqlite3_step(statement);
        PROF_STOP("SQLITE_EXEC");

	    while( nRes== SQLITE_ROW ) {
		    int nCount = sqlite3_data_count(statement);
		    int nCol = 0;
		    VALUE hashRec = rb_hash_new();

            //if ( !colNames )
            //    colNames = getColNames(statement, nCount);

		    for(;nCol<nCount;nCol++){
			    int nColType = sqlite3_column_type(statement,nCol);
			    const char* szColName = sqlite3_column_name(statement,nCol);
			    VALUE colName = rb_str_new2(szColName);
			    VALUE colValue = Qnil;
    			
			    switch(nColType){
				    case SQLITE_NULL:
					    break;
                    case SQLITE_FLOAT:
                    {
                        double dVal = sqlite3_column_double(statement, nCol);
                        colValue = DBL2NUM(dVal);
                        break;
                    }
                    case SQLITE_INTEGER:
                    {
                        sqlite_int64 nVal = sqlite3_column_int64(statement, nCol);
                        colValue = LL2NUM(nVal);
                        break;
                    }
				    default:{
                        sqlite3_value * sqlValue = sqlite3_column_value(statement, nCol);
                        int nLen = sqlite3_value_bytes(sqlValue);
                        const char*  szValue = (const char *)sqlite3_value_text(sqlValue);
					    //char *text = (char *)sqlite3_column_text(statement, nCol);
					    colValue = rb_str_new(szValue, nLen);
					    break;
				    }
			    }
    			
			    rb_hash_aset(hashRec, colName/*colNames[nCol]*/, colValue);
		    }
    		
		    rb_ary_push(arRes, hashRec);

            PROF_START_CREATED("SQLITE_EXEC");
            nRes = sqlite3_step(statement);
            PROF_STOP("SQLITE_EXEC");

	    }

        rho_db_unlock(*ppDB);

    }

    if ( statement )
        //sqlite3_finalize(statement);
        sqlite3_reset(statement);

    if ( colNames )
        free(colNames);

    if ( nRes != SQLITE_OK && nRes != SQLITE_ROW && nRes != SQLITE_DONE )
    {
        if ( !szErrMsg )
            szErrMsg = (char*)sqlite3_errmsg(db);

        rb_raise(rb_eArgError, "could not execute statement: %d; Message: %s",nRes, (szErrMsg?szErrMsg:""));
    }

    PROF_STOP("SQLITE");

	return arRes;
}
Esempio n. 16
0
int sphyraena_prepare_data(sphyraena *s, const char* sql_stmt)
{
	sqlite3_stmt *stmt;
	sphyraena_data *data = s->data_cpu;

	// get length of null terminated sql_stmt
	int i;
	for(i = 0; sql_stmt[i] != '\0'; i++);

	// prepare our sqlite3_stmt object
	sqlite3_prepare_v2(s->db, sql_stmt, i, &stmt, NULL);

#ifdef SPHY_DEBUG
	sphyraena_timer_start();
#endif
	
	// step once to examine the results to determine data stride
	int r = sqlite3_step(stmt);

	// if a row isn't returned when we step return error
	if(r != SQLITE_ROW)
		return SPHYRAENA_ERR_STMT;

	// get and set number of columns in table
	int columns = sqlite3_column_count(stmt);
	data->columns = columns;

	// offset tracks the offset of each column in bytes from the beginning
	// of the row, since not every column is 4 bytes
	int offset = 0;
	sqlite3_value *val;

	// go through the first row of results to get all of our data
	// types so we know column offsets, don't save column data yet
	//
	// for each column get it from the sqlite info
	for(i = 0; i < columns; i++) {
		val = sqlite3_column_value(stmt, i);

		// if column type is integer
		if(val->type == SQLITE_INTEGER) {
#ifdef USE_INT64
			// SQLite does not differentiate between 32 and 64 bit
			// ints in the types data column, this controls whether
			// or not we want to cast all of the int values to
			// int32 or int64

			// set the type in the sphyraena_data struct
			data->types[i] = SPHYRAENA_INT64;
			// set column offset
			data->offsets[i] = offset;
			// increment offset
			offset += sizeof(i64);
#else
			data->types[i] = SPHYRAENA_INT;
			data->offsets[i] = offset;
			offset += sizeof(int);
#endif
		}
		else if(val->type == SQLITE_FLOAT) {
#ifdef USE_DOUBLES
			// see USE_INT64
			data->types[i] = SPHYRAENA_DOUBLE;
			data->offsets[i] = offset;
			offset += sizeof(double);
#else
			data->types[i] = SPHYRAENA_FLOAT;
			data->offsets[i] = offset;
			offset += sizeof(float);
#endif
		}
		else {
			eprintf(stderr,
				"Error: the data type for column %i is not supported\n",
				i);
			return SPHYRAENA_ERR_TYPE;
		}
	}

	// set row stride to the current offset
	int stride = offset;

	// round stride to next power of 2
/*	stride--;
	stride |= stride >> 1;
	stride |= stride >> 2;
	stride |= stride >> 4;
	stride |= stride >> 8;
	stride |= stride >> 16;
	stride++;*/

	s->data_cpu->stride = stride;
	int rows = 0;
	int last_row = floor((float)s->data_size / (float)stride);
	char *d = (char*)&s->data_cpu->d;
	void *p;

	do {
		for(i = 0; i < columns; i++) {
			p = d + rows * stride + data->offsets[i];

			switch(data->types[i]) {

				case SPHYRAENA_INT :
					((int*)p)[0] = sqlite3_column_int(stmt, i);
					break;

				case SPHYRAENA_INT64 :
					((i64*)p)[0] = sqlite3_column_int64(stmt, i);
					break;

				case SPHYRAENA_FLOAT :
					((float*)p)[0] = (float)sqlite3_column_double(stmt, i);
					break;

				case SPHYRAENA_DOUBLE :
					((double*)p)[0] = sqlite3_column_double(stmt, i);
					break;

				default:
					eprintf(stderr,
						"Error: the data type for column %i is not supported\n",
						i);
					return SPHYRAENA_ERR_TYPE;
			}
		}

		rows++;

		if(rows >= last_row) {
			eprintf(stderr, "Warning: selected data too large for gpu data block\n");
			break;
		}
	} while(sqlite3_step(stmt) == SQLITE_ROW);

#ifdef COLUMNROW
	// the current format is row-column data format, this block performs a
	// translation to column-row format, which takes longer, but may make
	// query execution faster because of coalescing
	char *temp = (char*)malloc(s->data_size);
	int offsets[columns];
	int j;

	for(i = 0; i < rows; i++) {
		for(j = 0; j < columns; j++) {
			switch(data->types[j]) {

				case SPHYRAENA_INT :
					((int*)(temp + data->offsets[j] * rows))[i] =
						((int*)(d + i * stride + data->offsets[j]))[0];
					break;

				case SPHYRAENA_INT64 :
					((i64*)(temp + data->offsets[j] * rows))[i] =
						((i64*)(d + i * stride + data->offsets[j]))[0];
					break;

				case SPHYRAENA_FLOAT :
					((float*)(d + data->offsets[j] * rows))[i] =
						((float*)(d + i * stride + data->offsets[j]))[0];
					break;

				case SPHYRAENA_DOUBLE :
					((double*)(temp + data->offsets[j] * rows))[i] =
						((double*)(d + i * stride + data->offsets[j]))[0];
					break;
			}
		}
	}

	for(i = 0; i < columns; i++)
		data->offsets[i] *= rows;

	memcpy(d, temp, s->data_size);
	free(temp);
#endif

	data->rows = rows;


#ifdef SPHY_DEBUG
	sphyraena_timer_end("SQLite select");
#endif

	// clean up sqlite stmt
	sqlite3_finalize(stmt);

	return SPHYRAENA_SUCCESS;
}
Esempio n. 17
0
/*
 * Executes SQL statement zSql on zDatabase, using parameters zArgs and file name substitutions zFileArgs
 * Result data is loaded onto pData, and pRowCnt and pColCnt will indicate number of loaded rows and
 * number of columns in the row. Total number of items in pData will be nRowCnt * nColCnt
 */
static int
_runSql(char *zDatabase, char *zSrcSql, char *zArgs, char *zFileArgs, Array_t *pData, int *pColCnt,
        char *zEntryFilePath,
        char *zSubstFileNames)
{
    int result;

    sqlite3 *pDB = NULL;
    sqlite3_stmt *pStmt = NULL;
    sqlite3_stmt *pArgsStmt = NULL;
    Array_t sqlArgs;
    char *zError = NULL;
    char *zFullFilePath = NULL;
    sqlite3_stmt *pSubstStmt = NULL;
    char *zFileContent = NULL;
    char *zSchemaSql = NULL;

    char *zSql = strCopy(zSrcSql, -1);

    /*
    * Only first 16 substitute parameters will be processed. This is related to the fact that in C there
    * is no non-hacking way to dynamically build variadic arguments. So, to support list of values we just
    * limit maximum number of substitute strings to reasonably high number (16)
    */
    const char *zz[16];
    memset(&zz, 0, sizeof(zz));

    Array_init(&sqlArgs, sizeof(SqlArg_t), (void *) _freeSqlArg);

    *pColCnt = 0;

    //    Array_init(pData, sizeof(sqlite3_value *), (void *) _freeSqliteValue);

    /*
    * Open database (use :memory: if not defined)
    */
    if (zDatabase == NULL || strlen(zDatabase) == 0)
    {
        zDatabase = ":memory:";
    }
    CHECK_CALL(sqlite3_open_v2(zDatabase, &pDB,
                               SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_SHAREDCACHE,
                               NULL));

    CHECK_CALL(sqlite3_enable_load_extension(pDB, 1));

    // load extension library
    CHECK_CALL(sqlite3_load_extension(pDB, "../../bin/libFlexilite", NULL, &zError));

    // load and run db schema
    CHECK_CALL(file_load_utf8("../../sql/dbschema.sql", &zSchemaSql));
    CHECK_CALL(sqlite3_exec(pDB, (const char *) zSchemaSql, NULL, NULL, &zError));

    /*
     * Substitute strings
     */
    if (!STR_EMPTY(zSubstFileNames))
    {
        CHECK_STMT_PREPARE(pDB, "select key, value from json_each(:1);", &pSubstStmt);
        CHECK_CALL(sqlite3_bind_text(pSubstStmt, 1, zSubstFileNames, -1, NULL));
        int nSubst = 0;
        while ((result = sqlite3_step(pSubstStmt)) == SQLITE_ROW)
        {
            if (nSubst >= 16)
            {
                result = SQLITE_ERROR;
                zError = "Number of substitute strings must not exceed 16";
                goto ONERROR;
            }
            sqlite3_free(zFullFilePath);
            zFullFilePath = NULL;

            Path_join(&zFullFilePath, zEntryFilePath, (char *) sqlite3_column_text(pSubstStmt, 1));

            CHECK_CALL(file_load_utf8(zFullFilePath, &zFileContent));

            zz[nSubst++] = zFileContent;
            zFileContent = NULL; // Memory will be freed by zz
        }
        if (result != SQLITE_DONE)
            goto ONERROR;

        char *zTemp = zSql;
        zSql = sqlite3_mprintf(zTemp, zz[0], zz[1], zz[2], zz[3], zz[4], zz[5], zz[6], zz[7], zz[8],
                               zz[9], zz[10], zz[11], zz[12], zz[13], zz[14], zz[15]);
        sqlite3_free(zTemp);
    }

    // TODO use flexi('init')

    CHECK_STMT_PREPARE(pDB, zSql, &pStmt);

    // Check if we have arguments JSON. Prepare arguments
    if (!STR_EMPTY(zArgs))
    {
        CHECK_STMT_PREPARE(pDB, "select value, type from json_each(:1);", &pArgsStmt);
        CHECK_CALL(sqlite3_bind_text(pArgsStmt, 1, zArgs, -1, NULL));
        int nArgCnt = 0;
        while ((result = sqlite3_step(pArgsStmt)) == SQLITE_ROW)
        {
            SqlArg_t item;
            memset(&item, 0, sizeof(item));
            item.pValue = sqlite3_value_dup(sqlite3_column_value(pArgsStmt, 0));
            Array_setNth(&sqlArgs, sqlArgs.iCnt, &item);
            nArgCnt++;
        }

        if (result != SQLITE_DONE)
            goto ONERROR;

        /*
         * Process file args
         */
        CHECK_CALL(sqlite3_reset(pArgsStmt));
        CHECK_CALL(sqlite3_bind_text(pArgsStmt, 1, zFileArgs, -1, NULL));
        while ((result = sqlite3_step(pArgsStmt)) == SQLITE_ROW)
        {
            int argNo = sqlite3_column_int(pArgsStmt, 0);
            if (argNo >= 1 && argNo <= nArgCnt)
            {
                sqlite3_free(zFullFilePath);
                zFullFilePath = NULL;

                SqlArg_t *arg = Array_getNth(&sqlArgs, (u32) argNo - 1);
                Path_join(&zFullFilePath, zEntryFilePath, (char *) sqlite3_value_text(arg->pValue));

                CHECK_CALL(file_load_utf8(zFullFilePath, &arg->zText));
            }
        }

        if (result != SQLITE_DONE)
            goto ONERROR;

        Array_each(&sqlArgs, (void *) _bindSqlArg, pStmt);
    }

    while ((result = sqlite3_step(pStmt)) == SQLITE_ROW)
    {
        if (*pColCnt == 0)
            *pColCnt = sqlite3_column_count(pStmt);
        int iCol;
        for (iCol = 0; iCol < *pColCnt; iCol++)
        {
            sqlite3_value *pVal = sqlite3_value_dup(sqlite3_column_value(pStmt, iCol));
            Array_setNth(pData, pData->iCnt, &pVal);
        }
    }

    if (result != SQLITE_DONE)
        goto ONERROR;
    result = SQLITE_OK;
    goto EXIT;

    ONERROR:
    Array_clear(pData);
    if (pDB && zError == NULL)
    {
        zError = (char *) sqlite3_errmsg(pDB);
    }
    if (zError != NULL)
        printf("Error: %s\n", zError);

    EXIT:

    sqlite3_free(zSchemaSql);
    sqlite3_finalize(pStmt);
    sqlite3_finalize(pArgsStmt);
    sqlite3_finalize(pSubstStmt);
    if (pDB != NULL)
    {
        result = sqlite3_close(pDB);
        if (result != SQLITE_OK)
        {
            printf("DB Close Error %d. %s\n", result, sqlite3_errmsg(pDB));
        }
    }
    Array_clear(&sqlArgs);
    sqlite3_free(zFullFilePath);
    sqlite3_free(zSql);

    for (int i = 0; i < ARRAY_LEN(zz); i++)
        sqlite3_free((void *) zz[i]);

    if (zFileContent != NULL)
        sqlite3_free(zFileContent);

    return result;
}
GEOPACKAGE_DECLARE void
fnct_gpkgPointToTile (sqlite3_context * context, int argc UNUSED,
			sqlite3_value ** argv)
{
/* SQL function:
/ gpkgPointToTile (table, srid, x, y, zoom)
/
/ Returns tile from tile matrix for specified srid, point and zoom level
*/
    const unsigned char *table;
    int srid = 0;
    int target_srid = -1;
    double x_coord, y_coord;
    int int_value;
    int zoom;
    char *sql_stmt = NULL;
    sqlite3 *sqlite = NULL;
    sqlite3_stmt *stmt;
    int ret;
    
    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
    {
	sqlite3_result_error(context, "gpkgPointToTile() error: argument 1 [table] is not of the String type", -1);
	return;
    }
    table = sqlite3_value_text (argv[0]);
    
    if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
    {
	sqlite3_result_error(context, "gpkgPointToTile() error: argument 2 [srid] is not of the integer type", -1);
	return;
    }
    srid = sqlite3_value_int (argv[1]);
    if (sqlite3_value_type (argv[2]) == SQLITE_FLOAT)
    {
	x_coord = sqlite3_value_double (argv[2]);
    }
    else if (sqlite3_value_type (argv[2]) == SQLITE_INTEGER)
    {
	int_value = sqlite3_value_int (argv[2]);
	x_coord = int_value;
    }
    else
    {
	sqlite3_result_error(context, "gpkgPointToTile() error: argument 3 [x coordinate] is not of a numerical type", -1);
	return;
    }

    if (sqlite3_value_type (argv[3]) == SQLITE_FLOAT)
    {
	y_coord = sqlite3_value_double (argv[3]);
    }
    else if (sqlite3_value_type (argv[3]) == SQLITE_INTEGER)
    {
	int_value = sqlite3_value_int (argv[3]);
	y_coord = int_value;
    }
    else
    {
	sqlite3_result_error(context, "gpkgPointToTile() error: argument 4 [y coordinate] is not of a numerical type", -1);
	return;
    }
    
    if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
    {
	sqlite3_result_error(context, "gpkgPointToTile() error: argument 5 [zoom level] is not of the integer type", -1);
	return;
    }
    zoom = sqlite3_value_int (argv[4]);
    
    /* project into right coordinate basis if the input isn't already there */
    /* Get the target table SRID */
    sql_stmt = sqlite3_mprintf("SELECT srid FROM raster_columns WHERE r_table_name=%Q AND r_raster_column='tile_data'", table);

    sqlite = sqlite3_context_db_handle (context);
    ret = sqlite3_prepare_v2 (sqlite, sql_stmt, strlen(sql_stmt), &stmt, NULL);
    sqlite3_free(sql_stmt);
    if (ret != SQLITE_OK)
    {
	sqlite3_result_error(context, "gpkgPointToTile() error: failed to prepare SQL SRID select statement", -1);
        return;
    }
    ret = sqlite3_step (stmt);
    if (ret != SQLITE_ROW)
    {
	sqlite3_finalize (stmt);
	sqlite3_result_error(context, "gpkgPointToTile() error: Could not find SRID for specified table", -1);
        return;
    }
    if (sqlite3_column_type (stmt, 0) != SQLITE_INTEGER)
    {
	sqlite3_finalize (stmt);
	sqlite3_result_error(context, "gpkgPointToTile() error: SRID for table is not an integer. Corrupt GeoPackage?", -1);
	return;
    }
    target_srid = sqlite3_column_int(stmt, 0);
    sqlite3_finalize (stmt);
    
    if (srid != target_srid)
    {
	/* project input coordinates */
	sql_stmt = sqlite3_mprintf("SELECT ST_X(projected),ST_Y(projected) FROM (SELECT Transform(MakePoint(%f, %f, %i), %i) AS projected)",
				   x_coord, y_coord, srid, target_srid);

	sqlite = sqlite3_context_db_handle (context);
	ret = sqlite3_prepare_v2 (sqlite, sql_stmt, strlen(sql_stmt), &stmt, NULL);
	sqlite3_free(sql_stmt);
	if (ret != SQLITE_OK)
	{
	    sqlite3_result_error(context, "gpkgPointToTile() error: failed to prepare SQL Transform statement", -1);
	    return;
	}
	ret = sqlite3_step (stmt);
	if (ret == SQLITE_ROW)
	{
	    if ((sqlite3_column_type (stmt, 0) == SQLITE_FLOAT) && (sqlite3_column_type (stmt, 1) == SQLITE_FLOAT))
	    {
		x_coord = sqlite3_column_double(stmt, 0);
		y_coord = sqlite3_column_double(stmt, 1);
	    }
	}
	ret = sqlite3_finalize (stmt);
    }
    
    /* now we can get the tile blob */
    sql_stmt = sqlite3_mprintf("SELECT tile_data FROM \"%q\",\"%s_rt_metadata\" WHERE %q.id=%s_rt_metadata.id AND zoom_level=%i AND min_x <= %g AND max_x >=%g AND min_y <= %g AND max_y >= %g",
			table, table, table, table, zoom, x_coord, x_coord, y_coord, y_coord);

    sqlite = sqlite3_context_db_handle (context);
    ret = sqlite3_prepare_v2 (sqlite, sql_stmt, strlen(sql_stmt), &stmt, NULL);
    sqlite3_free(sql_stmt);
    if (ret != SQLITE_OK)
    {
	sqlite3_result_error(context, "gpkgPointToTile() error: failed to prepare SQL statement", -1);
        return;
    }
    ret = sqlite3_step (stmt);
    if (ret == SQLITE_ROW)
    {
	if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
	{
	    sqlite3_result_value (context, sqlite3_column_value(stmt, 0));
	}
    }
    ret = sqlite3_finalize (stmt);
}
sqlite3_value *
sqlite_statement::column_value (
  int _index
){
return sqlite3_column_value (this->stmt, _index);
}
Esempio n. 20
0
sqlite3_value* SQLiteSTMT::ColumnValue(int iCol) {
  return sqlite3_column_value(handle, iCol);
}