using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; using ServerCore; using ServerBase; namespace ServerBase; //============================================================================================== // 쿼리 내용을 작성하는 기반 클래스 //============================================================================================== public abstract partial class QueryExecutorBase { private readonly string m_query_name; public delegate Task FnCommit(QueryExecutorBase query); public delegate Task FnRollback(QueryExecutorBase query, Result errorResult); private FnCommit? m_fn_commit; // 쿼리 성공시 호출될 콜백함수 private FnRollback? m_fn_rollback; // 쿼리 실패시 호출될 콜백함수 private QueryBatchBase? m_parent; // 배치쿼리 public QueryExecutorBase(string queryName) { m_query_name = queryName; } public void bindCallback(FnCommit? fnCommit, FnRollback? fnRollback) { m_fn_commit = fnCommit; m_fn_rollback = fnRollback; } //===================================================================================== // DB 쿼리를 작성한다. //===================================================================================== public virtual bool onAddQueryRequests() => true; //===================================================================================== // DB 쿼리 직전에 준비해야 할 로직들을 작성한다. //===================================================================================== public abstract Task onPrepareQuery(); //===================================================================================== // onPrepareQuery()를 성공할 경우 호출된다. //===================================================================================== public abstract Task onQuery(); //===================================================================================== // DB 쿼리를 성공하고, doFnCommit()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다. //===================================================================================== public abstract Task onQueryResponseCommit(); //===================================================================================== // DB 쿼리를 실패하고, doFnRollback()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다. //===================================================================================== public abstract Task onQueryResponseRollback(Result errorResult); //===================================================================================== // DB commit 성공후 호출된다. //===================================================================================== public async Task doFnCommit() { if (null != m_fn_commit) { await m_fn_commit(this); return QueryBatchBase.QueryResultType.CalledQueryFunc; } return QueryBatchBase.QueryResultType.NotCalledQueryFunc; } //===================================================================================== // DB commit 실패후 호출된다. //===================================================================================== public async Task doFnRollback(Result errorResult) { if (null != m_fn_rollback) { await m_fn_rollback(this, errorResult); return QueryBatchBase.QueryResultType.CalledQueryFunc; } return QueryBatchBase.QueryResultType.NotCalledQueryFunc; } public void appendBusinessLog(ILogInvoker log) { if(null == m_parent) { var err_msg = $"Failed to QueryContextBase.appendBusinessLog() !!!, m_parent is null - {log.toBasicString()}, {toBasicString()}"; Log.getLogger().error(err_msg); return; } m_parent?.appendBusinessLog(log); } public TQuery? getQuery() where TQuery : QueryExecutorBase { if (this is TQuery query) { return query; } if (null == m_parent) { var err_msg = $"Failed to QueryContextBase.getQuery<{nameof(TQuery)}>() !!!, m_parent is null - {toBasicString()}"; Log.getLogger().error(err_msg); return null; } return m_parent.getQuery(); } public List? getQuerys() where TQuery : QueryExecutorBase { if (null == m_parent) { var err_msg = $"Failed to QueryContextBase.getQuerys<{nameof(TQuery)}>() !!!, m_parent is null - {toBasicString()}"; Log.getLogger().error(err_msg); return null; } return m_parent.getQuerys(); } public virtual EntityBase getOwner() { var query_batch = getQueryBatch(); NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!!"); var owner = query_batch.getLogActor() as EntityBase; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); return owner; } public virtual string toBasicString() { return $"QueryName:{getQueryName()}, "; } } //============================================================================================== // 배치 쿼리시 마지막 스텝의 콜백을 받기 위한 empty 쿼리 //============================================================================================== public class QueryFinal : QueryExecutorBase { public QueryFinal() : base(nameof(QueryFinal)) { } public override async Task onPrepareQuery() { await Task.CompletedTask; var result = new Result(); return result; } public override async Task onQuery() { await Task.CompletedTask; var result = new Result(); return result; } public override async Task onQueryResponseCommit() { await Task.CompletedTask; } public override async Task onQueryResponseRollback(Result errorResult) { await Task.CompletedTask; } }//QueryFinal