-
코드를 생성해 파일에 코드를 주입하자프로그래밍 2018. 1. 17. 04:11반응형
업무에 노가다를 줄여보고자 남는 시간에 코드를 만드는 코드를 만들었다.
PQL이라는 이름을 붙인 쿼리 파일로부터 클라이언트에 삽입되는 코드를 만드는 것이 목적이었다.
PQL은 이렇게 생겼다.
select [ID:int], [Level:short], [Name:nvarchar(20)] from Character;그냥 sql의 select 쿼리에 저장할 타입을 지정한 것이다. 사실 이것도 내가 만든거라 이름도 내가 붙인거다. 필규 쿼리 랭귀지라고 -_-;
여튼 저 문법을 통해서 만들어야 할 구조체를 알 수 있는데 위 PQL은 다음과 같은 구조체의 컨테이너에 로드가 될 것임을 알 수 있다.
struct Character{int id;short level;wchar_t name[20];};그런데 저 코드를 만드는 작업은 일일히 사람이 했어야 했고 나도 매번 만드는 게 귀찮아 잠깐 남는 시간에 짬을 내서 만들었다.
텍스트를 파싱해서 클래스로 만들고 그 클래스의 정보를 바탕으로 특정 파일들에 데이터 구조체 코드, 데이터 로드 코드를 추가한다.
현재 회사 프로젝트의 방식은 로드 코드를 한 함수에 나열하고, 모든 구조체가 한 파일 안에 있다보니 코드의 경계를 찾기가 어려워 pql이 바뀜에 따라 기존 구조체를 바꿔준다던지... 로드 방식을 바꾼다던지 하는 처리가 좀 까다롭다.
때문에 완전 자동화보단 커맨드 라인 파서를 만들어서 --add CashItem 처럼 추가할 테이블을 선택해서 수동으로 만들도록 했다.
기존 코드와의 호환성 유지를 위해 코드를 만들여 붙여넣기만 해주므로 기존 파일 내용을 유지한 체 원하는 위치에 텍스트만 주입하는 것이 결국 전부였다.
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.IO;namespace PQLAdder{public class FileInjector{public static Encoding GetFileEncoding(string path){using (StreamReader sr = new StreamReader(path)){return System.Text.Encoding.GetEncoding(51949);//sr.Peek();//return sr.CurrentEncoding;}throw new FileLoadException("file not found");}static public void InjectText(string path, string indicatorOrNull, string srcText){Encoding encoding = GetFileEncoding(path);string text = File.ReadAllText(path, encoding);int idx = text.Length - 1;if(!string.IsNullOrWhiteSpace(indicatorOrNull)){idx = text.IndexOf(indicatorOrNull);if(idx == -1){string message = string.Format("indicator not defined. {path:{0}, indicator:{1}}",path,indicatorOrNull);throw new ArgumentException(message);}}// 앞에 들어갈 탭, 스페이스를 계산한다.string front = "";for (int i = idx; i != 0; --i){char c = text[i];if (c == '\n'){idx = (text[i-1] == '\r' ? i - 1 : i);break;}if (c == ' ' || c == '\t')front += text[i];}string[] srcTextLines = srcText.Split(new [] { Environment.NewLine }, StringSplitOptions.None);srcText = srcText.Split(new string[] { Environment.NewLine }, StringSplitOptions.None).Select(line => Environment.NewLine + front + line).Aggregate((dest, src) => dest + src);text = text.Insert(idx, srcText);File.WriteAllText(path, text, encoding);}}}근데 파일 인코딩을 알아오는 부분이 잘 안 되더라. 이 부분은 다시 알아보면 좋을 듯.
+++
MDBModel, ColumnModel 등의 클래스는 최대한 간소화된 기능만 가지도록 하는 게 좋아보인다. 이름, 타입, 테이블 키 정도의 정보만 가진다. 그리고 CodeWriter클래스가 이걸 c# 버전 패킷으로 만드느냐 c++ 버전으로 결정한다.
CppCodeWriter는 키가 없다면 vector로, 키가 하나면 map으로, 키가 여러개면 별도의 키 구조체를 만들어서 map의 key로 만드는 처리를 해보려고 한다.(pql에 key 지정 추가와 함께)
반응형'프로그래밍' 카테고리의 다른 글
비주얼 스튜디오(Visual Studio) 빌드 완료 시 알림 (0) 2019.01.16 Visual Studio 사용자 정의 빌드로 proto 파일 빌드하기 (0) 2018.10.12 비주얼 스튜디오 확장 vsix, 간단 활용 정리 (0) 2017.12.27 유용하다고 생각한 비쥬얼 스튜디오 디버깅 기능. 중단점 설정. (0) 2017.12.25 트라이브스의 네트워킹 모델 (0) 2017.12.10