Permalink
Browse files

Fix for MySQL WithTotalCount

  • Loading branch information...
1 parent b6d7af2 commit 61bf4ed91b16f6e536d32a2f9d5f6b78412eca88 @markrendle committed Nov 29, 2012
Showing with 9 additions and 1,925 deletions.
  1. +1 −1 Simple.Data.Ado/AdoAdapter.cs
  2. +4 −2 Simple.Data.Ado/AdoAdapterQueryRunner.cs
  3. +2 −2 Simple.Data.Ado/AdoAdapterUpserter.cs
  4. +2 −2 Simple.Data.SqlTest/UpdateTests.cs
  5. +0 −150 Simple.Data/Ado/AdoAdapter.cs
  6. +0 −64 Simple.Data/Ado/AdoAdapterException.cs
  7. +0 −58 Simple.Data/Ado/AdoAdapterFinder.cs
  8. +0 −93 Simple.Data/Ado/AdoAdapterInserter.cs
  9. +0 −75 Simple.Data/Ado/AdoAdapterRelatedFinder.cs
  10. +0 −72 Simple.Data/Ado/CommandBuilder.cs
  11. +0 −61 Simple.Data/Ado/CommandHelper.cs
  12. +0 −51 Simple.Data/Ado/DataReaderExtensions.cs
  13. +0 −79 Simple.Data/Ado/DataReaderObservableRunner.cs
  14. +0 −32 Simple.Data/Ado/DataRecordExtensions.cs
  15. +0 −26 Simple.Data/Ado/DbCommandExtensions.cs
  16. +0 −24 Simple.Data/Ado/DbCommandObservableEx.cs
  17. +0 −41 Simple.Data/Ado/DeleteHelper.cs
  18. +0 −85 Simple.Data/Ado/ExpressionFormatter.cs
  19. +0 −41 Simple.Data/Ado/FindHelper.cs
  20. +0 −11 Simple.Data/Ado/ICommandBuilder.cs
  21. +0 −13 Simple.Data/Ado/IConnectionProvider.cs
  22. +0 −7 Simple.Data/Ado/IExpressionFormatter.cs
  23. +0 −13 Simple.Data/Ado/JoinType.cs
  24. +0 −106 Simple.Data/Ado/Joiner.cs
  25. +0 −29 Simple.Data/Ado/ObservableDataReader.cs
  26. +0 −54 Simple.Data/Ado/ProviderHelper.cs
  27. +0 −48 Simple.Data/Ado/Schema/AmbiguousObjectNameException.cs
  28. +0 −89 Simple.Data/Ado/Schema/Column.cs
  29. +0 −39 Simple.Data/Ado/Schema/ColumnCollection.cs
  30. +0 −59 Simple.Data/Ado/Schema/DatabaseSchema.cs
  31. +0 −40 Simple.Data/Ado/Schema/ForeignKey.cs
  32. +0 −19 Simple.Data/Ado/Schema/ForeignKeyCollection.cs
  33. +0 −14 Simple.Data/Ado/Schema/ISchemaProvider.cs
  34. +0 −29 Simple.Data/Ado/Schema/Key.cs
  35. +0 −8 Simple.Data/Ado/Schema/SchemaSpecificStringExtensions.cs
  36. +0 −202 Simple.Data/Ado/Schema/Table.cs
  37. +0 −61 Simple.Data/Ado/Schema/TableCollection.cs
  38. +0 −40 Simple.Data/Ado/Schema/TableJoin.cs
  39. +0 −8 Simple.Data/Ado/Schema/TableType.cs
  40. +0 −32 Simple.Data/Ado/SchemaResolutionException.cs
  41. +0 −45 Simple.Data/Ado/UpdateHelper.cs
View
2 Simple.Data.Ado/AdoAdapter.cs
@@ -342,4 +342,4 @@ protected override void OnReset()
_schema = DatabaseSchema.Get(_connectionProvider, _providerHelper);
}
}
-}
+}
View
6 Simple.Data.Ado/AdoAdapterQueryRunner.cs
@@ -109,8 +109,10 @@ public AdoAdapterQueryRunner(AdoAdapter adapter, AdoAdapterTransaction transacti
{
throw new InvalidOperationException();
}
- IDictionary<string, object> countRow = enumerator.Current.Single();
- withCountClause.SetCount((int) countRow.First().Value);
+ IDictionary<string, object> countRow = enumerator.Current.Single();
+ var value = countRow.First().Value;
+ int count = value is int ? (int) value : Convert.ToInt32(value);
+ withCountClause.SetCount(count);
if (!enumerator.MoveNext())
{
throw new InvalidOperationException();
View
4 Simple.Data.Ado/AdoAdapterUpserter.cs
@@ -95,7 +95,7 @@ public AdoAdapterUpserter(AdoAdapter adapter, IDbTransaction transaction)
yield return result;
}
}
-
+
public IEnumerable<IDictionary<string, object>> UpsertMany(string tableName, IList<IDictionary<string, object>> list, IList<string> keyFieldNames, bool isResultRequired, Func<IDictionary<string, object>, Exception, bool> errorCallback)
{
foreach (var row in list)
@@ -136,4 +136,4 @@ public AdoAdapterUpserter(AdoAdapter adapter, IDbTransaction transaction)
return ExpressionHelper.CriteriaDictionaryToExpression(tableName, criteria);
}
}
-}
+}
View
4 Simple.Data.SqlTest/UpdateTests.cs
@@ -1,7 +1,6 @@
using System.Dynamic;
using System.Linq;
using NUnit.Framework;
-using Simple.Data.SqlTest.Resources;
namespace Simple.Data.SqlTest
{
@@ -143,7 +142,8 @@ public void TestUpdateWithTimestamp()
public void TestUpdateByInputIsNotMutated()
{
var db = DatabaseHelper.Open();
- var user = new Dictionary<string, object>() {
+ var user = new Dictionary<string, object>
+ {
{"Id", 0},
{"Age", 1},
{"Name", "X"},
View
150 Simple.Data/Ado/AdoAdapter.cs
@@ -1,150 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.Data;
-using System.Data.Common;
-using System.Dynamic;
-using System.Linq;
-using System.Text;
-using Simple.Data.Ado.Schema;
-
-namespace Simple.Data.Ado
-{
- [Export("Ado", typeof(Adapter))]
- internal class AdoAdapter : Adapter, IAdapterWithRelation
- {
- private IConnectionProvider _connectionProvider;
- private DatabaseSchema _schema;
- private Lazy<AdoAdapterRelatedFinder> _relatedFinder;
-
- public AdoAdapter()
- {
-
- }
-
- internal AdoAdapter(IConnectionProvider connectionProvider)
- {
- _connectionProvider = connectionProvider;
- _schema = DatabaseSchema.Get(_connectionProvider);
- _relatedFinder = new Lazy<AdoAdapterRelatedFinder>(CreateRelatedFinder);
- }
-
- protected override void OnSetup()
- {
- var settingsKeys = ((IDictionary<string, object>) Settings).Keys;
- if (settingsKeys.Contains("ConnectionString"))
- {
- _connectionProvider = ProviderHelper.GetProviderByConnectionString(Settings.ConnectionString);
- }
- else if (settingsKeys.Contains("Filename"))
- {
- _connectionProvider = ProviderHelper.GetProviderByFilename(Settings.Filename);
- }
- _schema = DatabaseSchema.Get(_connectionProvider);
- _relatedFinder = new Lazy<AdoAdapterRelatedFinder>(CreateRelatedFinder);
- }
-
- private AdoAdapterRelatedFinder CreateRelatedFinder()
- {
- return new AdoAdapterRelatedFinder(this);
- }
-
- public override IEnumerable<IDictionary<string, object>> Find(string tableName, SimpleExpression criteria)
- {
- return new AdoAdapterFinder(this).Find(tableName, criteria);
- }
-
- public override IDictionary<string, object> Insert(string tableName, IDictionary<string, object> data)
- {
- return new AdoAdapterInserter(this).Insert(tableName, data);
- }
-
- public override int Update(string tableName, IDictionary<string, object> data, SimpleExpression criteria)
- {
- var commandBuilder = new UpdateHelper(_schema).GetUpdateCommand(tableName, data, criteria);
- return Execute(commandBuilder);
- }
-
- /// <summary>
- /// Deletes from the specified table.
- /// </summary>
- /// <param name="tableName">Name of the table.</param>
- /// <param name="criteria">The expression to use as criteria for the delete operation.</param>
- /// <returns>The number of records which were deleted.</returns>
- public override int Delete(string tableName, SimpleExpression criteria)
- {
- var commandBuilder = new DeleteHelper(_schema).GetDeleteCommand(tableName, criteria);
- return Execute(commandBuilder);
- }
-
- /// <summary>
- /// Gets the names of the fields which comprise the unique identifier for the specified table.
- /// </summary>
- /// <param name="tableName">Name of the table.</param>
- /// <returns>A list of field names; an empty list if no key is defined.</returns>
- public override IEnumerable<string> GetKeyFieldNames(string tableName)
- {
- return _schema.FindTable(tableName).PrimaryKey.AsEnumerable();
- }
-
- private int Execute(ICommandBuilder commandBuilder)
- {
- using (var connection = CreateConnection())
- {
- using (var command = commandBuilder.GetCommand(connection))
- {
- return TryExecute(connection, command);
- }
- }
- }
-
- private static int TryExecute(DbConnection connection, IDbCommand command)
- {
- try
- {
- connection.Open();
- return command.ExecuteNonQuery();
- }
- catch (DbException ex)
- {
- throw new AdoAdapterException(ex.Message, command);
- }
- }
-
- internal DbConnection CreateConnection()
- {
- return _connectionProvider.CreateConnection();
- }
-
- internal DatabaseSchema GetSchema()
- {
- return DatabaseSchema.Get(_connectionProvider);
- }
-
- /// <summary>
- /// Determines whether a relation is valid.
- /// </summary>
- /// <param name="tableName">Name of the known table.</param>
- /// <param name="relatedTableName">Name of the table to test.</param>
- /// <returns>
- /// <c>true</c> if there is a valid relation; otherwise, <c>false</c>.
- /// </returns>
- public bool IsValidRelation(string tableName, string relatedTableName)
- {
- return _relatedFinder.Value.IsValidRelation(tableName, relatedTableName);
- }
-
- /// <summary>
- /// Finds data from a "table" related to the specified "table".
- /// </summary>
- /// <param name="tableName">Name of the table.</param>
- /// <param name="row"></param>
- /// <param name="relatedTableName"></param>
- /// <returns>The list of records matching the criteria. If no records are found, return an empty list.</returns>
- /// <remarks>When implementing the <see cref="Adapter"/> interface, if relationships are not possible, throw a <see cref="NotSupportedException"/>.</remarks>
- public IEnumerable<IDictionary<string, object>> FindRelated(string tableName, IDictionary<string, object> row, string relatedTableName)
- {
- return _relatedFinder.Value.FindRelated(tableName, row, relatedTableName);
- }
- }
-}
View
64 Simple.Data/Ado/AdoAdapterException.cs
@@ -1,64 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Linq;
-using System.Runtime.Serialization;
-using System.Text;
-using Simple.Data.Extensions;
-
-namespace Simple.Data.Ado
-{
- public class AdoAdapterException : AdapterException
- {
- private readonly string _commandText;
- private readonly IDictionary<string,object> _parameters;
-
- public AdoAdapterException() : base(typeof(AdoAdapter))
- {
- }
-
- public AdoAdapterException(string message, IDbCommand command) : base(message, typeof(AdoAdapter))
- {
- _commandText = command.CommandText;
- _parameters = command.Parameters.Cast<IDbDataParameter>()
- .ToDictionary(p => p.ParameterName, p => p.Value);
- }
-
- public AdoAdapterException(string commandText, IEnumerable<KeyValuePair<string,object>> parameters)
- :base(typeof(AdoAdapter))
- {
- _commandText = commandText;
- _parameters = parameters.ToDictionary();
- }
-
-
- public AdoAdapterException(string message) : base(message, typeof(AdoAdapter))
- {
- }
-
- public AdoAdapterException(string message, string commandText, IEnumerable<KeyValuePair<string,object>> parameters)
- :base(message, typeof(AdoAdapter))
- {
- _commandText = commandText;
- _parameters = parameters.ToDictionary();
- }
-
- public AdoAdapterException(string message, Exception inner) : base(message, inner, typeof(AdoAdapter))
- {
- }
-
- public AdoAdapterException(SerializationInfo info, StreamingContext context) : base(info, context)
- {
- }
-
- public IDictionary<string, object> Parameters
- {
- get { return _parameters; }
- }
-
- public string CommandText
- {
- get { return _commandText; }
- }
- }
-}
View
58 Simple.Data/Ado/AdoAdapterFinder.cs
@@ -1,58 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Data.Common;
-using System.Linq;
-using System.Text;
-
-namespace Simple.Data.Ado
-{
- class AdoAdapterFinder
- {
- private readonly AdoAdapter _adapter;
-
- public AdoAdapterFinder(AdoAdapter adapter)
- {
- _adapter = adapter;
- }
-
- public IEnumerable<IDictionary<string, object>> Find(string tableName, SimpleExpression criteria)
- {
- if (criteria == null) return FindAll(tableName);
-
- var commandBuilder = new FindHelper(_adapter.GetSchema()).GetFindByCommand(tableName, criteria);
- return ExecuteQuery(commandBuilder);
- }
-
- private IEnumerable<IDictionary<string, object>> FindAll(string tableName)
- {
- return ExecuteQuery("select * from " + _adapter.GetSchema().FindTable(tableName).ActualName);
- }
-
- private IEnumerable<IDictionary<string, object>> ExecuteQuery(ICommandBuilder commandBuilder)
- {
- var connection = _adapter.CreateConnection();
- var command = commandBuilder.GetCommand(connection);
- return TryExecuteQuery(connection, command);
- }
-
- private IEnumerable<IDictionary<string, object>> ExecuteQuery(string sql, params object[] values)
- {
- var connection = _adapter.CreateConnection();
- var command = CommandHelper.Create(connection, sql, values);
- return command.ToAsyncEnumerable();
- }
-
- private static IEnumerable<IDictionary<string, object>> TryExecuteQuery(DbConnection connection, IDbCommand command)
- {
- try
- {
- return command.ToAsyncEnumerable();
- }
- catch (DbException ex)
- {
- throw new AdoAdapterException(ex.Message, command);
- }
- }
- }
-}
View
93 Simple.Data/Ado/AdoAdapterInserter.cs
@@ -1,93 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Data.Common;
-using System.Linq;
-using System.Text;
-
-namespace Simple.Data.Ado
-{
- class AdoAdapterInserter
- {
- private readonly AdoAdapter _adapter;
-
- public AdoAdapterInserter(AdoAdapter adapter)
- {
- _adapter = adapter;
- }
-
- public IDictionary<string, object> Insert(string tableName, IDictionary<string, object> data)
- {
- var table = _adapter.GetSchema().FindTable(tableName);
-
- string columnList =
- data.Keys.Select(s => table.FindColumn(s).QuotedName).Aggregate((agg, next) => agg + "," + next);
- string valueList = data.Keys.Select(s => "?").Aggregate((agg, next) => agg + "," + next);
-
- string insertSql = "insert into " + table.QuotedName + " (" + columnList + ") values (" + valueList + ")";
-
- var identityColumn = table.Columns.FirstOrDefault(col => col.IsIdentity);
-
- if (identityColumn != null)
- {
- insertSql += "; select * from " + table.QuotedName + " where " + identityColumn.QuotedName +
- " = scope_identity()";
- return ExecuteSingletonQuery(insertSql, data.Values.ToArray());
- }
-
- Execute(insertSql, data.Values.ToArray());
- return null;
- }
-
- internal IDictionary<string, object> ExecuteSingletonQuery(string sql, params object[] values)
- {
- using (var connection = _adapter.CreateConnection())
- {
- using (var command = CommandHelper.Create(connection, sql, values.ToArray()))
- {
- try
- {
- connection.Open();
- using (var reader = command.ExecuteReader())
- {
- if (reader.Read())
- {
- return reader.ToDictionary();
- }
- }
- }
- catch (DbException ex)
- {
- throw new AdoAdapterException(ex.Message, command);
- }
- }
- }
-
- return null;
- }
-
- internal int Execute(string sql, params object[] values)
- {
- using (var connection = _adapter.CreateConnection())
- {
- using (var command = CommandHelper.Create(connection, sql, values.ToArray()))
- {
- return TryExecute(connection, command);
- }
- }
- }
-
- private static int TryExecute(DbConnection connection, IDbCommand command)
- {
- try
- {
- connection.Open();
- return command.ExecuteNonQuery();
- }
- catch (DbException ex)
- {
- throw new AdoAdapterException(ex.Message, command);
- }
- }
- }
-}
View
75 Simple.Data/Ado/AdoAdapterRelatedFinder.cs
@@ -1,75 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using Simple.Data.Ado.Schema;
-
-namespace Simple.Data.Ado
-{
- class AdoAdapterRelatedFinder
- {
- private readonly Lazy<ConcurrentDictionary<Tuple<string, string>, TableJoin>> _tableJoins =
- new Lazy<ConcurrentDictionary<Tuple<string, string>, TableJoin>>(
- () => new ConcurrentDictionary<Tuple<string, string>, TableJoin>(), LazyThreadSafetyMode.ExecutionAndPublication
- );
-
- private readonly AdoAdapter _adapter;
-
- public AdoAdapterRelatedFinder(AdoAdapter adapter)
- {
- _adapter = adapter;
- }
-
- public bool IsValidRelation(string tableName, string relatedTableName)
- {
- return TryJoin(tableName, relatedTableName) != null;
- }
-
- public IEnumerable<IDictionary<string, object>> FindRelated(string tableName, IDictionary<string, object> row, string relatedTableName)
- {
- var join = TryJoin(tableName, relatedTableName);
- if (join == null) throw new AdoAdapterException("Could not resolve relationship.");
-
- return join.Master == _adapter.GetSchema().FindTable(tableName) ? GetDetail(row, join) : GetMaster(row, join);
- }
-
- private TableJoin TryJoin(string tableName, string relatedTableName)
- {
- return _tableJoins.Value.GetOrAdd(Tuple.Create(tableName, relatedTableName),
- t => TryCreateJoin(t.Item1, t.Item2));
- }
-
- private TableJoin TryCreateJoin(string tableName, string relatedTableName)
- {
- return TryMasterJoin(tableName, relatedTableName) ?? TryDetailJoin(tableName, relatedTableName);
- }
-
- private TableJoin TryMasterJoin(string tableName, string relatedTableName)
- {
- return _adapter.GetSchema().FindTable(tableName).GetMaster(relatedTableName);
- }
-
- private TableJoin TryDetailJoin(string tableName, string relatedTableName)
- {
- return _adapter.GetSchema().FindTable(tableName).GetDetail(relatedTableName);
- }
-
- private IEnumerable<IDictionary<string, object>> GetMaster(IDictionary<string, object> row, TableJoin masterJoin)
- {
- var criteria = new Dictionary<string, object> { { masterJoin.MasterColumn.ActualName, row[masterJoin.DetailColumn.HomogenizedName] } };
- yield return _adapter.Find(masterJoin.Master.ActualName,
- ExpressionHelper.CriteriaDictionaryToExpression(masterJoin.Master.ActualName,
- criteria)).FirstOrDefault();
- }
-
- private IEnumerable<IDictionary<string, object>> GetDetail(IDictionary<string, object> row, TableJoin join)
- {
- var criteria = new Dictionary<string, object> { { join.DetailColumn.ActualName, row[join.MasterColumn.HomogenizedName] } };
- return _adapter.Find(join.Detail.ActualName,
- ExpressionHelper.CriteriaDictionaryToExpression(join.Detail.ActualName,
- criteria));
- }
- }
-}
View
72 Simple.Data/Ado/CommandBuilder.cs
@@ -1,72 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Linq;
-using System.Text;
-using System.Threading;
-
-namespace Simple.Data.Ado
-{
- class CommandBuilder : ICommandBuilder
- {
- private int _number;
- private readonly Dictionary<string, object> _parameters = new Dictionary<string, object>();
- private readonly StringBuilder _text;
-
- public CommandBuilder()
- {
- _text = new StringBuilder();
- }
-
- public CommandBuilder(string text)
- {
- _text = new StringBuilder(text);
- }
-
- public string AddParameter(object value)
- {
- string name = "@p" + Interlocked.Increment(ref _number);
- _parameters.Add(name, value);
- return name;
- }
-
- public void Append(string text)
- {
- _text.Append(text);
- }
-
- public override string ToString()
- {
- return _text.ToString();
- }
-
- public IEnumerable<KeyValuePair<string, object>> Parameters
- {
- get { return _parameters.AsEnumerable(); }
- }
-
- public string Text
- {
- get { return _text.ToString(); }
- }
-
- public IDbCommand GetCommand(IDbConnection connection)
- {
- var command = connection.CreateCommand();
- command.CommandText = Text;
- SetParameters(command);
- return command;
- }
-
- private void SetParameters(IDbCommand command)
- {
- foreach (var pair in _parameters)
- {
- var parameter = command.CreateParameter();
- parameter.ParameterName = pair.Key;
- parameter.Value = pair.Value;
- command.Parameters.Add(parameter);
- }
- }
- }
-}
View
61 Simple.Data/Ado/CommandHelper.cs
@@ -1,61 +0,0 @@
-using System.Collections.Generic;
-using System.Data;
-using System.Text;
-
-namespace Simple.Data.Ado
-{
- internal static class CommandHelper
- {
- internal static IDbCommand Create(IDbConnection connection, string sql, IList<object> values)
- {
- var command = connection.CreateCommand();
-
- command.CommandText = PrepareCommand(sql, values, command);
-
- return command;
- }
-
- internal static IDbCommand Create(IDbConnection connection, CommandBuilder commandBuilder)
- {
- var command = connection.CreateCommand();
- command.CommandText = commandBuilder.Text;
- PrepareCommand(commandBuilder, command);
- return command;
- }
-
- private static string PrepareCommand(IEnumerable<char> sql, IList<object> values, IDbCommand command)
- {
- int index = 0;
- var sqlBuilder = new StringBuilder();
- foreach (var c in sql)
- {
- if (c == '?')
- {
- var parameter = command.CreateParameter();
- parameter.ParameterName = "@p" + index;
- parameter.Value = values[index];
- command.Parameters.Add(parameter);
-
- sqlBuilder.Append(parameter.ParameterName);
- index++;
- }
- else
- {
- sqlBuilder.Append(c);
- }
- }
- return sqlBuilder.ToString();
- }
-
- private static void PrepareCommand(CommandBuilder commandBuilder, IDbCommand command)
- {
- foreach (var pair in commandBuilder.Parameters)
- {
- var parameter = command.CreateParameter();
- parameter.ParameterName = pair.Key;
- parameter.Value = pair.Value;
- command.Parameters.Add(parameter);
- }
- }
- }
-}
View
51 Simple.Data/Ado/DataReaderExtensions.cs
@@ -1,51 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Data;
-
-namespace Simple.Data.Ado
-{
- internal static class DataReaderExtensions
- {
- public static IEnumerable<IDictionary<string, object>> ToDictionaries(this IDataReader reader)
- {
- var list = new List<IDictionary<string, object>>();
- using (reader)
- {
- while (reader.Read())
- {
- list.Add(reader.ToDictionary());
- }
- }
-
- return list.AsEnumerable();
- }
-
- public static IEnumerable<object> ToDynamicList(this IDataReader reader)
- {
- var list = new List<object>();
- using (reader)
- {
- while (reader.Read())
- {
- list.Add(reader.ToDynamicRecord());
- }
- }
-
- return list.AsEnumerable();
- }
-
- public static IEnumerable<object> ToDynamicList(this IDataReader reader, Database database, string tableName)
- {
- var list = new List<object>();
- using (reader)
- {
- while (reader.Read())
- {
- list.Add(reader.ToDynamicRecord(tableName, database));
- }
- }
-
- return list.AsEnumerable();
- }
- }
-}
View
79 Simple.Data/Ado/DataReaderObservableRunner.cs
@@ -1,79 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Data.Common;
-
-namespace Simple.Data.Ado
-{
- class DataReaderObservableRunner : IDisposable
- {
- private readonly IDbCommand _command;
- private readonly IObserver<IDictionary<string, object>> _observer;
- private bool _disposed;
-
- private DataReaderObservableRunner(IDbCommand command, IObserver<IDictionary<string, object>> observer)
- {
- _command = command;
- _observer = observer;
- }
-
- public static DataReaderObservableRunner RunAsync(IDbCommand command, IObserver<IDictionary<string, object>> observer)
- {
- var instance = new DataReaderObservableRunner(command, observer);
- var asyncAction = new Action(instance.Run);
- asyncAction.BeginInvoke(asyncAction.EndInvoke, null);
- return instance;
- }
-
- private void Run()
- {
- try
- {
- RunQuery();
- SendCompleted();
- }
- catch (Exception ex)
- {
- _observer.OnError(ex);
- }
- }
-
- private void RunQuery()
- {
- using (_command.Connection)
- using (_command)
- {
- _command.Connection.Open();
- RunReader();
- }
- }
-
- private void RunReader()
- {
- using (var reader = _command.ExecuteReader())
- {
- while ((!_disposed) && reader.Read())
- {
- _observer.OnNext(reader.ToDictionary());
- }
- }
- }
-
- private void SendCompleted()
- {
- if (!_disposed)
- {
- _observer.OnCompleted();
- }
- }
-
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- /// <filterpriority>2</filterpriority>
- public void Dispose()
- {
- _disposed = true;
- }
- }
-}
View
32 Simple.Data/Ado/DataRecordExtensions.cs
@@ -1,32 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Data;
-
-namespace Simple.Data.Ado
-{
- internal static class DataRecordExtensions
- {
- public static dynamic ToDynamicRecord(this IDataRecord dataRecord)
- {
- return ToDynamicRecord(dataRecord, null, null);
- }
-
- public static dynamic ToDynamicRecord(this IDataRecord dataRecord, string tableName, Database database)
- {
- return new DynamicRecord(dataRecord.ToDictionary(), tableName, database);
- }
-
- public static Dictionary<string, object> ToDictionary(this IDataRecord dataRecord)
- {
- return dataRecord.GetFieldNames().ToDictionary(fieldName => fieldName, fieldName => dataRecord[fieldName]);
- }
-
- public static IEnumerable<string> GetFieldNames(this IDataRecord dataRecord)
- {
- for (int i = 0; i < dataRecord.FieldCount; i++)
- {
- yield return dataRecord.GetName(i);
- }
- }
- }
-}
View
26 Simple.Data/Ado/DbCommandExtensions.cs
@@ -1,26 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Data.Common;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-
-namespace Simple.Data.Ado
-{
- static class DbCommandExtensions
- {
- public static IEnumerable<IDictionary<string, object>> ToAsyncEnumerable(this IDbCommand command)
- {
- if (command.Connection == null) throw new InvalidOperationException("Command has no connection.");
- if (command.Connection.State != ConnectionState.Closed) throw new InvalidOperationException(MethodBase.GetCurrentMethod().Name + " must be called with a closed DbConnection.");
- return ToObservable(command).ToEnumerable();
- }
-
- public static IObservable<IDictionary<string, object>> ToObservable(this IDbCommand command)
- {
- if (command.Connection.State != ConnectionState.Closed) throw new InvalidOperationException(MethodBase.GetCurrentMethod().Name + " must be called with a closed DbConnection.");
- return new ObservableDataReader(command);
- }
- }
-}
View
24 Simple.Data/Ado/DbCommandObservableEx.cs
@@ -1,24 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Data.Common;
-using System.Linq;
-using System.Reflection;
-
-namespace Simple.Data.Ado
-{
- public static class DbCommandObservableEx
- {
- public static IEnumerable<IDictionary<string, object>> ToAsyncEnumerable(this DbCommand command)
- {
- if (command.Connection.State != ConnectionState.Closed) throw new InvalidOperationException(MethodBase.GetCurrentMethod().Name + " must be called with a closed DbConnection.");
- return ToObservable(command).ToEnumerable();
- }
-
- public static IObservable<IDictionary<string,object>> ToObservable(this DbCommand command)
- {
- if (command.Connection.State != ConnectionState.Closed) throw new InvalidOperationException(MethodBase.GetCurrentMethod().Name + " must be called with a closed DbConnection.");
- return new ObservableDataReader(command);
- }
- }
-}
View
41 Simple.Data/Ado/DeleteHelper.cs
@@ -1,41 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Simple.Data.Ado.Schema;
-
-namespace Simple.Data.Ado
-{
- internal class DeleteHelper
- {
- private readonly DatabaseSchema _schema;
- private readonly ICommandBuilder _commandBuilder;
- private readonly IExpressionFormatter _expressionFormatter;
-
- public DeleteHelper(DatabaseSchema schema)
- {
- _schema = schema;
- _commandBuilder = new CommandBuilder();
- _expressionFormatter = new ExpressionFormatter(_commandBuilder, _schema);
- }
-
- public ICommandBuilder GetDeleteCommand(string tableName, SimpleExpression criteria)
- {
- _commandBuilder.Append(GetDeleteClause(tableName));
-
- if (criteria != null)
- {
- _commandBuilder.Append(" where ");
- _commandBuilder.Append(_expressionFormatter.Format(criteria));
- }
-
- return _commandBuilder;
- }
-
- private string GetDeleteClause(string tableName)
- {
- var table = _schema.FindTable(tableName);
- return string.Concat("delete from ", table.QuotedName);
- }
- }
-}
View
85 Simple.Data/Ado/ExpressionFormatter.cs
@@ -1,85 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Simple.Data.Ado.Schema;
-
-namespace Simple.Data.Ado
-{
- class ExpressionFormatter : IExpressionFormatter
- {
- private readonly ICommandBuilder _commandBuilder;
- private readonly DatabaseSchema _schema;
- private readonly Dictionary<SimpleExpressionType, Func<SimpleExpression, string>> _expressionFormatters;
-
- public ExpressionFormatter(ICommandBuilder commandBuilder, DatabaseSchema schema)
- {
- _commandBuilder = commandBuilder;
- _schema = schema;
- _expressionFormatters = new Dictionary<SimpleExpressionType, Func<SimpleExpression, string>>
- {
- {SimpleExpressionType.And, LogicalExpressionToWhereClause},
- {SimpleExpressionType.Or, LogicalExpressionToWhereClause},
- {SimpleExpressionType.Equal, EqualExpressionToWhereClause},
- {SimpleExpressionType.NotEqual, NotEqualExpressionToWhereClause},
- {SimpleExpressionType.GreaterThan, expr => BinaryExpressionToWhereClause(expr, ">")},
- {SimpleExpressionType.GreaterThanOrEqual, expr => BinaryExpressionToWhereClause(expr, ">=")},
- {SimpleExpressionType.LessThan, expr => BinaryExpressionToWhereClause(expr, "<")},
- {SimpleExpressionType.LessThanOrEqual, expr => BinaryExpressionToWhereClause(expr, "<=")},
- };
- }
-
- public string Format(SimpleExpression expression)
- {
- Func<SimpleExpression, string> formatter;
-
- if (_expressionFormatters.TryGetValue(expression.Type, out formatter))
- {
- return formatter(expression);
- }
-
- return string.Empty;
- }
-
- private string LogicalExpressionToWhereClause(SimpleExpression expression)
- {
- return string.Format("({0} {1} {2})",
- Format((SimpleExpression)expression.LeftOperand),
- expression.Type.ToString().ToUpperInvariant(),
- Format((SimpleExpression)expression.RightOperand));
- }
-
- private string EqualExpressionToWhereClause(SimpleExpression expression)
- {
- return string.Format("{0} {1} {2}", FormatObject(expression.LeftOperand),
- expression.RightOperand is string ? "LIKE" : "=",
- FormatObject(expression.RightOperand));
- }
-
- private string NotEqualExpressionToWhereClause(SimpleExpression expression)
- {
- return string.Format("{0} {1} {2}", FormatObject(expression.LeftOperand),
- expression.RightOperand is string ? "NOT LIKE" : "!=",
- FormatObject(expression.RightOperand));
- }
-
- private string BinaryExpressionToWhereClause(SimpleExpression expression, string comparisonOperator)
- {
- return string.Format("{0} {1} {2}", FormatObject(expression.LeftOperand),
- comparisonOperator,
- FormatObject(expression.RightOperand));
- }
-
- private string FormatObject(object value)
- {
- var reference = value as DynamicReference;
- if (!ReferenceEquals(reference, null))
- {
- var table = _schema.FindTable(reference.GetOwner().GetName());
- return table.QuotedName + "." + table.FindColumn(reference.GetName()).QuotedName;
- }
-
- return _commandBuilder.AddParameter(value);
- }
- }
-}
View
41 Simple.Data/Ado/FindHelper.cs
@@ -1,41 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Simple.Data.Ado.Schema;
-
-namespace Simple.Data.Ado
-{
- internal class FindHelper
- {
- private readonly DatabaseSchema _schema;
- private readonly ICommandBuilder _commandBuilder;
- private readonly IExpressionFormatter _expressionFormatter;
-
- public FindHelper(DatabaseSchema schema)
- {
- _schema = schema;
- _commandBuilder = new CommandBuilder();
- _expressionFormatter = new ExpressionFormatter(_commandBuilder, _schema);
- }
-
- public ICommandBuilder GetFindByCommand(string tableName, SimpleExpression criteria)
- {
- _commandBuilder.Append(GetSelectClause(tableName));
- _commandBuilder.Append(" ");
- _commandBuilder.Append(new Joiner(JoinType.Inner, _schema).GetJoinClauses(tableName, criteria));
-
- if (criteria != null)
- {
- _commandBuilder.Append(" where ");
- _commandBuilder.Append(_expressionFormatter.Format(criteria));
- }
-
- return _commandBuilder;
- }
-
- private string GetSelectClause(string tableName)
- {
- return string.Format("select {0}.* from {0}", _schema.FindTable(tableName).QuotedName);
- }
- }
-}
View
11 Simple.Data/Ado/ICommandBuilder.cs
@@ -1,11 +0,0 @@
-using System.Data;
-
-namespace Simple.Data.Ado
-{
- public interface ICommandBuilder
- {
- string AddParameter(object value);
- void Append(string text);
- IDbCommand GetCommand(IDbConnection connection);
- }
-}
View
13 Simple.Data/Ado/IConnectionProvider.cs
@@ -1,13 +0,0 @@
-using System.Data.Common;
-using Simple.Data.Ado.Schema;
-
-namespace Simple.Data.Ado
-{
- public interface IConnectionProvider
- {
- void SetConnectionString(string connectionString);
- DbConnection CreateConnection();
- ISchemaProvider GetSchemaProvider();
- string ConnectionString { get; }
- }
-}
View
7 Simple.Data/Ado/IExpressionFormatter.cs
@@ -1,7 +0,0 @@
-namespace Simple.Data.Ado
-{
- public interface IExpressionFormatter
- {
- string Format(SimpleExpression expression);
- }
-}
View
13 Simple.Data/Ado/JoinType.cs
@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Simple.Data.Ado
-{
- enum JoinType
- {
- Inner,
- Outer
- }
-}
View
106 Simple.Data/Ado/Joiner.cs
@@ -1,106 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Simple.Data.Ado.Schema;
-using Simple.Data.Extensions;
-
-namespace Simple.Data.Ado
-{
- class Joiner
- {
- private readonly JoinType _joinType;
- private readonly DatabaseSchema _schema;
- private readonly ConcurrentDictionary<string, string> _done = new ConcurrentDictionary<string, string>();
-
- public Joiner(JoinType joinType, DatabaseSchema schema)
- {
- if (schema == null) throw new ArgumentNullException("schema");
- _joinType = joinType;
- _schema = schema;
- }
-
- public string GetJoinClauses(string mainTableName, SimpleExpression expression)
- {
- _done.AddOrUpdate(mainTableName, string.Empty, (s, o) => string.Empty);
- var tablePairs = GetTablePairs(expression);
- foreach (var tablePair in tablePairs)
- {
- AddJoin(tablePair.Item1, tablePair.Item2);
- }
- return string.Join(" ", tablePairs.Select(tp => _done[tp.Item2]));
- }
-
- private void AddJoin(string table1Name, string table2Name)
- {
- var table1 = _schema.FindTable(table1Name);
- var table2 = _schema.FindTable(table2Name);
-
- var foreignKey =
- table2.ForeignKeys.SingleOrDefault(fk => fk.MasterTable == table1.ActualName)
- ??
- table1.ForeignKeys.SingleOrDefault(fk => fk.MasterTable == table2.ActualName);
-
- if (foreignKey == null) throw new SchemaResolutionException(
- string.Format("Could not join '{0}' and '{1}'", table1.ActualName, table2.ActualName));
-
- _done.GetOrAdd(table2Name, s => MakeJoinText(table2, foreignKey));
- }
-
- private string MakeJoinText(Table rightTable, ForeignKey foreignKey)
- {
- var builder = new StringBuilder(JoinKeyword);
- builder.AppendFormat(" JOIN {0} ON (", rightTable.QuotedName);
- builder.Append(FormatJoinExpression(foreignKey, 0));
-
- for (int i = 1; i < foreignKey.Columns.Length; i++)
- {
- builder.Append(" AND ");
- builder.Append(FormatJoinExpression(foreignKey, i));
- }
- builder.Append(")");
- return builder.ToString();
- }
-
- private string FormatJoinExpression(ForeignKey foreignKey, int columnIndex)
- {
- return string.Format("{0}.{1} = {2}.{3}", _schema.QuoteObjectName(foreignKey.MasterTable), _schema.QuoteObjectName(foreignKey.UniqueColumns[columnIndex]),
- _schema.QuoteObjectName(foreignKey.DetailTable), _schema.QuoteObjectName(foreignKey.Columns[columnIndex]));
- }
-
- private string JoinKeyword
- {
- get { return _joinType == JoinType.Inner ? string.Empty : "LEFT"; }
- }
-
- private static IEnumerable<Tuple<string,string>> GetTablePairs(SimpleExpression expression)
- {
- return GetReferencesFromExpression(expression)
- .SelectMany(dr => dr.GetAllObjectNames().SkipLast().ToTuplePairs())
- .Distinct();
- }
-
- private static IEnumerable<DynamicReference> GetReferencesFromExpression(SimpleExpression expression)
- {
- if (expression.Type == SimpleExpressionType.And || expression.Type == SimpleExpressionType.Or)
- {
- return GetReferencesFromExpression((SimpleExpression) expression.LeftOperand)
- .Concat(GetReferencesFromExpression((SimpleExpression) expression.LeftOperand));
- }
-
- var result = Enumerable.Empty<DynamicReference>();
-
- if (expression.LeftOperand is DynamicReference)
- {
- result = result.Concat(new[] {(DynamicReference) expression.LeftOperand});
- }
- if (expression.RightOperand is DynamicReference)
- {
- result = result.Concat(new[] { (DynamicReference)expression.RightOperand });
- }
-
- return result;
- }
- }
-}
View
29 Simple.Data/Ado/ObservableDataReader.cs
@@ -1,29 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Data.Common;
-
-namespace Simple.Data.Ado
-{
- class ObservableDataReader : IObservable<IDictionary<string, object>>
- {
- private readonly IDbCommand _command;
-
- public ObservableDataReader(IDbCommand command)
- {
- _command = command;
- }
-
- /// <summary>
- /// Notifies the provider that an observer is to receive notifications.
- /// </summary>
- /// <returns>
- /// The observer's interface that enables resources to be disposed.
- /// </returns>
- /// <param name="observer">The object that is to receive notifications.</param>
- public IDisposable Subscribe(IObserver<IDictionary<string, object>> observer)
- {
- return DataReaderObservableRunner.RunAsync(_command, observer);
- }
- }
-}
View
54 Simple.Data/Ado/ProviderHelper.cs
@@ -1,54 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.ComponentModel.Composition.Hosting;
-using System.Reflection;
-using System.IO;
-
-namespace Simple.Data.Ado
-{
- class ProviderHelper
- {
- private static readonly ConcurrentDictionary<string, IConnectionProvider> Cache = new ConcurrentDictionary<string,IConnectionProvider>();
-
- public static IConnectionProvider GetProviderByConnectionString(string connectionString)
- {
- return Cache.GetOrAdd(connectionString, LoadProviderByConnectionString);
- }
-
- public static IConnectionProvider GetProviderByFilename(string filename)
- {
- return Cache.GetOrAdd(filename, LoadProviderByFilename);
- }
-
- private static IConnectionProvider LoadProviderByConnectionString(string connectionString)
- {
- var provider = ComposeProvider("sql");
-
- provider.SetConnectionString(connectionString);
- return provider;
- }
-
- private static IConnectionProvider LoadProviderByFilename(string filename)
- {
- string extension = GetFileExtension(filename);
-
- var provider = ComposeProvider(extension);
-
- provider.SetConnectionString(string.Format("data source={0}", filename));
- return provider;
- }
-
- private static string GetFileExtension(string filename)
- {
- var extension = Path.GetExtension(filename);
-
- if (extension == null) throw new ArgumentException("Unrecognised file.");
- return extension.TrimStart('.').ToLower();
- }
-
- private static IConnectionProvider ComposeProvider(string extension)
- {
- return MefHelper.Compose<IConnectionProvider>(extension);
- }
- }
-}
View
48 Simple.Data/Ado/Schema/AmbiguousObjectNameException.cs
@@ -1,48 +0,0 @@
-using System;
-using System.Runtime.Serialization;
-
-namespace Simple.Data.Ado.Schema
-{
- [Serializable]
- public class AmbiguousObjectNameException : Exception
- {
- private readonly string _name;
-
- public AmbiguousObjectNameException()
- {
- }
-
- public AmbiguousObjectNameException(string name)
- {
- _name = name;
- }
-
- public AmbiguousObjectNameException(string name, string message) : base(message)
- {
- _name = name;
- }
-
- public AmbiguousObjectNameException(string name, string message, Exception inner) : base(message, inner)
- {
- _name = name;
- }
-
- protected AmbiguousObjectNameException(
- SerializationInfo info,
- StreamingContext context) : base(info, context)
- {
- _name = info.GetString("_name");
- }
-
- public string Name
- {
- get { return _name; }
- }
-
- public override void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- base.GetObjectData(info, context);
- info.AddValue("_name", _name);
- }
- }
-}
View
89 Simple.Data/Ado/Schema/Column.cs
@@ -1,89 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using Simple.Data.Extensions;
-
-namespace Simple.Data.Ado.Schema
-{
- public class Column : IEquatable<Column>
- {
- private readonly string _actualName;
- private readonly Table _table;
- private readonly bool _isIdentity;
-
- public Column(string actualName, Table table) : this(actualName, table, false)
- {
- }
-
- public Column(string actualName, Table table, bool isIdentity)
- {
- _actualName = actualName;
- _isIdentity = isIdentity;
- _table = table;
- }
-
- public string HomogenizedName
- {
- get { return ActualName.Homogenize(); }
- }
-
- public string ActualName
- {
- get { return _actualName; }
- }
-
- public string QuotedName
- {
- get { return _table.DatabaseSchema.QuoteObjectName(_actualName); }
- }
-
- public bool IsIdentity
- {
- get { return _isIdentity; }
- }
-
- /// <summary>
- /// Indicates whether the current object is equal to another object of the same type.
- /// </summary>
- /// <returns>
- /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
- /// </returns>
- /// <param name="other">An object to compare with this object.</param>
- public bool Equals(Column other)
- {
- if (ReferenceEquals(null, other)) return false;
- if (ReferenceEquals(this, other)) return true;
- return Equals(other._actualName, _actualName) && Equals(other._table, _table);
- }
-
- /// <summary>
- /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
- /// </summary>
- /// <returns>
- /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
- /// </returns>
- /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>. </param><filterpriority>2</filterpriority>
- public override bool Equals(object obj)
- {
- if (ReferenceEquals(null, obj)) return false;
- if (ReferenceEquals(this, obj)) return true;
- if (obj.GetType() != typeof (Column)) return false;
- return Equals((Column) obj);
- }
-
- /// <summary>
- /// Serves as a hash function for a particular type.
- /// </summary>
- /// <returns>
- /// A hash code for the current <see cref="T:System.Object"/>.
- /// </returns>
- /// <filterpriority>2</filterpriority>
- public override int GetHashCode()
- {
- unchecked
- {
- return ((_actualName != null ? _actualName.GetHashCode() : 0)*397) ^ (_table != null ? _table.GetHashCode() : 0);
- }
- }
- }
-}
View
39 Simple.Data/Ado/Schema/ColumnCollection.cs
@@ -1,39 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using Simple.Data.Extensions;
-
-namespace Simple.Data.Ado.Schema
-{
- class ColumnCollection : Collection<Column>
- {
- public ColumnCollection()
- {
-
- }
-
- public ColumnCollection(IEnumerable<Column> columns) : base(columns.ToList())
- {
-
- }
- /// <summary>
- /// Finds the column with a name most closely matching the specified column name.
- /// This method will try an exact match first, then a case-insensitve search, then a pluralized or singular version.
- /// </summary>
- /// <param name="columnName">Name of the column.</param>
- /// <returns>A <see cref="Column"/> if a match is found; otherwise, <c>null</c>.</returns>
- public Column Find(string columnName)
- {
- return FindColumnWithName(columnName);
- }
-
- private Column FindColumnWithName(string columnName)
- {
- columnName = columnName.Homogenize();
- return this
- .Where(c => c.HomogenizedName.Equals(columnName))
- .SingleOrDefault();
- }
- }
-}
View
59 Simple.Data/Ado/Schema/DatabaseSchema.cs
@@ -1,59 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Data;
-using System.Linq;
-
-namespace Simple.Data.Ado.Schema
-{
- internal class DatabaseSchema
- {
- private static readonly ConcurrentDictionary<string, DatabaseSchema> Instances = new ConcurrentDictionary<string, DatabaseSchema>();
-
- private readonly ISchemaProvider _schemaProvider;
- private readonly Lazy<TableCollection> _lazyTables;
-
- private DatabaseSchema(ISchemaProvider schemaProvider)
- {
- _lazyTables = new Lazy<TableCollection>(CreateTableCollection);
- _schemaProvider = schemaProvider;
- }
-
- public ISchemaProvider SchemaProvider
- {
- get { return _schemaProvider; }
- }
-
- public bool IsAvailable
- {
- get { return _schemaProvider != null; }
- }
-
- public IEnumerable<Table> Tables
- {
- get { return _lazyTables.Value.AsEnumerable(); }
- }
-
- public Table FindTable(string tableName)
- {
- return _lazyTables.Value.Find(tableName);
- }
-
- private TableCollection CreateTableCollection()
- {
- return new TableCollection(_schemaProvider.GetTables()
- .Select(table => new Table(table.ActualName, table.Schema, table.Type, this)));
- }
-
- public string QuoteObjectName(string unquotedName)
- {
- return _schemaProvider.QuoteObjectName(unquotedName);
- }
-
- public static DatabaseSchema Get(IConnectionProvider connectionProvider)
- {
- return Instances.GetOrAdd(connectionProvider.ConnectionString,
- sp => new DatabaseSchema(connectionProvider.GetSchemaProvider()));
- }
- }
-}
View
40 Simple.Data/Ado/Schema/ForeignKey.cs
@@ -1,40 +0,0 @@
-using System.Collections.Generic;
-
-namespace Simple.Data.Ado.Schema
-{
- public sealed class ForeignKey
- {
- private readonly Key _columns;
- private readonly string _detailTable;
- private readonly string _masterTable;
- private readonly Key _masterColumns;
-
- public ForeignKey(string detailTable, IEnumerable<string> columns, string masterTable, IEnumerable<string> masterColumns)
- {
- _columns = new Key(columns);
- _detailTable = detailTable;
- _masterTable = masterTable;
- _masterColumns = new Key(masterColumns);
- }
-
- public string DetailTable
- {
- get { return _detailTable; }
- }
-
- public Key UniqueColumns
- {
- get { return _masterColumns; }
- }
-
- public Key Columns
- {
- get { return _columns; }
- }
-
- public string MasterTable
- {
- get { return _masterTable; }
- }
- }
-}
View
19 Simple.Data/Ado/Schema/ForeignKeyCollection.cs
@@ -1,19 +0,0 @@
-using System.Collections.ObjectModel;
-
-namespace Simple.Data.Ado.Schema
-{
- class ForeignKeyCollection : KeyedCollection<string, ForeignKey>
- {
- /// <summary>
- /// When implemented in a derived class, extracts the key from the specified element.
- /// </summary>
- /// <returns>
- /// The key for the specified element.
- /// </returns>
- /// <param name="item">The element from which to extract the key.</param>
- protected override string GetKeyForItem(ForeignKey item)
- {
- return item.MasterTable;
- }
- }
-}
View
14 Simple.Data/Ado/Schema/ISchemaProvider.cs
@@ -1,14 +0,0 @@
-using System.Collections.Generic;
-using System.Data;
-
-namespace Simple.Data.Ado.Schema
-{
- public interface ISchemaProvider
- {
- IEnumerable<Table> GetTables();
- IEnumerable<Column> GetColumns(Table table);
- Key GetPrimaryKey(Table table);
- IEnumerable<ForeignKey> GetForeignKeys(Table table);
- string QuoteObjectName(string unquotedName);
- }
-}
View
29 Simple.Data/Ado/Schema/Key.cs
@@ -1,29 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Simple.Data.Ado.Schema
-{
- public sealed class Key
- {
- private readonly string[] _columns;
- public Key(IEnumerable<string> columns)
- {
- _columns = columns.ToArray();
- }
-
- public string this[int index]
- {
- get { return _columns[index]; }
- }
-
- public int Length
- {
- get { return _columns.Length; }
- }
-
- public IEnumerable<string> AsEnumerable()
- {
- return _columns.AsEnumerable();
- }
- }
-}
View
8 Simple.Data/Ado/Schema/SchemaSpecificStringExtensions.cs
@@ -1,8 +0,0 @@
-using System.Text.RegularExpressions;
-
-namespace Simple.Data.Ado.Schema
-{
- static class SchemaSpecificStringExtensions
- {
- }
-}
View
202 Simple.Data/Ado/Schema/Table.cs
@@ -1,202 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Linq;
-using Simple.Data.Extensions;
-
-namespace Simple.Data.Ado.Schema
-{
- public class Table : IEquatable<Table>
- {
- private readonly string _actualName;
- private readonly string _schema;
- private readonly TableType _type;
- private readonly DatabaseSchema _databaseSchema;
- private readonly Lazy<ColumnCollection> _lazyColumns;
- private readonly Lazy<Key> _lazyPrimaryKey;
- private readonly Lazy<ForeignKeyCollection> _lazyForeignKeys;
-
- public Table(string name, string schema, TableType type)
- {
- _actualName = name;
- _schema = schema;
- _type = type;
- }
-
- internal Table(string name, string schema, TableType type, DatabaseSchema databaseSchema)
- {
- _actualName = name;
- _databaseSchema = databaseSchema;
- _schema = schema;
- _type = type;
- _lazyColumns = new Lazy<ColumnCollection>(GetColumns);
- _lazyPrimaryKey = new Lazy<Key>(GetPrimaryKey);
- _lazyForeignKeys = new Lazy<ForeignKeyCollection>(GetForeignKeys);
- }
-
- public TableType Type
- {
- get { return _type; }
- }
-
- internal string HomogenizedName
- {
- get { return ActualName.Homogenize(); }
- }
-
- internal DatabaseSchema DatabaseSchema
- {
- get { return _databaseSchema; }
- }
-
- public string Schema
- {
- get { return _schema; }
- }
-
- public string ActualName
- {
- get { return _actualName; }
- }
-
- internal string QuotedName
- {
- get { return _databaseSchema.QuoteObjectName(_actualName); }
- }
-
- internal IEnumerable<Column> Columns
- {
- get { return _lazyColumns.Value.AsEnumerable(); }
- }
-
- internal Column FindColumn(string columnName)
- {
- var columns = _lazyColumns.Value;
- return columns.Find(columnName);
- }
-
- internal Key PrimaryKey
- {
- get { return _lazyPrimaryKey.Value; }
- }
-
- internal ForeignKeyCollection ForeignKeys
- {
- get { return _lazyForeignKeys.Value; }
- }
-
- private ColumnCollection GetColumns()
- {
- return new ColumnCollection(_databaseSchema.SchemaProvider.GetColumns(this));
- }
-
- private Key GetPrimaryKey()
- {
- return _databaseSchema.SchemaProvider.GetPrimaryKey(this);
- //var columns = _databaseSchema.SchemaProvider.GetSchema("PRIMARY_KEYS", ActualName).AsEnumerable()
- // .OrderBy(row => (int) row["ORDINAL_POSITION"])
- // .Select(row => row["COLUMN_NAME"].ToString())
- // .ToArray();
-
- //return new Key(columns);
- }
-
- private ForeignKeyCollection GetForeignKeys()
- {
- var collection = new ForeignKeyCollection();
-
- //var keys = _databaseSchema.SchemaProvider.GetSchema("FOREIGN_KEYS", ActualName).AsEnumerable()
- // .GroupBy(row => row["UNIQUE_TABLE_NAME"].ToString());
-
- foreach (var key in _databaseSchema.SchemaProvider.GetForeignKeys(this))
- {
- //var columns = key.OrderBy(row => (int)row["ORDINAL_POSITION"]).Select(row => row["COLUMN_NAME"].ToString()).ToArray();
- //var uniqueColumns = key.OrderBy(row => (int)row["ORDINAL_POSITION"]).Select(row => row["UNIQUE_COLUMN_NAME"].ToString()).ToArray();
- collection.Add(key);
- }
-
- return collection;
- }
-
- internal TableJoin GetMaster(string name)
- {
- var master = DatabaseSchema.FindTable(name);
- if (master != null)
- {
- string commonColumnName = GetCommonColumnName(master);
-
- if (commonColumnName != null)
- {
- return new TableJoin(master, master.FindColumn(commonColumnName), this, FindColumn(commonColumnName));
- }
- }
- return null;
- }
-
- private string GetCommonColumnName(Table other)
- {
- return other.Columns
- .Select(c => c.HomogenizedName)
- .Intersect(Columns.Select(c => c.HomogenizedName))
- .SingleOrDefault();
- }
-
- internal TableJoin GetDetail(string name)
- {
- var detail = DatabaseSchema.FindTable(name);
- string commonColumnName = GetCommonColumnName(detail);
- if (detail.Columns.Select(c => c.HomogenizedName).Intersect(Columns.Select(c => c.HomogenizedName)).Count() == 1)
- {
- return new TableJoin(this, FindColumn(commonColumnName), detail, detail.FindColumn(commonColumnName));
- }
- return null;
- }
-
- /// <summary>
- /// Indicates whether the current object is equal to another object of the same type.
- /// </summary>
- /// <returns>
- /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
- /// </returns>
- /// <param name="other">An object to compare with this object.</param>
- public bool Equals(Table other)
- {
- if (ReferenceEquals(null, other)) return false;
- if (ReferenceEquals(this, other)) return true;
- return Equals(other._actualName, _actualName) && Equals(other._schema, _schema) && Equals(other._type, _type);
- }
-
- /// <summary>
- /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
- /// </summary>
- /// <returns>
- /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
- /// </returns>
- /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>. </param><filterpriority>2</filterpriority>
- public override bool Equals(object obj)
- {
- if (ReferenceEquals(null, obj)) return false;
- if (ReferenceEquals(this, obj)) return true;
- if (obj.GetType() != typeof (Table)) return false;
- return Equals((Table) obj);
- }
-
- /// <summary>
- /// Serves as a hash function for a particular type.
- /// </summary>
- /// <returns>
- /// A hash code for the current <see cref="T:System.Object"/>.
- /// </returns>
- /// <filterpriority>2</filterpriority>
- public override int GetHashCode()
- {
- unchecked
- {
- int result = (_actualName != null ? _actualName.GetHashCode() : 0);
- result = (result*397) ^ (_schema != null ? _schema.GetHashCode() : 0);
- result = (result*397) ^ _type.GetHashCode();
- return result;
- }
- }
- }
-}
View
61 Simple.Data/Ado/Schema/TableCollection.cs
@@ -1,61 +0,0 @@
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using Simple.Data.Extensions;
-
-namespace Simple.Data.Ado.Schema
-{
- class TableCollection : Collection<Table>
- {
- public TableCollection()
- {
- }
-
- public TableCollection(IEnumerable<Table> tables)
- : base(tables.ToList())
- {
- }
-
- /// <summary>
- /// Finds the Table with a name most closely matching the specified table name.
- /// This method will try an exact match first, then a case-insensitve search, then a pluralized or singular version.
- /// </summary>
- /// <param name="tableName">Name of the table.</param>
- /// <returns>A <see cref="Table"/> if a match is found; otherwise, <c>null</c>.</returns>
- public Table Find(string tableName)
- {
- var table = FindTableWithName(tableName.Homogenize())
- ?? FindTableWithPluralName(tableName.Homogenize())
- ?? FindTableWithSingularName(tableName.Homogenize());
-
- if (table == null)
- {
- throw new UnresolvableObjectException(tableName, "No matching table found, or insufficient permissions.");
- }
-
- return table;
- }
-
- private Table FindTableWithName(string tableName)
- {
- return this
- .Where(t => t.HomogenizedName.Equals(tableName))
- .SingleOrDefault();
- }
-
- private Table FindTableWithPluralName(string tableName)
- {
- return FindTableWithName(tableName.Pluralize());
- }
-
- private Table FindTableWithSingularName(string tableName)
- {
- if (tableName.IsPlural())
- {
- return FindTableWithName(tableName.Singularize());
- }
-
- return null;
- }
- }
-}
View
40 Simple.Data/Ado/Schema/TableJoin.cs
@@ -1,40 +0,0 @@
-namespace Simple.Data.Ado.Schema
-{
- class TableJoin
- {
- private readonly Table _master;
- private readonly Column _masterColumn;
- private readonly Table _detail;
- private readonly Column _detailColumn;
-
- public TableJoin(Table master, Column masterColumn, Table detail, Column detailColumn)
- {
- _master = master;
- _masterColumn = masterColumn;
- _detailColumn = detailColumn;
- _detail = detail;
- }
-
- public Column MasterColumn
- {
- get { return _masterColumn; }
- }
-
- public Table Detail
- {
- get { return _detail; }
- }
-
- public Table Master
- {
- get { return _master; }
- }
-
- public Column DetailColumn
- {
- get {
- return _detailColumn;
- }
- }
- }
-}
View
8 Simple.Data/Ado/Schema/TableType.cs
@@ -1,8 +0,0 @@
-namespace Simple.Data.Ado.Schema
-{
- public enum TableType
- {
- Table,
- View
- }
-}
View
32 Simple.Data/Ado/SchemaResolutionException.cs
@@ -1,32 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.Serialization;
-using System.Text;
-
-namespace Simple.Data.Ado
-{
- [Serializable]
- public class SchemaResolutionException : SimpleDataException
- {
- public SchemaResolutionException() : base()
- {
- }
-
- public SchemaResolutionException(string message)
- : base(message)
- {
- }
-
- public SchemaResolutionException(string message, Exception inner)
- : base(message, inner)
- {
- }
-
- protected SchemaResolutionException(
- SerializationInfo info,
- StreamingContext context) : base(info, context)
- {
- }
- }
-}
View
45 Simple.Data/Ado/UpdateHelper.cs
@@ -1,45 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Simple.Data.Ado.Schema;
-
-namespace Simple.Data.Ado
-{
- internal class UpdateHelper
- {
- private readonly DatabaseSchema _schema;
- private readonly ICommandBuilder _commandBuilder;
- private readonly IExpressionFormatter _expressionFormatter;
-
- public UpdateHelper(DatabaseSchema schema)
- {
- _schema = schema;
- _commandBuilder = new CommandBuilder();
- _expressionFormatter = new ExpressionFormatter(_commandBuilder, _schema);
- }
-
- public ICommandBuilder GetUpdateCommand(string tableName, IDictionary<string, object> data, SimpleExpression criteria)
- {
- _commandBuilder.Append(GetUpdateClause(tableName, data));
-
- if (criteria != null)
- {
- _commandBuilder.Append(" where ");
- _commandBuilder.Append(_expressionFormatter.Format(criteria));
- }
-
- return _commandBuilder;
- }
-
- private string GetUpdateClause(string tableName, IDictionary<string, object> data)
- {
- var table = _schema.FindTable(tableName);
- var setClause = string.Join(", ",
- data.Select(
- kvp =>
- string.Format("{0} = {1}", table.FindColumn(kvp.Key).QuotedName, _commandBuilder.AddParameter(kvp.Value))));
- return string.Format("update {0} set {1}", table.QuotedName, setClause);
- }
- }
-}

0 comments on commit 61bf4ed

Please sign in to comment.