|
|
|
@ -28,6 +28,7 @@ use {
|
|
|
|
|
super::{Field, IWModel, Layer, ModelView},
|
|
|
|
|
crate::{
|
|
|
|
|
engine::{
|
|
|
|
|
core::GlobalNS,
|
|
|
|
|
data::{
|
|
|
|
|
tag::{DataTag, TagClass},
|
|
|
|
|
DictEntryGeneric,
|
|
|
|
@ -224,6 +225,8 @@ impl<'a> AlterPlan<'a> {
|
|
|
|
|
// no delta
|
|
|
|
|
}
|
|
|
|
|
(current_selector, new_selector) if interop(current_layer, &new_parsed_layer) => {
|
|
|
|
|
// now, we're not sure if we can run this
|
|
|
|
|
// FIXME(@ohsayan): look, should we be explicit about this?
|
|
|
|
|
no_lock &= new_selector >= current_selector;
|
|
|
|
|
deltasize += (new_selector != current_selector) as usize;
|
|
|
|
|
}
|
|
|
|
@ -243,3 +246,50 @@ impl<'a> AlterPlan<'a> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ModelView {
|
|
|
|
|
pub fn exec_alter(gns: &GlobalNS, space: &[u8], alter: AlterModel) -> DatabaseResult<()> {
|
|
|
|
|
let gns = gns.spaces().read();
|
|
|
|
|
let Some(space) = gns.st_get(space) else {
|
|
|
|
|
return Err(DatabaseError::DdlSpaceNotFound)
|
|
|
|
|
};
|
|
|
|
|
let space = space.models().read();
|
|
|
|
|
let Some(model) = space.st_get(alter.model.as_bytes()) else {
|
|
|
|
|
return Err(DatabaseError::DdlModelNotFound);
|
|
|
|
|
};
|
|
|
|
|
// make intent
|
|
|
|
|
let iwm = model.intent_write_model();
|
|
|
|
|
// prepare plan
|
|
|
|
|
let plan = AlterPlan::fdeltas(model, &iwm, alter)?;
|
|
|
|
|
// we have a legal plan; acquire exclusive if we need it
|
|
|
|
|
if !plan.no_lock {
|
|
|
|
|
// TODO(@ohsayan): allow this later on, once we define the syntax
|
|
|
|
|
return Err(DatabaseError::NeedLock);
|
|
|
|
|
}
|
|
|
|
|
// fine, we're good
|
|
|
|
|
let mut iwm = iwm;
|
|
|
|
|
match plan.action {
|
|
|
|
|
AlterAction::Ignore => drop(iwm),
|
|
|
|
|
AlterAction::Add(new_fields) => {
|
|
|
|
|
// TODO(@ohsayan): this impacts lockdown duration; fix it
|
|
|
|
|
new_fields
|
|
|
|
|
.st_iter_kv()
|
|
|
|
|
.map(|(x, y)| (x.clone(), y.clone()))
|
|
|
|
|
.for_each(|(field_id, field)| {
|
|
|
|
|
iwm.fields_mut().st_insert(field_id, field);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
AlterAction::Remove(remove) => {
|
|
|
|
|
remove.into_iter().for_each(|field_id| {
|
|
|
|
|
iwm.fields_mut().st_delete(field_id.as_str());
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
AlterAction::Update(u) => {
|
|
|
|
|
u.into_iter().for_each(|(field_id, field)| {
|
|
|
|
|
iwm.fields_mut().st_update(&field_id, field);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|