Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Modeling.Database.SQLServerCompact/3.2/DatabaseService.cs @ 2223

Last change on this file since 2223 was 2223, checked in by mkommend, 15 years ago

reintegrated branch new heuristic.modeling database backend (ticket #712)

File size: 9.6 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Reflection;
6
7using HeuristicLab.Core;
8using HeuristicLab.DataAnalysis;
9using HeuristicLab.Data;
10using System.Data.Linq;
11
12namespace HeuristicLab.Modeling.Database.SQLServerCompact {
13  public class DatabaseService : IModelingDatabase {
14
15    private readonly string connection;
16    public DatabaseService(string connection) {
17      this.connection = connection;
18      Connect();
19      if (!ctx.DatabaseExists())
20        ctx.CreateDatabase();
21    }
22
23    private void EmptyDatabase() {
24      ctx.DeleteDatabase();
25      ctx.CreateDatabase();
26    }
27
28    private ModelingDataContext ctx;
29    public void Connect() {
30      if (ctx != null)
31        return;
32
33      ctx = new ModelingDataContext(connection);
34      DataLoadOptions dlo = new DataLoadOptions();
35      dlo.LoadWith<ModelResult>(mr => mr.Result);
36      dlo.LoadWith<InputVariableResult>(ir => ir.Variable);
37      dlo.LoadWith<InputVariableResult>(ir => ir.Result);
38      dlo.LoadWith<Model>(m => m.TargetVariable);
39      ctx.LoadOptions = dlo;
40    }
41
42    public void Disconnect() {
43      if (ctx == null)
44        return;
45      ctx.Dispose();
46      ctx = null;
47    }
48
49    public void Persist(HeuristicLab.Modeling.IAlgorithm algorithm) {
50      int trainingSamplesStart = ((IntData)algorithm.Engine.GlobalScope.GetVariableValue("TrainingSamplesStart", false)).Data;
51      int trainingSamplesEnd = ((IntData)algorithm.Engine.GlobalScope.GetVariableValue("TrainingSamplesEnd", false)).Data;
52      int validationSamplesStart = ((IntData)algorithm.Engine.GlobalScope.GetVariableValue("ValidationSamplesStart", false)).Data;
53      int validationSamplesEnd = ((IntData)algorithm.Engine.GlobalScope.GetVariableValue("ValidationSamplesEnd", false)).Data;
54      int testSamplesStart = ((IntData)algorithm.Engine.GlobalScope.GetVariableValue("TestSamplesStart", false)).Data;
55      int testSamplesEnd = ((IntData)algorithm.Engine.GlobalScope.GetVariableValue("TestSamplesEnd", false)).Data;
56
57      GetOrCreateProblem(algorithm.Dataset);
58      Dictionary<string, Variable> variables = GetAllVariables();
59      Algorithm algo = GetOrCreateAlgorithm(algorithm.Name, algorithm.Description);
60      Variable target = variables[algorithm.Model.TargetVariable];
61      Model model;
62
63      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
64        model = new Model(target, algo);
65        model.TrainingSamplesStart = trainingSamplesStart;
66        model.TrainingSamplesEnd = trainingSamplesEnd;
67        model.ValidationSamplesStart = validationSamplesStart;
68        model.ValidationSamplesEnd = validationSamplesEnd;
69        model.TestSamplesStart = testSamplesStart;
70        model.TestSamplesEnd = testSamplesEnd;
71
72        ctx.Models.InsertOnSubmit(model);
73
74        ctx.SubmitChanges();
75      }
76
77      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
78        ctx.ModelData.InsertOnSubmit(new ModelData(model, PersistenceManager.SaveToGZip(algorithm.Model.Data)));
79      }
80
81      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
82        foreach (string inputVariable in algorithm.Model.InputVariables) {
83          ctx.InputVariables.InsertOnSubmit(new InputVariable(model, variables[inputVariable]));
84        }
85        ctx.SubmitChanges();
86      }
87
88      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
89        //get all double properties to save as modelResult
90        IEnumerable<PropertyInfo> modelResultInfos = algorithm.Model.GetType().GetProperties().Where(
91          info => info.PropertyType == typeof(double));
92        foreach (PropertyInfo modelResultInfo in modelResultInfos) {
93          Result result = GetOrCreateResult(modelResultInfo.Name);
94          double value = (double)modelResultInfo.GetValue(algorithm.Model, null);
95          ctx.ModelResults.InsertOnSubmit(new ModelResult(model, result, value));
96        }
97        ctx.SubmitChanges();
98      }
99
100      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
101        IEnumerable<MethodInfo> inputVariableResultInfos = algorithm.Model.GetType().GetMethods().Where(
102          info => info.GetParameters().Count() == 1 &&
103             info.GetParameters()[0].ParameterType == typeof(string) &&
104             info.GetParameters()[0].Name == "variableName" &&
105             info.ReturnParameter.ParameterType == typeof(double) &&
106             info.Name.StartsWith("Get"));
107        foreach (MethodInfo inputVariableResultInfo in inputVariableResultInfos) {
108          Result result = GetOrCreateResult(inputVariableResultInfo.Name.Substring(3));
109          foreach (InputVariable variable in ctx.InputVariables.Where(iv => iv.Model == model)) {
110            double value = (double)inputVariableResultInfo.Invoke(algorithm.Model, new object[] { variable.Variable.Name });
111            ctx.InputVariableResults.InsertOnSubmit(new InputVariableResult(variable, result, value));
112          }
113        }
114        ctx.SubmitChanges();
115      }
116
117    }
118
119    #region Problem
120
121    public Dataset GetDataset() {
122      if (ctx.Problems.Count() != 1)
123        throw new InvalidOperationException("Could not get dataset. No or more than one problems are persisted in the database.");
124
125      Problem problem = ctx.Problems.Single();
126      return problem.Dataset;
127
128    }
129
130    public Problem GetOrCreateProblem(Dataset dataset) {
131      Problem problem;
132      if (ctx.Problems.Count() == 0)
133        problem = PersistProblem(dataset);
134      else
135        problem = ctx.Problems.Single();
136      if (problem.Dataset.ToString() != dataset.ToString())
137        throw new InvalidOperationException("Could not persist dataset. The database already contains a different dataset.");
138      return problem;
139    }
140
141    private Problem PersistProblem(Dataset dataset) {
142      Problem problem;
143      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
144        if (ctx.Problems.Count() != 0)
145          throw new InvalidOperationException("Could not persist dataset. A dataset is already saved in the database.");
146        problem = new Problem(dataset);
147        ctx.Problems.InsertOnSubmit(problem);
148        foreach (string variable in dataset.VariableNames) {
149          ctx.Variables.InsertOnSubmit(new Variable(variable));
150        }
151        ctx.SubmitChanges();
152      }
153      return problem;
154    }
155
156    #endregion
157
158    #region Algorithm
159    public Algorithm GetOrCreateAlgorithm(string name, string description) {
160      Algorithm algorithm;
161      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
162        var algorithms = from algo in ctx.Algorithms
163                         where algo.Name == name && algo.Description == description
164                         select algo;
165        if (algorithms.Count() == 0) {
166          algorithm = new Algorithm(name, description);
167          ctx.Algorithms.InsertOnSubmit(algorithm);
168          ctx.SubmitChanges();
169        } else if (algorithms.Count() == 1)
170          algorithm = algorithms.Single();
171        else
172          throw new ArgumentException("Could not get Algorithm. More than one algorithm with the name " + name + " are saved in database.");
173      }
174      return algorithm;
175    }
176    #endregion
177
178    #region Variables
179    public Dictionary<string, Variable> GetAllVariables() {
180      Dictionary<string, Variable> dict = new Dictionary<string, Variable>();
181      dict = ctx.Variables.ToDictionary<Variable, string>(delegate(Variable v) { return v.Name; });
182      return dict;
183    }
184    #endregion
185
186    #region Result
187    public Result GetOrCreateResult(string name) {
188      Result result;
189      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
190        var results = from r in ctx.Results
191                      where r.Name == name
192                      select r;
193        if (results.Count() == 0) {
194          result = new Result(name);
195          ctx.Results.InsertOnSubmit(result);
196          ctx.SubmitChanges();
197        } else if (results.Count() == 1)
198          result = results.Single();
199        else
200          throw new ArgumentException("Could not get result. More than one result with the name " + name + " are saved in database.");
201      }
202      return result;
203    }
204
205    public IEnumerable<IResult> GetAllResults() {
206      return ctx.Results.ToList().Cast<IResult>();
207    }
208
209    public IEnumerable<IResult> GetAllResultsForInputVariables() {
210      return (from ir in ctx.InputVariableResults select ir.Result).Distinct().ToList().Cast<IResult>();
211    }
212
213    #endregion
214
215    #region ModelResult
216    public IEnumerable<IModelResult> GetModelResults(IModel model) {
217      var results = from result in ctx.ModelResults
218                    where result.Model == model
219                    select result;
220      return results.ToList().Cast<IModelResult>();
221    }
222    #endregion
223
224    #region InputVariableResults
225    public IEnumerable<IInputVariableResult> GetInputVariableResults(IModel model) {
226      var inputResults = from ir in ctx.InputVariableResults
227                         where ir.Model == model
228                         select ir;
229      return inputResults.ToList().Cast<IInputVariableResult>();
230    }
231
232    #endregion
233
234    #region Model
235    public IEnumerable<IModel> GetAllModels() {
236      return ctx.Models.ToList().Cast<IModel>();
237    }
238
239    public byte[] GetModelData(IModel model) {
240      var data = (from md in ctx.ModelData
241                  where md.Model == model
242                  select md);
243      if (data.Count() == 0)
244        return null;
245      return data.Single().Data;
246    }
247    #endregion
248
249  }
250}
Note: See TracBrowser for help on using the repository browser.