import "sqlite" for Database import "io" for File // This class provides a hook back into the C host to terminate the application. foreign class Host { foreign static signalDone() } // All database operations are asynchronous. We chain them together using // callbacks to ensure they execute in the correct order. var mainFiber = Fiber.new { var db = Database.new() var dbPath = "test.db" var isDone = false // Flag to keep the fiber alive. // Clean up database file from previous runs, if it exists. if (File.exists(dbPath)) { File.delete(dbPath) } System.print("--- Starting SQLite CRUD Example ---") // 1. Open the database connection. db.open(dbPath) { |err| if (err) { System.print("Error opening database: %(err)") isDone = true // Signal completion on error. return } System.print("Database opened successfully at '%(dbPath)'.") // 2. CREATE: Create a new table. var createSql = "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT);" db.exec(createSql) { |err| if (err) { System.print("Error creating table: %(err)") isDone = true return } System.print("Table 'users' created.") // 3. CREATE: Insert a new user. var insertSql = "INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');" db.exec(insertSql) { |err| if (err) { System.print("Error inserting user: %(err)") isDone = true return } System.print("Inserted user 'Alice'.") // 4. READ: Query all users. db.query("SELECT * FROM users;") { |err, rows| if (err) { System.print("Error querying users: %(err)") isDone = true return } System.print("\n--- Current Users (after insert): ---") for (row in rows) { System.print(" ID: %(row["id"]), Name: %(row["name"]), Email: %(row["email"])") } // 5. UPDATE: Change Alice's email. var updateSql = "UPDATE users SET email = 'alice.smith@example.com' WHERE name = 'Alice';" db.exec(updateSql) { |err| if (err) { System.print("Error updating user: %(err)") isDone = true return } System.print("\nUpdated Alice's email.") // 6. READ: Query again to see the update. db.query("SELECT * FROM users;") { |err, rows| if (err) { System.print("Error querying users: %(err)") isDone = true return } System.print("\n--- Current Users (after update): ---") for (row in rows) { System.print(" ID: %(row["id"]), Name: %(row["name"]), Email: %(row["email"])") } // 7. DELETE: Remove Alice from the database. var deleteSql = "DELETE FROM users WHERE name = 'Alice';" db.exec(deleteSql) { |err| if (err) { System.print("Error deleting user: %(err)") isDone = true return } System.print("\nDeleted Alice.") // 8. READ: Query one last time to confirm deletion. db.query("SELECT * FROM users;") { |err, rows| if (err) { System.print("Error querying users: %(err)") isDone = true return } System.print("\n--- Current Users (after delete): ---") if (rows.isEmpty) { System.print(" (No users found)") } else { for (row in rows) { System.print(" ID: %(row["id"]), Name: %(row["name"]), Email: %(row["email"])") } } // 9. Close the database connection. db.close() { |err| if (err) { System.print("Error closing database: %(err)") } else { System.print("\nDatabase closed successfully.") } System.print("\n--- SQLite CRUD Example Finished ---") isDone = true // This is the final step, signal completion. } } } } } } } } } // Keep the fiber alive by yielding until the 'isDone' flag is set. while (!isDone) { Fiber.yield() } // All asynchronous operations are complete, now we can safely exit. Host.signalDone() }