package database import ( "context" "fmt" "github.com/ddworken/hishtory/shared" "gorm.io/gorm" ) func (db *DB) CountApproximateHistoryEntries(ctx context.Context) (int64, error) { var numDbEntries int64 err := db.WithContext(ctx).Raw("SELECT reltuples::bigint FROM pg_class WHERE relname = 'enc_history_entries'").Row().Scan(&numDbEntries) if err != nil { return 0, fmt.Errorf("DB Error: %w", err) } return numDbEntries, nil } func (db *DB) AllHistoryEntriesForUser(ctx context.Context, userID string) ([]*shared.EncHistoryEntry, error) { var historyEntries []*shared.EncHistoryEntry tx := db.WithContext(ctx).Where("user_id = ?", userID).Find(&historyEntries) if tx.Error != nil { return nil, fmt.Errorf("tx.Error: %w", tx.Error) } return historyEntries, nil } func (db *DB) HistoryEntriesForDevice(ctx context.Context, deviceID string, limit int) ([]*shared.EncHistoryEntry, error) { var historyEntries []*shared.EncHistoryEntry tx := db.WithContext(ctx).Where("device_id = ? AND read_count < ?", deviceID, limit).Find(&historyEntries) if tx.Error != nil { return nil, fmt.Errorf("tx.Error: %w", tx.Error) } return historyEntries, nil } func (db *DB) AddHistoryEntries(ctx context.Context, entries ...*shared.EncHistoryEntry) error { return db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { for _, entry := range entries { resp := tx.Create(&entry) if resp.Error != nil { return fmt.Errorf("resp.Error: %w", resp.Error) } } return nil }) } func (db *DB) AddHistoryEntriesForAllDevices(ctx context.Context, devices []*shared.Device, entries []*shared.EncHistoryEntry) error { chunkSize := 1000 return db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { for _, device := range devices { for _, entry := range entries { entry.DeviceId = device.DeviceId } // Chunk the inserts to prevent the `extended protocol limited to 65535 parameters` error for _, entriesChunk := range shared.Chunks(entries, chunkSize) { resp := tx.Create(&entriesChunk) if resp.Error != nil { return fmt.Errorf("resp.Error: %w", resp.Error) } } } return nil }) } func (db *DB) Unsafe_DeleteAllHistoryEntries(ctx context.Context) error { tx := db.WithContext(ctx).Exec("DELETE FROM enc_history_entries") if tx.Error != nil { return fmt.Errorf("tx.Error: %w", tx.Error) } return nil } func (db *DB) IncrementEntryReadCountsForDevice(ctx context.Context, deviceID string) error { return db.WithContext(ctx).Exec("UPDATE enc_history_entries SET read_count = read_count + 1 WHERE device_id = ?", deviceID).Error }