{"action":"created","comment":{"url":"https://api.github.com/repos/pingcap/tidb-tools/pulls/comments/207166860","pull_request_review_id":142720907,"id":207166860,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwNzE2Njg2MA==","diff_hunk":"@@ -0,0 +1,321 @@\n+// Copyright 2018 PingCAP, Inc.\n+//\n+// Licensed under the Apache License, Version 2.0 (the \"License\");\n+// you may not use this file except in compliance with the License.\n+// You may obtain a copy of the License at\n+//\n+//     http://www.apache.org/licenses/LICENSE-2.0\n+//\n+// Unless required by applicable law or agreed to in writing, software\n+// distributed under the License is distributed on an \"AS IS\" BASIS,\n+// See the License for the specific language governing permissions and\n+// limitations under the License.\n+\n+package column\n+\n+import (\n+\t\"fmt\"\n+\t\"sync\"\n+\n+\t\"github.com/juju/errors\"\n+\t\"github.com/pingcap/tidb-tools/pkg/table-rule-selector\"\n+)\n+\n+// Expr indicates how to handle column mapping\n+type Expr string\n+\n+// poor Expr\n+const (\n+\tAddPrefix Expr = \"add prefix\"\n+\tAddSuffix Expr = \"add suffix\"\n+\tClone     Expr = \"clone column\"\n+)\n+\n+// Exprs is some built-in expression for column mapping\n+// only support some poor expressions now, we would unify tableInfo later and support more\n+var Exprs = map[Expr]func(*columnInfo, []interface{}) []interface{}{\n+\tAddPrefix: addPrefix,\n+\tAddSuffix: addSuffix,\n+\tClone:     cloneColumn,\n+}\n+\n+// Rule is a rule to map column\n+type Rule struct {\n+\tPatternSchema    string   `yaml:\"pattern-schema\" json:\"pattern-schema\" toml:\"pattern-schema\"`\n+\tPatternTable     string   `yaml:\"pattern-table\" json:\"pattern-table\" toml:\"pattern-table\"`\n+\tSourceColumn     string   `yaml:\"source-column\" json:\"source-column\" toml:\"source-column\"` // modify, add refer column, ignore\n+\tTargetColumn     string   `yaml:\"target-column\" json:\"target-column\" toml:\"target-column\"` // add column, modify\n+\tExpression       Expr     `yaml:\"expression\" json:\"expression\" toml:\"expression\"`\n+\tArguments        []string `yaml:\"arguments\" json:\"arguments\" toml:\"arguments\"`\n+\tCreateTableQuery string   `yaml:\"create-table-query\" json:\"create-table-query\" toml:\"create-table-query\"`\n+}\n+\n+// Valid checks validity of rule.\n+// add prefix/suffix: it should have target column and one argument\n+// clone: it should have source and target column\n+func (r *Rule) Valid() error {\n+\tif _, ok := Exprs[r.Expression]; !ok {\n+\t\treturn errors.NotFoundf(\"expression %s\", r.Expression)\n+\t}\n+\n+\tif (r.Expression == AddPrefix || r.Expression == AddSuffix) && len(r.Arguments) != 1 {\n+\t\treturn errors.NotValidf(\"arguments %v for add prefix/suffix\", r.Arguments)\n+\t}\n+\n+\treturn nil\n+}\n+\n+// check source and target position\n+func (r *Rule) checkColumnPosition(source, target int) (int, int, error) {\n+\t// if not found target, ignore it\n+\tif target == -1 {\n+\t\treturn source, target, errors.NotFoundf(\"target column %s\", r.TargetColumn)\n+\t}\n+\n+\tif r.Expression == Clone && source == -1 {\n+\t\treturn source, target, errors.NotFoundf(\"source column %s\", r.SourceColumn)\n+\t}\n+\n+\tif target < source { // must add column and added column is before source column\n+\t\tsource--\n+\t}\n+\n+\treturn source, target, nil\n+}\n+\n+type columnInfo struct {\n+\tignore         bool\n+\tsourcePosition int\n+\ttargetPosition int\n+\trule           *Rule\n+}\n+\n+// Mapping maps column to something by rules\n+type Mapping struct {\n+\tselector.Selector\n+\n+\tcache struct {\n+\t\tsync.RWMutex\n+\t\tinfos map[string]*columnInfo\n+\t}\n+}\n+\n+// NewMapping returns a column mapping\n+func NewMapping(rules []*Rule) (*Mapping, error) {\n+\tm := &Mapping{\n+\t\tSelector: selector.NewTrieSelector(),\n+\t}\n+\tm.resetCache()\n+\n+\tfor _, rule := range rules {\n+\t\tif err := m.AddRule(rule); err != nil {\n+\t\t\treturn nil, errors.Annotatef(err, \"initial rule %+v in mapping\", rule)\n+\t\t}\n+\t}\n+\n+\treturn m, nil\n+}\n+\n+// AddRule adds a rule into mapping\n+func (m *Mapping) AddRule(rule *Rule) error {\n+\terr := rule.Valid()\n+\tif err != nil {\n+\t\treturn errors.Trace(err)\n+\t}\n+\n+\tm.resetCache()\n+\terr = m.Insert(rule.PatternSchema, rule.PatternTable, rule, false)\n+\tif err != nil {\n+\t\treturn errors.Annotatef(err, \"add rule %+v into mapping\", rule)\n+\t}\n+\n+\treturn nil\n+}\n+\n+// UpdateRule updates mapping rule\n+func (m *Mapping) UpdateRule(rule *Rule) error {\n+\terr := rule.Valid()\n+\tif err != nil {\n+\t\treturn errors.Trace(err)\n+\t}\n+\n+\tm.resetCache()\n+\terr = m.Insert(rule.PatternSchema, rule.PatternTable, rule, true)\n+\tif err != nil {\n+\t\treturn errors.Annotatef(err, \"update rule %+v in mapping\", rule)\n+\t}\n+\n+\treturn nil\n+}\n+\n+// RemoveRule removes a rule from mapping\n+func (m *Mapping) RemoveRule(rule *Rule) error {\n+\tm.resetCache()\n+\terr := m.Remove(rule.PatternSchema, rule.PatternTable)\n+\tif err != nil {\n+\t\treturn errors.Annotatef(err, \"remove rule %+v\", rule)\n+\t}\n+\n+\treturn nil\n+}\n+\n+// HandleRowValue handles row value\n+func (m *Mapping) HandleRowValue(schema, table string, columns []string, vals []interface{}) ([]interface{}, error) {\n+\tinfo, err := m.queryColumnInfo(schema, table, columns)\n+\tif err != nil {\n+\t\treturn nil, errors.Trace(err)\n+\t}\n+\tif info.ignore == true {\n+\t\treturn vals, nil\n+\t}\n+\n+\texp, ok := Exprs[info.rule.Expression]\n+\tif !ok {\n+\t\treturn nil, errors.NotFoundf(\"column mapping expression %s\", info.rule.Expression)\n+\t}\n+\n+\treturn exp(info, vals), nil\n+}\n+\n+// HandleDDL handles ddl\n+func (m *Mapping) HandleDDL(schema, table string, columns []string, statement string) (string, error) {\n+\tinfo, err := m.queryColumnInfo(schema, table, columns)\n+\tif err != nil {\n+\t\treturn statement, errors.Trace(err)\n+\t}\n+\tif info.ignore == true {\n+\t\treturn statement, nil\n+\t}\n+\n+\t// only output erro now, wait fix it manually\n+\treturn statement, errors.NotImplementedf(\"ddl %s @ column mapping rule %s/%s:%+v\", statement, schema, table, info.rule)\n+}\n+\n+func (m *Mapping) queryColumnInfo(schema, table string, columns []string) (*columnInfo, error) {\n+\tvar info = &columnInfo{\n+\t\tignore: true,\n+\t}\n+\n+\tm.cache.RLock()\n+\tci, ok := m.cache.infos[tableName(schema, table)]\n+\tm.cache.RUnlock()\n+\tif ok {\n+\t\treturn ci, nil\n+\t}\n+\n+\trules := m.Match(schema, table)\n+\tif len(rules) == 0 {\n+\t\tm.cache.Lock()\n+\t\tm.cache.infos[tableName(schema, table)] = info\n+\t\tm.cache.Unlock()\n+\n+\t\treturn info, nil\n+\t}\n+\n+\tvar (\n+\t\tschemaRules []*Rule\n+\t\ttableRules  = make([]*Rule, 0, 1)\n+\t)\n+\t// classify rules into schema level rules and table level\n+\t// table level rules have highest priority\n+\tfor i := range rules {\n+\t\trule, ok := rules[i].(*Rule)\n+\t\tif !ok {\n+\t\t\treturn nil, errors.NotValidf(\"column mapping rule %+v\", rules[i])\n+\t\t}\n+\n+\t\tif len(rule.PatternTable) == 0 {\n+\t\t\tschemaRules = append(schemaRules, rule)\n+\t\t} else {\n+\t\t\ttableRules = append(tableRules, rule)\n+\t\t}\n+\t}\n+\n+\t// only support one expression for one table now, refine it later\n+\tvar rule *Rule\n+\tif len(table) == 0 || len(tableRules) == 0 {\n+\t\tif len(schemaRules) > 1 {\n+\t\t\treturn nil, errors.NotSupportedf(\"route %s/%s to rule set(%d)\", schema, table, len(schemaRules))\n+\t\t}\n+\n+\t\tif len(schemaRules) == 1 {\n+\t\t\trule = schemaRules[0]\n+\t\t}\n+\t} else {\n+\t\tif len(tableRules) > 1 {\n+\t\t\treturn nil, errors.NotSupportedf(\"route %s/%s to rule set(%d)\", schema, table, len(tableRules))\n+\t\t}\n+\n+\t\tif len(tableRules) == 1 {\n+\t\t\trule = tableRules[0]\n+\t\t}\n+\t}\n+\tif rule == nil {\n+\t\tm.cache.Lock()\n+\t\tm.cache.infos[tableName(schema, table)] = info\n+\t\tm.cache.Unlock()\n+\n+\t\treturn info, nil\n+\t}\n+\n+\tsourcePosition := findColumnPosition(columns, rule.SourceColumn)\n+\ttargetPosition := findColumnPosition(columns, rule.TargetColumn)\n+\n+\tsourcePosition, targetPosition, err := rule.checkColumnPosition(sourcePosition, targetPosition)\n+\tif err != nil {\n+\t\treturn nil, errors.Trace(err)\n+\t}\n+\n+\tinfo = &columnInfo{\n+\t\tsourcePosition: sourcePosition,\n+\t\ttargetPosition: targetPosition,\n+\t\trule:           rule,\n+\t}\n+\n+\tm.cache.Lock()\n+\tm.cache.infos[tableName(schema, table)] = info\n+\tm.cache.Unlock()\n+\n+\treturn info, nil\n+}\n+\n+func (m *Mapping) resetCache() {\n+\tm.cache.Lock()\n+\tm.cache.infos = make(map[string]*columnInfo)\n+\tm.cache.Unlock()\n+}\n+\n+func findColumnPosition(cols []string, col string) int {\n+\tfor i := range cols {\n+\t\tif cols[i] == col {\n+\t\t\treturn i\n+\t\t}\n+\t}\n+\n+\treturn -1\n+}\n+\n+func tableName(schema, table string) string {\n+\treturn fmt.Sprintf(\"`%s`.`%s`\", schema, table)\n+}\n+\n+func addPrefix(info *columnInfo, vals []interface{}) []interface{} {\n+\tprefix := info.rule.Arguments[0]\n+\tvals[info.targetPosition] = fmt.Sprintf(\"%s:%v\", prefix, vals[info.targetPosition])\n+\treturn vals\n+}\n+\n+func addSuffix(info *columnInfo, vals []interface{}) []interface{} {\n+\tsuffix := info.rule.Arguments[0]\n+\tvals[info.targetPosition] = fmt.Sprintf(\"%v:%s\", vals[info.targetPosition], suffix)\n+\treturn vals\n+}\n+\n+func cloneColumn(info *columnInfo, vals []interface{}) []interface{} {\n+\tnewVals := make([]interface{}, 0, len(vals))","path":"pkg/column-mapping/column.go","position":315,"original_position":315,"commit_id":"7081f5f1560990082518114122340e2146271096","original_commit_id":"7081f5f1560990082518114122340e2146271096","user":{"login":"csuzhangxc","id":3183039,"node_id":"MDQ6VXNlcjMxODMwMzk=","avatar_url":"https://avatars0.githubusercontent.com/u/3183039?v=4","gravatar_id":"","url":"https://api.github.com/users/csuzhangxc","html_url":"https://github.com/csuzhangxc","followers_url":"https://api.github.com/users/csuzhangxc/followers","following_url":"https://api.github.com/users/csuzhangxc/following{/other_user}","gists_url":"https://api.github.com/users/csuzhangxc/gists{/gist_id}","starred_url":"https://api.github.com/users/csuzhangxc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/csuzhangxc/subscriptions","organizations_url":"https://api.github.com/users/csuzhangxc/orgs","repos_url":"https://api.github.com/users/csuzhangxc/repos","events_url":"https://api.github.com/users/csuzhangxc/events{/privacy}","received_events_url":"https://api.github.com/users/csuzhangxc/received_events","type":"User","site_admin":false},"body":"always `len(vals) + 1`?","created_at":"2018-08-02T09:50:48Z","updated_at":"2018-08-02T09:59:01Z","html_url":"https://github.com/pingcap/tidb-tools/pull/46#discussion_r207166860","pull_request_url":"https://api.github.com/repos/pingcap/tidb-tools/pulls/46","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/pingcap/tidb-tools/pulls/comments/207166860"},"html":{"href":"https://github.com/pingcap/tidb-tools/pull/46#discussion_r207166860"},"pull_request":{"href":"https://api.github.com/repos/pingcap/tidb-tools/pulls/46"}}},"pull_request":{"url":"https://api.github.com/repos/pingcap/tidb-tools/pulls/46","id":203097565,"node_id":"MDExOlB1bGxSZXF1ZXN0MjAzMDk3NTY1","html_url":"https://github.com/pingcap/tidb-tools/pull/46","diff_url":"https://github.com/pingcap/tidb-tools/pull/46.diff","patch_url":"https://github.com/pingcap/tidb-tools/pull/46.patch","issue_url":"https://api.github.com/repos/pingcap/tidb-tools/issues/46","number":46,"state":"open","locked":false,"title":"pkg: add a poor column mapping","user":{"login":"GregoryIan","id":10701973,"node_id":"MDQ6VXNlcjEwNzAxOTcz","avatar_url":"https://avatars3.githubusercontent.com/u/10701973?v=4","gravatar_id":"","url":"https://api.github.com/users/GregoryIan","html_url":"https://github.com/GregoryIan","followers_url":"https://api.github.com/users/GregoryIan/followers","following_url":"https://api.github.com/users/GregoryIan/following{/other_user}","gists_url":"https://api.github.com/users/GregoryIan/gists{/gist_id}","starred_url":"https://api.github.com/users/GregoryIan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GregoryIan/subscriptions","organizations_url":"https://api.github.com/users/GregoryIan/orgs","repos_url":"https://api.github.com/users/GregoryIan/repos","events_url":"https://api.github.com/users/GregoryIan/events{/privacy}","received_events_url":"https://api.github.com/users/GregoryIan/received_events","type":"User","site_admin":false},"body":"it supports some poor expressions now, we would unify tableInfo later and support more","created_at":"2018-07-23T02:58:14Z","updated_at":"2018-08-02T09:59:01Z","closed_at":null,"merged_at":null,"merge_commit_sha":"bad52291468ce0c8fada9bf0e2cb86593c290849","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/pingcap/tidb-tools/pulls/46/commits","review_comments_url":"https://api.github.com/repos/pingcap/tidb-tools/pulls/46/comments","review_comment_url":"https://api.github.com/repos/pingcap/tidb-tools/pulls/comments{/number}","comments_url":"https://api.github.com/repos/pingcap/tidb-tools/issues/46/comments","statuses_url":"https://api.github.com/repos/pingcap/tidb-tools/statuses/7081f5f1560990082518114122340e2146271096","head":{"label":"pingcap:ian/column-mapping","ref":"ian/column-mapping","sha":"7081f5f1560990082518114122340e2146271096","user":{"login":"pingcap","id":11855343,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExODU1MzQz","avatar_url":"https://avatars3.githubusercontent.com/u/11855343?v=4","gravatar_id":"","url":"https://api.github.com/users/pingcap","html_url":"https://github.com/pingcap","followers_url":"https://api.github.com/users/pingcap/followers","following_url":"https://api.github.com/users/pingcap/following{/other_user}","gists_url":"https://api.github.com/users/pingcap/gists{/gist_id}","starred_url":"https://api.github.com/users/pingcap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pingcap/subscriptions","organizations_url":"https://api.github.com/users/pingcap/orgs","repos_url":"https://api.github.com/users/pingcap/repos","events_url":"https://api.github.com/users/pingcap/events{/privacy}","received_events_url":"https://api.github.com/users/pingcap/received_events","type":"Organization","site_admin":false},"repo":{"id":93518223,"node_id":"MDEwOlJlcG9zaXRvcnk5MzUxODIyMw==","name":"tidb-tools","full_name":"pingcap/tidb-tools","owner":{"login":"pingcap","id":11855343,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExODU1MzQz","avatar_url":"https://avatars3.githubusercontent.com/u/11855343?v=4","gravatar_id":"","url":"https://api.github.com/users/pingcap","html_url":"https://github.com/pingcap","followers_url":"https://api.github.com/users/pingcap/followers","following_url":"https://api.github.com/users/pingcap/following{/other_user}","gists_url":"https://api.github.com/users/pingcap/gists{/gist_id}","starred_url":"https://api.github.com/users/pingcap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pingcap/subscriptions","organizations_url":"https://api.github.com/users/pingcap/orgs","repos_url":"https://api.github.com/users/pingcap/repos","events_url":"https://api.github.com/users/pingcap/events{/privacy}","received_events_url":"https://api.github.com/users/pingcap/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/pingcap/tidb-tools","description":"tidb-tools are some useful tool collections for TiDB.","fork":false,"url":"https://api.github.com/repos/pingcap/tidb-tools","forks_url":"https://api.github.com/repos/pingcap/tidb-tools/forks","keys_url":"https://api.github.com/repos/pingcap/tidb-tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pingcap/tidb-tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pingcap/tidb-tools/teams","hooks_url":"https://api.github.com/repos/pingcap/tidb-tools/hooks","issue_events_url":"https://api.github.com/repos/pingcap/tidb-tools/issues/events{/number}","events_url":"https://api.github.com/repos/pingcap/tidb-tools/events","assignees_url":"https://api.github.com/repos/pingcap/tidb-tools/assignees{/user}","branches_url":"https://api.github.com/repos/pingcap/tidb-tools/branches{/branch}","tags_url":"https://api.github.com/repos/pingcap/tidb-tools/tags","blobs_url":"https://api.github.com/repos/pingcap/tidb-tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pingcap/tidb-tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pingcap/tidb-tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/pingcap/tidb-tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pingcap/tidb-tools/statuses/{sha}","languages_url":"https://api.github.com/repos/pingcap/tidb-tools/languages","stargazers_url":"https://api.github.com/repos/pingcap/tidb-tools/stargazers","contributors_url":"https://api.github.com/repos/pingcap/tidb-tools/contributors","subscribers_url":"https://api.github.com/repos/pingcap/tidb-tools/subscribers","subscription_url":"https://api.github.com/repos/pingcap/tidb-tools/subscription","commits_url":"https://api.github.com/repos/pingcap/tidb-tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/pingcap/tidb-tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/pingcap/tidb-tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/pingcap/tidb-tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/pingcap/tidb-tools/contents/{+path}","compare_url":"https://api.github.com/repos/pingcap/tidb-tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pingcap/tidb-tools/merges","archive_url":"https://api.github.com/repos/pingcap/tidb-tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pingcap/tidb-tools/downloads","issues_url":"https://api.github.com/repos/pingcap/tidb-tools/issues{/number}","pulls_url":"https://api.github.com/repos/pingcap/tidb-tools/pulls{/number}","milestones_url":"https://api.github.com/repos/pingcap/tidb-tools/milestones{/number}","notifications_url":"https://api.github.com/repos/pingcap/tidb-tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pingcap/tidb-tools/labels{/name}","releases_url":"https://api.github.com/repos/pingcap/tidb-tools/releases{/id}","deployments_url":"https://api.github.com/repos/pingcap/tidb-tools/deployments","created_at":"2017-06-06T12:53:46Z","updated_at":"2018-08-02T07:42:58Z","pushed_at":"2018-08-02T08:04:12Z","git_url":"git://github.com/pingcap/tidb-tools.git","ssh_url":"git@github.com:pingcap/tidb-tools.git","clone_url":"https://github.com/pingcap/tidb-tools.git","svn_url":"https://github.com/pingcap/tidb-tools","homepage":"","size":6975,"stargazers_count":35,"watchers_count":35,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":17,"mirror_url":null,"archived":false,"open_issues_count":5,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":17,"open_issues":5,"watchers":35,"default_branch":"master"}},"base":{"label":"pingcap:master","ref":"master","sha":"03cb27ac4cde08c03a833bb80cba6f88f439407b","user":{"login":"pingcap","id":11855343,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExODU1MzQz","avatar_url":"https://avatars3.githubusercontent.com/u/11855343?v=4","gravatar_id":"","url":"https://api.github.com/users/pingcap","html_url":"https://github.com/pingcap","followers_url":"https://api.github.com/users/pingcap/followers","following_url":"https://api.github.com/users/pingcap/following{/other_user}","gists_url":"https://api.github.com/users/pingcap/gists{/gist_id}","starred_url":"https://api.github.com/users/pingcap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pingcap/subscriptions","organizations_url":"https://api.github.com/users/pingcap/orgs","repos_url":"https://api.github.com/users/pingcap/repos","events_url":"https://api.github.com/users/pingcap/events{/privacy}","received_events_url":"https://api.github.com/users/pingcap/received_events","type":"Organization","site_admin":false},"repo":{"id":93518223,"node_id":"MDEwOlJlcG9zaXRvcnk5MzUxODIyMw==","name":"tidb-tools","full_name":"pingcap/tidb-tools","owner":{"login":"pingcap","id":11855343,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExODU1MzQz","avatar_url":"https://avatars3.githubusercontent.com/u/11855343?v=4","gravatar_id":"","url":"https://api.github.com/users/pingcap","html_url":"https://github.com/pingcap","followers_url":"https://api.github.com/users/pingcap/followers","following_url":"https://api.github.com/users/pingcap/following{/other_user}","gists_url":"https://api.github.com/users/pingcap/gists{/gist_id}","starred_url":"https://api.github.com/users/pingcap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pingcap/subscriptions","organizations_url":"https://api.github.com/users/pingcap/orgs","repos_url":"https://api.github.com/users/pingcap/repos","events_url":"https://api.github.com/users/pingcap/events{/privacy}","received_events_url":"https://api.github.com/users/pingcap/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/pingcap/tidb-tools","description":"tidb-tools are some useful tool collections for TiDB.","fork":false,"url":"https://api.github.com/repos/pingcap/tidb-tools","forks_url":"https://api.github.com/repos/pingcap/tidb-tools/forks","keys_url":"https://api.github.com/repos/pingcap/tidb-tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pingcap/tidb-tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pingcap/tidb-tools/teams","hooks_url":"https://api.github.com/repos/pingcap/tidb-tools/hooks","issue_events_url":"https://api.github.com/repos/pingcap/tidb-tools/issues/events{/number}","events_url":"https://api.github.com/repos/pingcap/tidb-tools/events","assignees_url":"https://api.github.com/repos/pingcap/tidb-tools/assignees{/user}","branches_url":"https://api.github.com/repos/pingcap/tidb-tools/branches{/branch}","tags_url":"https://api.github.com/repos/pingcap/tidb-tools/tags","blobs_url":"https://api.github.com/repos/pingcap/tidb-tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pingcap/tidb-tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pingcap/tidb-tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/pingcap/tidb-tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pingcap/tidb-tools/statuses/{sha}","languages_url":"https://api.github.com/repos/pingcap/tidb-tools/languages","stargazers_url":"https://api.github.com/repos/pingcap/tidb-tools/stargazers","contributors_url":"https://api.github.com/repos/pingcap/tidb-tools/contributors","subscribers_url":"https://api.github.com/repos/pingcap/tidb-tools/subscribers","subscription_url":"https://api.github.com/repos/pingcap/tidb-tools/subscription","commits_url":"https://api.github.com/repos/pingcap/tidb-tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/pingcap/tidb-tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/pingcap/tidb-tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/pingcap/tidb-tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/pingcap/tidb-tools/contents/{+path}","compare_url":"https://api.github.com/repos/pingcap/tidb-tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pingcap/tidb-tools/merges","archive_url":"https://api.github.com/repos/pingcap/tidb-tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pingcap/tidb-tools/downloads","issues_url":"https://api.github.com/repos/pingcap/tidb-tools/issues{/number}","pulls_url":"https://api.github.com/repos/pingcap/tidb-tools/pulls{/number}","milestones_url":"https://api.github.com/repos/pingcap/tidb-tools/milestones{/number}","notifications_url":"https://api.github.com/repos/pingcap/tidb-tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pingcap/tidb-tools/labels{/name}","releases_url":"https://api.github.com/repos/pingcap/tidb-tools/releases{/id}","deployments_url":"https://api.github.com/repos/pingcap/tidb-tools/deployments","created_at":"2017-06-06T12:53:46Z","updated_at":"2018-08-02T07:42:58Z","pushed_at":"2018-08-02T08:04:12Z","git_url":"git://github.com/pingcap/tidb-tools.git","ssh_url":"git@github.com:pingcap/tidb-tools.git","clone_url":"https://github.com/pingcap/tidb-tools.git","svn_url":"https://github.com/pingcap/tidb-tools","homepage":"","size":6975,"stargazers_count":35,"watchers_count":35,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":17,"mirror_url":null,"archived":false,"open_issues_count":5,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":17,"open_issues":5,"watchers":35,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/pingcap/tidb-tools/pulls/46"},"html":{"href":"https://github.com/pingcap/tidb-tools/pull/46"},"issue":{"href":"https://api.github.com/repos/pingcap/tidb-tools/issues/46"},"comments":{"href":"https://api.github.com/repos/pingcap/tidb-tools/issues/46/comments"},"review_comments":{"href":"https://api.github.com/repos/pingcap/tidb-tools/pulls/46/comments"},"review_comment":{"href":"https://api.github.com/repos/pingcap/tidb-tools/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/pingcap/tidb-tools/pulls/46/commits"},"statuses":{"href":"https://api.github.com/repos/pingcap/tidb-tools/statuses/7081f5f1560990082518114122340e2146271096"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"csuzhangxc"}}