Add various deleted flags to entities | Add active to subscriptions | Add DeleteUser && DeleteChannel endpoints [skip-tests]
All checks were successful
Build Docker and Deploy / Run Unit-Tests (push) Has been skipped
Build Docker and Deploy / Build Docker Container (push) Successful in 43s
Build Docker and Deploy / Deploy to Server (push) Successful in 16s

This commit is contained in:
2025-04-13 16:12:15 +02:00
parent aac34ef738
commit 8c0f0e3e8f
47 changed files with 2453 additions and 243 deletions

View File

@@ -10,6 +10,7 @@ type Channel struct {
TimestampCreated SCNTime `db:"timestamp_created" json:"timestamp_created"`
TimestampLastSent *SCNTime `db:"timestamp_lastsent" json:"timestamp_lastsent"`
MessagesSent int `db:"messages_sent" json:"messages_sent"`
Deleted bool `db:"deleted" json:"-"`
}
type ChannelWithSubscription struct {

View File

@@ -19,6 +19,7 @@ type Delivery struct {
RetryCount int `db:"retry_count" json:"retry_count"`
NextDelivery *SCNTime `db:"next_delivery" json:"next_delivery"`
FCMMessageID *string `db:"fcm_message_id" json:"fcm_message_id"`
Deleted bool `db:"deleted" json:"-"`
}
func (d Delivery) MaxRetryCount() int {

View File

@@ -5,7 +5,7 @@ package models
import "gogs.mikescher.com/BlackForestBytes/goext/langext"
import "gogs.mikescher.com/BlackForestBytes/goext/enums"
const ChecksumEnumGenerator = "a1b9c4807e1cec4ea2a8b19cd447aa4b47c13f8058a12470dff8eeec895ad8f8" // GoExtVersion: 0.0.513
const ChecksumEnumGenerator = "7585f93c9270c25db0e367d668827c6ae89b309b6fd2b3d1aaf7f7016b07e0b8" // GoExtVersion: 0.0.513
// ================================ ClientType ================================
//

View File

@@ -15,7 +15,7 @@ import "reflect"
import "regexp"
import "strings"
const ChecksumCharsetIDGenerator = "a1b9c4807e1cec4ea2a8b19cd447aa4b47c13f8058a12470dff8eeec895ad8f8" // GoExtVersion: 0.0.513
const ChecksumCharsetIDGenerator = "7585f93c9270c25db0e367d668827c6ae89b309b6fd2b3d1aaf7f7016b07e0b8" // GoExtVersion: 0.0.513
const idlen = 24

View File

@@ -80,6 +80,7 @@ type KeyToken struct {
Token string `db:"token" json:"token" jsonfilter:"INCLUDE_TOKEN"`
Permissions TokenPermissionList `db:"permissions" json:"permissions"`
MessagesSent int `db:"messages_sent" json:"messages_sent"`
Deleted bool `db:"deleted" json:"-"`
}
type KeyTokenPreview struct {

View File

@@ -13,10 +13,11 @@ const (
type Message struct {
MessageID MessageID `db:"message_id" json:"message_id"`
SenderUserID UserID `db:"sender_user_id" json:"sender_user_id"` // user that sent the message (this is also the owner of the channel that contains it)
ChannelInternalName string `db:"channel_internal_name" json:"channel_internal_name"`
ChannelID ChannelID `db:"channel_id" json:"channel_id"`
SenderName *string `db:"sender_name" json:"sender_name"`
SenderUserID UserID `db:"sender_user_id" json:"sender_user_id"` // user that sent the message (this is also the owner of the channel that contains it)
ChannelInternalName string `db:"channel_internal_name" json:"channel_internal_name"` //
ChannelOwnerUserID UserID `db:"channel_owner_user_id" json:"channel_owner_user_id"` // user that owns the channel
ChannelID ChannelID `db:"channel_id" json:"channel_id"` //
SenderName *string `db:"sender_name" json:"sender_name"` //
SenderIP string `db:"sender_ip" json:"sender_ip"`
TimestampReal SCNTime `db:"timestamp_real" json:"-"`
TimestampClient *SCNTime `db:"timestamp_client" json:"-"`

View File

@@ -14,60 +14,59 @@ import (
)
type MessageFilter struct {
ConfirmedSubscriptionBy *UserID
SearchStringFTS *[]string
SearchStringPlain *[]string
Sender *[]UserID
ChannelNameCS *[]string // case-sensitive
ChannelNameCI *[]string // case-insensitive
ChannelID *[]ChannelID
SenderNameCS *[]string // case-sensitive
SenderNameCI *[]string // case-insensitive
HasSenderName *bool
SenderIP *[]string
TimestampCoalesce *time.Time
TimestampCoalesceAfter *time.Time
TimestampCoalesceBefore *time.Time
TimestampReal *time.Time
TimestampRealAfter *time.Time
TimestampRealBefore *time.Time
TimestampClient *time.Time
TimestampClientAfter *time.Time
TimestampClientBefore *time.Time
TitleCS *string // case-sensitive
TitleCI *string // case-insensitive
Priority *[]int
UserMessageID *[]string
OnlyDeleted bool
IncludeDeleted bool
CompatAcknowledged *bool
UsedKeyID *[]KeyTokenID
ConfirmedAndActiveSubscriptionBy *UserID
SearchStringFTS *[]string
SearchStringPlain *[]string
Sender *[]UserID
ChannelNameCS *[]string // case-sensitive
ChannelNameCI *[]string // case-insensitive
ChannelID *[]ChannelID
SenderNameCS *[]string // case-sensitive
SenderNameCI *[]string // case-insensitive
HasSenderName *bool
SenderIP *[]string
TimestampCoalesce *time.Time
TimestampCoalesceAfter *time.Time
TimestampCoalesceBefore *time.Time
TimestampReal *time.Time
TimestampRealAfter *time.Time
TimestampRealBefore *time.Time
TimestampClient *time.Time
TimestampClientAfter *time.Time
TimestampClientBefore *time.Time
TitleCS *string // case-sensitive
TitleCI *string // case-insensitive
Priority *[]int
UserMessageID *[]string
OnlyDeleted bool
IncludeDeleted bool
CompatAcknowledged *bool
UsedKeyID *[]KeyTokenID
}
func (f MessageFilter) SQL() (string, string, sq.PP, error) {
params := sq.PP{}
joinClause := ""
if f.ConfirmedSubscriptionBy != nil {
joinClause += " LEFT JOIN subscriptions AS subs on messages.channel_id = subs.channel_id "
if f.ConfirmedAndActiveSubscriptionBy != nil {
joinClause += fmt.Sprintf(" LEFT JOIN subscriptions AS subs ON (messages.channel_id = subs.channel_id AND subs.subscriber_user_id = :%s AND subs.confirmed=1 AND subs.active=1 AND subs.deleted=0) ", params.Add(*f.ConfirmedAndActiveSubscriptionBy))
}
if f.SearchStringFTS != nil {
joinClause += " JOIN messages_fts AS mfts on (mfts.rowid = messages.rowid) "
joinClause += " JOIN messages_fts AS mfts ON (mfts.rowid = messages.rowid) "
}
sqlClauses := make([]string, 0)
params := sq.PP{}
if f.OnlyDeleted {
sqlClauses = append(sqlClauses, "(deleted=1)")
sqlClauses = append(sqlClauses, "(messages.deleted=1)")
} else if f.IncludeDeleted {
// nothing, return all
} else {
sqlClauses = append(sqlClauses, "(deleted=0)") // default
sqlClauses = append(sqlClauses, "(messages.deleted=0)") // default
}
if f.ConfirmedSubscriptionBy != nil {
sqlClauses = append(sqlClauses, fmt.Sprintf("(subs.subscriber_user_id = :%s AND subs.confirmed = 1)", params.Add(*f.ConfirmedSubscriptionBy)))
if f.ConfirmedAndActiveSubscriptionBy != nil {
sqlClauses = append(sqlClauses, "(subs.confirmed=1 AND subs.active=1 AND subs.deleted=0)")
}
if f.Sender != nil {

View File

@@ -8,11 +8,13 @@ package models
// (use keytokens for write-access)
type Subscription struct {
SubscriptionID SubscriptionID `db:"subscription_id" json:"subscription_id"`
SubscriberUserID UserID `db:"subscriber_user_id" json:"subscriber_user_id"`
ChannelOwnerUserID UserID `db:"channel_owner_user_id" json:"channel_owner_user_id"`
ChannelID ChannelID `db:"channel_id" json:"channel_id"`
ChannelInternalName string `db:"channel_internal_name" json:"channel_internal_name"`
TimestampCreated SCNTime `db:"timestamp_created" json:"timestamp_created"`
Confirmed bool `db:"confirmed" json:"confirmed"`
SubscriptionID SubscriptionID `db:"subscription_id" json:"subscription_id"` //
SubscriberUserID UserID `db:"subscriber_user_id" json:"subscriber_user_id"` //
ChannelOwnerUserID UserID `db:"channel_owner_user_id" json:"channel_owner_user_id"` //
ChannelID ChannelID `db:"channel_id" json:"channel_id"` //
ChannelInternalName string `db:"channel_internal_name" json:"channel_internal_name"` //
TimestampCreated SCNTime `db:"timestamp_created" json:"timestamp_created"` //
Confirmed bool `db:"confirmed" json:"confirmed"` // Channel-Owner confirmed subscription
Active bool `db:"active" json:"active"` // Subscriber has activated the subscription (default)
Deleted bool `db:"deleted" json:"-"` //
}

View File

@@ -19,6 +19,7 @@ type SubscriptionFilter struct {
ChannelOwnerUserID2 *[]UserID // Used to filter <ChannelOwnerUserID> again
ChannelID *[]ChannelID
Confirmed *bool
Active *bool
SubscriberIsChannelOwner *bool
Timestamp *time.Time
TimestampAfter *time.Time
@@ -33,6 +34,8 @@ func (f SubscriptionFilter) SQL() (string, string, sq.PP, error) {
params := sq.PP{}
sqlClauses = append(sqlClauses, "(deleted=0)")
if f.AnyUserID != nil {
sqlClauses = append(sqlClauses, fmt.Sprintf("(subscriber_user_id = :%s OR channel_owner_user_id = :%s)", params.Add(*f.AnyUserID), params.Add(*f.AnyUserID)))
}
@@ -85,6 +88,14 @@ func (f SubscriptionFilter) SQL() (string, string, sq.PP, error) {
}
}
if f.Active != nil {
if *f.Active {
sqlClauses = append(sqlClauses, "(active=1)")
} else {
sqlClauses = append(sqlClauses, "(active=0)")
}
}
if f.SubscriberIsChannelOwner != nil {
if *f.SubscriberIsChannelOwner {
sqlClauses = append(sqlClauses, "(subscriber_user_id = channel_owner_user_id)")

View File

@@ -15,6 +15,7 @@ type User struct {
QuotaUsedDay *string `db:"quota_used_day" json:"-"`
IsPro bool `db:"is_pro" json:"is_pro"`
ProToken *string `db:"pro_token" json:"-"`
Deleted bool `db:"deleted" json:"-"`
UserExtra `db:"-"` // fields that are not in DB and are set on PreMarshal
}