formular lesen (binär) und openspec für codex

This commit is contained in:
2026-09-05 08:36:40 +02:00
parent 05837cd846
commit 1cb6ae8fd9
34 changed files with 2211 additions and 149 deletions

View File

@@ -154,10 +154,19 @@ struct Bindung {
#[derive(Debug, Clone)]
enum Undo {
/// Der Satz wurde eingefügt — Rücknahme entfernt ihn wieder.
Eingefuegt { pfad: PathBuf, tabelle: String, id: u64 },
Eingefuegt {
pfad: PathBuf,
tabelle: String,
id: u64,
},
/// Der Satz wurde geändert oder gelöscht — Rücknahme stellt die
/// alten Bytes wieder her.
Vorher { pfad: PathBuf, tabelle: String, id: u64, bytes: Vec<u8> },
Vorher {
pfad: PathBuf,
tabelle: String,
id: u64,
bytes: Vec<u8>,
},
}
impl Undo {
@@ -294,7 +303,11 @@ fn schluessel_anhaengen(out: &mut Vec<u8>, wert: &Value, typ: &TypeInit, absteig
}
TypeInit::Sng => {
let bits = (crate::value::as_f64(wert) as f32).to_bits();
let k = if bits & 0x8000_0000 != 0 { !bits } else { bits | 0x8000_0000 };
let k = if bits & 0x8000_0000 != 0 {
!bits
} else {
bits | 0x8000_0000
};
out.extend_from_slice(&k.to_be_bytes());
}
TypeInit::Dbl => {
@@ -538,11 +551,7 @@ impl Isam {
return Err(RuntimeError::TYPE_MISMATCH);
}
let layout = Layout {
spalten: namen
.iter()
.map(|n| n.to_string())
.zip(felder)
.collect(),
spalten: namen.iter().map(|n| n.to_string()).zip(felder).collect(),
};
let pfad = fileio::pfad_normieren(datenbank);
@@ -616,9 +625,7 @@ impl Isam {
}
}
Some(_) => return Err(INKONSISTENT),
None if neu => {
meta_schreiben(&txn, "version", &FORMATVERSION.to_le_bytes())?
}
None if neu => meta_schreiben(&txn, "version", &FORMATVERSION.to_le_bytes())?,
// Bestehende Datei ohne Versionsmarke: keine Datenbank
// dieses Formats.
None => return Err(INKONSISTENT),
@@ -760,7 +767,11 @@ impl Isam {
if spalten.is_empty() {
return Err(SPALTE_UNGUELTIG);
}
let mut def = Indexdef { name: name.to_string(), eindeutig, spalten: Vec::new() };
let mut def = Indexdef {
name: name.to_string(),
eindeutig,
spalten: Vec::new(),
};
for s in spalten {
let (absteigend, sname) = match s.strip_prefix('-') {
Some(r) => (true, r),
@@ -930,7 +941,11 @@ impl Isam {
let id = self.schreiben(&pfad, move |txn, log| {
let id = naechste_id(txn, &tabelle)?;
satz_schreiben(txn, &tabelle, &layout, &udts, id, Some(&bytes), None)?;
log.push(Undo::Eingefuegt { pfad: fuer_log, tabelle: tabelle.clone(), id });
log.push(Undo::Eingefuegt {
pfad: fuer_log,
tabelle: tabelle.clone(),
id,
});
Ok(id)
})?;
self.belegt += bytes_von(&self.trans);
@@ -1132,7 +1147,9 @@ impl Isam {
praefix.clone()
};
let mut bereich = t.range(von.as_slice()..).map_err(|_| INKONSISTENT)?;
let Some(e) = bereich.next() else { return Ok(None) };
let Some(e) = bereich.next() else {
return Ok(None);
};
let (k, v) = e.map_err(|_| INKONSISTENT)?;
if art == Suchart::Gleich && !k.value().starts_with(&praefix) {
return Ok(None);
@@ -1215,7 +1232,10 @@ impl Isam {
/// `SAVEPOINT` — liefert die Kennung des gesetzten Sicherungspunkts.
pub fn sicherungspunkt(&mut self) -> Result<i16, RuntimeError> {
let t = self.trans.as_mut().ok_or(RuntimeError::ILLEGAL_FUNCTION_CALL)?;
let t = self
.trans
.as_mut()
.ok_or(RuntimeError::ILLEGAL_FUNCTION_CALL)?;
let kennung = t.naechste_kennung;
t.naechste_kennung = t.naechste_kennung.saturating_add(1);
let pos = t.log.len();
@@ -1283,18 +1303,15 @@ impl Isam {
let layout = self.layout_von(&pfad, &tabelle)?;
self.schreiben(&pfad, move |txn, _| {
let alt = satz_bytes_lesen(txn, &tabelle, id)?;
satz_schreiben(
txn,
&tabelle,
&layout,
&udts,
id,
None,
alt.as_deref(),
)
satz_schreiben(txn, &tabelle, &layout, &udts, id, None, alt.as_deref())
})?;
}
Undo::Vorher { pfad, tabelle, id, bytes } => {
Undo::Vorher {
pfad,
tabelle,
id,
bytes,
} => {
let layout = self.layout_von(&pfad, &tabelle)?;
self.schreiben(&pfad, move |txn, _| {
let alt = satz_bytes_lesen(txn, &tabelle, id)?;
@@ -1372,7 +1389,10 @@ fn satz_bytes_lesen(
let name = satz_def(tabelle);
let def: SatzTab = TableDefinition::new(&name);
let t = txn.open_table(def).map_err(|_| INKONSISTENT)?;
let gefunden = t.get(id).map_err(|_| INKONSISTENT)?.map(|v| v.value().to_vec());
let gefunden = t
.get(id)
.map_err(|_| INKONSISTENT)?
.map(|v| v.value().to_vec());
Ok(gefunden)
}