diff --git a/src/data/streams/aware_postgresql/container.R b/src/data/streams/aware_postgresql/container.R new file mode 100644 index 00000000..2aa9c9bb --- /dev/null +++ b/src/data/streams/aware_postgresql/container.R @@ -0,0 +1,107 @@ +# if you need a new package, you should add it with renv::install(package) so your renv venv is updated +library(RPostgres) +# Needs libpq-dev for compiling from source. + +# Error installing package 'RPostgres': +# ===================================== +# +# * installing *source* package 'RPostgres' ... +# ** package 'RPostgres' successfully unpacked and MD5 sums checked +# ** using staged installation +# Using PKG_CFLAGS= +# Using PKG_LIBS=-lpq +# Using PKG_PLOGR= +# ------------------------- ANTICONF ERROR --------------------------- +# Configuration failed because libpq was not found. Try installing: +# * deb: libpq-dev (Debian, Ubuntu, etc) +# * rpm: postgresql-devel (Fedora, EPEL) +# * rpm: postgreql8-devel, psstgresql92-devel, postgresql93-devel, or postgresql94-devel (Amazon Linux) +# * csw: postgresql_dev (Solaris) +# * brew: libpq (OSX) +# If libpq is already installed, check that either: +# (i) 'pkg-config' is in your PATH AND PKG_CONFIG_PATH contains +# a libpq.pc file; or +# (ii) 'pg_config' is in your PATH. +# If neither can detect , you can set INCLUDE_DIR +# and LIB_DIR manually via: +# R CMD INSTALL --configure-vars='INCLUDE_DIR=... LIB_DIR=...' +# --------------------------[ ERROR MESSAGE ]---------------------------- +# :1:10: fatal error: libpq-fe.h: No such file or directory +# compilation terminated. + +library(yaml) + +#' @description +#' Auxiliary function to parse the connection credentials from a specifc group in ./credentials.yaml +#' You can reause most of this function if you are connection to a DB or Web API. +#' It's OK to delete this function if you don't need credentials, e.g., you are pulling data from a CSV for example. +#' @param group the yaml key containing the credentials to connect to a database +#' @preturn dbEngine a database engine (connection) ready to perform queries +get_db_engine <- function(group){ + # The working dir is aways RAPIDS root folder, so your credentials file is always /credentials.yaml + credentials <- read_yaml("./credentials.yaml") + if(!group %in% names(credentials)) + stop(paste("The credentials group",group, "does not exist in ./credentials.yaml. The only groups that exist in that file are:", paste(names(credentials), collapse = ","), ". Did you forget to set the group in [PHONE_DATA_STREAMS][aware_mysql][DATABASE_GROUP] in config.yaml?")) + dbEngine <- dbConnect(Postgres(), db = credentials[[group]][["database"]], + user = credentials[[group]][["user"]], + password = credentials[[group]][["password"]], + host = credentials[[group]][["host"]], + port = credentials[[group]][["port"]]) + return(dbEngine) +} + +# This file gets executed for each PHONE_SENSOR of each participant +# If you are connecting to a database the env file containing its credentials is available at "./.env" +# If you are reading a CSV file instead of a DB table, the @param sensor_container wil contain the file path as set in config.yaml +# You are not bound to databases or files, you can query a web API or whatever data source you need. + +#' @description +#' RAPIDS allows users to use the keyword "infer" (previously "multiple") to automatically infer the mobile Operative System a device was running. +#' If you have a way to infer the OS of a device ID, implement this function. For example, for AWARE data we use the "aware_device" table. +#' +#' If you don't have a way to infer the OS, call stop("Error Message") so other users know they can't use "infer" or the inference failed, +#' and they have to assign the OS manually in the participant file +#' +#' @param stream_parameters The PHONE_STREAM_PARAMETERS key in config.yaml. If you need specific parameters add them there. +#' @param device A device ID string +#' @return The OS the device ran, "android" or "ios" + +infer_device_os <- function(stream_parameters, device){ + #dbEngine <- get_db_engine(stream_parameters$DATABASE_GROUP) + #query <- paste0("SELECT device_id,brand FROM aware_device WHERE device_id = '", device, "'") + #message(paste0("Executing the following query to infer phone OS: ", query)) + #os <- dbGetQuery(dbEngine, query) + #dbDisconnect(dbEngine) + + #if(nrow(os) > 0) + # return(os %>% mutate(os = ifelse(brand == "iPhone", "ios", "android")) %>% pull(os)) + #else + stop(paste("We cannot infer the OS of the following device id because the aware_device table does not exist.")) + + #return(os) +} + +#' @description +#' Gets the sensor data for a specific device id from a database table, file or whatever source you want to query +#' +#' @param stream_parameters The PHONE_STREAM_PARAMETERS key in config.yaml. If you need specific parameters add them there. +#' @param device A device ID string +#' @param sensor_container database table or file containing the sensor data for all participants. This is the PHONE_SENSOR[CONTAINER] key in config.yaml +#' @param columns the columns needed from this sensor (we recommend to only return these columns instead of every column in sensor_container) +#' @return A dataframe with the sensor data for device + +pull_data <- function(stream_parameters, device, sensor, sensor_container, columns){ + dbEngine <- get_db_engine(stream_parameters$DATABASE_GROUP) + query <- paste0("SELECT ", paste(columns, collapse = ",")," FROM ", sensor_container, " WHERE ", columns$DEVICE_ID ," = '", device,"'") + # Letting the user know what we are doing + message(paste0("Executing the following query to download data: ", query)) + sensor_data <- dbGetQuery(dbEngine, query) + + dbDisconnect(dbEngine) + + if(nrow(sensor_data) == 0) + warning(paste("The device '", device,"' did not have data in ", sensor_container)) + + return(sensor_data) +} +