|
@@ -1,4 +1,6 @@
|
|
|
import logging
|
|
import logging
|
|
|
|
|
+import sqlite3
|
|
|
|
|
+from contextlib import asynccontextmanager
|
|
|
from datetime import datetime
|
|
from datetime import datetime
|
|
|
from pathlib import Path
|
|
from pathlib import Path
|
|
|
|
|
|
|
@@ -37,6 +39,15 @@ class SQLiteBackend:
|
|
|
db_path = data_home() / db_path
|
|
db_path = data_home() / db_path
|
|
|
return cls(db_path, calendar_name)
|
|
return cls(db_path, calendar_name)
|
|
|
|
|
|
|
|
|
|
+ @asynccontextmanager
|
|
|
|
|
+ async def _connect(self):
|
|
|
|
|
+ import aiosqlite
|
|
|
|
|
+ try:
|
|
|
|
|
+ async with aiosqlite.connect(self._db_path) as db:
|
|
|
|
|
+ yield db
|
|
|
|
|
+ except sqlite3.OperationalError as e:
|
|
|
|
|
+ raise sqlite3.OperationalError(f"SQLite error for {self._db_path}: {e}") from None
|
|
|
|
|
+
|
|
|
def _to_record(self, row) -> EventRecord:
|
|
def _to_record(self, row) -> EventRecord:
|
|
|
uid, _, start, end, all_day, title, description, x_data = row
|
|
uid, _, start, end, all_day, title, description, x_data = row
|
|
|
return EventRecord(
|
|
return EventRecord(
|
|
@@ -50,8 +61,7 @@ class SQLiteBackend:
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
async def fetch_range(self, start: datetime, end: datetime) -> list[EventRecord]:
|
|
async def fetch_range(self, start: datetime, end: datetime) -> list[EventRecord]:
|
|
|
- import aiosqlite
|
|
|
|
|
- async with aiosqlite.connect(self._db_path) as db:
|
|
|
|
|
|
|
+ async with self._connect() as db:
|
|
|
await db.execute(_CREATE_TABLE)
|
|
await db.execute(_CREATE_TABLE)
|
|
|
cursor = await db.execute(
|
|
cursor = await db.execute(
|
|
|
f'SELECT {_COLS} FROM events WHERE calendar_name = ? AND start < ? AND end > ? ORDER BY start',
|
|
f'SELECT {_COLS} FROM events WHERE calendar_name = ? AND start < ? AND end > ? ORDER BY start',
|
|
@@ -61,8 +71,7 @@ class SQLiteBackend:
|
|
|
return [self._to_record(r) for r in rows]
|
|
return [self._to_record(r) for r in rows]
|
|
|
|
|
|
|
|
async def create(self, record: EventRecord) -> EventRecord:
|
|
async def create(self, record: EventRecord) -> EventRecord:
|
|
|
- import aiosqlite
|
|
|
|
|
- async with aiosqlite.connect(self._db_path) as db:
|
|
|
|
|
|
|
+ async with self._connect() as db:
|
|
|
await db.execute(_CREATE_TABLE)
|
|
await db.execute(_CREATE_TABLE)
|
|
|
await db.execute(
|
|
await db.execute(
|
|
|
f'INSERT INTO events ({_COLS}) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
|
f'INSERT INTO events ({_COLS}) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
|
@@ -75,8 +84,7 @@ class SQLiteBackend:
|
|
|
|
|
|
|
|
async def update(self, uid: str, *, title: str | None = None,
|
|
async def update(self, uid: str, *, title: str | None = None,
|
|
|
description: str | None = None, x_data: str | None = None) -> EventRecord:
|
|
description: str | None = None, x_data: str | None = None) -> EventRecord:
|
|
|
- import aiosqlite
|
|
|
|
|
- async with aiosqlite.connect(self._db_path) as db:
|
|
|
|
|
|
|
+ async with self._connect() as db:
|
|
|
await db.execute(_CREATE_TABLE)
|
|
await db.execute(_CREATE_TABLE)
|
|
|
if title is not None:
|
|
if title is not None:
|
|
|
await db.execute(
|
|
await db.execute(
|
|
@@ -103,8 +111,7 @@ class SQLiteBackend:
|
|
|
return self._to_record(row)
|
|
return self._to_record(row)
|
|
|
|
|
|
|
|
async def delete(self, uid: str) -> None:
|
|
async def delete(self, uid: str) -> None:
|
|
|
- import aiosqlite
|
|
|
|
|
- async with aiosqlite.connect(self._db_path) as db:
|
|
|
|
|
|
|
+ async with self._connect() as db:
|
|
|
await db.execute(_CREATE_TABLE)
|
|
await db.execute(_CREATE_TABLE)
|
|
|
await db.execute(
|
|
await db.execute(
|
|
|
'DELETE FROM events WHERE uid = ? AND calendar_name = ?',
|
|
'DELETE FROM events WHERE uid = ? AND calendar_name = ?',
|