feat: работа с несколькими схемами в пределах одного приложения

This commit is contained in:
2026-04-13 12:43:47 +03:00
parent dbfe27bbb8
commit 1b7220e647
6 changed files with 177 additions and 116 deletions

View File

@@ -2,9 +2,9 @@
#' @export
#' @description Function to open connection to db, disigned to easy dubugging.
#' @param where text mark to distingiush calss
make_db_connection = function(where = "") {
make_db_connection = function(scheme, where = "") {
if (getOption("APP.DEBUG", FALSE)) message("=== DB CONNECT ", where)
DBI::dbConnect(RSQLite::SQLite(), getOption("APP.FILE_DB", FALSE))
DBI::dbConnect(RSQLite::SQLite(), fs::path("db", scheme, ext = "sqlite"))
}
#' @export

View File

@@ -3,17 +3,19 @@
set_global_options = function(
SYMBOL_DELIM = "; ",
APP.DEBUG = FALSE,
APP.FILE_DB = fs::path("data.sqlite"),
# APP.FILE_DB = fs::path("data.sqlite"),
shiny.host = "127.0.0.1",
shiny.port = 1337,
enabled_schemas = c("schema", "schema_example"),
...
) {
options(
SYMBOL_DELIM = SYMBOL_DELIM,
APP.DEBUG = APP.DEBUG,
APP.FILE_DB = APP.FILE_DB,
# APP.FILE_DB = APP.FILE_DB,
shiny.host = shiny.host,
shiny.port = shiny.port,
enabled_schemas = enabled_schemas,
...
)
}
@@ -23,21 +25,27 @@ check_and_init_scheme = function() {
cli::cli_inform(c("*" = "проверка схемы..."))
scheme_file <- fs::path("configs/schemas", "schema.xlsx")
hash_file <- "schema_hash.rds"
# scheme_file <- fs::path("configs/schemas", "schema.xlsx")
scheme_names <- getOption("enabled_schemas")
scheme_file <- paste0("configs/schemas/", scheme_names, ".xlsx")
scheme_file <- stats::setNames(scheme_file, scheme_names)
db_files <- paste0("db/", scheme_names, ".sqlite")
hash_file <- "temp/schema_hash.rds"
#
exist_hash <- tools::md5sum(scheme_file)
# если первый запуск (нет файла с кешем) инициализация схемы
if (!file.exists("schema_hash.rds") | !file.exists("scheme.rds")) {
if (!file.exists(hash_file) | !file.exists("scheme.rds") | !all(file.exists(db_files))) {
init_scheme(scheme_file)
# в ином случае - проверяем кэш
} else {
saved_hash <- readRDS("schema_hash.rds")
saved_hash <- readRDS(hash_file)
# если данные были изменены проводим реинициализацию таблицы и схемы
if (!all(exist_hash == saved_hash)) {
@@ -50,6 +58,7 @@ check_and_init_scheme = function() {
}
# перезаписываем файл
if (!dir.exists("temp")) dir.create("temp")
saveRDS(exist_hash, hash_file)
}
@@ -62,12 +71,34 @@ init_scheme = function(scheme_file) {
modules/scheme_generator[scheme_R6]
)
con <- db$make_db_connection()
on.exit(db$close_db_connection(con), add = TRUE)
cli::cli_h1("Инициализация схемы")
schm <- scheme_R6$new(scheme_file)
db$check_if_table_is_exist_and_init_if_not(schm, con)
schms <- purrr::map2(
.x = scheme_file,
.y = names(scheme_file),
\(x, y) {
saveRDS(schm, "scheme.rds")
}
con <- db$make_db_connection(y)
on.exit(db$close_db_connection(con), add = TRUE)
schm <- scheme_R6$new(x)
db$check_if_table_is_exist_and_init_if_not(schm, con)
schm
}
)
# проверка на наличие дублирующихся названий вложенных таблиц
nested_tables_ids <- purrr::map(
names(schms),
\(x) schms[[x]]$nested_tables_names
)
nested_tables_ids <- unlist(nested_tables_ids)
tab <- table(nested_tables_ids)
# если встречается хоть одно значение несколько раз - начать истошно кричать (могут возникнуть пробемы при вызове всплывающих окон в формах)
if (!all(!tab > 1)) {
cli::cli_abort(c("В одной или нескольких схемах наименования вложенных форм совпадают:", paste("-", names(tab)[tab > 1])))
}
saveRDS(schms, "scheme.rds")
}

View File

@@ -125,18 +125,28 @@ scheme_R6 <- R6::R6Class(
c("subgroup", "form_id", "form_label", "form_type")
)
readxl::read_xlsx(private$scheme_file_path, sheet = sheet_name) |>
table <- readxl::read_xlsx(private$scheme_file_path, sheet = sheet_name) |>
# fill NA down
tidyr::fill(all_of(colnames), .direction = "down") |>
dplyr::group_by(form_id) |>
tidyr::fill(c(condition, required), .direction = "down") |>
dplyr::ungroup()
duplicate_ids <- table |>
dplyr::mutate(rleid = dplyr::consecutive_id(form_id)) |>
dplyr::distinct(form_id, rleid) |>
dplyr::count(form_id) |>
dplyr::filter(n > 1) |>
dplyr::pull(form_id)
if (length(duplicate_ids) > 0) {
cli::cli_abort(c("В схеме для формы '{sheet_name}' содержатся повторяющиеся id:", paste("-", duplicate_ids)))
}
table
}
)
)
# schm <- scheme_R6$new(fs::path("configs/schemas", "schema.xlsx"))
# object.size(schm)
# schm$get_key_id("main")
# schm$get_forms_ids("main")