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 } |