Skip to content

Commit

Permalink
Changed the approach to let the library create and dispose of the
Browse files Browse the repository at this point in the history
connection internally. Implemented as a constructor overload on
ExcelQueryFactory
  • Loading branch information
acorkery committed Sep 9, 2013
1 parent 0c48302 commit cc4d4c1
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 114 deletions.
75 changes: 0 additions & 75 deletions src/LinqToExcel.Tests/ExternalConnection_IntegrationTests.cs

This file was deleted.

1 change: 1 addition & 0 deletions src/LinqToExcel.Tests/LinqToExcel.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
<Compile Include="ConnectionString_UnitTests.cs" />
<Compile Include="Excel2007_IntegrationTests.cs" />
<Compile Include="ExcelQueryFactoryTests.cs" />
<Compile Include="PersistentConnection_IntegrationTests.cs" />
<Compile Include="NoHeader_IntregrationTests.cs" />
<Compile Include="NoHeader_SQLStatements_UnitTests.cs" />
<Compile Include="Range_IntegrationTests.cs" />
Expand Down
53 changes: 46 additions & 7 deletions src/LinqToExcel/ExcelQueryFactory.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Linq.Expressions;
using LinqToExcel.Domain;
using LinqToExcel.Query;
Expand All @@ -10,8 +12,9 @@ public class ExcelQueryFactory : IExcelQueryFactory
{
private readonly Dictionary<string, string> _columnMappings = new Dictionary<string, string>();
private readonly Dictionary<string, Func<string, object>> _transformations = new Dictionary<string, Func<string, object>>();
private OleDbConnection _persistentConnection;

/// <summary>
/// <summary>
/// Full path to the Excel spreadsheet
/// </summary>
public string FileName { get; set; }
Expand Down Expand Up @@ -39,6 +42,21 @@ public ExcelQueryFactory(string fileName)
DatabaseEngine = ExcelUtilities.DefaultDatabaseEngine();
}

/// <param name="fileName">Full path to the Excel spreadsheet</param>
/// <param name="createPersistentConnection">If <c>true</c>, a connection will be created and shared for the lifetime of the factory. If <c>false</c>, a connection will be created and disposed for each query operation (default)</param>
public ExcelQueryFactory(string fileName, bool createPersistentConnection) : this(fileName)
{
if (createPersistentConnection)
{
_persistentConnection = new OleDbConnection(ExcelUtilities.GetConnectionString(new ExcelQueryArgs
{
DatabaseEngine = DatabaseEngine,
FileName = fileName,
NoHeader = true
}));
}
}

#region Other Methods

/// <summary>
Expand Down Expand Up @@ -135,7 +153,8 @@ internal ExcelQueryConstructorArgs GetConstructorArgs()
DatabaseEngine = DatabaseEngine,
StrictMapping = StrictMapping,
ColumnMappings = _columnMappings,
Transformations = _transformations
Transformations = _transformations,
PersistentConnection = _persistentConnection
};
}

Expand Down Expand Up @@ -244,7 +263,8 @@ public ExcelQueryable<Row> WorksheetRange(string startRange, string endRange)
new ExcelQueryArgs(GetConstructorArgs())
{
StartRange = startRange,
EndRange = endRange
EndRange = endRange,
PersistentConnection = _persistentConnection
});
}

Expand Down Expand Up @@ -412,9 +432,28 @@ public ExcelQueryable<RowNoHeader> WorksheetRangeNoHeader(string startRange, str

#endregion

#region Static Methods

/// <summary>
#region IDisposable Methods
public void Dispose()
{
try
{
if (_persistentConnection != null)
{
_persistentConnection.Dispose();
}
}
catch
{}
finally
{
_persistentConnection = null;
}
}
#endregion

#region Static Methods

/// <summary>
/// Enables Linq queries against an Excel worksheet
/// </summary>
/// <typeparam name="TSheetData">Class type to return row data as</typeparam>
Expand Down Expand Up @@ -543,5 +582,5 @@ public static ExcelQueryable<TSheetData> Worksheet<TSheetData>(int worksheetInde
}

#endregion
}
}
}
3 changes: 2 additions & 1 deletion src/LinqToExcel/IExcelQueryFactory.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System;
using System.Data.OleDb;
using System.Linq.Expressions;
using LinqToExcel.Query;
using System.Collections.Generic;
using LinqToExcel.Domain;

namespace LinqToExcel
{
public interface IExcelQueryFactory
public interface IExcelQueryFactory : IDisposable
{
/// <summary>
/// Full path to the Excel spreadsheet
Expand Down
8 changes: 6 additions & 2 deletions src/LinqToExcel/Query/ExcelQueryArgs.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.Linq;
using System.Text;
using LinqToExcel.Domain;
Expand All @@ -18,6 +19,7 @@ internal class ExcelQueryArgs
internal string EndRange { get; set; }
internal bool NoHeader { get; set; }
internal StrictMappingType? StrictMapping { get; set; }
internal OleDbConnection PersistentConnection { get; set; }

internal ExcelQueryArgs()
: this(new ExcelQueryConstructorArgs() { DatabaseEngine = ExcelUtilities.DefaultDatabaseEngine() })
Expand All @@ -30,6 +32,7 @@ internal ExcelQueryArgs(ExcelQueryConstructorArgs args)
ColumnMappings = args.ColumnMappings ?? new Dictionary<string, string>();
Transformations = args.Transformations ?? new Dictionary<string, Func<string, object>>();
StrictMapping = args.StrictMapping ?? StrictMappingType.None;
PersistentConnection = args.PersistentConnection;
}

public override string ToString()
Expand All @@ -38,9 +41,10 @@ public override string ToString()
foreach (var kvp in ColumnMappings)
columnMappingsString.AppendFormat("[{0} = '{1}'] ", kvp.Key, kvp.Value);
var transformationsString = string.Join(", ", Transformations.Keys.ToArray());
string persistentConnection = (PersistentConnection == null) ? string.Empty : PersistentConnection.ConnectionString;

return string.Format("FileName: '{0}'; WorksheetName: '{1}'; WorksheetIndex: {2}; StartRange: {3}; EndRange: {4}; NoHeader: {5}; ColumnMappings: {6}; Transformations: {7}, StrictMapping: {8}",
FileName, WorksheetName, WorksheetIndex, StartRange, EndRange, NoHeader, columnMappingsString, transformationsString, StrictMapping);
return string.Format("FileName: '{0}'; WorksheetName: '{1}'; WorksheetIndex: {2}; StartRange: {3}; EndRange: {4}; NoHeader: {5}; ColumnMappings: {6}; Transformations: {7}, StrictMapping: {8}; PersistentConnection: {9}",
FileName, WorksheetName, WorksheetIndex, StartRange, EndRange, NoHeader, columnMappingsString, transformationsString, StrictMapping, persistentConnection);
}
}
}
3 changes: 3 additions & 0 deletions src/LinqToExcel/Query/ExcelQueryConstructorArgs.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.Linq;
using System.Text;
using LinqToExcel.Domain;
Expand All @@ -13,5 +14,7 @@ internal class ExcelQueryConstructorArgs
internal Dictionary<string, string> ColumnMappings { get; set; }
internal Dictionary<string, Func<string, object>> Transformations { get; set; }
internal StrictMappingType? StrictMapping { get; set; }
internal bool CreatePersistentConnection { get; set; }
internal OleDbConnection PersistentConnection { get; set; }
}
}
28 changes: 21 additions & 7 deletions src/LinqToExcel/Query/ExcelQueryExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,19 @@ internal class ExcelQueryExecutor : IQueryExecutor
{
private readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private readonly ExcelQueryArgs _args;
private readonly string _connectionString;

internal ExcelQueryExecutor(ExcelQueryArgs args)
{
ValidateArgs(args);
_args = args;
_connectionString = ExcelUtilities.GetConnectionString(args);
if (_log.IsDebugEnabled)
_log.DebugFormat("Connection String: {0}", _connectionString);

string connectionString = args.PersistentConnection != null ?
args.PersistentConnection.ConnectionString :
ExcelUtilities.GetConnectionString(args);

if (_log.IsDebugEnabled)
_log.DebugFormat("Connection String: {0}", connectionString);

GetWorksheetName();
}

Expand Down Expand Up @@ -164,11 +168,15 @@ protected IEnumerable<object> GetDataResults(SqlParts sql, QueryModel queryModel
{
IEnumerable<object> results;
OleDbDataReader data = null;
using (var conn = new OleDbConnection(_connectionString))

var conn = ExcelUtilities.GetConnection(_args);
using (var command = conn.CreateCommand())
{
conn.Open();
command.CommandText = sql.ToString();
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
command.CommandText = sql.ToString();
command.Parameters.AddRange(sql.Parameters.ToArray());
try { data = command.ExecuteReader(); }
catch (OleDbException e)
Expand All @@ -192,6 +200,12 @@ protected IEnumerable<object> GetDataResults(SqlParts sql, QueryModel queryModel
else
results = GetTypeResults(data, columns, queryModel);
}

if (_args.PersistentConnection == null)
{
conn.Dispose();
}

return results;
}

Expand Down
66 changes: 44 additions & 22 deletions src/LinqToExcel/Query/ExcelUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,33 +69,55 @@ internal static string GetConnectionString(ExcelQueryArgs args)

internal static IEnumerable<string> GetWorksheetNames(string fileName)
{
var args = new ExcelQueryArgs();
args.FileName = fileName;
return GetWorksheetNames(args);
return GetWorksheetNames(fileName, new ExcelQueryArgs());
}

internal static IEnumerable<string> GetWorksheetNames(string fileName, ExcelQueryArgs args)
{
args.FileName = fileName;
return GetWorksheetNames(args);
}

internal static OleDbConnection GetConnection(ExcelQueryArgs args)
{
if (args.PersistentConnection != null)
return args.PersistentConnection;

return new OleDbConnection(GetConnectionString(args));
}

internal static IEnumerable<string> GetWorksheetNames(ExcelQueryArgs args)
{
var worksheetNames = new List<string>();
using (var conn = new OleDbConnection(GetConnectionString(args)))
{
conn.Open();
var excelTables = conn.GetOleDbSchemaTable(
OleDbSchemaGuid.Tables,
new Object[] { null, null, null, "TABLE" });

worksheetNames.AddRange(
from DataRow row in excelTables.Rows
where IsTable(row)
let tableName = row["TABLE_NAME"].ToString()
.Replace("$", "")
.RegexReplace("(^'|'$)", "")
.Replace("''", "'")
where IsNotBuiltinTable(tableName)
select tableName);

excelTables.Dispose();
}

var conn = GetConnection(args);

if (conn.State != ConnectionState.Open)
{
conn.Open();
}

var excelTables = conn.GetOleDbSchemaTable(
OleDbSchemaGuid.Tables,
new Object[] { null, null, null, "TABLE" });

worksheetNames.AddRange(
from DataRow row in excelTables.Rows
where IsTable(row)
let tableName = row["TABLE_NAME"].ToString()
.Replace("$", "")
.RegexReplace("(^'|'$)", "")
.Replace("''", "'")
where IsNotBuiltinTable(tableName)
select tableName);

excelTables.Dispose();

if (args.PersistentConnection == null)
{
conn.Dispose();
}

return worksheetNames;
}

Expand Down

0 comments on commit cc4d4c1

Please sign in to comment.