diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/FetchResponse.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/FetchResponse.cs index 2a13ba0a..0e293540 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/FetchResponse.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/FetchResponse.cs @@ -23,35 +23,13 @@ namespace FirebirdSql.Data.Client.Managed { internal class FetchResponse : IResponse { - #region Fields - - private int _status; - private int _count; - - #endregion - - #region Properties - - public int Status - { - get { return _status; } - } - - public int Count - { - get { return _count; } - } - - #endregion - - #region Constructors + public int Status { get; } + public int Count { get; } public FetchResponse(int status, int count) { - _status = status; - _count = count; + Status = status; + Count = count; } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/GdsConnection.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/GdsConnection.cs index bf1d6a3c..94be7a6e 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/GdsConnection.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/GdsConnection.cs @@ -30,8 +30,8 @@ namespace FirebirdSql.Data.Client.Managed { internal class GdsConnection { - const ulong KeepAliveTime = 1800000; //30min - const ulong KeepAliveInterval = 1800000; //30min + const ulong KeepAliveTime = 1800000; // 30min + const ulong KeepAliveInterval = 1800000; // 30min #region Fields @@ -271,7 +271,7 @@ private IPAddress GetIPAddress(string dataSource, AddressFamily addressFamily) IPAddress[] addresses = Dns.GetHostEntry(dataSource).AddressList; #endif - // Try to avoid problems with IPV6 addresses + // try to avoid problems with IPv6 addresses foreach (IPAddress address in addresses) { if (address.AddressFamily == addressFamily) diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/GenericResponse.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/GenericResponse.cs index 9cae68d6..352f6afc 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/GenericResponse.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/GenericResponse.cs @@ -23,49 +23,17 @@ namespace FirebirdSql.Data.Client.Managed { internal sealed class GenericResponse : IResponse { - #region Fields - - private int _objectHandle; - private long _blobId; - private byte[] _data; - private IscException _exception; - - #endregion - - #region Properties - - public int ObjectHandle - { - get { return _objectHandle; } - } - - public long BlobId - { - get { return _blobId; } - } - - public byte[] Data - { - get { return _data; } - } - - public IscException Exception - { - get { return _exception; } - } - - #endregion - - #region Constructors + public int ObjectHandle { get; } + public long BlobId { get; } + public byte[] Data { get; } + public IscException Exception { get; } public GenericResponse(int objectHandle, long blobId, byte[] data, IscException exception) { - _objectHandle = objectHandle; - _blobId = blobId; - _data = data; - _exception = exception; + ObjectHandle = objectHandle; + BlobId = blobId; + Data = data; + Exception = exception; } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/SqlResponse.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/SqlResponse.cs index 2888d75d..bef0b566 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/SqlResponse.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/SqlResponse.cs @@ -23,28 +23,11 @@ namespace FirebirdSql.Data.Client.Managed { internal class SqlResponse : IResponse { - #region Fields - - private int _count; - - #endregion - - #region Properties - - public int Count - { - get { return _count; } - } - - #endregion - - #region Constructors + public int Count { get; } public SqlResponse(int count) { - _count = count; + Count = count; } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/SspiHelper.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/SspiHelper.cs index b3d7ddae..68ba6ee2 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/SspiHelper.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/SspiHelper.cs @@ -88,19 +88,15 @@ public SecBuffer(int bufferSize) } public SecBuffer(byte[] secBufferBytes) + : this(secBufferBytes.Length) { - cbBuffer = secBufferBytes.Length; - bufferType = (int)SecBufferType.SECBUFFER_TOKEN; - pvBuffer = Marshal.AllocHGlobal(cbBuffer); Marshal.Copy(secBufferBytes, 0, pvBuffer, cbBuffer); } public SecBuffer(byte[] secBufferBytes, SecBufferType bufferType) + : this(secBufferBytes) { - cbBuffer = secBufferBytes.Length; this.bufferType = (int)bufferType; - pvBuffer = Marshal.AllocHGlobal(cbBuffer); - Marshal.Copy(secBufferBytes, 0, pvBuffer, cbBuffer); } public void Dispose() @@ -129,7 +125,7 @@ private struct SecBufferDesc : IDisposable { public int ulVersion; public int cBuffers; - public IntPtr pBuffers; //Point to SecBuffer + public IntPtr pBuffers; public SecBufferDesc(int bufferSize) { @@ -272,9 +268,9 @@ public byte[] GetSecBufferBytes() #region Private members - private SecHandle _clientCredentials = new SecHandle(); - private SecHandle _clientContext = new SecHandle(); - private bool _disposed = false; + private SecHandle _clientCredentials; + private SecHandle _clientContext; + private bool _disposed; private string _securPackage; private string _remotePrincipal; @@ -309,10 +305,12 @@ public SspiHelper(string securityPackage, string remotePrincipal) { _securPackage = securityPackage; _remotePrincipal = remotePrincipal; + _clientCredentials = new SecHandle(); SecInteger expiry = new SecInteger(); - if (AcquireCredentialsHandle(null, securityPackage, SECPKG_CRED_OUTBOUND, - IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero, - out _clientCredentials, out expiry) != SEC_E_OK) + int resCode = AcquireCredentialsHandle(null, securityPackage, SECPKG_CRED_OUTBOUND, + IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero, + out _clientCredentials, out expiry); + if (resCode != SEC_E_OK) throw new Exception($"{nameof(AcquireCredentialsHandle)} failed"); } @@ -326,10 +324,10 @@ public SspiHelper(string securityPackage, string remotePrincipal) /// Client authentication data to be sent to server public byte[] InitializeClientSecurity() { - if (_disposed) - throw new ObjectDisposedException(nameof(SspiHelper)); + EnsureDisposed(); CloseClientContext(); - SecInteger expiry = new SecInteger(0); + _clientContext = new SecHandle(); + SecInteger expiry = new SecInteger(); uint contextAttributes; SecBufferDesc clientTokenBuf = new SecBufferDesc(MAX_TOKEN_SIZE); try @@ -337,16 +335,16 @@ public byte[] InitializeClientSecurity() int resCode = InitializeSecurityContext( ref _clientCredentials, IntPtr.Zero, - _remotePrincipal,// null string pszTargetName, + _remotePrincipal, STANDARD_CONTEXT_ATTRIBUTES, - 0,//int Reserved1, - SECURITY_NATIVE_DREP,//int TargetDataRep - IntPtr.Zero, //Always zero first time around... - 0, //int Reserved2, - out _clientContext, //pHandle CtxtHandle = SecHandle - ref clientTokenBuf,//ref SecBufferDesc pOutput, //PSecBufferDesc - out contextAttributes,//ref int pfContextAttr, - out expiry); //ref IntPtr ptsExpiry ); //PTimeStamp + 0, + SECURITY_NATIVE_DREP, + IntPtr.Zero, + 0, + out _clientContext, + ref clientTokenBuf, + out contextAttributes, + out expiry); if (resCode != SEC_E_OK && resCode != SEC_I_CONTINUE_NEEDED) throw new Exception($"{nameof(InitializeSecurityContext)} failed"); return clientTokenBuf.GetSecBufferBytes(); @@ -366,8 +364,7 @@ public byte[] InitializeClientSecurity() /// Client authentication data to be sent to server public byte[] GetClientSecurity(byte[] serverToken) { - if (_disposed) - throw new ObjectDisposedException(nameof(SspiHelper)); + EnsureDisposed(); if (_clientContext.IsInvalid) throw new InvalidOperationException($"{nameof(InitializeClientSecurity)} not called"); SecInteger expiry = new SecInteger(); @@ -381,16 +378,16 @@ public byte[] GetClientSecurity(byte[] serverToken) int resCode = InitializeSecurityContext( ref _clientCredentials, ref _clientContext, - _remotePrincipal,// null string pszTargetName, + _remotePrincipal, STANDARD_CONTEXT_ATTRIBUTES, - 0,//int Reserved1, - SECURITY_NATIVE_DREP,//int TargetDataRep - ref serverTokenBuf, // server token must be ref because it is struct - 0, //int Reserved2, - out _clientContext, //pHandle CtxtHandle = SecHandle - ref clientTokenBuf,//ref SecBufferDesc pOutput, //PSecBufferDesc - out contextAttributes,//ref int pfContextAttr, - out expiry); //ref IntPtr ptsExpiry ); //PTimeStamp + 0, + SECURITY_NATIVE_DREP, + ref serverTokenBuf, + 0, + out _clientContext, + ref clientTokenBuf, + out contextAttributes, + out expiry); if (resCode != SEC_E_OK && resCode != SEC_I_CONTINUE_NEEDED) throw new Exception($"{nameof(InitializeSecurityContext)} failed"); return clientTokenBuf.GetSecBufferBytes(); @@ -431,37 +428,30 @@ public void Dispose() private void Dispose(bool disposing) { - lock (this) + if (!_disposed) { - if (!_disposed) - { - CloseClientContext(); - CloseClientCredentials(); - - if (disposing) - { } - - _disposed = true; - } + _disposed = true; + CloseClientContext(); + CloseClientCredentials(); } } private void CloseClientContext() { if (!_clientContext.IsInvalid) - { DeleteSecurityContext(ref _clientContext); - _clientContext = new SecHandle(); - } } private void CloseClientCredentials() { if (!_clientCredentials.IsInvalid) - { FreeCredentialsHandle(ref _clientCredentials); - _clientCredentials = new SecHandle(); - } + } + + private void EnsureDisposed() + { + if (_disposed) + throw new ObjectDisposedException(nameof(SspiHelper)); } #endregion diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsArray.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsArray.cs index b3802de9..97c7715f 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsArray.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsArray.cs @@ -33,6 +33,8 @@ namespace FirebirdSql.Data.Client.Managed.Version10 { internal sealed class GdsArray : ArrayBase { + const long ArrayHandle = 0; + #region Fields private long _handle; @@ -79,12 +81,12 @@ public GdsArray(IDatabase db, TransactionBase transaction, long handle, string t { if (!(db is GdsDatabase)) { - throw new ArgumentException("Specified argument is not of GdsDatabase type."); + throw new ArgumentException($"Specified argument is not of {nameof(GdsDatabase)} type."); } if (!(transaction is GdsTransaction)) { - throw new ArgumentException("Specified argument is not of GdsTransaction type."); + throw new ArgumentException($"Specified argument is not of {nameof(GdsTransaction)} type."); } _database = (GdsDatabase)db; @@ -100,57 +102,51 @@ public GdsArray(IDatabase db, TransactionBase transaction, long handle, string t public override byte[] GetSlice(int sliceLength) { - lock (_database.SyncObject) + try { - try - { - byte[] sdl = GenerateSDL(Descriptor); - - _database.XdrStream.Write(IscCodes.op_get_slice); // Op code - _database.XdrStream.Write(_transaction.Handle);// Transaction - _database.XdrStream.Write(_handle); // Array id - _database.XdrStream.Write(sliceLength); // Slice length - _database.XdrStream.WriteBuffer(sdl); // Slice descriptor language - _database.XdrStream.Write(string.Empty); // Slice parameters - _database.XdrStream.Write(0); // Slice proper - _database.XdrStream.Flush(); - - return ReceiveSliceResponse(Descriptor); - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + byte[] sdl = GenerateSDL(Descriptor); + + _database.XdrStream.Write(IscCodes.op_get_slice); + _database.XdrStream.Write(_transaction.Handle); + _database.XdrStream.Write(_handle); + _database.XdrStream.Write(sliceLength); + _database.XdrStream.WriteBuffer(sdl); + _database.XdrStream.Write(string.Empty); + _database.XdrStream.Write(0); + _database.XdrStream.Flush(); + + return ReceiveSliceResponse(Descriptor); + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } - public override void PutSlice(System.Array sourceArray, int sliceLength) + public override void PutSlice(Array sourceArray, int sliceLength) { - lock (_database.SyncObject) + try { - try - { - byte[] sdl = GenerateSDL(Descriptor); - byte[] slice = EncodeSliceArray(sourceArray); - - _database.XdrStream.Write(IscCodes.op_put_slice); // Op code - _database.XdrStream.Write(_transaction.Handle); // Transaction - _database.XdrStream.Write((long)0); // Array Handle - _database.XdrStream.Write(sliceLength); // Slice length - _database.XdrStream.WriteBuffer(sdl); // Slice descriptor language - _database.XdrStream.Write(string.Empty); // Slice parameters - _database.XdrStream.Write(sliceLength); // Slice length - _database.XdrStream.Write(slice, 0, slice.Length); // Slice proper - _database.XdrStream.Flush(); - - GenericResponse response = _database.ReadGenericResponse(); - - _handle = response.BlobId; - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + byte[] sdl = GenerateSDL(Descriptor); + byte[] slice = EncodeSliceArray(sourceArray); + + _database.XdrStream.Write(IscCodes.op_put_slice); + _database.XdrStream.Write(_transaction.Handle); + _database.XdrStream.Write(ArrayHandle); + _database.XdrStream.Write(sliceLength); + _database.XdrStream.WriteBuffer(sdl); + _database.XdrStream.Write(string.Empty); + _database.XdrStream.Write(sliceLength); + _database.XdrStream.Write(slice, 0, slice.Length); + _database.XdrStream.Flush(); + + GenericResponse response = _database.ReadGenericResponse(); + + _handle = response.BlobId; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } @@ -158,7 +154,7 @@ public override void PutSlice(System.Array sourceArray, int sliceLength) #region Protected Methods - protected override System.Array DecodeSlice(byte[] slice) + protected override Array DecodeSlice(byte[] slice) { DbDataType dbType = DbDataType.Array; Array sliceData = null; @@ -169,7 +165,6 @@ protected override System.Array DecodeSlice(byte[] slice) int type = 0; int index = 0; - // Get upper and lower bounds of each dimension for (int i = 0; i < Descriptor.Dimensions; i++) { lowerBounds[i] = Descriptor.Bounds[i].LowerBound; @@ -181,15 +176,12 @@ protected override System.Array DecodeSlice(byte[] slice) } } - // Create arrays sliceData = Array.CreateInstance(systemType, lengths, lowerBounds); tempData = Array.CreateInstance(systemType, sliceData.Length); - // Infer Firebird and Db datatypes type = TypeHelper.GetSqlTypeFromBlrType(Descriptor.DataType); dbType = TypeHelper.GetDbDataTypeFromBlrType(Descriptor.DataType, 0, Descriptor.Scale); - // Decode slice data using (XdrStream xdr = new XdrStream(slice, _database.Charset)) { while (xdr.Position < xdr.Length) @@ -275,7 +267,6 @@ private byte[] ReceiveSliceResponse(ArrayDesc desc) if (operation == IscCodes.op_slice) { - // Read slice length bool isVariying = false; int elements = 0; int length = _database.XdrStream.ReadInt32(); @@ -481,9 +472,7 @@ private byte[] GenerateSDL(ArrayDesc desc) StuffLiteral(sdl, tail.UpperBound); } - Stuff( - sdl, 5, IscCodes.isc_sdl_element, - 1, IscCodes.isc_sdl_scalar, 0, dimensions); + Stuff(sdl, 5, IscCodes.isc_sdl_element, 1, IscCodes.isc_sdl_scalar, 0, dimensions); for (n = 0; n < dimensions; n++) { diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsBlob.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsBlob.cs index 8669c103..89249b8c 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsBlob.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsBlob.cs @@ -25,6 +25,9 @@ namespace FirebirdSql.Data.Client.Managed.Version10 { internal sealed class GdsBlob : BlobBase { + const int DataSegment = 0; + const int SeekMode = 0; + #region Fields private GdsDatabase _database; @@ -58,11 +61,11 @@ public GdsBlob(IDatabase db, TransactionBase transaction, long blobId) { if (!(db is GdsDatabase)) { - throw new ArgumentException("Specified argument is not of GdsDatabase type."); + throw new ArgumentException($"Specified argument is not of {nameof(GdsDatabase)} type."); } if (!(transaction is GdsTransaction)) { - throw new ArgumentException("Specified argument is not of GdsTransaction type."); + throw new ArgumentException($"Specified argument is not of {nameof(GdsTransaction)} type."); } _database = (GdsDatabase)db; @@ -105,102 +108,93 @@ protected override byte[] GetSegment() { int requested = SegmentSize; - lock (_database.SyncObject) + try { - try + _database.XdrStream.Write(IscCodes.op_get_segment); + _database.XdrStream.Write(_blobHandle); + _database.XdrStream.Write((requested + 2 < short.MaxValue) ? requested + 2 : short.MaxValue); + _database.XdrStream.Write(DataSegment); + _database.XdrStream.Flush(); + + GenericResponse response = _database.ReadGenericResponse(); + + RblRemoveValue(IscCodes.RBL_segment); + if (response.ObjectHandle == 1) + { + RblAddValue(IscCodes.RBL_segment); + } + else if (response.ObjectHandle == 2) { - _database.XdrStream.Write(IscCodes.op_get_segment); - _database.XdrStream.Write(_blobHandle); - _database.XdrStream.Write((requested + 2 < short.MaxValue) ? requested + 2 : short.MaxValue); - _database.XdrStream.Write(0); // Data segment - _database.XdrStream.Flush(); - - GenericResponse response = _database.ReadGenericResponse(); - - RblRemoveValue(IscCodes.RBL_segment); - if (response.ObjectHandle == 1) - { - RblAddValue(IscCodes.RBL_segment); - } - else if (response.ObjectHandle == 2) - { - RblAddValue(IscCodes.RBL_eof_pending); - } - - byte[] buffer = response.Data; - - if (buffer.Length == 0) - { - // previous segment was last, this has no data - return buffer; - } - - int len = 0; - int srcpos = 0; - int destpos = 0; - - while (srcpos < buffer.Length) - { - len = IscHelper.VaxInteger(buffer, srcpos, 2); - srcpos += 2; - - Buffer.BlockCopy(buffer, srcpos, buffer, destpos, len); - srcpos += len; - destpos += len; - } - - byte[] result = new byte[destpos]; - Buffer.BlockCopy(buffer, 0, result, 0, destpos); - - return result; + RblAddValue(IscCodes.RBL_eof_pending); } - catch (IOException ex) + + byte[] buffer = response.Data; + + if (buffer.Length == 0) { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); + // previous segment was last, this has no data + return buffer; } + + int len = 0; + int srcpos = 0; + int destpos = 0; + + while (srcpos < buffer.Length) + { + len = IscHelper.VaxInteger(buffer, srcpos, 2); + srcpos += 2; + + Buffer.BlockCopy(buffer, srcpos, buffer, destpos, len); + srcpos += len; + destpos += len; + } + + byte[] result = new byte[destpos]; + Buffer.BlockCopy(buffer, 0, result, 0, destpos); + + return result; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } protected override void PutSegment(byte[] buffer) { - lock (_database.SyncObject) + try { - try - { - _database.XdrStream.Write(IscCodes.op_batch_segments); - _database.XdrStream.Write(_blobHandle); - _database.XdrStream.WriteBlobBuffer(buffer); - _database.XdrStream.Flush(); + _database.XdrStream.Write(IscCodes.op_batch_segments); + _database.XdrStream.Write(_blobHandle); + _database.XdrStream.WriteBlobBuffer(buffer); + _database.XdrStream.Flush(); - _database.ReadResponse(); - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + _database.ReadResponse(); + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } protected override void Seek(int position) { - lock (_database.SyncObject) + try { - try - { - _database.XdrStream.Write(IscCodes.op_seek_blob); - _database.XdrStream.Write(_blobHandle); - _database.XdrStream.Write(0); // Seek mode - _database.XdrStream.Write(position); // Seek offset - _database.XdrStream.Flush(); + _database.XdrStream.Write(IscCodes.op_seek_blob); + _database.XdrStream.Write(_blobHandle); + _database.XdrStream.Write(SeekMode); + _database.XdrStream.Write(position); + _database.XdrStream.Flush(); - GenericResponse response = (GenericResponse)_database.ReadResponse(); + GenericResponse response = (GenericResponse)_database.ReadResponse(); - _position = response.ObjectHandle; - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_network_error, ex); - } + _position = response.ObjectHandle; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_network_error, ex); } } @@ -225,28 +219,25 @@ protected override void Cancel() private void CreateOrOpen(int op, BlobParameterBuffer bpb) { - lock (_database.SyncObject) + try { - try - { - _database.XdrStream.Write(op); - if (bpb != null) - { - _database.XdrStream.WriteTyped(IscCodes.isc_bpb_version1, bpb.ToArray()); - } - _database.XdrStream.Write(_transaction.Handle); - _database.XdrStream.Write(_blobId); - _database.XdrStream.Flush(); - - GenericResponse response = _database.ReadGenericResponse(); - - _blobId = response.BlobId; - _blobHandle = response.ObjectHandle; - } - catch (IOException ex) + _database.XdrStream.Write(op); + if (bpb != null) { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); + _database.XdrStream.WriteTyped(IscCodes.isc_bpb_version1, bpb.ToArray()); } + _database.XdrStream.Write(_transaction.Handle); + _database.XdrStream.Write(_blobId); + _database.XdrStream.Flush(); + + GenericResponse response = _database.ReadGenericResponse(); + + _blobId = response.BlobId; + _blobHandle = response.ObjectHandle; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsDatabase.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsDatabase.cs index ab188fb7..c7926603 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsDatabase.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsDatabase.cs @@ -33,6 +33,12 @@ namespace FirebirdSql.Data.Client.Managed.Version10 { internal class GdsDatabase : IDatabase { + const int DatabaseObjectId = 0; + const int PartnerIdentification = 0; + const int AddressOfAstRoutine = 0; + const int ArgumentToAstRoutine = 0; + internal const int Incarnation = 0; + #region Callbacks public WarningMessageCallback WarningMessage @@ -58,7 +64,6 @@ public WarningMessageCallback WarningMessage private int _eventsId; private bool _disposed; private XdrStream _xdrStream; - private object _syncObject; #endregion @@ -110,19 +115,6 @@ public XdrStream XdrStream get { return _xdrStream; } } - public object SyncObject - { - get - { - if (_syncObject == null) - { - Interlocked.CompareExchange(ref _syncObject, new object(), null); - } - - return _syncObject; - } - } - public string Password { get { return _connection.Password; } @@ -149,54 +141,24 @@ public GdsDatabase(GdsConnection connection) #endregion - #region Finalizer - - ~GdsDatabase() - { - Dispose(false); - } - - #endregion - #region IDisposable methods public void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - lock (SyncObject) + if (!_disposed) { - if (!_disposed) - { - try - { - Detach(); - } - catch - { } - finally - { - if (disposing) - { - _connection = null; - _charset = null; - _eventManager = null; - _serverVersion = null; - _dialect = 0; - _eventsId = 0; - _handle = 0; - _packetSize = 0; - _warningMessage = null; - _transactionCount = 0; - } - - _disposed = true; - } - } + _disposed = true; + Detach(); + _connection = null; + _charset = null; + _eventManager = null; + _serverVersion = null; + _dialect = 0; + _eventsId = 0; + _handle = 0; + _packetSize = 0; + _warningMessage = null; + _transactionCount = 0; } } @@ -206,27 +168,24 @@ private void Dispose(bool disposing) public virtual void Attach(DatabaseParameterBuffer dpb, string dataSource, int port, string database) { - lock (SyncObject) + try { - try - { - SendAttachToBuffer(dpb, database); - XdrStream.Flush(); - ProcessAttachResponse(ReadGenericResponse()); - } - catch (IscException) - { - SafelyDetach(); - throw; - } - catch (IOException ex) - { - SafelyDetach(); - throw IscException.ForErrorCode(IscCodes.isc_net_write_err, ex); - } - - AfterAttachActions(); + SendAttachToBuffer(dpb, database); + XdrStream.Flush(); + ProcessAttachResponse(ReadGenericResponse()); + } + catch (IscException) + { + SafelyDetach(); + throw; + } + catch (IOException ex) + { + SafelyDetach(); + throw IscException.ForErrorCode(IscCodes.isc_net_write_err, ex); } + + AfterAttachActions(); } protected virtual void SendAttachToBuffer(DatabaseParameterBuffer dpb, string database) @@ -258,56 +217,49 @@ public virtual void AttachWithTrustedAuth(DatabaseParameterBuffer dpb, string da public virtual void Detach() { - lock (SyncObject) + if (TransactionCount > 0) { - if (TransactionCount > 0) - { - throw IscException.ForErrorCodeIntParam(IscCodes.isc_open_trans, TransactionCount); - } + throw IscException.ForErrorCodeIntParam(IscCodes.isc_open_trans, TransactionCount); + } - try + try + { + if (_handle != 0) { - if (_handle != 0) - { - XdrStream.Write(IscCodes.op_detach); - XdrStream.Write(_handle); - } - XdrStream.Write(IscCodes.op_disconnect); - XdrStream.Flush(); + XdrStream.Write(IscCodes.op_detach); + XdrStream.Write(_handle); + } + XdrStream.Write(IscCodes.op_disconnect); + XdrStream.Flush(); - // Close the Event Manager - CloseEventManager(); + CloseEventManager(); - // Disconnect - CloseConnection(); + CloseConnection(); #warning Here - // Close Input and Output streams - _xdrStream?.Dispose(); - - // Clear members - _transactionCount = 0; - _handle = 0; - _dialect = 0; - _packetSize = 0; - _xdrStream = null; - _charset = null; - _connection = null; - _serverVersion = null; + _xdrStream?.Dispose(); + + _transactionCount = 0; + _handle = 0; + _dialect = 0; + _packetSize = 0; + _xdrStream = null; + _charset = null; + _connection = null; + _serverVersion = null; + } + catch (IOException ex) + { + try + { + CloseConnection(); } - catch (IOException ex) + catch (IOException ex2) { - try - { - CloseConnection(); - } - catch (IOException ex2) - { - throw IscException.ForErrorCode(IscCodes.isc_network_error, ex2); - } - - throw IscException.ForErrorCode(IscCodes.isc_network_error, ex); + throw IscException.ForErrorCode(IscCodes.isc_network_error, ex2); } + + throw IscException.ForErrorCode(IscCodes.isc_network_error, ex); } } @@ -327,42 +279,38 @@ protected void SafelyDetach() public virtual void CreateDatabase(DatabaseParameterBuffer dpb, string dataSource, int port, string database) { - lock (SyncObject) + try { + SendCreateToBuffer(dpb, database); + XdrStream.Flush(); + try { - SendCreateToBuffer(dpb, database); - XdrStream.Flush(); + ProcessCreateResponse(ReadGenericResponse()); + Detach(); + } + catch (IscException) + { try { - ProcessCreateResponse(ReadGenericResponse()); - - Detach(); - } - catch (IscException) - { - try - { - CloseConnection(); - } - catch - { } - throw; + CloseConnection(); } + catch + { } + throw; } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_write_err, ex); - } + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_write_err, ex); } } protected virtual void SendCreateToBuffer(DatabaseParameterBuffer dpb, string database) { XdrStream.Write(IscCodes.op_create); -#warning Some constant for default database object ID - XdrStream.Write(0); + XdrStream.Write(DatabaseObjectId); if (!string.IsNullOrEmpty(Password)) { dpb.Append(IscCodes.isc_dpb_password, Password); @@ -378,31 +326,28 @@ protected void ProcessCreateResponse(GenericResponse response) public virtual void DropDatabase() { - lock (SyncObject) + try { - try - { - XdrStream.Write(IscCodes.op_drop_database); - XdrStream.Write(_handle); - XdrStream.Flush(); + XdrStream.Write(IscCodes.op_drop_database); + XdrStream.Write(_handle); + XdrStream.Flush(); - ReadResponse(); + ReadResponse(); - _handle = 0; - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_network_error, ex); - } - finally + _handle = 0; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_network_error, ex); + } + finally + { + try { - try - { - CloseConnection(); - } - catch - { } + CloseConnection(); } + catch + { } } } @@ -412,58 +357,54 @@ public virtual void DropDatabase() public virtual void ConnectionRequest(out int auxHandle, out string ipAddress, out int portNumber) { - lock (SyncObject) + try { - try - { - XdrStream.Write(IscCodes.op_connect_request); - XdrStream.Write(IscCodes.P_REQ_async); // Connection type - XdrStream.Write(_handle); // Related object - XdrStream.Write(0); // Partner identification + XdrStream.Write(IscCodes.op_connect_request); + XdrStream.Write(IscCodes.P_REQ_async); + XdrStream.Write(_handle); + XdrStream.Write(PartnerIdentification); - XdrStream.Flush(); + XdrStream.Flush(); - ReadOperation(); + ReadOperation(); - auxHandle = XdrStream.ReadInt32(); + auxHandle = XdrStream.ReadInt32(); - // garbage - XdrStream.ReadBytes(8); + // garbage + XdrStream.ReadBytes(8); - int respLen = XdrStream.ReadInt32(); - respLen += respLen % 4; + int respLen = XdrStream.ReadInt32(); + respLen += respLen % 4; - // sin_family - XdrStream.ReadBytes(2); - respLen -= 2; + // sin_family + XdrStream.ReadBytes(2); + respLen -= 2; - // sin_port - byte[] buffer = XdrStream.ReadBytes(2); - portNumber = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, 0)); - respLen -= 2; + // sin_port + byte[] buffer = XdrStream.ReadBytes(2); + portNumber = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, 0)); + respLen -= 2; - // * The address returned by the server may be incorrect if it is behind a NAT box - // * so we must use the address that was used to connect the main socket, not the - // * address reported by the server. - // sin_addr - buffer = XdrStream.ReadBytes(4); - //ipAddress = string.Format( - // CultureInfo.InvariantCulture, - // "{0}.{1}.{2}.{3}", - // buffer[0], buffer[1], buffer[2], buffer[3]); - ipAddress = _connection.IPAddress.ToString(); - respLen -= 4; + // * The address returned by the server may be incorrect if it is behind a NAT box + // * so we must use the address that was used to connect the main socket, not the + // * address reported by the server. + // sin_addr + buffer = XdrStream.ReadBytes(4); + //ipAddress = string.Format( + // CultureInfo.InvariantCulture, + // "{0}.{1}.{2}.{3}", + // buffer[0], buffer[1], buffer[2], buffer[3]); + ipAddress = _connection.IPAddress.ToString(); + respLen -= 4; - // garbage - XdrStream.ReadBytes(respLen); + // garbage + XdrStream.ReadBytes(respLen); - // Read Status Vector - XdrStream.ReadStatusVector(); - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + XdrStream.ReadStatusVector(); + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } @@ -480,13 +421,10 @@ public void CloseConnection() public void CloseEventManager() { - lock (SyncObject) + if (_eventManager != null) { - if (_eventManager != null) - { - _eventManager.Close(); - _eventManager = null; - } + _eventManager.Close(); + _eventManager = null; } } @@ -499,67 +437,55 @@ public void QueueEvents(RemoteEvent events) { if (_eventManager == null) { - string ipAddress = string.Empty; - int portNumber = 0; - int auxHandle = 0; - + string ipAddress; + int portNumber; + int auxHandle; ConnectionRequest(out auxHandle, out ipAddress, out portNumber); - _eventManager = new GdsEventManager(auxHandle, ipAddress, portNumber); } - - lock (SyncObject) + try { - try - { - events.LocalId = Interlocked.Increment(ref _eventsId); - - // Enqueue events in the event manager - _eventManager.QueueEvents(events); + events.LocalId = Interlocked.Increment(ref _eventsId); + _eventManager.QueueEvents(events); - EventParameterBuffer epb = events.ToEpb(); + EventParameterBuffer epb = events.ToEpb(); - XdrStream.Write(IscCodes.op_que_events); - XdrStream.Write(_handle); // Database object id - XdrStream.WriteBuffer(epb.ToArray()); // Event description block - XdrStream.Write(0); // Address of ast routine - XdrStream.Write(0); // Argument to ast routine - XdrStream.Write(events.LocalId); // Client side id of remote event + XdrStream.Write(IscCodes.op_que_events); + XdrStream.Write(_handle); + XdrStream.WriteBuffer(epb.ToArray()); + XdrStream.Write(AddressOfAstRoutine); + XdrStream.Write(ArgumentToAstRoutine); + XdrStream.Write(events.LocalId); - XdrStream.Flush(); + XdrStream.Flush(); - GenericResponse response = (GenericResponse)ReadResponse(); + GenericResponse response = (GenericResponse)ReadResponse(); - // Update event Remote event ID - events.RemoteId = response.ObjectHandle; - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + events.RemoteId = response.ObjectHandle; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } public void CancelEvents(RemoteEvent events) { - lock (SyncObject) + try { - try - { - XdrStream.Write(IscCodes.op_cancel_events); - XdrStream.Write(_handle); // Database object id - XdrStream.Write(events.LocalId); // Event ID + XdrStream.Write(IscCodes.op_cancel_events); + XdrStream.Write(_handle); + XdrStream.Write(events.LocalId); - XdrStream.Flush(); + XdrStream.Flush(); - ReadResponse(); + ReadResponse(); - _eventManager.CancelEvents(events); - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + _eventManager.CancelEvents(events); + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } @@ -691,18 +617,15 @@ public virtual void SetOperation(int operation) public virtual void ReleaseObject(int op, int id) { - lock (SyncObject) + try { - try - { - DoReleaseObjectPacket(op, id); - XdrStream.Flush(); - ProcessReleaseObjectResponse(ReadResponse()); - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + DoReleaseObjectPacket(op, id); + XdrStream.Flush(); + ProcessReleaseObjectResponse(ReadResponse()); + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } @@ -721,39 +644,32 @@ protected virtual IResponse ReadSingleResponse() return response; } - /// - /// isc_database_info - /// private void DatabaseInfo(byte[] items, byte[] buffer, int bufferLength) { - lock (SyncObject) + try { - try - { - // see src/remote/protocol.h for packet definition (p_info struct) - XdrStream.Write(IscCodes.op_info_database); // operation - XdrStream.Write(_handle); // db_handle - XdrStream.Write(0); // incarnation - XdrStream.WriteBuffer(items, items.Length); // items - XdrStream.Write(bufferLength); // result buffer length - - XdrStream.Flush(); + XdrStream.Write(IscCodes.op_info_database); + XdrStream.Write(_handle); + XdrStream.Write(Incarnation); + XdrStream.WriteBuffer(items, items.Length); + XdrStream.Write(bufferLength); - GenericResponse response = (GenericResponse)ReadResponse(); + XdrStream.Flush(); - int responseLength = bufferLength; + GenericResponse response = (GenericResponse)ReadResponse(); - if (response.Data.Length < bufferLength) - { - responseLength = response.Data.Length; - } + int responseLength = bufferLength; - Buffer.BlockCopy(response.Data, 0, buffer, 0, responseLength); - } - catch (IOException ex) + if (response.Data.Length < bufferLength) { - throw IscException.ForErrorCode(IscCodes.isc_network_error, ex); + responseLength = response.Data.Length; } + + Buffer.BlockCopy(response.Data, 0, buffer, 0, responseLength); + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_network_error, ex); } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsEventManager.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsEventManager.cs index 8320275a..58cf89a5 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsEventManager.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsEventManager.cs @@ -28,14 +28,15 @@ namespace FirebirdSql.Data.Client.Managed.Version10 { +#warning Reevaluate threading races internal class GdsEventManager { #region Fields - private GdsDatabase _database; - private Thread _eventsThread; private ConcurrentDictionary _events; private int _handle; + private GdsDatabase _database; + private Thread _eventsThread; #endregion @@ -45,13 +46,9 @@ public GdsEventManager(int handle, string ipAddress, int portNumber) { _events = new ConcurrentDictionary(); _handle = handle; - - if (_database == null) - { - GdsConnection connection = new GdsConnection(ipAddress, portNumber); - connection.Connect(); - _database = new GdsDatabase(connection); - } + GdsConnection connection = new GdsConnection(ipAddress, portNumber); + connection.Connect(); + _database = new GdsDatabase(connection); } #endregion @@ -60,18 +57,15 @@ public GdsEventManager(int handle, string ipAddress, int portNumber) public void QueueEvents(RemoteEvent remoteEvent) { - lock (this) - { - _events[remoteEvent.LocalId] = remoteEvent; + _events[remoteEvent.LocalId] = remoteEvent; #warning Jiri Cincura: I'm pretty sure this is a race condition. - if (_eventsThread == null || _eventsThread.ThreadState.HasFlag(ThreadState.Stopped | ThreadState.Unstarted)) - { - _eventsThread = new Thread(ThreadHandler); - _eventsThread.IsBackground = true; - _eventsThread.Name = "FirebirdClient - Events Thread"; - _eventsThread.Start(); - } + if (_eventsThread == null || _eventsThread.ThreadState.HasFlag(ThreadState.Stopped | ThreadState.Unstarted)) + { + _eventsThread = new Thread(ThreadHandler); + _eventsThread.IsBackground = true; + _eventsThread.Name = "FirebirdClient - Events Thread"; + _eventsThread.Start(); } } @@ -83,23 +77,20 @@ public void CancelEvents(RemoteEvent remoteEvent) public void Close() { - lock (_database.SyncObject) + if (_database != null) { - if (_database != null) - { - _database.CloseConnection(); - } + _database.CloseConnection(); + } - if (_eventsThread != null) + if (_eventsThread != null) + { + // we don't have here clue about disposing vs. finalizer + if (!Environment.HasShutdownStarted) { - // we don't have here clue about disposing vs. finalizer - if (!Environment.HasShutdownStarted) - { - _eventsThread.Join(); - } - - _eventsThread = null; + _eventsThread.Join(); } + + _eventsThread = null; } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsServiceManager.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsServiceManager.cs index 4327cd44..eb2d3050 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsServiceManager.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsServiceManager.cs @@ -29,9 +29,9 @@ internal sealed class GdsServiceManager : IServiceManager { #region Fields - private int _handle; - private GdsDatabase _database; - private GdsConnection _connection; + private int _handle; + private GdsDatabase _database; + private GdsConnection _connection; #endregion @@ -65,41 +65,46 @@ public void Attach(ServiceParameterBuffer spb, string dataSource, int port, stri { GenericResponse response = null; - lock (this) + try { - try - { #warning Separate method for op_service_attach as for i.e. op_attach - _database.XdrStream.Write(IscCodes.op_service_attach); - _database.XdrStream.Write(0); - _database.XdrStream.Write(service); - _database.XdrStream.WriteBuffer(spb.ToArray()); - _database.XdrStream.Flush(); + _database.XdrStream.Write(IscCodes.op_service_attach); + _database.XdrStream.Write(0); + _database.XdrStream.Write(service); + _database.XdrStream.WriteBuffer(spb.ToArray()); + _database.XdrStream.Flush(); - response = _database.ReadGenericResponse(); + response = _database.ReadGenericResponse(); - _handle = response.ObjectHandle; - } - catch (IOException ex) - { - _database.Detach(); - throw IscException.ForErrorCode(IscCodes.isc_net_write_err, ex); - } + _handle = response.ObjectHandle; + } + catch (IOException ex) + { + _database.Detach(); + throw IscException.ForErrorCode(IscCodes.isc_net_write_err, ex); } } public void Detach() { - lock (this) + try + { + _database.XdrStream.Write(IscCodes.op_service_detach); + _database.XdrStream.Write(Handle); + _database.XdrStream.Write(IscCodes.op_disconnect); + _database.XdrStream.Flush(); + + _handle = 0; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_network_error, ex); + } + finally { try { - _database.XdrStream.Write(IscCodes.op_service_detach); - _database.XdrStream.Write(Handle); - _database.XdrStream.Write(IscCodes.op_disconnect); - _database.XdrStream.Flush(); - - _handle = 0; + _connection.Disconnect(); } catch (IOException ex) { @@ -107,86 +112,64 @@ public void Detach() } finally { - try - { - _connection.Disconnect(); - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_network_error, ex); - } - finally - { - _database = null; - _connection = null; - } + _database = null; + _connection = null; } } } public void Start(ServiceParameterBuffer spb) { - lock (this) + try { + _database.XdrStream.Write(IscCodes.op_service_start); + _database.XdrStream.Write(Handle); + _database.XdrStream.Write(0); + _database.XdrStream.WriteBuffer(spb.ToArray(), spb.Length); + _database.XdrStream.Flush(); + try { - _database.XdrStream.Write(IscCodes.op_service_start); - _database.XdrStream.Write(Handle); - _database.XdrStream.Write(0); - _database.XdrStream.WriteBuffer(spb.ToArray(), spb.Length); - _database.XdrStream.Flush(); - - try - { - _database.ReadResponse(); - } - catch (IscException) - { - throw; - } + _database.ReadResponse(); } - catch (IOException ex) + catch (IscException) { - throw IscException.ForErrorCode(IscCodes.isc_net_write_err, ex); + throw; } } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_write_err, ex); + } } - public void Query( - ServiceParameterBuffer spb, - int requestLength, - byte[] requestBuffer, - int bufferLength, - byte[] buffer) + public void Query(ServiceParameterBuffer spb, int requestLength, byte[] requestBuffer, int bufferLength, byte[] buffer) { - lock (this) + try { - try - { - _database.XdrStream.Write(IscCodes.op_service_info); // operation - _database.XdrStream.Write(Handle); // db_handle - _database.XdrStream.Write(0); // incarnation - _database.XdrStream.WriteBuffer(spb.ToArray(), spb.Length); // Service parameter buffer - _database.XdrStream.WriteBuffer(requestBuffer, requestLength); // request buffer - _database.XdrStream.Write(bufferLength); // result buffer length - - _database.XdrStream.Flush(); + _database.XdrStream.Write(IscCodes.op_service_info); + _database.XdrStream.Write(Handle); + _database.XdrStream.Write(GdsDatabase.Incarnation); + _database.XdrStream.WriteBuffer(spb.ToArray(), spb.Length); + _database.XdrStream.WriteBuffer(requestBuffer, requestLength); + _database.XdrStream.Write(bufferLength); - GenericResponse response = _database.ReadGenericResponse(); + _database.XdrStream.Flush(); - int responseLength = bufferLength; + GenericResponse response = _database.ReadGenericResponse(); - if (response.Data.Length < bufferLength) - { - responseLength = response.Data.Length; - } + int responseLength = bufferLength; - Buffer.BlockCopy(response.Data, 0, buffer, 0, responseLength); - } - catch (IOException ex) + if (response.Data.Length < bufferLength) { - throw IscException.ForErrorCode(IscCodes.isc_network_error, ex); + responseLength = response.Data.Length; } + + Buffer.BlockCopy(response.Data, 0, buffer, 0, responseLength); + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_network_error, ex); } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsStatement.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsStatement.cs index e3ca742c..74829aaa 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsStatement.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsStatement.cs @@ -23,6 +23,7 @@ using System.IO; using FirebirdSql.Data.Common; +using System.Diagnostics; namespace FirebirdSql.Data.Client.Managed.Version10 { @@ -60,10 +61,10 @@ public override TransactionBase Transaction { if (_transaction != value) { - if (_TransactionUpdate != null && _transaction != null) + if (TransactionUpdate != null && _transaction != null) { - _transaction.Update -= _TransactionUpdate; - _TransactionUpdate = null; + _transaction.Update -= TransactionUpdate; + TransactionUpdate = null; } if (value == null) @@ -73,8 +74,8 @@ public override TransactionBase Transaction else { _transaction = (GdsTransaction)value; - _TransactionUpdate = new EventHandler(TransactionUpdated); - _transaction.Update += _TransactionUpdate; + TransactionUpdate = new EventHandler(TransactionUpdated); + _transaction.Update += TransactionUpdate; } } } @@ -145,11 +146,11 @@ public GdsStatement(IDatabase db, TransactionBase transaction) { if (!(db is GdsDatabase)) { - throw new ArgumentException("Specified argument is not of GdsDatabase type."); + throw new ArgumentException($"Specified argument is not of {nameof(GdsDatabase)} type."); } if (transaction != null && !(transaction is GdsTransaction)) { - throw new ArgumentException("Specified argument is not of GdsTransaction type."); + throw new ArgumentException($"Specified argument is not of {nameof(GdsTransaction)} type."); } _handle = IscCodes.INVALID_OBJECT; @@ -170,42 +171,26 @@ public GdsStatement(IDatabase db, TransactionBase transaction) #region IDisposable methods - protected override void Dispose(bool disposing) + public override void Dispose() { - lock (this) + if (!_disposed) { - if (!_disposed) - { - try - { - Release(); - } - catch - { } - finally - { - if (disposing) - { - Clear(); - - _rows = null; - _outputParams = null; - _database = null; - _fields = null; - _parameters = null; - _transaction = null; - _allRowsFetched = false; - _state = StatementState.Deallocated; - _statementType = DbStatementType.None; - _handle = 0; - _fetchSize = 0; - RecordsAffected = 0; - } - - _disposed = true; - base.Dispose(disposing); - } - } + _disposed = true; + Release(); + Clear(); + _rows = null; + _outputParams = null; + _database = null; + _fields = null; + _parameters = null; + _transaction = null; + _allRowsFetched = false; + _state = StatementState.Deallocated; + _statementType = DbStatementType.None; + _handle = 0; + _fetchSize = 0; + RecordsAffected = 0; + base.Dispose(); } } @@ -248,40 +233,33 @@ public override ArrayBase CreateArray(long handle, string tableName, string fiel public override void Prepare(string commandText) { - // Clear data ClearAll(); - lock (_database.SyncObject) + try { - try + if (_state == StatementState.Deallocated) { - if (_state == StatementState.Deallocated) - { - // Allocate statement - SendAllocateToBuffer(); - _database.XdrStream.Flush(); - ProcessAllocateResponce(_database.ReadGenericResponse()); - } - - SendPrepareToBuffer(commandText); + SendAllocateToBuffer(); _database.XdrStream.Flush(); - ProcessPrepareResponse(_database.ReadGenericResponse()); + ProcessAllocateResponce(_database.ReadGenericResponse()); + } - // Grab statement type - SendInfoSqlToBuffer(StatementTypeInfoItems, IscCodes.STATEMENT_TYPE_BUFFER_SIZE); - _database.XdrStream.Flush(); - _statementType = ProcessStatementTypeInfoBuffer(ProcessInfoSqlResponse(_database.ReadGenericResponse())); + SendPrepareToBuffer(commandText); + _database.XdrStream.Flush(); + ProcessPrepareResponse(_database.ReadGenericResponse()); + + SendInfoSqlToBuffer(StatementTypeInfoItems, IscCodes.STATEMENT_TYPE_BUFFER_SIZE); + _database.XdrStream.Flush(); + _statementType = ProcessStatementTypeInfoBuffer(ProcessInfoSqlResponse(_database.ReadGenericResponse())); - _state = StatementState.Prepared; - } - catch (IOException ex) - { - // if the statement has been already allocated, it's now in error - if (_state == StatementState.Allocated) - _state = StatementState.Error; - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + _state = StatementState.Prepared; + } + catch (IOException ex) + { + if (_state == StatementState.Allocated) + _state = StatementState.Error; + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } @@ -292,46 +270,41 @@ public override void Execute() throw new InvalidOperationException("Statement is not correctly created."); } - // Clear data Clear(); - lock (_database.SyncObject) + try { - try - { - RecordsAffected = -1; + RecordsAffected = -1; - SendExecuteToBuffer(); + SendExecuteToBuffer(); - _database.XdrStream.Flush(); + _database.XdrStream.Flush(); - if (_statementType == DbStatementType.StoredProcedure) - { - ProcessStoredProcedureExecuteResponse(_database.ReadSqlResponse()); - } + if (_statementType == DbStatementType.StoredProcedure) + { + ProcessStoredProcedureExecuteResponse(_database.ReadSqlResponse()); + } - GenericResponse executeResponse = _database.ReadGenericResponse(); - ProcessExecuteResponse(executeResponse); + GenericResponse executeResponse = _database.ReadGenericResponse(); + ProcessExecuteResponse(executeResponse); - // Updated number of records affected by the statement execution - if (ReturnRecordsAffected && - (StatementType == DbStatementType.Insert || - StatementType == DbStatementType.Delete || - StatementType == DbStatementType.Update || - StatementType == DbStatementType.StoredProcedure)) - { - SendInfoSqlToBuffer(RowsAffectedInfoItems, IscCodes.ROWS_AFFECTED_BUFFER_SIZE); - _database.XdrStream.Flush(); - RecordsAffected = ProcessRecordsAffectedBuffer(ProcessInfoSqlResponse(_database.ReadGenericResponse())); - } - - _state = StatementState.Executed; - } - catch (IOException ex) + if (ReturnRecordsAffected && + (StatementType == DbStatementType.Insert || + StatementType == DbStatementType.Delete || + StatementType == DbStatementType.Update || + StatementType == DbStatementType.StoredProcedure)) { - _state = StatementState.Error; - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); + SendInfoSqlToBuffer(RowsAffectedInfoItems, IscCodes.ROWS_AFFECTED_BUFFER_SIZE); + _database.XdrStream.Flush(); + RecordsAffected = ProcessRecordsAffectedBuffer(ProcessInfoSqlResponse(_database.ReadGenericResponse())); } + + _state = StatementState.Executed; + } + catch (IOException ex) + { + _state = StatementState.Error; + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } @@ -349,59 +322,55 @@ public override DbValue[] Fetch() if (!_allRowsFetched && _rows.Count == 0) { - // Fetch next batch of rows - lock (_database.SyncObject) + try { - try + _database.XdrStream.Write(IscCodes.op_fetch); + _database.XdrStream.Write(_handle); + _database.XdrStream.WriteBuffer(_fields.ToBlrArray()); + _database.XdrStream.Write(0); // p_sqldata_message_number + _database.XdrStream.Write(_fetchSize); // p_sqldata_messages + _database.XdrStream.Flush(); + + if (_database.NextOperation() == IscCodes.op_fetch_response) { - _database.XdrStream.Write(IscCodes.op_fetch); - _database.XdrStream.Write(_handle); - _database.XdrStream.WriteBuffer(_fields.ToBlrArray()); - _database.XdrStream.Write(0); // p_sqldata_message_number - _database.XdrStream.Write(_fetchSize); // p_sqldata_messages - _database.XdrStream.Flush(); - - if (_database.NextOperation() == IscCodes.op_fetch_response) + IResponse response = null; + + while (!_allRowsFetched) { - IResponse response = null; + response = _database.ReadResponse(); - while (!_allRowsFetched) + if (response is FetchResponse) { - response = _database.ReadResponse(); + FetchResponse fetchResponse = (FetchResponse)response; - if (response is FetchResponse) + if (fetchResponse.Count > 0 && fetchResponse.Status == 0) + { + _rows.Enqueue(ReadRow()); + } + else if (fetchResponse.Status == 100) { - FetchResponse fetchResponse = (FetchResponse)response; - - if (fetchResponse.Count > 0 && fetchResponse.Status == 0) - { - _rows.Enqueue(ReadRow()); - } - else if (fetchResponse.Status == 100) - { - _allRowsFetched = true; - } - else - { - break; - } + _allRowsFetched = true; } else { break; } } - } - else - { - _database.ReadResponse(); + else + { + break; + } } } - catch (IOException ex) + else { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); + _database.ReadResponse(); } } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); + } } if (_rows != null && _rows.Count > 0) @@ -428,13 +397,12 @@ public override DbValue[] GetOutputParameters() public override void Describe() { - System.Diagnostics.Debug.Assert(true); + Debug.Assert(false, "Nothing for Gds, because it's pre-fetched in Prepare."); } - // these are not needed for Gds, because it's pre-fetched in Prepare - // maybe we can fetch these also for Fes and Ext etc. + public override void DescribeParameters() { - System.Diagnostics.Debug.Assert(true); + Debug.Assert(false, "Nothing for Gds, because it's pre-fetched in Prepare."); } #endregion @@ -465,12 +433,9 @@ protected void ProcessPrepareResponse(GenericResponse response) #region op_info_sql methods protected override byte[] GetSqlInfo(byte[] items, int bufferLength) { - lock (_database.SyncObject) - { - DoInfoSqlPacket(items, bufferLength); - _database.XdrStream.Flush(); - return ProcessInfoSqlResponse(_database.ReadGenericResponse()); - } + DoInfoSqlPacket(items, bufferLength); + _database.XdrStream.Flush(); + return ProcessInfoSqlResponse(_database.ReadGenericResponse()); } protected void DoInfoSqlPacket(byte[] items, int bufferLength) @@ -496,7 +461,7 @@ protected void SendInfoSqlToBuffer(byte[] items, int bufferLength) protected byte[] ProcessInfoSqlResponse(GenericResponse respose) { - System.Diagnostics.Debug.Assert(respose.Data != null && respose.Data.Length > 0); + Debug.Assert(respose.Data != null && respose.Data.Length > 0); return respose.Data; } #endregion @@ -507,12 +472,9 @@ protected override void Free(int option) if (FreeNotNeeded(option)) return; - lock (_database.SyncObject) - { - DoFreePacket(option); - _database.XdrStream.Flush(); - ProcessFreeResponse(_database.ReadResponse()); - } + DoFreePacket(option); + _database.XdrStream.Flush(); + ProcessFreeResponse(_database.ReadResponse()); } protected bool FreeNotNeeded(int option) @@ -535,7 +497,6 @@ protected void DoFreePacket(int option) { SendFreeToBuffer(option); - // Reset statement information if (option == IscCodes.DSQL_drop) { _parameters = null; @@ -586,7 +547,6 @@ protected void SendExecuteToBuffer() // this may throw error, so it needs to be before any writing var descriptor = WriteParameters(); - // Write the message if (_statementType == DbStatementType.StoredProcedure) { _database.XdrStream.Write(IscCodes.op_execute2); @@ -643,17 +603,14 @@ protected void ProcessStoredProcedureExecuteResponse(SqlResponse response) protected override void TransactionUpdated(object sender, EventArgs e) { - lock (this) + if (Transaction != null && TransactionUpdate != null) { - if (Transaction != null && _TransactionUpdate != null) - { - Transaction.Update -= _TransactionUpdate; - } - - _state = StatementState.Closed; - _TransactionUpdate = null; - _allRowsFetched = false; + Transaction.Update -= TransactionUpdate; } + + _state = StatementState.Closed; + TransactionUpdate = null; + _allRowsFetched = false; } protected void ParseSqlInfo(byte[] info, byte[] items, ref Descriptor[] rowDescs) @@ -1026,32 +983,29 @@ protected virtual byte[] WriteParameters() protected virtual DbValue[] ReadRow() { DbValue[] row = new DbValue[_fields.Count]; - lock (_database.SyncObject) + try { - try + for (int i = 0; i < _fields.Count; i++) { - for (int i = 0; i < _fields.Count; i++) + var value = ReadRawValue(_fields[i]); + var sqlInd = _database.XdrStream.ReadInt32(); + if (sqlInd == -1) { - var value = ReadRawValue(_fields[i]); - var sqlInd = _database.XdrStream.ReadInt32(); - if (sqlInd == -1) - { - row[i] = new DbValue(this, _fields[i], null); - } - else if (sqlInd == 0) - { - row[i] = new DbValue(this, _fields[i], value); - } - else - { - throw IscException.ForStrParam($"Invalid {nameof(sqlInd)} value: {sqlInd}."); - } + row[i] = new DbValue(this, _fields[i], null); + } + else if (sqlInd == 0) + { + row[i] = new DbValue(this, _fields[i], value); + } + else + { + throw IscException.ForStrParam($"Invalid {nameof(sqlInd)} value: {sqlInd}."); } } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } return row; } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsTransaction.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsTransaction.cs index 6016adab..57fed361 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsTransaction.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsTransaction.cs @@ -38,7 +38,6 @@ internal sealed class GdsTransaction : TransactionBase private bool _disposed; private GdsDatabase _database; private TransactionState _state; - private object _stateSyncRoot; #endregion @@ -58,17 +57,11 @@ public override TransactionState State #region Constructors - private GdsTransaction() - { - _stateSyncRoot = new object(); - } - public GdsTransaction(IDatabase db) - : this() { if (!(db is GdsDatabase)) { - throw new ArgumentException("Specified argument is not of GdsDatabase type."); + throw new ArgumentException($"Specified argument is not of {nameof(GdsDatabase)} type."); } _database = (GdsDatabase)db; @@ -79,34 +72,19 @@ public GdsTransaction(IDatabase db) #region IDisposable methods - protected override void Dispose(bool disposing) + public override void Dispose() { - lock (_stateSyncRoot) + if (!_disposed) { - if (!_disposed) + _disposed = true; + if (_state != TransactionState.NoTransaction) { - try - { - if (_state != TransactionState.NoTransaction) - { - Rollback(); - } - } - catch - { } - finally - { - if (disposing) - { - _database = null; - _handle = 0; - _state = TransactionState.NoTransaction; - } - - _disposed = true; - base.Dispose(disposing); - } + Rollback(); } + _database = null; + _handle = 0; + _state = TransactionState.NoTransaction; + base.Dispose(); } } @@ -116,147 +94,117 @@ protected override void Dispose(bool disposing) public override void BeginTransaction(TransactionParameterBuffer tpb) { - lock (_stateSyncRoot) + if (_state != TransactionState.NoTransaction) { - if (_state != TransactionState.NoTransaction) - { - throw new InvalidOperationException(); - } + throw new InvalidOperationException(); + } - try - { - GenericResponse response; - lock (_database.SyncObject) - { - _database.XdrStream.Write(IscCodes.op_transaction); - _database.XdrStream.Write(_database.Handle); - _database.XdrStream.WriteBuffer(tpb.ToArray()); - _database.XdrStream.Flush(); + try + { + GenericResponse response; + _database.XdrStream.Write(IscCodes.op_transaction); + _database.XdrStream.Write(_database.Handle); + _database.XdrStream.WriteBuffer(tpb.ToArray()); + _database.XdrStream.Flush(); - response = _database.ReadGenericResponse(); + response = _database.ReadGenericResponse(); - _database.TransactionCount++; - } + _database.TransactionCount++; - _handle = response.ObjectHandle; - _state = TransactionState.Active; - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + _handle = response.ObjectHandle; + _state = TransactionState.Active; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } public override void Commit() { - lock (_stateSyncRoot) - { - EnsureActiveTransactionState(); + EnsureActiveTransactionState(); - try - { - lock (_database.SyncObject) - { - _database.XdrStream.Write(IscCodes.op_commit); - _database.XdrStream.Write(_handle); - _database.XdrStream.Flush(); + try + { + _database.XdrStream.Write(IscCodes.op_commit); + _database.XdrStream.Write(_handle); + _database.XdrStream.Flush(); - _database.ReadResponse(); + _database.ReadResponse(); - _database.TransactionCount--; - } + _database.TransactionCount--; - Update?.Invoke(this, new EventArgs()); + Update?.Invoke(this, new EventArgs()); - _state = TransactionState.NoTransaction; - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + _state = TransactionState.NoTransaction; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } public override void Rollback() { - lock (_stateSyncRoot) - { - EnsureActiveTransactionState(); + EnsureActiveTransactionState(); - try - { - lock (_database.SyncObject) - { - _database.XdrStream.Write(IscCodes.op_rollback); - _database.XdrStream.Write(_handle); - _database.XdrStream.Flush(); + try + { + _database.XdrStream.Write(IscCodes.op_rollback); + _database.XdrStream.Write(_handle); + _database.XdrStream.Flush(); - _database.ReadResponse(); + _database.ReadResponse(); - _database.TransactionCount--; - } + _database.TransactionCount--; - Update?.Invoke(this, new EventArgs()); + Update?.Invoke(this, new EventArgs()); - _state = TransactionState.NoTransaction; - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + _state = TransactionState.NoTransaction; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } public override void CommitRetaining() { - lock (_stateSyncRoot) - { - EnsureActiveTransactionState(); + EnsureActiveTransactionState(); - try - { - lock (_database.SyncObject) - { - _database.XdrStream.Write(IscCodes.op_commit_retaining); - _database.XdrStream.Write(_handle); - _database.XdrStream.Flush(); + try + { + _database.XdrStream.Write(IscCodes.op_commit_retaining); + _database.XdrStream.Write(_handle); + _database.XdrStream.Flush(); - _database.ReadResponse(); - } + _database.ReadResponse(); - _state = TransactionState.Active; - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + _state = TransactionState.Active; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } public override void RollbackRetaining() { - lock (_stateSyncRoot) - { - EnsureActiveTransactionState(); + EnsureActiveTransactionState(); - try - { - lock (_database.SyncObject) - { - _database.XdrStream.Write(IscCodes.op_rollback_retaining); - _database.XdrStream.Write(_handle); - _database.XdrStream.Flush(); + try + { + _database.XdrStream.Write(IscCodes.op_rollback_retaining); + _database.XdrStream.Write(_handle); + _database.XdrStream.Flush(); - _database.ReadResponse(); - } + _database.ReadResponse(); - _state = TransactionState.Active; - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + _state = TransactionState.Active; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } @@ -266,58 +214,46 @@ public override void RollbackRetaining() public override void Prepare() { - lock (_stateSyncRoot) - { - EnsureActiveTransactionState(); + EnsureActiveTransactionState(); - try - { - _state = TransactionState.NoTransaction; + try + { + _state = TransactionState.NoTransaction; - lock (_database.SyncObject) - { - _database.XdrStream.Write(IscCodes.op_prepare); - _database.XdrStream.Write(_handle); - _database.XdrStream.Flush(); + _database.XdrStream.Write(IscCodes.op_prepare); + _database.XdrStream.Write(_handle); + _database.XdrStream.Flush(); - _database.ReadResponse(); - } + _database.ReadResponse(); - _state = TransactionState.Prepared; - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + _state = TransactionState.Prepared; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } public override void Prepare(byte[] buffer) { - lock (_stateSyncRoot) - { - EnsureActiveTransactionState(); + EnsureActiveTransactionState(); - try - { - _state = TransactionState.NoTransaction; + try + { + _state = TransactionState.NoTransaction; - lock (_database.SyncObject) - { - _database.XdrStream.Write(IscCodes.op_prepare2); - _database.XdrStream.Write(_handle); - _database.XdrStream.WriteBuffer(buffer, buffer.Length); - _database.XdrStream.Flush(); + _database.XdrStream.Write(IscCodes.op_prepare2); + _database.XdrStream.Write(_handle); + _database.XdrStream.WriteBuffer(buffer, buffer.Length); + _database.XdrStream.Flush(); - _database.ReadResponse(); - } + _database.ReadResponse(); - _state = TransactionState.Prepared; - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + _state = TransactionState.Prepared; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version11/AuthResponse.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version11/AuthResponse.cs index 279339ee..fcc542df 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version11/AuthResponse.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version11/AuthResponse.cs @@ -24,19 +24,11 @@ namespace FirebirdSql.Data.Client.Managed.Version11 { internal class AuthResponse : IResponse { - #region Properties - - public byte[] Data { get; private set; } - - #endregion - - #region Constructors + public byte[] Data { get; } public AuthResponse(byte[] data) { Data = data; } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version11/GdsDatabase.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version11/GdsDatabase.cs index 23ea8ecc..98580a1c 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version11/GdsDatabase.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version11/GdsDatabase.cs @@ -67,35 +67,32 @@ public override StatementBase CreateStatement(TransactionBase transaction) #region Trusted Auth public override void AttachWithTrustedAuth(DatabaseParameterBuffer dpb, string dataSource, int port, string database) { - lock (SyncObject) + try { - try + using (SspiHelper sspiHelper = new SspiHelper()) { - using (SspiHelper sspiHelper = new SspiHelper()) - { - byte[] authData = sspiHelper.InitializeClientSecurity(); - SendTrustedAuthToBuffer(dpb, authData); - SendAttachToBuffer(dpb, database); - XdrStream.Flush(); - - IResponse response = ReadResponse(); - ProcessTrustedAuthResponse(sspiHelper, ref response); - ProcessAttachResponse((GenericResponse)response); - } + byte[] authData = sspiHelper.InitializeClientSecurity(); + SendTrustedAuthToBuffer(dpb, authData); + SendAttachToBuffer(dpb, database); + XdrStream.Flush(); + + IResponse response = ReadResponse(); + ProcessTrustedAuthResponse(sspiHelper, ref response); + ProcessAttachResponse((GenericResponse)response); } - catch (IscException) - { - SafelyDetach(); - throw; - } - catch (IOException ex) - { - SafelyDetach(); - throw IscException.ForErrorCode(IscCodes.isc_net_write_err, ex); - } - - AfterAttachActions(); } + catch (IscException) + { + SafelyDetach(); + throw; + } + catch (IOException ex) + { + SafelyDetach(); + throw IscException.ForErrorCode(IscCodes.isc_net_write_err, ex); + } + + AfterAttachActions(); } protected virtual void SendTrustedAuthToBuffer(DatabaseParameterBuffer dpb, byte[] authData) @@ -119,17 +116,14 @@ protected void ProcessTrustedAuthResponse(SspiHelper sspiHelper, ref IResponse r #region Public methods public override void ReleaseObject(int op, int id) { - lock (SyncObject) + try { - try - { - DoReleaseObjectPacket(op, id); - DeferredPackets.Enqueue(ProcessReleaseObjectResponse); - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); - } + DoReleaseObjectPacket(op, id); + DeferredPackets.Enqueue(ProcessReleaseObjectResponse); + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version11/GdsStatement.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version11/GdsStatement.cs index 9418a7d1..fcd3a5ff 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version11/GdsStatement.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version11/GdsStatement.cs @@ -45,69 +45,60 @@ public GdsStatement(IDatabase db, TransactionBase transaction) public override void Prepare(string commandText) { - // Clear data ClearAll(); - lock (_database.SyncObject) + try { - try + int numberOfResponses = 0; + if (_state == StatementState.Deallocated) { - int numberOfResponses = 0; - if (_state == StatementState.Deallocated) - { - // Allocate statement - SendAllocateToBuffer(); - numberOfResponses++; - } - - // Prepare the statement - SendPrepareToBuffer(commandText); + SendAllocateToBuffer(); numberOfResponses++; + } - // Grab statement type - SendInfoSqlToBuffer(StatementTypeInfoItems, IscCodes.STATEMENT_TYPE_BUFFER_SIZE); - numberOfResponses++; + SendPrepareToBuffer(commandText); + numberOfResponses++; - _database.XdrStream.Flush(); + SendInfoSqlToBuffer(StatementTypeInfoItems, IscCodes.STATEMENT_TYPE_BUFFER_SIZE); + numberOfResponses++; - // allocate, prepare, statement type - try - { - GenericResponse allocateResponse = null; - if (_state == StatementState.Deallocated) - { - numberOfResponses--; - allocateResponse = _database.ReadGenericResponse(); - } - - numberOfResponses--; - GenericResponse prepareResponse = _database.ReadGenericResponse(); - bool deferredExecute = ((prepareResponse.ObjectHandle & IscCodes.STMT_DEFER_EXECUTE) == IscCodes.STMT_DEFER_EXECUTE); + _database.XdrStream.Flush(); + try + { + GenericResponse allocateResponse = null; + if (_state == StatementState.Deallocated) + { numberOfResponses--; - GenericResponse statementTypeResponse = _database.ReadGenericResponse(); - - if (allocateResponse != null) - { - ProcessAllocateResponce(allocateResponse); - } - ProcessPrepareResponse(prepareResponse); - _statementType = ProcessStatementTypeInfoBuffer(ProcessInfoSqlResponse(statementTypeResponse)); + allocateResponse = _database.ReadGenericResponse(); } - finally + + numberOfResponses--; + GenericResponse prepareResponse = _database.ReadGenericResponse(); + bool deferredExecute = ((prepareResponse.ObjectHandle & IscCodes.STMT_DEFER_EXECUTE) == IscCodes.STMT_DEFER_EXECUTE); + + numberOfResponses--; + GenericResponse statementTypeResponse = _database.ReadGenericResponse(); + + if (allocateResponse != null) { - SafeFinishFetching(ref numberOfResponses); + ProcessAllocateResponce(allocateResponse); } - - _state = StatementState.Prepared; + ProcessPrepareResponse(prepareResponse); + _statementType = ProcessStatementTypeInfoBuffer(ProcessInfoSqlResponse(statementTypeResponse)); } - catch (IOException ex) + finally { - // if the statement has been already allocated, it's now in error - if (_state == StatementState.Allocated) - _state = StatementState.Error; - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); + SafeFinishFetching(ref numberOfResponses); } + + _state = StatementState.Prepared; + } + catch (IOException ex) + { + if (_state == StatementState.Allocated) + _state = StatementState.Error; + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } @@ -118,73 +109,66 @@ public override void Execute() throw new InvalidOperationException("Statement is not correctly created."); } - // Clear data Clear(); - lock (_database.SyncObject) + try { - try + RecordsAffected = -1; + + SendExecuteToBuffer(); + + bool readRowsAffectedResponse = false; + if (ReturnRecordsAffected && + (StatementType == DbStatementType.Insert || + StatementType == DbStatementType.Delete || + StatementType == DbStatementType.Update || + StatementType == DbStatementType.StoredProcedure || + StatementType == DbStatementType.Select)) { - RecordsAffected = -1; - - SendExecuteToBuffer(); - - bool readRowsAffectedResponse = false; - // Obtain records affected by query execution - if (ReturnRecordsAffected && - (StatementType == DbStatementType.Insert || - StatementType == DbStatementType.Delete || - StatementType == DbStatementType.Update || - StatementType == DbStatementType.StoredProcedure || - StatementType == DbStatementType.Select)) - { - // Grab rows affected - SendInfoSqlToBuffer(RowsAffectedInfoItems, IscCodes.ROWS_AFFECTED_BUFFER_SIZE); + SendInfoSqlToBuffer(RowsAffectedInfoItems, IscCodes.ROWS_AFFECTED_BUFFER_SIZE); - readRowsAffectedResponse = true; - } + readRowsAffectedResponse = true; + } - _database.XdrStream.Flush(); + _database.XdrStream.Flush(); - // sql?, execute, rows affected? - int numberOfResponses = - (StatementType == DbStatementType.StoredProcedure ? 1 : 0) + 1 + (readRowsAffectedResponse ? 1 : 0); - try + int numberOfResponses = + (StatementType == DbStatementType.StoredProcedure ? 1 : 0) + 1 + (readRowsAffectedResponse ? 1 : 0); + try + { + SqlResponse sqlStoredProcedureResponse = null; + if (StatementType == DbStatementType.StoredProcedure) { - SqlResponse sqlStoredProcedureResponse = null; - if (StatementType == DbStatementType.StoredProcedure) - { - numberOfResponses--; - sqlStoredProcedureResponse = _database.ReadSqlResponse(); - ProcessStoredProcedureExecuteResponse(sqlStoredProcedureResponse); - } - numberOfResponses--; - GenericResponse executeResponse = _database.ReadGenericResponse(); - - GenericResponse rowsAffectedResponse = null; - if (readRowsAffectedResponse) - { - numberOfResponses--; - rowsAffectedResponse = _database.ReadGenericResponse(); - } - - ProcessExecuteResponse(executeResponse); - if (readRowsAffectedResponse) - RecordsAffected = ProcessRecordsAffectedBuffer(ProcessInfoSqlResponse(rowsAffectedResponse)); + sqlStoredProcedureResponse = _database.ReadSqlResponse(); + ProcessStoredProcedureExecuteResponse(sqlStoredProcedureResponse); } - finally + + numberOfResponses--; + GenericResponse executeResponse = _database.ReadGenericResponse(); + + GenericResponse rowsAffectedResponse = null; + if (readRowsAffectedResponse) { - SafeFinishFetching(ref numberOfResponses); + numberOfResponses--; + rowsAffectedResponse = _database.ReadGenericResponse(); } - _state = StatementState.Executed; + ProcessExecuteResponse(executeResponse); + if (readRowsAffectedResponse) + RecordsAffected = ProcessRecordsAffectedBuffer(ProcessInfoSqlResponse(rowsAffectedResponse)); } - catch (IOException ex) + finally { - _state = StatementState.Error; - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); + SafeFinishFetching(ref numberOfResponses); } + + _state = StatementState.Executed; + } + catch (IOException ex) + { + _state = StatementState.Error; + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } @@ -210,11 +194,8 @@ protected override void Free(int option) if (FreeNotNeeded(option)) return; - lock (_database.SyncObject) - { - DoFreePacket(option); - (Database as GdsDatabase).DeferredPackets.Enqueue(ProcessFreeResponse); - } + DoFreePacket(option); + (Database as GdsDatabase).DeferredPackets.Enqueue(ProcessFreeResponse); } #endregion } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version12/GdsStatement.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version12/GdsStatement.cs index 288349c3..e84367bc 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version12/GdsStatement.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version12/GdsStatement.cs @@ -49,77 +49,69 @@ public override void Execute() throw new InvalidOperationException("Statement is not correctly created."); } - // Clear data Clear(); - lock (_database.SyncObject) + try { + RecordsAffected = -1; + + SendExecuteToBuffer(); + + _database.XdrStream.Flush(); + + int numberOfResponses = + (StatementType == DbStatementType.StoredProcedure ? 1 : 0) + 1; try { - RecordsAffected = -1; + SqlResponse sqlStoredProcedureResponse = null; + if (StatementType == DbStatementType.StoredProcedure) + { + numberOfResponses--; + sqlStoredProcedureResponse = _database.ReadSqlResponse(); + ProcessStoredProcedureExecuteResponse(sqlStoredProcedureResponse); + } + + numberOfResponses--; + GenericResponse executeResponse = _database.ReadGenericResponse(); + ProcessExecuteResponse(executeResponse); + } + finally + { + SafeFinishFetching(ref numberOfResponses); + } + + // we need to split this in two, to alloow server handle op_cancel properly - SendExecuteToBuffer(); + if (ReturnRecordsAffected && + (StatementType == DbStatementType.Insert || + StatementType == DbStatementType.Delete || + StatementType == DbStatementType.Update || + StatementType == DbStatementType.StoredProcedure || + StatementType == DbStatementType.Select)) + { + SendInfoSqlToBuffer(RowsAffectedInfoItems, IscCodes.ROWS_AFFECTED_BUFFER_SIZE); _database.XdrStream.Flush(); - // sql?, execute - int numberOfResponses = - (StatementType == DbStatementType.StoredProcedure ? 1 : 0) + 1; + numberOfResponses = 1; try { - SqlResponse sqlStoredProcedureResponse = null; - if (StatementType == DbStatementType.StoredProcedure) - { - numberOfResponses--; - sqlStoredProcedureResponse = _database.ReadSqlResponse(); - ProcessStoredProcedureExecuteResponse(sqlStoredProcedureResponse); - } - numberOfResponses--; - GenericResponse executeResponse = _database.ReadGenericResponse(); - ProcessExecuteResponse(executeResponse); + GenericResponse rowsAffectedResponse = _database.ReadGenericResponse(); + RecordsAffected = ProcessRecordsAffectedBuffer(ProcessInfoSqlResponse(rowsAffectedResponse)); } finally { SafeFinishFetching(ref numberOfResponses); } - - //we need to split this in two, to alloow server handle op_cancel properly - - // Obtain records affected by query execution - if (ReturnRecordsAffected && - (StatementType == DbStatementType.Insert || - StatementType == DbStatementType.Delete || - StatementType == DbStatementType.Update || - StatementType == DbStatementType.StoredProcedure || - StatementType == DbStatementType.Select)) - { - // Grab rows affected - SendInfoSqlToBuffer(RowsAffectedInfoItems, IscCodes.ROWS_AFFECTED_BUFFER_SIZE); - - _database.XdrStream.Flush(); - - //rows affected - numberOfResponses = 1; - try - { - numberOfResponses--; - GenericResponse rowsAffectedResponse = _database.ReadGenericResponse(); - RecordsAffected = ProcessRecordsAffectedBuffer(ProcessInfoSqlResponse(rowsAffectedResponse)); - } - finally - { - SafeFinishFetching(ref numberOfResponses); - } - } - - _state = StatementState.Executed; - } - catch (IOException ex) - { - _state = StatementState.Error; - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } + + _state = StatementState.Executed; + } + catch (IOException ex) + { + _state = StatementState.Error; + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version13/GdsStatement.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version13/GdsStatement.cs index 196e354f..290cba01 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version13/GdsStatement.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version13/GdsStatement.cs @@ -89,31 +89,28 @@ protected override byte[] WriteParameters() protected override DbValue[] ReadRow() { DbValue[] row = new DbValue[_fields.Count]; - lock (_database.SyncObject) + try { - try + var nullBytes = _database.XdrStream.ReadOpaque((int)Math.Ceiling(_fields.Count / 8d)); + var nullBits = new BitArray(nullBytes); + for (int i = 0; i < _fields.Count; i++) { - var nullBytes = _database.XdrStream.ReadOpaque((int)Math.Ceiling(_fields.Count / 8d)); - var nullBits = new BitArray(nullBytes); - for (int i = 0; i < _fields.Count; i++) + if (nullBits.Get(i)) { - if (nullBits.Get(i)) - { - row[i] = new DbValue(this, _fields[i], null); - } - else - { - var value = ReadRawValue(_fields[i]); - row[i] = new DbValue(this, _fields[i], value); - } + row[i] = new DbValue(this, _fields[i], null); + } + else + { + var value = ReadRawValue(_fields[i]); + row[i] = new DbValue(this, _fields[i], value); } - - return row; - } - catch (IOException ex) - { - throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } + + return row; + } + catch (IOException ex) + { + throw IscException.ForErrorCode(IscCodes.isc_net_read_err, ex); } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/XdrStream.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/XdrStream.cs index 7623dad8..d846f23d 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/XdrStream.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/XdrStream.cs @@ -161,20 +161,12 @@ protected override void Dispose(bool disposing) { if (disposing) { - try + if (_ownsStream) { - if (_ownsStream) - { - _innerStream?.Dispose(); - } - } - catch - { } - finally - { - _innerStream = null; - _charset = null; + _innerStream?.Dispose(); } + _innerStream = null; + _charset = null; } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FbClientFactory.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FbClientFactory.cs index 3c9abce7..645b13d9 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FbClientFactory.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FbClientFactory.cs @@ -16,13 +16,14 @@ * All Rights Reserved. */ -using FirebirdSql.Data.Client.Native.Handle; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; +using System.Collections.Concurrent; +using FirebirdSql.Data.Client.Native.Handle; namespace FirebirdSql.Data.Client.Native { @@ -38,7 +39,7 @@ internal static class FbClientFactory /// Because generating the class at runtime is expensive, we cache it here based on the name /// specified. /// - private static IDictionary cache; + private static ConcurrentDictionary cache; private static HashSet injectionTypes; /// @@ -46,7 +47,7 @@ internal static class FbClientFactory /// static FbClientFactory() { - cache = new SortedDictionary(); + cache = new ConcurrentDictionary(); #if NETCORE10 injectionTypes = new HashSet(typeof(FbClientFactory).GetTypeInfo().Assembly.GetTypes() .Where(x => !x.GetTypeInfo().IsAbstract && !x.GetTypeInfo().IsInterface) @@ -72,41 +73,7 @@ public static IFbClient GetFbClient(string dllName) { dllName = DefaultDllName; } - - IFbClient fbClient; - - // First, try to get the IFbClient from the cache. - lock (cache) - { - if (cache.TryGetValue(dllName, out fbClient)) - { - // We got one! - return fbClient; - } - } - - // If we didn't get one, then generate a new one (note: because we're outside the lock, we - // may end up generating two different classes for the same DLL if we're called multiple times - // initially, but that's OK - only one is added to the cache and it only happens on startup) - fbClient = GenerateFbClient(dllName); - - // Add it into the cache for next time - lock (cache) - { - if (cache.ContainsKey(dllName)) - { - // If there's one in there now, it means somebody else already generated one while - // we were generating ours. Just use theirs... oh well - fbClient = cache[dllName]; - } - else - { - // Nothing in there yet, we must've been the first. Add it now. - cache.Add(dllName, fbClient); - } - } - - return fbClient; + return cache.GetOrAdd(dllName, GenerateFbClient); } /// diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesArray.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesArray.cs index 6f81b0fe..2bcf8a30 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesArray.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesArray.cs @@ -94,11 +94,11 @@ public FesArray(ArrayDesc descriptor) { if (!(db is FesDatabase)) { - throw new ArgumentException("Specified argument is not of GdsDatabase type."); + throw new ArgumentException($"Specified argument is not of {nameof(FesDatabase)} type."); } if (!(transaction is FesTransaction)) { - throw new ArgumentException("Specified argument is not of GdsTransaction type."); + throw new ArgumentException($"Specified argument is not of {nameof(FesTransaction)} type."); } _db = (FesDatabase)db; _transaction = (FesTransaction)transaction; @@ -114,7 +114,6 @@ public FesArray(ArrayDesc descriptor) public override byte[] GetSlice(int sliceLength) { - // Clear the status vector ClearStatusVector(); DatabaseHandle dbHandle = _db.HandlePtr; @@ -133,7 +132,6 @@ public override byte[] GetSlice(int sliceLength) buffer, ref sliceLength); - // Free memory ArrayDescMarshaler.CleanUpNativeData(ref arrayDesc); _db.ProcessStatusVector(_statusVector); @@ -141,9 +139,8 @@ public override byte[] GetSlice(int sliceLength) return buffer; } - public override void PutSlice(System.Array sourceArray, int sliceLength) + public override void PutSlice(Array sourceArray, int sliceLength) { - // Clear the status vector ClearStatusVector(); DatabaseHandle dbHandle = _db.HandlePtr; @@ -151,8 +148,6 @@ public override void PutSlice(System.Array sourceArray, int sliceLength) IntPtr arrayDesc = ArrayDescMarshaler.MarshalManagedToNative(Descriptor); - // Obtain the System of type of Array elements and - // Fill buffer Type systemType = GetSystemType(); byte[] buffer = new byte[sliceLength]; @@ -178,7 +173,6 @@ public override void PutSlice(System.Array sourceArray, int sliceLength) buffer, ref sliceLength); - // Free memory ArrayDescMarshaler.CleanUpNativeData(ref arrayDesc); _db.ProcessStatusVector(_statusVector); @@ -188,7 +182,7 @@ public override void PutSlice(System.Array sourceArray, int sliceLength) #region Protected Methods - protected override System.Array DecodeSlice(byte[] slice) + protected override Array DecodeSlice(byte[] slice) { Array sliceData = null; int slicePosition = 0; @@ -199,7 +193,6 @@ protected override System.Array DecodeSlice(byte[] slice) int[] lengths = new int[Descriptor.Dimensions]; int[] lowerBounds = new int[Descriptor.Dimensions]; - // Get upper and lower bounds of each dimension for (int i = 0; i < Descriptor.Dimensions; i++) { lowerBounds[i] = Descriptor.Bounds[i].LowerBound; @@ -211,12 +204,10 @@ protected override System.Array DecodeSlice(byte[] slice) } } - // Create slice arrays sliceData = Array.CreateInstance(systemType, lengths, lowerBounds); Array tempData = Array.CreateInstance(systemType, sliceData.Length); - // Infer data types type = TypeHelper.GetSqlTypeFromBlrType(Descriptor.DataType); dbType = TypeHelper.GetDbDataTypeFromBlrType(Descriptor.DataType, 0, Descriptor.Scale); @@ -368,7 +359,6 @@ private byte[] EncodeSlice(ArrayDesc desc, Array sourceArray, int length) int subType = (Descriptor.Scale < 0) ? 2 : 0; int type = 0; - // Infer data types type = TypeHelper.GetSqlTypeFromBlrType(Descriptor.DataType); dbType = TypeHelper.GetDbDataTypeFromBlrType(Descriptor.DataType, subType, Descriptor.Scale); diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesBlob.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesBlob.cs index dd57ff00..bb486faf 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesBlob.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesBlob.cs @@ -63,11 +63,11 @@ public FesBlob(IDatabase db, TransactionBase transaction, long blobId) { if (!(db is FesDatabase)) { - throw new ArgumentException("Specified argument is not of FesDatabase type."); + throw new ArgumentException($"Specified argument is not of {nameof(FesDatabase)} type."); } if (!(transaction is FesTransaction)) { - throw new ArgumentException("Specified argument is not of FesTransaction type."); + throw new ArgumentException($"Specified argument is not of {nameof(FesTransaction)} type."); } _db = (FesDatabase)db; @@ -84,50 +84,42 @@ public FesBlob(IDatabase db, TransactionBase transaction, long blobId) protected override void Create() { - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - DatabaseHandle dbHandle = _db.HandlePtr; - TransactionHandle trHandle = ((FesTransaction)_transaction).HandlePtr; + DatabaseHandle dbHandle = _db.HandlePtr; + TransactionHandle trHandle = ((FesTransaction)_transaction).HandlePtr; - _db.FbClient.isc_create_blob2( - _statusVector, - ref dbHandle, - ref trHandle, - ref _blobHandle, - ref _blobId, - 0, - new byte[0]); + _db.FbClient.isc_create_blob2( + _statusVector, + ref dbHandle, + ref trHandle, + ref _blobHandle, + ref _blobId, + 0, + new byte[0]); - _db.ProcessStatusVector(_statusVector); + _db.ProcessStatusVector(_statusVector); - RblAddValue(IscCodes.RBL_create); - } + RblAddValue(IscCodes.RBL_create); } protected override void Open() { - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - DatabaseHandle dbHandle = _db.HandlePtr; - TransactionHandle trHandle = ((FesTransaction)_transaction).HandlePtr; + DatabaseHandle dbHandle = _db.HandlePtr; + TransactionHandle trHandle = ((FesTransaction)_transaction).HandlePtr; - _db.FbClient.isc_open_blob2( - _statusVector, - ref dbHandle, - ref trHandle, - ref _blobHandle, - ref _blobId, - 0, - new byte[0]); + _db.FbClient.isc_open_blob2( + _statusVector, + ref dbHandle, + ref trHandle, + ref _blobHandle, + ref _blobId, + 0, + new byte[0]); - _db.ProcessStatusVector(_statusVector); - } + _db.ProcessStatusVector(_statusVector); } protected override byte[] GetSegment() @@ -135,66 +127,58 @@ protected override byte[] GetSegment() short requested = (short)SegmentSize; short segmentLength = 0; - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - using (MemoryStream segment = new MemoryStream()) - { - byte[] tmp = new byte[requested]; + using (MemoryStream segment = new MemoryStream()) + { + byte[] tmp = new byte[requested]; - IntPtr status = _db.FbClient.isc_get_segment( - _statusVector, - ref _blobHandle, - ref segmentLength, - requested, - tmp); + IntPtr status = _db.FbClient.isc_get_segment( + _statusVector, + ref _blobHandle, + ref segmentLength, + requested, + tmp); - if (segmentLength > 0) - { - segment.Write(tmp, 0, segmentLength > requested ? requested : segmentLength); - } + if (segmentLength > 0) + { + segment.Write(tmp, 0, segmentLength > requested ? requested : segmentLength); + } - RblRemoveValue(IscCodes.RBL_segment); + RblRemoveValue(IscCodes.RBL_segment); - if (_statusVector[1] == new IntPtr(IscCodes.isc_segstr_eof)) + if (_statusVector[1] == new IntPtr(IscCodes.isc_segstr_eof)) + { + segment.SetLength(0); + RblAddValue(IscCodes.RBL_eof_pending); + } + else + { + if (status == IntPtr.Zero || _statusVector[1] == new IntPtr(IscCodes.isc_segment)) { - segment.SetLength(0); - RblAddValue(IscCodes.RBL_eof_pending); + RblAddValue(IscCodes.RBL_segment); } else { - if (status == IntPtr.Zero || _statusVector[1] == new IntPtr(IscCodes.isc_segment)) - { - RblAddValue(IscCodes.RBL_segment); - } - else - { - _db.ProcessStatusVector(_statusVector); - } + _db.ProcessStatusVector(_statusVector); } - - return segment.ToArray(); } + + return segment.ToArray(); } } protected override void PutSegment(byte[] buffer) { - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - _db.FbClient.isc_put_segment( - _statusVector, - ref _blobHandle, - (short)buffer.Length, - buffer); + _db.FbClient.isc_put_segment( + _statusVector, + ref _blobHandle, + (short)buffer.Length, + buffer); - _db.ProcessStatusVector(_statusVector); - } + _db.ProcessStatusVector(_statusVector); } protected override void Seek(int position) @@ -209,28 +193,20 @@ protected override void GetBlobInfo() protected override void Close() { - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - _db.FbClient.isc_close_blob(_statusVector, ref _blobHandle); + _db.FbClient.isc_close_blob(_statusVector, ref _blobHandle); - _db.ProcessStatusVector(_statusVector); - } + _db.ProcessStatusVector(_statusVector); } protected override void Cancel() { - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - _db.FbClient.isc_cancel_blob(_statusVector, ref _blobHandle); + _db.FbClient.isc_cancel_blob(_statusVector, ref _blobHandle); - _db.ProcessStatusVector(_statusVector); - } + _db.ProcessStatusVector(_statusVector); } #endregion diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesDatabase.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesDatabase.cs index 99f18e99..76b348f7 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesDatabase.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesDatabase.cs @@ -53,7 +53,6 @@ public WarningMessageCallback WarningMessage private short _dialect; private bool _disposed; private IntPtr[] _statusVector; - private object _syncObject; private IFbClient _fbClient; @@ -110,19 +109,6 @@ public IFbClient FbClient get { return _fbClient; } } - public object SyncObject - { - get - { - if (_syncObject == null) - { - Interlocked.CompareExchange(ref _syncObject, new object(), null); - } - - return _syncObject; - } - } - #endregion #region Constructors @@ -139,41 +125,22 @@ public FesDatabase(string dllName, Charset charset) #endregion - #region Finalizer - - ~FesDatabase() - { - Dispose(false); - } - - #endregion - #region IDisposable methods public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) { if (!_disposed) { - if (disposing) - { - Detach(); - _warningMessage = null; - _charset = null; - _serverVersion = null; - _statusVector = null; - _transactionCount = 0; - _dialect = 0; - _handle.Dispose(); - _packetSize = 0; - } - _disposed = true; + Detach(); + _warningMessage = null; + _charset = null; + _serverVersion = null; + _statusVector = null; + _transactionCount = 0; + _dialect = 0; + _handle.Dispose(); + _packetSize = 0; } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesStatement.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesStatement.cs index e09d38a9..b92e20da 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesStatement.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesStatement.cs @@ -61,10 +61,10 @@ public override TransactionBase Transaction { if (_transaction != value) { - if (_TransactionUpdate != null && _transaction != null) + if (TransactionUpdate != null && _transaction != null) { - _transaction.Update -= _TransactionUpdate; - _TransactionUpdate = null; + _transaction.Update -= TransactionUpdate; + TransactionUpdate = null; } if (value == null) @@ -74,8 +74,8 @@ public override TransactionBase Transaction else { _transaction = (FesTransaction)value; - _TransactionUpdate = new EventHandler(TransactionUpdated); - _transaction.Update += _TransactionUpdate; + TransactionUpdate = new EventHandler(TransactionUpdated); + _transaction.Update += TransactionUpdate; } } } @@ -150,7 +150,7 @@ public FesStatement(IDatabase db, TransactionBase transaction) { if (!(db is FesDatabase)) { - throw new ArgumentException("Specified argument is not of FesDatabase type."); + throw new ArgumentException($"Specified argument is not of {nameof(FesDatabase)} type."); } _recordsAffected = -1; @@ -170,35 +170,26 @@ public FesStatement(IDatabase db, TransactionBase transaction) #region IDisposable methods - protected override void Dispose(bool disposing) + public override void Dispose() { if (!_disposed) { - try - { - if (disposing) - { - Release(); - Clear(); - _db = null; - _fields = null; - _parameters = null; - _transaction = null; - _outputParams = null; - _statusVector = null; - _allRowsFetched = false; - _state = StatementState.Deallocated; - _statementType = DbStatementType.None; - _recordsAffected = 0; - _handle.Dispose(); - FetchSize = 0; - } - } - finally - { - _disposed = true; - base.Dispose(disposing); - } + _disposed = true; + Release(); + Clear(); + _db = null; + _fields = null; + _parameters = null; + _transaction = null; + _outputParams = null; + _statusVector = null; + _allRowsFetched = false; + _state = StatementState.Deallocated; + _statementType = DbStatementType.None; + _recordsAffected = 0; + _handle.Dispose(); + FetchSize = 0; + base.Dispose(); } } @@ -255,73 +246,56 @@ public override void Close() public override void Prepare(string commandText) { - // Clear data ClearAll(); - lock (_db) + ClearStatusVector(); + + if (_state == StatementState.Deallocated) { - // Clear the status vector - ClearStatusVector(); + Allocate(); + } - // Allocate the statement if needed - if (_state == StatementState.Deallocated) - { - Allocate(); - } + _fields = new Descriptor(1); - // Marshal structures to pointer + IntPtr sqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _fields); + TransactionHandle trHandle = _transaction.HandlePtr; + byte[] buffer = _db.Charset.GetBytes(commandText); - // Setup fields structure - _fields = new Descriptor(1); + _db.FbClient.isc_dsql_prepare( + _statusVector, + ref trHandle, + ref _handle, + (short)buffer.Length, + buffer, + _db.Dialect, + sqlda); - IntPtr sqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _fields); - TransactionHandle trHandle = _transaction.HandlePtr; + Descriptor descriptor = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, sqlda); - byte[] buffer = _db.Charset.GetBytes(commandText); + XsqldaMarshaler.CleanUpNativeData(ref sqlda); - _db.FbClient.isc_dsql_prepare( - _statusVector, - ref trHandle, - ref _handle, - (short)buffer.Length, - buffer, - _db.Dialect, - sqlda); + _db.ProcessStatusVector(_statusVector); - // Marshal Pointer - Descriptor descriptor = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, sqlda); + _fields = descriptor; - // Free memory - XsqldaMarshaler.CleanUpNativeData(ref sqlda); - - // Parse status vector - _db.ProcessStatusVector(_statusVector); - - // Describe fields - _fields = descriptor; - - if (_fields.ActualCount > 0 && _fields.ActualCount != _fields.Count) - { - Describe(); - } - else + if (_fields.ActualCount > 0 && _fields.ActualCount != _fields.Count) + { + Describe(); + } + else + { + if (_fields.ActualCount == 0) { - if (_fields.ActualCount == 0) - { - _fields = new Descriptor(0); - } + _fields = new Descriptor(0); } + } - // Reset actual field values - _fields.ResetValues(); + _fields.ResetValues(); - // Get Statement type - _statementType = GetStatementType(); + _statementType = GetStatementType(); - // Update state - _state = StatementState.Prepared; - } + _state = StatementState.Prepared; } public override void Execute() @@ -331,62 +305,53 @@ public override void Execute() throw new InvalidOperationException("Statment is not correctly created."); } - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - // Marshal structures to pointer + IntPtr inSqlda = IntPtr.Zero; + IntPtr outSqlda = IntPtr.Zero; + if (_parameters != null) + { + inSqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _parameters); + } + if (_statementType == DbStatementType.StoredProcedure) + { + Fields.ResetValues(); + outSqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _fields); + } - IntPtr inSqlda = IntPtr.Zero; - IntPtr outSqlda = IntPtr.Zero; + TransactionHandle trHandle = _transaction.HandlePtr; - if (_parameters != null) - { - inSqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _parameters); - } - if (_statementType == DbStatementType.StoredProcedure) - { - Fields.ResetValues(); - outSqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _fields); - } + _db.FbClient.isc_dsql_execute2( + _statusVector, + ref trHandle, + ref _handle, + IscCodes.SQLDA_VERSION1, + inSqlda, + outSqlda); - TransactionHandle trHandle = _transaction.HandlePtr; + if (outSqlda != IntPtr.Zero) + { + Descriptor descriptor = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, outSqlda, true); - _db.FbClient.isc_dsql_execute2( - _statusVector, - ref trHandle, - ref _handle, - IscCodes.SQLDA_VERSION1, - inSqlda, - outSqlda); + DbValue[] values = new DbValue[descriptor.Count]; - if (outSqlda != IntPtr.Zero) + for (int i = 0; i < values.Length; i++) { - Descriptor descriptor = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, outSqlda, true); - - // This would be an Execute procedure - DbValue[] values = new DbValue[descriptor.Count]; - - for (int i = 0; i < values.Length; i++) - { - values[i] = new DbValue(this, descriptor[i]); - } - - _outputParams.Enqueue(values); + values[i] = new DbValue(this, descriptor[i]); } - // Free memory - XsqldaMarshaler.CleanUpNativeData(ref inSqlda); - XsqldaMarshaler.CleanUpNativeData(ref outSqlda); + _outputParams.Enqueue(values); + } - _db.ProcessStatusVector(_statusVector); + XsqldaMarshaler.CleanUpNativeData(ref inSqlda); + XsqldaMarshaler.CleanUpNativeData(ref outSqlda); - UpdateRecordsAffected(); + _db.ProcessStatusVector(_statusVector); - _state = StatementState.Executed; - } + UpdateRecordsAffected(); + + _state = StatementState.Executed; } public override DbValue[] Fetch() @@ -403,65 +368,48 @@ public override DbValue[] Fetch() return null; } - lock (_db) + if (!_allRowsFetched) { - if (!_allRowsFetched) - { - // Get the XSQLDA Marshaler - - - // Reset actual field values - _fields.ResetValues(); - - // Marshal structures to pointer - if (_fetchSqlDa == IntPtr.Zero) - { - _fetchSqlDa = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _fields); - } - - // Clear the status vector - ClearStatusVector(); + _fields.ResetValues(); - // Statement handle to be passed to the fetch method + if (_fetchSqlDa == IntPtr.Zero) + { + _fetchSqlDa = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _fields); + } + ClearStatusVector(); - // Fetch data - IntPtr status = _db.FbClient.isc_dsql_fetch(_statusVector, ref _handle, IscCodes.SQLDA_VERSION1, _fetchSqlDa); + IntPtr status = _db.FbClient.isc_dsql_fetch(_statusVector, ref _handle, IscCodes.SQLDA_VERSION1, _fetchSqlDa); - // Obtain values - Descriptor rowDesc = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, _fetchSqlDa, true); + Descriptor rowDesc = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, _fetchSqlDa, true); - if (_fields.Count == rowDesc.Count) + if (_fields.Count == rowDesc.Count) + { + for (int i = 0; i < _fields.Count; i++) { - // Try to preserve Array Handle information - for (int i = 0; i < _fields.Count; i++) + if (_fields[i].IsArray() && _fields[i].ArrayHandle != null) { - if (_fields[i].IsArray() && _fields[i].ArrayHandle != null) - { - rowDesc[i].ArrayHandle = _fields[i].ArrayHandle; - } + rowDesc[i].ArrayHandle = _fields[i].ArrayHandle; } } + } - _fields = rowDesc; + _fields = rowDesc; - // Parse status vector - _db.ProcessStatusVector(_statusVector); + _db.ProcessStatusVector(_statusVector); - if (status == new IntPtr(100)) - { - _allRowsFetched = true; + if (status == new IntPtr(100)) + { + _allRowsFetched = true; - XsqldaMarshaler.CleanUpNativeData(ref _fetchSqlDa); - } - else + XsqldaMarshaler.CleanUpNativeData(ref _fetchSqlDa); + } + else + { + row = new DbValue[_fields.ActualCount]; + for (int i = 0; i < row.Length; i++) { - // Set row values - row = new DbValue[_fields.ActualCount]; - for (int i = 0; i < row.Length; i++) - { - row[i] = new DbValue(this, _fields[i]); - } + row[i] = new DbValue(this, _fields[i]); } } } @@ -481,54 +429,55 @@ public override DbValue[] GetOutputParameters() public override void Describe() { - lock (_db) - { - // Clear the status vector - ClearStatusVector(); - - // Update structure - _fields = new Descriptor(_fields.ActualCount); - - // Marshal structures to pointer + ClearStatusVector(); + _fields = new Descriptor(_fields.ActualCount); - IntPtr sqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _fields); + IntPtr sqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _fields); - _db.FbClient.isc_dsql_describe( - _statusVector, - ref _handle, - IscCodes.SQLDA_VERSION1, - sqlda); + _db.FbClient.isc_dsql_describe( + _statusVector, + ref _handle, + IscCodes.SQLDA_VERSION1, + sqlda); - // Marshal Pointer - Descriptor descriptor = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, sqlda); + Descriptor descriptor = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, sqlda); - // Free memory - XsqldaMarshaler.CleanUpNativeData(ref sqlda); + XsqldaMarshaler.CleanUpNativeData(ref sqlda); - // Parse status vector - _db.ProcessStatusVector(_statusVector); + _db.ProcessStatusVector(_statusVector); - // Update field descriptor - _fields = descriptor; - } + _fields = descriptor; } public override void DescribeParameters() { - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); + + _parameters = new Descriptor(1); - // Marshal structures to pointer + IntPtr sqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _parameters); - _parameters = new Descriptor(1); + _db.FbClient.isc_dsql_describe_bind( + _statusVector, + ref _handle, + IscCodes.SQLDA_VERSION1, + sqlda); - IntPtr sqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _parameters); + Descriptor descriptor = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, sqlda); + _db.ProcessStatusVector(_statusVector); + + if (descriptor.ActualCount != 0 && descriptor.Count != descriptor.ActualCount) + { + short n = descriptor.ActualCount; + descriptor = new Descriptor(n); + + XsqldaMarshaler.CleanUpNativeData(ref sqlda); + + sqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, descriptor); _db.FbClient.isc_dsql_describe_bind( _statusVector, @@ -536,53 +485,26 @@ public override void DescribeParameters() IscCodes.SQLDA_VERSION1, sqlda); - Descriptor descriptor = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, sqlda); - - // Parse status vector - _db.ProcessStatusVector(_statusVector); - - if (descriptor.ActualCount != 0 && descriptor.Count != descriptor.ActualCount) - { - short n = descriptor.ActualCount; - descriptor = new Descriptor(n); - - // Fre memory - XsqldaMarshaler.CleanUpNativeData(ref sqlda); - - // Marshal new structure - sqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, descriptor); - - _db.FbClient.isc_dsql_describe_bind( - _statusVector, - ref _handle, - IscCodes.SQLDA_VERSION1, - sqlda); + descriptor = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, sqlda); - descriptor = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, sqlda); - - // Free memory - XsqldaMarshaler.CleanUpNativeData(ref sqlda); - - // Parse status vector - _db.ProcessStatusVector(_statusVector); - } - else - { - if (descriptor.ActualCount == 0) - { - descriptor = new Descriptor(0); - } - } + XsqldaMarshaler.CleanUpNativeData(ref sqlda); - // Free memory - if (sqlda != IntPtr.Zero) + _db.ProcessStatusVector(_statusVector); + } + else + { + if (descriptor.ActualCount == 0) { - XsqldaMarshaler.CleanUpNativeData(ref sqlda); + descriptor = new Descriptor(0); } + } - // Update parameter descriptor - _parameters = descriptor; + if (sqlda != IntPtr.Zero) + { + XsqldaMarshaler.CleanUpNativeData(ref sqlda); } + + _parameters = descriptor; } #endregion @@ -598,67 +520,55 @@ protected override void Free(int option) return; } - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - _db.FbClient.isc_dsql_free_statement( - _statusVector, - ref _handle, - (short)option); + _db.FbClient.isc_dsql_free_statement( + _statusVector, + ref _handle, + (short)option); - // Reset statement information - if (option == IscCodes.DSQL_drop) - { - _parameters = null; - _fields = null; - } + if (option == IscCodes.DSQL_drop) + { + _parameters = null; + _fields = null; + } - Clear(); - _allRowsFetched = false; + Clear(); + _allRowsFetched = false; - _db.ProcessStatusVector(_statusVector); - } + _db.ProcessStatusVector(_statusVector); } protected override void TransactionUpdated(object sender, EventArgs e) { - lock (this) + if (Transaction != null && TransactionUpdate != null) { - if (Transaction != null && _TransactionUpdate != null) - { - Transaction.Update -= _TransactionUpdate; - } - Clear(); - State = StatementState.Closed; - _TransactionUpdate = null; - _allRowsFetched = false; + Transaction.Update -= TransactionUpdate; } + Clear(); + State = StatementState.Closed; + TransactionUpdate = null; + _allRowsFetched = false; } protected override byte[] GetSqlInfo(byte[] items, int bufferLength) { - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - byte[] buffer = new byte[bufferLength]; + byte[] buffer = new byte[bufferLength]; - _db.FbClient.isc_dsql_sql_info( - _statusVector, - ref _handle, - (short)items.Length, - items, - (short)bufferLength, - buffer); + _db.FbClient.isc_dsql_sql_info( + _statusVector, + ref _handle, + (short)items.Length, + items, + (short)bufferLength, + buffer); - _db.ProcessStatusVector(_statusVector); + _db.ProcessStatusVector(_statusVector); - return buffer; - } + return buffer; } #endregion @@ -688,24 +598,20 @@ private void ClearAll() private void Allocate() { - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - DatabaseHandle dbHandle = _db.HandlePtr; + DatabaseHandle dbHandle = _db.HandlePtr; - _db.FbClient.isc_dsql_allocate_statement( - _statusVector, - ref dbHandle, - ref _handle); + _db.FbClient.isc_dsql_allocate_statement( + _statusVector, + ref dbHandle, + ref _handle); - _db.ProcessStatusVector(_statusVector); + _db.ProcessStatusVector(_statusVector); - _allRowsFetched = false; - _state = StatementState.Allocated; - _statementType = DbStatementType.None; - } + _allRowsFetched = false; + _state = StatementState.Allocated; + _statementType = DbStatementType.None; } private void UpdateRecordsAffected() diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesTransaction.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesTransaction.cs index 799d506c..608b847a 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesTransaction.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesTransaction.cs @@ -81,7 +81,7 @@ public FesTransaction(IDatabase db) { if (!(db is FesDatabase)) { - throw new ArgumentException("Specified argument is not of FesDatabase type."); + throw new ArgumentException($"Specified argument is not of {nameof(FesDatabase)} type."); } _db = (FesDatabase)db; @@ -94,35 +94,20 @@ public FesTransaction(IDatabase db) #region IDisposable methods - protected override void Dispose(bool disposing) + public override void Dispose() { if (!_disposed) { - if (disposing) + _disposed = true; + if (_state != TransactionState.NoTransaction) { - try - { - if (_state != TransactionState.NoTransaction) - { - Rollback(); - } - } - catch - { } - finally - { - if (disposing) - { - _db = null; - _handle.Dispose(); - _state = TransactionState.NoTransaction; - _statusVector = null; - } - - _disposed = true; - base.Dispose(disposing); - } + Rollback(); } + _db = null; + _handle.Dispose(); + _state = TransactionState.NoTransaction; + _statusVector = null; + base.Dispose(); } } @@ -137,68 +122,56 @@ public override void BeginTransaction(TransactionParameterBuffer tpb) throw new InvalidOperationException(); } - lock (_db) - { - IscTeb teb = new IscTeb(); - IntPtr tebData = IntPtr.Zero; + IscTeb teb = new IscTeb(); + IntPtr tebData = IntPtr.Zero; - try - { - // Clear the status vector - ClearStatusVector(); + try + { + ClearStatusVector(); - // Set db handle - teb.dbb_ptr = Marshal.AllocHGlobal(4); - Marshal.WriteInt32(teb.dbb_ptr, _db.Handle); + teb.dbb_ptr = Marshal.AllocHGlobal(4); + Marshal.WriteInt32(teb.dbb_ptr, _db.Handle); - // Set tpb length - teb.tpb_len = tpb.Length; + teb.tpb_len = tpb.Length; - // Set TPB data - teb.tpb_ptr = Marshal.AllocHGlobal(tpb.Length); - Marshal.Copy(tpb.ToArray(), 0, teb.tpb_ptr, tpb.Length); + teb.tpb_ptr = Marshal.AllocHGlobal(tpb.Length); + Marshal.Copy(tpb.ToArray(), 0, teb.tpb_ptr, tpb.Length); - // Alloc memory for the IscTeb structure - int size = Marshal2.SizeOf(); - tebData = Marshal.AllocHGlobal(size); + int size = Marshal2.SizeOf(); + tebData = Marshal.AllocHGlobal(size); - Marshal.StructureToPtr(teb, tebData, true); + Marshal.StructureToPtr(teb, tebData, true); - _db.FbClient.isc_start_multiple( - _statusVector, - ref _handle, - 1, - tebData); + _db.FbClient.isc_start_multiple( + _statusVector, + ref _handle, + 1, + tebData); - // Parse status vector - _db.ProcessStatusVector(_statusVector); + _db.ProcessStatusVector(_statusVector); - // Update transaction state - _state = TransactionState.Active; + _state = TransactionState.Active; - // Update transaction count - _db.TransactionCount++; + _db.TransactionCount++; + } + catch + { + throw; + } + finally + { + if (teb.dbb_ptr != IntPtr.Zero) + { + Marshal.FreeHGlobal(teb.dbb_ptr); } - catch + if (teb.tpb_ptr != IntPtr.Zero) { - throw; + Marshal.FreeHGlobal(teb.tpb_ptr); } - finally + if (tebData != IntPtr.Zero) { - // Free memory - if (teb.dbb_ptr != IntPtr.Zero) - { - Marshal.FreeHGlobal(teb.dbb_ptr); - } - if (teb.tpb_ptr != IntPtr.Zero) - { - Marshal.FreeHGlobal(teb.tpb_ptr); - } - if (tebData != IntPtr.Zero) - { - Marshal2.DestroyStructure(tebData); - Marshal.FreeHGlobal(tebData); - } + Marshal2.DestroyStructure(tebData); + Marshal.FreeHGlobal(tebData); } } } @@ -207,76 +180,60 @@ public override void Commit() { EnsureActiveTransactionState(); - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - _db.FbClient.isc_commit_transaction(_statusVector, ref _handle); + _db.FbClient.isc_commit_transaction(_statusVector, ref _handle); - _db.ProcessStatusVector(_statusVector); + _db.ProcessStatusVector(_statusVector); - _db.TransactionCount--; + _db.TransactionCount--; - Update?.Invoke(this, new EventArgs()); + Update?.Invoke(this, new EventArgs()); - _state = TransactionState.NoTransaction; - } + _state = TransactionState.NoTransaction; } public override void Rollback() { EnsureActiveTransactionState(); - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - _db.FbClient.isc_rollback_transaction(_statusVector, ref _handle); + _db.FbClient.isc_rollback_transaction(_statusVector, ref _handle); - _db.ProcessStatusVector(_statusVector); + _db.ProcessStatusVector(_statusVector); - _db.TransactionCount--; + _db.TransactionCount--; - Update?.Invoke(this, new EventArgs()); + Update?.Invoke(this, new EventArgs()); - _state = TransactionState.NoTransaction; - } + _state = TransactionState.NoTransaction; } public override void CommitRetaining() { EnsureActiveTransactionState(); - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - _db.FbClient.isc_commit_retaining(_statusVector, ref _handle); + _db.FbClient.isc_commit_retaining(_statusVector, ref _handle); - _db.ProcessStatusVector(_statusVector); + _db.ProcessStatusVector(_statusVector); - _state = TransactionState.Active; - } + _state = TransactionState.Active; } public override void RollbackRetaining() { EnsureActiveTransactionState(); - lock (_db) - { - // Clear the status vector - ClearStatusVector(); + ClearStatusVector(); - _db.FbClient.isc_rollback_retaining(_statusVector, ref _handle); + _db.FbClient.isc_rollback_retaining(_statusVector, ref _handle); - _db.ProcessStatusVector(_statusVector); + _db.ProcessStatusVector(_statusVector); - _state = TransactionState.Active; - } + _state = TransactionState.Active; } #endregion diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/Handle/FirebirdHandle.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/Handle/FirebirdHandle.cs index 162e94ca..2cd5181d 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/Handle/FirebirdHandle.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/Handle/FirebirdHandle.cs @@ -37,7 +37,7 @@ protected FirebirdHandle() // Method added because we can't inject IFbClient in ctor public void SetClient(IFbClient fbClient) { - Contract.Requires(_fbClient == null); // We shouldn't set this if already set + Contract.Requires(_fbClient == null); Contract.Requires(fbClient != null); Contract.Ensures(_fbClient != null); diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/Marshalers/ArrayDescMarshaler.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/Marshalers/ArrayDescMarshaler.cs index 0b3318ee..5f06beca 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/Marshalers/ArrayDescMarshaler.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/Marshalers/ArrayDescMarshaler.cs @@ -32,16 +32,13 @@ public static void CleanUpNativeData(ref IntPtr pNativeData) { if (pNativeData != IntPtr.Zero) { - // Destroy ArrayDescMarshal structure Marshal2.DestroyStructure(pNativeData); - // Destroy ArrayBound structures for (int i = 0; i < 16; i++) { Marshal2.DestroyStructure(pNativeData + ArrayDescMarshal.ComputeLength(i)); } - // Free pointer memory Marshal.FreeHGlobal(pNativeData); pNativeData = IntPtr.Zero; diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/Marshalers/XsqldaMarshaler.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/Marshalers/XsqldaMarshaler.cs index 925e89b7..830acfda 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/Marshalers/XsqldaMarshaler.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/Marshalers/XsqldaMarshaler.cs @@ -36,18 +36,14 @@ public static void CleanUpNativeData(ref IntPtr pNativeData) { if (pNativeData != IntPtr.Zero) { - // Obtain XSQLDA information XSQLDA xsqlda = Marshal2.PtrToStructure(pNativeData); - // Destroy XSQLDA structure Marshal2.DestroyStructure(pNativeData); - // Destroy XSQLVAR structures for (var i = 0; i < xsqlda.sqln; i++) { IntPtr ptr = GetIntPtr(pNativeData, ComputeLength(i)); - // Free sqldata and sqlind pointers if needed var sqlvar = new XSQLVAR(); MarshalXSQLVARNativeToManaged(ptr, sqlvar, true); @@ -66,7 +62,6 @@ public static void CleanUpNativeData(ref IntPtr pNativeData) Marshal2.DestroyStructure(ptr); } - // Free pointer memory Marshal.FreeHGlobal(pNativeData); pNativeData = IntPtr.Zero; @@ -75,7 +70,6 @@ public static void CleanUpNativeData(ref IntPtr pNativeData) public static IntPtr MarshalManagedToNative(Charset charset, Descriptor descriptor) { - // Set up XSQLDA structure var xsqlda = new XSQLDA { version = descriptor.Version, @@ -87,7 +81,6 @@ public static IntPtr MarshalManagedToNative(Charset charset, Descriptor descript for (var i = 0; i < xsqlvar.Length; i++) { - // Create a new XSQLVAR structure and fill it xsqlvar[i] = new XSQLVAR { sqltype = descriptor[i].DataType, @@ -97,7 +90,6 @@ public static IntPtr MarshalManagedToNative(Charset charset, Descriptor descript }; - // Create a new pointer for the xsqlvar data if (descriptor[i].HasDataType() && descriptor[i].DbDataType != DbDataType.Null) { var buffer = descriptor[i].DbValue.GetBytes(); @@ -109,23 +101,18 @@ public static IntPtr MarshalManagedToNative(Charset charset, Descriptor descript xsqlvar[i].sqldata = Marshal.AllocHGlobal(0); } - // Create a new pointer for the sqlind value xsqlvar[i].sqlind = Marshal.AllocHGlobal(Marshal2.SizeOf()); Marshal.WriteInt16(xsqlvar[i].sqlind, descriptor[i].NullFlag); - // Name xsqlvar[i].sqlname = GetStringBuffer(charset, descriptor[i].Name); xsqlvar[i].sqlname_length = (short)descriptor[i].Name.Length; - // Relation Name xsqlvar[i].relname = GetStringBuffer(charset, descriptor[i].Relation); xsqlvar[i].relname_length = (short)descriptor[i].Relation.Length; - // Owner name xsqlvar[i].ownername = GetStringBuffer(charset, descriptor[i].Owner); xsqlvar[i].ownername_length = (short)descriptor[i].Owner.Length; - // Alias name xsqlvar[i].aliasname = GetStringBuffer(charset, descriptor[i].Alias); xsqlvar[i].aliasname_length = (short)descriptor[i].Alias.Length; } @@ -156,31 +143,25 @@ public static Descriptor MarshalNativeToManaged(Charset charset, IntPtr pNativeD public static Descriptor MarshalNativeToManaged(Charset charset, IntPtr pNativeData, bool fetching) { - // Obtain XSQLDA information var xsqlda = Marshal2.PtrToStructure(pNativeData); - // Create a new Descriptor var descriptor = new Descriptor(xsqlda.sqln) { ActualCount = xsqlda.sqld }; - // Obtain XSQLVAR members information var xsqlvar = new XSQLVAR(); for (var i = 0; i < xsqlda.sqln; i++) { var ptr = GetIntPtr(pNativeData, ComputeLength(i)); MarshalXSQLVARNativeToManaged(ptr, xsqlvar); - // Map XSQLVAR information to Descriptor descriptor[i].DataType = xsqlvar.sqltype; descriptor[i].NumericScale = xsqlvar.sqlscale; descriptor[i].SubType = xsqlvar.sqlsubtype; descriptor[i].Length = xsqlvar.sqllen; - // Decode sqlind value descriptor[i].NullFlag = xsqlvar.sqlind == IntPtr.Zero ? (short)0 : Marshal.ReadInt16(xsqlvar.sqlind); - // Set value if (fetching) { if (descriptor[i].NullFlag != -1) diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ArrayBase.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ArrayBase.cs index 542dc621..9a182372 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ArrayBase.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ArrayBase.cs @@ -38,32 +38,15 @@ internal abstract class ArrayBase #region Properties - public ArrayDesc Descriptor - { - get { return _descriptor; } - } + public ArrayDesc Descriptor => _descriptor; #endregion #region Abstract Properties - public abstract long Handle - { - get; - set; - } - - public abstract IDatabase DB - { - get; - set; - } - - public abstract TransactionBase Transaction - { - get; - set; - } + public abstract long Handle { get; set; } + public abstract IDatabase DB { get; set; } + public abstract TransactionBase Transaction { get; set; } #endregion @@ -94,13 +77,13 @@ public Array Read() return DecodeSlice(slice); } - public void Write(System.Array sourceArray) + public void Write(Array sourceArray) { SetDesc(sourceArray); PutSlice(sourceArray, GetSliceLength(false)); } - public void SetDesc(System.Array sourceArray) + public void SetDesc(Array sourceArray) { _descriptor.Dimensions = (short)sourceArray.Rank; @@ -199,13 +182,13 @@ protected Type GetSystemType() #region Abstract Methods public abstract byte[] GetSlice(int slice_length); - public abstract void PutSlice(System.Array source_array, int slice_length); + public abstract void PutSlice(Array source_array, int slice_length); #endregion #region Protected Abstract Methods - protected abstract System.Array DecodeSlice(byte[] slice); + protected abstract Array DecodeSlice(byte[] slice); #endregion diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ArrayBound.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ArrayBound.cs index d87d0977..2c7df6d1 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ArrayBound.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ArrayBound.cs @@ -22,27 +22,7 @@ namespace FirebirdSql.Data.Common { internal struct ArrayBound { - #region Fields - - private int lowerBound; - private int upperBound; - - #endregion - - #region Properties - - public int LowerBound - { - get { return lowerBound; } - set { lowerBound = value; } - } - - public int UpperBound - { - get { return upperBound; } - set { upperBound = value; } - } - - #endregion + public int LowerBound { get; set; } + public int UpperBound { get; set; } } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ArrayDesc.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ArrayDesc.cs index 745e09e1..6e9f9682 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ArrayDesc.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ArrayDesc.cs @@ -23,77 +23,15 @@ namespace FirebirdSql.Data.Common { internal struct ArrayDesc { - #region Fields - - private byte dataType; - private short scale; - private short length; - private string fieldName; - private string relationName; - private short dimensions; - private short flags; - private ArrayBound[] bounds; - - #endregion - - #region Properties - - public byte DataType - { - get { return dataType; } - set { dataType = value; } - } - - // Scale for numeric datatypes - public short Scale - { - get { return scale; } - set { scale = value; } - } - - // Legth in bytes of each array element - public short Length - { - get { return length; } - set { length = value; } - } - - // Column name - 32 - public string FieldName - { - get { return fieldName; } - set { fieldName = value; } - } - - // Table name -32 - public string RelationName - { - get { return relationName; } - set { relationName = value; } - } - - // Number of array dimensions - public short Dimensions - { - get { return dimensions; } - set { dimensions = value; } - } - + public byte DataType { get; set; } + public short Scale { get; set; } + public short Length { get; set; } + public string FieldName { get; set; } + public string RelationName { get; set; } + public short Dimensions { get; set; } // Specifies wheter array is to be accesed in // row mayor or column-mayor order - public short Flags - { - get { return flags; } - set { flags = value; } - } - - // Lower and upper bounds for each dimension - 16 - public ArrayBound[] Bounds - { - get { return bounds; } - set { bounds = value; } - } - - #endregion + public short Flags { get; set; } + public ArrayBound[] Bounds { get; set; } } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/BinaryEncoding.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/BinaryEncoding.cs index bc060c95..c9b1b946 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/BinaryEncoding.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/BinaryEncoding.cs @@ -16,8 +16,6 @@ namespace FirebirdSql.Data.Common { internal class BinaryEncoding : Encoding { - #region Static Methods - public static string BytesToString(byte[] byteArray) { // This code isn't great because it requires a double copy, @@ -41,10 +39,6 @@ static void Validate(object data, int dataLength, int index, int count) } } - #endregion - - #region Methods - public override int GetByteCount(char[] chars, int index, int count) { Validate(chars, chars.Length, index, count); @@ -151,7 +145,5 @@ public override int GetMaxCharCount(int count) { return count; } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/BlobBase.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/BlobBase.cs index 578631c4..0b16c76d 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/BlobBase.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/BlobBase.cs @@ -26,60 +26,21 @@ namespace FirebirdSql.Data.Common { internal abstract class BlobBase { - #region Fields - - private int _rblFlags; + private int _rblFlags; private Charset _charset; - private int _segmentSize; - - #endregion - - #region Properties - - public abstract int Handle - { - get; - } - - public long Id - { - get { return _blobId; } - } - - public bool EOF - { - get { return (_rblFlags & IscCodes.RBL_eof_pending) != 0; } - } + private int _segmentSize; - #endregion + protected long _blobId; + protected int _position; + protected TransactionBase _transaction; - #region Protected Fields + public abstract int Handle { get; } + public long Id => _blobId; + public bool EOF => (_rblFlags & IscCodes.RBL_eof_pending) != 0; - protected long _blobId; - protected int _position; - protected TransactionBase _transaction; + protected int SegmentSize => _segmentSize; - #endregion - - #region Protected Properties - - protected int SegmentSize - { - get { return _segmentSize; } - } - - #endregion - - #region Abstract Properties - - public abstract IDatabase Database - { - get; - } - - #endregion - - #region Constructors + public abstract IDatabase Database { get; } protected BlobBase(IDatabase db) { @@ -87,10 +48,6 @@ protected BlobBase(IDatabase db) _charset = db.Charset; } - #endregion - - #region Methods - public string ReadString() { byte[] buffer = Read(); @@ -141,13 +98,11 @@ public void Write(byte[] buffer, int index, int count) { Create(); - byte[] tmpBuffer = null; - - int length = count; - int offset = index; - int chunk = length >= _segmentSize ? _segmentSize : length; + int length = count; + int offset = index; + int chunk = length >= _segmentSize ? _segmentSize : length; - tmpBuffer = new byte[chunk]; + byte[] tmpBuffer = new byte[chunk]; while (length > 0) { @@ -175,10 +130,6 @@ public void Write(byte[] buffer, int index, int count) } } - #endregion - - #region Protected Abstract Methods - protected abstract void Create(); protected abstract void Open(); protected abstract byte[] GetSegment(); @@ -188,10 +139,6 @@ public void Write(byte[] buffer, int index, int count) protected abstract void Close(); protected abstract void Cancel(); - #endregion - - #region Protected Methods - protected void RblAddValue(int rblValue) { _rblFlags |= rblValue; @@ -201,7 +148,5 @@ protected void RblRemoveValue(int rblValue) { _rblFlags &= ~rblValue; } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/BlobParameterBuffer.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/BlobParameterBuffer.cs index bc198f64..45039855 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/BlobParameterBuffer.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/BlobParameterBuffer.cs @@ -25,12 +25,8 @@ namespace FirebirdSql.Data.Common { internal sealed class BlobParameterBuffer : ParameterBuffer { - #region Constructors - public BlobParameterBuffer() : base(BitConverter.IsLittleEndian) { } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/DatabaseParameterBuffer.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/DatabaseParameterBuffer.cs index 5d004c57..61cc2242 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/DatabaseParameterBuffer.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/DatabaseParameterBuffer.cs @@ -28,16 +28,10 @@ namespace FirebirdSql.Data.Common { internal sealed class DatabaseParameterBuffer : ParameterBuffer { - #region Constructors - public DatabaseParameterBuffer() : base(BitConverter.IsLittleEndian) { } - #endregion - - #region Methods - public void Append(int type, byte value) { WriteByte(type); @@ -70,7 +64,5 @@ public void Append(int type, byte[] buffer) WriteByte(buffer.Length); Write(buffer); } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/DbStatementType.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/DbStatementType.cs index d365fc20..cbf707da 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/DbStatementType.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/DbStatementType.cs @@ -22,20 +22,20 @@ namespace FirebirdSql.Data.Common { internal enum DbStatementType : int { - None = 0, - Select = IscCodes.isc_info_sql_stmt_select, - Insert = IscCodes.isc_info_sql_stmt_insert, - Update = IscCodes.isc_info_sql_stmt_update, - Delete = IscCodes.isc_info_sql_stmt_delete, - DDL = IscCodes.isc_info_sql_stmt_ddl, - GetSegment = IscCodes.isc_info_sql_stmt_get_segment, - PutSegment = IscCodes.isc_info_sql_stmt_put_segment, + None = 0, + Select = IscCodes.isc_info_sql_stmt_select, + Insert = IscCodes.isc_info_sql_stmt_insert, + Update = IscCodes.isc_info_sql_stmt_update, + Delete = IscCodes.isc_info_sql_stmt_delete, + DDL = IscCodes.isc_info_sql_stmt_ddl, + GetSegment = IscCodes.isc_info_sql_stmt_get_segment, + PutSegment = IscCodes.isc_info_sql_stmt_put_segment, StoredProcedure = IscCodes.isc_info_sql_stmt_exec_procedure, - StartTrans = IscCodes.isc_info_sql_stmt_start_trans, - Commit = IscCodes.isc_info_sql_stmt_commit, - Rollback = IscCodes.isc_info_sql_stmt_rollback, + StartTrans = IscCodes.isc_info_sql_stmt_start_trans, + Commit = IscCodes.isc_info_sql_stmt_commit, + Rollback = IscCodes.isc_info_sql_stmt_rollback, SelectForUpdate = IscCodes.isc_info_sql_stmt_select_for_upd, - SetGenerator = IscCodes.isc_info_sql_stmt_set_generator, - SavePoint = IscCodes.isc_info_sql_stmt_savepoint + SetGenerator = IscCodes.isc_info_sql_stmt_set_generator, + SavePoint = IscCodes.isc_info_sql_stmt_savepoint } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/EventParameterBuffer.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/EventParameterBuffer.cs index 9c3080d6..0d69add1 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/EventParameterBuffer.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/EventParameterBuffer.cs @@ -27,16 +27,10 @@ namespace FirebirdSql.Data.Common { internal sealed class EventParameterBuffer : ParameterBuffer { - #region Constructors - public EventParameterBuffer() : base(BitConverter.IsLittleEndian) { } - #endregion - - #region Methods - public void Append(string content, int actualCount) { Append(Encoding.UTF8.GetBytes(content), actualCount); @@ -48,7 +42,5 @@ public void Append(byte[] content, int actualCount) Write(content); Write(actualCount); } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IDatabase.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IDatabase.cs index 5e7a3291..12cc2bd1 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IDatabase.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IDatabase.cs @@ -27,65 +27,15 @@ namespace FirebirdSql.Data.Common { internal interface IDatabase : IDisposable { - #region Callbacks + WarningMessageCallback WarningMessage { get; set; } - WarningMessageCallback WarningMessage - { - get; - set; - } - - #endregion - - #region Properties - - int Handle - { - get; - } - - int TransactionCount - { - get; - set; - } - - string ServerVersion - { - get; - } - - Charset Charset - { - get; - set; - } - - short PacketSize - { - get; - set; - } - - short Dialect - { - get; - set; - } - - bool HasRemoteEventSupport - { - get; - } - - object SyncObject - { - get; - } - - #endregion - - #region Methods + int Handle { get; } + int TransactionCount { get; set; } + string ServerVersion { get; } + Charset Charset { get; set; } + short PacketSize { get; set; } + short Dialect { get; set; } + bool HasRemoteEventSupport { get; } void Attach(DatabaseParameterBuffer dpb, string dataSource, int port, string database); void AttachWithTrustedAuth(DatabaseParameterBuffer dpb, string dataSource, int port, string database); @@ -108,7 +58,5 @@ object SyncObject void CancelEvents(RemoteEvent events); void CancelOperation(int kind); - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IServiceManager.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IServiceManager.cs index 9abb898b..445e1f3a 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IServiceManager.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IServiceManager.cs @@ -25,26 +25,11 @@ namespace FirebirdSql.Data.Common { internal interface IServiceManager { - #region Properties - - int Handle - { - get; - } - - #endregion - - #region Methods + int Handle { get; } void Attach(ServiceParameterBuffer spb, string dataSource, int port, string service); - void Detach(); - void Start(ServiceParameterBuffer spb); - - void Query(ServiceParameterBuffer spb, int requestLength, - byte[] requestBuffer, int bufferLength, byte[] buffer); - - #endregion + void Query(ServiceParameterBuffer spb, int requestLength, byte[] requestBuffer, int bufferLength, byte[] buffer); } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IscError.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IscError.cs index e7a9e990..3fe14f9d 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IscError.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IscError.cs @@ -29,33 +29,17 @@ namespace FirebirdSql.Data.Common #endif internal sealed class IscError { - #region Fields + private string _strParam; - private string _message; - private int _type; - private int _errorCode; - private string _strParam; - - #endregion - - #region Properties - - public string Message - { - get { return _message; } - set { _message = value; } - } - - public int ErrorCode - { - get { return _errorCode; } - } + public string Message { get; set; } + public int ErrorCode { get; } + public int Type { get; } public string StrParam { get { - switch (_type) + switch (Type) { case IscCodes.isc_arg_interpreted: case IscCodes.isc_arg_string: @@ -64,7 +48,7 @@ public string StrParam return _strParam; case IscCodes.isc_arg_number: - return _errorCode.ToString(CultureInfo.InvariantCulture); + return ErrorCode.ToString(CultureInfo.InvariantCulture); default: return string.Empty; @@ -72,16 +56,11 @@ public string StrParam } } - public int Type - { - get { return _type; } - } - public bool IsArgument { get { - switch (_type) + switch (Type) { case IscCodes.isc_arg_interpreted: case IscCodes.isc_arg_string: @@ -97,30 +76,24 @@ public bool IsArgument public bool IsWarning { - get { return _type == IscCodes.isc_arg_warning; } + get { return Type == IscCodes.isc_arg_warning; } } - #endregion - - #region Constructors - internal IscError(int errorCode) { - _errorCode = errorCode; + ErrorCode = errorCode; } internal IscError(int type, string strParam) { - _type = type; + Type = type; _strParam = strParam; } internal IscError(int type, int errorCode) { - _type = type; - _errorCode = errorCode; + Type = type; + ErrorCode = errorCode; } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IscException.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IscException.cs index 02d49ff3..86585111 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IscException.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/IscException.cs @@ -26,6 +26,7 @@ using System.Text; using System.Reflection; using System.Resources; +using System.Linq; #if !NETCORE10 using System.Runtime.Serialization; #endif @@ -37,41 +38,13 @@ namespace FirebirdSql.Data.Common #endif internal sealed class IscException : Exception { -#region Fields private string _message; -#endregion - -#region Properties public List Errors { get; private set; } - - public override string Message - { - get { return _message; } - } - public int ErrorCode { get; private set; } - public string SQLSTATE { get; private set; } - - public bool IsWarning - { - get - { - if (Errors.Count > 0) - { - return Errors[0].IsWarning; - } - else - { - return false; - } - } - } - -#endregion - -#region Constructors + public override string Message => _message; + public bool IsWarning => Errors.FirstOrDefault()?.IsWarning ?? false; private IscException(Exception innerException = null) : base(innerException?.Message, innerException) @@ -151,15 +124,11 @@ public static IscException ForTypeErrorCodeIntParamStrParam(int type, int errorC private IscException(SerializationInfo info, StreamingContext context) : base(info, context) { - Errors = (List)info.GetValue("errors", typeof(List)); - ErrorCode = info.GetInt32("errorCode"); + Errors = (List)info.GetValue(nameof(Errors), typeof(List)); + ErrorCode = info.GetInt32(nameof(ErrorCode)); } #endif -#endregion - -#region Public Methods - public void BuildExceptionData() { BuildErrorCode(); @@ -171,20 +140,12 @@ public void BuildExceptionData() public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); - - info.AddValue("errors", Errors); - info.AddValue("errorCode", ErrorCode); + info.AddValue(nameof(Errors), Errors); + info.AddValue(nameof(ErrorCode), ErrorCode); } #endif - public override string ToString() - { - return _message; - } - -#endregion - -#region Private Methods + public override string ToString() => _message; private void BuildErrorCode() { @@ -270,10 +231,6 @@ private string BuildDefaultErrorMessage(int code) return string.Format(CultureInfo.CurrentCulture, "No message for error code {0} found.", code); } -#endregion - -#region Static Methods - private static string GetValueOrDefault(IDictionary dictionary, int key, Func defaultValueFactory) { string result; @@ -292,7 +249,5 @@ private static void AppendMessage(StringBuilder builder, string message, List (short)ToArray().Length; + protected bool IsLittleEndian { get; } protected ParameterBuffer(bool isLittleEndian) { _stream = new MemoryStream(); - _isLittleEndian = isLittleEndian; + IsLittleEndian = isLittleEndian; } - #endregion - - #region Methods - public virtual void Append(int type) { WriteByte(type); @@ -75,10 +49,6 @@ public byte[] ToArray() return _stream.ToArray(); } - #endregion - - #region Protected Methods - protected void WriteByte(int value) { WriteByte((byte)value); @@ -127,7 +97,5 @@ protected void Write(byte[] buffer, int offset, int count) { _stream.Write(buffer, offset, count); } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/RemoteEvent.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/RemoteEvent.cs index 054a8d74..9a762780 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/RemoteEvent.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/RemoteEvent.cs @@ -28,24 +28,19 @@ internal class RemoteEvent { #region Callbacks - public RemoteEventCountsCallback EventCountsCallback - { - get { return _eventCountsCallback; } - set { _eventCountsCallback = value; } - } + public RemoteEventCountsCallback EventCountsCallback { get; set; } #endregion #region Fields - private RemoteEventCountsCallback _eventCountsCallback; - private List _events; - private IDatabase _db; - private int _localId; - private int _remoteId; - private bool _initialCounts; - private int[] _previousCounts; - private int[] _actualCounts; + private List _events; + private IDatabase _db; + private int _localId; + private int _remoteId; + private bool _initialCounts; + private int[] _previousCounts; + private int[] _actualCounts; #endregion @@ -65,39 +60,7 @@ public int RemoteId public List Events { - get - { - return _events; - } - } - - public bool HasChanges - { - get - { - if (_actualCounts == null && _previousCounts == null) - { - return false; - } - else if (_actualCounts != null && _previousCounts == null) - { - return true; - } - else if (_actualCounts.Length != _previousCounts.Length) - { - return true; - } - - for (int i = 0; i < _actualCounts.Length; i++) - { - if (_actualCounts[i] != _previousCounts[i]) - { - return true; - } - } - - return false; - } + get { return _events; } } public int[] PreviousCounts @@ -114,16 +77,12 @@ public int[] ActualCounts #region Constructors - public RemoteEvent(IDatabase db) : this(db, 0, 0, new List()) - { - } - - public RemoteEvent(IDatabase db, int localId, int remoteId, List events) + public RemoteEvent(IDatabase db) { + _localId = 0; + _remoteId = 0; + _events = new List(); _db = db; - _localId = localId; - _remoteId = remoteId; - _events = events; } #endregion @@ -132,19 +91,13 @@ public RemoteEvent(IDatabase db, int localId, int remoteId, List events) public void QueueEvents() { - lock (_db.SyncObject) - { - _db.QueueEvents(this); - } + _db.QueueEvents(this); } public void CancelEvents() { - lock (_db.SyncObject) - { - _db.CancelEvents(this); - ResetCounts(); - } + _db.CancelEvents(this); + ResetCounts(); } public void ResetCounts() @@ -199,9 +152,7 @@ public void EventCounts(byte[] buffer) public EventParameterBuffer ToEpb() { EventParameterBuffer epb = new EventParameterBuffer(); - epb.Append(IscCodes.EPB_version1); - for (int i = 0; i < _events.Count; i++) { if (_actualCounts != null) @@ -213,7 +164,6 @@ public EventParameterBuffer ToEpb() epb.Append(_events[i], 0); } } - return epb; } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ServiceParameterBuffer.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ServiceParameterBuffer.cs index 8b58bc61..b9c62262 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ServiceParameterBuffer.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/ServiceParameterBuffer.cs @@ -27,16 +27,10 @@ namespace FirebirdSql.Data.Common { internal sealed class ServiceParameterBuffer : ParameterBuffer { - #region Constructors - public ServiceParameterBuffer() : base(BitConverter.IsLittleEndian) { } - #endregion - - #region Methods - public void Append(int type, byte value) { WriteByte(type); @@ -72,7 +66,5 @@ public void Append(byte type, byte[] value) WriteByte((byte)value.Length); Write(value); } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/StatementBase.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/StatementBase.cs index 99110e30..92dd94ed 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/StatementBase.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/StatementBase.cs @@ -81,89 +81,28 @@ internal abstract class StatementBase : IDisposable #region Protected Fields - protected EventHandler _TransactionUpdate; + protected EventHandler TransactionUpdate; #endregion #region Abstract Properties - public abstract IDatabase Database - { - get; - } - - public abstract TransactionBase Transaction - { - get; - set; - } - - public abstract Descriptor Parameters - { - get; - set; - } - - public abstract Descriptor Fields - { - get; - } - - public abstract int RecordsAffected - { - get; - protected set; - } - - public abstract bool IsPrepared - { - get; - } - - public abstract DbStatementType StatementType - { - get; - protected set; - } - - public abstract StatementState State - { - get; - protected set; - } - - public abstract int FetchSize - { - get; - set; - } - - public abstract bool ReturnRecordsAffected - { - get; - set; - } - - #endregion - - #region Finalizer - - ~StatementBase() - { - Dispose(false); - } + public abstract IDatabase Database { get; } + public abstract TransactionBase Transaction { get; set; } + public abstract Descriptor Parameters { get; set; } + public abstract Descriptor Fields { get; } + public abstract int RecordsAffected { get; protected set; } + public abstract bool IsPrepared { get; } + public abstract DbStatementType StatementType { get; protected set; } + public abstract StatementState State { get; protected set; } + public abstract int FetchSize { get; set; } + public abstract bool ReturnRecordsAffected { get; set; } #endregion #region IDisposable methods - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) + public virtual void Dispose() { } #endregion @@ -232,10 +171,10 @@ public virtual void Close() public virtual void Release() { - if (Transaction != null && _TransactionUpdate != null) + if (Transaction != null && TransactionUpdate != null) { - Transaction.Update -= _TransactionUpdate; - _TransactionUpdate = null; + Transaction.Update -= TransactionUpdate; + TransactionUpdate = null; } Free(IscCodes.DSQL_drop); diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/TransactionBase.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/TransactionBase.cs index 988aee25..d343d5c6 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/TransactionBase.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/TransactionBase.cs @@ -44,18 +44,7 @@ protected void EnsureActiveTransactionState() public abstract void Prepare(); public abstract void Prepare(byte[] buffer); - ~TransactionBase() - { - Dispose(false); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) + public virtual void Dispose() { } } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/TransactionParameterBuffer.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/TransactionParameterBuffer.cs index 2ccb175a..70b61153 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Common/TransactionParameterBuffer.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Common/TransactionParameterBuffer.cs @@ -26,16 +26,10 @@ namespace FirebirdSql.Data.Common { internal sealed class TransactionParameterBuffer : ParameterBuffer { - #region Constructors - public TransactionParameterBuffer() : base(BitConverter.IsLittleEndian) { } - #endregion - - #region Methods - public void Append(int type, short value) { WriteByte(type); @@ -54,7 +48,5 @@ public void Append(int type, byte[] buffer) WriteByte(buffer.Length); Write(buffer); } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbCommand.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbCommand.cs index 1d7c4840..4ef5e479 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbCommand.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbCommand.cs @@ -41,7 +41,7 @@ public sealed class FbCommand : DbCommand , ICloneable #endif { -#region Fields + #region Fields private CommandType _commandType; private UpdateRowSource _updatedRowSource; @@ -59,9 +59,9 @@ public sealed class FbCommand : DbCommand private int _fetchSize; private Type[] _expectedColumnTypes; -#endregion + #endregion -#region Properties + #region Properties [Category("Data")] [DefaultValue("")] @@ -71,15 +71,12 @@ public override string CommandText get { return _commandText; } set { - lock (this) + if (_commandText != value && _statement != null) { - if (_commandText != value && _statement != null) - { - Release(); - } - - _commandText = value; + Release(); } + + _commandText = value; } } @@ -125,27 +122,24 @@ public new FbConnection Connection get { return _connection; } set { - lock (this) + if (_activeReader != null) { - if (_activeReader != null) - { - throw new InvalidOperationException("There is already an open DataReader associated with this Command which must be closed first."); - } - - if (_transaction != null && _transaction.IsCompleted) - { - _transaction = null; - } + throw new InvalidOperationException("There is already an open DataReader associated with this Command which must be closed first."); + } - if (_connection != null && - _connection != value && - _connection.State == ConnectionState.Open) - { - Release(); - } + if (_transaction != null && _transaction.IsCompleted) + { + _transaction = null; + } - _connection = value; + if (_connection != null && + _connection != value && + _connection.State == ConnectionState.Open) + { + Release(); } + + _connection = value; } } @@ -170,27 +164,24 @@ public new FbTransaction Transaction get { return _implicitTransaction ? null : _transaction; } set { - lock (this) + if (_activeReader != null) { - if (_activeReader != null) - { - throw new InvalidOperationException("There is already an open DataReader associated with this Command which must be closed first."); - } + throw new InvalidOperationException("There is already an open DataReader associated with this Command which must be closed first."); + } - RollbackImplicitTransaction(); + RollbackImplicitTransaction(); - _transaction = value; + _transaction = value; - if (_statement != null) + if (_statement != null) + { + if (_transaction != null) { - if (_transaction != null) - { - _statement.Transaction = _transaction.Transaction; - } - else - { - _statement.Transaction = null; - } + _statement.Transaction = _transaction.Transaction; + } + else + { + _statement.Transaction = null; } } } @@ -219,9 +210,9 @@ public int FetchSize } } -#endregion + #endregion -#region Protected DbCommand Properties + #region Protected DbCommand Properties protected override DbConnection DbConnection { @@ -240,9 +231,9 @@ protected override DbParameterCollection DbParameterCollection get { return Parameters; } } -#endregion + #endregion -#region Design-Time properties + #region Design-Time properties [Browsable(false)] [DesignOnly(true)] @@ -257,9 +248,9 @@ public override bool DesignTimeVisible } } -#endregion + #endregion -#region Internal Properties + #region Internal Properties internal int RecordsAffected { @@ -309,9 +300,9 @@ internal Type[] ExpectedColumnTypes get { return _expectedColumnTypes; } } -#endregion + #endregion -#region Constructors + #region Constructors public FbCommand() : this(null, null, null) @@ -360,46 +351,33 @@ public static FbCommand CreateWithTypeCoercions(Type[] expectedColumnTypes) return result; } -#endregion + #endregion -#region IDisposable methods + #region IDisposable methods protected override void Dispose(bool disposing) { - lock (this) + if (disposing) { if (!_disposed) { - try - { - // Release any unmanaged resources - Release(); - - if (disposing) - { - // release any managed resources - _commandTimeout = 0; - _fetchSize = 0; - _implicitTransaction = false; - _commandText = null; - _connection = null; - _transaction = null; - _parameters = null; - _statement = null; - _activeReader = null; - - if (_namedParameters != null) - { - _namedParameters.Clear(); - _namedParameters = null; - } - } - } - finally + _disposed = true; + Release(); + _commandTimeout = 0; + _fetchSize = 0; + _implicitTransaction = false; + _commandText = null; + _connection = null; + _transaction = null; + _parameters = null; + _statement = null; + _activeReader = null; + if (_namedParameters != null) { - _disposed = true; - base.Dispose(disposing); + _namedParameters.Clear(); + _namedParameters = null; } + base.Dispose(disposing); } } } @@ -442,9 +420,9 @@ object ICloneable.Clone() return command; } -#endregion + #endregion -#region Methods + #region Methods public override void Cancel() { @@ -458,58 +436,52 @@ public new FbParameter CreateParameter() public override void Prepare() { - lock (this) - { - CheckCommand(); + CheckCommand(); - try - { - Prepare(false); - } - catch (IscException ex) - { - DiscardImplicitTransaction(); + try + { + Prepare(false); + } + catch (IscException ex) + { + DiscardImplicitTransaction(); - throw new FbException(ex.Message, ex); - } - catch - { - DiscardImplicitTransaction(); + throw new FbException(ex.Message, ex); + } + catch + { + DiscardImplicitTransaction(); - throw; - } + throw; } } public override int ExecuteNonQuery() { - lock (this) + CheckCommand(); + + try { - CheckCommand(); + ExecuteCommand(CommandBehavior.Default); - try + if (_statement.StatementType == DbStatementType.StoredProcedure) { - ExecuteCommand(CommandBehavior.Default); - - if (_statement.StatementType == DbStatementType.StoredProcedure) - { - SetOutputParameters(); - } - - CommitImplicitTransaction(); + SetOutputParameters(); } - catch (IscException ex) - { - DiscardImplicitTransaction(); - throw new FbException(ex.Message, ex); - } - catch - { - DiscardImplicitTransaction(); + CommitImplicitTransaction(); + } + catch (IscException ex) + { + DiscardImplicitTransaction(); - throw; - } + throw new FbException(ex.Message, ex); + } + catch + { + DiscardImplicitTransaction(); + + throw; } return RecordsAffected; @@ -532,26 +504,23 @@ public new FbDataReader ExecuteReader() } public new FbDataReader ExecuteReader(CommandBehavior behavior) { - lock (this) - { - CheckCommand(); + CheckCommand(); - try - { - ExecuteCommand(behavior, true); - } - catch (IscException ex) - { - DiscardImplicitTransaction(); + try + { + ExecuteCommand(behavior, true); + } + catch (IscException ex) + { + DiscardImplicitTransaction(); - throw new FbException(ex.Message, ex); - } - catch - { - DiscardImplicitTransaction(); + throw new FbException(ex.Message, ex); + } + catch + { + DiscardImplicitTransaction(); - throw; - } + throw; } _activeReader = new FbDataReader(this, _connection, behavior); @@ -587,46 +556,43 @@ public override object ExecuteScalar() DbValue[] values = null; object val = null; - lock (this) + CheckCommand(); + + try { - CheckCommand(); + ExecuteCommand(CommandBehavior.Default); - try + // Gets only the values of the first row or + // the output parameters values if command is an Stored Procedure + if (_statement.StatementType == DbStatementType.StoredProcedure) { - ExecuteCommand(CommandBehavior.Default); - - // Gets only the values of the first row or - // the output parameters values if command is an Stored Procedure - if (_statement.StatementType == DbStatementType.StoredProcedure) - { - values = _statement.GetOutputParameters(); - SetOutputParameters(values); - } - else - { - values = _statement.Fetch(); - } - - // Get the return value - if (values != null && values.Length > 0) - { - val = values[0].Value; - } - - CommitImplicitTransaction(); + values = _statement.GetOutputParameters(); + SetOutputParameters(values); } - catch (IscException ex) + else { - DiscardImplicitTransaction(); - - throw new FbException(ex.Message, ex); + values = _statement.Fetch(); } - catch - { - DiscardImplicitTransaction(); - throw; + // Get the return value + if (values != null && values.Length > 0) + { + val = values[0].Value; } + + CommitImplicitTransaction(); + } + catch (IscException ex) + { + DiscardImplicitTransaction(); + + throw new FbException(ex.Message, ex); + } + catch + { + DiscardImplicitTransaction(); + + throw; } return val; @@ -643,9 +609,9 @@ public object EndExecuteScalar(IAsyncResult asyncResult) } #endif -#endregion + #endregion -#region DbCommand Protected Methods + #region DbCommand Protected Methods protected override DbParameter CreateDbParameter() { @@ -657,9 +623,9 @@ protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior) return ExecuteReader(behavior); } -#endregion + #endregion -#region Internal Methods + #region Internal Methods internal void DisposeReader() { @@ -820,19 +786,15 @@ internal void Close() internal void Release() { - // Rollback implicit transaction RollbackImplicitTransaction(); - // If there are an active reader close it DisposeReader(); - // Remove the command from the Prepared commands list if (_connection != null && _connection.State == ConnectionState.Open) { _connection.InnerConnection.RemovePreparedCommand(this); } - // Dipose the inner statement if (_statement != null) { _statement.Dispose(); @@ -840,9 +802,9 @@ internal void Release() } } -#endregion + #endregion -#region Input parameter descriptor generation methods + #region Input parameter descriptor generation methods private void DescribeInput() { @@ -1121,9 +1083,9 @@ private void UpdateParameterValues() } } -#endregion + #endregion -#region Private Methods + #region Private Methods private void Prepare(bool returnsSet) { @@ -1415,6 +1377,6 @@ private bool IsNullParameterValue(object value) return (value == DBNull.Value || value == null); } -#endregion + #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnection.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnection.cs index c5283daf..16ff92f7 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnection.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnection.cs @@ -101,8 +101,10 @@ private static void CreateDatabaseImpl(string connectionString, int pageSize = 4 dpb.Append(IscCodes.isc_dpb_page_size, pageSize); } - FbConnectionInternal db = new FbConnectionInternal(options); - db.CreateDatabase(dpb); + using (FbConnectionInternal db = new FbConnectionInternal(options)) + { + db.CreateDatabase(dpb); + } } catch (IscException ex) { @@ -117,8 +119,10 @@ public static void DropDatabase(string connectionString) try { - FbConnectionInternal db = new FbConnectionInternal(options); - db.DropDatabase(); + using (FbConnectionInternal db = new FbConnectionInternal(options)) + { + db.DropDatabase(); + } } catch (IscException ex) { @@ -159,19 +163,16 @@ public override string ConnectionString get { return _connectionString; } set { - lock (this) + if (_state == ConnectionState.Closed) { - if (_state == ConnectionState.Closed) + if (value == null) { - if (value == null) - { - value = string.Empty; - } - - _options.Load(value); - _options.Validate(); - _connectionString = value; + value = string.Empty; } + + _options.Load(value); + _options.Validate(); + _connectionString = value; } } } @@ -285,30 +286,16 @@ public FbConnection(string connectionString) protected override void Dispose(bool disposing) { - lock (this) + if (disposing) { if (!_disposed) { - try - { - // release any unmanaged resources - Close(); - - if (disposing) - { - // release any managed resources - _innerConnection = null; - _options = null; - _connectionString = null; - } - } - catch - { } - finally - { - _disposed = true; - base.Dispose(disposing); - } + _disposed = true; + Close(); + _innerConnection = null; + _options = null; + _connectionString = null; + base.Dispose(disposing); } } } @@ -424,115 +411,109 @@ public new FbCommand CreateCommand() public override void ChangeDatabase(string db) { - lock (this) - { - CheckClosed(); + CheckClosed(); - if (string.IsNullOrEmpty(db)) - { - throw new InvalidOperationException("Database name is not valid."); - } + if (string.IsNullOrEmpty(db)) + { + throw new InvalidOperationException("Database name is not valid."); + } - string cs = _connectionString; + string cs = _connectionString; - try - { - FbConnectionStringBuilder csb = new FbConnectionStringBuilder(_connectionString); + try + { + FbConnectionStringBuilder csb = new FbConnectionStringBuilder(_connectionString); - /* Close current connection */ - Close(); + /* Close current connection */ + Close(); - /* Set up the new Database */ - csb.Database = db; - ConnectionString = csb.ToString(); + /* Set up the new Database */ + csb.Database = db; + ConnectionString = csb.ToString(); - /* Open new connection */ - Open(); - } - catch (IscException ex) - { - ConnectionString = cs; - throw new FbException(ex.Message, ex); - } + /* Open new connection */ + Open(); + } + catch (IscException ex) + { + ConnectionString = cs; + throw new FbException(ex.Message, ex); } } public override void Open() { - lock (this) + if (string.IsNullOrEmpty(_connectionString)) + { + throw new InvalidOperationException("Connection String is not initialized."); + } + if (!IsClosed && _state != ConnectionState.Connecting) { - if (string.IsNullOrEmpty(_connectionString)) + throw new InvalidOperationException("Connection already Open."); + } +#if !NETCORE10 + if (_options.Enlist && System.Transactions.Transaction.Current == null) + { + throw new InvalidOperationException("There is no active TransactionScope to enlist transactions."); + } +#endif + + try + { + OnStateChange(_state, ConnectionState.Connecting); + + if (_options.Pooling) { - throw new InvalidOperationException("Connection String is not initialized."); + _innerConnection = FbConnectionPoolManager.Instance.Get(_options, this); } - if (!IsClosed && _state != ConnectionState.Connecting) + else { - throw new InvalidOperationException("Connection already Open."); + // Do not use Connection Pooling + _innerConnection = new FbConnectionInternal(_options); + _innerConnection.SetOwningConnection(this); + _innerConnection.Connect(); } + #if !NETCORE10 - if (_options.Enlist && System.Transactions.Transaction.Current == null) + try { - throw new InvalidOperationException("There is no active TransactionScope to enlist transactions."); + _innerConnection.EnlistTransaction(System.Transactions.Transaction.Current); } -#endif - - try + catch { - OnStateChange(_state, ConnectionState.Connecting); + // if enlistment fails clean up innerConnection + _innerConnection.DisposeTransaction(); if (_options.Pooling) { - _innerConnection = FbConnectionPoolManager.Instance.Get(_options, this); + // Send connection return back to the Pool + FbConnectionPoolManager.Instance.Release(_innerConnection); } else { - // Do not use Connection Pooling - _innerConnection = new FbConnectionInternal(_options); - _innerConnection.SetOwningConnection(this); - _innerConnection.Connect(); + _innerConnection.Dispose(); + _innerConnection = null; } -#if !NETCORE10 - try - { - _innerConnection.EnlistTransaction(System.Transactions.Transaction.Current); - } - catch - { - // if enlistment fails clean up innerConnection - _innerConnection.DisposeTransaction(); - - if (_options.Pooling) - { - // Send connection return back to the Pool - FbConnectionPoolManager.Instance.Release(_innerConnection); - } - else - { - _innerConnection.Dispose(); - _innerConnection = null; - } - - throw; - } + throw; + } #endif - // Bind Warning messages event - _innerConnection.Database.WarningMessage = new WarningMessageCallback(OnWarningMessage); + // Bind Warning messages event + _innerConnection.Database.WarningMessage = new WarningMessageCallback(OnWarningMessage); - // Update the connection state - OnStateChange(_state, ConnectionState.Open); - } - catch (IscException ex) - { - OnStateChange(_state, ConnectionState.Closed); - throw new FbException(ex.Message, ex); - } - catch - { - OnStateChange(_state, ConnectionState.Closed); - throw; - } + // Update the connection state + OnStateChange(_state, ConnectionState.Open); + } + catch (IscException ex) + { + OnStateChange(_state, ConnectionState.Closed); + throw new FbException(ex.Message, ex); + } + catch + { + OnStateChange(_state, ConnectionState.Closed); + throw; } } @@ -540,57 +521,43 @@ public override void Close() { if (!IsClosed && _innerConnection != null) { - lock (this) + try { - try + _innerConnection.CloseEventManager(); + + if (_innerConnection.Database != null) + { + _innerConnection.Database.WarningMessage = null; + } + + _innerConnection.DisposeTransaction(); + + _innerConnection.ReleasePreparedCommands(); + + if (_options.Pooling) { - lock (_innerConnection) + if (_innerConnection.CancelDisabled) { - // Close the Remote Event Manager - _innerConnection.CloseEventManager(); - - // Unbind Warning messages event - if (_innerConnection.Database != null) - { - _innerConnection.Database.WarningMessage = null; - } - - // Dispose Transaction - _innerConnection.DisposeTransaction(); - - // Dispose all active statemenets - _innerConnection.ReleasePreparedCommands(); - - // Close connection or send it back to the pool - if (_options.Pooling) - { - if (_innerConnection.CancelDisabled) - { - // Enable fb_cancel_operation if going into pool - _innerConnection.EnableCancel(); - } - - // Send connection to the Pool - FbConnectionPoolManager.Instance.Release(_innerConnection); - } - else - { - if (!_innerConnection.IsEnlisted) - { - _innerConnection.Dispose(); - } - _innerConnection = null; - } + _innerConnection.EnableCancel(); } + + FbConnectionPoolManager.Instance.Release(_innerConnection); } - catch - { } - finally + else { - // Update connection state - OnStateChange(_state, ConnectionState.Closed); + if (!_innerConnection.IsEnlisted) + { + _innerConnection.Dispose(); + } + _innerConnection = null; } } + catch + { } + finally + { + OnStateChange(_state, ConnectionState.Closed); + } } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnectionInternal.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnectionInternal.cs index aa78d9d4..61c2bb70 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnectionInternal.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnectionInternal.cs @@ -47,7 +47,6 @@ internal class FbConnectionInternal : IDisposable private FbConnectionString _options; private FbConnection _owningConnection; private bool _disposed; - private object _preparedCommandsCleanupSyncRoot; #if !NETCORE10 private FbEnlistmentNotification _enlistmentNotification; #endif @@ -105,43 +104,20 @@ public FbConnectionString Options public FbConnectionInternal(FbConnectionString options) { _preparedCommands = new List(); - _preparedCommandsCleanupSyncRoot = new object(); _options = options; } #endregion - #region Finalizer - - ~FbConnectionInternal() - { - Dispose(false); - } - - #endregion - #region IDisposable Methods public void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected void Dispose(bool disposing) - { - lock (this) + if (!_disposed) { - if (!_disposed) - { - Disconnect(); - - if (disposing) - { } - - _disposed = true; - } + _disposed = true; + Disconnect(); } } @@ -222,58 +198,52 @@ public void Disconnect() public FbTransaction BeginTransaction(IsolationLevel level, string transactionName) { - lock (this) + if (HasActiveTransaction) { - if (HasActiveTransaction) - { - throw new InvalidOperationException("A transaction is currently active. Parallel transactions are not supported."); - } + throw new InvalidOperationException("A transaction is currently active. Parallel transactions are not supported."); + } - try - { - _activeTransaction = new FbTransaction(_owningConnection, level); - _activeTransaction.BeginTransaction(); + try + { + _activeTransaction = new FbTransaction(_owningConnection, level); + _activeTransaction.BeginTransaction(); - if (transactionName != null) - { - _activeTransaction.Save(transactionName); - } - } - catch (IscException ex) + if (transactionName != null) { - throw new FbException(ex.Message, ex); + _activeTransaction.Save(transactionName); } } + catch (IscException ex) + { + throw new FbException(ex.Message, ex); + } return _activeTransaction; } public FbTransaction BeginTransaction(FbTransactionOptions options, string transactionName) { - lock (this) + if (HasActiveTransaction) { - if (HasActiveTransaction) - { - throw new InvalidOperationException("A transaction is currently active. Parallel transactions are not supported."); - } + throw new InvalidOperationException("A transaction is currently active. Parallel transactions are not supported."); + } - try - { - _activeTransaction = new FbTransaction( - _owningConnection, IsolationLevel.Unspecified); + try + { + _activeTransaction = new FbTransaction( + _owningConnection, IsolationLevel.Unspecified); - _activeTransaction.BeginTransaction(options); + _activeTransaction.BeginTransaction(options); - if (transactionName != null) - { - _activeTransaction.Save(transactionName); - } - } - catch (IscException ex) + if (transactionName != null) { - throw new FbException(ex.Message, ex); + _activeTransaction.Save(transactionName); } } + catch (IscException ex) + { + throw new FbException(ex.Message, ex); + } return _activeTransaction; } @@ -292,7 +262,7 @@ public void TransactionCompleted() for (int i = 0; i < _preparedCommands.Count; i++) { FbCommand command; - if (!_preparedCommands[i].TryGetTarget(out command)) + if (!_preparedCommands[i].TryGetTarget(out command)) continue; if (command.Transaction != null) @@ -402,34 +372,28 @@ public void AddPreparedCommand(FbCommand command) public void RemovePreparedCommand(FbCommand command) { - lock (_preparedCommandsCleanupSyncRoot) + for (int i = _preparedCommands.Count - 1; i >= 0; i--) { - for (int i = _preparedCommands.Count - 1; i >= 0; i--) + var item = _preparedCommands[i]; + FbCommand current; + if (item.TryGetTarget(out current) && current == command) { - var item = _preparedCommands[i]; - FbCommand current; - if (item.TryGetTarget(out current) && current == command) - { - _preparedCommands.RemoveAt(i); - return; - } + _preparedCommands.RemoveAt(i); + return; } } } public void ReleasePreparedCommands() { - WeakReference[] toProcess = new WeakReference[_preparedCommands.Count]; - _preparedCommands.CopyTo(toProcess); - for (int i = 0; i < toProcess.Length; i++) + for (int i = 0; i < _preparedCommands.Count; i++) { FbCommand current; - if (!toProcess[i].TryGetTarget(out current)) + if (!_preparedCommands[i].TryGetTarget(out current)) continue; try { - // Release statement handle current.Release(); } catch (System.IO.IOException) @@ -448,11 +412,7 @@ public void ReleasePreparedCommands() } } } - - lock (_preparedCommandsCleanupSyncRoot) - { - _preparedCommands.Clear(); - } + _preparedCommands.Clear(); } #endregion @@ -463,10 +423,7 @@ public void CloseEventManager() { if (_db != null && _db.HasRemoteEventSupport) { - lock (_db) - { - _db.CloseEventManager(); - } + _db.CloseEventManager(); } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnectionPoolManager.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnectionPoolManager.cs index 03d814b9..d656020b 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnectionPoolManager.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnectionPoolManager.cs @@ -45,13 +45,7 @@ sealed class Item : IDisposable public DateTimeOffset Created { get; private set; } public FbConnectionInternal Connection { get; private set; } - public Item() - { - _disposed = false; - } - public Item(DateTimeOffset created, FbConnectionInternal connection) - : this() { Created = created; Connection = connection; @@ -76,7 +70,6 @@ public void Dispose() public Pool(FbConnectionString connectionString) { - _disposed = false; _syncRoot = new object(); _connectionString = connectionString; _available = new Stack(); diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDataAdapter.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDataAdapter.cs index 670beb70..035e5908 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDataAdapter.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDataAdapter.cs @@ -41,7 +41,7 @@ public sealed class FbDataAdapter : DbDataAdapter, ICloneable #region Events - public event EventHandler RowUpdated + public event EventHandler RowUpdated { add { @@ -143,32 +143,20 @@ public FbDataAdapter(string selectCommandText, FbConnection selectConnection) protected override void Dispose(bool disposing) { - lock (this) + if (disposing) { if (!_disposed) { - try + _disposed = true; + if (_shouldDisposeSelectCommand) { - // Release any unmanaged resources - - // Release any managed resources - if (disposing) + if (SelectCommand != null) { - if (_shouldDisposeSelectCommand) - { - if (SelectCommand != null) - { - SelectCommand.Dispose(); - SelectCommand = null; - } - } + SelectCommand.Dispose(); + SelectCommand = null; } } - finally - { - _disposed = true; - base.Dispose(disposing); - } + base.Dispose(disposing); } } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDataReader.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDataReader.cs index 1cf497ef..9ad3fd06 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDataReader.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbDataReader.cs @@ -35,7 +35,7 @@ public sealed class FbDataReader : DbDataReader { #region Constants - private const int STARTPOS = -1; + private const int StartPosition = -1; #endregion @@ -84,7 +84,7 @@ internal FbDataReader() FbConnection connection, CommandBehavior commandBehavior) { - _position = STARTPOS; + _position = StartPosition; _command = command; _connection = connection; _commandBehavior = commandBehavior; @@ -95,15 +95,6 @@ internal FbDataReader() #endregion - #region Finalizer - - ~FbDataReader() - { - Dispose(false); - } - - #endregion - #region DbDataReader overriden Properties public override int Depth @@ -168,43 +159,31 @@ protected override void Dispose(bool disposing) { if (!IsClosed) { - try + if (_command != null && !_command.IsDisposed) { - if (_command != null && !_command.IsDisposed) + if (_command.CommandType == CommandType.StoredProcedure) { - if (_command.CommandType == CommandType.StoredProcedure) - { - // Set values of output parameters - _command.SetOutputParameters(); - } - - if (_command.HasImplicitTransaction) - { - // Commit implicit transaction if needed - _command.CommitImplicitTransaction(); - } - - // Set null the active reader of the command - _command.ActiveReader = null; + _command.SetOutputParameters(); } - } - finally - { - if (_connection != null && IsCommandBehavior(CommandBehavior.CloseConnection)) + if (_command.HasImplicitTransaction) { - _connection.Close(); + _command.CommitImplicitTransaction(); } - - _isClosed = true; - _position = STARTPOS; - _command = null; - _connection = null; - _row = null; + _command.ActiveReader = null; + } + if (_connection != null && IsCommandBehavior(CommandBehavior.CloseConnection)) + { + _connection.Close(); + } + _isClosed = true; + _position = StartPosition; + _command = null; + _connection = null; + _row = null; #if !NETCORE10 - _schemaTable = null; + _schemaTable = null; #endif - _fields = null; - } + _fields = null; } } } @@ -215,8 +194,7 @@ public override bool Read() bool retValue = false; - if (IsCommandBehavior(CommandBehavior.SingleRow) && - _position != STARTPOS) + if (IsCommandBehavior(CommandBehavior.SingleRow) && _position != StartPosition) { } else @@ -672,7 +650,7 @@ public override bool NextResult() private void CheckPosition() { - if (_eof || _position == STARTPOS) + if (_eof || _position == StartPosition) { throw new InvalidOperationException("There are no data to read."); } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbException.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbException.cs index 4cf737a3..022c75b8 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbException.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbException.cs @@ -72,9 +72,9 @@ public string SQLSTATE } } -#endregion + #endregion -#region Constructors + #region Constructors internal FbException() : base() @@ -128,6 +128,6 @@ internal void ProcessIscExceptionErrors(IscException innerException) } } -#endregion + #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbRemoteEvent.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbRemoteEvent.cs index 669f140d..29201540 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbRemoteEvent.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbRemoteEvent.cs @@ -55,25 +55,11 @@ public sealed class FbRemoteEvent public FbConnection Connection { get { return _connection; } - set { _connection = value; } - } - - public bool HasChanges - { - get { return _revent.HasChanges; } } public int RemoteEventId { - get - { - if (_revent != null) - { - return _revent.RemoteId; - } - - return -1; - } + get { return _revent?.RemoteId ?? -1; } } #endregion @@ -82,8 +68,7 @@ public int RemoteEventId public FbRemoteEvent(FbConnection connection) : this(connection, null) - { - } + { } public FbRemoteEvent(FbConnection connection, params string[] events) { @@ -110,13 +95,9 @@ public FbRemoteEvent(FbConnection connection, params string[] events) public void AddEvents(params string[] events) { if (events == null) - { - throw new ArgumentNullException("events cannot be null."); - } + throw new ArgumentNullException(nameof(events)); if (events.Length > 15) - { - throw new ArgumentException("Max number of events for request interest is 15"); - } + throw new ArgumentOutOfRangeException(nameof(events), "Maximum number of events is 15."); if (events.Length != _revent.Events.Count) { @@ -186,7 +167,6 @@ private void OnRemoteEventCounts() } } - // Send individual event notifications for (int i = 0; i < actualCounts.Length; i++) { FbRemoteEventEventArgs args = new FbRemoteEventEventArgs(_revent.Events[i], actualCounts[i]); @@ -204,12 +184,10 @@ private void OnRemoteEventCounts() if (canceled) { - // Requeque CancelEvents(); } else { - // Requeque QueueEvents(); } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbRemoteEventEventArgs.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbRemoteEventEventArgs.cs index 21f535ac..7bbdab70 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbRemoteEventEventArgs.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbRemoteEventEventArgs.cs @@ -17,33 +17,14 @@ */ using System; +using System.ComponentModel; namespace FirebirdSql.Data.FirebirdClient { - public sealed class FbRemoteEventEventArgs : System.ComponentModel.CancelEventArgs + public sealed class FbRemoteEventEventArgs : CancelEventArgs { - #region Fields - - private string _name; - private int _counts; - - #endregion - - #region Properties - - public string Name - { - get { return _name; } - } - - public int Counts - { - get { return _counts; } - } - - #endregion - - #region Constructors + public string Name { get; } + public int Counts { get; } public FbRemoteEventEventArgs(string name, int counts) : this(name, counts, false) @@ -52,10 +33,8 @@ public FbRemoteEventEventArgs(string name, int counts) public FbRemoteEventEventArgs(string name, int counts, bool cancel) : base(cancel) { - _name = name; - _counts = counts; + Name = name; + Counts = counts; } - - #endregion } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbTransaction.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbTransaction.cs index 6a348fbb..84e3e9c5 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbTransaction.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbTransaction.cs @@ -73,57 +73,32 @@ internal FbTransaction(FbConnection connection) internal FbTransaction(FbConnection connection, IsolationLevel il) { - _disposed = false; - _isCompleted = false; - _connection = connection; IsolationLevel = il; } #endregion - #region Finalizer - - ~FbTransaction() - { - Dispose(false); - } - - #endregion - #region IDisposable methods protected override void Dispose(bool disposing) { - lock (this) + if (disposing) { if (!_disposed) { - try + _disposed = true; + if (_transaction != null) { - // release any unmanaged resources - if (_transaction != null) + if (!_isCompleted) { - if (!_isCompleted) - { - _transaction.Dispose(); - } + _transaction.Dispose(); } - - // release any managed resources - if (disposing) - { - _connection = null; - _transaction = null; - } - } - catch - { } - finally - { - _isCompleted = true; - _disposed = true; } + _connection = null; + _transaction = null; + _isCompleted = true; + base.Dispose(disposing); } } } @@ -134,35 +109,29 @@ protected override void Dispose(bool disposing) public override void Commit() { - lock (this) + EnsureCompleted(); + try { - EnsureCompleted(); - try - { - _transaction.Commit(); - CompleteTransaction(); - } - catch (IscException ex) - { - throw new FbException(ex.Message, ex); - } + _transaction.Commit(); + CompleteTransaction(); + } + catch (IscException ex) + { + throw new FbException(ex.Message, ex); } } public override void Rollback() { - lock (this) + EnsureCompleted(); + try { - EnsureCompleted(); - try - { - _transaction.Rollback(); - CompleteTransaction(); - } - catch (IscException ex) - { - throw new FbException(ex.Message, ex); - } + _transaction.Rollback(); + CompleteTransaction(); + } + catch (IscException ex) + { + throw new FbException(ex.Message, ex); } } @@ -173,92 +142,77 @@ public override void Rollback() public void Save(string savePointName) { EnsureSavePointName(savePointName); - lock (this) + EnsureCompleted(); + try { - EnsureCompleted(); - try - { - using (var command = new FbCommand($"SAVEPOINT {savePointName}", _connection, this)) - { - command.ExecuteNonQuery(); - } - } - catch (IscException ex) + using (var command = new FbCommand($"SAVEPOINT {savePointName}", _connection, this)) { - throw new FbException(ex.Message, ex); + command.ExecuteNonQuery(); } } + catch (IscException ex) + { + throw new FbException(ex.Message, ex); + } } public void Commit(string savePointName) { EnsureSavePointName(savePointName); - lock (this) + EnsureCompleted(); + try { - EnsureCompleted(); - try - { - using (var command = new FbCommand($"RELEASE SAVEPOINT {savePointName}", _connection, this)) - { - command.ExecuteNonQuery(); - } - } - catch (IscException ex) + using (var command = new FbCommand($"RELEASE SAVEPOINT {savePointName}", _connection, this)) { - throw new FbException(ex.Message, ex); + command.ExecuteNonQuery(); } } + catch (IscException ex) + { + throw new FbException(ex.Message, ex); + } } public void Rollback(string savePointName) { EnsureSavePointName(savePointName); - lock (this) + EnsureCompleted(); + try { - EnsureCompleted(); - try + using (var command = new FbCommand($"ROLLBACK WORK TO SAVEPOINT {savePointName}", _connection, this)) { - using (var command = new FbCommand($"ROLLBACK WORK TO SAVEPOINT {savePointName}", _connection, this)) - { - command.ExecuteNonQuery(); - } - } - catch (IscException ex) - { - throw new FbException(ex.Message, ex); + command.ExecuteNonQuery(); } } + catch (IscException ex) + { + throw new FbException(ex.Message, ex); + } } public void CommitRetaining() { - lock (this) + EnsureCompleted(); + try { - EnsureCompleted(); - try - { - _transaction.CommitRetaining(); - } - catch (IscException ex) - { - throw new FbException(ex.Message, ex); - } + _transaction.CommitRetaining(); + } + catch (IscException ex) + { + throw new FbException(ex.Message, ex); } } public void RollbackRetaining() { - lock (this) + EnsureCompleted(); + try { - EnsureCompleted(); - try - { - _transaction.RollbackRetaining(); - } - catch (IscException ex) - { - throw new FbException(ex.Message, ex); - } + _transaction.RollbackRetaining(); + } + catch (IscException ex) + { + throw new FbException(ex.Message, ex); } } @@ -268,31 +222,25 @@ public void RollbackRetaining() internal void BeginTransaction() { - lock (this) + try { - try - { - _transaction = _connection.InnerConnection.Database.BeginTransaction(BuildTpb()); - } - catch (IscException ex) - { - throw new FbException(ex.Message, ex); - } + _transaction = _connection.InnerConnection.Database.BeginTransaction(BuildTpb()); + } + catch (IscException ex) + { + throw new FbException(ex.Message, ex); } } internal void BeginTransaction(FbTransactionOptions options) { - lock (this) + try { - try - { - _transaction = _connection.InnerConnection.Database.BeginTransaction(BuildTpb(options)); - } - catch (IscException ex) - { - throw new FbException(ex.Message, ex); - } + _transaction = _connection.InnerConnection.Database.BeginTransaction(BuildTpb(options)); + } + catch (IscException ex) + { + throw new FbException(ex.Message, ex); } } diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FirebirdClientFactory.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FirebirdClientFactory.cs index e94d59f7..2435a1c1 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FirebirdClientFactory.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FirebirdClientFactory.cs @@ -48,9 +48,9 @@ public override bool CanCreateDataSourceEnumerator #region Constructors - private FirebirdClientFactory() : base() - { - } + private FirebirdClientFactory() + : base() + { } #endregion diff --git a/Provider/src/FirebirdSql.Data.FirebirdClient/Schema/FbSchema.cs b/Provider/src/FirebirdSql.Data.FirebirdClient/Schema/FbSchema.cs index 29012299..e98b84c9 100644 --- a/Provider/src/FirebirdSql.Data.FirebirdClient/Schema/FbSchema.cs +++ b/Provider/src/FirebirdSql.Data.FirebirdClient/Schema/FbSchema.cs @@ -51,25 +51,21 @@ public FbSchema() public DataTable GetSchema(FbConnection connection, string collectionName, string[] restrictions) { DataTable dataTable = new DataTable(collectionName); - FbCommand command = BuildCommand(connection, collectionName, ParseRestrictions(restrictions)); - FbDataAdapter adapter = new FbDataAdapter(command); - - try - { - adapter.Fill(dataTable); - } - catch (Exception ex) + using (FbCommand command = BuildCommand(connection, collectionName, ParseRestrictions(restrictions))) { - throw new FbException(ex.Message); - } - finally - { - adapter.Dispose(); - command.Dispose(); + using (FbDataAdapter adapter = new FbDataAdapter(command)) + { + try + { + adapter.Fill(dataTable); + } + catch (Exception ex) + { + throw new FbException(ex.Message); + } + } } - TrimStringFields(dataTable); - return ProcessResult(dataTable); } @@ -79,11 +75,11 @@ public DataTable GetSchema(FbConnection connection, string collectionName, strin protected FbCommand BuildCommand(FbConnection connection, string collectionName, string[] restrictions) { - string filter = String.Format("CollectionName='{0}'", collectionName); - StringBuilder builder = GetCommandText(restrictions); - DataRow[] restriction = connection.GetSchema(DbMetaDataCollectionNames.Restrictions).Select(filter); - FbTransaction transaction = connection.InnerConnection.ActiveTransaction; - FbCommand command = new FbCommand(builder.ToString(), connection, transaction); + string filter = String.Format("CollectionName='{0}'", collectionName); + StringBuilder builder = GetCommandText(restrictions); + DataRow[] restriction = connection.GetSchema(DbMetaDataCollectionNames.Restrictions).Select(filter); + FbTransaction transaction = connection.InnerConnection.ActiveTransaction; + FbCommand command = new FbCommand(builder.ToString(), connection, transaction); if (restrictions != null && restrictions.Length > 0) {