From 50c74e5881178626bcb681e0cfcaca338b11b977 Mon Sep 17 00:00:00 2001 From: David Dworken Date: Tue, 12 Sep 2023 08:30:43 -0700 Subject: [PATCH] Rename a bunch of DB functions + add error checking for DB table creation (follow up to #104) --- backend/server/server.go | 88 ++++++++++++++--------------- internal/database/device.go | 48 +++++----------- internal/database/enchistory.go | 70 ----------------------- internal/database/historyentries.go | 85 ++++++++++++++++++++++++++++ internal/database/usagedata.go | 33 +++++------ 5 files changed, 156 insertions(+), 168 deletions(-) delete mode 100644 internal/database/enchistory.go create mode 100644 internal/database/historyentries.go diff --git a/backend/server/server.go b/backend/server/server.go index d39a3e0..4575350 100644 --- a/backend/server/server.go +++ b/backend/server/server.go @@ -60,7 +60,7 @@ func updateUsageData(r *http.Request, userId, deviceId string, numEntriesHandled return fmt.Errorf("db.UsageDataFindByUserAndDevice: %w", err) } if len(usageData) == 0 { - err := GLOBAL_DB.UsageDataCreate( + err := GLOBAL_DB.CreateUsageData( r.Context(), &shared.UsageData{ UserId: userId, @@ -71,28 +71,28 @@ func updateUsageData(r *http.Request, userId, deviceId string, numEntriesHandled }, ) if err != nil { - return fmt.Errorf("db.UsageDataCreate: %w", err) + return fmt.Errorf("db.CreateUsageData: %w", err) } } else { usage := usageData[0] - if err := GLOBAL_DB.UsageDataUpdate(r.Context(), userId, deviceId, time.Now(), getRemoteAddr(r)); err != nil { - return fmt.Errorf("db.UsageDataUpdate: %w", err) + if err := GLOBAL_DB.UpdateUsageData(r.Context(), userId, deviceId, time.Now(), getRemoteAddr(r)); err != nil { + return fmt.Errorf("db.UpdateUsageData: %w", err) } if numEntriesHandled > 0 { - if err := GLOBAL_DB.UsageDataUpdateNumEntriesHandled(r.Context(), userId, deviceId, numEntriesHandled); err != nil { - return fmt.Errorf("db.UsageDataUpdateNumEntriesHandled: %w", err) + if err := GLOBAL_DB.UpdateUsageDataForNumEntriesHandled(r.Context(), userId, deviceId, numEntriesHandled); err != nil { + return fmt.Errorf("db.UpdateUsageDataForNumEntriesHandled: %w", err) } } if usage.Version != getHishtoryVersion(r) { - if err := GLOBAL_DB.UsageDataUpdateVersion(r.Context(), userId, deviceId, getHishtoryVersion(r)); err != nil { - return fmt.Errorf("db.UsageDataUpdateVersion: %w", err) + if err := GLOBAL_DB.UpdateUsageDataClientVersion(r.Context(), userId, deviceId, getHishtoryVersion(r)); err != nil { + return fmt.Errorf("db.UpdateUsageDataClientVersion: %w", err) } } } if isQuery { - if err := GLOBAL_DB.UsageDataUpdateNumQueries(r.Context(), userId, deviceId); err != nil { - return fmt.Errorf("db.UsageDataUpdateNumQueries: %w", err) + if err := GLOBAL_DB.UpdateUsageDataNumberQueries(r.Context(), userId, deviceId); err != nil { + return fmt.Errorf("db.UpdateUsageDataNumberQueries: %w", err) } } @@ -125,23 +125,23 @@ func usageStatsHandler(w http.ResponseWriter, r *http.Request) { } func statsHandler(w http.ResponseWriter, r *http.Request) { - numDevices, err := GLOBAL_DB.DevicesCount(r.Context()) + numDevices, err := GLOBAL_DB.CountAllDevices(r.Context()) checkGormError(err, 0) numEntriesProcessed, err := GLOBAL_DB.UsageDataTotal(r.Context()) checkGormError(err, 0) - numDbEntries, err := GLOBAL_DB.EncHistoryEntryCount(r.Context()) + numDbEntries, err := GLOBAL_DB.CountHistoryEntries(r.Context()) checkGormError(err, 0) oneWeek := time.Hour * 24 * 7 - weeklyActiveInstalls, err := GLOBAL_DB.WeeklyActiveInstalls(r.Context(), oneWeek) + weeklyActiveInstalls, err := GLOBAL_DB.CountActiveInstalls(r.Context(), oneWeek) checkGormError(err, 0) - weeklyQueryUsers, err := GLOBAL_DB.WeeklyQueryUsers(r.Context(), oneWeek) + weeklyQueryUsers, err := GLOBAL_DB.CountQueryUsers(r.Context(), oneWeek) checkGormError(err, 0) - lastRegistration, err := GLOBAL_DB.LastRegistration(r.Context()) + lastRegistration, err := GLOBAL_DB.DateOfLastRegistration(r.Context()) checkGormError(err, 0) _, _ = fmt.Fprintf(w, "Num devices: %d\n", numDevices) @@ -166,9 +166,7 @@ func apiSubmitHandler(w http.ResponseWriter, r *http.Request) { if len(entries) == 0 { return } - if err := updateUsageData(r, entries[0].UserId, entries[0].DeviceId, len(entries), false); err != nil { - fmt.Printf("updateUsageData: %v\n", err) - } + _ = updateUsageData(r, entries[0].UserId, entries[0].DeviceId /* numEntriesHandled = */, len(entries) /* isQuery = */, false) devices, err := GLOBAL_DB.DevicesForUser(r.Context(), entries[0].UserId) checkGormError(err, 0) @@ -178,7 +176,7 @@ func apiSubmitHandler(w http.ResponseWriter, r *http.Request) { } fmt.Printf("apiSubmitHandler: Found %d devices\n", len(devices)) - err = GLOBAL_DB.DeviceEntriesCreateChunk(r.Context(), devices, entries, 1000) + err = GLOBAL_DB.AddHistoryEntriesForAllDevices(r.Context(), devices, entries) if err != nil { panic(fmt.Errorf("failed to execute transaction to add entries to DB: %w", err)) } @@ -193,8 +191,8 @@ func apiSubmitHandler(w http.ResponseWriter, r *http.Request) { func apiBootstrapHandler(w http.ResponseWriter, r *http.Request) { userId := getRequiredQueryParam(r, "user_id") deviceId := getRequiredQueryParam(r, "device_id") - updateUsageData(r, userId, deviceId, 0, false) - historyEntries, err := GLOBAL_DB.EncHistoryEntriesForUser(r.Context(), userId) + _ = updateUsageData(r, userId, deviceId /* numEntriesHandled = */, 0 /* isQuery = */, false) + historyEntries, err := GLOBAL_DB.AllHistoryEntriesForUser(r.Context(), userId) checkGormError(err, 1) fmt.Printf("apiBootstrapHandler: Found %d entries\n", len(historyEntries)) if err := json.NewEncoder(w).Encode(historyEntries); err != nil { @@ -206,7 +204,7 @@ func apiQueryHandler(w http.ResponseWriter, r *http.Request) { ctx := r.Context() userId := getRequiredQueryParam(r, "user_id") deviceId := getRequiredQueryParam(r, "device_id") - updateUsageData(r, userId, deviceId, 0, true) + _ = updateUsageData(r, userId, deviceId /* numEntriesHandled = */, 0 /* isQuery = */, true) // Delete any entries that match a pending deletion request deletionRequests, err := GLOBAL_DB.DeletionRequestsForUserAndDevice(r.Context(), userId, deviceId) @@ -217,7 +215,7 @@ func apiQueryHandler(w http.ResponseWriter, r *http.Request) { } // Then retrieve - historyEntries, err := GLOBAL_DB.EncHistoryEntriesForDevice(r.Context(), deviceId, 5) + historyEntries, err := GLOBAL_DB.HistoryEntriesForDevice(r.Context(), deviceId, 5) checkGormError(err, 0) fmt.Printf("apiQueryHandler: Found %d entries for %s\n", len(historyEntries), r.URL) if err := json.NewEncoder(w).Encode(historyEntries); err != nil { @@ -229,11 +227,11 @@ func apiQueryHandler(w http.ResponseWriter, r *http.Request) { if isProductionEnvironment() { go func() { span, ctx := tracer.StartSpanFromContext(ctx, "apiQueryHandler.incrementReadCount") - err := GLOBAL_DB.DeviceIncrementReadCounts(ctx, deviceId) + err := GLOBAL_DB.IncrementEntryReadCountsForDevice(ctx, deviceId) span.Finish(tracer.WithError(err)) }() } else { - err := GLOBAL_DB.DeviceIncrementReadCounts(ctx, deviceId) + err := GLOBAL_DB.IncrementEntryReadCountsForDevice(ctx, deviceId) if err != nil { panic("failed to increment read counts") } @@ -265,10 +263,10 @@ func apiRegisterHandler(w http.ResponseWriter, r *http.Request) { userId := getRequiredQueryParam(r, "user_id") deviceId := getRequiredQueryParam(r, "device_id") - existingDevicesCount, err := GLOBAL_DB.DevicesCountForUser(r.Context(), userId) + existingDevicesCount, err := GLOBAL_DB.CountDevicesForUser(r.Context(), userId) checkGormError(err, 0) fmt.Printf("apiRegisterHandler: existingDevicesCount=%d\n", existingDevicesCount) - if err := GLOBAL_DB.DeviceCreate(r.Context(), &shared.Device{UserId: userId, DeviceId: deviceId, RegistrationIp: getRemoteAddr(r), RegistrationDate: time.Now()}); err != nil { + if err := GLOBAL_DB.CreateDevice(r.Context(), &shared.Device{UserId: userId, DeviceId: deviceId, RegistrationIp: getRemoteAddr(r), RegistrationDate: time.Now()}); err != nil { checkGormError(err, 0) } @@ -276,9 +274,7 @@ func apiRegisterHandler(w http.ResponseWriter, r *http.Request) { err := GLOBAL_DB.DumpRequestCreate(r.Context(), &shared.DumpRequest{UserId: userId, RequestingDeviceId: deviceId, RequestTime: time.Now()}) checkGormError(err, 0) } - if err := updateUsageData(r, userId, deviceId, 0, false); err != nil { - fmt.Printf("updateUsageData: %v\n", err) - } + _ = updateUsageData(r, userId, deviceId /* numEntriesHandled = */, 0 /* isQuery = */, false) if GLOBAL_STATSD != nil { GLOBAL_STATSD.Incr("hishtory.register", []string{}, 1.0) @@ -324,11 +320,11 @@ func apiSubmitDumpHandler(w http.ResponseWriter, r *http.Request) { } } - err = GLOBAL_DB.EncHistoryCreateMulti(r.Context(), entries...) + err = GLOBAL_DB.AddHistoryEntries(r.Context(), entries...) checkGormError(err, 0) err = GLOBAL_DB.DumpRequestDeleteForUserAndDevice(r.Context(), userId, requestingDeviceId) checkGormError(err, 0) - updateUsageData(r, userId, srcDeviceId, len(entries), false) + _ = updateUsageData(r, userId, srcDeviceId /* numEntriesHandled = */, len(entries) /* isQuery = */, false) w.Header().Set("Content-Length", "0") w.WriteHeader(http.StatusOK) @@ -384,28 +380,19 @@ func addDeletionRequestHandler(w http.ResponseWriter, r *http.Request) { func healthCheckHandler(w http.ResponseWriter, r *http.Request) { if isProductionEnvironment() { - // Check that we have a reasonable looking set of devices/entries in the DB - //rows, err := GLOBAL_DB.Raw("SELECT true FROM enc_history_entries LIMIT 1 OFFSET 1000").Rows() - //if err != nil { - // panic(fmt.Sprintf("failed to count entries in DB: %v", err)) - //} - //defer rows.Close() - //if !rows.Next() { - // panic("Suspiciously few enc history entries!") - //} - encHistoryEntryCount, err := GLOBAL_DB.EncHistoryEntryCount(r.Context()) + encHistoryEntryCount, err := GLOBAL_DB.CountHistoryEntries(r.Context()) checkGormError(err, 0) if encHistoryEntryCount < 1000 { panic("Suspiciously few enc history entries!") } - deviceCount, err := GLOBAL_DB.DevicesCount(r.Context()) + deviceCount, err := GLOBAL_DB.CountAllDevices(r.Context()) checkGormError(err, 0) if deviceCount < 100 { panic("Suspiciously few devices!") } // Check that we can write to the DB. This entry will get written and then eventually cleaned by the cron. - err = GLOBAL_DB.EncHistoryCreate(r.Context(), &shared.EncHistoryEntry{ + err = GLOBAL_DB.AddHistoryEntries(r.Context(), &shared.EncHistoryEntry{ EncryptedData: []byte("data"), Nonce: []byte("nonce"), DeviceId: "healthcheck_device_id", @@ -432,7 +419,7 @@ func wipeDbEntriesHandler(w http.ResponseWriter, r *http.Request) { panic("refusing to wipe the DB non-test environment") } - err := GLOBAL_DB.EncHistoryClear(r.Context()) + err := GLOBAL_DB.Unsafe_DeleteAllHistoryEntries(r.Context()) checkGormError(err, 0) w.Header().Set("Content-Length", "0") @@ -468,7 +455,10 @@ func OpenDB() (*database.DB, error) { } underlyingDb.SetMaxOpenConns(1) db.Exec("PRAGMA journal_mode = WAL") - db.AddDatabaseTables() + err = db.AddDatabaseTables() + if err != nil { + return nil, fmt.Errorf("failed to create underlying DB tables: %w", err) + } return db, nil } @@ -506,7 +496,10 @@ func OpenDB() (*database.DB, error) { return nil, fmt.Errorf("failed to connect to the DB: %w", err) } } - db.AddDatabaseTables() + err := db.AddDatabaseTables() + if err != nil { + return nil, fmt.Errorf("failed to create underlying DB tables: %w", err) + } return db, nil } @@ -901,3 +894,4 @@ func getMaximumNumberOfAllowedUsers() int { } // TODO(optimization): Maybe optimize the endpoints a bit to reduce the number of round trips required? +// TODO: Add error checking for the calls to updateUsageData(...) that logs it/triggers an alert in prod, but is an error in test diff --git a/internal/database/device.go b/internal/database/device.go index 554e0e9..f8da3d7 100644 --- a/internal/database/device.go +++ b/internal/database/device.go @@ -3,21 +3,11 @@ package database import ( "context" "fmt" + "github.com/ddworken/hishtory/shared" - "gorm.io/gorm" ) -func (db *DB) DevicesCountForUser(ctx context.Context, userID string) (int64, error) { - var existingDevicesCount int64 - tx := db.WithContext(ctx).Model(&shared.Device{}).Where("user_id = ?", userID).Count(&existingDevicesCount) - if tx.Error != nil { - return 0, fmt.Errorf("tx.Error: %w", tx.Error) - } - - return existingDevicesCount, nil -} - -func (db *DB) DevicesCount(ctx context.Context) (int64, error) { +func (db *DB) CountAllDevices(ctx context.Context) (int64, error) { var numDevices int64 = 0 tx := db.WithContext(ctx).Model(&shared.Device{}).Count(&numDevices) if tx.Error != nil { @@ -27,7 +17,17 @@ func (db *DB) DevicesCount(ctx context.Context) (int64, error) { return numDevices, nil } -func (db *DB) DeviceCreate(ctx context.Context, device *shared.Device) error { +func (db *DB) CountDevicesForUser(ctx context.Context, userID string) (int64, error) { + var existingDevicesCount int64 + tx := db.WithContext(ctx).Model(&shared.Device{}).Where("user_id = ?", userID).Count(&existingDevicesCount) + if tx.Error != nil { + return 0, fmt.Errorf("tx.Error: %w", tx.Error) + } + + return existingDevicesCount, nil +} + +func (db *DB) CreateDevice(ctx context.Context, device *shared.Device) error { tx := db.WithContext(ctx).Create(device) if tx.Error != nil { return fmt.Errorf("tx.Error: %w", tx.Error) @@ -36,24 +36,6 @@ func (db *DB) DeviceCreate(ctx context.Context, device *shared.Device) error { return nil } -func (db *DB) DeviceEntriesCreateChunk(ctx context.Context, devices []*shared.Device, entries []*shared.EncHistoryEntry, chunkSize int) error { - 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) DevicesForUser(ctx context.Context, userID string) ([]*shared.Device, error) { var devices []*shared.Device tx := db.WithContext(ctx).Where("user_id = ?", userID).Find(&devices) @@ -63,7 +45,3 @@ func (db *DB) DevicesForUser(ctx context.Context, userID string) ([]*shared.Devi return devices, nil } - -func (db *DB) DeviceIncrementReadCounts(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 -} diff --git a/internal/database/enchistory.go b/internal/database/enchistory.go deleted file mode 100644 index bc15f6b..0000000 --- a/internal/database/enchistory.go +++ /dev/null @@ -1,70 +0,0 @@ -package database - -import ( - "context" - "fmt" - "github.com/ddworken/hishtory/shared" - "gorm.io/gorm" -) - -func (db *DB) EncHistoryEntryCount(ctx context.Context) (int64, error) { - var numDbEntries int64 - tx := db.WithContext(ctx).Model(&shared.EncHistoryEntry{}).Count(&numDbEntries) - if tx.Error != nil { - return 0, fmt.Errorf("tx.Error: %w", tx.Error) - } - - return numDbEntries, nil -} - -func (db *DB) EncHistoryEntriesForUser(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) EncHistoryEntriesForDevice(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) EncHistoryCreate(ctx context.Context, entry *shared.EncHistoryEntry) error { - tx := db.WithContext(ctx).Create(entry) - if tx.Error != nil { - return fmt.Errorf("tx.Error: %w", tx.Error) - } - - return nil -} - -func (db *DB) EncHistoryCreateMulti(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) EncHistoryClear(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 -} diff --git a/internal/database/historyentries.go b/internal/database/historyentries.go new file mode 100644 index 0000000..da15a12 --- /dev/null +++ b/internal/database/historyentries.go @@ -0,0 +1,85 @@ +package database + +import ( + "context" + "fmt" + + "github.com/ddworken/hishtory/shared" + "gorm.io/gorm" +) + +func (db *DB) CountHistoryEntries(ctx context.Context) (int64, error) { + var numDbEntries int64 + tx := db.WithContext(ctx).Model(&shared.EncHistoryEntry{}).Count(&numDbEntries) + if tx.Error != nil { + return 0, fmt.Errorf("tx.Error: %w", tx.Error) + } + + 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 +} diff --git a/internal/database/usagedata.go b/internal/database/usagedata.go index a9973ef..ae86f9e 100644 --- a/internal/database/usagedata.go +++ b/internal/database/usagedata.go @@ -3,8 +3,9 @@ package database import ( "context" "fmt" - "github.com/ddworken/hishtory/shared" "time" + + "github.com/ddworken/hishtory/shared" ) func (db *DB) UsageDataFindByUserAndDevice(ctx context.Context, userId, deviceId string) ([]shared.UsageData, error) { @@ -22,7 +23,7 @@ func (db *DB) UsageDataFindByUserAndDevice(ctx context.Context, userId, deviceId return usageData, nil } -func (db *DB) UsageDataCreate(ctx context.Context, usageData *shared.UsageData) error { +func (db *DB) CreateUsageData(ctx context.Context, usageData *shared.UsageData) error { tx := db.DB.WithContext(ctx).Create(usageData) if tx.Error != nil { return fmt.Errorf("db.WithContext.Create: %w", tx.Error) @@ -31,8 +32,8 @@ func (db *DB) UsageDataCreate(ctx context.Context, usageData *shared.UsageData) return nil } -// UsageDataUpdate updates the entry for a given userID/deviceID pair with the lastUsed and lastIP values -func (db *DB) UsageDataUpdate(ctx context.Context, userId, deviceId string, lastUsed time.Time, lastIP string) error { +// UpdateUsageData updates the entry for a given userID/deviceID pair with the lastUsed and lastIP values +func (db *DB) UpdateUsageData(ctx context.Context, userId, deviceId string, lastUsed time.Time, lastIP string) error { tx := db.DB.WithContext(ctx).Model(&shared.UsageData{}). Where("user_id = ? AND device_id = ?", userId, deviceId). Update("last_used", lastUsed). @@ -45,7 +46,7 @@ func (db *DB) UsageDataUpdate(ctx context.Context, userId, deviceId string, last return nil } -func (db *DB) UsageDataUpdateNumEntriesHandled(ctx context.Context, userId, deviceId string, numEntriesHandled int) error { +func (db *DB) UpdateUsageDataForNumEntriesHandled(ctx context.Context, userId, deviceId string, numEntriesHandled int) error { tx := db.DB.WithContext(ctx).Exec("UPDATE usage_data SET num_entries_handled = COALESCE(num_entries_handled, 0) + ? WHERE user_id = ? AND device_id = ?", numEntriesHandled, userId, deviceId) if tx.Error != nil { @@ -55,7 +56,7 @@ func (db *DB) UsageDataUpdateNumEntriesHandled(ctx context.Context, userId, devi return nil } -func (db *DB) UsageDataUpdateVersion(ctx context.Context, userID, deviceID string, version string) error { +func (db *DB) UpdateUsageDataClientVersion(ctx context.Context, userID, deviceID string, version string) error { tx := db.DB.WithContext(ctx).Exec("UPDATE usage_data SET version = ? WHERE user_id = ? AND device_id = ?", version, userID, deviceID) if tx.Error != nil { @@ -65,7 +66,7 @@ func (db *DB) UsageDataUpdateVersion(ctx context.Context, userID, deviceID strin return nil } -func (db *DB) UsageDataUpdateNumQueries(ctx context.Context, userID, deviceID string) error { +func (db *DB) UpdateUsageDataNumberQueries(ctx context.Context, userID, deviceID string) error { tx := db.DB.WithContext(ctx).Exec("UPDATE usage_data SET num_queries = COALESCE(num_queries, 0) + 1, last_queried = ? WHERE user_id = ? AND device_id = ?", time.Now(), userID, deviceID) if tx.Error != nil { @@ -148,27 +149,27 @@ func (db *DB) UsageDataTotal(ctx context.Context) (int64, error) { return int64(nep.Total), nil } -func (db *DB) WeeklyActiveInstalls(ctx context.Context, since time.Duration) (int64, error) { - var weeklyActiveInstalls int64 - tx := db.WithContext(ctx).Model(&shared.UsageData{}).Where("last_used > ?", time.Now().Add(-since)).Count(&weeklyActiveInstalls) +func (db *DB) CountActiveInstalls(ctx context.Context, since time.Duration) (int64, error) { + var activeInstalls int64 + tx := db.WithContext(ctx).Model(&shared.UsageData{}).Where("last_used > ?", time.Now().Add(-since)).Count(&activeInstalls) if tx.Error != nil { return 0, fmt.Errorf("tx.Error: %w", tx.Error) } - return weeklyActiveInstalls, nil + return activeInstalls, nil } -func (db *DB) WeeklyQueryUsers(ctx context.Context, since time.Duration) (int64, error) { - var weeklyQueryUsers int64 - tx := db.WithContext(ctx).Model(&shared.UsageData{}).Where("last_queried > ?", time.Now().Add(-since)).Count(&weeklyQueryUsers) +func (db *DB) CountQueryUsers(ctx context.Context, since time.Duration) (int64, error) { + var activeQueryUsers int64 + tx := db.WithContext(ctx).Model(&shared.UsageData{}).Where("last_queried > ?", time.Now().Add(-since)).Count(&activeQueryUsers) if tx.Error != nil { return 0, fmt.Errorf("tx.Error: %w", tx.Error) } - return weeklyQueryUsers, nil + return activeQueryUsers, nil } -func (db *DB) LastRegistration(ctx context.Context) (string, error) { +func (db *DB) DateOfLastRegistration(ctx context.Context) (string, error) { var lastRegistration string row := db.WithContext(ctx).Raw("SELECT to_char(max(registration_date), 'DD Month YYYY HH24:MI') FROM devices").Row() if err := row.Scan(&lastRegistration); err != nil {