From 9dbd855c2b3f14baa794f70bacb2c905ee343fd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sat, 28 May 2022 15:39:04 +0200 Subject: [PATCH 01/22] Move code --- tests/testthat/_snaps/learn.md | 40 ---------------------------------- tests/testthat/_snaps/meta.md | 7 ++++++ tests/testthat/test-learn.R | 9 -------- tests/testthat/test-meta.R | 15 +++++++++++++ 4 files changed, 22 insertions(+), 49 deletions(-) delete mode 100644 tests/testthat/_snaps/learn.md create mode 100644 tests/testthat/_snaps/meta.md create mode 100644 tests/testthat/test-meta.R diff --git a/tests/testthat/_snaps/learn.md b/tests/testthat/_snaps/learn.md deleted file mode 100644 index 065e3c5b2d..0000000000 --- a/tests/testthat/_snaps/learn.md +++ /dev/null @@ -1,40 +0,0 @@ -# dm_meta() data model - - Code - dm_meta(my_test_src()) %>% dm_paste(options = c("select", "keys", "color")) - Message - dm::dm( - schemata, - tables, - columns, - table_constraints, - key_column_usage, - constraint_column_usage, - ) %>% - dm::dm_select(schemata, catalog_name, schema_name) %>% - dm::dm_select(tables, table_catalog, table_schema, table_name, table_type) %>% - dm::dm_select(columns, table_catalog, table_schema, table_name, column_name, ordinal_position, column_default, is_nullable) %>% - dm::dm_select(table_constraints, constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, constraint_type) %>% - dm::dm_select(key_column_usage, constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, column_name, ordinal_position) %>% - dm::dm_select(constraint_column_usage, table_catalog, table_schema, table_name, column_name, constraint_catalog, constraint_schema, constraint_name, ordinal_position) %>% - dm::dm_add_pk(schemata, c(catalog_name, schema_name)) %>% - dm::dm_add_pk(tables, c(table_catalog, table_schema, table_name)) %>% - dm::dm_add_pk(columns, c(table_catalog, table_schema, table_name, column_name)) %>% - dm::dm_add_pk(table_constraints, c(constraint_catalog, constraint_schema, constraint_name)) %>% - dm::dm_add_pk(key_column_usage, c(constraint_catalog, constraint_schema, constraint_name, ordinal_position)) %>% - dm::dm_add_pk(constraint_column_usage, c(constraint_catalog, constraint_schema, constraint_name, ordinal_position)) %>% - dm::dm_add_fk(tables, c(table_catalog, table_schema), schemata) %>% - dm::dm_add_fk(columns, c(table_catalog, table_schema, table_name), tables) %>% - dm::dm_add_fk(table_constraints, c(table_catalog, table_schema, table_name), tables) %>% - dm::dm_add_fk(key_column_usage, c(table_catalog, table_schema, table_name, column_name), columns) %>% - dm::dm_add_fk(constraint_column_usage, c(table_catalog, table_schema, table_name, column_name), columns) %>% - dm::dm_add_fk(key_column_usage, c(constraint_catalog, constraint_schema, constraint_name), table_constraints) %>% - dm::dm_add_fk(constraint_column_usage, c(constraint_catalog, constraint_schema, constraint_name), table_constraints) %>% - dm::dm_add_fk(constraint_column_usage, c(constraint_catalog, constraint_schema, constraint_name, ordinal_position), key_column_usage) %>% - dm::dm_set_colors(`#0000FFFF` = schemata) %>% - dm::dm_set_colors(`#A52A2AFF` = tables) %>% - dm::dm_set_colors(`#A52A2AFF` = columns) %>% - dm::dm_set_colors(`#008B00FF` = table_constraints) %>% - dm::dm_set_colors(`#FFA500FF` = key_column_usage) %>% - dm::dm_set_colors(`#FFA500FF` = constraint_column_usage) - diff --git a/tests/testthat/_snaps/meta.md b/tests/testthat/_snaps/meta.md new file mode 100644 index 0000000000..a10723c7d4 --- /dev/null +++ b/tests/testthat/_snaps/meta.md @@ -0,0 +1,7 @@ +# dummy + + Code + TRUE + Output + [1] TRUE + diff --git a/tests/testthat/test-learn.R b/tests/testthat/test-learn.R index 1a617e5598..2c3a76dc28 100644 --- a/tests/testthat/test-learn.R +++ b/tests/testthat/test-learn.R @@ -371,12 +371,3 @@ test_that("Learning from a specific schema in another DB for MSSQL works?", { dm_local_no_keys ) }) - -test_that("dm_meta() data model", { - skip_if_src_not("mssql") - - expect_snapshot({ - dm_meta(my_test_src()) %>% - dm_paste(options = c("select", "keys", "color")) - }) -}) diff --git a/tests/testthat/test-meta.R b/tests/testthat/test-meta.R new file mode 100644 index 0000000000..f6a2ebb426 --- /dev/null +++ b/tests/testthat/test-meta.R @@ -0,0 +1,15 @@ +test_that("dummy", { + # To avoid deletion of file + expect_snapshot({ + TRUE + }) +}) + +test_that("dm_meta() data model", { + skip_if_src_not(c("mssql", "postgres")) + + expect_snapshot({ + dm_meta(my_test_src()) %>% + dm_paste(options = c("select", "keys", "color")) + }) +}) From 7ad6052307ba4a8ea46cd910c6bdb5da253dec98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 29 May 2022 06:43:10 +0200 Subject: [PATCH 02/22] Move code --- tests/testthat/test-learn.R | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/testthat/test-learn.R b/tests/testthat/test-learn.R index 2c3a76dc28..61ae7c5336 100644 --- a/tests/testthat/test-learn.R +++ b/tests/testthat/test-learn.R @@ -1,15 +1,5 @@ # FIXME: #313: learn only from current source -# produces a randomized schema name with a length of 4-10 characters -# consisting of the symbols in `reservoir` -random_schema <- function() { - reservoir <- c(letters, LETTERS, "'", "-", "_", as.character(0:9)) - how_long <- sample(4:10, 1) - paste0(reservoir[sample(seq_len(length(reservoir)), how_long, replace = TRUE)], collapse = "") -} - -schema_name <- random_schema() - test_that("Standard learning from MSSQL (schema 'dbo') or Postgres (schema 'public') and get_src_tbl_names() works?", { skip_if_src_not(c("mssql", "postgres")) @@ -91,6 +81,16 @@ test_that("Standard learning from MSSQL (schema 'dbo') or Postgres (schema 'publ test_that("Learning from specific schema on MSSQL or Postgres works?", { skip_if_src_not(c("mssql", "postgres")) + # produces a randomized schema name with a length of 4-10 characters + # consisting of the symbols in `reservoir` + random_schema <- function() { + reservoir <- c(letters, LETTERS, "'", "-", "_", as.character(0:9)) + how_long <- sample(4:10, 1) + paste0(reservoir[sample(seq_len(length(reservoir)), how_long, replace = TRUE)], collapse = "") + } + + schema_name <- random_schema() + src_db <- my_test_src() con_db <- src_db$con From 17fa98e0ea9d6622bef6038b057f487d1963b0e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sat, 28 May 2022 15:42:46 +0200 Subject: [PATCH 03/22] Pass on vars --- R/meta.R | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/R/meta.R b/R/meta.R index 3826c94514..a0ed4b3ed5 100644 --- a/R/meta.R +++ b/R/meta.R @@ -74,7 +74,10 @@ dm_meta_raw <- function(con, catalog) { filter(constraint_type == "FOREIGN KEY") constraint_column_usage <- - tbl_lc(src, dbplyr::ident_q("information_schema.constraint_column_usage")) %>% + tbl_lc(src, dbplyr::ident_q("information_schema.constraint_column_usage"), vars = c( + "table_catalog", "table_schema", "table_name", "column_name", + "constraint_catalog", "constraint_schema", "constraint_name" + )) %>% group_by(constraint_catalog, constraint_schema, constraint_name) %>% mutate(ordinal_position = row_number()) %>% ungroup() %>% From 6a567607166df574255f830cb329b18065858a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 29 May 2022 06:38:44 +0200 Subject: [PATCH 04/22] Add fixed column_constraints query --- R/postgres.R | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 R/postgres.R diff --git a/R/postgres.R b/R/postgres.R new file mode 100644 index 0000000000..a0fc072e6d --- /dev/null +++ b/R/postgres.R @@ -0,0 +1,47 @@ +# From \d+ information_schema.constraint_column_usage, adapted to include colnum +postgres_column_constraints <- "SELECT current_database()::information_schema.sql_identifier AS table_catalog, + x.tblschema::information_schema.sql_identifier AS table_schema, + x.tblname::information_schema.sql_identifier AS table_name, + x.colname::information_schema.sql_identifier AS column_name, + current_database()::information_schema.sql_identifier AS constraint_catalog, + x.cstrschema::information_schema.sql_identifier AS constraint_schema, + x.cstrname::information_schema.sql_identifier AS constraint_name, + x.colnum::information_schema.cardinal_number AS ordinal_position + + FROM ( SELECT DISTINCT nr.nspname, + r.relname, + r.relowner, + a.attname, + NULL::smallint AS attnum, + nc.nspname, + c.conname + FROM pg_namespace nr, + pg_class r, + pg_attribute a, + pg_depend d, + pg_namespace nc, + pg_constraint c + WHERE nr.oid = r.relnamespace AND r.oid = a.attrelid AND d.refclassid = 'pg_class'::regclass::oid AND d.refobjid = r.oid AND d.refobjsubid = a.attnum AND d.classid = 'pg_constraint'::regclass::oid AND d.objid = c.oid AND c.connamespace = nc.oid AND c.contype = 'c'::\"char\" AND (r.relkind = ANY (ARRAY['r'::\"char\", 'p'::\"char\"])) AND NOT a.attisdropped + UNION ALL + SELECT nr.nspname, + r.relname, + r.relowner, + a.attname, + a.attnum, + nc.nspname, + c.conname + FROM pg_namespace nr, + pg_class r, + pg_attribute a, + pg_namespace nc, + pg_constraint c + WHERE nr.oid = r.relnamespace AND r.oid = a.attrelid AND nc.oid = c.connamespace AND r.oid = + CASE c.contype + WHEN 'f'::\"char\" THEN c.confrelid + ELSE c.conrelid + END AND (a.attnum = ANY ( + CASE c.contype + WHEN 'f'::\"char\" THEN c.confkey + ELSE c.conkey + END)) AND NOT a.attisdropped AND (c.contype = ANY (ARRAY['p'::\"char\", 'u'::\"char\", 'f'::\"char\"])) AND (r.relkind = ANY (ARRAY['r'::\"char\", 'p'::\"char\"]))) x(tblschema, tblname, tblowner, colname, colnum, cstrschema, cstrname) + WHERE pg_has_role(x.tblowner, 'USAGE'::text)" From 0dd37dc0aab329ecf4a4ec50e17e9d0ee121ea13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 29 May 2022 06:39:12 +0200 Subject: [PATCH 05/22] REVERT ME: Tweak query for consistency with SQL Server --- R/postgres.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/postgres.R b/R/postgres.R index a0fc072e6d..31cbab291f 100644 --- a/R/postgres.R +++ b/R/postgres.R @@ -43,5 +43,5 @@ postgres_column_constraints <- "SELECT current_database()::information_schema.sq CASE c.contype WHEN 'f'::\"char\" THEN c.confkey ELSE c.conkey - END)) AND NOT a.attisdropped AND (c.contype = ANY (ARRAY['p'::\"char\", 'u'::\"char\", 'f'::\"char\"])) AND (r.relkind = ANY (ARRAY['r'::\"char\", 'p'::\"char\"]))) x(tblschema, tblname, tblowner, colname, colnum, cstrschema, cstrname) + END)) AND NOT a.attisdropped AND (c.contype = ANY (ARRAY['f'::\"char\"])) AND (r.relkind = ANY (ARRAY['r'::\"char\", 'p'::\"char\"]))) x(tblschema, tblname, tblowner, colname, colnum, cstrschema, cstrname) WHERE pg_has_role(x.tblowner, 'USAGE'::text)" From 019471c77b5be9eff36a43a0f1cde8e5e993b916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 29 May 2022 06:39:44 +0200 Subject: [PATCH 06/22] Use dm_meta() to learn from Postgres --- R/learn.R | 4 ---- R/meta.R | 22 +++++++++++----------- tests/testthat/test-learn.R | 3 --- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/R/learn.R b/R/learn.R index 015f656222..9b1d1f17df 100644 --- a/R/learn.R +++ b/R/learn.R @@ -41,10 +41,6 @@ dm_learn_from_db <- function(dest, dbname = NA, ...) { return() } - if (!is_mssql(con)) { - return(dm_learn_from_db_legacy(con, dbname, ...)) - } - dm_learn_from_db_meta(con, catalog = dbname, ...) } diff --git a/R/meta.R b/R/meta.R index a0ed4b3ed5..fce70084c4 100644 --- a/R/meta.R +++ b/R/meta.R @@ -68,22 +68,22 @@ dm_meta_raw <- function(con, catalog) { )) if (is_postgres(src)) { - info_fkc <- + info_pkc <- table_constraints %>% select(constraint_catalog, constraint_schema, constraint_name, constraint_type) %>% - filter(constraint_type == "FOREIGN KEY") + filter(constraint_type %in% c("PRIMARY KEY", "FOREIGN KEY")) + key_column_usage <- + key_column_usage %>% + semi_join(info_pkc, by = c("constraint_catalog", "constraint_schema", "constraint_name")) + + # Need hand-crafted query for now constraint_column_usage <- - tbl_lc(src, dbplyr::ident_q("information_schema.constraint_column_usage"), vars = c( + tbl(src, sql(postgres_column_constraints), vars = c( "table_catalog", "table_schema", "table_name", "column_name", - "constraint_catalog", "constraint_schema", "constraint_name" - )) %>% - group_by(constraint_catalog, constraint_schema, constraint_name) %>% - mutate(ordinal_position = row_number()) %>% - ungroup() %>% - semi_join(info_fkc, by = c("constraint_catalog", "constraint_schema", "constraint_name")) - - # FIXME: Also has `position_in_unique_constraint`, used elsewhere? + "constraint_catalog", "constraint_schema", "constraint_name", + "ordinal_position" + )) } else if (is_mssql(src)) { constraint_column_usage <- mssql_constraint_column_usage(src, table_constraints, catalog) } diff --git a/tests/testthat/test-learn.R b/tests/testthat/test-learn.R index 61ae7c5336..ff14b81c70 100644 --- a/tests/testthat/test-learn.R +++ b/tests/testthat/test-learn.R @@ -3,9 +3,6 @@ test_that("Standard learning from MSSQL (schema 'dbo') or Postgres (schema 'public') and get_src_tbl_names() works?", { skip_if_src_not(c("mssql", "postgres")) - # FIXME: Enable when fixed - skip_if_src("postgres") - # dm_learn_from_mssql() -------------------------------------------------- src_db <- my_test_src() From 79a4cff5c6ddc979409237cb40ee63270389e31f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 29 May 2022 07:15:23 +0200 Subject: [PATCH 07/22] Remove legacy code --- R/learn.R | 213 ------------------------------------------------------ 1 file changed, 213 deletions(-) diff --git a/R/learn.R b/R/learn.R index 9b1d1f17df..6fe55f89a8 100644 --- a/R/learn.R +++ b/R/learn.R @@ -160,38 +160,6 @@ dm_learn_from_db_meta <- function(con, catalog = NULL, schema = NULL, name_forma new_dm2(tables, pks_df, fks_df) } -dm_learn_from_db_legacy <- function(con, dbname, ...) { - sql <- db_learn_query(con, dbname = dbname, ...) - if (is.null(sql)) { - return() - } - - overview <- - dbGetQuery(con, sql) %>% - as_tibble() - - if (nrow(overview) == 0) { - return() - } - - table_names <- - overview %>% - arrange(table) %>% - distinct(schema, table) %>% - transmute( - name = table, - value = schema_if(schema = schema, table = table, con = con, dbname = dbname) - ) %>% - deframe() - - # FIXME: Use tbl_sql(vars = ...) - tables <- map(table_names, ~ tbl(con, dbplyr::ident_q(.x))) - - data_model <- get_datamodel_from_overview(overview) - - legacy_new_dm(tables, data_model) -} - schema_if <- function(schema, table, con, dbname = NULL) { table_sql <- DBI::dbQuoteIdentifier(con, table) if (is_null(dbname) || is.na(dbname) || dbname == "") { @@ -209,184 +177,3 @@ schema_if <- function(schema, table, con, dbname = NULL) { SQL(paste0(DBI::dbQuoteIdentifier(con, dbname), ".", DBI::dbQuoteIdentifier(con, schema), ".", table_sql)) } } - -db_learn_query <- function(dest, dbname, ...) { - if (is_postgres(dest)) { - return(postgres_learn_query(dest, ...)) - } -} - -postgres_learn_query <- function(con, schema = "public", table_type = "BASE TABLE") { - sprintf( - "SELECT - t.table_schema as schema, - t.table_name as table, - c.column_name as column, - case when pk.column_name is null then 0 else 1 end as key, - fk.ref, - fk.ref_col, - case c.is_nullable when 'YES' then 0 else 1 end as mandatory, - c.data_type as type, - c.ordinal_position as column_order - - from - information_schema.columns c - inner join information_schema.tables t on - t.table_name = c.table_name - and t.table_schema = c.table_schema - and t.table_catalog = c.table_catalog - - left join -- primary keys - ( SELECT DISTINCT - tc.constraint_name, tc.table_name, tc.table_schema, tc.table_catalog, kcu.column_name - FROM - information_schema.table_constraints AS tc - JOIN information_schema.key_column_usage AS kcu ON - tc.constraint_name = kcu.constraint_name - WHERE constraint_type = 'PRIMARY KEY' - ) pk on - pk.table_name = c.table_name - and pk.column_name = c.column_name - and pk.table_schema = c.table_schema - and pk.table_catalog = c.table_catalog - - left join -- foreign keys - ( SELECT DISTINCT - tc.constraint_name, kcu.table_name, kcu.table_schema, kcu.table_catalog, kcu.column_name, - ccu.table_name as ref, - ccu.column_name as ref_col - FROM - information_schema.table_constraints AS tc - JOIN information_schema.key_column_usage AS kcu ON - tc.constraint_name = kcu.constraint_name - JOIN information_schema.constraint_column_usage AS ccu ON - ccu.constraint_name = tc.constraint_name - WHERE tc.constraint_type = 'FOREIGN KEY' - ) fk on - fk.table_name = c.table_name - and fk.table_schema = c.table_schema - and fk.table_catalog = c.table_catalog - and fk.column_name = c.column_name - - where - c.table_schema = %s - and t.table_type = %s", - dbQuoteString(con, schema), - dbQuoteString(con, table_type) - ) -} - -# FIXME: only needed for `dm_learn_from_db()` <- needs to be implemented in a different manner -legacy_new_dm <- function(tables = NULL, data_model = NULL) { - if (is_null(tables) && is_null(data_model)) { - return(empty_dm()) - } - - if (!all_same_source(tables)) abort_not_same_src() - stopifnot(is.data_model(data_model)) - - columns <- as_tibble(data_model$columns) - - data_model_tables <- data_model$tables - - stopifnot(all(names(tables) %in% data_model_tables$table)) - stopifnot(all(data_model_tables$table %in% names(tables))) - - pks <- - columns %>% - select(column, table, key) %>% - filter(key > 0) %>% - select(-key) - - if (is.null(data_model$references) || nrow(data_model$references) == 0) { - fks <- tibble( - table = character(), - column = character(), - ref = character(), - ref_column = character(), - on_delete = character() - ) - } else { - fks <- - data_model$references %>% - transmute(table, column, ref, ref_column = ref_col, on_delete = "no_action") %>% - as_tibble() - } - - # Legacy - data <- unname(tables[data_model_tables$table]) - - table <- data_model_tables$table - segment <- data_model_tables$segment - # would be logical NA otherwise, but if set, it is class `character` - display <- as.character(data_model_tables$display) - zoom <- new_zoom() - col_tracker_zoom <- new_col_tracker_zoom() - - pks <- - pks %>% - # Legacy compatibility - mutate(column = as.list(column, list())) %>% - nest_compat(pks = -table) - - pks <- - tibble( - table = setdiff(table, pks$table), - pks = list_of(new_pk()) - ) %>% - vec_rbind(pks) - - # Legacy compatibility - fks$column <- as.list(fks$column) - fks$ref_column <- as.list(fks$ref_column) - - fks <- - fks %>% - nest_compat(fks = -ref) %>% - rename(table = ref) - - fks <- - tibble( - table = setdiff(table, fks$table), - fks = list_of(new_fk()) - ) %>% - vec_rbind(fks) - - # there are no filters at this stage - filters <- - tibble( - table = table, - filters = list_of(new_filter()) - ) - - def <- - tibble(table, data, segment, display) %>% - left_join(pks, by = "table") %>% - left_join(fks, by = "table") %>% - left_join(filters, by = "table") %>% - left_join(zoom, by = "table") %>% - left_join(col_tracker_zoom, by = "table") - - new_dm3(def) -} - -nest_compat <- function(.data, ...) { - # `...` has to be name-variable pair (see `?nest()`) of length 1 - quos <- enquos(...) - stopifnot(length(quos) == 1) - new_col <- names(quos) - if (nrow(.data) == 0) { - remove <- eval_select_indices(quo(c(...)), colnames(.data)) - keep <- setdiff(seq_along(.data), remove) - - nest <- new_list_of(list(), ptype = .data %>% select(!!!remove)) - - .data %>% - select(!!!keep) %>% - mutate(!!new_col := !!nest) - } else { - .data %>% - nest(...) %>% - mutate_at(vars(!!!new_col), as_list_of) - } -} From 11dee2571a8d2df78c4b06c24f90ec0134c78517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 29 May 2022 07:31:42 +0200 Subject: [PATCH 08/22] tryCatch() --- R/learn.R | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/R/learn.R b/R/learn.R index 6fe55f89a8..98722d6420 100644 --- a/R/learn.R +++ b/R/learn.R @@ -41,7 +41,13 @@ dm_learn_from_db <- function(dest, dbname = NA, ...) { return() } - dm_learn_from_db_meta(con, catalog = dbname, ...) + # FIXME: Try to make it work everywhere + tryCatch( + dm_learn_from_db_meta(con, catalog = dbname, ...), + error = function(e) { + NULL + } + ) } dm_learn_from_db_meta <- function(con, catalog = NULL, schema = NULL, name_format = "{table}") { From b54fd55a9cfe030a48c900ecb581cecbc8d9e19c Mon Sep 17 00:00:00 2001 From: krlmlr Date: Sun, 29 May 2022 05:49:54 +0000 Subject: [PATCH 09/22] [create-pull-request] automated change --- tests/testthat/_snaps/meta.md | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/testthat/_snaps/meta.md b/tests/testthat/_snaps/meta.md index a10723c7d4..66f0f1c4c5 100644 --- a/tests/testthat/_snaps/meta.md +++ b/tests/testthat/_snaps/meta.md @@ -5,3 +5,43 @@ Output [1] TRUE +# dm_meta() data model + + Code + dm_meta(my_test_src()) %>% dm_paste(options = c("select", "keys", "color")) + Message + dm::dm( + schemata, + tables, + columns, + table_constraints, + key_column_usage, + constraint_column_usage, + ) %>% + dm::dm_select(schemata, catalog_name, schema_name) %>% + dm::dm_select(tables, table_catalog, table_schema, table_name, table_type) %>% + dm::dm_select(columns, table_catalog, table_schema, table_name, column_name, ordinal_position, column_default, is_nullable) %>% + dm::dm_select(table_constraints, constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, constraint_type) %>% + dm::dm_select(key_column_usage, constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, column_name, ordinal_position) %>% + dm::dm_select(constraint_column_usage, table_catalog, table_schema, table_name, column_name, constraint_catalog, constraint_schema, constraint_name, ordinal_position) %>% + dm::dm_add_pk(schemata, c(catalog_name, schema_name)) %>% + dm::dm_add_pk(tables, c(table_catalog, table_schema, table_name)) %>% + dm::dm_add_pk(columns, c(table_catalog, table_schema, table_name, column_name)) %>% + dm::dm_add_pk(table_constraints, c(constraint_catalog, constraint_schema, constraint_name)) %>% + dm::dm_add_pk(key_column_usage, c(constraint_catalog, constraint_schema, constraint_name, ordinal_position)) %>% + dm::dm_add_pk(constraint_column_usage, c(constraint_catalog, constraint_schema, constraint_name, ordinal_position)) %>% + dm::dm_add_fk(tables, c(table_catalog, table_schema), schemata) %>% + dm::dm_add_fk(columns, c(table_catalog, table_schema, table_name), tables) %>% + dm::dm_add_fk(table_constraints, c(table_catalog, table_schema, table_name), tables) %>% + dm::dm_add_fk(key_column_usage, c(table_catalog, table_schema, table_name, column_name), columns) %>% + dm::dm_add_fk(constraint_column_usage, c(table_catalog, table_schema, table_name, column_name), columns) %>% + dm::dm_add_fk(key_column_usage, c(constraint_catalog, constraint_schema, constraint_name), table_constraints) %>% + dm::dm_add_fk(constraint_column_usage, c(constraint_catalog, constraint_schema, constraint_name), table_constraints) %>% + dm::dm_add_fk(constraint_column_usage, c(constraint_catalog, constraint_schema, constraint_name, ordinal_position), key_column_usage) %>% + dm::dm_set_colors(`#0000FFFF` = schemata) %>% + dm::dm_set_colors(`#A52A2AFF` = tables) %>% + dm::dm_set_colors(`#A52A2AFF` = columns) %>% + dm::dm_set_colors(`#008B00FF` = table_constraints) %>% + dm::dm_set_colors(`#FFA500FF` = key_column_usage) %>% + dm::dm_set_colors(`#FFA500FF` = constraint_column_usage) + From 5e8feaea861c91002796a8979bcdfb333a231d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 30 May 2022 06:05:32 +0200 Subject: [PATCH 10/22] Avoid race condition --- R/db-helpers.R | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/R/db-helpers.R b/R/db-helpers.R index 177f8e7547..27fc9ece6c 100644 --- a/R/db-helpers.R +++ b/R/db-helpers.R @@ -3,16 +3,19 @@ unique_db_table_name <- local({ function(table_name) { i <<- i + 1 - glue("{table_name}_", systime_convenient(), "_", get_pid(), "_", as.character(i)) + glue("{table_name}_", as.character(i), "_", systime_convenient(), "_", get_pid()) } }) systime_convenient <- function() { + # FIXME: Race condition here, but fast enough + local_options(digits.secs = 6) + if (Sys.getenv("IN_PKGDOWN") != "") { "2020_08_28_07_13_03" } else { time <- as.character(Sys.time()) - gsub("[-: ]", "_", time) + gsub("[-:. ]", "_", time) } } From bf9af1056320e4a63927e071207e1f917bf648ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 30 May 2022 06:36:41 +0200 Subject: [PATCH 11/22] Split test --- tests/testthat/test-learn.R | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-learn.R b/tests/testthat/test-learn.R index ff14b81c70..982c3cd0be 100644 --- a/tests/testthat/test-learn.R +++ b/tests/testthat/test-learn.R @@ -36,7 +36,40 @@ test_that("Standard learning from MSSQL (schema 'dbo') or Postgres (schema 'publ sort(dbQuoteIdentifier(src_db$con, remote_tbl_names)) ) - expect_message(dm_db_learned_all <- dm_from_src(src_db)) + expect_snapshot({ + dm_from_src(src_db) + }) +} + +test_that("Standard learning from MSSQL (schema 'dbo') or Postgres (schema 'public') and get_src_tbl_names() works?", { + skip_if_src_not(c("mssql", "postgres")) + + # dm_learn_from_mssql() -------------------------------------------------- + src_db <- my_test_src() + + # create an object on the MSSQL-DB that can be learned + withr::defer( + try(walk( + remote_tbl_names, + ~ try(dbExecute(src_db$con, paste0("DROP TABLE ", .x))) + )) + ) + + dm_for_filter_copied <- copy_dm_to(src_db, dm_for_filter(), temporary = FALSE, table_names = ~ DBI::SQL(unique_db_table_name(.x))) + order_of_deletion <- c("tf_2", "tf_1", "tf_5", "tf_6", "tf_4", "tf_3") + + remote_tbl_names <- + map_chr( + dm_get_tables(dm_for_filter_copied)[order_of_deletion], + dbplyr::remote_name + ) %>% + SQL() %>% + DBI::dbUnquoteIdentifier(conn = src_db$con) %>% + map_chr(~ .x@name[["table"]]) + + remote_tbl_map <- set_names(remote_tbl_names, gsub("^(tf_.).*$", "\\1", remote_tbl_names)) + + expect_silent(dm_db_learned_all <- dm_from_src(src_db, learn_keys = TRUE)) # Select and fix table names dm_db_learned <- From cd5851a075a5ccfefbc3c5abca4453e4a06443de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 30 May 2022 06:46:43 +0200 Subject: [PATCH 12/22] Fix --- tests/testthat/test-learn.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-learn.R b/tests/testthat/test-learn.R index 982c3cd0be..0a0177ca89 100644 --- a/tests/testthat/test-learn.R +++ b/tests/testthat/test-learn.R @@ -39,7 +39,7 @@ test_that("Standard learning from MSSQL (schema 'dbo') or Postgres (schema 'publ expect_snapshot({ dm_from_src(src_db) }) -} +}) test_that("Standard learning from MSSQL (schema 'dbo') or Postgres (schema 'public') and get_src_tbl_names() works?", { skip_if_src_not(c("mssql", "postgres")) From 92809209437ee999d7a4a7993efe86161ce8ff56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 30 May 2022 07:14:01 +0200 Subject: [PATCH 13/22] Add snapshot --- tests/testthat/_snaps/learn.md | 9 +++++++++ tests/testthat/test-learn.R | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 tests/testthat/_snaps/learn.md diff --git a/tests/testthat/_snaps/learn.md b/tests/testthat/_snaps/learn.md new file mode 100644 index 0000000000..f615bde7f9 --- /dev/null +++ b/tests/testthat/_snaps/learn.md @@ -0,0 +1,9 @@ +# Standard learning from MSSQL (schema 'dbo') or Postgres (schema 'public') and get_src_tbl_names() works? + + Code + dm_from_src(src_db)[integer()] + Message + Keys queried successfully, use `learn_keys = TRUE` to mute this message. + Output + dm() + diff --git a/tests/testthat/test-learn.R b/tests/testthat/test-learn.R index 0a0177ca89..70be4a761a 100644 --- a/tests/testthat/test-learn.R +++ b/tests/testthat/test-learn.R @@ -37,7 +37,7 @@ test_that("Standard learning from MSSQL (schema 'dbo') or Postgres (schema 'publ ) expect_snapshot({ - dm_from_src(src_db) + dm_from_src(src_db)[integer()] }) }) From 8324626b2e31a05b8071df13e2c1f3789a92e707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 30 May 2022 07:29:22 +0200 Subject: [PATCH 14/22] Error message when learning fails. --- R/dm-from-src.R | 58 ++++++++++++++++------------- R/learn.R | 8 +--- tests/testthat/test-error-helpers.R | 2 +- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/R/dm-from-src.R b/R/dm-from-src.R index 9092b7c6d6..627536e903 100644 --- a/R/dm-from-src.R +++ b/R/dm-from-src.R @@ -65,32 +65,36 @@ dm_from_src <- function(src = NULL, table_names = NULL, learn_keys = NULL, # FIXME: Get rid of legacy method once it works for all if (is.null(learn_keys) || isTRUE(learn_keys)) { - dm_learned <- dm_learn_from_db(src, ...) - - if (is.null(dm_learned)) { - if (isTRUE(learn_keys)) { - abort_learn_keys() - } - - inform("Keys could not be queried, use `learn_keys = FALSE` to mute this message.") - } else { - if (is_null(learn_keys)) { - inform("Keys queried successfully, use `learn_keys = TRUE` to mute this message.") - } - - if (is_null(table_names)) { - return(dm_learned) + # FIXME: Try to make it work everywhere + dm_learned <- tryCatch( + { + if (is_null(learn_keys)) { + inform("Keys queried successfully, use `learn_keys = TRUE` to mute this message.") + } + dm_learn_from_db(src, ...) + }, + error = function(e) { + if (isTRUE(learn_keys)) { + abort_learn_keys(conditionMessage(e)) + } + # FIXME: Use new-style error messages. + inform(paste0("Keys could not be queried: ", conditionMessage(e), ". Use `learn_keys = FALSE` to mute this message.")) + NULL } + ) - tbls_in_dm <- src_tbls_impl(dm_learned) + if (is_null(table_names)) { + return(dm_learned) + } - if (!all(table_names %in% tbls_in_dm)) { - abort_tbl_access(setdiff(table_names, tbls_in_dm)) - } - tbls_req <- intersect(tbls_in_dm, table_names) + tbls_in_dm <- src_tbls_impl(dm_learned) - return(dm_learned %>% dm_select_tbl(!!!tbls_req)) + if (!all(table_names %in% tbls_in_dm)) { + abort_tbl_access(setdiff(table_names, tbls_in_dm)) } + tbls_req <- intersect(tbls_in_dm, table_names) + + return(dm_learned %>% dm_select_tbl(!!!tbls_req)) } if (is_null(table_names)) { @@ -144,12 +148,16 @@ quote_ids <- function(x, con, schema = NULL) { # Errors ------------------------------------------------------------------ -abort_learn_keys <- function() { - abort(error_txt_learn_keys(), class = dm_error_full("learn_keys")) +abort_learn_keys <- function(reason) { + abort(error_txt_learn_keys(reason), class = dm_error_full("learn_keys")) } -error_txt_learn_keys <- function() { - "Failed to learn keys from database. Use `learn_keys = FALSE` to work around." +error_txt_learn_keys <- function(reason) { + # FIXME: Use new-style error messages. + paste0( + "Failed to learn keys from database:", reason, + ". Use `learn_keys = FALSE` to work around." + ) } abort_tbl_access <- function(bad) { diff --git a/R/learn.R b/R/learn.R index 98722d6420..6fe55f89a8 100644 --- a/R/learn.R +++ b/R/learn.R @@ -41,13 +41,7 @@ dm_learn_from_db <- function(dest, dbname = NA, ...) { return() } - # FIXME: Try to make it work everywhere - tryCatch( - dm_learn_from_db_meta(con, catalog = dbname, ...), - error = function(e) { - NULL - } - ) + dm_learn_from_db_meta(con, catalog = dbname, ...) } dm_learn_from_db_meta <- function(con, catalog = NULL, schema = NULL, name_format = "{table}") { diff --git a/tests/testthat/test-error-helpers.R b/tests/testthat/test-error-helpers.R index b8a65364c6..95912a0df6 100644 --- a/tests/testthat/test-error-helpers.R +++ b/tests/testthat/test-error-helpers.R @@ -42,7 +42,7 @@ test_that("output", { abort_con_only_for_dbi() abort_only_possible_wo_zoom("dm_zoom_to") abort_only_possible_w_zoom("dm_update_zoomed") - abort_learn_keys() + abort_learn_keys("some reason") abort_tbl_access("accessdenied") abort_unnamed_table_list() abort_need_unique_names("clone") From f6671603bc959bd84c2d3982c818f0de84d360ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 30 May 2022 07:41:09 +0200 Subject: [PATCH 15/22] Tweak snapshots --- R/dm-from-src.R | 2 +- tests/testthat/_snaps/error-helpers.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/R/dm-from-src.R b/R/dm-from-src.R index 627536e903..5d6c857c69 100644 --- a/R/dm-from-src.R +++ b/R/dm-from-src.R @@ -155,7 +155,7 @@ abort_learn_keys <- function(reason) { error_txt_learn_keys <- function(reason) { # FIXME: Use new-style error messages. paste0( - "Failed to learn keys from database:", reason, + "Failed to learn keys from database: ", reason, ". Use `learn_keys = FALSE` to work around." ) } diff --git a/tests/testthat/_snaps/error-helpers.md b/tests/testthat/_snaps/error-helpers.md index b65c0741d6..89fab2ad12 100644 --- a/tests/testthat/_snaps/error-helpers.md +++ b/tests/testthat/_snaps/error-helpers.md @@ -206,10 +206,10 @@ Error in `abort_only_possible_w_zoom()`: ! You can't call `dm_update_zoomed()` on an unzoomed `dm`. Consider using `dm_zoom_to()` first. Code - abort_learn_keys() + abort_learn_keys("some reason") Condition Error in `abort_learn_keys()`: - ! Failed to learn keys from database. Use `learn_keys = FALSE` to work around. + ! Failed to learn keys from database: some reason. Use `learn_keys = FALSE` to work around. Code abort_tbl_access("accessdenied") Condition From 6d7ed2235ca35b1e5228698cebdce9f331271e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 30 May 2022 07:44:34 +0200 Subject: [PATCH 16/22] Add filter --- R/learn.R | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/R/learn.R b/R/learn.R index 6fe55f89a8..79cdf87b44 100644 --- a/R/learn.R +++ b/R/learn.R @@ -153,6 +153,10 @@ dm_learn_from_db_meta <- function(con, catalog = NULL, schema = NULL, name_forma ))) %>% ungroup() %>% select(-(1:3)) %>% + + # FIXME: Where does this come from? + filter(!is.na(ref_table)) %>% + group_by(table = ref_table) %>% summarize(fks = list(bind_rows(fks))) %>% ungroup() From 938cfe78310a69007bd78dbcd0246f3adf03b905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 30 May 2022 07:48:36 +0200 Subject: [PATCH 17/22] Work around permission issues --- R/learn.R | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/R/learn.R b/R/learn.R index 79cdf87b44..4f4744e862 100644 --- a/R/learn.R +++ b/R/learn.R @@ -107,7 +107,10 @@ dm_learn_from_db_meta <- function(con, catalog = NULL, schema = NULL, name_forma left_join(columns, select = c(column_name, dm_name, table_catalog, table_schema, table_name)) %>% dm_update_zoomed() %>% dm_zoom_to(constraint_column_usage) %>% - left_join(columns, select = c(column_name, dm_name, table_catalog, table_schema, table_name)) %>% + + # inner_join(): Matching column sometimes not found on Postgres + inner_join(columns, select = c(column_name, dm_name, table_catalog, table_schema, table_name)) %>% + dm_update_zoomed() %>% dm_select_tbl(-columns) %>% dm_rename(constraint_column_usage, constraint_column_usage.table_catalog = table_catalog) %>% @@ -153,10 +156,6 @@ dm_learn_from_db_meta <- function(con, catalog = NULL, schema = NULL, name_forma ))) %>% ungroup() %>% select(-(1:3)) %>% - - # FIXME: Where does this come from? - filter(!is.na(ref_table)) %>% - group_by(table = ref_table) %>% summarize(fks = list(bind_rows(fks))) %>% ungroup() From e28deef7a83942027288c94c4cad9cabc4b1a430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 30 May 2022 07:50:58 +0200 Subject: [PATCH 18/22] Whitespace --- R/postgres.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/postgres.R b/R/postgres.R index 31cbab291f..4f36caa83e 100644 --- a/R/postgres.R +++ b/R/postgres.R @@ -44,4 +44,5 @@ postgres_column_constraints <- "SELECT current_database()::information_schema.sq WHEN 'f'::\"char\" THEN c.confkey ELSE c.conkey END)) AND NOT a.attisdropped AND (c.contype = ANY (ARRAY['f'::\"char\"])) AND (r.relkind = ANY (ARRAY['r'::\"char\", 'p'::\"char\"]))) x(tblschema, tblname, tblowner, colname, colnum, cstrschema, cstrname) - WHERE pg_has_role(x.tblowner, 'USAGE'::text)" + WHERE pg_has_role(x.tblowner, 'USAGE'::text) +" From 588af9e6c799457c34b6b4f6864436e1244441cf Mon Sep 17 00:00:00 2001 From: krlmlr Date: Mon, 30 May 2022 06:20:56 +0000 Subject: [PATCH 19/22] Auto-update from GitHub Actions Run: https://github.com/cynkra/dm/actions/runs/2407140452 --- R/learn.R | 2 -- 1 file changed, 2 deletions(-) diff --git a/R/learn.R b/R/learn.R index 4f4744e862..9d98b42d27 100644 --- a/R/learn.R +++ b/R/learn.R @@ -107,10 +107,8 @@ dm_learn_from_db_meta <- function(con, catalog = NULL, schema = NULL, name_forma left_join(columns, select = c(column_name, dm_name, table_catalog, table_schema, table_name)) %>% dm_update_zoomed() %>% dm_zoom_to(constraint_column_usage) %>% - # inner_join(): Matching column sometimes not found on Postgres inner_join(columns, select = c(column_name, dm_name, table_catalog, table_schema, table_name)) %>% - dm_update_zoomed() %>% dm_select_tbl(-columns) %>% dm_rename(constraint_column_usage, constraint_column_usage.table_catalog = table_catalog) %>% From 7c1b702e3970a8c3aebb47c33b5f600858e12b8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 30 May 2022 08:26:35 +0200 Subject: [PATCH 20/22] Spacing --- R/learn.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/learn.R b/R/learn.R index 9d98b42d27..ed5235f48c 100644 --- a/R/learn.R +++ b/R/learn.R @@ -107,8 +107,10 @@ dm_learn_from_db_meta <- function(con, catalog = NULL, schema = NULL, name_forma left_join(columns, select = c(column_name, dm_name, table_catalog, table_schema, table_name)) %>% dm_update_zoomed() %>% dm_zoom_to(constraint_column_usage) %>% + # # inner_join(): Matching column sometimes not found on Postgres inner_join(columns, select = c(column_name, dm_name, table_catalog, table_schema, table_name)) %>% + # dm_update_zoomed() %>% dm_select_tbl(-columns) %>% dm_rename(constraint_column_usage, constraint_column_usage.table_catalog = table_catalog) %>% From 174208c7a72e08f54d8aac9732a695bb172d98a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 30 May 2022 09:46:22 +0200 Subject: [PATCH 21/22] Fix logic --- R/dm-from-src.R | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/R/dm-from-src.R b/R/dm-from-src.R index 5d6c857c69..17408f888a 100644 --- a/R/dm-from-src.R +++ b/R/dm-from-src.R @@ -66,12 +66,25 @@ dm_from_src <- function(src = NULL, table_names = NULL, learn_keys = NULL, if (is.null(learn_keys) || isTRUE(learn_keys)) { # FIXME: Try to make it work everywhere - dm_learned <- tryCatch( + tryCatch( { + dm_learned <- dm_learn_from_db(src, ...) if (is_null(learn_keys)) { inform("Keys queried successfully, use `learn_keys = TRUE` to mute this message.") } - dm_learn_from_db(src, ...) + + if (is_null(table_names)) { + return(dm_learned) + } + + tbls_in_dm <- src_tbls_impl(dm_learned) + + if (!all(table_names %in% tbls_in_dm)) { + abort_tbl_access(setdiff(table_names, tbls_in_dm)) + } + tbls_req <- intersect(tbls_in_dm, table_names) + + return(dm_learned %>% dm_select_tbl(!!!tbls_req)) }, error = function(e) { if (isTRUE(learn_keys)) { @@ -82,19 +95,6 @@ dm_from_src <- function(src = NULL, table_names = NULL, learn_keys = NULL, NULL } ) - - if (is_null(table_names)) { - return(dm_learned) - } - - tbls_in_dm <- src_tbls_impl(dm_learned) - - if (!all(table_names %in% tbls_in_dm)) { - abort_tbl_access(setdiff(table_names, tbls_in_dm)) - } - tbls_req <- intersect(tbls_in_dm, table_names) - - return(dm_learned %>% dm_select_tbl(!!!tbls_req)) } if (is_null(table_names)) { From 00f8bf010e967c95b8230dd3bd96f88a3f1f35dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 30 May 2022 10:28:09 +0200 Subject: [PATCH 22/22] Remove dead code --- R/data-model-helpers.R | 31 ------------------------------- R/datamodelr-code.R | 4 ---- 2 files changed, 35 deletions(-) diff --git a/R/data-model-helpers.R b/R/data-model-helpers.R index f83cd58eef..4d350a9649 100644 --- a/R/data-model-helpers.R +++ b/R/data-model-helpers.R @@ -16,34 +16,3 @@ new_data_model <- function(tables, columns, references) { class = "data_model" ) } - -get_datamodel_from_overview <- function(overview) { - new_data_model( - tables = datamodel_tables_from_overview(overview), - columns = datamodel_columns_from_overview(overview), - references = datamodel_references_from_overview(overview) - ) -} - -datamodel_tables_from_overview <- function(overview) { - overview %>% - distinct(table) %>% - add_column(segment = NA_character_, display = NA_character_) %>% - as.data.frame(stringsAsFactors = FALSE) -} - -datamodel_columns_from_overview <- function(overview) { - overview %>% - select(column, type, table, key, ref, ref_col) %>% - mutate(key = as.numeric(key)) %>% - as.data.frame(stringsAsFactors = FALSE) -} - -datamodel_references_from_overview <- function(overview) { - overview %>% - filter(!is.na(ref)) %>% - select(table, column, ref, ref_col) %>% - mutate(ref_id = as.numeric(row_number())) %>% - add_column(ref_col_num = 1) %>% - as.data.frame(stringsAsFactors = FALSE) -} diff --git a/R/datamodelr-code.R b/R/datamodelr-code.R index 8445cc2e19..e9b384df46 100644 --- a/R/datamodelr-code.R +++ b/R/datamodelr-code.R @@ -1,10 +1,6 @@ # data_model code directly from {datamodelr} -------------------------------------- -is.data_model <- function(x) { - inherits(x, "data_model") -} - bdm_create_references <- function(col_table) { if (!inherits(col_table, "data.frame")) stop("Input must be a data frame.")