Skip to content

Commit

Permalink
实现基本功能
Browse files Browse the repository at this point in the history
  • Loading branch information
idoubi committed Oct 29, 2017
1 parent 041d02c commit 646fbc4
Show file tree
Hide file tree
Showing 15 changed files with 10,921 additions and 0 deletions.
46 changes: 46 additions & 0 deletions README.md
@@ -0,0 +1,46 @@
# SQL2Struct

> SQL2Struct是一款对golang开发者友好的chrome插件,根据在mysql中创建数据表的sql语句,自动生成golang中的struct,在golang开发者使用诸如gorm之类的框架时,可以很好的把mysql中的数据表与orm的结构体关联起来。
## 使用说明

1. 下载chrome扩展文件:[点击下载](http://qiniu.idoubi.cc/sql2struct.crx)

2. 安装扩展

![](http://qiniu.idoubi.cc/install.png)

3. 在mysql中获取生成数据表的sql语句


`show create table users\G;`

![](http://qiniu.idoubi.cc/Sql.png)

4. 进入插件主页面,把上一步得到的sql语句粘贴至左侧的输入框

5. 复制右侧生成的struct,粘贴至golang代码中即可

![](http://qiniu.idoubi.cc/plugin)

## 配置说明

目前只有三个配置项

- gorm:开启此配置项,则生成struct的时候,每个字段都会包含类似`gorm:column:"id"`这样的信息。
- json:开启此配置项,则生成struct的时候,每个字段都会包含类似`json:"id"`这样的信息。
- typeMap:此配置项定义mysql数据表字段类型与go字段类型的映射关系,在数据解析的时候会安装配置的映射关系进行结构体生成。

![](http://qiniu.idoubi.cc/options)

## Todolist

- [] 支持更多的mysql类型与go类型的映射
- [] 支持自定义要进行转换的字段配置
- [] 正则表达式优化
- [] 数据表名称复数形式与struct名称单数形式转换

## Contribution

欢迎fork代码、提issue或者是pull request

1 change: 1 addition & 0 deletions css/element-ui.css

Large diffs are not rendered by default.

Binary file added css/fonts/element-icons.ttf
Binary file not shown.
Binary file added css/fonts/element-icons.woff
Binary file not shown.
13 changes: 13 additions & 0 deletions css/sql2struct.css
@@ -0,0 +1,13 @@
body {
padding: 0px;
margin: 0px;
background-color: #fafaff;
}

a {
text-decoration: none;
}

.el-header {
padding: 0;
}
75 changes: 75 additions & 0 deletions html/sql2struct.html
@@ -0,0 +1,75 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>sql2struct</title>
<link rel="stylesheet" href="../css/element-ui.css">
<link rel="stylesheet" href="../css/sql2struct.css">
</head>
<body>
<div id="app">
<el-container>
<el-header>
<el-menu
:default-active="activeIndex"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<el-menu-item index="1">SQL2Struct</el-menu-item>
<el-menu-item index="2" @click="dialogFormVisible = true">options</el-menu-item>
<el-menu-item index="3"><a href="https://github.com/mikemintang/sql2struct.git" target="_blank">Github</a></el-menu-item>
</el-menu>
</el-header>
<el-main>
<el-row :gutter="60">
<el-col :span="12"><div class="grid-content bg-purple">
<el-form ref="form" label-position="top" label-width="80px">
<el-form-item label="SQL">
<el-input type="textarea" placeholder="input sql for creating table in mysql" :rows="30" v-model="sqlContent"></el-input>
</el-form-item>
</el-form>
</div></el-col>
<el-col :span="12"><div class="grid-content bg-purple-light">
<el-form ref="form" label-position="top" label-width="80px">
<el-form-item label="Struct">
<el-input type="textarea" placeholder="data struct used in golang" :rows="30" v-model="structContent"></el-input>
</el-form-item>
</el-form>
</div></el-col>
</el-row>
</el-main>
<el-footer>

</el-footer>
</el-container>

<el-dialog title="options" :visible.sync="dialogFormVisible">
<el-form>
<el-form-item label="gorm">
<el-switch
v-model="useGorm"
active-color="#13ce66"
inactive-color="#ff4949">
</el-switch>
</el-form-item>
<el-form-item label="json">
<el-switch
v-model="useJson"
active-color="#13ce66"
inactive-color="#ff4949">
</el-switch>
</el-form-item>
<el-form-item label="typeMap">
<el-input type="textarea" placeholder="" :rows="14" v-model="typeMapStr"></el-input>
</el-form-item>
</el-form>
</el-dialog>
</div>
<script src="../js/vue@2.5.2.js"></script>
<script src="../js/element-ui@2.0.1.js"></script>
<script src="../js/sql2struct.js"></script>
</body>
</html>
Binary file added img/logo128.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/logo16.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/logo48.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions js/background.js
@@ -0,0 +1,17 @@
chrome.browserAction.onClicked.addListener(function(activeTab) {
var url = 'html/sql2struct.html';
chrome.tabs.create({
url: url
});
});

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (message.act == 'setOptions') {
localStorage.setItem('sql2struct_options', message.data)
sendResponse('ok')
}
if (message.act = 'getOptions') {
options = localStorage.getItem('sql2struct_options')
sendResponse(options)
}
})
1 change: 1 addition & 0 deletions js/element-ui@2.0.1.js

Large diffs are not rendered by default.

188 changes: 188 additions & 0 deletions js/sql2struct.js
@@ -0,0 +1,188 @@
new Vue({
el: '#app',
data() {
return {
cache: null,
sqlContent: '',
structContent: '',
activeIndex: '1',
typeMap: '',
typeMapStr: '',
useGorm: true,
useJson: true,
dialogFormVisible: false
}
},
created() {
var message = {
act: 'getOptions'
}
var that = this
// 获取缓存数据
chrome.runtime.sendMessage(message, function(res) {
if (!res) { // 不存在缓存数据
// 初始配置数据
var data = {
useGorm: this.useGorm,
useJson: this.useJson,
typeMap: getTypeMap()
}
that.setCache(data)
return
}
var obj = JSON.parse(res)
if (obj.useGorm != undefined) {
that.useGorm = obj.useGorm
}
if (obj.useJson != undefined) {
that.useJson = obj.useJson
}
if (obj.typeMap != undefined) {
for (var k in obj.typeMap) {
that.typeMapStr += k + ': ' + obj.typeMap[k] + '\n'
}
}
})
},
watch: {
sqlContent(val) {
if (!val) {
this.structContent = ''
return
}
var res = val.match(/\`[\w_]+\`\s+[\w_\(\)]+(\s+|\,)/g)
if (!res) {
this.structContent = 'invalid sql'
return
}
var types = this.typeMap
var structResult = 'type '
for (var i = 0, len = res.length; i < len; i++) {
var field = res[i].match(/\`(.+)\`\s+(tinyint|smallint|int|mediumint|bigint|float|double|decimal|varchar|char|text|mediumtext|longtext|datetime|time|date|enum|set|blob)?/)
if (i == 0) { // 第一个字段为数据表名称
if (field && field[1] != undefined && field[2] == undefined) {
var tbName = titleCase(field[1])
structResult += tbName + ' struct {'
continue
} else {
return
}
} else { // 数据表字段
if (field && field[1] != undefined && field[2] != undefined) {
if (types[field[2]] != undefined) {
var fieldName = titleCase(field[1])
var fieldType = types[field[2]]
var fieldJsonName = field[1].toLowerCase()
if (fieldName.toLowerCase() == 'id') {
fieldName = 'ID'
}
structResult += '\n\t' + fieldName + ' ' + fieldType
if (this.useGorm) {
structResult += ' `gorm:"column:'+ fieldJsonName +'"'
if (this.useJson) {
structResult += ' json:"' + fieldJsonName + '"'
}
structResult += '`'
} else if (this.useJson) {
structResult += ' `json:"' + fieldJsonName + '"`'
}
} else {
continue
}
} else {
continue
}
}
}
structResult += '\n}'
this.structContent = structResult
},
typeMapStr(val) {
var typeArr = val.split('\n')
var typeMap = {}
for (var i = 0, len = typeArr.length; i < len; i++) {
var itemArr = typeArr[i].split(/\:\s+/)
if (itemArr[0] != undefined && itemArr[1] != undefined) {
typeMap[itemArr[0]] = itemArr[1]
}
}
this.typeMap = typeMap
var data = {
useGorm: this.useGorm,
useJson: this.useJson,
typeMap: this.typeMap
}
this.setCache(data)
},
useGorm(val) {
this.useGorm = val
var data = {
useGorm: this.useGorm,
useJson: this.useJson,
typeMap: this.typeMap
}
this.setCache(data)
},
useJson(val) {
this.useJson = val
var data = {
useGorm: this.useGorm,
useJson: this.useJson,
typeMap: this.typeMap
}
this.setCache(data)
}
},
methods: {
handleSelect(key, keyPath) {

},
setCache(data) {
var message = {
act: 'setOptions',
data: JSON.stringify(data)
}
chrome.runtime.sendMessage(message, function(res) {
//console.log(res)
})
}
}
})

// 首字母大写
function titleCase(str) {

var array = str.toLowerCase().split("_");
for (var i = 0; i < array.length; i++){
array[i] = array[i][0].toUpperCase() + array[i].substring(1, array[i].length);
}
var string = array.join("");

return string;
}

// 类型映射
function getTypeMap() {
return {
'tinyint': 'int64',
'smallint': 'int64',
'int': 'int64',
'mediumint': 'int64',
'bigint': 'int64',
'float': 'float64',
'double': 'float164',
'decimal': 'float64',
'char': 'string',
'varchar': 'string',
'text': 'string',
'mediumtext': 'string',
'longtext': 'string',
'time': 'time.Time',
'date': 'time.Time',
'datetime': 'time.Time',
'timestramp': 'int64',
'enum': 'string',
'set': 'string',
'blob': 'string'
}
}

0 comments on commit 646fbc4

Please sign in to comment.