Skip to main content

nu_command/stor/
import.rs

1use crate::database::{MEMORY_DB, SQLiteDatabase};
2use nu_engine::command_prelude::*;
3use nu_protocol::Signals;
4use nu_protocol::shell_error::generic::GenericError;
5
6#[derive(Clone)]
7pub struct StorImport;
8
9impl Command for StorImport {
10    fn name(&self) -> &str {
11        "stor import"
12    }
13
14    fn signature(&self) -> Signature {
15        Signature::build("stor import")
16            .input_output_types(vec![(Type::Nothing, Type::table())])
17            .required_named(
18                "file-name",
19                SyntaxShape::String,
20                "File name to import the sqlite in-memory database from.",
21                Some('f'),
22            )
23            .allow_variants_without_examples(true)
24            .category(Category::Database)
25    }
26
27    fn description(&self) -> &str {
28        "Import a sqlite database file into the in-memory sqlite database."
29    }
30
31    fn search_terms(&self) -> Vec<&str> {
32        vec!["sqlite", "open", "database", "restore", "file"]
33    }
34
35    fn examples(&self) -> Vec<Example<'_>> {
36        vec![Example {
37            description: "Import a sqlite database file into the in-memory sqlite database",
38            example: "stor import --file-name nudb.sqlite",
39            result: None,
40        }]
41    }
42
43    fn run(
44        &self,
45        engine_state: &EngineState,
46        stack: &mut Stack,
47        call: &Call,
48        _input: PipelineData,
49    ) -> Result<PipelineData, ShellError> {
50        let span = call.head;
51        let file_name_opt: Option<String> = call.get_flag(engine_state, stack, "file-name")?;
52        let file_name = match file_name_opt {
53            Some(file_name) => file_name,
54            None => {
55                return Err(ShellError::MissingParameter {
56                    param_name: "please supply a file name with the --file-name parameter".into(),
57                    span,
58                });
59            }
60        };
61
62        // Open the in-mem database
63        let db = Box::new(SQLiteDatabase::new(
64            std::path::Path::new(MEMORY_DB),
65            Signals::empty(),
66        ));
67
68        if let Ok(mut conn) = db.open_connection() {
69            db.restore_database_from_file(&mut conn, file_name)
70                .map_err(|err| {
71                    ShellError::Generic(GenericError::new_internal(
72                        "Failed to open SQLite connection in memory from import",
73                        err.to_string(),
74                    ))
75                })?;
76        }
77        // dbg!(db.clone());
78        Ok(Value::custom(db, span).into_pipeline_data())
79    }
80}
81
82#[cfg(test)]
83mod test {
84    use super::*;
85
86    #[test]
87    fn test_examples() -> nu_test_support::Result {
88        nu_test_support::test().examples(StorImport)
89    }
90}