DataMapper 개선, MQTTPipeLine 개발 중
This commit is contained in:
8
Assets/Scripts/SampleProject/Config.meta
Normal file
8
Assets/Scripts/SampleProject/Config.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 34b69b50cc4daee43ae66d0445ad941d
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Scripts/SampleProject/Config/Constants.cs
Normal file
8
Assets/Scripts/SampleProject/Config/Constants.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace SampleProject.Config
|
||||||
|
{
|
||||||
|
public static class Constants
|
||||||
|
{
|
||||||
|
public static string MQTT_DOMAIN = "localshot";
|
||||||
|
public static int MQTT_PORT = 1883;
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/Scripts/SampleProject/Config/Constants.cs.meta
Normal file
2
Assets/Scripts/SampleProject/Config/Constants.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 47f43889f1d579745a502b7f5d9f709e
|
||||||
@@ -19,10 +19,13 @@
|
|||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
//
|
//
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
#if WINDOWS_PHONE && !USE_WP8_NATIVE_SQLITE
|
#if WINDOWS_PHONE && !USE_WP8_NATIVE_SQLITE
|
||||||
#define USE_CSHARP_SQLITE
|
#define USE_CSHARP_SQLITE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|||||||
@@ -131,6 +131,65 @@ namespace UVC.Data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 모든 아이템이 추가 된것으로 표시합니다.
|
||||||
|
/// 전체 데이터가 갱신되었을 때 사용합니다.
|
||||||
|
/// </summary>
|
||||||
|
public void InitData()
|
||||||
|
{
|
||||||
|
addedList.Clear();
|
||||||
|
addedList.AddRange(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 다른 DataObject와 현재 객체를 비교하여 다른 부분만 설정합니다.
|
||||||
|
/// 변경된 키는 자동으로 추적됩니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="other">비교할 DataObject</param>
|
||||||
|
public void UpdateDifferent(IDataObject other)
|
||||||
|
{
|
||||||
|
if (other == null) return;
|
||||||
|
if (other is DataArray otherArray)
|
||||||
|
{
|
||||||
|
addedList.Clear();
|
||||||
|
removedList.Clear();
|
||||||
|
modifiedList.Clear();
|
||||||
|
|
||||||
|
// 현재 DataArray와 비교하여 변경된 항목을 추적
|
||||||
|
for (int i = 0; i < Math.Max(this.Count, otherArray.Count); i++)
|
||||||
|
{
|
||||||
|
if (i < this.Count && i < otherArray.Count)
|
||||||
|
{
|
||||||
|
if (!this[i].ToString().Equals(otherArray[i].ToString()))
|
||||||
|
{
|
||||||
|
modifiedList.Add(this[i]);
|
||||||
|
this[i].UpdateDifferent(otherArray[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (i < this.Count)
|
||||||
|
{
|
||||||
|
removedList.Add(this[i]);
|
||||||
|
}
|
||||||
|
else if (i < otherArray.Count)
|
||||||
|
{
|
||||||
|
addedList.Add(otherArray[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 업데이트 된 객체를 반환합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public IDataObject GetUpdatedObject()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 항목을 추가합니다.
|
/// 항목을 추가합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
17
Assets/Scripts/UVC/Data/DataMap.cs
Normal file
17
Assets/Scripts/UVC/Data/DataMap.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace UVC.Data
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// DataMapper에서 사용되는 데이터 값 매핑을 위한 클래스입니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// ...
|
||||||
|
/// 지원되는 타입:
|
||||||
|
/// ...
|
||||||
|
/// - DataMap (문자열 매핑 딕셔너리) - 특정 문자열 값을 다른 문자열로 변환합니다.
|
||||||
|
/// 예: "ON" -> "활성화", "OFF" -> "비활성화"
|
||||||
|
/// ...
|
||||||
|
/// </remarks>
|
||||||
|
public class DataMap : Dictionary<string, string>{}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace UVC.Data
|
namespace UVC.Data
|
||||||
{
|
{
|
||||||
@@ -9,7 +10,7 @@ namespace UVC.Data
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 이 클래스는 JSON 데이터를 DataObject와 DataArray 형식으로 변환하며, 중첩된 구조(nested structure)도 처리할 수 있습니다.
|
/// 이 클래스는 JSON 데이터를 DataObject와 DataArray 형식으로 변환하며, 중첩된 구조(nested structure)도 처리할 수 있습니다.
|
||||||
/// 소스 JSON 객체의 속성을 가이드 객체에 정의된 타입에 따라 적절히 변환합니다.
|
/// 소스 JSON 객체의 속성을 Mask 객체에 정의된 타입에 따라 적절히 변환합니다.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <example>
|
/// <example>
|
||||||
/// 기본 사용 예시:
|
/// 기본 사용 예시:
|
||||||
@@ -21,7 +22,7 @@ namespace UVC.Data
|
|||||||
/// ""isActive"": true
|
/// ""isActive"": true
|
||||||
/// }");
|
/// }");
|
||||||
///
|
///
|
||||||
/// // 가이드 객체 (타입 지정용)
|
/// // Mask 객체 (타입 지정용)
|
||||||
/// var maskJson = JObject.Parse(@"{
|
/// var maskJson = JObject.Parse(@"{
|
||||||
/// ""name"": """",
|
/// ""name"": """",
|
||||||
/// ""age"": 0,
|
/// ""age"": 0,
|
||||||
@@ -31,19 +32,24 @@ namespace UVC.Data
|
|||||||
/// var mapper = new DataMapper(maskJson);
|
/// var mapper = new DataMapper(maskJson);
|
||||||
/// DataObject result = mapper.Map(sourceJson);
|
/// DataObject result = mapper.Map(sourceJson);
|
||||||
///
|
///
|
||||||
/// // result는 원본과 동일한 구조이며 각 속성이 가이드에 따라 타입 변환됨
|
/// // result는 원본과 동일한 구조이며 각 속성이 Mask에 따라 타입 변환됨
|
||||||
/// </code>
|
/// </code>
|
||||||
/// </example>
|
/// </example>
|
||||||
public class DataMapper
|
public class DataMapper
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// 재귀 호출 제한하기 위한 설정 추가
|
||||||
|
private int maxRecursionDepth = 10;
|
||||||
|
private int currentDepth = 0;
|
||||||
|
|
||||||
private JObject mask;
|
private JObject mask;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DataMapper 클래스의 새 인스턴스를 초기화합니다.
|
/// DataMapper 클래스의 새 인스턴스를 초기화합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="mask">타입 변환을 위한 가이드 JSON 객체</param>
|
/// <param name="mask">타입 변환을 위한 Mask JSON 객체</param>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 가이드 객체는 원본 JSON 객체와 동일한 구조를 가질 필요는 없지만,
|
/// Mask 객체는 원본 JSON 객체와 동일한 구조를 가질 필요는 없지만,
|
||||||
/// 변환하려는 속성들에 대한 타입 정보를 제공해야 합니다.
|
/// 변환하려는 속성들에 대한 타입 정보를 제공해야 합니다.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public DataMapper(JObject mask)
|
public DataMapper(JObject mask)
|
||||||
@@ -52,7 +58,7 @@ namespace UVC.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 소스 객체를 가이드 객체를 기반으로 매핑하여 새로운 DataObject를 생성합니다.
|
/// 소스 객체를 Mask 객체를 기반으로 매핑하여 새로운 DataObject를 생성합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="source">매핑할 원본 JSON 객체</param>
|
/// <param name="source">매핑할 원본 JSON 객체</param>
|
||||||
/// <returns>매핑된 DataObject 객체</returns>
|
/// <returns>매핑된 DataObject 객체</returns>
|
||||||
@@ -64,18 +70,21 @@ namespace UVC.Data
|
|||||||
/// Debug.Log(result["age"].ToObject<int>()); // 30
|
/// Debug.Log(result["age"].ToObject<int>()); // 30
|
||||||
/// </code>
|
/// </code>
|
||||||
/// </example>
|
/// </example>
|
||||||
public DataObject Map(JObject source)
|
public DataObject Mapping(JObject source)
|
||||||
{
|
{
|
||||||
return MapObject(source, mask);
|
return MapObject(source, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 소스 배열을 가이드 객체를 기반으로 매핑하여 새로운 DataArray를 생성합니다.
|
/// 소스 배열을 Mask 객체를 기반으로 매핑하여 새로운 DataArray를 생성합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="source">매핑할 원본 JSON 배열</param>
|
/// <param name="source">매핑할 원본 JSON 배열</param>
|
||||||
/// <returns>매핑된 DataArray 객체</returns>
|
/// <returns>매핑된 DataArray 객체</returns>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 이 메서드는 가이드 객체로부터 새로운 배열을 생성하여 소스 배열의 각 항목을 매핑합니다.
|
/// 이 메서드는 Mask 객체를 JArray로 변환하여 소스 배열의 각 항목을 매핑합니다.
|
||||||
|
/// Mask 배열이 비어있으면 원본 배열의 각 항목을 그대로 변환하고,
|
||||||
|
/// 그렇지 않으면 Mask 배열이 하나인 경우 첫 번째 항목을 템플릿으로 사용하고
|
||||||
|
/// 하나 이상인 경우 Mask 배열 개수에 맞춰 템플릿으로 사용(배열 길이가 3이고, 소스 배열 길이가 5일때, 소스배열 3까지만 매핑) 합니다.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <example>
|
/// <example>
|
||||||
/// <code>
|
/// <code>
|
||||||
@@ -94,21 +103,36 @@ namespace UVC.Data
|
|||||||
/// // result는 원본 배열과 동일한 구조의 DataArray
|
/// // result는 원본 배열과 동일한 구조의 DataArray
|
||||||
/// </code>
|
/// </code>
|
||||||
/// </example>
|
/// </example>
|
||||||
public DataArray Map(JArray source)
|
public DataArray Mapping(JArray source)
|
||||||
{
|
{
|
||||||
JArray arr = new JArray(mask);
|
JArray arr = new JArray(mask);
|
||||||
return MapArray(source, arr);
|
return MapArray(source, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 대용량 JSON 데이터를 스트리밍 방식으로 매핑합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="jsonStream">JSON 데이터 스트림</param>
|
||||||
|
/// <returns>매핑된 DataObject</returns>
|
||||||
|
public DataObject MapStream(System.IO.Stream jsonStream)
|
||||||
|
{
|
||||||
|
using (var reader = new Newtonsoft.Json.JsonTextReader(new System.IO.StreamReader(jsonStream)))
|
||||||
|
{
|
||||||
|
var serializer = new Newtonsoft.Json.JsonSerializer();
|
||||||
|
var sourceObject = serializer.Deserialize<JObject>(reader);
|
||||||
|
return Mapping(sourceObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 객체를 재귀적으로 매핑합니다.
|
/// 객체를 재귀적으로 매핑합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sourceObject">원본 JSON 객체</param>
|
/// <param name="sourceObject">원본 JSON 객체</param>
|
||||||
/// <param name="maskObject">가이드 JSON 객체</param>
|
/// <param name="maskObject">Mask JSON 객체</param>
|
||||||
/// <returns>매핑된 DataObject 객체</returns>
|
/// <returns>매핑된 DataObject 객체</returns>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 이 메서드는 중첩된 객체와 배열을 포함하여 JSON 구조를 재귀적으로 처리합니다.
|
/// 이 메서드는 중첩된 객체와 배열을 포함하여 JSON 구조를 재귀적으로 처리합니다.
|
||||||
/// 가이드 객체에 포함되지 않은 속성은 원본 값을 그대로 사용합니다.
|
/// Mask 객체에 포함되지 않은 속성은 원본 값을 그대로 사용합니다.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <example>
|
/// <example>
|
||||||
/// 중첩 객체 매핑 예시:
|
/// 중첩 객체 매핑 예시:
|
||||||
@@ -138,8 +162,14 @@ namespace UVC.Data
|
|||||||
/// // result는 sourceJson과 동일한 중첩 구조를 유지
|
/// // result는 sourceJson과 동일한 중첩 구조를 유지
|
||||||
/// </code>
|
/// </code>
|
||||||
/// </example>
|
/// </example>
|
||||||
private DataObject MapObject(JObject sourceObject, JObject maskObject)
|
private DataObject MapObject(JObject sourceObject, JObject maskObject, int depth = 0)
|
||||||
{
|
{
|
||||||
|
if (depth >= maxRecursionDepth)
|
||||||
|
{
|
||||||
|
// 깊이 제한에 도달하면 간소화된 처리
|
||||||
|
return new DataObject(sourceObject);
|
||||||
|
}
|
||||||
|
|
||||||
DataObject target = new DataObject();
|
DataObject target = new DataObject();
|
||||||
foreach (var property in sourceObject.Properties())
|
foreach (var property in sourceObject.Properties())
|
||||||
{
|
{
|
||||||
@@ -151,7 +181,7 @@ namespace UVC.Data
|
|||||||
// 중첩된 객체 처리
|
// 중첩된 객체 처리
|
||||||
if (sourceValue.Type == JTokenType.Object && maskValue.Type == JTokenType.Object)
|
if (sourceValue.Type == JTokenType.Object && maskValue.Type == JTokenType.Object)
|
||||||
{
|
{
|
||||||
target[property.Name] = MapObject((JObject)sourceValue, (JObject)maskValue);
|
target[property.Name] = MapObject((JObject)sourceValue, (JObject)maskValue, depth + 1);
|
||||||
}
|
}
|
||||||
// 중첩된 배열 처리
|
// 중첩된 배열 처리
|
||||||
else if (sourceValue.Type == JTokenType.Array && maskValue.Type == JTokenType.Array)
|
else if (sourceValue.Type == JTokenType.Array && maskValue.Type == JTokenType.Array)
|
||||||
@@ -166,7 +196,7 @@ namespace UVC.Data
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
continue; // 가이드에 없는 속성은 무시
|
continue; // Mask에 없는 속성은 무시
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return target;
|
return target;
|
||||||
@@ -175,6 +205,12 @@ namespace UVC.Data
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// JToken을 실제 객체로 변환하는 헬퍼 메서드
|
/// JToken을 실제 객체로 변환하는 헬퍼 메서드
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="token">변환할 JToken 객체</param>
|
||||||
|
/// <returns>변환된 .NET 객체</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// 이 메서드는 JToken의 타입에 따라 적절한 .NET 타입의 객체로 변환합니다.
|
||||||
|
/// 객체는 DataObject로, 배열은 DataArray로 변환되며, 기본 타입은 해당하는 .NET 타입으로 변환됩니다.
|
||||||
|
/// </remarks>
|
||||||
private object ConvertJTokenToObject(JToken token)
|
private object ConvertJTokenToObject(JToken token)
|
||||||
{
|
{
|
||||||
switch (token.Type)
|
switch (token.Type)
|
||||||
@@ -209,13 +245,14 @@ namespace UVC.Data
|
|||||||
/// 배열을 재귀적으로 매핑합니다.
|
/// 배열을 재귀적으로 매핑합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sourceArray">원본 JSON 배열</param>
|
/// <param name="sourceArray">원본 JSON 배열</param>
|
||||||
/// <param name="maskArray">가이드 JSON 배열</param>
|
/// <param name="maskArray">Mask JSON 배열</param>
|
||||||
/// <returns>매핑된 DataArray 객체</returns>
|
/// <returns>매핑된 DataArray 객체</returns>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 가이드 배열이 비어있으면, 원본 배열의 각 항목을 DataObject로 변환하여 복사합니다.
|
/// Mask 배열이 비어있으면, 원본 배열의 각 항목을 DataObject로 변환하여 복사합니다.
|
||||||
/// 단순 값(문자열, 숫자 등)은 "value" 키를 가진 DataObject로 래핑됩니다.
|
/// 단순 값(문자열, 숫자 등)은 "value" 키를 가진 DataObject로 래핑됩니다.
|
||||||
///
|
///
|
||||||
/// 가이드 배열이 비어있지 않으면, 가이드 배열의 첫 번째 항목을 템플릿으로 사용하여
|
/// Mask 배열이 비어있지 않으면, Mask 배열의 첫 번째 항목을 템플릿으로 사용하고
|
||||||
|
/// 하나 이상인 경우 Mask 배열 개수에 맞춰 템플릿으로 사용(배열 길이가 3이고, 소스 배열 길이가 5일때, 소스배열 3까지만 매핑) 합니다.
|
||||||
/// 원본 배열의 각 항목을 매핑합니다. 중첩 배열은 "items" 키를 가진 DataObject로 래핑됩니다.
|
/// 원본 배열의 각 항목을 매핑합니다. 중첩 배열은 "items" 키를 가진 DataObject로 래핑됩니다.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <example>
|
/// <example>
|
||||||
@@ -241,9 +278,41 @@ namespace UVC.Data
|
|||||||
/// </example>
|
/// </example>
|
||||||
private DataArray MapArray(JArray sourceArray, JArray maskArray)
|
private DataArray MapArray(JArray sourceArray, JArray maskArray)
|
||||||
{
|
{
|
||||||
DataArray targetArray = new DataArray();
|
// 빠른 초기 크기 할당으로 재할당 방지
|
||||||
|
DataArray targetArray = new DataArray(sourceArray.Count);
|
||||||
|
|
||||||
// 가이드 배열이 비어있으면 원본 배열을 그대로 사용
|
// 특정 크기 이상일 경우 병렬 처리 적용
|
||||||
|
if (sourceArray.Count > 1000 && maskArray.Count <= 1)
|
||||||
|
{
|
||||||
|
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount };
|
||||||
|
|
||||||
|
// 배열을 병렬로 처리하되, 순서 유지
|
||||||
|
var results = new DataObject[sourceArray.Count];
|
||||||
|
|
||||||
|
Parallel.For(0, sourceArray.Count, parallelOptions, i =>
|
||||||
|
{
|
||||||
|
var sourceItem = sourceArray[i];
|
||||||
|
var maskTemplate = maskArray.Count > 0 ? maskArray[0] : null;
|
||||||
|
|
||||||
|
if (sourceItem.Type == JTokenType.Object && maskTemplate != null && maskTemplate.Type == JTokenType.Object)
|
||||||
|
{
|
||||||
|
results[i] = MapObject((JObject)sourceItem, (JObject)maskTemplate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 단순 값 처리...
|
||||||
|
var dataObject = new DataObject();
|
||||||
|
dataObject.Add("value", ConvertJTokenToObject(sourceItem));
|
||||||
|
results[i] = dataObject;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 결과를 순서대로 추가
|
||||||
|
targetArray.AddRange(results);
|
||||||
|
return targetArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mask 배열이 비어있으면 원본 배열을 그대로 사용
|
||||||
if (maskArray.Count == 0)
|
if (maskArray.Count == 0)
|
||||||
{
|
{
|
||||||
foreach (JToken sourceItem in sourceArray)
|
foreach (JToken sourceItem in sourceArray)
|
||||||
@@ -263,7 +332,7 @@ namespace UVC.Data
|
|||||||
return targetArray;
|
return targetArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 가이드 배열 개수가 1개면 1개만 템플릿으로 사용
|
// Mask 배열 개수가 1개면 1개만 템플릿으로 사용
|
||||||
JToken maskTemplate = maskArray.First;
|
JToken maskTemplate = maskArray.First;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
foreach (JToken sourceItem in sourceArray)
|
foreach (JToken sourceItem in sourceArray)
|
||||||
@@ -276,7 +345,7 @@ namespace UVC.Data
|
|||||||
}
|
}
|
||||||
else if (idx >= maskArray.Count)
|
else if (idx >= maskArray.Count)
|
||||||
{
|
{
|
||||||
continue; // 가이드 배열의 범위를 벗어나면 무시
|
continue; // Mask 배열의 범위를 벗어나면 무시
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,10 +379,10 @@ namespace UVC.Data
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="propertyName">속성 이름</param>
|
/// <param name="propertyName">속성 이름</param>
|
||||||
/// <param name="sourceValue">매핑할 원본 값</param>
|
/// <param name="sourceValue">매핑할 원본 값</param>
|
||||||
/// <param name="maskValue">타입을 결정하는 가이드 값</param>
|
/// <param name="maskValue">타입을 결정하는 Mask 값</param>
|
||||||
/// <param name="target">값을 추가할 대상 DataObject</param>
|
/// <param name="target">값을 추가할 대상 DataObject</param>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 이 메서드는 가이드 값의 타입에 따라 원본 값을 적절한 타입으로 변환합니다.
|
/// 이 메서드는 Mask 값의 타입에 따라 원본 값을 적절한 타입으로 변환합니다.
|
||||||
///
|
///
|
||||||
/// 지원되는 타입:
|
/// 지원되는 타입:
|
||||||
/// - 문자열 (JTokenType.String)
|
/// - 문자열 (JTokenType.String)
|
||||||
@@ -322,7 +391,7 @@ namespace UVC.Data
|
|||||||
/// - 불리언 (JTokenType.Boolean)
|
/// - 불리언 (JTokenType.Boolean)
|
||||||
/// - 날짜/시간 (JTokenType.Date)
|
/// - 날짜/시간 (JTokenType.Date)
|
||||||
/// - 열거형 (Enum)
|
/// - 열거형 (Enum)
|
||||||
/// - DataValueMapper (문자열 매핑 딕셔너리)
|
/// - DataMap (문자열 매핑 딕셔너리)
|
||||||
///
|
///
|
||||||
/// 타입 변환이 불가능한 경우 원본 값이 그대로 사용됩니다.
|
/// 타입 변환이 불가능한 경우 원본 값이 그대로 사용됩니다.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
@@ -338,7 +407,7 @@ namespace UVC.Data
|
|||||||
/// ""status"": ""Active""
|
/// ""status"": ""Active""
|
||||||
/// }");
|
/// }");
|
||||||
///
|
///
|
||||||
/// // 가이드 객체 설정 (열거형 포함)
|
/// // Mask 객체 설정 (열거형 포함)
|
||||||
/// var maskJson = new JObject();
|
/// var maskJson = new JObject();
|
||||||
/// maskJson["name"] = "";
|
/// maskJson["name"] = "";
|
||||||
/// maskJson["age"] = 0;
|
/// maskJson["age"] = 0;
|
||||||
@@ -354,23 +423,35 @@ namespace UVC.Data
|
|||||||
/// </example>
|
/// </example>
|
||||||
private void MapProperty(string propertyName, JToken sourceValue, JToken maskValue, DataObject target)
|
private void MapProperty(string propertyName, JToken sourceValue, JToken maskValue, DataObject target)
|
||||||
{
|
{
|
||||||
if (maskValue.Type == JTokenType.String && sourceValue.Type == JTokenType.String)
|
|
||||||
|
// 소스 값이 널이면 바로 널 설정
|
||||||
|
if (sourceValue.Type == JTokenType.Null)
|
||||||
{
|
{
|
||||||
|
target[propertyName] = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourceValue.Type == maskValue.Type)
|
||||||
|
{
|
||||||
|
switch (sourceValue.Type)
|
||||||
|
{
|
||||||
|
case JTokenType.String:
|
||||||
target[propertyName] = sourceValue.ToObject<string>();
|
target[propertyName] = sourceValue.ToObject<string>();
|
||||||
}
|
return;
|
||||||
else if (maskValue.Type == JTokenType.Integer && sourceValue.Type == JTokenType.Integer)
|
case JTokenType.Integer:
|
||||||
{
|
|
||||||
target[propertyName] = sourceValue.ToObject<int>();
|
target[propertyName] = sourceValue.ToObject<int>();
|
||||||
}
|
return;
|
||||||
else if (maskValue.Type == JTokenType.Float && sourceValue.Type == JTokenType.Float)
|
case JTokenType.Float:
|
||||||
{
|
|
||||||
target[propertyName] = sourceValue.ToObject<double>();
|
target[propertyName] = sourceValue.ToObject<double>();
|
||||||
}
|
return;
|
||||||
else if (maskValue.Type == JTokenType.Boolean && sourceValue.Type == JTokenType.Boolean)
|
case JTokenType.Boolean:
|
||||||
{
|
|
||||||
target[propertyName] = sourceValue.ToObject<bool>();
|
target[propertyName] = sourceValue.ToObject<bool>();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (maskValue.Type == JTokenType.Date && sourceValue.Type == JTokenType.String)
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (maskValue.Type == JTokenType.Date && sourceValue.Type == JTokenType.String)
|
||||||
{
|
{
|
||||||
string dateStr = sourceValue.ToObject<string>();
|
string dateStr = sourceValue.ToObject<string>();
|
||||||
if (DateTime.TryParse(dateStr, out DateTime dateValue))
|
if (DateTime.TryParse(dateStr, out DateTime dateValue))
|
||||||
@@ -391,14 +472,14 @@ namespace UVC.Data
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 먼저 DataValueMapper로 변환 시도
|
// 먼저 DataMap로 변환 시도
|
||||||
var dataValueMapper = maskValue.ToObject<DataValueMapper>();
|
var DataMap = maskValue.ToObject<DataMap>();
|
||||||
if (dataValueMapper != null)
|
if (DataMap != null)
|
||||||
{
|
{
|
||||||
string strValue = sourceValue.ToObject<string>();
|
string strValue = sourceValue.ToObject<string>();
|
||||||
if (dataValueMapper.ContainsKey(strValue))
|
if (DataMap.ContainsKey(strValue))
|
||||||
{
|
{
|
||||||
target[propertyName] = dataValueMapper[strValue];
|
target[propertyName] = DataMap[strValue];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -407,7 +488,7 @@ namespace UVC.Data
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// DataValueMapper가 아니면 소스 값 그대로 사용
|
// DataMap가 아니면 소스 값 그대로 사용
|
||||||
target[propertyName] = sourceValue.ToObject<object>();
|
target[propertyName] = sourceValue.ToObject<object>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
#nullable enable
|
||||||
|
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace UVC.Data
|
namespace UVC.Data
|
||||||
{
|
{
|
||||||
@@ -10,15 +13,23 @@ namespace UVC.Data
|
|||||||
// 직접적인 변경이 있었던 키를 저장하는 리스트
|
// 직접적인 변경이 있었던 키를 저장하는 리스트
|
||||||
protected List<string> changedProperies = new List<string>();
|
protected List<string> changedProperies = new List<string>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 변경된 속성의 키 목록을 읽기 전용으로 반환합니다.
|
||||||
|
/// </summary>
|
||||||
public ReadOnlyCollection<string> ChangedProperies => changedProperies.AsReadOnly();
|
public ReadOnlyCollection<string> ChangedProperies => changedProperies.AsReadOnly();
|
||||||
|
|
||||||
// 기존에 있던 속성 키를 추적하기 위한 집합
|
// 기존에 있던 속성 키를 추적하기 위한 집합
|
||||||
private HashSet<string> existingProperties = new HashSet<string>();
|
private HashSet<string> existingProperties = new HashSet<string>();
|
||||||
|
|
||||||
public DataObject()
|
/// <summary>
|
||||||
{
|
/// 기본 생성자입니다. 빈 데이터 객체를 생성합니다.
|
||||||
}
|
/// </summary>
|
||||||
|
public DataObject() {}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// JObject로부터 데이터 객체를 생성합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="other">복사할 JObject 객체</param>
|
||||||
public DataObject(JObject other)
|
public DataObject(JObject other)
|
||||||
{
|
{
|
||||||
// JObject로부터 속성을 복사
|
// JObject로부터 속성을 복사
|
||||||
@@ -30,7 +41,10 @@ namespace UVC.Data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dictionary로 초기화하는 생성자 추가
|
/// <summary>
|
||||||
|
/// Dictionary로 데이터 객체를 초기화합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dictionary">초기화에 사용할 Dictionary 객체</param>
|
||||||
public DataObject(Dictionary<string, object> dictionary) : base(dictionary)
|
public DataObject(Dictionary<string, object> dictionary) : base(dictionary)
|
||||||
{
|
{
|
||||||
// 생성자에서 초기 속성들을 기존 속성으로 등록
|
// 생성자에서 초기 속성들을 기존 속성으로 등록
|
||||||
@@ -40,7 +54,11 @@ namespace UVC.Data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// JToken을 실제 객체로 변환하는 헬퍼 메서드
|
/// <summary>
|
||||||
|
/// JToken을 적절한 C# 객체 타입으로 변환하는 헬퍼 메서드입니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="token">변환할 JToken 객체</param>
|
||||||
|
/// <returns>변환된 C# 객체</returns>
|
||||||
private object ConvertJTokenToObject(JToken token)
|
private object ConvertJTokenToObject(JToken token)
|
||||||
{
|
{
|
||||||
switch (token.Type)
|
switch (token.Type)
|
||||||
@@ -65,28 +83,20 @@ namespace UVC.Data
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 모든 프로퍼티를 변경된 것으로 표시합니다.
|
/// 모든 프로퍼티를 변경된 것으로 표시합니다.
|
||||||
|
/// 전체 데이터가 갱신되었을 때 사용합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ChangeAll()
|
public void InitData()
|
||||||
{
|
{
|
||||||
changedProperies.Clear();
|
changedProperies.Clear();
|
||||||
|
changedProperies.AddRange(this.Keys);
|
||||||
foreach (var key in this.Keys)
|
|
||||||
{
|
|
||||||
changedProperies.Add(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 변경된 키 목록을 초기화합니다.
|
|
||||||
/// </summary>
|
|
||||||
public void ClearChangedKeys()
|
|
||||||
{
|
|
||||||
changedProperies.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 속성이 변경될 때 호출되는 메서드입니다.
|
/// 속성이 변경될 때 호출되는 메서드입니다.
|
||||||
|
/// 파생 클래스에서 오버라이드하여 추가 동작을 정의할 수 있습니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="propertyName">변경된 속성의 이름</param>
|
||||||
protected virtual void OnPropertyChanged(string propertyName)
|
protected virtual void OnPropertyChanged(string propertyName)
|
||||||
{
|
{
|
||||||
// 기존에 존재하던 속성인 경우에만 변경된 것으로 추적
|
// 기존에 존재하던 속성인 경우에만 변경된 것으로 추적
|
||||||
@@ -107,6 +117,8 @@ namespace UVC.Data
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 새 속성을 추가할 때 이벤트 연결을 처리합니다.
|
/// 새 속성을 추가할 때 이벤트 연결을 처리합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="propertyName">추가할 속성의 이름</param>
|
||||||
|
/// <param name="value">속성의 값</param>
|
||||||
public new void Add(string propertyName, object value)
|
public new void Add(string propertyName, object value)
|
||||||
{
|
{
|
||||||
// 추가하기 전에 확인 - 속성이 이미 있는지 확인
|
// 추가하기 전에 확인 - 속성이 이미 있는지 확인
|
||||||
@@ -124,6 +136,7 @@ namespace UVC.Data
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 인덱서를 통한 속성 설정을 처리합니다.
|
/// 인덱서를 통한 속성 설정을 처리합니다.
|
||||||
|
/// 속성 변경 시 변경 사항을 자동으로 추적합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public new object this[string key]
|
public new object this[string key]
|
||||||
{
|
{
|
||||||
@@ -154,6 +167,7 @@ namespace UVC.Data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int GetInt(string propertyName, int defaultValue = 0)
|
public int GetInt(string propertyName, int defaultValue = 0)
|
||||||
{
|
{
|
||||||
if (TryGetValue(propertyName, out object value) && value != null)
|
if (TryGetValue(propertyName, out object value) && value != null)
|
||||||
@@ -165,7 +179,7 @@ namespace UVC.Data
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetString(string propertyName, string defaultValue = "")
|
public string? GetString(string propertyName, string? defaultValue = null)
|
||||||
{
|
{
|
||||||
if (TryGetValue(propertyName, out object value) && value != null)
|
if (TryGetValue(propertyName, out object value) && value != null)
|
||||||
{
|
{
|
||||||
@@ -229,7 +243,7 @@ namespace UVC.Data
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataArray GetDataArray(string propertyName, DataArray? defaultValue = null)
|
public DataArray? GetDataArray(string propertyName, DataArray? defaultValue = null)
|
||||||
{
|
{
|
||||||
if (TryGetValue(propertyName, out object value) && value != null)
|
if (TryGetValue(propertyName, out object value) && value != null)
|
||||||
{
|
{
|
||||||
@@ -241,7 +255,7 @@ namespace UVC.Data
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataObject GetDataObject(string propertyName, DataObject? defaultValue = null)
|
public DataObject? GetDataObject(string propertyName, DataObject? defaultValue = null)
|
||||||
{
|
{
|
||||||
if (TryGetValue(propertyName, out object value) && value != null)
|
if (TryGetValue(propertyName, out object value) && value != null)
|
||||||
{
|
{
|
||||||
@@ -258,6 +272,8 @@ namespace UVC.Data
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 속성이 제거될 때 기존 속성 목록에서도 제거합니다.
|
/// 속성이 제거될 때 기존 속성 목록에서도 제거합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="key">제거할 속성의 키</param>
|
||||||
|
/// <returns>제거 성공 여부</returns>
|
||||||
public new bool Remove(string key)
|
public new bool Remove(string key)
|
||||||
{
|
{
|
||||||
bool result = base.Remove(key);
|
bool result = base.Remove(key);
|
||||||
@@ -280,8 +296,9 @@ namespace UVC.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// JObject로 변환
|
/// 현재 DataObject를 JObject로 변환합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <returns>현재 객체의 데이터를 담은 JObject</returns>
|
||||||
public JObject ToJObject()
|
public JObject ToJObject()
|
||||||
{
|
{
|
||||||
JObject result = new JObject();
|
JObject result = new JObject();
|
||||||
@@ -292,10 +309,16 @@ namespace UVC.Data
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDifferent(DataObject other)
|
/// <summary>
|
||||||
|
/// 다른 DataObject와 현재 객체를 비교하여 다른 부분만 설정합니다.
|
||||||
|
/// 변경된 키는 자동으로 추적됩니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="other">비교할 DataObject</param>
|
||||||
|
public void UpdateDifferent(IDataObject other)
|
||||||
{
|
{
|
||||||
|
if (other == null || other is not DataObject) return;
|
||||||
changedProperies.Clear();
|
changedProperies.Clear();
|
||||||
foreach (var keyValue in other)
|
foreach (var keyValue in (DataObject)other)
|
||||||
{
|
{
|
||||||
if(!this.ContainsKey(keyValue.Key) || !this[keyValue.Key].Equals(keyValue.Value))
|
if(!this.ContainsKey(keyValue.Key) || !this[keyValue.Key].Equals(keyValue.Value))
|
||||||
{
|
{
|
||||||
@@ -304,6 +327,91 @@ namespace UVC.Data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 업데이트된 속성만 포함하는 새로운 DataObject를 반환합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>업데이트 된 항목만 가지고 있는 DataObject</returns>
|
||||||
|
public IDataObject GetUpdatedObject()
|
||||||
|
{
|
||||||
|
DataObject updated = new DataObject();
|
||||||
|
foreach (var key in changedProperies)
|
||||||
|
{
|
||||||
|
if (this.ContainsKey(key))
|
||||||
|
{
|
||||||
|
updated[key] = this[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Join(", ", this.Select(kvp => $"{kvp.Key}:{kvp.Value}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DataObject 인스턴스를 재사용하기 위한 객체 풀 클래스입니다.
|
||||||
|
/// 메모리 할당과 가비지 컬렉션을 최소화하기 위해 DataObject 인스턴스를 관리합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 객체 풀링은 자주 생성 및 삭제되는 객체의 성능을 향상시키는 패턴입니다.
|
||||||
|
/// 사용이 끝난 객체를 삭제하는 대신 풀에 반환하고, 새 객체가 필요할 때 풀에서 꺼내 재사용합니다.
|
||||||
|
/// </remarks>
|
||||||
|
/// <example>
|
||||||
|
/// <code>
|
||||||
|
/// // 객체 풀에서 DataObject 가져오기
|
||||||
|
/// DataObject obj = DataObjectPool.GetDataObjectFromPool();
|
||||||
|
///
|
||||||
|
/// // 객체 사용
|
||||||
|
/// obj["name"] = "홍길동";
|
||||||
|
/// obj["age"] = 30;
|
||||||
|
///
|
||||||
|
/// // 작업 완료 후 풀에 반환
|
||||||
|
/// DataObjectPool.ReturnToPool(obj);
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
public static class DataObjectPool
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// DataObject 인스턴스를 저장하는 큐입니다.
|
||||||
|
/// </summary>
|
||||||
|
private static Queue<DataObject> dataObjectPool = new Queue<DataObject>();
|
||||||
|
/// <summary>
|
||||||
|
/// 풀의 최대 크기입니다. 이 크기를 초과하는 객체는 풀에 저장되지 않습니다.
|
||||||
|
/// </summary>
|
||||||
|
private static int maxPoolSize = 1000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 풀에서 DataObject 인스턴스를 가져옵니다.
|
||||||
|
/// 풀이 비어있으면 새 인스턴스를 생성하여 반환합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>재사용 가능한 DataObject 인스턴스</returns>
|
||||||
|
public static DataObject GetDataObjectFromPool()
|
||||||
|
{
|
||||||
|
if (dataObjectPool.Count > 0)
|
||||||
|
{
|
||||||
|
return dataObjectPool.Dequeue();
|
||||||
|
}
|
||||||
|
return new DataObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 사용이 완료된 DataObject를 풀에 반환합니다.
|
||||||
|
/// 객체는 반환 전에 초기화되어 모든 속성이 제거됩니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">풀에 반환할 DataObject 인스턴스</param>
|
||||||
|
public static void ReturnToPool(DataObject obj)
|
||||||
|
{
|
||||||
|
if (obj != null && dataObjectPool.Count < maxPoolSize)
|
||||||
|
{
|
||||||
|
obj.RemoveAll(); // 재사용 전 정리
|
||||||
|
dataObjectPool.Enqueue(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -11,21 +11,26 @@ namespace UVC.Data
|
|||||||
public static DataRepository Instance { get { return instance.Value; } }
|
public static DataRepository Instance { get { return instance.Value; } }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private Dictionary<string, DataObject> dataObjects = new Dictionary<string, DataObject>();
|
private Dictionary<string, IDataObject> dataObjects = new Dictionary<string, IDataObject>();
|
||||||
|
|
||||||
public void AddData(string key, DataObject dataObject)
|
public IDataObject AddData(string key, IDataObject dataObject)
|
||||||
{
|
{
|
||||||
if (!dataObjects.ContainsKey(key))
|
if (!dataObjects.ContainsKey(key))
|
||||||
{
|
{
|
||||||
dataObject.ChangeAll();
|
dataObject.InitData();
|
||||||
dataObjects.Add(key, dataObject);
|
dataObjects.Add(key, dataObject);
|
||||||
|
return dataObject;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DataObject obj = dataObjects[key];
|
IDataObject obj = dataObjects[key];
|
||||||
obj.SetDifferent(obj);
|
obj.UpdateDifferent(dataObject);
|
||||||
|
return obj.GetUpdatedObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void RemoveData(string key)
|
public void RemoveData(string key)
|
||||||
{
|
{
|
||||||
if (dataObjects.ContainsKey(key))
|
if (dataObjects.ContainsKey(key))
|
||||||
@@ -33,7 +38,7 @@ namespace UVC.Data
|
|||||||
dataObjects.Remove(key);
|
dataObjects.Remove(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public DataObject GetData(string key)
|
public IDataObject GetData(string key)
|
||||||
{
|
{
|
||||||
if (dataObjects.ContainsKey(key))
|
if (dataObjects.ContainsKey(key))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace UVC.Data
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// DataMapper에서 사용되는 데이터 값 매핑을 위한 클래스입니다.
|
|
||||||
/// </summary>
|
|
||||||
public class DataValueMapper : Dictionary<string, string>{}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
#nullable enable
|
||||||
|
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UVC.Network;
|
using UVC.Network;
|
||||||
|
|
||||||
@@ -34,18 +36,24 @@ namespace UVC.Data
|
|||||||
HttpPipeLineInfo info = infoList[key];
|
HttpPipeLineInfo info = infoList[key];
|
||||||
|
|
||||||
string result = await HttpRequester.Request<string>(info.url, info.method, info.body, info.headers);
|
string result = await HttpRequester.Request<string>(info.url, info.method, info.body, info.headers);
|
||||||
JObject jsonResult = JObject.Parse(result);
|
|
||||||
DataObject dataObject = new DataObject(jsonResult);
|
|
||||||
|
|
||||||
if (info.dataMapper != null)
|
IDataObject? dataObject = null;
|
||||||
|
if (!string.IsNullOrEmpty(result))
|
||||||
{
|
{
|
||||||
dataObject = info.dataMapper.Map(jsonResult);
|
result = result.Trim();
|
||||||
}
|
if (result.StartsWith("{"))
|
||||||
DataRepository.Instance.AddData(key, dataObject);
|
|
||||||
if (info.handler != null)
|
|
||||||
{
|
{
|
||||||
info.handler(dataObject);
|
JObject source = JObject.Parse(result);
|
||||||
|
if (info.dataMapper != null) dataObject = info.dataMapper.Mapping(source);
|
||||||
}
|
}
|
||||||
|
else if(result.StartsWith("["))
|
||||||
|
{
|
||||||
|
JArray source = JArray.Parse(result);
|
||||||
|
if (info.dataMapper != null) dataObject = info.dataMapper.Mapping(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(dataObject != null) dataObject = DataRepository.Instance.AddData(key, dataObject);
|
||||||
|
info.handler?.Invoke(dataObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
#nullable enable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
@@ -8,16 +9,16 @@ namespace UVC.Data
|
|||||||
{
|
{
|
||||||
public string url;
|
public string url;
|
||||||
public string method;
|
public string method;
|
||||||
public Dictionary<string, string> headers;
|
public Dictionary<string, string>? headers = null;
|
||||||
public string body;
|
public string? body = null;
|
||||||
public Action<IDataObject> handler = null;
|
public Action<IDataObject?>? handler = null;
|
||||||
public bool repeat = false; // 반복 실행 여부
|
public bool repeat = false; // 반복 실행 여부
|
||||||
public int repeatCount = 0; // 반복 횟수, 0은 무한 반복
|
public int repeatCount = 0; // 반복 횟수, 0은 무한 반복
|
||||||
public int repeatInterval = 1000; // 반복 간격 (ms)
|
public int repeatInterval = 1000; // 반복 간격 (ms)
|
||||||
|
|
||||||
public DataMapper dataMapper = null; // 데이터 매퍼
|
public DataMapper? dataMapper = null; // 데이터 매퍼
|
||||||
|
|
||||||
public HttpPipeLineInfo(string url, string method = "post", Dictionary<string, string> headers = null, string body = null)
|
public HttpPipeLineInfo(string url, string method = "post", Dictionary<string, string>? headers = null, string? body = null)
|
||||||
{
|
{
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
|
|||||||
@@ -1,6 +1,19 @@
|
|||||||
namespace UVC.Data
|
namespace UVC.Data
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 서로 다른 JSON 데이터 구조 간에 매핑 기능을 제공하는 클래스입니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// ...
|
||||||
|
/// 이 클래스는 IDataObject 인터페이스를 구현한 DataObject와 DataArray로
|
||||||
|
/// 데이터를 변환하여 통일된 방식으로 접근할 수 있도록 합니다.
|
||||||
|
/// </remarks>
|
||||||
public interface IDataObject
|
public interface IDataObject
|
||||||
{
|
{
|
||||||
|
public void InitData();
|
||||||
|
|
||||||
|
public void UpdateDifferent(IDataObject other);
|
||||||
|
|
||||||
|
public IDataObject GetUpdatedObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,74 @@
|
|||||||
using System.Collections.Generic;
|
#nullable enable
|
||||||
|
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using SampleProject.Config;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
using UVC.network;
|
||||||
|
|
||||||
namespace UVC.Data
|
namespace UVC.Data
|
||||||
{
|
{
|
||||||
public class MQTTPipeLine
|
public class MQTTPipeLine
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private Dictionary<string, MQTTPipeLineInfo> infoList = new Dictionary<string, MQTTPipeLineInfo>();
|
||||||
|
|
||||||
|
private MQTTService mqtt = new MQTTService(Constants.MQTT_DOMAIN, Constants.MQTT_PORT);
|
||||||
|
|
||||||
|
|
||||||
|
public void Add(MQTTPipeLineInfo info)
|
||||||
|
{
|
||||||
|
if (!infoList.ContainsKey(info.topic))
|
||||||
|
{
|
||||||
|
infoList.Add(info.topic, info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
infoList[info.topic] = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Remove(string topic)
|
||||||
|
{
|
||||||
|
if (infoList.ContainsKey(topic))
|
||||||
|
{
|
||||||
|
infoList.Remove(topic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute()
|
||||||
|
{
|
||||||
|
foreach (var topic in infoList.Keys)
|
||||||
|
{
|
||||||
|
mqtt.AddTopicHandler(topic, OnTopicMessage);
|
||||||
|
}
|
||||||
|
mqtt.Connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTopicMessage(string topic, string message)
|
||||||
|
{
|
||||||
|
if (infoList.ContainsKey(topic))
|
||||||
|
{
|
||||||
|
MQTTPipeLineInfo info = infoList[topic];
|
||||||
|
IDataObject? dataObject = null;
|
||||||
|
if (!string.IsNullOrEmpty(message))
|
||||||
|
{
|
||||||
|
message = message.Trim();
|
||||||
|
if (message.StartsWith("{"))
|
||||||
|
{
|
||||||
|
JObject source = JObject.Parse(message);
|
||||||
|
if (info.dataMapper != null) dataObject = info.dataMapper.Mapping(source);
|
||||||
|
}
|
||||||
|
else if (message.StartsWith("["))
|
||||||
|
{
|
||||||
|
JArray source = JArray.Parse(message);
|
||||||
|
if (info.dataMapper != null) dataObject = info.dataMapper.Mapping(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dataObject != null) dataObject = DataRepository.Instance.AddData(topic, dataObject);
|
||||||
|
|
||||||
|
info.handler?.Invoke(dataObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace UVC.Data
|
namespace UVC.Data
|
||||||
{
|
{
|
||||||
public class MQTTPipeLineInfo
|
public class MQTTPipeLineInfo
|
||||||
{
|
{
|
||||||
public string topic; // MQTT 토픽
|
public string topic; // MQTT 토픽
|
||||||
public Action<DataObject> handler = null; // 메시지 핸들러
|
public Action<IDataObject?>? handler = null; // 메시지 핸들러
|
||||||
public DataMapper dataMapper = null; // 데이터 매퍼
|
public DataMapper? dataMapper = null; // 데이터 매퍼
|
||||||
|
|
||||||
public MQTTPipeLineInfo(string topic)
|
public MQTTPipeLineInfo(string topic)
|
||||||
{
|
{
|
||||||
this.topic = topic;
|
this.topic = topic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MQTTPipeLineInfo setHandler(Action<DataObject> handler)
|
public MQTTPipeLineInfo setHandler(Action<IDataObject?> handler)
|
||||||
{
|
{
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#nullable enable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using System;
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Serialization.Formatters.Binary;
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#nullable enable
|
||||||
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace UVC.Extension
|
namespace UVC.Extension
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#nullable enable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -63,7 +65,7 @@ namespace UVC.Linq
|
|||||||
/// <param name="setActive">자식 GameObject의 활성/비활성 상태를 설정합니다. null이면 지정된 값을 설정하지 않습니다.</param>
|
/// <param name="setActive">자식 GameObject의 활성/비활성 상태를 설정합니다. null이면 지정된 값을 설정하지 않습니다.</param>
|
||||||
/// <param name="specifiedName">자식 GameObject의 이름을 설정합니다. null이면 지정된 값을 설정하지 않습니다.</param>
|
/// <param name="specifiedName">자식 GameObject의 이름을 설정합니다. null이면 지정된 값을 설정하지 않습니다.</param>
|
||||||
/// <param name="setLayer">자식 GameObject의 레이어를 부모와 동일하게 설정할지 여부입니다.</param>
|
/// <param name="setLayer">자식 GameObject의 레이어를 부모와 동일하게 설정할지 여부입니다.</param>
|
||||||
public static T Add<T>(this GameObject parent, T childOriginal, TransformCloneType cloneType = TransformCloneType.KeepOriginal, bool? setActive = null, string specifiedName = null, bool setLayer = false)
|
public static T Add<T>(this GameObject parent, T childOriginal, TransformCloneType cloneType = TransformCloneType.KeepOriginal, bool? setActive = null, string? specifiedName = null, bool setLayer = false)
|
||||||
where T : UnityEngine.Object
|
where T : UnityEngine.Object
|
||||||
{
|
{
|
||||||
if (parent == null) throw new ArgumentNullException("parent");
|
if (parent == null) throw new ArgumentNullException("parent");
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
using log4net.Appender;
|
#nullable enable
|
||||||
|
|
||||||
|
using log4net.Appender;
|
||||||
using log4net.Core;
|
using log4net.Core;
|
||||||
using SQLite4Unity3d;
|
using SQLite4Unity3d;
|
||||||
using System;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using UVC.Extention;
|
using UVC.Extention;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using SQLite4Unity3d;
|
#nullable enable
|
||||||
|
|
||||||
|
using SQLite4Unity3d;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -98,7 +100,7 @@ namespace UVC.Log
|
|||||||
/// <param name="date">메시지가 수신된 날짜와 시간(문자열 형식)입니다.</param>
|
/// <param name="date">메시지가 수신된 날짜와 시간(문자열 형식)입니다.</param>
|
||||||
/// <param name="exception">처리 중 오류가 발생한 경우의 예외 메시지(옵션). <see langword="null"/>일 수 있습니다.</param>
|
/// <param name="exception">처리 중 오류가 발생한 경우의 예외 메시지(옵션). <see langword="null"/>일 수 있습니다.</param>
|
||||||
/// <returns>기록된 MQTT 메시지를 나타내는 <see cref="MqttLogEntry"/> 객체입니다.</returns>
|
/// <returns>기록된 MQTT 메시지를 나타내는 <see cref="MqttLogEntry"/> 객체입니다.</returns>
|
||||||
public static MqttLogEntry LogMqtt(string url, string port, string topic, string payload, string date, string exception = null)
|
public static MqttLogEntry LogMqtt(string url, string port, string topic, string payload, string date, string? exception = null)
|
||||||
{
|
{
|
||||||
var logEntry = new MqttLogEntry
|
var logEntry = new MqttLogEntry
|
||||||
{
|
{
|
||||||
@@ -111,7 +113,7 @@ namespace UVC.Log
|
|||||||
};
|
};
|
||||||
lock (_dbLock)
|
lock (_dbLock)
|
||||||
{
|
{
|
||||||
db.Insert(logEntry);
|
db?.Insert(logEntry);
|
||||||
return logEntry;
|
return logEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ namespace UVC.Tests.Data
|
|||||||
RunTest(nameof(Map_DoubleProperty_MapsCorrectly), Map_DoubleProperty_MapsCorrectly);
|
RunTest(nameof(Map_DoubleProperty_MapsCorrectly), Map_DoubleProperty_MapsCorrectly);
|
||||||
RunTest(nameof(Map_BoolProperty_MapsCorrectly), Map_BoolProperty_MapsCorrectly);
|
RunTest(nameof(Map_BoolProperty_MapsCorrectly), Map_BoolProperty_MapsCorrectly);
|
||||||
RunTest(nameof(Map_DateTimeProperty_MapsCorrectly), Map_DateTimeProperty_MapsCorrectly);
|
RunTest(nameof(Map_DateTimeProperty_MapsCorrectly), Map_DateTimeProperty_MapsCorrectly);
|
||||||
RunTest(nameof(Map_DataValueMapperProperty_MapsCorrectly), Map_DataValueMapperProperty_MapsCorrectly);
|
RunTest(nameof(Map_DataMapProperty_MapsCorrectly), Map_DataMapProperty_MapsCorrectly);
|
||||||
RunTest(nameof(Map_DataValueMapperWithUnmappedValue_ReturnsOriginal), Map_DataValueMapperWithUnmappedValue_ReturnsOriginal);
|
RunTest(nameof(Map_DataMapWithUnmappedValue_ReturnsOriginal), Map_DataMapWithUnmappedValue_ReturnsOriginal);
|
||||||
RunTest(nameof(Map_EnumProperty_MapsCorrectly), Map_EnumProperty_MapsCorrectly);
|
RunTest(nameof(Map_EnumProperty_MapsCorrectly), Map_EnumProperty_MapsCorrectly);
|
||||||
RunTest(nameof(Map_AdditionalProperty_AddsToResult), Map_AdditionalProperty_AddsToResult);
|
RunTest(nameof(Map_AdditionalProperty_AddsToResult), Map_AdditionalProperty_AddsToResult);
|
||||||
RunTest(nameof(Map_InvalidDateTimeString_ReturnsNull), Map_InvalidDateTimeString_ReturnsNull);
|
RunTest(nameof(Map_InvalidDateTimeString_ReturnsNull), Map_InvalidDateTimeString_ReturnsNull);
|
||||||
@@ -77,7 +77,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result.ContainsKey("Name"));
|
Assert.IsTrue(result.ContainsKey("Name"));
|
||||||
@@ -99,7 +99,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result.ContainsKey("Age"));
|
Assert.IsTrue(result.ContainsKey("Age"));
|
||||||
@@ -121,7 +121,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result.ContainsKey("Height"));
|
Assert.IsTrue(result.ContainsKey("Height"));
|
||||||
@@ -143,7 +143,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result.ContainsKey("IsActive"));
|
Assert.IsTrue(result.ContainsKey("IsActive"));
|
||||||
@@ -166,7 +166,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result.ContainsKey("BirthDate"));
|
Assert.IsTrue(result.ContainsKey("BirthDate"));
|
||||||
@@ -174,14 +174,14 @@ namespace UVC.Tests.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DataValueMapper 타입 매핑 테스트
|
/// DataMap 타입 매핑 테스트
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void Map_DataValueMapperProperty_MapsCorrectly()
|
public void Map_DataMapProperty_MapsCorrectly()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var mask = new JObject();
|
var mask = new JObject();
|
||||||
var valueMapper = new DataValueMapper();
|
var valueMapper = new DataMap();
|
||||||
valueMapper["ON"] = "활성화";
|
valueMapper["ON"] = "활성화";
|
||||||
valueMapper["OFF"] = "비활성화";
|
valueMapper["OFF"] = "비활성화";
|
||||||
mask["Status"] = JToken.FromObject(valueMapper);
|
mask["Status"] = JToken.FromObject(valueMapper);
|
||||||
@@ -191,7 +191,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result.ContainsKey("Status"));
|
Assert.IsTrue(result.ContainsKey("Status"));
|
||||||
@@ -199,14 +199,14 @@ namespace UVC.Tests.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DataValueMapper에 매핑되지 않는 값 처리 테스트
|
/// DataMap에 매핑되지 않는 값 처리 테스트
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void Map_DataValueMapperWithUnmappedValue_ReturnsOriginal()
|
public void Map_DataMapWithUnmappedValue_ReturnsOriginal()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var mask = new JObject();
|
var mask = new JObject();
|
||||||
var valueMapper = new DataValueMapper();
|
var valueMapper = new DataMap();
|
||||||
valueMapper["ON"] = "활성화";
|
valueMapper["ON"] = "활성화";
|
||||||
valueMapper["OFF"] = "비활성화";
|
valueMapper["OFF"] = "비활성화";
|
||||||
mask["Status"] = JToken.FromObject(valueMapper);
|
mask["Status"] = JToken.FromObject(valueMapper);
|
||||||
@@ -216,7 +216,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result.ContainsKey("Status"));
|
Assert.IsTrue(result.ContainsKey("Status"));
|
||||||
@@ -238,7 +238,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result.ContainsKey("Status"));
|
Assert.IsTrue(result.ContainsKey("Status"));
|
||||||
@@ -260,7 +260,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsFalse(result.ContainsKey("Email"));
|
Assert.IsFalse(result.ContainsKey("Email"));
|
||||||
@@ -282,7 +282,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result.ContainsKey("BirthDate"));
|
Assert.IsTrue(result.ContainsKey("BirthDate"));
|
||||||
@@ -318,7 +318,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.AreEqual(6, result.Count);
|
Assert.AreEqual(6, result.Count);
|
||||||
@@ -365,7 +365,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result.ContainsKey("User"));
|
Assert.IsTrue(result.ContainsKey("User"));
|
||||||
@@ -410,13 +410,13 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result.ContainsKey("Contacts"));
|
Assert.IsTrue(result.ContainsKey("Contacts"));
|
||||||
var contacts = result.GetDataArray("Contacts");
|
var contacts = result.GetDataArray("Contacts");
|
||||||
Assert.IsNotNull(contacts);
|
Assert.IsNotNull(contacts);
|
||||||
Assert.AreEqual(1, contacts.Count);
|
Assert.AreEqual(2, contacts.Count);
|
||||||
|
|
||||||
var contact1 = contacts[0];
|
var contact1 = contacts[0];
|
||||||
Assert.IsNotNull(contact1);
|
Assert.IsNotNull(contact1);
|
||||||
@@ -427,7 +427,7 @@ namespace UVC.Tests.Data
|
|||||||
Assert.IsNotNull(contact2);
|
Assert.IsNotNull(contact2);
|
||||||
Assert.AreEqual("home", contact2.GetString("Type"));
|
Assert.AreEqual("home", contact2.GetString("Type"));
|
||||||
Assert.AreEqual("02-123-4567", contact2.GetString("Number"));
|
Assert.AreEqual("02-123-4567", contact2.GetString("Number"));
|
||||||
Assert.AreEqual("123", contact2.GetString("Extension"));
|
Assert.AreEqual(null, contact2.GetString("Extension"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -449,7 +449,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result.ContainsKey("Tags"));
|
Assert.IsTrue(result.ContainsKey("Tags"));
|
||||||
@@ -526,14 +526,14 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var company = result.GetDataObject("Company");
|
var company = result.GetDataObject("Company");
|
||||||
Assert.IsNotNull(company);
|
Assert.IsNotNull(company);
|
||||||
Assert.AreEqual("XYZ 주식회사", company.GetString("Name"));
|
Assert.AreEqual("XYZ 주식회사", company.GetString("Name"));
|
||||||
Assert.AreEqual(new DateTime(2000, 1, 1), company.GetDateTime("Founded"));
|
Assert.AreEqual(new DateTime(2000, 1, 1), company.GetDateTime("Founded"));
|
||||||
Assert.AreEqual("서울시 강남구", company.GetString("Address"));
|
Assert.AreEqual(null, company.GetString("Address"));
|
||||||
|
|
||||||
var departments = company.GetDataArray("Departments");
|
var departments = company.GetDataArray("Departments");
|
||||||
Assert.IsNotNull(departments);
|
Assert.IsNotNull(departments);
|
||||||
@@ -551,7 +551,7 @@ namespace UVC.Tests.Data
|
|||||||
|
|
||||||
var marketingDept = departments[1];
|
var marketingDept = departments[1];
|
||||||
Assert.AreEqual("마케팅부", marketingDept.GetString("Name"));
|
Assert.AreEqual("마케팅부", marketingDept.GetString("Name"));
|
||||||
Assert.AreEqual(500000, marketingDept.GetInt("Budget"));
|
Assert.AreEqual(0, marketingDept.GetInt("Budget"));
|
||||||
var marketingEmployees = marketingDept.GetDataArray("Employees");
|
var marketingEmployees = marketingDept.GetDataArray("Employees");
|
||||||
Assert.AreEqual(1, marketingEmployees.Count);
|
Assert.AreEqual(1, marketingEmployees.Count);
|
||||||
Assert.AreEqual("박마케팅", marketingEmployees[0].GetString("Name"));
|
Assert.AreEqual("박마케팅", marketingEmployees[0].GetString("Name"));
|
||||||
@@ -590,7 +590,7 @@ namespace UVC.Tests.Data
|
|||||||
var mapper = new DataMapper(mask);
|
var mapper = new DataMapper(mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = mapper.Map(source);
|
var result = mapper.Mapping(source);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result.ContainsKey("MixedArray"));
|
Assert.IsTrue(result.ContainsKey("MixedArray"));
|
||||||
|
|||||||
Reference in New Issue
Block a user