Free cookie consent management tool by TermsFeed Policy Generator

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

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

added name in IModel
added update methods for IModel and ModelData
(ticket #712)

File size: 10.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Reflection;
26
27using HeuristicLab.Core;
28using HeuristicLab.DataAnalysis;
29using HeuristicLab.Data;
30using System.Data.Linq;
31
32namespace HeuristicLab.Modeling.Database.SQLServerCompact {
33  public class DatabaseService : IModelingDatabase {
34
35    private readonly string connection;
36    public DatabaseService(string connection) {
37      this.connection = connection;
38      Connect();
39      if (!ctx.DatabaseExists())
40        ctx.CreateDatabase();
41    }
42
43    private void EmptyDatabase() {
44      ctx.DeleteDatabase();
45      ctx.CreateDatabase();
46    }
47
48    private ModelingDataContext ctx;
49    public void Connect() {
50      if (ctx != null)
51        return;
52
53      ctx = new ModelingDataContext(connection);
54      DataLoadOptions dlo = new DataLoadOptions();
55      dlo.LoadWith<ModelResult>(mr => mr.Result);
56      dlo.LoadWith<InputVariableResult>(ir => ir.Variable);
57      dlo.LoadWith<InputVariableResult>(ir => ir.Result);
58      dlo.LoadWith<Model>(m => m.TargetVariable);
59      dlo.LoadWith<Model>(m => m.Algorithm);
60      ctx.LoadOptions = dlo;
61    }
62
63    public void Disconnect() {
64      if (ctx == null)
65        return;
66      ctx.Dispose();
67      ctx = null;
68    }
69
70    public IModel Persist(HeuristicLab.Modeling.IAlgorithm algorithm) {
71      GetOrCreateProblem(algorithm.Dataset);
72      return Persist(algorithm.Model, algorithm.Name, algorithm.Description);
73    }
74
75    public IModel Persist(HeuristicLab.Modeling.IAnalyzerModel model, string algorithmName, string algorithmDescription) {
76      Dictionary<string, Variable> variables = GetAllVariables();
77      Algorithm algo = GetOrCreateAlgorithm(algorithmName, algorithmDescription);
78      Variable target = variables[model.TargetVariable];
79      Model m;
80
81      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
82        m = new Model(target, algo);
83        m.TrainingSamplesStart = model.TrainingSamplesStart;
84        m.TrainingSamplesEnd = model.TrainingSamplesEnd;
85        m.ValidationSamplesStart = model.ValidationSamplesStart;
86        m.ValidationSamplesEnd = model.ValidationSamplesEnd;
87        m.TestSamplesStart = model.TestSamplesStart;
88        m.TestSamplesEnd = model.TestSamplesEnd;
89
90        ctx.Models.InsertOnSubmit(m);
91
92        ctx.SubmitChanges();
93      }
94
95      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
96        ctx.ModelData.InsertOnSubmit(new ModelData(m, PersistenceManager.SaveToGZip(model.Predictor)));
97        ctx.SubmitChanges();
98      }
99
100      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
101        foreach (string inputVariable in model.InputVariables) {
102          ctx.InputVariables.InsertOnSubmit(new InputVariable(m, variables[inputVariable]));
103        }
104        ctx.SubmitChanges();
105      }
106
107      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
108        //get all double properties to save as modelResult
109        IEnumerable<PropertyInfo> modelResultInfos = model.GetType().GetProperties().Where(
110          info => info.PropertyType == typeof(double));
111        foreach (PropertyInfo modelResultInfo in modelResultInfos) {
112          Result result = GetOrCreateResult(modelResultInfo.Name);
113          double value = (double)modelResultInfo.GetValue(model, null);
114          ctx.ModelResults.InsertOnSubmit(new ModelResult(m, result, value));
115        }
116        ctx.SubmitChanges();
117      }
118
119      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
120        IEnumerable<MethodInfo> inputVariableResultInfos = model.GetType().GetMethods().Where(
121          info => info.GetParameters().Count() == 1 &&
122             info.GetParameters()[0].ParameterType == typeof(string) &&
123             info.GetParameters()[0].Name == "variableName" &&
124             info.ReturnParameter.ParameterType == typeof(double) &&
125             info.Name.StartsWith("Get"));
126        foreach (MethodInfo inputVariableResultInfo in inputVariableResultInfos) {
127          Result result = GetOrCreateResult(inputVariableResultInfo.Name.Substring(3));
128          foreach (InputVariable variable in ctx.InputVariables.Where(iv => iv.Model == m)) {
129            double value = (double)inputVariableResultInfo.Invoke(model, new object[] { variable.Variable.Name });
130            ctx.InputVariableResults.InsertOnSubmit(new InputVariableResult(variable, result, value));
131          }
132        }
133        ctx.SubmitChanges();
134      }
135
136      //if connected to database return inserted model
137      if (this.ctx != null)
138        return this.ctx.Models.Where(x => x.Id == m.Id).Single();
139      return null;
140    }
141
142    #region Problem
143
144    public Dataset GetDataset() {
145      if (ctx.Problems.Count() != 1)
146        throw new InvalidOperationException("Could not get dataset. No or more than one problems are persisted in the database.");
147
148      Problem problem = ctx.Problems.Single();
149      return problem.Dataset;
150
151    }
152
153    public IProblem GetOrCreateProblem(Dataset dataset) {
154      IProblem problem;
155      if (ctx.Problems.Count() == 0)
156        problem = PersistProblem(dataset);
157      else
158        problem = ctx.Problems.Single();
159      if (problem.Dataset.ToString() != dataset.ToString())
160        throw new InvalidOperationException("Could not persist dataset. The database already contains a different dataset.");
161      return problem;
162    }
163
164    public IProblem PersistProblem(Dataset dataset) {
165      Problem problem;
166      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
167        if (ctx.Problems.Count() != 0)
168          throw new InvalidOperationException("Could not persist dataset. A dataset is already saved in the database.");
169        problem = new Problem(dataset);
170        ctx.Problems.InsertOnSubmit(problem);
171        foreach (string variable in dataset.VariableNames) {
172          ctx.Variables.InsertOnSubmit(new Variable(variable));
173        }
174        ctx.SubmitChanges();
175      }
176      return problem;
177    }
178
179    #endregion
180
181    #region Algorithm
182    public Algorithm GetOrCreateAlgorithm(string name, string description) {
183      Algorithm algorithm;
184      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
185        var algorithms = from algo in ctx.Algorithms
186                         where algo.Name == name && algo.Description == description
187                         select algo;
188        if (algorithms.Count() == 0) {
189          algorithm = new Algorithm(name, description);
190          ctx.Algorithms.InsertOnSubmit(algorithm);
191          ctx.SubmitChanges();
192        } else if (algorithms.Count() == 1)
193          algorithm = algorithms.Single();
194        else
195          throw new ArgumentException("Could not get Algorithm. More than one algorithm with the name " + name + " are saved in database.");
196      }
197      return algorithm;
198    }
199
200    public IEnumerable<IAlgorithm> GetAllAlgorithms() {
201      return ctx.Algorithms.ToList().Cast<IAlgorithm>();
202    }
203    #endregion
204
205    #region Variables
206    public Dictionary<string, Variable> GetAllVariables() {
207      Dictionary<string, Variable> dict = new Dictionary<string, Variable>();
208      dict = ctx.Variables.ToDictionary<Variable, string>(delegate(Variable v) { return v.Name; });
209      return dict;
210    }
211    #endregion
212
213    #region Result
214    public Result GetOrCreateResult(string name) {
215      Result result;
216      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
217        var results = from r in ctx.Results
218                      where r.Name == name
219                      select r;
220        if (results.Count() == 0) {
221          result = new Result(name);
222          ctx.Results.InsertOnSubmit(result);
223          ctx.SubmitChanges();
224        } else if (results.Count() == 1)
225          result = results.Single();
226        else
227          throw new ArgumentException("Could not get result. More than one result with the name " + name + " are saved in database.");
228      }
229      return result;
230    }
231
232    public IEnumerable<IResult> GetAllResults() {
233      return ctx.Results.ToList().Cast<IResult>();
234    }
235
236    public IEnumerable<IResult> GetAllResultsForInputVariables() {
237      return (from ir in ctx.InputVariableResults select ir.Result).Distinct().ToList().Cast<IResult>();
238    }
239
240    #endregion
241
242    #region ModelResult
243    public IEnumerable<IModelResult> GetModelResults(IModel model) {
244      var results = from result in ctx.ModelResults
245                    where result.Model == model
246                    select result;
247      return results.ToList().Cast<IModelResult>();
248    }
249    #endregion
250
251    #region InputVariableResults
252    public IEnumerable<IInputVariableResult> GetInputVariableResults(IModel model) {
253      var inputResults = from ir in ctx.InputVariableResults
254                         where ir.Model == model
255                         select ir;
256      return inputResults.ToList().Cast<IInputVariableResult>();
257    }
258
259    #endregion
260
261    #region Model
262    public IEnumerable<IModel> GetAllModels() {
263      return ctx.Models.ToList().Cast<IModel>();
264    }
265
266    public void UpdateModel(IModel model) {
267      Model m = (Model)model;
268      Model orginal = ctx.Models.GetOriginalEntityState(m);
269      if (orginal == null)
270        ctx.Models.Attach(m);
271      ctx.SubmitChanges();
272    }
273
274    public byte[] GetModelData(IModel model) {
275      var data = (from md in ctx.ModelData
276                  where md.Model == model
277                  select md);
278      if (data.Count() == 0)
279        return null;
280      return data.Single().Data;
281    }
282
283    public void UpdateModelData(IModel model, byte[] modelData) {
284      Model m = (Model)model;
285      ctx.ModelData.DeleteAllOnSubmit(ctx.ModelData.Where(x => x.Model == m));
286      ctx.ModelData.InsertOnSubmit(new ModelData(m, modelData));
287      ctx.SubmitChanges();
288    }
289
290    public IPredictor GetModelPredictor(IModel model) {
291      byte[] data = GetModelData(model);
292      return (IPredictor)PersistenceManager.RestoreFromGZip(data);
293    }
294    #endregion
295  }
296}
Note: See TracBrowser for help on using the repository browser.