diff --git a/bin/templates/configs_/settings.txt b/bin/templates/configs_/settings.txt index 205ebc0..f253b79 100644 --- a/bin/templates/configs_/settings.txt +++ b/bin/templates/configs_/settings.txt @@ -214,3 +214,11 @@ TEMPLATES_GRPC_SERVER_TABLE_UPDATE_FILENAME="server_grpc_table_update.go_" #TEMPLATES_GRPC_SERVER_TABLE_UPDATE_TEST_FILENAME - short filename of "server_grpc_table_update_test.go_" file TEMPLATES_GRPC_SERVER_TABLE_UPDATE_TEST_FILENAME="server_grpc_table_update_test.go_" +#NEED_CREATE_CACHE_FUNCTIONS - need create ReadFromCache() .proto API +NEED_CREATE_CACHE_API=true + +#NEED_CREATE_CACHE_FILES - need create "*_cache.go" files +NEED_CREATE_CACHE_FILES=true + +#NEED_CREATE_CACHE_TEST_FILES - need create "*_cache_test.go" files +NEED_CREATE_CACHE_TEST_FILES=true diff --git a/bin/templates/pkg/db/crud/crud_table_cache.go_ b/bin/templates/pkg/db/crud/crud_table_cache.go_ new file mode 100644 index 0000000..695651d --- /dev/null +++ b/bin/templates/pkg/db/crud/crud_table_cache.go_ @@ -0,0 +1,49 @@ +package crud_lawsuit_status_types + +import ( + "context" + "github.com/ManyakRus/starter/contextmain" + "github.com/hashicorp/golang-lru/v2/expirable" + "gitlab.aescorp.ru/dsp_dev/claim/sync_service/pkg/db/constants" + "gitlab.aescorp.ru/dsp_dev/claim/sync_service/pkg/object_model/entities/lawsuit_status_types" + "time" +) + +// cache - кэш с данными +var cache *expirable.LRU[int64, lawsuit_status_types.LawsuitStatusType] + +// CACHE_SIZE - количество элементо в кэше +const CACHE_SIZE = 100 + +// CACHE_EXPIRE_MINUTES - время жизни элемента в кэше +const CACHE_EXPIRE_MINUTES = 86400 + +// init - инициализация кэша +func init() { + cache = expirable.NewLRU[int64, lawsuit_status_types.LawsuitStatusType](CACHE_SIZE, nil, time.Minute*CACHE_EXPIRE_MINUTES) +} + +// ReadFromCache - находит запись в кеше или в БД по ID +func (crud Crud_DB) ReadFromCache(ID int64) (lawsuit_status_types.LawsuitStatusType, error) { + var Otvet lawsuit_status_types.LawsuitStatusType + var err error + + // поищем сначала в кэше + Otvet, ok := cache.Get(ID) + if ok { + return Otvet, nil + } + + // поищем в БД + ctxMain := contextmain.GetContext() + ctx, ctxCancelFunc := context.WithTimeout(ctxMain, time.Second*time.Duration(constants.TIMEOUT_DB_SECONDS)) + defer ctxCancelFunc() + + Otvet.ID = ID + err = crud.Read_ctx(ctx, &Otvet) + if err == nil { + cache.Add(ID, Otvet) + } + + return Otvet, err +} diff --git a/bin/templates/pkg/db/crud/crud_table_cache_test.go_ b/bin/templates/pkg/db/crud/crud_table_cache_test.go_ new file mode 100644 index 0000000..83b8cb7 --- /dev/null +++ b/bin/templates/pkg/db/crud/crud_table_cache_test.go_ @@ -0,0 +1,34 @@ +package crud_lawsuit_status_types + +import ( + "github.com/ManyakRus/starter/config_main" + "github.com/ManyakRus/starter/postgres_gorm" + "reflect" + "testing" +) + +func TestReadFromCache(t *testing.T) { + var err error + + config_main.LoadEnv() + postgres_gorm.Connect() + defer postgres_gorm.CloseConnection() + + //читаем из БД + m1, err := Crud_DB{}.ReadFromCache(Postgres_ID_Test) + if err != nil { + t.Errorf("TestReadFromCache() error:t %v", err) + } + + //читаем из БД + m2, err := Crud_DB{}.ReadFromCache(Postgres_ID_Test) + if err != nil { + t.Errorf("TestReadFromCache() error:t %v", err) + } + + //сравниваем + if reflect.DeepEqual(m1, m2) != true { + t.Errorf("TestReadFromCache() error: m1 != m2") + } + +} diff --git a/bin/templates/pkg/db/crud/crud_table_update_func.go_ b/bin/templates/pkg/db/crud/crud_table_update_func.go_ index b278dbc..e8daede 100644 --- a/bin/templates/pkg/db/crud/crud_table_update_func.go_ +++ b/bin/templates/pkg/db/crud/crud_table_update_func.go_ @@ -41,7 +41,11 @@ func (crud Crud_DB) Read_ctx(ctx context.Context, m *lawsuit_status_types.Lawsui err = tx.Error if err != nil { err = fmt.Errorf(m.TableNameDB()+" Read() id: %v, error: %v", m.ID, err) + return err } + //удалим из кэша + //cache.Remove(m.ID) + return err } diff --git a/bin/templates/pkg/db/crud/crud_tables.go_ b/bin/templates/pkg/db/crud/crud_tables.go_ index 3a8d5c6..10582fe 100644 --- a/bin/templates/pkg/db/crud/crud_tables.go_ +++ b/bin/templates/pkg/db/crud/crud_tables.go_ @@ -186,6 +186,9 @@ func (crud Crud_DB) create_update_ctx(ctx context.Context, m *lawsuit_status_typ return err } + //удалим из кэша + //cache.Remove(m.ID) + //запишем NULL в пустые колонки MapOmit := crud_functions.MapOmit_from_MassOmit(MassOmit) tx = db.Model(&m).Updates(MapOmit) diff --git a/bin/templates/pkg/db/crud/crud_tables_rapira.go_ b/bin/templates/pkg/db/crud/crud_tables_rapira.go_ index 97ee672..19cc22a 100644 --- a/bin/templates/pkg/db/crud/crud_tables_rapira.go_ +++ b/bin/templates/pkg/db/crud/crud_tables_rapira.go_ @@ -186,6 +186,9 @@ func (crud Crud_DB) create_update_ctx(ctx context.Context, m *lawsuit_status_typ return err } + //удалим из кэша + //cache.Remove(m.ID) + //запишем NULL в пустые колонки MapOmit := crud_functions.MapOmit_from_MassOmit(MassOmit) tx = db.Model(&m).Updates(MapOmit) diff --git a/internal/config/config.go b/internal/config/config.go index d794b63..59cd337 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -64,6 +64,9 @@ type SettingsINI struct { NEED_CREATE_NRPC_SERVER_TEST bool NEED_CREATE_NRPC_CLIENT_TEST bool NEED_CREATE_MANUAL_FILES bool + NEED_CREATE_CACHE_API bool + NEED_CREATE_CACHE_FILES bool + NEED_CREATE_CACHE_TEST_FILES bool SERVICE_NAME string SERVICE_REPOSITORY_URL string TEXT_TEMPLATE_MODEL string @@ -449,6 +452,22 @@ func FillSettings() { Name = "TEMPLATES_GRPC_SERVER_TABLE_UPDATE_TEST_FILENAME" s = Getenv(Name, true) Settings.TEMPLATES_GRPC_SERVER_TABLE_UPDATE_TEST_FILENAME = s + + // + Name = "NEED_CREATE_CACHE_API" + s = Getenv(Name, true) + Settings.NEED_CREATE_CACHE_API = BoolFromString(s) + + // + Name = "NEED_CREATE_CACHE_FILES" + s = Getenv(Name, true) + Settings.NEED_CREATE_CACHE_FILES = BoolFromString(s) + + // + Name = "NEED_CREATE_CACHE_TEST_FILES" + s = Getenv(Name, true) + Settings.NEED_CREATE_CACHE_TEST_FILES = BoolFromString(s) + } // CurrentDirectory - возвращает текущую директорию ОС diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 542841a..f02b8dd 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -53,3 +53,7 @@ const SERVER_GRPC_TABLE_UPDATE_FUNC_TEST_FILENAME = "server_grpc_table_update_fu const GRPC_CLIENT_TABLE_UPDATE_FUNC_FILENAME = "grpc_client_table_update_func.go_" const GRPC_CLIENT_TABLE_UPDATE_FUNC_TEST_FILENAME = "grpc_client_table_update_func_test.go_" + +const CRUD_TABLES_CACHE_FILENAME = "crud_table_cache.go_" +const CRUD_TABLES_CACHE_TEST_FILENAME = "crud_table_cache_test.go_" +const TEXT_CACHE_REMOVE = "cache.Remove(m.ID)" diff --git a/internal/create_files/create_files.go b/internal/create_files/create_files.go index b18cd8a..b3a0e3e 100644 --- a/internal/create_files/create_files.go +++ b/internal/create_files/create_files.go @@ -1304,3 +1304,14 @@ func FindTextEqualEmpty(Column1 *types.Column, VariableName string) string { // // return Otvet //} + +// FilenameWithoutLastUnderline - удаляет последний символ, если он = "_" +func FilenameWithoutLastUnderline(Filename string) string { + Otvet := Filename + + if strings.HasSuffix(Filename, "_") == true { + Otvet = Filename[:len(Filename)-1] + } + + return Otvet +} diff --git a/internal/create_files/db_crud_tables/db_crud_tables.go b/internal/create_files/db_crud_tables/db_crud_tables.go index 07b3085..fad1ee5 100644 --- a/internal/create_files/db_crud_tables/db_crud_tables.go +++ b/internal/create_files/db_crud_tables/db_crud_tables.go @@ -26,7 +26,7 @@ func CreateAllFiles(MapAll map[string]*types.Table) error { continue } - //файлы db + //файлы crud if config.Settings.NEED_CREATE_DB == true { err = CreateFiles(Table1) if err != nil { @@ -35,7 +35,7 @@ func CreateAllFiles(MapAll map[string]*types.Table) error { } } - //тестовые файлы db + //тестовые файлы crud if config.Settings.NEED_CREATE_DB_TEST == true { err = CreateTestFiles(Table1) if err != nil { @@ -44,6 +44,7 @@ func CreateAllFiles(MapAll map[string]*types.Table) error { } } + //файлы UpdateEveryColumn if config.Settings.NEED_CREATE_UPDATE_EVERY_COLUMN == true { //файлы db update err = CreateFilesUpdateEveryColumn(Table1) @@ -59,6 +60,27 @@ func CreateAllFiles(MapAll map[string]*types.Table) error { return err } } + + //файлы Cache + if config.Settings.NEED_CREATE_CACHE_API == true { + //файлы cache + if config.Settings.NEED_CREATE_CACHE_FILES == true { + err = CreateFilesCache(Table1) + if err != nil { + log.Error("CreateFiles() table: ", Table1.Name, " error: ", err) + return err + } + } + + //тестовые файлы cache + if config.Settings.NEED_CREATE_CACHE_TEST_FILES == true { + err = CreateFilesCacheTest(Table1) + if err != nil { + log.Error("CreateTestFiles() table: ", Table1.Name, " error: ", err) + return err + } + } + } } return err @@ -128,6 +150,11 @@ func CreateFiles(Table1 *types.Table) error { TextDB = strings.ReplaceAll(TextDB, config.Settings.TEXT_TEMPLATE_TABLENAME, Table1.Name) TextDB = config.Settings.TEXT_MODULE_GENERATED + TextDB + //кэш + if config.Settings.NEED_CREATE_CACHE_API == true { + TextDB = strings.ReplaceAll(TextDB, `//`+constants.TEXT_CACHE_REMOVE, constants.TEXT_CACHE_REMOVE) + } + //TextDB = create_files.DeleteFuncFind_byExtID(TextDB, Table1) //TextDB = create_files.DeleteFuncFind_byExtIDCtx(TextDB, Table1) TextDB = AddTextOmit(TextDB, Table1) @@ -461,7 +488,7 @@ func RenameFunctions(TextDB string, Table1 *types.Table) string { return Otvet } -// CreateFilesUpdateEveryColumn - создаёт 1 файл в папке grpc_client +// CreateFilesUpdateEveryColumn - создаёт 1 файл в папке crud func CreateFilesUpdateEveryColumn(Table1 *types.Table) error { var err error @@ -500,20 +527,6 @@ func CreateFilesUpdateEveryColumn(Table1 *types.Table) error { //заменим имя пакета на новое TextCrud = create_files.ReplacePackageName(TextCrud, DirReadyTable) - // TextCrud := "package " + config.Settings.PREFIX_CRUD + TableName + "\n\n" - // TextCrud = TextCrud + `import ( - // "errors" - // "context" - // "fmt" - // "time" - // "gorm.io/gorm" - // "github.com/ManyakRus/starter/contextmain" - // "github.com/ManyakRus/starter/micro" - // "github.com/ManyakRus/starter/postgres_gorm" - //) - // - //` - //заменим импорты if config.Settings.USE_DEFAULT_TEMPLATE == true { TextCrud = create_files.DeleteTemplateRepositoryImports(TextCrud) @@ -529,18 +542,20 @@ func CreateFilesUpdateEveryColumn(Table1 *types.Table) error { //создание текста TextUpdateEveryColumn := FindTextUpdateEveryColumn(TextCrudUpdateFunc, Table1) + // пустой файл не нужен if TextUpdateEveryColumn == "" { return err } - //ModelName := Table1.NameGo - //TextCrud = strings.ReplaceAll(TextCrud, config.Settings.TEXT_TEMPLATE_MODEL, ModelName) - //TextCrud = strings.ReplaceAll(TextCrud, config.Settings.TEXT_TEMPLATE_TABLENAME, Table1.Name) TextCrud = TextCrud + TextUpdateEveryColumn - TextCrud = config.Settings.TEXT_MODULE_GENERATED + TextCrud + //кэш + if config.Settings.NEED_CREATE_CACHE_API == true { + TextCrud = strings.ReplaceAll(TextCrud, `//`+constants.TEXT_CACHE_REMOVE, constants.TEXT_CACHE_REMOVE) + } + //удаление пустого импорта TextCrud = create_files.DeleteEmptyImport(TextCrud) @@ -758,3 +773,125 @@ func FindTextUpdateEveryColumnTest1(TextCrudUpdateFunc string, Table1 *types.Tab return Otvet } + +// CreateFilesCache - создаёт 1 файл "*_cache.go" в папке crud +func CreateFilesCache(Table1 *types.Table) error { + var err error + + TableName := strings.ToLower(Table1.Name) + + //чтение файлов + DirBin := micro.ProgramDir_bin() + DirTemplates := DirBin + config.Settings.TEMPLATE_FOLDERNAME + micro.SeparatorFile() + DirReady := DirBin + config.Settings.READY_FOLDERNAME + micro.SeparatorFile() + DirTemplatesCrud := DirTemplates + config.Settings.TEMPLATE_FOLDERNAME_CRUD + micro.SeparatorFile() + DirReadyCrud := DirReady + config.Settings.TEMPLATE_FOLDERNAME_CRUD + micro.SeparatorFile() + config.Settings.PREFIX_CRUD + TableName + micro.SeparatorFile() + + FilenameTemplateCache := DirTemplatesCrud + constants.CRUD_TABLES_CACHE_FILENAME + DirReadyTable := DirReadyCrud + FilenameReadyCache := DirReadyTable + create_files.FilenameWithoutLastUnderline(constants.CRUD_TABLES_CACHE_FILENAME) + + //создадим папку готовых файлов + folders.CreateFolder(DirReadyTable) + + //читаем шаблон файла + bytes, err := os.ReadFile(FilenameTemplateCache) + if err != nil { + log.Panic("ReadFile() ", FilenameTemplateCache, " error: ", err) + } + TextCache := string(bytes) + + //заменим имя пакета на новое + TextCache = create_files.ReplacePackageName(TextCache, DirReadyTable) + + //заменим импорты + if config.Settings.USE_DEFAULT_TEMPLATE == true { + TextCache = create_files.DeleteTemplateRepositoryImports(TextCache) + + DBConstantsURL := create_files.FindDBConstantsURL() + TextCache = create_files.AddImport(TextCache, DBConstantsURL) + + ModelTableURL := create_files.FindModelTableURL(TableName) + TextCache = create_files.AddImport(TextCache, ModelTableURL) + + //TextCache = create_files.ConvertIdToAlias(TextCache, Table1) + } + + //замена слов + ModelName := Table1.NameGo + TextCache = strings.ReplaceAll(TextCache, config.Settings.TEXT_TEMPLATE_MODEL, ModelName) + TextCache = strings.ReplaceAll(TextCache, config.Settings.TEXT_TEMPLATE_TABLENAME, Table1.Name) + TextCache = config.Settings.TEXT_MODULE_GENERATED + TextCache + + //удаление пустого импорта + TextCache = create_files.DeleteEmptyImport(TextCache) + + //удаление пустых строк + TextCache = create_files.DeleteEmptyLines(TextCache) + + //запись файла + err = os.WriteFile(FilenameReadyCache, []byte(TextCache), constants.FILE_PERMISSIONS) + + return err +} + +// CreateFilesCacheTest - создаёт 1 файл "*_cache_test.go" в папке crud +func CreateFilesCacheTest(Table1 *types.Table) error { + var err error + + TableName := strings.ToLower(Table1.Name) + + //чтение файлов + DirBin := micro.ProgramDir_bin() + DirTemplates := DirBin + config.Settings.TEMPLATE_FOLDERNAME + micro.SeparatorFile() + DirReady := DirBin + config.Settings.READY_FOLDERNAME + micro.SeparatorFile() + DirTemplatesCrud := DirTemplates + config.Settings.TEMPLATE_FOLDERNAME_CRUD + micro.SeparatorFile() + DirReadyCrud := DirReady + config.Settings.TEMPLATE_FOLDERNAME_CRUD + micro.SeparatorFile() + config.Settings.PREFIX_CRUD + TableName + micro.SeparatorFile() + + FilenameTemplateCache := DirTemplatesCrud + constants.CRUD_TABLES_CACHE_TEST_FILENAME + DirReadyTable := DirReadyCrud + FilenameReadyCache := DirReadyTable + create_files.FilenameWithoutLastUnderline(constants.CRUD_TABLES_CACHE_TEST_FILENAME) + + //создадим папку готовых файлов + folders.CreateFolder(DirReadyTable) + + //читаем шаблон файла + bytes, err := os.ReadFile(FilenameTemplateCache) + if err != nil { + log.Panic("ReadFile() ", FilenameTemplateCache, " error: ", err) + } + TextCache := string(bytes) + + //заменим имя пакета на новое + TextCache = create_files.ReplacePackageName(TextCache, DirReadyTable) + + //заменим импорты + if config.Settings.USE_DEFAULT_TEMPLATE == true { + TextCache = create_files.DeleteTemplateRepositoryImports(TextCache) + + DBConstantsURL := create_files.FindDBConstantsURL() + TextCache = create_files.AddImport(TextCache, DBConstantsURL) + + ModelTableURL := create_files.FindModelTableURL(TableName) + TextCache = create_files.AddImport(TextCache, ModelTableURL) + + //TextCache = create_files.ConvertIdToAlias(TextCache, Table1) + } + + //замена слов + ModelName := Table1.NameGo + TextCache = strings.ReplaceAll(TextCache, config.Settings.TEXT_TEMPLATE_MODEL, ModelName) + TextCache = strings.ReplaceAll(TextCache, config.Settings.TEXT_TEMPLATE_TABLENAME, Table1.Name) + TextCache = config.Settings.TEXT_MODULE_GENERATED + TextCache + + //удаление пустого импорта + TextCache = create_files.DeleteEmptyImport(TextCache) + + //удаление пустых строк + TextCache = create_files.DeleteEmptyLines(TextCache) + + //запись файла + err = os.WriteFile(FilenameReadyCache, []byte(TextCache), constants.FILE_PERMISSIONS) + + return err +}