Example #1
0
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
}
Example #2
0
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())
		}
	}
}