blob: 6b14d50535dfbdf3a58893e72b99320f0fc5e7d2 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
namespace Apache.Arrow.Adbc.Drivers.Apache
{
internal class ApacheUtility
{
internal const int QueryTimeoutSecondsDefault = 60;
public enum TimeUnit
{
Seconds,
Milliseconds
}
public static CancellationTokenSource GetCancellationTokenSource(int timeout, TimeUnit timeUnit)
{
TimeSpan timeSpan = CalculateTimeSpan(timeout, timeUnit);
return new CancellationTokenSource(timeSpan);
}
public static CancellationToken GetCancellationToken(int timeout, TimeUnit timeUnit)
{
TimeSpan timeSpan = CalculateTimeSpan(timeout, timeUnit);
var cts = new CancellationTokenSource(timeSpan);
return cts.Token;
}
private static TimeSpan CalculateTimeSpan(int timeout, TimeUnit timeUnit)
{
TimeSpan span;
if (timeout == 0 || timeout == int.MaxValue)
{
// the max TimeSpan for CancellationTokenSource is int.MaxValue in milliseconds (not TimeSpan.MaxValue)
// no matter what the unit is
span = TimeSpan.FromMilliseconds(int.MaxValue);
}
else
{
if (timeUnit == TimeUnit.Seconds)
{
span = TimeSpan.FromSeconds(timeout);
}
else
{
span = TimeSpan.FromMilliseconds(timeout);
}
}
return span;
}
public static bool QueryTimeoutIsValid(string key, string value, out int queryTimeoutSeconds)
{
if (!string.IsNullOrEmpty(value) && int.TryParse(value, out int queryTimeout) && (queryTimeout >= 0))
{
queryTimeoutSeconds = queryTimeout;
return true;
}
else
{
throw new ArgumentOutOfRangeException(key, value, $"The value '{value}' for option '{key}' is invalid. Must be a numeric value of 0 (infinite) or greater.");
}
}
public static bool BooleanIsValid(string key, string value, out bool booleanValue)
{
if (bool.TryParse(value, out booleanValue))
{
return true;
}
else
{
throw new ArgumentOutOfRangeException(key, nameof(value), $"Invalid value for {key}: {value}. Expected a boolean value.");
}
}
public static bool ContainsException<T>(Exception exception, out T? containedException) where T : Exception
{
Exception? e = exception;
while (e != null)
{
if (e is T ce)
{
containedException = ce;
return true;
}
else if (e is AggregateException aggregateException)
{
foreach (Exception? ex in aggregateException.InnerExceptions)
{
if (ContainsException(ex, out T? inner))
{
containedException = inner;
return true;
}
}
}
e = e.InnerException;
}
containedException = null;
return false;
}
public static bool ContainsException(Exception exception, Type? exceptionType, out Exception? containedException)
{
if (exceptionType == null)
{
containedException = null;
return false;
}
Exception? e = exception;
while (e != null)
{
if (exceptionType.IsInstanceOfType(e))
{
containedException = e;
return true;
}
else if (e is AggregateException aggregateException)
{
foreach (Exception? ex in aggregateException.InnerExceptions)
{
if (ContainsException(ex, exceptionType, out Exception? inner))
{
containedException = inner;
return true;
}
}
}
e = e.InnerException;
}
containedException = null;
return false;
}
internal static string FormatExceptionMessage(Exception exception)
{
if (exception is AggregateException aEx)
{
AggregateException flattenedEx = aEx.Flatten();
IEnumerable<string> messages = flattenedEx.InnerExceptions.Select((ex, index) => $"({index + 1}) {ex.Message}");
string fullMessage = $"{flattenedEx.Message}: {string.Join(", ", messages)}";
return fullMessage;
}
return exception.Message;
}
internal static string GetAssemblyName(Type type) => type.Assembly.GetName().Name!;
internal static string GetAssemblyVersion(Type type) => FileVersionInfo.GetVersionInfo(type.Assembly.Location).ProductVersion ?? string.Empty;
}
}