diff --git a/R/duckdf.R b/R/duckdf.R index f1b26ba..b9089f4 100644 --- a/R/duckdf.R +++ b/R/duckdf.R @@ -2,72 +2,46 @@ duckdf <- function(query = "", persist = FALSE, df_name = NULL, db_name = NULL) { - -# If they want a DuckDB on disk..... -if (persist == TRUE) { - + + # If they want a DuckDB on disk..... + if (persist == TRUE) { + duckdf::persist(query, db_name) - -} else { - -# create a DuckDB connection, either as a temporary in-memory database (default) -con <- DBI::dbConnect(duckdb::duckdb(), dbdir = ":memory:", read_only = FALSE) - -# if there's a named dataframe (or multiple), do this -if (!is.null(df_name)) { - -duckdb_reg <- function(x) { - - duckdb::duckdb_register(con, paste(x), get(x))} - - sapply(df_name, duckdb_reg) - -} else { - -# if there isn't a named dataframe, string queries -# Extract dataframe name using string splits -query_split <- stringi::stri_split_fixed(query, "FROM", - omit_empty = TRUE, - opts_fixed = stringi::stri_opts_fixed(case_insensitive = TRUE)) - -query_split <- trimws(unlist(query_split)) - -from_df_first <- stringi::stri_extract_first_words(query_split[2], - locale = NULL) - -# register a dataframe view in duckdb -duckdb::duckdb_register(con, paste(from_df_first), get(from_df_first)) - -# If a JOIN exists do this -if (stringi::stri_detect_fixed(query, "JOIN", - opts_fixed = stringi::stri_opts_fixed(case_insensitive = TRUE)) == TRUE) { - -# Extract dataframe name using sting splits -query_split_second <- stringi::stri_split_fixed(query, "JOIN", - omit_empty = TRUE, - opts_fixed = stringi::stri_opts_fixed(case_insensitive = TRUE)) - -query_split_second <- trimws(unlist(query_split_second)) - -from_df_second <- stringi::stri_extract_first_words(query_split_second[2], - locale = NULL) - -# register a dataframe view in duckdb -duckdb::duckdb_register(con, paste(from_df_second), get(from_df_second)) - - } + + } else { + + # create a DuckDB connection, either as a temporary in-memory database (default) + con <- DBI::dbConnect(duckdb::duckdb(), dbdir = ":memory:", read_only = FALSE) + + # if there's NOT a named dataframe (or multiple), find them in the query + if (is.null(df_name)) { + query_dfs=stringr::str_match_all(query, '(?i)(\\bfrom\\b|\\bjoin\\b)\\s*(\\w+)')[[1]][,3] + query_dfs=unique(query_dfs) + if_df_exists=function(x){ + tryCatch( + expr = { is(eval.parent(parse(text=x)), "data.frame") }, + error = function(e){ F } ) } - -# execute required SQL query against the new DuckDB table -statement_result <- DBI::dbGetQuery(con, query) - -# close the connection -DBI::dbDisconnect(con, shutdown = TRUE) - -# return results -return(statement_result) - + if(length(query_dfs)>0) df_name= query_dfs[ sapply(query_dfs,if_df_exists) ] } + + duckdb_reg <- function(x) { + + duckdb::duckdb_register(con, paste(x), get(x))} + + if (!is.null(df_name)) sapply(df_name, duckdb_reg) + + + + # execute required SQL query against the new DuckDB table + statement_result <- DBI::dbGetQuery(con, query) + + # close the connection + DBI::dbDisconnect(con, shutdown = TRUE) + + # return results + return(statement_result) + + } } -