func (c *Conn) handleQuery(sqlstmt string) (err error) { /*defer func() { if e := recover(); e != nil { err = fmt.Errorf("execute %s error %v", sql, e) return } }()*/ var stmt sql.IStatement stmt, err = sql.Parse(sqlstmt) if err != nil { return fmt.Errorf(`parse sql "%s" error "%s"`, sqlstmt, err.Error()) } switch v := stmt.(type) { case sql.ISelect: return c.handleSelect(v, sqlstmt) case *sql.Insert: return c.handleExec(stmt, sqlstmt, false) case *sql.Update: return c.handleExec(stmt, sqlstmt, false) case *sql.Delete: return c.handleExec(stmt, sqlstmt, false) case *sql.Replace: return c.handleExec(stmt, sqlstmt, false) case *sql.Set: return c.handleSet(v, sqlstmt) case *sql.Begin: return c.handleBegin() case *sql.Commit: return c.handleCommit() case *sql.Rollback: return c.handleRollback() case sql.IShow: return c.handleShow(sqlstmt, v) case sql.IDDLStatement: return c.handleExec(stmt, sqlstmt, false) case *sql.Do: return c.handleExec(stmt, sqlstmt, false) case *sql.Call: return c.handleExec(stmt, sqlstmt, false) case *sql.Use: if err := c.useDB(hack.String(stmt.(*sql.Use).DB)); err != nil { return err } else { return c.writeOK(nil) } default: return fmt.Errorf("statement %T[%s] not support now", stmt, sqlstmt) } return nil }
func (c *Conn) dispatch(data []byte) error { cmd := data[0] data = data[1:] switch cmd { case COM_QUIT: c.Close() return nil case COM_QUERY: return c.handleQuery(hack.String(data)) case COM_PING: return c.writeOK(nil) case COM_INIT_DB: if err := c.useDB(hack.String(data)); err != nil { return err } else { return c.writeOK(nil) } case COM_FIELD_LIST: return c.handleFieldList(data) case COM_STMT_PREPARE: return c.handleComStmtPrepare(hack.String(data)) case COM_STMT_EXECUTE: return c.handleComStmtExecute(data) case COM_STMT_CLOSE: return c.handleComStmtClose(data) case COM_STMT_SEND_LONG_DATA: return c.handleComStmtSendLongData(data) case COM_STMT_RESET: return c.handleComStmtReset(data) default: msg := fmt.Sprintf("command %d not supported now", cmd) AppLog.Warn(msg) return NewError(ER_UNKNOWN_ERROR, msg) } return nil }
func (r *Resultset) GetString(row, column int) (string, error) { d, err := r.GetValue(row, column) if err != nil { return "", err } switch v := d.(type) { case string: return v, nil case []byte: return hack.String(v), nil case int64: return strconv.FormatInt(v, 10), nil case uint64: return strconv.FormatUint(v, 10), nil case float64: return strconv.FormatFloat(v, 'f', -1, 64), nil case nil: return "", nil default: return "", fmt.Errorf("data type is %T", v) } }
func (c *Conn) handleQuery(sqlstmt string) (err error) { /*defer func() { if e := recover(); e != nil { err = fmt.Errorf("execute %s error %v", sql, e) return } }()*/ var stmt sql.IStatement var excess int64 fp := query.Fingerprint(sqlstmt) now := getTimestamp() c.server.mu.Lock() if lr, ok := c.server.fingerprints[fp]; ok { //how many microsecond elapsed since last query ms := now - lr.last //Default, we have 1 r/s excess = lr.excess - c.server.cfg.ReqRate*(ms/1000) + 1000 //If we need caculate every second speed, //Should reset to zero; if excess < 0 { excess = 0 } //the race out the max Burst? log.AppLog.Notice("the Query excess(%d), the reqBurst(%d)", excess, c.server.cfg.ReqBurst) if excess > c.server.cfg.ReqBurst { c.server.mu.Unlock() //Just close the client or return fmt.Errorf(`the query excess(%d) over the reqBurst(%d), sql: %s "`, excess, c.server.cfg.ReqBurst, sqlstmt) //TODO: more gracefully add a Timer and retry? } lr.excess = excess lr.last = now lr.count++ } else { lr := &LimitReqNode{} lr.excess = 0 lr.last = getTimestamp() lr.query = fp lr.count = 1 c.server.fingerprints[fp] = lr } c.server.mu.Unlock() stmt, err = sql.Parse(sqlstmt) if err != nil { return fmt.Errorf(`parse sql "%s" error "%s"`, sqlstmt, err.Error()) } switch v := stmt.(type) { case sql.ISelect: return c.handleSelect(v, sqlstmt) case *sql.Insert: return c.handleExec(stmt, sqlstmt, false) case *sql.Update: return c.handleExec(stmt, sqlstmt, false) case *sql.Delete: return c.handleExec(stmt, sqlstmt, false) case *sql.Replace: return c.handleExec(stmt, sqlstmt, false) case *sql.Set: return c.handleSet(v, sqlstmt) case *sql.Begin: return c.handleBegin() case *sql.Commit: return c.handleCommit() case *sql.Rollback: return c.handleRollback() case sql.IShow: return c.handleShow(sqlstmt, v) case sql.IDDLStatement: return c.handleExec(stmt, sqlstmt, false) case *sql.Do: return c.handleExec(stmt, sqlstmt, false) case *sql.Call: return c.handleExec(stmt, sqlstmt, false) case *sql.Use: if err := c.useDB(hack.String(stmt.(*sql.Use).DB)); err != nil { return err } else { return c.writeOK(nil) } default: return fmt.Errorf("statement %T[%s] not support now", stmt, sqlstmt) } return nil }
// String returns the raw value as a string func (v Value) String() string { if v.Inner == nil { return "" } return hack.String(v.Inner.raw()) }