Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
4bc04b9
生态新增 apijson-builder: 简单包装 APIJSON,相比直接构造查询 JSON 更好记,感谢 @yeli19950109…
TommyLemon Dec 6, 2023
886099f
SQLConfig 内把所有 AbstractSQLConfig 改成 SQLConfig;优化 Verifier 的注释
TommyLemon Dec 10, 2023
c4bae41
Merge branch 'master' of https://github.com/Tencent/APIJSON
TommyLemon Dec 10, 2023
b57ece8
升级版本至 6.3.0
TommyLemon Dec 11, 2023
f1bbdf1
贡献者说明:腾讯工程师,曾在华为、恒生担任C/C++开发工程师,在wps担任项目经理,在360担任技术专家
TommyLemon Dec 19, 2023
f3dc785
新增支持 NoSQL 数据库 MongoDB,版本升到 6.4.0
TommyLemon Jan 3, 2024
55064ee
新增支持 AI 向量数据库 Milvus
TommyLemon Jan 4, 2024
1636349
默认开启支持 Snowflake, Databricks, Cassandra 等数据库
TommyLemon Jan 7, 2024
d3db569
文档:新增 Milvus, MongoDB, InfluxDB 等数据库支持说明
TommyLemon Jan 7, 2024
6e95be6
SELECT column 内原始 SQL 片段支持 AS 别名 @raw:"@column", "@column":"(CASE WHE…
TommyLemon Jan 10, 2024
7c9ca1b
Operation 操作方式新增 IS_ID_CONDITION_MUST,是否强制要求必须有 id/id{}/id{}@ 条件
TommyLemon Jan 13, 2024
5b9b34c
解决某些情况下 @raw 对 @having:value 中 value 中的外层表达式不生效
TommyLemon Jan 13, 2024
7547cd2
登记上海翊丞互联网科技有限公司,感谢 @li-chaopeng-01 的 Gitee PR#7
TommyLemon Jan 18, 2024
fec206c
Merge branch 'springboot3' into master
TommyLemon Jan 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion APIJSONORM/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>com.github.Tencent</groupId>
<artifactId>APIJSON-spring-boot3</artifactId>
<version>6.2.0</version>
<version>6.4.0</version>
<packaging>jar</packaging>

<name>APIJSONORM</name>
Expand Down
2 changes: 1 addition & 1 deletion APIJSONORM/src/main/java/apijson/Log.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class Log {

public static boolean DEBUG = true;

public static final String VERSION = "6.2.1";
public static final String VERSION = "6.4.0";
public static final String KEY_SYSTEM_INFO_DIVIDER = "\n---|-----APIJSON SYSTEM INFO-----|---\n";

public static final String OS_NAME;
Expand Down
16 changes: 16 additions & 0 deletions APIJSONORM/src/main/java/apijson/RequestMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ public static boolean isHeadMethod(RequestMethod method, boolean containPrivate)
public static boolean isQueryMethod(RequestMethod method) {
return isGetMethod(method, true) || isHeadMethod(method, true);
}

/**是否为更新(增删改)的请求方法
* @param method
* @return 读操作(GET型或HEAD型) - false, 写操作(POST,PUT,DELETE) - true
*/
public static boolean isUpdateMethod(RequestMethod method) {
return ! isQueryMethod(method);
}

/**是否为开放(不限制请求的结构或内容;明文,浏览器能直接访问及查看)的请求方法
* @param method
Expand All @@ -92,6 +100,14 @@ public static boolean isPublicMethod(RequestMethod method) {
return method == null || method == GET || method == HEAD;
}

/**是否为私有(限制请求的结构或内容)的请求方法
* @param method
* @return
*/
public static boolean isPrivateMethod(RequestMethod method) {
return ! isPublicMethod(method);
}

public static String getName(RequestMethod method) {
return method == null ? GET.name() : method.name();
}
Expand Down
86 changes: 70 additions & 16 deletions APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public abstract class AbstractSQLConfig<T extends Object> implements SQLConfig<T
// TODO 改成更好的正则,校验前面为单词,中间为操作符,后面为值
PATTERN_FUNCTION = Pattern.compile("^[A-Za-z0-9%,:_@&~`!=\\<\\>\\|\\[\\]\\{\\} /\\.\\+\\-\\*\\^\\?\\(\\)\\$]+$");

TABLE_KEY_MAP = new HashMap<String, String>();
TABLE_KEY_MAP = new HashMap<>();
TABLE_KEY_MAP.put(Table.class.getSimpleName(), Table.TABLE_NAME);
TABLE_KEY_MAP.put(Column.class.getSimpleName(), Column.TABLE_NAME);
TABLE_KEY_MAP.put(PgClass.class.getSimpleName(), PgClass.TABLE_NAME);
Expand Down Expand Up @@ -195,9 +195,15 @@ public abstract class AbstractSQLConfig<T extends Object> implements SQLConfig<T
DATABASE_LIST.add(DATABASE_HIVE);
DATABASE_LIST.add(DATABASE_PRESTO);
DATABASE_LIST.add(DATABASE_TRINO);
DATABASE_LIST.add(DATABASE_MILVUS);
DATABASE_LIST.add(DATABASE_INFLUXDB);
DATABASE_LIST.add(DATABASE_TDENGINE);
DATABASE_LIST.add(DATABASE_SNOWFLAKE);
DATABASE_LIST.add(DATABASE_DATABRICKS);
DATABASE_LIST.add(DATABASE_REDIS);
DATABASE_LIST.add(DATABASE_MONGODB);
DATABASE_LIST.add(DATABASE_CASSANDRA);
DATABASE_LIST.add(DATABASE_KAFKA);
DATABASE_LIST.add(DATABASE_MQ);

RAW_MAP = new LinkedHashMap<>(); // 保证顺序,避免配置冲突等意外情况
Expand Down Expand Up @@ -1189,6 +1195,14 @@ public static boolean isPresto(String db) {
return DATABASE_PRESTO.equals(db);
}

@Override
public boolean isTrino() {
return isTrino(getSQLDatabase());
}
public static boolean isTrino(String db) {
return DATABASE_TRINO.equals(db);
}

@Override
public boolean isSnowflake() {
return isSnowflake(getSQLDatabase());
Expand All @@ -1214,11 +1228,11 @@ public static boolean isCassandra(String db) {
}

@Override
public boolean isTrino() {
return isTrino(getSQLDatabase());
public boolean isMilvus() {
return isMilvus(getSQLDatabase());
}
public static boolean isTrino(String db) {
return DATABASE_TRINO.equals(db);
public static boolean isMilvus(String db) {
return DATABASE_MILVUS.equals(db);
}

@Override
Expand All @@ -1245,20 +1259,36 @@ public static boolean isRedis(String db) {
return DATABASE_REDIS.equals(db);
}

@Override
public boolean isMongoDB() {
return isMongoDB(getSQLDatabase());
}
public static boolean isMongoDB(String db) {
return DATABASE_MONGODB.equals(db);
}

@Override
public boolean isKafka() {
return isKafka(getSQLDatabase());
}
public static boolean isKafka(String db) {
return DATABASE_KAFKA.equals(db);
}

@Override
public boolean isMQ() {
return isMQ(getSQLDatabase());
}
public static boolean isMQ(String db) {
return DATABASE_MQ.equals(db);
return DATABASE_MQ.equals(db) || isKafka(db);
}

@Override
public String getQuote() {
if(isElasticsearch()) {
return "";
}
return isMySQL() || isMariaDB() || isTiDB() || isClickHouse() || isTDengine() ? "`" : "\"";
return isMySQL() || isMariaDB() || isTiDB() || isClickHouse() || isTDengine() || isMilvus() ? "`" : "\"";
}

public String quote(String s) {
Expand All @@ -1272,6 +1302,7 @@ public String getSchema() {
}

@NotNull
@Override
public String getSQLSchema() {
String table = getTable();
//强制,避免因为全局默认的 @schema 自动填充进来,导致这几个类的 schema 为 sys 等其它值
Expand Down Expand Up @@ -1953,14 +1984,14 @@ public String getColumnString(boolean inSQLJoin) throws Exception {
}

// 简单点, 后台配置就带上 AS
// int index = expression.lastIndexOf(":");
// String alias = expression.substring(index+1);
// boolean hasAlias = StringUtil.isName(alias);
// String pre = index > 0 && hasAlias ? expression.substring(0, index) : expression;
// if (RAW_MAP.containsValue(pre) || "".equals(RAW_MAP.get(pre))) { // newSQLConfig 提前处理好的
// expression = pre + (hasAlias ? " AS " + alias : "");
// continue;
// }
int index = expression.lastIndexOf(":");
String alias = expression.substring(index+1);
boolean hasAlias = StringUtil.isName(alias);
String pre = index > 0 && hasAlias ? expression.substring(0, index) : expression;
if (RAW_MAP.containsValue(pre) || "".equals(RAW_MAP.get(pre))) { // newSQLConfig 提前处理好的
keys[i] = pre + (hasAlias ? " AS " + alias : "");
continue;
}
}

if (expression.length() > 100) {
Expand Down Expand Up @@ -2001,6 +2032,16 @@ public String parseSQLExpression(String key, String expression, boolean containR
* @return
*/
public String parseSQLExpression(String key, String expression, boolean containRaw, boolean allowAlias, String example) {
if (containRaw) {
String s = RAW_MAP.get(expression);
if ("".equals(s)) {
return expression;
}
if (s != null) {
return s;
}
}

String quote = getQuote();
int start = expression.indexOf('(');
if (start < 0) {
Expand Down Expand Up @@ -2578,9 +2619,22 @@ public static int getOffset(int page, int count) {
*/
@JSONField(serialize = false)
public String getLimitString() {
if (count <= 0 || RequestMethod.isHeadMethod(getMethod(), true)) {
int count = getCount();

if (isMilvus()) {
if (count == 0) {
Parser<T> parser = getParser();
count = parser == null ? AbstractParser.MAX_QUERY_COUNT : parser.getMaxQueryCount();
}

int offset = getOffset(getPage(), count);
return " LIMIT " + offset + ", " + count; // 目前 moql-transx 的限制
}

if (count <= 0 || RequestMethod.isHeadMethod(getMethod(), true)) { // TODO HEAD 真的不需要 LIMIT ?
return "";
}

return getLimitString(
getPage()
, getCount()
Expand Down
11 changes: 6 additions & 5 deletions APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
public abstract class AbstractVerifier<T extends Object> implements Verifier<T>, IdCallback<T> {
private static final String TAG = "AbstractVerifier";

/**为 PUT, DELETE 强制要求必须有 id/id{} 条件
/**为 PUT, DELETE 强制要求必须有 id/id{}/id{}@ 条件
*/
public static boolean IS_UPDATE_MUST_HAVE_ID_CONDITION = true;
/**开启校验请求角色权限
Expand Down Expand Up @@ -700,8 +700,9 @@ public JSONObject onParseJSONObject(String key, JSONObject tobj, JSONObject robj
throw new IllegalArgumentException(method + "请求," + name + "/" + key + " 不能传 " + finalIdKey + " !");
}
} else {
if (RequestMethod.isQueryMethod(method) == false) {
verifyId(method.name(), name, key, robj, finalIdKey, maxUpdateCount, IS_UPDATE_MUST_HAVE_ID_CONDITION);
Boolean atLeastOne = tobj == null ? null : tobj.getBoolean(Operation.IS_ID_CONDITION_MUST.name());
if (Boolean.TRUE.equals(atLeastOne) || RequestMethod.isUpdateMethod(method)) {
verifyId(method.name(), name, key, robj, finalIdKey, maxUpdateCount, atLeastOne != null ? atLeastOne : IS_UPDATE_MUST_HAVE_ID_CONDITION);

String userIdKey = idCallback == null ? null : idCallback.getUserIdKey(db, sh, ds, key);
String finalUserIdKey = StringUtil.isEmpty(userIdKey, false) ? apijson.JSONObject.KEY_USER_ID : userIdKey;
Expand Down Expand Up @@ -746,7 +747,7 @@ private static void verifyId(@NotNull String method, @NotNull String name, @NotN
Object id = robj.get(idKey); //如果必须传 id ,可在Request表中配置NECESSARY
if (id != null && id instanceof Number == false && id instanceof String == false) {
throw new IllegalArgumentException(method + "请求," + name + "/" + key
+ " 里面的 " + idKey + ":value 中value的类型只能是 Long 或 String !");
+ " 里面的 " + idKey + ":value 中value的类型只能是 Long 或 String !");
}


Expand Down Expand Up @@ -795,7 +796,7 @@ else if (o instanceof String) {
}
else {
throw new IllegalArgumentException(method + "请求," + name + "/" + key
+ " 里面的 " + idInKey + ":[] 中所有项的类型都只能是 Long 或 String !");
+ " 里面的 " + idInKey + ":[] 中所有项的类型都只能是 Long 或 String !");
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions APIJSONORM/src/main/java/apijson/orm/Operation.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,13 @@ public enum Operation {
/**
* 允许批量增删改部分失败,结构是
* "Table[],key[],key:alias[]"
* 自动 ALLOW_PARTIAL_UPDATE_FAILED_TABLE_MAP.put
* 自动 ALLOW_PARTIAL_UPDATE_FAILED_TABLE_MAP.put,结构是 Boolean,例如 true
*/
ALLOW_PARTIAL_UPDATE_FAIL;
ALLOW_PARTIAL_UPDATE_FAIL,

/**
* 强制要求必须有 id/id{}/id{}@ 条件,结构是 Boolean,例如 true
*/
IS_ID_CONDITION_MUST;

}
25 changes: 16 additions & 9 deletions APIJSONORM/src/main/java/apijson/orm/SQLConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ public interface SQLConfig<T extends Object> {
String DATABASE_SNOWFLAKE = "SNOWFLAKE"; // https://www.snowflake.com
String DATABASE_DATABRICKS = "DATABRICKS"; // https://www.databricks.com
String DATABASE_CASSANDRA = "CASSANDRA"; // https://cassandra.apache.org
String DATABASE_MILVUS = "MILVUS"; // https://milvus.io
String DATABASE_INFLUXDB = "INFLUXDB"; // https://www.influxdata.com/products/influxdb-overview
String DATABASE_TDENGINE = "TDENGINE"; // https://tdengine.com
String DATABASE_REDIS = "REDIS";
String DATABASE_MQ = "MQ";
String DATABASE_REDIS = "REDIS"; // https://redisql.com
String DATABASE_MONGODB = "MONGODB"; // https://www.mongodb.com/docs/atlas/data-federation/query/query-with-sql
String DATABASE_KAFKA = "KAFKA"; // https://github.com/APIJSON/APIJSON-Demo/tree/master/APIJSON-Java-Server/APIJSONDemo-MultiDataSource-Kafka
String DATABASE_MQ = "MQ"; //

String SCHEMA_INFORMATION = "information_schema"; //MySQL, PostgreSQL, SQL Server 都有的系统模式
String SCHEMA_SYS = "sys"; //SQL Server 系统模式
Expand All @@ -50,19 +53,19 @@ public interface SQLConfig<T extends Object> {

Parser<T> getParser();

AbstractSQLConfig setParser(Parser<T> parser);
SQLConfig setParser(Parser<T> parser);

ObjectParser getObjectParser();

AbstractSQLConfig setObjectParser(ObjectParser objectParser);
SQLConfig setObjectParser(ObjectParser objectParser);

int getVersion();

AbstractSQLConfig setVersion(int version);
SQLConfig setVersion(int version);

String getTag();

AbstractSQLConfig setTag(String tag);
SQLConfig setTag(String tag);

boolean isMySQL();
boolean isPostgreSQL();
Expand All @@ -77,17 +80,20 @@ public interface SQLConfig<T extends Object> {
boolean isClickHouse();
boolean isHive();
boolean isPresto();
boolean isTrino();
boolean isSnowflake();
boolean isDatabricks();
boolean isCassandra();
boolean isTrino();
boolean isMilvus();
boolean isInfluxDB();
boolean isTDengine();
boolean isRedis();
boolean isMongoDB();
boolean isKafka();
boolean isMQ();


//暂时只兼容以上几种
// 暂时只兼容以上几种
// boolean isSQL();
// boolean isTSQL();
// boolean isPLSQL();
Expand Down Expand Up @@ -215,6 +221,7 @@ default int[] getDBVersionNums() {
String getDatabase();
SQLConfig setDatabase(String database);

String getSQLSchema();
String getSchema();
SQLConfig setSchema(String schema);

Expand Down Expand Up @@ -243,7 +250,7 @@ default int[] getDBVersionNums() {
String getTablePath();

Map<String, String> getKeyMap();
AbstractSQLConfig setKeyMap(Map<String, String> keyMap);
SQLConfig setKeyMap(Map<String, String> keyMap);

List<String> getRaw();
SQLConfig setRaw(List<String> raw);
Expand Down
Loading