////////////////////////////////////////////////////////////////////////// // // 文件:Assets/Editor/Tools/DBTools.cs // 作者:Xoen Xie // 时间:2023/06/19 // 描述:db code tools // 说明: // ////////////////////////////////////////////////////////////////////////// using UnityEditor; using UnityEngine; using System.IO; using System.Xml; using System.Text; public static class DBTools { private static string SERVER_DIR = Application.dataPath + $"/../../../NLDServer"; private static string DB_DEF_PATH = SERVER_DIR + "/common/db/db_def.go"; [MenuItem("Tools/*配置工具/生成数据库代码", false, (int)NLDMenuID.DBCodeExport)] public static void DBCodeExport() { ExportRedisCode(); ExportMongoCode(); } private static void ExportRedisCode() { string redisConfig = SERVER_DIR + "/bin/scp/DBRedis.xml"; if (!File.Exists(redisConfig)) { Debug.LogError($"{redisConfig} 不存在"); return; } XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreComments = true; string sContent = File.ReadAllText(redisConfig); XmlReader reader = XmlReader.Create(new MemoryStream(Encoding.UTF8.GetBytes(sContent)), settings); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(reader); XmlNode RootNode = xmlDoc.SelectSingleNode("root"); XmlNodeList nodes = RootNode.ChildNodes; string Ids = ""; string funcs = ""; //string structs = ""; for (int i = 0; i < nodes.Count; ++i) { XmlElement ele = nodes[i] as XmlElement; int id = EditorUtil.GetInt(ele, "id"); string sName = EditorUtil.GetString(ele, "name"); string sDesc = EditorUtil.GetString(ele, "desc"); string sOp = EditorUtil.GetString(ele, "op"); string sKey = EditorUtil.GetString(ele, "key"); string sFmtKey = EditorUtil.GetString(ele, "fmt_key"); string currentID = $"REDIS_{sName.ToUpper()}"; Ids += $"\t{currentID}\t\t\t= {id}\t// {sDesc}\n"; string[] names = sName.Split("_"); string funcDesc = $"// {sDesc}\n"; string funcName = "RD_"; for (int J = 0; J < names.Length; ++J) { funcName += EditorUtil.FirstLetterToUpper(names[J].ToLower()); } string fullFunc = funcDesc + "func " + funcName + "(keyID uint32, keyStr string, rpc *xsf_rpc.Acceptor"; string funcContent = $"\tcfg := xsf_scp.XSFSchema().DBRedis.Get({currentID})\n"; funcContent += "\tif cfg == nil {\n"; funcContent += $"\t\txsf_log.Error(\"{funcName} cfg == nil {currentID}\")\n"; funcContent += "\t\treturn\n"; funcContent += "\t}\n\n"; funcContent += "\txsf_redis.Request(keyID, keyStr, cfg, rpc"; XmlNodeList param = ele.ChildNodes; if (param.Count > 0) { XmlElement xmlParam = param[0] as XmlElement; string sParamName = EditorUtil.GetString(xmlParam, "name"); string sType = EditorUtil.GetString(xmlParam, "type"); if (sOp.Contains("SET")) { fullFunc += $", {sParamName} {sType}" + ") {\n"; funcContent += $", {sParamName})\n"; } else if (sOp.Contains("GET")) { fullFunc += ") {\n"; funcContent += $")\n"; } } else { fullFunc += ") {\n"; funcContent += $")\n"; } funcs += fullFunc + funcContent + "}\n\n"; } string codePath = SERVER_DIR + "/common/db/redis_func.go"; EditorUtil.ReplaceContentByTag(DB_DEF_PATH, "REDIS_REQUEST_ID_BEGIN", "REDIS_REQUEST_ID_END", Ids); EditorUtil.ReplaceContentByTag(codePath, "REQUEST_FUNC_BEGEIN", "REQUEST_FUNC_END", funcs); } private static void ExportMongoCode() { string redisConfig = SERVER_DIR + "/bin/scp/DBMongo.xml"; if (!File.Exists(redisConfig)) { Debug.LogError($"{redisConfig} 不存在"); return; } XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreComments = true; string sContent = File.ReadAllText(redisConfig); XmlReader reader = XmlReader.Create(new MemoryStream(Encoding.UTF8.GetBytes(sContent)), settings); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(reader); XmlNode RootNode = xmlDoc.SelectSingleNode("root"); XmlNodeList nodes = RootNode.ChildNodes; string Ids = ""; string funcs = ""; //string structs = ""; for (int db = 0; db < nodes.Count; db++) { XmlElement eleDB= nodes[db] as XmlElement; XmlNodeList cols = eleDB.ChildNodes; for (int col = 0; col < cols.Count; col++) { XmlElement eleCol = cols[col] as XmlElement; bool isSplit = false; if(EditorUtil.GetInt(eleCol, "split") > 0) { isSplit = true; } XmlNodeList reqs = eleCol.ChildNodes; for (int r = 0; r < reqs.Count; r++) { XmlElement ele = reqs[r] as XmlElement; Debug.Log("name=" + ele.Name); int id = EditorUtil.GetInt(ele, "id"); string sName = EditorUtil.GetString(ele, "name"); string sDesc = EditorUtil.GetString(ele, "desc"); string sOp = EditorUtil.GetString(ele, "op"); bool dataNotFormat = EditorUtil.GetBoolean(ele, "data_not_format"); string currentID = $"MONGO_{sName.ToUpper()}"; Ids += $"\t{currentID}\t\t\t= {id}\t// {sDesc}\n"; string[] names = sName.Split("_"); string funcDesc = $"// {sDesc}\n"; string funcName = "MG_"; for (int J = 0; J < names.Length; ++J) { funcName += EditorUtil.FirstLetterToUpper(names[J].ToLower()); } string fullFunc; if(isSplit) { fullFunc = funcDesc + "func " + funcName + "(keyID uint32, colID uint32, rpc *xsf_rpc.Acceptor"; } else { fullFunc = funcDesc + "func " + funcName + "(keyID uint32, rpc *xsf_rpc.Acceptor"; } string funcContent = $"\tcfg := xsf_scp.XSFSchema().DBMongo.Get({currentID})\n"; funcContent += "\tif cfg == nil {\n"; funcContent += $"\t\txsf_log.Error(\"{funcName} cfg == nil {currentID}\")\n"; funcContent += "\t\treturn\n"; funcContent += "\t}\n\n"; switch (sOp) { case "Insert": { XmlNodeList datas = ele.SelectNodes("data"); string dataM = ""; for (int z = 0; z < datas.Count; z++) { XmlElement eleData = datas[z] as XmlElement; string name = EditorUtil.GetString(eleData, "name"); string type = EditorUtil.GetString(eleData, "type"); fullFunc += $", D_{name} {type}"; dataM += $"\t\t\"{name}\": D_{name},\n"; } fullFunc += ") {\n"; funcContent += "\tdata := bson.M{\n"; funcContent += dataM; funcContent += "\t}\n\n"; funcContent += "\txsf_mongo.Insert(keyID, cfg, rpc, data)\n"; } break; case "FindAll": case "FindOneSort": case "FindOne": { switch(sOp) { case "FindAll": fullFunc += ", page uint32"; break; default: break; } XmlNodeList datas = ele.SelectNodes("filter"); string dataF = ""; for (int z = 0; z < datas.Count; z++) { XmlElement eleData = datas[z] as XmlElement; string name = EditorUtil.GetString(eleData, "name"); string type = EditorUtil.GetString(eleData, "type"); fullFunc += $", F_{name} {type}"; dataF += $"\t\t\"{name}\": F_{name},\n"; } fullFunc += ") {\n"; funcContent += "\tfilter := bson.M{\n"; funcContent += dataF; funcContent += "\t}\n\n"; XmlNodeList Pdatas = ele.SelectNodes("projection"); string dataP = ""; for (int z = 0; z < Pdatas.Count; z++) { XmlElement eleData = Pdatas[z] as XmlElement; string name = EditorUtil.GetString(eleData, "name"); string v = EditorUtil.GetString(eleData, "value"); dataP += $"\t\t\"{name}\": {v},\n"; } funcContent += "\tprojection := bson.M{\n"; funcContent += dataP; funcContent += "\t}\n\n"; switch(sOp) { case "FindAll": if(isSplit) { funcContent += "\txsf_mongo.FindAllByColID(keyID, colID, cfg, rpc, page, filter, projection)\n"; } else { funcContent += "\txsf_mongo.FindAll(keyID, cfg, rpc, page, filter, projection)\n"; } break; case "FindOneSort": funcContent += "\txsf_mongo.FindOneSort(keyID, cfg, rpc, filter, projection)\n"; break; case "FindOne": funcContent += $"\txsf_mongo.FindOne(keyID, cfg, rpc, filter, projection)\n"; break; default: break; } } break; case "UpdateOne": case "DeleteOne": { { XmlNodeList datas = ele.SelectNodes("filter"); string dataF = ""; for (int z = 0; z < datas.Count; z++) { XmlElement eleData = datas[z] as XmlElement; string name = EditorUtil.GetString(eleData, "name"); string type = EditorUtil.GetString(eleData, "type"); fullFunc += $", F_{name} {type}"; dataF += $"\t\t\"{name}\": F_{name},\n"; } funcContent += "\tfilter := bson.M{\n"; funcContent += dataF; funcContent += "\t}\n\n"; } if (dataNotFormat) { if(sOp == "UpdateOne") { XmlNodeList datas = ele.SelectNodes("data"); XmlElement eleData = datas[0] as XmlElement; string name = EditorUtil.GetString(eleData, "name"); string type = EditorUtil.GetString(eleData, "type"); fullFunc += $", D_{name} {type}"; fullFunc += ", IsUpsert bool) {\n"; if(isSplit) { funcContent += $"\txsf_mongo.UpdateOneByColID(keyID, colID, cfg, rpc, IsUpsert, filter, D_{name})\n"; } else { funcContent += $"\txsf_mongo.UpdateOne(keyID, cfg, rpc, IsUpsert, filter, D_{name})\n"; } } else { fullFunc += ") {\n"; funcContent += $"\txsf_mongo.DeleteOne(keyID, cfg, rpc, filter)\n"; } } else { XmlNodeList datas = ele.SelectNodes("data"); string dataM = ""; for (int z = 0; z < datas.Count; z++) { XmlElement eleData = datas[z] as XmlElement; string name = EditorUtil.GetString(eleData, "name"); string type = EditorUtil.GetString(eleData, "type"); fullFunc += $", D_{name} {type}"; dataM += $"\t\t\"{name}\": D_{name},\n"; } if(sOp == "UpdateOne") { funcContent += "\tdata := bson.M{\n"; funcContent += dataM; funcContent += "\t}\n"; fullFunc += ", IsUpsert bool) {\n"; if(isSplit) { funcContent += "\txsf_mongo.UpdateOneByColID(keyID, colID, cfg, rpc, IsUpsert, filter, data)\n"; } else { funcContent += "\txsf_mongo.UpdateOne(keyID, cfg, rpc, IsUpsert, filter, data)\n"; } } else { fullFunc += ") {\n"; funcContent += $"\txsf_mongo.DeleteOne(keyID, cfg, rpc, filter)\n"; } } } break; } funcs += fullFunc + funcContent + "}\n\n"; } } } string codePath = SERVER_DIR + "/common/db/mongo_func.go"; EditorUtil.ReplaceContentByTag(DB_DEF_PATH, "MONGO_REQUEST_ID_BEGIN", "MONGO_REQUEST_ID_END", Ids); EditorUtil.ReplaceContentByTag(codePath, "REQUEST_FUNC_BEGEIN", "REQUEST_FUNC_END", funcs); } }