com.hundsun.lightdb.unisql.golang.GoParserFactory Maven / Gradle / Ivy
package com.hundsun.lightdb.unisql.golang;
import com.hundsun.lightdb.unisql.model.SshResponse;
import com.hundsun.lightdb.unisql.model.UnisqlProperties;
import com.hundsun.lightdb.unisql.utils.ExecuteUtils;
import jnr.ffi.LibraryLoader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static com.hundsun.lightdb.unisql.constant.SystemConst.CODE_LINUX;
import static com.hundsun.lightdb.unisql.constant.SystemConst.CODE_MAC;
import static com.hundsun.lightdb.unisql.constant.SystemConst.CODE_OS;
import static com.hundsun.lightdb.unisql.constant.SystemConst.CODE_OS_NAME;
import static com.hundsun.lightdb.unisql.constant.SystemConst.CODE_WINDOWS;
import static com.hundsun.lightdb.unisql.constant.SystemConst.DYNAMIC_LIBRARY_SUFFIX_DLL;
import static com.hundsun.lightdb.unisql.constant.SystemConst.DYNAMIC_LIBRARY_SUFFIX_DYLIB;
import static com.hundsun.lightdb.unisql.constant.SystemConst.DYNAMIC_LIBRARY_SUFFIX_SO;
import static com.hundsun.lightdb.unisql.constant.SystemConst.GLOBAL_MARK_DOT;
public class GoParserFactory {
/** 库文件名前缀 */
private static final String LIB_NAME_PREFIX = "unisql.";
/** 单例 */
private static final IGoParser INSTANCE;
static {
final UnisqlProperties properties = UnisqlProperties.getInstance();
// 操作系统名称
String OS = System.getProperty(CODE_OS_NAME).toLowerCase();
// 根据操作系统 + unisql.lib.dir 寻找对应的库
final String suffix;
if (OS.contains(CODE_MAC) && OS.contains(CODE_OS)) {
String arch = getArch();
suffix = CODE_MAC + GLOBAL_MARK_DOT + arch + GLOBAL_MARK_DOT + DYNAMIC_LIBRARY_SUFFIX_DYLIB;
} else if (OS.contains(CODE_WINDOWS)) {
suffix = CODE_WINDOWS + GLOBAL_MARK_DOT + DYNAMIC_LIBRARY_SUFFIX_DLL;
} else {
String arch = getArch();
suffix = CODE_LINUX + GLOBAL_MARK_DOT + arch + GLOBAL_MARK_DOT + DYNAMIC_LIBRARY_SUFFIX_SO;
}
String fileName = LIB_NAME_PREFIX + suffix;
final String libPath;
// 允许用户直接指定动态库
String fullPath = properties.getLibFullPath();
if (fullPath != null && !fullPath.isEmpty()) {
// 若配置了完整路径,则直接使用,不再使用其他方式寻找
libPath = fullPath;
} else {
// 首先尝试读取 jar 包中的动态库,如 unisql.linux.x86_64.so
final InputStream in = GoParserFactory.class.getClassLoader().getResourceAsStream(fileName);
if (in != null) {
// final long start = System.nanoTime();
// write to temp file
final Path tmpFile;
try {
final int bufferSize = 8192;
final byte[] buffer = new byte[bufferSize];
final Path tmpDir = Files.createTempDirectory("unisql_lib");
tmpDir.toFile().deleteOnExit();
tmpFile = tmpDir.resolve(fileName);
try (final OutputStream out = Files.newOutputStream(tmpFile)) {
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
} finally {
try {
in.close();
} catch (Exception ignore) {
}
}
tmpFile.toFile().deleteOnExit();
} catch (IOException e) {
throw new RuntimeException(e);
}
// System.out.println("Total Cost: " + (System.nanoTime() - start) + "ns");
libPath = tmpFile.toAbsolutePath().toString();
} else {
// 不存在 jar 包中的动态库时,尝试用路径去获取
String configDir = properties.getLibDir();
String tempDir = System.getProperty("java.io.tmpdir");
Path path = Paths.get(configDir, fileName);
if (Files.notExists(path)) {
path = Paths.get(tempDir, fileName);
if (Files.notExists(path)) {
throw new IllegalStateException("parser lib not found [ " + fileName + " ], you can use " +
"system " +
"environment variable [unisql.lib.dir] or java environment variable [java.io.tmpdir] " +
"to " +
"set the search path, current path is [ " + path.toAbsolutePath() + " ]");
}
}
libPath = path.toAbsolutePath().toString();
}
}
INSTANCE = LibraryLoader.create(IGoParser.class).load(libPath);
}
/**
* 获取 架构
*
* @return 如 x86_64, aarch64
*/
private static String getArch() {
// 目前将非 mac 与 windows 的一律视为 Linux 处理 linux.${arch}
final SshResponse uname = ExecuteUtils.execResult("uname -m");
if (uname.getStatus() != ExecuteUtils.STATUS_SUCCESS) {
throw new RuntimeException("Cannot detect OS Type");
}
return uname.getOut();
}
public static IGoParser getGoParser() {
return INSTANCE;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy