Refactor parent thread SQL to use a CTE (one query rather than several)
This commit is contained in:
parent
3c3fd55991
commit
bb6a7738ba
@ -1,7 +1,6 @@
|
|||||||
package persistence
|
package persistence
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
@ -175,51 +174,42 @@ func NewTweetDetailView() TweetDetailView {
|
|||||||
func (p Profile) GetTweetDetail(id TweetID) (TweetDetailView, error) {
|
func (p Profile) GetTweetDetail(id TweetID) (TweetDetailView, error) {
|
||||||
// TODO: compound-query-structs
|
// TODO: compound-query-structs
|
||||||
ret := NewTweetDetailView()
|
ret := NewTweetDetailView()
|
||||||
|
ret.MainTweetID = id
|
||||||
|
|
||||||
stmt, err := p.DB.Preparex(
|
stmt, err := p.DB.Preparex(`
|
||||||
`select id, user_id, text, posted_at, num_likes, num_retweets, num_replies, num_quote_tweets, in_reply_to_id, quoted_tweet_id,
|
with recursive all_replies(id) as (values(?) union all
|
||||||
mentions, reply_mentions, hashtags, ifnull(space_id, '') space_id, ifnull(tombstone_types.short_name, "") tombstone_type,
|
select tweets.in_reply_to_id from tweets, all_replies
|
||||||
is_expandable,
|
where tweets.id = all_replies.id and tweets.in_reply_to_id != 0
|
||||||
|
)
|
||||||
|
|
||||||
|
select tweets.id id, user_id, text, posted_at, num_likes, num_retweets, num_replies, num_quote_tweets, in_reply_to_id,
|
||||||
|
quoted_tweet_id, mentions, reply_mentions, hashtags, ifnull(space_id, '') space_id,
|
||||||
|
ifnull(tombstone_types.short_name, "") tombstone_type, is_expandable,
|
||||||
is_stub, is_content_downloaded, is_conversation_scraped, last_scraped_at
|
is_stub, is_content_downloaded, is_conversation_scraped, last_scraped_at
|
||||||
from tweets
|
from tweets
|
||||||
left join tombstone_types on tweets.tombstone_type = tombstone_types.rowid
|
left join tombstone_types on tweets.tombstone_type = tombstone_types.rowid
|
||||||
where id = ?`)
|
inner join all_replies on tweets.id = all_replies.id
|
||||||
|
order by id asc`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main tweet
|
// Main tweet and parents
|
||||||
var tweet Tweet
|
var thread []Tweet
|
||||||
err = stmt.Get(&tweet, id)
|
err = stmt.Select(&thread, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
panic(err)
|
||||||
|
}
|
||||||
|
if len(thread) == 0 {
|
||||||
return ret, fmt.Errorf("Tweet ID %d: %w", id, ErrNotInDB)
|
return ret, fmt.Errorf("Tweet ID %d: %w", id, ErrNotInDB)
|
||||||
} else {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
for _, tweet := range thread {
|
||||||
ret.Tweets[tweet.ID] = tweet
|
ret.Tweets[tweet.ID] = tweet
|
||||||
ret.MainTweetID = tweet.ID
|
if tweet.ID != ret.MainTweetID {
|
||||||
|
ret.ParentIDs = append(ret.ParentIDs, tweet.ID)
|
||||||
// Parent tweets
|
|
||||||
for tweet.InReplyToID != 0 {
|
|
||||||
err := stmt.Get(&tweet, tweet.InReplyToID)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret.Tweets[tweet.ID] = tweet
|
|
||||||
ret.ParentIDs = append([]TweetID{tweet.ID}, ret.ParentIDs...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: tweet-detail-thread-chains
|
|
||||||
|
|
||||||
// Replies lvl 1
|
|
||||||
// TODO: this can be done with a recursive Common Table Expression:
|
|
||||||
// - https://www.sqlite.org/lang_with.html#recursive_query_examples
|
|
||||||
var replies []Tweet
|
var replies []Tweet
|
||||||
stmt, err = p.DB.Preparex(
|
stmt, err = p.DB.Preparex(
|
||||||
`select id, user_id, text, posted_at, num_likes, num_retweets, num_replies, num_quote_tweets, in_reply_to_id, quoted_tweet_id,
|
`select id, user_id, text, posted_at, num_likes, num_retweets, num_replies, num_quote_tweets, in_reply_to_id, quoted_tweet_id,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user