Make SQLBlob overwrite on put rather than ignoring

Summary:
We want to end up with two `put` behaviours - overwrite and do not overwrite.

Currently, SQLBlob only implements the latter, but some users assume that `put` always overwrites. Change to match Manifold

Reviewed By: aslpavel

Differential Revision: D24079501

fbshipit-source-id: f75cac81acf874337c38f82597aae645c41a319b
This commit is contained in:
Simon Farnsworth 2020-10-02 10:39:27 -07:00 committed by Facebook GitHub Bot
parent 4197dfd689
commit 83801357d4
2 changed files with 56 additions and 1 deletions

View File

@ -76,6 +76,16 @@ queries! {
) VALUES {values}"
}
write UpdateData(id: &str, ctime: i64, chunk_id: &str, chunk_count: u32, chunking_method: ChunkingMethod) {
none,
"UPDATE data SET
creation_time = {ctime}
, chunk_id = {chunk_id}
, chunk_count = {chunk_count}
, chunking_method = {chunking_method}
WHERE id = {id}"
}
write InsertChunk(values: (id: &str, chunk_num: u32, value: &[u8])) {
insert_or_ignore,
"{insert_or_ignore} INTO chunk (
@ -177,12 +187,24 @@ impl DataSqlStore {
self.delay.delay(shard_id).await;
InsertData::query(
let res = InsertData::query(
&self.write_connection[shard_id],
&[(&key, &ctime, &chunk_id, &chunk_count, &chunking_method)],
)
.compat()
.await?;
if res.affected_rows() == 0 {
UpdateData::query(
&self.write_connection[shard_id],
&key,
&ctime,
&chunk_id,
&chunk_count,
&chunking_method,
)
.compat()
.await?;
}
Ok(())
}

View File

@ -77,6 +77,39 @@ async fn double_put(fb: FacebookInit) {
);
}
#[fbinit::compat_test]
async fn overwrite(fb: FacebookInit) -> Result<()> {
let ctx = CoreContext::test_mock(fb);
// Generate unique keys.
let suffix: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
let key = format!("manifoldblob_test_{}", suffix);
let bs = Arc::new(Sqlblob::with_sqlite_in_memory().unwrap());
let mut bytes_1 = [0u8; 64];
thread_rng().fill_bytes(&mut bytes_1);
let mut bytes_2 = [0u8; 32];
thread_rng().fill_bytes(&mut bytes_2);
let blobstore_bytes_1 = BlobstoreBytes::from_bytes(Bytes::copy_from_slice(&bytes_1));
let blobstore_bytes_2 = BlobstoreBytes::from_bytes(Bytes::copy_from_slice(&bytes_2));
// Write a fresh blob
bs.put(ctx.clone(), key.clone(), blobstore_bytes_1.clone())
.await?;
// Overwrite it
bs.put(ctx.clone(), key.clone(), blobstore_bytes_2.clone())
.await?;
assert_eq!(
bs.get(ctx.clone(), key.clone())
.await?
.map(|get| get.into_bytes()),
Some(blobstore_bytes_2),
);
Ok(())
}
#[fbinit::compat_test]
async fn dedup(fb: FacebookInit) {
let ctx = CoreContext::test_mock(fb);