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
}