using System; using System.Collections.Generic; using System.Linq; using System.Text; using AR; namespace Project.Manager { public class DatabaseManager { /// /// 파일검색방법 /// public enum eFileSearchMode { Normal, Project, Model, MCCode, Barcode, All, } public enum eStripSearchResult { None, OK, NG, } /// /// 버퍼갯수(지정 갯수가 차면 실제파일에 기록을 한다) /// private int MaxBufferCount = 1; /// /// 최종파일 /// private String LastFileName; private string[] dataPath = new string[] { }; private DataSet1.ResultDataDataTable dt; // private string _subDirName = string.Empty; /// /// 파일디비초기화작업(클라이언트 갯수만큼 버퍼를 확보한다) /// public DatabaseManager(string[] dataPath_, int _MaxBufferCount = 100) { LastFileName = string.Empty; dt = new DataSet1.ResultDataDataTable(); this.dataPath = dataPath_; if (dataPath_.Length == 0) dataPath = new string[]{ System.IO.Path.Combine(UTIL.CurrentPath, "Data")}; //최대버퍼갯수(이 갯수를 넘어가면 실제 파일에 기록한다) MaxBufferCount = _MaxBufferCount; //_subDirName = subDirName; } //해당 결과를 버퍼에 추가한다. public void Add(DataSet1.ResultDataRow dataRow, Boolean autoFlush = false) { //입력된 자료를 복사해서 버퍼에 넣는다. var newdr = this.dt.NewResultDataRow(); foreach (string col in getDataColumnList()) { newdr[col] = dataRow[col]; } this.dt.AddResultDataRow(newdr); //만약자료가 일정데이터수를 넘었다면 flush 한다 if (autoFlush || dt.Rows.Count >= MaxBufferCount) { Flush(); //파일에 실제저장한다. } } /// /// 신규파일을 생성합니다. /// /// void MakeFile(string filename) { //파일이없다면 헤더를 만들어준다. AR.XMLHelper xml = new AR.XMLHelper(filename); xml.CreateFile(); } /// /// 저장해야할 컬럼명을 반환한다.(idx는 제외한다) /// /// public string[] getDataColumnList() { //저장하고자하는 순서를 미리 지정한다.(지정안된 자료는 알아서 저장된다) string[] reserveCols = new string[] { }; List cols = new List(); cols.AddRange(reserveCols); for (int i = 0; i < this.dt.Columns.Count; i++) { string colname = dt.Columns[i].ColumnName; if (reserveCols.Contains(colname)) continue; cols.Add(colname); } return cols.ToArray(); } public void Flush() { //데이터가없다면 처리하지 않음 if (this.dt.Rows.Count < 1) return; //쓸데이터를 모두 버퍼에 밀어넣는다. foreach (DataSet1.ResultDataRow dr in dt.Rows) { if (dr.RowState == System.Data.DataRowState.Deleted || dr.RowState == System.Data.DataRowState.Detached) continue; //lot date check if (dr.time_start.Year == 1982) dr.time_start = DateTime.Now; if (dr.time_end.Year == 1982) dr.time_end = DateTime.Now; //작업이 종료된 시간을 기준으로 파일을 생성한다. // if (dr.info_lot.isEmpty()) dr.info_lot = "NoLot"; //if (dr.info_stripid.isEmpty()) dr.info_stripid = "S" + dr.time_pcbstart.ToString("yyyyMMddHHmmss"); //string curdatestr = string.Format("{0:0000}\\{1:00}\\{2:00}\\{3}\\{4}", // dr.time_lotstart.Year, dr.time_lotstart.Month, dr.time_lotstart.Day, dr.info_lot,dr.info_stripid); //저장할 파일 체크 System.IO.FileInfo fi =new System.IO.FileInfo( dr.info_filename+".xml"); //폴더새엇ㅇ if (!fi.Directory.Exists) fi.Directory.Create(); //파일없는경우 헤더생성 if (!fi.Exists) MakeFile(fi.FullName); //파일에기록 try { //general info var xml = new AR.XMLHelper(fi.FullName); foreach(System.Data.DataColumn dc in this.dt.Columns) { if (dc.ColumnName.ToLower() == "idx") continue; if (dc.ColumnName.ToLower() == "filename") continue; var colname = dc.ColumnName.Split('_'); var data = dr[dc.ColumnName]; if(colname[0].ToLower()=="time") { string date_value = ""; if (data != null && data != DBNull.Value) date_value = ((DateTime)data).ToString("yyyy-MM-dd HH:mm:ss"); xml.set_Data(colname[0], colname[1], date_value); } else { if(data != null && data != DBNull.Value) xml.set_Data(colname[0], colname[1], data.ToString()); else xml.set_Data(colname[0], colname[1], ""); } } string savemsg; xml.Save(out savemsg); } catch (Exception ex) { PUB.log.AddE("DBMAN:FLUSH:" + ex.Message); return; } PUB.log.Add("DATABASE", string.Format("◆ Data Saved : {0}", fi.Name)); } dt.Clear(); dt.AcceptChanges(); } /// /// 지정된 파일의 모든 내용을 읽어서 DataTable 로 반환합니다. /// /// /// public DataSet1.ResultDataDataTable GetDatas(List files) { DataSet1.ResultDataDataTable retval = new DataSet1.ResultDataDataTable(); //모든파일을 대상으로한다. foreach(var file in files) { var newdr = retval.NewResultDataRow(); newdr.info_filename = file.FullName; var xml = new AR.XMLHelper(file.FullName); foreach (System.Data.DataColumn col in retval.Columns) { if (col.ColumnName.ToLower() == "idx") continue; if (col.ColumnName.ToLower() == "filename") continue; var colbuf = col.ColumnName.Split('_'); var readstr = xml.get_Data(colbuf[0], colbuf[1]); if(col.DataType == typeof(DateTime)) { if(readstr != "") { DateTime dt; if (DateTime.TryParse(readstr, out dt)) newdr[col.ColumnName] = dt; } } else { newdr[col.ColumnName] =readstr; } } retval.AddResultDataRow(newdr); } retval.AcceptChanges(); return retval; } public eStripSearchResult FindStrip(List pathlist, string strip) { //지정된 경로내에 스트립파일이 존재하는가? foreach(var path in pathlist) { var filese = System.IO.Directory.GetFiles( path , strip + ".xml"); if(filese .Length == 1) { var xml = new AR.XMLHelper(filese[0]); var upload = xml.get_Data("info", "upload"); if (upload == "O") return eStripSearchResult.OK; } } return eStripSearchResult.None; } /// /// 지정된 파일의 모든 내용을 읽어서 DataTable 로 반환합니다. /// /// /// public eStripSearchResult FindStrip(List files, string strip) { eStripSearchResult retval = eStripSearchResult.None; System.Text.StringBuilder sbError = new StringBuilder(); if (files.Count < 1) return eStripSearchResult.None; //가장최신의데이터를 찾아야한다. DateTime MaxDate = DateTime.Parse("1982-11-23"); string MaxResult = string.Empty; foreach (var fi in files.OrderByDescending(t => t.FullName)) { Boolean DataFind = false; List cols = new List(); System.IO.FileStream fs = new System.IO.FileStream(fi.FullName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite); System.IO.StreamReader sr = new System.IO.StreamReader(fs, System.Text.Encoding.ASCII); int LineCount = 0; while (sr.Peek() > 0) { string buffer = sr.ReadLine(); LineCount += 1; if (buffer.isEmpty() || buffer.StartsWith(";")) continue; var databuffer = buffer.Split(','); if (cols.Count < 1) { //줄로처리한다. foreach (string colname in databuffer) cols.Add(colname); } else { //지정한 바코드 자료만 처리한다. if (databuffer[2] != strip) continue; DateTime endtime; if (DateTime.TryParse(databuffer[4], out endtime)) { MaxResult = databuffer[5]; if (MaxResult.ToUpper() != "FAIL") { if (endtime > MaxDate) { MaxDate = endtime; if (MaxResult == "OK") retval = eStripSearchResult.OK; else if (MaxResult == "NG") retval = eStripSearchResult.NG; } DataFind = true; //다른파일은 작동하지 않게한다. } } } } sr.Close(); sr.Dispose(); fs.Close(); fs.Dispose(); if (DataFind) break; } return retval; } public List GetPathListbyLot(DateTime sdate, DateTime edate, string lot) { List retfiles = new List(); //날짜사이의 모든 파일을 대상으로해야함 string sd = sdate.ToShortDateString(); string ed = edate.ToShortDateString(); int sy = sdate.Year; int ey = edate.Year; int sm = sdate.Month; int em = edate.Month; int sday = sdate.Day; int eday = edate.Day; Boolean endtast = false; for (int y = sy; y <= ey; y++) { for (int m = 1; m <= 12; m++) { for (int d = 1; d <= 31; d++) { string daystr = string.Format("{0:0000}-{1:00}-{2:00}", y, m, d); if (ed == daystr) endtast = true; //마지막 날짜이다. if (y == sy && m < sm) continue; //시작년도 시작월 이전의 자료라면 넘어간다. else if (y == sy && m == sm && d < sday) continue; //시작년도 시작월 시작일 이전의 자료라면 넘어간다. foreach (var data in this.dataPath) { var path = new System.IO.DirectoryInfo(System.IO.Path.Combine(data, daystr.Replace("-", "\\"), lot)); if (path.Exists == false) continue; else retfiles.Add(path.FullName); } if (endtast) break; // TODO: might not be correct. Was : Exit For } if (endtast) break; // TODO: might not be correct. Was : Exit For } if (endtast) break; // TODO: might not be correct. Was : Exit For } return retfiles; } /// /// 지정된 기간사이의 파일명을 반환합니다. /// /// 검색시작일(시간은 적용안함) /// 검색종료일(시간은 적용안함) /// 검색필터 /// 장치번호 /// 검색바코드 /// public List Getfiles(DateTime sdate, DateTime edate) { List retfiles = new List(); //날짜사이의 모든 파일을 대상으로해야함 string sd = sdate.ToShortDateString(); string ed = edate.ToShortDateString(); int sy = sdate.Year; int ey = edate.Year; int sm = sdate.Month; int em = edate.Month; int sday = sdate.Day; int eday = edate.Day; Boolean endtast = false; for (int y = sy; y <= ey; y++) { for (int m = 1; m <= 12; m++) { for (int d = 1; d <= 31; d++) { string daystr = string.Format("{0:0000}-{1:00}-{2:00}", y, m, d); if (ed == daystr) endtast = true; //마지막 날짜이다. if (y == sy && m < sm) continue; //시작년도 시작월 이전의 자료라면 넘어간다. else if (y == sy && m == sm && d < sday) continue; //시작년도 시작월 시작일 이전의 자료라면 넘어간다. foreach(var data in this.dataPath) { var path = new System.IO.DirectoryInfo(System.IO.Path.Combine(data, daystr.Replace("-", "\\"))); if (path.Exists == false) continue; var files = path.GetFiles("*.xml", System.IO.SearchOption.AllDirectories); if (files != null && files.Length > 0) retfiles.AddRange(files); } if (endtast) break; // TODO: might not be correct. Was : Exit For } if (endtast) break; // TODO: might not be correct. Was : Exit For } if (endtast) break; // TODO: might not be correct. Was : Exit For } return retfiles; } } }