Files
manual_wpf/Models/SqlDatas.cs
2025-07-16 17:40:50 +09:00

310 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 제품 활성화용
readonly string connectionString = "Host=localhost;Database=postgres;Username=postgres;Password=Qwer1234";
void ActivateAndInitializeODA()
{
var userInfo = "c2FtYW4gZW5naW5lZXJpbmc=";
var userSignature = "F0kuQTmtVpHtvl/TgaFVGE92/YqGmYR9SLoXckEjnOk8NoAQh7Sg6GQruVC04JqD4C/IipxJYqpqvMfMc2auRMG+cAJCKqKUE2djIMdkUdb+C5IVx2c97fcK5ba3n8DDvB54Upokajl+6j12yD8h8MKGOR3Z3zysObeXD62bFpQgp00GCYTqlxEZtTIRjHIPAfJfix8Y0jtXWWYyVJ3LYOu86as5xtx+hY1aakpYIJiQk/6pGd84qSn/9K1w8nxR7UrFzieDeQ/xM58BHSD4u/ZxVJwvv6Uy10tsdBFBTvfJMAFp05Y7yeyeCNr100tA3iOfmWoXAVRHfxnkPfiYR54aK04QI+R6OGkI+yd1oR5BtmN6BdDt3z8KYK5EpFGJGiJIGoUy5PvkYdJ2VV6xe9JWBiIJuI/tDn1Y+uyTQFA9qaDHnOURriXsRGfy8reDPf1eejybSJxWKkpilG6RXhq3xHlCkjZzh1Q45S+xYXNGatcWMm9nkn20M8Ke5JEVaI9w/p2GE36CHRtRQbt8kfPmsbWNXJCFr4svHW2MPbCKWoyn5XEyMWBnuAKi74zvczB13DKjf29SqSIgF5k/hwy2QrgvnaKzY1k8bw8w2/k0vJXcS3GKOB/ZYDle1tf/lkAD1HtnF9zE18TiXhVnqwAVjwg4ui1RPLn/LMs6b5Y=";
Services.odActivate(userInfo, userSignature);
appServices = new Services();
}
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()
{
ActivateAndInitializeODA();
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)
{
appServices.Dispose();
appServices = null;
}
}
}
}