func (s *Server) execute(tx bool, stmts []string) ([]FailedSqlStmt, error) { var failures = make([]FailedSqlStmt, 0) if tx { log.Trace("Transaction requested") s.metrics.executeTxReceived.Inc(1) _, err := s.raftServer.Do(command.NewTransactionExecuteCommandSet(stmts)) if err != nil { log.Tracef("Transaction failed: %s", err.Error()) s.metrics.executeFail.Inc(1) failures = append(failures, FailedSqlStmt{stmts[0], err.Error()}) } else { s.metrics.executeSuccess.Inc(1) } } else { log.Trace("No transaction requested") for i := range stmts { _, err := s.raftServer.Do(command.NewExecuteCommand(stmts[i])) if err != nil { log.Tracef("Execute statement %s failed: %s", stmts[i], err.Error()) s.metrics.executeFail.Inc(1) failures = append(failures, FailedSqlStmt{stmts[i], err.Error()}) } else { s.metrics.executeSuccess.Inc(1) } } } return failures, nil }
func (s *Server) writeHandler(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("writeHandler 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 } stmts := strings.Split(string(b), ";") if stmts[len(stmts)-1] == "" { stmts = stmts[:len(stmts)-1] } 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()) } } }