Skip to content

Commit

Permalink
ORM implementation
Browse files Browse the repository at this point in the history
CRUD ORM implementation for directly quering database, without interacting with caching mechanics.
  • Loading branch information
saklis committed Nov 19, 2020
1 parent 3a2032c commit 2040b9c
Show file tree
Hide file tree
Showing 12 changed files with 538 additions and 17 deletions.
6 changes: 6 additions & 0 deletions .cr/personal/FavoritesList/List.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Root Type="DevExpress.CodeRush.Foundation.CodePlaces.Options.FavoritesListContainer">
<Options Language="Neutral">
<Groups />
</Options>
</Root>
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/.vs/
/AdoCacheEngine/bin
/AdoCacheEngine/obj
/packages/
/packages/
/TestConsoleApp/
6 changes: 6 additions & 0 deletions Ado Cache Engine.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.30517.126
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdoCacheEngine", "AdoCacheEngine\AdoCacheEngine.csproj", "{9FB34478-E895-42CD-B758-929F8DB4CBD2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestConsoleApp", "TestConsoleApp\TestConsoleApp.csproj", "{0A8E693F-6AA8-403C-A015-917E6007382B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -15,6 +17,10 @@ Global
{9FB34478-E895-42CD-B758-929F8DB4CBD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FB34478-E895-42CD-B758-929F8DB4CBD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FB34478-E895-42CD-B758-929F8DB4CBD2}.Release|Any CPU.Build.0 = Release|Any CPU
{0A8E693F-6AA8-403C-A015-917E6007382B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0A8E693F-6AA8-403C-A015-917E6007382B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0A8E693F-6AA8-403C-A015-917E6007382B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0A8E693F-6AA8-403C-A015-917E6007382B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
2 changes: 1 addition & 1 deletion AdoCacheEngine/AdoCacheEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public AdoCacheEngine(string connectionString) {
}

/// <summary>
/// Get cached item.
/// Execute cached item.
/// </summary>
/// <typeparam name="TEntity">Cached type inheriting from AdoCacheEntity.</typeparam>
/// <exception cref="InvalidOperationException">Thrown when CacheItem for supplied type does not exists.</exception>
Expand Down
5 changes: 5 additions & 0 deletions AdoCacheEngine/AdoCacheEngine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
<Compile Include="ConcurrentAdoCacheEngine.cs" />
<Compile Include="ConcurrentAdoCacheItem.cs" />
<Compile Include="EntityComparer.cs" />
<Compile Include="ORM\Database.cs" />
<Compile Include="ORM\Delete.cs" />
<Compile Include="ORM\Insert.cs" />
<Compile Include="ORM\Select.cs" />
<Compile Include="ORM\Update.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ryanohs\WhereBuilder.cs" />
<Compile Include="ryanohs\WherePart.cs" />
Expand Down
26 changes: 13 additions & 13 deletions AdoCacheEngine/AdoCacheItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ public virtual void Delete(TEntity entity)
}

/// <summary>
/// Get entity from dictionary.
/// Execute entity from dictionary.
/// </summary>
/// <param name="nameOfColumn">Name of column.</param>
/// <param name="value">Value of key field.</param>
Expand Down Expand Up @@ -572,7 +572,7 @@ public virtual List<TEntity> FindInIndex(string nameOfColumn, object value)
}

/// <summary>
/// Get dictionary for column.
/// Execute dictionary for column.
/// </summary>
/// <param name="nameOfColumn">Name of column that dictionary is based on.</param>
/// <returns>Dictionary - a collection of KeyValuePair objects optimized for quick access by object's key.</returns>
Expand All @@ -582,7 +582,7 @@ public virtual ConcurrentDictionary<object, TEntity> GetDictionary(string nameOf
}

/// <summary>
/// Get index for column.
/// Execute index for column.
/// </summary>
/// <param name="nameOfColumn">Name of column that index is based on.</param>
/// <returns>Index - list of references sorted by column.</returns>
Expand Down Expand Up @@ -613,11 +613,11 @@ public virtual TEntity Insert(TEntity entity)

// create instance of TEntity while passing 'true' to isManagedByCacheEngine
TEntity newEntity = (TEntity) Activator.CreateInstance(typeof(TEntity),
BindingFlags.Instance | BindingFlags.NonPublic, null,
new object[]
{
true
}, null, null);
BindingFlags.Instance | BindingFlags.NonPublic, null,
new object[]
{
true
}, null, null);

using (SqlConnection conn = new SqlConnection(_connectionString))
{
Expand Down Expand Up @@ -649,7 +649,7 @@ public virtual TEntity Insert(TEntity entity)
{
throw new
InvalidOperationException($"Column(s) {string.Join<PropertyInfo>(", ", _autoIncrementColumns)} are marked with [AutoIncrement] attribute, but db engine did not return scope identity after Insert(). DATA ARE INCONSISTENT.",
ex);
ex);
}
}

Expand All @@ -672,7 +672,7 @@ public virtual TEntity Insert(TEntity entity)
else
{
foreach (PropertyInfo info in _columns
.Except(_keyColumns).Except(_autoIncrementColumns).Except(_readOnlyColumns))
.Except(_keyColumns).Except(_autoIncrementColumns).Except(_readOnlyColumns))
{
info.SetValue(newEntity, info.GetValue(entity));
}
Expand Down Expand Up @@ -927,7 +927,7 @@ private static List<TEntity> FilterOutNotMatchingKeys(List<TEntity> orgList, Pro
}

/// <summary>
/// Get list of entities for table.
/// Execute list of entities for table.
/// </summary>
/// <param name="table">Table name.</param>
/// <returns>List of entities.</returns>
Expand Down Expand Up @@ -1053,7 +1053,7 @@ private List<TEntity> GetEntities()
}

/// <summary>
/// Get Entities from database.
/// Execute Entities from database.
/// </summary>
/// <typeparam name="TRelation">Type of cached entity that is base for loading data.</typeparam>
/// <param name="cachedItem">Cached item object that is used as base for loading data.</param>
Expand Down Expand Up @@ -1155,7 +1155,7 @@ private List<TEntity> GetEntitiesRelatedWith<TRelation>(AdoCacheItem<TRelation>
}

/// <summary>
/// Get Entities from database.
/// Execute Entities from database.
/// </summary>
/// <param name="clause">Where clause.</param>
/// <returns>The <see cref="List{T}" /> list of Entities.</returns>
Expand Down
44 changes: 44 additions & 0 deletions AdoCacheEngine/ORM/Database.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.Data;
using System.Data.SqlClient;

namespace AdoCache.ORM
{
public class Database
{
private SqlConnection _sqlConn;

public Database(string connectionString) => ConnectionString = connectionString;

#region API

public Delete<TEntity> Delete<TEntity>() where TEntity : AdoCacheEntity, new() => new Delete<TEntity>(_sqlConn);

public Insert<TEntity> Insert<TEntity>() where TEntity : AdoCacheEntity, new() => new Insert<TEntity>(_sqlConn);

public Select<TEntity> Select<TEntity>() where TEntity : AdoCacheEntity, new() => new Select<TEntity>(_sqlConn);

public Update<TEntity> Update<TEntity>() where TEntity : AdoCacheEntity, new() => new Update<TEntity>(_sqlConn);

#endregion API

#region Open/Close connection

public string ConnectionString { get; }

public void Close()
{
if (_sqlConn != null && (_sqlConn.State != ConnectionState.Closed || _sqlConn.State != ConnectionState.Broken))
{
_sqlConn.Close();
}
}

public void Open()
{
_sqlConn = new SqlConnection(ConnectionString);
_sqlConn.Open();
}

#endregion Open/Close connection
}
}
77 changes: 77 additions & 0 deletions AdoCacheEngine/ORM/Delete.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq.Expressions;
using AdoCache.Attributes;
using AdoCache.ryanohs;

namespace AdoCache.ORM
{
public class Delete<TEntity> where TEntity : AdoCacheEntity, new()
{
private readonly SqlConnection _sqlConn;

private Expression<Func<TEntity, bool>> _clause;

internal Delete(SqlConnection sqlConn)
{
_sqlConn = sqlConn;

string tableName = (typeof(TEntity).GetCustomAttributes(typeof(TableNameAttribute), false)[0] as TableNameAttribute)?.TableName;
if (string.IsNullOrWhiteSpace(tableName))
{
throw new ArgumentException("Could not deduce table name.");
}

TableName = tableName;
}

/// <summary>
/// Name of Table in data base.
/// </summary>
public string TableName { get; }

#region API

public int All() => Execute();

public int Execute()
{
SqlCommand command = new SqlCommand("", _sqlConn);

if (_clause == null)
{
command.CommandText = $"DELETE FROM {TableName}";
}
else
{
WherePart sql = new WhereBuilder().ToSql(_clause);
string whereClause = sql.Sql;

foreach (KeyValuePair<string, object> pair in sql.Parameters)
{
if (pair.Value == null)
{
whereClause = whereClause.Replace($"@{pair.Key}", "NULL");
}
else
{
command.Parameters.AddWithValue($"@{pair.Key}", pair.Value);
}
}

command.CommandText = $"DELETE FROM {TableName} WHERE {whereClause}";
}

return command.ExecuteNonQuery();
}

public Delete<TEntity> Where(Expression<Func<TEntity, bool>> clause)
{
_clause = clause;
return this;
}

#endregion API
}
}
Loading

0 comments on commit 2040b9c

Please sign in to comment.