diff --git a/src/main/java/com/chenjf/service/ResolveDDL.java b/src/main/java/com/chenjf/service/ResolveDDL.java index ae34707aca202a0800e7eb77af9933ef1f1bcda8..aa47573eeccf39ddd90dfe4e7636bf8abe944eee 100644 --- a/src/main/java/com/chenjf/service/ResolveDDL.java +++ b/src/main/java/com/chenjf/service/ResolveDDL.java @@ -1,79 +1,163 @@ package com.chenjf.service; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.List; - import com.chenjf.entity.Gtable; import com.chenjf.util.resolve.ResolveDB; import com.chenjf.util.resolve.ResolveFactory; -//@Service +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +/** + * 分析数据库文件 + * + * @date 2021-05-25 03:26:56 + */ public class ResolveDDL { - /* - * 解析SQL DDL语句 - */ - public int resolve(String filepath,String dbtype) { - int tablecount = 0;// 导入表数量 - String sqlStr=readSQL(filepath,dbtype); - List createtable=new ArrayList(); - ResolveFactory factory=new ResolveFactory(); - ResolveDB resolve=factory.create(dbtype); - createtable=resolve.loadSql(sqlStr); - for(String table:createtable) { - Gtable gtables=resolve.getTable(table); - resolve.saveColumn(table,gtables.getGtid()); - tablecount=tablecount+1; - } - return tablecount; - } + /** + * 解析SQL DDL语句 + * + * @param filepath 文件路径 + * @param dbtype 数据库类型 + * @return int + */ + public int resolve(String filepath, String dbtype) { + // 导入表数量 + int tablecount = 0; + String sqlStr = readSQL(filepath, dbtype); + List createTable = new ArrayList(); + ResolveFactory factory = new ResolveFactory(); + ResolveDB resolve = factory.create(dbtype); + createTable = resolve.loadSql(sqlStr); + for (String table : createTable) { + Gtable gTables = resolve.getTable(table); + resolve.saveColumn(table, gTables.getGtid()); + tablecount = tablecount + 1; + } + return tablecount; + } + + /** + * 读取sql + * + * @param sqlFile sql文件 + * @param dbtype 数据库类型 + * @return {@link String } + */ + public String readSQL(String sqlFile, String dbtype) { + String sql = ""; + List list = new ArrayList(); + BufferedReader reader = null; + String encoding = System.getProperty("file.encoding"); + try { + //获取当前项目路径 + File currentpath = new File(System.getProperty("user.dir")); + //获取当前项目路径的父路径 + File parentfile = currentpath.getParentFile(); + //指定文件上传径路径 + File uploadpath = new File(parentfile.getAbsolutePath() + File.separator + "upload" + File.separator); + String filePath = uploadpath + File.separator + sqlFile; + File file = new File(filePath); + FileInputStream f4 = new FileInputStream(file); + reader = new BufferedReader(new InputStreamReader(f4, getFileCharset(filePath))); + String str = ""; + String temp = ""; + while ((str = reader.readLine()) != null) { + temp = new String(str.getBytes(), encoding); + list.add(temp.toLowerCase()); + } + sql = String.join("\r\n", list); + } catch (UnsupportedEncodingException ex) { + ex.printStackTrace(); + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + } + return sql; + } - public String readSQL(String sqlFile,String dbtype) { - String sql=""; - List list=new ArrayList(); - BufferedReader reader =null; - String encoding=System.getProperty("file.encoding"); - try { - //获取当前项目路径 - File currentpath = new File(System.getProperty("user.dir")); - //获取当前项目路径的父路径 - File parentfile = currentpath.getParentFile(); - //指定文件上传径路径 - File uploadpath= new File(parentfile.getAbsolutePath()+File.separator+"upload"+File.separator); - File file=new File(uploadpath+File.separator+sqlFile); - FileInputStream f4 = new FileInputStream(file); - reader = new BufferedReader(new InputStreamReader(f4,"GB2312")); - String str=""; - String temp=""; - while ((str = reader.readLine()) != null) { - temp=new String(str.getBytes(),encoding); - list.add(temp.toLowerCase()); - } - sql= String.join("\r\n", list); - } catch (UnsupportedEncodingException ex) { - ex.printStackTrace(); - }catch (Exception ex) { - ex.printStackTrace(); - }finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException e1) { - e1.printStackTrace(); - } - } - } - return sql; - } + /** + * 判断文本文件的字符集,文件开头三个字节表明编码格式。 + * 参考的博客地址 + * + * @param path + * @return + * @throws Exception + * @throws Exception + */ + public static String getFileCharset(String path) { + String charset = "GBK"; + byte[] first3Bytes = new byte[3]; + try { + boolean checked = false; + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path)); + // 读者注: bis.mark(0);修改为 bis.mark(100);我用过这段代码,需要修改上面标出的地方。 + bis.mark(0); + // Wagsn注:不过暂时使用正常,遂不改之 + int read = bis.read(first3Bytes, 0, 3); + if (read == -1) { + bis.close(); + // 文件编码为 ANSI + return charset; + } else if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) { + // 文件编码为 Unicode + charset = "UTF-16LE"; + checked = true; + } else if (first3Bytes[0] == (byte) 0xFE && first3Bytes[1] == (byte) 0xFF) { + // 文件编码为 Unicode big endian + charset = "UTF-16BE"; + checked = true; + } else if (first3Bytes[0] == (byte) 0xEF && first3Bytes[1] == (byte) 0xBB + && first3Bytes[2] == (byte) 0xBF) { + // 文件编码为 UTF-8 + charset = "UTF-8"; + checked = true; + } + bis.reset(); + if (!checked) { + while ((read = bis.read()) != -1) { + if (read >= 0xF0) + break; + // 单独出现BF以下的,也算是GBK + if (0x80 <= read && read <= 0xBF) + break; + if (0xC0 <= read && read <= 0xDF) { + read = bis.read(); + // 双字节 (0xC0 - 0xDF) + if (0x80 <= read && read <= 0xBF) + // (0x80 - 0xBF),也可能在GB编码内 + continue; + else + break; + } else if (0xE0 <= read && read <= 0xEF) { + // 也有可能出错,但是几率较小 + read = bis.read(); + if (0x80 <= read && read <= 0xBF) { + read = bis.read(); + if (0x80 <= read && read <= 0xBF) { + charset = "UTF-8"; + break; + } else + break; + } else + break; + } + } + } + bis.close(); + } catch (Exception e) { + e.printStackTrace(); + } + System.out.println("======> 文件-> [" + path + "] 采用的字符集为: [" + charset + "]"); + return charset; + } - public static void main(String[] args) { - ResolveDDL ddl = new ResolveDDL(); - System.out.println(ddl.resolve("d:\\test.sql","mysql")); - } } diff --git a/src/main/java/com/chenjf/util/entity/Expression.java b/src/main/java/com/chenjf/util/entity/Expression.java index f1df9c9611a90debee859c1de87f149c3532417b..e4f7e811c899e91dd86455562ebeff009c88b9cc 100644 --- a/src/main/java/com/chenjf/util/entity/Expression.java +++ b/src/main/java/com/chenjf/util/entity/Expression.java @@ -36,6 +36,15 @@ public class Expression { } } + + if(result.startsWith("\"")) { + result = result.substring(1); + } + + if(result.endsWith("\"")) { + result = result.substring(1, result.length() - 1); + } + return result; } } diff --git a/src/main/java/com/chenjf/util/resolve/MysqlDDL.java b/src/main/java/com/chenjf/util/resolve/MysqlDDL.java index d7bd3e5a60dbf594efc88370d96331601f6fbb77..458380e0e75760b98ca9e94b966d782da03e9017 100644 --- a/src/main/java/com/chenjf/util/resolve/MysqlDDL.java +++ b/src/main/java/com/chenjf/util/resolve/MysqlDDL.java @@ -1,126 +1,166 @@ package com.chenjf.util.resolve; +import com.chenjf.entity.Gcolumn; +import com.chenjf.entity.Gtable; + import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; -import com.chenjf.entity.Gcolumn; -import com.chenjf.entity.Gtable; /* * MySQL解析DDL */ -public class MysqlDDL implements ResolveDB{ - /** - * 加载解析sql字符串的DDL - */ - public List loadSql(String sqlStr) { - List sqlList = new ArrayList(); - try { - String temp= sqlStr.toLowerCase(); - temp= temp.substring(temp.indexOf("create table")); - if(temp.indexOf("drop view")>0)temp=temp.substring(0, temp.indexOf("drop view")); - if(temp.indexOf("drop function")>0)temp=temp.substring(0, temp.indexOf("drop function")); - StringBuffer sqlbuffer=new StringBuffer(temp); - String[] sqlArr = sqlbuffer.toString().split(";"); - for (int i = 0; i < sqlArr.length; i++) { - String sql = sqlArr[i].trim(); - if(!sql.equals("") && sql.indexOf("create table")>=0) { - sql=sql.replaceAll("`", ""); - sqlList.add(sql); - } - } - } catch (Exception ex) { - ex.printStackTrace(); - } - return sqlList; - } - /* - * 获取并保存表信息 - */ - public Gtable getTable(String ddl) { - Gtable gtable = new Gtable(); - String tablename=ddl.substring(0, ddl.indexOf("(")).replace("create table", "").trim(); - String chinesename=""; - String[] tablestr=ddl.substring(ddl.lastIndexOf(")")).replaceAll(" = ", "=").split(" "); - for(int i=0;i0)datatype=getType(typetemp.substring(0,typetemp.indexOf("("))); - else datatype=getType(typetemp); - if(typetemp.indexOf("(")>0) dltemp=typetemp.substring(typetemp.indexOf("(")+1,typetemp.indexOf(")")); - if(isInteger(dltemp))datalength=Integer.valueOf(dltemp); - chinesename=col[col.length-1].replaceAll("'", ""); - Gcolumn column=new Gcolumn(); - column.setGtid(gtid); - column.setChinesename(chinesename); - column.setColumnname(columnname); - column.setDatalength(datalength); - column.setDatatype(datatype); - column.insert(); - } - return count; - } - /* - * 数据类型的统一 - */ - private String getType(String type) { - String datatype=""; - switch(type.toLowerCase()){ - case "tinyint":datatype="int";break; - case "smallint":datatype="int";break; - case "mediumint":datatype="int";break; - case "int":datatype="int";break; - case "integer":datatype="int";break; - case "bigint":datatype="int";break; - case "float":datatype="double";break; - case "double":datatype="double";break; - case "decimal":datatype="double";break; - case "date":datatype="date";break; - case "time":datatype="date";break; - case "datetime":datatype="date";break; - case "timestamp":datatype="date";break; - case "char":datatype="string";break; - case "varchar":datatype="string";break; - case "text":datatype="string";break; - default:datatype="string";break; - } - return datatype; - } - /* +public class MysqlDDL implements ResolveDB { + /** + * 加载解析sql字符串的DDL + */ + public List loadSql(String sqlStr) { + List sqlList = new ArrayList(); + try { + String temp = sqlStr.toLowerCase(); + temp = temp.substring(temp.indexOf("create table")); + if (temp.indexOf("drop view") > 0) temp = temp.substring(0, temp.indexOf("drop view")); + if (temp.indexOf("drop function") > 0) temp = temp.substring(0, temp.indexOf("drop function")); + StringBuffer sqlbuffer = new StringBuffer(temp); + String[] sqlArr = sqlbuffer.toString().split(";"); + for (int i = 0; i < sqlArr.length; i++) { + String sql = sqlArr[i].trim(); + if (!sql.equals("") && sql.indexOf("create table") >= 0) { + sql = sql.replaceAll("`", ""); + sqlList.add(sql); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + return sqlList; + } + + /* + * 获取并保存表信息 + */ + public Gtable getTable(String ddl) { + Gtable gtable = new Gtable(); + String tablename = ddl.substring(0, ddl.indexOf("(")).replace("create table", "").trim(); + String chinesename = ""; + String[] tablestr = ddl.substring(ddl.lastIndexOf(")")).replaceAll(" = ", "=").split(" "); + for (int i = 0; i < tablestr.length; i++) { + if (tablestr[i].indexOf("comment=") >= 0) { + String[] temp = tablestr[i].split("="); + chinesename = temp[1].replaceAll("'", ""); + } + } + gtable.setChinesename(chinesename); + gtable.setGeneratecount(1000); + gtable.setIsincludefield(true); + gtable.setIssql(true); + gtable.setTablename(tablename); + gtable.setIsexcel(true); + gtable.insert(); + //boolean flag=gtable.insert(); + //System.out.println(flag); + //int gid=gtable.getGtid(); + //System.out.print(gid); + return gtable; + } + + /* + * 保存所有列信息 + */ + public int saveColumn(String ddl, int gtid) { + int count = 0; + String columnname = "", datatype = "", chinesename = "", dltemp = "0"; + int datalength = 0; + String[] cols = ddl.substring(ddl.indexOf("(") + 1, ddl.lastIndexOf(")")).split(","); + for (String colstr : cols) { + String[] col = colstr.trim().split(" "); + columnname = col[0]; + String typetemp = col[1]; + if (typetemp.indexOf("(") > 0) datatype = getType(typetemp.substring(0, typetemp.indexOf("("))); + else datatype = getType(typetemp); + if (typetemp.indexOf("(") > 0) + dltemp = typetemp.substring(typetemp.indexOf("(") + 1, typetemp.indexOf(")")); + if (isInteger(dltemp)) datalength = Integer.valueOf(dltemp); + chinesename = col[col.length - 1].replaceAll("'", ""); + Gcolumn column = new Gcolumn(); + column.setGtid(gtid); + column.setChinesename(chinesename); + column.setColumnname(columnname); + column.setDatalength(datalength); + column.setDatatype(datatype); + column.insert(); + } + return count; + } + + /* + * 数据类型的统一 + */ + private String getType(String type) { + String datatype = ""; + switch (type.toLowerCase()) { + case "tinyint": + datatype = "int"; + break; + case "smallint": + datatype = "int"; + break; + case "mediumint": + datatype = "int"; + break; + case "int": + datatype = "int"; + break; + case "integer": + datatype = "int"; + break; + case "bigint": + datatype = "int"; + break; + case "float": + datatype = "double"; + break; + case "double": + datatype = "double"; + break; + case "decimal": + datatype = "double"; + break; + case "date": + datatype = "date"; + break; + case "time": + datatype = "date"; + break; + case "datetime": + datatype = "date"; + break; + case "timestamp": + datatype = "date"; + break; + case "char": + datatype = "string"; + break; + case "varchar": + datatype = "string"; + break; + case "text": + datatype = "string"; + break; + default: + datatype = "string"; + break; + } + return datatype; + } + + /* * 判断是否为整数 * @param str 传入的字符串 * @return 是整数返回true,否则返回false */ - private boolean isInteger(String str) { - Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$"); - return pattern.matcher(str).matches(); - } + private boolean isInteger(String str) { + Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$"); + return pattern.matcher(str).matches(); + } }