diff --git a/AmalgamationTool/DynamORM.Amalgamation.cs b/AmalgamationTool/DynamORM.Amalgamation.cs index 97bb861..dce3fc5 100644 --- a/AmalgamationTool/DynamORM.Amalgamation.cs +++ b/AmalgamationTool/DynamORM.Amalgamation.cs @@ -1,4 +1,3 @@ - /* * DynamORM - Dynamic Object-Relational Mapping library. * Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com) @@ -3374,6 +3373,9 @@ namespace DynamORM /// Gets the value stored in object. public object Value { get; internal set; } + + /// Gets the last access time. + public long Ticks { get; internal set; } } private Dictionary _data = new Dictionary(); @@ -3405,6 +3407,7 @@ namespace DynamORM _lastProp.Name = binder.Name; _lastProp.Value = result; _lastProp.Type = result == null ? typeof(void) : result.GetType(); + _lastProp.Ticks = DateTime.Now.Ticks; return true; } @@ -3422,6 +3425,7 @@ namespace DynamORM _lastProp.Name = binder.Name; _lastProp.Value = value; _lastProp.Type = value == null ? typeof(void) : value.GetType(); + _lastProp.Ticks = DateTime.Now.Ticks; return true; } @@ -4180,7 +4184,7 @@ namespace DynamORM }); if (method != null) - ret = o.ToString().TryParseDefault(defaultValue, delegate(string v, out T r) + ret = o.ToString().TryParseDefault(defaultValue, delegate (string v, out T r) { r = defaultValue; return (bool)method.Invoke(null, new object[] { v, r }); @@ -4239,7 +4243,7 @@ namespace DynamORM else if (typeof(T) == typeof(object)) ret = (T)o; else if (method != null) - ret = o.ToString().TryParseDefault(defaultValue, delegate(string v, out T r) + ret = o.ToString().TryParseDefault(defaultValue, delegate (string v, out T r) { r = defaultValue; return (bool)method.Invoke(null, new object[] { v, r }); @@ -6482,7 +6486,8 @@ namespace DynamORM private DynamicConnection _con; private bool _singleTransaction; private Action _disposed; - private bool _operational = false; + private bool _isDisposed = false; + private bool _isOperational = false; /// Initializes a new instance of the class. /// Database connection manager. @@ -6503,24 +6508,39 @@ namespace DynamORM if (!_db.TransactionPool.ContainsKey(_con.Connection)) throw new InvalidOperationException("Can't create transaction using disposed connection."); else if (_singleTransaction && _db.TransactionPool[_con.Connection].Count > 0) - _operational = false; + { + _isOperational = false; + + if (_db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "BEGIN TRAN [NON OPERATIONAL]"); + } else { if (customParams != null) { MethodInfo mi = _con.Connection.GetType().GetMethods().Where(m => m.GetParameters().Count() == 1 && m.GetParameters().First().ParameterType == customParams.GetType()).FirstOrDefault(); if (mi != null) + { _db.TransactionPool[_con.Connection].Push((IDbTransaction)mi.Invoke(_con.Connection, new object[] { customParams, })); + + if (_db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "BEGIN TRAN [CUSTOM ARGS]"); + } else throw new MissingMethodException(string.Format("Method 'BeginTransaction' accepting parameter of type '{0}' in '{1}' not found.", customParams.GetType().FullName, _con.Connection.GetType().FullName)); } else + { _db.TransactionPool[_con.Connection] .Push(il.HasValue ? _con.Connection.BeginTransaction(il.Value) : _con.Connection.BeginTransaction()); + if (_db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "BEGIN TRAN"); + } + _db.PoolStamp = DateTime.Now.Ticks; - _operational = true; + _isOperational = true; } } } @@ -6530,7 +6550,7 @@ namespace DynamORM { lock (_db.SyncLock) { - if (_operational) + if (_isOperational) { Stack t = _db.TransactionPool.TryGetValue(_con.Connection); @@ -6542,10 +6562,15 @@ namespace DynamORM trans.Commit(); trans.Dispose(); + + if (_db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "COMMIT"); } - _operational = false; + _isOperational = false; } + else if (!_isDisposed && _db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "COMMIT [NON OPERATIONAL]"); } } @@ -6554,7 +6579,7 @@ namespace DynamORM { lock (_db.SyncLock) { - if (_operational) + if (_isOperational) { Stack t = _db.TransactionPool.TryGetValue(_con.Connection); @@ -6566,10 +6591,15 @@ namespace DynamORM trans.Rollback(); trans.Dispose(); + + if (_db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "ROLLBACK"); } - _operational = false; + _isOperational = false; } + else if (!_isDisposed && _db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "ROLLBACK [NON OPERATIONAL]"); } } @@ -6588,6 +6618,7 @@ namespace DynamORM /// freeing, releasing, or resetting unmanaged resources. public void Dispose() { + _isDisposed = true; Rollback(); if (_disposed != null) @@ -6595,7 +6626,7 @@ namespace DynamORM } /// Gets a value indicating whether this instance is disposed. - public bool IsDisposed { get { return !_operational; } } + public bool IsDisposed { get { return !_isOperational; } } #endregion IExtendedDisposable Members } @@ -13186,6 +13217,36 @@ namespace DynamORM } } + /// Exception thrown when mapper fails to set or get a property. + /// + public class DynamicMapperException : Exception + { + /// Initializes a new instance of the class. + public DynamicMapperException() + { + } + + /// Initializes a new instance of the class. + /// The message that describes the error. + public DynamicMapperException(string message) : base(message) + { + } + + /// Initializes a new instance of the class. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public DynamicMapperException(string message, Exception innerException) : base(message, innerException) + { + } + + /// Initializes a new instance of the class. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + protected DynamicMapperException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } + /// Dynamic property invoker. public class DynamicPropertyInvoker { @@ -13336,9 +13397,9 @@ namespace DynamORM } catch (Exception ex) { - throw new InvalidCastException( - string.Format("Error trying to convert value '{0}' of type '{1}' to value of type '{2}' in object of type '{3}'", - (val ?? string.Empty).ToString(), val.GetType(), Type.FullName, dest.GetType().FullName), + throw new DynamicMapperException( + string.Format("Error trying to convert and set value '{0}' of type '{1}' to type '{2}' in object of type '{3}'", + val == null ? string.Empty : val.ToString(), val.GetType(), Type.FullName, dest.GetType().FullName), ex); } } diff --git a/DynamORM.Tests/DynamORM.Tests.csproj b/DynamORM.Tests/DynamORM.Tests.csproj index 6ee31c5..a90cc01 100644 --- a/DynamORM.Tests/DynamORM.Tests.csproj +++ b/DynamORM.Tests/DynamORM.Tests.csproj @@ -22,6 +22,7 @@ OnBuildSuccess + PackageReference Full @@ -36,6 +37,7 @@ Auto False AnyCPU + PackageReference PdbOnly @@ -49,6 +51,7 @@ Auto False AnyCPU + PackageReference 4194304 @@ -56,12 +59,15 @@ False Auto False + PackageReference False + PackageReference False + PackageReference @@ -112,13 +118,13 @@ - 1.2.1 + 2.0.0-beta4 - 1.2.1 + 2.0.0-beta4 - 1.0.109.1 + 1.0.111 diff --git a/DynamORM/DynamORM.csproj b/DynamORM/DynamORM.csproj index e4773c5..5757d10 100644 --- a/DynamORM/DynamORM.csproj +++ b/DynamORM/DynamORM.csproj @@ -101,6 +101,7 @@ + diff --git a/DynamORM/DynamicExpando.cs b/DynamORM/DynamicExpando.cs index 7cca1bb..bc110fc 100644 --- a/DynamORM/DynamicExpando.cs +++ b/DynamORM/DynamicExpando.cs @@ -63,6 +63,9 @@ namespace DynamORM /// Gets the value stored in object. public object Value { get; internal set; } + + /// Gets the last access time. + public long Ticks { get; internal set; } } private Dictionary _data = new Dictionary(); @@ -94,6 +97,7 @@ namespace DynamORM _lastProp.Name = binder.Name; _lastProp.Value = result; _lastProp.Type = result == null ? typeof(void) : result.GetType(); + _lastProp.Ticks = DateTime.Now.Ticks; return true; } @@ -111,6 +115,7 @@ namespace DynamORM _lastProp.Name = binder.Name; _lastProp.Value = value; _lastProp.Type = value == null ? typeof(void) : value.GetType(); + _lastProp.Ticks = DateTime.Now.Ticks; return true; } diff --git a/DynamORM/DynamicTransaction.cs b/DynamORM/DynamicTransaction.cs index 6d15e7a..28df70a 100644 --- a/DynamORM/DynamicTransaction.cs +++ b/DynamORM/DynamicTransaction.cs @@ -42,7 +42,8 @@ namespace DynamORM private DynamicConnection _con; private bool _singleTransaction; private Action _disposed; - private bool _operational = false; + private bool _isDisposed = false; + private bool _isOperational = false; /// Initializes a new instance of the class. /// Database connection manager. @@ -63,24 +64,39 @@ namespace DynamORM if (!_db.TransactionPool.ContainsKey(_con.Connection)) throw new InvalidOperationException("Can't create transaction using disposed connection."); else if (_singleTransaction && _db.TransactionPool[_con.Connection].Count > 0) - _operational = false; + { + _isOperational = false; + + if (_db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "BEGIN TRAN [NON OPERATIONAL]"); + } else { if (customParams != null) { MethodInfo mi = _con.Connection.GetType().GetMethods().Where(m => m.GetParameters().Count() == 1 && m.GetParameters().First().ParameterType == customParams.GetType()).FirstOrDefault(); if (mi != null) + { _db.TransactionPool[_con.Connection].Push((IDbTransaction)mi.Invoke(_con.Connection, new object[] { customParams, })); + + if (_db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "BEGIN TRAN [CUSTOM ARGS]"); + } else throw new MissingMethodException(string.Format("Method 'BeginTransaction' accepting parameter of type '{0}' in '{1}' not found.", customParams.GetType().FullName, _con.Connection.GetType().FullName)); } else + { _db.TransactionPool[_con.Connection] .Push(il.HasValue ? _con.Connection.BeginTransaction(il.Value) : _con.Connection.BeginTransaction()); + if (_db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "BEGIN TRAN"); + } + _db.PoolStamp = DateTime.Now.Ticks; - _operational = true; + _isOperational = true; } } } @@ -90,7 +106,7 @@ namespace DynamORM { lock (_db.SyncLock) { - if (_operational) + if (_isOperational) { Stack t = _db.TransactionPool.TryGetValue(_con.Connection); @@ -102,10 +118,15 @@ namespace DynamORM trans.Commit(); trans.Dispose(); + + if (_db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "COMMIT"); } - _operational = false; + _isOperational = false; } + else if (!_isDisposed && _db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "COMMIT [NON OPERATIONAL]"); } } @@ -114,7 +135,7 @@ namespace DynamORM { lock (_db.SyncLock) { - if (_operational) + if (_isOperational) { Stack t = _db.TransactionPool.TryGetValue(_con.Connection); @@ -126,10 +147,15 @@ namespace DynamORM trans.Rollback(); trans.Dispose(); + + if (_db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "ROLLBACK"); } - _operational = false; + _isOperational = false; } + else if (!_isDisposed && _db.DumpCommands && _db.DumpCommandDelegate != null) + _db.DumpCommandDelegate(null, "ROLLBACK [NON OPERATIONAL]"); } } @@ -148,6 +174,7 @@ namespace DynamORM /// freeing, releasing, or resetting unmanaged resources. public void Dispose() { + _isDisposed = true; Rollback(); if (_disposed != null) @@ -155,7 +182,7 @@ namespace DynamORM } /// Gets a value indicating whether this instance is disposed. - public bool IsDisposed { get { return !_operational; } } + public bool IsDisposed { get { return !_isOperational; } } #endregion IExtendedDisposable Members } diff --git a/DynamORM/Mapper/DynamicMapperException.cs b/DynamORM/Mapper/DynamicMapperException.cs new file mode 100644 index 0000000..27ec2b8 --- /dev/null +++ b/DynamORM/Mapper/DynamicMapperException.cs @@ -0,0 +1,35 @@ +using System; +using System.Runtime.Serialization; + +namespace DynamORM.Mapper +{ + /// Exception thrown when mapper fails to set or get a property. + /// + public class DynamicMapperException : Exception + { + /// Initializes a new instance of the class. + public DynamicMapperException() + { + } + + /// Initializes a new instance of the class. + /// The message that describes the error. + public DynamicMapperException(string message) : base(message) + { + } + + /// Initializes a new instance of the class. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public DynamicMapperException(string message, Exception innerException) : base(message, innerException) + { + } + + /// Initializes a new instance of the class. + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + protected DynamicMapperException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/DynamORM/Mapper/DynamicPropertyInvoker.cs b/DynamORM/Mapper/DynamicPropertyInvoker.cs index 2a409b4..6e84334 100644 --- a/DynamORM/Mapper/DynamicPropertyInvoker.cs +++ b/DynamORM/Mapper/DynamicPropertyInvoker.cs @@ -186,9 +186,9 @@ namespace DynamORM.Mapper } catch (Exception ex) { - throw new InvalidCastException( - string.Format("Error trying to convert value '{0}' of type '{1}' to value of type '{2}' in object of type '{3}'", - (val ?? string.Empty).ToString(), val.GetType(), Type.FullName, dest.GetType().FullName), + throw new DynamicMapperException( + string.Format("Error trying to convert and set value '{0}' of type '{1}' to type '{2}' in object of type '{3}'", + val == null ? string.Empty : val.ToString(), val.GetType(), Type.FullName, dest.GetType().FullName), ex); } }