<commit_before>package models

import (
	"errors"
	"socialapi/request"
	"time"
	"github.com/koding/bongo"
)

type MessageReply struct {
	// unique identifier of the MessageReply
	Id int64 `json:"id,string"`

	// Id of the interacted message
	MessageId int64 `json:"messageId,string"     sql:"NOT NULL"`

	// Id of the reply
	ReplyId int64 `json:"replyId,string"         sql:"NOT NULL"`

	// holds troll, unsafe, etc
	MetaBits MetaBits `json:"-"`

	// Creation of the MessageReply
	CreatedAt time.Time `json:"createdAt"         sql:"NOT NULL"`
}

func (m MessageReply) GetId() int64 {
	return m.Id
}

func (m MessageReply) TableName() string {
	return "api.message_reply"
}

func NewMessageReply() *MessageReply {
	return &MessageReply{}
}

func (m *MessageReply) BeforeCreate() {
	if m.ReplyId == 0 {
		return
	}

	cm := NewChannelMessage()
	cm.Id = m.ReplyId
	if res, err := cm.isExemptContent(); err == nil && res {
		m.MetaBits = updateTrollModeBit(m.MetaBits)
	}
}

func (m *MessageReply) BeforeUpdate() {
	if m.ReplyId == 0 {
		return
	}

	cm := NewChannelMessage()
	cm.Id = m.ReplyId
	if res, err := cm.isExemptContent(); err == nil && res {
		m.MetaBits = updateTrollModeBit(m.MetaBits)
	}
}

func (m *MessageReply) AfterCreate() {
	bongo.B.AfterCreate(m)
}

func (m *MessageReply) AfterUpdate() {
	bongo.B.AfterUpdate(m)
}

func (m MessageReply) AfterDelete() {
	bongo.B.AfterDelete(m)
}

func (m *MessageReply) ById(id int64) error {
	return bongo.B.ById(m, id)
}

func (m *MessageReply) Create() error {
	return bongo.B.Create(m)
}

func (m *MessageReply) CreateRaw() error {
	insertSql := "INSERT INTO " +
		m.TableName() +
		` ("message_id","reply_id","created_at") VALUES ($1,$2,$3) ` +
		"RETURNING ID"
	return bongo.B.DB.CommonDB().
		QueryRow(insertSql, m.MessageId, m.ReplyId, m.CreatedAt).
		Scan(&m.Id)
}

func (m *MessageReply) Some(data interface{}, q *bongo.Query) error {
	return bongo.B.Some(m, data, q)
}

func (m *MessageReply) One(q *bongo.Query) error {
	return bongo.B.One(m, m, q)
}

func (m *MessageReply) Delete() error {
	selector := map[string]interface{}{
		"message_id": m.MessageId,
		"reply_id":   m.ReplyId,
	}

	if err := m.One(bongo.NewQS(selector)); err != nil {
		return err
	}

	err := bongo.B.Delete(m)
	if err != nil {
		return err
	}

	return nil
}

func (m *MessageReply) DeleteByOrQuery(messageId int64) error {
	var messageReplies []MessageReply
	query := bongo.B.DB.Table(m.TableName())
	query = query.Where("message_id = ? or reply_id = ?", messageId, messageId)

	if err := query.Find(&messageReplies).Error; err != bongo.RecordNotFound && err != nil {
		return err
	}

	if messageReplies == nil {
		return nil
	}

	if len(messageReplies) == 0 {
		return nil
	}

	for _, messageReply := range messageReplies {
		err := bongo.B.Delete(messageReply)
		if err != nil {
			return err
		}
	}

	return nil
}

func (m *MessageReply) List(query *request.Query) ([]ChannelMessage, error) {
	return m.fetchMessages(query)
}

func (m *MessageReply) ListAll() ([]ChannelMessage, error) {
	query := request.NewQuery()
	query.Limit = 0
	query.Skip = 0
	return m.fetchMessages(query)
}

func (m *MessageReply) fetchMessages(query *request.Query) ([]ChannelMessage, error) {
	var replies []int64

	if m.MessageId == 0 {
		return nil, errors.New("messageId is not set")
	}

	q := &bongo.Query{
		Selector: map[string]interface{}{
			"message_id": m.MessageId,
		},
		Pluck:      "reply_id",
		Pagination: *bongo.NewPagination(query.Limit, query.Skip),
		Sort:       map[string]string{"created_at": "DESC"},
	}

	bongoQuery := bongo.B.BuildQuery(m, q)
	if !query.From.IsZero() {
		bongoQuery = bongoQuery.Where("created_at < ?", query.From)
	}

	if err := bongo.CheckErr(
		bongoQuery.Pluck(q.Pluck, &replies),
	); err != nil {
		return nil, err
	}

	parent := NewChannelMessage()
	channelMessageReplies, err := parent.FetchByIds(replies)
	if err != nil {
		return nil, err
	}

	return channelMessageReplies, nil
}

func (m *MessageReply) UnreadCount(messageId int64, addedAt time.Time) (int, error) {
	if messageId == 0 {
		return 0, errors.New("messageId is not set")
	}
<commit_msg>Social: add troll mode filter into message reply listing query<commit_after>package models

import (
	"errors"
	"socialapi/request"
	"time"

	"github.com/koding/bongo"
)

type MessageReply struct {
	// unique identifier of the MessageReply
	Id int64 `json:"id,string"`

	// Id of the interacted message
	MessageId int64 `json:"messageId,string"     sql:"NOT NULL"`

	// Id of the reply
	ReplyId int64 `json:"replyId,string"         sql:"NOT NULL"`

	// holds troll, unsafe, etc
	MetaBits MetaBits `json:"-"`

	// Creation of the MessageReply
	CreatedAt time.Time `json:"createdAt"         sql:"NOT NULL"`
}

func (m MessageReply) GetId() int64 {
	return m.Id
}

func (m MessageReply) TableName() string {
	return "api.message_reply"
}

func NewMessageReply() *MessageReply {
	return &MessageReply{}
}

func (m *MessageReply) BeforeCreate() {
	if m.ReplyId == 0 {
		return
	}

	cm := NewChannelMessage()
	cm.Id = m.ReplyId
	if res, err := cm.isExemptContent(); err == nil && res {
		m.MetaBits = updateTrollModeBit(m.MetaBits)
	}
}

func (m *MessageReply) BeforeUpdate() {
	if m.ReplyId == 0 {
		return
	}

	cm := NewChannelMessage()
	cm.Id = m.ReplyId
	if res, err := cm.isExemptContent(); err == nil && res {
		m.MetaBits = updateTrollModeBit(m.MetaBits)
	}
}

func (m *MessageReply) AfterCreate() {
	bongo.B.AfterCreate(m)
}

func (m *MessageReply) AfterUpdate() {
	bongo.B.AfterUpdate(m)
}

func (m MessageReply) AfterDelete() {
	bongo.B.AfterDelete(m)
}

func (m *MessageReply) ById(id int64) error {
	return bongo.B.ById(m, id)
}

func (m *MessageReply) Create() error {
	return bongo.B.Create(m)
}

func (m *MessageReply) CreateRaw() error {
	insertSql := "INSERT INTO " +
		m.TableName() +
		` ("message_id","reply_id","created_at") VALUES ($1,$2,$3) ` +
		"RETURNING ID"
	return bongo.B.DB.CommonDB().
		QueryRow(insertSql, m.MessageId, m.ReplyId, m.CreatedAt).
		Scan(&m.Id)
}

func (m *MessageReply) Some(data interface{}, q *bongo.Query) error {
	return bongo.B.Some(m, data, q)
}

func (m *MessageReply) One(q *bongo.Query) error {
	return bongo.B.One(m, m, q)
}

func (m *MessageReply) Delete() error {
	selector := map[string]interface{}{
		"message_id": m.MessageId,
		"reply_id":   m.ReplyId,
	}

	if err := m.One(bongo.NewQS(selector)); err != nil {
		return err
	}

	err := bongo.B.Delete(m)
	if err != nil {
		return err
	}

	return nil
}

func (m *MessageReply) DeleteByOrQuery(messageId int64) error {
	var messageReplies []MessageReply
	query := bongo.B.DB.Table(m.TableName())
	query = query.Where("message_id = ? or reply_id = ?", messageId, messageId)

	if err := query.Find(&messageReplies).Error; err != bongo.RecordNotFound && err != nil {
		return err
	}

	if messageReplies == nil {
		return nil
	}

	if len(messageReplies) == 0 {
		return nil
	}

	for _, messageReply := range messageReplies {
		err := bongo.B.Delete(messageReply)
		if err != nil {
			return err
		}
	}

	return nil
}

func (m *MessageReply) List(query *request.Query) ([]ChannelMessage, error) {
	return m.fetchMessages(query)
}

func (m *MessageReply) ListAll() ([]ChannelMessage, error) {
	query := request.NewQuery()
	query.Limit = 0
	query.Skip = 0
	return m.fetchMessages(query)
}

func (m *MessageReply) fetchMessages(query *request.Query) ([]ChannelMessage, error) {
	var replies []int64

	if m.MessageId == 0 {
		return nil, errors.New("messageId is not set")
	}

	q := &bongo.Query{
		Selector: map[string]interface{}{
			"message_id": m.MessageId,
		},
		Pluck:      "reply_id",
		Pagination: *bongo.NewPagination(query.Limit, query.Skip),
		Sort:       map[string]string{"created_at": "DESC"},
	}

	q.AddScope(RemoveTrollContent(m, query.ShowExempt))

	bongoQuery := bongo.B.BuildQuery(m, q)
	if !query.From.IsZero() {
		bongoQuery = bongoQuery.Where("created_at < ?", query.From)
	}

	if err := bongo.CheckErr(
		bongoQuery.Pluck(q.Pluck, &replies),
	); err != nil {
		return nil, err
	}

	parent := NewChannelMessage()
	channelMessageReplies, err := parent.FetchByIds(replies)
	if err != nil {
		return nil, err
	}

	return channelMessageReplies, nil
}

func (m *MessageReply) UnreadCount(messageId int64, addedAt time.Time) (int, error) {
	if messageId == 0 {
		return 0, errors.New("messageId is not set")
	}

{'fraction_non_alphanumeric': 0.15052732502396932, 'fraction_numerical': 0.006471716203259827, 'mean_word_length': 3.988045427375971, 'pattern_counts': {'":': 8, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7472847', 'n_tokens_mistral': 3213, 'n_tokens_neox': 3078, 'n_words': 751}