Add Filters!

This commit is contained in:
Evan Reichard 2021-02-08 12:41:58 -05:00
parent 5fede6d6da
commit 6697358960
8 changed files with 664 additions and 855 deletions

1
go.mod
View File

@ -10,6 +10,7 @@ require (
github.com/dsoprea/go-exif/v3 v3.0.0-20201216222538-db167117f483 github.com/dsoprea/go-exif/v3 v3.0.0-20201216222538-db167117f483
github.com/gabriel-vasile/mimetype v1.1.2 github.com/gabriel-vasile/mimetype v1.1.2
github.com/google/uuid v1.1.5 github.com/google/uuid v1.1.5
github.com/iancoleman/strcase v0.1.3
github.com/lestrrat-go/jwx v1.0.8 github.com/lestrrat-go/jwx v1.0.8
github.com/mattn/go-sqlite3 v1.14.6 github.com/mattn/go-sqlite3 v1.14.6
github.com/sirupsen/logrus v1.7.0 github.com/sirupsen/logrus v1.7.0

2
go.sum
View File

@ -96,6 +96,8 @@ github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplb
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/iancoleman/strcase v0.1.3 h1:dJBk1m2/qjL1twPLf68JND55vvivMupZ4wIzE8CTdBw=
github.com/iancoleman/strcase v0.1.3/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=

File diff suppressed because it is too large Load Diff

View File

@ -16,15 +16,14 @@ type Album struct {
CreatedAt *time.Time `json:"createdAt" ` CreatedAt *time.Time `json:"createdAt" `
UpdatedAt *time.Time `json:"updatedAt" ` UpdatedAt *time.Time `json:"updatedAt" `
Name string `json:"name" gorm:"unique;not null"` Name string `json:"name" gorm:"unique;not null"`
UserID string `json:"userID" gorm:"not null"`
} }
type AlbumFilter struct { type AlbumFilter struct {
ID *IDFilter `json:"id" ` ID *IDFilter `json:"id" `
CreatedAt *TimeFilter `json:"createdAt" ` CreatedAt *TimeFilter `json:"createdAt" `
UpdatedAt *TimeFilter `json:"updatedAt" ` UpdatedAt *TimeFilter `json:"updatedAt" `
Name *StringFilter `json:"name" ` Name *StringFilter `json:"name" `
And *MediaItemFilter `json:"and" `
Or *MediaItemFilter `json:"or" `
} }
type AlbumResponse struct { type AlbumResponse struct {
@ -39,10 +38,8 @@ type AuthResponse struct {
} }
type AuthTypeFilter struct { type AuthTypeFilter struct {
EqualTo *AuthType `json:"equalTo" ` EqualTo *AuthType `json:"equalTo" `
NotEqualTo *AuthType `json:"notEqualTo" ` NotEqualTo *AuthType `json:"notEqualTo" `
In []AuthType `json:"in" `
NotIn []AuthType `json:"notIn" `
} }
type BooleanFilter struct { type BooleanFilter struct {
@ -56,8 +53,8 @@ type Device struct {
UpdatedAt *time.Time `json:"updatedAt" ` UpdatedAt *time.Time `json:"updatedAt" `
Name string `json:"name" gorm:"not null"` Name string `json:"name" gorm:"not null"`
Type DeviceType `json:"type" gorm:"default:Unknown;not null"` Type DeviceType `json:"type" gorm:"default:Unknown;not null"`
UserID string `json:"userID" gorm:"not null"`
RefreshKey *string `json:"refreshKey" ` RefreshKey *string `json:"refreshKey" `
UserID string `json:"userID" gorm:"not null"`
} }
type DeviceFilter struct { type DeviceFilter struct {
@ -66,8 +63,6 @@ type DeviceFilter struct {
UpdatedAt *TimeFilter `json:"updatedAt" ` UpdatedAt *TimeFilter `json:"updatedAt" `
Name *StringFilter `json:"name" ` Name *StringFilter `json:"name" `
Type *DeviceTypeFilter `json:"type" ` Type *DeviceTypeFilter `json:"type" `
And *MediaItemFilter `json:"and" `
Or *MediaItemFilter `json:"or" `
} }
type DeviceResponse struct { type DeviceResponse struct {
@ -76,39 +71,31 @@ type DeviceResponse struct {
} }
type DeviceTypeFilter struct { type DeviceTypeFilter struct {
EqualTo *DeviceType `json:"equalTo" ` EqualTo *DeviceType `json:"equalTo" `
NotEqualTo *DeviceType `json:"notEqualTo" ` NotEqualTo *DeviceType `json:"notEqualTo" `
In []DeviceType `json:"in" `
NotIn []DeviceType `json:"notIn" `
} }
type FloatFilter struct { type FloatFilter struct {
EqualTo *float64 `json:"equalTo" ` EqualTo *float64 `json:"equalTo" `
NotEqualTo *float64 `json:"notEqualTo" ` NotEqualTo *float64 `json:"notEqualTo" `
LessThan *float64 `json:"lessThan" ` LessThan *float64 `json:"lessThan" `
LessThanOrEqualTo *float64 `json:"lessThanOrEqualTo" ` LessThanOrEqualTo *float64 `json:"lessThanOrEqualTo" `
MoreThan *float64 `json:"moreThan" ` GreaterThan *float64 `json:"greaterThan" `
MoreThanOrEqualTo *float64 `json:"moreThanOrEqualTo" ` GreaterThanOrEqualTo *float64 `json:"greaterThanOrEqualTo" `
In []float64 `json:"in" `
NotIn []float64 `json:"notIn" `
} }
type IDFilter struct { type IDFilter struct {
EqualTo *string `json:"equalTo" ` EqualTo *string `json:"equalTo" `
NotEqualTo *string `json:"notEqualTo" ` NotEqualTo *string `json:"notEqualTo" `
In []string `json:"in" `
NotIn []string `json:"notIn" `
} }
type IntFilter struct { type IntFilter struct {
EqualTo *int `json:"equalTo" ` EqualTo *int `json:"equalTo" `
NotEqualTo *int `json:"notEqualTo" ` NotEqualTo *int `json:"notEqualTo" `
LessThan *int `json:"lessThan" ` LessThan *int `json:"lessThan" `
LessThanOrEqualTo *int `json:"lessThanOrEqualTo" ` LessThanOrEqualTo *int `json:"lessThanOrEqualTo" `
MoreThan *int `json:"moreThan" ` GreaterThan *int `json:"greaterThan" `
MoreThanOrEqualTo *int `json:"moreThanOrEqualTo" ` GreaterThanOrEqualTo *int `json:"greaterThanOrEqualTo" `
In []int `json:"in" `
NotIn []int `json:"notIn" `
} }
type MediaItem struct { type MediaItem struct {
@ -116,29 +103,27 @@ type MediaItem struct {
CreatedAt *time.Time `json:"createdAt" ` CreatedAt *time.Time `json:"createdAt" `
UpdatedAt *time.Time `json:"updatedAt" ` UpdatedAt *time.Time `json:"updatedAt" `
ExifDate *time.Time `json:"exifDate" ` ExifDate *time.Time `json:"exifDate" `
Latitude *float64 `json:"latitude" ` Latitude *float64 `json:"latitude" gorm:"precision:5"`
Longitude *float64 `json:"longitude" ` Longitude *float64 `json:"longitude" gorm:"precision:5"`
IsVideo bool `json:"isVideo" gorm:"default:false;not null"` IsVideo bool `json:"isVideo" gorm:"default:false;not null"`
FileName string `json:"fileName" gorm:"not null"` FileName string `json:"fileName" gorm:"not null"`
OrigName string `json:"origName" gorm:"not null"` OrigName string `json:"origName" gorm:"not null"`
Tags []*Tag `json:"tags" gorm:"many2many:media_tags"` Tags []*Tag `json:"tags" gorm:"many2many:media_tags;foreignKey:ID,UserID;References:ID"`
Albums []*Album `json:"albums" gorm:"many2many:media_albums"` Albums []*Album `json:"albums" gorm:"many2many:media_albums;foreignKey:ID,UserID;Refrences:ID"`
UserID string `json:"userID" gorm:"not null"` UserID string `json:"userID" gorm:"not null"`
} }
type MediaItemFilter struct { type MediaItemFilter struct {
ID *IDFilter `json:"id" ` ID *IDFilter `json:"id" `
CreatedAt *TimeFilter `json:"createdAt" ` CreatedAt *TimeFilter `json:"createdAt" `
UpdatedAt *TimeFilter `json:"updatedAt" ` UpdatedAt *TimeFilter `json:"updatedAt" `
ExifDate *TimeFilter `json:"exifDate" ` ExifDate *TimeFilter `json:"exifDate" `
Latitude *FloatFilter `json:"latitude" ` Latitude *FloatFilter `json:"latitude" `
Longitude *FloatFilter `json:"longitude" ` Longitude *FloatFilter `json:"longitude" `
IsVideo *BooleanFilter `json:"isVideo" ` IsVideo *BooleanFilter `json:"isVideo" `
OrigName *StringFilter `json:"origName" ` OrigName *StringFilter `json:"origName" `
Tags *TagFilter `json:"tags" ` Tags *TagFilter `json:"tags" `
Albums *AlbumFilter `json:"albums" ` Albums *AlbumFilter `json:"albums" `
And *MediaItemFilter `json:"and" `
Or *MediaItemFilter `json:"or" `
} }
type MediaItemResponse struct { type MediaItemResponse struct {
@ -177,29 +162,19 @@ type PageInfo struct {
} }
type RoleFilter struct { type RoleFilter struct {
EqualTo *Role `json:"equalTo" ` EqualTo *Role `json:"equalTo" `
NotEqualTo *Role `json:"notEqualTo" ` NotEqualTo *Role `json:"notEqualTo" `
In []Role `json:"in" `
NotIn []Role `json:"notIn" `
} }
type StringFilter struct { type StringFilter struct {
EqualTo *string `json:"equalTo" ` EqualTo *string `json:"equalTo" `
NotEqualTo *string `json:"notEqualTo" ` NotEqualTo *string `json:"notEqualTo" `
StartWith *string `json:"startWith" ` StartsWith *string `json:"startsWith" `
NotStartWith *string `json:"notStartWith" ` NotStartsWith *string `json:"notStartsWith" `
EndWith *string `json:"endWith" ` EndsWith *string `json:"endsWith" `
NotEndWith *string `json:"notEndWith" ` NotEndsWith *string `json:"notEndsWith" `
Contain *string `json:"contain" ` Contains *string `json:"contains" `
NotContain *string `json:"notContain" ` NotContains *string `json:"notContains" `
In []string `json:"in" `
NotIn []string `json:"notIn" `
StartWithStrict *string `json:"startWithStrict" `
NotStartWithStrict *string `json:"notStartWithStrict" `
EndWithStrict *string `json:"endWithStrict" `
NotEndWithStrict *string `json:"notEndWithStrict" `
ContainStrict *string `json:"containStrict" `
NotContainStrict *string `json:"notContainStrict" `
} }
type Tag struct { type Tag struct {
@ -207,15 +182,14 @@ type Tag struct {
CreatedAt *time.Time `json:"createdAt" ` CreatedAt *time.Time `json:"createdAt" `
UpdatedAt *time.Time `json:"updatedAt" ` UpdatedAt *time.Time `json:"updatedAt" `
Name string `json:"name" gorm:"unique;not null"` Name string `json:"name" gorm:"unique;not null"`
UserID string `json:"userID" gorm:"not null"`
} }
type TagFilter struct { type TagFilter struct {
ID *IDFilter `json:"id" ` ID *IDFilter `json:"id" `
CreatedAt *TimeFilter `json:"createdAt" ` CreatedAt *TimeFilter `json:"createdAt" `
UpdatedAt *TimeFilter `json:"updatedAt" ` UpdatedAt *TimeFilter `json:"updatedAt" `
Name *StringFilter `json:"name" ` Name *StringFilter `json:"name" `
And *MediaItemFilter `json:"and" `
Or *MediaItemFilter `json:"or" `
} }
type TagResponse struct { type TagResponse struct {
@ -224,12 +198,12 @@ type TagResponse struct {
} }
type TimeFilter struct { type TimeFilter struct {
EqualTo *time.Time `json:"equalTo" ` EqualTo *time.Time `json:"equalTo" `
NotEqualTo *time.Time `json:"notEqualTo" ` NotEqualTo *time.Time `json:"notEqualTo" `
LessThan *time.Time `json:"lessThan" ` LessThan *time.Time `json:"lessThan" `
LessThanOrEqualTo *time.Time `json:"lessThanOrEqualTo" ` LessThanOrEqualTo *time.Time `json:"lessThanOrEqualTo" `
MoreThan *time.Time `json:"moreThan" ` GreaterThan *time.Time `json:"greaterThan" `
MoreThanOrEqualTo *time.Time `json:"moreThanOrEqualTo" ` GreaterThanOrEqualTo *time.Time `json:"greaterThanOrEqualTo" `
} }
type User struct { type User struct {
@ -256,8 +230,6 @@ type UserFilter struct {
LastName *StringFilter `json:"lastName" ` LastName *StringFilter `json:"lastName" `
Role *RoleFilter `json:"role" ` Role *RoleFilter `json:"role" `
AuthType *AuthTypeFilter `json:"authType" ` AuthType *AuthTypeFilter `json:"authType" `
And *UserFilter `json:"and" `
Or *UserFilter `json:"or" `
} }
type UserResponse struct { type UserResponse struct {

View File

@ -56,8 +56,8 @@ input TimeFilter {
notEqualTo: Time notEqualTo: Time
lessThan: Time lessThan: Time
lessThanOrEqualTo: Time lessThanOrEqualTo: Time
moreThan: Time greaterThan: Time
moreThanOrEqualTo: Time greaterThanOrEqualTo: Time
} }
input IntFilter { input IntFilter {
@ -65,10 +65,8 @@ input IntFilter {
notEqualTo: Int notEqualTo: Int
lessThan: Int lessThan: Int
lessThanOrEqualTo: Int lessThanOrEqualTo: Int
moreThan: Int greaterThan: Int
moreThanOrEqualTo: Int greaterThanOrEqualTo: Int
in: [Int!]
notIn: [Int!]
} }
input FloatFilter { input FloatFilter {
@ -76,10 +74,8 @@ input FloatFilter {
notEqualTo: Float notEqualTo: Float
lessThan: Float lessThan: Float
lessThanOrEqualTo: Float lessThanOrEqualTo: Float
moreThan: Float greaterThan: Float
moreThanOrEqualTo: Float greaterThanOrEqualTo: Float
in: [Float!]
notIn: [Float!]
} }
input BooleanFilter { input BooleanFilter {
@ -90,49 +86,32 @@ input BooleanFilter {
input IDFilter { input IDFilter {
equalTo: ID equalTo: ID
notEqualTo: ID notEqualTo: ID
in: [ID!]
notIn: [ID!]
} }
input StringFilter { input StringFilter {
equalTo: String equalTo: String
notEqualTo: String notEqualTo: String
startWith: String startsWith: String
notStartWith: String notStartsWith: String
endWith: String endsWith: String
notEndWith: String notEndsWith: String
contain: String contains: String
notContain: String notContains: String
in: [String!]
notIn: [String!]
startWithStrict: String
notStartWithStrict: String
endWithStrict: String
notEndWithStrict: String
containStrict: String
notContainStrict: String
} }
input RoleFilter { input RoleFilter {
equalTo: Role equalTo: Role
notEqualTo: Role notEqualTo: Role
in: [Role!]
notIn: [Role!]
} }
input DeviceTypeFilter { input DeviceTypeFilter {
equalTo: DeviceType equalTo: DeviceType
notEqualTo: DeviceType notEqualTo: DeviceType
in: [DeviceType!]
notIn: [DeviceType!]
} }
input AuthTypeFilter { input AuthTypeFilter {
equalTo: AuthType equalTo: AuthType
notEqualTo: AuthType notEqualTo: AuthType
in: [AuthType!]
notIn: [AuthType!]
} }
# ------------------------------------------------------------ # ------------------------------------------------------------
@ -160,8 +139,8 @@ type Device {
updatedAt: Time updatedAt: Time
name: String! @meta(gorm: "not null") name: String! @meta(gorm: "not null")
type: DeviceType! @meta(gorm: "default:Unknown;not null") type: DeviceType! @meta(gorm: "default:Unknown;not null")
userID: ID! @meta(gorm: "not null")
refreshKey: String @isPrivate refreshKey: String @isPrivate
userID: ID! @meta(gorm: "not null")
} }
type MediaItem { type MediaItem {
@ -169,21 +148,22 @@ type MediaItem {
createdAt: Time createdAt: Time
updatedAt: Time updatedAt: Time
exifDate: Time exifDate: Time
latitude: Float latitude: Float @meta(gorm: "precision:5")
longitude: Float longitude: Float @meta(gorm: "precision:5")
isVideo: Boolean! @meta(gorm: "default:false;not null") isVideo: Boolean! @meta(gorm: "default:false;not null")
fileName: String! @meta(gorm: "not null") fileName: String! @meta(gorm: "not null")
origName: String! @meta(gorm: "not null") origName: String! @meta(gorm: "not null")
tags: [Tag] @meta(gorm: "many2many:media_tags") tags: [Tag] @meta(gorm: "many2many:media_tags;foreignKey:ID,UserID;References:ID")
albums: [Album] @meta(gorm: "many2many:media_albums") albums: [Album] @meta(gorm: "many2many:media_albums;foreignKey:ID,UserID;Refrences:ID")
userID: ID! @meta(gorm: "not null") userID: ID! @meta(gorm: "not null")
} }
type Tag { type Tag {
id: ID! @meta(gorm: "primaryKey;not null") id: ID! @meta(gorm: "primaryKey;not null")
createdAt: Time createdAt: Time
updatedAt: Time updatedAt: Time
name: String! @meta(gorm: "unique;not null") name: String! @meta(gorm: "unique;not null")
userID: ID! @meta(gorm: "not null")
} }
type Album { type Album {
@ -191,7 +171,7 @@ type Album {
createdAt: Time createdAt: Time
updatedAt: Time updatedAt: Time
name: String! @meta(gorm: "unique;not null") name: String! @meta(gorm: "unique;not null")
# userID: ID! @meta(gorm: "not null") userID: ID! @meta(gorm: "not null")
} }
# ------------------------------------------------------------ # ------------------------------------------------------------
@ -208,8 +188,8 @@ input UserFilter {
role: RoleFilter role: RoleFilter
authType: AuthTypeFilter authType: AuthTypeFilter
and: UserFilter # and: UserFilter
or: UserFilter # or: UserFilter
} }
input MediaItemFilter { input MediaItemFilter {
@ -224,8 +204,8 @@ input MediaItemFilter {
tags: TagFilter tags: TagFilter
albums: AlbumFilter albums: AlbumFilter
and: MediaItemFilter # and: MediaItemFilter
or: MediaItemFilter # or: MediaItemFilter
} }
input DeviceFilter { input DeviceFilter {
@ -235,8 +215,8 @@ input DeviceFilter {
name: StringFilter name: StringFilter
type: DeviceTypeFilter type: DeviceTypeFilter
and: MediaItemFilter # and: MediaItemFilter
or: MediaItemFilter # or: MediaItemFilter
} }
input TagFilter { input TagFilter {
@ -245,8 +225,8 @@ input TagFilter {
updatedAt: TimeFilter updatedAt: TimeFilter
name: StringFilter name: StringFilter
and: MediaItemFilter # and: MediaItemFilter
or: MediaItemFilter # or: MediaItemFilter
} }
input AlbumFilter { input AlbumFilter {
@ -255,8 +235,8 @@ input AlbumFilter {
updatedAt: TimeFilter updatedAt: TimeFilter
name: StringFilter name: StringFilter
and: MediaItemFilter # and: MediaItemFilter
or: MediaItemFilter # or: MediaItemFilter
} }
# ------------------------------------------------------------ # ------------------------------------------------------------

View File

@ -102,13 +102,14 @@ func (r *mutationResolver) CreateAlbum(ctx context.Context, input model.NewAlbum
// Get Context // Get Context
authContext := ctx.Value("auth").(*model.AuthContext) authContext := ctx.Value("auth").(*model.AuthContext)
accessToken := *authContext.AccessToken accessToken := *authContext.AccessToken
_, ok := accessToken.Get("sub") userID, ok := accessToken.Get("sub")
if !ok { if !ok {
return nil, errors.New("Upload Failed") return nil, errors.New("Upload Failed")
} }
album := &model.Album{ album := &model.Album{
Name: input.Name, Name: input.Name,
UserID: userID.(string),
} }
err := r.DB.CreateAlbum(album) err := r.DB.CreateAlbum(album)
@ -120,8 +121,17 @@ func (r *mutationResolver) CreateAlbum(ctx context.Context, input model.NewAlbum
} }
func (r *mutationResolver) CreateTag(ctx context.Context, input model.NewTag) (*model.Tag, error) { func (r *mutationResolver) CreateTag(ctx context.Context, input model.NewTag) (*model.Tag, error) {
// Get Context
authContext := ctx.Value("auth").(*model.AuthContext)
accessToken := *authContext.AccessToken
userID, ok := accessToken.Get("sub")
if !ok {
return nil, errors.New("Upload Failed")
}
tag := &model.Tag{ tag := &model.Tag{
Name: input.Name, Name: input.Name,
UserID: userID.(string),
} }
err := r.DB.CreateTag(tag) err := r.DB.CreateTag(tag)
@ -223,13 +233,20 @@ func (r *queryResolver) Logout(ctx context.Context) (*model.AuthResponse, error)
} }
func (r *queryResolver) MediaItem(ctx context.Context, id string, delete *bool) (*model.MediaItem, error) { func (r *queryResolver) MediaItem(ctx context.Context, id string, delete *bool) (*model.MediaItem, error) {
// TODO: User Specific // Get Context
deviceID, err := uuid.Parse(id) authContext := ctx.Value("auth").(*model.AuthContext)
accessToken := *authContext.AccessToken
userID, ok := accessToken.Get("sub")
if !ok {
return nil, errors.New("Context Error")
}
mediaItemID, err := uuid.Parse(id)
if err != nil { if err != nil {
return nil, errors.New("Invalid ID Format") return nil, errors.New("Invalid ID Format")
} }
foundMediaItem := &model.MediaItem{ID: deviceID.String()} foundMediaItem := &model.MediaItem{ID: mediaItemID.String(), UserID: userID.(string)}
count, err := r.DB.MediaItem(foundMediaItem) count, err := r.DB.MediaItem(foundMediaItem)
if err != nil { if err != nil {
return nil, errors.New("DB Error") return nil, errors.New("DB Error")
@ -240,13 +257,20 @@ func (r *queryResolver) MediaItem(ctx context.Context, id string, delete *bool)
} }
func (r *queryResolver) Device(ctx context.Context, id string, delete *bool) (*model.Device, error) { func (r *queryResolver) Device(ctx context.Context, id string, delete *bool) (*model.Device, error) {
// TODO: User Specific // Get Context
authContext := ctx.Value("auth").(*model.AuthContext)
accessToken := *authContext.AccessToken
userID, ok := accessToken.Get("sub")
if !ok {
return nil, errors.New("Context Error")
}
deviceID, err := uuid.Parse(id) deviceID, err := uuid.Parse(id)
if err != nil { if err != nil {
return nil, errors.New("Invalid ID Format") return nil, errors.New("Invalid ID Format")
} }
foundDevice := &model.Device{ID: deviceID.String()} foundDevice := &model.Device{ID: deviceID.String(), UserID: userID.(string)}
count, err := r.DB.Device(foundDevice) count, err := r.DB.Device(foundDevice)
if err != nil { if err != nil {
return nil, errors.New("DB Error") return nil, errors.New("DB Error")
@ -257,13 +281,20 @@ func (r *queryResolver) Device(ctx context.Context, id string, delete *bool) (*m
} }
func (r *queryResolver) Album(ctx context.Context, id string, delete *bool) (*model.Album, error) { func (r *queryResolver) Album(ctx context.Context, id string, delete *bool) (*model.Album, error) {
// TODO: User Specific // Get Context
authContext := ctx.Value("auth").(*model.AuthContext)
accessToken := *authContext.AccessToken
userID, ok := accessToken.Get("sub")
if !ok {
return nil, errors.New("Context Error")
}
albumID, err := uuid.Parse(id) albumID, err := uuid.Parse(id)
if err != nil { if err != nil {
return nil, errors.New("Invalid ID Format") return nil, errors.New("Invalid ID Format")
} }
foundAlbum := &model.Album{ID: albumID.String()} foundAlbum := &model.Album{ID: albumID.String(), UserID: userID.(string)}
count, err := r.DB.Album(foundAlbum) count, err := r.DB.Album(foundAlbum)
if err != nil { if err != nil {
return nil, errors.New("DB Error") return nil, errors.New("DB Error")
@ -323,7 +354,7 @@ func (r *queryResolver) Me(ctx context.Context, delete *bool) (*model.User, erro
} }
func (r *queryResolver) MediaItems(ctx context.Context, delete *bool, filter *model.MediaItemFilter, count *int, page *int) (*model.MediaItemResponse, error) { func (r *queryResolver) MediaItems(ctx context.Context, delete *bool, filter *model.MediaItemFilter, count *int, page *int) (*model.MediaItemResponse, error) {
resp, totalCount, err := r.DB.MediaItems() resp, totalCount, err := r.DB.MediaItems(filter)
if err != nil { if err != nil {
return nil, errors.New("Context Error") return nil, errors.New("Context Error")
} }
@ -338,10 +369,18 @@ func (r *queryResolver) MediaItems(ctx context.Context, delete *bool, filter *mo
} }
func (r *queryResolver) Devices(ctx context.Context, delete *bool, filter *model.DeviceFilter, count *int, page *int) (*model.DeviceResponse, error) { func (r *queryResolver) Devices(ctx context.Context, delete *bool, filter *model.DeviceFilter, count *int, page *int) (*model.DeviceResponse, error) {
// TODO: User Specific // Get Context
authContext := ctx.Value("auth").(*model.AuthContext)
accessToken := *authContext.AccessToken
userID, ok := accessToken.Get("sub")
if !ok {
return nil, errors.New("Context Error")
}
_ = userID
resp, totalCount, err := r.DB.Devices() resp, totalCount, err := r.DB.Devices()
if err != nil { if err != nil {
return nil, errors.New("Context Error") return nil, errors.New("DB Error")
} }
return &model.DeviceResponse{ return &model.DeviceResponse{
Data: resp, Data: resp,

193
internal/db/filters.go Normal file
View File

@ -0,0 +1,193 @@
package db
import (
"fmt"
"reflect"
"github.com/iancoleman/strcase"
"gorm.io/gorm"
"reichard.io/imagini/graph/model"
)
// Generic function used to generate filters for the DB
func (dbm *DBManager) generateFilters(filter interface{}) (*gorm.DB, error) {
tx := dbm.db.Session(&gorm.Session{}).Debug()
v := reflect.ValueOf(filter)
for i := 0; i < v.NumField(); i++ {
fieldName := strcase.ToSnake(v.Type().Field(i).Name)
fieldVal := v.Field(i)
if fieldVal.IsNil() {
continue
}
switch valType := fieldVal.Type(); valType {
case reflect.TypeOf(&model.StringFilter{}):
tx = generateStringFilter(tx, fieldName, fieldVal.Interface().(*model.StringFilter))
case reflect.TypeOf(&model.BooleanFilter{}):
tx = generateBooleanFilter(tx, fieldName, fieldVal.Interface().(*model.BooleanFilter))
case reflect.TypeOf(&model.FloatFilter{}):
tx = generateFloatFilter(tx, fieldName, fieldVal.Interface().(*model.FloatFilter))
case reflect.TypeOf(&model.IntFilter{}):
tx = generateIntFilter(tx, fieldName, fieldVal.Interface().(*model.IntFilter))
case reflect.TypeOf(&model.IDFilter{}):
tx = generateIDFilter(tx, fieldName, fieldVal.Interface().(*model.IDFilter))
case reflect.TypeOf(&model.TimeFilter{}):
tx = generateTimeFilter(tx, fieldName, fieldVal.Interface().(*model.TimeFilter))
case reflect.TypeOf(&model.RoleFilter{}):
tx = generateRoleFilter(tx, fieldName, fieldVal.Interface().(*model.RoleFilter))
case reflect.TypeOf(&model.DeviceTypeFilter{}):
tx = generateDeviceTypeFilter(tx, fieldName, fieldVal.Interface().(*model.DeviceTypeFilter))
case reflect.TypeOf(&model.AuthTypeFilter{}):
tx = generateAuthTypeFilter(tx, fieldName, fieldVal.Interface().(*model.AuthTypeFilter))
}
}
return tx, nil
}
func generateStringFilter(tx *gorm.DB, fieldName string, filter *model.StringFilter) *gorm.DB {
if filter.EqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo)
}
if filter.NotEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo)
}
if filter.StartsWith != nil {
tx = tx.Where(fmt.Sprintf("%s LIKE ?", fieldName), fmt.Sprintf("%s%%", *filter.StartsWith))
}
if filter.NotStartsWith != nil {
tx = tx.Where(fmt.Sprintf("%s NOT LIKE ?", fieldName), fmt.Sprintf("%s%%", *filter.NotStartsWith))
}
if filter.EndsWith != nil {
tx = tx.Where(fmt.Sprintf("%s LIKE ?", fieldName), fmt.Sprintf("%%%s", *filter.EndsWith))
}
if filter.NotEndsWith != nil {
tx = tx.Where(fmt.Sprintf("%s NOT LIKE ?", fieldName), fmt.Sprintf("%%%s", *filter.NotEndsWith))
}
if filter.Contains != nil {
tx = tx.Where(fmt.Sprintf("%s LIKE ?", fieldName), fmt.Sprintf("%%%s%%", *filter.Contains))
}
if filter.NotContains != nil {
tx = tx.Where(fmt.Sprintf("%s NOT LIKE ?", fieldName), fmt.Sprintf("%%%s%%", *filter.NotContains))
}
return tx
}
func generateBooleanFilter(tx *gorm.DB, fieldName string, filter *model.BooleanFilter) *gorm.DB {
if filter.EqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo)
}
if filter.NotEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo)
}
return tx
}
func generateFloatFilter(tx *gorm.DB, fieldName string, filter *model.FloatFilter) *gorm.DB {
if filter.EqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo)
}
if filter.NotEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo)
}
if filter.GreaterThan != nil {
tx = tx.Where(fmt.Sprintf("%s > ?", fieldName), *filter.GreaterThan)
}
if filter.GreaterThanOrEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s >= ?", fieldName), *filter.GreaterThanOrEqualTo)
}
if filter.LessThan != nil {
tx = tx.Where(fmt.Sprintf("%s < ?", fieldName), *filter.LessThan)
}
if filter.LessThanOrEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s <= ?", fieldName), *filter.LessThanOrEqualTo)
}
return tx
}
func generateIntFilter(tx *gorm.DB, fieldName string, filter *model.IntFilter) *gorm.DB {
if filter.EqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo)
}
if filter.NotEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo)
}
if filter.GreaterThan != nil {
tx = tx.Where(fmt.Sprintf("%s > ?", fieldName), *filter.GreaterThan)
}
if filter.GreaterThanOrEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s >= ?", fieldName), *filter.GreaterThanOrEqualTo)
}
if filter.LessThan != nil {
tx = tx.Where(fmt.Sprintf("%s < ?", fieldName), *filter.LessThan)
}
if filter.LessThanOrEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s <= ?", fieldName), *filter.LessThanOrEqualTo)
}
return tx
}
func generateIDFilter(tx *gorm.DB, fieldName string, filter *model.IDFilter) *gorm.DB {
if filter.EqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo)
}
if filter.NotEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo)
}
return tx
}
func generateTimeFilter(tx *gorm.DB, fieldName string, filter *model.TimeFilter) *gorm.DB {
if filter.EqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo)
}
if filter.NotEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo)
}
if filter.GreaterThan != nil {
tx = tx.Where(fmt.Sprintf("%s > ?", fieldName), *filter.GreaterThan)
}
if filter.GreaterThanOrEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s >= ?", fieldName), *filter.GreaterThanOrEqualTo)
}
if filter.LessThan != nil {
tx = tx.Where(fmt.Sprintf("%s < ?", fieldName), *filter.LessThan)
}
if filter.LessThanOrEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s <= ?", fieldName), *filter.LessThanOrEqualTo)
}
return tx
}
func generateRoleFilter(tx *gorm.DB, fieldName string, filter *model.RoleFilter) *gorm.DB {
if filter.EqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo)
}
if filter.NotEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo)
}
return tx
}
func generateDeviceTypeFilter(tx *gorm.DB, fieldName string, filter *model.DeviceTypeFilter) *gorm.DB {
if filter.EqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo)
}
if filter.NotEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo)
}
return tx
}
func generateAuthTypeFilter(tx *gorm.DB, fieldName string, filter *model.AuthTypeFilter) *gorm.DB {
if filter.EqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo)
}
if filter.NotEqualTo != nil {
tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo)
}
return tx
}

View File

@ -18,9 +18,14 @@ func (dbm *DBManager) MediaItem(mediaItem *model.MediaItem) (int64, error) {
return count, err return count, err
} }
func (dbm *DBManager) MediaItems() ([]*model.MediaItem, int64, error) { func (dbm *DBManager) MediaItems(filters *model.MediaItemFilter) ([]*model.MediaItem, int64, error) {
// Perform Filters
tx, err := dbm.generateFilters(*filters)
if err != nil {
return nil, 0, err
}
var mediaItems []*model.MediaItem var mediaItems []*model.MediaItem
var count int64 var count int64
err := dbm.db.Find(&mediaItems).Count(&count).Error err = tx.Find(&mediaItems).Count(&count).Error
return mediaItems, count, err return mediaItems, count, err
} }