commit cloud: Use changeset handlers in data structures

Summary:
So for commit cloud there's two DBs, `xdb.commit_cloud`(prod) and a sqlite one we use for test and that we're aiming to move to as we move more things over to mononoke.  I'm trying to make these queries as deduped as possible so there's a seamless db usage instead of having to define everything twice.

One of the main differences is that we store hex-encoded commits in `xdb.commit_cloud`, so, the previous diff added functions that encode changesets depending on the db type, and here we just use them in the existing data structures. Technically we could still simply use `HgChangesetId`for sqlite and bytes for mysql. But again, I'm trying to make this as seamless and possible and abstract all of the minor type casting within the db and avoid duplication.

Differential Revision: D56597877

fbshipit-source-id: a02ea5ee0f55e06baaae9b45532e2da2251a565b
This commit is contained in:
Luisa Vasquez Gomez 2024-04-29 16:16:34 -07:00 committed by Facebook GitHub Bot
parent 93cbf4c687
commit 4170dd22a4
7 changed files with 64 additions and 35 deletions

View File

@ -13,5 +13,5 @@ pub mod local_bookmarks;
pub mod ops;
pub mod remote_bookmarks;
pub mod snapshots;
pub(crate) mod utils;
pub mod utils;
pub mod versions;

View File

@ -16,6 +16,9 @@ use crate::sql::ops::Get;
use crate::sql::ops::Insert;
use crate::sql::ops::SqlCommitCloud;
use crate::sql::ops::Update;
use crate::sql::utils::changeset_as_bytes;
use crate::sql::utils::changeset_from_bytes;
use crate::sql::utils::list_as_bytes;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct WorkspaceHead {
pub commit: HgChangesetId,
@ -26,18 +29,16 @@ pub struct DeleteArgs {
}
mononoke_queries! {
read GetHeads(reponame: String, workspace: String) -> (String, HgChangesetId){
"SELECT `reponame`, `commit` FROM `heads`
WHERE `reponame`={reponame} AND `workspace`={workspace}
ORDER BY `seq`"
read GetHeads(reponame: String, workspace: String) -> (String, Vec<u8>){
"SELECT `reponame`, `commit` FROM `heads` WHERE `reponame`={reponame} AND `workspace`={workspace} ORDER BY `seq`"
}
write DeleteHead(reponame: String, workspace: String, >list commits: HgChangesetId) {
write DeleteHead(reponame: String, workspace: String, >list commits: Vec<u8>) {
none,
"DELETE FROM `heads` WHERE `reponame`={reponame} AND `workspace`={workspace} AND `commit` IN {commits}"
}
write InsertHead(reponame: String, workspace: String, commit: HgChangesetId) {
write InsertHead(reponame: String, workspace: String, commit: Vec<u8>) {
none,
"INSERT INTO `heads` (`reponame`, `workspace`, `commit`) VALUES ({reponame}, {workspace}, {commit})"
}
@ -49,7 +50,11 @@ impl Get<WorkspaceHead> for SqlCommitCloud {
let rows =
GetHeads::query(&self.connections.read_connection, &reponame, &workspace).await?;
rows.into_iter()
.map(|(_reponame, commit)| Ok(WorkspaceHead { commit }))
.map(|(_reponame, commit)| {
Ok(WorkspaceHead {
commit: changeset_from_bytes(&commit, self.uses_mysql)?,
})
})
.collect::<anyhow::Result<Vec<WorkspaceHead>>>()
}
}
@ -66,7 +71,7 @@ impl Insert<WorkspaceHead> for SqlCommitCloud {
&self.connections.write_connection,
&reponame,
&workspace,
&data.commit,
&changeset_as_bytes(&data.commit, self.uses_mysql)?,
)
.await?;
Ok(())
@ -101,7 +106,7 @@ impl Delete<WorkspaceHead> for SqlCommitCloud {
&self.connections.write_connection,
&reponame,
&workspace,
args.removed_commits.as_slice(),
&list_as_bytes(args.removed_commits, self.uses_mysql)?,
)
.await?;
Ok(())

View File

@ -17,6 +17,9 @@ use crate::sql::ops::Get;
use crate::sql::ops::Insert;
use crate::sql::ops::SqlCommitCloud;
use crate::sql::ops::Update;
use crate::sql::utils::changeset_as_bytes;
use crate::sql::utils::changeset_from_bytes;
use crate::sql::utils::list_as_bytes;
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
pub struct WorkspaceLocalBookmark {
@ -29,15 +32,14 @@ pub struct DeleteArgs {
}
mononoke_queries! {
read GetLocalBookmarks(reponame: String, workspace: String) -> (String, HgChangesetId){
"SELECT `name`, `commit` FROM `workspacebookmarks`
WHERE `reponame`={reponame} AND `workspace`={workspace}"
read GetLocalBookmarks(reponame: String, workspace: String) -> (String, Vec<u8>){
"SELECT `name`, `commit` FROM `workspacebookmarks` WHERE `reponame`={reponame} AND `workspace`={workspace}"
}
write DeleteLocalBookmark(reponame: String, workspace: String, >list removed_bookmarks: HgChangesetId) {
write DeleteLocalBookmark(reponame: String, workspace: String, >list removed_bookmarks: Vec<u8>) {
none,
"DELETE FROM `workspacebookmarks` WHERE `reponame`={reponame} AND `workspace`={workspace} AND `commit` IN {removed_bookmarks}"
}
write InsertLocalBookmark(reponame: String, workspace: String, name: String, commit: HgChangesetId) {
write InsertLocalBookmark(reponame: String, workspace: String, name: String, commit: Vec<u8>) {
none,
"INSERT INTO `workspacebookmarks` (`reponame`, `workspace`, `name`, `commit`) VALUES ({reponame}, {workspace}, {name}, {commit})"
}
@ -57,7 +59,12 @@ impl Get<WorkspaceLocalBookmark> for SqlCommitCloud {
)
.await?;
rows.into_iter()
.map(|(name, commit)| Ok(WorkspaceLocalBookmark { name, commit }))
.map(|(name, commit)| {
Ok(WorkspaceLocalBookmark {
name,
commit: changeset_from_bytes(&commit, self.uses_mysql)?,
})
})
.collect::<anyhow::Result<Vec<WorkspaceLocalBookmark>>>()
}
}
@ -75,7 +82,7 @@ impl Insert<WorkspaceLocalBookmark> for SqlCommitCloud {
&reponame,
&workspace,
&data.name,
&data.commit,
&changeset_as_bytes(&data.commit, self.uses_mysql)?,
)
.await?;
Ok(())
@ -110,7 +117,7 @@ impl Delete<WorkspaceLocalBookmark> for SqlCommitCloud {
&self.connections.write_connection,
&reponame,
&workspace,
args.removed_bookmarks.as_slice(),
&list_as_bytes(args.removed_bookmarks, self.uses_mysql)?,
)
.await?;
Ok(())

View File

@ -17,7 +17,7 @@ pub struct SqlCommitCloud {
// 3. mock mysql db (test) This is used in integration tests, it's never queried or populated,
/// just there to avoid a clash between "bookmarks" tables
#[allow(unused)]
uses_mysql: bool,
pub(crate) uses_mysql: bool,
}
impl SqlCommitCloud {

View File

@ -16,7 +16,8 @@ use crate::sql::ops::Get;
use crate::sql::ops::Insert;
use crate::sql::ops::SqlCommitCloud;
use crate::sql::ops::Update;
use crate::sql::utils::changeset_as_bytes;
use crate::sql::utils::changeset_from_bytes;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct WorkspaceRemoteBookmark {
pub name: String,
@ -29,16 +30,16 @@ pub struct DeleteArgs {
}
mononoke_queries! {
read GetRemoteBookmarks(reponame: String, workspace: String) -> (String, String, HgChangesetId){
"SELECT `remote`, `name`, `commit` FROM `remotebookmarks`
WHERE `reponame`={reponame} AND `workspace`={workspace}"
read GetRemoteBookmarks(reponame: String, workspace: String) -> (String, String, Vec<u8>){
"SELECT `remote`, `name`, `commit` FROM `remotebookmarks` WHERE `reponame`={reponame} AND `workspace`={workspace}"
}
//TODO: Handle changesets as bytes (migth require an entirely different query)
write DeleteRemoteBookmark(reponame: String, workspace: String, >list removed_bookmarks: String) {
none,
mysql("DELETE FROM `remotebookmarks` WHERE `reponame`={reponame} AND `workspace`={workspace} AND CONCAT(`remote`, '/', `name`) IN {removed_bookmarks}")
sqlite( "DELETE FROM `remotebookmarks` WHERE `reponame`={reponame} AND `workspace`={workspace} AND CAST(`remote`||'/'||`name` AS BLOB) IN {removed_bookmarks}")
}
write InsertRemoteBookmark(reponame: String, workspace: String, remote: String, name: String, commit: HgChangesetId) {
write InsertRemoteBookmark(reponame: String, workspace: String, remote: String, name: String, commit: Vec<u8>) {
none,
"INSERT INTO `remotebookmarks` (`reponame`, `workspace`, `remote`,`name`, `commit` ) VALUES ({reponame}, {workspace}, {remote}, {name}, {commit})"
}
@ -61,7 +62,7 @@ impl Get<WorkspaceRemoteBookmark> for SqlCommitCloud {
.map(|(remote, name, commit)| {
Ok(WorkspaceRemoteBookmark {
name,
commit,
commit: changeset_from_bytes(&commit, self.uses_mysql)?,
remote,
})
})
@ -83,7 +84,7 @@ impl Insert<WorkspaceRemoteBookmark> for SqlCommitCloud {
&workspace,
&data.remote,
&data.name,
&data.commit,
&changeset_as_bytes(&data.commit, self.uses_mysql)?,
)
.await?;
Ok(())

View File

@ -14,6 +14,9 @@ use crate::sql::ops::Get;
use crate::sql::ops::Insert;
use crate::sql::ops::SqlCommitCloud;
use crate::sql::ops::Update;
use crate::sql::utils::changeset_as_bytes;
use crate::sql::utils::changeset_from_bytes;
use crate::sql::utils::list_as_bytes;
#[derive(Clone, Debug, PartialEq)]
pub struct WorkspaceSnapshot {
@ -25,18 +28,16 @@ pub struct DeleteArgs {
}
mononoke_queries! {
read GetSnapshots(reponame: String, workspace: String) -> (String, HgChangesetId){
"SELECT `reponame`, `commit` FROM snapshots
WHERE `reponame`={reponame} AND `workspace`={workspace}
ORDER BY `seq`"
read GetSnapshots(reponame: String, workspace: String) -> (String, Vec<u8>){
"SELECT `reponame`, `commit` FROM snapshots WHERE `reponame`={reponame} AND `workspace`={workspace} ORDER BY `seq`"
}
write DeleteSnapshot(reponame: String, workspace: String, >list commits: HgChangesetId) {
write DeleteSnapshot(reponame: String, workspace: String, >list commits: Vec<u8>) {
none,
"DELETE FROM `snapshots` WHERE `reponame`={reponame} AND `workspace`={workspace} AND `commit` IN {commits}"
}
write InsertSnapshot(reponame: String, workspace: String, commit: HgChangesetId) {
write InsertSnapshot(reponame: String, workspace: String, commit: Vec<u8>) {
none,
"INSERT INTO `snapshots` (`reponame`, `workspace`, `commit`) VALUES ({reponame}, {workspace}, {commit})"
}
@ -52,7 +53,11 @@ impl Get<WorkspaceSnapshot> for SqlCommitCloud {
let rows =
GetSnapshots::query(&self.connections.read_connection, &reponame, &workspace).await?;
rows.into_iter()
.map(|(_reponame, commit)| Ok(WorkspaceSnapshot { commit }))
.map(|(_reponame, commit)| {
Ok(WorkspaceSnapshot {
commit: changeset_from_bytes(&commit, self.uses_mysql)?,
})
})
.collect::<anyhow::Result<Vec<WorkspaceSnapshot>>>()
}
}
@ -68,7 +73,7 @@ impl Insert<WorkspaceSnapshot> for SqlCommitCloud {
&self.connections.write_connection,
&reponame,
&workspace,
&data.commit,
&changeset_as_bytes(&data.commit, self.uses_mysql)?,
)
.await?;
Ok(())
@ -102,7 +107,7 @@ impl Delete<WorkspaceSnapshot> for SqlCommitCloud {
&self.connections.write_connection,
&reponame,
&workspace,
args.removed_commits.as_slice(),
&list_as_bytes(args.removed_commits, self.uses_mysql)?,
)
.await?;
Ok(())

View File

@ -30,6 +30,17 @@ pub fn changeset_as_bytes(cs_id: &HgChangesetId, encode_as_hex: bool) -> anyhow:
Ok(cs_id.as_bytes().to_vec())
}
pub fn list_as_bytes(
list: Vec<HgChangesetId>,
is_hex_encoded: bool,
) -> anyhow::Result<Vec<Vec<u8>>> {
let mut res: Vec<Vec<u8>> = Vec::new();
for cs_id in list {
res.push(changeset_as_bytes(&cs_id, is_hex_encoded)?);
}
Ok(res)
}
#[cfg(test)]
mod test {
use std::str::FromStr;