修复 sqlite 兼容性问题

This commit is contained in:
xmdhs 2023-10-11 15:08:39 +08:00
parent 7c8fafc16e
commit 378afee54e
No known key found for this signature in database
GPG Key ID: E809D6D43DEFCC95
12 changed files with 156 additions and 6 deletions

View File

@ -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
View 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 }}

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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} />
} }

View File

@ -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
} }

View File

@ -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) {