Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DeploymentServer Prototype/HeuristicLab.Services/HeuristicLab.Services.Deployment.DataAccess/PluginStore.cs @ 2771

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

Implemented and tested rudimentary WCF service interface on top of the Linq2Sql data access layer. #860

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