feat: работа с орфанными записями
This commit is contained in:
4
app.R
4
app.R
@@ -1227,13 +1227,15 @@ server <- function(input, output, session) {
|
|||||||
append = TRUE
|
append = TRUE
|
||||||
)
|
)
|
||||||
|
|
||||||
message <- glue::glue("Данные таблицы '{table_name}' успешно обновлены (добавлено {nrow(df)} записей)")
|
message <- glue::glue("Данные таблицы '{table_name}' успешно загружены (добавлено {nrow(df)} записей)")
|
||||||
showNotification(
|
showNotification(
|
||||||
message,
|
message,
|
||||||
type = "message"
|
type = "message"
|
||||||
)
|
)
|
||||||
cli::cli_alert_success(message)
|
cli::cli_alert_success(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db$db_clean_orphans(mhcs(), con)
|
||||||
log_action_to_db("importing data from xlsx", con = con)
|
log_action_to_db("importing data from xlsx", con = con)
|
||||||
removeModal()
|
removeModal()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -409,14 +409,11 @@ server <- function(id, values, scheme, mhcs) {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
# get key
|
# get key
|
||||||
new_main_key <- values$tasks_data[input$dt_todays_tasks_rows_selected,]$task_main_key
|
main_key_to_jump <- values$tasks_data[input$dt_todays_tasks_rows_selected,]$task_main_key
|
||||||
values$main_key <- new_main_key
|
values$main_key <- main_key_to_jump
|
||||||
|
|
||||||
showNotification("TODO: если ключа нет в таблице?!", type = "warning", duration = NULL)
|
|
||||||
removeModal()
|
removeModal()
|
||||||
|
|
||||||
# log_action_to_db("loading data", values$main_key, con = con)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
59
modules/db.R
59
modules/db.R
@@ -52,6 +52,7 @@ check_if_table_is_exist_and_init_if_not = function(
|
|||||||
schm = schm
|
schm = schm
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# инициализируем все таблицы
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (table_name == "main") {
|
if (table_name == "main") {
|
||||||
@@ -61,6 +62,7 @@ check_if_table_is_exist_and_init_if_not = function(
|
|||||||
.before = 1
|
.before = 1
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table_name != "main") {
|
if (table_name != "main") {
|
||||||
dummy_df <- get_dummy_df(forms_id_type_list) |>
|
dummy_df <- get_dummy_df(forms_id_type_list) |>
|
||||||
dplyr::mutate(
|
dplyr::mutate(
|
||||||
@@ -402,3 +404,60 @@ 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} орфанных записей")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ init_scheme = function(scheme_file) {
|
|||||||
if (!dir.exists(db_path)) dir.create(db_path)
|
if (!dir.exists(db_path)) dir.create(db_path)
|
||||||
|
|
||||||
cli::cli_h1("Инициализация схемы")
|
cli::cli_h1("Инициализация схемы")
|
||||||
|
|
||||||
schms <- purrr::map2(
|
schms <- purrr::map2(
|
||||||
.x = scheme_file,
|
.x = scheme_file,
|
||||||
.y = names(scheme_file),
|
.y = names(scheme_file),
|
||||||
@@ -118,8 +119,15 @@ init_scheme = function(scheme_file) {
|
|||||||
con <- db$make_db_connection(y)
|
con <- db$make_db_connection(y)
|
||||||
on.exit(db$close_db_connection(con), add = TRUE)
|
on.exit(db$close_db_connection(con), add = TRUE)
|
||||||
|
|
||||||
|
# новый объект
|
||||||
schm <- scheme_R6$new(x)
|
schm <- scheme_R6$new(x)
|
||||||
|
|
||||||
|
# проверка схемы с существующей базой данных и инициализация таблиц
|
||||||
db$check_if_table_is_exist_and_init_if_not(schm, con)
|
db$check_if_table_is_exist_and_init_if_not(schm, con)
|
||||||
|
|
||||||
|
# удаление орфанных записей
|
||||||
|
|
||||||
|
db$db_clean_orphans(schm = schm, con = con)
|
||||||
schm
|
schm
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -129,13 +137,13 @@ init_scheme = function(scheme_file) {
|
|||||||
names(schms),
|
names(schms),
|
||||||
\(x) schms[[x]]$nested_tables_names
|
\(x) schms[[x]]$nested_tables_names
|
||||||
)
|
)
|
||||||
|
|
||||||
nested_tables_ids <- unlist(nested_tables_ids)
|
nested_tables_ids <- unlist(nested_tables_ids)
|
||||||
tab <- table(nested_tables_ids)
|
tab <- table(nested_tables_ids)
|
||||||
|
|
||||||
# если встречается хоть одно значение несколько раз - начать истошно кричать (могут возникнуть пробемы при вызове всплывающих окон в формах)
|
# если встречается хоть одно значение несколько раз - начать истошно кричать (могут возникнуть пробемы при вызове всплывающих окон в формах)
|
||||||
if (!all(!tab > 1)) {
|
if (!all(!tab > 1)) {
|
||||||
cli::cli_abort(c("В одной или нескольких схемах наименования вложенных форм совпадают:", paste("-", names(tab)[tab > 1])))
|
cli::cli_abort(c("В одной или нескольких схемах наименования вложенных форм совпадают:", paste("-", names(tab)[tab > 1])))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
saveRDS(schms, "scheme.rds")
|
saveRDS(schms, "scheme.rds")
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ scheme_R6 <- R6::R6Class(
|
|||||||
"task_status", "select_one", "Статус задачи", NA, "completed",
|
"task_status", "select_one", "Статус задачи", NA, "completed",
|
||||||
"task_status", "select_one", "Статус задачи", NA, "deleted",
|
"task_status", "select_one", "Статус задачи", NA, "deleted",
|
||||||
"task_title", "text", "Название задачи", NA, NA,
|
"task_title", "text", "Название задачи", NA, NA,
|
||||||
"task_description", "text", "Описание задачи", "краткое описание", "2",
|
"task_description", "text", "Описание задачи", "краткое описание", "3",
|
||||||
"task_due_date", "date", "Дата выполнения задачи", NA, NA,
|
"task_due_date", "date", "Дата выполнения задачи", NA, NA,
|
||||||
) |>
|
) |>
|
||||||
dplyr::mutate(condition = NA)
|
dplyr::mutate(condition = NA)
|
||||||
|
|||||||
Reference in New Issue
Block a user