package minsecurity.identity.persist.sqlite; import org.sqlite.mc.SQLiteMCSqlCipherConfig; import java.io.File; import java.sql.*; /* * @Author: zhengqi wu * @Description: Sqlite封装 * @Version: 1.0.0 * @Date: 22:34 2021/04/01 * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 */ // 存在配置信息,使用单例模式封装工具类 public class Sqlite { private static final Sqlite Instance = new Sqlite(); // sqlite 唯一object private String passwd = "2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99"; // 初始数据库密码 private String db_file = "identity.db"; // 数据库文件名 private String db_path = ""; private String table_create = "CREATE TABLE IF NOT EXISTS \"identityinfo\" (\n" + "\t\"name\"\tvarchar(255) NOT NULL,\n" + "\t\"pubkey\"\tvarchar(255),\n" + "\t\"prikey\"\tvarchar(255),\n" + "\t\"pubkey_algo\"\tint,\n" + "\t\"signature_algo\"int,\n" + "\t\"pass\"\tvarchar(255),\n" + "\t\"cert\"\tTEXT,\n" + "\t\"is_default\"\tint DEFAULT 0,\n" + "\t\"prikey_raw_byte\" varchar(255),\n" + "\tPRIMARY KEY(\"name\")\n" + ");"; private Sqlite(){ } /** * 将密码转换为16进制表示 * @return 16进制字符串 String */ private String passwd2HexKey(){ return String.format("x'%s'", passwd); } /** * 获取Sqlite 实例 * @return Sqlite object */ public static Sqlite getInstance() { return Instance; } /** * 设置数据库的连接密码 * @param pass 新密码 * @throws Exception */ public void setPasswd(String pass) throws Exception { if (pass.length() != 64){ throw new Exception("Invalid Length"); } passwd = pass; } /** * 进行数据库文件的连接测试,如果表不存在则新建 * 数据库文件默认写入地址为~/.min/identity/identity.db * @throws Exception */ public void openDefault() throws Exception { Connection c = null; Statement stmt = null; try{ String homePath = SqliteUtil.home(); homePath += "/min/identity/"; db_path = homePath; if (!SqliteUtil.pathExists(db_path)){ new File(db_path).mkdirs(); } String real_db_file = db_path + db_file; // 兼容sqlcipher c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file, SQLiteMCSqlCipherConfig.getV4Defaults().withKey(passwd2HexKey()).toProperties()); stmt = c.createStatement(); int res = stmt.executeUpdate(table_create); System.out.println(res); stmt.close(); c.close(); }catch (Exception ex){ if (c != null) c.close(); throw ex; } } //自定义文件地址,注意要用/结尾,比如:/min/identity/ /** * 打开用户指定路径的数据库文件 * @param filePath String * @throws Exception */ public void open(String filePath) throws Exception { Connection c = null; Statement stmt = null; try{ if (filePath == null || filePath.length() == 0){ throw new Exception("invalid db path!"); } db_path = filePath; boolean db_exists = SqliteUtil.pathExists(db_path); if (!db_exists){ new File(db_path).mkdirs(); } String real_db_file = db_path + db_file; // 兼容sqlcipher c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file, SQLiteMCSqlCipherConfig.getV4Defaults().withKey(passwd2HexKey()).toProperties()); stmt = c.createStatement(); stmt.executeUpdate(table_create); stmt.close(); c.close(); }catch (Exception ex){ // DONE 出错时关闭数据库 if (c != null) c.close(); throw ex; } } /** * 从打开的数据库获取连接 * @return Connection * @throws Exception */ public Connection getConn() throws Exception { Connection c = null; try{ String real_db_file = db_path + db_file; // Class.forName("org.sqlite.JDBC"); // 兼容sqlcipher c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file, SQLiteMCSqlCipherConfig.getV4Defaults().withKey(passwd2HexKey()).toProperties()); // TODO 设置数据库最大连接数 return c; }catch (Exception ex){ throw ex; } } }