Esempio n. 1
0
/*
 * 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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
/*
 * 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;
}
Esempio n. 4
0
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;
}