Управление потоком результатов запроса в SQLX (ленивый / нетерпеливый) - PullRequest
0 голосов
/ 11 июля 2019

Я реализую таблицу сообщений с postgres (aws-rds) и использую golang в качестве бэкэнда для запроса таблицы.

CREATE TABLE:

CREATE TABLE IF NOT EXISTS msg.Messages(
    id SERIAL PRIMARY KEY,
    content BYTEA,
    timestamp DATE
);

Вот запрос INSERT:

INSERT INTO msg.Messages (content,timestamp) VALUES ('blob', 'date')
RETURNING id;

Теперь я хочу получить определенное сообщение, например:

определенный запрос SELECT:

SELECT id, content,timestamp
FROM msg.Messages
WHERE id = $1

Теперь предположим, что пользователь был в автономном режиме в течение длительного времени, и ему нужно получить много сообщений из этой таблицы, скажем, 10M сообщений, я не хочу возвращать все результаты, потому что это может взорвать память приложения.

каждый пользователь сохраняет свой последний message.id, который он получил, поэтому запрос будет:

SELECT id, content, timestamp
FROM msg.Messages
WHERE id > $1

Реализация подкачки в этом запросе напоминает изобретение колеса, для этого должно быть готовое решение.

Я использую sqlx, вот пример моего кода:

query := `
        SELECT id, content, timestamp
        FROM msg.Messages
        WHERE id > $0
    `

args = 5
query = ado.db.Rebind(query)
rows, err := ado.db.Queryx(query, args...)
var res []Message

for rows.Next() {
    msg := Message{}
    err = rows.StructScan(&msg)
    if err != nil {
        return nil, err
    }
    res = append(res, msg)
}

return res, nil

Как я могу преобразовать этот код в ленивую загрузку, чтобы только в rows.next () получал следующий элемент (и не загружал все элементы заранее), а как насчет сборщика мусора, освободит ли он память на каждой итерации row.next () ??

...