fix: restart/ uninstall sometimes didn't work (#1527)

* fix: restart/ uninstall sometimes didn't work

* Fix: Match the original lock types
This commit is contained in:
J M
2022-06-13 14:18:41 -06:00
committed by GitHub
parent 4d89e3beba
commit dbf59a7853

View File

@@ -1,20 +1,66 @@
use std::collections::BTreeMap;
use patch_db::{DbHandle, LockType};
use patch_db::{DbHandle, LockReceipt, LockTargetId, LockType, Verifier};
use rpc_toolkit::command;
use tracing::instrument;
use crate::config::not_found;
use crate::context::RpcContext;
use crate::dependencies::{break_transitive, BreakageRes, DependencyError};
use crate::db::model::CurrentDependents;
use crate::dependencies::{
break_transitive, BreakTransitiveReceipts, BreakageRes, DependencyError,
};
use crate::s9pk::manifest::PackageId;
use crate::util::serde::display_serializable;
use crate::util::Version;
use crate::Error;
pub struct UpdateReceipts {
break_receipts: BreakTransitiveReceipts,
current_dependents: LockReceipt<CurrentDependents, String>,
dependency: LockReceipt<crate::dependencies::DepInfo, (String, String)>,
}
impl UpdateReceipts {
pub async fn new<'a>(db: &'a mut impl DbHandle) -> Result<Self, Error> {
let mut locks = Vec::new();
let setup = Self::setup(&mut locks);
Ok(setup(&db.lock_all(locks).await?)?)
}
pub fn setup(locks: &mut Vec<LockTargetId>) -> impl FnOnce(&Verifier) -> Result<Self, Error> {
let break_receipts = BreakTransitiveReceipts::setup(locks);
let current_dependents = crate::db::DatabaseModel::new()
.package_data()
.star()
.installed()
.map(|x| x.current_dependents())
.make_locker(LockType::Write)
.add_to_keys(locks);
let dependency = crate::db::DatabaseModel::new()
.package_data()
.star()
.installed()
.map(|x| x.manifest().dependencies().star())
.make_locker(LockType::Write)
.add_to_keys(locks);
move |skeleton_key| {
Ok(Self {
break_receipts: break_receipts(skeleton_key)?,
current_dependents: current_dependents.verify(skeleton_key)?,
dependency: dependency.verify(skeleton_key)?,
})
}
}
}
#[command(subcommands(dry))]
pub async fn update() -> Result<(), Error> {
Ok(())
}
#[instrument(skip(ctx))]
#[command(display(display_serializable))]
pub async fn dry(
#[context] ctx: RpcContext,
@@ -24,52 +70,34 @@ pub async fn dry(
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;
let mut breakages = BTreeMap::new();
let receipts = crate::dependencies::BreakTransitiveReceipts::new(&mut tx).await?;
crate::db::DatabaseModel::new()
.package_data()
.lock(&mut tx, LockType::Read)
.await?;
let receipts = UpdateReceipts::new(&mut tx).await?;
for dependent in crate::db::DatabaseModel::new()
.package_data()
.idx_model(&id)
.and_then(|m| m.installed())
.expect(&mut tx)
.await?
.current_dependents()
.keys(&mut tx, true)
for dependent in receipts
.current_dependents
.get(&mut tx, &id)
.await?
.ok_or_else(not_found)?
.0
.keys()
.into_iter()
.filter(|dependent| &id != dependent)
.filter(|dependent| &&id != dependent)
{
let version_req = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&dependent)
.and_then(|m| m.installed())
.expect(&mut tx)
.await?
.manifest()
.dependencies()
.idx_model(&id)
.expect(&mut tx)
.await?
.get(&mut tx, true)
.await?
.into_owned()
.version;
if !version.satisfies(&version_req) {
break_transitive(
&mut tx,
&dependent,
&id,
DependencyError::IncorrectVersion {
expected: version_req,
received: version.clone(),
},
&mut breakages,
&receipts,
)
.await?;
if let Some(dep_info) = receipts.dependency.get(&mut tx, (&dependent, &id)).await? {
let version_req = dep_info.version;
if !version.satisfies(&version_req) {
break_transitive(
&mut tx,
&dependent,
&id,
DependencyError::IncorrectVersion {
expected: version_req,
received: version.clone(),
},
&mut breakages,
&receipts.break_receipts,
)
.await?;
}
}
}
tx.abort().await?;