초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
using ServerCore;
using ServerBase;
using ServerCommon;
namespace GameServer;
public class DBQCaliumStorageLoad : QueryExecutorBase
{
private string m_pk = string.Empty;
public DBQCaliumStorageLoad() : base(nameof(DBQCaliumStorageLoad)) {}
//===================================================================================================
// DB 쿼리 직전에 준비해야 할 로직들을 작성한다.
//===================================================================================================
public override Task<Result> onPrepareQuery()
{
var result = new Result();
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var doc = new CaliumStorageDoc();
doc.setCombinationKeyForPK(string.Empty);
var error_code = doc.onApplyPKSK();
if (error_code.isFail())
{
var err_msg = $"Failed to onApplyPKSK() !!! : {error_code.toBasicString()} - {toBasicString()}, {owner.toBasicString()}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
return Task.FromResult(result);
}
m_pk = doc.getPK();
return Task.FromResult(result);
}
//===================================================================================================
// onPrepareQuery()를 성공할 경우 호출된다.
//===================================================================================================
public override async Task<Result> onQuery()
{
var result = new Result();
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => "owner is null !!!");
var query_batch = getQueryBatch();
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!!");
var db_connector = query_batch.getDynamoDbConnector();
var query_config = db_connector.makeQueryConfigForReadByPKOnly(m_pk);
(result, var read_docs) = await db_connector.simpleQueryDocTypesWithQueryOperationConfig<CaliumStorageDoc>(query_config, eventTid: query_batch.getTransId());
if (result.isFail()) return result;
if (read_docs.Count <= 0)
{
result.setFail(ServerErrorCode.DynamoDbQueryNoMatchAttribute, $"fail to find calium storage doc");
return result;
}
var calium_storage_doc = read_docs.FirstOrDefault();
NullReferenceCheckHelper.throwIfNull(calium_storage_doc, () => $"calium_storage_doc is null !!! - {owner.toBasicString()}");
var calium_storage_attribute = owner.getEntityAttribute<CaliumStorageAttribute>();
NullReferenceCheckHelper.throwIfNull(calium_storage_attribute, () => $"calium_storage_attribute is null !!! - {owner.toBasicString()}");
if (false == calium_storage_attribute.copyEntityAttributeFromDoc(calium_storage_doc))
{
var err_msg = $"failed to load Calium Storage !!! - {owner.toBasicString()}";
result.setFail(ServerErrorCode.FailToLoadCalium, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
//===================================================================================================
// DB 쿼리를 성공하고, doFnCommit()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
//===================================================================================================
public override Task onQueryResponseCommit()
{
return Task.CompletedTask;
}
//===================================================================================================
// DB 쿼리를 실패하고, doFnRollback()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
//===================================================================================================
public override Task onQueryResponseRollback(Result errorResult)
{
return Task.CompletedTask;
}
private new CaliumStorageEntity? getOwner() => getQueryBatch()?.getLogActor() as CaliumStorageEntity;
}

View File

@@ -0,0 +1,88 @@
using Amazon.DynamoDBv2.DocumentModel;
using Amazon.DynamoDBv2.Model;
using ServerCore;
using ServerBase;
using ServerCommon;
namespace GameServer;
public class DBQContentCaliumCreate : QueryExecutorBase
{
private readonly string m_contentId;
private readonly double m_calium;
public DBQContentCaliumCreate(string contentId, double calium) : base(nameof(DBQContentCaliumCreate))
{
m_contentId = contentId;
m_calium = calium;
}
//=====================================================================================
// DB 쿼리 직전에 준비해야 할 로직들을 작성한다.
//=====================================================================================
public override async Task<Result> onPrepareQuery() => await Task.FromResult(new Result());
//=====================================================================================
// onPrepareQuery()를 성공할 경우 호출된다.
//=====================================================================================
public override async Task<Result> onQuery()
{
var owner = getOwner();
var query_batch = getQueryBatch() as QueryBatch<QueryRunnerWithItemRequest>;
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!! - {owner.toBasicString()}");
var query_runner_with_item_request = query_batch.getQueryRunner();
NullReferenceCheckHelper.throwIfNull(query_runner_with_item_request, () => $"query_runner_with_item_request is null !!! - {owner.toBasicString()}");
var db_connector = query_batch.getDynamoDbConnector();
var create = await makeCreateItemRequestCaliumContentStorage(db_connector);
if (create.result.isFail()) return create.result;
NullReferenceCheckHelper.throwIfNull(create.putItemRequest, () => $"create_request is null !!! - {owner.toBasicString()}");
var query_context = create.putItemRequest.createItemRequestQueryContext(QueryType.Insert);
var result = await query_runner_with_item_request.tryRegisterQueryContext(query_context);
return result;
}
//=====================================================================================
// DB 쿼리를 성공하고, doFnCommit()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
//=====================================================================================
public override async Task onQueryResponseCommit()
{
await Task.CompletedTask;
return;
}
//=====================================================================================
// DB 쿼리를 실패하고, doFnRollback()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
//=====================================================================================
public override async Task onQueryResponseRollback(Result errorResult)
{
await Task.CompletedTask;
return;
}
private async Task<(Result result, PutItemRequest? putItemRequest)> makeCreateItemRequestCaliumContentStorage(DynamoDbClient dbClient)
{
var target_doc = new CaliumContentDoc(m_contentId);
var attrib = target_doc.getAttrib<CaliumContentAttrib>();
NullReferenceCheckHelper.throwIfNull(attrib, () => $"calium_content_attrib is null !!! - {getOwner().toBasicString()}");
attrib.ContentId = m_contentId;
attrib.TotalCalium = m_calium;
var (result, document) = await target_doc.onCopyToDocument();
if (result.isFail()) return (result, null);
var put_item_request = new PutItemRequest();
put_item_request.TableName = dbClient.getTableFullName(ServerBase.DynamoDbDefine.TableNames.Main);
put_item_request.Item = document.ToAttributeMap();
return (result, put_item_request);
}
}

View File

@@ -0,0 +1,133 @@
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using ServerCore;
using ServerBase;
using ServerCommon;
namespace GameServer;
public class DBQStorageCaliumSyncDateUpdate : QueryExecutorBase
{
private PrimaryKey m_primary_key = new();
private DateTime m_sync_date { get; set; }
public DBQStorageCaliumSyncDateUpdate(DateTime syncDate) : base(nameof(DBQStorageCaliumSyncDateUpdate))
{
m_sync_date = syncDate;
}
//=====================================================================================
// DB 쿼리 직전에 준비해야 할 로직들을 작성한다.
//=====================================================================================
public override async Task<Result> onPrepareQuery()
{
var owner = getOwner();
var (result, make_primary_key) = await DynamoDBDocBaseHelper.makePrimaryKey<CaliumStorageDoc>(string.Empty);
if (result.isFail())
{
return result;
}
NullReferenceCheckHelper.throwIfNull(make_primary_key, () => $"make_primary_key is null !!! - {owner.toBasicString()}");
m_primary_key = make_primary_key;
return result;
}
//=====================================================================================
// onPrepareQuery()를 성공할 경우 호출된다.
//=====================================================================================
public override async Task<Result> onQuery()
{
var owner = getOwner();
var query_batch = getQueryBatch() as QueryBatch<QueryRunnerWithItemRequest>;
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!! - {owner.toBasicString()}");
var query_runner_with_item_request = query_batch.getQueryRunner();
NullReferenceCheckHelper.throwIfNull(query_runner_with_item_request, () => $"query_runner_with_item_request is null !!! - {owner.toBasicString()}");
var db_connector = query_batch.getDynamoDbConnector();
var target = JsonHelper.getJsonPropertyName<CaliumStorageAttrib>(nameof(CaliumStorageAttrib.DailyRollUpCheckDate));
var update = makeUpdateItemRequest(db_connector, m_primary_key.toKeyWithAttributeValue(), target);
if (update.result.isFail()) return update.result;
NullReferenceCheckHelper.throwIfNull(update.updateRequest, () => $"update_request is null !!! - {owner.toBasicString()}");
var exception_handler = new DynamoDbQueryExceptionNotifier.ExceptionHandler(DynamoDbQueryExceptionNotifier.ConditionalCheckFailed, ServerErrorCode.LackOfTotalCalium);
var query_context = update.updateRequest.createItemRequestQueryContext(QueryType.Update, exception_handler);
var result = await query_runner_with_item_request.tryRegisterQueryContext(query_context);
return result;
}
//=====================================================================================
// DB 쿼리를 성공하고, doFnCommit()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
//=====================================================================================
public override async Task onQueryResponseCommit()
{
await Task.CompletedTask;
return;
}
//=====================================================================================
// DB 쿼리를 실패하고, doFnRollback()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
//=====================================================================================
public override async Task onQueryResponseRollback(Result errorResult)
{
await Task.CompletedTask;
return;
}
private (Result result, UpdateItemRequest? updateRequest) makeUpdateItemRequest(DynamoDbClient dbClient, Dictionary<string, AttributeValue> attributeValueWithPrimaryKey, string targetAttribName)
{
var result = new Result();
string err_msg;
if (string.IsNullOrEmpty(targetAttribName))
{
err_msg = $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : targetAttribName - {targetAttribName}";
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
var target_doc = new CaliumStorageDoc();
var query_builder = new DynamoDbItemRequestHelper.UpdateItemRequestBuilder(dbClient.getTableFullName(target_doc.TableName));
query_builder.withKeys(attributeValueWithPrimaryKey);
var attrib_path_json_string = target_doc.toJsonStringOfAttribs();
(var is_success, var attribute_expression) = DynamoDbClientHelper.toAttributeExpressionFromJson(attrib_path_json_string, targetAttribName);
if (false == is_success)
{
err_msg = $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : attribPath:{attrib_path_json_string}, targetKey:{targetAttribName}";
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
var attribute_names = DynamoDbClientHelper.toExpressionAttributeNamesFromJson(attrib_path_json_string, targetAttribName);
query_builder.withExpressionAttributeNames(attribute_names);
var update_expression = $"SET {attribute_expression} = :changeValue";
query_builder.withUpdateExpression(update_expression);
var expression_attribute_values = new Dictionary<string, AttributeValue>
{
{ ":changeValue", new AttributeValue { S = m_sync_date.toString("yyyy-MM-ddTHH:mm:ss") } }
};
query_builder.withExpressionAttributeValues(expression_attribute_values);
query_builder.withReturnValues(ReturnValue.ALL_NEW);
return query_builder.build();
}
}

View File

@@ -0,0 +1,216 @@
using System.Globalization;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using ServerCore; using ServerBase;
using ServerCommon;
namespace GameServer;
public enum CaliumStorageType
{
None = 0,
Converter = 1,
Operator = 2
}
public class DBQStorageCaliumUpdate : QueryExecutorBase
{
private CaliumStorageType m_storage_type { get; set; } = CaliumStorageType.None;
private double m_delta { get; set; }
private bool m_is_update_last_date { get; set; }
private bool m_is_pivot { get; set; }
private PrimaryKey m_primary_key = new();
//=====================================================================================
// 0 < deltaCount => 증가
// 0 > deltaCount => 감소
//=====================================================================================
public DBQStorageCaliumUpdate(CaliumStorageType storageType, double deltaCalium, bool isUpdateLastDate = false, bool isPivot = false) : base(nameof(DBQStorageCaliumUpdate))
{
m_storage_type = storageType;
m_delta = deltaCalium;
m_is_update_last_date = isUpdateLastDate;
m_is_pivot = isPivot;
}
//=====================================================================================
// DB 쿼리 직전에 준비해야 할 로직들을 작성한다.
//=====================================================================================
public override async Task<Result> onPrepareQuery()
{
var owner = getOwner();
var (result, make_primary_key) = await DynamoDBDocBaseHelper.makePrimaryKey<CaliumStorageDoc>(string.Empty);
if (result.isFail())
{
return result;
}
NullReferenceCheckHelper.throwIfNull(make_primary_key, () => $"make_primary_key is null !!! - {owner.toBasicString()}");
m_primary_key = make_primary_key;
return result;
}
//=====================================================================================
// onPrepareQuery()를 성공할 경우 호출된다.
//=====================================================================================
public override async Task<Result> onQuery()
{
var owner = getOwner();
var query_batch = getQueryBatch() as QueryBatch<QueryRunnerWithItemRequest>;
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!! - {owner.toBasicString()}");
var query_runner_with_item_request = query_batch.getQueryRunner();
NullReferenceCheckHelper.throwIfNull(query_runner_with_item_request, () => $"query_runner_with_item_request is null !!! - {owner.toBasicString()}");
var db_connector = query_batch.getDynamoDbConnector();
var update = makeUpdateItemRequestChangeConverterTotalCalium(db_connector, m_primary_key.toKeyWithAttributeValue(), convertCaliumStorageTypeToValueName());
if (update.result.isFail()) return update.result;
NullReferenceCheckHelper.throwIfNull(update.updateRequest, () => $"update_request is null !!! - {owner.toBasicString()}");
var exception_handler = new DynamoDbQueryExceptionNotifier.ExceptionHandler(DynamoDbQueryExceptionNotifier.ConditionalCheckFailed, ServerErrorCode.LackOfTotalCalium);
var query_context = update.updateRequest.createItemRequestQueryContext(QueryType.Update, exception_handler);
var result = await query_runner_with_item_request.tryRegisterQueryContext(query_context);
return result;
}
//=====================================================================================
// DB 쿼리를 성공하고, doFnCommit()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
//=====================================================================================
public override async Task onQueryResponseCommit()
{
await Task.CompletedTask;
return;
}
//=====================================================================================
// DB 쿼리를 실패하고, doFnRollback()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
//=====================================================================================
public override async Task onQueryResponseRollback(Result errorResult)
{
await Task.CompletedTask;
return;
}
private string convertCaliumStorageTypeToValueName()
{
return m_storage_type switch
{
CaliumStorageType.Converter => JsonHelper.getJsonPropertyName<CaliumConverterInfo>(nameof(CaliumConverterInfo.TotalCalium)),
CaliumStorageType.Operator => JsonHelper.getJsonPropertyName<CaliumOperatorInfo>(nameof(CaliumOperatorInfo.TotalCalium)),
_ => string.Empty
};
}
private (Result result, UpdateItemRequest? updateRequest) makeUpdateItemRequestChangeConverterTotalCalium( DynamoDbClient dbClient
, Dictionary<string, AttributeValue> attributeValueWithPrimaryKey
, string targetAttribName )
{
var result = new Result();
string err_msg;
if (string.IsNullOrEmpty(targetAttribName))
{
err_msg = $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : targetAttribName - {targetAttribName}";
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
var target_doc = new CaliumStorageDoc();
var query_builder = new DynamoDbItemRequestHelper.UpdateItemRequestBuilder(dbClient.getTableFullName(target_doc.TableName));
query_builder.withKeys(attributeValueWithPrimaryKey);
var attrib_path_json_string = target_doc.toJsonStringOfAttribs();
(var is_success, var attribute_expression) = DynamoDbClientHelper.toAttributeExpressionFromJson(attrib_path_json_string, targetAttribName);
if (false == is_success)
{
err_msg = $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : attribPath:{attrib_path_json_string}, targetKey:{targetAttribName}";
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
var attribute_names = DynamoDbClientHelper.toExpressionAttributeNamesFromJson(attrib_path_json_string, targetAttribName);
query_builder.withExpressionAttributeNames(attribute_names);
var update_expression = (m_delta >= 0)
? $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) + :changeValue"
: $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) - :changeValue";
query_builder.withUpdateExpression(update_expression);
// 차감시 조건 추가
if (m_delta < 0)
{
query_builder.withConditionExpression($"{attribute_expression} >= :changeValue");
}
var expression_attribute_values = new Dictionary<string, AttributeValue>
{
{ ":changeValue", new AttributeValue { N = Math.Abs(m_delta).ToString(CultureInfo.InvariantCulture) } },
{ ":start", new AttributeValue { N = "0" } }
};
query_builder.withExpressionAttributeValues(expression_attribute_values);
// 마지막 업데이트 날짜 수정
if (m_is_update_last_date)
{
result = updateLastDate(query_builder, attrib_path_json_string);
if (result.isFail()) return (result, null);
}
query_builder.withReturnValues(ReturnValue.ALL_NEW);
return query_builder.build();
}
private Result updateLastDate(DynamoDbItemRequestHelper.UpdateItemRequestBuilder query_builder, string attrib_path_json_string)
{
var result = new Result();
var request = query_builder.getItemRequest();
var attribute_last_date = JsonHelper.getJsonPropertyName<CaliumConverterInfo>(nameof(CaliumConverterInfo.LastFillUpDate));
// 1. add attribute names
var attribute_last_date_names = DynamoDbClientHelper.toExpressionAttributeNamesFromJson(attrib_path_json_string, attribute_last_date);
foreach (var name in attribute_last_date_names.Where(name => !request.ExpressionAttributeNames.ContainsKey(name.Key)))
{
request.ExpressionAttributeNames.Add(name.Key, name.Value);
}
// 2. add attribute expression
var (is_success, last_date_expression) = DynamoDbClientHelper.toAttributeExpressionFromJson(attrib_path_json_string, attribute_last_date);
if (false == is_success)
{
var err_msg = $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : attribPath:{attrib_path_json_string}, targetKey:{attribute_last_date}";
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
request.UpdateExpression += ", ";
request.UpdateExpression += $"{last_date_expression} = :lastDateValue";
// 3. add values
request.ExpressionAttributeValues.Add(":lastDateValue", new AttributeValue { S = DateTimeHelper.Current.toString("yyyy-MM-ddTHH:mm:ss")});
return result;
}
}