Skip to content

Commit 3a0fb9a

Browse files
committed
fixup! Add protocol compliant PostgresKvStore impl.
1 parent 2e82585 commit 3a0fb9a

File tree

1 file changed

+35
-18
lines changed

1 file changed

+35
-18
lines changed

rust/impls/src/postgres_store.rs

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,19 @@ const KEY_COLUMN: &str = "key";
2727
const VALUE_COLUMN: &str = "value";
2828
const VERSION_COLUMN: &str = "version";
2929

30-
const LIST_KEY_VERSIONS_MAX_PAGE_SIZE: i32 = 100;
30+
/// The maximum number of key versions that can be returned in a single page.
31+
///
32+
/// This constant helps control memory and bandwidth usage for list operations,
33+
/// preventing overly large payloads. If the number of results exceeds this limit,
34+
/// the response will be paginated.
35+
pub const LIST_KEY_VERSIONS_MAX_PAGE_SIZE: i32 = 100;
36+
37+
/// The maximum number of items allowed in a single `PutObjectRequest`.
38+
///
39+
/// Setting an upper bound on the number of items helps ensure that
40+
/// each request stays within acceptable memory and performance limits.
41+
/// Exceeding this value will result in request rejection through [`VssError::InvalidRequestError`].
42+
pub const MAX_PUT_REQUEST_ITEM_COUNT: usize = 1000;
3143

3244
/// A [PostgreSQL](https://www.postgresql.org/) based backend implementation for VSS.
3345
pub struct PostgresBackendImpl {
@@ -47,12 +59,12 @@ impl PostgresBackendImpl {
4759
Ok(PostgresBackendImpl { pool })
4860
}
4961

50-
fn build_vss_record(&self, user_token: &str, store_id: &str, kv: &KeyValue) -> VssDbRecord {
62+
fn build_vss_record(&self, user_token: String, store_id: String, kv: KeyValue) -> VssDbRecord {
5163
let now = Utc::now();
5264
VssDbRecord {
53-
user_token: user_token.to_string(),
54-
store_id: store_id.to_string(),
55-
key: kv.key.clone(),
65+
user_token,
66+
store_id,
67+
key: kv.key,
5668
value: kv.value.to_vec(),
5769
version: kv.version,
5870
created_at: now,
@@ -227,28 +239,30 @@ impl KvStore for PostgresBackendImpl {
227239
&self, user_token: String, request: PutObjectRequest,
228240
) -> Result<PutObjectResponse, VssError> {
229241
let store_id = &request.store_id;
230-
if request.transaction_items.len() + request.delete_items.len() > 1000 {
231-
return Err(VssError::InvalidRequestError(
232-
"Number of write items per request should be less than equal to 1000".to_string(),
233-
));
242+
if request.transaction_items.len() + request.delete_items.len() > MAX_PUT_REQUEST_ITEM_COUNT
243+
{
244+
return Err(VssError::InvalidRequestError(format!(
245+
"Number of write items per request should be less than equal to {}",
246+
MAX_PUT_REQUEST_ITEM_COUNT
247+
)));
234248
}
235249
let mut vss_put_records: Vec<VssDbRecord> = request
236250
.transaction_items
237-
.iter()
238-
.map(|kv| self.build_vss_record(&user_token, store_id, kv))
251+
.into_iter()
252+
.map(|kv| self.build_vss_record(user_token.to_string(), store_id.to_string(), kv))
239253
.collect();
240254

241255
let vss_delete_records: Vec<VssDbRecord> = request
242256
.delete_items
243-
.iter()
244-
.map(|kv| self.build_vss_record(&user_token, store_id, kv))
257+
.into_iter()
258+
.map(|kv| self.build_vss_record(user_token.to_string(), store_id.to_string(), kv))
245259
.collect();
246260

247261
if let Some(global_version) = request.global_version {
248262
let global_version_record = self.build_vss_record(
249-
&user_token,
250-
store_id,
251-
&KeyValue {
263+
user_token,
264+
store_id.to_string(),
265+
KeyValue {
252266
key: GLOBAL_VERSION_KEY.to_string(),
253267
value: Bytes::new(),
254268
version: global_version,
@@ -300,7 +314,10 @@ impl KvStore for PostgresBackendImpl {
300314
&self, user_token: String, request: DeleteObjectRequest,
301315
) -> Result<DeleteObjectResponse, VssError> {
302316
let store_id = &request.store_id;
303-
let vss_record = self.build_vss_record(&user_token, store_id, &request.key_value.unwrap());
317+
let key_value = request.key_value.ok_or_else(|| {
318+
VssError::InvalidRequestError("key_value missing in DeleteObjectRequest".to_string())
319+
})?;
320+
let vss_record = self.build_vss_record(user_token, store_id.to_string(), key_value);
304321

305322
let mut conn = self
306323
.pool
@@ -362,7 +379,7 @@ impl KvStore for PostgresBackendImpl {
362379
let key_like = format!("{}%", key_prefix.as_deref().unwrap_or(""));
363380
let page_token_param = page_token.as_deref().unwrap_or("");
364381
let params: Vec<&(dyn tokio_postgres::types::ToSql + Sync)> =
365-
vec![&user_token, &store_id, &page_token_param, &key_like, &(limit)];
382+
vec![&user_token, &store_id, &page_token_param, &key_like, &limit];
366383

367384
let rows = conn
368385
.query(stmt, &params)

0 commit comments

Comments
 (0)