func NewCursorEventsFromEvent(e hey.Event) CursorEvents { return NewCursorFromSource(e.EventID(), e.CreatedAt()) }
func (r *EventRepository) findEvents( clientID, watcherID, threadID uuid.UUID, cursorStr string, perPage int, ) ([]hey.Event, string, error) { cursor := utils.NewCursorEvents(cursorStr) lastEventID := cursor.LastEventID() lastEventCreatedAt := cursor.LastCreatedAt() cursor = utils.EmptyCursorEvents // reset cursor if perPage <= 0 || perPage > PerPageMax { perPage = PerPageDefault } var events = make([]hey.Event, perPage) // var events []hey.Event // find // args for first page var args = []interface{}{ clientID, threadID, perPage, } sqlFirstPage := `SELECT t.event_id, t.created_at FROM threadline as t WHERE t.client_id = $1 AND t.thread_id = $2 ORDER BY t.created_at DESC, t.event_id ASC LIMIT $3` sqlNextPages := `SELECT t.event_id, t.created_at FROM threadline as t WHERE t.client_id = $1 AND t.thread_id = $2 AND (t.created_at, t.event_id) < ($3, $4) ORDER BY t.created_at DESC, t.event_id ASC LIMIT $5` sql := sqlFirstPage if !uuid.Equal(lastEventID, uuid.Nil) { sql = sqlNextPages args = []interface{}{ clientID, threadID, lastEventCreatedAt, lastEventID, perPage, } } rows, err := r.db.Query(sql, args...) if err != nil { return events, "", err } var _event hey.Event var _eventID uuid.UUID var _createdAt time.Time var i = 0 for rows.Next() { if err = rows.Scan( &_eventID, &_createdAt, ); err != nil { println("[ERR] error scan row", err.Error()) continue } _event, err = r.FindEvent( clientID, _eventID, ) if err != nil { println( "[ERR] error find event by ID", _eventID.String(), err.Error()) continue } events[i] = _event i++ } if _event != nil { cursor = utils.NewCursorFromSource( _event.EventID(), _event.CreatedAt(), ) } if i < perPage-1 { // обрезать хвост у массива событий, если кол-во найденных меньше // чем ожидаемое кол-во events = events[:i] } return events, cursor.String(), err }