Summary

Class:CBAM.SQL.PostgreSQL.PgSQLConnectionPoolProvider
Assembly:CBAM.SQL.PostgreSQL.Implementation
File(s):/repo-dir/contents/Source/Code/CBAM.SQL.PostgreSQL.Implementation/ConnectionPoolProvider.cs
Covered lines:45
Uncovered lines:12
Coverable lines:57
Total lines:149
Line coverage:78.9%
Branch coverage:0%

Coverage History

Metrics

MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage
.cctor()101%0%
.ctor()100%0%
TransformFactoryParameters(...)400%0%
CreateFactory()100%0%

File(s)

/repo-dir/contents/Source/Code/CBAM.SQL.PostgreSQL.Implementation/ConnectionPoolProvider.cs

#LineLine coverage
 1/*
 2 * Copyright 2017 Stanislav Muhametsin. All rights Reserved.
 3 *
 4 * Licensed  under the  Apache License,  Version 2.0  (the "License");
 5 * you may not use  this file  except in  compliance with the License.
 6 * You may obtain a copy of the License at
 7 *
 8 *   http://www.apache.org/licenses/LICENSE-2.0
 9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed  under the  License is distributed on an "AS IS" BASIS,
 12 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
 13 * implied.
 14 *
 15 * See the License for the specific language governing permissions and
 16 * limitations under the License.
 17 */
 18using CBAM.Abstractions;
 19using CBAM.Abstractions.Implementation.NetworkStream;
 20using CBAM.SQL.Implementation;
 21using CBAM.SQL.PostgreSQL;
 22using CBAM.SQL.PostgreSQL.Implementation;
 23using IOUtils.Network.Configuration;
 24using ResourcePooling.Async.Abstractions;
 25using System;
 26using System.Collections.Generic;
 27using System.IO;
 28using System.Text;
 29using System.Threading;
 30using System.Threading.Tasks;
 31using UtilPack;
 32namespace CBAM.SQL.PostgreSQL
 33{
 34   using TIntermediateState = ValueTuple<BackendABIHelper, ResizableArray<Byte>, CancellationToken, Stream>;
 35   /// <summary>
 36   /// This is the entrypoint-class for using PostgreSQL connections.
 37   /// Use <see cref="Factory"/> static property to acquire <see cref="AsyncResourceFactory{TResource, TParams}"/> for <
 38   /// This <see cref="AsyncResourceFactory{TResource}"/> with one generic type parameter then has a number of extension
 39   /// </summary>
 40   /// <remarks>
 41   /// This class also (explicitly) implements <see cref="AsyncResourceFactoryProvider"/> interface in order to provide 
 42   /// </remarks>
 43   public sealed class PgSQLConnectionPoolProvider : AbstractAsyncResourceFactoryProvider<PgSQLConnection, PgSQLConnecti
 44   {
 45
 46      /// <summary>
 47      /// Gets the <see cref="AsyncResourceFactory{TResource, TParams}"/> which can create pools that provide instances 
 48      /// </summary>
 49      /// <value>The <see cref="AsyncResourceFactory{TResource, TParams}"/> which can create <see cref="PgSQLConnection"
 50      /// <remarks>
 51      /// By invoking <see cref="AsyncResourceFactory{TResource, TParams}.BindCreationParameters"/>, one gets the bound 
 52      /// Instead of directly using <see cref="AsyncResourceFactory{TResource}.CreateAcquireResourceContext"/>, typical 
 53      /// </remarks>
 2454      public static AsyncResourceFactory<PgSQLConnection, PgSQLConnectionCreationInfo> Factory { get; } = new DefaultAsy
 2455         config.NewFactoryParametrizer<PgSQLConnectionCreationInfo, PgSQLConnectionCreationInfoData, PgSQLConnectionConf
 2456            .BindPublicConnectionType<PgSQLConnection>()
 2457            .CreateStatefulDelegatingConnectionFactory(
 2458               new UTF8EncodingInfo(),
 4859               ( parameters, encodingInfo, stringPool, stringPoolIsDedicated, socketOrNull, stream, token ) => new TInte
 2460               async ( parameters, encodingInfo, stringPool, stringPoolIsDedicated, state ) =>
 2461               {
 4862                  var sslMode = parameters.CreationData?.Connection?.ConnectionSSLMode ?? ConnectionSSLMode.NotRequired;
 4863                  var retVal = sslMode == ConnectionSSLMode.Required || sslMode == ConnectionSSLMode.Preferred;
 4864                  if ( retVal )
 2465                  {
 2566                     await SSLRequestMessage.INSTANCE.SendMessageAsync( (state.Item1, state.Item4, state.Item3, state.It
 2467
 2568                     await state.Item4.ReadSpecificAmountAsync( state.Item2.Array, 0, 1, state.Item3 );
 2569                     retVal = state.Item2.Array[0] == (Byte) 'S';
 2470                  }
 2471
 4872                  return retVal;
 4873               },
 2474               () => new PgSQLException( "Server accepted SSL request, but the creation parameters did not have callback
 2475               () => new PgSQLException( "Server does not support SSL." ),
 2476               () => new PgSQLException( "SSL stream creation callback returned null." ),
 2477               () => new PgSQLException( "Authentication callback given by SSL stream creation callback was null." ),
 2478               inner => new PgSQLException( "Unable to start SSL client.", inner ),
 2479               async ( parameters, encodingInfo, stringPool, stringPoolIsDedicated, stream, socketOrNull, token, state )
 2480               {
 4881                  (var proto, var warnings) = await PostgreSQLProtocol.PerformStartup(
 4882                  new PgSQLConnectionVendorFunctionalityImpl(),
 4883                     parameters,
 4884                     token,
 4885                     stream,
 4886                     state.Item1,
 4887                     state.Item2
 4888#if !NETSTANDARD1_0
 4889                     , (System.Net.Sockets.Socket) socketOrNull
 4890#endif
 4891                  );
 2492
 4893                  return proto;
 4894               },
 4895               protocol => new ValueTask<PgSQLConnectionImpl>( new PgSQLConnectionImpl( protocol, new PgSQLDatabaseMetaD
 4896               ( protocol, connection ) => new PgSQLConnectionAcquireInfo( connection, protocol ),
 2497               ( functionality, connection, token, error ) => functionality?.Stream
 2498         ) );
 99
 100      //new PgSQLConnectionFactory( config, new UTF8EncodingInfo() ) );
 101
 102      /// <summary>
 103      /// Creates a new instance of <see cref="PgSQLConnectionPoolProvider"/>.
 104      /// </summary>
 105      /// <remarks>
 106      /// This constructor is not intended to be used directly, but a generic scenarios like MSBuild task dynamically lo
 107      /// </remarks>
 108      public PgSQLConnectionPoolProvider()
 0109         : base( typeof( PgSQLConnectionCreationInfoData ) )
 110      {
 0111      }
 112
 113      /// <summary>
 114      /// This method implements <see cref="AbstractAsyncResourceFactoryProvider{TFactoryResource, TCreationParameters}.
 115      /// </summary>
 116      /// <param name="creationParameters">The untyped creation parameters.</param>
 117      /// <returns>The <see cref="PgSQLConnectionCreationInfo"/>.</returns>
 118      /// <exception cref="ArgumentNullException">If <paramref name="creationParameters"/> is <c>null</c>.</exception>
 119      /// <exception cref="ArgumentException">If <paramref name="creationParameters"/> is not <see cref="PgSQLConnection
 120      protected override PgSQLConnectionCreationInfo TransformFactoryParameters( Object creationParameters )
 121      {
 0122         ArgumentValidator.ValidateNotNull( nameof( creationParameters ), creationParameters );
 123
 124         PgSQLConnectionCreationInfo retVal;
 0125         if ( creationParameters is PgSQLConnectionCreationInfoData creationData )
 126         {
 0127            retVal = new PgSQLConnectionCreationInfo( creationData );
 128
 0129         }
 0130         else if ( creationParameters is PgSQLConnectionCreationInfo creationInfo )
 131         {
 0132            retVal = creationInfo;
 0133         }
 134         else
 135         {
 0136            throw new ArgumentException( $"The {nameof( creationParameters )} must be instance of {typeof( PgSQLConnecti
 137         }
 138
 0139         return retVal;
 140      }
 141
 142      /// <summary>
 143      /// This method implements <see cref="AbstractAsyncResourceFactoryProvider{TFactoryResource, TCreationParameters}.
 144      /// </summary>
 145      /// <returns>The value of <see cref="Factory"/> static property.</returns>
 146      protected override AsyncResourceFactory<PgSQLConnection, PgSQLConnectionCreationInfo> CreateFactory()
 0147         => Factory;
 148   }
 149}