You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
4.5KB

  1. #' Pipe operator
  2. #'
  3. #' @name %>%
  4. #' @rdname pipe
  5. #' @keywords internal
  6. #' @importFrom dplyr %>%
  7. #' @export
  8. #' @usage lhs \%>\% rhs
  9. NULL
  10. #' Generate a random password
  11. #'
  12. #' Generate a random alphanumeric password of any length
  13. #'
  14. #' Generate a random alphanumeric ([A-Za-z0-9]) password
  15. #'
  16. #' @param length Length of the desired password
  17. #' @return A password of length length
  18. create_password <- function(length = 8)
  19. {
  20. stringr::str_c(sample(c(LETTERS, letters, 0:9), length), collapse = "")
  21. }
  22. #' Push a dataframe into a database table
  23. #'
  24. #' @param df Dataframe to push into the database
  25. #' @param con Database connection
  26. #' @param table Table in the database in which to push the dataframe
  27. dbPush <- function(df, con, table)
  28. {
  29. options(scipen = 999)
  30. columns <- stringr::str_c(names(df), collapse = ",")
  31. df %>%
  32. apply(1, function(oneline)
  33. {
  34. oneline[is.na(oneline)] <- "NULL"
  35. oneline %>%
  36. stringr::str_c("'", ., "'", collapse = ",") %>%
  37. stringr::str_c("(", ., ")") %>%
  38. stringr::str_replace("'NULL'", "NULL")
  39. }) %>%
  40. stringr::str_c(collapse = ",") %>%
  41. stringr::str_c("INSERT INTO ", table, " (", columns, ") VALUES ", ., ";") %>%
  42. RPostgreSQL::dbGetQuery(conn = con, .)
  43. }
  44. #' Update a dataframe into a database table
  45. #'
  46. #' @param df Dataframe to update into the database
  47. #' @param con Database connection
  48. #' @param table Table in the database in which to push the dataframe
  49. #' @param PK Character vector of the primary key(s)
  50. dbUpdate <- function(df, con, table, PK)
  51. {
  52. options(scipen = 999)
  53. df %>%
  54. apply(1, function(oneline)
  55. {
  56. oneline[is.na(oneline)] <- "NULL"
  57. stringr::str_c(names(oneline), " = '", oneline, "'", collapse = ",") %>%
  58. stringr::str_replace("'NULL'", "NULL") -> set
  59. stringr::str_c(PK, " = '", oneline[PK], "'", collapse = " AND ") -> where
  60. stringr::str_c("UPDATE ", table, " SET ", set, " WHERE ", where, ";") %>%
  61. RPostgreSQL::dbGetQuery(conn = con, .)
  62. })
  63. }
  64. #' Clear a database table
  65. #'
  66. #' Clear a database table
  67. #'
  68. #' @param db Name of the database
  69. #' @param table Name of the table
  70. #' @param host The host to connect to
  71. #' @param admin The admin account for the PostgreSQL database
  72. #' @param pass the password for the admin account
  73. #' @export
  74. clear_table <- function(db, table, host = "", admin = "", pass = "")
  75. {
  76. con <- RPostgreSQL::dbConnect(RPostgreSQL::PostgreSQL(), host = host, dbname = db, user = admin, password = pass)
  77. RPostgreSQL::dbGetQuery(con, stringr::str_c("DELETE FROM ", table, ";"))
  78. RPostgreSQL::dbGetQuery(con, stringr::str_c("VACUUM ", table, ";"))
  79. RPostgreSQL::dbDisconnect(con)
  80. }
  81. #' Upserta dataframe into a database table
  82. #'
  83. #' @param df Dataframe to upsert into the database
  84. #' @param con Database connection
  85. #' @param table Table in the database in which to push the dataframe
  86. #' @param PK Character vector of the primary key(s)
  87. dbUpsert <- function(df, con, table, PK)
  88. {
  89. options(scipen = 999)
  90. columns <- setdiff(names(df), PK)
  91. utils::write.csv(df, file = "/tmp/data.csv", row.names = F, na = "")
  92. temp <- stringr::str_c(table, "_tmp")
  93. # Create a temp table
  94. stringr::str_c("CREATE TEMP TABLE ", temp, " (LIKE ", table, ");") %>%
  95. RPostgreSQL::dbGetQuery(conn = con, .)
  96. # Load data in the temp table
  97. stringr::str_c("COPY ", temp, " (", names(df) %>% stringr::str_c(collapse = ","), ") FROM '/tmp/data.csv' WITH CSV HEADER;") %>%
  98. RPostgreSQL::dbGetQuery(conn = con, .)
  99. # Update existing rows
  100. stringr::str_c("UPDATE", table,
  101. "SET", stringr::str_c(columns, "=", temp, ".", columns, collapse = ","),
  102. "FROM", temp,
  103. "WHERE", stringr::str_c(table, ".", PK, "=", temp, ".", PK, collapse = " AND "),
  104. ";", sep = " ") %>%
  105. RPostgreSQL::dbGetQuery(conn = con, .)
  106. # Insert new rows
  107. stringr::str_c("INSERT INTO", table,
  108. "SELECT", stringr::str_c(temp, ".*"),
  109. "FROM", temp,
  110. "LEFT OUTER JOIN", table,
  111. "ON (", stringr::str_c(table, ".", PK, "=", temp, ".", PK, collapse = " AND "), ")",
  112. "WHERE", stringr::str_c(table, ".", PK, " IS NULL", collapse = " AND "),
  113. ";", sep = " ") %>%
  114. RPostgreSQL::dbGetQuery(conn = con, .)
  115. # Delete the temp table and file
  116. stringr::str_c("DROP TABLE", temp, ";", sep = " ") %>%
  117. RPostgreSQL::dbGetQuery(conn = con, .)
  118. unlink("/tmp/data.csv")
  119. }
  120. `%||%` <- function(a, b) if (is.null(a)) b else a