using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading; using UnityEngine.Networking; using UnityEngine.XR; using XRTool.Util; namespace PublicTools.XMLDataBase { public enum DataType { /// /// xml的方式存储 /// Xml = 0, /// /// json文本的方式存储 /// Json = 1, /// /// sqlite /// SqlLite = 2, /// /// 文本的方式存储 /// Txt = 3, /// /// mysql读写 /// MySql = 4, /// /// 预留扩展 /// Other = 5 } /// /// 数据库的管理类 /// 注意同时只能操作一个数据库文件,当传入新的路径时,老的文件连接都将被关闭 /// public class XSql : Singleton { private Dictionary sqlList = new Dictionary(); /// /// 缓存表格处理对象 /// private Dictionary tableDic = new Dictionary(); private string sqlPath; /// /// 当前正在处理的数据库文件路径 /// public string SqlPath { get => sqlPath; set => sqlPath = value; } /// /// 打开数据库 /// 即创建文件夹,开启对应的文件的读取流 /// 同时仅能操作一个文件夹 /// /// 绝对路径 public bool Open(string sqlPath, bool isforceCreate = false) { if (!string.IsNullOrEmpty(sqlPath) && SqlPath == sqlPath) { return true; } try { if (isforceCreate && !Directory.Exists(sqlPath)) { Directory.CreateDirectory(sqlPath); } if (Directory.Exists(sqlPath)) { this.SqlPath = sqlPath; return true; } } catch (Exception ex) { UnityLog.LogException(ex); UnityLog.LogError(ex.ToString()); } return false; } /// /// 关闭数据库 /// 即关闭此文件夹的所有文件读取流 /// /// public void Close() { foreach (var item in tableDic) { item.Value.Close(); } tableDic.Clear(); } public TableInterface OpenTable(string tableName, DataType dataType, bool forceCreate = false) { string suffix = ".xml"; if (dataType == DataType.Xml) { suffix = ".xml"; } else if (dataType == DataType.Json) { suffix = ".json"; } return OpenTable(tableName, suffix, forceCreate); } /// /// 打开本地表格 /// 打开对应的文件流,文件流存在时可能为空 /// 操作表格的情况:不存在文件,存在但是字节流为空,字节流不为空 /// 字节流为空时如何处理? /// /// /// 强制创建,文件为空时创建我呢见 /// 文件后缀名 public TableInterface OpenTable(string tableName, string suffix = ".xml", bool forceCreate = false) { return OpenTable(SqlPath, tableName, suffix, forceCreate); } /// /// 打开本地表格 /// 打开对应的文件流,文件流存在时可能为空 /// 操作表格的情况:不存在文件,存在但是字节流为空,字节流不为空 /// 字节流为空时如何处理? /// 注意安卓下StreamPath下无法使用File类读取!会报告异常 /// /// /// 强制创建,文件为空时创建我呢见 /// 文件后缀名 public TableInterface OpenTable(string sqlPath, string tableName, string suffix = ".xml", bool forceCreate = false) { if (!Open(sqlPath, forceCreate)) { return null; } string unExtenName = Path.GetFileNameWithoutExtension(tableName); if (tableDic.ContainsKey(unExtenName)) { return tableDic[unExtenName]; } ///文件后缀,如果table已有后缀不添加后缀,若无后缀名,则添加指定的后缀名 if (string.IsNullOrEmpty(Path.GetExtension(tableName))) { tableName += suffix; } string path = Path.Combine(sqlPath, tableName); try { bool isCreateNewTable = false; ///目标文件不存在,强制创建 if (forceCreate && !File.Exists(path)) { File.Create(path).Dispose(); isCreateNewTable = true; } ///文件存在,创建对应的对象 if (File.Exists(path)) { TableInterface fs = new XTable(path); tableDic.Add(unExtenName, fs); if (isCreateNewTable) { fs.Create(tableName); fs.Save(); } return fs; } } catch (Exception ex) { ///IO异常处理 UnityEngine.Debug.LogException(ex); UnityLog.LogError(ex.ToString()); } return null; } /// /// 关闭本地表操作 /// /// public void CloseTable(string tableName) { string unExtenName = Path.GetFileNameWithoutExtension(tableName); if (tableDic.ContainsKey(unExtenName)) { tableDic[unExtenName].Close(); tableDic.Remove(unExtenName); } } /// /// 新建一个表格 /// /// public bool CreateTable(string tableName, DataType dataType) { string suffix = ".xml"; if (dataType == DataType.Xml) { suffix = ".xml"; } else if (dataType == DataType.Json) { suffix = ".json"; } return CreateTable(tableName, suffix); } /// /// 新建一个表格 /// /// public bool CreateTable(string tableName, string suffix = ".xml") { if (string.IsNullOrEmpty(Path.GetExtension(tableName))) { tableName += suffix; } TableInterface table = new XTable(); return table.Create(tableName); } /// /// 读取远程的表格数据信息 /// 或者在只读文件夹下读取数据 /// /// /// 数据 /// 数据类型,可能是.xml或者json文本0代表xml文本 /// public List ReadServerData(byte[] data, int type = 0) { TableInterface table = new XTable(type); List list = table.FindAllData(data); table.Close(); table = null; return list; } /// /// 读取远程的表格数据信息 /// 或者在只读文件夹下读取数据 /// /// /// 数据 /// 数据类型,可能是.xml或者json文本0代表xml文本 /// public List ReadServerData(string data, int type = 0) { TableInterface table = new XTable(type); List list = table.FindAllData(data); table.Close(); table = null; return list; } public IEnumerator ReadServerData(string url, Action> action, int type = 0) { yield return UnityUtil.RequestDownData(url, (string error, UnityWebRequest handler) => { if (!string.IsNullOrEmpty(error)) { UnityLog.LogError(url + "Read Data Error" + error); action?.Invoke(null); } else { action?.Invoke(ReadServerData(handler.downloadHandler.data, type)); } }); } } }