Browse Source

More generic naming + dispose ADO connection (#7284)

Co-authored-by: LLT21 <[email protected]>
LLT21 3 years ago
parent
commit
a5a20f958f

+ 17 - 18
frameworks/CSharp/appmpower/src/Db/PooledCommand.cs → frameworks/CSharp/appmpower/src/Data/DbCommand.cs

@@ -1,36 +1,36 @@
 using System.Data;
 using System.Threading.Tasks;
 
-namespace appMpower.Db
+namespace appMpower.Data
 {
-   public class PooledCommand : IDbCommand
+   public class DbCommand : IDbCommand
    {
       private IDbCommand _dbCommand;
-      private PooledConnection _pooledConnection;
+      private DbConnection _dbConnection;
 
-      public PooledCommand(PooledConnection pooledConnection)
+      public DbCommand(DbConnection dbConnection)
       {
-         _dbCommand = pooledConnection.CreateCommand();
-         _pooledConnection = pooledConnection;
+         _dbCommand = dbConnection.CreateCommand();
+         _dbConnection = dbConnection;
       }
 
-      public PooledCommand(string commandText, PooledConnection pooledConnection)
+      public DbCommand(string commandText, DbConnection dbConnection)
       {
-         pooledConnection.GetCommand(commandText, CommandType.Text, this);
+         dbConnection.GetCommand(commandText, CommandType.Text, this);
       }
 
-      public PooledCommand(string commandText, CommandType commandType, PooledConnection pooledConnection)
+      public DbCommand(string commandText, CommandType commandType, DbConnection dbConnection)
       {
-         pooledConnection.GetCommand(commandText, commandType, this);
+         dbConnection.GetCommand(commandText, commandType, this);
       }
 
-      internal PooledCommand(IDbCommand dbCommand, PooledConnection pooledConnection)
+      internal DbCommand(IDbCommand dbCommand, DbConnection dbConnection)
       {
          _dbCommand = dbCommand;
-         _pooledConnection = pooledConnection;
+         _dbConnection = dbConnection;
       }
 
-      internal IDbCommand DbCommand
+      internal IDbCommand Command
       {
          get
          {
@@ -42,15 +42,15 @@ namespace appMpower.Db
          }
       }
 
-      internal PooledConnection PooledConnection
+      internal DbConnection DbConnection
       {
          get
          {
-            return _pooledConnection;
+            return _dbConnection;
          }
          set
          {
-            _pooledConnection = value;
+            _dbConnection = value;
          }
       }
 
@@ -103,7 +103,6 @@ namespace appMpower.Db
       }
 #nullable disable
 
-
       public IDataParameterCollection Parameters
       {
          get
@@ -220,7 +219,7 @@ namespace appMpower.Db
 
       public void Dispose()
       {
-         _pooledConnection.ReleaseCommand(this);
+         _dbConnection.ReleaseCommand(this);
       }
    }
 }

+ 42 - 29
frameworks/CSharp/appmpower/src/Db/PooledConnection.cs → frameworks/CSharp/appmpower/src/Data/DbConnection.cs

@@ -2,27 +2,32 @@ using System.Collections.Concurrent;
 using System.Data;
 using System.Threading.Tasks;
 
-namespace appMpower.Db
+namespace appMpower.Data
 {
-   public class PooledConnection : IDbConnection
+   public class DbConnection : IDbConnection
    {
       private string _connectionString;
-      internal InternalConnection _internalConnection; 
+      internal InternalConnection _internalConnection;
 
-      public PooledConnection(string connectionString)
+      public DbConnection()
+      {
+         _connectionString = DbProviderFactory.ConnectionString;
+      }
+
+      public DbConnection(string connectionString)
       {
          _connectionString = connectionString;
       }
 
-      internal ConcurrentDictionary<string, PooledCommand> PooledCommands
+      internal ConcurrentDictionary<string, DbCommand> DbCommands
       {
          get
          {
-            return _internalConnection.PooledCommands;
+            return _internalConnection.DbCommands;
          }
          set
          {
-            _internalConnection.PooledCommands = value;
+            _internalConnection.DbCommands = value;
          }
       }
 
@@ -38,7 +43,7 @@ namespace appMpower.Db
          }
       }
 
-      public IDbConnection DbConnection
+      public IDbConnection Connection
       {
          get
          {
@@ -127,18 +132,26 @@ namespace appMpower.Db
 
       public void Dispose()
       {
-         PooledConnections.Release(_internalConnection);
+#if ADO
+         _internalConnection.DbConnection.Dispose();
+         _internalConnection.Dispose();
+#else
+         DbConnections.Release(_internalConnection);
+#endif
       }
 
       public async Task OpenAsync()
       {
-#if ADO
+#if ADO && SQLSERVER
+         _internalConnection = new();
+         _internalConnection.DbConnection = new System.Data.SqlClient.SqlConnection(_connectionString);
+#elif ADO && POSTGRESQL
          _internalConnection = new(); 
          _internalConnection.DbConnection = new Npgsql.NpgsqlConnection(_connectionString);
 #else
          if (_internalConnection is null)
          {
-            _internalConnection = await PooledConnections.GetConnection(_connectionString);
+            _internalConnection = await DbConnections.GetConnection(_connectionString);
          }
 #endif
 
@@ -148,42 +161,42 @@ namespace appMpower.Db
          }
       }
 
-      internal PooledCommand GetCommand(string commandText, CommandType commandType, PooledCommand pooledCommand)
+      internal DbCommand GetCommand(string commandText, CommandType commandType, DbCommand dbCommand)
       {
 #if ADO
-         pooledCommand.DbCommand = this.DbConnection.CreateCommand();
-         pooledCommand.DbCommand.CommandText = commandText;
-         pooledCommand.DbCommand.CommandType = commandType;
-         pooledCommand.PooledConnection = this;
+         dbCommand.Command = _internalConnection.DbConnection.CreateCommand();
+         dbCommand.Command.CommandText = commandText;
+         dbCommand.Command.CommandType = commandType;
+         dbCommand.DbConnection = this;
 #else
-         PooledCommand internalCommand;
+         DbCommand internalCommand;
 
-         if (_internalConnection.PooledCommands.TryRemove(commandText, out internalCommand))
+         if (_internalConnection.DbCommands.TryRemove(commandText, out internalCommand))
          {
-            pooledCommand.DbCommand = internalCommand.DbCommand;
-            pooledCommand.PooledConnection = internalCommand.PooledConnection;
+            dbCommand.Command = internalCommand.Command;
+            dbCommand.DbConnection = internalCommand.DbConnection;
          }
          else
          {
-            pooledCommand.DbCommand = this.DbConnection.CreateCommand();
-            pooledCommand.DbCommand.CommandText = commandText;
-            pooledCommand.DbCommand.CommandType = commandType;
-            pooledCommand.PooledConnection = this;
+            dbCommand.Command = _internalConnection.DbConnection.CreateCommand();
+            dbCommand.Command.CommandText = commandText;
+            dbCommand.Command.CommandType = commandType;
+            dbCommand.DbConnection = this;
 
             //For non odbc drivers like Npgsql which do not support Prepare
-            pooledCommand.DbCommand.Prepare();
+            dbCommand.Command.Prepare();
 
-            //Console.WriteLine("prepare pool connection: " + this._internalConnection.Number + " for command " + _internalConnection.PooledCommands.Count);
+            //Console.WriteLine("prepare pool connection: " + this._internalConnection.Number + " for command " + _internalConnection.DbCommands.Count);
          }
 #endif
 
-         return pooledCommand;
+         return dbCommand;
       }
 
-      public void ReleaseCommand(PooledCommand pooledCommand)
+      public void ReleaseCommand(DbCommand dbCommand)
       {
 #if !ADO
-         _internalConnection.PooledCommands.TryAdd(pooledCommand.CommandText, pooledCommand);
+         _internalConnection.DbCommands.TryAdd(dbCommand.CommandText, dbCommand);
 #endif
       }
    }

+ 7 - 12
frameworks/CSharp/appmpower/src/Db/PooledConnections.cs → frameworks/CSharp/appmpower/src/Data/DbConnections.cs

@@ -1,13 +1,13 @@
 using System.Collections.Concurrent;
 using System.Threading.Tasks;
 
-namespace appMpower.Db
+namespace appMpower.Data
 {
-   public static class PooledConnections
+   public static class DbConnections
    {
       private static bool _connectionsCreated = false;
       private static short _createdConnections = 0;
-      private static short _maxConnections = 240;
+      private static short _maxConnections = 250;
 
       private static ConcurrentStack<InternalConnection> _stack = new();
       private static ConcurrentQueue<TaskCompletionSource<InternalConnection>> _waitingQueue = new();
@@ -20,7 +20,7 @@ namespace appMpower.Db
          {
             if (!_stack.TryPop(out internalConnection))
             {
-               internalConnection = await GetPooledConnectionAsync();
+               internalConnection = await GetDbConnectionAsync();
             }
 
             return internalConnection;
@@ -28,26 +28,21 @@ namespace appMpower.Db
          else
          {
             internalConnection = new InternalConnection();
-
-#if ADO
-            internalConnection.DbConnection = new Npgsql.NpgsqlConnection(connectionString);
-#else
             internalConnection.DbConnection = new System.Data.Odbc.OdbcConnection(connectionString);
-#endif               
 
             _createdConnections++;
 
             if (_createdConnections == _maxConnections) _connectionsCreated = true;
 
             internalConnection.Number = _createdConnections;
-            internalConnection.PooledCommands = new ConcurrentDictionary<string, PooledCommand>();
-            //Console.WriteLine("opened connection number: " + pooledConnection.Number);
+            internalConnection.DbCommands = new ConcurrentDictionary<string, DbCommand>();
+            //Console.WriteLine("opened connection number: " + dbConnection.Number);
 
             return internalConnection;
          }
       }
 
-      public static Task<InternalConnection> GetPooledConnectionAsync()
+      public static Task<InternalConnection> GetDbConnectionAsync()
       {
          var taskCompletionSource = new TaskCompletionSource<InternalConnection>(TaskCreationOptions.RunContinuationsAsynchronously);
 

+ 4 - 2
frameworks/CSharp/appmpower/src/Db/DataProvider.cs → frameworks/CSharp/appmpower/src/Data/DbProviderFactory.cs

@@ -1,6 +1,8 @@
-namespace appMpower.Db
+using System.Data;
+
+namespace appMpower.Data
 {
-   public static class DataProvider
+   public static class DbProviderFactory
    {
 #if MYSQL
       public const string ConnectionString = "Driver={MariaDB};Server=tfb-database;Database=hello_world;Uid=benchmarkdbuser;Pwd=benchmarkdbpass;Pooling=false;OPTIONS=67108864;FLAG_FORWARD_CURSOR=1"; 

+ 2 - 2
frameworks/CSharp/appmpower/src/Db/InternalConnection.cs → frameworks/CSharp/appmpower/src/Data/InternalConnection.cs

@@ -1,13 +1,13 @@
 using System.Collections.Concurrent;
 using System.Data;
 
-namespace appMpower.Db
+namespace appMpower.Data
 {
    public class InternalConnection : System.IDisposable
    {
       public short Number { get; set; }
       public IDbConnection DbConnection { get; set; }
-      public ConcurrentDictionary<string, PooledCommand> PooledCommands { get; set; }
+      public ConcurrentDictionary<string, DbCommand> DbCommands { get; set; }
 
       public void Dispose()
       {

+ 36 - 37
frameworks/CSharp/appmpower/src/RawDb.cs

@@ -1,11 +1,10 @@
 using System;
 using System.Collections.Generic;
 using System.Data;
-using System.Data.Common;
 using System.Linq;
 using System.Threading.Tasks;
 using Microsoft.Extensions.Caching.Memory;
-using appMpower.Db;
+using appMpower.Data; 
 using PlatformBenchmarks;
 
 namespace appMpower
@@ -32,14 +31,14 @@ namespace appMpower
 
       public static async Task<World> LoadSingleQueryRow()
       {
-         using var pooledConnection = new PooledConnection(DataProvider.ConnectionString);
+         using var pooledConnection = new DbConnection(DbProviderFactory.ConnectionString);
          await pooledConnection.OpenAsync();
 
-         var (pooledCommand, _) = CreateReadCommand(pooledConnection);
+         var (dbCommand, _) = CreateReadCommand(pooledConnection);
 
-         using (pooledCommand)
+         using (dbCommand)
          {
-            var world = await ReadSingleRow(pooledCommand);
+            var world = await ReadSingleRow(dbCommand);
 
             return world;
          }
@@ -49,16 +48,16 @@ namespace appMpower
       {
          var worlds = new World[count];
 
-         using var pooledConnection = new PooledConnection(DataProvider.ConnectionString);
+         using var pooledConnection = new DbConnection(DbProviderFactory.ConnectionString);
          await pooledConnection.OpenAsync();
 
-         var (pooledCommand, dbDataParameter) = CreateReadCommand(pooledConnection);
+         var (dbCommand, dbDataParameter) = CreateReadCommand(pooledConnection);
 
-         using (pooledCommand)
+         using (dbCommand)
          {
             for (int i = 0; i < count; i++)
             {
-               worlds[i] = await ReadSingleRow(pooledCommand);
+               worlds[i] = await ReadSingleRow(dbCommand);
                dbDataParameter.Value = _random.Next(1, 10001);
             }
          }
@@ -70,14 +69,14 @@ namespace appMpower
       {
          var fortunes = new List<Fortune>();
 
-         using var pooledConnection = new PooledConnection(DataProvider.ConnectionString);
+         using var pooledConnection = new DbConnection(DbProviderFactory.ConnectionString);
          await pooledConnection.OpenAsync();
 
-         var pooledCommand = new PooledCommand("SELECT * FROM fortune", pooledConnection);
+         var dbCommand = new DbCommand("SELECT * FROM fortune", pooledConnection);
 
-         using (pooledCommand)
+         using (dbCommand)
          {
-            var dataReader = await pooledCommand.ExecuteReaderAsync(CommandBehavior.SingleResult & CommandBehavior.SequentialAccess);
+            var dataReader = await dbCommand.ExecuteReaderAsync(CommandBehavior.SingleResult & CommandBehavior.SequentialAccess);
 
             while (dataReader.Read())
             {
@@ -107,7 +106,7 @@ namespace appMpower
       {
          var worlds = new World[count];
 
-         using var pooledConnection = new PooledConnection(DataProvider.ConnectionString);
+         using var pooledConnection = new DbConnection(DbProviderFactory.ConnectionString);
          await pooledConnection.OpenAsync();
 
          var (queryCommand, dbDataParameter) = CreateReadCommand(pooledConnection);
@@ -121,7 +120,7 @@ namespace appMpower
             }
          }
 
-         using var updateCommand = new PooledCommand(PlatformBenchmarks.BatchUpdateString.Query(count), pooledConnection);
+         using var updateCommand = new DbCommand(PlatformBenchmarks.BatchUpdateString.Query(count), pooledConnection);
 
          var ids = PlatformBenchmarks.BatchUpdateString.Ids;
          var randoms = PlatformBenchmarks.BatchUpdateString.Randoms;
@@ -152,20 +151,20 @@ namespace appMpower
          return worlds;
       }
 
-      private static (PooledCommand pooledCommand, IDbDataParameter dbDataParameter) CreateReadCommand(PooledConnection pooledConnection)
+      private static (DbCommand dbCommand, IDbDataParameter dbDataParameter) CreateReadCommand(DbConnection pooledConnection)
       {
 #if ADO         
-         var pooledCommand = new PooledCommand("SELECT * FROM world WHERE id=@Id", pooledConnection);
+         var dbCommand = new DbCommand("SELECT * FROM world WHERE id=@Id", pooledConnection);
 #else         
-         var pooledCommand = new PooledCommand("SELECT * FROM world WHERE id=?", pooledConnection);
+         var dbCommand = new DbCommand("SELECT * FROM world WHERE id=?", pooledConnection);
 #endif         
 
-         return (pooledCommand, pooledCommand.CreateParameter("Id", DbType.Int32, _random.Next(1, 10001)));
+         return (dbCommand, dbCommand.CreateParameter("Id", DbType.Int32, _random.Next(1, 10001)));
       }
 
-      private static async Task<World> ReadSingleRow(PooledCommand pooledCommand)
+      private static async Task<World> ReadSingleRow(DbCommand dbCommand)
       {
-         var dataReader = await pooledCommand.ExecuteReaderAsync(CommandBehavior.SingleRow & CommandBehavior.SequentialAccess);
+         var dataReader = await dbCommand.ExecuteReaderAsync(CommandBehavior.SingleRow & CommandBehavior.SequentialAccess);
 
          dataReader.Read();
 
@@ -203,17 +202,17 @@ namespace appMpower
             queryString = _queriesMultipleRows[count] = PlatformBenchmarks.StringBuilderCache.GetStringAndRelease(stringBuilder);
          }
 
-         using var pooledConnection = new PooledConnection(DataProvider.ConnectionString);
+         using var pooledConnection = new DbConnection(DbProviderFactory.ConnectionString);
          await pooledConnection.OpenAsync();
 
-         using var pooledCommand = new PooledCommand(queryString, pooledConnection);
+         using var dbCommand = new DbCommand(queryString, pooledConnection);
 
          for (int i = 0; i < count; i++)
          {
-            pooledCommand.CreateParameter(ids[i], DbType.Int32, _random.Next(1, 10001));
+            dbCommand.CreateParameter(ids[i], DbType.Int32, _random.Next(1, 10001));
          }
 
-         var dataReader = await pooledCommand.ExecuteReaderAsync(CommandBehavior.Default & CommandBehavior.SequentialAccess);
+         var dataReader = await dbCommand.ExecuteReaderAsync(CommandBehavior.Default & CommandBehavior.SequentialAccess);
 
          do
          {
@@ -233,9 +232,9 @@ namespace appMpower
          return worlds;
       }
 
-      public static string ReadColumn(DbDataReader dbDataReader, int column)
+      public static string ReadColumn(IDataReader dataReader, int column)
       {
-         long size = dbDataReader.GetBytes(column, 0, null, 0, 0);  //get the length of data
+         long size = dataReader.GetBytes(column, 0, null, 0, 0);  //get the length of data
          byte[] values = new byte[size];
 
          int bufferSize = 64;
@@ -244,7 +243,7 @@ namespace appMpower
 
          while (bytesRead < size)
          {
-            bytesRead += dbDataReader.GetBytes(column, currentPosition, values, currentPosition, bufferSize);
+            bytesRead += dataReader.GetBytes(column, currentPosition, values, currentPosition, bufferSize);
             currentPosition += bufferSize;
          }
 
@@ -253,12 +252,12 @@ namespace appMpower
 
       public static async Task PopulateCache()
       {
-         using var pooledConnection = new PooledConnection(DataProvider.ConnectionString);
+         using var pooledConnection = new DbConnection(DbProviderFactory.ConnectionString);
          await pooledConnection.OpenAsync();
 
-         var (pooledCommand, dbDataParameter) = CreateReadCommand(pooledConnection);
+         var (dbCommand, dbDataParameter) = CreateReadCommand(pooledConnection);
 
-         using (pooledCommand)
+         using (dbCommand)
          {
             var cacheKeys = _cacheKeys;
             var cache = _cache;
@@ -266,7 +265,7 @@ namespace appMpower
             for (var i = 1; i < 10001; i++)
             {
                dbDataParameter.Value = i;
-               cache.Set<CachedWorld>(cacheKeys[i], await ReadSingleRow(pooledCommand));
+               cache.Set<CachedWorld>(cacheKeys[i], await ReadSingleRow(dbCommand));
             }
          }
       }
@@ -299,16 +298,16 @@ namespace appMpower
 
       static async Task<CachedWorld[]> LoadUncachedQueries(int id, int i, int count, CachedWorld[] result)
       {
-         using var pooledConnection = new PooledConnection(DataProvider.ConnectionString);
+         using var pooledConnection = new DbConnection(DbProviderFactory.ConnectionString);
          await pooledConnection.OpenAsync();
 
-         var (pooledCommand, dbDataParameter) = CreateReadCommand(pooledConnection);
+         var (dbCommand, dbDataParameter) = CreateReadCommand(pooledConnection);
 
-         using (pooledCommand)
+         using (dbCommand)
          {
             Func<ICacheEntry, Task<CachedWorld>> create = async (entry) =>
             {
-               return await ReadSingleRow(pooledCommand);
+               return await ReadSingleRow(dbCommand);
             };
 
             var cacheKeys = _cacheKeys;

+ 3 - 0
frameworks/CSharp/appmpower/src/appMpower.ado

@@ -18,11 +18,14 @@
 
    <ItemGroup>
       <PackageReference Include="Npgsql" Version="6.0.2" />
+      <PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
+      <PackageReference Include="System.Data.Odbc" Version="6.0.0" />
       <PackageReference Include="Microsoft.DotNet.ILCompiler" Version="7.0.0-*" />
    </ItemGroup>
 
    <PropertyGroup>
       <DefineConstants>$(DefineConstants);ADO</DefineConstants>
+      <DefineConstants>$(DefineConstants);POSTGRESQL</DefineConstants>
    </PropertyGroup>
 
 </Project>

+ 2 - 1
frameworks/CSharp/appmpower/src/appMpower.csproj

@@ -33,7 +33,8 @@
   </ItemGroup>
 
   <PropertyGroup>
-    <DefineConstants Condition=" '$(Database)' == 'mysql' ">$(DefineConstants);MYSQL</DefineConstants>
+      <DefineConstants>$(DefineConstants);ODBC</DefineConstants>
+      <DefineConstants Condition=" '$(Database)' == 'mysql' ">$(DefineConstants);MYSQL</DefineConstants>
   </PropertyGroup>
 
 </Project>