Skip to main content

SqliteStore

Struct SqliteStore 

Source
pub struct SqliteStore { /* private fields */ }
Expand description

SQLite-backed persistence store using sqlx connection pool.

Implementations§

Source§

impl SqliteStore

Source

pub async fn open(path: impl AsRef<Path>) -> KanbanResult<Self>

Source

pub fn pool(&self) -> &Pool<Sqlite>

Source

pub fn read_metadata_sync(&self) -> KanbanResult<Option<PersistenceMetadata>>

Read the metadata singleton row from the DB. Cheap (single row, indexed by primary key). Returns Ok(None) if the row is absent — only possible on a brand-new DB before load_or_create_instance_id has run, which the public API doesn’t expose.

Source

pub async fn stamp_writer(&self) -> KanbanResult<DateTime<Utc>>

Record the current binary as the most-recent writer of this DB by stamping saved_at, writer_version, and writer_commit into the metadata singleton row. Returns the timestamp it wrote so callers can echo it back into a PersistenceMetadata without re-reading the row.

Separated from [checkpoint] so each function does one thing — see the post-PR-288 review for the SRP rationale.

Source

pub async fn checkpoint(&self) -> KanbanResult<()>

Truncate the WAL. Pure I/O step; does not touch the writer-stamp columns. Callers that want a durable save with attribution should invoke [stamp_writer] alongside this.

Source

pub async fn append_command_batch( &self, batch_index: u64, commands_json: &str, ) -> KanbanResult<()>

Append a single command batch at logical index batch_index. commands_json is the serde-JSON encoding of the Vec<Command> batch.

Source

pub async fn load_all_command_batches(&self) -> KanbanResult<Vec<String>>

Load all persisted command batches in order. Returns the JSON strings so callers can deserialise inside the domain layer.

Source

pub async fn truncate_command_log_after(&self, after: u64) -> KanbanResult<()>

Remove batches with logical index >= after. Retains [0, after).

Source

pub async fn shift_command_log(&self, drop_count: u64) -> KanbanResult<()>

Remove the oldest drop_count batches and renumber the rest so the surviving log starts at index 0.

Trait Implementations§

Source§

impl DataStore for SqliteStore

Source§

fn get_board(&self, id: Uuid) -> KanbanResult<Option<Board>>

Source§

fn list_boards(&self) -> KanbanResult<Vec<Board>>

Source§

fn upsert_board(&self, board: Board) -> KanbanResult<()>

Source§

fn delete_board(&self, id: Uuid) -> KanbanResult<()>

Source§

fn get_column(&self, id: Uuid) -> KanbanResult<Option<Column>>

Source§

fn list_columns_by_board(&self, board_id: Uuid) -> KanbanResult<Vec<Column>>

Source§

fn list_all_columns(&self) -> KanbanResult<Vec<Column>>

Source§

fn upsert_column(&self, column: Column) -> KanbanResult<()>

Source§

fn delete_column(&self, id: Uuid) -> KanbanResult<()>

Source§

fn delete_columns_by_board(&self, board_id: Uuid) -> KanbanResult<()>

Source§

fn get_card(&self, id: Uuid) -> KanbanResult<Option<Card>>

Source§

fn list_all_cards(&self) -> KanbanResult<Vec<Card>>

Source§

fn list_cards_by_column(&self, column_id: Uuid) -> KanbanResult<Vec<Card>>

Source§

fn list_cards_by_columns(&self, column_ids: &[Uuid]) -> KanbanResult<Vec<Card>>

Return all cards across the given columns in one call. Read more
Source§

fn list_cards_by_sprint(&self, sprint_id: Uuid) -> KanbanResult<Vec<Card>>

Source§

fn count_cards_in_column(&self, column_id: Uuid) -> KanbanResult<usize>

Source§

fn count_cards_in_column_excluding( &self, column_id: Uuid, exclude: &[Uuid], ) -> KanbanResult<usize>

Source§

fn upsert_card(&self, card: Card) -> KanbanResult<()>

Source§

fn delete_card(&self, id: Uuid) -> KanbanResult<()>

Source§

fn delete_cards_by_columns(&self, column_ids: &[Uuid]) -> KanbanResult<()>

Source§

fn clear_sprint_from_cards( &self, sprint_id: Uuid, timestamp: DateTime<Utc>, ) -> KanbanResult<()>

Source§

fn get_archived_card(&self, card_id: Uuid) -> KanbanResult<Option<ArchivedCard>>

Source§

fn list_archived_cards(&self) -> KanbanResult<Vec<ArchivedCard>>

Source§

fn insert_archived_card(&self, ac: ArchivedCard) -> KanbanResult<()>

Source§

fn delete_archived_card(&self, card_id: Uuid) -> KanbanResult<()>

Source§

fn list_archived_cards_by_columns( &self, column_ids: &[Uuid], ) -> KanbanResult<Vec<ArchivedCard>>

Source§

fn clear_sprint_from_archived_cards( &self, sprint_id: Uuid, timestamp: DateTime<Utc>, ) -> KanbanResult<()>

Source§

fn get_sprint(&self, id: Uuid) -> KanbanResult<Option<Sprint>>

Source§

fn list_sprints_by_board(&self, board_id: Uuid) -> KanbanResult<Vec<Sprint>>

Source§

fn list_all_sprints(&self) -> KanbanResult<Vec<Sprint>>

Source§

fn upsert_sprint(&self, sprint: Sprint) -> KanbanResult<()>

Source§

fn delete_sprint(&self, id: Uuid) -> KanbanResult<()>

Source§

fn delete_sprints_by_board(&self, board_id: Uuid) -> KanbanResult<()>

Source§

fn get_graph(&self) -> KanbanResult<DependencyGraph>

Source§

fn set_graph(&self, graph: DependencyGraph) -> KanbanResult<()>

Source§

fn modify_graph(&self, f: GraphMutFn) -> KanbanResult<()>

Atomically read-modify-write the dependency graph. Read more
Source§

fn snapshot(&self) -> KanbanResult<Snapshot>

Source§

fn apply_snapshot(&self, snapshot: Snapshot) -> KanbanResult<()>

Source§

impl PersistenceStore for SqliteStore

Source§

fn save<'life0, 'async_trait>( &'life0 self, snapshot: StoreSnapshot, ) -> Pin<Box<dyn Future<Output = PersistenceResult<PersistenceMetadata>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Save a snapshot to the store
Source§

fn load<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = PersistenceResult<(StoreSnapshot, PersistenceMetadata)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Load the current snapshot from the store
Source§

fn exists<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Check if the store file exists
Source§

fn path(&self) -> &Path

Get the path to the store file
Source§

fn instance_id(&self) -> Uuid

Get the unique instance ID for this store
Source§

fn close<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Drain any open connections / file handles before the backing file is unlinked. Required on Windows: the OS refuses to delete files that still have live handles, and async resources (e.g. an sqlx pool) outlive synchronous Drop because the runtime needs time to close each connection. Read more
Source§

fn load_sync( &self, ) -> Result<Option<(StoreSnapshot, PersistenceMetadata)>, PersistenceError>

Load the store synchronously (no async runtime required). Returns Ok(None) when the backing file does not exist. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more