github.com/Bio-core/jtree@v0.0.0-20190705165106-1d7a7e7d6272/database/query_builder.go (about) 1 package database 2 3 import ( 4 "fmt" 5 "reflect" 6 7 strings "strings" 8 9 "github.com/Bio-core/jtree/models" 10 ) 11 12 //Map for types 13 var Map map[string]string 14 15 //BuildQuery takes a Query object and returns a string of the query 16 func BuildQuery(query models.Query) string { 17 if len(query.SelectedFields) == 1 && query.SelectedFields[0] == "*" { 18 query.SelectedFields = GetColumns(query.SelectedTables) 19 } 20 fields := printFields(query.SelectedFields) 21 query.SelectedTables = orderTablesByHigharch(query.SelectedTables) 22 query.SelectedTables = detemineMissingTablesLinks(query.SelectedTables) 23 tables := printTables(query.SelectedTables) 24 queryString := "SELECT " + fields + " FROM " + tables 25 if len(query.SelectedCondition) != 0 { 26 if len(query.SelectedCondition[0]) != 0 { 27 conditions := printConditions(query.SelectedCondition) 28 queryString += " WHERE (" + conditions + ")" 29 } 30 } 31 return queryString 32 } 33 34 // Print comma separated selected fields 35 func printFields(selectedFields []string) string { 36 var str = "" 37 for i := 0; i < len(selectedFields); i++ { 38 str += selectedFields[i] + " AS '" + selectedFields[i] + "', " 39 } 40 str = str[0 : len(str)-2] 41 return str 42 } 43 44 func printTables(selectedTables []string) string { 45 var str = "" 46 for i := 0; i < len(selectedTables); i++ { 47 if i == 0 { 48 str += selectedTables[i] 49 } else { 50 str += " JOIN " + selectedTables[i] + " ON " + selectedTables[i-1] + "." + joinMap[selectedTables[i-1]][selectedTables[i]] + "=" + selectedTables[i] + "." + joinMap[selectedTables[i-1]][selectedTables[i]] 51 } 52 53 } 54 return str 55 } 56 57 func printConditions(SelectedCondition [][]string) string { 58 var str = "" 59 for i := 0; i < len(SelectedCondition); i++ { 60 SelectedCondition[i][3] = escapeChars(SelectedCondition[i][3]) 61 SelectedCondition[i] = formatCondition(SelectedCondition[i]) 62 if SelectedCondition[i] == nil { 63 return "0=1" 64 } 65 str += SelectedCondition[i][0] + " " + SelectedCondition[i][1] + SelectedCondition[i][2] 66 if Map[SelectedCondition[i][1]] == "*string" || Map[SelectedCondition[i][1]] == "*time.Time" { 67 str += "\"" + SelectedCondition[i][3] + "\" " 68 } else if Map[SelectedCondition[i][1]] == "*float32" || Map[SelectedCondition[i][1]] == "*bool" || Map[SelectedCondition[i][1]] == "*int64" { 69 str += SelectedCondition[i][3] + " " 70 71 } 72 } 73 74 str = str[4 : len(str)-1] 75 return str 76 } 77 78 //GetColumns returns colums based off of table names 79 func GetColumns(tables []string) []string { 80 var columns []string 81 for _, tableName := range tables { 82 rows, err := DBSelect.Query("Select * from " + tableName + " where 0=1") 83 defer rows.Close() 84 if err != nil { 85 fmt.Println(err) 86 return nil 87 } 88 columnsSet, err := rows.Columns() 89 if err != nil { 90 fmt.Println(err) 91 return nil 92 } 93 for _, j := range columnsSet { 94 columns = append(columns, tableName+"."+j) 95 } 96 } 97 return columns 98 } 99 100 //GetTables gets all of the tables in the db 101 func GetTables() []string { 102 var tables []string 103 rows, err := DBSelect.Query("Show Tables") 104 defer rows.Close() 105 if err != nil { 106 fmt.Println(err) 107 return nil 108 } 109 for rows.Next() { 110 var tname string 111 rows.Scan(&tname) 112 tables = append(tables, strings.ToLower(tname)) 113 } 114 return tables 115 } 116 117 func formatCondition(condition []string) []string { 118 switch condition[2] { 119 case "Equal to": 120 if Map[condition[1]] != "*string" && Map[condition[1]] != "*float32" && Map[condition[1]] != "*bool" && Map[condition[1]] != "*int64" && Map[condition[1]] != "*time.Time" { 121 condition[2] = "" 122 return nil 123 } 124 condition[2] = "=" 125 break 126 case "Not equal to": 127 if Map[condition[1]] != "*string" && Map[condition[1]] != "*float32" && Map[condition[1]] != "*bool" && Map[condition[1]] != "*int64" && Map[condition[1]] != "*time.Time" { 128 condition[2] = "" 129 return nil 130 } 131 condition[2] = "<>" 132 133 break 134 case "Greater than": 135 if Map[condition[1]] != "*float32" && Map[condition[1]] != "*int64" && Map[condition[1]] != "*time.Time" { 136 condition[2] = "" 137 return nil 138 } 139 condition[2] = ">" 140 break 141 case "Less than": 142 if Map[condition[1]] != "*float32" && Map[condition[1]] != "*int64" && Map[condition[1]] != "*time.Time" { 143 condition[2] = "" 144 return nil 145 } 146 condition[2] = "<" 147 break 148 case "Greater or equal to": 149 if Map[condition[1]] != "*float32" && Map[condition[1]] != "*int64" && Map[condition[1]] != "*time.Time" { 150 condition[2] = "" 151 return nil 152 } 153 condition[2] = ">=" 154 break 155 case "Less or equal to": 156 if Map[condition[1]] != "*float32" && Map[condition[1]] != "*int64" && Map[condition[1]] != "*time.Time" { 157 condition[2] = "" 158 return nil 159 } 160 condition[2] = "<=" 161 break 162 case "Begins with": 163 if Map[condition[1]] != "*string" { 164 condition[2] = "" 165 return nil 166 } 167 condition[2] = " LIKE " 168 condition[3] += "%" 169 break 170 case "Not begins with": 171 if Map[condition[1]] != "*string" { 172 condition[2] = "" 173 return nil 174 } 175 condition[0] += " NOT" 176 condition[2] = " LIKE " 177 condition[3] += "%" 178 break 179 case "Ends with": 180 if Map[condition[1]] != "*string" { 181 condition[2] = "" 182 return nil 183 } 184 condition[2] = " LIKE " 185 condition[3] = "%" + condition[3] 186 break 187 case "Not ends with": 188 if Map[condition[1]] != "*string" { 189 condition[2] = "" 190 return nil 191 } 192 condition[0] += " NOT" 193 condition[2] = " LIKE " 194 condition[3] = "%" + condition[3] 195 break 196 case "Contains": 197 if Map[condition[1]] != "*string" { 198 condition[2] = "" 199 return nil 200 } 201 condition[2] = " LIKE " 202 condition[3] = "%" + condition[3] + "%" 203 break 204 case "Not contains": 205 if Map[condition[1]] != "*string" { 206 condition[2] = "" 207 return nil 208 } 209 condition[0] += " NOT" 210 condition[2] = " LIKE " 211 condition[3] = "%" + condition[3] + "%" 212 break 213 default: 214 return nil 215 } 216 return condition 217 } 218 219 //MapSuper makes a map 220 func MapSuper() map[string]string { 221 m := make(map[string]string) 222 v := reflect.ValueOf(models.Patient{}) 223 224 for i := 0; i < v.NumField(); i++ { 225 tag := string(reflect.TypeOf(models.Patient{}).Field(i).Tag) 226 runes := []rune(tag) 227 j := strings.Index(tag, ":") 228 k := strings.Index(tag, "omit") 229 tag = string(runes[j+2 : k-1]) 230 varType := reflect.TypeOf(models.Patient{}).Field(i).Type.String() 231 m[tag] = varType 232 } 233 v = reflect.ValueOf(models.Sample{}) 234 235 for i := 0; i < v.NumField(); i++ { 236 tag := string(reflect.TypeOf(models.Sample{}).Field(i).Tag) 237 runes := []rune(tag) 238 j := strings.Index(tag, ":") 239 k := strings.Index(tag, "omit") 240 tag = string(runes[j+2 : k-1]) 241 varType := reflect.TypeOf(models.Sample{}).Field(i).Type.String() 242 m[tag] = varType 243 } 244 v = reflect.ValueOf(models.Experiment{}) 245 246 for i := 0; i < v.NumField(); i++ { 247 tag := string(reflect.TypeOf(models.Experiment{}).Field(i).Tag) 248 runes := []rune(tag) 249 j := strings.Index(tag, ":") 250 k := strings.Index(tag, "omit") 251 tag = string(runes[j+2 : k-1]) 252 varType := reflect.TypeOf(models.Experiment{}).Field(i).Type.String() 253 m[tag] = varType 254 } 255 v = reflect.ValueOf(models.Result{}) 256 257 for i := 0; i < v.NumField(); i++ { 258 tag := string(reflect.TypeOf(models.Result{}).Field(i).Tag) 259 runes := []rune(tag) 260 j := strings.Index(tag, ":") 261 k := strings.Index(tag, "omit") 262 tag = string(runes[j+2 : k-1]) 263 varType := reflect.TypeOf(models.Result{}).Field(i).Type.String() 264 m[tag] = varType 265 } 266 267 v = reflect.ValueOf(models.Resultdetails{}) 268 269 for i := 0; i < v.NumField(); i++ { 270 tag := string(reflect.TypeOf(models.Resultdetails{}).Field(i).Tag) 271 runes := []rune(tag) 272 j := strings.Index(tag, ":") 273 k := strings.Index(tag, "omit") 274 tag = string(runes[j+2 : k-1]) 275 varType := reflect.TypeOf(models.Resultdetails{}).Field(i).Type.String() 276 m[tag] = varType 277 } 278 279 return m 280 } 281 282 func orderTablesByHigharch(selectedTables []string) []string { 283 order := []string{"patients", "samples", "experiments", "results", "resultdetails"} 284 newTables := make([]string, 0) 285 for _, o := range order { 286 for i := range selectedTables { 287 if selectedTables[i] == o { 288 newTables = append(newTables, o) 289 } 290 } 291 } 292 return newTables 293 } 294 295 func detemineMissingTablesLinks(selectedTables []string) []string { 296 order := []string{"patients", "samples", "experiments", "results", "resultdetails"} 297 if selectedTables[len(selectedTables)-1] == order[4] { 298 if len(selectedTables) == 5 { 299 return selectedTables 300 } 301 return order 302 } 303 if selectedTables[len(selectedTables)-1] == order[3] { 304 if len(selectedTables) == 4 { 305 return selectedTables 306 } 307 return order[:4] 308 } 309 if selectedTables[len(selectedTables)-1] == order[2] { 310 if len(selectedTables) == 3 { 311 return selectedTables 312 } 313 return order[:3] 314 } 315 if selectedTables[len(selectedTables)-1] == order[1] { 316 if len(selectedTables) == 2 { 317 return selectedTables 318 } 319 return order[:2] 320 } 321 return selectedTables 322 }