static ham_status_t _remote_cursor_move(ham_cursor_t *cursor, ham_key_t *key, ham_record_t *record, ham_u32_t flags) { ham_status_t st; ham_db_t *db=cursor_get_db(cursor); ham_env_t *env=db_get_env(db); proto_wrapper_t *request, *reply; request=proto_init_cursor_move_request(cursor_get_remote_handle(cursor), key, record, flags); st=_perform_request(env, env_get_curl(env), request, &reply); proto_delete(request); if (st) { if (reply) proto_delete(reply); return (st); } ham_assert(reply!=0, ("")); ham_assert(proto_has_cursor_move_reply(reply)!=0, ("")); st=proto_cursor_move_reply_get_status(reply); if (st) goto bail; /* modify key/record, but make sure that USER_ALLOC is respected! */ if (proto_cursor_move_reply_has_key(reply)) { ham_assert(key, ("")); key->_flags=proto_cursor_move_reply_get_key_intflags(reply); key->size=proto_cursor_move_reply_get_key_size(reply); if (!(key->flags&HAM_KEY_USER_ALLOC)) { st=db_resize_key_allocdata(db, key->size); if (st) goto bail; key->data=db_get_key_allocdata(db); } memcpy(key->data, proto_cursor_move_reply_get_key_data(reply), key->size); } /* same for the record */ if (proto_cursor_move_reply_has_record(reply)) { ham_assert(record, ("")); record->size=proto_cursor_move_reply_get_record_size(reply); if (!(record->flags&HAM_RECORD_USER_ALLOC)) { st=db_resize_record_allocdata(db, record->size); if (st) goto bail; record->data=db_get_record_allocdata(db); } memcpy(record->data, proto_cursor_move_reply_get_record_data(reply), record->size); } bail: proto_delete(reply); return (st); }
static ham_status_t _remote_fun_find(ham_db_t *db, ham_txn_t *txn, ham_key_t *key, ham_record_t *record, ham_u32_t flags) { ham_status_t st; ham_env_t *env=db_get_env(db); proto_wrapper_t *request, *reply; request=proto_init_db_find_request(db_get_remote_handle(db), txn ? txn_get_remote_handle(txn) : 0, key, record, flags); st=_perform_request(env, env_get_curl(env), request, &reply); proto_delete(request); if (st) { if (reply) proto_delete(reply); return (st); } ham_assert(reply!=0, ("")); ham_assert(proto_has_db_find_reply(reply)!=0, ("")); st=proto_db_find_reply_get_status(reply); if (st==0) { /* approx. matching: need to copy the _flags and the key data! */ if (proto_db_find_reply_has_key(reply)) { ham_assert(key, ("")); key->_flags=proto_db_find_reply_get_key_intflags(reply); key->size=proto_db_find_reply_get_key_size(reply); if (!(key->flags&HAM_KEY_USER_ALLOC)) { st=db_resize_key_allocdata(db, key->size); if (st) goto bail; key->data=db_get_key_allocdata(db); } memcpy(key->data, proto_db_find_reply_get_key_data(reply), key->size); } if (proto_db_find_reply_has_record(reply)) { record->size=proto_db_find_reply_get_record_size(reply); if (!(record->flags&HAM_RECORD_USER_ALLOC)) { st=db_resize_record_allocdata(db, record->size); if (st) goto bail; record->data=db_get_record_allocdata(db); } memcpy(record->data, proto_db_find_reply_get_record_data(reply), record->size); } } bail: proto_delete(reply); return (st); }
static ham_status_t _remote_cursor_find(ham_cursor_t *cursor, ham_key_t *key, ham_record_t *record, ham_u32_t flags) { ham_status_t st; ham_db_t *db=cursor_get_db(cursor); ham_env_t *env=db_get_env(db); proto_wrapper_t *request, *reply; request=proto_init_cursor_find_request(cursor_get_remote_handle(cursor), key, record, flags); st=_perform_request(env, env_get_curl(env), request, &reply); proto_delete(request); if (st) { if (reply) proto_delete(reply); return (st); } ham_assert(reply!=0, ("")); ham_assert(proto_has_cursor_find_reply(reply)!=0, ("")); st=proto_cursor_find_reply_get_status(reply); if (st) goto bail; /* approx. matching: need to copy the _flags! */ if (proto_cursor_find_reply_has_key(reply)) { key->_flags=proto_cursor_find_reply_get_key_intflags(reply); } if (proto_cursor_find_reply_has_record(reply)) { ham_assert(record, ("")); record->size=proto_cursor_find_reply_get_record_size(reply); if (!(record->flags&HAM_RECORD_USER_ALLOC)) { st=db_resize_record_allocdata(db, record->size); if (st) goto bail; record->data=db_get_record_allocdata(db); } memcpy(record->data, proto_cursor_find_reply_get_record_data(reply), record->size); } bail: proto_delete(reply); return (st); }
ham_status_t blob_read(ham_db_t *db, ham_offset_t blobid, ham_record_t *record, ham_u32_t flags) { ham_status_t st; ham_page_t *page; blob_t hdr; ham_size_t blobsize=0; /* * in-memory-database: the blobid is actually a pointer to the memory * buffer, in which the blob is stored */ if (env_get_rt_flags(db_get_env(db))&HAM_IN_MEMORY_DB) { blob_t *hdr=(blob_t *)U64_TO_PTR(blobid); ham_u8_t *data=(ham_u8_t *)(U64_TO_PTR(blobid))+sizeof(blob_t); /* when the database is closing, the header is already deleted */ if (!hdr) { record->size = 0; return (0); } blobsize = (ham_size_t)blob_get_size(hdr); if (flags&HAM_PARTIAL) { if (record->partial_offset>blobsize) { ham_trace(("partial offset is greater than the total " "record size")); return (HAM_INV_PARAMETER); } if (record->partial_offset+record->partial_size>blobsize) blobsize=blobsize-record->partial_offset; else blobsize=record->partial_size; } if (!blobsize) { /* empty blob? */ record->data = 0; record->size = 0; } else { ham_u8_t *d=data; if (flags&HAM_PARTIAL) d+=record->partial_offset; if ((flags&HAM_DIRECT_ACCESS) && !(record->flags&HAM_RECORD_USER_ALLOC)) { record->size=blobsize; record->data=d; } else { /* resize buffer, if necessary */ if (!(record->flags & HAM_RECORD_USER_ALLOC)) { st=db_resize_record_allocdata(db, blobsize); if (st) return (st); record->data = db_get_record_allocdata(db); } /* and copy the data */ memcpy(record->data, d, blobsize); record->size = blobsize; } } return (0); } ham_assert(blobid%DB_CHUNKSIZE==0, ("blobid is %llu", blobid)); /* * first step: read the blob header */ st=__read_chunk(db_get_env(db), 0, &page, blobid, (ham_u8_t *)&hdr, sizeof(hdr)); if (st) return (st); ham_assert(blob_get_alloc_size(&hdr)%DB_CHUNKSIZE==0, (0)); /* * sanity check */ if (blob_get_self(&hdr)!=blobid) return (HAM_BLOB_NOT_FOUND); blobsize = (ham_size_t)blob_get_size(&hdr); if (flags&HAM_PARTIAL) { if (record->partial_offset>blobsize) { ham_trace(("partial offset+size is greater than the total " "record size")); return (HAM_INV_PARAMETER); } if (record->partial_offset+record->partial_size>blobsize) blobsize=blobsize-record->partial_offset; else blobsize=record->partial_size; } /* * empty blob? */ if (!blobsize) { record->data = 0; record->size = 0; return (0); } /* * second step: resize the blob buffer */ if (!(record->flags & HAM_RECORD_USER_ALLOC)) { st=db_resize_record_allocdata(db, blobsize); if (st) return (st); record->data = db_get_record_allocdata(db); } /* * third step: read the blob data */ st=__read_chunk(db_get_env(db), page, 0, blobid+sizeof(blob_t)+(flags&HAM_PARTIAL ? record->partial_offset : 0), record->data, blobsize); if (st) return (st); record->size = blobsize; return (0); }