-
-
Save ghuntley/aa5a92d020035e8ee0a71e0b20465d5c to your computer and use it in GitHub Desktop.
Code to mark a SQL string before it's passed to Dapper.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static List<T> Query<T>(this DataContext db, string sql, object param = null, int? commandTimeout = null, IDbTransaction transaction = null, [CallerFilePath]string fromFile = null, [CallerLineNumber]int onLine = 0, string comment = null) | |
{ | |
using (db.Connection.EnsureOpen()) | |
{ | |
try | |
{ | |
return db.Connection.Query<T>(MarkSqlString(sql, fromFile, onLine, comment), param, transaction ?? db.Transaction, true, commandTimeout).AsDapperList(); | |
} | |
catch (SqlException ex) when (ex.Is(SqlErrorCode.DatabaseReadOnly_3906)) | |
{ | |
HandleReadOnlyException(db, ex); | |
return EmptyDapperList<T>(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private static readonly ConcurrentDictionary<int, string> MarkedSql = new ConcurrentDictionary<int, string>(); | |
/// <summary> | |
/// Takes a SQL query, and inserts the path and line in as a comment. | |
/// </summary> | |
private static string MarkSqlString(string sql, string path, int lineNumber, string comment) | |
{ | |
if (path.IsNullOrEmpty() || lineNumber == 0) return sql; | |
int key = 17; | |
unchecked | |
{ | |
key = key*23 + sql.GetHashCode(); | |
key = key*23 + path.GetHashCode(); | |
key = key*23 + lineNumber.GetHashCode(); | |
if (comment.HasValue()) key = key*23 + comment.GetHashCode(); | |
} | |
// Have we seen this before??? | |
string output; | |
if (MarkedSql.TryGetValue(key, out output)) return output; | |
// nope | |
var commentWrap = " "; | |
var i = sql.IndexOf(Environment.NewLine); | |
// if we didn't find \n, or it was the very end, go to the first space method | |
if (i < 0 || i == sql.Length - 1) | |
{ | |
i = sql.IndexOf(' '); | |
commentWrap = Environment.NewLine; | |
} | |
if (i < 0) return sql; | |
// Grab one directory and the file name worth of the path | |
// this dodges problems with the build server using temp dirs | |
// but also gives us enough info to uniquely identify a queries location | |
var split = path.LastIndexOf('\\') - 1; | |
if (split < 0) return sql; | |
split = path.LastIndexOf('\\', split); | |
if (split < 0) return sql; | |
split++; // just for Craver | |
var sqlComment = " /* " + path.Substring(split) + "@" + lineNumber.ToString() + (comment.HasValue() ? " - " + comment : "") + " */" + commentWrap; | |
var ret = sql.Substring(0, i) + sqlComment + sql.Substring(i); | |
// Cache, don't allocate all this pass again | |
MarkedSql[key] = ret; | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment