Created
February 28, 2018 23:37
-
-
Save dmitrymomot/f25e0b599e1b88a9789cc0cd8483a01f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
// init mysql | |
_ "github.com/go-sql-driver/mysql" | |
"github.com/jinzhu/gorm" | |
"github.com/mitchellh/mapstructure" | |
) | |
const ( | |
driver = "mysql" | |
connStr = "user:password@tcp(localhost:3306)/flxbase?charset=utf8&parseTime=True&loc=Local" | |
) | |
// Test struct | |
type Test struct { | |
gorm.Model | |
String string | |
Integer int | |
Boolean bool | |
AnotherField uint64 | |
} | |
func main() { | |
db, err := gorm.Open(driver, connStr) | |
checkErr(err) | |
defer db.Close() | |
db.LogMode(true) | |
if !db.HasTable(&Test{}) { | |
checkErr(db.CreateTable(&Test{}).Error) | |
} | |
db.AutoMigrate(&Test{}) | |
table, err := TableSchema(db, "tests") | |
checkErr(err) | |
jsonData, err := json.Marshal(table) | |
checkErr(err) | |
fmt.Println(string(jsonData)) | |
} | |
func checkErr(err error) { | |
if err != nil { | |
panic(err) | |
} | |
} | |
// TableField struct | |
type TableField struct { | |
Collation string | |
Comment string | |
Default string | |
Extra string | |
Field string | |
Key string | |
Null string | |
Privileges string | |
Type string | |
} | |
// MapToStruct converts map to structure | |
func MapToStruct(data map[string]interface{}, output interface{}) error { | |
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ | |
TagName: "json", | |
Metadata: nil, | |
Result: output, | |
}) | |
if err != nil { | |
return err | |
} | |
if err := decoder.Decode(data); err != nil { | |
return err | |
} | |
return nil | |
} | |
// TableSchema returns table schema | |
func TableSchema(db *gorm.DB, table string) ([]*TableField, error) { | |
rows, err := db.Raw("SHOW FULL COLUMNS FROM " + table).Rows() | |
if err != nil { | |
return nil, err | |
} | |
columns, err := rows.Columns() | |
if err != nil { | |
return nil, err | |
} | |
count := len(columns) | |
tableData := make([]*TableField, 0) | |
values := make([]interface{}, count) | |
valuePtrs := make([]interface{}, count) | |
for rows.Next() { | |
for i := 0; i < count; i++ { | |
valuePtrs[i] = &values[i] | |
} | |
rows.Scan(valuePtrs...) | |
entry := make(map[string]interface{}) | |
for i, col := range columns { | |
var v interface{} | |
val := values[i] | |
b, ok := val.([]byte) | |
if ok { | |
v = string(b) | |
} else { | |
v = val | |
} | |
entry[col] = v | |
} | |
tf := &TableField{} | |
if err := MapToStruct(entry, tf); err != nil { | |
return nil, err | |
} | |
tableData = append(tableData, tf) | |
} | |
return tableData, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment