Exemplo n.º 1
0
/*
** Usage:   btree_next ID
**
** Move the cursor to the next entry in the table.  Return 0 on success
** or 1 if the cursor was already on the last entry in the table or if
** the table is empty.
*/
static int btree_next(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  int rc;
  int res = 0;
  char zBuf[100];

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pCur->pBtree);
  rc = sqlite3BtreeNext(pCur, &res);
  sqlite3BtreeLeave(pCur->pBtree);
  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res);
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}
Exemplo n.º 2
0
/*
** If a MoveTo operation is pending on the given cursor, then do that
** MoveTo now.  Return an error code.  If no MoveTo is pending, this
** routine does nothing and returns SQLITE_OK.
*/
int sqlite3VdbeCursorMoveto(Cursor *p){
  if( p->deferredMoveto ){
    int res;
    extern int sqlite3_search_count;
    assert( p->intKey );
    if( p->intKey ){
      sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res);
    }else{
      sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,sizeof(i64),&res);
    }
    *p->pIncrKey = 0;
    p->lastRecno = keyToInt(p->movetoTarget);
    p->recnoIsValid = res==0;
    if( res<0 ){
      sqlite3BtreeNext(p->pCursor, &res);
    }
    sqlite3_search_count++;
    p->deferredMoveto = 0;
    p->cacheValid = 0;
  }
  return SQLITE_OK;
}
Exemplo n.º 3
0
void testUpdate() {

	puts("testUpdate()");

	sqlite3 *db;

	char * file = UPDATE_FILE;

	int rc = sqlite3_open(file, &db);

	if (rc != SQLITE_OK) {
		printf("failed open: %d \n", rc);
		return;
	}

	if (db->nDb == 0) {
		puts("backends count is zero");
		goto close;
	}

	Btree *pBt = db->aDb[0].pBt;

	rc = sqlite3BtreeBeginTrans(pBt, 1);
	if (rc != SQLITE_OK) {
		printf("failed begin transaction: %d", rc);
		goto close;
	}

	char* pData = "Test data";
	int nData = strlen(pData);

	BtCursor cur;
	int x = 0;

	for (x = 1; x <= 3; x++) {

		int table = 0;
		rc = sqlite3BtreeCreateTable(pBt, &table, BTREE_INTKEY
						| BTREE_LEAFDATA);
		if (rc != SQLITE_OK) {
			printf("failed create table: %d", rc);
			goto close;
		}

		memset(&cur, 0, sizeof(BtCursor));
		rc = sqlite3BtreeCursor(pBt, table, 0, 0, &cur);
		if (rc != SQLITE_OK) {
			printf("failed get cursor: %d", rc);
			goto close;
		}

		int y = 0;
		for (y = 1; y <= 3; y++) {
			rc = sqlite3BtreeInsert(&cur, NULL, y, pData, nData, 0, 0);
			if (rc != SQLITE_OK) {
				printf("failed insert data: %d", rc);
				goto close;
			}
		}

		rc = sqlite3BtreeCloseCursor(&cur);
		if (rc != SQLITE_OK) {
			printf("failed close cursor: %d", rc);
			goto close;
		}

	}

	rc = sqlite3BtreeCommit(pBt);
	if (rc != SQLITE_OK) {
		printf("failed commit transaction: %d", rc);
	} else {
		puts("success commit transaction");
	}

	sqlite3_close(db);

	rc = sqlite3_open(file, &db);

	if (rc != SQLITE_OK) {
		printf("failed open: %d \n", rc);
		return;
	}

	if (db->nDb == 0) {
		puts("backends count is zero");
		goto close;
	}

	pBt = db->aDb[0].pBt;

	rc = sqlite3BtreeBeginTrans(pBt, 1);
	if (rc != SQLITE_OK) {
		printf("failed begin transaction: %d", rc);
		goto close;
	}

	int pages = 0;

	rc = sqlite3PagerPagecount(pBt->pBt->pPager, &pages);

	if (rc != SQLITE_OK) {
		printf("failed get pages count: %d \n", rc);
		goto close;
	}

	if (pages == 0) {
		puts("pages count is zero");
		goto close;
	}

	printf("pages count: %d \n", pages);


	pData = "Data test";
	nData = strlen(pData);

	x = 0;

	for (x = 1; x <= pages; x++) {

		memset(&cur, 0, sizeof(BtCursor));
		rc = sqlite3BtreeCursor(pBt, x, 1, 0, &cur);
		if (rc != SQLITE_OK) {
			printf("failed get cursor: %d", rc);
			goto close;
		}

		int next = 0;
		rc = sqlite3BtreeFirst(&cur, &next);
		if (rc != SQLITE_OK) {
			printf("failed first(): %d \n", rc);
			goto closeCursor;
		}

		if (next != 0) {
			puts("cursor is empty");
			goto closeCursor;
		}

		sqlite3BtreeCacheOverflow(&cur);

		do {

			rc = sqlite3BtreePutData(&cur,0,nData,pData);
			if (rc != SQLITE_OK) {
				printf("failed putData(): %d \n", rc);
				goto closeCursor;
			}

			puts("data updated");

		} while (SQLITE_OK == sqlite3BtreeNext(&cur, &next) && next == 0);

		closeCursor:
		rc = sqlite3BtreeCloseCursor(&cur);
		if (rc != SQLITE_OK) {
			printf("failed close cursor: %d", rc);
			goto close;
		}

	}

	rc = sqlite3BtreeCommit(pBt);
	if (rc != SQLITE_OK) {
		printf("failed commit transaction: %d", rc);
	} else {
		puts("success commit transaction");
	}


	close:
	sqlite3_close(db);

}
Exemplo n.º 4
0
/*
** Reset an Agg structure.  Delete all its contents.
**
** For installable aggregate functions, if the step function has been
** called, make sure the finalizer function has also been called.  The
** finalizer might need to free memory that was allocated as part of its
** private context.  If the finalizer has not been called yet, call it
** now.
**
** If db is NULL, then this is being called from sqliteVdbeReset(). In
** this case clean up all references to the temp-table used for
** aggregates (if it was ever opened).
**
** If db is not NULL, then this is being called from with an OP_AggReset
** opcode. Open the temp-table, if it has not already been opened and
** delete the contents of the table used for aggregate information, ready
** for the next round of aggregate processing.
*/
int sqlite3VdbeAggReset(sqlite3 *db, Agg *pAgg, KeyInfo *pKeyInfo){
  int rc = 0;
  BtCursor *pCsr = pAgg->pCsr;

  assert( (pCsr && pAgg->nTab>0) || (!pCsr && pAgg->nTab==0)
         || sqlite3_malloc_failed );

  /* If pCsr is not NULL, then the table used for aggregate information
  ** is open. Loop through it and free the AggElem* structure pointed at
  ** by each entry. If the finalizer has not been called for an AggElem,
  ** do that too. Finally, clear the btree table itself.
  */
  if( pCsr ){
    int res;
    assert( pAgg->pBtree );
    assert( pAgg->nTab>0 );

    rc=sqlite3BtreeFirst(pCsr, &res);
    while( res==0 && rc==SQLITE_OK ){
      AggElem *pElem;
      rc = sqlite3BtreeData(pCsr, 0, sizeof(AggElem*), (char *)&pElem);
      if( res!=SQLITE_OK ){
        return rc;
      }
      assert( pAgg->apFunc!=0 );
      freeAggElem(pElem, pAgg);
      rc=sqlite3BtreeNext(pCsr, &res);
    }
    if( rc!=SQLITE_OK ){
      return rc;
    }

    sqlite3BtreeCloseCursor(pCsr);
    sqlite3BtreeClearTable(pAgg->pBtree, pAgg->nTab);
  }else{ 
    /* The cursor may not be open because the aggregator was never used,
    ** or it could be that it was used but there was no GROUP BY clause.
    */
    if( pAgg->pCurrent ){
      freeAggElem(pAgg->pCurrent, pAgg);
    }
  }

  /* If db is not NULL and we have not yet and we have not yet opened
  ** the temporary btree then do so and create the table to store aggregate
  ** information.
  **
  ** If db is NULL, then close the temporary btree if it is open.
  */
  if( db ){
    if( !pAgg->pBtree ){
      assert( pAgg->nTab==0 );
      rc = sqlite3BtreeFactory(db, ":memory:", 0, TEMP_PAGES, &pAgg->pBtree);
      if( rc!=SQLITE_OK ) return rc;
      sqlite3BtreeBeginTrans(pAgg->pBtree, 1);
      rc = sqlite3BtreeCreateTable(pAgg->pBtree, &pAgg->nTab, 0);
      if( rc!=SQLITE_OK ) return rc;
    }
    assert( pAgg->nTab!=0 );

    rc = sqlite3BtreeCursor(pAgg->pBtree, pAgg->nTab, 1,
        sqlite3VdbeRecordCompare, pKeyInfo, &pAgg->pCsr);
    if( rc!=SQLITE_OK ) return rc;
  }else{
    if( pAgg->pBtree ){
      sqlite3BtreeClose(pAgg->pBtree);
      pAgg->pBtree = 0;
      pAgg->nTab = 0;
    }
    pAgg->pCsr = 0;
  }

  if( pAgg->apFunc ){ 
    sqliteFree(pAgg->apFunc);
    pAgg->apFunc = 0;
  }
  pAgg->pCurrent = 0;
  pAgg->nMem = 0;
  pAgg->searching = 0;
  return SQLITE_OK;
}