2021-11-30 15:38:37 +01:00
// mautrix-whatsapp - A Matrix-WhatsApp puppeting bridge.
// Copyright (C) 2021 Tulir Asokan
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package database
import (
"database/sql"
"errors"
"time"
)
func ( user * User ) GetLastReadTS ( portal PortalKey ) time . Time {
2021-12-29 20:40:08 +01:00
user . lastReadCacheLock . Lock ( )
defer user . lastReadCacheLock . Unlock ( )
if cached , ok := user . lastReadCache [ portal ] ; ok {
return cached
}
2021-11-30 15:38:37 +01:00
var ts int64
err := user . db . QueryRow ( "SELECT last_read_ts FROM user_portal WHERE user_mxid=$1 AND portal_jid=$2 AND portal_receiver=$3" , user . MXID , portal . JID , portal . Receiver ) . Scan ( & ts )
if err != nil && ! errors . Is ( err , sql . ErrNoRows ) {
user . log . Warnfln ( "Failed to scan last read timestamp from user portal table: %v" , err )
}
if ts == 0 {
2021-12-29 20:40:08 +01:00
user . lastReadCache [ portal ] = time . Time { }
} else {
user . lastReadCache [ portal ] = time . Unix ( ts , 0 )
2021-11-30 15:38:37 +01:00
}
2021-12-29 20:40:08 +01:00
return user . lastReadCache [ portal ]
2021-11-30 15:38:37 +01:00
}
func ( user * User ) SetLastReadTS ( portal PortalKey , ts time . Time ) {
2021-12-29 20:40:08 +01:00
user . lastReadCacheLock . Lock ( )
defer user . lastReadCacheLock . Unlock ( )
_ , err := user . db . Exec ( `
2021-11-30 15:38:37 +01:00
INSERT INTO user_portal ( user_mxid , portal_jid , portal_receiver , last_read_ts ) VALUES ( $ 1 , $ 2 , $ 3 , $ 4 )
2021-12-29 20:40:08 +01:00
ON CONFLICT ( user_mxid , portal_jid , portal_receiver ) DO UPDATE SET last_read_ts = excluded . last_read_ts WHERE user_portal . last_read_ts < excluded . last_read_ts
2021-11-30 15:38:37 +01:00
` , user . MXID , portal . JID , portal . Receiver , ts . Unix ( ) )
2021-12-29 20:40:08 +01:00
if err != nil {
user . log . Warnfln ( "Failed to update last read timestamp: %v" , err )
2021-11-30 15:38:37 +01:00
} else {
2021-12-29 20:40:08 +01:00
user . lastReadCache [ portal ] = ts
}
}
func ( user * User ) IsInSpace ( portal PortalKey ) bool {
user . inSpaceCacheLock . Lock ( )
defer user . inSpaceCacheLock . Unlock ( )
if cached , ok := user . inSpaceCache [ portal ] ; ok {
return cached
2021-11-30 15:38:37 +01:00
}
2021-12-29 20:40:08 +01:00
var inSpace bool
err := user . db . QueryRow ( "SELECT in_space FROM user_portal WHERE user_mxid=$1 AND portal_jid=$2 AND portal_receiver=$3" , user . MXID , portal . JID , portal . Receiver ) . Scan ( & inSpace )
if err != nil && ! errors . Is ( err , sql . ErrNoRows ) {
user . log . Warnfln ( "Failed to scan in space status from user portal table: %v" , err )
}
user . inSpaceCache [ portal ] = inSpace
return inSpace
}
func ( user * User ) MarkInSpace ( portal PortalKey ) {
user . inSpaceCacheLock . Lock ( )
defer user . inSpaceCacheLock . Unlock ( )
_ , err := user . db . Exec ( `
INSERT INTO user_portal ( user_mxid , portal_jid , portal_receiver , in_space ) VALUES ( $ 1 , $ 2 , $ 3 , true )
ON CONFLICT ( user_mxid , portal_jid , portal_receiver ) DO UPDATE SET in_space = true
` , user . MXID , portal . JID , portal . Receiver )
2021-11-30 15:38:37 +01:00
if err != nil {
2021-12-29 20:40:08 +01:00
user . log . Warnfln ( "Failed to update in space status: %v" , err )
} else {
user . inSpaceCache [ portal ] = true
2021-11-30 15:38:37 +01:00
}
}