|
|
using Apewer.Internals;
#if NETFX
using System; using System.Collections.Generic; using System.Data; using System.Data.OleDb; using System.IO; using System.Text; #endif
namespace Apewer.Source {
/// <summary>用于快速连接 Microsoft Access 数据库的辅助。</summary>
public partial class Access {
/// <summary>尝试解析 Access 文件的密码。</summary>
/// <remarks>当操作系统启用随机化内存分配时,此方法可能会产生异常。</remarks>
public static string[] ParsePassword(string path) => AccessHelper.GetPassword(path);
}
#if NETFX
public partial class Access : IDatabase, IDisposable {
/// <summary>创建 Access 类的新实例。</summary>
public static Access Jet4() => new Access(AccessHelper.JetOleDB4);
/// <summary>创建 Access 类的新实例。</summary>
public static Access Ace12() => new Access(AccessHelper.AceOleDB12);
#region 属性、构造函数和 Dispose。
private OleDbConnection _connection = null;
internal string Provider { get; set; }
/// <summary>构造函数。</summary>
internal Access(string provider) { Provider = provider; Timeout = new Timeout(); }
/// <summary>释放资源。</summary>
public void Dispose() => Close();
#endregion
#region 日志。
/// <summary>获取或设置日志记录。</summary>
public Logger Logger { get; set; }
private void LogError(string action, Exception ex, string addtion) { var logger = Logger; if (logger != null) logger.Error(this, "Access", action, ex.GetType().FullName, ex.Message, addtion); }
#endregion
#region 连接。
/// <summary>获取或设置数据库文件的路径。</summary>
public string Path { get; set; }
/// <summary>Microsoft Access System Database。</summary>
public string Josd { get; set; }
/// <summary>获取或设置用于连接数据库的密码。</summary>
public string Pass { get; set; }
/// <summary>获取或设置超时。</summary>
public Timeout Timeout { get; set; }
/// <summary>数据库是否已经连接。</summary>
public bool Online { get { if (_connection != null) { if (_connection.State == ConnectionState.Open) return true; } return false; } }
/// <summary>连接数据库,若未连接则尝试连接。</summary>
/// <returns>是否已连接。</returns>
public bool Connect() { var cs = GenerateConnectionString(); if (_connection == null) { _connection = new OleDbConnection(); _connection.ConnectionString = cs; } else { if (_connection.State == ConnectionState.Open) return true; } try { _connection.Open(); if (_connection.State == ConnectionState.Open) return true; } catch (Exception argException) { LogError("Connect", argException, cs); Close(); } return false; }
/// <summary>释放对象所占用的系统资源。</summary>
public void Close() { if (_connection != null) { _connection.Close(); _connection.Dispose(); _connection = null; } }
/// <summary>获取或设置连接字符串。</summary>
private string GenerateConnectionString() { if (!File.Exists(Path)) return null;
var sb = new StringBuilder();
sb.Append("provider=", Provider, "; ");
if (!string.IsNullOrEmpty(Path)) sb.Append("data source=", Path, "; ");
if (string.IsNullOrEmpty(Pass)) sb.Append("persist security info=false; "); else sb.Append("jet oledb:database password=\"", Pass, "\"; ");
// Microsoft Access Workgroup Information
if (!string.IsNullOrEmpty(Josd)) sb.Append("jet oledb:system database=", Josd, "; ");
return sb.ToString(); }
#endregion
#region 查询和执行。
/// <summary>使用 SQL 语句进行查询。</summary>
public IQuery Query(string sql) => Query(sql, null);
/// <summary>使用 SQL 语句进行查询。</summary>
public IQuery Query(string sql, IEnumerable<IDataParameter> parameters) { if (sql.IsBlank()) return Example.InvalidQueryStatement;
const string table = "queryresult";
var connected = Connect(); if (!connected) return Example.InvalidQueryConnection;
var query = new Query(); try { var command = new OleDbCommand(); command.Connection = _connection; command.CommandTimeout = Timeout.Query; command.CommandText = sql; if (parameters != null) { foreach (var p in parameters) { if (p != null) command.Parameters.Add(p); } } using (var ds = new DataSet()) { using (var da = new OleDbDataAdapter(sql, _connection)) { da.Fill(ds, table); query.Table = ds.Tables[table]; } } command.Dispose(); query.Success = true; } catch (Exception exception) { LogError("Query", exception, sql); query.Success = false; query.Exception = exception; } return query; }
/// <summary>执行 SQL 语句。</summary>
public IExecute Execute(string sql) => Execute(sql, null);
/// <summary>执行 SQL 语句,并加入参数。</summary>
public IExecute Execute(string sql, IEnumerable<IDataParameter> parameters) { if (sql.IsBlank()) return Example.InvalidExecuteStatement;
var connected = Connect(); if (!connected) return Example.InvalidExecuteConnection;
var execute = new Execute(); using (var transaction = _connection.BeginTransaction()) { try { using (var command = new OleDbCommand()) { command.Connection = _connection; command.Transaction = transaction; command.CommandTimeout = Timeout.Execute; command.CommandText = sql; if (parameters != null) { foreach (var parameter in parameters) { if (parameter == null) continue; command.Parameters.Add(parameter); } } execute.Rows += command.ExecuteNonQuery(); transaction.Commit(); } execute.Success = true; } catch (Exception exception) { LogError("Execute", exception, sql); try { transaction.Rollback(); } catch { } execute.Success = false; execute.Exception = exception; } }
return execute; }
#endregion
#region Parameter
/// <summary>创建参数列表。</summary>
public static List<IDbDataParameter> NewParameterList() { return new List<IDbDataParameter>(); }
/// <summary>创建参数。</summary>
public static IDbDataParameter CreateParameter(String field, DbType type, Int32 size, Object value) { var p = new OleDbParameter(); p.ParameterName = field; p.DbType = type; p.Size = size; p.Value = value; return p; }
/// <summary>创建参数。</summary>
public static IDbDataParameter CreateParameter(String field, DbType type, Object value) { var p = new OleDbParameter(); p.ParameterName = field; p.DbType = type; p.Value = value; return p; }
#endregion
}
/// <summary>使用 Microsoft.Jet.OLEDB.4.0 访问 Access 97 - 2003 数据库文件。</summary>
public class AccessJet4 : Access {
/// <summary>创建 Access 类的新实例。</summary>
public AccessJet4() : base(AccessHelper.JetOleDB4) { }
/// <summary>创建 Access 类的新实例。</summary>
public AccessJet4(string path) : base(AccessHelper.JetOleDB4) { Path = path; }
}
/// <summary>使用 Microsoft.ACE.OLEDB.12.0 访问 Access 2007 数据库文件。</summary>
public class AccessAce12 : Access {
/// <summary>创建 Access 类的新实例。</summary>
public AccessAce12() : base(AccessHelper.AceOleDB12) { }
/// <summary>创建 Access 类的新实例。</summary>
public AccessAce12(string path) : base(AccessHelper.AceOleDB12) { Path = path; }
}
#endif
}
|