Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Services.OKB/3.3/TableService.cs @ 4298

Last change on this file since 4298 was 4298, checked in by swagner, 14 years ago

Worked on OKB user authentication (#1167)

File size: 8.1 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;
24using System.Collections.Generic;
25using System.Data;
26using System.Data.Linq;
27using System.Diagnostics;
28using System.Linq;
29using System.Reflection;
30using System.ServiceModel;
31using HeuristicLab.Services.OKB.AttributeSelection;
32using HeuristicLab.Services.OKB.DataAccess;
33using log4net;
34
35namespace HeuristicLab.Services.OKB {
36
37  /// <summary>
38  /// Implementation of the <see cref="ITableService"/>.
39  /// </summary>
40  [ServiceBehavior(
41    InstanceContextMode = InstanceContextMode.PerSession,
42    IncludeExceptionDetailInFaults = true)]
43  public class TableService : ITableService, IDisposable {
44
45    private static ILog logger = LogManager.GetLogger(typeof(TableService));
46
47    private OKBDataContext GetDataContext() {
48      return new OKBDataContext();
49    }
50
51    private static List<Type> SupportedTypes = new List<Type>() {
52      typeof(int),
53      typeof(double),
54      typeof(string),
55      typeof(Guid),
56      typeof(DateTime?)
57    };
58
59    #region ITableService Members
60
61    /// <summary>
62    /// Updates the data table.
63    /// </summary>
64    /// <param name="updatedRows">The updated rows.</param>
65    /// <param name="tableName">Name of the table.</param>
66    public void UpdateDataTable(DataTable updatedRows, string tableName) {
67      logger.Info("updating table: " + tableName);
68      Type tableType = Assembly.GetAssembly(typeof(Run)).GetType("HeuristicLab.Services.OKB.DataAccess." + tableName, true);
69      var properties = from p in tableType.GetProperties()
70                       where SupportedTypes.Contains(p.PropertyType)
71                       select p;
72      OKBDataContext okb = GetDataContext();
73      ITable table = okb.GetTable(tableType);
74      foreach (DataRow row in updatedRows.Rows) {
75        if (row["Id"] == DBNull.Value)
76          table.InsertOnSubmit(CreateEntity(tableType, properties, row));
77      }
78      var updated = updatedRows.Rows.Cast<DataRow>().Where(row => row["Id"] != DBNull.Value).OrderBy(row => row["Id"]);
79      var entities = DataSetBuilder.GetEntities(okb, tableType, updated.Select(u => (int)u["Id"]));
80      var updateEnum = updated.GetEnumerator();
81      var entityEnum = entities.GetEnumerator();
82      while (updateEnum.MoveNext() && entityEnum.MoveNext()) {
83        bool idChecked = false;
84        foreach (var property in properties) {
85          Console.WriteLine("{0}.{1} = '{2}' -> '{3}'",
86            tableName, property.Name,
87            property.GetGetMethod().Invoke(entityEnum.Current, new object[0]),
88            updateEnum.Current[property.Name]);
89          if (property.Name == "Id") {
90            int entityId = (int)property.GetGetMethod().Invoke(entityEnum.Current, new object[0]);
91            int updateId = (int)updateEnum.Current["Id"];
92            Debug.Assert(entityId == updateId);
93            idChecked = true;
94          }
95          object newValue = updateEnum.Current[property.Name];
96          if (newValue != DBNull.Value)
97            property.GetSetMethod().Invoke(entityEnum.Current, new object[] { newValue });
98        }
99        Debug.Assert(idChecked);
100      }
101      okb.SubmitChanges();
102    }
103
104    private object CreateEntity(Type tableType, IEnumerable<PropertyInfo> properties, DataRow row) {
105      object instance = Activator.CreateInstance(tableType);
106      logger.Info("Creating new instance of " + tableType.Name);
107      bool empty = true;
108      foreach (var property in properties) {
109        if (row[property.Name] != DBNull.Value) {
110          property.GetSetMethod().Invoke(instance, new object[] { row[property.Name] });
111          Console.WriteLine("{0}.{1} = '{2}'", tableType.Name, property.Name, row[property.Name]);
112          empty = false;
113        }
114      }
115      if (empty)
116        throw new ArgumentException("cannot create completely empty entity");
117      return instance;
118    }
119
120    /// <summary>
121    /// Deletes the selected table rows using the value of the
122    /// "Id" column.
123    /// </summary>
124    /// <param name="ids">The ids.</param>
125    /// <param name="tableName">Name of the table.</param>
126    public void DeleteTableRows(int[] ids, string tableName) {
127      logger.Info("delete rows from table: " + tableName);
128      Type tableType = Assembly.GetAssembly(typeof(Run)).GetType("HeuristicLab.Services.OKB.DataAccess" + tableName, true);
129      OKBDataContext okb = GetDataContext();
130      ITable table = okb.GetTable(tableType);
131      table.DeleteAllOnSubmit(DataSetBuilder.GetEntities(okb, tableType, ids));
132      okb.SubmitChanges();
133    }
134
135    private DataTable tableTemplate;
136    private IEnumerable<PropertyInfo> properties;
137    private IEnumerator rowEnumerator;
138
139    /// <summary>
140    /// Prepares the data table to be downloaded.
141    /// </summary>
142    /// <param name="tableName">Name of the table.</param>
143    /// <param name="count">The number of rows.</param>
144    /// <returns>
145    /// An empyt <see cref="DataType"/> that contains just
146    /// the column headers.
147    /// </returns>
148    public DataTable PrepareDataTable(string tableName, out int count) {
149      logger.Info("preparing data table: " + tableName);
150      Type tableType = Assembly.GetAssembly(typeof(Run)).GetType("HeuristicLab.Services.OKB.DataAccess" + tableName, true);
151      properties = from p in tableType.GetProperties()
152                   where SupportedTypes.Contains(p.PropertyType)
153                   select p;
154      tableTemplate = new DataTable(tableName);
155      foreach (var property in properties) {
156        Type type = property.PropertyType;
157        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
158          type = type.GetGenericArguments()[0];
159        DataColumn column = new DataColumn(property.Name, type);
160        if (type.Name == "Id") {
161          column.ReadOnly = true;
162        }
163        tableTemplate.Columns.Add(column);
164      }
165      OKBDataContext okb = GetDataContext();
166      ITable table = okb.GetTable(tableType);
167      rowEnumerator = table.GetEnumerator();
168      count = DataSetBuilder.CountEntities(GetDataContext(), tableType);
169      return tableTemplate;
170    }
171
172    /// <summary>
173    /// Gets the next few rows.
174    /// </summary>
175    /// <param name="count">The maximum number of rows to return.</param>
176    /// <returns>
177    /// A partial <see cref="DataTable"/> with the
178    /// next few rows.
179    /// </returns>
180    public DataTable GetNextRows(int count) {
181      DataTable dataTable = tableTemplate.Clone();
182      int i = 0;
183      while (i < count && rowEnumerator.MoveNext()) {
184        i++;
185        DataRow row = dataTable.NewRow();
186        foreach (var property in properties) {
187          row[property.Name] = property.GetGetMethod().Invoke(rowEnumerator.Current, new object[0]) ?? DBNull.Value;
188        }
189        dataTable.Rows.Add(row);
190      }
191      return dataTable;
192    }
193
194    /// <summary>
195    /// Finishes fetching rows and closes the connection.
196    /// </summary>
197    public void FinishFetchingRows() {
198      Dispose();
199    }
200
201    #endregion
202
203    #region IDisposable Members
204
205    /// <summary>
206    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
207    /// </summary>
208    public void Dispose() {
209      tableTemplate = null;
210      properties = null;
211    }
212
213    #endregion
214  }
215}
Note: See TracBrowser for help on using the repository browser.