package com.hwtd.mes.collect.util;
import com.healthmarketscience.jackcess.Column;
import com.healthmarketscience.jackcess.Cursor;
import com.healthmarketscience.jackcess.CursorBuilder;
import com.healthmarketscience.jackcess.DataType;
import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.DatabaseBuilder;
import com.healthmarketscience.jackcess.Row;
import com.healthmarketscience.jackcess.Table;
import com.healthmarketscience.jackcess.crypt.CryptCodecProvider;
import com.healthmarketscience.jackcess.crypt.InvalidCredentialsException;
import com.healthmarketscience.jackcess.crypt.InvalidCryptoConfigurationException;
import com.hwtd.mes.collect.dto.DatabaseDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 用 jackcess 直读 .mdb/.accdb 表数据(只读),用于“只取某张表的几列”这种简单场景。
*
* 与 UCanAccess 的区别:UCanAccess 打开连接时要把整个库镜像进 HSQLDB(表多时极慢),
* 这里只打开文件、顺序扫描一张表、按需取列,完全不经过 SQL 引擎。
*
* 代价与限制:
*
* - 没有 SQL:按字段过滤、按字段排序都在 Java 侧完成,过滤必然是整表扫描——本库文本索引的排序规则是
* 中文 2052,jackcess 不支持(索引只读),索引游标会直接抛异常,所以没有可用的索引查询路径;
* - 结果全部装在内存里,未加过滤条件的超大表要留意内存占用;
* - 设置了打开密码的库会自动用 jackcess-encrypt 打开,密码取请求参数 {@code password}
* (Access 的文件加密只有“打开密码”,{@code userName} 不参与;.mdw 工作组级安全性 jackcess 不支持);
* - Access 中指向外部库的“链接表”行为与 UCanAccess 的 remap 参数不同,遇到问题可切回
* {@code mes.access.read-mode=ucanaccess}。
*
*/
@Slf4j
public final class JackcessTableReader {
private JackcessTableReader() {
}
public static List