feat: add chapter eight call records

This commit is contained in:
richjohnrambo
2026-08-13 16:14:57 +08:00
parent 92d0066a02
commit dfcccbb761
9 changed files with 711 additions and 20 deletions
+85 -3
View File
@@ -791,6 +791,9 @@ func (a *adapter) CreateDb(reset bool) error {
if err = createIMRelationTables(tx); err != nil {
return err
}
if err = createIMCallTables(tx); err != nil {
return err
}
// Deletion log
if _, err = tx.Exec(
@@ -919,6 +922,34 @@ func createIMNotificationTables(tx *sql.Tx) error {
return err
}
func createIMCallTables(tx *sql.Tx) error {
_, err := tx.Exec(
`CREATE TABLE im_call_records(
id BIGINT NOT NULL AUTO_INCREMENT,
call_id VARCHAR(64) NOT NULL,
topic CHAR(25) NOT NULL,
seq_id INT NOT NULL,
caller_id BIGINT NOT NULL,
callee_id BIGINT NOT NULL,
call_type VARCHAR(16) NOT NULL,
status VARCHAR(32) NOT NULL,
end_reason VARCHAR(64) NOT NULL DEFAULT '',
duration_ms BIGINT NOT NULL DEFAULT 0,
started_at DATETIME(3) NOT NULL,
accepted_at DATETIME(3),
finished_at DATETIME(3),
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
PRIMARY KEY(id),
UNIQUE INDEX uk_im_call_records_call(call_id),
UNIQUE INDEX uk_im_call_records_topic_seq(topic, seq_id),
INDEX idx_im_call_records_caller(caller_id, id DESC),
INDEX idx_im_call_records_callee(callee_id, id DESC),
INDEX idx_im_call_records_status(status, updated_at)
)`)
return err
}
func ensureTenantRoutingColumns(a *adapter) error {
statements := []string{
"ALTER TABLE im_tenant ADD COLUMN db_name VARCHAR(128) NOT NULL DEFAULT '' AFTER tenant_desc",
@@ -1258,7 +1289,7 @@ func (a *adapter) TenantAuthDelScheme(tenantID t.TenantID, uid t.Uid, scheme str
if cancel != nil {
defer cancel()
}
_, err := a.db.ExecContext(ctx, "DELETE FROM auth WHERE tenant_id=? AND userid=? AND scheme=?",
_, err = a.db.ExecContext(ctx, "DELETE FROM auth WHERE tenant_id=? AND userid=? AND scheme=?",
tenantID, store.DecodeUid(uid), scheme)
return err
}
@@ -3942,7 +3973,7 @@ func (a *adapter) TenantCredFail(tenantID t.TenantID, uid t.Uid, method string)
if cancel != nil {
defer cancel()
}
_, err := a.db.ExecContext(ctx, "UPDATE credentials SET updatedat=?,retries=retries+1 "+
_, err = a.db.ExecContext(ctx, "UPDATE credentials SET updatedat=?,retries=retries+1 "+
"WHERE tenant_id=? AND userid=? AND method=? AND done=FALSE",
t.TimeNow(), tenantID, store.DecodeUid(uid), method)
return err
@@ -3983,7 +4014,7 @@ func (a *adapter) TenantCredGetActive(tenantID t.TenantID, uid t.Uid, method str
defer cancel()
}
var cred t.Credential
err := a.db.GetContext(ctx, &cred, "SELECT createdat,updatedat,method,value,resp,done,retries "+
err = a.db.GetContext(ctx, &cred, "SELECT createdat,updatedat,method,value,resp,done,retries "+
"FROM credentials WHERE tenant_id=? AND userid=? AND deletedat IS NULL AND method=? AND done=FALSE",
tenantID, store.DecodeUid(uid), method)
if err == sql.ErrNoRows {
@@ -4292,6 +4323,57 @@ func (a *adapter) FileLinkAttachments(topic string, userId, msgId t.Uid, fids []
return tx.Commit()
}
func (a *adapter) FileUserHasAccess(fid string, uid t.Uid) (bool, error) {
if uid.IsZero() {
return false, t.ErrMalformed
}
fileID := t.ParseUid(fid)
if fileID.IsZero() {
return false, t.ErrMalformed
}
ctx, cancel := a.getContext()
if cancel != nil {
defer cancel()
}
var allowed int
err := a.db.GetContext(ctx, &allowed, `
SELECT COUNT(*) FROM fileuploads AS fu
WHERE fu.id=? AND fu.status=? AND (
fu.userid=?
OR EXISTS (
SELECT 1 FROM filemsglinks AS fml
WHERE fml.fileid=fu.id AND fml.userid=?
)
OR EXISTS (
SELECT 1 FROM filemsglinks AS fml
INNER JOIN subscriptions AS s
ON s.topic=fml.topic AND s.userid=?
WHERE fml.fileid=fu.id AND fml.topic IS NOT NULL
AND s.deletedat IS NULL AND INSTR(s.modewant,'R')>0 AND INSTR(s.modegiven,'R')>0
)
OR EXISTS (
SELECT 1 FROM filemsglinks AS fml
INNER JOIN messages AS m
ON m.id=fml.msgid
INNER JOIN subscriptions AS s
ON s.topic=m.topic AND s.userid=?
WHERE fml.fileid=fu.id AND fml.msgid IS NOT NULL
AND m.deletedat IS NULL AND m.recalled_at IS NULL
AND s.deletedat IS NULL AND INSTR(s.modewant,'R')>0 AND INSTR(s.modegiven,'R')>0
AND NOT EXISTS (
SELECT 1 FROM dellog AS d
WHERE d.topic=m.topic AND d.deletedfor=?
AND d.low<=m.seqid AND (d.hi=0 OR d.hi>m.seqid)
)
)
) LIMIT 1`,
store.DecodeUid(fileID), t.UploadCompleted, store.DecodeUid(uid), store.DecodeUid(uid), store.DecodeUid(uid), store.DecodeUid(uid), store.DecodeUid(uid))
if err != nil {
return false, err
}
return allowed > 0, nil
}
// PCacheGet reads a persistet cache entry.
func (a *adapter) PCacheGet(key string) (string, error) {
ctx, cancel := a.getContext()