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 { /// 用于快速连接 Microsoft Access 数据库的辅助。 public partial class Access { /// 尝试解析 Access 文件的密码。 /// 当操作系统启用随机化内存分配时,此方法可能会产生异常。 public static string[] ParsePassword(string path) => AccessHelper.GetPassword(path); } #if NETFX public partial class Access : IDatabase, IDisposable { /// 创建 Access 类的新实例。 public static Access Jet4() => new Access(AccessHelper.JetOleDB4); /// 创建 Access 类的新实例。 public static Access Ace12() => new Access(AccessHelper.AceOleDB12); #region 属性、构造函数和 Dispose。 private OleDbConnection _connection = null; internal string Provider { get; set; } /// 构造函数。 internal Access(string provider) { Provider = provider; Timeout = new Timeout(); } /// 释放资源。 public void Dispose() => Close(); #endregion #region 日志。 /// 获取或设置日志记录。 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 连接。 /// 获取或设置数据库文件的路径。 public string Path { get; set; } /// Microsoft Access System Database。 public string Josd { get; set; } /// 获取或设置用于连接数据库的密码。 public string Pass { get; set; } /// 获取或设置超时。 public Timeout Timeout { get; set; } /// 数据库是否已经连接。 public bool Online { get { if (_connection != null) { if (_connection.State == ConnectionState.Open) return true; } return false; } } /// 连接数据库,若未连接则尝试连接。 /// 是否已连接。 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; } /// 释放对象所占用的系统资源。 public void Close() { if (_connection != null) { _connection.Close(); _connection.Dispose(); _connection = null; } } /// 获取或设置连接字符串。 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 查询和执行。 /// 使用 SQL 语句进行查询。 public IQuery Query(string sql) => Query(sql, null); /// 使用 SQL 语句进行查询。 public IQuery Query(string sql, IEnumerable 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; } /// 执行 SQL 语句。 public IExecute Execute(string sql) => Execute(sql, null); /// 执行 SQL 语句,并加入参数。 public IExecute Execute(string sql, IEnumerable 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 /// 创建参数列表。 public static List NewParameterList() { return new List(); } /// 创建参数。 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; } /// 创建参数。 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 } /// 使用 Microsoft.Jet.OLEDB.4.0 访问 Access 97 - 2003 数据库文件。 public class AccessJet4 : Access { /// 创建 Access 类的新实例。 public AccessJet4() : base(AccessHelper.JetOleDB4) { } /// 创建 Access 类的新实例。 public AccessJet4(string path) : base(AccessHelper.JetOleDB4) { Path = path; } } /// 使用 Microsoft.ACE.OLEDB.12.0 访问 Access 2007 数据库文件。 public class AccessAce12 : Access { /// 创建 Access 类的新实例。 public AccessAce12() : base(AccessHelper.AceOleDB12) { } /// 创建 Access 类的新实例。 public AccessAce12(string path) : base(AccessHelper.AceOleDB12) { Path = path; } } #endif }