/// <summary> /// 在题目库中使用给定的新题目 ID 创建已存在题目的精确副本。 /// </summary> /// <param name="newProblemId">要创建的新题目 ID。</param> /// <param name="oldProblemId">已存在的题目 ID。</param> /// <returns>新题目句柄。</returns> /// <exception cref="ArgumentNullException"/> /// <exception cref="ProblemNotExistException"/> /// <exception cref="ProblemAlreadyExistException"/> public ProblemHandle CloneProblem(string newProblemId, string oldProblemId) { if (newProblemId == null) { throw new ArgumentNullException(nameof(newProblemId)); } if (oldProblemId == null) { throw new ArgumentNullException(nameof(oldProblemId)); } ProblemHandle oldHandle = new ProblemHandle(oldProblemId); ProblemHandle newHandle = CreateProblem(newProblemId); using (ProblemDataProvider newData = ProblemDataProvider.Create(newHandle, false)) { using (ProblemDataProvider oldData = ProblemDataProvider.Create(oldHandle, true)) { oldData.CopyTo(newData); // 维护评测数据集源链接。 if (oldData.TestSuiteOrigin != null) { newData.TestSuiteOrigin = oldData.TestSuiteOrigin; } else { newData.TestSuiteOrigin = oldData.ProblemId; } } } return(newHandle); }
/// <summary> /// 使用指定的题目句柄初始化 ProblemSession 类的新实例。 /// </summary> /// <param name="handle">题目句柄对象。</param> /// <param name="desiredAccess">创建的 ProblemSession 对象具有的访问权限。</param> public ProblemSession(ProblemHandle handle, ProblemDataAccess desiredAccess) { m_handle = handle; m_problemData = ProblemDataProviderFactory.CreateDataProvider(handle, desiredAccess == ProblemDataAccess.ReadOnly); m_disposed = false; }
/// <summary> /// 在主题目库中创建一道新题目并返回该题目的句柄。 /// </summary> /// <returns>创建的题目句柄。</returns> /// <exception cref="ArgumentNullException"/> /// <exception cref="ProblemAlreadyExistException"/> public ProblemHandle CreateProblem(string problemId) { if (problemId == null) { throw new ArgumentNullException(nameof(problemId)); } if (IsProblemExist(problemId)) { throw new ProblemAlreadyExistException(new ProblemHandle(problemId)); } // 为题目创建文件系统目录。 string directory = string.Concat(ms_archieveDirectory, "\\", problemId); Directory.CreateDirectory(directory); ProblemEntity entity = new ProblemEntity() { Id = problemId, ProblemDirectory = directory, }; // 将题目实体对象添加至底层数据库中。 m_factory.WithContext(context => { context.AddProblemEntity(entity); context.SaveChanges(); }); // 创建句柄并返回。 ProblemHandle handle = ProblemHandle.FromProblemEntity(entity); return(handle); }
/// <summary> /// 使用指定的查询对象查询题目句柄。 /// </summary> /// <param name="query">为查询提供参数。</param> /// <returns>一个列表,该列表中包含了所有的查询结果。</returns> /// <exception cref="ArgumentNullException"/> /// <exception cref="ArgumentOutOfRangeException"/> public IList <ProblemHandle> QueryProblems(ProblemArchieveQueryParameter query) { if (query == null) { throw new ArgumentNullException(nameof(query)); } if (query.QueryByTitle && query.Title == null) { throw new ArgumentNullException(nameof(query.Title)); } if (query.QueryBySource && query.Source == null) { throw new ArgumentNullException(nameof(query.Source)); } if (query.QueryByAuthor && query.Author == null) { throw new ArgumentNullException(nameof(query.Author)); } if (query.Page == null) { throw new ArgumentNullException(nameof(query.Page)); } if (query.Page.Page <= 0 || query.Page.EntriesPerPage <= 0) { throw new ArgumentOutOfRangeException(nameof(query.Page)); } IQueryable <ProblemEntity> set = m_context.GetAllProblemEntities(); // 根据查询参数执行相应的查询,动态维护查询基础数据集。 if (query.QueryByTitle) { set = ProblemArchieveDataContext.QueryProblemEntitiesByTitle(set, query.Title); } if (query.QueryBySource) { set = ProblemArchieveDataContext.QueryProblemEntitiesBySource(set, query.Source); } if (query.QueryByAuthor) { set = ProblemArchieveDataContext.QueryProblemEntitiesByAuthor(set, query.Author); } // 执行分页。 set = set.Page(query.Page.Page, query.Page.EntriesPerPage); List <ProblemHandle> handleList = new List <ProblemHandle>(); foreach (ProblemEntity entity in set) { handleList.Add(ProblemHandle.FromProblemEntity(entity)); } return(handleList); }
/// <summary> /// 由给定的题目 ID 获取题目句柄对象。 /// </summary> /// <param name="id">题目 ID。</param> /// <returns>具有给定题目 ID 的题目句柄对象。若主题库中不存在这样的题目,返回 null。</returns> public ProblemHandle GetProblemById(int id) { ProblemEntity entity = m_context.GetProblemEntityById(id); if (entity == null) { return(null); } return(ProblemHandle.FromProblemEntity(entity)); }
/// <summary> /// 在主题目库中创建一道新题目并返回该题目的句柄。 /// </summary> /// <returns></returns> public ProblemHandle CreateProblem() { ProblemEntity entity = new ProblemEntity(); // 为题目创建文件系统目录。 string directory = string.Concat(ms_archieveDirectory, "\\", entity.Id.ToString("D4")); Directory.CreateDirectory(directory); // 将题目实体对象添加至底层数据库中。 m_context.AddProblemEntity(entity); // 创建句柄并返回。 ProblemHandle handle = ProblemHandle.FromProblemEntity(entity); return(handle); }
/// <summary> /// 从给定的题目句柄创建 IProblemDataProvider 对象。 /// </summary> /// <param name="handle">题目句柄对象。</param> /// <param name="isReadonly">一个值,该值指示创建的 IProblemDataProvider 对象是否应仅具有读权限。</param> /// <returns>创建的 IProblemDataProvider 对象。</returns> /// <exception cref="ArgumentNullException"/> public static IProblemDataProvider CreateDataProvider(ProblemHandle handle, bool isReadonly) { if (handle == null) { throw new ArgumentNullException(nameof(handle)); } if (handle.IsNativeProblem) { // 本地题目。 return(NativeProblemDataProvider.Create(handle, isReadonly)); } else { // 非本地题目。需要 VJ 技术支持。第一版本暂不支持。 throw new NotSupportedException("暂不支持访问非本地平台题目。"); } }
/// <summary> /// 由给定的题目 ID 获取题目句柄对象。 /// </summary> /// <param name="id">题目 ID。</param> /// <returns>具有给定题目 ID 的题目句柄对象。若主题库中不存在这样的题目,返回 null。</returns> /// <exception cref="ArgumentNullException"/> public ProblemHandle GetProblemById(string id) { if (id == null) { throw new ArgumentNullException(nameof(id)); } return(m_factory.WithContext(context => { ProblemEntity entity = context.GetProblemEntityById(id); if (entity == null) { return null; } else { return ProblemHandle.FromProblemEntity(entity); } })); }
/// <summary> /// 使用指定的查询对象查询题目句柄。 /// </summary> /// <param name="query">为查询提供参数。</param> /// <returns>一个包含了所有的查询结果的查询结果对象。</returns> /// <exception cref="ArgumentNullException"/> /// <exception cref="ArgumentOutOfRangeException"/> public ReadOnlyCollection <ProblemHandle> QueryProblems(ProblemArchieveQueryParameter query) { if (query == null) { throw new ArgumentNullException(nameof(query)); } if (query.QueryByTitle && query.Title == null) { throw new ArgumentNullException(nameof(query.Title)); } if (query.QueryBySource && query.Source == null) { throw new ArgumentNullException(nameof(query.Source)); } if (query.QueryByAuthor && query.Author == null) { throw new ArgumentNullException(nameof(query.Author)); } return(m_factory.WithContext(context => { IQueryable <ProblemEntity> set = DoQuery(context, query); // 对数据集进行排序以准备随时执行分页。 set = set.OrderBy(entity => entity.Id); if (query.EnablePageQuery) { set = set.Page(query.PageQuery); } List <ProblemHandle> handles = new List <ProblemHandle>(); foreach (ProblemEntity ent in set) { handles.Add(ProblemHandle.FromProblemEntity(ent)); } return new ReadOnlyCollection <ProblemHandle>(handles); })); }
/// <summary> /// 使用给定的 ProblemHandle 对象和异常消息初始化 ProblemException 类的新实例。 /// </summary> /// <param name="entry">要使用的 ProblemEntry 对象。</param> /// <param name="message">要使用的异常消息。</param> public ProblemException(ProblemHandle entry, string message) : base(message) { Problem = entry ?? throw new ArgumentNullException(nameof(entry)); }
/// <summary> /// 使用 ProblemHandle 对象初始化 ProblemException 类的新实例。 /// </summary> /// <param name="entry">要使用的 ProblemEntry 对象。</param> /// <exception cref="NullReferenceException"/> public ProblemException(ProblemHandle entry) : base($"编号为 {entry.ProblemId} 的题目出现错误。") { Problem = entry; }