store

package
v0.0.0-...-fd33c92 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package store provides the client-side data access layer for the Xyncra messaging system, backed by SQLite via GORM.

Architecture

The package centers on ClientDB, which aggregates nine domain-specific sub-stores (Conversations, Messages, UserUpdates, SyncStates, Drafts, Queue, RPCLogs, NotificationLogs). Each sub-store encapsulates all CRUD and query operations for its domain model.

This package mirrors the server-side internal/store package but is placed under pkg/ so that external client applications can import it. The three shared models (Conversation, Message, UserUpdate) are copied from internal/store/model since Go's internal/ packages cannot be imported externally.

SQLite Configuration

The database is opened with PRAGMAs optimized for single-writer WAL mode:

  • journal_mode=WAL — concurrent reads during writes
  • busy_timeout=5000 — wait up to 5s for lock acquisition
  • cache_size=-8000 — 8 MB page cache
  • synchronous=NORMAL — safe with WAL
  • foreign_keys=ON — enforce referential integrity

MaxOpenConns is set to 1 because SQLite uses file-level locking; multiple write connections would cause "database is locked" errors. WAL mode allows concurrent reads via a separate reader path.

Auto-Migration

AutoMigrate runs automatically during New() / NewInMemory() (D-023), ensuring the schema is always up to date when the client starts.

Package store provides the client-side data access layer for the Xyncra messaging system, backed by SQLite via GORM.

Index

Constants

View Source
const DefaultCleanupRetention = 30 * 24 * time.Hour // 30 days

DefaultCleanupRetention is the default retention period for user updates.

Variables

View Source
var (
	// ErrNotFound indicates that the requested record does not exist.
	ErrNotFound = errors.New("store: record not found")

	// ErrDuplicateKey indicates a unique constraint violation.
	ErrDuplicateKey = errors.New("store: duplicate key")

	// ErrForeignKeyViolation indicates a foreign key constraint violation.
	ErrForeignKeyViolation = errors.New("store: foreign key violation")

	// ErrConnectionFailed indicates a database connection failure.
	ErrConnectionFailed = errors.New("store: connection failed")

	// ErrContextDeadlineExceeded indicates the context deadline was exceeded.
	ErrContextDeadlineExceeded = errors.New("store: context deadline exceeded")

	// ErrDatabaseLocked indicates the SQLite database is locked by another writer.
	ErrDatabaseLocked = errors.New("store: database is locked")
)

Standard errors returned by store operations.

Functions

This section is empty.

Types

type ClientDB

type ClientDB struct {

	// Conversations provides conversation-related operations.
	Conversations *ConversationStore

	// Messages provides message-related operations.
	Messages *MessageStore

	// UserUpdates provides user-update related operations.
	UserUpdates *UserUpdateStore

	// SyncStates provides sync state key-value operations.
	SyncStates *SyncStateStore

	// Drafts provides message draft operations.
	Drafts *DraftStore

	// Queue provides retry task queue operations.
	Queue *QueueStore

	// RPCLogs provides RPC log operations.
	RPCLogs *RPCLogStore

	// NotificationLogs provides notification log operations.
	NotificationLogs *NotificationLogStore

	// RemoteCallings provides remote calling operations (D-137).
	RemoteCallings *RemoteCallingStore
	// contains filtered or unexported fields
}

ClientDB is the top-level data access entry point for the Xyncra client. It aggregates the individual domain stores and provides SQLite-specific initialization with appropriate PRAGMAs for single-writer access.

func New

func New(dbPath string) (*ClientDB, error)

New opens a SQLite database at the given path, configures PRAGMAs for single-writer WAL mode, initializes all sub-stores, and runs AutoMigrate. This is the primary constructor for production use (D-001, D-023).

func NewInMemory

func NewInMemory(name string) (*ClientDB, error)

NewInMemory creates an in-memory SQLite database for testing. The name parameter is used to create a named shared memory database.

func (*ClientDB) AutoMigrate

func (c *ClientDB) AutoMigrate(ctx context.Context) error

AutoMigrate runs GORM's auto-migration for all known models, creating or updating tables and indexes as needed.

func (*ClientDB) Close

func (c *ClientDB) Close() error

Close closes the underlying database connection pool.

func (*ClientDB) Ping

func (c *ClientDB) Ping(ctx context.Context) error

Ping verifies that the database connection is alive by executing a trivial query.

func (*ClientDB) Transaction

func (c *ClientDB) Transaction(ctx context.Context, fn func(tx *gorm.DB) error) error

Transaction executes fn inside a database transaction. If fn returns an error, the transaction is rolled back; otherwise it is committed.

type ConversationStore

type ConversationStore struct {
	// contains filtered or unexported fields
}

ConversationStore provides data access operations for the Conversation model.

func (*ConversationStore) Create

func (cs *ConversationStore) Create(ctx context.Context, conv *model.Conversation) error

Create inserts a new conversation record into the database.

func (*ConversationStore) Delete

func (cs *ConversationStore) Delete(ctx context.Context, id string) error

Delete performs a cascading soft delete: the conversation and all its messages are soft-deleted within a single transaction (D-013).

func (*ConversationStore) Get

Get retrieves a conversation by its primary key. Returns ErrNotFound if no record exists.

func (*ConversationStore) GetByUser

func (cs *ConversationStore) GetByUser(ctx context.Context, userID string, offset, limit int) ([]*model.Conversation, error)

GetByUser returns conversations where the given user is either UserID1 or UserID2, ordered by LastMessageAt descending, with offset/limit pagination. Soft-deleted records are excluded automatically by GORM's soft-delete plugin.

func (*ConversationStore) GetByUsers

func (cs *ConversationStore) GetByUsers(ctx context.Context, user1, user2 string) (*model.Conversation, error)

GetByUsers returns the 1-on-1 conversation between user1 and user2. It checks both (user1, user2) and (user2, user1) orderings. Returns ErrNotFound if no matching conversation exists.

func (*ConversationStore) GetUnscoped

func (cs *ConversationStore) GetUnscoped(ctx context.Context, id string) (*model.Conversation, error)

GetUnscoped retrieves a conversation including soft-deleted records. Returns ErrNotFound if no record exists.

func (*ConversationStore) Restore

func (cs *ConversationStore) Restore(ctx context.Context, id string) error

Restore undeletes a soft-deleted conversation and cascades the restore to all its messages within a single transaction (D-015). Calling Restore on a conversation that already exists but is not soft-deleted is idempotent — it returns nil without error (D-015). Returns ErrNotFound only if the conversation does not exist at all.

func (*ConversationStore) RestoreTx

func (cs *ConversationStore) RestoreTx(ctx context.Context, tx *gorm.DB, id string) error

RestoreTx performs cascading restore within the given transaction (D-015).

func (*ConversationStore) SearchByTitle

func (cs *ConversationStore) SearchByTitle(ctx context.Context, userID, title string, limit int) ([]*model.Conversation, error)

SearchByTitle searches conversations for the given user that contain the specified title substring (case-insensitive via LIKE), ordered by LastMessageAt descending.

func (*ConversationStore) SoftDeleteTx

func (cs *ConversationStore) SoftDeleteTx(ctx context.Context, tx *gorm.DB, id string) error

SoftDeleteTx performs cascading soft delete within the given transaction (D-013).

func (*ConversationStore) Update

func (cs *ConversationStore) Update(ctx context.Context, conv *model.Conversation) error

Update saves all fields of the conversation back to the database. It uses Unscoped() so that soft-deleted records can be updated (including clearing deleted_at to NULL when restoring a conversation).

func (*ConversationStore) UpdateLastMessage

func (cs *ConversationStore) UpdateLastMessage(ctx context.Context, convID string, lastMessageAt time.Time, lastProcessedMessageID uint32) error

UpdateLastMessage updates the LastMessageAt and LastProcessedMessageID fields of the conversation identified by convID.

func (*ConversationStore) UpdateLastMessageTx

func (cs *ConversationStore) UpdateLastMessageTx(ctx context.Context, tx *gorm.DB, convID string, lastMessageAt time.Time, lastProcessedMessageID uint32) error

UpdateLastMessageTx updates last message fields within the given transaction.

func (*ConversationStore) UpdateLastRead

func (cs *ConversationStore) UpdateLastRead(ctx context.Context, convID, userID string, messageID uint32) error

UpdateLastRead updates the last-read message ID for the specified user. Uses MAX semantics: only advances forward, never backward (D-012). Uses a single SQL statement to avoid TOCTOU races.

func (*ConversationStore) UpdateLastReadTx

func (cs *ConversationStore) UpdateLastReadTx(ctx context.Context, tx *gorm.DB, convID, userID string, messageID uint32) error

UpdateLastReadTx updates read cursor within the given transaction. Uses MAX semantics: only advances forward (D-012).

func (*ConversationStore) Upsert

func (cs *ConversationStore) Upsert(ctx context.Context, conv *model.Conversation) error

Upsert creates the conversation if it does not exist, or saves (overwrites) it if it already exists. This is used by the client sync pipeline to apply conversation create events idempotently (D-045). It uses Unscoped() to also find soft-deleted records, so that restoring a previously deleted conversation correctly transitions it back to active. If a concurrent insert causes a duplicate key error, the operation retries as an update to handle the TOCTOU race between SELECT and INSERT.

func (*ConversationStore) UpsertTx

func (cs *ConversationStore) UpsertTx(ctx context.Context, tx *gorm.DB, conv *model.Conversation) error

UpsertTx creates or updates a conversation within the given transaction. It uses Unscoped() to also find soft-deleted records, so that restoring a previously deleted conversation correctly transitions it back to active. If a concurrent insert causes a duplicate key error, the operation retries as an update to handle the TOCTOU race between SELECT and INSERT.

type DraftStore

type DraftStore struct {
	// contains filtered or unexported fields
}

DraftStore provides data access operations for message drafts. Each conversation can have at most one draft (one-draft-per-conversation).

func (*DraftStore) Delete

func (ds *DraftStore) Delete(ctx context.Context, id string) error

Delete removes a draft by its primary key. Returns ErrNotFound if not found.

func (*DraftStore) DeleteByConversation

func (ds *DraftStore) DeleteByConversation(ctx context.Context, conversationID string) error

DeleteByConversation removes the draft for the given conversation. Returns ErrNotFound if no draft exists.

func (*DraftStore) GetByConversation

func (ds *DraftStore) GetByConversation(ctx context.Context, conversationID string) (*model.Draft, error)

GetByConversation retrieves the draft for the given conversation. Returns ErrNotFound if no draft exists.

func (*DraftStore) List

func (ds *DraftStore) List(ctx context.Context) ([]*model.Draft, error)

List returns all drafts ordered by UpdatedAt descending.

func (*DraftStore) Save

func (ds *DraftStore) Save(ctx context.Context, draft *model.Draft) error

Save performs an UPSERT for a draft. If a draft for the conversation already exists (by ConversationID uniqueIndex), it is updated; otherwise a new record is inserted.

type MessageStore

type MessageStore struct {
	// contains filtered or unexported fields
}

MessageStore provides data access operations for the Message model.

func (*MessageStore) CountUnread

func (ms *MessageStore) CountUnread(ctx context.Context, convID string, afterMessageID uint32) (int64, error)

CountUnread returns the number of messages in the given conversation with MessageID greater than afterMessageID. Soft-deleted messages are excluded automatically by GORM's soft-delete plugin.

func (*MessageStore) Create

func (ms *MessageStore) Create(ctx context.Context, msg *model.Message) error

Create inserts a new message record into the database.

func (*MessageStore) CreateOrUpdateTx

func (ms *MessageStore) CreateOrUpdateTx(ctx context.Context, tx *gorm.DB, msg *model.Message) error

CreateOrUpdateTx implements upsert semantics within the given transaction. If a message with the same id exists, it updates content, type, and status. Otherwise, it creates a new record. This is used by the client SDK to handle tool_calling message updates (D-141).

func (*MessageStore) CreateTx

func (ms *MessageStore) CreateTx(ctx context.Context, tx *gorm.DB, msg *model.Message) error

CreateTx inserts a message within the given transaction.

func (*MessageStore) Delete

func (ms *MessageStore) Delete(ctx context.Context, id string) error

Delete performs a soft delete on the message identified by id.

func (*MessageStore) DeleteByConversation

func (ms *MessageStore) DeleteByConversation(ctx context.Context, convID string) error

DeleteByConversation performs a soft delete on all messages belonging to the given conversation.

func (*MessageStore) Get

func (ms *MessageStore) Get(ctx context.Context, id string) (*model.Message, error)

Get retrieves a message by its primary key. Returns ErrNotFound if no record exists.

func (*MessageStore) GetByClientMessageID

func (ms *MessageStore) GetByClientMessageID(ctx context.Context, clientMessageID, senderID string) (*model.Message, error)

GetByClientMessageID retrieves a message by its client-generated unique ID and sender ID (composite uniqueness). Returns ErrNotFound if no matching record exists.

func (*MessageStore) GetLatestToolCallingMessage

func (ms *MessageStore) GetLatestToolCallingMessage(ctx context.Context, convID string) (*model.Message, error)

GetLatestToolCallingMessage returns the most recent tool_calling message for a conversation that is in "executing" status. This is used to associate with RemoteCalling without relying on in-memory tracker (which would be lost on server restart). Returns nil, ErrNotFound if no executing tool_calling message exists.

func (*MessageStore) ListByConversation

func (ms *MessageStore) ListByConversation(ctx context.Context, convID string, afterMessageID uint32, limit int) ([]*model.Message, error)

ListByConversation returns messages for the given conversation with MessageID greater than afterMessageID, ordered by MessageID ascending.

func (*MessageStore) ListByTimeRange

func (ms *MessageStore) ListByTimeRange(ctx context.Context, convID string, startTime, endTime time.Time, limit int) ([]*model.Message, error)

ListByTimeRange returns messages for the given conversation within the specified time range (inclusive), ordered by MessageID ascending.

func (*MessageStore) ListRecentByConversation

func (ms *MessageStore) ListRecentByConversation(ctx context.Context, convID string, limit int) ([]*model.Message, error)

ListRecentByConversation returns the most recent messages for a conversation, ordered by MessageID descending (newest first), limited to at most limit rows. Soft-deleted messages are excluded automatically by GORM's soft-delete plugin. This is used by the Agent context manager to load conversation history.

func (*MessageStore) Restore

func (ms *MessageStore) Restore(ctx context.Context, id string) error

Restore undeletes a soft-deleted message identified by id.

func (*MessageStore) RestoreByConversation

func (ms *MessageStore) RestoreByConversation(ctx context.Context, convID string) (int64, error)

RestoreByConversation restores all soft-deleted messages belonging to the given conversation. Returns the number of restored rows.

func (*MessageStore) SearchByConversation

func (ms *MessageStore) SearchByConversation(ctx context.Context, convID, content string, afterMessageID uint32, limit int) ([]*model.Message, error)

SearchByConversation returns messages for the given conversation that contain the specified content substring (case-insensitive via LIKE), ordered by MessageID descending (newest first).

func (*MessageStore) SoftDeleteTx

func (ms *MessageStore) SoftDeleteTx(ctx context.Context, tx *gorm.DB, id string) error

SoftDeleteTx performs a soft delete within the given transaction.

func (*MessageStore) Upsert

func (ms *MessageStore) Upsert(ctx context.Context, msg *model.Message) error

Upsert creates the message if it does not exist, or updates it if it does. Uniqueness is determined by the composite index (client_message_id, sender_id). If a concurrent insert causes a duplicate key error, the operation retries as an update to handle the TOCTOU race between SELECT and INSERT.

type NotificationLogFilter

type NotificationLogFilter struct {
	StartTime *time.Time
	EndTime   *time.Time
	Type      string
	Limit     int
}

NotificationLogFilter defines optional filters for listing notification logs.

type NotificationLogStore

type NotificationLogStore struct {
	// contains filtered or unexported fields
}

NotificationLogStore provides data access operations for push notification logging and deduplication.

func (*NotificationLogStore) CleanupBefore

func (ns *NotificationLogStore) CleanupBefore(ctx context.Context, before time.Time) (int64, error)

CleanupBefore hard-deletes notification logs with CreatedAt strictly before the given time. Returns the number of deleted rows.

func (*NotificationLogStore) CountBefore

func (ns *NotificationLogStore) CountBefore(ctx context.Context, before time.Time) (int64, error)

CountBefore returns the number of notification logs with CreatedAt strictly before the given time without deleting them.

func (*NotificationLogStore) ExportCSV

ExportCSV writes notification logs matching the filter as CSV to the given writer.

func (*NotificationLogStore) ExportJSON

func (ns *NotificationLogStore) ExportJSON(ctx context.Context, w io.Writer, filter NotificationLogFilter) error

ExportJSON writes notification logs matching the filter as JSON to the given writer.

func (*NotificationLogStore) GetLatestSeq

func (ns *NotificationLogStore) GetLatestSeq(ctx context.Context) (uint32, error)

GetLatestSeq returns the highest Seq value in the notification log. Returns 0 if the log is empty.

func (*NotificationLogStore) List

List returns notification logs matching the given filters, ordered by CreatedAt descending (newest first).

func (*NotificationLogStore) ListBySeqRange

func (ns *NotificationLogStore) ListBySeqRange(ctx context.Context, startSeq, endSeq uint32) ([]*model.NotificationLog, error)

ListBySeqRange returns notification logs with Seq in the range [startSeq, endSeq] (inclusive), ordered by Seq ascending.

func (*NotificationLogStore) Save

Save inserts a new notification log record.

func (*NotificationLogStore) SaveTx

SaveTx inserts a notification log record within the given transaction.

type QueueStore

type QueueStore struct {
	// contains filtered or unexported fields
}

QueueStore provides data access operations for the retry task queue.

func (*QueueStore) Count

func (qs *QueueStore) Count(ctx context.Context, status string) (int64, error)

Count returns the total number of retry tasks with the given status.

func (*QueueStore) Delete

func (qs *QueueStore) Delete(ctx context.Context, id string) error

Delete removes a retry task by its primary key.

func (*QueueStore) ListPending

func (qs *QueueStore) ListPending(ctx context.Context, limit int) ([]*model.RetryTask, error)

ListPending returns retry tasks with status "pending" and NextRetry <= now, ordered by NextRetry ascending (soonest first).

func (*QueueStore) MarkFailed

func (qs *QueueStore) MarkFailed(ctx context.Context, id string, lastError string) error

MarkFailed sets the task's status to "failed" so it no longer appears in ListPending results.

func (*QueueStore) Save

func (qs *QueueStore) Save(ctx context.Context, task *model.RetryTask) error

Save inserts a new retry task into the queue.

func (*QueueStore) Update

func (qs *QueueStore) Update(ctx context.Context, task *model.RetryTask) error

Update saves changes to a retry task (attempt count, next retry time, last error, etc.).

type RPCAggregateRow

type RPCAggregateRow struct {
	Method     string  `json:"method"`
	Count      int64   `json:"count"`
	Success    int64   `json:"success"`
	ErrorCount int64   `json:"error_count"`
	AvgMs      float64 `json:"avg_ms"`
}

RPCAggregateRow represents a single row in an aggregate report.

type RPCIntervalRow

type RPCIntervalRow struct {
	Interval   string  `json:"interval"` // e.g. "2026-07-09 10:00"
	Method     string  `json:"method"`
	Count      int64   `json:"count"`
	Success    int64   `json:"success"`
	ErrorCount int64   `json:"error_count"`
	AvgMs      float64 `json:"avg_ms"`
}

RPCIntervalRow represents aggregated RPC log statistics for a time interval.

type RPCLogFilter

type RPCLogFilter struct {
	StartTime          *time.Time
	EndTime            *time.Time
	Method             string
	StatusCode         *int
	StatusCodeLessThan *int // StatusCodeLessThan filters logs where status_code < value.
	ConversationID     string
	Limit              int
}

RPCLogFilter defines optional filters for listing RPC logs.

type RPCLogStore

type RPCLogStore struct {
	// contains filtered or unexported fields
}

RPCLogStore provides data access operations for RPC call logging.

func (*RPCLogStore) Aggregate

func (rs *RPCLogStore) Aggregate(ctx context.Context, startTime, endTime time.Time) ([]RPCAggregateRow, error)

Aggregate returns per-method RPC statistics for the given time range.

func (*RPCLogStore) AggregateByInterval

func (rs *RPCLogStore) AggregateByInterval(ctx context.Context, startTime, endTime time.Time, interval string) ([]RPCIntervalRow, error)

AggregateByInterval returns per-interval, per-method RPC statistics for the given time range [startTime, endTime). Supported intervals: "1m", "5m", "15m", "1h", "1d". Results are ordered by interval ASC, method ASC.

func (*RPCLogStore) CleanupBefore

func (rs *RPCLogStore) CleanupBefore(ctx context.Context, before time.Time) (int64, error)

CleanupBefore hard-deletes RPC logs with CreatedAt strictly before the given time. Returns the number of deleted rows.

func (*RPCLogStore) CleanupOlderThan

func (rs *RPCLogStore) CleanupOlderThan(ctx context.Context, retention time.Duration) (int64, error)

CleanupOlderThan hard-deletes RPC logs older than the given duration.

func (*RPCLogStore) CountBefore

func (rs *RPCLogStore) CountBefore(ctx context.Context, before time.Time) (int64, error)

CountBefore returns the number of RPC logs with CreatedAt strictly before the given time without deleting them.

func (*RPCLogStore) ExportCSV

func (rs *RPCLogStore) ExportCSV(ctx context.Context, w io.Writer, filter RPCLogFilter) error

ExportCSV writes RPC logs matching the filter as CSV to the given writer.

func (*RPCLogStore) ExportJSON

func (rs *RPCLogStore) ExportJSON(ctx context.Context, w io.Writer, filter RPCLogFilter) error

ExportJSON writes RPC logs matching the filter as JSON to the given writer.

func (*RPCLogStore) GetByRequestID

func (rs *RPCLogStore) GetByRequestID(ctx context.Context, requestID string) (*model.RPCLog, error)

GetByRequestID retrieves an RPC log by its request ID. Returns ErrNotFound if no matching record exists.

func (*RPCLogStore) List

func (rs *RPCLogStore) List(ctx context.Context, filter RPCLogFilter) ([]*model.RPCLog, error)

List returns RPC logs matching the given filters, ordered by CreatedAt descending (newest first).

func (*RPCLogStore) Save

func (rs *RPCLogStore) Save(ctx context.Context, log *model.RPCLog) error

Save inserts a new RPC log record.

func (*RPCLogStore) Update

func (rs *RPCLogStore) Update(ctx context.Context, log *model.RPCLog) error

Update updates an existing RPC log record (e.g. after receiving the response).

type RemoteCallingStore

type RemoteCallingStore struct {
	// contains filtered or unexported fields
}

RemoteCallingStore handles RemoteCalling persistence for the client (D-137).

func NewRemoteCallingStore

func NewRemoteCallingStore(db *gorm.DB) *RemoteCallingStore

NewRemoteCallingStore creates a new RemoteCallingStore.

func (*RemoteCallingStore) DeleteByConversation

func (s *RemoteCallingStore) DeleteByConversation(ctx context.Context, conversationID string) error

DeleteByConversation deletes all RemoteCallings for a conversation.

func (*RemoteCallingStore) DeleteByConversationTx

func (s *RemoteCallingStore) DeleteByConversationTx(tx *gorm.DB, conversationID string) error

DeleteByConversationTx deletes all RemoteCallings for a conversation within a transaction.

func (*RemoteCallingStore) GetByConversation

func (s *RemoteCallingStore) GetByConversation(ctx context.Context, conversationID string) ([]*model.RemoteCalling, error)

GetByConversation returns all RemoteCallings for a conversation.

func (*RemoteCallingStore) GetPendingByConversation

func (s *RemoteCallingStore) GetPendingByConversation(ctx context.Context, conversationID string) ([]*model.RemoteCalling, error)

GetPendingByConversation returns all pending RemoteCallings for a conversation.

func (*RemoteCallingStore) Upsert

Upsert creates or updates a RemoteCalling (idempotent by ID).

type SyncStateStore

type SyncStateStore struct {
	// contains filtered or unexported fields
}

SyncStateStore provides key-value data access for client-side synchronization state tracking (e.g. local_max_seq, latest_seq).

func (*SyncStateStore) Get

func (ss *SyncStateStore) Get(ctx context.Context, key string) (string, error)

Get retrieves the value for the given key. Returns ErrNotFound if the key does not exist.

func (*SyncStateStore) GetLatestSeq

func (ss *SyncStateStore) GetLatestSeq(ctx context.Context) (uint32, error)

GetLatestSeq returns the latest_seq value. Returns 0 if not set.

func (*SyncStateStore) GetLocalMaxSeq

func (ss *SyncStateStore) GetLocalMaxSeq(ctx context.Context) (uint32, error)

GetLocalMaxSeq returns the local_max_seq value. Returns 0 if not set.

func (*SyncStateStore) Set

func (ss *SyncStateStore) Set(ctx context.Context, key, value string) error

Set performs an UPSERT for the given key-value pair. If the key already exists, the value is updated; otherwise a new record is inserted.

func (*SyncStateStore) SetLatestSeq

func (ss *SyncStateStore) SetLatestSeq(ctx context.Context, seq uint32) error

SetLatestSeq sets the latest_seq value.

func (*SyncStateStore) SetLocalMaxSeq

func (ss *SyncStateStore) SetLocalMaxSeq(ctx context.Context, seq uint32) error

SetLocalMaxSeq sets the local_max_seq value.

func (*SyncStateStore) SetLocalMaxSeqTx

func (ss *SyncStateStore) SetLocalMaxSeqTx(ctx context.Context, tx *gorm.DB, seq uint32) error

SetLocalMaxSeqTx sets local_max_seq within the given transaction.

type UserUpdateStore

type UserUpdateStore struct {
	// contains filtered or unexported fields
}

UserUpdateStore provides data access operations for the UserUpdate model.

func (*UserUpdateStore) CleanupExpired

func (us *UserUpdateStore) CleanupExpired(ctx context.Context) (int64, error)

CleanupExpired hard-deletes all user updates older than DefaultCleanupRetention (30 days). Convenience wrapper around CleanupExpiredBefore.

func (*UserUpdateStore) CleanupExpiredBefore

func (us *UserUpdateStore) CleanupExpiredBefore(ctx context.Context, before time.Time) (int64, error)

CleanupExpiredBefore hard-deletes all user updates with CreatedAt strictly before the given time. Returns the number of deleted rows.

func (*UserUpdateStore) Create

func (us *UserUpdateStore) Create(ctx context.Context, updates []model.UserUpdate) error

Create inserts a batch of user update records using CreateInBatches (batch size 100) for efficient bulk insertion.

func (*UserUpdateStore) GetLatestSeq

func (us *UserUpdateStore) GetLatestSeq(ctx context.Context, userID string) (uint32, error)

GetLatestSeq returns the highest Seq value for the given user. Returns 0 if the user has no update records.

func (*UserUpdateStore) ListByUser

func (us *UserUpdateStore) ListByUser(ctx context.Context, userID string, afterSeq uint32, limit int) ([]*model.UserUpdate, error)

ListByUser returns user updates for the given userID with Seq greater than afterSeq, ordered by Seq ascending, limited to at most limit rows.

func (*UserUpdateStore) ListByUserRange

func (us *UserUpdateStore) ListByUserRange(ctx context.Context, userID string, afterSeq, maxSeq uint32) ([]*model.UserUpdate, error)

ListByUserRange returns user updates for the given userID with Seq in the range (afterSeq, maxSeq] (exclusive start, inclusive end), ordered by Seq ascending.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL