diff --git a/R/archive_table.R b/R/archive_table.R index d94b3f89be784ab011535178a93fafc219a84ce1..36ad48a05a52d38cf7cc6e69e6a67ac31a9fadd3 100644 --- a/R/archive_table.R +++ b/R/archive_table.R @@ -82,6 +82,9 @@ archive_table <- function(host, database, schema, new_schema = NULL, table, role db_dest = database, user = role) + # Fermer la connexion à la base de données + DBI::dbDisconnect(connexion) + # Retourner le nom de la nouvelle table archivée return(new_table) } diff --git a/R/check_structure_table.R b/R/check_structure_table.R index 7aeae79de90df3918a379ebfbac3db63ea5bb3df..95e56f29d4afa53a7d1d78e45f5b507cc0580a7f 100644 --- a/R/check_structure_table.R +++ b/R/check_structure_table.R @@ -22,17 +22,26 @@ #' @export #' @examples #' \dontrun{ -#' # Création d'un dataframe à partir d'un fichier XLSX -#' data_ars_2022 <- import_xlsx( -#' filepath = system.file("Nitrates_2022.xlsx", package = "collectr"), -#' sheet = 1, -#' row = 2) +#' # Création d'un dataframe de test +#' test <- data.frame( +#' id = 1:5, +#' name = c("Alice", "Bob", "Charlie", "David", "Eve"), +#' birthdate = c("1990-01-15", "1985-06-22", "1992-09-10", "1988-03-05", "1995-12-30"), +#' value = rnorm(5) +#' ) +#' # Création d'une table de test en base +#' create_dummy(host = "localhost", +#' database = "collectr", +#' schema = "public", +#' table = "dummy", +#' role = "runner") #' # Utilisation de la fonction check_structure_table() -#' check_structure_table(database = "si_eau", -#' schema = "nitrates", -#' table = "nitrate_data_analyse_ars_test", -#' dataframe = data_ars_2022, -#' role = "admin") +#' check_structure_table(host = "localhost", +#' database = "collectr", +#' schema = "public", +#' table = "dummy", +#' dataframe = test, +#' role = "runner") #' } check_structure_table <- function(host, database, schema, table, dataframe, role) { # Se connecter à la base de données PostgreSQL @@ -42,7 +51,8 @@ check_structure_table <- function(host, database, schema, table, dataframe, role ecoSQL = FALSE) # Vérifier si la table existe dans la base de données - if (!table_exists(database = database, schema = schema, table = table, role = role)) { + if (!table_exists(host = host, database = database, schema = schema, + table = table, role = role)) { stop("La table sp\u00e9cifi\u00e9e n\'existe pas dans la base de donn\u00e9es.") } @@ -72,5 +82,9 @@ check_structure_table <- function(host, database, schema, table, dataframe, role return(FALSE) } + # Fermer la connexion à la base de données + DBI::dbDisconnect(connexion) + + # Retourner TRUE si les attributs correspondent return(TRUE) } diff --git a/R/create_dummy.R b/R/create_dummy.R index b336040f9af7def14646b63a146bd677003fedd3..faa2ec5c8d398bbd425b748644ad39889f69ca78 100644 --- a/R/create_dummy.R +++ b/R/create_dummy.R @@ -8,6 +8,7 @@ #' @param database Nom de la base de données PostgreSQL. #' @param schema Nom du schéma dans lequel créer la table. #' @param table Nom de la table à créer. +#' @param pk Clé primaire de la table à créer. NULL par défaut. #' @param role Nom du rôle (utilisateur) pour se connecter à la base de données. #' #' @return Un message indiquant si la table a été créée avec succès. @@ -27,7 +28,7 @@ #' table = "dummy", #' role = "runner") #' } -create_dummy <- function(host, database, schema, table, role) { +create_dummy <- function(host, database, schema, table, pk = NULL, role) { # Se connecter à la base de données PostgreSQL connexion <- datalibaba::connect_to_db(server = host, db = database, @@ -52,6 +53,7 @@ create_dummy <- function(host, database, schema, table, role) { table = table, schema = schema, db = database, + pk = pk, overwrite = TRUE, user = role, server = host) diff --git a/R/download_and_extract_wfs.R b/R/download_and_extract_wfs.R index 7235a2306122651b01f9ea97f74c515550d3f1b7..7b2d51f37fd8fefc3c41c1a9ab0c300f4661371d 100644 --- a/R/download_and_extract_wfs.R +++ b/R/download_and_extract_wfs.R @@ -1,18 +1,18 @@ -#' Télécharge et extrait un fichier compressé à partir de l'URL d'un flux WFS +#' Télécharge et extrait un fichier compressé à partir de l'URL d'un flux WFS #' (Web Feature Service) #' -#' @description Cette fonction télécharge un fichier zippé à partir de l'URL -#' d'un flux WFS (Web Feature Service), le décompresse dans un dossier -#' temporaire et renvoie le chemin vers le fichier extrait avec l'extension +#' @description Cette fonction télécharge un fichier zippé à partir de l'URL +#' d'un flux WFS (Web Feature Service), le décompresse dans un dossier +#' temporaire et renvoie le chemin vers le fichier extrait avec l'extension #' spécifiée. #' #' @param url L'URL du fichier compressé à télécharger. -#' @param file_extension L'extension du fichier à extraire du fichier compressé +#' @param file_extension L'extension du fichier à extraire du fichier compressé #' (par exemple, "shp", "gpkg", "csv", etc.). #' @return Le chemin vers le fichier extrait avec l'extension spécifiée. #' @importFrom utils download.file unzip -#' +#' #' @export #' @examples #' \dontrun{ @@ -22,7 +22,7 @@ #' "SERVICE=WFS&", #' "VERSION=2.0.0&", #' "REQUEST=GetFeature&", -#' "typename=BassinDCE&", +#' "typename=ObstEcoul_GUF&", #' "SRSNAME=EPSG:4326&", #' "OUTPUTFORMAT=SHAPEZIP" #' ) @@ -44,11 +44,11 @@ download_and_extract_wfs <- function(url, file_extension) { # Trouver le chemin vers le fichier extrait avec l'extension spécifiée extracted_files <- list.files(temp_dir, full.names = TRUE, recursive = TRUE) file_path <- extracted_files[grep(paste0("\\.", file_extension, "$"), extracted_files)] - + # Vérifier si le fichier a été trouvé if (length(file_path) == 0) { stop(paste("Le fichier avec l\'extension", file_extension, "n\'a pas \u00e9t\u00e9 trouv\u00e9 dans le dossier temporaire.")) } - + return(file_path) } diff --git a/R/format_colnames.R b/R/format_colnames.R index 791162307163d64cc406c0f373feba12963a3ee6..7a22ec833fef0e652b2cab8e3aedb5712cfcac98 100644 --- a/R/format_colnames.R +++ b/R/format_colnames.R @@ -1,9 +1,9 @@ #' Formate les noms des colonnes #' -#' @description Cette fonction formate les noms des colonnes d'un dataframe en -#' remplaçant les caractères spéciaux par des chaînes vides, en mettant les noms -#' en minuscules et en ajoutant des underscores avant les majuscules +#' @description Cette fonction formate les noms des colonnes d'un dataframe en +#' remplaçant les caractères spéciaux par des chaînes vides, en mettant les noms +#' en minuscules et en ajoutant des underscores avant les majuscules #' (sauf au début du nom). #' #' @param colnames Vecteur contenant les noms des colonnes à formater. @@ -23,8 +23,14 @@ format_colnames <- function(colnames) { # Ajouter des underscores avant les majuscules (sauf au début du nom) colnames <- gsub("([[:lower:]]|\\s)([[:upper:]])", "\\1_\\2", colnames) - # Remplacer les caractères spéciaux et mettre en minuscules - colnames <- gsub("[^[:alnum:]_]", "", tolower(colnames)) + # Remplacer les accents par leurs équivalents sans accent + colnames <- iconv(colnames, from = "UTF-8", to = "ASCII//TRANSLIT") + + # Remplacer les caractères spéciaux (hors underscores et alphanumériques) + colnames <- gsub("[^[:alnum:]_]", "", colnames) + + # Mettre en minuscules + colnames <- tolower(colnames) return(colnames) } diff --git a/R/import_xlsx.R b/R/import_xlsx.R index 35d983a6cfb0b0342261d642b1fb62d1cb6b14e8..fe58a0009cc175d2294f05579dd8f45032e2b6c1 100644 --- a/R/import_xlsx.R +++ b/R/import_xlsx.R @@ -1,7 +1,7 @@ #' Importe un fichier XLSX dans un dataframe #' -#' @description Cette fonction importe un fichier au format XLSX dans un +#' @description Cette fonction importe un fichier au format XLSX dans un #' dataframe en supprimant les caractères spéciaux des noms de colonnes. #' #' @return Un dataframe correspondant au contenu du fichier. @@ -9,14 +9,13 @@ #' @param sheet Numéro de l'onglet à importer. #' @param row Numéro de la ligne de début de lecture. #' @importFrom readxl read_xlsx -#' +#' #' @export #' @examples #' # Utilisation de la fonction import_xlsx() -#' data_ars_2022 <- import_xlsx( -#' filepath = "C:\\TEMP\\Nitrates_2022.xlsx", -#' sheet = 1, -#' row = 1) +#' plans_eau_usage <- import_xlsx(system.file("plans_eau_usage.xlsx", +#' package = "collectr"), +#' sheet = 1, row = 0) #' import_xlsx <- function(filepath, sheet, row) { @@ -30,8 +29,8 @@ import_xlsx <- function(filepath, sheet, row) { # Déclarer la première ligne comme nom de variable col_names = TRUE ) - - colnames(data) <- collectr::remove_special_chars(colnames(data)) + + colnames(data) <- collectr::format_colnames(colnames(data)) return(data) } diff --git a/R/table_exists.R b/R/table_exists.R index 9d6126e002e5f9368068938a630c6056ddc4baf6..add84c2804b291212afb396e602777d2a3fa42a7 100644 --- a/R/table_exists.R +++ b/R/table_exists.R @@ -35,11 +35,15 @@ table_exists <- function(host, database, schema, table, role) { stop("La connexion fournie n\'est pas une connexion PostgreSQL valide.") } + # Lister les tables du schéma spécifié tables <- datalibaba::list_tables(connexion, schema = schema, db = database) + + # Vérifier la présence de la table spécifiée parmi celles du schéma table_exists <- table %in% tables # Fermer la connexion à la base de données DBI::dbDisconnect(connexion) + # Retourner TRUE si la table existe return(table_exists) } diff --git a/dev/0-dev_history.Rmd b/dev/0-dev_history.Rmd index ca0023d0342d82b682d7f11793590242e506a7f0..e545891433edfc668916a66d259352e51fba7b4a 100644 --- a/dev/0-dev_history.Rmd +++ b/dev/0-dev_history.Rmd @@ -75,6 +75,7 @@ gitlabr::use_gitlab_ci(type = "check-coverage-pkgdown") ## Fonctions ```{r, eval=FALSE} usethis::use_r("archive_table") +usethis::use_r("check_structure_table") usethis::use_r("close_all_connections") usethis::use_r("create_dummy") usethis::use_r("create_schema") @@ -84,6 +85,7 @@ usethis::use_r("format_filepath") usethis::use_r("get_variable_completion_rate") usethis::use_r("import_geopackage") usethis::use_r("import_shapefile") +usethis::use_r("import_xlsx") usethis::use_r("modify_column_type") usethis::use_r("remove_special_chars") usethis::use_r("rename_field") @@ -95,6 +97,7 @@ usethis::use_r("table_exists") ```{r, eval=FALSE} usethis::use_test("archive_table") +usethis::use_test("check_structure_table") usethis::use_test("close_all_connections") usethis::use_test("create_dummy") usethis::use_test("create_schema") @@ -104,6 +107,7 @@ usethis::use_test("format_filepath") usethis::use_test("get_variable_completion_rate") usethis::use_test("import_geopackage") usethis::use_test("import_shapefile") +usethis::use_test("import_xlsx") usethis::use_test("modify_column_type") usethis::use_test("remove_special_chars") usethis::use_test("rename_field") @@ -116,18 +120,21 @@ usethis::use_test("table_exists") ```{r} # Simulate package installation pkgload::load_all() +``` +```{r} # Generate documentation and deal with dependencies attachment::att_amend_desc() +``` +```{r} # Add variables in globals.R checkhelper::print_globals() +``` +```{r} # Check the package devtools::check() - -# Manually add dependances -usethis::use_package("mockery") ``` # Share the package diff --git a/inst/plans_eau_usage.xlsx b/inst/plans_eau_usage.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..04a25cb32378b7263e566b28d00dfe6f9fbd784c Binary files /dev/null and b/inst/plans_eau_usage.xlsx differ diff --git a/man/check_structure_table.Rd b/man/check_structure_table.Rd index 045b68fa4b670763b08105fe36318c4034920e62..3083713da0ad34e878d504c51e384148dd4fc9d5 100644 --- a/man/check_structure_table.Rd +++ b/man/check_structure_table.Rd @@ -30,16 +30,25 @@ dataframe source et celle d'une table cible dans la base de données } \examples{ \dontrun{ -# Création d'un dataframe à partir d'un fichier XLSX -data_ars_2022 <- import_xlsx( - filepath = system.file("Nitrates_2022.xlsx", package = "collectr"), - sheet = 1, - row = 2) +# Création d'un dataframe de test +test <- data.frame( + id = 1:5, + name = c("Alice", "Bob", "Charlie", "David", "Eve"), + birthdate = c("1990-01-15", "1985-06-22", "1992-09-10", "1988-03-05", "1995-12-30"), + value = rnorm(5) +) +# Création d'une table de test en base +create_dummy(host = "localhost", + database = "collectr", + schema = "public", + table = "dummy", + role = "runner") # Utilisation de la fonction check_structure_table() -check_structure_table(database = "si_eau", - schema = "nitrates", - table = "nitrate_data_analyse_ars_test", - dataframe = data_ars_2022, - role = "admin") +check_structure_table(host = "localhost", + database = "collectr", + schema = "public", + table = "dummy", + dataframe = test, + role = "runner") } } diff --git a/man/create_dummy.Rd b/man/create_dummy.Rd index cc6902834dac38e07617c329851348b1a5c9d1d5..20c3bcd7277e296b8b888a0c1d4405ade4cebb0d 100644 --- a/man/create_dummy.Rd +++ b/man/create_dummy.Rd @@ -4,7 +4,7 @@ \alias{create_dummy} \title{Crée une table de test dans une base de données PostgreSQL} \usage{ -create_dummy(host, database, schema, table, role) +create_dummy(host, database, schema, table, pk = NULL, role) } \arguments{ \item{host}{Hôte de la base de données PostgreSQL.} @@ -15,6 +15,8 @@ create_dummy(host, database, schema, table, role) \item{table}{Nom de la table à créer.} +\item{pk}{Clé primaire de la table à créer. NULL par défaut.} + \item{role}{Nom du rôle (utilisateur) pour se connecter à la base de données.} } \value{ diff --git a/man/download_and_extract_wfs.Rd b/man/download_and_extract_wfs.Rd index 23153f1c14491c949d9893600f99117b62c798da..a004d06e6ebb62dfb14d60091f2ebd7a64bb5d48 100644 --- a/man/download_and_extract_wfs.Rd +++ b/man/download_and_extract_wfs.Rd @@ -30,7 +30,7 @@ url_wfs <- paste0( "SERVICE=WFS&", "VERSION=2.0.0&", "REQUEST=GetFeature&", - "typename=BassinDCE&", + "typename=ObstEcoul_GUF&", "SRSNAME=EPSG:4326&", "OUTPUTFORMAT=SHAPEZIP" ) diff --git a/man/import_shapefile.Rd b/man/import_shapefile.Rd index 7d70b861de80f25f42f50d625b5551ca5e9db5ac..37901a55f99274ef3252a609feb55130a2ca40b0 100644 --- a/man/import_shapefile.Rd +++ b/man/import_shapefile.Rd @@ -24,6 +24,6 @@ si elle existe. \examples{ \dontrun{ # Importer le fichier shapefile dans un dataframe -chef_lieu <- import_shapefile(system.file("CHFLIEU_COMMUNE_ASSOCIEE_OU_DELEGUEE.shp", package = "collectr"),2154) +gare <- import_shapefile(system.file("GARE.shp", package = "collectr"),2154) } } diff --git a/man/import_xlsx.Rd b/man/import_xlsx.Rd index 81bdde3194cfe8dadf69be873497947d8304305e..fb1ea3e9a4c55846dc9d234c3dbd7e57329ec566 100644 --- a/man/import_xlsx.Rd +++ b/man/import_xlsx.Rd @@ -22,9 +22,8 @@ dataframe en supprimant les caractères spéciaux des noms de colonnes. } \examples{ # Utilisation de la fonction import_xlsx() -data_ars_2022 <- import_xlsx( - filepath = "C:\\\\TEMP\\\\Nitrates_2022.xlsx", - sheet = 1, - row = 1) +plans_eau_usage <- import_xlsx(system.file("plans_eau_usage.xlsx", + package = "collectr"), + sheet = 1, row = 0) } diff --git a/tests/testthat/test-check_structure_table.R b/tests/testthat/test-check_structure_table.R new file mode 100644 index 0000000000000000000000000000000000000000..234f1f712c908b4334dff7311594710119cf2dc6 --- /dev/null +++ b/tests/testthat/test-check_structure_table.R @@ -0,0 +1,64 @@ +test_that("check_structure_table works", { + + Sys.setenv(user_runner="runner") + Sys.setenv(pwd_runner=Sys.getenv("BDD_RUNNER_PWD")) + + # Création d'un dataframe de test + test <- data.frame( + id = 1:5, + name = c("Alice", "Bob", "Charlie", "David", "Eve"), + birthdate = c("1990-01-15", "1985-06-22", "1992-09-10", "1988-03-05", "1995-12-30"), + value = rnorm(5) + ) + + # Création d'une table de test en base avec id en clé primaire + create_dummy(host = "localhost", + database = "collectr", + schema = "public", + table = "dummy", + pk = "id", + role = "runner") + + expect_true(check_structure_table( + "localhost", "collectr", "public", "dummy", test, "runner")) + + # Création d'une table de test en base sans clé primaire indiquée + create_dummy(host = "localhost", + database = "collectr", + schema = "public", + table = "dummy", + role = "runner") + + expect_false(check_structure_table( + "localhost", "collectr", "public", "dummy", test, "runner")) + + # Création d'un dataframe avec une colonne en trop + test_extra_col <- data.frame( + id = integer(), + name = character(), + birthdate = as.Date(character()), + value = numeric(), + extra_col = character() + ) + + expect_false(check_structure_table( + "localhost", "collectr", "public", "dummy", test_extra_col, "runner")) + +}) + +test_that("check_structure_table fails", { + + Sys.setenv(user_runner="runner") + Sys.setenv(pwd_runner=Sys.getenv("BDD_RUNNER_PWD")) + + skip_on_ci() + # Vérification qu'une erreur est retournée en cas d'absence de la table à archiver + expect_error( + check_structure_table( + host = "localhost", database = "collectr", schema = "public", + table = "ghost", role = "runner"), + regexp = "La table sp\u00e9cifi\u00e9e n\'existe pas dans la base de donn\u00e9es." + ) + +}) + diff --git a/tests/testthat/test-import_xlsx.R b/tests/testthat/test-import_xlsx.R new file mode 100644 index 0000000000000000000000000000000000000000..5cbedb0ea00b86609637697a97a1fdd799035697 --- /dev/null +++ b/tests/testthat/test-import_xlsx.R @@ -0,0 +1,18 @@ +test_that("import_xlsx works", { + + result <- import_xlsx(system.file("plans_eau_usage.xlsx", + package = "collectr"), + sheet = 1, row = 0) + + # Vérifier que la sortie est un dataframe + expect_s3_class(result, "data.frame") + + # Vérifier le nombre de lignes + expect_equal(nrow(result), 13) + + # Vérifier le nombre de colonnes + expect_equal(ncol(result), 3) + + # Vérifier qu'il n'y a plus de caractères spéciaux + expect_true(!any(grepl("[^A-Za-z0-9_]", colnames(result)))) +}) diff --git a/vignettes/database-utils.Rmd b/vignettes/database-utils.Rmd index 215c68e110630459d40e52aa2a458420974625bb..7f177bff99e42f22fc7d69710f7223be297608db 100644 --- a/vignettes/database-utils.Rmd +++ b/vignettes/database-utils.Rmd @@ -92,17 +92,26 @@ table_exists(host = "localhost", ```{r examples-check_structure_table, eval=FALSE} #' \dontrun{ -# Création d'un dataframe à partir d'un fichier XLSX -data_ars_2022 <- import_xlsx( - filepath = "C:\\TEMP\\Nitrates_2022.xlsx", - sheet = 1, - row = 2) +# Création d'un dataframe de test +test <- data.frame( + id = 1:5, + name = c("Alice", "Bob", "Charlie", "David", "Eve"), + birthdate = c("1990-01-15", "1985-06-22", "1992-09-10", "1988-03-05", "1995-12-30"), + value = rnorm(5) +) +# Création d'une table de test en base +create_dummy(host = "localhost", + database = "collectr", + schema = "public", + table = "dummy", + role = "runner") # Utilisation de la fonction check_structure_table() -check_structure_table(database = "si_eau", - schema = "nitrates", - table = "nitrate_data_analyse_ars_test", - dataframe = data_ars_2022, - role = "admin") +check_structure_table(host = "localhost", + database = "collectr", + schema = "public", + table = "dummy", + dataframe = test, + role = "runner") #' } ``` diff --git a/vignettes/import-data.Rmd b/vignettes/import-data.Rmd index f7d161b9df7f2688647d914199d97ead312b718e..1353589578ab6d3a6851e6f3e4aea65b334103d9 100644 --- a/vignettes/import-data.Rmd +++ b/vignettes/import-data.Rmd @@ -32,7 +32,7 @@ url_wfs <- paste0( "SERVICE=WFS&", "VERSION=2.0.0&", "REQUEST=GetFeature&", - "typename=BassinDCE&", + "typename=ObstEcoul_GUF&", "SRSNAME=EPSG:4326&", "OUTPUTFORMAT=SHAPEZIP" ) @@ -46,7 +46,7 @@ shapefile_path <- download_and_extract_wfs(url_wfs, "shp") ```{r examples-import_geopackage, eval=FALSE} #' \dontrun{ -# Utilisation de la fonction import_geopackage() +# Importer le fichier GeoPackage dans un dataframe aerodrome <- import_geopackage(system.file("aerodrome.gpkg", package = "collectr")) #' } ``` @@ -55,7 +55,7 @@ aerodrome <- import_geopackage(system.file("aerodrome.gpkg", package = "collectr ```{r examples-import_shp, eval=FALSE} #' \dontrun{ -# Importer le fichier shapefile dans un dataframe +# Importer le fichier Shapefile dans un dataframe gare <- import_shapefile(system.file("GARE.shp", package = "collectr"),2154) #' } ``` @@ -65,12 +65,12 @@ gare <- import_shapefile(system.file("GARE.shp", package = "collectr"),2154) ## Import de données au format XLSX ```{r examples-import_xlsx, eval=FALSE} -# Utilisation de la fonction import_xlsx() -data_ars_2022 <- import_xlsx( - filepath = "C:\\TEMP\\Nitrates_2022.xlsx", - sheet = 1, - row = 1) - +#' \dontrun{ +# Importer le fichier XLSX dans un dataframe +plans_eau_usage <- import_xlsx(system.file("plans_eau_usage.xlsx", + package = "collectr"), + sheet = 1, row = 0) +#' } ``` ## Import de données au format XLS