<commit_before>package models

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

	"github.com/jinzhu/gorm"
	"github.com/koding/bongo"
)

type ChannelMessageList struct {
	// unique identifier of the channel message list
	Id int64 `json:"id,string"`

	// Id of the channel
	ChannelId int64 `json:"channelId,string"     sql:"NOT NULL"`

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

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

	// Addition date of the message to the channel
	// this date will be update whever message added/removed/re-added to the channel
	AddedAt time.Time `json:"addedAt"            sql:"NOT NULL"`

	// Update time of the message/list
	RevisedAt time.Time `json:"revisedAt"        sql:"NOT NULL"`
}

func (c *ChannelMessageList) BeforeCreate() {
	c.AddedAt = time.Now()
	c.RevisedAt = time.Now()
}

func (c *ChannelMessageList) BeforeUpdate() {
	c.AddedAt = time.Now()
}

func (c *ChannelMessageList) AfterCreate() {
	bongo.B.AfterCreate(c)
}

func (c *ChannelMessageList) AfterUpdate() {
	bongo.B.AfterUpdate(c)
}

func (c ChannelMessageList) AfterDelete() {
	bongo.B.AfterDelete(c)
}

func (c ChannelMessageList) GetId() int64 {
	return c.Id
}

func (c ChannelMessageList) TableName() string {
	return "api.channel_message_list"
}

func NewChannelMessageList() *ChannelMessageList {
	return &ChannelMessageList{}
}

func (c *ChannelMessageList) ById(id int64) error {
	return bongo.B.ById(c, id)
}

func (c *ChannelMessageList) One(q *bongo.Query) error {
	return bongo.B.One(c, c, q)
}

func (c *ChannelMessageList) Update() error {
	return bongo.B.Update(c)
}

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

func (c *ChannelMessageList) UnreadCount(cp *ChannelParticipant) (int, error) {
	if cp.ChannelId == 0 {
		return 0, errors.New("ChannelId is not set")
	}

	if cp.AccountId == 0 {
		return 0, errors.New("AccountId is not set")
	}

	if cp.LastSeenAt.IsZero() {
		return 0, errors.New("Last seen at date is not valid - it is zero")
	}

	return bongo.B.Count(c,
		"channel_id = ? and added_at > ?",
		cp.ChannelId,
		// todo change this format to get from a specific place
		cp.LastSeenAt.UTC().Format(time.RFC3339),
	)
}

func (c *ChannelMessageList) Create() error {
	return bongo.B.Create(c)
}

func (c *ChannelMessageList) CreateRaw() error {
	insertSql := "INSERT INTO " +
		c.TableName() +
		` ("channel_id","message_id","added_at","revised_at") VALUES ($1,$2,$3,$4) ` +
		"RETURNING ID"

	return bongo.B.DB.CommonDB().
		QueryRow(insertSql, c.ChannelId, c.MessageId, c.AddedAt, c.RevisedAt).
		Scan(&c.Id)
}

func (c *ChannelMessageList) Delete() error {
	return bongo.B.Delete(c)
}

func (c *ChannelMessageList) List(q *request.Query, populateUnreadCount bool) (*HistoryResponse, error) {
	messageList, err := c.getMessages(q)
	if err != nil {
		return nil, err
	}

	if populateUnreadCount {
		messageList = c.populateUnreadCount(messageList)
	}

	hr := NewHistoryResponse()
	hr.MessageList = messageList
	return hr, nil
}

// populateUnreadCount adds unread count into message containers
func (c *ChannelMessageList) populateUnreadCount(messageList []*ChannelMessageContainer) []*ChannelMessageContainer {
	channel := NewChannel()
	channel.Id = c.ChannelId

	for i, message := range messageList {
		cml, err := channel.FetchMessageList(message.Message.Id)
		if err != nil {
			// helper.MustGetLogger().Error(err.Error())
			continue
		}

		count, err := NewMessageReply().UnreadCount(cml.MessageId, cml.AddedAt)<commit_msg>social: change added at with revisedAt<commit_after>package models

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

	"github.com/jinzhu/gorm"
	"github.com/koding/bongo"
)

type ChannelMessageList struct {
	// unique identifier of the channel message list
	Id int64 `json:"id,string"`

	// Id of the channel
	ChannelId int64 `json:"channelId,string"     sql:"NOT NULL"`

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

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

	// Addition date of the message to the channel
	// this date will be update whever message added/removed/re-added to the channel
	AddedAt time.Time `json:"addedAt"            sql:"NOT NULL"`

	// Update time of the message/list
	RevisedAt time.Time `json:"revisedAt"        sql:"NOT NULL"`
}

func (c *ChannelMessageList) BeforeCreate() {
	c.AddedAt = time.Now()
	c.RevisedAt = time.Now()
}

func (c *ChannelMessageList) BeforeUpdate() {
	c.AddedAt = time.Now()
}

func (c *ChannelMessageList) AfterCreate() {
	bongo.B.AfterCreate(c)
}

func (c *ChannelMessageList) AfterUpdate() {
	bongo.B.AfterUpdate(c)
}

func (c ChannelMessageList) AfterDelete() {
	bongo.B.AfterDelete(c)
}

func (c ChannelMessageList) GetId() int64 {
	return c.Id
}

func (c ChannelMessageList) TableName() string {
	return "api.channel_message_list"
}

func NewChannelMessageList() *ChannelMessageList {
	return &ChannelMessageList{}
}

func (c *ChannelMessageList) ById(id int64) error {
	return bongo.B.ById(c, id)
}

func (c *ChannelMessageList) One(q *bongo.Query) error {
	return bongo.B.One(c, c, q)
}

func (c *ChannelMessageList) Update() error {
	return bongo.B.Update(c)
}

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

func (c *ChannelMessageList) UnreadCount(cp *ChannelParticipant) (int, error) {
	if cp.ChannelId == 0 {
		return 0, errors.New("ChannelId is not set")
	}

	if cp.AccountId == 0 {
		return 0, errors.New("AccountId is not set")
	}

	if cp.LastSeenAt.IsZero() {
		return 0, errors.New("Last seen at date is not valid - it is zero")
	}

	return bongo.B.Count(c,
		"channel_id = ? and added_at > ?",
		cp.ChannelId,
		// todo change this format to get from a specific place
		cp.LastSeenAt.UTC().Format(time.RFC3339),
	)
}

func (c *ChannelMessageList) Create() error {
	return bongo.B.Create(c)
}

func (c *ChannelMessageList) CreateRaw() error {
	insertSql := "INSERT INTO " +
		c.TableName() +
		` ("channel_id","message_id","added_at","revised_at") VALUES ($1,$2,$3,$4) ` +
		"RETURNING ID"

	return bongo.B.DB.CommonDB().
		QueryRow(insertSql, c.ChannelId, c.MessageId, c.AddedAt, c.RevisedAt).
		Scan(&c.Id)
}

func (c *ChannelMessageList) Delete() error {
	return bongo.B.Delete(c)
}

func (c *ChannelMessageList) List(q *request.Query, populateUnreadCount bool) (*HistoryResponse, error) {
	messageList, err := c.getMessages(q)
	if err != nil {
		return nil, err
	}

	if populateUnreadCount {
		messageList = c.populateUnreadCount(messageList)
	}

	hr := NewHistoryResponse()
	hr.MessageList = messageList
	return hr, nil
}

// populateUnreadCount adds unread count into message containers
func (c *ChannelMessageList) populateUnreadCount(messageList []*ChannelMessageContainer) []*ChannelMessageContainer {
	channel := NewChannel()
	channel.Id = c.ChannelId

	for i, message := range messageList {
		cml, err := channel.FetchMessageList(message.Message.Id)
		if err != nil {
			// helper.MustGetLogger().Error(err.Error())
			continue
		}

		count, err := NewMessageReply().UnreadCount(cml.MessageId, cml.RevisedAt)
{'fraction_non_alphanumeric': 0.13581278729628082, 'fraction_numerical': 0.006964758322886196, 'mean_word_length': 4.3343239227340264, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '4660325', 'n_tokens_mistral': 2616, 'n_tokens_neox': 2499, 'n_words': 646}