feat: работа с орфанными записями

This commit is contained in:
2026-04-24 15:58:29 +03:00
parent 87444b5718
commit c63beeef0c
5 changed files with 75 additions and 9 deletions

4
app.R
View File

@@ -1227,13 +1227,15 @@ server <- function(input, output, session) {
append = TRUE
)
message <- glue::glue("Данные таблицы '{table_name}' успешно обновлены (добавлено {nrow(df)} записей)")
message <- glue::glue("Данные таблицы '{table_name}' успешно загружены (добавлено {nrow(df)} записей)")
showNotification(
message,
type = "message"
)
cli::cli_alert_success(message)
}
db$db_clean_orphans(mhcs(), con)
log_action_to_db("importing data from xlsx", con = con)
removeModal()
})

View File

@@ -409,14 +409,11 @@ server <- function(id, values, scheme, mhcs) {
} else {
# get key
new_main_key <- values$tasks_data[input$dt_todays_tasks_rows_selected,]$task_main_key
values$main_key <- new_main_key
main_key_to_jump <- values$tasks_data[input$dt_todays_tasks_rows_selected,]$task_main_key
values$main_key <- main_key_to_jump
showNotification("TODO: если ключа нет в таблице?!", type = "warning", duration = NULL)
removeModal()
# log_action_to_db("loading data", values$main_key, con = con)
}
})

View File

@@ -52,6 +52,7 @@ check_if_table_is_exist_and_init_if_not = function(
schm = schm
)
# инициализируем все таблицы
} else {
if (table_name == "main") {
@@ -61,6 +62,7 @@ check_if_table_is_exist_and_init_if_not = function(
.before = 1
)
}
if (table_name != "main") {
dummy_df <- get_dummy_df(forms_id_type_list) |>
dplyr::mutate(
@@ -401,4 +403,61 @@ local_db_backup <- function(
}
}
)
}
}
#' @export
db_clean_orphans = function(schm, con) {
main_key <- schm$get_main_key_id
nested_tables <- schm$nested_tables_names
all_main_keys <- DBI::dbGetQuery(con, glue::glue("SELECT DISTINCT {main_key} FROM main"))
all_main_keys <- dplyr::pull(all_main_keys)
purrr::walk(
.x = nested_tables,
.f = \(table_name) clear_orphans(table_name = table_name, main_key = main_key, all_main_keys = all_main_keys, con = con)
)
clear_orphans(table_name = "tasks", main_key = "task_main_key", all_main_keys = all_main_keys, con = con, drop_na_keys = FALSE)
clear_orphans(table_name = "log", main_key = "key", all_main_keys = all_main_keys, con = con, drop_na_keys = FALSE)
}
clear_orphans <- function(
table_name,
main_key,
all_main_keys,
con,
drop_na_keys = TRUE
) {
if (!table_name %in% DBI::dbListTables(con)) return(invisible())
all_main_keys_from_nested <- DBI::dbGetQuery(con, glue::glue("SELECT DISTINCT {main_key} FROM {table_name}"))
all_main_keys_from_nested <- dplyr::pull(all_main_keys_from_nested)
if (!drop_na_keys) {
all_main_keys_from_nested <- all_main_keys_from_nested[!is.na(all_main_keys_from_nested)]
}
if (all(all_main_keys_from_nested %in% all_main_keys)) {
cli::cli_alert_success("Все ключи в таблице '{table_name}' соответствуют действующим")
} else {
orphaned_keys <- all_main_keys_from_nested[!all_main_keys_from_nested %in% all_main_keys]
cli::cli_alert_warning(c("В таблице '{table_name}' найдены орфанные записи для следующих ID: ", paste("\n -", orphaned_keys)))
orphaned_keys <- paste0("'", orphaned_keys, "'", collapse = ", ")
del_query <- glue::glue("DELETE FROM {table_name} WHERE {main_key} IN ({orphaned_keys})")
deleted <- DBI::dbExecute(con, del_query)
if (drop_na_keys) {
deleted <- deleted + DBI::dbExecute(con, glue::glue("DELETE FROM {table_name} WHERE {main_key} IS NULL"))
}
cli::cli_alert_success("Из таблицы '{table_name}' было удалено {deleted} орфанных записей")
}
}

View File

@@ -110,6 +110,7 @@ init_scheme = function(scheme_file) {
if (!dir.exists(db_path)) dir.create(db_path)
cli::cli_h1("Инициализация схемы")
schms <- purrr::map2(
.x = scheme_file,
.y = names(scheme_file),
@@ -118,8 +119,15 @@ init_scheme = function(scheme_file) {
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)
# удаление орфанных записей
db$db_clean_orphans(schm = schm, con = con)
schm
}
)
@@ -129,13 +137,13 @@ init_scheme = function(scheme_file) {
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

@@ -48,7 +48,7 @@ scheme_R6 <- R6::R6Class(
"task_status", "select_one", "Статус задачи", NA, "completed",
"task_status", "select_one", "Статус задачи", NA, "deleted",
"task_title", "text", "Название задачи", NA, NA,
"task_description", "text", "Описание задачи", "краткое описание", "2",
"task_description", "text", "Описание задачи", "краткое описание", "3",
"task_due_date", "date", "Дата выполнения задачи", NA, NA,
) |>
dplyr::mutate(condition = NA)