Commit d3260f44 authored by Marc Gravell's avatar Marc Gravell

Add cache bypass option (Issue #66)

parent 5039ea1c
...@@ -43,6 +43,10 @@ public enum CommandFlags ...@@ -43,6 +43,10 @@ public enum CommandFlags
/// Can async queries be pipelined? /// Can async queries be pipelined?
/// </summary> /// </summary>
Pipelined = 2, Pipelined = 2,
/// <summary>
/// Should the plan cache be bypassed?
/// </summary>
NoCache = 4
} }
/// <summary> /// <summary>
/// Represents the key aspects of a sql operation /// Represents the key aspects of a sql operation
...@@ -84,6 +88,11 @@ public struct CommandDefinition ...@@ -84,6 +88,11 @@ public struct CommandDefinition
/// </summary> /// </summary>
public bool Buffered { get { return (flags & CommandFlags.Buffered) != 0; } } public bool Buffered { get { return (flags & CommandFlags.Buffered) != 0; } }
/// <summary>
/// Should the plan for this query be cached?
/// </summary>
internal bool AddToCache { get { return (flags & CommandFlags.NoCache) == 0; } }
/// <summary> /// <summary>
/// Additional state flags against this command /// Additional state flags against this command
/// </summary> /// </summary>
...@@ -1032,7 +1041,7 @@ private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition com ...@@ -1032,7 +1041,7 @@ private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition com
masterSql = cmd.CommandText; masterSql = cmd.CommandText;
isFirst = false; isFirst = false;
identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null); identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null);
info = GetCacheInfo(identity, obj); info = GetCacheInfo(identity, obj, command.AddToCache);
} }
else else
{ {
...@@ -1054,11 +1063,17 @@ private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition com ...@@ -1054,11 +1063,17 @@ private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition com
if (param != null) if (param != null)
{ {
identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType(), null); identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType(), null);
info = GetCacheInfo(identity, param); info = GetCacheInfo(identity, param, command.AddToCache);
} }
return ExecuteCommand(cnn, ref command, param == null ? null : info.ParamReader); return ExecuteCommand(cnn, ref command, param == null ? null : info.ParamReader);
} }
private static CacheInfo GetCacheInfo(Identity identity, object obj, object addToCache)
{
throw new NotImplementedException();
}
/// <summary> /// <summary>
/// Execute parameterized SQL and return an <see cref="IDataReader"/> /// Execute parameterized SQL and return an <see cref="IDataReader"/>
/// </summary> /// </summary>
...@@ -1232,7 +1247,7 @@ private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandD ...@@ -1232,7 +1247,7 @@ private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandD
{ {
object param = command.Parameters; object param = command.Parameters;
Identity identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(GridReader), param == null ? null : param.GetType(), null); Identity identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(GridReader), param == null ? null : param.GetType(), null);
CacheInfo info = GetCacheInfo(identity, param); CacheInfo info = GetCacheInfo(identity, param, command.AddToCache);
IDbCommand cmd = null; IDbCommand cmd = null;
IDataReader reader = null; IDataReader reader = null;
...@@ -1268,7 +1283,7 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini ...@@ -1268,7 +1283,7 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini
{ {
object param = command.Parameters; object param = command.Parameters;
var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param == null ? null : param.GetType(), null); var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param == null ? null : param.GetType(), null);
var info = GetCacheInfo(identity, param); var info = GetCacheInfo(identity, param, command.AddToCache);
IDbCommand cmd = null; IDbCommand cmd = null;
IDataReader reader = null; IDataReader reader = null;
...@@ -1502,7 +1517,7 @@ partial class DontMap { } ...@@ -1502,7 +1517,7 @@ partial class DontMap { }
{ {
object param = command.Parameters; object param = command.Parameters;
identity = identity ?? new Identity(command.CommandText, command.CommandType, cnn, typeof(TFirst), param == null ? null : param.GetType(), new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh) }); identity = identity ?? new Identity(command.CommandText, command.CommandType, cnn, typeof(TFirst), param == null ? null : param.GetType(), new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh) });
CacheInfo cinfo = GetCacheInfo(identity, param); CacheInfo cinfo = GetCacheInfo(identity, param, command.AddToCache);
IDbCommand ownedCommand = null; IDbCommand ownedCommand = null;
IDataReader ownedReader = null; IDataReader ownedReader = null;
...@@ -1688,7 +1703,7 @@ private static int GetNextSplit(int startIdx, string splitOn, IDataReader reader ...@@ -1688,7 +1703,7 @@ private static int GetNextSplit(int startIdx, string splitOn, IDataReader reader
throw new ArgumentException(MultiMapSplitExceptionMessage); throw new ArgumentException(MultiMapSplitExceptionMessage);
} }
private static CacheInfo GetCacheInfo(Identity identity, object exampleParameters) private static CacheInfo GetCacheInfo(Identity identity, object exampleParameters, bool addToCache)
{ {
CacheInfo info; CacheInfo info;
if (!TryGetQueryCache(identity, out info)) if (!TryGetQueryCache(identity, out info))
...@@ -1717,7 +1732,7 @@ private static CacheInfo GetCacheInfo(Identity identity, object exampleParameter ...@@ -1717,7 +1732,7 @@ private static CacheInfo GetCacheInfo(Identity identity, object exampleParameter
info.ParamReader = CreateParamInfoGenerator(identity, false, true, literals); info.ParamReader = CreateParamInfoGenerator(identity, false, true, literals);
} }
} }
SetQueryCache(identity, info); if(addToCache) SetQueryCache(identity, info);
} }
return info; return info;
} }
...@@ -2875,7 +2890,7 @@ private static IDataReader ExecuteReaderImpl(IDbConnection cnn, ref CommandDefin ...@@ -2875,7 +2890,7 @@ private static IDataReader ExecuteReaderImpl(IDbConnection cnn, ref CommandDefin
if (param != null) if (param != null)
{ {
identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType(), null); identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType(), null);
info = GetCacheInfo(identity, param); info = GetCacheInfo(identity, param, command.AddToCache);
} }
var paramReader = info == null ? null : info.ParamReader; var paramReader = info == null ? null : info.ParamReader;
return paramReader; return paramReader;
...@@ -3548,7 +3563,7 @@ public IEnumerable<T> Read<T>(bool buffered = true) ...@@ -3548,7 +3563,7 @@ public IEnumerable<T> Read<T>(bool buffered = true)
if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed"); if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed");
if (consumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once"); if (consumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once");
var typedIdentity = identity.ForGrid(typeof(T), gridIndex); var typedIdentity = identity.ForGrid(typeof(T), gridIndex);
CacheInfo cache = GetCacheInfo(typedIdentity, null); CacheInfo cache = GetCacheInfo(typedIdentity, null, true);
var deserializer = cache.Deserializer; var deserializer = cache.Deserializer;
int hash = GetColumnHash(reader); int hash = GetColumnHash(reader);
...@@ -3575,7 +3590,7 @@ public IEnumerable<object> Read(Type type, bool buffered = true) ...@@ -3575,7 +3590,7 @@ public IEnumerable<object> Read(Type type, bool buffered = true)
if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed"); if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed");
if (consumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once"); if (consumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once");
var typedIdentity = identity.ForGrid(type, gridIndex); var typedIdentity = identity.ForGrid(type, gridIndex);
CacheInfo cache = GetCacheInfo(typedIdentity, null); CacheInfo cache = GetCacheInfo(typedIdentity, null, true);
var deserializer = cache.Deserializer; var deserializer = cache.Deserializer;
int hash = GetColumnHash(reader); int hash = GetColumnHash(reader);
......
...@@ -50,7 +50,7 @@ private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn, ...@@ -50,7 +50,7 @@ private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn,
{ {
object param = command.Parameters; object param = command.Parameters;
var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param == null ? null : param.GetType(), null); var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param == null ? null : param.GetType(), null);
var info = GetCacheInfo(identity, param); var info = GetCacheInfo(identity, param, command.AddToCache);
bool wasClosed = cnn.State == ConnectionState.Closed; bool wasClosed = cnn.State == ConnectionState.Closed;
using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader)) using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
{ {
...@@ -130,7 +130,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD ...@@ -130,7 +130,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
cmd = (DbCommand)command.SetupCommand(cnn, null); cmd = (DbCommand)command.SetupCommand(cnn, null);
masterSql = cmd.CommandText; masterSql = cmd.CommandText;
var identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null); var identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null);
info = GetCacheInfo(identity, obj); info = GetCacheInfo(identity, obj, command.AddToCache);
} else if(pending.Count >= MAX_PENDING) } else if(pending.Count >= MAX_PENDING)
{ {
var recycled = pending.Dequeue(); var recycled = pending.Dequeue();
...@@ -177,7 +177,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD ...@@ -177,7 +177,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
masterSql = cmd.CommandText; masterSql = cmd.CommandText;
isFirst = false; isFirst = false;
var identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null); var identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null);
info = GetCacheInfo(identity, obj); info = GetCacheInfo(identity, obj, command.AddToCache);
} }
else else
{ {
...@@ -199,7 +199,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD ...@@ -199,7 +199,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefinition command, object param) private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefinition command, object param)
{ {
var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param == null ? null : param.GetType(), null); var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param == null ? null : param.GetType(), null);
var info = GetCacheInfo(identity, param); var info = GetCacheInfo(identity, param, command.AddToCache);
bool wasClosed = cnn.State == ConnectionState.Closed; bool wasClosed = cnn.State == ConnectionState.Closed;
using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader)) using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
{ {
...@@ -390,7 +390,7 @@ private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefini ...@@ -390,7 +390,7 @@ private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefini
{ {
object param = command.Parameters; object param = command.Parameters;
var identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(TFirst), param == null ? null : param.GetType(), new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh) }); var identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(TFirst), param == null ? null : param.GetType(), new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh) });
var info = GetCacheInfo(identity, param); var info = GetCacheInfo(identity, param, command.AddToCache);
bool wasClosed = cnn.State == ConnectionState.Closed; bool wasClosed = cnn.State == ConnectionState.Closed;
try try
{ {
...@@ -446,7 +446,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn, ...@@ -446,7 +446,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn,
{ {
object param = command.Parameters; object param = command.Parameters;
Identity identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(GridReader), param == null ? null : param.GetType(), null); Identity identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(GridReader), param == null ? null : param.GetType(), null);
CacheInfo info = GetCacheInfo(identity, param); CacheInfo info = GetCacheInfo(identity, param, command.AddToCache);
DbCommand cmd = null; DbCommand cmd = null;
IDataReader reader = null; IDataReader reader = null;
......
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