mirror of
https://github.com/muety/wakapi.git
synced 2025-12-05 22:20:24 -08:00
refactor(perf): user first heartbeats query
This commit is contained in:
@@ -134,20 +134,22 @@ func (r *HeartbeatRepository) GetLatestByFilters(user *models.User, filterMap ma
|
||||
|
||||
func (r *HeartbeatRepository) GetFirstByUsers() ([]*models.TimeByUser, error) {
|
||||
var result []*models.TimeByUser
|
||||
r.db.Model(&models.User{}).
|
||||
Select(utils.QuoteSql(r.db, "users.id as %s, min(time) as %s", "user", "time")).
|
||||
Joins("left join heartbeats on users.id = heartbeats.user_id").
|
||||
Group("users.id").
|
||||
r.db.Raw("with agg as (select " + utils.QuoteSql(r.db, "user_id, min(time) as %s", "time") + " from heartbeats group by user_id) " +
|
||||
"select " + utils.QuoteSql(r.db, "id as %s, time ", "user") +
|
||||
"from users " +
|
||||
"left join agg on agg.user_id = id " +
|
||||
"order by users.id").
|
||||
Scan(&result)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *HeartbeatRepository) GetLastByUsers() ([]*models.TimeByUser, error) {
|
||||
var result []*models.TimeByUser
|
||||
r.db.Model(&models.User{}).
|
||||
Select(utils.QuoteSql(r.db, "users.id as %s, max(time) as %s", "user", "time")).
|
||||
Joins("left join heartbeats on users.id = heartbeats.user_id").
|
||||
Group("user").
|
||||
r.db.Raw("with agg as (select " + utils.QuoteSql(r.db, "user_id, max(time) as %s", "time") + " from heartbeats group by user_id) " +
|
||||
"select " + utils.QuoteSql(r.db, "id as %s, time ", "user") +
|
||||
"from users " +
|
||||
"left join agg on agg.user_id = id " +
|
||||
"order by users.id").
|
||||
Scan(&result)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -68,14 +68,14 @@ func (srv *AggregationService) AggregateSummaries(userIds datastructure.Set[stri
|
||||
slog.Info("generating summaries")
|
||||
|
||||
// Get a map from user ids to the time of their latest summary or nil if none exists yet
|
||||
lastUserSummaryTimes, err := srv.summaryService.GetLatestByUser()
|
||||
lastUserSummaryTimes, err := srv.summaryService.GetLatestByUser() // TODO: build user-specific variant of this query for efficiency
|
||||
if err != nil {
|
||||
config.Log().Error("error occurred", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Get a map from user ids to the time of their earliest heartbeats or nil if none exists yet
|
||||
firstUserHeartbeatTimes, err := srv.heartbeatService.GetFirstByUsers()
|
||||
firstUserHeartbeatTimes, err := srv.heartbeatService.GetFirstByUsers() // TODO: build user-specific variant of this query for efficiency
|
||||
if err != nil {
|
||||
config.Log().Error("error occurred", "error", err)
|
||||
return err
|
||||
|
||||
@@ -66,22 +66,16 @@ func (s stringWriter) WriteString(str string) (int, error) {
|
||||
|
||||
// QuoteDbIdentifier quotes a column name used in a query.
|
||||
func QuoteDbIdentifier(db *gorm.DB, identifier string) string {
|
||||
|
||||
builder := stringWriter{Builder: &strings.Builder{}}
|
||||
|
||||
db.Dialector.QuoteTo(builder, identifier)
|
||||
|
||||
return builder.Builder.String()
|
||||
}
|
||||
|
||||
// QuoteSql quotes a SQL statement with the given identifiers.
|
||||
func QuoteSql(db *gorm.DB, queryTemplate string, identifiers ...string) string {
|
||||
|
||||
quotedIdentifiers := make([]interface{}, len(identifiers))
|
||||
|
||||
for i, identifier := range identifiers {
|
||||
quotedIdentifiers[i] = QuoteDbIdentifier(db, identifier)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(queryTemplate, quotedIdentifiers...)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user