
com.hundsun.lightdb.unisql.golang.Transformer Maven / Gradle / Ivy
package com.hundsun.lightdb.unisql.golang;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.hundsun.lightdb.unisql.model.UnisqlProperties;
import jnr.ffi.Pointer;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
@Slf4j
public class Transformer {
public static final String PARSE_ERROR = "PARSE ERROR";
public static final String RESTORE_ERROR = "RESTORE ERROR";
private static final String ignoreTrans = "/*skipTransform*/";
private static final Cache sqlCache;
static {
final UnisqlProperties properties = UnisqlProperties.getInstance();
final long maxSize = properties.getCacheMaximumSize();
final long expireSeconds = properties.getCacheExpireSeconds();
final boolean debug = properties.isDebug();
sqlCache = Caffeine.newBuilder()
.maximumSize(maxSize)
.expireAfterWrite(expireSeconds, TimeUnit.SECONDS)
.removalListener((key, value, cause) -> {
if (debug) {
log.debug("[LTSQL][sqlCache] {} is removed from sqlCache, cause: {}", key, cause);
}
})
.build();
// 初始化 gogc 与 gomemlimit 参数
IGoParser parser = GoParserFactory.getGoParser();
// 如果程序配置了 GOGC ,则忽略参数配置
if (properties.isEnvironmentGOGCNotSet()) {
long gogc = properties.getGOGC();
try {
parser.SetGoGc(gogc);
} catch (Exception ignore) {
// 不强制要求一定成功,为兼容以前版本的 so
}
}
// 如果程序配置了 GOMEMLIMIT ,则忽略参数配置
if (properties.isEnvironmentGOMEMLIMITNotSet()) {
long gomemlimit = properties.getGOMEMLIMIT();
// gomenlimit 是以字节为单位的,我们约定我们的配置项以 MB 为单位,是为了避免配置过于不直观
try {
parser.SetGoMemLimit(gomemlimit * 1024 * 1024);
} catch (Exception ignore) {
// 不强制要求一定成功,为兼容以前版本的 so
}
}
}
public static String parse(String sql, String source, String target) {
if (sql.startsWith(ignoreTrans)) {
return sql.substring(ignoreTrans.length());
}
return parseUseCache(sql, source, target, true);
}
public static String parseUseCache(String sql, String source, String target, boolean useCache) {
IGoParser parser = GoParserFactory.getGoParser();
String cacheKey = "";
if (useCache) {
cacheKey = source + ":" + target + ":" + sql;
String cacheSql = sqlCache.getIfPresent(cacheKey);
if (cacheSql != null) {
return cacheSql;
}
}
Pointer p4 = parser.Transform(sql, source, target);
try {
String utf8 = p4.getString(0, Integer.MAX_VALUE, StandardCharsets.UTF_8);
if (useCache) {
sqlCache.put(cacheKey, utf8);
}
return utf8;
} finally {
parser.FreePointer(p4);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy