mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
sql desensitize support.
This commit is contained in:
@@ -15,11 +15,9 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.DruidRuntimeException;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLObject;
|
||||
import com.alibaba.druid.sql.ast.SQLReplaceable;
|
||||
@@ -277,8 +275,9 @@ public class SQLUtils {
|
||||
option = DEFAULT_FORMAT_OPTION;
|
||||
}
|
||||
visitor.setUppCase(option.isUppCase());
|
||||
visitor.setPrettyFormat(option.isPrettyFormat());
|
||||
visitor.setParameterized(option.isParameterized());
|
||||
visitor.setPrettyFormat(option.prettyFormat);
|
||||
visitor.setParameterized(option.parameterized);
|
||||
visitor.setDesensitize(option.desensitize);
|
||||
|
||||
if (tableMapping != null) {
|
||||
visitor.setTableMapping(tableMapping);
|
||||
@@ -630,6 +629,7 @@ public class SQLUtils {
|
||||
private boolean ucase = true;
|
||||
private boolean prettyFormat = true;
|
||||
private boolean parameterized = false;
|
||||
private boolean desensitize = false;
|
||||
|
||||
public FormatOption() {
|
||||
|
||||
@@ -649,6 +649,14 @@ public class SQLUtils {
|
||||
this.parameterized = parameterized;
|
||||
}
|
||||
|
||||
public boolean isDesensitize() {
|
||||
return desensitize;
|
||||
}
|
||||
|
||||
public void setDesensitize(boolean desensitize) {
|
||||
this.desensitize = desensitize;
|
||||
}
|
||||
|
||||
public boolean isUppCase() {
|
||||
return ucase;
|
||||
}
|
||||
@@ -865,5 +873,15 @@ public class SQLUtils {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String desensitizeTable(String tableName) {
|
||||
if (tableName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
tableName = normalize(tableName);
|
||||
long hash = Utils.fnv_64_lower(tableName);
|
||||
return Utils.hex_t(hash);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ public class SQLCreateViewStatement extends SQLStatementImpl implements SQLDDLSt
|
||||
|
||||
private boolean orReplace = false;
|
||||
private boolean force = false;
|
||||
protected SQLName name;
|
||||
// protected SQLName name;
|
||||
protected SQLSelect subQuery;
|
||||
protected boolean ifNotExists = false;
|
||||
|
||||
@@ -38,6 +38,8 @@ public class SQLCreateViewStatement extends SQLStatementImpl implements SQLDDLSt
|
||||
protected SQLName definer;
|
||||
protected String sqlSecurity;
|
||||
|
||||
protected SQLExprTableSource tableSource;
|
||||
|
||||
protected final List<Column> columns = new ArrayList<Column>();
|
||||
|
||||
private Level with;
|
||||
@@ -61,11 +63,26 @@ public class SQLCreateViewStatement extends SQLStatementImpl implements SQLDDLSt
|
||||
}
|
||||
|
||||
public SQLName getName() {
|
||||
return name;
|
||||
if (tableSource == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (SQLName) tableSource.getExpr();
|
||||
}
|
||||
|
||||
public void setName(SQLName name) {
|
||||
this.name = name;
|
||||
this.setTableSource(new SQLExprTableSource(name));
|
||||
}
|
||||
|
||||
public SQLExprTableSource getTableSource() {
|
||||
return tableSource;
|
||||
}
|
||||
|
||||
public void setTableSource(SQLExprTableSource tableSource) {
|
||||
if (tableSource != null) {
|
||||
tableSource.setParent(this);
|
||||
}
|
||||
this.tableSource = tableSource;
|
||||
}
|
||||
|
||||
public Level getWith() {
|
||||
@@ -151,7 +168,7 @@ public class SQLCreateViewStatement extends SQLStatementImpl implements SQLDDLSt
|
||||
|
||||
public void output(StringBuffer buf) {
|
||||
buf.append("CREATE VIEW ");
|
||||
this.name.output(buf);
|
||||
this.getName().output(buf);
|
||||
|
||||
if (this.columns.size() > 0) {
|
||||
buf.append(" (");
|
||||
@@ -176,7 +193,7 @@ public class SQLCreateViewStatement extends SQLStatementImpl implements SQLDDLSt
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, this.name);
|
||||
acceptChild(visitor, this.tableSource);
|
||||
acceptChild(visitor, this.columns);
|
||||
acceptChild(visitor, this.comment);
|
||||
acceptChild(visitor, this.subQuery);
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.sql.NClob;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.ast.expr.*;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
@@ -69,6 +70,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
|
||||
protected transient int lines = 0;
|
||||
|
||||
protected boolean desensitize = false;
|
||||
|
||||
public SQLASTOutputVisitor(Appendable appender){
|
||||
this.appender = appender;
|
||||
}
|
||||
@@ -118,6 +121,14 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public boolean isDesensitize() {
|
||||
return desensitize;
|
||||
}
|
||||
|
||||
public void setDesensitize(boolean desensitize) {
|
||||
this.desensitize = desensitize;
|
||||
}
|
||||
|
||||
public Set<String> getTables() {
|
||||
return this.tables;
|
||||
}
|
||||
@@ -1423,6 +1434,26 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
addTable(expr.toString());
|
||||
}
|
||||
|
||||
if (desensitize) {
|
||||
SQLExpr owner = null;
|
||||
String ident = null;
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
ident = ((SQLIdentifierExpr) expr).getName();
|
||||
} else if (expr instanceof SQLPropertyExpr) {
|
||||
SQLPropertyExpr propertyExpr = (SQLPropertyExpr) expr;
|
||||
propertyExpr.getOwner().accept(this);
|
||||
print('.');
|
||||
|
||||
ident = propertyExpr.getName();
|
||||
}
|
||||
|
||||
if (ident != null) {
|
||||
String desensitizeTable = SQLUtils.desensitizeTable(ident);
|
||||
print0(desensitizeTable);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (tableMapping != null && expr instanceof SQLName) {
|
||||
String tableName = expr.toString();
|
||||
|
||||
@@ -2446,7 +2477,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
print0(ucase ? "IF NOT EXISTS " : "if not exists ");
|
||||
}
|
||||
|
||||
x.getName().accept(this);
|
||||
x.getTableSource().accept(this);
|
||||
|
||||
if (x.getColumns().size() > 0) {
|
||||
println();
|
||||
|
||||
@@ -426,7 +426,11 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (x.getOperator()) {
|
||||
final SQLBinaryOperator op = x.getOperator();
|
||||
final SQLExpr left = x.getLeft();
|
||||
final SQLExpr right = x.getRight();
|
||||
|
||||
switch (op) {
|
||||
case Equality:
|
||||
case NotEqual:
|
||||
case GreaterThan:
|
||||
@@ -439,15 +443,32 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
case NotLike:
|
||||
case Is:
|
||||
case IsNot:
|
||||
handleCondition(x.getLeft(), x.getOperator().name, x.getRight());
|
||||
handleCondition(x.getRight(), x.getOperator().name, x.getLeft());
|
||||
handleCondition(left, x.getOperator().name, right);
|
||||
handleCondition(right, x.getOperator().name, left);
|
||||
|
||||
handleRelationship(x.getLeft(), x.getOperator().name, x.getRight());
|
||||
handleRelationship(left, x.getOperator().name, right);
|
||||
break;
|
||||
case BooleanOr:{
|
||||
List<SQLExpr> list = SQLBinaryOpExpr.split(x, op);
|
||||
|
||||
for (SQLExpr item : list) {
|
||||
if (item instanceof SQLBinaryOpExpr) {
|
||||
visit((SQLBinaryOpExpr) item);
|
||||
} else {
|
||||
item.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
left.accept(this);
|
||||
right.accept(this);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void handleRelationship(SQLExpr left, String operator, SQLExpr right) {
|
||||
|
||||
@@ -334,4 +334,117 @@ public class Utils {
|
||||
public static boolean equals(Object a, Object b) {
|
||||
return (a == b) || (a != null && a.equals(b));
|
||||
}
|
||||
|
||||
public static String hex(int hash) {
|
||||
byte[] bytes = new byte[4];
|
||||
|
||||
bytes[3] = (byte) (hash );
|
||||
bytes[2] = (byte) (hash >>> 8);
|
||||
bytes[1] = (byte) (hash >>> 16);
|
||||
bytes[0] = (byte) (hash >>> 24);
|
||||
|
||||
|
||||
char[] chars = new char[8];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
byte b = bytes[i];
|
||||
|
||||
int a = b & 0xFF;
|
||||
int b0 = a >> 4;
|
||||
int b1 = a & 0xf;
|
||||
|
||||
chars[i * 2] = (char) (b0 + (b0 < 10 ? 48 : 55));
|
||||
chars[i * 2 + 1] = (char) (b1 + (b1 < 10 ? 48 : 55));
|
||||
}
|
||||
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
public static String hex(long hash) {
|
||||
byte[] bytes = new byte[8];
|
||||
|
||||
bytes[7] = (byte) (hash );
|
||||
bytes[6] = (byte) (hash >>> 8);
|
||||
bytes[5] = (byte) (hash >>> 16);
|
||||
bytes[4] = (byte) (hash >>> 24);
|
||||
bytes[3] = (byte) (hash >>> 32);
|
||||
bytes[2] = (byte) (hash >>> 40);
|
||||
bytes[1] = (byte) (hash >>> 48);
|
||||
bytes[0] = (byte) (hash >>> 56);
|
||||
|
||||
char[] chars = new char[16];
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
byte b = bytes[i];
|
||||
|
||||
int a = b & 0xFF;
|
||||
int b0 = a >> 4;
|
||||
int b1 = a & 0xf;
|
||||
|
||||
chars[i * 2] = (char) (b0 + (b0 < 10 ? 48 : 55));
|
||||
chars[i * 2 + 1] = (char) (b1 + (b1 < 10 ? 48 : 55));
|
||||
}
|
||||
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
public static String hex_t(long hash) {
|
||||
byte[] bytes = new byte[8];
|
||||
|
||||
bytes[7] = (byte) (hash );
|
||||
bytes[6] = (byte) (hash >>> 8);
|
||||
bytes[5] = (byte) (hash >>> 16);
|
||||
bytes[4] = (byte) (hash >>> 24);
|
||||
bytes[3] = (byte) (hash >>> 32);
|
||||
bytes[2] = (byte) (hash >>> 40);
|
||||
bytes[1] = (byte) (hash >>> 48);
|
||||
bytes[0] = (byte) (hash >>> 56);
|
||||
|
||||
char[] chars = new char[18];
|
||||
chars[0] = 'T';
|
||||
chars[1] = '_';
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
byte b = bytes[i];
|
||||
|
||||
int a = b & 0xFF;
|
||||
int b0 = a >> 4;
|
||||
int b1 = a & 0xf;
|
||||
|
||||
chars[i * 2 + 2] = (char) (b0 + (b0 < 10 ? 48 : 55));
|
||||
chars[i * 2 + 3] = (char) (b1 + (b1 < 10 ? 48 : 55));
|
||||
}
|
||||
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
public static long fnv_64(String input) {
|
||||
if (input == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long hash = 0x811c9dc5;
|
||||
for (int i = 0; i < input.length(); ++i) {
|
||||
char c = input.charAt(i);
|
||||
hash ^= c;
|
||||
hash *= 0x1000193;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static long fnv_64_lower(String input) {
|
||||
if (input == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long hash = 0x811c9dc5;
|
||||
for (int i = 0; i < input.length(); ++i) {
|
||||
char c = input.charAt(i);
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
c += 32;
|
||||
}
|
||||
hash ^= c;
|
||||
hash *= 0x1000193;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user