database

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2025 License: MIT Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AdminTokenEntity

type AdminTokenEntity struct {
	ID          int64     `datastore:"-"`
	TokenHash   string    `datastore:"token_hash"`
	Description string    `datastore:"description"`
	CreatedAt   time.Time `datastore:"created_at"`
	LastUsedAt  time.Time `datastore:"last_used_at"`
	IsActive    bool      `datastore:"is_active"`
}

type Article

type Article struct {
	ID          int       `json:"id"`
	FeedID      int       `json:"feed_id"`
	FeedTitle   string    `json:"feed_title,omitempty"`
	Title       string    `json:"title"`
	URL         string    `json:"url"`
	Content     string    `json:"content"`
	Description string    `json:"description"`
	Author      string    `json:"author"`
	PublishedAt time.Time `json:"published_at"`
	CreatedAt   time.Time `json:"created_at"`
	IsRead      bool      `json:"is_read"`
	IsStarred   bool      `json:"is_starred"`
}

type ArticleEntity

type ArticleEntity struct {
	ID          int64     `datastore:"-"`
	FeedID      int64     `datastore:"feed_id"`
	Title       string    `datastore:"title"`
	URL         string    `datastore:"url"`
	Content     string    `datastore:"content,noindex"`
	Description string    `datastore:"description,noindex"`
	Author      string    `datastore:"author"`
	PublishedAt time.Time `datastore:"published_at"`
	CreatedAt   time.Time `datastore:"created_at"`
	IsRead      bool      `datastore:"is_read"`
	IsStarred   bool      `datastore:"is_starred"`
}

type ArticlePaginationResult

type ArticlePaginationResult struct {
	Articles   []Article
	NextCursor string // Empty string means no more results
}

ArticlePaginationResult contains paginated articles and a cursor for the next page

type AuditLog

type AuditLog struct {
	ID               int       `json:"id"`
	Timestamp        time.Time `json:"timestamp"`
	AdminUserID      int       `json:"admin_user_id"`
	AdminEmail       string    `json:"admin_email"`
	OperationType    string    `json:"operation_type"`
	TargetUserID     int       `json:"target_user_id"`
	TargetUserEmail  string    `json:"target_user_email"`
	OperationDetails string    `json:"operation_details"` // JSON string
	IPAddress        string    `json:"ip_address"`
	Result           string    `json:"result"` // "success" or "failure"
	ErrorMessage     string    `json:"error_message"`
}

type AuditLogEntity

type AuditLogEntity struct {
	ID               int64     `datastore:"-"`
	Timestamp        time.Time `datastore:"timestamp"`
	AdminUserID      int64     `datastore:"admin_user_id"`
	AdminEmail       string    `datastore:"admin_email"`
	OperationType    string    `datastore:"operation_type"`
	TargetUserID     int64     `datastore:"target_user_id"`
	TargetUserEmail  string    `datastore:"target_user_email"`
	OperationDetails string    `datastore:"operation_details,noindex"`
	IPAddress        string    `datastore:"ip_address"`
	Result           string    `datastore:"result"`
	ErrorMessage     string    `datastore:"error_message,noindex"`
}

type DB

type DB struct {
	*sql.DB
}

func (*DB) AddArticle

func (db *DB) AddArticle(article *Article) error

func (*DB) AddFeed

func (db *DB) AddFeed(feed *Feed) error

func (*DB) BatchSetUserArticleStatus

func (db *DB) BatchSetUserArticleStatus(userID int, articles []Article, isRead, isStarred bool) error

func (*DB) CleanupOrphanedUserArticles

func (db *DB) CleanupOrphanedUserArticles(olderThanDays int) (int, error)

CleanupOrphanedUserArticles removes user_articles that reference articles from feeds the user is no longer subscribed to. Only cleans up articles older than the specified number of days. Returns the number of records deleted.

func (*DB) Close

func (db *DB) Close() error

func (*DB) CreateAuditLog

func (db *DB) CreateAuditLog(log *AuditLog) error

Audit log methods for SQLite

func (*DB) CreateIndexes

func (db *DB) CreateIndexes() error

CreateIndexes creates all database indexes (public for testing)

func (*DB) CreateSession

func (db *DB) CreateSession(session *Session) error

Session methods for SQLite

func (*DB) CreateTables

func (db *DB) CreateTables() error

CreateTables creates all necessary database tables (public for testing)

func (*DB) CreateUser

func (db *DB) CreateUser(user *User) error

User methods

func (*DB) DeleteExpiredSessions

func (db *DB) DeleteExpiredSessions() error

func (*DB) DeleteFeed

func (db *DB) DeleteFeed(id int) error

func (*DB) DeleteSession

func (db *DB) DeleteSession(sessionID string) error

func (*DB) FindArticleByURL

func (db *DB) FindArticleByURL(url string) (*Article, error)

func (*DB) GetAllUserFeeds

func (db *DB) GetAllUserFeeds() ([]Feed, error)

func (*DB) GetArticles

func (db *DB) GetArticles(feedID int) ([]Article, error)

func (*DB) GetAuditLogs

func (db *DB) GetAuditLogs(limit, offset int, filters map[string]interface{}) ([]AuditLog, error)

func (*DB) GetFeedByURL

func (db *DB) GetFeedByURL(url string) (*Feed, error)

func (*DB) GetFeeds

func (db *DB) GetFeeds() ([]Feed, error)

func (*DB) GetSession

func (db *DB) GetSession(sessionID string) (*Session, error)

func (*DB) GetUserArticleStatus

func (db *DB) GetUserArticleStatus(userID, articleID int) (*UserArticle, error)

User article status methods

func (*DB) GetUserArticles

func (db *DB) GetUserArticles(userID int) ([]Article, error)

User article methods

func (*DB) GetUserArticlesPaginated

func (db *DB) GetUserArticlesPaginated(userID int, limit int, cursor string, unreadOnly bool) (*ArticlePaginationResult, error)

GetUserArticlesPaginated fetches user articles with cursor-based pagination Uses keyset pagination for efficient querying without scanning skipped rows

func (*DB) GetUserByEmail

func (db *DB) GetUserByEmail(email string) (*User, error)

func (*DB) GetUserByGoogleID

func (db *DB) GetUserByGoogleID(googleID string) (*User, error)

func (*DB) GetUserByID

func (db *DB) GetUserByID(userID int) (*User, error)

func (*DB) GetUserFeedArticles

func (db *DB) GetUserFeedArticles(userID, feedID int) ([]Article, error)

func (*DB) GetUserFeedCount

func (db *DB) GetUserFeedCount(userID int) (int, error)

func (*DB) GetUserFeeds

func (db *DB) GetUserFeeds(userID int) ([]Feed, error)

User feed methods

func (*DB) GetUserUnreadCounts

func (db *DB) GetUserUnreadCounts(userID int) (map[int]int, error)

func (*DB) GrantFreeMonths

func (db *DB) GrantFreeMonths(userID int, months int) error

func (*DB) IsUserSubscriptionActive

func (db *DB) IsUserSubscriptionActive(userID int) (bool, error)

func (*DB) MarkUserArticleRead

func (db *DB) MarkUserArticleRead(userID, articleID int, isRead bool) error

func (*DB) SetUserAdmin

func (db *DB) SetUserAdmin(userID int, isAdmin bool) error

Admin management methods

func (*DB) SetUserArticleStatus

func (db *DB) SetUserArticleStatus(userID, articleID int, isRead, isStarred bool) error

func (*DB) SubscribeUserToFeed

func (db *DB) SubscribeUserToFeed(userID, feedID int) error

func (*DB) ToggleUserArticleStar

func (db *DB) ToggleUserArticleStar(userID, articleID int) error

func (*DB) UnsubscribeUserFromFeed

func (db *DB) UnsubscribeUserFromFeed(userID, feedID int) error

func (*DB) UpdateFeed

func (db *DB) UpdateFeed(feed *Feed) error

func (*DB) UpdateFeedLastFetch

func (db *DB) UpdateFeedLastFetch(feedID int, lastFetch time.Time) error

func (*DB) UpdateFeedTracking

func (db *DB) UpdateFeedTracking(feedID int, lastChecked, lastHadNewContent time.Time, averageUpdateInterval int) error

func (*DB) UpdateUserMaxArticlesOnFeedAdd

func (db *DB) UpdateUserMaxArticlesOnFeedAdd(userID int, maxArticles int) error

func (*DB) UpdateUserSubscription

func (db *DB) UpdateUserSubscription(userID int, status, subscriptionID string, lastPaymentDate, nextBillingDate time.Time) error

Subscription management methods

type Database

type Database interface {
	// User methods
	CreateUser(user *User) error
	GetUserByGoogleID(googleID string) (*User, error)
	GetUserByID(userID int) (*User, error)
	UpdateUserSubscription(userID int, status, subscriptionID string, lastPaymentDate, nextBillingDate time.Time) error
	IsUserSubscriptionActive(userID int) (bool, error)
	GetUserFeedCount(userID int) (int, error)
	UpdateUserMaxArticlesOnFeedAdd(userID int, maxArticles int) error

	// Admin methods
	SetUserAdmin(userID int, isAdmin bool) error
	GrantFreeMonths(userID int, months int) error
	GetUserByEmail(email string) (*User, error)

	// Feed methods
	AddFeed(feed *Feed) error
	UpdateFeed(feed *Feed) error
	UpdateFeedTracking(feedID int, lastChecked, lastHadNewContent time.Time, averageUpdateInterval int) error
	GetFeeds() ([]Feed, error)
	GetFeedByURL(url string) (*Feed, error)
	GetUserFeeds(userID int) ([]Feed, error)
	GetAllUserFeeds() ([]Feed, error)
	DeleteFeed(id int) error
	SubscribeUserToFeed(userID, feedID int) error
	UnsubscribeUserFromFeed(userID, feedID int) error

	// Article methods
	AddArticle(article *Article) error
	GetArticles(feedID int) ([]Article, error)
	FindArticleByURL(url string) (*Article, error)
	GetUserArticles(userID int) ([]Article, error)
	GetUserArticlesPaginated(userID int, limit int, cursor string, unreadOnly bool) (*ArticlePaginationResult, error)
	GetUserFeedArticles(userID, feedID int) ([]Article, error)

	// User article status methods
	GetUserArticleStatus(userID, articleID int) (*UserArticle, error)
	SetUserArticleStatus(userID, articleID int, isRead, isStarred bool) error
	BatchSetUserArticleStatus(userID int, articles []Article, isRead, isStarred bool) error
	MarkUserArticleRead(userID, articleID int, isRead bool) error
	ToggleUserArticleStar(userID, articleID int) error
	GetUserUnreadCounts(userID int) (map[int]int, error)
	CleanupOrphanedUserArticles(olderThanDays int) (int, error)

	// Session methods
	CreateSession(session *Session) error
	GetSession(sessionID string) (*Session, error)
	DeleteSession(sessionID string) error
	DeleteExpiredSessions() error

	// Audit log methods
	CreateAuditLog(log *AuditLog) error
	GetAuditLogs(limit, offset int, filters map[string]interface{}) ([]AuditLog, error)

	UpdateFeedLastFetch(feedID int, lastFetch time.Time) error
	Close() error
}

func InitDB

func InitDB() (Database, error)

type DatastoreDB

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

func NewDatastoreDB

func NewDatastoreDB(projectID string) (*DatastoreDB, error)

func (*DatastoreDB) AddArticle

func (db *DatastoreDB) AddArticle(article *Article) error

func (*DatastoreDB) AddFeed

func (db *DatastoreDB) AddFeed(feed *Feed) error

func (*DatastoreDB) BatchSetUserArticleStatus

func (db *DatastoreDB) BatchSetUserArticleStatus(userID int, articles []Article, isRead, isStarred bool) error

func (*DatastoreDB) CleanupOrphanedUserArticles

func (db *DatastoreDB) CleanupOrphanedUserArticles(olderThanDays int) (int, error)

CleanupOrphanedUserArticles removes UserArticle entities that reference articles from feeds the user is no longer subscribed to. Only cleans up articles older than the specified number of days. Returns the number of records deleted.

func (*DatastoreDB) Close

func (db *DatastoreDB) Close() error

func (*DatastoreDB) CreateAuditLog

func (db *DatastoreDB) CreateAuditLog(log *AuditLog) error

Audit log methods for Datastore

func (*DatastoreDB) CreateSession

func (db *DatastoreDB) CreateSession(session *Session) error

Session methods for Datastore

func (*DatastoreDB) CreateUser

func (db *DatastoreDB) CreateUser(user *User) error

User methods for Datastore

func (*DatastoreDB) DeleteExpiredSessions

func (db *DatastoreDB) DeleteExpiredSessions() error

func (*DatastoreDB) DeleteFeed

func (db *DatastoreDB) DeleteFeed(id int) error

func (*DatastoreDB) DeleteSession

func (db *DatastoreDB) DeleteSession(sessionID string) error

func (*DatastoreDB) FindArticleByURL

func (db *DatastoreDB) FindArticleByURL(url string) (*Article, error)

func (*DatastoreDB) GetAllUserFeeds

func (db *DatastoreDB) GetAllUserFeeds() ([]Feed, error)

func (*DatastoreDB) GetArticles

func (db *DatastoreDB) GetArticles(feedID int) ([]Article, error)

func (*DatastoreDB) GetAuditLogs

func (db *DatastoreDB) GetAuditLogs(limit, offset int, filters map[string]interface{}) ([]AuditLog, error)

func (*DatastoreDB) GetClient

func (db *DatastoreDB) GetClient() *datastore.Client

GetClient returns the underlying datastore client for direct access

func (*DatastoreDB) GetFeedByID

func (db *DatastoreDB) GetFeedByID(feedID int) (*Feed, error)

func (*DatastoreDB) GetFeedByURL

func (db *DatastoreDB) GetFeedByURL(url string) (*Feed, error)

func (*DatastoreDB) GetFeeds

func (db *DatastoreDB) GetFeeds() ([]Feed, error)

func (*DatastoreDB) GetSession

func (db *DatastoreDB) GetSession(sessionID string) (*Session, error)

func (*DatastoreDB) GetUserArticleStatus

func (db *DatastoreDB) GetUserArticleStatus(userID, articleID int) (*UserArticle, error)

func (*DatastoreDB) GetUserArticles

func (db *DatastoreDB) GetUserArticles(userID int) ([]Article, error)

func (*DatastoreDB) GetUserArticlesPaginated

func (db *DatastoreDB) GetUserArticlesPaginated(userID int, limit int, cursor string, unreadOnly bool) (*ArticlePaginationResult, error)

func (*DatastoreDB) GetUserByEmail

func (db *DatastoreDB) GetUserByEmail(email string) (*User, error)

func (*DatastoreDB) GetUserByGoogleID

func (db *DatastoreDB) GetUserByGoogleID(googleID string) (*User, error)

func (*DatastoreDB) GetUserByID

func (db *DatastoreDB) GetUserByID(userID int) (*User, error)

func (*DatastoreDB) GetUserFeedArticles

func (db *DatastoreDB) GetUserFeedArticles(userID, feedID int) ([]Article, error)

func (*DatastoreDB) GetUserFeedCount

func (db *DatastoreDB) GetUserFeedCount(userID int) (int, error)

func (*DatastoreDB) GetUserFeeds

func (db *DatastoreDB) GetUserFeeds(userID int) ([]Feed, error)

func (*DatastoreDB) GetUserUnreadCounts

func (db *DatastoreDB) GetUserUnreadCounts(userID int) (map[int]int, error)

func (*DatastoreDB) GrantFreeMonths

func (db *DatastoreDB) GrantFreeMonths(userID int, months int) error

func (*DatastoreDB) IsUserSubscriptionActive

func (db *DatastoreDB) IsUserSubscriptionActive(userID int) (bool, error)

func (*DatastoreDB) MarkUserArticleRead

func (db *DatastoreDB) MarkUserArticleRead(userID, articleID int, isRead bool) error

func (*DatastoreDB) SetUserAdmin

func (db *DatastoreDB) SetUserAdmin(userID int, isAdmin bool) error

Admin management methods

func (*DatastoreDB) SetUserArticleStatus

func (db *DatastoreDB) SetUserArticleStatus(userID, articleID int, isRead, isStarred bool) error

func (*DatastoreDB) SubscribeUserToFeed

func (db *DatastoreDB) SubscribeUserToFeed(userID, feedID int) error

func (*DatastoreDB) ToggleUserArticleStar

func (db *DatastoreDB) ToggleUserArticleStar(userID, articleID int) error

func (*DatastoreDB) UnsubscribeUserFromFeed

func (db *DatastoreDB) UnsubscribeUserFromFeed(userID, feedID int) error

func (*DatastoreDB) UpdateFeed

func (db *DatastoreDB) UpdateFeed(feed *Feed) error

func (*DatastoreDB) UpdateFeedLastFetch

func (db *DatastoreDB) UpdateFeedLastFetch(feedID int, lastFetch time.Time) error

func (*DatastoreDB) UpdateFeedTracking

func (db *DatastoreDB) UpdateFeedTracking(feedID int, lastChecked, lastHadNewContent time.Time, averageUpdateInterval int) error

func (*DatastoreDB) UpdateUserMaxArticlesOnFeedAdd

func (db *DatastoreDB) UpdateUserMaxArticlesOnFeedAdd(userID int, maxArticles int) error

func (*DatastoreDB) UpdateUserSubscription

func (db *DatastoreDB) UpdateUserSubscription(userID int, status, subscriptionID string, lastPaymentDate, nextBillingDate time.Time) error

Subscription management methods

type Feed

type Feed struct {
	ID                    int       `json:"id"`
	Title                 string    `json:"title"`
	URL                   string    `json:"url"`
	Description           string    `json:"description"`
	CreatedAt             time.Time `json:"created_at"`
	UpdatedAt             time.Time `json:"updated_at"`
	LastFetch             time.Time `json:"last_fetch"`
	LastChecked           time.Time `json:"last_checked"`            // When we last attempted to check for updates
	LastHadNewContent     time.Time `json:"last_had_new_content"`    // When we last found new articles
	AverageUpdateInterval int       `json:"average_update_interval"` // Average seconds between updates (0 = unknown)
}

type FeedEntity

type FeedEntity struct {
	ID                    int64     `datastore:"-"`
	Title                 string    `datastore:"title"`
	URL                   string    `datastore:"url"`
	Description           string    `datastore:"description"`
	CreatedAt             time.Time `datastore:"created_at"`
	UpdatedAt             time.Time `datastore:"updated_at"`
	LastFetch             time.Time `datastore:"last_fetch"`
	LastChecked           time.Time `datastore:"last_checked"`
	LastHadNewContent     time.Time `datastore:"last_had_new_content"`
	AverageUpdateInterval int       `datastore:"average_update_interval"`
}

type Session

type Session struct {
	ID        string    `json:"id"`
	UserID    int       `json:"user_id"`
	CreatedAt time.Time `json:"created_at"`
	ExpiresAt time.Time `json:"expires_at"`
}

type SessionEntity

type SessionEntity struct {
	ID        string    `datastore:"-"` // SessionID is the key
	UserID    int64     `datastore:"user_id"`
	CreatedAt time.Time `datastore:"created_at"`
	ExpiresAt time.Time `datastore:"expires_at"`
}

type User

type User struct {
	ID                   int       `json:"id"`
	GoogleID             string    `json:"google_id"`
	Email                string    `json:"email"`
	Name                 string    `json:"name"`
	Avatar               string    `json:"avatar"`
	CreatedAt            time.Time `json:"created_at"`
	SubscriptionStatus   string    `json:"subscription_status"`      // 'trial', 'active', 'cancelled', 'expired', 'admin'
	SubscriptionID       string    `json:"subscription_id"`          // Stripe subscription ID
	TrialEndsAt          time.Time `json:"trial_ends_at"`            // When free trial expires
	LastPaymentDate      time.Time `json:"last_payment_date"`        // Last successful payment
	NextBillingDate      time.Time `json:"next_billing_date"`        // Next billing date for active subscriptions
	IsAdmin              bool      `json:"is_admin"`                 // Admin users bypass subscription limits
	FreeMonthsRemaining  int       `json:"free_months_remaining"`    // Additional free months granted
	MaxArticlesOnFeedAdd int       `json:"max_articles_on_feed_add"` // Max articles to import when adding a new feed (0 = unlimited)
}

type UserArticle

type UserArticle struct {
	UserID    int  `json:"user_id"`
	ArticleID int  `json:"article_id"`
	IsRead    bool `json:"is_read"`
	IsStarred bool `json:"is_starred"`
}

type UserArticleEntity

type UserArticleEntity struct {
	UserID    int64 `datastore:"user_id"`
	ArticleID int64 `datastore:"article_id"`
	IsRead    bool  `datastore:"is_read"`
	IsStarred bool  `datastore:"is_starred"`
}

type UserEntity

type UserEntity struct {
	ID                   int64     `datastore:"-"`
	GoogleID             string    `datastore:"google_id"`
	Email                string    `datastore:"email"`
	Name                 string    `datastore:"name"`
	Avatar               string    `datastore:"avatar"`
	CreatedAt            time.Time `datastore:"created_at"`
	SubscriptionStatus   string    `datastore:"subscription_status"`
	SubscriptionID       string    `datastore:"subscription_id"`
	TrialEndsAt          time.Time `datastore:"trial_ends_at"`
	LastPaymentDate      time.Time `datastore:"last_payment_date"`
	NextBillingDate      time.Time `datastore:"next_billing_date"`
	IsAdmin              bool      `datastore:"is_admin"`
	FreeMonthsRemaining  int       `datastore:"free_months_remaining"`
	MaxArticlesOnFeedAdd int       `datastore:"max_articles_on_feed_add"`
}

type UserFeed

type UserFeed struct {
	UserID int `json:"user_id"`
	FeedID int `json:"feed_id"`
}

type UserFeedEntity

type UserFeedEntity struct {
	UserID int64 `datastore:"user_id"`
	FeedID int64 `datastore:"feed_id"`
}

Jump to

Keyboard shortcuts

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