mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
adding sequence marker to get topics to support staggard loading
This commit is contained in:
parent
e4830093e3
commit
1c05180251
33
doc/api.oa3
33
doc/api.oa3
@ -2485,7 +2485,7 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- content
|
||||
description: Get channel topic slots. If revision set, detail fields omitted in response
|
||||
description: Get channel topic slots. If revision set, detail fields omitted in response. Staggered loading supported through sequnce marker. Initially count can be used to limit the topics returned. The sequence marker returned in the header must be used in subsequent queries for the same topic window.
|
||||
operationId: get-channel-topics
|
||||
security:
|
||||
- bearerAuth: []
|
||||
@ -2501,16 +2501,43 @@ paths:
|
||||
description: return updated topics since revision
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
type: integer
|
||||
format: int64
|
||||
- name: count
|
||||
in: query
|
||||
description: limit number of topics from latest when revision not set
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
- name: begin
|
||||
in: query
|
||||
description: return topics after and including sequence marker
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
- name: end
|
||||
in: query
|
||||
description: return topics before and not including sequence marker
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Topic-Revision:
|
||||
Topic-Revision:
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
description: current topic revision
|
||||
Topic-Marker:
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
description: sequnce marker of first topic when count set
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
|
@ -6,9 +6,23 @@ import (
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func reverse(input []store.TopicSlot) []store.TopicSlot {
|
||||
var output []store.TopicSlot
|
||||
for i := len(input) - 1; i >= 0; i-- {
|
||||
output = append(output, input[i])
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func GetChannelTopics(w http.ResponseWriter, r *http.Request) {
|
||||
var revisionSet bool
|
||||
var revision int64
|
||||
var beginSet bool
|
||||
var begin int64
|
||||
var endSet bool
|
||||
var end int64
|
||||
var countSet bool
|
||||
var count int
|
||||
|
||||
channelSlot, _, err, code := getChannelSlot(r, false)
|
||||
if err != nil {
|
||||
@ -25,24 +39,102 @@ func GetChannelTopics(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
cnt := r.FormValue("count")
|
||||
if cnt != "" {
|
||||
countSet = true
|
||||
if count, err = strconv.Atoi(cnt); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
bn := r.FormValue("begin")
|
||||
if bn != "" {
|
||||
beginSet = true
|
||||
if begin, err = strconv.ParseInt(bn, 10, 64); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
en := r.FormValue("end")
|
||||
if en != "" {
|
||||
endSet = true
|
||||
if end, err = strconv.ParseInt(en, 10, 64); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
response := []*Topic{}
|
||||
if revisionSet {
|
||||
var slots []store.TopicSlot
|
||||
if err := store.DB.Preload("Topic").Where("channel_id = ? AND revision > ?", channelSlot.Channel.ID, revision).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
if beginSet && !endSet {
|
||||
if err := store.DB.Preload("Topic").Where("channel_id = ? AND revision > ? AND id >= ?", channelSlot.Channel.ID, revision, begin).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
} else if !beginSet && endSet {
|
||||
if err := store.DB.Preload("Topic").Where("channel_id = ? AND revision > ? AND id < ?", channelSlot.Channel.ID, revision, end).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
} else if beginSet && endSet {
|
||||
if err := store.DB.Preload("Topic").Where("channel_id = ? AND revision > ? AND id >= ? AND id < ?", channelSlot.Channel.ID, revision, begin, end).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := store.DB.Preload("Topic").Where("channel_id = ? AND revision > ?", channelSlot.Channel.ID, revision).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
for _, slot := range slots {
|
||||
response = append(response, getTopicRevisionModel(&slot))
|
||||
}
|
||||
} else {
|
||||
var slots []store.TopicSlot
|
||||
if err := store.DB.Preload("Topic.Assets").Where("channel_id = ?", channelSlot.Channel.ID).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
if countSet {
|
||||
if !endSet {
|
||||
if err := store.DB.Preload("Topic.Assets").Where("channel_id = ?", channelSlot.Channel.ID).Order("id desc").Limit(count).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := store.DB.Preload("Topic.Assets").Where("channel_id = ? AND id < ?", channelSlot.Channel.ID, end).Order("id desc").Limit(count).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
slots = reverse(slots)
|
||||
} else if beginSet && !endSet {
|
||||
if err := store.DB.Preload("Topic.Assets").Where("channel_id = ? AND id >= ?", channelSlot.Channel.ID, begin).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
} else if !beginSet && endSet {
|
||||
if err := store.DB.Preload("Topic.Assets").Where("channel_id = ? AND id < ?", channelSlot.Channel.ID, end).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
} else if beginSet && endSet {
|
||||
if err := store.DB.Preload("Topic.Assets").Where("channel_id = ? AND id >= ? AND id < ?", channelSlot.Channel.ID, begin, end).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := store.DB.Preload("Topic.Assets").Where("channel_id = ?", channelSlot.Channel.ID).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
for _, slot := range slots {
|
||||
if slot.Topic != nil {
|
||||
if countSet {
|
||||
w.Header().Set("Topic-Index", strconv.FormatUint(uint64(slot.ID), 10))
|
||||
countSet = false
|
||||
}
|
||||
response = append(response, getTopicModel(&slot))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user