Commit b67d6850 authored by jedidja's avatar jedidja

Derived SqlCompactDatabase from Database

Changed CreateTableConstructor to work for child table type
parent 5e8051e1
......@@ -43,6 +43,7 @@
<Compile Include="Database.cs" />
<Compile Include="Snapshotter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SqlCompactDatabase.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Dapper\Dapper.csproj">
......
......@@ -26,9 +26,9 @@ public abstract class Database<TDatabase> : IDisposable where TDatabase : Databa
{
public class Table<T>
{
Database<TDatabase> database;
string tableName;
string likelyTableName;
internal Database<TDatabase> database;
internal string tableName;
internal string likelyTableName;
public Table(Database<TDatabase> database, string likelyTableName)
{
......@@ -50,7 +50,7 @@ public string TableName
/// </summary>
/// <param name="data">Either DynamicParameters or an anonymous type or concrete type</param>
/// <returns></returns>
public int? Insert(dynamic data)
public virtual int? Insert(dynamic data)
{
var o = (object)data;
List<string> paramNames = GetParamNames(o);
......@@ -114,7 +114,7 @@ public IEnumerable<T> All()
}
static ConcurrentDictionary<Type, List<string>> paramNameCache = new ConcurrentDictionary<Type, List<string>>();
private static List<string> GetParamNames(object o)
internal static List<string> GetParamNames(object o)
{
if (o is DynamicParameters)
{
......@@ -147,18 +147,23 @@ public static TDatabase Init(DbConnection connection, int commandTimeout)
return db;
}
private static Action<Database<TDatabase>> tableConstructor;
internal static Action<TDatabase> tableConstructor;
private void InitDatabase(DbConnection connection, int commandTimeout)
internal void InitDatabase(DbConnection connection, int commandTimeout)
{
this.connection = connection;
this.commandTimeout = commandTimeout;
if (tableConstructor == null)
{
tableConstructor = CreateTableConstructor();
tableConstructor = CreateTableConstructorForTable();
}
tableConstructor(this);
tableConstructor(this as TDatabase);
}
internal virtual Action<TDatabase> CreateTableConstructorForTable()
{
return CreateTableConstructor(typeof(Table<>));
}
public void BeginTransaction(IsolationLevel isolation = IsolationLevel.ReadCommitted)
......@@ -178,16 +183,16 @@ public void RollbackTransaction()
transaction = null;
}
protected Action<Database<TDatabase>> CreateTableConstructor()
protected Action<TDatabase> CreateTableConstructor(Type tableType)
{
var dm = new DynamicMethod("ConstructInstances", null, new Type[] { typeof(Database<TDatabase>) }, true);
var dm = new DynamicMethod("ConstructInstances", null, new Type[] { typeof(TDatabase) }, true);
var il = dm.GetILGenerator();
var setters = GetType().GetProperties()
.Where(p => p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(Table<>))
.Where(p => p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == tableType)
.Select(p => Tuple.Create(
p.GetSetMethod(true),
p.PropertyType.GetConstructor(new Type[] { typeof(Database<TDatabase>), typeof(string) }),
p.PropertyType.GetConstructor(new Type[] { typeof(TDatabase), typeof(string) }),
p.Name,
p.DeclaringType
));
......@@ -221,7 +226,7 @@ protected Action<Database<TDatabase>> CreateTableConstructor()
}
il.Emit(OpCodes.Ret);
return (Action<Database<TDatabase>>)dm.CreateDelegate(typeof(Action<Database<TDatabase>>));
return (Action<TDatabase>)dm.CreateDelegate(typeof(Action<TDatabase>));
}
static ConcurrentDictionary<Type, string> tableNameMap = new ConcurrentDictionary<Type, string>();
......
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
namespace Dapper.Rainbow
{
public abstract class SqlCompactDatabase<TDatabase> : Database<TDatabase>, IDisposable where TDatabase : Database<TDatabase>, new()
{
public class SqlCompactTable<T> : Table<T>
{
public SqlCompactTable(Database<TDatabase> database, string likelyTableName)
: base(database, likelyTableName)
{
}
/// <summary>
/// Insert a row into the db
/// </summary>
/// <param name="data">Either DynamicParameters or an anonymous type or concrete type</param>
/// <returns></returns>
public override int? Insert(dynamic data)
{
var o = (object)data;
List<string> paramNames = GetParamNames(o);
paramNames.Remove("Id");
string cols = string.Join(",", paramNames);
string cols_params = string.Join(",", paramNames.Select(p => "@" + p));
var sql = "insert " + TableName + " (" + cols + ") values (" + cols_params + ")";
if (database.Execute(sql, o) != 1)
{
return null;
}
return (int)database.Query<decimal>("SELECT @@IDENTITY AS LastInsertedId").Single();
}
}
public static TDatabase Init(DbConnection connection)
{
TDatabase db = new TDatabase();
db.InitDatabase(connection, 0);
return db;
}
internal override Action<TDatabase> CreateTableConstructorForTable()
{
return CreateTableConstructor(typeof(SqlCompactTable<>));
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment