using System;
using System.ComponentModel;
using System.Data.Common;
using System.Data.Jet.JetStoreSchemaDefinition;
using System.Data.OleDb;
using System.Reflection;
using System.Transactions;
namespace System.Data.Jet
{
public class JetConnection : DbConnection, IDisposable, ICloneable
{
internal DbConnection WrappedConnection { get; private set; }
///
/// Initializes a new instance of the class.
///
public JetConnection()
{
WrappedConnection = new OleDbConnection();
WrappedConnection.StateChange += WrappedConnection_StateChange;
}
///
/// Initializes a new instance of the class.
///
/// The underling OleDb connection.
public JetConnection(OleDbConnection connection)
{
WrappedConnection = connection;
WrappedConnection.StateChange += WrappedConnection_StateChange;
}
///
/// Initializes a new instance of the class.
///
/// The connection string.
public JetConnection(string connectionString) : this()
{
this.ConnectionString = connectionString;
}
///
/// Gets or sets a value indicating whether this instance is empty.
/// It is similar to connection to master and can be used only to create and drop databases
///
///
/// true if this instance is empty; otherwise, false.
///
public bool IsEmpty { get; set; }
///
/// Gets the for this .
///
protected override DbProviderFactory DbProviderFactory
{
get
{
return JetProviderFactory.Instance;
}
}
///
/// Starts a database transaction.
///
/// Specifies the isolation level for the transaction.
///
/// An object representing the new transaction.
///
protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
{
switch (isolationLevel)
{
case IsolationLevel.Serializable:
return new JetTransaction(WrappedConnection.BeginTransaction(IsolationLevel.ReadCommitted), this);
case IsolationLevel.Chaos:
case IsolationLevel.ReadCommitted:
case IsolationLevel.ReadUncommitted:
case IsolationLevel.RepeatableRead:
case IsolationLevel.Snapshot:
case IsolationLevel.Unspecified:
default:
return new JetTransaction(WrappedConnection.BeginTransaction(isolationLevel), this);
}
}
///
/// Changes the current database for an open connection.
///
/// Specifies the name of the database for the connection to use.
public override void ChangeDatabase(string databaseName)
{
this.WrappedConnection.ChangeDatabase(databaseName);
}
///
/// Closes the connection to the database. This is the preferred method of closing any open connection.
///
public override void Close()
{
this.WrappedConnection.Close();
}
///
/// Gets or sets the string used to open the connection.
///
public override string ConnectionString
{
get
{
return this.WrappedConnection.ConnectionString;
}
set
{
this.WrappedConnection.ConnectionString = value;
}
}
///
/// Gets the time to wait while establishing a connection before terminating the attempt and generating an error.
///
public override int ConnectionTimeout
{
get
{
return this.WrappedConnection.ConnectionTimeout;
}
}
///
/// Creates and returns a object associated with the current connection.
///
///
/// A object.
///
protected override DbCommand CreateDbCommand()
{
DbCommand command = JetProviderFactory.Instance.CreateCommand();
command.Connection = this;
return command;
}
///
/// Gets the name of the current database after a connection is opened, or the database name specified in the connection string before the connection is opened.
///
public override string Database
{
get { return this.WrappedConnection.Database; }
}
///
/// Gets the name of the database server to which to connect.
///
public override string DataSource
{
get { return this.WrappedConnection.DataSource; }
}
///
/// Releases the unmanaged resources used by the and optionally releases the managed resources.
///
/// true to release both managed and unmanaged resources; false to release only unmanaged resources.
protected override void Dispose(bool disposing)
{
if (disposing)
this.WrappedConnection.Dispose();
base.Dispose(disposing);
OnDisposed(EventArgs.Empty);
}
///
/// Enlists in the specified transaction.
///
/// A reference to an existing in which to enlist.
public override void EnlistTransaction(Transaction transaction)
{
this.WrappedConnection.EnlistTransaction(transaction);
}
///
/// Returns schema information for the data source of this using the specified string for the schema name.
///
/// Specifies the name of the schema to return.
///
/// A that contains schema information.
///
///
///
///
public override DataTable GetSchema(string collectionName)
{
return this.WrappedConnection.GetSchema(collectionName);
}
///
/// Returns schema information for the data source of this .
///
///
/// A that contains schema information.
///
///
///
///
public override DataTable GetSchema()
{
return this.WrappedConnection.GetSchema();
}
///
/// Returns schema information for the data source of this using the specified string for the schema name and the specified string array for the restriction values.
///
/// Specifies the name of the schema to return.
/// Specifies a set of restriction values for the requested schema.
///
/// A that contains schema information.
///
///
///
///
public override DataTable GetSchema(string collectionName, string[] restrictionValues)
{
return this.WrappedConnection.GetSchema(collectionName, restrictionValues);
}
///
/// Opens a database connection with the settings specified by the .
///
public override void Open()
{
if (IsEmpty)
return;
this.WrappedConnection.Open();
}
///
/// Gets a string that represents the version of the server to which the object is connected.
///
public override string ServerVersion
{
get { return this.WrappedConnection.ServerVersion; }
}
///
/// Gets or sets the of the .
///
public override ISite Site
{
get
{
return this.WrappedConnection.Site;
}
set
{
this.WrappedConnection.Site = value;
}
}
///
/// Gets a string that describes the state of the connection.
///
public override ConnectionState State
{
get { return this.WrappedConnection.State; }
}
void WrappedConnection_StateChange(object sender, StateChangeEventArgs e)
{
OnStateChange(e);
}
public bool TableExists(string tableName)
{
ConnectionState oldConnectionState = State;
bool tableExists;
if (oldConnectionState == ConnectionState.Closed)
Open();
try
{
string sqlFormat = "select count(*) from [{0}] where 1=2";
CreateCommand(String.Format(sqlFormat, tableName)).ExecuteNonQuery();
tableExists = true;
}
catch
{
tableExists = false;
}
if (oldConnectionState == ConnectionState.Closed)
Close();
return tableExists;
}
public DbCommand CreateCommand(string commandText, int? commandTimeout = null)
{
if (String.IsNullOrEmpty(commandText))
// SqlCommand will complain if the command text is empty
commandText = Environment.NewLine;
var command = new JetCommand(commandText, this);
if (commandTimeout.HasValue)
command.CommandTimeout = commandTimeout.Value;
return command;
}
///
/// Occurs when the component is disposed by a call to the method.
///
public new event EventHandler Disposed;
///
/// Raises the event.
///
/// The instance containing the event data.
protected virtual void OnDisposed(EventArgs e)
{
if (Disposed != null)
Disposed(this, e);
}
///
/// Creates a new object that is a copy of the current instance.
///
///
/// A new object that is a copy of this instance.
///
object ICloneable.Clone()
{
JetConnection clone = new JetConnection();
clone.WrappedConnection = (DbConnection)((ICloneable)this.WrappedConnection).Clone();
return clone;
}
///
/// Performs an explicit conversion from to .
///
/// The connection.
///
/// The result of the conversion.
///
public static explicit operator OleDbConnection(JetConnection connection)
{
return (OleDbConnection)connection.WrappedConnection;
}
///
/// Clears the pool.
///
/// The connection.
public static void ClearPool(JetConnection connection)
{
// Actually Jet does not support pools
}
///
/// Clears all pools.
///
public static void ClearAllPools()
{
// Actually Jet does not support pools
}
public void CreateEmptyDatabase()
{
AdoxWrapper.CreateEmptyDatabase(WrappedConnection.ConnectionString);
}
public static string GetConnectionString(string fileName)
{
return $"Provider={JetConfiguration.OleDbDefaultProvider};Data Source={fileName}";
}
public void DropDatabase(bool throwOnError = true)
{
DropDatabase(WrappedConnection.ConnectionString, throwOnError);
}
public static void DropDatabase(string connectionString, bool throwOnError = true)
{
string fileName = JetStoreDatabaseHandling.ExtractFileNameFromConnectionString(connectionString);
if (string.IsNullOrWhiteSpace(fileName))
throw new Exception("Cannot retrieve file name from connection string");
JetStoreDatabaseHandling.DeleteFile(fileName.Trim(), throwOnError);
}
public bool DatabaseExists()
{
return DatabaseExists(WrappedConnection.ConnectionString);
}
public static bool DatabaseExists(string connectionString)
{
string fileName = JetStoreDatabaseHandling.ExtractFileNameFromConnectionString(connectionString);
if (string.IsNullOrWhiteSpace(fileName))
throw new Exception("Cannot retrieve file name from connection string");
return System.IO.File.Exists(fileName);
}
}
}