提交 cc9079ba 编写于 作者: P porju7

first commit

上级
# Created by .ignore support plugin (hsz.mobi)
/target/
/out/
/classes/
.mvn
.idea
*.iws
*.iml
*.ipr
.DS_Store
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.definesys</groupId>
<artifactId>sqlmd</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.atlassian.commonmark</groupId>
<artifactId>commonmark</artifactId>
<version>0.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.definesys.sqlmd.Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.definesys.sqlmd;
import com.definesys.sqlmd.parser.SQLRender;
import com.definesys.sqlmd.util.AppUtil;
import org.commonmark.node.*;
import org.commonmark.parser.Parser;
/**
* @Description:
* @author: jianfeng.zheng
* @since: 2020/1/29 10:29 AM
* @history: 1.2020/1/29 created by jianfeng.zheng
*/
public class Main {
public static void main(String[] cmd) {
String md = AppUtil.getSysClipboardText();
if (md == null || md.trim().length() == 0) {
System.out.println("请将markdown内容复制到剪贴板");
return;
}
String vendor = "oracle";
if (cmd.length > 0) {
if ("mysql".equals(cmd[0]) || "oracle".equals(cmd[0])) {
vendor = cmd[0];
} else {
System.err.println("目前只支持oracle和mysql数据库");
}
}
Parser parser = Parser.builder().build();
Node document = parser.parse(md);
SQLRender renderer = SQLRender.builder().vendor(vendor).build();
String sql = renderer.render(document);
AppUtil.setSysClipboardText(sql);
System.out.println(sql);
}
}
package com.definesys.sqlmd.parser;
import org.commonmark.node.*;
import org.commonmark.renderer.NodeRenderer;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* @Description:
* @author: jianfeng.zheng
* @since: 2020/1/29 11:39 AM
* @history: 1.2020/1/29 created by jianfeng.zheng
*/
public class CoreSQLNodeRender extends AbstractVisitor implements NodeRenderer {
private SQLRendererContext context;
private SQLWriter sqlContent;
public CoreSQLNodeRender(SQLRendererContext context) {
this.context = context;
this.sqlContent = context.getWriter();
}
@Override
public Set<Class<? extends Node>> getNodeTypes() {
return new HashSet<>(Arrays.asList(
Document.class,
Heading.class,
Paragraph.class,
BlockQuote.class,
BulletList.class,
FencedCodeBlock.class,
HtmlBlock.class,
ThematicBreak.class,
IndentedCodeBlock.class,
Link.class,
ListItem.class,
OrderedList.class,
Image.class,
Emphasis.class,
StrongEmphasis.class,
Text.class,
Code.class,
HtmlInline.class,
SoftLineBreak.class,
HardLineBreak.class
));
}
@Override
public void render(Node node) {
node.accept(this);
}
@Override
public void visit(FencedCodeBlock fencedCodeBlock) {
sqlContent.writeTableComment(fencedCodeBlock.getLiteral());
}
@Override
public void visit(Heading heading) {
if (heading.getLevel() == 1 && heading.getFirstChild() instanceof Text) {
sqlContent.newTable();
sqlContent.writeTableName(((Text) heading.getFirstChild()).getLiteral());
} else if ((heading.getLevel() == 2 || heading.getLevel() == 3) &&
heading.getFirstChild() instanceof Text) {
sqlContent.newIndex();
sqlContent.writeIndexName(((Text) heading.getFirstChild()).getLiteral());
}
}
@Override
public void visit(Text text) {
if (text.getLiteral().contains("|")) {
sqlContent.writeColumn(text.getLiteral());
}else{
sqlContent.writeIndex(text.getLiteral());
}
}
}
package com.definesys.sqlmd.parser;
import com.definesys.sqlmd.util.AppUtil;
import com.definesys.sqlmd.util.TemplateEngine;
import org.commonmark.internal.renderer.NodeRendererMap;
import org.commonmark.node.Node;
import org.commonmark.renderer.Renderer;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @Description:
* @author: jianfeng.zheng
* @since: 2020/1/29 11:31 AM
* @history: 1.2020/1/29 created by jianfeng.zheng
*/
public class SQLRender implements Renderer {
private String vendor;
private SQLRender() {
}
private SQLRender(String vendor) {
this.vendor = vendor;
}
@Override
public void render(Node node, Appendable output) {
SQLRendererContext context = new SQLRendererContext(new SQLWriter());
NodeRendererMap nodeRendererMap = new NodeRendererMap();
nodeRendererMap.add(new CoreSQLNodeRender(context));
nodeRendererMap.render(node);
TemplateEngine engine = new TemplateEngine();
Map data = new HashMap<>();
data.put("items", context.getWriter().getTables());
data.put("util", AppUtil.class);
engine.setEngineData(data);
try {
output.append(engine.evaluateFromResource(vendor + ".vm"));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String render(Node node) {
StringBuilder sb = new StringBuilder();
render(node, sb);
return sb.toString();
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String vendor = "mysql";
public SQLRender build() {
return new SQLRender(vendor);
}
public Builder vendor(String vendor) {
this.vendor = vendor;
return this;
}
}
}
package com.definesys.sqlmd.parser;
/**
* @Description:
* @author: jianfeng.zheng
* @since: 2020/1/29 3:47 PM
* @history: 1.2020/1/29 created by jianfeng.zheng
*/
public class SQLRendererContext {
private SQLWriter writer;
public SQLRendererContext(SQLWriter sqlWriter) {
this.writer=sqlWriter;
}
public SQLWriter getWriter() {
return writer;
}
public SQLRendererContext setWriter(SQLWriter writer) {
this.writer = writer;
return this;
}
}
package com.definesys.sqlmd.parser;
import com.definesys.sqlmd.sql.Column;
import com.definesys.sqlmd.sql.Index;
import com.definesys.sqlmd.sql.Table;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
/**
* @Description:
* @author: jianfeng.zheng
* @since: 2020/1/29 11:39 AM
* @history: 1.2020/1/29 created by jianfeng.zheng
*/
public class SQLWriter {
private final static Pattern START_COLUMN_PT = Pattern.compile("^[-|\\|]+$");
private List<Table> tables = new ArrayList<>();
private Table currentTable;
private Index currentIndex;
private Boolean startColumn = false;
public void newTable() {
currentTable = new Table();
tables.add(currentTable);
startColumn = false;
currentIndex = null;
}
public void newIndex() {
currentIndex = new Index();
currentTable.addIndex(currentIndex);
}
public void startColumn() {
this.startColumn = true;
}
public void writeTableName(String tableName) {
currentTable.setName(tableName);
}
public void writeIndexName(String indexName) {
currentIndex.setName(indexName);
}
public void writeColumn(String column) {
if (START_COLUMN_PT.matcher(column).find()) {
this.startColumn = true;
return;
}
if (this.startColumn) {
String[] ss = column.split("\\|");
Column c = new Column();
if (ss[0].startsWith("*")) {
c.setPrimaryKey(true);
ss[0] = ss[0].substring(1);
}
c.setName(ss[0]);
c.setType(ss.length > 1 ? ss[1] : null);
c.setComment(ss.length > 2 ? ss[2] : null);
c.setDefaultValue(ss.length > 3 ? ss[3] : null);
currentTable.addColumn(c);
}
}
public void writeTableComment(String comment) {
currentTable.setComment(comment.trim());
}
public List<Table> getTables() {
return tables;
}
public void writeIndex(String column) {
if (currentIndex == null) {
throw new RuntimeException("解析markdown异常");
}
this.currentIndex.addColumn(column);
}
}
package com.definesys.sqlmd.sql;
/**
* @Description:
* @author: jianfeng.zheng
* @since: 2020/1/31 12:19 PM
* @history: 1.2020/1/31 created by jianfeng.zheng
*/
public class Column {
private String name;
private String type;
private Boolean primaryKey = false;
private String comment;
private String defaultValue;
public String getName() {
return name;
}
public Column setName(String name) {
this.name = name;
return this;
}
public String getType() {
return type;
}
public Column setType(String type) {
this.type = type;
return this;
}
public Boolean getPrimaryKey() {
return primaryKey;
}
public Boolean isPrimaryKey() {
return primaryKey;
}
public Column setPrimaryKey(Boolean primaryKey) {
this.primaryKey = primaryKey;
return this;
}
public String getDefaultValue() {
return defaultValue;
}
public Column setDefaultValue(String defaultValue) {
if ("-".equals(defaultValue) || (defaultValue != null && defaultValue.trim().length() == 0)) {
return this;
}
this.defaultValue = defaultValue;
return this;
}
public String getComment() {
return comment;
}
public Column setComment(String comment) {
this.comment = comment;
return this;
}
}
package com.definesys.sqlmd.sql;
import java.util.ArrayList;
import java.util.List;
/**
* @Description:
* @author: jianfeng.zheng
* @since: 2020/1/31 12:20 PM
* @history: 1.2020/1/31 created by jianfeng.zheng
*/
public class Index {
private String name;
private List<String> columns = new ArrayList<>();
private String type;
public String getName() {
return name;
}
public Index setName(String name) {
this.name = name;
return this;
}
public List<String> getColumns() {
return columns;
}
public Index setColumns(List<String> columns) {
this.columns = columns;
return this;
}
public String getType() {
return type;
}
public Index setType(String type) {
this.type = type;
return this;
}
public void addColumn(String column) {
this.columns.add(column);
}
}
package com.definesys.sqlmd.sql;
import java.util.ArrayList;
import java.util.List;
/**
* @Description:
* @author: jianfeng.zheng
* @since: 2020/1/31 12:18 PM
* @history: 1.2020/1/31 created by jianfeng.zheng
*/
public class Table {
private String name;
private String comment;
private List<Column> columns = new ArrayList<>();
private List<Index> indexs = new ArrayList<>();
public Table(String tableName) {
this.name = tableName;
}
public Table() {
}
public String getName() {
return name;
}
public Table setName(String name) {
this.name = name;
return this;
}
public String getComment() {
return comment;
}
public Table setComment(String comment) {
this.comment = comment;
return this;
}
public List<Column> getColumns() {
return columns;
}
public Table setColumns(List<Column> columns) {
this.columns = columns;
return this;
}
public List<Index> getIndexs() {
return indexs;
}
public Table setIndexs(List<Index> indexs) {
this.indexs = indexs;
return this;
}
public void addColumn(Column c) {
columns.add(c);
}
public void addIndex(Index index) {
this.indexs.add(index);
}
public List<String> getKeys() {
List<String> keys = new ArrayList<>();
for (Column c : columns) {
if (c.isPrimaryKey()) {
keys.add(c.getName());
}
}
return keys;
}
}
package com.definesys.sqlmd.util;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
/**
* @Description:
* @author: jianfeng.zheng
* @since: 2020/1/31 6:45 PM
* @history: 1.2020/1/31 created by jianfeng.zheng
*/
public class AppUtil {
public static final Integer BUF_SIZE = 1024;
public static String loadResourceText(String resource) {
InputStream inputStream = AppUtil.class.getClassLoader().getResourceAsStream(resource);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
AppUtil.copyStream(inputStream, bout);
String content = null;
try {
content = bout.toString("utf-8");
inputStream.close();
bout.close();
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
/**
* 流复制
*
* @param from
* @param to
*/
public static void copyStream(InputStream from, OutputStream to) {
byte[] buf = new byte[BUF_SIZE];
int size = 0;
do {
try {
size = from.read(buf);
if (size > 0) {
to.write(buf, 0, size);
} else {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
} while (true);
}
public static String joinUpper(Collection list) {
return join(list, true);
}
public static String join(Collection list) {
return join(list, false);
}
public static String join(Collection list, Boolean upper) {
StringBuffer buf = new StringBuffer();
for (Object item : list) {
if (buf.length() > 0) {
buf.append(",");
}
if (item != null) {
buf.append(item.toString());
}
}
if (upper) {
return buf.toString().toUpperCase();
}
return buf.toString();
}
/**
* 1. 从剪切板获得文字。
*/
public static String getSysClipboardText() {
String ret = "";
Clipboard sysClip = Toolkit.getDefaultToolkit().getSystemClipboard();
// 获取剪切板中的内容
Transferable clipTf = sysClip.getContents(null);
if (clipTf != null) {
// 检查内容是否是文本类型
if (clipTf.isDataFlavorSupported(DataFlavor.stringFlavor)) {
try {
ret = (String) clipTf
.getTransferData(DataFlavor.stringFlavor);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return ret;
}
/**
* 2.将字符串复制到剪切板。
*/
public static void setSysClipboardText(String writeMe) {
Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable tText = new StringSelection(writeMe);
clip.setContents(tText, null);
}
}
package com.definesys.sqlmd.util;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import java.io.*;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* @Description:
* @author: jianfeng.zheng
* @since: 2020/1/31 4:04 PM
* @history: 1.2020/1/31 created by jianfeng.zheng
*/
public class TemplateEngine {
public static final int BUFFER_SIZE = 1024;
private VelocityEngine engine;
private Map<String, Object> engineData = new HashMap<>();
private String basePath;
private String sp = System.getProperty("file.separator");
public TemplateEngine() {
}
/**
* 设置上下文数据
*
* @param data
*/
public void setEngineData(Object data) {
this.toEngineData(data);
}
/**
* 将模板file转换为to
*
* @param resource
*/
public String evaluateFromResource(String resource) {
String tpl = AppUtil.loadResourceText(resource);
return this.evaluate(tpl, this.engineData);
}
/**
* 获取生成的文件名
*
* @param from
* @param to
* @return
*/
private String getTargetFileName(String from, String to) {
int index = to.lastIndexOf(sp);
//to如果是文件直接返回
if (index != -1 && to.substring(index).indexOf(".") != -1) {
return to;
}
int size = basePath.length();
String t = to + from.substring(size);
return t;
}
/**
* 处理路径
*
* @param path
* @return
*/
private String evaluatePath(String path) {
if (path.endsWith(sp)) {
path = path.substring(0, path.length() - 1);
}
if (path.indexOf(sp) == -1) {
path = System.getProperty("user.dir") + sp + path;
}
return path;
}
/**
* 处理基础路径
*
* @param path
* @return
*/
private String evaluateBashPath(String path) {
File f = new File(path);
if (f.isDirectory()) {
return path;
}
int index = path.lastIndexOf(sp);
if (index != -1) {
return path.substring(0, index);
}
return System.getProperty("user.dir");
}
/**
* 模版转换
*
* @param tpl
* @param data
*/
public String evaluate(String tpl, Map<String, Object> data) {
this.initEngie();
VelocityContext context = new VelocityContext();
for (String key : data.keySet()) {
context.put(key, data.get(key));
}
StringWriter writer = new StringWriter();
try {
engine.evaluate(context, writer, "bud", tpl);
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
return writer.getBuffer().toString();
}
/**
* 创建目录
*
* @param path
*/
private void mkdir(String path) {
int index = path.lastIndexOf(sp);
if (index > 0) {
File f = new File(path.substring(0, index));
f.mkdirs();
}
}
/**
* 模板初始化
*/
private void initEngie() {
if (engine == null) {
engine = new VelocityEngine();
engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
engine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
engine.init();
}
}
/**
* 将pojo数据转换为map
*
* @param ob
*/
private void toEngineData(Object ob) {
if (ob instanceof Map) {
this.engineData = (Map<String, Object>) ob;
} else {
this.engineData = new HashMap<>();
Method[] methods = ob.getClass().getDeclaredMethods();
for (Method m : methods) {
String name = m.getName();
if (!name.startsWith("get")) {
continue;
}
System.out.println(name);
name = name.substring(3);
try {
this.engineData.put(name.substring(0, 1).toLowerCase() + name.substring(1), m.invoke(ob));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
\ No newline at end of file
# mx_user
```text
用户表
```
列名|类型|备注|默认值
---|---|---|---
*id|varchar(100)|主键|-
name|varchar(100)|姓名|-
email|varchar(100)|邮箱|-
### idx_name
- name
- email
# mx_order
```text
订单表
```
列名|类型|备注|默认值
---|---|---|---
*id|varchar(100)|主键|-
orderNo|varchar(100)|订单编号|-
address|varchar(100)|订单地址|-
### idx_orderNo
- orderNo
# mx_user1
```text
用户表
```
列名|类型|备注|默认值
---|---|---|---
*id|varchar2(100)|主键|-
name|varchar2(100)|姓名|-
*email|varchar2(100)|邮箱|-
### idx_name
- name
- email
# mx_order1
```text
订单表
```
列名|类型|备注|默认值
---|---|---|---
*id|varchar2(100)|主键|-
orderNo|varchar2(100)|订单编号|-
address|varchar2(100)|订单地址|-
### idx_x
- orderNo
- address
\ No newline at end of file
#foreach($item in $items)
create table $item.name
(
#foreach($column in $item.columns)
#set($spliter = "#if($foreach.count != $item.columns.size()),#end")
#set($defaultValue = "#if($column.defaultValue) default $column.defaultValue#end")
#set($comment = "#if($column.comment) comment '$column.comment'#end")
$column.name $column.type.toUpperCase()$defaultValue$comment$spliter
#end
);
#if($item.comment)
-- Add comments to the table
ALTER TABLE $item.name COMMENT '$item.comment';
#end
-- Create primary
alter table $item.name add primary key ($util.join($item.keys));
-- Create indexes
#foreach($index in $item.indexs)
create index $index.name on ${item.name}($util.join($index.columns));
#end
#end
\ No newline at end of file
-- Create table
#foreach($item in $items)
create table $item.name.toUpperCase()
(
#foreach($column in $item.columns)
#set($s = "#if($foreach.count != $item.columns.size()),#end")
#set($s1 = "#if($column.defaultValue) default $column.defaultValue#end")
$column.name.toUpperCase() $column.type.toUpperCase()$s1$s
#end
);
#if($item.comment)
-- Add comments to the table
comment on table $item.name.toUpperCase()
is '$item.comment';
#end
-- Add comments to the columns
#foreach($column in $item.columns)
comment on column $item.name.toUpperCase().$column.name.toUpperCase()
is '$column.comment';
#end
-- Create primary, unique and foreign key constraints
alter table $item.name.toUpperCase()
add constraint $item.name.toUpperCase()_PK primary key ($util.joinUpper($item.keys));
-- Create/Recreate indexes
#foreach($index in $item.indexs)
create unique $index.name on ($util.joinUpper($index.columns));
#end
#end
\ No newline at end of file
org.slf4j.simpleLogger.defaultLogLevel=off
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册