Changeset 489 in code for trunk/db.go


Ignore:
Timestamp:
Mar 31, 2021, 4:04:13 PM (4 years ago)
Author:
contact
Message:

Save delivery receipts in DB

This avoids loosing history on restart for clients that don't
support chathistory.

Closes: https://todo.sr.ht/~emersion/soju/80

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/db.go

    r457 r489  
    119119        DetachAfter   time.Duration
    120120        DetachOn      MessageFilter
     121}
     122
     123type DeliveryReceipt struct {
     124        ID            int64
     125        Target        string // channel or nick
     126        Client        string
     127        InternalMsgID string
    121128}
    122129
     
    161168        FOREIGN KEY(network) REFERENCES Network(id),
    162169        UNIQUE(network, name)
     170);
     171
     172CREATE TABLE DeliveryReceipt (
     173        id INTEGER PRIMARY KEY,
     174        network INTEGER NOT NULL,
     175        target VARCHAR(255) NOT NULL,
     176        client VARCHAR(255),
     177        internal_msgid VARCHAR(255) NOT NULL,
     178        FOREIGN KEY(network) REFERENCES Network(id),
     179        UNIQUE(network, target, client)
    163180);
    164181`
     
    218235                ALTER TABLE Channel ADD COLUMN detach_on INTEGER NOT NULL DEFAULT 0;
    219236        `,
     237        `
     238                CREATE TABLE DeliveryReceipt (
     239                        id INTEGER PRIMARY KEY,
     240                        network INTEGER NOT NULL,
     241                        target VARCHAR(255) NOT NULL,
     242                        client VARCHAR(255),
     243                        internal_msgid VARCHAR(255) NOT NULL,
     244                        FOREIGN KEY(network) REFERENCES Network(id),
     245                        UNIQUE(network, target, client)
     246                );
     247        `,
    220248}
    221249
     
    579607        return err
    580608}
     609
     610func (db *DB) ListDeliveryReceipts(networkID int64) ([]DeliveryReceipt, error) {
     611        db.lock.RLock()
     612        defer db.lock.RUnlock()
     613
     614        rows, err := db.db.Query(`SELECT id, target, client, internal_msgid
     615                FROM DeliveryReceipt
     616                WHERE network = ?`, networkID)
     617        if err != nil {
     618                return nil, err
     619        }
     620        defer rows.Close()
     621
     622        var receipts []DeliveryReceipt
     623        for rows.Next() {
     624                var rcpt DeliveryReceipt
     625                var client sql.NullString
     626                if err := rows.Scan(&rcpt.ID, &rcpt.Target, &client, &rcpt.InternalMsgID); err != nil {
     627                        return nil, err
     628                }
     629                rcpt.Client = client.String
     630                receipts = append(receipts, rcpt)
     631        }
     632        if err := rows.Err(); err != nil {
     633                return nil, err
     634        }
     635
     636        return receipts, nil
     637}
     638
     639func (db *DB) StoreClientDeliveryReceipts(networkID int64, client string, receipts []DeliveryReceipt) error {
     640        db.lock.Lock()
     641        defer db.lock.Unlock()
     642
     643        tx, err := db.db.Begin()
     644        if err != nil {
     645                return err
     646        }
     647        defer tx.Rollback()
     648
     649        _, err = tx.Exec("DELETE FROM DeliveryReceipt WHERE network = ? AND client = ?",
     650                networkID, toNullString(client))
     651        if err != nil {
     652                return err
     653        }
     654
     655        for i := range receipts {
     656                rcpt := &receipts[i]
     657
     658                res, err := tx.Exec("INSERT INTO DeliveryReceipt(network, target, client, internal_msgid) VALUES (?, ?, ?, ?)",
     659                        networkID, rcpt.Target, toNullString(client), rcpt.InternalMsgID)
     660                if err != nil {
     661                        return err
     662                }
     663                rcpt.ID, err = res.LastInsertId()
     664                if err != nil {
     665                        return err
     666                }
     667        }
     668
     669        return tx.Commit()
     670}
Note: See TracChangeset for help on using the changeset viewer.