/* * Fetch a record by its unique ID. */ UNQLITE_PRIVATE int unqliteCollectionFetchRecordById( unqlite_col *pCol, /* Target collection */ jx9_int64 nId, /* Unique record ID */ jx9_value *pValue /* OUT: record value */ ) { SyBlob *pWorker = &pCol->sWorker; unqlite_col_record *pRec; int rc; jx9_value_null(pValue); /* Perform a cache lookup first */ pRec = CollectionCacheFetchRecord(pCol,nId); if( pRec ){ /* Copy record value */ jx9MemObjStore(&pRec->sValue,pValue); return UNQLITE_OK; } /* Reset the working buffer */ SyBlobReset(pWorker); /* Generate the unique ID */ 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; } /* Consume the binary JSON */ SyBlobReset(pWorker); unqlite_kv_cursor_data_callback(pCol->pCursor,unqliteDataConsumer,pWorker); if( SyBlobLength(pWorker) < 1 ){ unqliteGenErrorFormat(pCol->pVm->pDb, "Empty record '%qd'",nId ); jx9_value_null(pValue); }else{ /* Decode the binary JSON */ rc = FastJsonDecode(SyBlobData(pWorker),SyBlobLength(pWorker),pValue,0,0); if( rc == UNQLITE_OK ){ /* Install the record in the cache */ CollectionCacheInstallRecord(pCol,nId,pValue); } } return rc; }
ValueBuffer* UnqliteCursor::get_data( bool as_binary, sxi64 value_len, pyunqlite::UserCallback* callback, pyunqlite::ValueBuffer* direct_buffer ) { ValueBuffer* value = 0; // setup the buffer for retrieving data if (direct_buffer) { if (value_len < 0) value_len = direct_buffer->get_data_len(); else if (direct_buffer->get_data_len() < value_len) throw UnqliteException(UNQLITE_INVALID); value = new ValueBuffer(*direct_buffer); } else if (!callback) { // determine the size of the stored data if it is unknown if (value_len < 0) value_len = get_data_len(); // create a new buffer value = new ValueBuffer(as_binary, value_len); if (!value) throw UnqliteException(UNQLITE_NOMEM); } int rc; if (callback) { rc = unqlite_kv_cursor_data_callback( this->_cursor, callback->get_unqlite_callback_function(), callback->get_unqlite_callback_data() ); } else { rc = unqlite_kv_cursor_data(this->_cursor, value->get_data(), &value_len); } if (callback && (rc == UNQLITE_ABORT)) callback->process_exception(); else if (rc != UNQLITE_OK) throw UnqliteException(rc, this->_db); return value; }
/* * Load a binary collection from disk. */ static int CollectionLoadHeader(unqlite_col *pCol) { SyBlob *pHeader = &pCol->sHeader; unsigned char *zRaw,*zEnd; sxu16 nMagic; sxu32 iDos; int rc; SyBlobReset(pHeader); /* Read the binary header */ rc = unqlite_kv_cursor_data_callback(pCol->pCursor,unqliteDataConsumer,pHeader); if( rc != UNQLITE_OK ){ return rc; } /* Perform a sanity check */ if( SyBlobLength(pHeader) < (2 /* magic */ + 8 /* record_id */ + 8 /* total_records */+ 4 /* DOS creation time*/) ){ return UNQLITE_CORRUPT; } zRaw = (unsigned char *)SyBlobData(pHeader); zEnd = &zRaw[SyBlobLength(pHeader)]; /* Extract the magic number */ SyBigEndianUnpack16(zRaw,&nMagic); if( nMagic != UNQLITE_COLLECTION_MAGIC ){ return UNQLITE_CORRUPT; } zRaw += 2; /* sizeof(sxu16) */ /* Extract the record ID */ SyBigEndianUnpack64(zRaw,(sxu64 *)&pCol->nLastid); zRaw += 8; /* sizeof(sxu64) */ /* Total records in the collection */ SyBigEndianUnpack64(zRaw,(sxu64 *)&pCol->nTotRec); /* Extract the collection creation date (DOS) */ zRaw += 8; /* sizeof(sxu64) */ SyBigEndianUnpack32(zRaw,&iDos); SyDosTimeFormat(iDos,&pCol->sCreation); zRaw += 4; /* Check for a collection schema */ pCol->nSchemaOfft = (sxu32)(zRaw - (unsigned char *)SyBlobData(pHeader)); if( zRaw < zEnd ){ /* Decode the FastJson value */ FastJsonDecode((const void *)zRaw,(sxu32)(zEnd-zRaw),&pCol->sSchema,0,0); } return UNQLITE_OK; }
bool KVUnqlite::getRecords(const std::string& filter, Records& records) { unqlite* pDbHandle = static_cast<unqlite*>(_pDbHandle); if (!pDbHandle) { return false; } unqlite_kv_cursor* pCursor = 0; if (unqlite_kv_cursor_init(pDbHandle, &pCursor) != UNQLITE_OK || !pCursor) { log_error(); return false; } RecordConsumer consumer; consumer.filter = filter; consumer.records = &records; /* Point to the first record */ for ( unqlite_kv_cursor_first_entry(pCursor); unqlite_kv_cursor_valid_entry(pCursor); unqlite_kv_cursor_next_entry(pCursor)) { unqlite_kv_cursor_key_callback(pCursor, RecordConsumerCallback,(void*)&consumer); if (!consumer.key.empty()) { // // We got a key so consume the data // unqlite_kv_cursor_data_callback(pCursor, RecordConsumerCallback,(void*)&consumer); } } unqlite_kv_cursor_release(pDbHandle, pCursor); return true; }