Mercurial > repos > prog > lcmsmatching
comparison mysql.R @ 0:e66bb061af06 draft
planemo upload for repository https://github.com/workflow4metabolomics/lcmsmatching.git commit 3529b25417f8e1a5836474c9adec4b696d35099d-dirty
| author | prog |
|---|---|
| date | Tue, 12 Jul 2016 12:02:37 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:e66bb061af06 |
|---|---|
| 1 library(RMySQL, quietly = TRUE) | |
| 2 | |
| 3 ############# | |
| 4 # RUN QUERY # | |
| 5 ############# | |
| 6 | |
| 7 # conn The connection to the database. | |
| 8 # queries A query or a list of queries. | |
| 9 # close Close query with a ';' if not already done. | |
| 10 # RETURN The last query result. | |
| 11 run_query <- function(conn, queries, close = TRUE) { | |
| 12 | |
| 13 for (query in queries) { | |
| 14 | |
| 15 # Append ';' | |
| 16 if (close) { | |
| 17 n <- nchar(query) | |
| 18 if (substr(query, n, n) != ';') | |
| 19 query <- paste0(query, ';') | |
| 20 } | |
| 21 | |
| 22 # Send query | |
| 23 result <- dbSendQuery(conn, query) | |
| 24 | |
| 25 # Test that everything went right | |
| 26 # if ( ! dbHasCompleted(result)) | |
| 27 # stop("Can't run the following query : ", query) | |
| 28 } | |
| 29 | |
| 30 # Return result | |
| 31 return(invisible(result)) | |
| 32 } | |
| 33 | |
| 34 ################ | |
| 35 # RUN SQL FILE # | |
| 36 ################ | |
| 37 | |
| 38 # conn The connection to the DBMS. | |
| 39 # file The path to the SQL file. | |
| 40 run_sql_file <- function(conn, file) { | |
| 41 | |
| 42 # Split SQL into single queries and put them into a list | |
| 43 queries <- character() | |
| 44 query <- "" | |
| 45 for (line in readLines(file)) { | |
| 46 line <- sub('^(.*)\\s*--.*$', '\\1', line, perl = TRUE) # remove one line comment | |
| 47 if (grepl("^\\s*$", line)) next # empty line | |
| 48 query <- paste(query, line) | |
| 49 if (grepl(";\\s*$", line, perl = TRUE)) { | |
| 50 query <- gsub("\t", " ", query, perl = TRUE) # replace tabulation by spaces | |
| 51 query <- gsub("/\\*.*\\*/", "", query, perl = TRUE) # remove multiline comments | |
| 52 queries <- c(queries, query) | |
| 53 query <- "" | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 # Run queries | |
| 58 invisible(run_query(conn, queries)) | |
| 59 } | |
| 60 | |
| 61 ################# | |
| 62 # DROP DATABASE # | |
| 63 ################# | |
| 64 | |
| 65 # conn The connection to the DBMS. | |
| 66 # db The name of the database to drop. | |
| 67 # fail_if_doesnt_exist Fails if database doesn't exist. | |
| 68 drop_database <- function(conn, db, fail_if_doesnt_exist = FALSE) { | |
| 69 invisible(run_query(conn, paste("drop database", if (fail_if_doesnt_exist) "" else "if exists", db))) | |
| 70 } | |
| 71 | |
| 72 ################### | |
| 73 # CREATE DATABASE # | |
| 74 ################### | |
| 75 | |
| 76 # conn The connection to the DBMS. | |
| 77 # db The name of the database to create. | |
| 78 # drop Drop/erase existing database. | |
| 79 # encoding Set the character set encoding to use as default for the database. | |
| 80 # use If true, switch to the newly created database. | |
| 81 create_database <- function(conn, db, drop = FALSE, encoding = 'utf8', use = TRUE) { | |
| 82 | |
| 83 # Drop database | |
| 84 if (drop) drop_database(conn, db) | |
| 85 | |
| 86 # Create database | |
| 87 enc <- if (is.null(encoding) || is.na(encoding)) "" else paste("character set", encoding) | |
| 88 run_query(conn, paste("create database", db, enc)) | |
| 89 | |
| 90 # Switch to database | |
| 91 invisible(run_query(conn, paste("use", db))) | |
| 92 } | |
| 93 | |
| 94 ############################## | |
| 95 # CONVERT VALUE TO SQL VALUE # | |
| 96 ############################## | |
| 97 | |
| 98 to_sql_value <- function(x) { | |
| 99 | |
| 100 # NA or NULL | |
| 101 if (length(x) == 0 || is.na(x) || is.null(x)) | |
| 102 return('null') | |
| 103 | |
| 104 # String | |
| 105 if (is.character(x)) | |
| 106 return(paste0('"', as.character(x), '"')) | |
| 107 | |
| 108 return(x) | |
| 109 } | |
| 110 | |
| 111 #################### | |
| 112 # MAKE INSERT LINE # | |
| 113 #################### | |
| 114 | |
| 115 make_insert_line <- function(values) { | |
| 116 values <- lapply(values, to_sql_value) | |
| 117 return(paste0("(", paste(values, collapse=','), ")")) | |
| 118 } | |
| 119 | |
| 120 ########## | |
| 121 # INSERT # | |
| 122 ########## | |
| 123 | |
| 124 # Run a insert query on a MySQL database. | |
| 125 # conn Connection to a database. | |
| 126 # table Table name. | |
| 127 # fields List of field names. | |
| 128 # values List of list of values. NA values will be translated as NULL. | |
| 129 insert <- function(conn, table, fields, values) { | |
| 130 | |
| 131 # Do nothing if no values | |
| 132 if (length(values) == 0 ) return | |
| 133 | |
| 134 # Build header | |
| 135 h <- paste("insert into", table) | |
| 136 h <- paste0(h, "(", paste(fields, collapse = ','), ")") | |
| 137 h <- paste(h, "values") | |
| 138 | |
| 139 qr <- paste(h, paste0(lapply(values, make_insert_line), collapse=','), ';') | |
| 140 | |
| 141 # Send query | |
| 142 run_query(conn, qr) | |
| 143 } | |
| 144 | |
| 145 ######## | |
| 146 # JOIN # | |
| 147 ######## | |
| 148 | |
| 149 Join <- setRefClass("Join", fields = list(table = "character", left_field = "character", right_field = "character", outer = "character")) | |
| 150 | |
| 151 Join$methods( initialize = function(table, left_field, right_field, outer = NA_character_) { | |
| 152 table <<- table | |
| 153 left_field <<- left_field | |
| 154 right_field <<- right_field | |
| 155 outer <<- outer | |
| 156 }) | |
| 157 | |
| 158 Join$methods( getStatement = function() { | |
| 159 type <- 'INNER JOIN' | |
| 160 if ( ! is.na(outer)) | |
| 161 switch(tolower(outer), | |
| 162 left = type <- 'LEFT OUTER JOIN', | |
| 163 right = type <- 'RIGHT OUTER JOIN', | |
| 164 stop('Error in join outer type. "', outer ,'" is unknown. You must choose between "LEFT" and "RIGHT".') | |
| 165 ) | |
| 166 | |
| 167 return(paste(type, .self$table, 'ON', .self$left_field, '=', .self$right_field)) | |
| 168 }) | |
| 169 | |
| 170 ########## | |
| 171 # SELECT # | |
| 172 ########## | |
| 173 | |
| 174 # Run a select query on a MySQL database. Returns the dataframe of results. | |
| 175 # conn Connection to a database. | |
| 176 select <- function(conn, fields, from, joins = NULL , where = NULL, orderby = NULL) { | |
| 177 | |
| 178 # Select/from | |
| 179 rq <- paste("SELECT ", paste(fields, collapse = ', '), 'FROM', from) | |
| 180 | |
| 181 # Joins | |
| 182 if ( ! is.null(joins) && length(joins) > 0) | |
| 183 rq <- paste(rq, paste(lapply(joins, function (x) x$getStatement() ), collapse = ' ')) | |
| 184 | |
| 185 # Where | |
| 186 if ( ! is.null(where)) rq <- paste(rq, 'WHERE', where) | |
| 187 | |
| 188 # Order by | |
| 189 if ( ! is.null(orderby)) rq <- paste(rq, 'ORDER BY', orderby) | |
| 190 | |
| 191 # End request, send it and get results | |
| 192 rq <- paste0(rq, ';') | |
| 193 res <- try(dbSendQuery(conn, rq)) | |
| 194 data <- fetch(res, n=-1) | |
| 195 | |
| 196 return(data) | |
| 197 } | |
| 198 | |
| 199 ####################### | |
| 200 # SELECT SINGLE FIELD # | |
| 201 ####################### | |
| 202 | |
| 203 select_single_field <- function(conn, field, from, where = NULL) { | |
| 204 values <- select(conn, fields = field, from = from, where = where) | |
| 205 val <- if (field %in% colnames(values) && length(values[field][[1]]) > 0) values[field][[1]] else NA_character_ | |
| 206 return(val) | |
| 207 } |
