1use structsy::internal::Description;
2use structsy::record::Record;
3use structsy::{RawAccess, RawRead, Snapshot, Structsy, StructsyError};
4
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub enum Data {
9 Definition(Description),
10 Record(Record),
11}
12
13pub fn export(structsy: &Structsy) -> Result<impl Iterator<Item = Data>, StructsyError> {
17 let definitions = structsy.list_defined()?.map(|def| Data::Definition(def));
18 let st = structsy.clone();
19 let data_iter = structsy
20 .list_defined()?
21 .map(move |def| {
22 RawRead::raw_scan(&st, &def.get_name())
23 .ok()
24 .map(|it| it.map(|(_, record)| Data::Record(record)))
25 })
26 .flatten()
27 .flatten();
28 Ok(definitions.chain(data_iter))
29}
30
31pub fn export_from_snapshot(snapshot: Snapshot) -> Result<impl Iterator<Item = Data>, StructsyError> {
35 let definitions = snapshot.list_defined()?.map(|def| Data::Definition(def));
36 let snap = snapshot.clone();
37 let data_iter = snapshot
38 .list_defined()?
39 .map(move |def| {
40 RawRead::raw_scan(&snap, &def.get_name())
41 .ok()
42 .map(|it| it.map(|(_, record)| Data::Record(record)))
43 })
44 .flatten()
45 .flatten();
46 Ok(definitions.chain(data_iter))
47}
48pub fn import(structsy: &Structsy, iter: impl Iterator<Item = Data>) -> Result<(), StructsyError> {
51 for values in iter {
52 match values {
53 Data::Definition(def) => {
54 structsy.raw_define(def)?;
55 }
56 Data::Record(rec) => {
57 let mut raw_tx = structsy.raw_begin()?;
58 raw_tx.raw_insert(&rec)?;
59 raw_tx.prepare()?.commit()?;
60 }
61 }
62 }
63 Ok(())
64}
65
66#[cfg(test)]
67mod tests {
68 use structsy_derive::{queries, Persistent};
69
70 use super::{export, import};
71 use structsy::{Structsy, StructsyTx};
72 #[derive(Persistent)]
73 struct Simple {
74 #[index(mode = "cluster")]
75 name: String,
76 size: u32,
77 }
78
79 #[queries(Simple)]
80 trait SimpleQueries {
81 fn by_name(self, name: &str) -> Self;
82 }
83
84 #[test]
85 fn simple_export_import() {
86 let db = Structsy::memory().unwrap();
87 db.define::<Simple>().unwrap();
88 let mut tx = db.begin().unwrap();
89 tx.insert(&Simple {
90 name: "first".to_owned(),
91 size: 10,
92 })
93 .unwrap();
94 tx.commit().unwrap();
95
96 let loaded = Structsy::memory().unwrap();
97 let data = export(&db).unwrap();
98 import(&loaded, data).unwrap();
99
100 assert_eq!(loaded.query::<Simple>().by_name("first").into_iter().count(), 1);
101 }
102}