func convertToQueries(anchors *Anchors) []string { var stmts []string for _, dataPoint := range anchors.DataPoints { log.Debugf("Datapoint is %s", dataPoint) table := dataPoint.(map[string]interface{})["table"].(string) payload := dataPoint.(map[string]interface{})["payload"] log.Debugf("Table Name is %s", table) log.Debugf("Payload is %s", payload) log.Debugf("Payload type is %s", reflect.TypeOf(payload)) log.Debugf("Table type is %s", reflect.TypeOf(table)) dataRows := payload.([]interface{}) for _, rowVal := range dataRows { log.Debugf("Row value is %s", rowVal.(map[string]interface{})) keys := make([]string, len(rowVal.(map[string]interface{}))) values := make([]string, len(rowVal.(map[string]interface{}))) keyCount := 0 for k, v := range rowVal.(map[string]interface{}) { keys[keyCount] = "\"" + k + "\"" var strVal = "\"" + v.(string) + "\"" values[keyCount] = strVal log.Debugf("Adding Key %s and %s value to query", k, v) keyCount++ } columns := strings.Join(keys, ",") rows := strings.Join(values, ",") log.Debugf("Columns are %s", columns) log.Debugf("Row Values are %s", rows) stmts = append(stmts, "INSERT INTO "+table+"("+columns+") VALUES("+rows+")") } } return stmts }
// Query runs the supplied query against the sqlite database. It returns a slice of // RowResults. func (db *DB) Query(query string) (RowResults, error) { if !strings.HasPrefix(strings.ToUpper(query), "SELECT ") { log.Warnf("Query \"%s\" may modify the database", query) } rows, err := db.dbConn.Query(query) if err != nil { log.Errorf("failed to execute SQLite query: %s", err.Error()) return nil, err } defer func() { err = rows.Close() if err != nil { log.Errorf("failed to close rows: %s", err.Error()) } }() results := make(RowResults, 0) columns, _ := rows.Columns() rawResult := make([][]byte, len(columns)) dest := make([]interface{}, len(columns)) for i := range rawResult { dest[i] = &rawResult[i] // Pointers to each string in the interface slice } for rows.Next() { err = rows.Scan(dest...) if err != nil { log.Errorf("failed to scan SQLite row: %s", err.Error()) return nil, err } r := make(RowResult) for i, raw := range rawResult { if raw == nil { r[columns[i]] = "null" } else { r[columns[i]] = string(raw) } } results = append(results, r) } log.Debugf("Executed query successfully: %s", query) return results, nil }
func (s *Server) tableWriteHandler(w http.ResponseWriter, req *http.Request) { s.mutex.Lock() defer s.mutex.Unlock() if s.raftServer.State() != "leader" { s.leaderRedirect(w, req) return } log.Tracef("tableWriteHandler for URL: %s", req.URL) s.metrics.executeReceived.Inc(1) currentIndex := s.raftServer.CommitIndex() count := currentIndex - s.snapConf.lastIndex if uint64(count) > s.snapConf.snapshotAfter { log.Info("Committed log entries snapshot threshold reached, starting snapshot") err := s.raftServer.TakeSnapshot() s.logSnapshot(err, currentIndex, count) s.snapConf.lastIndex = currentIndex s.metrics.snapshotCreated.Inc(1) } // Read the value from the POST body. b, err := ioutil.ReadAll(req.Body) if err != nil { log.Tracef("Bad HTTP request: %s", err.Error()) s.metrics.executeFail.Inc(1) w.WriteHeader(http.StatusBadRequest) return } anchors := Anchors{} if err := json.Unmarshal(b, &anchors); err != nil { log.Errorf("Parsing error : %s", err.Error()) s.metrics.executeFail.Inc(1) w.WriteHeader(http.StatusBadRequest) return } log.Debugf("Parsed data is %s", anchors) var stmts []string = convertToQueries(&anchors) log.Tracef("Execute statement contains %d commands", len(stmts)) if len(stmts) == 0 { log.Trace("No database execute commands supplied") s.metrics.executeFail.Inc(1) w.WriteHeader(http.StatusBadRequest) return } transaction, _ := isTransaction(req) startTime := time.Now() failures, err := s.execute(transaction, stmts) if err != nil { log.Errorf("Database mutation failed: %s", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } duration := time.Since(startTime) wr := StmtResponse{Failures: failures} if e, _ := isExplain(req); e { wr.Time = duration.String() } pretty, _ := isPretty(req) if pretty { b, err = json.MarshalIndent(wr, "", " ") } else { b, err = json.Marshal(wr) } if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } else { _, err = w.Write([]byte(b)) if err != nil { log.Errorf("Error writting JSON data: %s", err.Error()) } } }