Skip to content

Commit

Permalink
server: schema info api of http status server (pingcap#5256)
Browse files Browse the repository at this point in the history
  • Loading branch information
jackysp committed Jan 12, 2018
1 parent 76c5083 commit 091039d
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 3 deletions.
3 changes: 3 additions & 0 deletions server/http_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ func (s *Server) startHTTPServer() {
router.Handle("/mvcc/txn/{startTS}/{db}/{table}", mvccTxnHandler{tikvHandler, opMvccGetByTxn})
router.Handle("/mvcc/txn/{startTS}", mvccTxnHandler{tikvHandler, opMvccGetByTxn})
router.Handle("/mvcc/hex/{hexKey}", mvccTxnHandler{tikvHandler, opMvccGetByHex})
router.Handle("/schema", schemaHandler{tikvHandler})
router.Handle("/schema/{db}", schemaHandler{tikvHandler})
router.Handle("/schema/{db}/{table}", schemaHandler{tikvHandler})
}
addr := fmt.Sprintf(":%d", s.cfg.Status.StatusPort)
if s.cfg.Status.StatusPort == 0 {
Expand Down
76 changes: 73 additions & 3 deletions server/region_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,16 @@ import (

const (
pDBName = "db"
pTableName = "table"
pRegionID = "regionID"
pHexKey = "hexKey"
pRecordID = "recordID"
pRegionID = "regionID"
pStartTS = "startTS"
pHexKey = "hexKey"
pTableName = "table"
)

// For query string
const qTableID = "table_id"

const (
headerContentType = "Content-Type"
contentTypeJSON = "application/json"
Expand All @@ -72,6 +75,11 @@ type regionHandler struct {
*regionHandlerTool
}

// schemaHandler is the handler for list database or table schemas.
type schemaHandler struct {
*regionHandler
}

// tableRegionsHandler is the handler for list table's regions.
type tableRegionsHandler struct {
*regionHandler
Expand Down Expand Up @@ -227,6 +235,68 @@ func (t *regionHandlerTool) getRegionsMeta(regionIDs []uint64) ([]RegionMeta, er
return regions, nil
}

// ServeHTTP handles request of list a database or table's schemas.
func (rh schemaHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
schema, err := rh.schema()
if err != nil {
rh.writeError(w, err)
return
}

// parse params
params := mux.Vars(req)

if dbName, ok := params[pDBName]; ok {
cDBName := model.NewCIStr(dbName)
if tableName, ok := params[pTableName]; ok {
// table schema of a specified table name
cTableName := model.NewCIStr(tableName)
data, err := schema.TableByName(cDBName, cTableName)
if err != nil {
rh.writeError(w, err)
return
}
rh.writeData(w, data.Meta())
return
}
// all table schemas in a specified database
if schema.SchemaExists(cDBName) {
tbs := schema.SchemaTables(cDBName)
tbsInfo := make([]*model.TableInfo, len(tbs))
for i := range tbsInfo {
tbsInfo[i] = tbs[i].Meta()
}
rh.writeData(w, tbsInfo)
return
}
rh.writeError(w, infoschema.ErrDatabaseNotExists.GenByArgs(dbName))
return
}

if tableID := req.FormValue(qTableID); len(tableID) > 0 {
// table schema of a specified tableID
tid, err := strconv.Atoi(tableID)
if err != nil {
rh.writeError(w, err)
return
}
if tid < 0 {
rh.writeError(w, infoschema.ErrTableNotExists.Gen("Table which ID = %s does not exist.", tableID))
return
}
if data, ok := schema.TableByID(int64(tid)); ok {
rh.writeData(w, data.Meta())
return
}
rh.writeError(w, infoschema.ErrTableNotExists.Gen("Table which ID = %s does not exist.", tableID))
return
}

// all databases' schemas
rh.writeData(w, schema.AllSchemas())
return
}

// ServeHTTP handles request of list a table's regions.
func (rh tableRegionsHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// parse params
Expand Down
59 changes: 59 additions & 0 deletions server/region_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ import (
"fmt"
"math"
"net/http"
"sort"

. "github.com/pingcap/check"
"github.com/pingcap/kvproto/pkg/kvrpcpb"
"github.com/pingcap/tidb"
"github.com/pingcap/tidb/config"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/store/tikv"
"github.com/pingcap/tidb/store/tikv/mock-tikv"
"github.com/pingcap/tidb/tablecodec"
Expand Down Expand Up @@ -302,3 +304,60 @@ func (ts *TidbRegionHandlerTestSuite) TestGetMvccNotFound(c *C) {
c.Assert(err, IsNil)
c.Assert(p.Info, IsNil)
}

func (ts *TidbRegionHandlerTestSuite) TestGetSchema(c *C) {
ts.startServer(c)
ts.prepareData(c)
defer ts.stopServer(c)
resp, err := http.Get(fmt.Sprintf("http://127.0.0.1:10090/schema"))
c.Assert(err, IsNil)
decoder := json.NewDecoder(resp.Body)
var dbs []*model.DBInfo
err = decoder.Decode(&dbs)
c.Assert(err, IsNil)
expects := []string{"information_schema", "mysql", "performance_schema", "test", "tidb"}
names := make([]string, len(dbs))
for i, v := range dbs {
names[i] = v.Name.L
}
sort.Strings(names)
c.Assert(names, DeepEquals, expects)

resp, err = http.Get(fmt.Sprintf("http://127.0.0.1:10090/schema?table_id=5"))
c.Assert(err, IsNil)
var t *model.TableInfo
decoder = json.NewDecoder(resp.Body)
err = decoder.Decode(&t)
c.Assert(err, IsNil)
c.Assert(t.Name.L, Equals, "user")

_, err = http.Get(fmt.Sprintf("http://127.0.0.1:10090/schema?table_id=a"))
c.Assert(err, IsNil)

_, err = http.Get(fmt.Sprintf("http://127.0.0.1:10090/schema?table_id=1"))
c.Assert(err, IsNil)

_, err = http.Get(fmt.Sprintf("http://127.0.0.1:10090/schema?table_id=-1"))
c.Assert(err, IsNil)

resp, err = http.Get(fmt.Sprintf("http://127.0.0.1:10090/schema/tidb"))
c.Assert(err, IsNil)
var lt []*model.TableInfo
decoder = json.NewDecoder(resp.Body)
err = decoder.Decode(&lt)
c.Assert(err, IsNil)
c.Assert(lt[0].Name.L, Equals, "test")

_, err = http.Get(fmt.Sprintf("http://127.0.0.1:10090/schema/abc"))
c.Assert(err, IsNil)

resp, err = http.Get(fmt.Sprintf("http://127.0.0.1:10090/schema/tidb/test"))
c.Assert(err, IsNil)
decoder = json.NewDecoder(resp.Body)
err = decoder.Decode(&t)
c.Assert(err, IsNil)
c.Assert(t.Name.L, Equals, "test")

_, err = http.Get(fmt.Sprintf("http://127.0.0.1:10090/schema/tidb/abc"))
c.Assert(err, IsNil)
}

0 comments on commit 091039d

Please sign in to comment.