You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
299 lines
9.9 KiB
C#
299 lines
9.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Data.Common;
|
|
using System.Data.Odbc;
|
|
using System.Data.OleDb;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
|
|
namespace EntityFrameworkCore.Jet.Data.Tests
|
|
{
|
|
static class Helpers
|
|
{
|
|
public static int CountRows(JetConnection jetConnection, string sqlStatement)
|
|
{
|
|
var command = jetConnection.CreateCommand(sqlStatement);
|
|
var dataReader = command.ExecuteReader();
|
|
|
|
var count = 0;
|
|
while (dataReader.Read())
|
|
count++;
|
|
|
|
return count;
|
|
}
|
|
|
|
public static string GetDataReaderContent(DbConnection dbConnection, string sqlStatement)
|
|
{
|
|
const string delimiter = " | ";
|
|
|
|
using var command = dbConnection.CreateCommand();
|
|
command.CommandText = sqlStatement;
|
|
|
|
using var dataReader = command.ExecuteReader();
|
|
var content = new StringBuilder();
|
|
|
|
for (var i = 0; i < dataReader.FieldCount; i++)
|
|
{
|
|
content.Append($"`{dataReader.GetName(i)}`");
|
|
content.Append(delimiter);
|
|
}
|
|
content.Remove(content.Length - delimiter.Length, delimiter.Length);
|
|
content.AppendLine();
|
|
|
|
for (var i = 0; i < dataReader.FieldCount; i++)
|
|
{
|
|
content.Append("---");
|
|
content.Append(delimiter);
|
|
}
|
|
content.Remove(content.Length - delimiter.Length, delimiter.Length);
|
|
content.AppendLine();
|
|
|
|
while (dataReader.Read())
|
|
{
|
|
for (var i = 0; i < dataReader.FieldCount; i++)
|
|
{
|
|
content.Append(dataReader.GetValue(i));
|
|
content.Append(delimiter);
|
|
}
|
|
content.Remove(content.Length - delimiter.Length, delimiter.Length);
|
|
content.AppendLine();
|
|
}
|
|
|
|
return content.ToString().TrimEnd();
|
|
}
|
|
|
|
public static void ShowDataTableContent(DataTable dataTable)
|
|
{
|
|
var first = true;
|
|
|
|
foreach (DataColumn column in dataTable.Columns)
|
|
{
|
|
if (first)
|
|
first = false;
|
|
else
|
|
Console.Write("\t");
|
|
|
|
Console.Write(column.ColumnName);
|
|
}
|
|
|
|
Console.WriteLine();
|
|
|
|
foreach (DataRow row in dataTable.Rows)
|
|
{
|
|
first = true;
|
|
foreach (DataColumn column in dataTable.Columns)
|
|
{
|
|
if (first)
|
|
first = false;
|
|
else
|
|
Console.Write("\t");
|
|
|
|
Console.Write("{0}", row[column]);
|
|
}
|
|
|
|
Console.WriteLine();
|
|
}
|
|
}
|
|
|
|
private static string GetTestDirectory()
|
|
{
|
|
return System.IO.Path.GetDirectoryName(
|
|
System.Reflection.Assembly.GetExecutingAssembly()
|
|
.GetName()
|
|
.CodeBase.Replace("file:///", ""));
|
|
}
|
|
|
|
public static string[] GetQueries(string s)
|
|
{
|
|
var query = string.Empty;
|
|
var queries = new List<string>();
|
|
|
|
foreach (var line in s.Replace("\r\n", "\n")
|
|
.Split('\n'))
|
|
{
|
|
if (line.Contains("======="))
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(query))
|
|
queries.Add(query);
|
|
|
|
query = string.Empty;
|
|
}
|
|
|
|
query += line + "\n";
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(query))
|
|
queries.Add(query);
|
|
|
|
return queries.ToArray();
|
|
}
|
|
|
|
public static DbDataReader Execute(DbConnection connection, string query)
|
|
{
|
|
return InternatExecute(connection, null, query);
|
|
}
|
|
|
|
public static DbDataReader Execute(DbConnection connection, DbTransaction transaction, string query)
|
|
{
|
|
return InternatExecute(connection, transaction, query);
|
|
}
|
|
|
|
private static Regex _parseParameterRegex = new Regex(@"(?<name>.*)\((?<type>.*)\) = (?<value>.*)", RegexOptions.IgnoreCase);
|
|
|
|
private static DbDataReader InternatExecute(DbConnection connection, DbTransaction transaction, string queryAndParameters)
|
|
{
|
|
string query;
|
|
string parameterString;
|
|
|
|
if (queryAndParameters.Contains("\n-\n"))
|
|
{
|
|
var i = queryAndParameters.IndexOf("\n-\n", StringComparison.Ordinal);
|
|
query = queryAndParameters.Substring(0, i);
|
|
parameterString = queryAndParameters.Substring(i + 3);
|
|
}
|
|
else
|
|
{
|
|
query = queryAndParameters;
|
|
parameterString = null;
|
|
}
|
|
|
|
var sqlParts = query.Split('\n');
|
|
var executionMethod = sqlParts[0];
|
|
var sql = string.Empty;
|
|
for (var i = 1; i < sqlParts.Length; i++)
|
|
sql += sqlParts[i] + "\r\n";
|
|
|
|
var command = connection.CreateCommand();
|
|
if (transaction != null)
|
|
command.Transaction = transaction;
|
|
command.CommandText = sql;
|
|
|
|
if (parameterString != null)
|
|
{
|
|
var parameterStringList = parameterString.Split('\n');
|
|
foreach (var sParameter in parameterStringList)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(sParameter))
|
|
continue;
|
|
var match = _parseParameterRegex.Match(sParameter);
|
|
if (!match.Success)
|
|
throw new Exception("Parameter not valid " + sParameter);
|
|
var parameterName = match.Groups["name"]
|
|
.Value;
|
|
var parameterType = match.Groups["type"]
|
|
.Value;
|
|
var sparameterValue = match.Groups["value"]
|
|
.Value;
|
|
object parameterValue;
|
|
if (sparameterValue == "null")
|
|
parameterValue = DBNull.Value;
|
|
else
|
|
parameterValue = Convert.ChangeType(sparameterValue, Type.GetType("System." + parameterType));
|
|
|
|
var parameter = command.CreateParameter();
|
|
parameter.ParameterName = parameterName;
|
|
parameter.Value = parameterValue;
|
|
|
|
command.Parameters.Add(parameter);
|
|
}
|
|
}
|
|
|
|
if (executionMethod.StartsWith("ExecuteNonQuery"))
|
|
{
|
|
command.ExecuteNonQuery();
|
|
return null;
|
|
}
|
|
else if (executionMethod.StartsWith("ExecuteDbDataReader"))
|
|
{
|
|
return command.ExecuteReader();
|
|
}
|
|
else
|
|
throw new Exception("Unknown execution method " + executionMethod);
|
|
}
|
|
|
|
public static void ExecuteScript(DbConnection connection, string script)
|
|
{
|
|
using var command = connection.CreateCommand();
|
|
|
|
var batches = new Regex(@"\s*;\s*", RegexOptions.IgnoreCase | RegexOptions.Multiline, TimeSpan.FromMilliseconds(1000.0))
|
|
.Split(script)
|
|
.Where(b => !string.IsNullOrEmpty(b))
|
|
.ToList();
|
|
|
|
var retryWaitTime = TimeSpan.FromMilliseconds(250);
|
|
const int maxRetryCount = 6;
|
|
var retryCount = 0;
|
|
|
|
foreach (var batch in batches)
|
|
{
|
|
command.CommandText = batch;
|
|
|
|
try
|
|
{
|
|
command.ExecuteNonQuery();
|
|
retryCount = 0;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (retryCount >= maxRetryCount)
|
|
{
|
|
Console.WriteLine(e.Message);
|
|
Console.WriteLine(batch);
|
|
throw;
|
|
}
|
|
|
|
retryCount++;
|
|
Thread.Sleep(retryWaitTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static JetConnection CreateAndOpenDatabase(string storeName)
|
|
{
|
|
CreateDatabase(storeName);
|
|
var connection = new JetConnection(storeName);
|
|
connection.Open();
|
|
return connection;
|
|
}
|
|
|
|
public static void CreateDatabase(
|
|
string storeName,
|
|
DatabaseVersion version = DatabaseVersion.NewestSupported,
|
|
CollatingOrder collatingOrder = CollatingOrder.General,
|
|
string databasePassword = null)
|
|
{
|
|
DeleteDatabase(storeName);
|
|
JetConnection.CreateDatabase(storeName, version, collatingOrder, databasePassword);
|
|
}
|
|
|
|
public static void DeleteDatabase(string storeName)
|
|
{
|
|
JetConnection.ClearAllPools();
|
|
JetConnection.DropDatabase(storeName);
|
|
}
|
|
|
|
public static JetConnection OpenDatabase(string storeName, DbProviderFactory dataAccessProviderFactory = null)
|
|
{
|
|
var connection = new JetConnection(storeName, dataAccessProviderFactory ?? DataAccessProviderFactory);
|
|
|
|
try
|
|
{
|
|
connection.Open();
|
|
return connection;
|
|
}
|
|
catch
|
|
{
|
|
connection.Dispose();
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public static JetConnection OpenDatabase(string storeName, DataAccessProviderType providerType)
|
|
=> OpenDatabase(storeName, JetFactory.Instance.GetDataAccessProviderFactory(providerType));
|
|
|
|
public static DbProviderFactory DataAccessProviderFactory { get; set; } = OleDbFactory.Instance; //OdbcFactory.Instance;
|
|
}
|
|
} |