int SLNSessionGetFileInfo(SLNSessionRef const session, strarg_t const URI, SLNFileInfo *const info) { DB_env *db = NULL; int rc = SLNSessionDBOpen(session, SLN_RDONLY, &db); if(rc < 0) return rc; DB_txn *txn = NULL; rc = db_txn_begin(db, NULL, DB_RDONLY, &txn); if(rc < 0) { SLNSessionDBClose(session, &db); return rc; } DB_cursor *cursor; rc = db_txn_cursor(txn, &cursor); assert(!rc); DB_range fileIDs[1]; SLNURIAndFileIDRange1(fileIDs, txn, URI); DB_val URIAndFileID_key[1]; rc = db_cursor_firstr(cursor, fileIDs, URIAndFileID_key, NULL, +1); DB_val file_val[1]; if(rc >= 0) { strarg_t URI2; uint64_t fileID; SLNURIAndFileIDKeyUnpack(URIAndFileID_key, txn, &URI2, &fileID); assert(0 == strcmp(URI, URI2)); if(info) { DB_val fileID_key[1]; SLNFileByIDKeyPack(fileID_key, txn, fileID); rc = db_get(txn, fileID_key, file_val); } } if(rc < 0) { db_txn_abort(txn); txn = NULL; SLNSessionDBClose(session, &db); return rc; } if(info) { // Clear padding for later assert_zeroed. memset(info, 0, sizeof(*info)); strarg_t const internalHash = db_read_string(file_val, txn); strarg_t const type = db_read_string(file_val, txn); uint64_t const size = db_read_uint64(file_val); info->hash = strdup(internalHash); info->path = SLNRepoCopyInternalPath(SLNSessionGetRepo(session), internalHash); info->type = strdup(type); info->size = size; if(!info->hash || !info->path || !info->type) { SLNFileInfoCleanup(info); db_txn_abort(txn); txn = NULL; SLNSessionDBClose(session, &db); return DB_ENOMEM; } } db_txn_abort(txn); txn = NULL; SLNSessionDBClose(session, &db); return 0; }
int SLNSessionCopyLastSubmissionURIs(SLNSessionRef const session, str_t *const outFileURI, str_t *const outMetaURI) { DB_env *db = NULL; DB_txn *txn = NULL; int rc = SLNSessionDBOpen(session, SLN_RDWR, &db); if(rc < 0) goto cleanup; rc = db_txn_begin(db, NULL, DB_RDONLY, &txn); if(rc < 0) goto cleanup; if(outFileURI) { DB_val key[1], val[1]; DB_VAL_STORAGE(key, DB_VARINT_MAX*2); db_bind_uint64(key, SLNLastFileURIBySessionID); db_bind_uint64(key, session->sessionID); DB_VAL_STORAGE_VERIFY(key); rc = db_get(txn, key, val); if(rc >= 0) { strarg_t const URI = db_read_string(val, txn); strlcpy(outFileURI, URI, SLN_URI_MAX); } else if(DB_NOTFOUND == rc) { outFileURI[0] = '\0'; rc = 0; } else { goto cleanup; } } if(outMetaURI) { DB_val key[1], val[1]; DB_VAL_STORAGE(key, DB_VARINT_MAX*2); db_bind_uint64(key, SLNLastMetaURIBySessionID); db_bind_uint64(key, session->sessionID); DB_VAL_STORAGE_VERIFY(key); rc = db_get(txn, key, val); if(rc >= 0) { strarg_t const URI = db_read_string(val, txn); strlcpy(outMetaURI, URI, SLN_URI_MAX); } else if(DB_NOTFOUND == rc) { outMetaURI[0] = '\0'; rc = 0; } else { goto cleanup; } } cleanup: db_txn_abort(txn); txn = NULL; SLNSessionDBClose(session, &db); return rc; }
int SLNFilterCopyURI(SLNFilterRef const filter, uint64_t const fileID, bool const meta, DB_txn *const txn, str_t **const out) { DB_val fileID_key[1], file_val[1]; SLNFileByIDKeyPack(fileID_key, txn, fileID); int rc = db_get(txn, fileID_key, file_val); if(rc < 0) return rc; strarg_t const hash = db_read_string(file_val, txn); db_assert(hash); str_t *URI = NULL; if(!meta) { URI = SLNFormatURI(SLN_INTERNAL_ALGO, hash); if(!URI) return DB_ENOMEM; } else { DB_val key[1], val[1]; SLNMetaFileByIDKeyPack(key, txn, fileID); rc = db_get(txn, key, val); if(rc < 0) return rc; uint64_t f; strarg_t target = NULL; SLNMetaFileByIDValUnpack(val, txn, &f, &target); db_assert(target); URI = aasprintf("hash://%s/%s -> %s", SLN_INTERNAL_ALGO, hash, target); if(!URI) return DB_ENOMEM; } *out = URI; URI = NULL; return 0; }