Возврат пустых записей с помощью Golang, SQLC и PostgreSQL

Я пытаюсь реализовать нумерацию страниц в своем внутреннем API GO. API использует SQLC для абстракции к моей базе данных PostgreSQL. Проблема в том, что он возвращает пустые записи, и я не могу понять, что делаю не так. Ниже приведены соответствующие коды, относящиеся к моей текущей работе:

  1. SQLC-код:
const getAllFeeds = `-- name: GetAllFeeds :many
SELECT count(*) OVER(), id, created_at, updated_at, name, url, user_id, version
FROM feeds
WHERE ($1 = '' OR to_tsvector('simple', name) @@ plainto_tsquery('simple', $1))
AND ($2 = '' OR url LIKE '%' || $2 || '%')
ORDER BY id ASC
LIMIT $3 OFFSET $4
`

type GetAllFeedsParams struct {
    Column1 interface{}
    Column2 interface{}
    Limit   int32
    Offset  int32
}

type GetAllFeedsRow struct {
    Count     int64
    ID        uuid.UUID
    CreatedAt time.Time
    UpdatedAt time.Time
    Name      string
    Url       string
    UserID    int64
    Version   int32
}

func (q *Queries) GetAllFeeds(ctx context.Context, arg GetAllFeedsParams) ([]GetAllFeedsRow, error) {
    rows, err := q.db.QueryContext(ctx, getAllFeeds,
        arg.Column1,
        arg.Column2,
        arg.Limit,
        arg.Offset,
    )
    if err != nil {
        return nil, err
    }
    defer rows.Close()
    var items []GetAllFeedsRow
    for rows.Next() {
        var i GetAllFeedsRow
        if err := rows.Scan(
            &i.Count,
            &i.ID,
            &i.CreatedAt,
            &i.UpdatedAt,
            &i.Name,
            &i.Url,
            &i.UserID,
            &i.Version,
        ); err != nil {
            return nil, err
        }
        items = append(items, i)
    }
    if err := rows.Close(); err != nil {
        return nil, err
    }
    if err := rows.Err(); err != nil {
        return nil, err
    }
    return items, nil
}
  1. Код Голанга:
func (m FeedModel) GetAllFeeds(name string, url string, filters Filters) ([]*Feed, Metadata, error) {
    // create our timeout context. All of them will just be 5 seconds
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    // retrieve our data
    fmt.Printf("Executing GetAllFeeds with name: [%s], url: [%s], limit: %d, offset: %d\n",
        name, url, filters.limit(), filters.offset())

    rows, err := m.DB.GetAllFeeds(ctx, database.GetAllFeedsParams{
        Column1: name,
        Column2: sql.NullString{String: url, Valid: url != ""}, // Convert string to sql.NullString
        Limit:   int32(filters.limit()),
        Offset:  int32(filters.offset()),
    })
    //check for an error
    if err != nil {
        return nil, Metadata{}, err
    }
    fmt.Println("Rows: ", rows)
    totalRecords := 0
    feeds := []*Feed{}
    for _, row := range rows {
        var feed Feed
        totalRecords = int(row.Count)
        feed.ID = row.ID
        feed.CreatedAt = row.CreatedAt
        feed.UpdatedAt = row.UpdatedAt
        feed.Name = row.Name
        feed.Url = row.Url
        feed.Version = row.Version
        feed.UserID = row.UserID
        feeds = append(feeds, &feed)
    }
    // Generate a Metadata struct, passing in the total record count and pagination
    // parameters from the client.
    metadata := calculateMetadata(totalRecords, filters.Page, filters.PageSize)
    return feeds, metadata, nil
}

Пример вывода: Executing GetAllFeeds with name: [], url: [], limit: 30, offset: 0 Rows: [] Total Records: 0 Исходная схема:

-- +goose Up
CREATE TABLE feeds(
    id UUID PRIMARY KEY,
        created_at timestamp(0) with time zone NOT NULL DEFAULT NOW(),
        updated_at timestamp(0) with time zone NOT NULL DEFAULT NOW(),
        name TEXT NOT NULL,
        url TEXT UNIQUE NOT NULL,
        version INT NOT NULL DEFAULT 1,
        user_id bigserial NOT NULL REFERENCES users(id) ON DELETE CASCADE
);

Если я запустил следующее непосредственно в psql или даже pgAdmin, я получу все записи:

SELECT count(*) OVER(), id, created_at, updated_at, name, url, user_id, version
                FROM feeds
                WHERE (to_tsvector('simple', name) @@ plainto_tsquery('simple','' ) OR  ''= '')
                AND (url LIKE '%' || '' || '%' OR '' = '')
                ORDER BY id ASC
                LIMIT 30 OFFSET 0;

Теперь мой вопрос: есть ли что-то, что мне может не хватать, поскольку я получаю пустые результаты, используя свой собственный код Golang? Добавлю: у меня есть собственные функции, которые считывают запросы из URL-адреса, поэтому я уверен в том, что именно читается. Смещение и предел по умолчанию равны 0 и 30, если они не указаны, поэтому API возвращает все записи.

Заранее спасибо.

Я полагаю, что вы устанавливаете GetAllFeedsParams.Column2 на null (поскольку url — пустая строка, то есть url != "" — это false, поэтому sql.NullString.Vaild — это false). Это означает, что ваше предложение where фактически содержит null = '' or url like '%' || null || '%' (которое можно упростить до null or null, то есть null, то есть не true).

Brits 21.06.2024 11:07

@Brits Спасибо, сэр! Наверное, слишком устал, чтобы увидеть такую ​​тривиальную ошибку. Не могли бы вы опубликовать, чтобы я установил это как ответ?

B.Doe 21.06.2024 14:51
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Судя по комментариям, ваш пункт where включает в себя:

AND ($2 = '' OR url LIKE '%' || $2 || '%')

$2 — это GetAllFeedsParams.Column2 в коде go, и, если url — пустая строка (как в примере), вы устанавливаете GetAllFeedsParams.Column2.Valid в false. Это означает, что параметр равен null. В результате предложение where фактически:

AND (null = '' OR url LIKE '%' || null || '%')

Это можно упростить до:

AND (null OR null)

Конечным результатом будет null (это не true, поэтому строка отклоняется).

Другие вопросы по теме