1
Fork 0

Fix SQL errors for Timeline view,

when using Postgres or Sqlite. Closes #194
This commit is contained in:
viktorstrate 2021-02-14 10:11:10 +01:00
parent d13a99b678
commit 1ba45dbe09
No known key found for this signature in database
GPG Key ID: 3F855605109C1E8A
3 changed files with 64 additions and 5 deletions

1
.gitignore vendored
View File

@ -4,6 +4,7 @@ cache/
media_cache/
/photos_path
photoview.db
photoview.db-journal
.env

48
api/database/helpers.go Normal file
View File

@ -0,0 +1,48 @@
package database
import (
"fmt"
"log"
"gorm.io/gorm"
)
// DateComponent a component of a date (day, month, year)
type DateComponent string
const (
DateCompYear DateComponent = "YEAR"
DateCompMonth DateComponent = "MONTH"
DateCompDay DateComponent = "DAY"
)
// DateExtract is a helper function that is used to generate the proper SQL syntax
// for extracting date components (day, month, year) for different database backends.
func DateExtract(db *gorm.DB, component DateComponent, attribute string) string {
var result string
switch db.Dialector.Name() {
case "mysql", "postgress":
result = fmt.Sprintf("EXTRACT(%s FROM %s)", component, attribute)
break
case "sqlite":
var sqliteFormatted string
switch component {
case DateCompYear:
sqliteFormatted = "%Y"
case DateCompMonth:
sqliteFormatted = "%m"
case DateCompDay:
sqliteFormatted = "%d"
}
result = fmt.Sprintf("CAST(strftime('%s', %s) AS INTEGER)", sqliteFormatted, attribute)
break
default:
log.Panicf("unsupported database backend: %s", db.Dialector.Name())
}
return result
}

View File

@ -2,8 +2,10 @@ package resolvers
import (
"context"
"fmt"
"time"
"github.com/photoview/photoview/api/database"
"github.com/photoview/photoview/api/graphql/auth"
"github.com/photoview/photoview/api/graphql/models"
"gorm.io/gorm"
@ -21,9 +23,9 @@ func (r *queryResolver) MyTimeline(ctx context.Context, paginate *models.Paginat
// album_id, year, month, day
daysQuery := tx.Select(
"albums.id AS album_id",
"YEAR(media.date_shot) AS year",
"MONTH(media.date_shot) AS month",
"DAY(media.date_shot) AS day",
fmt.Sprintf("%s AS year", database.DateExtract(tx, database.DateCompYear, "media.date_shot")),
fmt.Sprintf("%s AS month", database.DateExtract(tx, database.DateCompMonth, "media.date_shot")),
fmt.Sprintf("%s AS day", database.DateExtract(tx, database.DateCompDay, "media.date_shot")),
).
Table("media").
Joins("JOIN albums ON media.album_id = albums.id").
@ -43,7 +45,12 @@ func (r *queryResolver) MyTimeline(ctx context.Context, paginate *models.Paginat
}
}
rows, err := daysQuery.Group("albums.id, YEAR(media.date_shot), MONTH(media.date_shot), DAY(media.date_shot)").
rows, err := daysQuery.Group(
fmt.Sprintf("albums.id, %s, %s, %s",
database.DateExtract(tx, database.DateCompYear, "media.date_shot"),
database.DateExtract(tx, database.DateCompMonth, "media.date_shot"),
database.DateExtract(tx, database.DateCompDay, "media.date_shot")),
).
Order("media.date_shot DESC").
Rows()
@ -81,7 +88,10 @@ func (r *queryResolver) MyTimeline(ctx context.Context, paginate *models.Paginat
// Fill media
var groupMedia []*models.Media
mediaQuery := tx.Model(&models.Media{}).
Where("album_id = ? AND YEAR(date_shot) = ? AND MONTH(date_shot) = ? AND DAY(date_shot) = ?", group.albumID, group.year, group.month, group.day).
Where("album_id = ?", group.albumID).
Where(fmt.Sprintf("%s = ?", database.DateExtract(tx, database.DateCompYear, "media.date_shot")), group.year).
Where(fmt.Sprintf("%s = ?", database.DateExtract(tx, database.DateCompMonth, "media.date_shot")), group.month).
Where(fmt.Sprintf("%s = ?", database.DateExtract(tx, database.DateCompDay, "media.date_shot")), group.day).
Order("date_shot DESC")
if onlyFavorites != nil && *onlyFavorites == true {