Import dotnetDBF for error handling.
This commit is contained in:
38
DotNetDBF.Enumerable/DotNetDBF.Enumerable.csproj
Normal file
38
DotNetDBF.Enumerable/DotNetDBF.Enumerable.csproj
Normal file
@@ -0,0 +1,38 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net40;netstandard2.0</TargetFrameworks>
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>sn.snk</AssemblyOriginatorKeyFile>
|
||||
<PackageId>dotnetdbf.enumerable</PackageId>
|
||||
<Authors>Jay Tuley</Authors>
|
||||
<Company>Ekon Benefits</Company>
|
||||
<Description>For dotnetdbf projects using .net 4.0 projects this is an enumeration framework in which makes it easy to use Linq to Objects.</Description>
|
||||
<PackageLicense>lgpl</PackageLicense>
|
||||
<PackageProjectUrl>https://github.com/ekonbenefits/dotnetdbf</PackageProjectUrl>
|
||||
<PackageTags>clipper xbase dbf linq</PackageTags>
|
||||
<PackageLicenseExpression>LGPL-2.1-or-later</PackageLicenseExpression>
|
||||
<PackageIconUrl>https://github.com/ekonbenefits/dotnetdbf</PackageIconUrl>
|
||||
<RepositoryUrl>https://github.com/ekonbenefits/dotnetdbf.git</RepositoryUrl>
|
||||
<RepositoryType>gits</RepositoryType>
|
||||
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<Version>6.0.0.2</Version>
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<IncludeSource>True</IncludeSource>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\Copying.txt" Pack="true" PackagePath="" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-18618-05" PrivateAssets="All"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ImpromptuInterface" Version="7.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DotNetDBF\DotNetDBF.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
271
DotNetDBF.Enumerable/Enumerable.cs
Normal file
271
DotNetDBF.Enumerable/Enumerable.cs
Normal file
@@ -0,0 +1,271 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using ImpromptuInterface;
|
||||
using Dynamitey;
|
||||
|
||||
namespace DotNetDBF.Enumerable
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface to get the contents of the DBF Wrapper
|
||||
/// </summary>
|
||||
public interface IDBFInterceptor
|
||||
{
|
||||
/// <summary>
|
||||
/// Does field exist in row
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool Exists(string fieldName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data row.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
object[] GetDataRow();
|
||||
}
|
||||
|
||||
#pragma warning disable 618
|
||||
public class DBFInterceptor : DBFIntercepter
|
||||
#pragma warning restore 618
|
||||
{
|
||||
public DBFInterceptor(object[] wrappedObj, string[] fieldNames) : base(wrappedObj, fieldNames)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// DBF Dynamic Wrapper
|
||||
/// </summary>
|
||||
public abstract class BaseDBFInterceptor : Dynamitey.DynamicObjects.BaseObject, IDBFInterceptor
|
||||
{
|
||||
private readonly string[] _fieldNames;
|
||||
private readonly object[] _wrappedArray;
|
||||
|
||||
protected BaseDBFInterceptor(object[] wrappedObj, string[] fieldNames)
|
||||
{
|
||||
_wrappedArray = wrappedObj;
|
||||
_fieldNames = fieldNames;
|
||||
}
|
||||
|
||||
public override IEnumerable<string> GetDynamicMemberNames()
|
||||
{
|
||||
return _fieldNames;
|
||||
}
|
||||
|
||||
public bool Exists(string fieldName)
|
||||
{
|
||||
return _fieldNames.Contains(fieldName);
|
||||
}
|
||||
|
||||
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
||||
{
|
||||
result = null;
|
||||
var tLookup = binder.Name;
|
||||
var tIndex = Array.FindIndex(_fieldNames,
|
||||
it => it.Equals(tLookup, StringComparison.InvariantCultureIgnoreCase));
|
||||
|
||||
if (tIndex < 0)
|
||||
return false;
|
||||
|
||||
|
||||
result = _wrappedArray[tIndex];
|
||||
|
||||
|
||||
if (TryTypeForName(tLookup, out var outType))
|
||||
{
|
||||
result = Dynamic.CoerceConvert(result, outType);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool TrySetMember(SetMemberBinder binder, object value)
|
||||
{
|
||||
var tLookup = binder.Name;
|
||||
var tIndex = Array.FindIndex(_fieldNames,
|
||||
it => it.Equals(tLookup, StringComparison.InvariantCultureIgnoreCase));
|
||||
|
||||
if (tIndex < 0)
|
||||
return false;
|
||||
|
||||
if (TryTypeForName(tLookup, out var outType))
|
||||
{
|
||||
value = Dynamic.CoerceConvert(value, outType);
|
||||
}
|
||||
|
||||
_wrappedArray[tIndex] = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public object[] GetDataRow()
|
||||
{
|
||||
return _wrappedArray;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerable API
|
||||
/// </summary>
|
||||
public static partial class DBFEnumerable
|
||||
{
|
||||
/// <summary>
|
||||
/// New Blank Row Dynamic object that matches writer;
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <returns></returns>
|
||||
public static dynamic NewBlankRow(this DBFWriter writer)
|
||||
{
|
||||
var fields = writer.Fields.Select(it => it.Name).ToArray();
|
||||
var obj = new object[fields.Length];
|
||||
return new Enumerable.DBFInterceptor(obj, fields);
|
||||
}
|
||||
|
||||
public static void CopyRecordTo(this IDBFInterceptor original, IDBFInterceptor dest)
|
||||
{
|
||||
foreach (var fieldName in Dynamitey.Dynamic.GetMemberNames(dest, true))
|
||||
{
|
||||
try
|
||||
{
|
||||
var val = Dynamic.InvokeGet(original, fieldName);
|
||||
Dynamic.InvokeSet(dest, fieldName, val);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Writes the record.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
public static void WriteRecord(this DBFWriter writer, Enumerable.IDBFInterceptor value)
|
||||
{
|
||||
writer.WriteRecord(value.GetDataRow());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the record.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
public static void AddRecord(this DBFWriter writer, Enumerable.IDBFInterceptor value)
|
||||
{
|
||||
writer.AddRecord(value.GetDataRow());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return all the records. T should be interface with getter properties that match types and names of the database.
|
||||
/// Optionally instead of T being and interface you can pass in an anonymous object with properties that match that
|
||||
/// database and then you'll get an IEnumerable of that anonymous type with the data filled in.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="prototype">The prototype. Anonymous class instance</param>
|
||||
/// <param name="throwOnParsingError">Indicates if parsing error throws an exception. Default: true</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<T> AllRecords<T>(this DBFReader reader, T prototype = null, bool throwOnParsingError = true) where T : class
|
||||
{
|
||||
var tType = typeof(T);
|
||||
|
||||
var tProperties = tType.GetProperties()
|
||||
.Where(
|
||||
it =>
|
||||
Array.FindIndex(reader.Fields,
|
||||
f => f.Name.Equals(it.Name, StringComparison.InvariantCultureIgnoreCase)) >= 0)
|
||||
.ToList();
|
||||
var tProps = tProperties
|
||||
.Select(
|
||||
it =>
|
||||
Array.FindIndex(reader.Fields,
|
||||
jt => jt.Name.Equals(it.Name, StringComparison.InvariantCultureIgnoreCase)))
|
||||
.Where(it => it >= 0)
|
||||
.ToArray();
|
||||
|
||||
var tOrderedProps = tProps.OrderBy(it => it).ToArray();
|
||||
var tReturn = new List<T>();
|
||||
|
||||
|
||||
if (tType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Any())
|
||||
{
|
||||
var tAnon = reader.NextRecord(tProps, tOrderedProps, throwOnParsingError);
|
||||
while (tAnon != null)
|
||||
{
|
||||
tReturn.Add((T) Activator.CreateInstance(tType, tAnon));
|
||||
tAnon = reader.NextRecord(tProps, tOrderedProps, throwOnParsingError);
|
||||
}
|
||||
|
||||
|
||||
return tReturn;
|
||||
}
|
||||
|
||||
var t = reader.NextRecord(tProps, tOrderedProps, throwOnParsingError);
|
||||
|
||||
while (t != null)
|
||||
{
|
||||
var interceptor = new Enumerable.DBFInterceptor(t, tProperties.Select(it => it.Name).ToArray());
|
||||
|
||||
tReturn.Add(interceptor.ActLike<T>(typeof(Enumerable.IDBFInterceptor)));
|
||||
t = reader.NextRecord(tProps, tOrderedProps, throwOnParsingError);
|
||||
}
|
||||
|
||||
|
||||
return tReturn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of dynamic objects whose properties and types match up with that database name.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="whereColumn">The where column name.</param>
|
||||
/// <param name="whereColumnEquals">What the were column should equal.</param>
|
||||
/// <param name="throwOnParsingError">Indicates if parsing error throws an exception. Default: true</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<dynamic> DynamicAllRecords(this DBFReader reader, string whereColumn = null,
|
||||
dynamic whereColumnEquals = null, bool throwOnParsingError = true)
|
||||
{
|
||||
var props = reader.GetSelectFields().Select(it => it.Name).ToArray();
|
||||
|
||||
int? whereColumnIndex = null;
|
||||
if (!String.IsNullOrEmpty(whereColumn))
|
||||
{
|
||||
whereColumnIndex = Array.FindIndex(props,
|
||||
it => it.Equals(whereColumn, StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
|
||||
|
||||
var tReturn = new List<object>();
|
||||
var t = reader.NextRecord(throwOnParsingError);
|
||||
|
||||
while (t != null)
|
||||
{
|
||||
if (whereColumnIndex is int i)
|
||||
{
|
||||
dynamic tO = t[i];
|
||||
if (!tO.Equals(whereColumnEquals))
|
||||
{
|
||||
t = reader.NextRecord(throwOnParsingError);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var interceptor = new Enumerable.DBFInterceptor(t, props);
|
||||
|
||||
|
||||
tReturn.Add(interceptor);
|
||||
t = reader.NextRecord(throwOnParsingError);
|
||||
}
|
||||
|
||||
|
||||
return tReturn;
|
||||
}
|
||||
}
|
||||
}
|
||||
128
DotNetDBF.Enumerable/Obsolete.cs
Normal file
128
DotNetDBF.Enumerable/Obsolete.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
// ReSharper disable StringLiteralTypo
|
||||
// ReSharper disable IdentifierTypo
|
||||
|
||||
|
||||
namespace DotNetDBF.Enumerable
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface to get the contents of the DBF Wrapper
|
||||
/// </summary>
|
||||
///
|
||||
[Obsolete("DotNetDBF.Enumerable.IDBFInterceptor is the new interface name",error:true)]
|
||||
public interface IDBFIntercepter:IDBFInterceptor
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("DotNetDBF.Enumerable.DBFInterceptor is the new class name")]
|
||||
public class DBFIntercepter : DBFEnumerable.DBFIntercepter
|
||||
{
|
||||
public DBFIntercepter(object[] wrappedObj, string[] fieldNames) : base(wrappedObj, fieldNames)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace DotNetDBF.Enumerable
|
||||
{
|
||||
public static partial class DBFEnumerable
|
||||
{
|
||||
[Obsolete("DotNetDBF.Enumerable.IDBFIntercepter is the new interface name")]
|
||||
public interface IDBFIntercepter : DotNetDBF.Enumerable.IDBFIntercepter
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("DotNetDBF.Enumerable.DBFIntercepter is the new class name")]
|
||||
public class DBFIntercepter : DotNetDBF.Enumerable.Enuemrable.DBFIntercepter, IDBFIntercepter
|
||||
{
|
||||
public DBFIntercepter(object[] wrappedObj, string[] fieldNames)
|
||||
: base(wrappedObj, fieldNames)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("DBFEnumerable is the new class name")]
|
||||
public static class Enuemrable
|
||||
{
|
||||
/// <summary>
|
||||
/// New Blank Row Dynamic object that matches writer;
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <returns></returns>
|
||||
public static dynamic NewBlankRow(DBFWriter writer)
|
||||
{
|
||||
return writer.NewBlankRow();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Writes the record.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
public static void WriteRecord(DBFWriter writer, IDBFIntercepter value)
|
||||
{
|
||||
writer.WriteRecord(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the record.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
public static void AddRecord(DBFWriter writer, IDBFIntercepter value)
|
||||
{
|
||||
writer.AddRecord(writer, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return all the records. T should be interface with getter properties that match types and names of the database.
|
||||
/// Optionally instead of T being and interface you can pass in an anonymous object with properties that match that
|
||||
/// database and then you'll get an IEnumerable of that anonymous type with the data filled in.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="prototype">The prototype. Anonymous class instance</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<T> AllRecords<T>(DBFReader reader, T prototype = null) where T : class
|
||||
{
|
||||
return reader.AllRecords(prototype);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of dynamic objects whose properties and types match up with that database name.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="whereColumn">The where column name.</param>
|
||||
/// <param name="whereColumnEquals">What the were column should equal.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<dynamic> DynamicAllRecords(DBFReader reader, string whereColumn = null,
|
||||
dynamic whereColumnEquals = null)
|
||||
{
|
||||
return reader.DynamicAllRecords(whereColumn, (object) whereColumnEquals);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("DotNetDBF.Enumerable.IDBFIntercepter is the new interface name",error:true)]
|
||||
public interface IDBFIntercepter : DotNetDBF.Enumerable.IDBFInterceptor
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("DotNetDBF.Enumerable.DBFIntercepter is the new class name")]
|
||||
public class DBFIntercepter : DotNetDBF.Enumerable.BaseDBFInterceptor, IDBFIntercepter
|
||||
{
|
||||
public DBFIntercepter(object[] wrappedObj, string[] fieldNames)
|
||||
: base(wrappedObj, fieldNames)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
DotNetDBF.Enumerable/sn.snk
Normal file
BIN
DotNetDBF.Enumerable/sn.snk
Normal file
Binary file not shown.
Reference in New Issue
Block a user