修复 sqlite 兼容性问题
This commit is contained in:
parent
7c8fafc16e
commit
378afee54e
@ -37,5 +37,5 @@ type Cache struct {
|
|||||||
type Captcha struct {
|
type Captcha struct {
|
||||||
Type string `yaml:"type"`
|
Type string `yaml:"type"`
|
||||||
SiteKey string `yaml:"siteKey"`
|
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
|
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,
|
Unique: false,
|
||||||
Columns: []*schema.Column{UserProfilesColumns[3]},
|
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.
|
// UserTexturesColumns holds the columns for the "user_textures" table.
|
||||||
|
@ -739,6 +739,26 @@ func (tq *TextureQuery) ForShare(opts ...sql.LockOption) *TextureQuery {
|
|||||||
return tq
|
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.
|
// TextureGroupBy is the group-by builder for Texture entities.
|
||||||
type TextureGroupBy struct {
|
type TextureGroupBy struct {
|
||||||
selector
|
selector
|
||||||
|
@ -694,6 +694,26 @@ func (uq *UserQuery) ForShare(opts ...sql.LockOption) *UserQuery {
|
|||||||
return uq
|
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.
|
// UserGroupBy is the group-by builder for User entities.
|
||||||
type UserGroupBy struct {
|
type UserGroupBy struct {
|
||||||
selector
|
selector
|
||||||
|
@ -739,6 +739,26 @@ func (upq *UserProfileQuery) ForShare(opts ...sql.LockOption) *UserProfileQuery
|
|||||||
return upq
|
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.
|
// UserProfileGroupBy is the group-by builder for UserProfile entities.
|
||||||
type UserProfileGroupBy struct {
|
type UserProfileGroupBy struct {
|
||||||
selector
|
selector
|
||||||
|
@ -626,6 +626,26 @@ func (utq *UserTextureQuery) ForShare(opts ...sql.LockOption) *UserTextureQuery
|
|||||||
return utq
|
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.
|
// UserTextureGroupBy is the group-by builder for UserTexture entities.
|
||||||
type UserTextureGroupBy struct {
|
type UserTextureGroupBy struct {
|
||||||
selector
|
selector
|
||||||
|
@ -559,6 +559,26 @@ func (utq *UserTokenQuery) ForShare(opts ...sql.LockOption) *UserTokenQuery {
|
|||||||
return utq
|
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.
|
// UserTokenGroupBy is the group-by builder for UserToken entities.
|
||||||
type UserTokenGroupBy struct {
|
type UserTokenGroupBy struct {
|
||||||
selector
|
selector
|
||||||
|
@ -44,7 +44,7 @@ const CaptchaWidget = forwardRef<refType, prop>(({ onSuccess }, ref) => {
|
|||||||
console.warn(error)
|
console.warn(error)
|
||||||
return <Alert severity="warning">{String(error)}</Alert>
|
return <Alert severity="warning">{String(error)}</Alert>
|
||||||
}
|
}
|
||||||
if (loading) {
|
if (!data && loading) {
|
||||||
return <Skeleton variant="rectangular" width={300} height={65} />
|
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)
|
p, s := utils.Argon2ID(u.Password)
|
||||||
|
|
||||||
err = utils.WithTx(ctx, w.client, func(tx *ent.Tx) error {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if count != 0 {
|
if count != 0 {
|
||||||
return ErrExistUser
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ func CreateToken(ctx context.Context, u *ent.User, client *ent.Client, cache cac
|
|||||||
var utoken *ent.UserToken
|
var utoken *ent.UserToken
|
||||||
err := utils.WithTx(ctx, client, func(tx *ent.Tx) error {
|
err := utils.WithTx(ctx, client, func(tx *ent.Tx) error {
|
||||||
var err 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 {
|
if err != nil {
|
||||||
var nf *ent.NotFoundError
|
var nf *ent.NotFoundError
|
||||||
if !errors.As(err, &nf) {
|
if !errors.As(err, &nf) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user