Commit 4be8df79 authored by Nick Craver's avatar Nick Craver

Lots of documentation fixes/additions.

parent 7820ee2e
......@@ -306,11 +306,35 @@ public static partial class SqlMapperExtensions
public partial interface ISqlAdapter
{
/// <summary>
/// Inserts <paramref name="entityToInsert"/> into the database, returning the Id of the row created.
/// </summary>
/// <param name="connection">The connection to use.</param>
/// <param name="transaction">The transaction to use.</param>
/// <param name="commandTimeout">The command timeout to use.</param>
/// <param name="tableName">The table to insert into.</param>
/// <param name="columnList">The columns to set with this insert.</param>
/// <param name="parameterList">The parameters to set for this insert.</param>
/// <param name="keyProperties">The key columns in this table.</param>
/// <param name="entityToInsert">The entity to insert.</param>
/// <returns>The Id of the row created.</returns>
Task<int> InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, String tableName, string columnList, string parameterList, IEnumerable<PropertyInfo> keyProperties, object entityToInsert);
}
public partial class SqlServerAdapter
{
/// <summary>
/// Inserts <paramref name="entityToInsert"/> into the database, returning the Id of the row created.
/// </summary>
/// <param name="connection">The connection to use.</param>
/// <param name="transaction">The transaction to use.</param>
/// <param name="commandTimeout">The command timeout to use.</param>
/// <param name="tableName">The table to insert into.</param>
/// <param name="columnList">The columns to set with this insert.</param>
/// <param name="parameterList">The parameters to set for this insert.</param>
/// <param name="keyProperties">The key columns in this table.</param>
/// <param name="entityToInsert">The entity to insert.</param>
/// <returns>The Id of the row created.</returns>
public async Task<int> InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, String tableName, string columnList, string parameterList, IEnumerable<PropertyInfo> keyProperties, object entityToInsert)
{
var cmd = $"INSERT INTO {tableName} ({columnList}) values ({parameterList}); SELECT SCOPE_IDENTITY() id";
......@@ -332,6 +356,18 @@ public async Task<int> InsertAsync(IDbConnection connection, IDbTransaction tran
public partial class SqlCeServerAdapter
{
/// <summary>
/// Inserts <paramref name="entityToInsert"/> into the database, returning the Id of the row created.
/// </summary>
/// <param name="connection">The connection to use.</param>
/// <param name="transaction">The transaction to use.</param>
/// <param name="commandTimeout">The command timeout to use.</param>
/// <param name="tableName">The table to insert into.</param>
/// <param name="columnList">The columns to set with this insert.</param>
/// <param name="parameterList">The parameters to set for this insert.</param>
/// <param name="keyProperties">The key columns in this table.</param>
/// <param name="entityToInsert">The entity to insert.</param>
/// <returns>The Id of the row created.</returns>
public async Task<int> InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable<PropertyInfo> keyProperties, object entityToInsert)
{
var cmd = $"INSERT INTO {tableName} ({columnList}) VALUES ({parameterList})";
......@@ -353,6 +389,18 @@ public async Task<int> InsertAsync(IDbConnection connection, IDbTransaction tran
public partial class MySqlAdapter
{
/// <summary>
/// Inserts <paramref name="entityToInsert"/> into the database, returning the Id of the row created.
/// </summary>
/// <param name="connection">The connection to use.</param>
/// <param name="transaction">The transaction to use.</param>
/// <param name="commandTimeout">The command timeout to use.</param>
/// <param name="tableName">The table to insert into.</param>
/// <param name="columnList">The columns to set with this insert.</param>
/// <param name="parameterList">The parameters to set for this insert.</param>
/// <param name="keyProperties">The key columns in this table.</param>
/// <param name="entityToInsert">The entity to insert.</param>
/// <returns>The Id of the row created.</returns>
public async Task<int> InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName,
string columnList, string parameterList, IEnumerable<PropertyInfo> keyProperties, object entityToInsert)
{
......@@ -374,6 +422,18 @@ public partial class MySqlAdapter
public partial class PostgresAdapter
{
/// <summary>
/// Inserts <paramref name="entityToInsert"/> into the database, returning the Id of the row created.
/// </summary>
/// <param name="connection">The connection to use.</param>
/// <param name="transaction">The transaction to use.</param>
/// <param name="commandTimeout">The command timeout to use.</param>
/// <param name="tableName">The table to insert into.</param>
/// <param name="columnList">The columns to set with this insert.</param>
/// <param name="parameterList">The parameters to set for this insert.</param>
/// <param name="keyProperties">The key columns in this table.</param>
/// <param name="entityToInsert">The entity to insert.</param>
/// <returns>The Id of the row created.</returns>
public async Task<int> InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable<PropertyInfo> keyProperties, object entityToInsert)
{
var sb = new StringBuilder();
......@@ -414,6 +474,18 @@ public async Task<int> InsertAsync(IDbConnection connection, IDbTransaction tran
public partial class SQLiteAdapter
{
/// <summary>
/// Inserts <paramref name="entityToInsert"/> into the database, returning the Id of the row created.
/// </summary>
/// <param name="connection">The connection to use.</param>
/// <param name="transaction">The transaction to use.</param>
/// <param name="commandTimeout">The command timeout to use.</param>
/// <param name="tableName">The table to insert into.</param>
/// <param name="columnList">The columns to set with this insert.</param>
/// <param name="parameterList">The parameters to set for this insert.</param>
/// <param name="keyProperties">The key columns in this table.</param>
/// <param name="entityToInsert">The entity to insert.</param>
/// <returns>The Id of the row created.</returns>
public async Task<int> InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable<PropertyInfo> keyProperties, object entityToInsert)
{
var cmd = $"INSERT INTO {tableName} ({columnList}) VALUES ({parameterList}); SELECT last_insert_rowid() id";
......@@ -432,6 +504,18 @@ public async Task<int> InsertAsync(IDbConnection connection, IDbTransaction tran
public partial class FbAdapter
{
/// <summary>
/// Inserts <paramref name="entityToInsert"/> into the database, returning the Id of the row created.
/// </summary>
/// <param name="connection">The connection to use.</param>
/// <param name="transaction">The transaction to use.</param>
/// <param name="commandTimeout">The command timeout to use.</param>
/// <param name="tableName">The table to insert into.</param>
/// <param name="columnList">The columns to set with this insert.</param>
/// <param name="parameterList">The parameters to set for this insert.</param>
/// <param name="keyProperties">The key columns in this table.</param>
/// <param name="entityToInsert">The entity to insert.</param>
/// <returns>The Id of the row created.</returns>
public async Task<int> InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable<PropertyInfo> keyProperties, object entityToInsert)
{
var cmd = $"insert into {tableName} ({columnList}) values ({parameterList})";
......
This diff is collapsed.
......@@ -45,7 +45,7 @@ public Task<int> UpdateAsync(TId id, dynamic data)
builder.AppendLine(string.Join(",", paramNames.Where(n => n != "Id").Select(p => p + "= @" + p)));
builder.Append("where Id = @Id");
DynamicParameters parameters = new DynamicParameters(data);
var parameters = new DynamicParameters(data);
parameters.Add("Id", id);
return database.ExecuteAsync(builder.ToString(), parameters);
......@@ -62,61 +62,115 @@ public async Task<bool> DeleteAsync(TId id)
}
/// <summary>
/// Grab a record with a particular Id from the DB asynchronously
/// Asynchronously gets a record with a particular Id from the DB
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<T> GetAsync(TId id)
/// <param name="id">The primary key of the table to fetch.</param>
/// <returns>The record with the specified Id.</returns>
public Task<T> GetAsync(TId id)
{
return (await database.QueryAsync<T>("select * from " + TableName + " where Id = @id", new { id }).ConfigureAwait(false)).FirstOrDefault();
return database.QueryFirstOrDefaultAsync<T>("select * from " + TableName + " where Id = @id", new { id });
}
public virtual async Task<T> FirstAsync()
/// <summary>
/// Asynchronously gets the first row from this table (order determined by the database provider).
/// </summary>
/// <returns>Data from the first table row.</returns>
public virtual Task<T> FirstAsync()
{
return (await database.QueryAsync<T>("select top 1 * from " + TableName).ConfigureAwait(false)).FirstOrDefault();
return database.QueryFirstOrDefaultAsync<T>("select top 1 * from " + TableName);
}
/// <summary>
/// Asynchronously gets the all rows from this table.
/// </summary>
/// <returns>Data from all table rows.</returns>
public Task<IEnumerable<T>> AllAsync()
{
return database.QueryAsync<T>("select * from " + TableName);
}
}
/// <summary>
/// Asynchronously executes SQL against the current database.
/// </summary>
/// <param name="sql">The SQL to execute.</param>
/// <param name="param">The parameters to use.</param>
/// <returns>The number of rows affected.</returns>
public Task<int> ExecuteAsync(string sql, dynamic param = null)
{
return _connection.ExecuteAsync(sql, param as object, _transaction, this._commandTimeout);
}
/// <summary>
/// Asynchronously queries the current database.
/// </summary>
/// <typeparam name="T">The type to return.</typeparam>
/// <param name="sql">The SQL to execute.</param>
/// <param name="param">The parameters to use.</param>
/// <returns>An enumerable of <typeparamref name="T"/> for the rows fetched.</returns>
public Task<IEnumerable<T>> QueryAsync<T>(string sql, dynamic param = null)
{
return _connection.QueryAsync<T>(sql, param as object, _transaction, _commandTimeout);
}
/// <summary>
/// Asynchronously queries the current database for a single record.
/// </summary>
/// <typeparam name="T">The type to return.</typeparam>
/// <param name="sql">The SQL to execute.</param>
/// <param name="param">The parameters to use.</param>
/// <returns>An enumerable of <typeparamref name="T"/> for the rows fetched.</returns>
public Task<T> QueryFirstOrDefaultAsync<T>(string sql, dynamic param = null)
{
return _connection.QueryFirstOrDefaultAsync<T>(sql, param as object, _transaction, _commandTimeout);
}
/// <summary>
/// Perform an asynchronous multi mapping query with 2 input parameters
/// </summary>
public Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TReturn>(string sql, Func<TFirst, TSecond, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null)
{
return _connection.QueryAsync(sql, map, param as object, transaction, buffered, splitOn);
return _connection.QueryAsync(sql, map, param as object, transaction, buffered, splitOn, commandTimeout);
}
/// <summary>
/// Perform an asynchronous multi mapping query with 3 input parameters
/// </summary>
public Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TReturn>(string sql, Func<TFirst, TSecond, TThird, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null)
{
return _connection.QueryAsync(sql, map, param as object, transaction, buffered, splitOn);
return _connection.QueryAsync(sql, map, param as object, transaction, buffered, splitOn, commandTimeout);
}
/// <summary>
/// Perform an asynchronous multi mapping query with 4 input parameters
/// </summary>
public Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TFourth, TReturn>(string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null)
{
return _connection.QueryAsync(sql, map, param as object, transaction, buffered, splitOn);
return _connection.QueryAsync(sql, map, param as object, transaction, buffered, splitOn, commandTimeout);
}
/// <summary>
/// Perform an asynchronous multi mapping query with 5 input parameters
/// </summary>
public Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null)
{
return _connection.QueryAsync(sql, map, param as object, transaction, buffered, splitOn);
return _connection.QueryAsync(sql, map, param as object, transaction, buffered, splitOn, commandTimeout);
}
/// <summary>
/// Execute a query asynchronously using .NET 4.5 Task.
/// </summary>
/// <param name="sql">The SQL to execute.</param>
/// <param name="param">The parameters to use.</param>
/// <remarks>Note: each row can be accessed via "dynamic", or by casting to an IDictionary&lt;string,object&gt;</remarks>
public Task<IEnumerable<dynamic>> QueryAsync(string sql, dynamic param = null)
{
return _connection.QueryAsync(sql, param as object, _transaction);
}
/// <summary>
/// Execute a command that returns multiple result sets, and access each in turn
/// </summary>
public Task<SqlMapper.GridReader> QueryMultipleAsync(string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
{
return SqlMapper.QueryMultipleAsync(_connection, sql, param, transaction, commandTimeout, commandType);
......
This diff is collapsed.
......@@ -2,14 +2,24 @@
namespace Dapper
{
/// <summary>
/// Specifies whether a property should be ignored for database operations.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class IgnorePropertyAttribute : Attribute
{
/// <summary>
/// Specifies whether a property should be ignored for database operations.
/// </summary>
/// <param name="ignore">Whether to ignore this property.</param>
public IgnorePropertyAttribute(bool ignore)
{
Value = ignore;
}
/// <summary>
/// Whether to ignore this property.
/// </summary>
public bool Value { get; set; }
}
}
......@@ -6,32 +6,62 @@
namespace Dapper
{
/// <summary>
/// Snapshots an object for comparison later.
/// </summary>
public static class Snapshotter
{
/// <summary>
/// Starts the snapshot of an objec by making a copy of the current state.
/// </summary>
/// <typeparam name="T">The type of object to snapshot.</typeparam>
/// <param name="obj">The object to snapshot.</param>
/// <returns>The snapshot of the object.</returns>
public static Snapshot<T> Start<T>(T obj)
{
return new Snapshot<T>(obj);
}
/// <summary>
/// A snapshot of an object's state.
/// </summary>
/// <typeparam name="T"></typeparam>
public class Snapshot<T>
{
static Func<T, T> cloner;
static Func<T, T, List<Change>> differ;
T memberWiseClone;
T trackedObject;
private static Func<T, T> cloner;
private static Func<T, T, List<Change>> differ;
private readonly T memberWiseClone;
private readonly T trackedObject;
/// <summary>
/// Creates a snapshot from an object.
/// </summary>
/// <param name="original">The original object to snapshot.</param>
public Snapshot(T original)
{
memberWiseClone = Clone(original);
trackedObject = original;
}
/// <summary>
/// A holder for listing new values of changes fields and properties.
/// </summary>
public class Change
{
/// <summary>
/// The name of the field or property that changed.
/// </summary>
public string Name { get; set; }
/// <summary>
/// The new value of the field or property.
/// </summary>
public object NewValue { get; set; }
}
/// <summary>
/// Does a diff between the original object and the current state.
/// </summary>
/// <returns>The list of the fields changes in the object.</returns>
public DynamicParameters Diff()
{
return Diff(memberWiseClone, trackedObject);
......@@ -66,15 +96,12 @@ static List<PropertyInfo> RelevantProperties()
).ToList();
}
// This is used by IL, ReSharper is wrong.
// ReSharper disable UnusedMember.Local
private static bool AreEqual<U>(U first, U second)
{
if (first == null && second == null) return true;
if (first == null) return false;
if (EqualityComparer<U>.Default.Equals(first, default(U)) && EqualityComparer<U>.Default.Equals(second, default(U))) return true;
if (EqualityComparer<U>.Default.Equals(first, default(U))) return false;
return first.Equals(second);
}
// ReSharper restore UnusedMember.Local
private static Func<T, T, List<Change>> GenerateDiffer()
{
......@@ -114,7 +141,7 @@ private static bool AreEqual<U>(U first, U second)
il.Emit(OpCodes.Stloc_2);
// [original prop val, current prop val]
il.EmitCall(OpCodes.Call, typeof(Snapshot<T>).GetMethod("AreEqual", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(new Type[] { prop.PropertyType }), null);
il.EmitCall(OpCodes.Call, typeof(Snapshot<T>).GetMethod(nameof(AreEqual), BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(new Type[] { prop.PropertyType }), null);
// [result]
Label skip = il.DefineLabel();
......
......@@ -5,10 +5,23 @@
namespace Dapper
{
/// <summary>
/// A SQL Compact specific <see cref="Database{TDatabase}"/> implementation.
/// </summary>
/// <typeparam name="TDatabase">The type of database.</typeparam>
public abstract class SqlCompactDatabase<TDatabase> : Database<TDatabase> where TDatabase : Database<TDatabase>, new()
{
/// <summary>
/// A SQL Compact specific table, which handles the syntax correctly across operations.
/// </summary>
/// <typeparam name="T">The type in the table.</typeparam>
public class SqlCompactTable<T> : Table<T>
{
/// <summary>
/// Creates a table for a SQL Compact database.
/// </summary>
/// <param name="database"></param>
/// <param name="likelyTableName"></param>
public SqlCompactTable(Database<TDatabase> database, string likelyTableName)
: base(database, likelyTableName)
{
......@@ -38,9 +51,14 @@ public SqlCompactTable(Database<TDatabase> database, string likelyTableName)
}
}
/// <summary>
/// Initializes the databases.
/// </summary>
/// <param name="connection">The connection to use.</param>
/// <returns>The newly created database.</returns>
public static TDatabase Init(DbConnection connection)
{
TDatabase db = new TDatabase();
var db = new TDatabase();
db.InitDatabase(connection, 0);
return db;
}
......
......@@ -1112,7 +1112,7 @@ public PocoData(Type t)
{
var colattr = (Column)ColAttrs[0];
pc.ColumnName = colattr.Name;
if ((colattr as ResultColumn) != null)
if (colattr is ResultColumn)
pc.ResultColumn = true;
}
if (pc.ColumnName == null)
......
......@@ -24,12 +24,12 @@ public partial class DynamicParameters : SqlMapper.IDynamicParameters, SqlMapper
Dictionary<string, ParamInfo> parameters = new Dictionary<string, ParamInfo>();
List<object> templates;
object SqlMapper.IParameterLookup.this[string member]
object SqlMapper.IParameterLookup.this[string name]
{
get
{
ParamInfo param;
return parameters.TryGetValue(member, out param) ? param.Value : null;
return parameters.TryGetValue(name, out param) ? param.Value : null;
}
}
......
......@@ -39,9 +39,9 @@ private sealed class DeadValue
}
}
public bool TryGetValue(string name, out object value)
public bool TryGetValue(string key, out object value)
{
var index = table.IndexOfName(name);
var index = table.IndexOfName(key);
if (index < 0)
{ // doesn't exist
value = 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