Release v2.0.5 (#5033)
* add: generic cache random time offset expired. * bugfix: Csrf token should be Secure and httpOnly, but not now * fix: expose the Offset property to allow external modifications * improving the concurrency performance of random value calculation * add WithOffsetFunc to define private RandomExpireCache.offset field * fix: add seconds definition * build(deps): bump github.com/stretchr/testify from 1.7.1 to 1.8.0 Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.1 to 1.8.0. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.7.1...v1.8.0) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * fix 4907: force admin service http only * Feat: add get all tasks function (#4999) * feat: add get all tasks function * Refine Comments : admin/profile.go,bean/mock.go,config/global.go... (#5009) * Refine Comments * refine comments for cache.go * refine comments for log.go * Update orm.go * refine comments for orm_log.go,types.go * Update utils.go * Update doc.go * refine comments for for four files (#5011) * refine comments for cache.go * refine comments for log.go * Update orm.go * refine comments for orm_log.go,types.go * Update utils.go * Update doc.go * Update db.go * fix pass []any as any in variadic function by asasalint (#5012) * fix pass []any as any in variadic function * add change log * build(deps): bump go.opentelemetry.io/otel/trace from 1.7.0 to 1.8.0 (#5019) Bumps [go.opentelemetry.io/otel/trace](https://github.com/open-telemetry/opentelemetry-go) from 1.7.0 to 1.8.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.7.0...v1.8.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/trace dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * refine comments for package core (#5014) * Refine Comments * refine comments for cache.go * refine comments for log.go * Update orm.go * refine comments for orm_log.go,types.go * Update utils.go * Update doc.go * refine comments * refine comments * Update db.go * refine comments for core * build(deps): bump go.opentelemetry.io/otel/exporters/stdout/stdouttrace (#5018) Bumps [go.opentelemetry.io/otel/exporters/stdout/stdouttrace](https://github.com/open-telemetry/opentelemetry-go) from 1.7.0 to 1.8.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.7.0...v1.8.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/exporters/stdout/stdouttrace dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix 5022: Miss assiging ln to graceful Server (#5028) * prepare for releasing v2.0.5 (#5032) Co-authored-by: auual <ding@ibyte.me> Co-authored-by: Leon Ding <deen.job@qq.com> Co-authored-by: dada0z <zhang.guangda@qq.com> Co-authored-by: kevinzeng <kevinzeng@zego.im> Co-authored-by: Kevin Tsang <39397413+ktalg@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: 日暮颂歌1991 <448081525@qq.com> Co-authored-by: Regan Yue <1131625869@qq.com> Co-authored-by: alingse <alingse@foxmail.com>
This commit is contained in:
@@ -245,7 +245,7 @@ func Any(rootpath string, f FilterFunc) *App {
|
||||
// fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
|
||||
// }))
|
||||
func Handler(rootpath string, h http.Handler, options ...interface{}) *App {
|
||||
return (*App)(web.Handler(rootpath, h, options))
|
||||
return (*App)(web.Handler(rootpath, h, options...))
|
||||
}
|
||||
|
||||
// InsertFilter adds a FilterFunc with pattern condition and action constant.
|
||||
|
||||
16
adapter/cache/cache.go
vendored
16
adapter/cache/cache.go
vendored
@@ -47,23 +47,23 @@ import (
|
||||
// c.Incr("counter") // now is 2
|
||||
// count := c.Get("counter").(int)
|
||||
type Cache interface {
|
||||
// get cached value by key.
|
||||
// Get will get cached value by key.
|
||||
Get(key string) interface{}
|
||||
// GetMulti is a batch version of Get.
|
||||
GetMulti(keys []string) []interface{}
|
||||
// set cached value with key and expire time.
|
||||
// Put will set cached value with key and expire time.
|
||||
Put(key string, val interface{}, timeout time.Duration) error
|
||||
// delete cached value by key.
|
||||
// Delete will delete cached value by key.
|
||||
Delete(key string) error
|
||||
// increase cached int value by key, as a counter.
|
||||
// Incr will increase cached int value by key, as a counter.
|
||||
Incr(key string) error
|
||||
// decrease cached int value by key, as a counter.
|
||||
// Decr will decrease cached int value by key, as a counter.
|
||||
Decr(key string) error
|
||||
// check if cached value exists or not.
|
||||
// IsExist can check if cached value exists or not.
|
||||
IsExist(key string) bool
|
||||
// clear all cache.
|
||||
// ClearAll will clear all cache.
|
||||
ClearAll() error
|
||||
// start gc routine based on config string settings.
|
||||
// StartAndGC will start gc routine based on config string settings.
|
||||
StartAndGC(config string) error
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ func (ctx *Context) GetCookie(key string) string {
|
||||
// SetCookie Set cookie for response.
|
||||
// It's alias of BeegoOutput.Cookie.
|
||||
func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
|
||||
(*context.Context)(ctx).SetCookie(name, value, others)
|
||||
(*context.Context)(ctx).SetCookie(name, value, others...)
|
||||
}
|
||||
|
||||
// GetSecureCookie Get secure cookie from request by a given key.
|
||||
@@ -88,7 +88,7 @@ func (ctx *Context) GetSecureCookie(Secret, key string) (string, bool) {
|
||||
|
||||
// SetSecureCookie Set Secure cookie for response.
|
||||
func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interface{}) {
|
||||
(*context.Context)(ctx).SetSecureCookie(Secret, name, value, others)
|
||||
(*context.Context)(ctx).SetSecureCookie(Secret, name, value, others...)
|
||||
}
|
||||
|
||||
// XSRFToken creates a xsrf token string and returns.
|
||||
|
||||
@@ -47,7 +47,7 @@ func (output *BeegoOutput) Body(content []byte) error {
|
||||
// Cookie sets cookie value via given key.
|
||||
// others are ordered as cookie's max age time, path,domain, secure and httponly.
|
||||
func (output *BeegoOutput) Cookie(name string, value string, others ...interface{}) {
|
||||
(*context.BeegoOutput)(output).Cookie(name, value, others)
|
||||
(*context.BeegoOutput)(output).Cookie(name, value, others...)
|
||||
}
|
||||
|
||||
// JSON writes json to response body.
|
||||
|
||||
@@ -12,5 +12,5 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// used to keep compatible with v1.x
|
||||
// Package adapter used to keep compatible with v1.x
|
||||
package adapter
|
||||
|
||||
@@ -158,7 +158,7 @@ func (bl *BeeLogger) EnableFuncCallDepth(b bool) {
|
||||
(*logs.BeeLogger)(bl).EnableFuncCallDepth(b)
|
||||
}
|
||||
|
||||
// set prefix
|
||||
// SetPrefix will set prefix
|
||||
func (bl *BeeLogger) SetPrefix(s string) {
|
||||
(*logs.BeeLogger)(bl).SetPrefix(s)
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ func (d *DB) QueryContext(ctx context.Context, query string, args ...interface{}
|
||||
}
|
||||
|
||||
func (d *DB) QueryRow(query string, args ...interface{}) *sql.Row {
|
||||
return (*orm.DB)(d).QueryRow(query, args)
|
||||
return (*orm.DB)(d).QueryRow(query, args...)
|
||||
}
|
||||
|
||||
func (d *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build go1.8
|
||||
// +build go1.8
|
||||
|
||||
// Package orm provide ORM for MySQL/PostgreSQL/sqlite
|
||||
@@ -92,7 +93,7 @@ type ormer struct {
|
||||
|
||||
var _ Ormer = new(ormer)
|
||||
|
||||
// read data to model
|
||||
// Read read data to model
|
||||
func (o *ormer) Read(md interface{}, cols ...string) error {
|
||||
if o.isTx {
|
||||
return o.txDelegate.Read(md, cols...)
|
||||
@@ -100,7 +101,7 @@ func (o *ormer) Read(md interface{}, cols ...string) error {
|
||||
return o.delegate.Read(md, cols...)
|
||||
}
|
||||
|
||||
// read data to model, like Read(), but use "SELECT FOR UPDATE" form
|
||||
// ReadForUpdate read data to model, like Read(), but use "SELECT FOR UPDATE" form
|
||||
func (o *ormer) ReadForUpdate(md interface{}, cols ...string) error {
|
||||
if o.isTx {
|
||||
return o.txDelegate.ReadForUpdate(md, cols...)
|
||||
@@ -108,7 +109,7 @@ func (o *ormer) ReadForUpdate(md interface{}, cols ...string) error {
|
||||
return o.delegate.ReadForUpdate(md, cols...)
|
||||
}
|
||||
|
||||
// Try to read a row from the database, or insert one if it doesn't exist
|
||||
// ReadOrCreate Try to read a row from the database, or insert one if it doesn't exist
|
||||
func (o *ormer) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
|
||||
if o.isTx {
|
||||
return o.txDelegate.ReadOrCreate(md, col1, cols...)
|
||||
@@ -116,7 +117,7 @@ func (o *ormer) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool,
|
||||
return o.delegate.ReadOrCreate(md, col1, cols...)
|
||||
}
|
||||
|
||||
// insert model data to database
|
||||
// Insert will insert model data to database
|
||||
func (o *ormer) Insert(md interface{}) (int64, error) {
|
||||
if o.isTx {
|
||||
return o.txDelegate.Insert(md)
|
||||
@@ -124,7 +125,7 @@ func (o *ormer) Insert(md interface{}) (int64, error) {
|
||||
return o.delegate.Insert(md)
|
||||
}
|
||||
|
||||
// insert some models to database
|
||||
// InsertMulti will insert some models to database
|
||||
func (o *ormer) InsertMulti(bulk int, mds interface{}) (int64, error) {
|
||||
if o.isTx {
|
||||
return o.txDelegate.InsertMulti(bulk, mds)
|
||||
@@ -140,7 +141,7 @@ func (o *ormer) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int
|
||||
return o.delegate.InsertOrUpdate(md, colConflitAndArgs...)
|
||||
}
|
||||
|
||||
// update model to database.
|
||||
// Update will update model to database.
|
||||
// cols set the columns those want to update.
|
||||
func (o *ormer) Update(md interface{}, cols ...string) (int64, error) {
|
||||
if o.isTx {
|
||||
@@ -149,7 +150,7 @@ func (o *ormer) Update(md interface{}, cols ...string) (int64, error) {
|
||||
return o.delegate.Update(md, cols...)
|
||||
}
|
||||
|
||||
// delete model in database
|
||||
// Delete delete model in database
|
||||
// cols shows the delete conditions values read from. default is pk
|
||||
func (o *ormer) Delete(md interface{}, cols ...string) (int64, error) {
|
||||
if o.isTx {
|
||||
@@ -158,7 +159,7 @@ func (o *ormer) Delete(md interface{}, cols ...string) (int64, error) {
|
||||
return o.delegate.Delete(md, cols...)
|
||||
}
|
||||
|
||||
// create a models to models queryer
|
||||
// QueryM2M create a models to models queryer
|
||||
func (o *ormer) QueryM2M(md interface{}, name string) QueryM2Mer {
|
||||
if o.isTx {
|
||||
return o.txDelegate.QueryM2M(md, name)
|
||||
@@ -166,7 +167,7 @@ func (o *ormer) QueryM2M(md interface{}, name string) QueryM2Mer {
|
||||
return o.delegate.QueryM2M(md, name)
|
||||
}
|
||||
|
||||
// load related models to md model.
|
||||
// LoadRelated load related models to md model.
|
||||
// args are limit, offset int and order string.
|
||||
//
|
||||
// example:
|
||||
@@ -200,7 +201,7 @@ func (o *ormer) LoadRelated(md interface{}, name string, args ...interface{}) (i
|
||||
return o.delegate.LoadRelated(md, name, kvs...)
|
||||
}
|
||||
|
||||
// return a QuerySeter for table operations.
|
||||
// QueryTable return a QuerySeter for table operations.
|
||||
// table name can be string or struct.
|
||||
// e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)),
|
||||
func (o *ormer) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) {
|
||||
@@ -210,7 +211,7 @@ func (o *ormer) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) {
|
||||
return o.delegate.QueryTable(ptrStructOrTableName)
|
||||
}
|
||||
|
||||
// switch to another registered database driver by given name.
|
||||
// Using switch to another registered database driver by given name.
|
||||
func (o *ormer) Using(name string) error {
|
||||
if o.isTx {
|
||||
return ErrTxHasBegan
|
||||
@@ -219,7 +220,7 @@ func (o *ormer) Using(name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// begin transaction
|
||||
// Begin will begin transaction
|
||||
func (o *ormer) Begin() error {
|
||||
if o.isTx {
|
||||
return ErrTxHasBegan
|
||||
@@ -240,7 +241,7 @@ func (o *ormer) BeginTx(ctx context.Context, opts *sql.TxOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// commit transaction
|
||||
// Commit will commit transaction
|
||||
func (o *ormer) Commit() error {
|
||||
if !o.isTx {
|
||||
return ErrTxDone
|
||||
@@ -255,7 +256,7 @@ func (o *ormer) Commit() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// rollback transaction
|
||||
// Rollback will rollback transaction
|
||||
func (o *ormer) Rollback() error {
|
||||
if !o.isTx {
|
||||
return ErrTxDone
|
||||
@@ -270,7 +271,7 @@ func (o *ormer) Rollback() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// return a raw query seter for raw sql string.
|
||||
// Raw return a raw query seter for raw sql string.
|
||||
func (o *ormer) Raw(query string, args ...interface{}) RawSeter {
|
||||
if o.isTx {
|
||||
return o.txDelegate.Raw(query, args...)
|
||||
@@ -278,7 +279,7 @@ func (o *ormer) Raw(query string, args ...interface{}) RawSeter {
|
||||
return o.delegate.Raw(query, args...)
|
||||
}
|
||||
|
||||
// return current using database Driver
|
||||
// Driver return current using database Driver
|
||||
func (o *ormer) Driver() Driver {
|
||||
if o.isTx {
|
||||
return o.txDelegate.Driver()
|
||||
@@ -286,7 +287,7 @@ func (o *ormer) Driver() Driver {
|
||||
return o.delegate.Driver()
|
||||
}
|
||||
|
||||
// return sql.DBStats for current database
|
||||
// DBStats return sql.DBStats for current database
|
||||
func (o *ormer) DBStats() *sql.DBStats {
|
||||
if o.isTx {
|
||||
return o.txDelegate.DBStats()
|
||||
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
// Log implement the log.Logger
|
||||
type Log orm.Log
|
||||
|
||||
// costomer log func
|
||||
// LogFunc is costomer log func
|
||||
var LogFunc = orm.LogFunc
|
||||
|
||||
// NewLog set io.Writer to create a Logger.
|
||||
|
||||
@@ -35,7 +35,7 @@ type Fielder orm.Fielder
|
||||
|
||||
// Ormer define the orm interface
|
||||
type Ormer interface {
|
||||
// read data to model
|
||||
// Read read data to model
|
||||
// for example:
|
||||
// this will find User by Id field
|
||||
// u = &User{Id: user.Id}
|
||||
@@ -44,25 +44,25 @@ type Ormer interface {
|
||||
// u = &User{UserName: "astaxie", Password: "pass"}
|
||||
// err = Ormer.Read(u, "UserName")
|
||||
Read(md interface{}, cols ...string) error
|
||||
// Like Read(), but with "FOR UPDATE" clause, useful in transaction.
|
||||
// ReadForUpdate Like Read(), but with "FOR UPDATE" clause, useful in transaction.
|
||||
// Some databases are not support this feature.
|
||||
ReadForUpdate(md interface{}, cols ...string) error
|
||||
// Try to read a row from the database, or insert one if it doesn't exist
|
||||
// ReadOrCreate Try to read a row from the database, or insert one if it doesn't exist
|
||||
ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error)
|
||||
// insert model data to database
|
||||
// Insert will insert model data to database
|
||||
// for example:
|
||||
// user := new(User)
|
||||
// id, err = Ormer.Insert(user)
|
||||
// user must be a pointer and Insert will set user's pk field
|
||||
Insert(interface{}) (int64, error)
|
||||
// mysql:InsertOrUpdate(model) or InsertOrUpdate(model,"colu=colu+value")
|
||||
// InsertOrUpdate(model,"colu=colu+value") or mysql:InsertOrUpdate(model)
|
||||
// if colu type is integer : can use(+-*/), string : convert(colu,"value")
|
||||
// postgres: InsertOrUpdate(model,"conflictColumnName") or InsertOrUpdate(model,"conflictColumnName","colu=colu+value")
|
||||
// if colu type is integer : can use(+-*/), string : colu || "value"
|
||||
InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error)
|
||||
// insert some models to database
|
||||
// InsertMulti insert some models to database
|
||||
InsertMulti(bulk int, mds interface{}) (int64, error)
|
||||
// update model to database.
|
||||
// Update update model to database.
|
||||
// cols set the columns those want to update.
|
||||
// find model by Id(pk) field and update columns specified by fields, if cols is null then update all columns
|
||||
// for example:
|
||||
@@ -72,9 +72,9 @@ type Ormer interface {
|
||||
// user.Extra.Data = "orm"
|
||||
// num, err = Ormer.Update(&user, "Langs", "Extra")
|
||||
Update(md interface{}, cols ...string) (int64, error)
|
||||
// delete model in database
|
||||
// Delete delete model in database
|
||||
Delete(md interface{}, cols ...string) (int64, error)
|
||||
// load related models to md model.
|
||||
// LoadRelated load related models to md model.
|
||||
// args are limit, offset int and order string.
|
||||
//
|
||||
// example:
|
||||
@@ -87,25 +87,25 @@ type Ormer interface {
|
||||
// args[3] string order for example : "-Id"
|
||||
// make sure the relation is defined in model struct tags.
|
||||
LoadRelated(md interface{}, name string, args ...interface{}) (int64, error)
|
||||
// create a models to models queryer
|
||||
// QueryM2M create a models to models queryer
|
||||
// for example:
|
||||
// post := Post{Id: 4}
|
||||
// m2m := Ormer.QueryM2M(&post, "Tags")
|
||||
QueryM2M(md interface{}, name string) QueryM2Mer
|
||||
// return a QuerySeter for table operations.
|
||||
// QueryTable return a QuerySeter for table operations.
|
||||
// table name can be string or struct.
|
||||
// e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)),
|
||||
QueryTable(ptrStructOrTableName interface{}) QuerySeter
|
||||
// switch to another registered database driver by given name.
|
||||
Using(name string) error
|
||||
// begin transaction
|
||||
// Begin begin transaction
|
||||
// for example:
|
||||
// o := NewOrm()
|
||||
// err := o.Begin()
|
||||
// ...
|
||||
// err = o.Rollback()
|
||||
Begin() error
|
||||
// begin transaction with provided context and option
|
||||
// BeginTx begin transaction with provided context and option
|
||||
// the provided context is used until the transaction is committed or rolled back.
|
||||
// if the context is canceled, the transaction will be rolled back.
|
||||
// the provided TxOptions is optional and may be nil if defaults should be used.
|
||||
@@ -116,11 +116,11 @@ type Ormer interface {
|
||||
// ...
|
||||
// err = o.Rollback()
|
||||
BeginTx(ctx context.Context, opts *sql.TxOptions) error
|
||||
// commit transaction
|
||||
// Commit commit transaction
|
||||
Commit() error
|
||||
// rollback transaction
|
||||
// Rollback rollback transaction
|
||||
Rollback() error
|
||||
// return a raw query seter for raw sql string.
|
||||
// Raw return a raw query seter for raw sql string.
|
||||
// for example:
|
||||
// ormer.Raw("UPDATE `user` SET `user_name` = ? WHERE `user_name` = ?", "slene", "testing").Exec()
|
||||
// // update user testing's name to slene
|
||||
|
||||
@@ -246,7 +246,7 @@ func camelString(s string) string {
|
||||
|
||||
type argString []string
|
||||
|
||||
// get string by index from string slice
|
||||
// Get will get string by index from string slice
|
||||
func (a argString) Get(i int, args ...string) (r string) {
|
||||
if i >= 0 && i < len(a) {
|
||||
r = a[i]
|
||||
@@ -258,7 +258,7 @@ func (a argString) Get(i int, args ...string) (r string) {
|
||||
|
||||
type argInt []int
|
||||
|
||||
// get int by index from int slice
|
||||
// Get will get int by index from int slice
|
||||
func (a argInt) Get(i int, args ...int) (r int) {
|
||||
if i >= 0 && i < len(a) {
|
||||
r = a[i]
|
||||
@@ -269,13 +269,13 @@ func (a argInt) Get(i int, args ...int) (r int) {
|
||||
return
|
||||
}
|
||||
|
||||
// parse time to string with location
|
||||
// timeParse parse time to string with location
|
||||
func timeParse(dateString, format string) (time.Time, error) {
|
||||
tp, err := time.ParseInLocation(format, dateString, DefaultTimeLoc)
|
||||
return tp, err
|
||||
}
|
||||
|
||||
// get pointer indirect type
|
||||
// indirectType get pointer indirect type
|
||||
func indirectType(v reflect.Type) reflect.Type {
|
||||
switch v.Kind() {
|
||||
case reflect.Ptr:
|
||||
|
||||
@@ -212,7 +212,7 @@ func (p *ControllerRegister) AddMethod(method, pattern string, f FilterFunc) {
|
||||
|
||||
// Handler add user defined Handler
|
||||
func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ...interface{}) {
|
||||
(*web.ControllerRegister)(p).Handler(pattern, h, options)
|
||||
(*web.ControllerRegister)(p).Handler(pattern, h, options...)
|
||||
}
|
||||
|
||||
// AddAuto router to ControllerRegister.
|
||||
|
||||
Reference in New Issue
Block a user