mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
updating channel model for consistency with topics
This commit is contained in:
parent
31bb532470
commit
c6653f126b
57
doc/api.oa3
57
doc/api.oa3
@ -2395,43 +2395,6 @@ paths:
|
|||||||
'500':
|
'500':
|
||||||
description: internal server error
|
description: internal server error
|
||||||
|
|
||||||
/content/channels/{channelId}/topics/{topicId}/count:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- content
|
|
||||||
description: Get count of associated taghs.
|
|
||||||
operationId: get-channel-topic-count
|
|
||||||
security:
|
|
||||||
- bearerAuth: []
|
|
||||||
parameters:
|
|
||||||
- name: channelId
|
|
||||||
in: path
|
|
||||||
description: specified channel id
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
- name: topicId
|
|
||||||
in: path
|
|
||||||
description: specified topic id
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: success
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/TagCount'
|
|
||||||
'401':
|
|
||||||
description: invalid password
|
|
||||||
'404':
|
|
||||||
description: channel not found
|
|
||||||
'410':
|
|
||||||
description: account disabled
|
|
||||||
'500':
|
|
||||||
description: internal server error
|
|
||||||
|
|
||||||
/content/channels/{channelId}/topics/{topicId}/subject/{field}:
|
/content/channels/{channelId}/topics/{topicId}/subject/{field}:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -3253,10 +3216,14 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- detailRevision
|
- detailRevision
|
||||||
|
- topicRevision
|
||||||
properties:
|
properties:
|
||||||
detailRevision:
|
detailRevision:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
topicRevision:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
channelDetail:
|
channelDetail:
|
||||||
$ref: '#/components/schemas/ChannelDetail'
|
$ref: '#/components/schemas/ChannelDetail'
|
||||||
|
|
||||||
@ -3324,8 +3291,6 @@ components:
|
|||||||
format: int64
|
format: int64
|
||||||
topicDetail:
|
topicDetail:
|
||||||
$ref: '#/components/schemas/TopicDetail'
|
$ref: '#/components/schemas/TopicDetail'
|
||||||
topicTags::
|
|
||||||
$ref: '#/components/schemas/TagCount'
|
|
||||||
|
|
||||||
TopicDetail:
|
TopicDetail:
|
||||||
type: object
|
type: object
|
||||||
@ -3356,19 +3321,6 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
enum: [ complete, incomplete ]
|
enum: [ complete, incomplete ]
|
||||||
|
|
||||||
TagCount:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- count
|
|
||||||
- updated
|
|
||||||
properties:
|
|
||||||
count:
|
|
||||||
type: integer
|
|
||||||
format: int32
|
|
||||||
updated:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
|
|
||||||
Tag:
|
Tag:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
@ -3642,3 +3594,4 @@ components:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@ func AddChannel(w http.ResponseWriter, r *http.Request) {
|
|||||||
channel := &store.Channel{}
|
channel := &store.Channel{}
|
||||||
channel.Data = subject.Data
|
channel.Data = subject.Data
|
||||||
channel.DataType = subject.DataType
|
channel.DataType = subject.DataType
|
||||||
|
channel.DetailRevision = account.ChannelRevision + 1
|
||||||
|
channel.TopicRevision = account.ChannelRevision + 1
|
||||||
if res := tx.Save(channel).Error; res != nil {
|
if res := tx.Save(channel).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,6 @@ func AddChannelTopic(w http.ResponseWriter, r *http.Request) {
|
|||||||
topic.TopicSlotID = topicSlot.ID
|
topic.TopicSlotID = topicSlot.ID
|
||||||
topic.Data = subject.Data
|
topic.Data = subject.Data
|
||||||
topic.DataType = subject.DataType
|
topic.DataType = subject.DataType
|
||||||
topic.TagCount = 0
|
|
||||||
topic.Guid = guid
|
topic.Guid = guid
|
||||||
topic.DetailRevision = act.ChannelRevision + 1
|
topic.DetailRevision = act.ChannelRevision + 1
|
||||||
topic.TagRevision = act.ChannelRevision + 1
|
topic.TagRevision = act.ChannelRevision + 1
|
||||||
@ -56,6 +55,9 @@ func AddChannelTopic(w http.ResponseWriter, r *http.Request) {
|
|||||||
topicSlot.Topic = topic
|
topicSlot.Topic = topic
|
||||||
|
|
||||||
// update parent revision
|
// update parent revision
|
||||||
|
if res := tx.Model(&channelSlot.Channel).Update("topic_revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -130,6 +130,9 @@ func AddChannelTopicAsset(w http.ResponseWriter, r *http.Request) {
|
|||||||
if res := tx.Model(&topicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&topicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
if res := tx.Model(&channelSlot.Channel).Update("topic_revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package databag
|
package databag
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
@ -68,18 +67,15 @@ func AddChannelTopicTag(w http.ResponseWriter, r *http.Request) {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
if res := tx.Model(&topicSlot.Topic).Update("tag_count", len(topicSlot.Topic.Tags) + 1).Error; res != nil {
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
if res := tx.Model(&topicSlot.Topic).Update("tag_updated", time.Now().Unix()).Error; res != nil {
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
if res := tx.Model(&topicSlot.Topic).Update("tag_revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&topicSlot.Topic).Update("tag_revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
if res := tx.Model(&topicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&topicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
if res := tx.Model(&channelSlot.Channel).Update("topic_revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
package databag
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
"databag/internal/store"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetChannelTopicCount(w http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
// scan parameters
|
|
||||||
params := mux.Vars(r)
|
|
||||||
topicId := params["topicId"]
|
|
||||||
|
|
||||||
var subject Subject
|
|
||||||
if err := ParseRequest(r, w, &subject); err != nil {
|
|
||||||
ErrResponse(w, http.StatusBadRequest, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
channelSlot, _, err, code := getChannelSlot(r, false)
|
|
||||||
if err != nil {
|
|
||||||
ErrResponse(w, code, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// load topic
|
|
||||||
var topicSlot store.TopicSlot
|
|
||||||
if err = store.DB.Where("channel_id = ? AND topic_slot_id = ?", channelSlot.Channel.ID, topicId).First(&topicSlot).Error; err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
code = http.StatusNotFound
|
|
||||||
} else {
|
|
||||||
code = http.StatusInternalServerError
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteResponse(w, getTopicCountModel(&topicSlot))
|
|
||||||
}
|
|
||||||
|
|
@ -64,6 +64,9 @@ func RemoveChannelTopic(w http.ResponseWriter, r *http.Request) {
|
|||||||
if res := tx.Model(&topicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&topicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
if res := tx.Model(&channelSlot.Channel).Update("topic_revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,9 @@ func RemoveChannelTopicAsset(w http.ResponseWriter, r *http.Request) {
|
|||||||
if res := tx.Model(&asset.Topic.TopicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&asset.Topic.TopicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
if res := tx.Model(&channelSlot.Channel).Update("topic_revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package databag
|
package databag
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -74,16 +73,13 @@ func RemoveChannelTopicTag(w http.ResponseWriter, r *http.Request) {
|
|||||||
if res := tx.Model(&tag.TagSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&tag.TagSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
if res := tx.Model(&topicSlot.Topic).Update("tag_count", len(topicSlot.Topic.Tags)).Error; res != nil {
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
if res := tx.Model(&topicSlot.Topic).Update("tag_revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&topicSlot.Topic).Update("tag_revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
if res := tx.Model(&topicSlot.Topic).Update("tag_updated", time.Now().Unix()).Error; res != nil {
|
if res := tx.Model(&topicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
if res := tx.Model(&topicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&channelSlot.Channel).Update("topic_revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
|
@ -53,6 +53,9 @@ func SetChannelTopicConfirmed(w http.ResponseWriter, r *http.Request) {
|
|||||||
if res := tx.Model(&topicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&topicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
if res := tx.Model(&channelSlot.Channel).Update("topic_revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,9 @@ func SetChannelTopicSubject(w http.ResponseWriter, r *http.Request) {
|
|||||||
if res := tx.Model(&topicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&topicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
if res := tx.Model(&channelSlot.Channel).Update("topic_revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package databag
|
package databag
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -71,10 +70,10 @@ func SetChannelTopicTagSubject(w http.ResponseWriter, r *http.Request) {
|
|||||||
if res := tx.Model(&tagSlot.Tag.Topic).Update("tag_revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&tagSlot.Tag.Topic).Update("tag_revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
if res := tx.Model(&tagSlot.Tag.Topic).Update("tag_updated", time.Now().Unix()).Error; res != nil {
|
if res := tx.Model(&tagSlot.Tag.Topic.TopicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
if res := tx.Model(&tagSlot.Tag.Topic.TopicSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&channelSlot.Channel).Update("topic_revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
if res := tx.Model(&channelSlot).Update("revision", act.ChannelRevision + 1).Error; res != nil {
|
||||||
|
@ -258,18 +258,6 @@ func getTopicDetailModel(slot *store.TopicSlot) *TopicDetail {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTopicCountModel(slot *store.TopicSlot) *TagCount {
|
|
||||||
|
|
||||||
if slot.Topic == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &TagCount{
|
|
||||||
Count: slot.Topic.TagCount,
|
|
||||||
Updated: slot.Topic.TagUpdated,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTopicModel(slot *store.TopicSlot) *Topic {
|
func getTopicModel(slot *store.TopicSlot) *Topic {
|
||||||
|
|
||||||
if slot.Topic == nil {
|
if slot.Topic == nil {
|
||||||
@ -286,7 +274,6 @@ func getTopicModel(slot *store.TopicSlot) *Topic {
|
|||||||
DetailRevision: slot.Topic.DetailRevision,
|
DetailRevision: slot.Topic.DetailRevision,
|
||||||
TopicDetail: getTopicDetailModel(slot),
|
TopicDetail: getTopicDetailModel(slot),
|
||||||
TagRevision: slot.Topic.TagRevision,
|
TagRevision: slot.Topic.TagRevision,
|
||||||
TopicTags: getTopicCountModel(slot),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,6 +158,8 @@ type ChannelData struct {
|
|||||||
|
|
||||||
DetailRevision int64 `json:"detailRevision"`
|
DetailRevision int64 `json:"detailRevision"`
|
||||||
|
|
||||||
|
TopicRevision int64 `json:"topicRevision"`
|
||||||
|
|
||||||
ChannelDetail *ChannelDetail `json:"channelDetail,omitempty"`
|
ChannelDetail *ChannelDetail `json:"channelDetail,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,13 +370,6 @@ type Tag struct {
|
|||||||
Data *TagData `json:"data"`
|
Data *TagData `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TagCount struct {
|
|
||||||
|
|
||||||
Count int32 `json:"count"`
|
|
||||||
|
|
||||||
Updated int64 `json:"updated"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type TagData struct {
|
type TagData struct {
|
||||||
|
|
||||||
Guid string `json:"guid"`
|
Guid string `json:"guid"`
|
||||||
@ -404,8 +399,6 @@ type TopicData struct {
|
|||||||
TagRevision int64 `json:"tagRevision"`
|
TagRevision int64 `json:"tagRevision"`
|
||||||
|
|
||||||
TopicDetail *TopicDetail `json:"topicDetail,omitempty"`
|
TopicDetail *TopicDetail `json:"topicDetail,omitempty"`
|
||||||
|
|
||||||
TopicTags *TagCount `json:"topicTags:,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TopicDetail struct {
|
type TopicDetail struct {
|
||||||
|
@ -579,13 +579,6 @@ var routes = Routes{
|
|||||||
GetChannelTopicDetail,
|
GetChannelTopicDetail,
|
||||||
},
|
},
|
||||||
|
|
||||||
Route{
|
|
||||||
"GetChannelTopicCount",
|
|
||||||
strings.ToUpper("Get"),
|
|
||||||
"/content/channels/{channelId}/topics/{topicId}/count",
|
|
||||||
GetChannelTopicCount,
|
|
||||||
},
|
|
||||||
|
|
||||||
Route{
|
Route{
|
||||||
"GetChannelTopicSubjectField",
|
"GetChannelTopicSubjectField",
|
||||||
strings.ToUpper("Get"),
|
strings.ToUpper("Get"),
|
||||||
|
@ -195,6 +195,7 @@ type ChannelSlot struct {
|
|||||||
|
|
||||||
type Channel struct {
|
type Channel struct {
|
||||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||||
|
TopicRevision int64 `gorm:"not null"`
|
||||||
DetailRevision int64 `gorm:"not null"`
|
DetailRevision int64 `gorm:"not null"`
|
||||||
DataType string `gorm:"index"`
|
DataType string `gorm:"index"`
|
||||||
Data string
|
Data string
|
||||||
@ -228,8 +229,6 @@ type Topic struct {
|
|||||||
Status string `gorm:"not null;index"`
|
Status string `gorm:"not null;index"`
|
||||||
Created int64 `gorm:"autoCreateTime"`
|
Created int64 `gorm:"autoCreateTime"`
|
||||||
Updated int64 `gorm:"autoUpdateTime"`
|
Updated int64 `gorm:"autoUpdateTime"`
|
||||||
TagCount int32 `gorm:"not null"`
|
|
||||||
TagUpdated int64
|
|
||||||
TagRevision int64 `gorm:"not null"`
|
TagRevision int64 `gorm:"not null"`
|
||||||
Channel *Channel
|
Channel *Channel
|
||||||
Assets []Asset
|
Assets []Asset
|
||||||
|
@ -520,8 +520,6 @@ func (a *TestApp) UpdateApp(rev *Revision) {
|
|||||||
a.mutex.Lock()
|
a.mutex.Lock()
|
||||||
defer a.mutex.Unlock()
|
defer a.mutex.Unlock()
|
||||||
|
|
||||||
PrintMsg(rev)
|
|
||||||
|
|
||||||
if rev.Profile != a.revision.Profile {
|
if rev.Profile != a.revision.Profile {
|
||||||
if err := a.UpdateProfile(); err != nil {
|
if err := a.UpdateProfile(); err != nil {
|
||||||
PrintMsg(err)
|
PrintMsg(err)
|
||||||
|
Loading…
Reference in New Issue
Block a user