feat: add im home and message action flows
This commit is contained in:
+251
-11
@@ -41,7 +41,7 @@ type adapter struct {
|
||||
}
|
||||
|
||||
const (
|
||||
adpVersion = 118
|
||||
adpVersion = 122
|
||||
adapterName = "mysql"
|
||||
|
||||
defaultDSN = "root:@tcp(localhost:3306)/tinode?parseTime=true"
|
||||
@@ -56,6 +56,8 @@ const (
|
||||
txTimeoutMultiplier = 1.5
|
||||
)
|
||||
|
||||
const defaultTenantID = t.TenantID(1)
|
||||
|
||||
type configType struct {
|
||||
// DB connection settings.
|
||||
// See https://pkg.go.dev/github.com/go-sql-driver/mysql#Config
|
||||
@@ -381,6 +383,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
tenant_id BIGINT NOT NULL,
|
||||
challenge_id VARCHAR(64) NOT NULL,
|
||||
scene VARCHAR(32) NOT NULL,
|
||||
action VARCHAR(64) NOT NULL DEFAULT '',
|
||||
phone_hash CHAR(64) NOT NULL,
|
||||
phone_mask VARCHAR(32) NOT NULL,
|
||||
target_user BIGINT,
|
||||
@@ -412,6 +415,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE users(
|
||||
id BIGINT NOT NULL,
|
||||
tenant_id BIGINT NOT NULL DEFAULT 1,
|
||||
createdat DATETIME(3) NOT NULL,
|
||||
updatedat DATETIME(3) NOT NULL,
|
||||
state SMALLINT NOT NULL DEFAULT 0,
|
||||
@@ -423,6 +427,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
trusted JSON,
|
||||
tags JSON,
|
||||
PRIMARY KEY(id),
|
||||
INDEX users_tenant_id_id(tenant_id, id),
|
||||
INDEX users_state_stateat(state, stateat),
|
||||
INDEX users_lastseen_updatedat(lastseen, updatedat)
|
||||
)`); err != nil {
|
||||
@@ -443,15 +448,24 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = createIMSecurityTables(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = createIMNotificationTables(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Indexed user tags.
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE usertags(
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL DEFAULT 1,
|
||||
userid BIGINT NOT NULL,
|
||||
tag VARCHAR(96) NOT NULL,
|
||||
PRIMARY KEY(id),
|
||||
FOREIGN KEY(userid) REFERENCES users(id),
|
||||
INDEX usertags_tag(tag),
|
||||
INDEX usertags_tenant_tag(tenant_id, tag),
|
||||
UNIQUE INDEX usertags_userid_tag(userid, tag)
|
||||
)`); err != nil {
|
||||
return err
|
||||
@@ -461,6 +475,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE devices(
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL DEFAULT 1,
|
||||
userid BIGINT NOT NULL,
|
||||
hash CHAR(16) NOT NULL,
|
||||
deviceid TEXT NOT NULL,
|
||||
@@ -469,6 +484,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
lang VARCHAR(8),
|
||||
PRIMARY KEY(id),
|
||||
FOREIGN KEY(userid) REFERENCES users(id),
|
||||
INDEX devices_tenant_userid(tenant_id, userid),
|
||||
UNIQUE INDEX devices_hash(hash)
|
||||
)`); err != nil {
|
||||
return err
|
||||
@@ -478,6 +494,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE auth(
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL DEFAULT 1,
|
||||
uname VARCHAR(32) NOT NULL,
|
||||
userid BIGINT NOT NULL,
|
||||
scheme VARCHAR(16) NOT NULL,
|
||||
@@ -486,8 +503,8 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
expires DATETIME,
|
||||
PRIMARY KEY(id),
|
||||
FOREIGN KEY(userid) REFERENCES users(id),
|
||||
UNIQUE INDEX auth_userid_scheme(userid, scheme),
|
||||
UNIQUE INDEX auth_uname(uname)
|
||||
UNIQUE INDEX auth_tenant_uname(tenant_id, uname),
|
||||
UNIQUE INDEX auth_userid_scheme(userid, scheme)
|
||||
)`); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -496,6 +513,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE topics(
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL DEFAULT 1,
|
||||
createdat DATETIME(3) NOT NULL,
|
||||
updatedat DATETIME(3) NOT NULL,
|
||||
state SMALLINT NOT NULL DEFAULT 0,
|
||||
@@ -513,8 +531,10 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
tags JSON,
|
||||
aux JSON,
|
||||
PRIMARY KEY(id),
|
||||
UNIQUE INDEX topics_tenant_name(tenant_id, name),
|
||||
UNIQUE INDEX topics_name(name),
|
||||
INDEX topics_owner(owner),
|
||||
INDEX topics_tenant_owner(tenant_id, owner),
|
||||
INDEX topics_state_stateat(state, stateat),
|
||||
INDEX topics_name_state_seqid(name, state, seqid)
|
||||
)`); err != nil {
|
||||
@@ -530,11 +550,13 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE topictags(
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL DEFAULT 1,
|
||||
topic CHAR(25) NOT NULL,
|
||||
tag VARCHAR(96) NOT NULL,
|
||||
PRIMARY KEY(id),
|
||||
FOREIGN KEY(topic) REFERENCES topics(name),
|
||||
INDEX topictags_tag(tag),
|
||||
INDEX topictags_tenant_tag(tenant_id, tag),
|
||||
UNIQUE INDEX topictags_topic_tag(topic, tag)
|
||||
)`); err != nil {
|
||||
return err
|
||||
@@ -544,6 +566,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE subscriptions(
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL DEFAULT 1,
|
||||
createdat DATETIME(3) NOT NULL,
|
||||
updatedat DATETIME(3) NOT NULL,
|
||||
deletedat DATETIME(3),
|
||||
@@ -557,6 +580,8 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
private JSON,
|
||||
PRIMARY KEY(id),
|
||||
FOREIGN KEY(userid) REFERENCES users(id),
|
||||
INDEX subscriptions_tenant_userid(tenant_id, userid),
|
||||
INDEX subscriptions_tenant_topic(tenant_id, topic),
|
||||
UNIQUE INDEX subscriptions_topic_userid(topic, userid),
|
||||
INDEX subscriptions_topic(topic),
|
||||
INDEX subscriptions_deletedat(deletedat),
|
||||
@@ -569,6 +594,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE messages(
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL DEFAULT 1,
|
||||
createdat DATETIME(3) NOT NULL,
|
||||
updatedat DATETIME(3) NOT NULL,
|
||||
deletedat DATETIME(3),
|
||||
@@ -576,19 +602,46 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
seqid INT NOT NULL,
|
||||
topic CHAR(25) NOT NULL,` +
|
||||
"`from` BIGINT NOT NULL," +
|
||||
`head JSON,
|
||||
`client_msg_id VARCHAR(64),
|
||||
version INT NOT NULL DEFAULT 1,
|
||||
recalled_at DATETIME(3),
|
||||
recalled_by BIGINT,
|
||||
head JSON,
|
||||
content JSON,
|
||||
PRIMARY KEY(id),
|
||||
FOREIGN KEY(topic) REFERENCES topics(name),
|
||||
INDEX messages_tenant_topic(tenant_id, topic),
|
||||
UNIQUE INDEX messages_sender_client_mid(tenant_id, ` + "`from`" + `, client_msg_id),
|
||||
UNIQUE INDEX messages_topic_seqid(topic, seqid)
|
||||
)`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE im_message_revisions(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
createdat DATETIME(3) NOT NULL,
|
||||
updatedat DATETIME(3) NOT NULL,
|
||||
topic CHAR(25) NOT NULL,
|
||||
seqid INT NOT NULL,
|
||||
version INT NOT NULL,
|
||||
actor BIGINT NOT NULL,
|
||||
head JSON,
|
||||
content JSON,
|
||||
reason VARCHAR(256) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY(id),
|
||||
UNIQUE INDEX uk_im_message_revisions_version(tenant_id, topic, seqid, version),
|
||||
CONSTRAINT fk_im_message_revisions_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
)`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Deletion log
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE dellog(
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL DEFAULT 1,
|
||||
topic CHAR(25) NOT NULL,
|
||||
deletedfor BIGINT NOT NULL DEFAULT 0,
|
||||
delid INT NOT NULL,
|
||||
@@ -596,6 +649,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
hi INT NOT NULL,
|
||||
PRIMARY KEY(id),
|
||||
FOREIGN KEY(topic) REFERENCES topics(name),
|
||||
INDEX dellog_tenant_topic(tenant_id, topic),
|
||||
INDEX dellog_topic_delid_deletedfor(topic,delid,deletedfor),
|
||||
INDEX dellog_topic_deletedfor_low_hi(topic,deletedfor,low,hi),
|
||||
INDEX dellog_deletedfor(deletedfor)
|
||||
@@ -607,6 +661,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE credentials(
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL DEFAULT 1,
|
||||
createdat DATETIME(3) NOT NULL,
|
||||
updatedat DATETIME(3) NOT NULL,
|
||||
deletedat DATETIME(3),
|
||||
@@ -619,7 +674,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
retries INT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(id),
|
||||
FOREIGN KEY(userid) REFERENCES users(id),
|
||||
UNIQUE credentials_uniqueness(synthetic)
|
||||
UNIQUE credentials_tenant_uniqueness(tenant_id, synthetic)
|
||||
)`); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -629,6 +684,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE fileuploads(
|
||||
id BIGINT NOT NULL,
|
||||
tenant_id BIGINT NOT NULL DEFAULT 1,
|
||||
createdat DATETIME(3) NOT NULL,
|
||||
updatedat DATETIME(3) NOT NULL,
|
||||
userid BIGINT,
|
||||
@@ -638,6 +694,7 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
etag VARCHAR(128),
|
||||
location VARCHAR(2048) NOT NULL,
|
||||
PRIMARY KEY(id),
|
||||
INDEX fileuploads_tenant_status(tenant_id, status),
|
||||
INDEX fileuploads_status(status)
|
||||
)`); err != nil {
|
||||
return err
|
||||
@@ -647,12 +704,14 @@ func (a *adapter) CreateDb(reset bool) error {
|
||||
if _, err = tx.Exec(
|
||||
`CREATE TABLE filemsglinks(
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL DEFAULT 1,
|
||||
createdat DATETIME(3) NOT NULL,
|
||||
fileid BIGINT NOT NULL,
|
||||
msgid INT,
|
||||
topic CHAR(25),
|
||||
userid BIGINT,
|
||||
PRIMARY KEY(id),
|
||||
INDEX filemsglinks_tenant_fileid(tenant_id, fileid),
|
||||
FOREIGN KEY(fileid) REFERENCES fileuploads(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY(msgid) REFERENCES messages(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY(topic) REFERENCES topics(name) ON DELETE CASCADE,
|
||||
@@ -984,6 +1043,7 @@ func (a *adapter) UpgradeDb() error {
|
||||
tenant_id BIGINT NOT NULL,
|
||||
challenge_id VARCHAR(64) NOT NULL,
|
||||
scene VARCHAR(32) NOT NULL,
|
||||
action VARCHAR(64) NOT NULL DEFAULT '',
|
||||
phone_hash CHAR(64) NOT NULL,
|
||||
phone_mask VARCHAR(32) NOT NULL,
|
||||
target_user BIGINT,
|
||||
@@ -1031,6 +1091,64 @@ func (a *adapter) UpgradeDb() error {
|
||||
}
|
||||
}
|
||||
|
||||
if a.version == 118 {
|
||||
if _, err := a.db.Exec("ALTER TABLE im_verification_codes ADD COLUMN action VARCHAR(64) NOT NULL DEFAULT '' AFTER scene"); err != nil {
|
||||
return err
|
||||
}
|
||||
tx, err := a.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = createIMSecurityTables(tx); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := bumpVersion(a, 119); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if a.version == 119 {
|
||||
tx, err := a.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = createIMNotificationTables(tx); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := bumpVersion(a, 120); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if a.version == 120 {
|
||||
if _, err := a.db.Exec("ALTER TABLE messages ADD COLUMN client_msg_id VARCHAR(64) AFTER `from`"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := a.db.Exec("CREATE UNIQUE INDEX messages_sender_client_mid ON messages(tenant_id, `from`, client_msg_id)"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := bumpVersion(a, 121); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if a.version == 121 {
|
||||
if err := upgradeIMMessageActions(a); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := bumpVersion(a, 122); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if a.version != adpVersion {
|
||||
return errors.New("Failed to perform database upgrade to version " + strconv.Itoa(adpVersion) +
|
||||
". DB is still at " + strconv.Itoa(a.version))
|
||||
@@ -1038,6 +1156,121 @@ func (a *adapter) UpgradeDb() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func createIMNotificationTables(tx *sql.Tx) error {
|
||||
_, err := tx.Exec(
|
||||
`CREATE TABLE im_system_notifications(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
event_id VARCHAR(64) NOT NULL,
|
||||
event_type VARCHAR(64) NOT NULL,
|
||||
title VARCHAR(128) NOT NULL,
|
||||
summary VARCHAR(512) NOT NULL,
|
||||
action JSON,
|
||||
read_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_system_notifications_event(tenant_id, user_id, event_id),
|
||||
INDEX idx_im_system_notifications_inbox(tenant_id, user_id, id DESC),
|
||||
CONSTRAINT fk_im_system_notifications_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
)`)
|
||||
return err
|
||||
}
|
||||
|
||||
func upgradeIMMessageActions(a *adapter) error {
|
||||
statements := []string{
|
||||
"ALTER TABLE messages ADD COLUMN version INT NOT NULL DEFAULT 1 AFTER client_msg_id",
|
||||
"ALTER TABLE messages ADD COLUMN recalled_at DATETIME(3) AFTER version",
|
||||
"ALTER TABLE messages ADD COLUMN recalled_by BIGINT AFTER recalled_at",
|
||||
`CREATE TABLE im_message_revisions(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
createdat DATETIME(3) NOT NULL,
|
||||
updatedat DATETIME(3) NOT NULL,
|
||||
topic CHAR(25) NOT NULL,
|
||||
seqid INT NOT NULL,
|
||||
version INT NOT NULL,
|
||||
actor BIGINT NOT NULL,
|
||||
head JSON,
|
||||
content JSON,
|
||||
reason VARCHAR(256) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY(id),
|
||||
UNIQUE INDEX uk_im_message_revisions_version(tenant_id, topic, seqid, version),
|
||||
CONSTRAINT fk_im_message_revisions_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
)`,
|
||||
}
|
||||
for _, stmt := range statements {
|
||||
if _, err := a.db.Exec(stmt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createIMSecurityTables(tx *sql.Tx) error {
|
||||
if _, err := tx.Exec(
|
||||
`CREATE TABLE im_realname_verifications(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
submission_id VARCHAR(64) NOT NULL,
|
||||
status VARCHAR(16) NOT NULL,
|
||||
name_cipher TEXT NOT NULL,
|
||||
id_type VARCHAR(32) NOT NULL,
|
||||
id_number_cipher TEXT NOT NULL,
|
||||
id_number_hash CHAR(64) NOT NULL,
|
||||
masked_name VARCHAR(64) NOT NULL,
|
||||
masked_id_number VARCHAR(64) NOT NULL,
|
||||
review_reason VARCHAR(256),
|
||||
verified_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_realname_submission(tenant_id, submission_id),
|
||||
INDEX idx_im_realname_user_latest(tenant_id, user_id, created_at),
|
||||
INDEX idx_im_realname_id_hash(tenant_id, id_number_hash),
|
||||
CONSTRAINT fk_im_realname_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
)`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tx.Exec(
|
||||
`CREATE TABLE im_action_tokens(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
tenant_id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
token_id VARCHAR(64) NOT NULL,
|
||||
action VARCHAR(64) NOT NULL,
|
||||
target VARCHAR(128) NOT NULL DEFAULT '',
|
||||
token_hash CHAR(64) NOT NULL,
|
||||
state SMALLINT NOT NULL,
|
||||
expires_at DATETIME(3) NOT NULL,
|
||||
consumed_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_action_tokens_token(tenant_id, token_id),
|
||||
INDEX idx_im_action_tokens_user_action(tenant_id, user_id, action, target, state, expires_at),
|
||||
CONSTRAINT fk_im_action_tokens_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
)`); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := tx.Exec(
|
||||
`CREATE TABLE im_youth_mode_settings(
|
||||
tenant_id BIGINT NOT NULL,
|
||||
user_id BIGINT NOT NULL,
|
||||
purpose VARCHAR(64) NOT NULL,
|
||||
password_hash VARBINARY(255) NOT NULL,
|
||||
failed_attempts INT NOT NULL DEFAULT 0,
|
||||
locked_until 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(tenant_id, user_id, purpose),
|
||||
CONSTRAINT fk_im_youth_settings_tenant FOREIGN KEY(tenant_id) REFERENCES im_tenant(id) ON DELETE CASCADE
|
||||
)`)
|
||||
return err
|
||||
}
|
||||
|
||||
// Create system topic 'sys'.
|
||||
func createSystemTopic(tx *sql.Tx) error {
|
||||
now := t.TimeNow()
|
||||
@@ -1117,9 +1350,12 @@ func removeTags(tx *sqlx.Tx, table, keyName string, keyVal any, tags []string) e
|
||||
// UserCreate creates a new user. Returns error and true if error is due to duplicate user name,
|
||||
// false for any other error
|
||||
func (a *adapter) UserCreate(user *t.User) error {
|
||||
if user == nil || user.TenantID.IsZero() {
|
||||
if user == nil {
|
||||
return t.ErrMalformed
|
||||
}
|
||||
if user.TenantID.IsZero() {
|
||||
user.TenantID = defaultTenantID
|
||||
}
|
||||
ctx, cancel := a.getContextForTx()
|
||||
if cancel != nil {
|
||||
defer cancel()
|
||||
@@ -1955,9 +2191,13 @@ func (a *adapter) TopicCreate(topic *t.Topic) error {
|
||||
|
||||
// If undelete = true - update subscription on duplicate key, otherwise ignore the duplicate.
|
||||
func createSubscription(tx *sqlx.Tx, sub *t.Subscription, undelete bool) error {
|
||||
if sub == nil || sub.TenantID.IsZero() {
|
||||
if sub == nil {
|
||||
return t.ErrMalformed
|
||||
}
|
||||
tenantID := sub.TenantID
|
||||
if tenantID.IsZero() {
|
||||
tenantID = defaultTenantID
|
||||
}
|
||||
|
||||
isOwner := (sub.ModeGiven & sub.ModeWant).IsOwner()
|
||||
|
||||
@@ -1966,26 +2206,26 @@ func createSubscription(tx *sqlx.Tx, sub *t.Subscription, undelete bool) error {
|
||||
_, err := tx.Exec(
|
||||
"INSERT INTO subscriptions(tenant_id,createdat,updatedat,deletedat,userid,topic,modeWant,modeGiven,private) "+
|
||||
"VALUES(?,?,?,NULL,?,?,?,?,?)",
|
||||
sub.TenantID, sub.CreatedAt, sub.UpdatedAt, decoded_uid, sub.Topic, sub.ModeWant.String(), sub.ModeGiven.String(), jpriv)
|
||||
tenantID, sub.CreatedAt, sub.UpdatedAt, decoded_uid, sub.Topic, sub.ModeWant.String(), sub.ModeGiven.String(), jpriv)
|
||||
|
||||
if err != nil && isDupe(err) {
|
||||
if undelete {
|
||||
_, err = tx.Exec("UPDATE subscriptions SET createdat=?,updatedat=?,deletedat=NULL,modeWant=?,modeGiven=?,"+
|
||||
"delid=0,recvseqid=0,readseqid=0 WHERE tenant_id=? AND topic=? AND userid=?",
|
||||
sub.CreatedAt, sub.UpdatedAt, sub.ModeWant.String(), sub.ModeGiven.String(), sub.TenantID,
|
||||
sub.CreatedAt, sub.UpdatedAt, sub.ModeWant.String(), sub.ModeGiven.String(), tenantID,
|
||||
sub.Topic, decoded_uid)
|
||||
} else {
|
||||
_, err = tx.Exec("UPDATE subscriptions SET createdat=?,updatedat=?,deletedat=NULL,modeWant=?,modeGiven=?,"+
|
||||
"delid=0,recvseqid=0,readseqid=0,private=? WHERE tenant_id=? AND topic=? AND userid=?",
|
||||
sub.CreatedAt, sub.UpdatedAt, sub.ModeWant.String(), sub.ModeGiven.String(), jpriv,
|
||||
sub.TenantID, sub.Topic, decoded_uid)
|
||||
tenantID, sub.Topic, decoded_uid)
|
||||
}
|
||||
}
|
||||
|
||||
if err == nil && isOwner {
|
||||
// Update topic owner if the subscription is with owner rights.
|
||||
// Don't increment subscriber count here - it's done in TopicShare in bulk.
|
||||
_, err = tx.Exec("UPDATE topics SET owner=? WHERE tenant_id=? AND name=?", decoded_uid, sub.TenantID, sub.Topic)
|
||||
_, err = tx.Exec("UPDATE topics SET owner=? WHERE tenant_id=? AND name=?", decoded_uid, tenantID, sub.Topic)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user