Nothing
enumerate_all_paths <- function(dm, start) {
all_fks <-
dm %>%
dm_get_all_fks() %>%
rename(child_cols = child_fk_cols, parent_cols = parent_key_cols) %>%
mutate(edge_id = row_number())
helper_env <- new_environment()
helper_env$tbl_node <- list()
helper_env$all_paths <- tibble(
child_table = character(),
child_cols = new_keys(),
parent_table = character(),
parent_cols = new_keys(),
new_child_table = character(),
new_parent_table = character()
)
enumerate_all_paths_impl(start, all_fks = all_fks, helper_env = helper_env)
all_paths <- helper_env$all_paths
# need to take into account FKs from unconnected components (graph representation)
fks_from_unconnected <- anti_join(
all_fks,
all_paths,
by = c("child_table", "parent_table")
) %>%
mutate(new_child_table = child_table, new_parent_table = parent_table)
all_paths %>%
rename_unique() %>%
bind_rows(fks_from_unconnected) %>%
split_to_list()
}
enumerate_all_paths_impl <- function(node,
edge_id = NULL,
path = set_names(node),
all_fks,
helper_env) {
if (!is.null(edge_id)) {
# increase tbl_node[[node]] by 1, return this index in a suffix
usage_idx <- inc_tbl_node(node, helper_env)
new_node <- paste0(node, "-", usage_idx)
# new nodes appended to the front
path <- c(set_names(node, new_node), path)
# the first two elements serve as (reverse) lookup for new table names
node_lookup <- prep_recode(path[1:2])
add_path_to_all_paths(all_fks, edge_id, node_lookup, helper_env)
}
in_edges <-
all_fks %>%
filter(parent_table == !!node) %>%
filter(!(child_table %in% !!path)) %>%
select(node = child_table, edge_id)
out_edges <-
all_fks %>%
filter(child_table == !!node) %>%
filter(!(parent_table %in% !!path)) %>%
select(node = parent_table, edge_id)
bind_rows(in_edges, out_edges) %>%
pwalk(enumerate_all_paths_impl, path, all_fks, helper_env)
}
#' @autoglobal
rename_unique <- function(all_paths) {
node_lookup <-
bind_rows(
select(all_paths, new_table = new_child_table, table = child_table),
select(all_paths, new_table = new_parent_table, table = parent_table)
) %>%
distinct() %>%
arrange(table, new_table) %>%
add_count(table) %>%
mutate(table = if_else(n == 1L, table, new_table)) %>%
select(new_table, table) %>%
deframe()
all_paths %>%
mutate(
new_child_table = (!!node_lookup)[new_child_table],
new_parent_table = (!!node_lookup)[new_parent_table]
)
}
inc_tbl_node <- function(node, helper_env) {
tbl_node <- helper_env$tbl_node
out <- (tbl_node[[node]] %||% 0) + 1
tbl_node[[node]] <- out
helper_env$tbl_node <- tbl_node
out
}
add_path_to_all_paths <- function(all_fks,
edge_id,
node_lookup,
helper_env) {
all_paths <- helper_env$all_paths
path_element <-
all_fks %>%
filter(edge_id == !!edge_id)
helper_env$all_paths <- bind_rows(
all_paths,
path_element %>%
mutate(
new_child_table = (!!node_lookup)[child_table],
new_parent_table = (!!node_lookup)[parent_table]
)
)
}
#' @autoglobal
split_to_list <- function(all_paths) {
table_mapping <- bind_rows(
select(all_paths, new_table = new_child_table, table = child_table),
select(all_paths, new_table = new_parent_table, table = parent_table)
) %>%
filter(new_table != table) %>%
distinct() %>%
mutate(new_table = unname(new_table)) %>%
arrange()
new_fks <- select(
all_paths,
new_child_table,
child_cols,
new_parent_table,
parent_cols,
on_delete
)
list(table_mapping = table_mapping, new_fks = new_fks)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.