<commit_before>package db

import (
	"database/sql"
	"github.com/OpenBazaar/openbazaar-go/repo"
	"strconv"
	"sync"
	"time"
)

type ChatDB struct {
	db   *sql.DB
	lock sync.RWMutex
}

func (c *ChatDB) Put(messageId string, peerId string, subject string, message string, timestamp time.Time, read bool, outgoing bool) error {
	c.lock.Lock()
	defer c.lock.Unlock()

	tx, err := c.db.Begin()
	if err != nil {
		return err
	}
	stm := `insert or replace into chat(messageID, peerID, subject, message, read, timestamp, outgoing) values(?,?,?,?,?,?,?)`
	stmt, err := tx.Prepare(stm)
	if err != nil {
		return err
	}
	readInt := 0
	if read {
		readInt = 1
	}

	outgoingInt := 0
	if outgoing {
		outgoingInt = 1
	}

	defer stmt.Close()
	_, err = stmt.Exec(
		messageId,
		peerId,
		subject,
		message,
		readInt,
		int(timestamp.Unix()),
		outgoingInt,
	)
	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}

func (c *ChatDB) GetConversations() []repo.ChatConversation {
	c.lock.RLock()
	defer c.lock.RUnlock()
	var ret []repo.ChatConversation

	stm := "select distinct peerID from chat order by timestamp desc;"
	rows, err := c.db.Query(stm)
	if err != nil {
		return ret
	}
	var ids []string
	for rows.Next() {
		var peerId string
		if err := rows.Scan(&peerId); err != nil {
			continue
		}
		ids = append(ids, peerId)

	}
	defer rows.Close()
	for _, peerId := range ids {
		stm := "select Count(*) from chat where peerID='" + peerId + "' and read=0 and subject='' and outgoing=0;"
		row := c.db.QueryRow(stm)
		var count int
		row.Scan(&count)
		stm = "select max(timestamp), message, outgoing from chat where peerID='" + peerId + "' and subject=''"
		row = c.db.QueryRow(stm)
		var m string
		var ts int
		var outInt int
		row.Scan(&ts, &m, &outInt)
		outgoing := false
		if outInt > 0 {
			outgoing = true
		}
		convo := repo.ChatConversation{
			PeerId:   peerId,
			Unread:   count,
			Last:     m,
			Outgoing: outgoing,
		}
		ret = append(ret, convo)
	}
	return ret
}

func (c *ChatDB) GetMessages(peerID string, subject string, offsetId string, limit int) []repo.ChatMessage {
	c.lock.RLock()
	defer c.lock.RUnlock()
	var ret []repo.ChatMessage

	var stm string
	if offsetId != "" {
		stm = "select messageID, message, read, timestamp, outgoing from chat where subject='" + subject + "' and peerID='" + peerID + "' and timestamp<(select timestamp from chat where messageID=" + offsetId + ") order by timestamp desc limit " + strconv.Itoa(limit) + " ;"
	} else {
		stm = "select messageID, message, read, timestamp, outgoing from chat where subject='" + subject + "' and peerID='" + peerID + "' order by timestamp desc limit " + strconv.Itoa(limit) + ";"
	}
	rows, err := c.db.Query(stm)
	if err != nil {<commit_msg>Fix bug fetching chat messages<commit_after>package db

import (
	"database/sql"
	"github.com/OpenBazaar/openbazaar-go/repo"
	"strconv"
	"sync"
	"time"
)

type ChatDB struct {
	db   *sql.DB
	lock sync.RWMutex
}

func (c *ChatDB) Put(messageId string, peerId string, subject string, message string, timestamp time.Time, read bool, outgoing bool) error {
	c.lock.Lock()
	defer c.lock.Unlock()

	tx, err := c.db.Begin()
	if err != nil {
		return err
	}
	stm := `insert or replace into chat(messageID, peerID, subject, message, read, timestamp, outgoing) values(?,?,?,?,?,?,?)`
	stmt, err := tx.Prepare(stm)
	if err != nil {
		return err
	}
	readInt := 0
	if read {
		readInt = 1
	}

	outgoingInt := 0
	if outgoing {
		outgoingInt = 1
	}

	defer stmt.Close()
	_, err = stmt.Exec(
		messageId,
		peerId,
		subject,
		message,
		readInt,
		int(timestamp.Unix()),
		outgoingInt,
	)
	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}

func (c *ChatDB) GetConversations() []repo.ChatConversation {
	c.lock.RLock()
	defer c.lock.RUnlock()
	var ret []repo.ChatConversation

	stm := "select distinct peerID from chat order by timestamp desc;"
	rows, err := c.db.Query(stm)
	if err != nil {
		return ret
	}
	var ids []string
	for rows.Next() {
		var peerId string
		if err := rows.Scan(&peerId); err != nil {
			continue
		}
		ids = append(ids, peerId)

	}
	defer rows.Close()
	for _, peerId := range ids {
		stm := "select Count(*) from chat where peerID='" + peerId + "' and read=0 and subject='' and outgoing=0;"
		row := c.db.QueryRow(stm)
		var count int
		row.Scan(&count)
		stm = "select max(timestamp), message, outgoing from chat where peerID='" + peerId + "' and subject=''"
		row = c.db.QueryRow(stm)
		var m string
		var ts int
		var outInt int
		row.Scan(&ts, &m, &outInt)
		outgoing := false
		if outInt > 0 {
			outgoing = true
		}
		convo := repo.ChatConversation{
			PeerId:   peerId,
			Unread:   count,
			Last:     m,
			Outgoing: outgoing,
		}
		ret = append(ret, convo)
	}
	return ret
}

func (c *ChatDB) GetMessages(peerID string, subject string, offsetId string, limit int) []repo.ChatMessage {
	c.lock.RLock()
	defer c.lock.RUnlock()
	var ret []repo.ChatMessage

	var stm string
	if offsetId != "" {
		stm = "select messageID, message, read, timestamp, outgoing from chat where subject='" + subject + "' and peerID='" + peerID + "' and timestamp<(select timestamp from chat where messageID='" + offsetId + "') order by timestamp desc limit " + strconv.Itoa(limit) + " ;"
	} else {
		stm = "select messageID, message, read, timestamp, outgoing from chat where subject='" + subject + "' and peerID='" + peerID + "' order by timestamp desc limit " + strconv.Itoa(limit) + ";"
	}
	rows, err := c.db.Query(stm)
	if err != nil {
{'fraction_non_alphanumeric': 0.14329878159665393, 'fraction_numerical': 0.002545917439534461, 'mean_word_length': 3.4971381847914964, 'pattern_counts': {'":': 0, '<': 5, '<?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': '570093', 'n_tokens_mistral': 2128, 'n_tokens_neox': 1999, 'n_words': 598}