From 070ed823a8b69ab9de39c7930a26cf27a2598a6c Mon Sep 17 00:00:00 2001 From: "daniel.w" Date: Fri, 16 Aug 2024 09:12:15 +0800 Subject: [PATCH] feat: add permission table --- ...816014305_create_permission_table.down.sql | 1 + ...40816014305_create_permission_table.up.sql | 15 ++ internal/model/permission_model.go | 27 +++ internal/model/permission_model_gen.go | 157 ++++++++++++++++++ internal/model/vars.go | 5 + internal/usecase/opa_test.go | 13 +- 6 files changed, 209 insertions(+), 9 deletions(-) create mode 100644 generate/database/mysql/20240816014305_create_permission_table.down.sql create mode 100644 generate/database/mysql/20240816014305_create_permission_table.up.sql create mode 100755 internal/model/permission_model.go create mode 100755 internal/model/permission_model_gen.go create mode 100644 internal/model/vars.go diff --git a/generate/database/mysql/20240816014305_create_permission_table.down.sql b/generate/database/mysql/20240816014305_create_permission_table.down.sql new file mode 100644 index 0000000..6dc8750 --- /dev/null +++ b/generate/database/mysql/20240816014305_create_permission_table.down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS `permission`; diff --git a/generate/database/mysql/20240816014305_create_permission_table.up.sql b/generate/database/mysql/20240816014305_create_permission_table.up.sql new file mode 100644 index 0000000..cbe4d31 --- /dev/null +++ b/generate/database/mysql/20240816014305_create_permission_table.up.sql @@ -0,0 +1,15 @@ +-- 通常會把整個表都放到記憶體當中,不常搜尋,不需要加其他搜尋的 index +CREATE TABLE `permission` +( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'PK', + `parent` bigint unsigned DEFAULT NULL, + `name` varchar(255) NOT NULL, + `http_method` varchar(255) NOT NULL, + `http_path` text NOT NULL, + `status` tinyint NOT NULL DEFAULT '1' COMMENT '狀態 1: 啟用, 2: 關閉', + `type` tinyint NOT NULL DEFAULT '1' COMMENT '狀態 1: 後台, 2: 前台', + `create_time` bigint DEFAULT 0 NOT NULL COMMENT '創建時間', + `update_time` bigint DEFAULT 0 NOT NULL COMMENT '更新時間', + PRIMARY KEY (`id`), + UNIQUE KEY `name_unique_key` (`name`) +) ENGINE = InnoDB COMMENT ='權限表'; \ No newline at end of file diff --git a/internal/model/permission_model.go b/internal/model/permission_model.go new file mode 100755 index 0000000..719486a --- /dev/null +++ b/internal/model/permission_model.go @@ -0,0 +1,27 @@ +package model + +import ( + "github.com/zeromicro/go-zero/core/stores/cache" + "github.com/zeromicro/go-zero/core/stores/sqlx" +) + +var _ PermissionModel = (*customPermissionModel)(nil) + +type ( + // PermissionModel is an interface to be customized, add more methods here, + // and implement the added methods in customPermissionModel. + PermissionModel interface { + permissionModel + } + + customPermissionModel struct { + *defaultPermissionModel + } +) + +// NewPermissionModel returns a model for the database table. +func NewPermissionModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) PermissionModel { + return &customPermissionModel{ + defaultPermissionModel: newPermissionModel(conn, c, opts...), + } +} diff --git a/internal/model/permission_model_gen.go b/internal/model/permission_model_gen.go new file mode 100755 index 0000000..74bd248 --- /dev/null +++ b/internal/model/permission_model_gen.go @@ -0,0 +1,157 @@ +// Code generated by goctl. DO NOT EDIT. + +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/cache" + "github.com/zeromicro/go-zero/core/stores/sqlc" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + permissionFieldNames = builder.RawFieldNames(&Permission{}) + permissionRows = strings.Join(permissionFieldNames, ",") + permissionRowsExpectAutoSet = strings.Join(stringx.Remove(permissionFieldNames, "`id`"), ",") + permissionRowsWithPlaceHolder = strings.Join(stringx.Remove(permissionFieldNames, "`id`"), "=?,") + "=?" + + cachePermissionIdPrefix = "cache:permission:id:" + cachePermissionNamePrefix = "cache:permission:name:" +) + +type ( + permissionModel interface { + Insert(ctx context.Context, data *Permission) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*Permission, error) + FindOneByName(ctx context.Context, name string) (*Permission, error) + Update(ctx context.Context, data *Permission) error + Delete(ctx context.Context, id int64) error + } + + defaultPermissionModel struct { + sqlc.CachedConn + table string + } + + Permission struct { + Id int64 `db:"id"` // PK + Parent sql.NullInt64 `db:"parent"` + Name string `db:"name"` + HttpMethod string `db:"http_method"` + HttpPath string `db:"http_path"` + Status int64 `db:"status"` // 狀態 1: 啟用, 2: 關閉 + Type int64 `db:"type"` // 狀態 1: 後台, 2: 前台 + CreateTime int64 `db:"create_time"` // 創建時間 + UpdateTime int64 `db:"update_time"` // 更新時間 + } +) + +func newPermissionModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) *defaultPermissionModel { + return &defaultPermissionModel{ + CachedConn: sqlc.NewConn(conn, c, opts...), + table: "`permission`", + } +} + +func (m *defaultPermissionModel) withSession(session sqlx.Session) *defaultPermissionModel { + return &defaultPermissionModel{ + CachedConn: m.CachedConn.WithSession(session), + table: "`permission`", + } +} + +func (m *defaultPermissionModel) Delete(ctx context.Context, id int64) error { + data, err := m.FindOne(ctx, id) + if err != nil { + return err + } + + permissionIdKey := fmt.Sprintf("%s%v", cachePermissionIdPrefix, id) + permissionNameKey := fmt.Sprintf("%s%v", cachePermissionNamePrefix, data.Name) + _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("delete from %s where `id` = ?", m.table) + return conn.ExecCtx(ctx, query, id) + }, permissionIdKey, permissionNameKey) + return err +} + +func (m *defaultPermissionModel) FindOne(ctx context.Context, id int64) (*Permission, error) { + permissionIdKey := fmt.Sprintf("%s%v", cachePermissionIdPrefix, id) + var resp Permission + err := m.QueryRowCtx(ctx, &resp, permissionIdKey, func(ctx context.Context, conn sqlx.SqlConn, v any) error { + query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", permissionRows, m.table) + return conn.QueryRowCtx(ctx, v, query, id) + }) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultPermissionModel) FindOneByName(ctx context.Context, name string) (*Permission, error) { + permissionNameKey := fmt.Sprintf("%s%v", cachePermissionNamePrefix, name) + var resp Permission + err := m.QueryRowIndexCtx(ctx, &resp, permissionNameKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v any) (i any, e error) { + query := fmt.Sprintf("select %s from %s where `name` = ? limit 1", permissionRows, m.table) + if err := conn.QueryRowCtx(ctx, &resp, query, name); err != nil { + return nil, err + } + return resp.Id, nil + }, m.queryPrimary) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultPermissionModel) Insert(ctx context.Context, data *Permission) (sql.Result, error) { + permissionIdKey := fmt.Sprintf("%s%v", cachePermissionIdPrefix, data.Id) + permissionNameKey := fmt.Sprintf("%s%v", cachePermissionNamePrefix, data.Name) + ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?)", m.table, permissionRowsExpectAutoSet) + return conn.ExecCtx(ctx, query, data.Parent, data.Name, data.HttpMethod, data.HttpPath, data.Status, data.Type, data.CreateTime, data.UpdateTime) + }, permissionIdKey, permissionNameKey) + return ret, err +} + +func (m *defaultPermissionModel) Update(ctx context.Context, newData *Permission) error { + data, err := m.FindOne(ctx, newData.Id) + if err != nil { + return err + } + + permissionIdKey := fmt.Sprintf("%s%v", cachePermissionIdPrefix, data.Id) + permissionNameKey := fmt.Sprintf("%s%v", cachePermissionNamePrefix, data.Name) + _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, permissionRowsWithPlaceHolder) + return conn.ExecCtx(ctx, query, newData.Parent, newData.Name, newData.HttpMethod, newData.HttpPath, newData.Status, newData.Type, newData.CreateTime, newData.UpdateTime, newData.Id) + }, permissionIdKey, permissionNameKey) + return err +} + +func (m *defaultPermissionModel) formatPrimary(primary any) string { + return fmt.Sprintf("%s%v", cachePermissionIdPrefix, primary) +} + +func (m *defaultPermissionModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary any) error { + query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", permissionRows, m.table) + return conn.QueryRowCtx(ctx, v, query, primary) +} + +func (m *defaultPermissionModel) tableName() string { + return m.table +} diff --git a/internal/model/vars.go b/internal/model/vars.go new file mode 100644 index 0000000..69ca814 --- /dev/null +++ b/internal/model/vars.go @@ -0,0 +1,5 @@ +package model + +import "github.com/zeromicro/go-zero/core/stores/sqlx" + +var ErrNotFound = sqlx.ErrNotFound diff --git a/internal/usecase/opa_test.go b/internal/usecase/opa_test.go index e26f4e3..c9d42ad 100644 --- a/internal/usecase/opa_test.go +++ b/internal/usecase/opa_test.go @@ -194,7 +194,6 @@ func BenchmarkLoadPolicy(b *testing.B) { got, _ := NewOpaUseCase(OpaUseCaseParam{}) logx.Disable() - // 定义不同数量的 Policy 用于基准测试 policiesSmall := []usecase.Policy{ { Role: "admin", @@ -220,7 +219,6 @@ func BenchmarkLoadPolicy(b *testing.B) { } } - // 定义基准测试的不同场景 benchmarks := []struct { name string policies []usecase.Policy @@ -229,34 +227,31 @@ func BenchmarkLoadPolicy(b *testing.B) { { name: "SmallPolicy_NoTimeout", policies: policiesSmall, - ctxTimeout: 1 * time.Second, // 没有超时 + ctxTimeout: 1 * time.Second, // 沒有超時 }, { name: "LargePolicy_NoTimeout", policies: policiesLarge, - ctxTimeout: 1 * time.Second, // 没有超时 + ctxTimeout: 1 * time.Second, // 沒有超時 }, { name: "SmallPolicy_WithTimeout", policies: policiesSmall, - ctxTimeout: 1 * time.Millisecond, // 很短的超时 + ctxTimeout: 1 * time.Millisecond, // 沒有超時 }, { name: "LargePolicy_WithTimeout", policies: policiesLarge, - ctxTimeout: 1 * time.Millisecond, // 很短的超时 + ctxTimeout: 1 * time.Millisecond, // 沒有超時 }, } - // 遍历基准测试场景 for _, bm := range benchmarks { b.Run(bm.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - // 每次运行基准测试时,设置一个带有超时的 Context ctx, cancel := context.WithTimeout(context.Background(), bm.ctxTimeout) defer cancel() - // 调用 LoadPolicy 函数进行基准测试 _ = got.LoadPolicy(ctx, bm.policies) } })