/* * Drop a record from a given collection. */ UNQLITE_PRIVATE int unqliteCollectionDropRecord( unqlite_col *pCol, /* Target collection */ jx9_int64 nId, /* Unique ID of the record to be droped */ int wr_header, /* True to alter collection header */ int log_err /* True to log error */ ) { SyBlob *pWorker = &pCol->sWorker; int rc; /* Reset the working buffer */ SyBlobReset(pWorker); /* Prepare the unique ID for this record */ SyBlobFormat(pWorker,"%z_%qd",&pCol->sName,nId); /* Reset the cursor */ unqlite_kv_cursor_reset(pCol->pCursor); /* Seek the cursor to the desired location */ rc = unqlite_kv_cursor_seek(pCol->pCursor, SyBlobData(pWorker),SyBlobLength(pWorker), UNQLITE_CURSOR_MATCH_EXACT ); if( rc != UNQLITE_OK ){ return rc; } /* Remove the record from the storage engine */ rc = unqlite_kv_cursor_delete_entry(pCol->pCursor); /* Finally, Remove the record from the cache */ unqliteCollectionCacheRemoveRecord(pCol,nId); if( rc == UNQLITE_OK ){ pCol->nTotRec--; if( wr_header ){ /* Relect in the collection header */ rc = CollectionSetHeader(0,pCol,-1,pCol->nTotRec,0); } }else if( rc == UNQLITE_NOTIMPLEMENTED ){ if( log_err ){ unqliteGenErrorFormat(pCol->pVm->pDb, "Cannot delete record from collection '%z' due to a read-only Key/Value storage engine", &pCol->sName ); } } return rc; }
/* * array db_fetch_all(string $col_name,[callback filter_callback]) * array db_get_all(string $col_name,[callback filter_callback]) * Retrieve all records of a given collection and apply the given * callback if available to filter records. * Parameter * col_name: Collection name * Return * Contents of the collection (JSON array) on success. NULL on failure. */ static int unqliteBuiltin_db_fetch_all(jx9_context *pCtx,int argc,jx9_value **argv) { unqlite_col *pCol; const char *zName; unqlite_vm *pVm; SyString sName; int nByte; int rc; /* Extract collection name */ if( argc < 1 ){ /* Missing arguments */ jx9_context_throw_error(pCtx,JX9_CTX_ERR,"Missing collection name"); /* Return NULL */ jx9_result_null(pCtx); return JX9_OK; } zName = jx9_value_to_string(argv[0],&nByte); if( nByte < 1){ jx9_context_throw_error(pCtx,JX9_CTX_ERR,"Invalid collection name"); /* Return NULL */ jx9_result_null(pCtx); return JX9_OK; } SyStringInitFromBuf(&sName,zName,nByte); pVm = (unqlite_vm *)jx9_context_user_data(pCtx); /* Fetch the collection */ pCol = unqliteCollectionFetch(pVm,&sName,UNQLITE_VM_AUTO_LOAD); if( pCol ){ jx9_value *pValue,*pArray,*pCallback = 0; jx9_value sResult; /* Callback result */ /* Allocate an empty scalar value and an empty JSON array */ pArray = jx9_context_new_array(pCtx); pValue = jx9_context_new_scalar(pCtx); jx9MemObjInit(pCtx->pVm,&sResult); if( pValue == 0 || pArray == 0 ){ jx9_context_throw_error(pCtx,JX9_CTX_ERR,"Jx9 is running out of memory"); jx9_result_null(pCtx); return JX9_OK; } if( argc > 1 && jx9_value_is_callable(argv[1]) ){ pCallback = argv[1]; } unqliteCollectionResetRecordCursor(pCol); /* Fetch collection records one after one */ while( UNQLITE_OK == unqliteCollectionFetchNextRecord(pCol,pValue) ){ if( pCallback ){ jx9_value *apArg[2]; /* Invoke the filter callback */ apArg[0] = pValue; rc = jx9VmCallUserFunction(pCtx->pVm,pCallback,1,apArg,&sResult); if( rc == JX9_OK ){ int iResult; /* Callback result */ /* Extract callback result */ iResult = jx9_value_to_bool(&sResult); if( !iResult ){ /* Discard the result */ unqliteCollectionCacheRemoveRecord(pCol,unqliteCollectionCurrentRecordId(pCol) - 1); continue; } } } /* Put the value in the JSON array */ jx9_array_add_elem(pArray,0,pValue); /* Release the value */ jx9_value_null(pValue); } jx9MemObjRelease(&sResult); /* Finally, return our array */ jx9_result_value(pCtx,pArray); /* pValue will be automatically released as soon we return from * this foreign function. */ }else{ /* No such collection, return null */ jx9_result_null(pCtx); } return JX9_OK; }