summaryrefslogtreecommitdiffstats
path: root/store
diff options
context:
space:
mode:
authorChristopher Speller <crspeller@gmail.com>2015-11-03 11:34:52 -0500
committerChristopher Speller <crspeller@gmail.com>2015-11-03 11:34:52 -0500
commit188182a3a4499965dbbde254aed0ae5e60e71dc5 (patch)
treec8827517f2a65790b0f1e6fcaad5ff517710fcc2 /store
parent65acb1b201147ee20d3a07f97073ab7cd8c0efc2 (diff)
downloadchat-188182a3a4499965dbbde254aed0ae5e60e71dc5.tar.gz
chat-188182a3a4499965dbbde254aed0ae5e60e71dc5.tar.bz2
chat-188182a3a4499965dbbde254aed0ae5e60e71dc5.zip
Adding ability to fetch posts around a specifc post
Diffstat (limited to 'store')
-rw-r--r--store/sql_post_store.go98
-rw-r--r--store/sql_post_store_test.go105
-rw-r--r--store/store.go2
3 files changed, 205 insertions, 0 deletions
diff --git a/store/sql_post_store.go b/store/sql_post_store.go
index f514d23ed..8b1cae3dd 100644
--- a/store/sql_post_store.go
+++ b/store/sql_post_store.go
@@ -332,6 +332,104 @@ func (s SqlPostStore) GetPostsSince(channelId string, time int64) StoreChannel {
return storeChannel
}
+func (s SqlPostStore) GetPostsBefore(channelId string, postId string, numPosts int, offset int) StoreChannel {
+ return s.getPostsAround(channelId, postId, numPosts, offset, true)
+}
+
+func (s SqlPostStore) GetPostsAfter(channelId string, postId string, numPosts int, offset int) StoreChannel {
+ return s.getPostsAround(channelId, postId, numPosts, offset, false)
+}
+
+func (s SqlPostStore) getPostsAround(channelId string, postId string, numPosts int, offset int, before bool) StoreChannel {
+ storeChannel := make(StoreChannel)
+
+ go func() {
+ result := StoreResult{}
+
+ var direction string
+ var sort string
+ if before {
+ direction = "<"
+ sort = "DESC"
+ } else {
+ direction = ">"
+ sort = "ASC"
+ }
+
+ var posts []*model.Post
+ var parents []*model.Post
+ _, err1 := s.GetReplica().Select(&posts,
+ `(SELECT
+ *
+ FROM
+ Posts
+ WHERE
+ (CreateAt `+direction+` (SELECT CreateAt FROM Posts WHERE Id = :PostId)
+ AND ChannelId = :ChannelId
+ AND DeleteAt = 0)
+ ORDER BY CreateAt `+sort+`
+ LIMIT :NumPosts
+ OFFSET :Offset)`,
+ map[string]interface{}{"ChannelId": channelId, "PostId": postId, "NumPosts": numPosts, "Offset": offset})
+ _, err2 := s.GetReplica().Select(&parents,
+ `(SELECT
+ *
+ FROM
+ Posts
+ WHERE
+ Id
+ IN
+ (SELECT * FROM (SELECT
+ RootId
+ FROM
+ Posts
+ WHERE
+ (CreateAt `+direction+` (SELECT CreateAt FROM Posts WHERE Id = :PostId)
+ AND ChannelId = :ChannelId
+ AND DeleteAt = 0)
+ ORDER BY CreateAt `+sort+`
+ LIMIT :NumPosts
+ OFFSET :Offset)
+ temp_tab))
+ ORDER BY CreateAt DESC`,
+ map[string]interface{}{"ChannelId": channelId, "PostId": postId, "NumPosts": numPosts, "Offset": offset})
+
+ if err1 != nil {
+ result.Err = model.NewAppError("SqlPostStore.GetPostContext", "We couldn't get the posts for the channel", "channelId="+channelId+err1.Error())
+ } else if err2 != nil {
+ result.Err = model.NewAppError("SqlPostStore.GetPostContext", "We couldn't get the parent posts for the channel", "channelId="+channelId+err2.Error())
+ } else {
+
+ list := &model.PostList{Order: make([]string, 0, len(posts))}
+
+ // We need to flip the order if we selected backwards
+ if before {
+ for _, p := range posts {
+ list.AddPost(p)
+ list.AddOrder(p.Id)
+ }
+ } else {
+ l := len(posts)
+ for i := range posts {
+ list.AddPost(posts[l-i-1])
+ list.AddOrder(posts[l-i-1].Id)
+ }
+ }
+
+ for _, p := range parents {
+ list.AddPost(p)
+ }
+
+ result.Data = list
+ }
+
+ storeChannel <- result
+ close(storeChannel)
+ }()
+
+ return storeChannel
+}
+
func (s SqlPostStore) getRootPosts(channelId string, offset int, limit int) StoreChannel {
storeChannel := make(StoreChannel)
diff --git a/store/sql_post_store_test.go b/store/sql_post_store_test.go
index 872423c5a..c2348b04c 100644
--- a/store/sql_post_store_test.go
+++ b/store/sql_post_store_test.go
@@ -383,6 +383,111 @@ func TestPostStoreGetPostsWtihDetails(t *testing.T) {
}
}
+func TestPostStoreGetPostsBeforeAfter(t *testing.T) {
+ Setup()
+ o0 := &model.Post{}
+ o0.ChannelId = model.NewId()
+ o0.UserId = model.NewId()
+ o0.Message = "a" + model.NewId() + "b"
+ o0 = (<-store.Post().Save(o0)).Data.(*model.Post)
+ time.Sleep(2 * time.Millisecond)
+
+ o1 := &model.Post{}
+ o1.ChannelId = model.NewId()
+ o1.UserId = model.NewId()
+ o1.Message = "a" + model.NewId() + "b"
+ o1 = (<-store.Post().Save(o1)).Data.(*model.Post)
+ time.Sleep(2 * time.Millisecond)
+
+ o2 := &model.Post{}
+ o2.ChannelId = o1.ChannelId
+ o2.UserId = model.NewId()
+ o2.Message = "a" + model.NewId() + "b"
+ o2.ParentId = o1.Id
+ o2.RootId = o1.Id
+ o2 = (<-store.Post().Save(o2)).Data.(*model.Post)
+ time.Sleep(2 * time.Millisecond)
+
+ o2a := &model.Post{}
+ o2a.ChannelId = o1.ChannelId
+ o2a.UserId = model.NewId()
+ o2a.Message = "a" + model.NewId() + "b"
+ o2a.ParentId = o1.Id
+ o2a.RootId = o1.Id
+ o2a = (<-store.Post().Save(o2a)).Data.(*model.Post)
+ time.Sleep(2 * time.Millisecond)
+
+ o3 := &model.Post{}
+ o3.ChannelId = o1.ChannelId
+ o3.UserId = model.NewId()
+ o3.Message = "a" + model.NewId() + "b"
+ o3.ParentId = o1.Id
+ o3.RootId = o1.Id
+ o3 = (<-store.Post().Save(o3)).Data.(*model.Post)
+ time.Sleep(2 * time.Millisecond)
+
+ o4 := &model.Post{}
+ o4.ChannelId = o1.ChannelId
+ o4.UserId = model.NewId()
+ o4.Message = "a" + model.NewId() + "b"
+ o4 = (<-store.Post().Save(o4)).Data.(*model.Post)
+ time.Sleep(2 * time.Millisecond)
+
+ o5 := &model.Post{}
+ o5.ChannelId = o1.ChannelId
+ o5.UserId = model.NewId()
+ o5.Message = "a" + model.NewId() + "b"
+ o5.ParentId = o4.Id
+ o5.RootId = o4.Id
+ o5 = (<-store.Post().Save(o5)).Data.(*model.Post)
+
+ r1 := (<-store.Post().GetPostsBefore(o1.ChannelId, o1.Id, 4, 0)).Data.(*model.PostList)
+
+ if len(r1.Posts) != 0 {
+ t.Fatal("Wrong size")
+ }
+
+ r2 := (<-store.Post().GetPostsAfter(o1.ChannelId, o1.Id, 4, 0)).Data.(*model.PostList)
+
+ if r2.Order[0] != o4.Id {
+ t.Fatal("invalid order")
+ }
+
+ if r2.Order[1] != o3.Id {
+ t.Fatal("invalid order")
+ }
+
+ if r2.Order[2] != o2a.Id {
+ t.Fatal("invalid order")
+ }
+
+ if r2.Order[3] != o2.Id {
+ t.Fatal("invalid order")
+ }
+
+ if len(r2.Posts) != 5 {
+ t.Fatal("wrong size")
+ }
+
+ r3 := (<-store.Post().GetPostsBefore(o3.ChannelId, o3.Id, 2, 0)).Data.(*model.PostList)
+
+ if r3.Order[0] != o2a.Id {
+ t.Fatal("invalid order")
+ }
+
+ if r3.Order[1] != o2.Id {
+ t.Fatal("invalid order")
+ }
+
+ if len(r3.Posts) != 3 {
+ t.Fatal("wrong size")
+ }
+
+ if r3.Posts[o1.Id].Message != o1.Message {
+ t.Fatal("Missing parent")
+ }
+}
+
func TestPostStoreGetPostsSince(t *testing.T) {
Setup()
o0 := &model.Post{}
diff --git a/store/store.go b/store/store.go
index 53a6e053b..ce4d90883 100644
--- a/store/store.go
+++ b/store/store.go
@@ -86,6 +86,8 @@ type PostStore interface {
Get(id string) StoreChannel
Delete(postId string, time int64) StoreChannel
GetPosts(channelId string, offset int, limit int) StoreChannel
+ GetPostsBefore(channelId string, postId string, numPosts int, offset int) StoreChannel
+ GetPostsAfter(channelId string, postId string, numPosts int, offset int) StoreChannel
GetPostsSince(channelId string, time int64) StoreChannel
GetEtag(channelId string) StoreChannel
Search(teamId string, userId string, params *model.SearchParams) StoreChannel