mirror of
https://git.vectorsigma.ru/public/photoview.git
synced 2026-08-03 21:19:18 +00:00
Fix postgres errors + fix search results without thumbnails
This closes #241
This commit is contained in:
@@ -11,6 +11,8 @@ import (
|
|||||||
|
|
||||||
"github.com/Kagami/go-face"
|
"github.com/Kagami/go-face"
|
||||||
"github.com/photoview/photoview/api/scanner/image_helpers"
|
"github.com/photoview/photoview/api/scanner/image_helpers"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FaceGroup struct {
|
type FaceGroup struct {
|
||||||
@@ -32,8 +34,14 @@ type ImageFace struct {
|
|||||||
type FaceDescriptor face.Descriptor
|
type FaceDescriptor face.Descriptor
|
||||||
|
|
||||||
// GormDataType datatype used in database
|
// GormDataType datatype used in database
|
||||||
func (fd FaceDescriptor) GormDataType() string {
|
func (FaceDescriptor) GormDBDataType(db *gorm.DB, field *schema.Field) string {
|
||||||
|
switch db.Dialector.Name() {
|
||||||
|
case "mysql", "sqlite":
|
||||||
return "BLOB"
|
return "BLOB"
|
||||||
|
case "postgres":
|
||||||
|
return "BYTEA"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan tells GORM how to convert database data to Go format
|
// Scan tells GORM how to convert database data to Go format
|
||||||
@@ -81,8 +89,13 @@ func (fr FaceRectangle) GormDataType() string {
|
|||||||
|
|
||||||
// Scan tells GORM how to convert database data to Go format
|
// Scan tells GORM how to convert database data to Go format
|
||||||
func (fr *FaceRectangle) Scan(value interface{}) error {
|
func (fr *FaceRectangle) Scan(value interface{}) error {
|
||||||
|
stringArray, ok := value.(string)
|
||||||
|
if !ok {
|
||||||
byteArray := value.([]uint8)
|
byteArray := value.([]uint8)
|
||||||
slices := strings.Split(string(byteArray), ":")
|
stringArray = string(byteArray)
|
||||||
|
}
|
||||||
|
|
||||||
|
slices := strings.Split(stringArray, ":")
|
||||||
|
|
||||||
if len(slices) != 4 {
|
if len(slices) != 4 {
|
||||||
return fmt.Errorf("Invalid face rectangle format, expected 4 values, got %d", len(slices))
|
return fmt.Errorf("Invalid face rectangle format, expected 4 values, got %d", len(slices))
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ func (r faceGroupResolver) ImageFaces(ctx context.Context, obj *models.FaceGroup
|
|||||||
query := r.Database.
|
query := r.Database.
|
||||||
Joins("Media").
|
Joins("Media").
|
||||||
Where("face_group_id = ?", obj.ID).
|
Where("face_group_id = ?", obj.ID).
|
||||||
Where("Media.album_id IN (?)", userAlbumIDs)
|
Where("album_id IN (?)", userAlbumIDs)
|
||||||
|
|
||||||
query = models.FormatSQL(query, nil, paginate)
|
query = models.FormatSQL(query, nil, paginate)
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ func (r faceGroupResolver) ImageFaceCount(ctx context.Context, obj *models.FaceG
|
|||||||
Model(&models.ImageFace{}).
|
Model(&models.ImageFace{}).
|
||||||
Joins("Media").
|
Joins("Media").
|
||||||
Where("face_group_id = ?", obj.ID).
|
Where("face_group_id = ?", obj.ID).
|
||||||
Where("Media.album_id IN (?)", userAlbumIDs)
|
Where("album_id IN (?)", userAlbumIDs)
|
||||||
|
|
||||||
var count int64
|
var count int64
|
||||||
if err := query.Count(&count).Error; err != nil {
|
if err := query.Count(&count).Error; err != nil {
|
||||||
@@ -148,6 +148,7 @@ func (r *queryResolver) MyFaceGroups(ctx context.Context, paginate *models.Pagin
|
|||||||
Joins("JOIN image_faces ON image_faces.face_group_id = face_groups.id").
|
Joins("JOIN image_faces ON image_faces.face_group_id = face_groups.id").
|
||||||
Where("image_faces.media_id IN (?)", r.Database.Select("media.id").Table("media").Where("media.album_id IN (?)", userAlbumIDs)).
|
Where("image_faces.media_id IN (?)", r.Database.Select("media.id").Table("media").Where("media.album_id IN (?)", userAlbumIDs)).
|
||||||
Group("image_faces.face_group_id").
|
Group("image_faces.face_group_id").
|
||||||
|
Group("face_groups.id").
|
||||||
Order("CASE WHEN label IS NULL THEN 1 ELSE 0 END").
|
Order("CASE WHEN label IS NULL THEN 1 ELSE 0 END").
|
||||||
Order("COUNT(image_faces.id) DESC")
|
Order("COUNT(image_faces.id) DESC")
|
||||||
|
|
||||||
@@ -371,7 +372,7 @@ func userOwnedFaceGroup(db *gorm.DB, user *models.User, faceGroupID int) (*model
|
|||||||
imageFaceQuery := db.
|
imageFaceQuery := db.
|
||||||
Select("image_faces.id").
|
Select("image_faces.id").
|
||||||
Table("image_faces").
|
Table("image_faces").
|
||||||
Joins("LEFT JOIN media ON media.id = image_faces.media_id").
|
Joins("JOIN media ON media.id = image_faces.media_id").
|
||||||
Where("media.album_id IN (?)", userAlbumIDs)
|
Where("media.album_id IN (?)", userAlbumIDs)
|
||||||
|
|
||||||
faceGroupQuery := db.
|
faceGroupQuery := db.
|
||||||
|
|||||||
@@ -31,8 +31,15 @@ func (r *Resolver) Search(ctx context.Context, query string, _limitMedia *int, _
|
|||||||
|
|
||||||
var media []*models.Media
|
var media []*models.Media
|
||||||
|
|
||||||
|
userSubquery := r.Database.Table("user_albums").Where("user_id = ?", user.ID)
|
||||||
|
if r.Database.Dialector.Name() == "postgres" {
|
||||||
|
userSubquery = userSubquery.Where("album_id = \"Album\".id")
|
||||||
|
} else {
|
||||||
|
userSubquery = userSubquery.Where("album_id = Album.id")
|
||||||
|
}
|
||||||
|
|
||||||
err := r.Database.Joins("Album").
|
err := r.Database.Joins("Album").
|
||||||
Where("EXISTS (?)", r.Database.Table("user_albums").Where("user_id = ?", user.ID).Where("album_id = Album.id")).
|
Where("EXISTS (?)", userSubquery).
|
||||||
Where("media.title LIKE ? OR media.path LIKE ?", wildQuery, wildQuery).
|
Where("media.title LIKE ? OR media.path LIKE ?", wildQuery, wildQuery).
|
||||||
Clauses(clause.OrderBy{
|
Clauses(clause.OrderBy{
|
||||||
Expression: clause.Expr{
|
Expression: clause.Expr{
|
||||||
@@ -40,8 +47,7 @@ func (r *Resolver) Search(ctx context.Context, query string, _limitMedia *int, _
|
|||||||
Vars: []interface{}{wildQuery, wildQuery},
|
Vars: []interface{}{wildQuery, wildQuery},
|
||||||
WithoutParentheses: true},
|
WithoutParentheses: true},
|
||||||
}).
|
}).
|
||||||
Limit(limitMedia).
|
Limit(limitMedia).Find(&media).Error
|
||||||
Find(&media).Error
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "searching media")
|
return nil, errors.Wrapf(err, "searching media")
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ const RowTitle = styled.span`
|
|||||||
|
|
||||||
const PhotoRow = ({ query, media }) => (
|
const PhotoRow = ({ query, media }) => (
|
||||||
<RowLink to={`/album/${media.album.id}`}>
|
<RowLink to={`/album/${media.album.id}`}>
|
||||||
<PhotoSearchThumbnail src={media.thumbnail.url} />
|
<PhotoSearchThumbnail src={media?.thumbnail?.url} />
|
||||||
<RowTitle>{searchHighlighted(query, media.title)}</RowTitle>
|
<RowTitle>{searchHighlighted(query, media.title)}</RowTitle>
|
||||||
</RowLink>
|
</RowLink>
|
||||||
)
|
)
|
||||||
@@ -204,7 +204,7 @@ PhotoRow.propTypes = {
|
|||||||
|
|
||||||
const AlbumRow = ({ query, album }) => (
|
const AlbumRow = ({ query, album }) => (
|
||||||
<RowLink to={`/album/${album.id}`}>
|
<RowLink to={`/album/${album.id}`}>
|
||||||
<AlbumSearchThumbnail src={album.thumbnail.thumbnail.url} />
|
<AlbumSearchThumbnail src={album?.thumbnail?.thumbnail?.url} />
|
||||||
<RowTitle>{searchHighlighted(query, album.title)}</RowTitle>
|
<RowTitle>{searchHighlighted(query, album.title)}</RowTitle>
|
||||||
</RowLink>
|
</RowLink>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user