Changeset 781 in code for trunk/db_postgres.go


Ignore:
Timestamp:
Feb 11, 2022, 6:41:46 PM (3 years ago)
Author:
delthas
Message:

Add support for the wip soju.im/read capability and READ command

READ lets downstream clients share information between each other about
what messages have been read by other downstreams.

Each target/entity has an optional corresponding read receipt, which is
stored as a timestamp.

  • When a downstream sends: READ #chan timestamp=2020-01-01T01:23:45.000Z the read receipt for that target is set to that date
  • soju sends READ to downstreams:
    • on JOIN, if the client uses the soju.im/read capability
    • when the read receipt timestamp is set by any downstream

The read receipt date is clamped by the previous receipt date and the
current time.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/db_postgres.go

    r774 r781  
    7878        UNIQUE(network, target, client)
    7979);
     80
     81CREATE TABLE "ReadReceipt" (
     82        id SERIAL PRIMARY KEY,
     83        network INTEGER NOT NULL REFERENCES "Network"(id) ON DELETE CASCADE,
     84        target VARCHAR(255) NOT NULL,
     85        timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
     86        UNIQUE(network, target)
     87);
    8088`
    8189
     
    8997                        TYPE sasl_mechanism
    9098                        USING sasl_mechanism::sasl_mechanism;
     99        `,
     100        `
     101                CREATE TABLE "ReadReceipt" (
     102                        id SERIAL PRIMARY KEY,
     103                        network INTEGER NOT NULL REFERENCES "Network"(id) ON DELETE CASCADE,
     104                        target VARCHAR(255) NOT NULL,
     105                        timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
     106                        UNIQUE(network, target)
     107                );
    91108        `,
    92109}
     
    501518        return tx.Commit()
    502519}
     520
     521func (db *PostgresDB) GetReadReceipt(ctx context.Context, networkID int64, name string) (*ReadReceipt, error) {
     522        ctx, cancel := context.WithTimeout(ctx, postgresQueryTimeout)
     523        defer cancel()
     524
     525        receipt := &ReadReceipt{
     526                Target: name,
     527        }
     528
     529        row := db.db.QueryRowContext(ctx,
     530                `SELECT id, timestamp FROM "ReadReceipt" WHERE network = $1 AND target = $2`,
     531                networkID, name)
     532        if err := row.Scan(&receipt.ID, &receipt.Timestamp); err != nil {
     533                if err == sql.ErrNoRows {
     534                        return nil, nil
     535                }
     536                return nil, err
     537        }
     538        return receipt, nil
     539}
     540
     541func (db *PostgresDB) StoreReadReceipt(ctx context.Context, networkID int64, receipt *ReadReceipt) error {
     542        ctx, cancel := context.WithTimeout(ctx, postgresQueryTimeout)
     543        defer cancel()
     544
     545        var err error
     546        if receipt.ID != 0 {
     547                _, err = db.db.ExecContext(ctx, `
     548                        UPDATE "ReadReceipt"
     549                        SET timestamp = $1
     550                        WHERE id = $2`,
     551                        receipt.Timestamp, receipt.ID)
     552        } else {
     553                err = db.db.QueryRowContext(ctx, `
     554                        INSERT INTO "ReadReceipt" (network, target, timestamp)
     555                        VALUES ($1, $2, $3)
     556                        RETURNING id`,
     557                        networkID, receipt.Target, receipt.Timestamp).Scan(&receipt.ID)
     558        }
     559        return err
     560}
Note: See TracChangeset for help on using the changeset viewer.