Handle the install command SQLite-style initialization: Creates database files and fully initializes the database using a coordinator instance that lives only during this command. All state is persisted to disk via Sled before the process exits.
(
path: PathBuf,
admin_user: String,
admin_password: Option<String>,
force: bool,
yes: bool,
)
| 21 | /// the database using a coordinator instance that lives only during this command. |
| 22 | /// All state is persisted to disk via Sled before the process exits. |
| 23 | pub fn handle_install( |
| 24 | path: PathBuf, |
| 25 | admin_user: String, |
| 26 | admin_password: Option<String>, |
| 27 | force: bool, |
| 28 | yes: bool, |
| 29 | ) -> Result<(), Box<dyn std::error::Error>> { |
| 30 | // Check if database already exists |
| 31 | if path.exists() && !force && !yes { |
| 32 | println!( |
| 33 | "{}", |
| 34 | format!("Database already exists at {:?}", path).yellow() |
| 35 | ); |
| 36 | println!("Use --force to reinstall, or choose a different path."); |
| 37 | return Err("Database already exists".into()); |
| 38 | } |
| 39 | |
| 40 | // Prompt for password if not provided |
| 41 | let password = match admin_password { |
| 42 | Some(pwd) => pwd, |
| 43 | None => { |
| 44 | print!("Enter admin password: "); |
| 45 | std::io::Write::flush(&mut std::io::stdout())?; |
| 46 | rpassword::read_password()? |
| 47 | } |
| 48 | }; |
| 49 | |
| 50 | println!("{}", "Initializing GraphLite...".bold().green()); |
| 51 | |
| 52 | // Create database directory |
| 53 | std::fs::create_dir_all(&path)?; |
| 54 | |
| 55 | // SQLite-style pattern: Create coordinator for this command's lifetime |
| 56 | // The coordinator will initialize all components and persist state to disk |
| 57 | println!(" → Creating database files..."); |
| 58 | |
| 59 | // Initialize coordinator - this handles all internal component setup |
| 60 | let coordinator = QueryCoordinator::from_path(&path) |
| 61 | .map_err(|e| format!("Failed to initialize database: {}", e))?; |
| 62 | |
| 63 | println!(" → Initializing security catalog..."); |
| 64 | |
| 65 | // The security catalog provider already created a default 'admin' user during initialization |
| 66 | // Now we need to set the password for this user |
| 67 | println!(" → Setting admin user password..."); |
| 68 | |
| 69 | coordinator |
| 70 | .set_user_password(&admin_user, &password) |
| 71 | .map_err(|e| format!("Failed to set admin password: {}", e))?; |
| 72 | |
| 73 | println!(" Password set for user '{}'", admin_user); |
| 74 | println!(" Security catalog saved to disk"); |
| 75 | |
| 76 | // Create a system session for additional setup operations |
| 77 | let session_id = coordinator.create_simple_session("system")?; |
| 78 | |
| 79 | // Create default schema |
| 80 | println!(" → Creating default schema..."); |
no test coverage detected