Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 3072 was 3072, checked in by gkronber, 14 years ago

Copied projects related to the deployment service from the feature branch. #918 (Integrate deployment service into trunk and HL3.3 solution file)

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