mirror of
https://github.com/ddworken/hishtory.git
synced 2025-02-17 02:50:49 +01:00
remove direct db instructions from apiRegisterHandler and statsHandler
This commit is contained in:
parent
382f234c09
commit
0d6aa081d8
@ -125,29 +125,27 @@ func usageStatsHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func statsHandler(w http.ResponseWriter, r *http.Request) {
|
func statsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
var numDevices int64 = 0
|
numDevices, err := GLOBAL_DB.DevicesCount(r.Context())
|
||||||
checkGormResult(GLOBAL_DB.WithContext(r.Context()).Model(&shared.Device{}).Count(&numDevices))
|
checkGormError(err, 0)
|
||||||
type numEntriesProcessed struct {
|
|
||||||
Total int
|
numEntriesProcessed, err := GLOBAL_DB.UsageDataTotal(r.Context())
|
||||||
}
|
checkGormError(err, 0)
|
||||||
nep := numEntriesProcessed{}
|
|
||||||
checkGormResult(GLOBAL_DB.WithContext(r.Context()).Model(&shared.UsageData{}).Select("SUM(num_entries_handled) as total").Find(&nep))
|
numDbEntries, err := GLOBAL_DB.EncHistoryEntryCount(r.Context())
|
||||||
var numDbEntries int64 = 0
|
checkGormError(err, 0)
|
||||||
checkGormResult(GLOBAL_DB.WithContext(r.Context()).Model(&shared.EncHistoryEntry{}).Count(&numDbEntries))
|
|
||||||
|
oneWeek := time.Hour * 24 * 7
|
||||||
|
weeklyActiveInstalls, err := GLOBAL_DB.WeeklyActiveInstalls(r.Context(), oneWeek)
|
||||||
|
checkGormError(err, 0)
|
||||||
|
|
||||||
|
weeklyQueryUsers, err := GLOBAL_DB.WeeklyQueryUsers(r.Context(), oneWeek)
|
||||||
|
checkGormError(err, 0)
|
||||||
|
|
||||||
|
lastRegistration, err := GLOBAL_DB.LastRegistration(r.Context())
|
||||||
|
checkGormError(err, 0)
|
||||||
|
|
||||||
lastWeek := time.Now().AddDate(0, 0, -7)
|
|
||||||
var weeklyActiveInstalls int64 = 0
|
|
||||||
checkGormResult(GLOBAL_DB.WithContext(r.Context()).Model(&shared.UsageData{}).Where("last_used > ?", lastWeek).Count(&weeklyActiveInstalls))
|
|
||||||
var weeklyQueryUsers int64 = 0
|
|
||||||
checkGormResult(GLOBAL_DB.WithContext(r.Context()).Model(&shared.UsageData{}).Where("last_queried > ?", lastWeek).Count(&weeklyQueryUsers))
|
|
||||||
var lastRegistration string = ""
|
|
||||||
row := GLOBAL_DB.WithContext(r.Context()).Raw("select to_char(max(registration_date), 'DD Month YYYY HH24:MI') from devices").Row()
|
|
||||||
err := row.Scan(&lastRegistration)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
_, _ = fmt.Fprintf(w, "Num devices: %d\n", numDevices)
|
_, _ = fmt.Fprintf(w, "Num devices: %d\n", numDevices)
|
||||||
_, _ = fmt.Fprintf(w, "Num history entries processed: %d\n", nep.Total)
|
_, _ = fmt.Fprintf(w, "Num history entries processed: %d\n", numEntriesProcessed)
|
||||||
_, _ = fmt.Fprintf(w, "Num DB entries: %d\n", numDbEntries)
|
_, _ = fmt.Fprintf(w, "Num DB entries: %d\n", numDbEntries)
|
||||||
_, _ = fmt.Fprintf(w, "Weekly active installs: %d\n", weeklyActiveInstalls)
|
_, _ = fmt.Fprintf(w, "Weekly active installs: %d\n", weeklyActiveInstalls)
|
||||||
_, _ = fmt.Fprintf(w, "Weekly active queries: %d\n", weeklyQueryUsers)
|
_, _ = fmt.Fprintf(w, "Weekly active queries: %d\n", weeklyQueryUsers)
|
||||||
@ -275,11 +273,9 @@ func getRemoteAddr(r *http.Request) string {
|
|||||||
|
|
||||||
func apiRegisterHandler(w http.ResponseWriter, r *http.Request) {
|
func apiRegisterHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
if getMaximumNumberOfAllowedUsers() < math.MaxInt {
|
if getMaximumNumberOfAllowedUsers() < math.MaxInt {
|
||||||
row := GLOBAL_DB.WithContext(r.Context()).Raw("SELECT COUNT(DISTINCT devices.user_id) FROM devices").Row()
|
numDistinctUsers, err := GLOBAL_DB.DistinctUsers(r.Context())
|
||||||
var numDistinctUsers int64 = 0
|
|
||||||
err := row.Scan(&numDistinctUsers)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(fmt.Errorf("db.DistinctUsers: %w", err))
|
||||||
}
|
}
|
||||||
if numDistinctUsers >= int64(getMaximumNumberOfAllowedUsers()) {
|
if numDistinctUsers >= int64(getMaximumNumberOfAllowedUsers()) {
|
||||||
panic(fmt.Sprintf("Refusing to allow registration of new device since there are currently %d users and this server allows a max of %d users", numDistinctUsers, getMaximumNumberOfAllowedUsers()))
|
panic(fmt.Sprintf("Refusing to allow registration of new device since there are currently %d users and this server allows a max of %d users", numDistinctUsers, getMaximumNumberOfAllowedUsers()))
|
||||||
@ -287,14 +283,21 @@ func apiRegisterHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
userId := getRequiredQueryParam(r, "user_id")
|
userId := getRequiredQueryParam(r, "user_id")
|
||||||
deviceId := getRequiredQueryParam(r, "device_id")
|
deviceId := getRequiredQueryParam(r, "device_id")
|
||||||
var existingDevicesCount int64 = -1
|
|
||||||
checkGormResult(GLOBAL_DB.WithContext(r.Context()).Model(&shared.Device{}).Where("user_id = ?", userId).Count(&existingDevicesCount))
|
existingDevicesCount, err := GLOBAL_DB.DevicesCountForUser(r.Context(), userId)
|
||||||
|
checkGormError(err, 0)
|
||||||
fmt.Printf("apiRegisterHandler: existingDevicesCount=%d\n", existingDevicesCount)
|
fmt.Printf("apiRegisterHandler: existingDevicesCount=%d\n", existingDevicesCount)
|
||||||
checkGormResult(GLOBAL_DB.WithContext(r.Context()).Create(&shared.Device{UserId: userId, DeviceId: deviceId, RegistrationIp: getRemoteAddr(r), RegistrationDate: time.Now()}))
|
if err := GLOBAL_DB.DeviceCreate(r.Context(), &shared.Device{UserId: userId, DeviceId: deviceId, RegistrationIp: getRemoteAddr(r), RegistrationDate: time.Now()}); err != nil {
|
||||||
if existingDevicesCount > 0 {
|
checkGormError(err, 0)
|
||||||
checkGormResult(GLOBAL_DB.WithContext(r.Context()).Create(&shared.DumpRequest{UserId: userId, RequestingDeviceId: deviceId, RequestTime: time.Now()}))
|
}
|
||||||
|
|
||||||
|
if existingDevicesCount > 0 {
|
||||||
|
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, 0, false)
|
|
||||||
|
|
||||||
if GLOBAL_STATSD != nil {
|
if GLOBAL_STATSD != nil {
|
||||||
GLOBAL_STATSD.Incr("hishtory.register", []string{}, 1.0)
|
GLOBAL_STATSD.Incr("hishtory.register", []string{}, 1.0)
|
||||||
@ -959,10 +962,16 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func checkGormResult(result *gorm.DB) {
|
func checkGormResult(result *gorm.DB) {
|
||||||
if result.Error != nil {
|
checkGormError(result.Error, 1)
|
||||||
_, filename, line, _ := runtime.Caller(1)
|
}
|
||||||
panic(fmt.Sprintf("DB error at %s:%d: %v", filename, line, result.Error))
|
|
||||||
|
func checkGormError(err error, skip int) {
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, filename, line, _ := runtime.Caller(skip + 1)
|
||||||
|
panic(fmt.Sprintf("DB error at %s:%d: %v", filename, line, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMaximumNumberOfAllowedUsers() int {
|
func getMaximumNumberOfAllowedUsers() int {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ddworken/hishtory/shared"
|
"github.com/ddworken/hishtory/shared"
|
||||||
@ -93,3 +94,62 @@ func (db *DB) Stats() (sql.DBStats, error) {
|
|||||||
|
|
||||||
return rawDB.Stats(), nil
|
return rawDB.Stats(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DB) DistinctUsers(ctx context.Context) (int64, error) {
|
||||||
|
row := db.WithContext(ctx).Raw("SELECT COUNT(DISTINCT devices.user_id) FROM devices").Row()
|
||||||
|
var numDistinctUsers int64
|
||||||
|
err := row.Scan(&numDistinctUsers)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("row.Scan: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return numDistinctUsers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
var numDevices int64 = 0
|
||||||
|
tx := db.WithContext(ctx).Model(&shared.Device{}).Count(&numDevices)
|
||||||
|
if tx.Error != nil {
|
||||||
|
return 0, fmt.Errorf("tx.Error: %w", tx.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return numDevices, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) DeviceCreate(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)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) DumpRequestCreate(ctx context.Context, req *shared.DumpRequest) error {
|
||||||
|
tx := db.WithContext(ctx).Create(req)
|
||||||
|
if tx.Error != nil {
|
||||||
|
return fmt.Errorf("tx.Error: %w", tx.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
@ -133,3 +133,47 @@ func (db *DB) UsageDataStats(ctx context.Context) ([]*UsageDataStats, error) {
|
|||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DB) UsageDataTotal(ctx context.Context) (int64, error) {
|
||||||
|
type numEntriesProcessed struct {
|
||||||
|
Total int
|
||||||
|
}
|
||||||
|
nep := numEntriesProcessed{}
|
||||||
|
|
||||||
|
tx := db.WithContext(ctx).Model(&shared.UsageData{}).Select("SUM(num_entries_handled) as total").Find(&nep)
|
||||||
|
if tx.Error != nil {
|
||||||
|
return 0, fmt.Errorf("tx.Error: %w", tx.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)
|
||||||
|
if tx.Error != nil {
|
||||||
|
return 0, fmt.Errorf("tx.Error: %w", tx.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return weeklyActiveInstalls, 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)
|
||||||
|
if tx.Error != nil {
|
||||||
|
return 0, fmt.Errorf("tx.Error: %w", tx.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return weeklyQueryUsers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) LastRegistration(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 {
|
||||||
|
return "", fmt.Errorf("row.Scan: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastRegistration, nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user