정확히 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 형식을 자유로이 왔다갔다 할 수 있어서 앞으론 좀 편하겠네요.

+ Recent posts