refactor: remove unnecessary type conversions and handle ignored errors across codebase

Remove redundant type conversions that Go 1.26 makes unnecessary or that
were already no-ops:

- uuid.UUID(x.Bytes) → x.Bytes (uuid.UUID is [16]byte, same as pgtype UUID Bytes)
- pgtype.UUID{Bytes: [16]byte(u), Valid: true} → pgtype.UUID{Bytes: u, Valid: true}
- (*time.Time)(&x.Time) → &x.Time
- json.RawMessage(x) → x where x is already []byte
- []byte(stringVal) → stringVal where []byte is expected
- int()/int64()/byte() casts on values already of the target type
- Decompressor(fn) → fn (type is identical)

Handle previously ignored error returns:

- collections.go: check json.Unmarshal error in GetCollection
- conversion_service.go: check fileSize.Scan() error
- app_test.go: check app.Shutdown() error in benchmark
This commit is contained in:
2026-04-21 21:15:59 -04:00
parent ad27902790
commit e389df92c3
23 changed files with 85 additions and 75 deletions
+4 -1
View File
@@ -55,6 +55,9 @@ func BenchmarkApp_Shutdown(b *testing.B) {
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
app := New(e) app := New(e)
app.Shutdown() err := app.Shutdown()
if err != nil {
return
}
} }
} }
+1 -1
View File
@@ -79,7 +79,7 @@ func (h *DocsHandler) LoadDocument(docPath string) (*templates.Document, error)
// Convert markdown to HTML // Convert markdown to HTML
var buf bytes.Buffer var buf bytes.Buffer
context := parser.NewContext() context := parser.NewContext()
if err := h.markdown.Convert([]byte(content), &buf, parser.WithContext(context)); err != nil { if err := h.markdown.Convert(content, &buf, parser.WithContext(context)); err != nil {
return nil, fmt.Errorf("failed to convert markdown: %w", err) return nil, fmt.Errorf("failed to convert markdown: %w", err)
} }
+5 -5
View File
@@ -262,7 +262,7 @@ func (h *AuthHandler) Register(c *echo.Context) error {
} }
c.SetCookie(cookie) c.SetCookie(cookie)
_, refreshToken, err := h.CreateRefreshToken(uuid.UUID(user.ID.Bytes)) _, refreshToken, err := h.CreateRefreshToken(user.ID.Bytes)
if err != nil { if err != nil {
if c.Request().Header.Get("HX-Request") == "true" { if c.Request().Header.Get("HX-Request") == "true" {
return c.HTML(http.StatusInternalServerError, `<div class="text-red-500">Failed to generate refresh token</div>`) return c.HTML(http.StatusInternalServerError, `<div class="text-red-500">Failed to generate refresh token</div>`)
@@ -408,7 +408,7 @@ func (h *AuthHandler) Login(c *echo.Context) error {
} }
c.SetCookie(cookie) c.SetCookie(cookie)
_, refreshToken, err := h.CreateRefreshToken(uuid.UUID(user.ID.Bytes)) _, refreshToken, err := h.CreateRefreshToken(user.ID.Bytes)
if err != nil { if err != nil {
if c.Request().Header.Get("HX-Request") == "true" { if c.Request().Header.Get("HX-Request") == "true" {
return c.HTML(http.StatusInternalServerError, `<div class="text-red-500">Failed to generate refresh token</div>`) return c.HTML(http.StatusInternalServerError, `<div class="text-red-500">Failed to generate refresh token</div>`)
@@ -496,7 +496,7 @@ func (h *AuthHandler) UpdateProfile(c *echo.Context) error {
if err != nil { if err != nil {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid user id"}) return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid user id"})
} }
targetUserUUID = pgtype.UUID{Bytes: [16]byte(parsedUUID), Valid: true} targetUserUUID = pgtype.UUID{Bytes: parsedUUID, Valid: true}
} else { } else {
// Self-edit mode // Self-edit mode
targetUserUUID = currentUser.ID targetUserUUID = currentUser.ID
@@ -760,7 +760,7 @@ func (h *AuthHandler) UpdatePassword(c *echo.Context) error {
if err != nil { if err != nil {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid user id"}) return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid user id"})
} }
targetUserUUID = pgtype.UUID{Bytes: [16]byte(parsedUUID), Valid: true} targetUserUUID = pgtype.UUID{Bytes: parsedUUID, Valid: true}
} else { } else {
// Self-change mode // Self-change mode
targetUserUUID = currentUser.ID targetUserUUID = currentUser.ID
@@ -840,7 +840,7 @@ func (h *AuthHandler) DeleteUser(c *echo.Context) error {
if err != nil { if err != nil {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid user id"}) return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid user id"})
} }
targetUserUUID = pgtype.UUID{Bytes: [16]byte(parsedUUID), Valid: true} targetUserUUID = pgtype.UUID{Bytes: parsedUUID, Valid: true}
} else { } else {
// Self-deletion mode // Self-deletion mode
targetUserUUID = currentUser.ID targetUserUUID = currentUser.ID
+9 -6
View File
@@ -160,12 +160,12 @@ func (h *CollectionHandler) GetCollections(c *echo.Context) error {
continue continue
} }
response = append(response, CollectionResponse{ response = append(response, CollectionResponse{
ID: uuid.UUID(col.ID.Bytes), ID: col.ID.Bytes,
Name: col.Name, Name: col.Name,
Description: textToString(col.Description), Description: textToString(col.Description),
Color: textToString(col.Color), Color: textToString(col.Color),
Icon: textToString(col.Icon), Icon: textToString(col.Icon),
AutoAssignRules: json.RawMessage(col.AutoAssignRules), AutoAssignRules: col.AutoAssignRules,
CreatedAt: col.CreatedAt.Time.String(), CreatedAt: col.CreatedAt.Time.String(),
}) })
} }
@@ -214,7 +214,10 @@ func (h *CollectionHandler) GetCollection(c *echo.Context) error {
var viewSettings map[string]interface{} var viewSettings map[string]interface{}
if len(collection.ViewSettings) > 0 { if len(collection.ViewSettings) > 0 {
json.Unmarshal(collection.ViewSettings, &viewSettings) err := json.Unmarshal(collection.ViewSettings, &viewSettings)
if err != nil {
return err
}
} }
return c.JSON(http.StatusOK, map[string]interface{}{ return c.JSON(http.StatusOK, map[string]interface{}{
@@ -460,8 +463,8 @@ func (h *CollectionHandler) GetDeviceMappings(c *echo.Context) error {
response := make([]MappingResponse, 0, len(mappings)) response := make([]MappingResponse, 0, len(mappings))
for _, m := range mappings { for _, m := range mappings {
response = append(response, MappingResponse{ response = append(response, MappingResponse{
ID: uuid.UUID(m.ID.Bytes), ID: m.ID.Bytes,
CollectionID: uuid.UUID(m.CollectionID.Bytes), CollectionID: m.CollectionID.Bytes,
CollectionName: m.CollectionName, CollectionName: m.CollectionName,
DeviceShelfName: textToString(m.DeviceShelfName), DeviceShelfName: textToString(m.DeviceShelfName),
SyncDirection: textToString(m.SyncDirection), SyncDirection: textToString(m.SyncDirection),
@@ -586,7 +589,7 @@ func (h *CollectionHandler) GetBookCollections(c *echo.Context) error {
response := make([]CollectionResponse, 0, len(collections)) response := make([]CollectionResponse, 0, len(collections))
for _, col := range collections { for _, col := range collections {
response = append(response, CollectionResponse{ response = append(response, CollectionResponse{
ID: uuid.UUID(col.ID.Bytes), ID: col.ID.Bytes,
Name: col.Name, Name: col.Name,
Description: textToString(col.Description), Description: textToString(col.Description),
Color: textToString(col.Color), Color: textToString(col.Color),
+10 -10
View File
@@ -257,8 +257,8 @@ func (h *DeviceHandler) ListDevices(c *echo.Context) error {
ID: device.ID.Bytes, ID: device.ID.Bytes,
DeviceName: device.DeviceName, DeviceName: device.DeviceName,
DeviceType: device.DeviceType, DeviceType: device.DeviceType,
LastSync: (*time.Time)(&device.LastSync.Time), LastSync: &device.LastSync.Time,
LastSeen: (*time.Time)(&device.LastSeen.Time), LastSeen: &device.LastSeen.Time,
SyncEnabled: syncEnabled, SyncEnabled: syncEnabled,
AutoSync: autoSync, AutoSync: autoSync,
SyncFrequency: syncFreq, SyncFrequency: syncFreq,
@@ -301,8 +301,8 @@ func (h *DeviceHandler) GetDevicesData(c *echo.Context) ([]DeviceInfo, error) {
ID: device.ID.Bytes, ID: device.ID.Bytes,
DeviceName: device.DeviceName, DeviceName: device.DeviceName,
DeviceType: device.DeviceType, DeviceType: device.DeviceType,
LastSync: (*time.Time)(&device.LastSync.Time), LastSync: &device.LastSync.Time,
LastSeen: (*time.Time)(&device.LastSeen.Time), LastSeen: &device.LastSeen.Time,
SyncEnabled: syncEnabled, SyncEnabled: syncEnabled,
AutoSync: autoSync, AutoSync: autoSync,
SyncFrequency: syncFreq, SyncFrequency: syncFreq,
@@ -353,8 +353,8 @@ func (h *DeviceHandler) GetDevice(c *echo.Context) error {
ID: device.ID.Bytes, ID: device.ID.Bytes,
DeviceName: device.DeviceName, DeviceName: device.DeviceName,
DeviceType: device.DeviceType, DeviceType: device.DeviceType,
LastSync: (*time.Time)(&device.LastSync.Time), LastSync: &device.LastSync.Time,
LastSeen: (*time.Time)(&device.LastSeen.Time), LastSeen: &device.LastSeen.Time,
SyncEnabled: syncEnabled, SyncEnabled: syncEnabled,
AutoSync: autoSync, AutoSync: autoSync,
SyncFrequency: syncFreq, SyncFrequency: syncFreq,
@@ -447,8 +447,8 @@ func (h *DeviceHandler) UpdateDevice(c *echo.Context) error {
ID: updatedDevice.ID.Bytes, ID: updatedDevice.ID.Bytes,
DeviceName: updatedDevice.DeviceName, DeviceName: updatedDevice.DeviceName,
DeviceType: updatedDevice.DeviceType, DeviceType: updatedDevice.DeviceType,
LastSync: (*time.Time)(&updatedDevice.LastSync.Time), LastSync: &updatedDevice.LastSync.Time,
LastSeen: (*time.Time)(&updatedDevice.LastSeen.Time), LastSeen: &updatedDevice.LastSeen.Time,
SyncEnabled: syncEnabled, SyncEnabled: syncEnabled,
AutoSync: autoSync, AutoSync: autoSync,
SyncFrequency: syncFreq, // Now correctly returns the updated value SyncFrequency: syncFreq, // Now correctly returns the updated value
@@ -566,8 +566,8 @@ func (h *DeviceHandler) RegenerateDeviceToken(c *echo.Context) error {
ID: updatedDevice.ID.Bytes, ID: updatedDevice.ID.Bytes,
DeviceName: updatedDevice.DeviceName, DeviceName: updatedDevice.DeviceName,
DeviceType: updatedDevice.DeviceType, DeviceType: updatedDevice.DeviceType,
LastSync: (*time.Time)(&updatedDevice.LastSync.Time), LastSync: &updatedDevice.LastSync.Time,
LastSeen: (*time.Time)(&updatedDevice.LastSeen.Time), LastSeen: &updatedDevice.LastSeen.Time,
SyncEnabled: syncEnabled, SyncEnabled: syncEnabled,
AutoSync: autoSync, AutoSync: autoSync,
SyncFrequency: syncFreq, SyncFrequency: syncFreq,
+1 -1
View File
@@ -77,7 +77,7 @@ func (h *FiltersHandler) GetSavedFilters(c *echo.Context) error {
ID: uuid.Must(uuid.FromBytes(f.ID.Bytes[:])), ID: uuid.Must(uuid.FromBytes(f.ID.Bytes[:])),
Name: f.Name, Name: f.Name,
ResourceType: f.ResourceType, ResourceType: f.ResourceType,
Filters: json.RawMessage(f.Filters), // Return JSONB as-is Filters: f.Filters,
CreatedAt: f.CreatedAt.Time.Format(time.RFC3339), CreatedAt: f.CreatedAt.Time.Format(time.RFC3339),
UpdatedAt: f.UpdatedAt.Time.Format(time.RFC3339), UpdatedAt: f.UpdatedAt.Time.Format(time.RFC3339),
} }
+2 -2
View File
@@ -33,7 +33,7 @@ func (h *KoboHandler) mapContentIdToBookhoardUUID(ctx *echo.Context, contentId s
catalog, err := h.db.GetDeviceCatalogByKoboContentId(ctx.Request().Context(), contentId) catalog, err := h.db.GetDeviceCatalogByKoboContentId(ctx.Request().Context(), contentId)
if err == nil && catalog.ID.Valid { if err == nil && catalog.ID.Valid {
// Found! Use canonical Bookhoard UUID // Found! Use canonical Bookhoard UUID
return uuid.UUID(catalog.BookhoardUuid.Bytes), nil, "catalog_match" return catalog.BookhoardUuid.Bytes, nil, "catalog_match"
} }
// Step 2: ContentId not found - check if it looks like a SHA-256 hash // Step 2: ContentId not found - check if it looks like a SHA-256 hash
@@ -52,7 +52,7 @@ func (h *KoboHandler) mapContentIdToBookhoardUUID(ctx *echo.Context, contentId s
DeliveryDate: pgtype.Timestamptz{Time: time.Now(), Valid: true}, DeliveryDate: pgtype.Timestamptz{Time: time.Now(), Valid: true},
DeliveryMethod: pgtype.Text{String: "sync", Valid: true}, DeliveryMethod: pgtype.Text{String: "sync", Valid: true},
}) })
return uuid.UUID(mediaItem.ID.Bytes), nil, "sha256_match" return mediaItem.ID.Bytes, nil, "sha256_match"
} }
} }
+2 -2
View File
@@ -544,7 +544,7 @@ func (h *KOReaderHandler) updateProgressForBook(c *echo.Context, userID pgtype.U
} }
h.connManager.BroadcastProgressUpdate( h.connManager.BroadcastProgressUpdate(
uuid.UUID(mediaItemID.Bytes), mediaItemID.Bytes,
book.Percentage, book.Percentage,
wsync.SourceDevice{ wsync.SourceDevice{
ID: uuid.UUID(userID.Bytes).String(), ID: uuid.UUID(userID.Bytes).String(),
@@ -608,7 +608,7 @@ func (h *KOReaderHandler) GetMetadata(c *echo.Context) error {
progressData.ChapterProgress = new(progress.ChapterProgress.Float64) progressData.ChapterProgress = new(progress.ChapterProgress.Float64)
} }
if progress.CharacterOffset.Valid { if progress.CharacterOffset.Valid {
progressData.Character = new(int64(progress.CharacterOffset.Int64)) progressData.Character = new(progress.CharacterOffset.Int64)
} }
if progress.CurrentPage.Valid { if progress.CurrentPage.Valid {
progressData.Page = new(int(progress.CurrentPage.Int32)) progressData.Page = new(int(progress.CurrentPage.Int32))
+1 -1
View File
@@ -320,7 +320,7 @@ func parseUUID(uuidStr string) (pgtype.UUID, error) {
if err != nil { if err != nil {
return pgtype.UUID{}, err return pgtype.UUID{}, err
} }
return pgtype.UUID{Bytes: [16]byte(parsedUUID), Valid: true}, nil return pgtype.UUID{Bytes: parsedUUID, Valid: true}, nil
} }
// GetUserVisibleLibrariesData returns libraries for SSR (not JSON response) // GetUserVisibleLibrariesData returns libraries for SSR (not JSON response)
+5 -5
View File
@@ -194,7 +194,7 @@ func (h *OPDSHandler) GetDeviceCatalog(c *echo.Context) error {
if err == nil { if err == nil {
collectionScheme := fmt.Sprintf("%s/collections", baseURL) collectionScheme := fmt.Sprintf("%s/collections", baseURL)
for _, col := range collections { for _, col := range collections {
if col.UserID.Valid && uuid.UUID(col.UserID.Bytes) == userUUID { if col.UserID.Valid && col.UserID.Bytes == userUUID {
entry.AddCategory(collectionScheme, col.Name) entry.AddCategory(collectionScheme, col.Name)
} }
} }
@@ -312,7 +312,7 @@ func (h *OPDSHandler) SearchDeviceCatalog(c *echo.Context) error {
if err == nil { if err == nil {
collectionScheme := fmt.Sprintf("%s/collections", baseURL) collectionScheme := fmt.Sprintf("%s/collections", baseURL)
for _, col := range collections { for _, col := range collections {
if col.UserID.Valid && uuid.UUID(col.UserID.Bytes) == userUUID { if col.UserID.Valid && col.UserID.Bytes == userUUID {
entry.AddCategory(collectionScheme, col.Name) entry.AddCategory(collectionScheme, col.Name)
} }
} }
@@ -367,7 +367,7 @@ func (h *OPDSHandler) DownloadBook(c *echo.Context) error {
// Check if book is in visible library // Check if book is in visible library
visible := false visible := false
for _, lib := range libraries { for _, lib := range libraries {
if uuid.UUID(lib.ID.Bytes) == uuid.UUID(mediaItem.LibraryID.Bytes) { if lib.ID.Bytes == mediaItem.LibraryID.Bytes {
visible = true visible = true
break break
} }
@@ -514,7 +514,7 @@ func (h *OPDSHandler) GetCoverImage(c *echo.Context) error {
// Check if book is in visible library // Check if book is in visible library
visible := false visible := false
for _, lib := range libraries { for _, lib := range libraries {
if uuid.UUID(lib.ID.Bytes) == uuid.UUID(mediaItem.LibraryID.Bytes) { if lib.ID.Bytes == mediaItem.LibraryID.Bytes {
visible = true visible = true
break break
} }
@@ -655,7 +655,7 @@ func (h *OPDSHandler) ListFormats(c *echo.Context) error {
// Check if book is in visible library // Check if book is in visible library
visible := false visible := false
for _, lib := range libraries { for _, lib := range libraries {
if uuid.UUID(lib.ID.Bytes) == uuid.UUID(mediaItem.LibraryID.Bytes) { if lib.ID.Bytes == mediaItem.LibraryID.Bytes {
visible = true visible = true
break break
} }
+1 -1
View File
@@ -76,7 +76,7 @@ func (h *Handler) GetUniversalProgress(c *echo.Context) error {
response["location_references"].(map[string]interface{})["chapter_progress"] = progress.ChapterProgress.Float64 response["location_references"].(map[string]interface{})["chapter_progress"] = progress.ChapterProgress.Float64
} }
if progress.CharacterOffset.Valid { if progress.CharacterOffset.Valid {
response["location_references"].(map[string]interface{})["character"] = int64(progress.CharacterOffset.Int64) response["location_references"].(map[string]interface{})["character"] = progress.CharacterOffset.Int64
} }
deviceSync := map[string]interface{}{} deviceSync := map[string]interface{}{}
+4 -4
View File
@@ -362,7 +362,7 @@ func (h *ReaderHandler) UpdateReadingSpeed(c *echo.Context) error {
// Update reading speed using service // Update reading speed using service
err = h.readerService.CalculateReadingSpeed( err = h.readerService.CalculateReadingSpeed(
c.Request().Context(), c.Request().Context(),
uuid.UUID(user.ID.Bytes), user.ID.Bytes,
parsedUUID, parsedUUID,
req.PagesRead, req.PagesRead,
req.TimeSpentMinutes, req.TimeSpentMinutes,
@@ -477,7 +477,7 @@ func (h *ReaderHandler) GetSettings(c *echo.Context) error {
user := c.Get("user").(database.Users) user := c.Get("user").(database.Users)
// Use reader service to get settings // Use reader service to get settings
settings, err := h.readerService.GetSettings(c.Request().Context(), uuid.UUID(user.ID.Bytes)) settings, err := h.readerService.GetSettings(c.Request().Context(), user.ID.Bytes)
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to fetch settings"}) return c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to fetch settings"})
} }
@@ -510,13 +510,13 @@ func (h *ReaderHandler) UpdateSettings(c *echo.Context) error {
} }
// Use reader service to update settings // Use reader service to update settings
err := h.readerService.UpdateSettings(c.Request().Context(), uuid.UUID(user.ID.Bytes), settings) err := h.readerService.UpdateSettings(c.Request().Context(), user.ID.Bytes, settings)
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to update settings"}) return c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to update settings"})
} }
// Return updated settings // Return updated settings
updatedSettings, _ := h.readerService.GetSettings(c.Request().Context(), uuid.UUID(user.ID.Bytes)) updatedSettings, _ := h.readerService.GetSettings(c.Request().Context(), user.ID.Bytes)
return c.JSON(http.StatusOK, updatedSettings) return c.JSON(http.StatusOK, updatedSettings)
} }
+3 -3
View File
@@ -27,7 +27,7 @@ func parseTokenUUID(tokenStr string) (pgtype.UUID, error) {
if err != nil { if err != nil {
return pgtype.UUID{}, err return pgtype.UUID{}, err
} }
return pgtype.UUID{Bytes: [16]byte(tokenUUID), Valid: true}, nil return pgtype.UUID{Bytes: tokenUUID, Valid: true}, nil
} }
type RefreshTokenResponse struct { type RefreshTokenResponse struct {
@@ -103,8 +103,8 @@ func (h *AuthHandler) CreateRefreshToken(userID uuid.UUID) (string, string, erro
expiresAt := time.Now().Add(refreshTokenExpiration) expiresAt := time.Now().Add(refreshTokenExpiration)
_, err := h.db.CreateRefreshToken(context.Background(), database.CreateRefreshTokenParams{ _, err := h.db.CreateRefreshToken(context.Background(), database.CreateRefreshTokenParams{
UserID: pgtype.UUID{Bytes: [16]byte(userID), Valid: true}, UserID: pgtype.UUID{Bytes: userID, Valid: true},
Token: pgtype.UUID{Bytes: [16]byte(tokenUUID), Valid: true}, Token: pgtype.UUID{Bytes: tokenUUID, Valid: true},
ExpiresAt: pgtype.Timestamptz{Time: expiresAt, Valid: true}, ExpiresAt: pgtype.Timestamptz{Time: expiresAt, Valid: true},
}) })
if err != nil { if err != nil {
+3 -3
View File
@@ -62,7 +62,7 @@ func (h *Handler) ScanLibrary(c *echo.Context) error {
} }
// Fetch library folders from database // Fetch library folders from database
libraryFolders, err := h.db.GetLibraryFolders(c.Request().Context(), pgtype.UUID{Bytes: [16]byte(libraryUUID), Valid: true}) libraryFolders, err := h.db.GetLibraryFolders(c.Request().Context(), pgtype.UUID{Bytes: libraryUUID, Valid: true})
if err != nil { if err != nil {
return c.JSON(http.StatusNotFound, map[string]string{"error": "library not found or has no folders"}) return c.JSON(http.StatusNotFound, map[string]string{"error": "library not found or has no folders"})
} }
@@ -261,7 +261,7 @@ func (h *Handler) StartWatchMode(c *echo.Context) error {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid library id"}) return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid library id"})
} }
if err := h.StartWatchModeForLibrary(c.Request().Context(), pgtype.UUID{Bytes: [16]byte(libraryID), Valid: true}, pgtype.UUID{Bytes: [16]byte(userUUID), Valid: true}); err != nil { if err := h.StartWatchModeForLibrary(c.Request().Context(), pgtype.UUID{Bytes: libraryID, Valid: true}, pgtype.UUID{Bytes: userUUID, Valid: true}); err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
} }
@@ -289,7 +289,7 @@ func (h *Handler) StopWatchMode(c *echo.Context) error {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid library id"}) return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid library id"})
} }
if err := h.StopWatchModeForLibrary(pgtype.UUID{Bytes: [16]byte(libraryID), Valid: true}); err != nil { if err := h.StopWatchModeForLibrary(pgtype.UUID{Bytes: libraryID, Valid: true}); err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
} }
+1 -1
View File
@@ -78,5 +78,5 @@ func parseUUID(s string) (uuid.UUID, error) {
} }
func uuidToPGType(u uuid.UUID) pgtype.UUID { func uuidToPGType(u uuid.UUID) pgtype.UUID {
return pgtype.UUID{Bytes: [16]byte(u), Valid: true} return pgtype.UUID{Bytes: u, Valid: true}
} }
+1 -1
View File
@@ -90,7 +90,7 @@ func createJWTMiddleware(cfg *Config) echo.MiddlewareFunc {
} }
c.Set("user", database.Users{ c.Set("user", database.Users{
ID: pgtype.UUID{Bytes: [16]byte(userUUID), Valid: true}, ID: pgtype.UUID{Bytes: userUUID, Valid: true},
Email: claims["user_email"].(string), Email: claims["user_email"].(string),
Username: claims["user_username"].(string), Username: claims["user_username"].(string),
Role: claims["user_role"].(string), Role: claims["user_role"].(string),
+5 -1
View File
@@ -12,6 +12,7 @@ import (
"time" "time"
"bookhoard/internal/database" "bookhoard/internal/database"
"github.com/jackc/pgx/v5/pgtype" "github.com/jackc/pgx/v5/pgtype"
) )
@@ -81,7 +82,10 @@ func (s *ConversionService) ConvertEPUBToKEPUB(ctx context.Context, mediaItemID
} }
var fileSize pgtype.Int8 var fileSize pgtype.Int8
fileSize.Scan(int64(fileinfo.Size())) err = fileSize.Scan(fileinfo.Size())
if err != nil {
return nil, err
}
_, err = s.db.CreateMediaItemFormat(ctx, database.CreateMediaItemFormatParams{ _, err = s.db.CreateMediaItemFormat(ctx, database.CreateMediaItemFormatParams{
MediaItemID: mediaItemID, MediaItemID: mediaItemID,
+2 -2
View File
@@ -154,7 +154,7 @@ func (s *DashboardService) GetDashboardSections(
} }
results = append(results, DashboardSection{ results = append(results, DashboardSection{
CollectionID: uuid.UUID(coll.ID.Bytes), CollectionID: coll.ID.Bytes,
CollectionName: coll.Name, CollectionName: coll.Name,
Items: items, Items: items,
QueryType: coll.QueryType.String, QueryType: coll.QueryType.String,
@@ -182,7 +182,7 @@ func (s *DashboardService) GetDashboardSections(
} }
results = append(results, DashboardSection{ results = append(results, DashboardSection{
CollectionID: uuid.UUID(coll.ID.Bytes), CollectionID: coll.ID.Bytes,
CollectionName: coll.Name, CollectionName: coll.Name,
Items: items, Items: items,
QueryType: coll.QueryType.String, QueryType: coll.QueryType.String,
+1 -1
View File
@@ -1536,7 +1536,7 @@ func (s *MediaScanner) extractEPUBCover(epubPath string) (string, error) {
opfStartAttr += len("full-path=") opfStartAttr += len("full-path=")
quote := content[opfStart+opfStartAttr] quote := content[opfStart+opfStartAttr]
opfStartQuote := opfStart + opfStartAttr + 1 opfStartQuote := opfStart + opfStartAttr + 1
opfEndQuote := bytes.Index(content[opfStartQuote:], []byte{byte(quote)}) opfEndQuote := bytes.Index(content[opfStartQuote:], []byte{quote})
if opfEndQuote == -1 { if opfEndQuote == -1 {
continue continue
} }
+1 -1
View File
@@ -383,7 +383,7 @@ func (s *ReaderService) UpdateSettings(
// Update in database // Update in database
_, err = s.db.UpsertReaderSettings(ctx, database.UpsertReaderSettingsParams{ _, err = s.db.UpsertReaderSettings(ctx, database.UpsertReaderSettingsParams{
UserID: pgtype.UUID{Bytes: userID, Valid: true}, UserID: pgtype.UUID{Bytes: userID, Valid: true},
SettingValue: []byte(settingsJSON), SettingValue: settingsJSON,
}) })
return err return err
+15 -15
View File
@@ -42,35 +42,35 @@ func newCopyReader(_ []byte, _ uint64, readers []io.ReadCloser) (io.ReadCloser,
//nolint:gochecknoinits //nolint:gochecknoinits
func init() { func init() {
// Copy // Copy
RegisterDecompressor([]byte{0x00}, Decompressor(newCopyReader)) RegisterDecompressor([]byte{0x00}, newCopyReader)
// Delta // Delta
RegisterDecompressor([]byte{0x03}, Decompressor(delta.NewReader)) RegisterDecompressor([]byte{0x03}, delta.NewReader)
// LZMA // LZMA
RegisterDecompressor([]byte{0x03, 0x01, 0x01}, Decompressor(lzma.NewReader)) RegisterDecompressor([]byte{0x03, 0x01, 0x01}, lzma.NewReader)
// BCJ // BCJ
RegisterDecompressor([]byte{0x03, 0x03, 0x01, 0x03}, Decompressor(bra.NewBCJReader)) RegisterDecompressor([]byte{0x03, 0x03, 0x01, 0x03}, bra.NewBCJReader)
// BCJ2 // BCJ2
RegisterDecompressor([]byte{0x03, 0x03, 0x01, 0x1b}, Decompressor(bcj2.NewReader)) RegisterDecompressor([]byte{0x03, 0x03, 0x01, 0x1b}, bcj2.NewReader)
// PPC // PPC
RegisterDecompressor([]byte{0x03, 0x03, 0x02, 0x05}, Decompressor(bra.NewPPCReader)) RegisterDecompressor([]byte{0x03, 0x03, 0x02, 0x05}, bra.NewPPCReader)
// ARM // ARM
RegisterDecompressor([]byte{0x03, 0x03, 0x05, 0x01}, Decompressor(bra.NewARMReader)) RegisterDecompressor([]byte{0x03, 0x03, 0x05, 0x01}, bra.NewARMReader)
// SPARC // SPARC
RegisterDecompressor([]byte{0x03, 0x03, 0x08, 0x05}, Decompressor(bra.NewSPARCReader)) RegisterDecompressor([]byte{0x03, 0x03, 0x08, 0x05}, bra.NewSPARCReader)
// Deflate // Deflate
RegisterDecompressor([]byte{0x04, 0x01, 0x08}, Decompressor(deflate.NewReader)) RegisterDecompressor([]byte{0x04, 0x01, 0x08}, deflate.NewReader)
// Bzip2 // Bzip2
RegisterDecompressor([]byte{0x04, 0x02, 0x02}, Decompressor(bzip2.NewReader)) RegisterDecompressor([]byte{0x04, 0x02, 0x02}, bzip2.NewReader)
// Zstandard // Zstandard
RegisterDecompressor([]byte{0x04, 0xf7, 0x11, 0x01}, Decompressor(zstd.NewReader)) RegisterDecompressor([]byte{0x04, 0xf7, 0x11, 0x01}, zstd.NewReader)
// Brotli // Brotli
RegisterDecompressor([]byte{0x04, 0xf7, 0x11, 0x02}, Decompressor(brotli.NewReader)) RegisterDecompressor([]byte{0x04, 0xf7, 0x11, 0x02}, brotli.NewReader)
// LZ4 // LZ4
RegisterDecompressor([]byte{0x04, 0xf7, 0x11, 0x04}, Decompressor(lz4.NewReader)) RegisterDecompressor([]byte{0x04, 0xf7, 0x11, 0x04}, lz4.NewReader)
// AES-CBC-256 & SHA-256 // AES-CBC-256 & SHA-256
RegisterDecompressor([]byte{0x06, 0xf1, 0x07, 0x01}, Decompressor(aes7z.NewReader)) RegisterDecompressor([]byte{0x06, 0xf1, 0x07, 0x01}, aes7z.NewReader)
// LZMA2 // LZMA2
RegisterDecompressor([]byte{0x21}, Decompressor(lzma2.NewReader)) RegisterDecompressor([]byte{0x21}, lzma2.NewReader)
} }
// RegisterDecompressor allows custom decompressors for a specified method ID. // RegisterDecompressor allows custom decompressors for a specified method ID.
+2 -2
View File
@@ -424,8 +424,8 @@ func dbItemToSyncQueueItem(item database.SyncQueue) SyncQueueItem {
Attempts: item.Attempts.Int32, Attempts: item.Attempts.Int32,
MaxAttempts: item.MaxAttempts.Int32, MaxAttempts: item.MaxAttempts.Int32,
Status: item.Status.String, Status: item.Status.String,
ErrorMessage: (*string)(&item.ErrorMessage.String), ErrorMessage: &item.ErrorMessage.String,
CreatedAt: item.CreatedAt.Time, CreatedAt: item.CreatedAt.Time,
ProcessedAt: (*time.Time)(&item.ProcessedAt.Time), ProcessedAt: &item.ProcessedAt.Time,
} }
} }
+6 -6
View File
@@ -50,10 +50,10 @@ func TestSyncStatusConstants(t *testing.T) {
} }
func TestPriorityConstants(t *testing.T) { func TestPriorityConstants(t *testing.T) {
assert.Equal(t, int(1), PriorityUserInitiated) assert.Equal(t, 1, PriorityUserInitiated)
assert.Equal(t, int(2), PriorityBookCompletion) assert.Equal(t, 2, PriorityBookCompletion)
assert.Equal(t, int(3), PriorityCriticalNote) assert.Equal(t, 3, PriorityCriticalNote)
assert.Equal(t, int(5), PriorityPageTurn) assert.Equal(t, 5, PriorityPageTurn)
assert.Equal(t, int(7), PriorityCheckpoint) assert.Equal(t, 7, PriorityCheckpoint)
assert.Equal(t, int(10), PriorityBackgroundSync) assert.Equal(t, 10, PriorityBackgroundSync)
} }