정확히 1년만의 포스팅 (...) 왜냐하면 실컷 놀았거든요.
-------------------------------------------------------------
지금 개발하고 있는 프로젝트에선.. 정말 특이하게 단순정보만 담은 리소스들도 DB로 관리하고 있습니다.
아니, DB로만 관리하는게 아니라 어디엔 xml, 어디엔 스크립트 안에서(;;) 아주 중구난방이긴 한데
기획자들에게 직접 DB수정을 요할 수는 없으니 대부분 요청사항을 전달받을 때 Excel로 작업하곤 합니다.
보통 데이터테이블을 csv형식으로 뽑아주면, 이를 엑셀로 Import시켜 기획팀에서 수정 후 다시 엑셀을 제가 받아오는.. 그런 식인데
어찌됐든 요놈을 db에 집어넣고, 파싱하고, bytes파일로 바꾸고 하는 일은 온전히 제 일이란 말이죠. 그런데 말썽이.. 좀 있었습니다.
뭐 예를 들어, column별로 정리된 데이터테이블이 있다고 칩시다.
제 인생은 되는 일이 잘 없더라구요.
일단 구글링을 좀 해보니, DB INSERT시 칼럼이 NOT NULL 여부에 관계없이 실수, 정수형 데이타에 빈 문자열을 입력하면 발생하는 오류랍니다.
위에 엑셀 파일에 null값을 넣었는데, 처음엔 저게 빈칸으로 왔었어요.
일일히 쿼리문 써가면서 수정하자니 머리가 나빠 손이 고생하는 느낌도 들고..
뭐 여튼 해결방법은, 제한설정을 좀 풀어주면 됩니다. 자료형이 비좁다면 더 크게 바꾸고, 65535바이트 이상이라면 MEDIUMTEXT로 바꾸고 뭐 그런 식이요.
그리고 null값 관련은 ini 설정에서
sql-mode=”STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION”
추가해주시면 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; [System.Serializable] public class SqliteItem { public string Name; public string Path; public string Data; public string[] querys; public SqliteItem(string name, string path, string data) { Name = name; Path = path; Data = data; } } public class Converter : MonoBehaviour { public SqliteItem[] Items; public void Btn_Convert() { StartCoroutine(ReadFile()); } public void Btn_Exit() { Application.Quit(); } //불러온 .sql 파일들을 sqlite 데이터베이스 파일로 변환하여 생성하기 void Write() { foreach (var item in Items) { SqliteDB db = new SqliteDB(item.Name); db.connection(); for (int i = 0; i < item.querys.Length; i++) { db.ApplyQuery(item.querys[i]); } db.Disconnection(); } } //.sql 파일들을 불러와 저장하기 IEnumerator ReadFile() { DirectoryInfo di = new DirectoryInfo(Application.streamingAssetsPath); List<SqliteItem> tmp = new List<SqliteItem>(); foreach (var item in di.GetFiles("*.sql")) { WWW www = new WWW(Application.streamingAssetsPath + "/" + item.Name); while (!www.isDone) { Debug.Log("대기중"); yield return new WaitForFixedUpdate(); } tmp.Add(new SqliteItem(item.Name.Split('.')[0], item.DirectoryName, www.text)); } if (tmp.Count == 0) { Debug.Log("파일이 없습니다"); } Items = tmp.ToArray(); StartCoroutine(Convert()); } IEnumerator Convert() { foreach (var item in Items) { StringReader sr = new StringReader(item.Data); List<string> querys = new List<string>(); string line = sr.ReadLine(); string query = ""; if (line.Contains(" ")) { line = line.Replace(" ", " "); } while (line != null) { if (line.Contains("--") || line.Contains("/*") || line.Contains("*/") || line.Contains("USE") || line.Contains("COMMENT") || line.Contains("UNIQUE KEY") || line.Contains("ENGINE") || line.Contains("PRIMARY KEY") || line.Contains("KEY `")) { if(line.Contains("DATABASE")) { line = sr.ReadLine(); continue; } if(line.Contains("CREATE")||line.Contains("INSERT INTO")) { query += line; line = sr.ReadLine(); continue; } line = sr.ReadLine(); continue; } if (line.Equals("")) { if (!query.Equals("")) { query = SqlToSqlite(query); querys.Add(query); query = ""; } } else { if(line.Contains("INSERT IGNORE INTO")) { line = line.Replace("INSERT IGNORE INTO", "INSERT OR IGNORE INTO"); } query += line; } line = sr.ReadLine(); } //M용 유저 테이블 추가 querys.Add(); item.querys = querys.ToArray(); yield return null; } Write(); } string SqlToSqlite(string query) { string[] tmp = query.Split(' '); query = ""; for (int i = 0; i < tmp.Length; i++) { if (tmp[i].Contains("int(")) tmp[i] = "INTEGER"; if (tmp[i].Contains("varchar(")) { tmp[i] = "TEXT"; } if (tmp[i].Contains("AUTO_INCREMENT")) tmp[i] = tmp[i].Replace("AUTO_INCREMENT", "PRIMARY KEY AUTOINCREMENT"); if (tmp[i].Contains("float")) tmp[i] = "NUMERIC"; query += tmp[i] + " "; } query = query.TrimEnd(); query += ")"; query = query.Replace("))", ")"); query = query.Replace(";)", ";"); query = query.Replace(",)", ")"); query = query.Replace(" ", " "); return query; } } | cs |
그리고 아주 약간의 하드코딩을 통해, sql을 그대로 .db로 바꿔주는 함수를 짜둡니다.
그렇게 db파일을 퉤 하고 뱉어내면 확장자를 .bytes로 바꾸어 주면 됩니다.
그래도 일단 이렇게 만들어두면 XML, DB, bytes, csv 형식을 자유로이 왔다갔다 할 수 있어서 앞으론 좀 편하겠네요.
'Works > Programming' 카테고리의 다른 글
Unity : AdditiveSceneLoad로 생성된 씬 스크립트에서 OnDisable() 호출이 안 되는 문제. (0) | 2020.02.06 |
---|---|
유니티 빌드오류 : Failed to align APK (0) | 2019.09.17 |
마비노기 염색 도우미 수정 (0) | 2018.09.27 |
C++) ifstream 읽기 성능 비교 (0) | 2018.08.07 |
JAVA) I/O 퍼포먼스 개선 (0) | 2018.08.03 |