package routes import ( "gifuu/tools" "net/http" ) func GET_Art_Search(w http.ResponseWriter, r *http.Request) { ctx := r.Context() query := r.URL.Query() paramLimit := tools.ParseLimit(query.Get("limit")) paramAfter := tools.ParseSnowflake(query.Get("after")) var paramTags []int64 if params, ok := query["tag"]; ok { paramTags = make([]int64, 0, len(params)) indexTags := make(map[int64]struct{}, len(params)) for _, raw := range params { id := tools.ParseSnowflake(raw) if _, exists := indexTags[id]; exists || id == 0 { tools.SendClientError(w, r, tools.ERROR_BODY_INVALID_FIELD) return } indexTags[id] = struct{}{} paramTags = append(paramTags, id) } } if len(paramTags) == 0 { tools.SendClientError(w, r, tools.ERROR_BODY_EMPTY) return } var Results []byte err := tools.Database.QueryRow(ctx, `SELECT COALESCE(jsonb_agg(t.obj), '[]') FROM ( SELECT jsonb_build_object( 'id', u.id::text, 'created', u.created::timestamptz, 'sticker', u.flag_sticker, 'audio', u.flag_audio, 'framerate', u.encode_fps, 'width', u.encode_width, 'height', u.encode_height, 'rating', u.meta_rating, 'title', u.meta_title, 'tags', COALESCE( jsonb_agg( jsonb_build_object( 'id', t.id::text, 'label', t.label, 'usage', t.usage ) ORDER BY t.usage DESC ) FILTER (WHERE t.id IS NOT NULL), '[]' ) ) AS obj FROM gifuu.upload u LEFT JOIN gifuu.upload_tag ut ON ut.gif_id = u.id LEFT JOIN gifuu.tag t ON t.id = ut.tag_id WHERE ut.tag_id = ANY($1::bigint[]) AND ($2::bigint = 0 OR u.id < $2::bigint) AND u.meta_rating < $4 GROUP BY u.id HAVING COUNT(DISTINCT ut.tag_id) = cardinality($1::bigint[]) ORDER BY u.id DESC LIMIT $3::int ) t`, paramTags, paramAfter, paramLimit, tools.MODEL_THRESHOLD_HIDE, ).Scan(&Results) if err != nil { tools.SendServerError(w, r, err) return } tools.SendJSON(w, r, http.StatusOK, Results) }