329 lines
16 KiB
C#
329 lines
16 KiB
C#
using Microsoft.Office.Interop.Excel;
|
|
using Npgsql;
|
|
using System.Diagnostics;
|
|
using Teigha.DatabaseServices;
|
|
using Teigha.Runtime;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System;
|
|
|
|
namespace DwgExtractorManual.Models
|
|
{
|
|
/// <summary>
|
|
/// DWG 파일에서 PostgreSQL 데이터베이스로 데이터 내보내기 클래스
|
|
/// AttributeReference, AttributeDefinition, DBText, MText 추출 지원
|
|
/// </summary>
|
|
internal sealed class SqlDatas : IDisposable
|
|
{
|
|
Services appServices; // ODA 제품 활성화용 (managed by singleton)
|
|
readonly string connectionString = "Host=localhost;Database=postgres;Username=postgres;Password=Qwer1234";
|
|
|
|
void InitializeTeighaServices()
|
|
{
|
|
try
|
|
{
|
|
Debug.WriteLine("[SqlDatas] TeighaServicesManager를 통한 Services 획득 중...");
|
|
appServices = TeighaServicesManager.Instance.AcquireServices();
|
|
Debug.WriteLine($"[SqlDatas] Services 획득 성공. Reference Count: {TeighaServicesManager.Instance.ReferenceCount}");
|
|
}
|
|
catch (Teigha.Runtime.Exception ex)
|
|
{
|
|
Debug.WriteLine($"[SqlDatas] Teigha Services 초기화 실패: {ex.Message}");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
void CreateTables()
|
|
{
|
|
try
|
|
{
|
|
using (var conn = new NpgsqlConnection(connectionString))
|
|
{
|
|
conn.Open();
|
|
|
|
// AttributeReferences 테이블 생성 (Title Block용)
|
|
using (var cmd = new NpgsqlCommand())
|
|
{
|
|
cmd.Connection = conn;
|
|
cmd.CommandText = @"
|
|
CREATE TABLE IF NOT EXISTS AttributeReferences (
|
|
Type VARCHAR(100),
|
|
Name VARCHAR(255),
|
|
Tag VARCHAR(255),
|
|
Prompt VARCHAR(255),
|
|
Value TEXT,
|
|
Path TEXT,
|
|
FileName TEXT,
|
|
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)";
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
|
|
// TextEntities 테이블 생성 (DBText/MText용)
|
|
using (var cmd = new NpgsqlCommand())
|
|
{
|
|
cmd.Connection = conn;
|
|
cmd.CommandText = @"
|
|
CREATE TABLE IF NOT EXISTS TextEntities (
|
|
Type VARCHAR(50),
|
|
Layer VARCHAR(255),
|
|
Text TEXT,
|
|
Path TEXT,
|
|
FileName TEXT,
|
|
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)";
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
}
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
Debug.WriteLine($"테이블 생성 중 오류: {ex.Message}");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public SqlDatas()
|
|
{
|
|
InitializeTeighaServices();
|
|
CreateTables();
|
|
}
|
|
|
|
/// <summary>
|
|
/// DWG 파일 데이터를 데이터베이스에 저장
|
|
/// </summary>
|
|
/// <param name="filePath">DWG 파일 경로</param>
|
|
/// <returns>실패시 true, 성공시 false (기존 콘솔 버전과 호환성)</returns>
|
|
public bool DwgToDB(string filePath)
|
|
{
|
|
var result = false;
|
|
using (var database = new Database(false, true))
|
|
{
|
|
try
|
|
{
|
|
database.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndWriteNoShare, false, null);
|
|
|
|
using (var conn = new NpgsqlConnection(connectionString))
|
|
{
|
|
conn.Open();
|
|
|
|
using (var tran = database.TransactionManager.StartTransaction())
|
|
{
|
|
// Document Information 추출
|
|
DatabaseSummaryInfo summaryInfo = database.SummaryInfo;
|
|
string documentInfo = $"Title: {summaryInfo.Title}, Subject: {summaryInfo.Subject}, Author: {summaryInfo.Author}";
|
|
Dictionary<string, string> dicTagPrompt = new Dictionary<string, string>();
|
|
|
|
// Block Table 접근
|
|
var bt = tran.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;
|
|
using (var btr = tran.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord)
|
|
{
|
|
foreach (ObjectId entId in btr)
|
|
{
|
|
using (var ent = tran.GetObject(entId, OpenMode.ForRead) as Entity)
|
|
{
|
|
// Layer 이름 가져오기 (공통)
|
|
string layerName = GetLayerName(ent.LayerId, tran, database);
|
|
|
|
// AttributeDefinition 처리는 생략 (필요시 추가)
|
|
if (ent is AttributeDefinition attDef)
|
|
{
|
|
// 현재는 AttributeDefinition 처리하지 않음
|
|
}
|
|
// DBText 엔티티 처리 (별도 테이블)
|
|
else if (ent is DBText dbText)
|
|
{
|
|
using (var cmd = new NpgsqlCommand())
|
|
{
|
|
cmd.Connection = conn;
|
|
cmd.CommandText = @"
|
|
INSERT INTO TextEntities (Type, Layer, Text, Path, FileName)
|
|
VALUES (@Type, @Layer, @Text, @Path, @FileName)";
|
|
|
|
cmd.Parameters.AddWithValue("Type", "DBText");
|
|
cmd.Parameters.AddWithValue("Layer", layerName);
|
|
cmd.Parameters.AddWithValue("Text", dbText.TextString ?? "");
|
|
cmd.Parameters.AddWithValue("Path", database.Filename);
|
|
cmd.Parameters.AddWithValue("FileName", Path.GetFileName(database.Filename));
|
|
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
}
|
|
// MText 엔티티 처리 (별도 테이블)
|
|
else if (ent is MText mText)
|
|
{
|
|
using (var cmd = new NpgsqlCommand())
|
|
{
|
|
cmd.Connection = conn;
|
|
cmd.CommandText = @"
|
|
INSERT INTO TextEntities (Type, Layer, Text, Path, FileName)
|
|
VALUES (@Type, @Layer, @Text, @Path, @FileName)";
|
|
|
|
cmd.Parameters.AddWithValue("Type", "MText");
|
|
cmd.Parameters.AddWithValue("Layer", layerName);
|
|
cmd.Parameters.AddWithValue("Text", mText.Contents ?? "");
|
|
cmd.Parameters.AddWithValue("Path", database.Filename);
|
|
cmd.Parameters.AddWithValue("FileName", Path.GetFileName(database.Filename));
|
|
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
}
|
|
else if (ent is BlockReference blr)
|
|
{
|
|
foreach (ObjectId attId in blr.AttributeCollection)
|
|
{
|
|
using (var attRef = tran.GetObject(attId, OpenMode.ForRead) as AttributeReference)
|
|
{
|
|
using (var cmd = new NpgsqlCommand())
|
|
{
|
|
cmd.Connection = conn;
|
|
cmd.CommandText = @"
|
|
INSERT INTO AttributeReferences (Type, Name, Tag, Prompt, Value, Path, FileName)
|
|
VALUES (@Type, @Name, @Tag, @Prompt, @Value, @Path, @FileName)";
|
|
|
|
var typeFullName = attRef.GetType().ToString();
|
|
var typeName = typeFullName.Substring(typeFullName.LastIndexOf('.') + 1);
|
|
var blkName = blr.Name;
|
|
var attTag = attRef.Tag;
|
|
string prompt = "";
|
|
string tString = "";
|
|
|
|
if (!bt.Has(blkName))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (dicTagPrompt.ContainsKey(attTag))
|
|
{
|
|
prompt = dicTagPrompt[attTag];
|
|
}
|
|
else
|
|
{
|
|
// 블록 정의 찾기
|
|
ObjectId blockDefId = bt[blkName];
|
|
BlockTableRecord blkDef = (BlockTableRecord)tran.GetObject(blockDefId, OpenMode.ForRead);
|
|
|
|
// AttributeDefinition 순회 및 태그 일치 확인
|
|
foreach (ObjectId objId in blkDef)
|
|
{
|
|
DBObject dbObj = tran.GetObject(objId, OpenMode.ForRead);
|
|
|
|
if (dbObj is AttributeDefinition adef)
|
|
{
|
|
if (adef.Tag.ToUpper() == attTag.ToUpper())
|
|
{
|
|
prompt = adef.Prompt;
|
|
dicTagPrompt.Add(attTag, prompt);
|
|
tString = adef.TextString;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
cmd.Parameters.AddWithValue("Type", typeName);
|
|
cmd.Parameters.AddWithValue("Name", blr.Name);
|
|
cmd.Parameters.AddWithValue("Tag", attTag);
|
|
cmd.Parameters.AddWithValue("Prompt", prompt);
|
|
|
|
if (!string.IsNullOrEmpty(attRef.TextString))
|
|
cmd.Parameters.AddWithValue("Value", attRef.TextString);
|
|
else
|
|
cmd.Parameters.AddWithValue("Value", tString);
|
|
|
|
cmd.Parameters.AddWithValue("Path", database.Filename);
|
|
cmd.Parameters.AddWithValue("FileName", Path.GetFileName(database.Filename));
|
|
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
tran.Commit();
|
|
}
|
|
}
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
result = true; // 실패시 true 반환 (기존 버전과 호환성)
|
|
Debug.WriteLine($"DWG 파일 처리 중 오류: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 데이터베이스 연결 테스트
|
|
/// </summary>
|
|
/// <returns>연결 성공 여부</returns>
|
|
public bool TestConnection()
|
|
{
|
|
try
|
|
{
|
|
using (var conn = new NpgsqlConnection(connectionString))
|
|
{
|
|
conn.Open();
|
|
return true;
|
|
}
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
Debug.WriteLine($"데이터베이스 연결 테스트 실패: {ex.Message}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Layer ID로부터 Layer 이름을 가져옵니다.
|
|
/// </summary>
|
|
/// <param name="layerId">Layer ObjectId</param>
|
|
/// <param name="transaction">현재 트랜잭션</param>
|
|
/// <param name="database">데이터베이스 객체</param>
|
|
/// <returns>Layer 이름 또는 빈 문자열</returns>
|
|
private string GetLayerName(ObjectId layerId, Transaction transaction, Database database)
|
|
{
|
|
try
|
|
{
|
|
using (var layerTableRecord = transaction.GetObject(layerId, OpenMode.ForRead) as LayerTableRecord)
|
|
{
|
|
return layerTableRecord?.Name ?? "";
|
|
}
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
Debug.WriteLine($"Layer 이름 가져오기 오류: {ex.Message}");
|
|
return "";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 리소스 해제
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
if (appServices != null)
|
|
{
|
|
try
|
|
{
|
|
Debug.WriteLine("[SqlDatas] Teigha Services 해제 중...");
|
|
TeighaServicesManager.Instance.ReleaseServices();
|
|
Debug.WriteLine($"[SqlDatas] Teigha Services 해제 완료. Remaining ref count: {TeighaServicesManager.Instance.ReferenceCount}");
|
|
}
|
|
catch (Teigha.Runtime.Exception ex)
|
|
{
|
|
Debug.WriteLine($"[SqlDatas] Teigha Services 해제 중 오류 (무시됨): {ex.Message}");
|
|
}
|
|
finally
|
|
{
|
|
appServices = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|