#region License Information
/* HeuristicLab
* Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
namespace HeuristicLab.Services.Hive.DataAccess.Daos {
public class ProjectDao : GenericDao {
public ProjectDao(DataContext dataContext) : base(dataContext) { }
public class ProjectStats {
public Guid ProjectId { get; set; }
public int Cores { get; set; }
public int Memory { get; set; }
}
public override Project GetById(Guid id) {
return GetByIdQuery(DataContext, id);
}
public void DeleteByIds(IEnumerable ids) {
string paramProjectIds = string.Join(",", ids.ToList().Select(x => string.Format("'{0}'", x)));
if (!string.IsNullOrWhiteSpace(paramProjectIds)) {
string queryString = string.Format(DeleteByIdsQueryString, paramProjectIds);
DataContext.ExecuteCommand(queryString);
}
}
public IEnumerable GetUsageGrantedProjectsForUser(IEnumerable userAndGroupIds) {
string paramUserAndGroupIds = string.Join(",", userAndGroupIds.ToList().Select(x => string.Format("'{0}'", x)));
if (!string.IsNullOrWhiteSpace(paramUserAndGroupIds)) {
string queryString = string.Format(GetUsageGrantedProjectsForUserQueryString, paramUserAndGroupIds);
return DataContext.ExecuteQuery(queryString);
}
return Enumerable.Empty();
}
public IEnumerable GetAdministrationGrantedProjectsForUser(Guid userId) {
return DataContext.ExecuteQuery(GetAdministrationGrantedProjectsForUserQueryString, userId);
}
public IEnumerable GetChildProjectsById(Guid id) {
return DataContext.ExecuteQuery(GetChildProjectsByIdQuery, id);
}
public IEnumerable GetChildProjectIdsById(Guid id) {
return DataContext.ExecuteQuery(GetChildProjectIdsByIdQuery, id);
}
public IEnumerable GetParentProjectsById(Guid id) {
return DataContext.ExecuteQuery(GetParentProjectsByIdQuery, id);
}
public IEnumerable GetParentProjectIdsById(Guid id) {
return DataContext.ExecuteQuery(GetParentProjectIdsByIdQuery, id);
}
public IEnumerable GetCurrentAndParentProjectsById(Guid id) {
return DataContext.ExecuteQuery(GetCurrentAndParentProjectsByIdQuery, id);
}
public IEnumerable GetCurrentAndParentProjectIdsById(Guid id) {
return DataContext.ExecuteQuery(GetCurrentAndParentProjectIdsByIdQuery, id);
}
public IEnumerable GetUsageStatsPerProject() {
return DataContext.ExecuteQuery(GetUsageStatsPerProjectQueryString).ToList();
}
public IEnumerable GetAvailabilityStatsPerProject() {
return DataContext.ExecuteQuery(GetAvailabilityStatsPerProjectQueryString).ToList();
}
#region Compiled queries
private static readonly Func GetByIdQuery =
CompiledQuery.Compile((DataContext db, Guid projectId) =>
(from project in db.GetTable()
where project.ProjectId == projectId
select project).SingleOrDefault());
#endregion
#region String queries
private const string DeleteByIdsQueryString = @"
DELETE FROM [Project]
WHERE ProjectId IN ({0})
";
private const string GetUsageStatsPerProjectQueryString = @"
SELECT j.ProjectId, SUM(t.CoresNeeded) AS Cores, SUM(t.MemoryNeeded) AS Memory
FROM [Task] t, [Job] j
WHERE t.TaskState = 'Calculating'
AND t.JobId = j.JobId
GROUP BY j.ProjectId
";
private const string GetAvailabilityStatsPerProjectQueryString = @"
WITH rtree AS
(
SELECT ResourceId, ParentResourceId
FROM [Resource]
UNION ALL
SELECT rt.ResourceId, r.ParentResourceId
FROM [Resource] r
JOIN rtree rt ON rt.ParentResourceId = r.ResourceId
)
SELECT [union].ProjectId, SUM([union].Cores), SUM([union].Memory)
FROM
(
SELECT apr.ProjectId, res.Cores, res.Memory
FROM rtree, [AssignedProjectResource] apr, [Resource] res
WHERE rtree.ResourceId = res.ResourceId
AND res.ResourceType = 'Slave'
AND (res.SlaveState = 'Idle' OR SlaveState = 'Calculating')
AND rtree.ParentResourceId = apr.ResourceId
UNION ALL
SELECT apr.ProjectId, res.Cores, res.Memory
FROM [AssignedProjectResource] apr, [Resource] res
WHERE apr.ResourceId = res.ResourceId
AND res.ResourceType = 'Slave'
AND (res.SlaveState = 'Idle' OR SlaveState = 'Calculating')
) AS [union]
GROUP BY [union].ProjectId
";
private const string GetUsageGrantedProjectsForUserQueryString = @"
SELECT DISTINCT p.*
FROM [Project] p, [ProjectPermission] pp
WHERE p.ProjectId = pp.ProjectId
AND pp.GrantedUserId IN ({0})
";
private const string GetAdministrationGrantedProjectsForUserQueryString = @"
WITH ptree AS
(
SELECT ProjectId, ParentProjectId
FROM [Project]
UNION ALL
SELECT pt.ProjectId, p.ParentProjectId
FROM [Project] p
JOIN ptree pt ON pt.ParentProjectId = p.ProjectId AND p.ParentProjectId <> p.ProjectId AND pt.ParentProjectId <> pt.ProjectId
)
SELECT DISTINCT parent.*
FROM [Project] parent
WHERE parent.OwnerUserId = {0}
UNION
SELECT DISTINCT child.*
FROM ptree, [Project] parent, [Project] child
WHERE ptree.ParentProjectId = parent.ProjectId
AND ptree.ProjectId = child.ProjectId
AND parent.OwnerUserId = {0}
";
private const string GetChildProjectsByIdQuery = @"
WITH ptree AS
(
SELECT ProjectId, ParentProjectId
FROM [Project]
UNION ALL
SELECT pt.ProjectId, p.ParentProjectId
FROM [Project] p
JOIN ptree pt ON pt.ParentProjectId = p.ProjectId AND p.ParentProjectId <> p.ProjectId AND pt.ParentProjectId <> pt.ProjectId
)
SELECT DISTINCT pro.*
FROM ptree, [Project] pro
WHERE ptree.ParentProjectId = {0}
AND ptree.ProjectId = pro.ProjectId
";
private const string GetChildProjectIdsByIdQuery = @"
WITH ptree AS
(
SELECT ProjectId, ParentProjectId
FROM [Project]
UNION ALL
SELECT pt.ProjectId, r.ParentProjectId
FROM [Project] r
JOIN ptree pt ON pt.ParentProjectId = r.ProjectId AND r.ParentProjectId <> r.ProjectId AND pt.ParentProjectId <> pt.ProjectId
)
SELECT DISTINCT ptree.ProjectId
FROM ptree
WHERE ptree.ParentProjectId = {0}
";
private const string GetParentProjectsByIdQuery = @"
WITH pbranch AS
(
SELECT ProjectId, ParentProjectId
FROM [Project]
UNION ALL
SELECT pb.ProjectId, p.ParentProjectId
FROM [Project] p
JOIN pbranch pb ON pb.ParentProjectId = p.ProjectId AND p.ParentProjectId <> p.ProjectId AND pb.ParentProjectId <> pb.ProjectId
)
SELECT DISTINCT pro.*
FROM pbranch, [Project] pro
WHERE pbranch.ProjectId = {0}
AND pbranch.ParentProjectId = pro.ProjectId
";
private const string GetParentProjectIdsByIdQuery = @"
WITH pbranch AS
(
SELECT ProjectId, ParentProjectId
FROM [Project]
UNION ALL
SELECT pb.ProjectId, p.ParentProjectId
FROM [Project] p
JOIN pbranch pb ON pb.ParentProjectId = p.ProjectId AND p.ParentProjectId <> p.ProjectId AND pb.ParentProjectId <> pb.ProjectId
)
SELECT DISTINCT pbranch.ParentProjectId
FROM pbranch
WHERE pbranch.ProjectId = {0}
";
private const string GetCurrentAndParentProjectsByIdQuery = @"
WITH pbranch AS
(
SELECT ProjectId, ParentProjectId
FROM Project
WHERE ProjectId = {0}
UNION ALL
SELECT p.ProjectId, p.ParentProjectId
FROM Project p
JOIN pbranch pb ON pb.ParentProjectId = p.ProjectId
)
SELECT DISTINCT pro.*
FROM pbranch, Project pro
WHERE pbranch.ProjectId = pro.ProjectId
";
private const string GetCurrentAndParentProjectIdsByIdQuery = @"
WITH pbranch AS
(
SELECT ProjectId, ParentProjectId
FROM Project
WHERE ProjectId = {0}
UNION ALL
SELECT p.ProjectId, p.ParentProjectId
FROM Project p
JOIN pbranch pb ON pb.ParentProjectId = p.ProjectId
)
SELECT DISTINCT pbranch.ProjectId
FROM pbranch
";
private const string GetNearestOwnedParentProjectByIdQuery = @"
WITH pbranch AS
(
SELECT ProjectId, ParentProjectId, CAST(ProjectId AS NVARCHAR(MAX)) Path, 1 Distance
FROM [Project]
WHERE ProjectId = {0}
UNION ALL
SELECT pb.ProjectId, p.ParentProjectId, pb.Path + N', ' + CAST(pb.ProjectId AS NVARCHAR(MAX)), pb.Distance + 1
FROM [Project] p
JOIN pbranch pb ON pb.ParentProjectId = p.ProjectId AND p.ParentProjectId <> p.ProjectId AND pb.ParentProjectId <> pb.ProjectId
)
SELECT TOP(1) pro.*
FROM pbranch, [Project] pro
WHERE pbranch.ParentProjectId = pro.ProjectId
AND pro.OwnerUserId = {1}
ORDER BY pbranch.Distance
";
private const string GetFarestOwnedParentProjectIdByIdQuery = @"
WITH pbranch AS
(
SELECT ProjectId, ParentProjectId, CAST(ProjectId AS NVARCHAR(MAX)) Path, 1 Distance
FROM [Project]
WHERE ProjectId = {0}
UNION ALL
SELECT pb.ProjectId, p.ParentProjectId, pb.Path + N', ' + CAST(pb.ProjectId AS NVARCHAR(MAX)), pb.Distance + 1
FROM [Project] p
JOIN pbranch pb ON pb.ParentProjectId = p.ProjectId AND p.ParentProjectId <> p.ProjectId AND pb.ParentProjectId <> pb.ProjectId
)
SELECT TOP(1) pro.*
FROM pbranch, [Project] pro
WHERE pbranch.ParentProjectId = pro.ProjectId
AND pro.OwnerUserId = {1}
ORDER BY pbranch.Distance DESC
";
#endregion
}
}