Tasks are now stored in SQLite (DB_PATH env var, defaults to ./tasks.db). Pre-seeding runs only when the table is empty, so upgrades preserve data. This is the v1.0.0 baseline for the persistence demo. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
88 lines
2.8 KiB
Scala
88 lines
2.8 KiB
Scala
import java.util.UUID
|
|
import java.sql.{Connection, DriverManager}
|
|
|
|
case class Task(id: UUID, title: String, completed: Boolean)
|
|
|
|
object TaskStore:
|
|
private val dbPath = sys.env.getOrElse("DB_PATH", "./tasks.db")
|
|
private val url = s"jdbc:sqlite:$dbPath"
|
|
|
|
Class.forName("org.sqlite.JDBC")
|
|
|
|
private def connect(): Connection = DriverManager.getConnection(url)
|
|
|
|
// Initialize schema and pre-seed if empty
|
|
locally {
|
|
val conn = connect()
|
|
try
|
|
val stmt = conn.createStatement()
|
|
stmt.execute(
|
|
"CREATE TABLE IF NOT EXISTS tasks (id TEXT PRIMARY KEY, title TEXT NOT NULL, completed INTEGER NOT NULL DEFAULT 0)"
|
|
)
|
|
val rs = stmt.executeQuery("SELECT COUNT(*) FROM tasks")
|
|
val count = rs.getInt(1)
|
|
if count == 0 then
|
|
val samples = List(
|
|
"Deploy Scala app to Clouderized",
|
|
"Set up CI/CD with Gitea Actions",
|
|
"Configure custom domain"
|
|
)
|
|
val ps = conn.prepareStatement("INSERT INTO tasks (id, title, completed) VALUES (?, ?, 0)")
|
|
samples.foreach { title =>
|
|
ps.setString(1, UUID.randomUUID().toString)
|
|
ps.setString(2, title)
|
|
ps.executeUpdate()
|
|
}
|
|
finally conn.close()
|
|
}
|
|
|
|
def all(): List[Task] =
|
|
val conn = connect()
|
|
try
|
|
val rs = conn.createStatement().executeQuery("SELECT id, title, completed FROM tasks ORDER BY title")
|
|
val buf = collection.mutable.ListBuffer.empty[Task]
|
|
while rs.next() do
|
|
buf += Task(UUID.fromString(rs.getString("id")), rs.getString("title"), rs.getInt("completed") == 1)
|
|
buf.toList
|
|
finally conn.close()
|
|
|
|
def add(title: String): Task =
|
|
val id = UUID.randomUUID()
|
|
val conn = connect()
|
|
try
|
|
val ps = conn.prepareStatement("INSERT INTO tasks (id, title, completed) VALUES (?, ?, 0)")
|
|
ps.setString(1, id.toString)
|
|
ps.setString(2, title.trim)
|
|
ps.executeUpdate()
|
|
Task(id, title.trim, false)
|
|
finally conn.close()
|
|
|
|
def toggle(id: UUID): Unit =
|
|
val conn = connect()
|
|
try
|
|
val ps = conn.prepareStatement(
|
|
"UPDATE tasks SET completed = CASE WHEN completed = 1 THEN 0 ELSE 1 END WHERE id = ?"
|
|
)
|
|
ps.setString(1, id.toString)
|
|
ps.executeUpdate()
|
|
finally conn.close()
|
|
|
|
def delete(id: UUID): Unit =
|
|
val conn = connect()
|
|
try
|
|
val ps = conn.prepareStatement("DELETE FROM tasks WHERE id = ?")
|
|
ps.setString(1, id.toString)
|
|
ps.executeUpdate()
|
|
finally conn.close()
|
|
|
|
def get(id: UUID): Option[Task] =
|
|
val conn = connect()
|
|
try
|
|
val ps = conn.prepareStatement("SELECT id, title, completed FROM tasks WHERE id = ?")
|
|
ps.setString(1, id.toString)
|
|
val rs = ps.executeQuery()
|
|
if rs.next() then
|
|
Some(Task(UUID.fromString(rs.getString("id")), rs.getString("title"), rs.getInt("completed") == 1))
|
|
else None
|
|
finally conn.close()
|