修复 sqlite 兼容性问题
This commit is contained in:
parent
7c8fafc16e
commit
378afee54e
@ -37,5 +37,5 @@ type Cache struct {
|
||||
type Captcha struct {
|
||||
Type string `yaml:"type"`
|
||||
SiteKey string `yaml:"siteKey"`
|
||||
Secret string `yaml:"ecret"`
|
||||
Secret string `yaml:"secret"`
|
||||
}
|
||||
|
40
db/ent/for_update.tmpl
Normal file
40
db/ent/for_update.tmpl
Normal file
@ -0,0 +1,40 @@
|
||||
{{/*
|
||||
Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
This source code is licensed under the Apache 2.0 license found
|
||||
in the LICENSE file in the root directory of this source tree.
|
||||
*/}}
|
||||
|
||||
{{/* gotype: entgo.io/ent/entc/gen.Type */}}
|
||||
|
||||
{{/* Templates used by the "sql/lock" feature-flag to add "SELECT ... FOR UPDATE/SHARE" capabilities. */}}
|
||||
|
||||
{{ define "dialect/sql/query/additional/locking_sqlite" }}
|
||||
{{ if $.FeatureEnabled "sql/lock" }}
|
||||
{{ template "helper/sqlock_sqlite" $ }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ define "helper/sqlock_sqlite" }}
|
||||
{{ $builder := pascal $.Scope.Builder }}
|
||||
{{ $receiver := receiver $builder }}
|
||||
|
||||
// ForUpdate locks the selected rows against concurrent updates, and prevent them from being
|
||||
// updated, deleted or "selected ... for update" by other sessions, until the transaction is
|
||||
// either committed or rolled-back.
|
||||
func ({{ $receiver }} *{{ $builder }}) ForUpdateA(opts ...sql.LockOption) *{{ $builder }} {
|
||||
if {{ $receiver }}.driver.Dialect() == dialect.SQLite {
|
||||
return {{ $receiver }}
|
||||
}
|
||||
return {{ $receiver }}.ForUpdate(opts...)
|
||||
}
|
||||
|
||||
// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock
|
||||
// on any rows that are read. Other sessions can read the rows, but cannot modify them
|
||||
// until your transaction commits.
|
||||
func ({{ $receiver }} *{{ $builder }}) ForShareA(opts ...sql.LockOption) *{{ $builder }} {
|
||||
if {{ $receiver }}.driver.Dialect() == dialect.SQLite {
|
||||
return {{ $receiver }}
|
||||
}
|
||||
return {{ $receiver }}.ForShare(opts...)
|
||||
}
|
||||
{{ end }}
|
@ -1,3 +1,3 @@
|
||||
package ent
|
||||
|
||||
//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate --feature sql/lock ./schema
|
||||
//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate --feature sql/lock --template for_update.tmpl ./schema
|
||||
|
@ -89,6 +89,16 @@ var (
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{UserProfilesColumns[3]},
|
||||
},
|
||||
{
|
||||
Name: "userprofile_name",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{UserProfilesColumns[1]},
|
||||
},
|
||||
{
|
||||
Name: "userprofile_uuid",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{UserProfilesColumns[2]},
|
||||
},
|
||||
},
|
||||
}
|
||||
// UserTexturesColumns holds the columns for the "user_textures" table.
|
||||
|
@ -739,6 +739,26 @@ func (tq *TextureQuery) ForShare(opts ...sql.LockOption) *TextureQuery {
|
||||
return tq
|
||||
}
|
||||
|
||||
// ForUpdate locks the selected rows against concurrent updates, and prevent them from being
|
||||
// updated, deleted or "selected ... for update" by other sessions, until the transaction is
|
||||
// either committed or rolled-back.
|
||||
func (tq *TextureQuery) ForUpdateA(opts ...sql.LockOption) *TextureQuery {
|
||||
if tq.driver.Dialect() == dialect.SQLite {
|
||||
return tq
|
||||
}
|
||||
return tq.ForUpdate(opts...)
|
||||
}
|
||||
|
||||
// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock
|
||||
// on any rows that are read. Other sessions can read the rows, but cannot modify them
|
||||
// until your transaction commits.
|
||||
func (tq *TextureQuery) ForShareA(opts ...sql.LockOption) *TextureQuery {
|
||||
if tq.driver.Dialect() == dialect.SQLite {
|
||||
return tq
|
||||
}
|
||||
return tq.ForShare(opts...)
|
||||
}
|
||||
|
||||
// TextureGroupBy is the group-by builder for Texture entities.
|
||||
type TextureGroupBy struct {
|
||||
selector
|
||||
|
@ -694,6 +694,26 @@ func (uq *UserQuery) ForShare(opts ...sql.LockOption) *UserQuery {
|
||||
return uq
|
||||
}
|
||||
|
||||
// ForUpdate locks the selected rows against concurrent updates, and prevent them from being
|
||||
// updated, deleted or "selected ... for update" by other sessions, until the transaction is
|
||||
// either committed or rolled-back.
|
||||
func (uq *UserQuery) ForUpdateA(opts ...sql.LockOption) *UserQuery {
|
||||
if uq.driver.Dialect() == dialect.SQLite {
|
||||
return uq
|
||||
}
|
||||
return uq.ForUpdate(opts...)
|
||||
}
|
||||
|
||||
// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock
|
||||
// on any rows that are read. Other sessions can read the rows, but cannot modify them
|
||||
// until your transaction commits.
|
||||
func (uq *UserQuery) ForShareA(opts ...sql.LockOption) *UserQuery {
|
||||
if uq.driver.Dialect() == dialect.SQLite {
|
||||
return uq
|
||||
}
|
||||
return uq.ForShare(opts...)
|
||||
}
|
||||
|
||||
// UserGroupBy is the group-by builder for User entities.
|
||||
type UserGroupBy struct {
|
||||
selector
|
||||
|
@ -739,6 +739,26 @@ func (upq *UserProfileQuery) ForShare(opts ...sql.LockOption) *UserProfileQuery
|
||||
return upq
|
||||
}
|
||||
|
||||
// ForUpdate locks the selected rows against concurrent updates, and prevent them from being
|
||||
// updated, deleted or "selected ... for update" by other sessions, until the transaction is
|
||||
// either committed or rolled-back.
|
||||
func (upq *UserProfileQuery) ForUpdateA(opts ...sql.LockOption) *UserProfileQuery {
|
||||
if upq.driver.Dialect() == dialect.SQLite {
|
||||
return upq
|
||||
}
|
||||
return upq.ForUpdate(opts...)
|
||||
}
|
||||
|
||||
// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock
|
||||
// on any rows that are read. Other sessions can read the rows, but cannot modify them
|
||||
// until your transaction commits.
|
||||
func (upq *UserProfileQuery) ForShareA(opts ...sql.LockOption) *UserProfileQuery {
|
||||
if upq.driver.Dialect() == dialect.SQLite {
|
||||
return upq
|
||||
}
|
||||
return upq.ForShare(opts...)
|
||||
}
|
||||
|
||||
// UserProfileGroupBy is the group-by builder for UserProfile entities.
|
||||
type UserProfileGroupBy struct {
|
||||
selector
|
||||
|
@ -626,6 +626,26 @@ func (utq *UserTextureQuery) ForShare(opts ...sql.LockOption) *UserTextureQuery
|
||||
return utq
|
||||
}
|
||||
|
||||
// ForUpdate locks the selected rows against concurrent updates, and prevent them from being
|
||||
// updated, deleted or "selected ... for update" by other sessions, until the transaction is
|
||||
// either committed or rolled-back.
|
||||
func (utq *UserTextureQuery) ForUpdateA(opts ...sql.LockOption) *UserTextureQuery {
|
||||
if utq.driver.Dialect() == dialect.SQLite {
|
||||
return utq
|
||||
}
|
||||
return utq.ForUpdate(opts...)
|
||||
}
|
||||
|
||||
// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock
|
||||
// on any rows that are read. Other sessions can read the rows, but cannot modify them
|
||||
// until your transaction commits.
|
||||
func (utq *UserTextureQuery) ForShareA(opts ...sql.LockOption) *UserTextureQuery {
|
||||
if utq.driver.Dialect() == dialect.SQLite {
|
||||
return utq
|
||||
}
|
||||
return utq.ForShare(opts...)
|
||||
}
|
||||
|
||||
// UserTextureGroupBy is the group-by builder for UserTexture entities.
|
||||
type UserTextureGroupBy struct {
|
||||
selector
|
||||
|
@ -559,6 +559,26 @@ func (utq *UserTokenQuery) ForShare(opts ...sql.LockOption) *UserTokenQuery {
|
||||
return utq
|
||||
}
|
||||
|
||||
// ForUpdate locks the selected rows against concurrent updates, and prevent them from being
|
||||
// updated, deleted or "selected ... for update" by other sessions, until the transaction is
|
||||
// either committed or rolled-back.
|
||||
func (utq *UserTokenQuery) ForUpdateA(opts ...sql.LockOption) *UserTokenQuery {
|
||||
if utq.driver.Dialect() == dialect.SQLite {
|
||||
return utq
|
||||
}
|
||||
return utq.ForUpdate(opts...)
|
||||
}
|
||||
|
||||
// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock
|
||||
// on any rows that are read. Other sessions can read the rows, but cannot modify them
|
||||
// until your transaction commits.
|
||||
func (utq *UserTokenQuery) ForShareA(opts ...sql.LockOption) *UserTokenQuery {
|
||||
if utq.driver.Dialect() == dialect.SQLite {
|
||||
return utq
|
||||
}
|
||||
return utq.ForShare(opts...)
|
||||
}
|
||||
|
||||
// UserTokenGroupBy is the group-by builder for UserToken entities.
|
||||
type UserTokenGroupBy struct {
|
||||
selector
|
||||
|
@ -44,7 +44,7 @@ const CaptchaWidget = forwardRef<refType, prop>(({ onSuccess }, ref) => {
|
||||
console.warn(error)
|
||||
return <Alert severity="warning">{String(error)}</Alert>
|
||||
}
|
||||
if (loading) {
|
||||
if (!data && loading) {
|
||||
return <Skeleton variant="rectangular" width={300} height={65} />
|
||||
}
|
||||
|
||||
|
@ -51,14 +51,14 @@ func (w *WebService) Reg(ctx context.Context, u model.UserReg, ipPrefix, ip stri
|
||||
p, s := utils.Argon2ID(u.Password)
|
||||
|
||||
err = utils.WithTx(ctx, w.client, func(tx *ent.Tx) error {
|
||||
count, err := tx.User.Query().Where(user.EmailEQ(u.Email)).ForUpdate().Count(ctx)
|
||||
count, err := tx.User.Query().Where(user.EmailEQ(u.Email)).ForUpdateA().Count(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count != 0 {
|
||||
return ErrExistUser
|
||||
}
|
||||
nameCount, err := tx.UserProfile.Query().Where(userprofile.NameEQ(u.Name)).ForUpdate().Count(ctx)
|
||||
nameCount, err := tx.UserProfile.Query().Where(userprofile.NameEQ(u.Name)).ForUpdateA().Count(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ func CreateToken(ctx context.Context, u *ent.User, client *ent.Client, cache cac
|
||||
var utoken *ent.UserToken
|
||||
err := utils.WithTx(ctx, client, func(tx *ent.Tx) error {
|
||||
var err error
|
||||
utoken, err = tx.User.QueryToken(u).ForUpdate().First(ctx)
|
||||
utoken, err = tx.User.QueryToken(u).ForUpdateA().First(ctx)
|
||||
if err != nil {
|
||||
var nf *ent.NotFoundError
|
||||
if !errors.As(err, &nf) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user