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 }