You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
317 lines
9.7 KiB
317 lines
9.7 KiB
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
|
|
|
|
}
|
|
|