Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKB/HeuristicLab.Services.OKB/3.3/TableService.cs @ 7928

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

Worked on OKB data model and services (#1174).

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