예제 #1
0
static void UdfInsertFunc(sqlite3_context* aCtx, int aCnt, sqlite3_value** aValues)
	{
	int err;
  	const char* tail = 0;
  	sqlite3* db = 0;
  	
	TEST2(aCnt, 1);
	
	db = sqlite3_context_db_handle(aCtx);/* to test that sqlite3_context_db_handle() can be called */
	TEST(db != 0);
	
	TEST(!TheStmt);
	err = sqlite3_prepare(TheDb, "INSERT INTO t1(x) VALUES(:Val)", -1, &TheStmt, &tail);
	if(err == SQLITE_OK)
		{
		err = sqlite3_bind_value(TheStmt, 1, aValues[0]);
		if(err == SQLITE_OK)
			{
			err = sqlite3_step(TheStmt);
			}
		}
	(void)sqlite3_finalize(TheStmt);
	TheStmt = 0;
	
	sqlite3_result_int(aCtx, err);		
	}
예제 #2
0
파일: func.c 프로젝트: blingstorm/sqlcipher
/*
** group_concat(EXPR, ?SEPARATOR?)
*/
static void groupConcatStep(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zVal;
  StrAccum *pAccum;
  const char *zSep;
  int nVal, nSep;
  assert( argc==1 || argc==2 );
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));

  if( pAccum ){
    sqlite3 *db = sqlite3_context_db_handle(context);
    int firstTerm = pAccum->useMalloc==0;
    pAccum->useMalloc = 2;
    pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
    if( !firstTerm ){
      if( argc==2 ){
        zSep = (char*)sqlite3_value_text(argv[1]);
        nSep = sqlite3_value_bytes(argv[1]);
      }else{
        zSep = ",";
        nSep = 1;
      }
      sqlite3StrAccumAppend(pAccum, zSep, nSep);
    }
    zVal = (char*)sqlite3_value_text(argv[0]);
    nVal = sqlite3_value_bytes(argv[0]);
    sqlite3StrAccumAppend(pAccum, zVal, nVal);
  }
}
예제 #3
0
파일: pkgdb_repo.c 프로젝트: ppentchev/pkg
static void
file_exists(sqlite3_context *ctx, int argc, sqlite3_value **argv)
{
    char	 fpath[MAXPATHLEN];
    sqlite3	*db = sqlite3_context_db_handle(ctx);
    char	*path = dirname(sqlite3_db_filename(db, "main"));
    char	 cksum[SHA256_DIGEST_LENGTH * 2 +1];

    if (argc != 2) {
        sqlite3_result_error(ctx, "file_exists needs two argument", -1);
        return;
    }

    snprintf(fpath, sizeof(fpath), "%s/%s", path, sqlite3_value_text(argv[0]));

    if (access(fpath, R_OK) == 0) {
        sha256_file(fpath, cksum);
        if (strcmp(cksum, sqlite3_value_text(argv[1])) == 0)
            sqlite3_result_int(ctx, 1);
        else
            sqlite3_result_int(ctx, 0);
    } else {
        sqlite3_result_int(ctx, 0);
    }
}
예제 #4
0
파일: dbpage.c 프로젝트: cznic/cc
static int dbpageColumn(
  sqlite3_vtab_cursor *pCursor, 
  sqlite3_context *ctx, 
  int i
){
  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
  DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
  int rc = SQLITE_OK;
  switch( i ){
    case 0: {           /* pgno */
      sqlite3_result_int(ctx, pCsr->pgno);
      break;
    }
    case 1: {           /* data */
      DbPage *pDbPage = 0;
      rc = sqlite3PagerGet(pTab->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0);
      if( rc==SQLITE_OK ){
        sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pTab->szPage,
                            SQLITE_TRANSIENT);
      }
      sqlite3PagerUnref(pDbPage);
      break;
    }
    default: {          /* schema */
      sqlite3 *db = sqlite3_context_db_handle(ctx);
      sqlite3_result_text(ctx, db->aDb[pTab->iDb].zDbSName, -1, SQLITE_STATIC);
      break;
    }
  }
  return SQLITE_OK;
}
예제 #5
0
/*
 * SQLite manages explicit transactions by setting a flag when a BEGIN; is
 * issued, then starting an actual transaction in the btree layer when the
 * first operation happens (a read txn if it's a read op, a write txn if write)
 * Then each statement will be contained in a sub-transaction. Since sequences
 * are implemented using a custom function, we need to emulate that
 * functionality. So there are three cases here:
 * - Not in an explicit transaction - start a statement, since we might do
 *   write operations, and thus we need a valid statement_txn.
 * - In an explicit transaction, and the first statement. Start a txn and a
     statement txn.
 * - In an explicit transaction and not the first statemetn. Start a statement
 *   transaction.
 *
 * The SQLite vdbe will take care of closing the statement transaction for us,
 * so we don't need to worry about that.
 *
 * Caching sequences can't be transactionally protected, so it's a no-op in
 * that case (and this function should not be called).
 *
 * It's safe to call this method multiple times since both
 * sqlite3BtreeBeginTrans and sqlite3BtreeBeginStmt are no-ops on subsequent
 * calls.
 */
static int btreeSeqStartTransaction(
    sqlite3_context *context, Btree *p, int is_write)
{
	sqlite3 *db;
	Vdbe *vdbe;
	int rc;

	db = sqlite3_context_db_handle(context);
	/*
	 * TODO: This is actually a linked list of VDBEs, not necessarily
	 *       the vdbe we want. I can't see a way to get the correct
	 *       vdbe handle.
	 *       It's possible that there is only one VDBE handle in DB, since
	 *       we use a shared cache.
	 */
	vdbe = db->pVdbe;

	if (!sqlite3BtreeIsInTrans(p) &&
	    (rc = btreeBeginTransInternal(p, 1)) != SQLITE_OK) {
		btreeSeqError(context, SQLITE_ERROR,
		    "Could not begin transaction.");
		return (rc);
	}

	/*
	 * TODO: Do we need logic bumping the VDBE statement count here?
	 *       vdbe.c:OP_Transaction does, but adding it here causes an
	 *       assert failure. It should be OK, because this code is only
	 *       really relevant in the case where there is a single statement.
	 */
	rc = sqlite3BtreeBeginStmt(p, vdbe->iStatement);
	return (rc);
}
예제 #6
0
/*
 ** The implementation of the sqlite_record() function. This function accepts
 ** a single argument of any type. The return value is a formatted database
 ** record (a blob) containing the argument value.
 **
 ** This is used to convert the value stored in the 'sample' column of the
 ** sqlite_stat3 table to the record format SQLite uses internally.
 */
static void recordFunc(
                       sqlite3_context *context,
                       int argc,
                       sqlite3_value **argv
                       ){
    const int file_format = 1;
    int iSerial;                    /* Serial type */
    int nSerial;                    /* Bytes of space for iSerial as varint */
    int nVal;                       /* Bytes of space required for argv[0] */
    int nRet;
    sqlite3 *db;
    u8 *aRet;
    
    UNUSED_PARAMETER( argc );
    iSerial = sqlite3VdbeSerialType(argv[0], file_format);
    nSerial = sqlite3VarintLen(iSerial);
    nVal = sqlite3VdbeSerialTypeLen(iSerial);
    db = sqlite3_context_db_handle(context);
    
    nRet = 1 + nSerial + nVal;
    aRet = sqlite3DbMallocRaw(db, nRet);
    if( aRet==0 ){
        sqlite3_result_error_nomem(context);
    }else{
        aRet[0] = nSerial+1;
        sqlite3PutVarint(&aRet[1], iSerial);
        sqlite3VdbeSerialPut(&aRet[1+nSerial], nVal, argv[0], file_format);
        sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
        sqlite3DbFree(db, aRet);
    }
}
예제 #7
0
/* Create or update the cookie entry in the metadata db. */
static int btreeSeqPutCookie(
    sqlite3_context *context, Btree *p, SEQ_COOKIE *cookie, u_int32_t flags) {
	BtShared *pBt;
	DBT cookie_key, cookie_data;
	int rc, ret;
	sqlite3 *db;

	pBt = p->pBt;
	db = sqlite3_context_db_handle(context);
	/* Ensure a transaction has been started. */
	if (cookie->cache == 0 &&
	    (rc = btreeSeqStartTransaction(context, p, 1)) != SQLITE_OK) {
		btreeSeqError(context, SQLITE_ERROR,
		    "Could not begin transaction for create.");
		return rc;
	}
	/* Create the matching cookie entry in the metadata db. */
	memset(&cookie_key, 0, sizeof(cookie_key));
	memset(&cookie_data, 0, sizeof(cookie_data));

	cookie_key.data = cookie->name;
	cookie_key.size = cookie_key.ulen = cookie->name_len;
	cookie_key.flags = cookie_data.flags = DB_DBT_USERMEM;

	cookie_data.data = cookie;
	cookie_data.size = cookie_data.ulen = sizeof(SEQ_COOKIE);
	if ((ret = pBt->metadb->put(pBt->metadb, p->savepoint_txn,
	    &cookie_key, &cookie_data, flags)) != 0)
		return ret;
	return (0);
}
예제 #8
0
/*
** Implementation of the eval(X) and eval(X,Y) SQL functions.
**
** Evaluate the SQL text in X.  Return the results, using string
** Y as the separator.  If Y is omitted, use a single space character.
*/
static void sqlEvalFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zSql;
  sqlite3 *db;
  char *zErr = 0;
  int rc;
  struct EvalResult x;

  memset(&x, 0, sizeof(x));
  x.zSep = " ";
  zSql = (const char*)sqlite3_value_text(argv[0]);
  if( zSql==0 ) return;
  if( argc>1 ){
    x.zSep = (const char*)sqlite3_value_text(argv[1]);
    if( x.zSep==0 ) return;
  }
  x.szSep = (int)strlen(x.zSep);
  db = sqlite3_context_db_handle(context);
  rc = sqlite3_exec(db, zSql, callback, &x, &zErr);
  if( rc!=SQLITE_OK ){
    sqlite3_result_error(context, zErr, -1);
    sqlite3_free(zErr);
  }else if( x.zSep==0 ){
    sqlite3_result_error_nomem(context);
    sqlite3_free(x.z);
  }else{
    sqlite3_result_text(context, x.z, (int)x.nUsed, sqlite3_free);
  }
}
예제 #9
0
파일: test_func.c 프로젝트: 7kbird/chrome
/*
** 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);
  }
}
예제 #10
0
/*
** Implementation of the substr() function.
**
** substr(x,p1,p2)  returns p2 characters of x[] beginning with p1.
** p1 is 1-indexed.  So substr(x,1,1) returns the first character
** of x.  If x is text, then we actually count UTF-8 characters.
** If x is a blob, then we count bytes.
**
** If p1 is negative, then we begin abs(p1) from the end of x[].
*/
static void substrFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const unsigned char *z;
  const unsigned char *z2;
  int len;
  int p0type;
  i64 p1, p2;

  assert( argc==3 || argc==2 );
  p0type = sqlite3_value_type(argv[0]);
  if( p0type==SQLITE_BLOB ){
    len = sqlite3_value_bytes(argv[0]);
    z = sqlite3_value_blob(argv[0]);
    if( z==0 ) return;
    assert( len==sqlite3_value_bytes(argv[0]) );
  }else{
    z = sqlite3_value_text(argv[0]);
    if( z==0 ) return;
    len = 0;
    for(z2=z; *z2; len++){
      SQLITE_SKIP_UTF8(z2);
    }
  }
  p1 = sqlite3_value_int(argv[1]);
  if( argc==3 ){
    p2 = sqlite3_value_int(argv[2]);
  }else{
    p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH];
  }
  if( p1<0 ){
    p1 += len;
    if( p1<0 ){
      p2 += p1;
      p1 = 0;
    }
  }else if( p1>0 ){
    p1--;
  }
  if( p1+p2>len ){
    p2 = len-p1;
  }
  if( p0type!=SQLITE_BLOB ){
    while( *z && p1 ){
      SQLITE_SKIP_UTF8(z);
      p1--;
    }
    for(z2=z; *z2 && p2; p2--){
      SQLITE_SKIP_UTF8(z2);
    }
    sqlite3_result_text(context, (char*)z, z2-z, SQLITE_TRANSIENT);
  }else{
    if( p2<0 ) p2 = 0;
    sqlite3_result_blob(context, (char*)&z[p1], p2, SQLITE_TRANSIENT);
  }
}
예제 #11
0
파일: func.c 프로젝트: kaomte/sqlcipher
/*
** Implementation of the last_insert_rowid() SQL function.  The return
** value is the same as the sqlite3_last_insert_rowid() API function.
*/
static void last_insert_rowid(
  sqlite3_context *context, 
  int NotUsed, 
  sqlite3_value **NotUsed2
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  UNUSED_PARAMETER2(NotUsed, NotUsed2);
  sqlite3_result_int64(context, sqlite3_last_insert_rowid(db));
}
예제 #12
0
파일: func.c 프로젝트: kaomte/sqlcipher
/*
** Implementation of the total_changes() SQL function.  The return value is
** the same as the sqlite3_total_changes() API function.
*/
static void total_changes(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **NotUsed2
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  UNUSED_PARAMETER2(NotUsed, NotUsed2);
  sqlite3_result_int(context, sqlite3_total_changes(db));
}
예제 #13
0
파일: func.c 프로젝트: blingstorm/sqlcipher
/*
** Implementation of the total_changes() SQL function.  The return value is
** the same as the sqlite3_total_changes() API function.
*/
static void total_changes(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **NotUsed2
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  UNUSED_PARAMETER2(NotUsed, NotUsed2);
  /* IMP: R-52756-41993 This function is a wrapper around the
  ** sqlite3_total_changes() C/C++ interface. */
  sqlite3_result_int(context, sqlite3_total_changes(db));
}
예제 #14
0
static void
function_property_names (sqlite3_context *context,
                         int              argc,
                         sqlite3_value   *argv[])
{
	static gchar **names = NULL;
	static GMutex mutex;
	int rc = SQLITE_DONE;

	g_mutex_lock (&mutex);

	if (G_UNLIKELY (names == NULL)) {
		GPtrArray *names_array;
		sqlite3_stmt *stmt;
		sqlite3 *db;

		names_array = g_ptr_array_new ();
		db = sqlite3_context_db_handle (context);
		rc = sqlite3_prepare_v2 (db,
		                         "SELECT Uri "
		                         "FROM Resource "
		                         "JOIN \"rdf:Property\" "
		                         "ON Resource.ID = \"rdf:Property\".ID "
		                         "WHERE \"rdf:Property\".\"tracker:fulltextIndexed\" = 1 "
		                         "ORDER BY \"rdf:Property\".ID ",
		                         -1, &stmt, NULL);

		while ((rc = sqlite3_step (stmt)) != SQLITE_DONE) {
			if (rc == SQLITE_ROW) {
				const gchar *name;

				name = sqlite3_column_text (stmt, 0);
				g_ptr_array_add (names_array, g_strdup (name));
			} else if (rc != SQLITE_BUSY) {
				break;
			}
		}

		sqlite3_finalize (stmt);

		if (rc == SQLITE_DONE) {
			names = (gchar **) g_ptr_array_free (names_array, FALSE);
		} else {
			g_ptr_array_free (names_array, TRUE);
		}
	}

	g_mutex_unlock (&mutex);

	if (rc == SQLITE_DONE)
		sqlite3_result_blob (context, names, sizeof (names), NULL);
	else
		sqlite3_result_error_code (context, rc);
}
예제 #15
0
파일: test_func.c 프로젝트: 7kbird/chrome
static void test_agg_errmsg16_final(sqlite3_context *ctx){
#ifndef SQLITE_OMIT_UTF16
  const void *z;
  sqlite3 * db = sqlite3_context_db_handle(ctx);
  sqlite3_aggregate_context(ctx, 2048);
  sqlite3BeginBenignMalloc();
  z = sqlite3_errmsg16(db);
  sqlite3EndBenignMalloc();
  sqlite3_result_text16(ctx, z, -1, SQLITE_TRANSIENT);
#endif
}
예제 #16
0
extern void my_row_count(sqlite3_context  *context,
                         int               argc,
                         sqlite3_value   **argv){
  sqlite3      *thisdb; 

  thisdb = sqlite3_context_db_handle(context);
  if (thisdb) {
    sqlite3_result_int(context, sqlite3_changes(thisdb));
  } else {
    sqlite3_result_null(context);
  }
}
ikptr
ik_sqlite3_context_db_handle (ikptr s_context, ikpcb * pcb)
{
#ifdef HAVE_SQLITE3_CONTEXT_DB_HANDLE
  sqlite3_context *	context = IK_SQLITE_CONTEXT(s_context);
  sqlite3 *		conn;
  conn = sqlite3_context_db_handle(context);
  return (conn)? ika_pointer_alloc(pcb, (ik_ulong)conn) : IK_FALSE;
#else
  feature_failure(__func__);
#endif
}
예제 #18
0
파일: func.c 프로젝트: blingstorm/sqlcipher
/*
** Implementation of the last_insert_rowid() SQL function.  The return
** value is the same as the sqlite3_last_insert_rowid() API function.
*/
static void last_insert_rowid(
  sqlite3_context *context, 
  int NotUsed, 
  sqlite3_value **NotUsed2
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  UNUSED_PARAMETER2(NotUsed, NotUsed2);
  /* IMP: R-51513-12026 The last_insert_rowid() SQL function is a
  ** wrapper around the sqlite3_last_insert_rowid() C/C++ interface
  ** function. */
  sqlite3_result_int64(context, sqlite3_last_insert_rowid(db));
}
예제 #19
0
/*
** This function is used by SQL generated to implement the 
** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
** CREATE INDEX command. The second is a table name. The table name in 
** the CREATE TABLE or CREATE INDEX statement is replaced with the third
** argument and the result returned. Examples:
**
** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
**     -> 'CREATE TABLE def(a, b, c)'
**
** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
**     -> 'CREATE INDEX i ON def(a, b, c)'
这个函数使用SQL执行ALTER TABLE命令生成。
第一个参数是创建表或文本
创建索引的命令。第二个是表名。
创建表的表名或创建INDEX语句被替换为第三个参数,返回的结果。
例子:
** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
**     -> 'CREATE TABLE def(a, b, c)'
**
** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
**     -> 'CREATE INDEX i ON def(a, b, c)'
*/
static void renameTableFunc(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **argv
){
  unsigned char const *zSql = sqlite3_value_text(argv[0]);
  unsigned char const *zTableName = sqlite3_value_text(argv[1]);

  int token;
  Token tname;
  unsigned char const *zCsr = zSql;
  int len = 0;
  char *zRet;

  sqlite3 *db = sqlite3_context_db_handle(context);

  UNUSED_PARAMETER(NotUsed);

  /* The principle used to locate the table name in the CREATE TABLE 
  ** statement is that the table name is the first non-space token that
  ** is immediately followed by a TK_LP or TK_USING token.
  原理用于定位在CREATE table语句表名,
  该语句是表名是立即紧随其后TK_LP或进行技术改造TK_USING令牌的第一个非空间令牌。
  */
  if( zSql ){
    do {
      if( !*zCsr ){
        /* Ran out of input before finding an opening bracket. Return NULL. 找到一个开括号之前放弃输入。返回null。*/
        return;
      }

      /* Store the token that zCsr points to in tname. 存储tname zCsr指向表名的令牌 */
      tname.z = (char*)zCsr;
      tname.n = len;

      /* Advance zCsr to the next token. Store that token type in 'token',
      ** and its length in 'len' (to be used next iteration of this loop).
      推进zCsr到下一个令牌。令牌类型存储用“token”,
      和它的长度的用‘len’(下一个迭代的循环使用)。
      */
      do {
        zCsr += len;
        len = sqlite3GetToken(zCsr, &token);
      } while( token==TK_SPACE );
      assert( len>0 );
    } while( token!=TK_LP && token!=TK_USING );

    zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, 
       zTableName, tname.z+tname.n);
    sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
  }
}
예제 #20
0
/*
** Allocate nByte bytes of space using sqlite3_malloc(). If the
** allocation fails, call sqlite3_result_error_nomem() to notify
** the database handle that malloc() has failed.
*/
static void *contextMalloc(sqlite3_context *context, i64 nByte){
  char *z;
  if( nByte>sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH] ){
    sqlite3_result_error_toobig(context);
    z = 0;
  }else{
    z = sqlite3Malloc(nByte);
    if( !z && nByte>0 ){
      sqlite3_result_error_nomem(context);
    }
  }
  return z;
}
예제 #21
0
static void
function_weights (sqlite3_context *context,
                  int              argc,
                  sqlite3_value   *argv[])
{
	static guint *weights = NULL;
	static GMutex mutex;
	int rc = SQLITE_DONE;

	g_mutex_lock (&mutex);

	if (G_UNLIKELY (weights == NULL)) {
		GArray *weight_array;
		sqlite3_stmt *stmt;
		sqlite3 *db;

		weight_array = g_array_new (FALSE, FALSE, sizeof (guint));
		db = sqlite3_context_db_handle (context);
		rc = sqlite3_prepare_v2 (db,
		                         "SELECT \"rdf:Property\".\"tracker:weight\" "
		                         "FROM \"rdf:Property\" "
		                         "WHERE \"rdf:Property\".\"tracker:fulltextIndexed\" = 1 "
		                         "ORDER BY \"rdf:Property\".ID ",
		                         -1, &stmt, NULL);

		while ((rc = sqlite3_step (stmt)) != SQLITE_DONE) {
			if (rc == SQLITE_ROW) {
				guint weight;
				weight = sqlite3_column_int (stmt, 0);
				g_array_append_val (weight_array, weight);
			} else if (rc != SQLITE_BUSY) {
				break;
			}
		}

		sqlite3_finalize (stmt);

		if (rc == SQLITE_DONE) {
			weights = (guint *) g_array_free (weight_array, FALSE);
		} else {
			g_array_free (weight_array, TRUE);
		}
	}

	g_mutex_unlock (&mutex);

	if (rc == SQLITE_DONE)
		sqlite3_result_blob (context, weights, sizeof (weights), NULL);
	else
		sqlite3_result_error_code (context, rc);
}
예제 #22
0
/*
** Auxiliary SQL function to return the name of the VFS
*/
static void vfsNameFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  char *zVfs = 0;
  UNUSED_PARAMETER(argc);
  UNUSED_PARAMETER(argv);
  sqlite3_file_control(db, "main", SQLITE_FCNTL_VFSNAME, &zVfs);
  if( zVfs ){
    sqlite3_result_text(context, zVfs, -1, sqlite3_free);
  }
}
예제 #23
0
파일: alter.c 프로젝트: qiuping/sqlcipher
/*
** This function is used by SQL generated to implement the 
** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
** CREATE INDEX command. The second is a table name. The table name in 
** the CREATE TABLE or CREATE INDEX statement is replaced with the third
** argument and the result returned. Examples:
**
** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
**     -> 'CREATE TABLE def(a, b, c)'
**
** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
**     -> 'CREATE INDEX i ON def(a, b, c)'
*/
static void renameTableFunc(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **argv
){
  unsigned char const *zSql = sqlite3_value_text(argv[0]);
  unsigned char const *zTableName = sqlite3_value_text(argv[1]);

  int token;
  Token tname;
  unsigned char const *zCsr = zSql;
  int len = 0;
  char *zRet;

  sqlite3 *db = sqlite3_context_db_handle(context);

  UNUSED_PARAMETER(NotUsed);

  /* The principle used to locate the table name in the CREATE TABLE 
  ** statement is that the table name is the first non-space token that
  ** is immediately followed by a TK_LP or TK_USING token.
  */
  if( zSql ){
    do {
      if( !*zCsr ){
        /* Ran out of input before finding an opening bracket. Return NULL. */
        return;
      }

      /* Store the token that zCsr points to in tname. */
      tname.z = zCsr;
      tname.n = len;

      /* Advance zCsr to the next token. Store that token type in 'token',
      ** and its length in 'len' (to be used next iteration of this loop).
      */
      do {
        zCsr += len;
        len = sqlite3GetToken(zCsr, &token);
      } while( token==TK_SPACE );
      assert( len>0 );
    } while( token!=TK_LP && token!=TK_USING );

    zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql, 
       zTableName, tname.z+tname.n);
    sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
  }
}
예제 #24
0
파일: func.c 프로젝트: kaomte/sqlcipher
/*
** A function that loads a shared-library extension then returns NULL.
*/
static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
  const char *zFile = (const char *)sqlite3_value_text(argv[0]);
  const char *zProc;
  sqlite3 *db = sqlite3_context_db_handle(context);
  char *zErrMsg = 0;

  if( argc==2 ){
    zProc = (const char *)sqlite3_value_text(argv[1]);
  }else{
    zProc = 0;
  }
  if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){
    sqlite3_result_error(context, zErrMsg, -1);
    sqlite3_free(zErrMsg);
  }
}
예제 #25
0
파일: func.c 프로젝트: kaomte/sqlcipher
/*
** Implementation of the like() SQL function.  This function implements
** the build-in LIKE operator.  The first argument to the function is the
** pattern and the second argument is the string.  So, the SQL statements:
**
**       A LIKE B
**
** is implemented as like(B,A).
**
** This same function (with a different compareInfo structure) computes
** the GLOB operator.
*/
static void likeFunc(
  sqlite3_context *context, 
  int argc, 
  sqlite3_value **argv
){
  const unsigned char *zA, *zB;
  int escape = 0;
  int nPat;
  sqlite3 *db = sqlite3_context_db_handle(context);

  zB = sqlite3_value_text(argv[0]);
  zA = sqlite3_value_text(argv[1]);

  /* Limit the length of the LIKE or GLOB pattern to avoid problems
  ** of deep recursion and N*N behavior in patternCompare().
  */
  nPat = sqlite3_value_bytes(argv[0]);
  testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] );
  testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 );
  if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){
    sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
    return;
  }
  assert( zB==sqlite3_value_text(argv[0]) );  /* Encoding did not change */

  if( argc==3 ){
    /* The escape character string must consist of a single UTF-8 character.
    ** Otherwise, return an error.
    */
    const unsigned char *zEsc = sqlite3_value_text(argv[2]);
    if( zEsc==0 ) return;
    if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){
      sqlite3_result_error(context, 
          "ESCAPE expression must be a single character", -1);
      return;
    }
    escape = sqlite3Utf8Read(zEsc, &zEsc);
  }
  if( zA && zB ){
    struct compareInfo *pInfo = sqlite3_user_data(context);
#ifdef SQLITE_TEST
    sqlite3_like_count++;
#endif
    
    sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape));
  }
}
예제 #26
0
/*
** An SQL user-function registered to do the work of an DETACH statement. The
** three arguments to the function come directly from a detach statement:
**
**     DETACH DATABASE x
**
**     SELECT sqlite_detach(x)
*/
static void detachFunc(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **argv
){
  const char *zName = (const char *)sqlite3_value_text(argv[0]);
  sqlite3 *db = sqlite3_context_db_handle(context);
  int i;
  Db *pDb = 0;
  char zErr[128];

  UNUSED_PARAMETER(NotUsed);

  if( zName==0 ) zName = "";
  for(i=0; i<db->nDb; i++){
    pDb = &db->aDb[i];
    if( pDb->pBt==0 ) continue;
    if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
  }

  if( i>=db->nDb ){
    sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName);
    goto detach_error;
  }
  if( i<2 ){
    sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
    goto detach_error;
  }
  if( !db->autoCommit ){
    sqlite3_snprintf(sizeof(zErr), zErr,
                     "cannot DETACH database within transaction");
    goto detach_error;
  }
  if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
    sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
    goto detach_error;
  }

  sqlite3BtreeClose(pDb->pBt);
  pDb->pBt = 0;
  pDb->pSchema = 0;
  sqlite3ResetInternalSchema(db, 0);
  return;

detach_error:
  sqlite3_result_error(context, zErr, -1);
}
예제 #27
0
파일: alter.c 프로젝트: arizwanp/intel_sgx
static void renameParentFunc(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **argv
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  char *zOutput = 0;
  char *zResult;
  unsigned char const *zInput = sqlite3_value_text(argv[0]);
  unsigned char const *zOld = sqlite3_value_text(argv[1]);
  unsigned char const *zNew = sqlite3_value_text(argv[2]);

  unsigned const char *z;         /* Pointer to token */
  int n;                          /* Length of token z */
  int token;                      /* Type of token */

  UNUSED_PARAMETER(NotUsed);
  if( zInput==0 || zOld==0 ) return;
  for(z=zInput; *z; z=z+n){
    n = sqlite3GetToken(z, &token);
    if( token==TK_REFERENCES ){
      char *zParent;
      do {
        z += n;
        n = sqlite3GetToken(z, &token);
      }while( token==TK_SPACE );

      if( token==TK_ILLEGAL ) break;
      zParent = sqlite3DbStrNDup(db, (const char *)z, n);
      if( zParent==0 ) break;
      sqlite3Dequote(zParent);
      if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){
        char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"",
            (zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew
        );
        sqlite3DbFree(db, zOutput);
        zOutput = zOut;
        zInput = &z[n];
      }
      sqlite3DbFree(db, zParent);
    }
  }

  zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput),
  sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC);
  sqlite3DbFree(db, zOutput);
}
예제 #28
0
파일: dbstat.c 프로젝트: 1018824313/sqlite
static int statColumn(
  sqlite3_vtab_cursor *pCursor, 
  sqlite3_context *ctx, 
  int i
){
  StatCursor *pCsr = (StatCursor *)pCursor;
  switch( i ){
    case 0:            /* name */
      sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT);
      break;
    case 1:            /* path */
      sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT);
      break;
    case 2:            /* pageno */
      sqlite3_result_int64(ctx, pCsr->iPageno);
      break;
    case 3:            /* pagetype */
      sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC);
      break;
    case 4:            /* ncell */
      sqlite3_result_int(ctx, pCsr->nCell);
      break;
    case 5:            /* payload */
      sqlite3_result_int(ctx, pCsr->nPayload);
      break;
    case 6:            /* unused */
      sqlite3_result_int(ctx, pCsr->nUnused);
      break;
    case 7:            /* mx_payload */
      sqlite3_result_int(ctx, pCsr->nMxPayload);
      break;
    case 8:            /* pgoffset */
      sqlite3_result_int64(ctx, pCsr->iOffset);
      break;
    case 9:            /* pgsize */
      sqlite3_result_int(ctx, pCsr->szPage);
      break;
    default: {          /* schema */
      sqlite3 *db = sqlite3_context_db_handle(ctx);
      int iDb = pCsr->iDb;
      sqlite3_result_text(ctx, db->aDb[iDb].zName, -1, SQLITE_STATIC);
      break;
    }
  }
  return SQLITE_OK;
}
예제 #29
0
파일: func.c 프로젝트: kaomte/sqlcipher
/*
** Allocate nByte bytes of space using sqlite3_malloc(). If the
** allocation fails, call sqlite3_result_error_nomem() to notify
** the database handle that malloc() has failed and return NULL.
** If nByte is larger than the maximum string or blob length, then
** raise an SQLITE_TOOBIG exception and return NULL.
*/
static void *contextMalloc(sqlite3_context *context, i64 nByte){
  char *z;
  sqlite3 *db = sqlite3_context_db_handle(context);
  assert( nByte>0 );
  testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] );
  testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
  if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
    sqlite3_result_error_toobig(context);
    z = 0;
  }else{
    z = sqlite3Malloc((int)nByte);
    if( !z ){
      sqlite3_result_error_nomem(context);
    }
  }
  return z;
}
예제 #30
0
파일: func.c 프로젝트: kaomte/sqlcipher
/*
** The zeroblob(N) function returns a zero-filled blob of size N bytes.
*/
static void zeroblobFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  i64 n;
  sqlite3 *db = sqlite3_context_db_handle(context);
  assert( argc==1 );
  UNUSED_PARAMETER(argc);
  n = sqlite3_value_int64(argv[0]);
  testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH] );
  testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
  if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
    sqlite3_result_error_toobig(context);
  }else{
    sqlite3_result_zeroblob(context, (int)n);
  }
}