Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 2370 was 2370, checked in by gkronber, 15 years ago

Added enumerable type for model results and changed analyzer model, the database backend and the model analysis operators to use the enumerable type instead of hard-coded strings. #755 (Hard-coded strings for variable names of data-modeling results)

File size: 11.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    public void EmptyDatabase() {
44      ctx.Connection.Dispose();
45      ctx.DeleteDatabase();
46      Connect();
47      ctx.CreateDatabase();
48    }
49
50    private ModelingDataContext ctx;
51    public void Connect() {
52      if (ctx != null)
53        Disconnect();
54
55      ctx = new ModelingDataContext(connection);
56      DataLoadOptions dlo = new DataLoadOptions();
57      dlo.LoadWith<ModelResult>(mr => mr.Result);
58      dlo.LoadWith<ModelMetaData>(mmd => mmd.MetaData);
59      dlo.LoadWith<InputVariableResult>(ir => ir.Variable);
60      dlo.LoadWith<InputVariableResult>(ir => ir.Result);
61      dlo.LoadWith<Model>(m => m.TargetVariable);
62      dlo.LoadWith<Model>(m => m.Algorithm);
63      ctx.LoadOptions = dlo;
64    }
65
66    public void Disconnect() {
67      if (ctx == null)
68        return;
69      ctx.Connection.Dispose();
70      ctx.Dispose();
71      ctx = null;
72    }
73
74    public IModel Persist(HeuristicLab.Modeling.IAlgorithm algorithm) {
75      GetOrCreateProblem(algorithm.Dataset);
76      return Persist(algorithm.Model, algorithm.Name, algorithm.Description);
77    }
78
79    public IModel Persist(HeuristicLab.Modeling.IAnalyzerModel model, string algorithmName, string algorithmDescription) {
80      Dictionary<string, Variable> variables = GetAllVariables();
81      Algorithm algo = GetOrCreateAlgorithm(algorithmName, algorithmDescription);
82      Variable target = variables[model.TargetVariable];
83      Model m;
84
85      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
86        m = new Model(target, algo);
87        m.TrainingSamplesStart = model.TrainingSamplesStart;
88        m.TrainingSamplesEnd = model.TrainingSamplesEnd;
89        m.ValidationSamplesStart = model.ValidationSamplesStart;
90        m.ValidationSamplesEnd = model.ValidationSamplesEnd;
91        m.TestSamplesStart = model.TestSamplesStart;
92        m.TestSamplesEnd = model.TestSamplesEnd;
93
94        ctx.Models.InsertOnSubmit(m);
95
96        ctx.SubmitChanges();
97      }
98
99      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
100        ctx.ModelData.InsertOnSubmit(new ModelData(m, PersistenceManager.SaveToGZip(model.Predictor)));
101        ctx.SubmitChanges();
102      }
103
104      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
105        foreach (string inputVariable in model.InputVariables) {
106          ctx.InputVariables.InsertOnSubmit(new InputVariable(m, variables[inputVariable]));
107        }
108        ctx.SubmitChanges();
109      }
110
111      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
112        foreach (KeyValuePair<ModelingResult, double> pair in model.Results) {
113          Result result = GetOrCreateResult(pair.Key.ToString());
114          ctx.ModelResults.InsertOnSubmit(new ModelResult(m, result, pair.Value));
115        }
116        ctx.SubmitChanges();
117      }
118
119      // code to store meta-information for models (gkronber (8.9.09))
120      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
121        foreach (KeyValuePair<string, double> pair in model.MetaData) {
122          MetaData metaData = GetOrCreateMetaData(pair.Key);
123          ctx.ModelMetaData.InsertOnSubmit(new ModelMetaData(m, metaData, pair.Value));
124        }
125        ctx.SubmitChanges();
126      }
127
128      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
129        foreach (InputVariable variable in ctx.InputVariables.Where(iv => iv.Model == m)) {
130          foreach (KeyValuePair<ModelingResult, double> variableResult in model.GetVariableResults(variable.Variable.Name)) {
131            Result result = GetOrCreateResult(variableResult.Key.ToString());
132            ctx.InputVariableResults.InsertOnSubmit(new InputVariableResult(variable, result, variableResult.Value));
133          }
134        }
135        ctx.SubmitChanges();
136      }
137
138      //if connected to database return inserted model
139      if (this.ctx != null)
140        return this.ctx.Models.Where(x => x.Id == m.Id).Single();
141      return null;
142    }
143
144    #region Problem
145
146    public Dataset GetDataset() {
147      if (ctx.Problems.Count() != 1)
148        throw new InvalidOperationException("Could not get dataset. No or more than one problems are persisted in the database.");
149
150      Problem problem = ctx.Problems.Single();
151      return problem.Dataset;
152
153    }
154
155    public IProblem GetOrCreateProblem(Dataset dataset) {
156      IProblem problem;
157      if (ctx.Problems.Count() == 0)
158        problem = PersistProblem(dataset);
159      else
160        problem = ctx.Problems.Single();
161      if (problem.Dataset.ToString() != dataset.ToString())
162        throw new InvalidOperationException("Could not persist dataset. The database already contains a different dataset.");
163      return problem;
164    }
165
166    public IProblem PersistProblem(Dataset dataset) {
167      Problem problem;
168      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
169        if (ctx.Problems.Count() != 0)
170          throw new InvalidOperationException("Could not persist dataset. A dataset is already saved in the database.");
171        problem = new Problem(dataset);
172        ctx.Problems.InsertOnSubmit(problem);
173        foreach (string variable in dataset.VariableNames) {
174          ctx.Variables.InsertOnSubmit(new Variable(variable));
175        }
176        ctx.SubmitChanges();
177      }
178      return problem;
179    }
180
181    #endregion
182
183    #region Algorithm
184    public Algorithm GetOrCreateAlgorithm(string name, string description) {
185      Algorithm algorithm;
186      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
187        var algorithms = from algo in ctx.Algorithms
188                         where algo.Name == name && algo.Description == description
189                         select algo;
190        if (algorithms.Count() == 0) {
191          algorithm = new Algorithm(name, description);
192          ctx.Algorithms.InsertOnSubmit(algorithm);
193          ctx.SubmitChanges();
194        } else if (algorithms.Count() == 1)
195          algorithm = algorithms.Single();
196        else
197          throw new ArgumentException("Could not get Algorithm. More than one algorithm with the name " + name + " are saved in database.");
198      }
199      return algorithm;
200    }
201
202    public IEnumerable<IAlgorithm> GetAllAlgorithms() {
203      return ctx.Algorithms.ToList().Cast<IAlgorithm>();
204    }
205    #endregion
206
207    #region Variables
208    public Dictionary<string, Variable> GetAllVariables() {
209      Dictionary<string, Variable> dict = new Dictionary<string, Variable>();
210      dict = ctx.Variables.ToDictionary<Variable, string>(delegate(Variable v) { return v.Name; });
211      return dict;
212    }
213    #endregion
214
215    #region Result
216    public Result GetOrCreateResult(string name) {
217      Result result;
218      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
219        var results = from r in ctx.Results
220                      where r.Name == name
221                      select r;
222        if (results.Count() == 0) {
223          result = new Result(name);
224          ctx.Results.InsertOnSubmit(result);
225          ctx.SubmitChanges();
226        } else if (results.Count() == 1)
227          result = results.Single();
228        else
229          throw new ArgumentException("Could not get result. More than one result with the name " + name + " are saved in database.");
230      }
231      return result;
232    }
233
234    public IEnumerable<IResult> GetAllResults() {
235      return ctx.Results.ToList().Cast<IResult>();
236    }
237
238    public IEnumerable<IResult> GetAllResultsForInputVariables() {
239      return (from ir in ctx.InputVariableResults select ir.Result).Distinct().ToList().Cast<IResult>();
240    }
241
242    #endregion
243
244    #region ModelResult
245    public IEnumerable<IModelResult> GetModelResults(IModel model) {
246      var results = from result in ctx.ModelResults
247                    where result.Model == model
248                    select result;
249      return results.ToList().Cast<IModelResult>();
250    }
251    #endregion
252
253    #region InputVariableResults
254    public IEnumerable<IInputVariableResult> GetInputVariableResults(IModel model) {
255      var inputResults = from ir in ctx.InputVariableResults
256                         where ir.Model == model
257                         select ir;
258      return inputResults.ToList().Cast<IInputVariableResult>();
259    }
260
261    #endregion
262
263    #region ModelMetaData
264    public IEnumerable<IModelMetaData> GetModelMetaData(IModel model) {
265      var metadata = from md in ctx.ModelMetaData
266                     where md.Model == model
267                     select md;
268      return metadata.ToList().Cast<IModelMetaData>();
269    }
270    #endregion
271
272    #region MetaData
273    public IEnumerable<IMetaData> GetAllMetaData() {
274      return ctx.MetaData.ToList().Cast<IMetaData>();
275    }
276
277    public MetaData GetOrCreateMetaData(string name) {
278      MetaData metadata;
279      using (ModelingDataContext ctx = new ModelingDataContext(connection)) {
280        var md = from r in ctx.MetaData
281                 where r.Name == name
282                 select r;
283        if (md.Count() == 0) {
284          metadata = new MetaData(name);
285          ctx.MetaData.InsertOnSubmit(metadata);
286          ctx.SubmitChanges();
287        } else if (md.Count() == 1)
288          metadata = md.Single();
289        else
290          throw new ArgumentException("Could not get metadata. More than one metadata with the name " + name + " are saved in database.");
291      }
292      return metadata;
293    }
294
295    #endregion
296
297    #region Model
298    public IEnumerable<IModel> GetAllModels() {
299      return ctx.Models.ToList().Cast<IModel>();
300    }
301
302    public void UpdateModel(IModel model) {
303      Model m = (Model)model;
304      Model orginal = ctx.Models.GetOriginalEntityState(m);
305      if (orginal == null)
306        ctx.Models.Attach(m);
307      ctx.Refresh(RefreshMode.KeepCurrentValues, m);
308      ctx.SubmitChanges();
309    }
310
311    public byte[] GetModelData(IModel model) {
312      var data = (from md in ctx.ModelData
313                  where md.Model == model
314                  select md);
315      if (data.Count() == 0)
316        return null;
317      return data.Single().Data;
318    }
319
320    public void UpdateModelData(IModel model, byte[] modelData) {
321      Model m = (Model)model;
322      ctx.ModelData.DeleteAllOnSubmit(ctx.ModelData.Where(x => x.Model == m));
323      ctx.ModelData.InsertOnSubmit(new ModelData(m, modelData));
324      ctx.SubmitChanges();
325    }
326
327    public IPredictor GetModelPredictor(IModel model) {
328      byte[] data = GetModelData(model);
329      return (IPredictor)PersistenceManager.RestoreFromGZip(data);
330    }
331    #endregion
332  }
333}
Note: See TracBrowser for help on using the repository browser.