From 93c25b61c64fe9bd75e002b958871eda4a379a39 Mon Sep 17 00:00:00 2001 From: ivamp Date: Fri, 6 Dec 2024 23:38:22 +0800 Subject: [PATCH] update --- README.md | 2 +- cmd/grpc.go | 1 - cmd/wire.go | 4 +- cmd/wire_gen.go | 22 +- configs/config.go | 3 - configs/rbac_model.conf | 19 - go.mod | 3 + go.sum | 12 + hack/gorm-gen/gorm.go | 7 +- internal/api/grpc/interceptor/auth.go | 29 +- internal/api/http/middleware/auth.go | 41 +- internal/api/http/middleware/rbac.go | 24 +- internal/api/http/provider.go | 2 +- internal/api/http/v1/test.go | 23 +- internal/base/app.go | 6 +- internal/base/conf/rbac_model.go | 9 - internal/base/server/error.go | 49 ++ internal/base/server/http.go | 11 +- internal/consts/auth.go | 31 - internal/consts/rbac.go | 9 - internal/consts/router.go | 7 - internal/dao/block_chunks.gen.go | 530 ++++++++++++++ internal/dao/collections.gen.go | 478 ++++++++++++ internal/dao/document_blocks.gen.go | 518 +++++++++++++ internal/dao/documents.gen.go | 678 ++++++++++++++++++ internal/dao/gen.go | 64 +- internal/dao/users.gen.go | 392 ---------- internal/dao/workspace_members.gen.go | 474 ++++++++++++ internal/dao/workspaces.gen.go | 400 +++++++++++ internal/database/migrations/1_setup.sql | 84 ++- .../2_add_parent_id_to_documents.sql | 7 + internal/entity/Collection.go | 19 + internal/entity/Document.go | 55 ++ internal/entity/Model.go | 8 +- internal/entity/User.go | 10 - internal/entity/Workspace.go | 29 + internal/pkg/validator/validator.go | 64 ++ internal/router/api.go | 4 +- internal/schema/jwt.go | 12 - internal/{service => services}/auth/auth.go | 33 +- .../{service => services}/auth/provider.go | 2 +- .../jwks/auth_refresh.go | 0 internal/{service => services}/jwks/jwks.go | 0 internal/{service => services}/provider.go | 8 +- .../{service => services}/stream/consumer.go | 0 .../{service => services}/stream/kafka.go | 0 .../{service => services}/stream/producer.go | 4 +- .../{service => services}/stream/provider.go | 0 internal/types/constants/auth.go | 20 + internal/types/constants/rbac.go | 9 + .../response/http.go => types/dto/dto.go} | 39 +- internal/{schema => types/dto}/entity.go | 2 +- internal/types/dto/test_request.go | 5 + .../{schema => types/dto}/user_response.go | 6 +- internal/types/errs/auth.go | 15 + internal/types/errs/error.go | 7 + internal/{consts => types/errs}/model.go | 3 +- internal/types/errs/router.go | 10 + internal/types/errs/validation.go | 7 + internal/{schema => types/events}/stream.go | 2 +- internal/{pkg => types}/user/user.go | 3 + 61 files changed, 3681 insertions(+), 634 deletions(-) delete mode 100644 configs/rbac_model.conf delete mode 100644 internal/base/conf/rbac_model.go create mode 100644 internal/base/server/error.go delete mode 100644 internal/consts/auth.go delete mode 100644 internal/consts/rbac.go delete mode 100644 internal/consts/router.go create mode 100644 internal/dao/block_chunks.gen.go create mode 100644 internal/dao/collections.gen.go create mode 100644 internal/dao/document_blocks.gen.go create mode 100644 internal/dao/documents.gen.go delete mode 100644 internal/dao/users.gen.go create mode 100644 internal/dao/workspace_members.gen.go create mode 100644 internal/dao/workspaces.gen.go create mode 100644 internal/database/migrations/2_add_parent_id_to_documents.sql create mode 100644 internal/entity/Collection.go create mode 100644 internal/entity/Document.go delete mode 100644 internal/entity/User.go create mode 100644 internal/entity/Workspace.go create mode 100644 internal/pkg/validator/validator.go delete mode 100644 internal/schema/jwt.go rename internal/{service => services}/auth/auth.go (67%) rename internal/{service => services}/auth/provider.go (87%) rename internal/{service => services}/jwks/auth_refresh.go (100%) rename internal/{service => services}/jwks/jwks.go (100%) rename internal/{service => services}/provider.go (71%) rename internal/{service => services}/stream/consumer.go (100%) rename internal/{service => services}/stream/kafka.go (100%) rename internal/{service => services}/stream/producer.go (97%) rename internal/{service => services}/stream/provider.go (100%) create mode 100644 internal/types/constants/auth.go create mode 100644 internal/types/constants/rbac.go rename internal/{api/http/response/http.go => types/dto/dto.go} (76%) rename internal/{schema => types/dto}/entity.go (95%) create mode 100644 internal/types/dto/test_request.go rename internal/{schema => types/dto}/user_response.go (73%) create mode 100644 internal/types/errs/auth.go create mode 100644 internal/types/errs/error.go rename internal/{consts => types/errs}/model.go (56%) create mode 100644 internal/types/errs/router.go create mode 100644 internal/types/errs/validation.go rename internal/{schema => types/events}/stream.go (96%) rename internal/{pkg => types}/user/user.go (96%) diff --git a/README.md b/README.md index 3dae0ea..f23a881 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# go-template +# leafdev.top/Leaf/leaf-library-3 diff --git a/cmd/grpc.go b/cmd/grpc.go index 9391ded..3899cca 100644 --- a/cmd/grpc.go +++ b/cmd/grpc.go @@ -26,7 +26,6 @@ var documentServiceCommand = &cobra.Command{ app, err := CreateApp() if err != nil { panic(err) - return } lis, err := net.Listen("tcp", app.Config.Grpc.Address) diff --git a/cmd/wire.go b/cmd/wire.go index 9951cb9..8a27b07 100644 --- a/cmd/wire.go +++ b/cmd/wire.go @@ -16,7 +16,7 @@ import ( "leafdev.top/Leaf/leaf-library-3/internal/batch" "leafdev.top/Leaf/leaf-library-3/internal/dao" "leafdev.top/Leaf/leaf-library-3/internal/router" - "leafdev.top/Leaf/leaf-library-3/internal/service" + "leafdev.top/Leaf/leaf-library-3/internal/services" "github.com/google/wire" ) @@ -30,7 +30,7 @@ var ProviderSet = wire.NewSet( s3.NewS3, milvus.NewService, batch.NewBatch, - service.Provide, + services.Provide, api.Provide, router.Provide, server.NewHTTPServer, diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index fe0510d..9ec1a9d 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -25,10 +25,10 @@ import ( "leafdev.top/Leaf/leaf-library-3/internal/batch" "leafdev.top/Leaf/leaf-library-3/internal/dao" "leafdev.top/Leaf/leaf-library-3/internal/router" - "leafdev.top/Leaf/leaf-library-3/internal/service" - "leafdev.top/Leaf/leaf-library-3/internal/service/auth" - "leafdev.top/Leaf/leaf-library-3/internal/service/jwks" - "leafdev.top/Leaf/leaf-library-3/internal/service/stream" + "leafdev.top/Leaf/leaf-library-3/internal/services" + "leafdev.top/Leaf/leaf-library-3/internal/services/auth" + "leafdev.top/Leaf/leaf-library-3/internal/services/jwks" + "leafdev.top/Leaf/leaf-library-3/internal/services/stream" ) // Injectors from wire.go: @@ -37,31 +37,31 @@ func CreateApp() (*base.Application, error) { config := conf.NewConfig() loggerLogger := logger.NewZapLogger(config) jwksJWKS := jwks.NewJWKS(config, loggerLogger) - authService := auth.NewService(config, jwksJWKS, loggerLogger) - userController := v1.NewUserController(authService) + service := auth.NewService(config, jwksJWKS, loggerLogger) + userController := v1.NewUserController(service) handlers := http.NewHandler(userController) - middleware := http.NewMiddleware(config, loggerLogger, authService) + middleware := http.NewMiddleware(config, loggerLogger, service) routerApi := router.NewApiRoute(handlers, middleware) swaggerRouter := router.NewSwaggerRoute() httpServer := server.NewHTTPServer(config, routerApi, swaggerRouter, middleware, loggerLogger) db := orm.NewGORM(config, loggerLogger) query := dao.NewQuery(db) handler := documents.NewHandler(query) - interceptorAuth := interceptor.NewAuth(authService, loggerLogger, config) + interceptorAuth := interceptor.NewAuth(service, loggerLogger, config) interceptorLogger := interceptor.NewLogger(loggerLogger) grpcInterceptor := grpc.NewInterceptor(interceptorAuth, interceptorLogger) grpcHandlers := grpc.NewHandler(handler, grpcInterceptor) apiApi := api.NewApi(grpcHandlers, handlers) streamService := stream.NewService(config) - serviceService := service.NewService(loggerLogger, jwksJWKS, authService, streamService) + servicesService := services.NewService(loggerLogger, jwksJWKS, service, streamService) redisRedis := redis.NewRedis(config) batchBatch := batch.NewBatch(loggerLogger) s3S3 := s3.NewS3(config) client := milvus.NewService(config, loggerLogger) - application := base.NewApplication(config, httpServer, apiApi, loggerLogger, serviceService, redisRedis, batchBatch, s3S3, db, query, client) + application := base.NewApplication(config, httpServer, apiApi, loggerLogger, servicesService, redisRedis, batchBatch, s3S3, db, query, client) return application, nil } // wire.go: -var ProviderSet = wire.NewSet(conf.NewConfig, logger.NewZapLogger, orm.NewGORM, dao.NewQuery, redis.NewRedis, s3.NewS3, milvus.NewService, batch.NewBatch, service.Provide, api.Provide, router.Provide, server.NewHTTPServer, base.NewApplication) +var ProviderSet = wire.NewSet(conf.NewConfig, logger.NewZapLogger, orm.NewGORM, dao.NewQuery, redis.NewRedis, s3.NewS3, milvus.NewService, batch.NewBatch, services.Provide, api.Provide, router.Provide, server.NewHTTPServer, base.NewApplication) diff --git a/configs/config.go b/configs/config.go index 681f6bf..bc2ad64 100644 --- a/configs/config.go +++ b/configs/config.go @@ -4,6 +4,3 @@ import _ "embed" //go:embed config.yaml var Config []byte - -//go:embed rbac_model.conf -var RBACModel []byte diff --git a/configs/rbac_model.conf b/configs/rbac_model.conf deleted file mode 100644 index 10027a5..0000000 --- a/configs/rbac_model.conf +++ /dev/null @@ -1,19 +0,0 @@ -# Request definition 即为请求定义,代表了可以传入什么样的参数来确定权限 -[request_definition] -r = sub, obj, act - -# Policy definition 代表了规则的组成 -[policy_definition] -p = sub, obj, act - -# g 是一个 RBAC系统, _, _表示角色继承关系的前项和后项,即前项继承后项角色的权限 -[role_definition] -g = _, _ - -# Policy effect 则表示什么样的规则可以被允许, e = some(where (p.eft == allow)) 这句就表示当前请求中包含的任何一个规则被允许的话,这个权限就会被允许 -[policy_effect] -e = some(where (p.eft == allow)) - -# 是策略匹配程序的定义。表示请求与规则是如何起作用的 -[matchers] -m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act diff --git a/go.mod b/go.mod index 2cec6d0..4b1ac18 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/gofiber/swagger v1.1.0 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/wire v0.6.0 + github.com/gookit/validate v1.5.2 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 github.com/milvus-io/milvus-sdk-go/v2 v2.4.2 @@ -60,6 +61,8 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/gookit/filter v1.2.1 // indirect + github.com/gookit/goutil v0.6.15 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect diff --git a/go.sum b/go.sum index 481ff0f..23b6d66 100644 --- a/go.sum +++ b/go.sum @@ -134,6 +134,14 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= +github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= +github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= +github.com/gookit/filter v1.2.1 h1:37XivkBm2E5qe1KaGdJ5ZfF5l9NYdGWfLEeQadJD8O4= +github.com/gookit/filter v1.2.1/go.mod h1:rxynQFr793x+XDwnRmJFEb53zDw0Zqx3OD7TXWoR9mQ= +github.com/gookit/goutil v0.6.15 h1:mMQ0ElojNZoyPD0eVROk5QXJPh2uKR4g06slgPDF5Jo= +github.com/gookit/goutil v0.6.15/go.mod h1:qdKdYEHQdEtyH+4fNdQNZfJHhI0jUZzHxQVAV3DaMDY= +github.com/gookit/validate v1.5.2 h1:i5I2OQ7WYHFRPRATGu9QarR9snnNHydvwSuHXaRWAV0= +github.com/gookit/validate v1.5.2/go.mod h1:yuPy2WwDlwGRa06fFJ5XIO8QEwhRnTC2LmxmBa5SE14= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= @@ -336,6 +344,8 @@ github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -456,6 +466,8 @@ golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= +golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= diff --git a/hack/gorm-gen/gorm.go b/hack/gorm-gen/gorm.go index 46a0f4e..fa2ec85 100644 --- a/hack/gorm-gen/gorm.go +++ b/hack/gorm-gen/gorm.go @@ -25,7 +25,12 @@ func main() { //g.UseDB(app.GORM) g.ApplyBasic( - entity.User{}, + entity.Workspace{}, + entity.WorkspaceMember{}, + entity.Collection{}, + entity.Document{}, + entity.DocumentBlock{}, + entity.BlockChunk{}, ) // Generate Type Safe API with Dynamic SQL defined on Querier interface for `model.User` and `model.Company` diff --git a/internal/api/grpc/interceptor/auth.go b/internal/api/grpc/interceptor/auth.go index 7d996a4..ced97a3 100644 --- a/internal/api/grpc/interceptor/auth.go +++ b/internal/api/grpc/interceptor/auth.go @@ -3,14 +3,15 @@ package interceptor import ( "context" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "google.golang.org/grpc" "leafdev.top/Leaf/leaf-library-3/internal/base/conf" "leafdev.top/Leaf/leaf-library-3/internal/base/logger" - "leafdev.top/Leaf/leaf-library-3/internal/consts" - "leafdev.top/Leaf/leaf-library-3/internal/schema" - auth2 "leafdev.top/Leaf/leaf-library-3/internal/service/auth" + authService "leafdev.top/Leaf/leaf-library-3/internal/services/auth" + "leafdev.top/Leaf/leaf-library-3/internal/types/constants" + "leafdev.top/Leaf/leaf-library-3/internal/types/errs" + + authInterceptor "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth" + "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" + "google.golang.org/grpc" ) var ignoreAuthApis = map[string]bool{ @@ -22,13 +23,13 @@ var ignoreAuthApis = map[string]bool{ } type Auth struct { - authService *auth2.Service + authService *authService.Service logger *logger.Logger config *conf.Config } func NewAuth( - authService *auth2.Service, + authService *authService.Service, logger *logger.Logger, config *conf.Config, ) *Auth { @@ -58,7 +59,7 @@ func (a *Auth) authCtx(ctx context.Context) (context.Context, error) { var tokenString string var err error - tokenString, err = auth.AuthFromMD(ctx, "bearer") + tokenString, err = authInterceptor.AuthFromMD(ctx, "bearer") if err != nil { // 如果是调试模式,就不处理报错,并且继续执行 if a.config.Debug.Enabled { @@ -69,17 +70,17 @@ func (a *Auth) authCtx(ctx context.Context) (context.Context, error) { } } - token, err := a.authService.AuthFromToken(schema.JWTIDToken, tokenString) + token, err := a.authService.AuthFromToken(constants.JwtTokenTypeIDToken, tokenString) if err != nil { return nil, err } if !token.Valid { - return nil, consts.ErrNotValidToken + return nil, errs.NotValidToken } - ctx = logging.InjectFields(ctx, logging.Fields{consts.AuthMiddlewareKey, token.Token.Sub}) - ctx = context.WithValue(ctx, consts.AuthMiddlewareKey, token) + ctx = logging.InjectFields(ctx, logging.Fields{constants.AuthMiddlewareKey, token.Token.Sub}) + ctx = context.WithValue(ctx, constants.AuthMiddlewareKey, token) return ctx, nil } @@ -134,7 +135,7 @@ func (a *Auth) StreamJWTAuth() grpc.StreamServerInterceptor { // return nil, err // } // -// token, err := a.authService.AuthFromToken(schema.JWTIDToken, tokenString) +// token, err := a.authService.AuthFromToken(constants.JwtTokenTypeIDToken, tokenString) // if err != nil { // return nil, err // } diff --git a/internal/api/http/middleware/auth.go b/internal/api/http/middleware/auth.go index d1ace79..04693cc 100644 --- a/internal/api/http/middleware/auth.go +++ b/internal/api/http/middleware/auth.go @@ -5,23 +5,24 @@ import ( "slices" "strings" - "github.com/gofiber/fiber/v2" - "leafdev.top/Leaf/leaf-library-3/internal/api/http/response" "leafdev.top/Leaf/leaf-library-3/internal/base/conf" - "leafdev.top/Leaf/leaf-library-3/internal/consts" - "leafdev.top/Leaf/leaf-library-3/internal/pkg/user" - "leafdev.top/Leaf/leaf-library-3/internal/schema" - "leafdev.top/Leaf/leaf-library-3/internal/service/auth" + authService "leafdev.top/Leaf/leaf-library-3/internal/services/auth" + "leafdev.top/Leaf/leaf-library-3/internal/types/constants" + "leafdev.top/Leaf/leaf-library-3/internal/types/dto" + "leafdev.top/Leaf/leaf-library-3/internal/types/errs" + authType "leafdev.top/Leaf/leaf-library-3/internal/types/user" + + "github.com/gofiber/fiber/v2" ) type Auth struct { config *conf.Config - authService *auth.Service + authService *authService.Service } var audienceLength int -func NewAuth(config *conf.Config, authService *auth.Service) *Auth { +func NewAuth(config *conf.Config, authService *authService.Service) *Auth { audienceLength = len(config.App.AllowedAudiences) return &Auth{ @@ -32,37 +33,37 @@ func NewAuth(config *conf.Config, authService *auth.Service) *Auth { func (a *Auth) Handler() fiber.Handler { return func(c *fiber.Ctx) error { - var r = response.Ctx(c) + var r = dto.Ctx(c) var err error - var token = new(user.User) + var token = new(authType.User) if a.config.Debug.Enabled { - token, err = a.authService.AuthFromToken(schema.JWTAccessToken, "") + token, err = a.authService.AuthFromToken(constants.JwtTokenTypeAccessToken, "") if err != nil { return r.Error(err).Send() } - c.Locals(consts.AuthMiddlewareKey, token) + c.Locals(constants.AuthMiddlewareKey, token) return c.Next() } - authorization := c.Get(consts.AuthHeader) + authorization := c.Get(constants.AuthHeader) if authorization == "" { - return r.Error(consts.ErrJWTFormatError).Send() + return r.Error(errs.JWTFormatError).Send() } authSplit := strings.Split(authorization, " ") if len(authSplit) != 2 { - return r.Error(consts.ErrJWTFormatError).Send() + return r.Error(errs.JWTFormatError).Send() } - if authSplit[0] != consts.AuthPrefix { - return r.Error(consts.ErrNotBearerType).Send() + if authSplit[0] != constants.AuthPrefix { + return r.Error(errs.NotBearerType).Send() } - token, err = a.authService.AuthFromToken(schema.JWTIDToken, authSplit[1]) + token, err = a.authService.AuthFromToken(constants.JwtTokenTypeIDToken, authSplit[1]) if err != nil { return r.Error(err).Status(http.StatusUnauthorized).Send() @@ -75,11 +76,11 @@ func (a *Auth) Handler() fiber.Handler { if audienceLength > 0 { // 检测 aud if !slices.Contains(a.config.App.AllowedAudiences, token.Token.Aud) { - return r.Error(consts.ErrNotValidToken).Send() + return r.Error(errs.NotValidToken).Send() } } - c.Locals(consts.AuthMiddlewareKey, token) + c.Locals(constants.AuthMiddlewareKey, token) return c.Next() } diff --git a/internal/api/http/middleware/rbac.go b/internal/api/http/middleware/rbac.go index 8b33042..ae9b768 100644 --- a/internal/api/http/middleware/rbac.go +++ b/internal/api/http/middleware/rbac.go @@ -6,10 +6,10 @@ import ( "strings" "github.com/gofiber/fiber/v2" - "leafdev.top/Leaf/leaf-library-3/internal/api/http/response" "leafdev.top/Leaf/leaf-library-3/internal/base/conf" - userPkg "leafdev.top/Leaf/leaf-library-3/internal/pkg/user" - "leafdev.top/Leaf/leaf-library-3/internal/service/auth" + "leafdev.top/Leaf/leaf-library-3/internal/services/auth" + "leafdev.top/Leaf/leaf-library-3/internal/types/dto" + userPkg "leafdev.top/Leaf/leaf-library-3/internal/types/user" ) type RBAC struct { @@ -21,11 +21,11 @@ func (m *RBAC) RoutePermission() fiber.Handler { return func(c *fiber.Ctx) error { user, ok := m.authService.GetUserSafe(c) if !ok { - return response.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() + return dto.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() } if !user.Valid { - return response.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() + return dto.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() } var path = cleanPath(c.Path()) @@ -35,7 +35,7 @@ func (m *RBAC) RoutePermission() fiber.Handler { pass := user.HasPermissions(permissionName) if !pass { - return response.Ctx(c). + return dto.Ctx(c). Message(fmt.Sprintf("permission denied, permission name: %s", permissionName)). Error(nil). Status(http.StatusForbidden). @@ -50,11 +50,11 @@ func (m *RBAC) RequirePermissions(permissions ...string) fiber.Handler { return func(c *fiber.Ctx) error { user, ok := m.authService.GetUserSafe(c) if !ok { - return response.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() + return dto.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() } if !user.Valid { - return response.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() + return dto.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() } var pass = true @@ -72,7 +72,7 @@ func (m *RBAC) RequirePermissions(permissions ...string) fiber.Handler { } if !pass { - return response.Ctx(c). + return dto.Ctx(c). Message(fmt.Sprintf("permission denied, required permissions: %s, failed permission: %s", permissions, failedPermissionName)). Error(nil). @@ -88,11 +88,11 @@ func (m *RBAC) RequireRoles(roles ...string) fiber.Handler { return func(c *fiber.Ctx) error { user, ok := m.authService.GetUserSafe(c) if !ok { - return response.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() + return dto.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() } if !user.Valid { - return response.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() + return dto.Ctx(c).Error(nil).Status(http.StatusUnauthorized).Send() } var pass = true @@ -110,7 +110,7 @@ func (m *RBAC) RequireRoles(roles ...string) fiber.Handler { } if !pass { - return response.Ctx(c). + return dto.Ctx(c). Message(fmt.Sprintf("permission denied, required roles: %s, failed role %s", roles, failedRoleName)). Error(nil). Status(http.StatusForbidden). diff --git a/internal/api/http/provider.go b/internal/api/http/provider.go index 38702a7..0b5424c 100644 --- a/internal/api/http/provider.go +++ b/internal/api/http/provider.go @@ -7,7 +7,7 @@ import ( v1 "leafdev.top/Leaf/leaf-library-3/internal/api/http/v1" "leafdev.top/Leaf/leaf-library-3/internal/base/conf" "leafdev.top/Leaf/leaf-library-3/internal/base/logger" - "leafdev.top/Leaf/leaf-library-3/internal/service/auth" + "leafdev.top/Leaf/leaf-library-3/internal/services/auth" ) type IMiddleware interface { diff --git a/internal/api/http/v1/test.go b/internal/api/http/v1/test.go index 8c1d3cc..7a4dedd 100644 --- a/internal/api/http/v1/test.go +++ b/internal/api/http/v1/test.go @@ -4,9 +4,9 @@ import ( "net/http" "github.com/gofiber/fiber/v2" - "leafdev.top/Leaf/leaf-library-3/internal/api/http/response" - "leafdev.top/Leaf/leaf-library-3/internal/schema" - "leafdev.top/Leaf/leaf-library-3/internal/service/auth" + "leafdev.top/Leaf/leaf-library-3/internal/pkg/validator" + "leafdev.top/Leaf/leaf-library-3/internal/services/auth" + "leafdev.top/Leaf/leaf-library-3/internal/types/dto" ) type UserController struct { @@ -31,7 +31,20 @@ func NewUserController(authService *auth.Service) *UserController { func (u *UserController) Test(c *fiber.Ctx) error { user := u.authService.GetUser(c) - var currentUserResponse = &schema.CurrentUserResponse{ + // bind + var testRequest = &dto.TestRequest{} + err := c.QueryParser(testRequest) + if err != nil { + return err + } + + // 验证 + validationErrors, err := validator.Struct(testRequest) + if err != nil { + return dto.Ctx(c).Error(err).Data(validationErrors).Send() + } + + var currentUserResponse = &dto.CurrentUserResponse{ IP: c.IP(), Valid: user.Valid, UserEmail: user.Token.Email, @@ -39,5 +52,5 @@ func (u *UserController) Test(c *fiber.Ctx) error { UserName: user.Token.Name, } - return response.Ctx(c).Status(http.StatusOK).Data(currentUserResponse).Send() + return dto.Ctx(c).Status(http.StatusOK).Data(currentUserResponse).Send() } diff --git a/internal/base/app.go b/internal/base/app.go index 1c73233..8f5603c 100644 --- a/internal/base/app.go +++ b/internal/base/app.go @@ -11,7 +11,7 @@ import ( "leafdev.top/Leaf/leaf-library-3/internal/base/server" "leafdev.top/Leaf/leaf-library-3/internal/batch" "leafdev.top/Leaf/leaf-library-3/internal/dao" - "leafdev.top/Leaf/leaf-library-3/internal/service" + "leafdev.top/Leaf/leaf-library-3/internal/services" ) type Application struct { @@ -21,7 +21,7 @@ type Application struct { HttpServer *server.HttpServer GORM *gorm.DB DAO *dao.Query - Service *service.Service + Service *services.Service Redis *redis.Redis Batch *batch.Batch S3 *s3.S3 @@ -33,7 +33,7 @@ func NewApplication( httpServer *server.HttpServer, api *api.Api, logger *logger.Logger, - services *service.Service, + services *services.Service, redis *redis.Redis, batch *batch.Batch, s3 *s3.S3, diff --git a/internal/base/conf/rbac_model.go b/internal/base/conf/rbac_model.go deleted file mode 100644 index b1ebb19..0000000 --- a/internal/base/conf/rbac_model.go +++ /dev/null @@ -1,9 +0,0 @@ -package conf - -import ( - "leafdev.top/Leaf/leaf-library-3/configs" -) - -func (c *Config) GetRBACModel() string { - return string(configs.RBACModel) -} diff --git a/internal/base/server/error.go b/internal/base/server/error.go new file mode 100644 index 0000000..a391491 --- /dev/null +++ b/internal/base/server/error.go @@ -0,0 +1,49 @@ +package server + +import ( + "errors" + "net/http" + + "github.com/gofiber/fiber/v2" + "gorm.io/gorm" + "leafdev.top/Leaf/leaf-library-3/internal/base/logger" + "leafdev.top/Leaf/leaf-library-3/internal/pkg/validator" + "leafdev.top/Leaf/leaf-library-3/internal/types/dto" + "leafdev.top/Leaf/leaf-library-3/internal/types/errs" +) + +func errorConverter(logger *logger.Logger, ctx *fiber.Ctx, err error) error { + status := http.StatusInternalServerError + + if err == nil { + return dto.Ctx(ctx).Error(errs.ErrInternalServerError).Status(status).Send() + } + + var errorMsg dto.IError + + switch { + // 404 + //case errors.Is(err, fiber.ErrNotFound): + // status = http.StatusNotFound + // errorMsg = errs.RouteNotFound + + case errors.Is(err, fiber.ErrUnprocessableEntity): + status = http.StatusUnprocessableEntity + errorMsg = err + + case errors.Is(err, errs.ErrPermissionDenied): + status = http.StatusForbidden + + case errors.Is(err, validator.ErrValidationFailed): + status = http.StatusBadRequest + + case errors.Is(err, gorm.ErrRecordNotFound): + errorMsg = errs.ErrNotFound + + default: + logger.Sugar.Errorf("fiber error: %s", err) + errorMsg = errs.UnknownError + } + + return dto.Ctx(ctx).Status(status).Error(errorMsg).Send() +} diff --git a/internal/base/server/http.go b/internal/base/server/http.go index 6c2cd3e..28d8d89 100644 --- a/internal/base/server/http.go +++ b/internal/base/server/http.go @@ -10,12 +10,12 @@ import ( "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/recover" httpApi "leafdev.top/Leaf/leaf-library-3/internal/api/http" - "leafdev.top/Leaf/leaf-library-3/internal/api/http/response" "leafdev.top/Leaf/leaf-library-3/internal/base/conf" "leafdev.top/Leaf/leaf-library-3/internal/base/logger" - "leafdev.top/Leaf/leaf-library-3/internal/consts" "leafdev.top/Leaf/leaf-library-3/internal/router" - "leafdev.top/Leaf/leaf-library-3/internal/service/auth" + "leafdev.top/Leaf/leaf-library-3/internal/services/auth" + "leafdev.top/Leaf/leaf-library-3/internal/types/dto" + "leafdev.top/Leaf/leaf-library-3/internal/types/errs" ) type HttpServer struct { @@ -39,8 +39,7 @@ func NewHTTPServer( JSONEncoder: sonic.Marshal, JSONDecoder: sonic.Unmarshal, ErrorHandler: func(ctx *fiber.Ctx, err error) error { - logger.Sugar.Errorf("fiber error: %s", err) - return response.Ctx(ctx).Status(fiber.StatusInternalServerError).Error(consts.ErrInternalServerError).Send() + return errorConverter(logger, ctx, err) }, }) app.Use(recover.New()) @@ -84,7 +83,7 @@ func (hs *HttpServer) BizRouter() *fiber.App { // 404 Route hs.Fiber.Use(func(ctx *fiber.Ctx) error { - return response.Ctx(ctx).Status(fiber.StatusNotFound).Send() + return dto.Ctx(ctx).Status(fiber.StatusNotFound).Error(errs.RouteNotFound).Send() }) return hs.Fiber diff --git a/internal/consts/auth.go b/internal/consts/auth.go deleted file mode 100644 index 17a8d48..0000000 --- a/internal/consts/auth.go +++ /dev/null @@ -1,31 +0,0 @@ -package consts - -import ( - "errors" - - "leafdev.top/Leaf/leaf-library-3/internal/pkg/user" -) - -const ( - AuthHeader = "Authorization" - AuthPrefix = "Bearer" - - // AnonymousUser 调试模式下的用户 - AnonymousUser user.Id = "anonymous" - - AuthMiddlewareKey = "auth.user" - AuthAssistantShareMiddlewareKey = "auth.assistant.share" -) - -var ( - ErrNotValidToken = errors.New("JWT not valid") - ErrJWTFormatError = errors.New("JWT format error") - ErrNotBearerType = errors.New("not bearer token") - ErrEmptyResponse = errors.New("empty response") - ErrTokenError = errors.New("token type error") - ErrUnauthorized = errors.New("unauthorized") - ErrAudienceNotAllowed = errors.New("audience not allowed") - - ErrNotYourResource = errors.New("this resource not yours") - ErrPermissionDenied = errors.New("permission denied") -) diff --git a/internal/consts/rbac.go b/internal/consts/rbac.go deleted file mode 100644 index e4f1b69..0000000 --- a/internal/consts/rbac.go +++ /dev/null @@ -1,9 +0,0 @@ -package consts - -import ( - "leafdev.top/Leaf/leaf-library-3/internal/pkg/user" -) - -const ( - RoleSuperAdmin user.Role = "super-admin" -) diff --git a/internal/consts/router.go b/internal/consts/router.go deleted file mode 100644 index 5f13318..0000000 --- a/internal/consts/router.go +++ /dev/null @@ -1,7 +0,0 @@ -package consts - -import "errors" - -var ( - ErrInternalServerError = errors.New("there was a server error, but we have logged this request for further investigation") -) diff --git a/internal/dao/block_chunks.gen.go b/internal/dao/block_chunks.gen.go new file mode 100644 index 0000000..1dd2495 --- /dev/null +++ b/internal/dao/block_chunks.gen.go @@ -0,0 +1,530 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package dao + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "leafdev.top/Leaf/leaf-library-3/internal/entity" +) + +func newBlockChunk(db *gorm.DB, opts ...gen.DOOption) blockChunk { + _blockChunk := blockChunk{} + + _blockChunk.blockChunkDo.UseDB(db, opts...) + _blockChunk.blockChunkDo.UseModel(&entity.BlockChunk{}) + + tableName := _blockChunk.blockChunkDo.TableName() + _blockChunk.ALL = field.NewAsterisk(tableName) + _blockChunk.Id = field.NewUint(tableName, "id") + _blockChunk.CreatedAt = field.NewTime(tableName, "created_at") + _blockChunk.UpdatedAt = field.NewTime(tableName, "updated_at") + _blockChunk.DocumentBlockId = field.NewUint(tableName, "document_block_id") + _blockChunk.Content = field.NewString(tableName, "content") + _blockChunk.DocumentBlock = blockChunkBelongsToDocumentBlock{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("DocumentBlock", "entity.DocumentBlock"), + Document: struct { + field.RelationField + Workspace struct { + field.RelationField + } + Collection struct { + field.RelationField + Workspace struct { + field.RelationField + } + } + Parent struct { + field.RelationField + } + }{ + RelationField: field.NewRelation("DocumentBlock.Document", "entity.Document"), + Workspace: struct { + field.RelationField + }{ + RelationField: field.NewRelation("DocumentBlock.Document.Workspace", "entity.Workspace"), + }, + Collection: struct { + field.RelationField + Workspace struct { + field.RelationField + } + }{ + RelationField: field.NewRelation("DocumentBlock.Document.Collection", "entity.Collection"), + Workspace: struct { + field.RelationField + }{ + RelationField: field.NewRelation("DocumentBlock.Document.Collection.Workspace", "entity.Workspace"), + }, + }, + Parent: struct { + field.RelationField + }{ + RelationField: field.NewRelation("DocumentBlock.Document.Parent", "entity.Document"), + }, + }, + } + + _blockChunk.fillFieldMap() + + return _blockChunk +} + +type blockChunk struct { + blockChunkDo + + ALL field.Asterisk + Id field.Uint + CreatedAt field.Time + UpdatedAt field.Time + DocumentBlockId field.Uint + Content field.String + DocumentBlock blockChunkBelongsToDocumentBlock + + fieldMap map[string]field.Expr +} + +func (b blockChunk) Table(newTableName string) *blockChunk { + b.blockChunkDo.UseTable(newTableName) + return b.updateTableName(newTableName) +} + +func (b blockChunk) As(alias string) *blockChunk { + b.blockChunkDo.DO = *(b.blockChunkDo.As(alias).(*gen.DO)) + return b.updateTableName(alias) +} + +func (b *blockChunk) updateTableName(table string) *blockChunk { + b.ALL = field.NewAsterisk(table) + b.Id = field.NewUint(table, "id") + b.CreatedAt = field.NewTime(table, "created_at") + b.UpdatedAt = field.NewTime(table, "updated_at") + b.DocumentBlockId = field.NewUint(table, "document_block_id") + b.Content = field.NewString(table, "content") + + b.fillFieldMap() + + return b +} + +func (b *blockChunk) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := b.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (b *blockChunk) fillFieldMap() { + b.fieldMap = make(map[string]field.Expr, 6) + b.fieldMap["id"] = b.Id + b.fieldMap["created_at"] = b.CreatedAt + b.fieldMap["updated_at"] = b.UpdatedAt + b.fieldMap["document_block_id"] = b.DocumentBlockId + b.fieldMap["content"] = b.Content + +} + +func (b blockChunk) clone(db *gorm.DB) blockChunk { + b.blockChunkDo.ReplaceConnPool(db.Statement.ConnPool) + return b +} + +func (b blockChunk) replaceDB(db *gorm.DB) blockChunk { + b.blockChunkDo.ReplaceDB(db) + return b +} + +type blockChunkBelongsToDocumentBlock struct { + db *gorm.DB + + field.RelationField + + Document struct { + field.RelationField + Workspace struct { + field.RelationField + } + Collection struct { + field.RelationField + Workspace struct { + field.RelationField + } + } + Parent struct { + field.RelationField + } + } +} + +func (a blockChunkBelongsToDocumentBlock) Where(conds ...field.Expr) *blockChunkBelongsToDocumentBlock { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a blockChunkBelongsToDocumentBlock) WithContext(ctx context.Context) *blockChunkBelongsToDocumentBlock { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a blockChunkBelongsToDocumentBlock) Session(session *gorm.Session) *blockChunkBelongsToDocumentBlock { + a.db = a.db.Session(session) + return &a +} + +func (a blockChunkBelongsToDocumentBlock) Model(m *entity.BlockChunk) *blockChunkBelongsToDocumentBlockTx { + return &blockChunkBelongsToDocumentBlockTx{a.db.Model(m).Association(a.Name())} +} + +type blockChunkBelongsToDocumentBlockTx struct{ tx *gorm.Association } + +func (a blockChunkBelongsToDocumentBlockTx) Find() (result *entity.DocumentBlock, err error) { + return result, a.tx.Find(&result) +} + +func (a blockChunkBelongsToDocumentBlockTx) Append(values ...*entity.DocumentBlock) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a blockChunkBelongsToDocumentBlockTx) Replace(values ...*entity.DocumentBlock) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a blockChunkBelongsToDocumentBlockTx) Delete(values ...*entity.DocumentBlock) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a blockChunkBelongsToDocumentBlockTx) Clear() error { + return a.tx.Clear() +} + +func (a blockChunkBelongsToDocumentBlockTx) Count() int64 { + return a.tx.Count() +} + +type blockChunkDo struct{ gen.DO } + +type IBlockChunkDo interface { + gen.SubQuery + Debug() IBlockChunkDo + WithContext(ctx context.Context) IBlockChunkDo + WithResult(fc func(tx gen.Dao)) gen.ResultInfo + ReplaceDB(db *gorm.DB) + ReadDB() IBlockChunkDo + WriteDB() IBlockChunkDo + As(alias string) gen.Dao + Session(config *gorm.Session) IBlockChunkDo + Columns(cols ...field.Expr) gen.Columns + Clauses(conds ...clause.Expression) IBlockChunkDo + Not(conds ...gen.Condition) IBlockChunkDo + Or(conds ...gen.Condition) IBlockChunkDo + Select(conds ...field.Expr) IBlockChunkDo + Where(conds ...gen.Condition) IBlockChunkDo + Order(conds ...field.Expr) IBlockChunkDo + Distinct(cols ...field.Expr) IBlockChunkDo + Omit(cols ...field.Expr) IBlockChunkDo + Join(table schema.Tabler, on ...field.Expr) IBlockChunkDo + LeftJoin(table schema.Tabler, on ...field.Expr) IBlockChunkDo + RightJoin(table schema.Tabler, on ...field.Expr) IBlockChunkDo + Group(cols ...field.Expr) IBlockChunkDo + Having(conds ...gen.Condition) IBlockChunkDo + Limit(limit int) IBlockChunkDo + Offset(offset int) IBlockChunkDo + Count() (count int64, err error) + Scopes(funcs ...func(gen.Dao) gen.Dao) IBlockChunkDo + Unscoped() IBlockChunkDo + Create(values ...*entity.BlockChunk) error + CreateInBatches(values []*entity.BlockChunk, batchSize int) error + Save(values ...*entity.BlockChunk) error + First() (*entity.BlockChunk, error) + Take() (*entity.BlockChunk, error) + Last() (*entity.BlockChunk, error) + Find() ([]*entity.BlockChunk, error) + FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.BlockChunk, err error) + FindInBatches(result *[]*entity.BlockChunk, batchSize int, fc func(tx gen.Dao, batch int) error) error + Pluck(column field.Expr, dest interface{}) error + Delete(...*entity.BlockChunk) (info gen.ResultInfo, err error) + Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + Updates(value interface{}) (info gen.ResultInfo, err error) + UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + UpdateColumns(value interface{}) (info gen.ResultInfo, err error) + UpdateFrom(q gen.SubQuery) gen.Dao + Attrs(attrs ...field.AssignExpr) IBlockChunkDo + Assign(attrs ...field.AssignExpr) IBlockChunkDo + Joins(fields ...field.RelationField) IBlockChunkDo + Preload(fields ...field.RelationField) IBlockChunkDo + FirstOrInit() (*entity.BlockChunk, error) + FirstOrCreate() (*entity.BlockChunk, error) + FindByPage(offset int, limit int) (result []*entity.BlockChunk, count int64, err error) + ScanByPage(result interface{}, offset int, limit int) (count int64, err error) + Scan(result interface{}) (err error) + Returning(value interface{}, columns ...string) IBlockChunkDo + UnderlyingDB() *gorm.DB + schema.Tabler +} + +func (b blockChunkDo) Debug() IBlockChunkDo { + return b.withDO(b.DO.Debug()) +} + +func (b blockChunkDo) WithContext(ctx context.Context) IBlockChunkDo { + return b.withDO(b.DO.WithContext(ctx)) +} + +func (b blockChunkDo) ReadDB() IBlockChunkDo { + return b.Clauses(dbresolver.Read) +} + +func (b blockChunkDo) WriteDB() IBlockChunkDo { + return b.Clauses(dbresolver.Write) +} + +func (b blockChunkDo) Session(config *gorm.Session) IBlockChunkDo { + return b.withDO(b.DO.Session(config)) +} + +func (b blockChunkDo) Clauses(conds ...clause.Expression) IBlockChunkDo { + return b.withDO(b.DO.Clauses(conds...)) +} + +func (b blockChunkDo) Returning(value interface{}, columns ...string) IBlockChunkDo { + return b.withDO(b.DO.Returning(value, columns...)) +} + +func (b blockChunkDo) Not(conds ...gen.Condition) IBlockChunkDo { + return b.withDO(b.DO.Not(conds...)) +} + +func (b blockChunkDo) Or(conds ...gen.Condition) IBlockChunkDo { + return b.withDO(b.DO.Or(conds...)) +} + +func (b blockChunkDo) Select(conds ...field.Expr) IBlockChunkDo { + return b.withDO(b.DO.Select(conds...)) +} + +func (b blockChunkDo) Where(conds ...gen.Condition) IBlockChunkDo { + return b.withDO(b.DO.Where(conds...)) +} + +func (b blockChunkDo) Order(conds ...field.Expr) IBlockChunkDo { + return b.withDO(b.DO.Order(conds...)) +} + +func (b blockChunkDo) Distinct(cols ...field.Expr) IBlockChunkDo { + return b.withDO(b.DO.Distinct(cols...)) +} + +func (b blockChunkDo) Omit(cols ...field.Expr) IBlockChunkDo { + return b.withDO(b.DO.Omit(cols...)) +} + +func (b blockChunkDo) Join(table schema.Tabler, on ...field.Expr) IBlockChunkDo { + return b.withDO(b.DO.Join(table, on...)) +} + +func (b blockChunkDo) LeftJoin(table schema.Tabler, on ...field.Expr) IBlockChunkDo { + return b.withDO(b.DO.LeftJoin(table, on...)) +} + +func (b blockChunkDo) RightJoin(table schema.Tabler, on ...field.Expr) IBlockChunkDo { + return b.withDO(b.DO.RightJoin(table, on...)) +} + +func (b blockChunkDo) Group(cols ...field.Expr) IBlockChunkDo { + return b.withDO(b.DO.Group(cols...)) +} + +func (b blockChunkDo) Having(conds ...gen.Condition) IBlockChunkDo { + return b.withDO(b.DO.Having(conds...)) +} + +func (b blockChunkDo) Limit(limit int) IBlockChunkDo { + return b.withDO(b.DO.Limit(limit)) +} + +func (b blockChunkDo) Offset(offset int) IBlockChunkDo { + return b.withDO(b.DO.Offset(offset)) +} + +func (b blockChunkDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IBlockChunkDo { + return b.withDO(b.DO.Scopes(funcs...)) +} + +func (b blockChunkDo) Unscoped() IBlockChunkDo { + return b.withDO(b.DO.Unscoped()) +} + +func (b blockChunkDo) Create(values ...*entity.BlockChunk) error { + if len(values) == 0 { + return nil + } + return b.DO.Create(values) +} + +func (b blockChunkDo) CreateInBatches(values []*entity.BlockChunk, batchSize int) error { + return b.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (b blockChunkDo) Save(values ...*entity.BlockChunk) error { + if len(values) == 0 { + return nil + } + return b.DO.Save(values) +} + +func (b blockChunkDo) First() (*entity.BlockChunk, error) { + if result, err := b.DO.First(); err != nil { + return nil, err + } else { + return result.(*entity.BlockChunk), nil + } +} + +func (b blockChunkDo) Take() (*entity.BlockChunk, error) { + if result, err := b.DO.Take(); err != nil { + return nil, err + } else { + return result.(*entity.BlockChunk), nil + } +} + +func (b blockChunkDo) Last() (*entity.BlockChunk, error) { + if result, err := b.DO.Last(); err != nil { + return nil, err + } else { + return result.(*entity.BlockChunk), nil + } +} + +func (b blockChunkDo) Find() ([]*entity.BlockChunk, error) { + result, err := b.DO.Find() + return result.([]*entity.BlockChunk), err +} + +func (b blockChunkDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.BlockChunk, err error) { + buf := make([]*entity.BlockChunk, 0, batchSize) + err = b.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (b blockChunkDo) FindInBatches(result *[]*entity.BlockChunk, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return b.DO.FindInBatches(result, batchSize, fc) +} + +func (b blockChunkDo) Attrs(attrs ...field.AssignExpr) IBlockChunkDo { + return b.withDO(b.DO.Attrs(attrs...)) +} + +func (b blockChunkDo) Assign(attrs ...field.AssignExpr) IBlockChunkDo { + return b.withDO(b.DO.Assign(attrs...)) +} + +func (b blockChunkDo) Joins(fields ...field.RelationField) IBlockChunkDo { + for _, _f := range fields { + b = *b.withDO(b.DO.Joins(_f)) + } + return &b +} + +func (b blockChunkDo) Preload(fields ...field.RelationField) IBlockChunkDo { + for _, _f := range fields { + b = *b.withDO(b.DO.Preload(_f)) + } + return &b +} + +func (b blockChunkDo) FirstOrInit() (*entity.BlockChunk, error) { + if result, err := b.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*entity.BlockChunk), nil + } +} + +func (b blockChunkDo) FirstOrCreate() (*entity.BlockChunk, error) { + if result, err := b.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*entity.BlockChunk), nil + } +} + +func (b blockChunkDo) FindByPage(offset int, limit int) (result []*entity.BlockChunk, count int64, err error) { + result, err = b.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = b.Offset(-1).Limit(-1).Count() + return +} + +func (b blockChunkDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = b.Count() + if err != nil { + return + } + + err = b.Offset(offset).Limit(limit).Scan(result) + return +} + +func (b blockChunkDo) Scan(result interface{}) (err error) { + return b.DO.Scan(result) +} + +func (b blockChunkDo) Delete(models ...*entity.BlockChunk) (result gen.ResultInfo, err error) { + return b.DO.Delete(models) +} + +func (b *blockChunkDo) withDO(do gen.Dao) *blockChunkDo { + b.DO = *do.(*gen.DO) + return b +} diff --git a/internal/dao/collections.gen.go b/internal/dao/collections.gen.go new file mode 100644 index 0000000..f1f3bc5 --- /dev/null +++ b/internal/dao/collections.gen.go @@ -0,0 +1,478 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package dao + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "leafdev.top/Leaf/leaf-library-3/internal/entity" +) + +func newCollection(db *gorm.DB, opts ...gen.DOOption) collection { + _collection := collection{} + + _collection.collectionDo.UseDB(db, opts...) + _collection.collectionDo.UseModel(&entity.Collection{}) + + tableName := _collection.collectionDo.TableName() + _collection.ALL = field.NewAsterisk(tableName) + _collection.Id = field.NewUint(tableName, "id") + _collection.CreatedAt = field.NewTime(tableName, "created_at") + _collection.UpdatedAt = field.NewTime(tableName, "updated_at") + _collection.Name = field.NewString(tableName, "name") + _collection.WorkspaceId = field.NewUint(tableName, "workspace_id") + _collection.DeletedAt = field.NewField(tableName, "deleted_at") + _collection.Workspace = collectionBelongsToWorkspace{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Workspace", "entity.Workspace"), + } + + _collection.fillFieldMap() + + return _collection +} + +type collection struct { + collectionDo + + ALL field.Asterisk + Id field.Uint + CreatedAt field.Time + UpdatedAt field.Time + Name field.String + WorkspaceId field.Uint + DeletedAt field.Field + Workspace collectionBelongsToWorkspace + + fieldMap map[string]field.Expr +} + +func (c collection) Table(newTableName string) *collection { + c.collectionDo.UseTable(newTableName) + return c.updateTableName(newTableName) +} + +func (c collection) As(alias string) *collection { + c.collectionDo.DO = *(c.collectionDo.As(alias).(*gen.DO)) + return c.updateTableName(alias) +} + +func (c *collection) updateTableName(table string) *collection { + c.ALL = field.NewAsterisk(table) + c.Id = field.NewUint(table, "id") + c.CreatedAt = field.NewTime(table, "created_at") + c.UpdatedAt = field.NewTime(table, "updated_at") + c.Name = field.NewString(table, "name") + c.WorkspaceId = field.NewUint(table, "workspace_id") + c.DeletedAt = field.NewField(table, "deleted_at") + + c.fillFieldMap() + + return c +} + +func (c *collection) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := c.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (c *collection) fillFieldMap() { + c.fieldMap = make(map[string]field.Expr, 7) + c.fieldMap["id"] = c.Id + c.fieldMap["created_at"] = c.CreatedAt + c.fieldMap["updated_at"] = c.UpdatedAt + c.fieldMap["name"] = c.Name + c.fieldMap["workspace_id"] = c.WorkspaceId + c.fieldMap["deleted_at"] = c.DeletedAt + +} + +func (c collection) clone(db *gorm.DB) collection { + c.collectionDo.ReplaceConnPool(db.Statement.ConnPool) + return c +} + +func (c collection) replaceDB(db *gorm.DB) collection { + c.collectionDo.ReplaceDB(db) + return c +} + +type collectionBelongsToWorkspace struct { + db *gorm.DB + + field.RelationField +} + +func (a collectionBelongsToWorkspace) Where(conds ...field.Expr) *collectionBelongsToWorkspace { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a collectionBelongsToWorkspace) WithContext(ctx context.Context) *collectionBelongsToWorkspace { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a collectionBelongsToWorkspace) Session(session *gorm.Session) *collectionBelongsToWorkspace { + a.db = a.db.Session(session) + return &a +} + +func (a collectionBelongsToWorkspace) Model(m *entity.Collection) *collectionBelongsToWorkspaceTx { + return &collectionBelongsToWorkspaceTx{a.db.Model(m).Association(a.Name())} +} + +type collectionBelongsToWorkspaceTx struct{ tx *gorm.Association } + +func (a collectionBelongsToWorkspaceTx) Find() (result *entity.Workspace, err error) { + return result, a.tx.Find(&result) +} + +func (a collectionBelongsToWorkspaceTx) Append(values ...*entity.Workspace) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a collectionBelongsToWorkspaceTx) Replace(values ...*entity.Workspace) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a collectionBelongsToWorkspaceTx) Delete(values ...*entity.Workspace) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a collectionBelongsToWorkspaceTx) Clear() error { + return a.tx.Clear() +} + +func (a collectionBelongsToWorkspaceTx) Count() int64 { + return a.tx.Count() +} + +type collectionDo struct{ gen.DO } + +type ICollectionDo interface { + gen.SubQuery + Debug() ICollectionDo + WithContext(ctx context.Context) ICollectionDo + WithResult(fc func(tx gen.Dao)) gen.ResultInfo + ReplaceDB(db *gorm.DB) + ReadDB() ICollectionDo + WriteDB() ICollectionDo + As(alias string) gen.Dao + Session(config *gorm.Session) ICollectionDo + Columns(cols ...field.Expr) gen.Columns + Clauses(conds ...clause.Expression) ICollectionDo + Not(conds ...gen.Condition) ICollectionDo + Or(conds ...gen.Condition) ICollectionDo + Select(conds ...field.Expr) ICollectionDo + Where(conds ...gen.Condition) ICollectionDo + Order(conds ...field.Expr) ICollectionDo + Distinct(cols ...field.Expr) ICollectionDo + Omit(cols ...field.Expr) ICollectionDo + Join(table schema.Tabler, on ...field.Expr) ICollectionDo + LeftJoin(table schema.Tabler, on ...field.Expr) ICollectionDo + RightJoin(table schema.Tabler, on ...field.Expr) ICollectionDo + Group(cols ...field.Expr) ICollectionDo + Having(conds ...gen.Condition) ICollectionDo + Limit(limit int) ICollectionDo + Offset(offset int) ICollectionDo + Count() (count int64, err error) + Scopes(funcs ...func(gen.Dao) gen.Dao) ICollectionDo + Unscoped() ICollectionDo + Create(values ...*entity.Collection) error + CreateInBatches(values []*entity.Collection, batchSize int) error + Save(values ...*entity.Collection) error + First() (*entity.Collection, error) + Take() (*entity.Collection, error) + Last() (*entity.Collection, error) + Find() ([]*entity.Collection, error) + FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.Collection, err error) + FindInBatches(result *[]*entity.Collection, batchSize int, fc func(tx gen.Dao, batch int) error) error + Pluck(column field.Expr, dest interface{}) error + Delete(...*entity.Collection) (info gen.ResultInfo, err error) + Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + Updates(value interface{}) (info gen.ResultInfo, err error) + UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + UpdateColumns(value interface{}) (info gen.ResultInfo, err error) + UpdateFrom(q gen.SubQuery) gen.Dao + Attrs(attrs ...field.AssignExpr) ICollectionDo + Assign(attrs ...field.AssignExpr) ICollectionDo + Joins(fields ...field.RelationField) ICollectionDo + Preload(fields ...field.RelationField) ICollectionDo + FirstOrInit() (*entity.Collection, error) + FirstOrCreate() (*entity.Collection, error) + FindByPage(offset int, limit int) (result []*entity.Collection, count int64, err error) + ScanByPage(result interface{}, offset int, limit int) (count int64, err error) + Scan(result interface{}) (err error) + Returning(value interface{}, columns ...string) ICollectionDo + UnderlyingDB() *gorm.DB + schema.Tabler +} + +func (c collectionDo) Debug() ICollectionDo { + return c.withDO(c.DO.Debug()) +} + +func (c collectionDo) WithContext(ctx context.Context) ICollectionDo { + return c.withDO(c.DO.WithContext(ctx)) +} + +func (c collectionDo) ReadDB() ICollectionDo { + return c.Clauses(dbresolver.Read) +} + +func (c collectionDo) WriteDB() ICollectionDo { + return c.Clauses(dbresolver.Write) +} + +func (c collectionDo) Session(config *gorm.Session) ICollectionDo { + return c.withDO(c.DO.Session(config)) +} + +func (c collectionDo) Clauses(conds ...clause.Expression) ICollectionDo { + return c.withDO(c.DO.Clauses(conds...)) +} + +func (c collectionDo) Returning(value interface{}, columns ...string) ICollectionDo { + return c.withDO(c.DO.Returning(value, columns...)) +} + +func (c collectionDo) Not(conds ...gen.Condition) ICollectionDo { + return c.withDO(c.DO.Not(conds...)) +} + +func (c collectionDo) Or(conds ...gen.Condition) ICollectionDo { + return c.withDO(c.DO.Or(conds...)) +} + +func (c collectionDo) Select(conds ...field.Expr) ICollectionDo { + return c.withDO(c.DO.Select(conds...)) +} + +func (c collectionDo) Where(conds ...gen.Condition) ICollectionDo { + return c.withDO(c.DO.Where(conds...)) +} + +func (c collectionDo) Order(conds ...field.Expr) ICollectionDo { + return c.withDO(c.DO.Order(conds...)) +} + +func (c collectionDo) Distinct(cols ...field.Expr) ICollectionDo { + return c.withDO(c.DO.Distinct(cols...)) +} + +func (c collectionDo) Omit(cols ...field.Expr) ICollectionDo { + return c.withDO(c.DO.Omit(cols...)) +} + +func (c collectionDo) Join(table schema.Tabler, on ...field.Expr) ICollectionDo { + return c.withDO(c.DO.Join(table, on...)) +} + +func (c collectionDo) LeftJoin(table schema.Tabler, on ...field.Expr) ICollectionDo { + return c.withDO(c.DO.LeftJoin(table, on...)) +} + +func (c collectionDo) RightJoin(table schema.Tabler, on ...field.Expr) ICollectionDo { + return c.withDO(c.DO.RightJoin(table, on...)) +} + +func (c collectionDo) Group(cols ...field.Expr) ICollectionDo { + return c.withDO(c.DO.Group(cols...)) +} + +func (c collectionDo) Having(conds ...gen.Condition) ICollectionDo { + return c.withDO(c.DO.Having(conds...)) +} + +func (c collectionDo) Limit(limit int) ICollectionDo { + return c.withDO(c.DO.Limit(limit)) +} + +func (c collectionDo) Offset(offset int) ICollectionDo { + return c.withDO(c.DO.Offset(offset)) +} + +func (c collectionDo) Scopes(funcs ...func(gen.Dao) gen.Dao) ICollectionDo { + return c.withDO(c.DO.Scopes(funcs...)) +} + +func (c collectionDo) Unscoped() ICollectionDo { + return c.withDO(c.DO.Unscoped()) +} + +func (c collectionDo) Create(values ...*entity.Collection) error { + if len(values) == 0 { + return nil + } + return c.DO.Create(values) +} + +func (c collectionDo) CreateInBatches(values []*entity.Collection, batchSize int) error { + return c.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (c collectionDo) Save(values ...*entity.Collection) error { + if len(values) == 0 { + return nil + } + return c.DO.Save(values) +} + +func (c collectionDo) First() (*entity.Collection, error) { + if result, err := c.DO.First(); err != nil { + return nil, err + } else { + return result.(*entity.Collection), nil + } +} + +func (c collectionDo) Take() (*entity.Collection, error) { + if result, err := c.DO.Take(); err != nil { + return nil, err + } else { + return result.(*entity.Collection), nil + } +} + +func (c collectionDo) Last() (*entity.Collection, error) { + if result, err := c.DO.Last(); err != nil { + return nil, err + } else { + return result.(*entity.Collection), nil + } +} + +func (c collectionDo) Find() ([]*entity.Collection, error) { + result, err := c.DO.Find() + return result.([]*entity.Collection), err +} + +func (c collectionDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.Collection, err error) { + buf := make([]*entity.Collection, 0, batchSize) + err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (c collectionDo) FindInBatches(result *[]*entity.Collection, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return c.DO.FindInBatches(result, batchSize, fc) +} + +func (c collectionDo) Attrs(attrs ...field.AssignExpr) ICollectionDo { + return c.withDO(c.DO.Attrs(attrs...)) +} + +func (c collectionDo) Assign(attrs ...field.AssignExpr) ICollectionDo { + return c.withDO(c.DO.Assign(attrs...)) +} + +func (c collectionDo) Joins(fields ...field.RelationField) ICollectionDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Joins(_f)) + } + return &c +} + +func (c collectionDo) Preload(fields ...field.RelationField) ICollectionDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Preload(_f)) + } + return &c +} + +func (c collectionDo) FirstOrInit() (*entity.Collection, error) { + if result, err := c.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*entity.Collection), nil + } +} + +func (c collectionDo) FirstOrCreate() (*entity.Collection, error) { + if result, err := c.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*entity.Collection), nil + } +} + +func (c collectionDo) FindByPage(offset int, limit int) (result []*entity.Collection, count int64, err error) { + result, err = c.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = c.Offset(-1).Limit(-1).Count() + return +} + +func (c collectionDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = c.Count() + if err != nil { + return + } + + err = c.Offset(offset).Limit(limit).Scan(result) + return +} + +func (c collectionDo) Scan(result interface{}) (err error) { + return c.DO.Scan(result) +} + +func (c collectionDo) Delete(models ...*entity.Collection) (result gen.ResultInfo, err error) { + return c.DO.Delete(models) +} + +func (c *collectionDo) withDO(do gen.Dao) *collectionDo { + c.DO = *do.(*gen.DO) + return c +} diff --git a/internal/dao/document_blocks.gen.go b/internal/dao/document_blocks.gen.go new file mode 100644 index 0000000..e9bc706 --- /dev/null +++ b/internal/dao/document_blocks.gen.go @@ -0,0 +1,518 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package dao + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "leafdev.top/Leaf/leaf-library-3/internal/entity" +) + +func newDocumentBlock(db *gorm.DB, opts ...gen.DOOption) documentBlock { + _documentBlock := documentBlock{} + + _documentBlock.documentBlockDo.UseDB(db, opts...) + _documentBlock.documentBlockDo.UseModel(&entity.DocumentBlock{}) + + tableName := _documentBlock.documentBlockDo.TableName() + _documentBlock.ALL = field.NewAsterisk(tableName) + _documentBlock.Id = field.NewUint(tableName, "id") + _documentBlock.CreatedAt = field.NewTime(tableName, "created_at") + _documentBlock.UpdatedAt = field.NewTime(tableName, "updated_at") + _documentBlock.DocumentId = field.NewUint(tableName, "document_id") + _documentBlock.Type = field.NewString(tableName, "type") + _documentBlock.Content = field.NewString(tableName, "content") + _documentBlock.Hash = field.NewString(tableName, "hash") + _documentBlock.Document = documentBlockBelongsToDocument{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Document", "entity.Document"), + Workspace: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Document.Workspace", "entity.Workspace"), + }, + Collection: struct { + field.RelationField + Workspace struct { + field.RelationField + } + }{ + RelationField: field.NewRelation("Document.Collection", "entity.Collection"), + Workspace: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Document.Collection.Workspace", "entity.Workspace"), + }, + }, + Parent: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Document.Parent", "entity.Document"), + }, + } + + _documentBlock.fillFieldMap() + + return _documentBlock +} + +type documentBlock struct { + documentBlockDo + + ALL field.Asterisk + Id field.Uint + CreatedAt field.Time + UpdatedAt field.Time + DocumentId field.Uint + Type field.String + Content field.String + Hash field.String + Document documentBlockBelongsToDocument + + fieldMap map[string]field.Expr +} + +func (d documentBlock) Table(newTableName string) *documentBlock { + d.documentBlockDo.UseTable(newTableName) + return d.updateTableName(newTableName) +} + +func (d documentBlock) As(alias string) *documentBlock { + d.documentBlockDo.DO = *(d.documentBlockDo.As(alias).(*gen.DO)) + return d.updateTableName(alias) +} + +func (d *documentBlock) updateTableName(table string) *documentBlock { + d.ALL = field.NewAsterisk(table) + d.Id = field.NewUint(table, "id") + d.CreatedAt = field.NewTime(table, "created_at") + d.UpdatedAt = field.NewTime(table, "updated_at") + d.DocumentId = field.NewUint(table, "document_id") + d.Type = field.NewString(table, "type") + d.Content = field.NewString(table, "content") + d.Hash = field.NewString(table, "hash") + + d.fillFieldMap() + + return d +} + +func (d *documentBlock) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := d.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (d *documentBlock) fillFieldMap() { + d.fieldMap = make(map[string]field.Expr, 8) + d.fieldMap["id"] = d.Id + d.fieldMap["created_at"] = d.CreatedAt + d.fieldMap["updated_at"] = d.UpdatedAt + d.fieldMap["document_id"] = d.DocumentId + d.fieldMap["type"] = d.Type + d.fieldMap["content"] = d.Content + d.fieldMap["hash"] = d.Hash + +} + +func (d documentBlock) clone(db *gorm.DB) documentBlock { + d.documentBlockDo.ReplaceConnPool(db.Statement.ConnPool) + return d +} + +func (d documentBlock) replaceDB(db *gorm.DB) documentBlock { + d.documentBlockDo.ReplaceDB(db) + return d +} + +type documentBlockBelongsToDocument struct { + db *gorm.DB + + field.RelationField + + Workspace struct { + field.RelationField + } + Collection struct { + field.RelationField + Workspace struct { + field.RelationField + } + } + Parent struct { + field.RelationField + } +} + +func (a documentBlockBelongsToDocument) Where(conds ...field.Expr) *documentBlockBelongsToDocument { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a documentBlockBelongsToDocument) WithContext(ctx context.Context) *documentBlockBelongsToDocument { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a documentBlockBelongsToDocument) Session(session *gorm.Session) *documentBlockBelongsToDocument { + a.db = a.db.Session(session) + return &a +} + +func (a documentBlockBelongsToDocument) Model(m *entity.DocumentBlock) *documentBlockBelongsToDocumentTx { + return &documentBlockBelongsToDocumentTx{a.db.Model(m).Association(a.Name())} +} + +type documentBlockBelongsToDocumentTx struct{ tx *gorm.Association } + +func (a documentBlockBelongsToDocumentTx) Find() (result *entity.Document, err error) { + return result, a.tx.Find(&result) +} + +func (a documentBlockBelongsToDocumentTx) Append(values ...*entity.Document) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a documentBlockBelongsToDocumentTx) Replace(values ...*entity.Document) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a documentBlockBelongsToDocumentTx) Delete(values ...*entity.Document) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a documentBlockBelongsToDocumentTx) Clear() error { + return a.tx.Clear() +} + +func (a documentBlockBelongsToDocumentTx) Count() int64 { + return a.tx.Count() +} + +type documentBlockDo struct{ gen.DO } + +type IDocumentBlockDo interface { + gen.SubQuery + Debug() IDocumentBlockDo + WithContext(ctx context.Context) IDocumentBlockDo + WithResult(fc func(tx gen.Dao)) gen.ResultInfo + ReplaceDB(db *gorm.DB) + ReadDB() IDocumentBlockDo + WriteDB() IDocumentBlockDo + As(alias string) gen.Dao + Session(config *gorm.Session) IDocumentBlockDo + Columns(cols ...field.Expr) gen.Columns + Clauses(conds ...clause.Expression) IDocumentBlockDo + Not(conds ...gen.Condition) IDocumentBlockDo + Or(conds ...gen.Condition) IDocumentBlockDo + Select(conds ...field.Expr) IDocumentBlockDo + Where(conds ...gen.Condition) IDocumentBlockDo + Order(conds ...field.Expr) IDocumentBlockDo + Distinct(cols ...field.Expr) IDocumentBlockDo + Omit(cols ...field.Expr) IDocumentBlockDo + Join(table schema.Tabler, on ...field.Expr) IDocumentBlockDo + LeftJoin(table schema.Tabler, on ...field.Expr) IDocumentBlockDo + RightJoin(table schema.Tabler, on ...field.Expr) IDocumentBlockDo + Group(cols ...field.Expr) IDocumentBlockDo + Having(conds ...gen.Condition) IDocumentBlockDo + Limit(limit int) IDocumentBlockDo + Offset(offset int) IDocumentBlockDo + Count() (count int64, err error) + Scopes(funcs ...func(gen.Dao) gen.Dao) IDocumentBlockDo + Unscoped() IDocumentBlockDo + Create(values ...*entity.DocumentBlock) error + CreateInBatches(values []*entity.DocumentBlock, batchSize int) error + Save(values ...*entity.DocumentBlock) error + First() (*entity.DocumentBlock, error) + Take() (*entity.DocumentBlock, error) + Last() (*entity.DocumentBlock, error) + Find() ([]*entity.DocumentBlock, error) + FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.DocumentBlock, err error) + FindInBatches(result *[]*entity.DocumentBlock, batchSize int, fc func(tx gen.Dao, batch int) error) error + Pluck(column field.Expr, dest interface{}) error + Delete(...*entity.DocumentBlock) (info gen.ResultInfo, err error) + Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + Updates(value interface{}) (info gen.ResultInfo, err error) + UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + UpdateColumns(value interface{}) (info gen.ResultInfo, err error) + UpdateFrom(q gen.SubQuery) gen.Dao + Attrs(attrs ...field.AssignExpr) IDocumentBlockDo + Assign(attrs ...field.AssignExpr) IDocumentBlockDo + Joins(fields ...field.RelationField) IDocumentBlockDo + Preload(fields ...field.RelationField) IDocumentBlockDo + FirstOrInit() (*entity.DocumentBlock, error) + FirstOrCreate() (*entity.DocumentBlock, error) + FindByPage(offset int, limit int) (result []*entity.DocumentBlock, count int64, err error) + ScanByPage(result interface{}, offset int, limit int) (count int64, err error) + Scan(result interface{}) (err error) + Returning(value interface{}, columns ...string) IDocumentBlockDo + UnderlyingDB() *gorm.DB + schema.Tabler +} + +func (d documentBlockDo) Debug() IDocumentBlockDo { + return d.withDO(d.DO.Debug()) +} + +func (d documentBlockDo) WithContext(ctx context.Context) IDocumentBlockDo { + return d.withDO(d.DO.WithContext(ctx)) +} + +func (d documentBlockDo) ReadDB() IDocumentBlockDo { + return d.Clauses(dbresolver.Read) +} + +func (d documentBlockDo) WriteDB() IDocumentBlockDo { + return d.Clauses(dbresolver.Write) +} + +func (d documentBlockDo) Session(config *gorm.Session) IDocumentBlockDo { + return d.withDO(d.DO.Session(config)) +} + +func (d documentBlockDo) Clauses(conds ...clause.Expression) IDocumentBlockDo { + return d.withDO(d.DO.Clauses(conds...)) +} + +func (d documentBlockDo) Returning(value interface{}, columns ...string) IDocumentBlockDo { + return d.withDO(d.DO.Returning(value, columns...)) +} + +func (d documentBlockDo) Not(conds ...gen.Condition) IDocumentBlockDo { + return d.withDO(d.DO.Not(conds...)) +} + +func (d documentBlockDo) Or(conds ...gen.Condition) IDocumentBlockDo { + return d.withDO(d.DO.Or(conds...)) +} + +func (d documentBlockDo) Select(conds ...field.Expr) IDocumentBlockDo { + return d.withDO(d.DO.Select(conds...)) +} + +func (d documentBlockDo) Where(conds ...gen.Condition) IDocumentBlockDo { + return d.withDO(d.DO.Where(conds...)) +} + +func (d documentBlockDo) Order(conds ...field.Expr) IDocumentBlockDo { + return d.withDO(d.DO.Order(conds...)) +} + +func (d documentBlockDo) Distinct(cols ...field.Expr) IDocumentBlockDo { + return d.withDO(d.DO.Distinct(cols...)) +} + +func (d documentBlockDo) Omit(cols ...field.Expr) IDocumentBlockDo { + return d.withDO(d.DO.Omit(cols...)) +} + +func (d documentBlockDo) Join(table schema.Tabler, on ...field.Expr) IDocumentBlockDo { + return d.withDO(d.DO.Join(table, on...)) +} + +func (d documentBlockDo) LeftJoin(table schema.Tabler, on ...field.Expr) IDocumentBlockDo { + return d.withDO(d.DO.LeftJoin(table, on...)) +} + +func (d documentBlockDo) RightJoin(table schema.Tabler, on ...field.Expr) IDocumentBlockDo { + return d.withDO(d.DO.RightJoin(table, on...)) +} + +func (d documentBlockDo) Group(cols ...field.Expr) IDocumentBlockDo { + return d.withDO(d.DO.Group(cols...)) +} + +func (d documentBlockDo) Having(conds ...gen.Condition) IDocumentBlockDo { + return d.withDO(d.DO.Having(conds...)) +} + +func (d documentBlockDo) Limit(limit int) IDocumentBlockDo { + return d.withDO(d.DO.Limit(limit)) +} + +func (d documentBlockDo) Offset(offset int) IDocumentBlockDo { + return d.withDO(d.DO.Offset(offset)) +} + +func (d documentBlockDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IDocumentBlockDo { + return d.withDO(d.DO.Scopes(funcs...)) +} + +func (d documentBlockDo) Unscoped() IDocumentBlockDo { + return d.withDO(d.DO.Unscoped()) +} + +func (d documentBlockDo) Create(values ...*entity.DocumentBlock) error { + if len(values) == 0 { + return nil + } + return d.DO.Create(values) +} + +func (d documentBlockDo) CreateInBatches(values []*entity.DocumentBlock, batchSize int) error { + return d.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (d documentBlockDo) Save(values ...*entity.DocumentBlock) error { + if len(values) == 0 { + return nil + } + return d.DO.Save(values) +} + +func (d documentBlockDo) First() (*entity.DocumentBlock, error) { + if result, err := d.DO.First(); err != nil { + return nil, err + } else { + return result.(*entity.DocumentBlock), nil + } +} + +func (d documentBlockDo) Take() (*entity.DocumentBlock, error) { + if result, err := d.DO.Take(); err != nil { + return nil, err + } else { + return result.(*entity.DocumentBlock), nil + } +} + +func (d documentBlockDo) Last() (*entity.DocumentBlock, error) { + if result, err := d.DO.Last(); err != nil { + return nil, err + } else { + return result.(*entity.DocumentBlock), nil + } +} + +func (d documentBlockDo) Find() ([]*entity.DocumentBlock, error) { + result, err := d.DO.Find() + return result.([]*entity.DocumentBlock), err +} + +func (d documentBlockDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.DocumentBlock, err error) { + buf := make([]*entity.DocumentBlock, 0, batchSize) + err = d.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (d documentBlockDo) FindInBatches(result *[]*entity.DocumentBlock, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return d.DO.FindInBatches(result, batchSize, fc) +} + +func (d documentBlockDo) Attrs(attrs ...field.AssignExpr) IDocumentBlockDo { + return d.withDO(d.DO.Attrs(attrs...)) +} + +func (d documentBlockDo) Assign(attrs ...field.AssignExpr) IDocumentBlockDo { + return d.withDO(d.DO.Assign(attrs...)) +} + +func (d documentBlockDo) Joins(fields ...field.RelationField) IDocumentBlockDo { + for _, _f := range fields { + d = *d.withDO(d.DO.Joins(_f)) + } + return &d +} + +func (d documentBlockDo) Preload(fields ...field.RelationField) IDocumentBlockDo { + for _, _f := range fields { + d = *d.withDO(d.DO.Preload(_f)) + } + return &d +} + +func (d documentBlockDo) FirstOrInit() (*entity.DocumentBlock, error) { + if result, err := d.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*entity.DocumentBlock), nil + } +} + +func (d documentBlockDo) FirstOrCreate() (*entity.DocumentBlock, error) { + if result, err := d.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*entity.DocumentBlock), nil + } +} + +func (d documentBlockDo) FindByPage(offset int, limit int) (result []*entity.DocumentBlock, count int64, err error) { + result, err = d.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = d.Offset(-1).Limit(-1).Count() + return +} + +func (d documentBlockDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = d.Count() + if err != nil { + return + } + + err = d.Offset(offset).Limit(limit).Scan(result) + return +} + +func (d documentBlockDo) Scan(result interface{}) (err error) { + return d.DO.Scan(result) +} + +func (d documentBlockDo) Delete(models ...*entity.DocumentBlock) (result gen.ResultInfo, err error) { + return d.DO.Delete(models) +} + +func (d *documentBlockDo) withDO(do gen.Dao) *documentBlockDo { + d.DO = *do.(*gen.DO) + return d +} diff --git a/internal/dao/documents.gen.go b/internal/dao/documents.gen.go new file mode 100644 index 0000000..e336d53 --- /dev/null +++ b/internal/dao/documents.gen.go @@ -0,0 +1,678 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package dao + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "leafdev.top/Leaf/leaf-library-3/internal/entity" +) + +func newDocument(db *gorm.DB, opts ...gen.DOOption) document { + _document := document{} + + _document.documentDo.UseDB(db, opts...) + _document.documentDo.UseModel(&entity.Document{}) + + tableName := _document.documentDo.TableName() + _document.ALL = field.NewAsterisk(tableName) + _document.Id = field.NewUint(tableName, "id") + _document.CreatedAt = field.NewTime(tableName, "created_at") + _document.UpdatedAt = field.NewTime(tableName, "updated_at") + _document.Name = field.NewString(tableName, "name") + _document.WorkspaceId = field.NewUint(tableName, "workspace_id") + _document.CollectionId = field.NewUint(tableName, "collection_id") + _document.ParentId = field.NewUint(tableName, "parent_id") + _document.DeletedAt = field.NewField(tableName, "deleted_at") + _document.Workspace = documentBelongsToWorkspace{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Workspace", "entity.Workspace"), + } + + _document.Collection = documentBelongsToCollection{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Collection", "entity.Collection"), + Workspace: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Collection.Workspace", "entity.Workspace"), + }, + } + + _document.Parent = documentBelongsToParent{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Parent", "entity.Document"), + Workspace: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Parent.Workspace", "entity.Workspace"), + }, + Collection: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Parent.Collection", "entity.Collection"), + }, + Parent: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Parent.Parent", "entity.Document"), + }, + } + + _document.fillFieldMap() + + return _document +} + +type document struct { + documentDo + + ALL field.Asterisk + Id field.Uint + CreatedAt field.Time + UpdatedAt field.Time + Name field.String + WorkspaceId field.Uint + CollectionId field.Uint + ParentId field.Uint + DeletedAt field.Field + Workspace documentBelongsToWorkspace + + Collection documentBelongsToCollection + + Parent documentBelongsToParent + + fieldMap map[string]field.Expr +} + +func (d document) Table(newTableName string) *document { + d.documentDo.UseTable(newTableName) + return d.updateTableName(newTableName) +} + +func (d document) As(alias string) *document { + d.documentDo.DO = *(d.documentDo.As(alias).(*gen.DO)) + return d.updateTableName(alias) +} + +func (d *document) updateTableName(table string) *document { + d.ALL = field.NewAsterisk(table) + d.Id = field.NewUint(table, "id") + d.CreatedAt = field.NewTime(table, "created_at") + d.UpdatedAt = field.NewTime(table, "updated_at") + d.Name = field.NewString(table, "name") + d.WorkspaceId = field.NewUint(table, "workspace_id") + d.CollectionId = field.NewUint(table, "collection_id") + d.ParentId = field.NewUint(table, "parent_id") + d.DeletedAt = field.NewField(table, "deleted_at") + + d.fillFieldMap() + + return d +} + +func (d *document) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := d.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (d *document) fillFieldMap() { + d.fieldMap = make(map[string]field.Expr, 11) + d.fieldMap["id"] = d.Id + d.fieldMap["created_at"] = d.CreatedAt + d.fieldMap["updated_at"] = d.UpdatedAt + d.fieldMap["name"] = d.Name + d.fieldMap["workspace_id"] = d.WorkspaceId + d.fieldMap["collection_id"] = d.CollectionId + d.fieldMap["parent_id"] = d.ParentId + d.fieldMap["deleted_at"] = d.DeletedAt + +} + +func (d document) clone(db *gorm.DB) document { + d.documentDo.ReplaceConnPool(db.Statement.ConnPool) + return d +} + +func (d document) replaceDB(db *gorm.DB) document { + d.documentDo.ReplaceDB(db) + return d +} + +type documentBelongsToWorkspace struct { + db *gorm.DB + + field.RelationField +} + +func (a documentBelongsToWorkspace) Where(conds ...field.Expr) *documentBelongsToWorkspace { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a documentBelongsToWorkspace) WithContext(ctx context.Context) *documentBelongsToWorkspace { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a documentBelongsToWorkspace) Session(session *gorm.Session) *documentBelongsToWorkspace { + a.db = a.db.Session(session) + return &a +} + +func (a documentBelongsToWorkspace) Model(m *entity.Document) *documentBelongsToWorkspaceTx { + return &documentBelongsToWorkspaceTx{a.db.Model(m).Association(a.Name())} +} + +type documentBelongsToWorkspaceTx struct{ tx *gorm.Association } + +func (a documentBelongsToWorkspaceTx) Find() (result *entity.Workspace, err error) { + return result, a.tx.Find(&result) +} + +func (a documentBelongsToWorkspaceTx) Append(values ...*entity.Workspace) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a documentBelongsToWorkspaceTx) Replace(values ...*entity.Workspace) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a documentBelongsToWorkspaceTx) Delete(values ...*entity.Workspace) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a documentBelongsToWorkspaceTx) Clear() error { + return a.tx.Clear() +} + +func (a documentBelongsToWorkspaceTx) Count() int64 { + return a.tx.Count() +} + +type documentBelongsToCollection struct { + db *gorm.DB + + field.RelationField + + Workspace struct { + field.RelationField + } +} + +func (a documentBelongsToCollection) Where(conds ...field.Expr) *documentBelongsToCollection { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a documentBelongsToCollection) WithContext(ctx context.Context) *documentBelongsToCollection { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a documentBelongsToCollection) Session(session *gorm.Session) *documentBelongsToCollection { + a.db = a.db.Session(session) + return &a +} + +func (a documentBelongsToCollection) Model(m *entity.Document) *documentBelongsToCollectionTx { + return &documentBelongsToCollectionTx{a.db.Model(m).Association(a.Name())} +} + +type documentBelongsToCollectionTx struct{ tx *gorm.Association } + +func (a documentBelongsToCollectionTx) Find() (result *entity.Collection, err error) { + return result, a.tx.Find(&result) +} + +func (a documentBelongsToCollectionTx) Append(values ...*entity.Collection) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a documentBelongsToCollectionTx) Replace(values ...*entity.Collection) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a documentBelongsToCollectionTx) Delete(values ...*entity.Collection) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a documentBelongsToCollectionTx) Clear() error { + return a.tx.Clear() +} + +func (a documentBelongsToCollectionTx) Count() int64 { + return a.tx.Count() +} + +type documentBelongsToParent struct { + db *gorm.DB + + field.RelationField + + Workspace struct { + field.RelationField + } + Collection struct { + field.RelationField + } + Parent struct { + field.RelationField + } +} + +func (a documentBelongsToParent) Where(conds ...field.Expr) *documentBelongsToParent { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a documentBelongsToParent) WithContext(ctx context.Context) *documentBelongsToParent { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a documentBelongsToParent) Session(session *gorm.Session) *documentBelongsToParent { + a.db = a.db.Session(session) + return &a +} + +func (a documentBelongsToParent) Model(m *entity.Document) *documentBelongsToParentTx { + return &documentBelongsToParentTx{a.db.Model(m).Association(a.Name())} +} + +type documentBelongsToParentTx struct{ tx *gorm.Association } + +func (a documentBelongsToParentTx) Find() (result *entity.Document, err error) { + return result, a.tx.Find(&result) +} + +func (a documentBelongsToParentTx) Append(values ...*entity.Document) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a documentBelongsToParentTx) Replace(values ...*entity.Document) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a documentBelongsToParentTx) Delete(values ...*entity.Document) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a documentBelongsToParentTx) Clear() error { + return a.tx.Clear() +} + +func (a documentBelongsToParentTx) Count() int64 { + return a.tx.Count() +} + +type documentDo struct{ gen.DO } + +type IDocumentDo interface { + gen.SubQuery + Debug() IDocumentDo + WithContext(ctx context.Context) IDocumentDo + WithResult(fc func(tx gen.Dao)) gen.ResultInfo + ReplaceDB(db *gorm.DB) + ReadDB() IDocumentDo + WriteDB() IDocumentDo + As(alias string) gen.Dao + Session(config *gorm.Session) IDocumentDo + Columns(cols ...field.Expr) gen.Columns + Clauses(conds ...clause.Expression) IDocumentDo + Not(conds ...gen.Condition) IDocumentDo + Or(conds ...gen.Condition) IDocumentDo + Select(conds ...field.Expr) IDocumentDo + Where(conds ...gen.Condition) IDocumentDo + Order(conds ...field.Expr) IDocumentDo + Distinct(cols ...field.Expr) IDocumentDo + Omit(cols ...field.Expr) IDocumentDo + Join(table schema.Tabler, on ...field.Expr) IDocumentDo + LeftJoin(table schema.Tabler, on ...field.Expr) IDocumentDo + RightJoin(table schema.Tabler, on ...field.Expr) IDocumentDo + Group(cols ...field.Expr) IDocumentDo + Having(conds ...gen.Condition) IDocumentDo + Limit(limit int) IDocumentDo + Offset(offset int) IDocumentDo + Count() (count int64, err error) + Scopes(funcs ...func(gen.Dao) gen.Dao) IDocumentDo + Unscoped() IDocumentDo + Create(values ...*entity.Document) error + CreateInBatches(values []*entity.Document, batchSize int) error + Save(values ...*entity.Document) error + First() (*entity.Document, error) + Take() (*entity.Document, error) + Last() (*entity.Document, error) + Find() ([]*entity.Document, error) + FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.Document, err error) + FindInBatches(result *[]*entity.Document, batchSize int, fc func(tx gen.Dao, batch int) error) error + Pluck(column field.Expr, dest interface{}) error + Delete(...*entity.Document) (info gen.ResultInfo, err error) + Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + Updates(value interface{}) (info gen.ResultInfo, err error) + UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + UpdateColumns(value interface{}) (info gen.ResultInfo, err error) + UpdateFrom(q gen.SubQuery) gen.Dao + Attrs(attrs ...field.AssignExpr) IDocumentDo + Assign(attrs ...field.AssignExpr) IDocumentDo + Joins(fields ...field.RelationField) IDocumentDo + Preload(fields ...field.RelationField) IDocumentDo + FirstOrInit() (*entity.Document, error) + FirstOrCreate() (*entity.Document, error) + FindByPage(offset int, limit int) (result []*entity.Document, count int64, err error) + ScanByPage(result interface{}, offset int, limit int) (count int64, err error) + Scan(result interface{}) (err error) + Returning(value interface{}, columns ...string) IDocumentDo + UnderlyingDB() *gorm.DB + schema.Tabler +} + +func (d documentDo) Debug() IDocumentDo { + return d.withDO(d.DO.Debug()) +} + +func (d documentDo) WithContext(ctx context.Context) IDocumentDo { + return d.withDO(d.DO.WithContext(ctx)) +} + +func (d documentDo) ReadDB() IDocumentDo { + return d.Clauses(dbresolver.Read) +} + +func (d documentDo) WriteDB() IDocumentDo { + return d.Clauses(dbresolver.Write) +} + +func (d documentDo) Session(config *gorm.Session) IDocumentDo { + return d.withDO(d.DO.Session(config)) +} + +func (d documentDo) Clauses(conds ...clause.Expression) IDocumentDo { + return d.withDO(d.DO.Clauses(conds...)) +} + +func (d documentDo) Returning(value interface{}, columns ...string) IDocumentDo { + return d.withDO(d.DO.Returning(value, columns...)) +} + +func (d documentDo) Not(conds ...gen.Condition) IDocumentDo { + return d.withDO(d.DO.Not(conds...)) +} + +func (d documentDo) Or(conds ...gen.Condition) IDocumentDo { + return d.withDO(d.DO.Or(conds...)) +} + +func (d documentDo) Select(conds ...field.Expr) IDocumentDo { + return d.withDO(d.DO.Select(conds...)) +} + +func (d documentDo) Where(conds ...gen.Condition) IDocumentDo { + return d.withDO(d.DO.Where(conds...)) +} + +func (d documentDo) Order(conds ...field.Expr) IDocumentDo { + return d.withDO(d.DO.Order(conds...)) +} + +func (d documentDo) Distinct(cols ...field.Expr) IDocumentDo { + return d.withDO(d.DO.Distinct(cols...)) +} + +func (d documentDo) Omit(cols ...field.Expr) IDocumentDo { + return d.withDO(d.DO.Omit(cols...)) +} + +func (d documentDo) Join(table schema.Tabler, on ...field.Expr) IDocumentDo { + return d.withDO(d.DO.Join(table, on...)) +} + +func (d documentDo) LeftJoin(table schema.Tabler, on ...field.Expr) IDocumentDo { + return d.withDO(d.DO.LeftJoin(table, on...)) +} + +func (d documentDo) RightJoin(table schema.Tabler, on ...field.Expr) IDocumentDo { + return d.withDO(d.DO.RightJoin(table, on...)) +} + +func (d documentDo) Group(cols ...field.Expr) IDocumentDo { + return d.withDO(d.DO.Group(cols...)) +} + +func (d documentDo) Having(conds ...gen.Condition) IDocumentDo { + return d.withDO(d.DO.Having(conds...)) +} + +func (d documentDo) Limit(limit int) IDocumentDo { + return d.withDO(d.DO.Limit(limit)) +} + +func (d documentDo) Offset(offset int) IDocumentDo { + return d.withDO(d.DO.Offset(offset)) +} + +func (d documentDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IDocumentDo { + return d.withDO(d.DO.Scopes(funcs...)) +} + +func (d documentDo) Unscoped() IDocumentDo { + return d.withDO(d.DO.Unscoped()) +} + +func (d documentDo) Create(values ...*entity.Document) error { + if len(values) == 0 { + return nil + } + return d.DO.Create(values) +} + +func (d documentDo) CreateInBatches(values []*entity.Document, batchSize int) error { + return d.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (d documentDo) Save(values ...*entity.Document) error { + if len(values) == 0 { + return nil + } + return d.DO.Save(values) +} + +func (d documentDo) First() (*entity.Document, error) { + if result, err := d.DO.First(); err != nil { + return nil, err + } else { + return result.(*entity.Document), nil + } +} + +func (d documentDo) Take() (*entity.Document, error) { + if result, err := d.DO.Take(); err != nil { + return nil, err + } else { + return result.(*entity.Document), nil + } +} + +func (d documentDo) Last() (*entity.Document, error) { + if result, err := d.DO.Last(); err != nil { + return nil, err + } else { + return result.(*entity.Document), nil + } +} + +func (d documentDo) Find() ([]*entity.Document, error) { + result, err := d.DO.Find() + return result.([]*entity.Document), err +} + +func (d documentDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.Document, err error) { + buf := make([]*entity.Document, 0, batchSize) + err = d.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (d documentDo) FindInBatches(result *[]*entity.Document, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return d.DO.FindInBatches(result, batchSize, fc) +} + +func (d documentDo) Attrs(attrs ...field.AssignExpr) IDocumentDo { + return d.withDO(d.DO.Attrs(attrs...)) +} + +func (d documentDo) Assign(attrs ...field.AssignExpr) IDocumentDo { + return d.withDO(d.DO.Assign(attrs...)) +} + +func (d documentDo) Joins(fields ...field.RelationField) IDocumentDo { + for _, _f := range fields { + d = *d.withDO(d.DO.Joins(_f)) + } + return &d +} + +func (d documentDo) Preload(fields ...field.RelationField) IDocumentDo { + for _, _f := range fields { + d = *d.withDO(d.DO.Preload(_f)) + } + return &d +} + +func (d documentDo) FirstOrInit() (*entity.Document, error) { + if result, err := d.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*entity.Document), nil + } +} + +func (d documentDo) FirstOrCreate() (*entity.Document, error) { + if result, err := d.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*entity.Document), nil + } +} + +func (d documentDo) FindByPage(offset int, limit int) (result []*entity.Document, count int64, err error) { + result, err = d.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = d.Offset(-1).Limit(-1).Count() + return +} + +func (d documentDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = d.Count() + if err != nil { + return + } + + err = d.Offset(offset).Limit(limit).Scan(result) + return +} + +func (d documentDo) Scan(result interface{}) (err error) { + return d.DO.Scan(result) +} + +func (d documentDo) Delete(models ...*entity.Document) (result gen.ResultInfo, err error) { + return d.DO.Delete(models) +} + +func (d *documentDo) withDO(do gen.Dao) *documentDo { + d.DO = *do.(*gen.DO) + return d +} diff --git a/internal/dao/gen.go b/internal/dao/gen.go index 13df407..9c2385a 100644 --- a/internal/dao/gen.go +++ b/internal/dao/gen.go @@ -16,34 +16,59 @@ import ( ) var ( - Q = new(Query) - User *user + Q = new(Query) + BlockChunk *blockChunk + Collection *collection + Document *document + DocumentBlock *documentBlock + Workspace *workspace + WorkspaceMember *workspaceMember ) func SetDefault(db *gorm.DB, opts ...gen.DOOption) { *Q = *Use(db, opts...) - User = &Q.User + BlockChunk = &Q.BlockChunk + Collection = &Q.Collection + Document = &Q.Document + DocumentBlock = &Q.DocumentBlock + Workspace = &Q.Workspace + WorkspaceMember = &Q.WorkspaceMember } func Use(db *gorm.DB, opts ...gen.DOOption) *Query { return &Query{ - db: db, - User: newUser(db, opts...), + db: db, + BlockChunk: newBlockChunk(db, opts...), + Collection: newCollection(db, opts...), + Document: newDocument(db, opts...), + DocumentBlock: newDocumentBlock(db, opts...), + Workspace: newWorkspace(db, opts...), + WorkspaceMember: newWorkspaceMember(db, opts...), } } type Query struct { db *gorm.DB - User user + BlockChunk blockChunk + Collection collection + Document document + DocumentBlock documentBlock + Workspace workspace + WorkspaceMember workspaceMember } func (q *Query) Available() bool { return q.db != nil } func (q *Query) clone(db *gorm.DB) *Query { return &Query{ - db: db, - User: q.User.clone(db), + db: db, + BlockChunk: q.BlockChunk.clone(db), + Collection: q.Collection.clone(db), + Document: q.Document.clone(db), + DocumentBlock: q.DocumentBlock.clone(db), + Workspace: q.Workspace.clone(db), + WorkspaceMember: q.WorkspaceMember.clone(db), } } @@ -57,18 +82,33 @@ func (q *Query) WriteDB() *Query { func (q *Query) ReplaceDB(db *gorm.DB) *Query { return &Query{ - db: db, - User: q.User.replaceDB(db), + db: db, + BlockChunk: q.BlockChunk.replaceDB(db), + Collection: q.Collection.replaceDB(db), + Document: q.Document.replaceDB(db), + DocumentBlock: q.DocumentBlock.replaceDB(db), + Workspace: q.Workspace.replaceDB(db), + WorkspaceMember: q.WorkspaceMember.replaceDB(db), } } type queryCtx struct { - User IUserDo + BlockChunk IBlockChunkDo + Collection ICollectionDo + Document IDocumentDo + DocumentBlock IDocumentBlockDo + Workspace IWorkspaceDo + WorkspaceMember IWorkspaceMemberDo } func (q *Query) WithContext(ctx context.Context) *queryCtx { return &queryCtx{ - User: q.User.WithContext(ctx), + BlockChunk: q.BlockChunk.WithContext(ctx), + Collection: q.Collection.WithContext(ctx), + Document: q.Document.WithContext(ctx), + DocumentBlock: q.DocumentBlock.WithContext(ctx), + Workspace: q.Workspace.WithContext(ctx), + WorkspaceMember: q.WorkspaceMember.WithContext(ctx), } } diff --git a/internal/dao/users.gen.go b/internal/dao/users.gen.go deleted file mode 100644 index 70c2ea1..0000000 --- a/internal/dao/users.gen.go +++ /dev/null @@ -1,392 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package dao - -import ( - "context" - - "gorm.io/gorm" - "gorm.io/gorm/clause" - "gorm.io/gorm/schema" - - "gorm.io/gen" - "gorm.io/gen/field" - - "gorm.io/plugin/dbresolver" - - "leafdev.top/Leaf/leaf-library-3/internal/entity" -) - -func newUser(db *gorm.DB, opts ...gen.DOOption) user { - _user := user{} - - _user.userDo.UseDB(db, opts...) - _user.userDo.UseModel(&entity.User{}) - - tableName := _user.userDo.TableName() - _user.ALL = field.NewAsterisk(tableName) - _user.Id = field.NewUint(tableName, "id") - _user.CreatedAt = field.NewTime(tableName, "created_at") - _user.UpdatedAt = field.NewTime(tableName, "updated_at") - _user.Name = field.NewString(tableName, "name") - - _user.fillFieldMap() - - return _user -} - -type user struct { - userDo - - ALL field.Asterisk - Id field.Uint - CreatedAt field.Time - UpdatedAt field.Time - Name field.String - - fieldMap map[string]field.Expr -} - -func (u user) Table(newTableName string) *user { - u.userDo.UseTable(newTableName) - return u.updateTableName(newTableName) -} - -func (u user) As(alias string) *user { - u.userDo.DO = *(u.userDo.As(alias).(*gen.DO)) - return u.updateTableName(alias) -} - -func (u *user) updateTableName(table string) *user { - u.ALL = field.NewAsterisk(table) - u.Id = field.NewUint(table, "id") - u.CreatedAt = field.NewTime(table, "created_at") - u.UpdatedAt = field.NewTime(table, "updated_at") - u.Name = field.NewString(table, "name") - - u.fillFieldMap() - - return u -} - -func (u *user) GetFieldByName(fieldName string) (field.OrderExpr, bool) { - _f, ok := u.fieldMap[fieldName] - if !ok || _f == nil { - return nil, false - } - _oe, ok := _f.(field.OrderExpr) - return _oe, ok -} - -func (u *user) fillFieldMap() { - u.fieldMap = make(map[string]field.Expr, 4) - u.fieldMap["id"] = u.Id - u.fieldMap["created_at"] = u.CreatedAt - u.fieldMap["updated_at"] = u.UpdatedAt - u.fieldMap["name"] = u.Name -} - -func (u user) clone(db *gorm.DB) user { - u.userDo.ReplaceConnPool(db.Statement.ConnPool) - return u -} - -func (u user) replaceDB(db *gorm.DB) user { - u.userDo.ReplaceDB(db) - return u -} - -type userDo struct{ gen.DO } - -type IUserDo interface { - gen.SubQuery - Debug() IUserDo - WithContext(ctx context.Context) IUserDo - WithResult(fc func(tx gen.Dao)) gen.ResultInfo - ReplaceDB(db *gorm.DB) - ReadDB() IUserDo - WriteDB() IUserDo - As(alias string) gen.Dao - Session(config *gorm.Session) IUserDo - Columns(cols ...field.Expr) gen.Columns - Clauses(conds ...clause.Expression) IUserDo - Not(conds ...gen.Condition) IUserDo - Or(conds ...gen.Condition) IUserDo - Select(conds ...field.Expr) IUserDo - Where(conds ...gen.Condition) IUserDo - Order(conds ...field.Expr) IUserDo - Distinct(cols ...field.Expr) IUserDo - Omit(cols ...field.Expr) IUserDo - Join(table schema.Tabler, on ...field.Expr) IUserDo - LeftJoin(table schema.Tabler, on ...field.Expr) IUserDo - RightJoin(table schema.Tabler, on ...field.Expr) IUserDo - Group(cols ...field.Expr) IUserDo - Having(conds ...gen.Condition) IUserDo - Limit(limit int) IUserDo - Offset(offset int) IUserDo - Count() (count int64, err error) - Scopes(funcs ...func(gen.Dao) gen.Dao) IUserDo - Unscoped() IUserDo - Create(values ...*entity.User) error - CreateInBatches(values []*entity.User, batchSize int) error - Save(values ...*entity.User) error - First() (*entity.User, error) - Take() (*entity.User, error) - Last() (*entity.User, error) - Find() ([]*entity.User, error) - FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.User, err error) - FindInBatches(result *[]*entity.User, batchSize int, fc func(tx gen.Dao, batch int) error) error - Pluck(column field.Expr, dest interface{}) error - Delete(...*entity.User) (info gen.ResultInfo, err error) - Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error) - UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) - Updates(value interface{}) (info gen.ResultInfo, err error) - UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error) - UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) - UpdateColumns(value interface{}) (info gen.ResultInfo, err error) - UpdateFrom(q gen.SubQuery) gen.Dao - Attrs(attrs ...field.AssignExpr) IUserDo - Assign(attrs ...field.AssignExpr) IUserDo - Joins(fields ...field.RelationField) IUserDo - Preload(fields ...field.RelationField) IUserDo - FirstOrInit() (*entity.User, error) - FirstOrCreate() (*entity.User, error) - FindByPage(offset int, limit int) (result []*entity.User, count int64, err error) - ScanByPage(result interface{}, offset int, limit int) (count int64, err error) - Scan(result interface{}) (err error) - Returning(value interface{}, columns ...string) IUserDo - UnderlyingDB() *gorm.DB - schema.Tabler -} - -func (u userDo) Debug() IUserDo { - return u.withDO(u.DO.Debug()) -} - -func (u userDo) WithContext(ctx context.Context) IUserDo { - return u.withDO(u.DO.WithContext(ctx)) -} - -func (u userDo) ReadDB() IUserDo { - return u.Clauses(dbresolver.Read) -} - -func (u userDo) WriteDB() IUserDo { - return u.Clauses(dbresolver.Write) -} - -func (u userDo) Session(config *gorm.Session) IUserDo { - return u.withDO(u.DO.Session(config)) -} - -func (u userDo) Clauses(conds ...clause.Expression) IUserDo { - return u.withDO(u.DO.Clauses(conds...)) -} - -func (u userDo) Returning(value interface{}, columns ...string) IUserDo { - return u.withDO(u.DO.Returning(value, columns...)) -} - -func (u userDo) Not(conds ...gen.Condition) IUserDo { - return u.withDO(u.DO.Not(conds...)) -} - -func (u userDo) Or(conds ...gen.Condition) IUserDo { - return u.withDO(u.DO.Or(conds...)) -} - -func (u userDo) Select(conds ...field.Expr) IUserDo { - return u.withDO(u.DO.Select(conds...)) -} - -func (u userDo) Where(conds ...gen.Condition) IUserDo { - return u.withDO(u.DO.Where(conds...)) -} - -func (u userDo) Order(conds ...field.Expr) IUserDo { - return u.withDO(u.DO.Order(conds...)) -} - -func (u userDo) Distinct(cols ...field.Expr) IUserDo { - return u.withDO(u.DO.Distinct(cols...)) -} - -func (u userDo) Omit(cols ...field.Expr) IUserDo { - return u.withDO(u.DO.Omit(cols...)) -} - -func (u userDo) Join(table schema.Tabler, on ...field.Expr) IUserDo { - return u.withDO(u.DO.Join(table, on...)) -} - -func (u userDo) LeftJoin(table schema.Tabler, on ...field.Expr) IUserDo { - return u.withDO(u.DO.LeftJoin(table, on...)) -} - -func (u userDo) RightJoin(table schema.Tabler, on ...field.Expr) IUserDo { - return u.withDO(u.DO.RightJoin(table, on...)) -} - -func (u userDo) Group(cols ...field.Expr) IUserDo { - return u.withDO(u.DO.Group(cols...)) -} - -func (u userDo) Having(conds ...gen.Condition) IUserDo { - return u.withDO(u.DO.Having(conds...)) -} - -func (u userDo) Limit(limit int) IUserDo { - return u.withDO(u.DO.Limit(limit)) -} - -func (u userDo) Offset(offset int) IUserDo { - return u.withDO(u.DO.Offset(offset)) -} - -func (u userDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IUserDo { - return u.withDO(u.DO.Scopes(funcs...)) -} - -func (u userDo) Unscoped() IUserDo { - return u.withDO(u.DO.Unscoped()) -} - -func (u userDo) Create(values ...*entity.User) error { - if len(values) == 0 { - return nil - } - return u.DO.Create(values) -} - -func (u userDo) CreateInBatches(values []*entity.User, batchSize int) error { - return u.DO.CreateInBatches(values, batchSize) -} - -// Save : !!! underlying implementation is different with GORM -// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) -func (u userDo) Save(values ...*entity.User) error { - if len(values) == 0 { - return nil - } - return u.DO.Save(values) -} - -func (u userDo) First() (*entity.User, error) { - if result, err := u.DO.First(); err != nil { - return nil, err - } else { - return result.(*entity.User), nil - } -} - -func (u userDo) Take() (*entity.User, error) { - if result, err := u.DO.Take(); err != nil { - return nil, err - } else { - return result.(*entity.User), nil - } -} - -func (u userDo) Last() (*entity.User, error) { - if result, err := u.DO.Last(); err != nil { - return nil, err - } else { - return result.(*entity.User), nil - } -} - -func (u userDo) Find() ([]*entity.User, error) { - result, err := u.DO.Find() - return result.([]*entity.User), err -} - -func (u userDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.User, err error) { - buf := make([]*entity.User, 0, batchSize) - err = u.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { - defer func() { results = append(results, buf...) }() - return fc(tx, batch) - }) - return results, err -} - -func (u userDo) FindInBatches(result *[]*entity.User, batchSize int, fc func(tx gen.Dao, batch int) error) error { - return u.DO.FindInBatches(result, batchSize, fc) -} - -func (u userDo) Attrs(attrs ...field.AssignExpr) IUserDo { - return u.withDO(u.DO.Attrs(attrs...)) -} - -func (u userDo) Assign(attrs ...field.AssignExpr) IUserDo { - return u.withDO(u.DO.Assign(attrs...)) -} - -func (u userDo) Joins(fields ...field.RelationField) IUserDo { - for _, _f := range fields { - u = *u.withDO(u.DO.Joins(_f)) - } - return &u -} - -func (u userDo) Preload(fields ...field.RelationField) IUserDo { - for _, _f := range fields { - u = *u.withDO(u.DO.Preload(_f)) - } - return &u -} - -func (u userDo) FirstOrInit() (*entity.User, error) { - if result, err := u.DO.FirstOrInit(); err != nil { - return nil, err - } else { - return result.(*entity.User), nil - } -} - -func (u userDo) FirstOrCreate() (*entity.User, error) { - if result, err := u.DO.FirstOrCreate(); err != nil { - return nil, err - } else { - return result.(*entity.User), nil - } -} - -func (u userDo) FindByPage(offset int, limit int) (result []*entity.User, count int64, err error) { - result, err = u.Offset(offset).Limit(limit).Find() - if err != nil { - return - } - - if size := len(result); 0 < limit && 0 < size && size < limit { - count = int64(size + offset) - return - } - - count, err = u.Offset(-1).Limit(-1).Count() - return -} - -func (u userDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { - count, err = u.Count() - if err != nil { - return - } - - err = u.Offset(offset).Limit(limit).Scan(result) - return -} - -func (u userDo) Scan(result interface{}) (err error) { - return u.DO.Scan(result) -} - -func (u userDo) Delete(models ...*entity.User) (result gen.ResultInfo, err error) { - return u.DO.Delete(models) -} - -func (u *userDo) withDO(do gen.Dao) *userDo { - u.DO = *do.(*gen.DO) - return u -} diff --git a/internal/dao/workspace_members.gen.go b/internal/dao/workspace_members.gen.go new file mode 100644 index 0000000..9ae2fbe --- /dev/null +++ b/internal/dao/workspace_members.gen.go @@ -0,0 +1,474 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package dao + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "leafdev.top/Leaf/leaf-library-3/internal/entity" +) + +func newWorkspaceMember(db *gorm.DB, opts ...gen.DOOption) workspaceMember { + _workspaceMember := workspaceMember{} + + _workspaceMember.workspaceMemberDo.UseDB(db, opts...) + _workspaceMember.workspaceMemberDo.UseModel(&entity.WorkspaceMember{}) + + tableName := _workspaceMember.workspaceMemberDo.TableName() + _workspaceMember.ALL = field.NewAsterisk(tableName) + _workspaceMember.Id = field.NewUint(tableName, "id") + _workspaceMember.CreatedAt = field.NewTime(tableName, "created_at") + _workspaceMember.UpdatedAt = field.NewTime(tableName, "updated_at") + _workspaceMember.WorkspaceId = field.NewUint(tableName, "workspace_id") + _workspaceMember.UserId = field.NewString(tableName, "user_id") + _workspaceMember.Workspace = workspaceMemberBelongsToWorkspace{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Workspace", "entity.Workspace"), + } + + _workspaceMember.fillFieldMap() + + return _workspaceMember +} + +type workspaceMember struct { + workspaceMemberDo + + ALL field.Asterisk + Id field.Uint + CreatedAt field.Time + UpdatedAt field.Time + WorkspaceId field.Uint + UserId field.String + Workspace workspaceMemberBelongsToWorkspace + + fieldMap map[string]field.Expr +} + +func (w workspaceMember) Table(newTableName string) *workspaceMember { + w.workspaceMemberDo.UseTable(newTableName) + return w.updateTableName(newTableName) +} + +func (w workspaceMember) As(alias string) *workspaceMember { + w.workspaceMemberDo.DO = *(w.workspaceMemberDo.As(alias).(*gen.DO)) + return w.updateTableName(alias) +} + +func (w *workspaceMember) updateTableName(table string) *workspaceMember { + w.ALL = field.NewAsterisk(table) + w.Id = field.NewUint(table, "id") + w.CreatedAt = field.NewTime(table, "created_at") + w.UpdatedAt = field.NewTime(table, "updated_at") + w.WorkspaceId = field.NewUint(table, "workspace_id") + w.UserId = field.NewString(table, "user_id") + + w.fillFieldMap() + + return w +} + +func (w *workspaceMember) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := w.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (w *workspaceMember) fillFieldMap() { + w.fieldMap = make(map[string]field.Expr, 6) + w.fieldMap["id"] = w.Id + w.fieldMap["created_at"] = w.CreatedAt + w.fieldMap["updated_at"] = w.UpdatedAt + w.fieldMap["workspace_id"] = w.WorkspaceId + w.fieldMap["user_id"] = w.UserId + +} + +func (w workspaceMember) clone(db *gorm.DB) workspaceMember { + w.workspaceMemberDo.ReplaceConnPool(db.Statement.ConnPool) + return w +} + +func (w workspaceMember) replaceDB(db *gorm.DB) workspaceMember { + w.workspaceMemberDo.ReplaceDB(db) + return w +} + +type workspaceMemberBelongsToWorkspace struct { + db *gorm.DB + + field.RelationField +} + +func (a workspaceMemberBelongsToWorkspace) Where(conds ...field.Expr) *workspaceMemberBelongsToWorkspace { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a workspaceMemberBelongsToWorkspace) WithContext(ctx context.Context) *workspaceMemberBelongsToWorkspace { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a workspaceMemberBelongsToWorkspace) Session(session *gorm.Session) *workspaceMemberBelongsToWorkspace { + a.db = a.db.Session(session) + return &a +} + +func (a workspaceMemberBelongsToWorkspace) Model(m *entity.WorkspaceMember) *workspaceMemberBelongsToWorkspaceTx { + return &workspaceMemberBelongsToWorkspaceTx{a.db.Model(m).Association(a.Name())} +} + +type workspaceMemberBelongsToWorkspaceTx struct{ tx *gorm.Association } + +func (a workspaceMemberBelongsToWorkspaceTx) Find() (result *entity.Workspace, err error) { + return result, a.tx.Find(&result) +} + +func (a workspaceMemberBelongsToWorkspaceTx) Append(values ...*entity.Workspace) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a workspaceMemberBelongsToWorkspaceTx) Replace(values ...*entity.Workspace) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a workspaceMemberBelongsToWorkspaceTx) Delete(values ...*entity.Workspace) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a workspaceMemberBelongsToWorkspaceTx) Clear() error { + return a.tx.Clear() +} + +func (a workspaceMemberBelongsToWorkspaceTx) Count() int64 { + return a.tx.Count() +} + +type workspaceMemberDo struct{ gen.DO } + +type IWorkspaceMemberDo interface { + gen.SubQuery + Debug() IWorkspaceMemberDo + WithContext(ctx context.Context) IWorkspaceMemberDo + WithResult(fc func(tx gen.Dao)) gen.ResultInfo + ReplaceDB(db *gorm.DB) + ReadDB() IWorkspaceMemberDo + WriteDB() IWorkspaceMemberDo + As(alias string) gen.Dao + Session(config *gorm.Session) IWorkspaceMemberDo + Columns(cols ...field.Expr) gen.Columns + Clauses(conds ...clause.Expression) IWorkspaceMemberDo + Not(conds ...gen.Condition) IWorkspaceMemberDo + Or(conds ...gen.Condition) IWorkspaceMemberDo + Select(conds ...field.Expr) IWorkspaceMemberDo + Where(conds ...gen.Condition) IWorkspaceMemberDo + Order(conds ...field.Expr) IWorkspaceMemberDo + Distinct(cols ...field.Expr) IWorkspaceMemberDo + Omit(cols ...field.Expr) IWorkspaceMemberDo + Join(table schema.Tabler, on ...field.Expr) IWorkspaceMemberDo + LeftJoin(table schema.Tabler, on ...field.Expr) IWorkspaceMemberDo + RightJoin(table schema.Tabler, on ...field.Expr) IWorkspaceMemberDo + Group(cols ...field.Expr) IWorkspaceMemberDo + Having(conds ...gen.Condition) IWorkspaceMemberDo + Limit(limit int) IWorkspaceMemberDo + Offset(offset int) IWorkspaceMemberDo + Count() (count int64, err error) + Scopes(funcs ...func(gen.Dao) gen.Dao) IWorkspaceMemberDo + Unscoped() IWorkspaceMemberDo + Create(values ...*entity.WorkspaceMember) error + CreateInBatches(values []*entity.WorkspaceMember, batchSize int) error + Save(values ...*entity.WorkspaceMember) error + First() (*entity.WorkspaceMember, error) + Take() (*entity.WorkspaceMember, error) + Last() (*entity.WorkspaceMember, error) + Find() ([]*entity.WorkspaceMember, error) + FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.WorkspaceMember, err error) + FindInBatches(result *[]*entity.WorkspaceMember, batchSize int, fc func(tx gen.Dao, batch int) error) error + Pluck(column field.Expr, dest interface{}) error + Delete(...*entity.WorkspaceMember) (info gen.ResultInfo, err error) + Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + Updates(value interface{}) (info gen.ResultInfo, err error) + UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + UpdateColumns(value interface{}) (info gen.ResultInfo, err error) + UpdateFrom(q gen.SubQuery) gen.Dao + Attrs(attrs ...field.AssignExpr) IWorkspaceMemberDo + Assign(attrs ...field.AssignExpr) IWorkspaceMemberDo + Joins(fields ...field.RelationField) IWorkspaceMemberDo + Preload(fields ...field.RelationField) IWorkspaceMemberDo + FirstOrInit() (*entity.WorkspaceMember, error) + FirstOrCreate() (*entity.WorkspaceMember, error) + FindByPage(offset int, limit int) (result []*entity.WorkspaceMember, count int64, err error) + ScanByPage(result interface{}, offset int, limit int) (count int64, err error) + Scan(result interface{}) (err error) + Returning(value interface{}, columns ...string) IWorkspaceMemberDo + UnderlyingDB() *gorm.DB + schema.Tabler +} + +func (w workspaceMemberDo) Debug() IWorkspaceMemberDo { + return w.withDO(w.DO.Debug()) +} + +func (w workspaceMemberDo) WithContext(ctx context.Context) IWorkspaceMemberDo { + return w.withDO(w.DO.WithContext(ctx)) +} + +func (w workspaceMemberDo) ReadDB() IWorkspaceMemberDo { + return w.Clauses(dbresolver.Read) +} + +func (w workspaceMemberDo) WriteDB() IWorkspaceMemberDo { + return w.Clauses(dbresolver.Write) +} + +func (w workspaceMemberDo) Session(config *gorm.Session) IWorkspaceMemberDo { + return w.withDO(w.DO.Session(config)) +} + +func (w workspaceMemberDo) Clauses(conds ...clause.Expression) IWorkspaceMemberDo { + return w.withDO(w.DO.Clauses(conds...)) +} + +func (w workspaceMemberDo) Returning(value interface{}, columns ...string) IWorkspaceMemberDo { + return w.withDO(w.DO.Returning(value, columns...)) +} + +func (w workspaceMemberDo) Not(conds ...gen.Condition) IWorkspaceMemberDo { + return w.withDO(w.DO.Not(conds...)) +} + +func (w workspaceMemberDo) Or(conds ...gen.Condition) IWorkspaceMemberDo { + return w.withDO(w.DO.Or(conds...)) +} + +func (w workspaceMemberDo) Select(conds ...field.Expr) IWorkspaceMemberDo { + return w.withDO(w.DO.Select(conds...)) +} + +func (w workspaceMemberDo) Where(conds ...gen.Condition) IWorkspaceMemberDo { + return w.withDO(w.DO.Where(conds...)) +} + +func (w workspaceMemberDo) Order(conds ...field.Expr) IWorkspaceMemberDo { + return w.withDO(w.DO.Order(conds...)) +} + +func (w workspaceMemberDo) Distinct(cols ...field.Expr) IWorkspaceMemberDo { + return w.withDO(w.DO.Distinct(cols...)) +} + +func (w workspaceMemberDo) Omit(cols ...field.Expr) IWorkspaceMemberDo { + return w.withDO(w.DO.Omit(cols...)) +} + +func (w workspaceMemberDo) Join(table schema.Tabler, on ...field.Expr) IWorkspaceMemberDo { + return w.withDO(w.DO.Join(table, on...)) +} + +func (w workspaceMemberDo) LeftJoin(table schema.Tabler, on ...field.Expr) IWorkspaceMemberDo { + return w.withDO(w.DO.LeftJoin(table, on...)) +} + +func (w workspaceMemberDo) RightJoin(table schema.Tabler, on ...field.Expr) IWorkspaceMemberDo { + return w.withDO(w.DO.RightJoin(table, on...)) +} + +func (w workspaceMemberDo) Group(cols ...field.Expr) IWorkspaceMemberDo { + return w.withDO(w.DO.Group(cols...)) +} + +func (w workspaceMemberDo) Having(conds ...gen.Condition) IWorkspaceMemberDo { + return w.withDO(w.DO.Having(conds...)) +} + +func (w workspaceMemberDo) Limit(limit int) IWorkspaceMemberDo { + return w.withDO(w.DO.Limit(limit)) +} + +func (w workspaceMemberDo) Offset(offset int) IWorkspaceMemberDo { + return w.withDO(w.DO.Offset(offset)) +} + +func (w workspaceMemberDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IWorkspaceMemberDo { + return w.withDO(w.DO.Scopes(funcs...)) +} + +func (w workspaceMemberDo) Unscoped() IWorkspaceMemberDo { + return w.withDO(w.DO.Unscoped()) +} + +func (w workspaceMemberDo) Create(values ...*entity.WorkspaceMember) error { + if len(values) == 0 { + return nil + } + return w.DO.Create(values) +} + +func (w workspaceMemberDo) CreateInBatches(values []*entity.WorkspaceMember, batchSize int) error { + return w.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (w workspaceMemberDo) Save(values ...*entity.WorkspaceMember) error { + if len(values) == 0 { + return nil + } + return w.DO.Save(values) +} + +func (w workspaceMemberDo) First() (*entity.WorkspaceMember, error) { + if result, err := w.DO.First(); err != nil { + return nil, err + } else { + return result.(*entity.WorkspaceMember), nil + } +} + +func (w workspaceMemberDo) Take() (*entity.WorkspaceMember, error) { + if result, err := w.DO.Take(); err != nil { + return nil, err + } else { + return result.(*entity.WorkspaceMember), nil + } +} + +func (w workspaceMemberDo) Last() (*entity.WorkspaceMember, error) { + if result, err := w.DO.Last(); err != nil { + return nil, err + } else { + return result.(*entity.WorkspaceMember), nil + } +} + +func (w workspaceMemberDo) Find() ([]*entity.WorkspaceMember, error) { + result, err := w.DO.Find() + return result.([]*entity.WorkspaceMember), err +} + +func (w workspaceMemberDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.WorkspaceMember, err error) { + buf := make([]*entity.WorkspaceMember, 0, batchSize) + err = w.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (w workspaceMemberDo) FindInBatches(result *[]*entity.WorkspaceMember, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return w.DO.FindInBatches(result, batchSize, fc) +} + +func (w workspaceMemberDo) Attrs(attrs ...field.AssignExpr) IWorkspaceMemberDo { + return w.withDO(w.DO.Attrs(attrs...)) +} + +func (w workspaceMemberDo) Assign(attrs ...field.AssignExpr) IWorkspaceMemberDo { + return w.withDO(w.DO.Assign(attrs...)) +} + +func (w workspaceMemberDo) Joins(fields ...field.RelationField) IWorkspaceMemberDo { + for _, _f := range fields { + w = *w.withDO(w.DO.Joins(_f)) + } + return &w +} + +func (w workspaceMemberDo) Preload(fields ...field.RelationField) IWorkspaceMemberDo { + for _, _f := range fields { + w = *w.withDO(w.DO.Preload(_f)) + } + return &w +} + +func (w workspaceMemberDo) FirstOrInit() (*entity.WorkspaceMember, error) { + if result, err := w.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*entity.WorkspaceMember), nil + } +} + +func (w workspaceMemberDo) FirstOrCreate() (*entity.WorkspaceMember, error) { + if result, err := w.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*entity.WorkspaceMember), nil + } +} + +func (w workspaceMemberDo) FindByPage(offset int, limit int) (result []*entity.WorkspaceMember, count int64, err error) { + result, err = w.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = w.Offset(-1).Limit(-1).Count() + return +} + +func (w workspaceMemberDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = w.Count() + if err != nil { + return + } + + err = w.Offset(offset).Limit(limit).Scan(result) + return +} + +func (w workspaceMemberDo) Scan(result interface{}) (err error) { + return w.DO.Scan(result) +} + +func (w workspaceMemberDo) Delete(models ...*entity.WorkspaceMember) (result gen.ResultInfo, err error) { + return w.DO.Delete(models) +} + +func (w *workspaceMemberDo) withDO(do gen.Dao) *workspaceMemberDo { + w.DO = *do.(*gen.DO) + return w +} diff --git a/internal/dao/workspaces.gen.go b/internal/dao/workspaces.gen.go new file mode 100644 index 0000000..4d4b4af --- /dev/null +++ b/internal/dao/workspaces.gen.go @@ -0,0 +1,400 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package dao + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "leafdev.top/Leaf/leaf-library-3/internal/entity" +) + +func newWorkspace(db *gorm.DB, opts ...gen.DOOption) workspace { + _workspace := workspace{} + + _workspace.workspaceDo.UseDB(db, opts...) + _workspace.workspaceDo.UseModel(&entity.Workspace{}) + + tableName := _workspace.workspaceDo.TableName() + _workspace.ALL = field.NewAsterisk(tableName) + _workspace.Id = field.NewUint(tableName, "id") + _workspace.CreatedAt = field.NewTime(tableName, "created_at") + _workspace.UpdatedAt = field.NewTime(tableName, "updated_at") + _workspace.Name = field.NewString(tableName, "name") + _workspace.UserId = field.NewString(tableName, "user_id") + _workspace.DeletedAt = field.NewField(tableName, "deleted_at") + + _workspace.fillFieldMap() + + return _workspace +} + +type workspace struct { + workspaceDo + + ALL field.Asterisk + Id field.Uint + CreatedAt field.Time + UpdatedAt field.Time + Name field.String + UserId field.String + DeletedAt field.Field + + fieldMap map[string]field.Expr +} + +func (w workspace) Table(newTableName string) *workspace { + w.workspaceDo.UseTable(newTableName) + return w.updateTableName(newTableName) +} + +func (w workspace) As(alias string) *workspace { + w.workspaceDo.DO = *(w.workspaceDo.As(alias).(*gen.DO)) + return w.updateTableName(alias) +} + +func (w *workspace) updateTableName(table string) *workspace { + w.ALL = field.NewAsterisk(table) + w.Id = field.NewUint(table, "id") + w.CreatedAt = field.NewTime(table, "created_at") + w.UpdatedAt = field.NewTime(table, "updated_at") + w.Name = field.NewString(table, "name") + w.UserId = field.NewString(table, "user_id") + w.DeletedAt = field.NewField(table, "deleted_at") + + w.fillFieldMap() + + return w +} + +func (w *workspace) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := w.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (w *workspace) fillFieldMap() { + w.fieldMap = make(map[string]field.Expr, 6) + w.fieldMap["id"] = w.Id + w.fieldMap["created_at"] = w.CreatedAt + w.fieldMap["updated_at"] = w.UpdatedAt + w.fieldMap["name"] = w.Name + w.fieldMap["user_id"] = w.UserId + w.fieldMap["deleted_at"] = w.DeletedAt +} + +func (w workspace) clone(db *gorm.DB) workspace { + w.workspaceDo.ReplaceConnPool(db.Statement.ConnPool) + return w +} + +func (w workspace) replaceDB(db *gorm.DB) workspace { + w.workspaceDo.ReplaceDB(db) + return w +} + +type workspaceDo struct{ gen.DO } + +type IWorkspaceDo interface { + gen.SubQuery + Debug() IWorkspaceDo + WithContext(ctx context.Context) IWorkspaceDo + WithResult(fc func(tx gen.Dao)) gen.ResultInfo + ReplaceDB(db *gorm.DB) + ReadDB() IWorkspaceDo + WriteDB() IWorkspaceDo + As(alias string) gen.Dao + Session(config *gorm.Session) IWorkspaceDo + Columns(cols ...field.Expr) gen.Columns + Clauses(conds ...clause.Expression) IWorkspaceDo + Not(conds ...gen.Condition) IWorkspaceDo + Or(conds ...gen.Condition) IWorkspaceDo + Select(conds ...field.Expr) IWorkspaceDo + Where(conds ...gen.Condition) IWorkspaceDo + Order(conds ...field.Expr) IWorkspaceDo + Distinct(cols ...field.Expr) IWorkspaceDo + Omit(cols ...field.Expr) IWorkspaceDo + Join(table schema.Tabler, on ...field.Expr) IWorkspaceDo + LeftJoin(table schema.Tabler, on ...field.Expr) IWorkspaceDo + RightJoin(table schema.Tabler, on ...field.Expr) IWorkspaceDo + Group(cols ...field.Expr) IWorkspaceDo + Having(conds ...gen.Condition) IWorkspaceDo + Limit(limit int) IWorkspaceDo + Offset(offset int) IWorkspaceDo + Count() (count int64, err error) + Scopes(funcs ...func(gen.Dao) gen.Dao) IWorkspaceDo + Unscoped() IWorkspaceDo + Create(values ...*entity.Workspace) error + CreateInBatches(values []*entity.Workspace, batchSize int) error + Save(values ...*entity.Workspace) error + First() (*entity.Workspace, error) + Take() (*entity.Workspace, error) + Last() (*entity.Workspace, error) + Find() ([]*entity.Workspace, error) + FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.Workspace, err error) + FindInBatches(result *[]*entity.Workspace, batchSize int, fc func(tx gen.Dao, batch int) error) error + Pluck(column field.Expr, dest interface{}) error + Delete(...*entity.Workspace) (info gen.ResultInfo, err error) + Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + Updates(value interface{}) (info gen.ResultInfo, err error) + UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + UpdateColumns(value interface{}) (info gen.ResultInfo, err error) + UpdateFrom(q gen.SubQuery) gen.Dao + Attrs(attrs ...field.AssignExpr) IWorkspaceDo + Assign(attrs ...field.AssignExpr) IWorkspaceDo + Joins(fields ...field.RelationField) IWorkspaceDo + Preload(fields ...field.RelationField) IWorkspaceDo + FirstOrInit() (*entity.Workspace, error) + FirstOrCreate() (*entity.Workspace, error) + FindByPage(offset int, limit int) (result []*entity.Workspace, count int64, err error) + ScanByPage(result interface{}, offset int, limit int) (count int64, err error) + Scan(result interface{}) (err error) + Returning(value interface{}, columns ...string) IWorkspaceDo + UnderlyingDB() *gorm.DB + schema.Tabler +} + +func (w workspaceDo) Debug() IWorkspaceDo { + return w.withDO(w.DO.Debug()) +} + +func (w workspaceDo) WithContext(ctx context.Context) IWorkspaceDo { + return w.withDO(w.DO.WithContext(ctx)) +} + +func (w workspaceDo) ReadDB() IWorkspaceDo { + return w.Clauses(dbresolver.Read) +} + +func (w workspaceDo) WriteDB() IWorkspaceDo { + return w.Clauses(dbresolver.Write) +} + +func (w workspaceDo) Session(config *gorm.Session) IWorkspaceDo { + return w.withDO(w.DO.Session(config)) +} + +func (w workspaceDo) Clauses(conds ...clause.Expression) IWorkspaceDo { + return w.withDO(w.DO.Clauses(conds...)) +} + +func (w workspaceDo) Returning(value interface{}, columns ...string) IWorkspaceDo { + return w.withDO(w.DO.Returning(value, columns...)) +} + +func (w workspaceDo) Not(conds ...gen.Condition) IWorkspaceDo { + return w.withDO(w.DO.Not(conds...)) +} + +func (w workspaceDo) Or(conds ...gen.Condition) IWorkspaceDo { + return w.withDO(w.DO.Or(conds...)) +} + +func (w workspaceDo) Select(conds ...field.Expr) IWorkspaceDo { + return w.withDO(w.DO.Select(conds...)) +} + +func (w workspaceDo) Where(conds ...gen.Condition) IWorkspaceDo { + return w.withDO(w.DO.Where(conds...)) +} + +func (w workspaceDo) Order(conds ...field.Expr) IWorkspaceDo { + return w.withDO(w.DO.Order(conds...)) +} + +func (w workspaceDo) Distinct(cols ...field.Expr) IWorkspaceDo { + return w.withDO(w.DO.Distinct(cols...)) +} + +func (w workspaceDo) Omit(cols ...field.Expr) IWorkspaceDo { + return w.withDO(w.DO.Omit(cols...)) +} + +func (w workspaceDo) Join(table schema.Tabler, on ...field.Expr) IWorkspaceDo { + return w.withDO(w.DO.Join(table, on...)) +} + +func (w workspaceDo) LeftJoin(table schema.Tabler, on ...field.Expr) IWorkspaceDo { + return w.withDO(w.DO.LeftJoin(table, on...)) +} + +func (w workspaceDo) RightJoin(table schema.Tabler, on ...field.Expr) IWorkspaceDo { + return w.withDO(w.DO.RightJoin(table, on...)) +} + +func (w workspaceDo) Group(cols ...field.Expr) IWorkspaceDo { + return w.withDO(w.DO.Group(cols...)) +} + +func (w workspaceDo) Having(conds ...gen.Condition) IWorkspaceDo { + return w.withDO(w.DO.Having(conds...)) +} + +func (w workspaceDo) Limit(limit int) IWorkspaceDo { + return w.withDO(w.DO.Limit(limit)) +} + +func (w workspaceDo) Offset(offset int) IWorkspaceDo { + return w.withDO(w.DO.Offset(offset)) +} + +func (w workspaceDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IWorkspaceDo { + return w.withDO(w.DO.Scopes(funcs...)) +} + +func (w workspaceDo) Unscoped() IWorkspaceDo { + return w.withDO(w.DO.Unscoped()) +} + +func (w workspaceDo) Create(values ...*entity.Workspace) error { + if len(values) == 0 { + return nil + } + return w.DO.Create(values) +} + +func (w workspaceDo) CreateInBatches(values []*entity.Workspace, batchSize int) error { + return w.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (w workspaceDo) Save(values ...*entity.Workspace) error { + if len(values) == 0 { + return nil + } + return w.DO.Save(values) +} + +func (w workspaceDo) First() (*entity.Workspace, error) { + if result, err := w.DO.First(); err != nil { + return nil, err + } else { + return result.(*entity.Workspace), nil + } +} + +func (w workspaceDo) Take() (*entity.Workspace, error) { + if result, err := w.DO.Take(); err != nil { + return nil, err + } else { + return result.(*entity.Workspace), nil + } +} + +func (w workspaceDo) Last() (*entity.Workspace, error) { + if result, err := w.DO.Last(); err != nil { + return nil, err + } else { + return result.(*entity.Workspace), nil + } +} + +func (w workspaceDo) Find() ([]*entity.Workspace, error) { + result, err := w.DO.Find() + return result.([]*entity.Workspace), err +} + +func (w workspaceDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.Workspace, err error) { + buf := make([]*entity.Workspace, 0, batchSize) + err = w.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (w workspaceDo) FindInBatches(result *[]*entity.Workspace, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return w.DO.FindInBatches(result, batchSize, fc) +} + +func (w workspaceDo) Attrs(attrs ...field.AssignExpr) IWorkspaceDo { + return w.withDO(w.DO.Attrs(attrs...)) +} + +func (w workspaceDo) Assign(attrs ...field.AssignExpr) IWorkspaceDo { + return w.withDO(w.DO.Assign(attrs...)) +} + +func (w workspaceDo) Joins(fields ...field.RelationField) IWorkspaceDo { + for _, _f := range fields { + w = *w.withDO(w.DO.Joins(_f)) + } + return &w +} + +func (w workspaceDo) Preload(fields ...field.RelationField) IWorkspaceDo { + for _, _f := range fields { + w = *w.withDO(w.DO.Preload(_f)) + } + return &w +} + +func (w workspaceDo) FirstOrInit() (*entity.Workspace, error) { + if result, err := w.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*entity.Workspace), nil + } +} + +func (w workspaceDo) FirstOrCreate() (*entity.Workspace, error) { + if result, err := w.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*entity.Workspace), nil + } +} + +func (w workspaceDo) FindByPage(offset int, limit int) (result []*entity.Workspace, count int64, err error) { + result, err = w.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = w.Offset(-1).Limit(-1).Count() + return +} + +func (w workspaceDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = w.Count() + if err != nil { + return + } + + err = w.Offset(offset).Limit(limit).Scan(result) + return +} + +func (w workspaceDo) Scan(result interface{}) (err error) { + return w.DO.Scan(result) +} + +func (w workspaceDo) Delete(models ...*entity.Workspace) (result gen.ResultInfo, err error) { + return w.DO.Delete(models) +} + +func (w *workspaceDo) withDO(do gen.Dao) *workspaceDo { + w.DO = *do.(*gen.DO) + return w +} diff --git a/internal/database/migrations/1_setup.sql b/internal/database/migrations/1_setup.sql index b28f3d2..f1a074e 100644 --- a/internal/database/migrations/1_setup.sql +++ b/internal/database/migrations/1_setup.sql @@ -1,15 +1,83 @@ -- +goose Up -CREATE TABLE IF NOT EXISTS users -( +CREATE TABLE workspaces ( id BIGSERIAL PRIMARY KEY, - username VARCHAR(255) NOT NULL, - email VARCHAR(255) NOT NULL, - password VARCHAR(255) NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP + name varchar(255), + user_id varchar(255), + created_at timestamp default now(), + updated_at timestamp default now(), + deleted_at timestamp default null ); +CREATE INDEX workspaces_user_id_idx ON workspaces (user_id); +CREATE INDEX workspaces_deleted_at_idx ON workspaces (deleted_at); + +CREATE TABLE workspace_members ( + id BIGSERIAL PRIMARY KEY, + workspace_id bigint REFERENCES workspaces(id), + user_id varchar(255), +-- role +-- role varchar(255), +-- permission varchar(255), + created_at timestamp default now(), + updated_at timestamp default now() +); + +CREATE TABLE collections ( + id BIGSERIAL PRIMARY KEY, + name varchar(255), + workspace_id bigint REFERENCES workspaces(id), + created_at timestamp default now(), + updated_at timestamp default now(), + deleted_at timestamp default null +); +CREATE INDEX collections_workspace_id_idx ON collections (workspace_id); +CREATE INDEX collections_deleted_at_idx ON collections (deleted_at); + +CREATE TABLE documents ( + id BIGSERIAL PRIMARY KEY, + name varchar(255), + workspace_id bigint REFERENCES workspaces(id), + collection_id bigint REFERENCES collections(id), + created_at timestamp default now(), + updated_at timestamp default now(), + deleted_at timestamp default null +); + +CREATE INDEX documents_workspace_id_idx ON documents (workspace_id); +CREATE INDEX documents_collection_id_idx ON documents (collection_id); +CREATE INDEX documents_deleted_at_idx ON documents (deleted_at); + +CREATE TABLE document_blocks ( + id BIGSERIAL PRIMARY KEY, + document_id bigint REFERENCES documents(id), + type varchar(255), + hash varchar(255), + content text, + created_at timestamp default now(), + updated_at timestamp default now() +); + +CREATE INDEX document_blocks_document_id_idx ON document_blocks (document_id); +CREATE INDEX document_blocks_type_idx ON document_blocks (type); +CREATE INDEX document_blocks_hash_idx ON document_blocks (hash); + +CREATE TABLE block_chunks ( + id BIGSERIAL PRIMARY KEY, + block_id bigint REFERENCES document_blocks(id), + content text +); + +CREATE INDEX block_chunks_block_id_idx ON block_chunks (block_id); + + + -- +goose Down -DROP TABLE IF EXISTS users; +DROP TABLE IF EXISTS block_chunks; +DROP TABLE IF EXISTS document_blocks; +DROP TABLE IF EXISTS documents; +DROP TABLE IF EXISTS collections; +DROP TABLE IF EXISTS workspace_members; +DROP TABLE IF EXISTS workspaces; + diff --git a/internal/database/migrations/2_add_parent_id_to_documents.sql b/internal/database/migrations/2_add_parent_id_to_documents.sql new file mode 100644 index 0000000..737d764 --- /dev/null +++ b/internal/database/migrations/2_add_parent_id_to_documents.sql @@ -0,0 +1,7 @@ +-- +goose Up +ALTER TABLE documents + ADD COLUMN parent_id BIGINT REFERENCES documents (id); + +-- +goose Down +ALTER TABLE documents + DROP COLUMN parent_id; diff --git a/internal/entity/Collection.go b/internal/entity/Collection.go new file mode 100644 index 0000000..e8e48c1 --- /dev/null +++ b/internal/entity/Collection.go @@ -0,0 +1,19 @@ +package entity + +import ( + "gorm.io/gorm" + "leafdev.top/Leaf/leaf-library-3/internal/types/dto" +) + +type Collection struct { + Model + Name string `json:"name"` + Workspace *Workspace `json:"workspace"` + WorkspaceId dto.EntityId `json:"workspace_id"` + + DeletedAt gorm.DeletedAt `json:"deleted_at"` +} + +func (*Collection) TableName() string { + return "collections" +} diff --git a/internal/entity/Document.go b/internal/entity/Document.go new file mode 100644 index 0000000..fcdc4fe --- /dev/null +++ b/internal/entity/Document.go @@ -0,0 +1,55 @@ +package entity + +import ( + "gorm.io/gorm" + "leafdev.top/Leaf/leaf-library-3/internal/types/dto" +) + +type Document struct { + Model + + Name string `json:"name"` + + WorkspaceId dto.EntityId `json:"workspace_id"` + Workspace *Workspace `json:"workspace"` + + CollectionId dto.EntityId `json:"collection_id"` + Collection *Collection `json:"collection"` + + ParentId dto.EntityId `json:"parent_id"` + Parent *Document `json:"parent"` + + DeletedAt gorm.DeletedAt `json:"deleted_at"` +} + +func (*Document) TableName() string { + return "documents" +} + +type DocumentBlock struct { + Model + + DocumentId dto.EntityId `json:"document_id"` + Document *Document `json:"document"` + + Type string `json:"type"` + Content string `json:"content"` + Hash string `json:"hash"` +} + +func (*DocumentBlock) TableName() string { + return "document_blocks" +} + +type BlockChunk struct { + Model + + DocumentBlockId dto.EntityId `json:"document_block_id"` + DocumentBlock *DocumentBlock `json:"document_block"` + + Content string `json:"content"` +} + +func (*BlockChunk) TableName() string { + return "block_chunks" +} diff --git a/internal/entity/Model.go b/internal/entity/Model.go index 7ff105f..0e4739a 100644 --- a/internal/entity/Model.go +++ b/internal/entity/Model.go @@ -3,13 +3,13 @@ package entity import ( "time" - "leafdev.top/Leaf/leaf-library-3/internal/schema" + "leafdev.top/Leaf/leaf-library-3/internal/types/dto" ) // Model 是所有 entity 的基类,后期要将所有的 Base 改成这种形式 type Model struct { - Id schema.EntityId `gorm:"primarykey" json:"id"` - CreatedAt time.Time `gorm:"autoUpdateTime:milli" json:"created_at"` - UpdatedAt time.Time `gorm:"autoUpdateTime:milli" json:"updated_at"` + Id dto.EntityId `gorm:"primarykey" json:"id"` + CreatedAt time.Time `gorm:"autoUpdateTime:milli" json:"created_at"` + UpdatedAt time.Time `gorm:"autoUpdateTime:milli" json:"updated_at"` //DeletedAt gorm.DeletedAt `gorm:"index"` } diff --git a/internal/entity/User.go b/internal/entity/User.go deleted file mode 100644 index 2b33f90..0000000 --- a/internal/entity/User.go +++ /dev/null @@ -1,10 +0,0 @@ -package entity - -type User struct { - Model - Name string `json:"name"` -} - -func (u *User) TableName() string { - return "users" -} diff --git a/internal/entity/Workspace.go b/internal/entity/Workspace.go new file mode 100644 index 0000000..3ad2154 --- /dev/null +++ b/internal/entity/Workspace.go @@ -0,0 +1,29 @@ +package entity + +import ( + "gorm.io/gorm" + "leafdev.top/Leaf/leaf-library-3/internal/types/dto" + "leafdev.top/Leaf/leaf-library-3/internal/types/user" +) + +type Workspace struct { + Model + Name string `json:"name"` + UserId user.Id `json:"user_id"` + DeletedAt gorm.DeletedAt `json:"deleted_at"` +} + +func (*Workspace) TableName() string { + return "workspaces" +} + +type WorkspaceMember struct { + Model + WorkspaceId dto.EntityId `json:"workspace_id"` + UserId user.Id `json:"user_id"` + Workspace *Workspace `json:"workspace"` +} + +func (*WorkspaceMember) TableName() string { + return "workspace_members" +} diff --git a/internal/pkg/validator/validator.go b/internal/pkg/validator/validator.go new file mode 100644 index 0000000..6da6698 --- /dev/null +++ b/internal/pkg/validator/validator.go @@ -0,0 +1,64 @@ +package validator + +import ( + "errors" + + "github.com/gookit/validate" + "leafdev.top/Leaf/leaf-library-3/internal/types/dto" +) + +var ( + ErrValidationFailed = errors.New("validation field failed") +) + +func init() { + // 可以自定义验证 + // Custom struct validation tag format + //if err := validate.Struct("teener", func(fl validator.FieldLevel) bool { + // // User.Age needs to fit our needs, 12-18 years old. + // return fl.Field().Int() >= 12 && fl.Field().Int() <= 18 + //}); err != nil { + // panic(err) + //} + + validate.AddValidator("myCheck0", func(val any) bool { + // do validate val ... + return true + }) +} + +func Struct(data interface{}) (validationErrors *[]dto.ValidateError, err error) { + v := validate.Struct(data) + + var e error + var ves []dto.ValidateError + + if v.Validate() { + return &ves, e // 返回指针 + } else { + e = ErrValidationFailed + + for _, err := range v.Errors { + ves = append(ves, dto.ValidateError{ + Message: err.String(), + }) + } + } + + //if errs != nil { + // for + // //for _, err := range errs.(validator.ValidationErrors) { + // // // In this case data object is actually holding the User struct + // // var elem ErrorResponse + // // + // // elem.FailedField = err.Field() // Export struct field name + // // elem.Tag = err.Tag() // Export struct tag + // // elem.Value = err.Value() // Export field value + // // elem.Error = true + // // + // // validationErrors = append(validationErrors, elem) + // //} + //} + + return &ves, e +} diff --git a/internal/router/api.go b/internal/router/api.go index 607a986..9a42dd8 100644 --- a/internal/router/api.go +++ b/internal/router/api.go @@ -37,7 +37,9 @@ func (a *Api) V1(r fiber.Router) { auth.Use(a.Middleware.Auth.Handler()) // RoutePermission 为权限验证 - r.Get("/ping", a.Middleware.RBAC.RoutePermission(), a.HttpHandler.User.Test) + //auth.Get("/ping", a.Middleware.RBAC.RoutePermission(), a.HttpHandler.User.Test) + + auth.Get("/ping", a.HttpHandler.User.Test) } guest := r.Group("/api/v1") diff --git a/internal/schema/jwt.go b/internal/schema/jwt.go deleted file mode 100644 index 8654c65..0000000 --- a/internal/schema/jwt.go +++ /dev/null @@ -1,12 +0,0 @@ -package schema - -type JWTTokenTypes string - -const ( - JWTAccessToken JWTTokenTypes = "access_token" - JWTIDToken JWTTokenTypes = "id_token" -) - -func (jwtTokenTypes JWTTokenTypes) String() string { - return string(jwtTokenTypes) -} diff --git a/internal/service/auth/auth.go b/internal/services/auth/auth.go similarity index 67% rename from internal/service/auth/auth.go rename to internal/services/auth/auth.go index 454528c..8ae6281 100644 --- a/internal/service/auth/auth.go +++ b/internal/services/auth/auth.go @@ -3,14 +3,15 @@ package auth import ( "context" + "leafdev.top/Leaf/leaf-library-3/internal/types/constants" + "leafdev.top/Leaf/leaf-library-3/internal/types/errs" + "leafdev.top/Leaf/leaf-library-3/internal/types/user" + "github.com/gofiber/fiber/v2" "github.com/mitchellh/mapstructure" - "leafdev.top/Leaf/leaf-library-3/internal/consts" - "leafdev.top/Leaf/leaf-library-3/internal/pkg/user" - "leafdev.top/Leaf/leaf-library-3/internal/schema" ) -func (a *Service) AuthFromToken(tokenType schema.JWTTokenTypes, token string) (*user.User, error) { +func (a *Service) AuthFromToken(tokenType constants.JwtTokenTypes, token string) (*user.User, error) { if a.config.Debug.Enabled { return a.parseUserJWT(tokenType, "") } @@ -19,11 +20,11 @@ func (a *Service) AuthFromToken(tokenType schema.JWTTokenTypes, token string) (* } func (a *Service) GetUserFromIdToken(idToken string) (*user.User, error) { - return a.parseUserJWT(schema.JWTIDToken, idToken) + return a.parseUserJWT(constants.JwtTokenTypeIDToken, idToken) } func (a *Service) GetUser(ctx *fiber.Ctx) *user.User { - userCtx := ctx.Locals(consts.AuthMiddlewareKey) + userCtx := ctx.Locals(constants.AuthMiddlewareKey) u, ok := userCtx.(*user.User) u.Id = u.Token.Sub @@ -36,7 +37,7 @@ func (a *Service) GetUser(ctx *fiber.Ctx) *user.User { } func (a *Service) GetCtx(ctx context.Context) *user.User { - userCtx := ctx.Value(consts.AuthMiddlewareKey) + userCtx := ctx.Value(constants.AuthMiddlewareKey) u, ok := userCtx.(*user.User) u.Id = u.Token.Sub @@ -49,7 +50,7 @@ func (a *Service) GetCtx(ctx context.Context) *user.User { } func (a *Service) GetUserSafe(ctx *fiber.Ctx) (*user.User, bool) { - userCtx := ctx.Locals(consts.AuthMiddlewareKey) + userCtx := ctx.Locals(constants.AuthMiddlewareKey) u, ok := userCtx.(*user.User) u.Id = u.Token.Sub @@ -58,7 +59,7 @@ func (a *Service) GetUserSafe(ctx *fiber.Ctx) (*user.User, bool) { } func (a *Service) GetCtxSafe(ctx context.Context) (*user.User, bool) { - userCtx := ctx.Value(consts.AuthMiddlewareKey) + userCtx := ctx.Value(constants.AuthMiddlewareKey) u, ok := userCtx.(*user.User) u.Id = u.Token.Sub @@ -67,11 +68,11 @@ func (a *Service) GetCtxSafe(ctx context.Context) (*user.User, bool) { } func (a *Service) SetUser(ctx context.Context, user *user.User) context.Context { - return context.WithValue(ctx, consts.AuthMiddlewareKey, user) + return context.WithValue(ctx, constants.AuthMiddlewareKey, user) } -func (a *Service) parseUserJWT(tokenType schema.JWTTokenTypes, jwtToken string) (*user.User, error) { - var sub = consts.AnonymousUser +func (a *Service) parseUserJWT(tokenType constants.JwtTokenTypes, jwtToken string) (*user.User, error) { + var sub = user.AnonymousUser var jwtIdToken = new(user.User) if a.config.Debug.Enabled { @@ -81,24 +82,24 @@ func (a *Service) parseUserJWT(tokenType schema.JWTTokenTypes, jwtToken string) } else { token, err := a.jwks.ParseJWT(jwtToken) if err != nil { - return nil, consts.ErrNotValidToken + return nil, errs.NotValidToken } subStr, err := token.Claims.GetSubject() if err != nil { - return nil, consts.ErrNotValidToken + return nil, errs.NotValidToken } sub = user.Id(subStr) // 如果 token.Header 中没有 typ if token.Header["typ"] == "" { - return nil, consts.ErrEmptyResponse + return nil, errs.EmptyResponse } // 验证 token 类型 if tokenType != "" && tokenType.String() != token.Header["typ"] { - return nil, consts.ErrTokenError + return nil, errs.TokenError } jwtIdToken.Valid = true diff --git a/internal/service/auth/provider.go b/internal/services/auth/provider.go similarity index 87% rename from internal/service/auth/provider.go rename to internal/services/auth/provider.go index 6807614..79cb912 100644 --- a/internal/service/auth/provider.go +++ b/internal/services/auth/provider.go @@ -3,7 +3,7 @@ package auth import ( "leafdev.top/Leaf/leaf-library-3/internal/base/conf" "leafdev.top/Leaf/leaf-library-3/internal/base/logger" - "leafdev.top/Leaf/leaf-library-3/internal/service/jwks" + "leafdev.top/Leaf/leaf-library-3/internal/services/jwks" ) type Service struct { diff --git a/internal/service/jwks/auth_refresh.go b/internal/services/jwks/auth_refresh.go similarity index 100% rename from internal/service/jwks/auth_refresh.go rename to internal/services/jwks/auth_refresh.go diff --git a/internal/service/jwks/jwks.go b/internal/services/jwks/jwks.go similarity index 100% rename from internal/service/jwks/jwks.go rename to internal/services/jwks/jwks.go diff --git a/internal/service/provider.go b/internal/services/provider.go similarity index 71% rename from internal/service/provider.go rename to internal/services/provider.go index eb71efd..5c6d34a 100644 --- a/internal/service/provider.go +++ b/internal/services/provider.go @@ -1,10 +1,10 @@ -package service +package services import ( "leafdev.top/Leaf/leaf-library-3/internal/base/logger" - "leafdev.top/Leaf/leaf-library-3/internal/service/auth" - "leafdev.top/Leaf/leaf-library-3/internal/service/jwks" - "leafdev.top/Leaf/leaf-library-3/internal/service/stream" + "leafdev.top/Leaf/leaf-library-3/internal/services/auth" + "leafdev.top/Leaf/leaf-library-3/internal/services/jwks" + "leafdev.top/Leaf/leaf-library-3/internal/services/stream" "github.com/google/wire" ) diff --git a/internal/service/stream/consumer.go b/internal/services/stream/consumer.go similarity index 100% rename from internal/service/stream/consumer.go rename to internal/services/stream/consumer.go diff --git a/internal/service/stream/kafka.go b/internal/services/stream/kafka.go similarity index 100% rename from internal/service/stream/kafka.go rename to internal/services/stream/kafka.go diff --git a/internal/service/stream/producer.go b/internal/services/stream/producer.go similarity index 97% rename from internal/service/stream/producer.go rename to internal/services/stream/producer.go index ed5c231..73e43cf 100644 --- a/internal/service/stream/producer.go +++ b/internal/services/stream/producer.go @@ -5,7 +5,7 @@ import ( "time" "github.com/segmentio/kafka-go" - "leafdev.top/Leaf/leaf-library-3/internal/schema" + "leafdev.top/Leaf/leaf-library-3/internal/types/events" ) //var connections = map[string]*kafka.Conn{} @@ -101,7 +101,7 @@ func (s *Service) SendMessage(ctx context.Context, topic string, data []byte) er return err } -func (s *Service) SendEvent(ctx context.Context, topic string, data schema.EventMessage) error { +func (s *Service) SendEvent(ctx context.Context, topic string, data events.EventMessage) error { j, err := data.JSON() if err != nil { return err diff --git a/internal/service/stream/provider.go b/internal/services/stream/provider.go similarity index 100% rename from internal/service/stream/provider.go rename to internal/services/stream/provider.go diff --git a/internal/types/constants/auth.go b/internal/types/constants/auth.go new file mode 100644 index 0000000..0028937 --- /dev/null +++ b/internal/types/constants/auth.go @@ -0,0 +1,20 @@ +package constants + +type JwtTokenTypes string + +const ( + JwtTokenTypeAccessToken JwtTokenTypes = "access_token" + JwtTokenTypeIDToken JwtTokenTypes = "id_token" +) + +func (jwtTokenType JwtTokenTypes) String() string { + return string(jwtTokenType) +} + +const ( + AuthHeader = "Authorization" + AuthPrefix = "Bearer" + + AuthMiddlewareKey = "auth.user" + AuthAssistantShareMiddlewareKey = "auth.assistant.share" +) diff --git a/internal/types/constants/rbac.go b/internal/types/constants/rbac.go new file mode 100644 index 0000000..ea3d0b1 --- /dev/null +++ b/internal/types/constants/rbac.go @@ -0,0 +1,9 @@ +package constants + +import ( + "leafdev.top/Leaf/leaf-library-3/internal/types/user" +) + +const ( + RoleSuperAdmin user.Role = "super-admin" +) diff --git a/internal/api/http/response/http.go b/internal/types/dto/dto.go similarity index 76% rename from internal/api/http/response/http.go rename to internal/types/dto/dto.go index eeb0aaf..d2f5c4e 100644 --- a/internal/api/http/response/http.go +++ b/internal/types/dto/dto.go @@ -1,16 +1,26 @@ -package response +package dto import ( "github.com/gofiber/fiber/v2" "net/http" ) +type IError interface { + Error() string +} + +type ValidateError struct { + Message string `json:"message"` +} + +// Body 为 HTTP 响应 type Body struct { Message string `json:"message"` Error string `json:"error"` - Success bool `json:"success"` - Data any `json:"data,omitempty"` - Wrap bool `json:"-"` + //ValidationErrors *[]ValidateError `json:"validation_error,omitempty"` + Success bool `json:"success"` + Data any `json:"data,omitempty"` + Wrap bool `json:"-"` } type HttpResponse struct { @@ -57,15 +67,9 @@ func (r *HttpResponse) Data(data any) *HttpResponse { } -func (r *HttpResponse) Error(err error) *HttpResponse { +func (r *HttpResponse) Error(err IError) *HttpResponse { if err != nil { - var errMsg = err.Error() - - if errMsg == "EOF" { - errMsg = "Request body is empty or missing some fields, make sure you have provided all the required fields" - } - - r.body.Error = errMsg + r.body.Error = err.Error() if r.httpStatus == 0 { r.httpStatus = http.StatusBadRequest @@ -110,6 +114,17 @@ func (r *HttpResponse) Send() error { return r.ctx.Status(r.httpStatus).JSON(r.body.Data) } +//func (r *HttpResponse) ValidationError(validationErrors *[]ValidateError) *HttpResponse { +// if validationErrors == nil || len(*validationErrors) == 0 { +// } +// +// r.body.ValidationErrors = validationErrors +// +// r.Error(errs.ErrBadRequest) +// +// return r +//} + // //func ResponseMessage(c *gin.Context, code int, message string, data interface{}) { // c.JSON(code, &Body{ diff --git a/internal/schema/entity.go b/internal/types/dto/entity.go similarity index 95% rename from internal/schema/entity.go rename to internal/types/dto/entity.go index 9cdb9bf..ac73df7 100644 --- a/internal/schema/entity.go +++ b/internal/types/dto/entity.go @@ -1,4 +1,4 @@ -package schema +package dto import ( "strconv" diff --git a/internal/types/dto/test_request.go b/internal/types/dto/test_request.go new file mode 100644 index 0000000..951b0f3 --- /dev/null +++ b/internal/types/dto/test_request.go @@ -0,0 +1,5 @@ +package dto + +type TestRequest struct { + Message string `json:"message" form:"message" validate:"string|required|min:1"` +} diff --git a/internal/schema/user_response.go b/internal/types/dto/user_response.go similarity index 73% rename from internal/schema/user_response.go rename to internal/types/dto/user_response.go index b1f5edb..5cab9ee 100644 --- a/internal/schema/user_response.go +++ b/internal/types/dto/user_response.go @@ -1,6 +1,8 @@ -package schema +package dto -import "leafdev.top/Leaf/leaf-library-3/internal/pkg/user" +import ( + "leafdev.top/Leaf/leaf-library-3/internal/types/user" +) type CurrentUserResponse struct { IP string `json:"ip"` diff --git a/internal/types/errs/auth.go b/internal/types/errs/auth.go new file mode 100644 index 0000000..5449aa5 --- /dev/null +++ b/internal/types/errs/auth.go @@ -0,0 +1,15 @@ +package errs + +import "errors" + +var ( + NotValidToken = errors.New("JWT not valid") + JWTFormatError = errors.New("JWT format error") + NotBearerType = errors.New("not bearer token") + TokenError = errors.New("token type error") + ErrUnauthorized = errors.New("unauthorized") + ErrAudienceNotAllowed = errors.New("audience not allowed") + + ErrNotYourResource = errors.New("this resource not yours") + ErrPermissionDenied = errors.New("permission denied") +) diff --git a/internal/types/errs/error.go b/internal/types/errs/error.go new file mode 100644 index 0000000..1e3268c --- /dev/null +++ b/internal/types/errs/error.go @@ -0,0 +1,7 @@ +package errs + +import "errors" + +var ( + UnknownError = errors.New("unknown error") +) diff --git a/internal/consts/model.go b/internal/types/errs/model.go similarity index 56% rename from internal/consts/model.go rename to internal/types/errs/model.go index 58eeb88..b55c2bd 100644 --- a/internal/consts/model.go +++ b/internal/types/errs/model.go @@ -1,7 +1,8 @@ -package consts +package errs import "errors" var ( ErrPageNotFound = errors.New("page not found") + ErrNotFound = errors.New("not found") ) diff --git a/internal/types/errs/router.go b/internal/types/errs/router.go new file mode 100644 index 0000000..b13310a --- /dev/null +++ b/internal/types/errs/router.go @@ -0,0 +1,10 @@ +package errs + +import "errors" + +var ( + EmptyResponse = errors.New("empty response") + ErrInternalServerError = errors.New("there was a server error, but we have logged this request for further investigation") + ErrValidationError = errors.New("unprocessable Entity") + RouteNotFound = errors.New("route not found") +) diff --git a/internal/types/errs/validation.go b/internal/types/errs/validation.go new file mode 100644 index 0000000..f342e55 --- /dev/null +++ b/internal/types/errs/validation.go @@ -0,0 +1,7 @@ +package errs + +import "errors" + +var ( + ErrBadRequest = errors.New("bad request") +) diff --git a/internal/schema/stream.go b/internal/types/events/stream.go similarity index 96% rename from internal/schema/stream.go rename to internal/types/events/stream.go index d554ff2..6aa29cf 100644 --- a/internal/schema/stream.go +++ b/internal/types/events/stream.go @@ -1,4 +1,4 @@ -package schema +package events import "encoding/json" diff --git a/internal/pkg/user/user.go b/internal/types/user/user.go similarity index 96% rename from internal/pkg/user/user.go rename to internal/types/user/user.go index 6e4c582..da7f19d 100644 --- a/internal/pkg/user/user.go +++ b/internal/types/user/user.go @@ -5,6 +5,9 @@ import ( "time" ) +// AnonymousUser 调试模式下的用户 +const AnonymousUser Id = "anonymous" + type Token struct { Aud string `json:"aud"` Iss string `json:"iss"`