그리드 표현 일부 완료. 데이터 검측 필수 예정
This commit is contained in:
73
SchemaEditor/Services/ExcelService.cs
Normal file
73
SchemaEditor/Services/ExcelService.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ExcelKv.Core;
|
||||
|
||||
namespace SchemaEditor.Services;
|
||||
|
||||
public record ParsedItem(string Key, string Value, int Row, int Col);
|
||||
|
||||
public class InMemoryStorage : IStorageWrapper
|
||||
{
|
||||
public ConcurrentDictionary<string, ParsedItem> Data { get; private set; } = new();
|
||||
|
||||
public Task SetAsync(string key, string value)
|
||||
{
|
||||
Data[key] = new ParsedItem(key, value, -1, -1);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task SetAsync(string key, string value, int row, int col)
|
||||
{
|
||||
Data[key] = new ParsedItem(key, value, row, col);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task IncrementAsync(string key, double value)
|
||||
{
|
||||
Data[key] = new ParsedItem(key, $"[Metric] {value} (Accumulated)", -1, -1);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public List<ParsedItem> GetEntries()
|
||||
{
|
||||
return Data.Values.OrderBy(x => x.Key).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public class ExcelService
|
||||
{
|
||||
// Changed to List<ParsedItem> for metadata access
|
||||
public List<ParsedItem> LoadedData { get; private set; } = new();
|
||||
|
||||
public async Task<List<string>> GetSheetsAsync(string filePath)
|
||||
{
|
||||
return await ExcelLoader.GetSheetNamesAsync(filePath);
|
||||
}
|
||||
|
||||
public async Task<List<string[]>> GetPreviewAsync(string filePath, string sheetName)
|
||||
{
|
||||
// Increased limit to 1000 to ensure highlighting works for larger files
|
||||
return await ExcelLoader.GetPreviewRowsAsync(filePath, sheetName, 1000);
|
||||
}
|
||||
|
||||
public async Task LoadFileAsync(string filePath, string sheetName, RegionConfig config)
|
||||
{
|
||||
var storage = new InMemoryStorage();
|
||||
var registry = new SchemaRegistry();
|
||||
|
||||
await ExcelLoader.ProcessFileAsync(filePath, sheetName, config, storage, registry);
|
||||
|
||||
LoadedData = storage.GetEntries();
|
||||
}
|
||||
|
||||
public async Task SaveToStorageAsync(IStorageWrapper targetStorage)
|
||||
{
|
||||
foreach (var entry in LoadedData)
|
||||
{
|
||||
await targetStorage.SetAsync(entry.Key, entry.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
68
SchemaEditor/Services/GarnetClientService.cs
Normal file
68
SchemaEditor/Services/GarnetClientService.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using StackExchange.Redis;
|
||||
using ExcelKv.Core;
|
||||
|
||||
namespace SchemaEditor.Services;
|
||||
|
||||
public class GarnetClientService : IStorageWrapper, IDisposable
|
||||
{
|
||||
private ConnectionMultiplexer _redis;
|
||||
private IDatabase _db;
|
||||
|
||||
public bool IsConnected => _redis != null && _redis.IsConnected;
|
||||
|
||||
public void Connect(string connectionString = "localhost:3187")
|
||||
{
|
||||
if (_redis == null || !_redis.IsConnected)
|
||||
{
|
||||
_redis = ConnectionMultiplexer.Connect(connectionString);
|
||||
_db = _redis.GetDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SetAsync(string key, string value)
|
||||
{
|
||||
if (_db == null) Connect();
|
||||
await _db.StringSetAsync(key, value);
|
||||
}
|
||||
|
||||
public async Task SetAsync(string key, string value, int row, int col)
|
||||
{
|
||||
// For Garnet, we currently only store Key-Value string.
|
||||
// Traceability metadata (row, col) could be stored in a hash or side key if needed.
|
||||
// For now, we just proceed with standard storage.
|
||||
if (_db == null) Connect();
|
||||
await _db.StringSetAsync(key, value);
|
||||
}
|
||||
|
||||
public async Task IncrementAsync(string key, double value)
|
||||
{
|
||||
if (_db == null) Connect();
|
||||
await _db.StringIncrementAsync(key, value);
|
||||
}
|
||||
|
||||
// For Data Explorer
|
||||
public async Task<List<string>> SearchKeysAsync(string pattern)
|
||||
{
|
||||
if (_db == null) Connect();
|
||||
var server = _redis.GetServer(_redis.GetEndPoints().First());
|
||||
// Use Keys for simplicity in Schema Editor (low traffic)
|
||||
// In high production, use SCAN
|
||||
var keys = server.Keys(pattern: pattern).Select(k => k.ToString()).ToList();
|
||||
return await Task.FromResult(keys);
|
||||
}
|
||||
|
||||
public async Task<string> GetValueAsync(string key)
|
||||
{
|
||||
if (_db == null) Connect();
|
||||
return await _db.StringGetAsync(key);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_redis?.Dispose();
|
||||
}
|
||||
}
|
||||
40
SchemaEditor/Services/GarnetHost.cs
Normal file
40
SchemaEditor/Services/GarnetHost.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Garnet;
|
||||
|
||||
namespace SchemaEditor.Services;
|
||||
|
||||
public class GarnetHost : IHostedService, IDisposable
|
||||
{
|
||||
private GarnetServer? _server;
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var serverArgs = new string[] { "--port", "3187" }; // Changed to 3187
|
||||
_server = new GarnetServer(serverArgs);
|
||||
_server.Start();
|
||||
Console.WriteLine("[GarnetHost] Server started on port 3278");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[GarnetHost] Failed to start: {ex.Message}");
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_server?.Dispose();
|
||||
Console.WriteLine("[GarnetHost] Server stopped");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_server?.Dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user