using System; using System.Collections.Generic; using System.Linq; using System.Text; using HeuristicLab.Hive.Contracts.BusinessObjects; using System.Data.Linq; using HeuristicLab.Hive.Server.DataAccess; using System.IO; using System.Data.SqlClient; 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)).ToList(); } public IEnumerable FindWithLimitations(State jobState, int offset, int count) { IQueryable query = null; if (jobState == State.Finished) { query = from job in Context.Jobs where job.JobState == Enum.GetName(typeof (State), jobState) orderby job.DateFinished select EntityToDto(job, null); } else if (jobState == State.Calculating || jobState == State.RequestSnapshot || jobState == State.RequestSnapshotSent) { query = from job in Context.Jobs where job.JobState == Enum.GetName(typeof(State), jobState) orderby job.DateCalculated select EntityToDto(job, null); } else { query = from job in Context.Jobs where job.JobState == Enum.GetName(typeof(State), 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(JobDto bObj) { Job job = Context.Jobs.SingleOrDefault(j => j.JobId.Equals(bObj.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(ClientDto client) { return (from j in Context.Jobs where (j.JobState == Enum.GetName(typeof (State), State.Calculating) || j.JobState == Enum.GetName(typeof (State), State.Abort) || j.JobState == Enum.GetName(typeof (State), State.RequestSnapshot) || j.JobState == Enum.GetName(typeof (State), State.RequestSnapshotSent)) && (j.ResourceId.Equals(client.Id)) select EntityToDto(j, null)).ToList(); } public IEnumerable FindFittingJobsForSlave(State state, int freeCores, int freeMemory, Guid clientId) { ClientGroupDao cgd = new ClientGroupDao(); List idList = new List(cgd.FindAllGroupAndParentGroupIdsForClient(clientId)); //Add myself too - enables jobs for one specific host! idList.Add(clientId); var q = (from ar in Context.AssignedResources where ar.Job.JobState == Enum.GetName(typeof (State), State.Offline) && 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 GetJobsByState(State state) { return (from j in Context.Jobs where (j.JobState == Enum.GetName(typeof (State), state)) select EntityToDto(j, null)).ToList(); } public void AssignSlaveToJob(Guid clientId, Guid jobId) { Client c = Context.Resources.OfType().SingleOrDefault(client => client.ResourceId.Equals(clientId)); Job j = Context.Jobs.SingleOrDefault(job => job.JobId.Equals(jobId)); c.Jobs.Add(j); j.Client = c; CommitChanges(); } public void SetJobOffline(JobDto job) { Job j = Context.Jobs.SingleOrDefault(jq => jq.JobId.Equals(job.Id)); j.Client = null; j.JobState = Enum.GetName(typeof(State), State.Offline); 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(); } #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.Percentage = source.Percentage; target.Exception = source.Exception; target.Priority = source.Priority; target.JobState = Enum.GetName(typeof(State), source.State); return target; } //Assigned ressources are not used atm! //Client 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.ParentJob = null; //target.PluginsNeeded = null; //target.Client = null; //target.Project = null; 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; target.Percentage = source.Percentage; target.Priority = source.Priority; target.State = (State) Enum.Parse(typeof (State), source.JobState, true); return target; } } }