feat: вместо встроенных таблиц - вложенные формы, перемещение кода в отдельные модули, инициация таблиц для вложенных форм

This commit is contained in:
2026-03-29 18:40:49 +03:00
parent cdf92a81a3
commit 339f2b9127
9 changed files with 318 additions and 173 deletions

View File

@@ -24,4 +24,110 @@ close_db_connection <- function(con, where = "") {
warning = function(w) if (getOption("APP.DEBUG", FALSE)) message("=!= ALREADY DISCONNECTED ", where),
finally = if (getOption("APP.DEBUG", FALSE)) message("=/= DB DISCONNECT ", where)
)
}
#' @export
#' проверить если таблица есть в базе данных и инициировать ее, если от
check_if_table_is_exist_and_init_if_not <- function(
table_name,
forms_id_type_list,
con = rlang::env_get(rlang::caller_env(), nm = "con")
) {
if (table_name %in% DBI::dbListTables(con)) {
cli::cli_inform("таблица есть такая: 'table_name'")
# если таблица существует, производим проверку структуры таблицы
compare_existing_table_with_schema(table_name, forms_id_type_list)
} else {
dummy_df <- dplyr::mutate(get_dummy_df(forms_id_type_list), id = "dummy")
# write dummy df into base, then delete dummy row
DBI::dbWriteTable(con, table_name, dummy_df, append = TRUE)
DBI::dbExecute(con, "DELETE FROM main WHERE id = 'dummy'")
cli::cli_alert_success("таблица '{table_name}' успешно создана")
}
}
get_dummy_data <- function(type) {
if (type %in% c("text", "select_one", "select_multiple")) return("dummy")
if (type %in% c("radio", "checkbox")) return("dummy")
if (type %in% c("date")) return(as.Date("1990-01-01"))
if (type %in% c("number")) return(as.double(999))
}
get_dummy_df <- function(forms_id_type_list) {
options(box.path = here::here())
box::use(modules/utils)
purrr::map(
.x = forms_id_type_list,
.f = utils$get_empty_data
) |>
dplyr::as_tibble()
}
compare_existing_table_with_schema <- function(
table_name,
forms_id_type_list,
con = rlang::env_get(rlang::caller_env(), nm = "con")
) {
options(box.path = here::here())
box::use(modules/utils)
# checking if db structure in form compatible with alrady writed data (in case on changig form)
if (identical(colnames(DBI::dbReadTable(con, table_name)), names(forms_id_type_list))) {
print("identical")
} else {
df_to_rewrite <- DBI::dbReadTable(con, table_name)
form_base_difference <- setdiff(names(forms_id_type_list), colnames(df_to_rewrite))
base_form_difference <- setdiff(colnames(df_to_rewrite), names(forms_id_type_list))
# if lengths are equal
if (length(names(forms_id_type_list)) == length(colnames(df_to_rewrite)) &&
length(form_base_difference) == 0 &&
length(base_form_difference) == 0) {
warning("changes in scheme file detected: assuming order changed only")
}
if (length(names(forms_id_type_list)) == length(colnames(df_to_rewrite)) &&
length(form_base_difference) != 0 &&
length(base_form_difference) != 0) {
stop("changes in scheme file detected: structure has been changed")
}
if (length(names(forms_id_type_list)) > length(colnames(df_to_rewrite)) && length(form_base_difference) != 0) {
warning("changes in scheme file detected: new inputs form was added")
warning("trying to adapt database")
# add empty data for each new input form
for (i in form_base_difference) {
df_to_rewrite <- df_to_rewrite |>
dplyr::mutate(!!dplyr::sym(i) := utils$get_empty_data(forms_id_type_list[i]))
}
# reorder due to scheme
df_to_rewrite <- df_to_rewrite |>
dplyr::select(dplyr::all_of(names(forms_id_type_list)))
DBI::dbWriteTable(con, table_name, df_to_rewrite, overwrite = TRUE)
DBI::dbExecute(con, "DELETE FROM main WHERE id = 'dummy'")
}
if (length(names(forms_id_type_list)) < length(colnames(df_to_rewrite))) {
stop("changes in scheme file detected: some of inputs form was deleted! it may cause data loss!")
}
# cleaning
rm(df_to_rewrite, form_base_difference)
}
}