Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Services.Deployment/3.3/PluginStore.cs @ 3181

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

Added deployment service projects to HL 3.3 solution. #918 (Integrate deployment service into trunk and HL3.3 solution file)

File size: 10.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Text;
26using System.Data.Common;
27using System.Transactions;
28using System.Data.SqlClient;
29using HeuristicLab.Services.Deployment.DataAccess;
30
31namespace HeuristicLab.Services.Deployment {
32  public class PluginStore {
33
34    public PluginStore() {
35    }
36
37    #region context creating members
38    public IEnumerable<ProductDescription> Products {
39      get {
40        using (var ctx = new PluginStoreClassesDataContext()) {
41          return (from p in ctx.Products
42                  let plugins = from pair in ctx.ProductPlugins
43                                from plugin in ctx.Plugins
44                                where pair.ProductId == p.Id
45                                where plugin.Id == pair.PluginId
46                                select plugin
47                  select MakeProductDescription(ctx, p, plugins)).ToList();
48        }
49      }
50    }
51
52    public IEnumerable<PluginDescription> Plugins {
53      get {
54        using (var ctx = new PluginStoreClassesDataContext()) {
55          return (from plugin in ctx.Plugins
56                  select MakePluginDescription(ctx, plugin)).ToList();
57        }
58      }
59    }
60
61    public byte[] PluginFile(PluginDescription pluginDescription) {
62      using (var ctx = new PluginStoreClassesDataContext()) {
63        return GetExistingPlugin(ctx, pluginDescription.Name, pluginDescription.Version).PluginPackage.Data.ToArray();
64      }
65    }
66
67    public void Persist(PluginDescription pluginDescription, byte[] pluginPackage) {
68      using (var ctx = new PluginStoreClassesDataContext()) {
69        try {
70          using (var transaction = new TransactionScope()) {
71            Plugin pluginEntity = InsertOrUpdatePlugin(ctx, pluginDescription);
72            if (pluginEntity.PluginPackage == null) {
73              // insert
74              pluginEntity.PluginPackage = MakePluginPackage(pluginEntity, pluginPackage);
75            } else {
76              // update
77              pluginEntity.PluginPackage.Data = pluginPackage;
78            }
79            ctx.SubmitChanges();
80            transaction.Complete();
81          }
82        }
83        catch (SqlException ex) {
84          throw new ArgumentException("Something went wrong while trying to persist plugin", ex);
85        }
86        catch (InvalidOperationException ex) {
87          throw new ArgumentException("Something went wrong while trying to persist plugin", ex);
88        }
89      }
90    }
91
92    public void Persist(ProductDescription productDescription) {
93      using (var ctx = new PluginStoreClassesDataContext()) {
94        try {
95          using (var transaction = new TransactionScope()) {
96            foreach (var plugin in productDescription.Plugins) {
97              var pluginEntity = GetExistingPlugin(ctx, plugin.Name, plugin.Version);
98              UpdatePlugin(ctx, pluginEntity, plugin);
99            }
100            InsertOrUpdateProduct(ctx, productDescription);
101            ctx.SubmitChanges();
102            transaction.Complete();
103          }
104        }
105        catch (SqlException ex) {
106          throw new ArgumentException("Something went wrong while trying to persist product", ex);
107        }
108        catch (InvalidOperationException ex) {
109          throw new ArgumentException("Something went wrong while trying to persist product", ex);
110        }
111      }
112    }
113
114    #endregion
115
116    #region insert/update product
117    private void InsertOrUpdateProduct(PluginStoreClassesDataContext ctx, ProductDescription product) {
118      var productEntity = (from p in ctx.Products
119                           where p.Name == product.Name
120                           where p.Version == product.Version.ToString()
121                           select p).FirstOrDefault() ?? MakeProductFromDescription(product);
122
123      if (productEntity.Id <= 0) {
124        ctx.Products.InsertOnSubmit(productEntity);
125        ctx.SubmitChanges();
126      }
127
128      DeleteOldPlugins(ctx, productEntity);
129
130      foreach (var plugin in product.Plugins) {
131        var existingPlugin = GetExistingPlugin(ctx, plugin.Name, plugin.Version);
132        ProductPlugin prodPlugin = new ProductPlugin();
133        prodPlugin.PluginId = existingPlugin.Id;
134        prodPlugin.ProductId = productEntity.Id;
135        ctx.ProductPlugins.InsertOnSubmit(prodPlugin);
136      }
137    }
138
139    private void DeleteOldPlugins(PluginStoreClassesDataContext ctx, Product productEntity) {
140      var oldPlugins = (from p in ctx.ProductPlugins
141                        where p.ProductId == productEntity.Id
142                        select p).ToList();
143      ctx.ProductPlugins.DeleteAllOnSubmit(oldPlugins);
144      ctx.SubmitChanges();
145    }
146    #endregion
147
148    #region insert/update plugins
149    private Plugin InsertOrUpdatePlugin(PluginStoreClassesDataContext ctx, PluginDescription pluginDescription) {
150      var pluginEntity = (from p in ctx.Plugins
151                          where p.Name == pluginDescription.Name
152                          where p.Version == pluginDescription.Version.ToString()
153                          select p).FirstOrDefault() ?? MakePluginFromDescription(pluginDescription);
154
155      if (pluginEntity.Id <= 0) {
156        ctx.Plugins.InsertOnSubmit(pluginEntity);
157        ctx.SubmitChanges();
158      }
159
160      UpdatePlugin(ctx, pluginEntity, pluginDescription);
161      return pluginEntity;
162    }
163
164    private void UpdatePlugin(PluginStoreClassesDataContext ctx, Plugin pluginEntity, PluginDescription pluginDescription) {
165      // update plugin data
166      pluginEntity.License = pluginDescription.LicenseText;
167      pluginEntity.ContactName = pluginDescription.ContactName;
168      pluginEntity.ContactEmail = pluginDescription.ContactEmail;
169
170      // delete cached entry
171      if (pluginDescriptions.ContainsKey(pluginEntity)) pluginDescriptions.Remove(pluginEntity);
172
173      DeleteOldDependencies(ctx, pluginEntity);
174
175      foreach (var dependency in pluginDescription.Dependencies) {
176        var dependencyEntity = GetExistingPlugin(ctx, dependency.Name, dependency.Version);
177        Dependency d = new Dependency();
178        d.PluginId = pluginEntity.Id;
179        d.DependencyId = dependencyEntity.Id;
180        ctx.Dependencies.InsertOnSubmit(d);
181      }
182    }
183
184
185
186    private void DeleteOldDependencies(PluginStoreClassesDataContext ctx, Plugin pluginEntity) {
187      var oldDependencies = (from dep in ctx.Dependencies
188                             where dep.PluginId == pluginEntity.Id
189                             select dep).ToList();
190
191      ctx.Dependencies.DeleteAllOnSubmit(oldDependencies);
192      ctx.SubmitChanges();
193    }
194    #endregion
195
196    #region product <-> productDescription transformation
197    private ProductDescription MakeProductDescription(PluginStoreClassesDataContext ctx, Product p, IQueryable<Plugin> plugins) {
198      var desc = new ProductDescription(p.Name, new Version(p.Version), from plugin in plugins
199                                                                        select MakePluginDescription(ctx, plugin));
200      return desc;
201    }
202    private Product MakeProductFromDescription(ProductDescription desc) {
203      var product = new Product();
204      product.Name = desc.Name;
205      product.Version = desc.Version.ToString();
206      return product;
207    }
208    #endregion
209
210    #region plugin <-> pluginDescription transformation
211    // cache for plugin descriptions
212    private Dictionary<Plugin, PluginDescription> pluginDescriptions = new Dictionary<Plugin, PluginDescription>();
213    private PluginDescription MakePluginDescription(PluginStoreClassesDataContext ctx, Plugin plugin) {
214      if (!pluginDescriptions.ContainsKey(plugin)) {
215        // no cached description -> create new
216        var desc = new PluginDescription(plugin.Name,
217          new Version(plugin.Version),
218          from dep in GetDependencies(ctx, plugin)
219          select MakePluginDescription(ctx, dep),
220          plugin.ContactName ?? string.Empty,
221          plugin.ContactEmail ?? string.Empty,
222          plugin.License ?? string.Empty
223          );
224        pluginDescriptions[plugin] = desc;
225      }
226      return pluginDescriptions[plugin];
227    }
228
229    private Plugin MakePluginFromDescription(PluginDescription pluginDescription) {
230      var plugin = new Plugin();
231      plugin.Name = pluginDescription.Name;
232      plugin.Version = pluginDescription.Version.ToString();
233      plugin.ContactName = pluginDescription.ContactName;
234      plugin.ContactEmail = pluginDescription.ContactEmail;
235      plugin.License = pluginDescription.LicenseText;
236      return plugin;
237    }
238
239    private PluginPackage MakePluginPackage(Plugin plugin, byte[] pluginPackage) {
240      var package = new PluginPackage();
241      package.Data = pluginPackage;
242      package.PluginId = plugin.Id;
243      return package;
244    }
245
246    #endregion
247
248    #region helper queries
249    private Plugin GetExistingPlugin(PluginStoreClassesDataContext ctx, string name, Version version) {
250      return (from p in ctx.Plugins
251              where p.Name == name
252              where p.Version == version.ToString()
253              select p).Single();
254    }
255
256    private IEnumerable<Plugin> GetDependencies(PluginStoreClassesDataContext ctx, Plugin plugin) {
257      return from pair in ctx.Dependencies
258             from dependency in ctx.Plugins
259             where pair.PluginId == plugin.Id
260             where pair.DependencyId == dependency.Id
261             select dependency;
262    }
263    #endregion
264  }
265}
Note: See TracBrowser for help on using the repository browser.