All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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