#region License Information
/* HeuristicLab
* Copyright (C) 2002-2010 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.SqlClient;
using System.IO;
using System.Linq;
using HeuristicLab.Hive.Contracts.BusinessObjects;
using HeuristicLab.Hive.Server.DataAccess;
namespace HeuristicLab.Hive.Server.LINQDataAccess {
public class JobDao : BaseDao, IJobDao {
#region IGenericDao Members
public JobDto FindById(Guid id) {
return (from job in Context.Jobs
where job.JobId.Equals(id)
select EntityToDto(job, null)).SingleOrDefault();
}
public IEnumerable FindAll() {
return (from job in Context.Jobs select EntityToDto(job, null)).ToArray();
}
public IEnumerable FindWithLimitations(JobState jobState, int offset, int count) {
IQueryable query = null;
if (jobState == JobState.Finished) {
query = from job in Context.Jobs
where job.JobState == Enum.GetName(typeof(JobState), jobState)
orderby job.DateFinished
select EntityToDto(job, null);
} else if (jobState == JobState.Calculating || jobState == JobState.SnapshotRequested || jobState == JobState.SnapshotSent) {
query = from job in Context.Jobs
where job.JobState == Enum.GetName(typeof(JobState), jobState)
orderby job.DateCalculated
select EntityToDto(job, null);
} else {
query = from job in Context.Jobs
where job.JobState == Enum.GetName(typeof(JobState), jobState)
orderby job.DateCreated
select EntityToDto(job, null);
}
return query.Skip(offset).Take(count).ToList();
}
public byte[] GetBinaryJobFile(Guid jobId) {
return (from job in Context.Jobs
where job.JobId.Equals(jobId)
select job.SerializedJob).SingleOrDefault().ToArray();
}
public JobDto Insert(JobDto bObj) {
Job j = DtoToEntity(bObj, null);
Context.Jobs.InsertOnSubmit(j);
CommitChanges();
bObj.Id = j.JobId;
return bObj;
}
public void SetBinaryJobFile(Guid jobId, byte[] data) {
Job j = (from job in Context.Jobs
where job.JobId.Equals(jobId)
select job).SingleOrDefault();
j.SerializedJob = data;
CommitChanges();
}
public SerializedJob InsertWithAttachedJob(SerializedJob job) {
Job j = DtoToEntity(job.JobInfo, null);
j.SerializedJob = job.SerializedJobData;
//foreach (Guid assignRessourceId in job.JobInfo.AssignedResourceIds)
// j.AssignedResources.Add(new AssignedResource { ResourceId = assignRessourceId });
Context.Jobs.InsertOnSubmit(j);
CommitChanges();
job.JobInfo.Id = j.JobId;
return job;
}
public void Delete(Guid id) {
Job job = Context.Jobs.SingleOrDefault(j => j.JobId.Equals(id));
Context.Jobs.DeleteOnSubmit(job);
CommitChanges();
}
public void Update(JobDto bObj) {
Job job = Context.Jobs.SingleOrDefault(j => j.JobId.Equals(bObj.Id));
DtoToEntity(bObj, job);
CommitChanges();
}
public IEnumerable FindActiveJobsOfSlave(SlaveDto slave) {
return (from j in Context.Jobs
where (j.JobState == Enum.GetName(typeof(JobState), JobState.Calculating) ||
j.JobState == Enum.GetName(typeof(JobState), JobState.Aborted) ||
j.JobState == Enum.GetName(typeof(JobState), JobState.SnapshotRequested) ||
j.JobState == Enum.GetName(typeof(JobState), JobState.SnapshotSent) ||
j.JobState == Enum.GetName(typeof(JobState), JobState.WaitForChildJobs)) &&
(j.ResourceId.Equals(slave.Id))
select EntityToDto(j, null)).ToList();
}
public IEnumerable FindFittingJobs(JobState state, int freeCores, int freeMemory, Guid slaveId) {
SlaveGroupDao cgd = new SlaveGroupDao();
List idList = new List(cgd.FindAllGroupAndParentGroupIdsForSlave(slaveId));
//Add myself too - enables jobs for one specific host!
idList.Add(slaveId);
var q = (from ar in Context.AssignedResources
where ar.Job.JobState == Enum.GetName(typeof(JobState), state) &&
ar.Job.CoresNeeded <= freeCores &&
ar.Job.MemoryNeeded <= freeMemory &&
idList.Contains(ar.ResourceId)
orderby ar.Job.Priority descending
select EntityToDto(ar.Job, null));
return q.ToList();
}
public IEnumerable FindJobsWithFinishedChilds(Guid slaveId) {
SlaveGroupDao cgd = new SlaveGroupDao();
List idList = new List(cgd.FindAllGroupAndParentGroupIdsForSlave(slaveId));
//Add myself too - enables jobs for one specific host!
idList.Add(slaveId);
var query = from ar in Context.AssignedResources
where ar.Job.JobState == Enum.GetName(typeof(JobState), JobState.WaitForChildJobs) &&
(from child in Context.Jobs
where child.ParentJobId == ar.Job.JobId
select
(child.JobState == Enum.GetName(typeof(JobState), JobState.Finished) ||
child.JobState == Enum.GetName(typeof(JobState), JobState.Failed) ||
child.JobState == Enum.GetName(typeof(JobState), JobState.Aborted))
).All(x => x) &&
(from child in Context.Jobs // avoid returning WaitForChildJobs jobs where no child-jobs exist (yet)
where child.ParentJobId == ar.Job.JobId
select child).Count() > 0
orderby ar.Job.Priority descending
select EntityToDto(ar.Job, null);
var list = query.ToList();
return list;
}
public IEnumerable GetJobsByState(JobState state) {
return (from j in Context.Jobs
where (j.JobState == Enum.GetName(typeof(JobState), state))
select EntityToDto(j, null)).ToList();
}
public void AssignSlaveToJob(Guid slaveId, Guid jobId) {
Slave s = Context.Resources.OfType().SingleOrDefault(slave => slave.ResourceId.Equals(slaveId));
Job j = Context.Jobs.SingleOrDefault(job => job.JobId.Equals(jobId));
s.Jobs.Add(j);
j.Slave = s;
CommitChanges();
}
public void UnAssignSlaveToJob(Guid jobId) {
Job j = Context.Jobs.SingleOrDefault(job => job.JobId.Equals(jobId));
j.Slave = null;
CommitChanges();
}
public void SetJobOffline(JobDto job) {
Job j = Context.Jobs.SingleOrDefault(jq => jq.JobId.Equals(job.Id));
j.Slave = null;
var childJobs = Context.Jobs.Where(child => child.ParentJobId == j.JobId);
if (childJobs.Count() > 0) {
j.JobState = JobState.WaitForChildJobs.ToString();
} else {
j.JobState = JobState.Offline.ToString();
}
CommitChanges();
}
public Stream GetSerializedJobStream(Guid jobId) {
VarBinarySource source = new VarBinarySource((SqlConnection)Context.Connection, null, "Job", "SerializedJob", "JobId", jobId);
return new VarBinaryStream(source);
}
public IEnumerable FindJobsById(IEnumerable jobIds) {
IQueryable jobs = from job in Context.Jobs
where jobIds.Contains(job.JobId)
select EntityToDto(job, null);
return jobs.ToList();
}
public bool IsUserAuthorizedForJobs(Guid userId, params Guid[] jobIds) {
var jobs = from job in Context.Jobs
where jobIds.Contains(job.JobId)
select job;
return jobs.All(job => job.UserId == userId);
}
public IEnumerable FindJobsByParentId(Guid? parentJobId, bool recursive) {
IQueryable query = from job in Context.Jobs
where parentJobId == null ? !job.ParentJobId.HasValue : job.ParentJobId.Value == parentJobId
select EntityToDto(job, null);
List jobs = query.ToList();
if (recursive) {
List childs = new List();
foreach (JobDto job in jobs) {
childs.AddRange(FindJobsByParentId(job.Id, recursive));
}
jobs.AddRange(childs);
}
return jobs;
}
#endregion
public override Job DtoToEntity(JobDto source, Job target) {
if (source == null)
return null;
if (target == null)
target = new Job();
target.CoresNeeded = source.CoresNeeded;
target.MemoryNeeded = source.MemoryNeeded;
target.DateCalculated = source.DateCalculated;
target.DateCreated = source.DateCreated;
target.DateFinished = source.DateFinished;
target.JobId = source.Id;
target.ExecutionTime = source.ExecutionTime.ToString();
target.Exception = source.Exception;
target.Priority = source.Priority;
target.JobState = Enum.GetName(typeof(JobState), source.State);
target.UserId = source.UserId;
target.ParentJobId = source.ParentJobId;
foreach (Guid assignRessourceId in source.AssignedResourceIds) {
if (!target.AssignedResources.Select(x => x.ResourceId).Contains(assignRessourceId)) {
target.AssignedResources.Add(new AssignedResource { ResourceId = assignRessourceId });
}
}
return target;
}
//Slave is not used ATM - not sure when we stopped using those...
public override JobDto EntityToDto(Job source, JobDto target) {
if (source == null)
return null;
if (target == null)
target = new JobDto();
target.CoresNeeded = source.CoresNeeded;
target.MemoryNeeded = source.MemoryNeeded;
target.DateCalculated = source.DateCalculated;
target.DateCreated = source.DateCreated;
target.DateFinished = source.DateFinished;
target.Id = source.JobId;
target.Exception = source.Exception;
TimeSpan ts;
if (!TimeSpan.TryParse(source.ExecutionTime, out ts)) ts = TimeSpan.Zero;
target.ExecutionTime = ts;
target.Priority = source.Priority;
target.State = (JobState)Enum.Parse(typeof(JobState), source.JobState, true);
target.UserId = source.UserId;
target.ParentJobId = source.ParentJobId;
target.AssignedResourceIds = source.AssignedResources.Select(x => x.ResourceId).ToList();
return target;
}
}
}