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.
541 lines
19 KiB
541 lines
19 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Data.SqlClient;
|
|
using DataService;
|
|
|
|
namespace FileDriver
|
|
{
|
|
[Description("SQL 数据库")]
|
|
public class DataBaseReader : IFileDriver, IMultiReadWrite
|
|
{
|
|
public bool IsClosed
|
|
{
|
|
get
|
|
{
|
|
return m_Conn == null || m_Conn.State != ConnectionState.Open;
|
|
}
|
|
}
|
|
|
|
short _id;
|
|
public short ID
|
|
{
|
|
get
|
|
{
|
|
return _id;
|
|
}
|
|
}
|
|
|
|
int _timeOut;
|
|
public int TimeOut
|
|
{
|
|
get { return m_Conn == null ? _timeOut : m_Conn.ConnectionTimeout; }
|
|
set
|
|
{
|
|
_timeOut = value;
|
|
}
|
|
}
|
|
|
|
string _name;
|
|
public string Name
|
|
{
|
|
get
|
|
{
|
|
return _name;
|
|
}
|
|
}
|
|
|
|
string _serverIP;
|
|
public string ServerName
|
|
{
|
|
get
|
|
{
|
|
return _serverIP;
|
|
}
|
|
set
|
|
{
|
|
_serverIP = value;
|
|
}
|
|
}
|
|
|
|
string _ins;
|
|
public string Instance
|
|
{
|
|
get
|
|
{
|
|
return _ins;
|
|
}
|
|
set
|
|
{
|
|
_ins = value;
|
|
}
|
|
}
|
|
|
|
string _database;
|
|
public string FileName
|
|
{
|
|
get
|
|
{
|
|
return _database;
|
|
}
|
|
set
|
|
{
|
|
_database = value;
|
|
}
|
|
}
|
|
|
|
List<IGroup> _groups = new List<IGroup>();
|
|
public IEnumerable<IGroup> Groups
|
|
{
|
|
get { return _groups; }
|
|
}
|
|
|
|
IDataServer _server;
|
|
public IDataServer Parent
|
|
{
|
|
get { return _server; }
|
|
}
|
|
|
|
public DataBaseReader(IDataServer parent, short id, string name, string server = ".", int timeOut = 2, string databaseName = "SharpSCADA", string ins = null)
|
|
{
|
|
_id = id;
|
|
_name = name;
|
|
_server = parent;
|
|
_database = databaseName;
|
|
_serverIP = server;
|
|
_ins = ins;
|
|
_timeOut = timeOut / 1000;
|
|
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
|
|
builder.DataSource = (ins == null ? server : string.Format(@"{0}\{1}", _serverIP, _ins));
|
|
builder.InitialCatalog = _database;
|
|
builder.ConnectTimeout = _timeOut;
|
|
builder.IntegratedSecurity = true;
|
|
m_ConnStr = builder.ConnectionString;
|
|
}
|
|
|
|
string m_ConnStr;
|
|
SqlConnection m_Conn;
|
|
public bool Connect()
|
|
{
|
|
m_Conn = new SqlConnection(m_ConnStr);
|
|
//mySqlConnection.ConnectionTimeout = 1;//设置连接超时的时间,写在连接字符串内
|
|
try
|
|
{
|
|
//Open DataBase
|
|
//打开数据库
|
|
m_Conn.Open();
|
|
return m_Conn.State == ConnectionState.Open;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (OnClose != null)
|
|
OnClose(this, new ShutdownRequestEventArgs(e.Message));
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public IGroup AddGroup(string name, short id, int updateRate, float deadBand = 0f, bool active = false)
|
|
{
|
|
FileDeviceGroup grp = new FileDeviceGroup(id, name, updateRate, active, this);
|
|
_groups.Add(grp);
|
|
return grp;
|
|
}
|
|
|
|
public bool RemoveGroup(IGroup grp)
|
|
{
|
|
grp.IsActive = false;
|
|
return _groups.Remove(grp);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
foreach (IGroup grp in _groups)
|
|
{
|
|
grp.Dispose();
|
|
}
|
|
_groups.Clear();
|
|
m_Conn.Close(); m_Conn.Dispose();
|
|
}
|
|
|
|
public SqlDataReader ExecuteProcedureReader(string sSQL, params SqlParameter[] ParaName)
|
|
{
|
|
SqlCommand command = new SqlCommand(sSQL, m_Conn);
|
|
command.CommandType = CommandType.StoredProcedure;
|
|
if (ParaName != null)
|
|
{
|
|
command.Parameters.AddRange(ParaName);
|
|
}
|
|
try
|
|
{
|
|
if (m_Conn.State == ConnectionState.Closed)
|
|
m_Conn.Open();
|
|
return command.ExecuteReader(CommandBehavior.CloseConnection);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (OnClose != null)
|
|
OnClose(this, new ShutdownRequestEventArgs(e.Message));
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public int ExecuteStoredProcedure(string ProName, params SqlParameter[] ParaName)
|
|
{
|
|
try
|
|
{
|
|
SqlCommand cmd = new SqlCommand(ProName, m_Conn);
|
|
cmd.CommandType = CommandType.StoredProcedure;
|
|
if (ParaName != null)
|
|
{
|
|
cmd.Parameters.AddRange(ParaName);
|
|
}
|
|
SqlParameter param = new SqlParameter();
|
|
cmd.Parameters.Add(param);
|
|
param.Direction = ParameterDirection.ReturnValue;
|
|
if (m_Conn.State == ConnectionState.Closed)
|
|
m_Conn.Open();
|
|
cmd.ExecuteNonQuery();
|
|
m_Conn.Close();
|
|
return (int)param.Value;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_Conn.Close();
|
|
if (OnClose != null)
|
|
OnClose(this, new ShutdownRequestEventArgs(e.Message));
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
public byte[] ReadBytes(DeviceAddress address, ushort size)
|
|
{
|
|
using (var dataReader = ExecuteProcedureReader("ReadValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType }))
|
|
{
|
|
if (dataReader != null)
|
|
{
|
|
while (dataReader.Read())
|
|
{
|
|
return dataReader[0] as byte[];
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public ItemData<int> ReadInt32(DeviceAddress address)
|
|
{
|
|
ItemData<int> data = new ItemData<int>();
|
|
var dataReader = ExecuteProcedureReader("ReadValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
|
|
if (dataReader == null)
|
|
{
|
|
data.Quality = QUALITIES.QUALITY_BAD;
|
|
return data;
|
|
}
|
|
while (dataReader.Read())
|
|
{
|
|
data.Value = dataReader.GetInt32(0);
|
|
data.Quality = QUALITIES.QUALITY_GOOD;
|
|
}
|
|
dataReader.Close();
|
|
return data;
|
|
}
|
|
|
|
public ItemData<short> ReadInt16(DeviceAddress address)
|
|
{
|
|
ItemData<short> data = new ItemData<short>();
|
|
var dataReader = ExecuteProcedureReader("ReadValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
|
|
if (dataReader == null)
|
|
{
|
|
data.Quality = QUALITIES.QUALITY_BAD;
|
|
return data;
|
|
}
|
|
while (dataReader.Read())
|
|
{
|
|
data.Value = dataReader.GetInt16(0);
|
|
data.Quality = QUALITIES.QUALITY_GOOD;
|
|
}
|
|
dataReader.Close();
|
|
return data;
|
|
}
|
|
|
|
public ItemData<byte> ReadByte(DeviceAddress address)
|
|
{
|
|
ItemData<byte> data = new ItemData<byte>();
|
|
var dataReader = ExecuteProcedureReader("ReadValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
|
|
if (dataReader == null)
|
|
{
|
|
data.Quality = QUALITIES.QUALITY_BAD;
|
|
return data;
|
|
}
|
|
while (dataReader.Read())
|
|
{
|
|
data.Value = dataReader.GetByte(0);
|
|
data.Quality = QUALITIES.QUALITY_GOOD;
|
|
}
|
|
dataReader.Close();
|
|
return data;
|
|
}
|
|
|
|
public ItemData<string> ReadString(DeviceAddress address, ushort size)
|
|
{
|
|
ItemData<string> data = new ItemData<string>();
|
|
var dataReader = ExecuteProcedureReader("ReadValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
|
|
if (dataReader == null)
|
|
{
|
|
data.Quality = QUALITIES.QUALITY_BAD;
|
|
return data;
|
|
}
|
|
while (dataReader.Read())
|
|
{
|
|
data.Value = dataReader.GetString(0);
|
|
data.Quality = QUALITIES.QUALITY_GOOD;
|
|
}
|
|
dataReader.Close();
|
|
return data;
|
|
}
|
|
|
|
public ItemData<float> ReadFloat(DeviceAddress address)
|
|
{
|
|
ItemData<float> data = new ItemData<float>();
|
|
var dataReader = ExecuteProcedureReader("ReadValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
|
|
if (dataReader == null)
|
|
{
|
|
data.Quality = QUALITIES.QUALITY_BAD;
|
|
return data;
|
|
}
|
|
while (dataReader.Read())
|
|
{
|
|
data.Value = dataReader.GetFloat(0);
|
|
data.Quality = QUALITIES.QUALITY_GOOD;
|
|
}
|
|
dataReader.Close();
|
|
return data;
|
|
}
|
|
|
|
public ItemData<bool> ReadBit(DeviceAddress address)
|
|
{
|
|
ItemData<bool> data = new ItemData<bool>();
|
|
var dataReader = ExecuteProcedureReader("ReadValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
|
|
if (dataReader == null)
|
|
{
|
|
data.Quality = QUALITIES.QUALITY_BAD;
|
|
return data;
|
|
}
|
|
while (dataReader.Read())
|
|
{
|
|
data.Value = dataReader.GetBoolean(0);
|
|
data.Quality = QUALITIES.QUALITY_GOOD;
|
|
}
|
|
dataReader.Close();
|
|
return data;
|
|
}
|
|
|
|
public ItemData<object> ReadValue(DeviceAddress address)
|
|
{
|
|
ItemData<object> data = new ItemData<object>();
|
|
var dataReader = ExecuteProcedureReader("ReadValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
|
|
if (dataReader == null)
|
|
{
|
|
data.Quality = QUALITIES.QUALITY_BAD;
|
|
return data;
|
|
}
|
|
while (dataReader.Read())
|
|
{
|
|
data.Value = dataReader.GetValue(0);
|
|
data.Quality = QUALITIES.QUALITY_GOOD;
|
|
}
|
|
dataReader.Close();
|
|
return data;
|
|
}
|
|
|
|
public int WriteBytes(DeviceAddress address, byte[] bits)
|
|
{
|
|
return ExecuteStoredProcedure("UpdateValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@Value", SqlDbType.Variant) { Value = bits });
|
|
}
|
|
|
|
public int WriteBit(DeviceAddress address, bool bit)
|
|
{
|
|
return ExecuteStoredProcedure("UpdateValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@Value", SqlDbType.Variant) { Value = bit });
|
|
}
|
|
|
|
public int WriteBits(DeviceAddress address, byte bits)
|
|
{
|
|
return ExecuteStoredProcedure("UpdateValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@Value", SqlDbType.Variant) { Value = bits });
|
|
}
|
|
|
|
public int WriteInt16(DeviceAddress address, short value)
|
|
{
|
|
return ExecuteStoredProcedure("UpdateValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@Value", SqlDbType.Variant) { Value = value });
|
|
}
|
|
|
|
public int WriteInt32(DeviceAddress address, int value)
|
|
{
|
|
return ExecuteStoredProcedure("UpdateValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@Value", SqlDbType.Variant) { Value = value });
|
|
}
|
|
|
|
public int WriteFloat(DeviceAddress address, float value)
|
|
{
|
|
return ExecuteStoredProcedure("UpdateValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@Value", SqlDbType.Variant) { Value = value });
|
|
}
|
|
|
|
public int WriteString(DeviceAddress address, string str)
|
|
{
|
|
return ExecuteStoredProcedure("UpdateValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@Value", SqlDbType.Variant, address.DataSize) { Value = str });
|
|
}
|
|
|
|
public int WriteValue(DeviceAddress address, object value)
|
|
{
|
|
return ExecuteStoredProcedure("UpdateValueByID",
|
|
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
|
|
new SqlParameter("@Value", SqlDbType.Variant, address.DataSize) { Value = value });
|
|
}
|
|
|
|
|
|
public ItemData<Storage>[] ReadMultiple(DeviceAddress[] addrsArr)
|
|
{
|
|
int len = addrsArr.Length;
|
|
SqlParameter param = new SqlParameter("@IDARRAY", SqlDbType.VarChar);
|
|
string str = string.Empty;
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
str += addrsArr[i].CacheIndex + '|' + (int)addrsArr[i].VarType + ',';
|
|
}
|
|
param.Value = str;
|
|
var dataReader = ExecuteProcedureReader("BatchReadByID", param);//可以采用IN 操作符+,
|
|
if (dataReader == null)
|
|
return null;
|
|
else
|
|
{
|
|
ItemData<Storage>[] itemArr = new ItemData<Storage>[len];
|
|
int i = 0;
|
|
while (dataReader.Read())
|
|
{
|
|
switch (addrsArr[i].VarType)
|
|
{
|
|
case DataType.BOOL:
|
|
itemArr[i].Value.Boolean = dataReader.GetBoolean(0);
|
|
break;
|
|
case DataType.BYTE:
|
|
itemArr[i].Value.Byte = dataReader.GetByte(0);
|
|
break;
|
|
case DataType.WORD:
|
|
case DataType.SHORT:
|
|
itemArr[i].Value.Int16 = dataReader.GetInt16(0);
|
|
break;
|
|
case DataType.TIME:
|
|
case DataType.INT:
|
|
itemArr[i].Value.Int32 = dataReader.GetInt32(0);
|
|
break;
|
|
case DataType.FLOAT:
|
|
itemArr[i].Value.Single = dataReader.GetFloat(0);
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
dataReader.Close();
|
|
return itemArr;
|
|
}
|
|
}
|
|
|
|
public int WriteMultiple(DeviceAddress[] addrArr, object[] buffer)
|
|
{
|
|
int len = addrArr.Length;
|
|
SqlParameter param = new SqlParameter("@IDARRAY", SqlDbType.VarChar);
|
|
string str = string.Empty;
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
str += addrArr[i].CacheIndex.ToString() + "|" + buffer[i].ToString() + ",";
|
|
}
|
|
param.Value = str;
|
|
return ExecuteStoredProcedure("BatchUpdateByID", param);
|
|
}
|
|
|
|
public FileData[] ReadAll(short groupId)
|
|
{
|
|
FileData[] list = null;
|
|
using (var reader = ExecuteProcedureReader("ReadAll", new SqlParameter("@GroupId", groupId)))
|
|
{
|
|
if (reader == null) return null;
|
|
if (reader.Read())
|
|
{
|
|
int count = reader.GetInt32(0);
|
|
list = new FileData[count];
|
|
reader.NextResult();
|
|
int i = 0;
|
|
while (reader.Read())
|
|
{
|
|
if (i < count)
|
|
{
|
|
list[i].ID = reader.GetInt16(0);
|
|
switch ((DataType)reader.GetByte(1))
|
|
{
|
|
case DataType.BOOL:
|
|
list[i].Value.Boolean = Convert.ToBoolean(reader.GetValue(2));
|
|
break;
|
|
case DataType.BYTE:
|
|
list[i].Value.Byte = Convert.ToByte(reader.GetValue(2));
|
|
break;
|
|
case DataType.WORD:
|
|
case DataType.SHORT:
|
|
list[i].Value.Int16 = Convert.ToInt16(reader.GetValue(2));
|
|
break;
|
|
case DataType.TIME:
|
|
case DataType.INT:
|
|
list[i].Value.Int32 = Convert.ToInt32(reader.GetValue(2));
|
|
break;
|
|
case DataType.FLOAT:
|
|
list[i].Value.Single = Convert.ToSingle(reader.GetValue(2));
|
|
break;
|
|
case DataType.STR:
|
|
list[i].Text = Convert.ToString(reader.GetValue(2));
|
|
//如何传送字符串?
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
|
|
public int Limit
|
|
{
|
|
get { return 0x100; }
|
|
}
|
|
|
|
public event ShutdownRequestEventHandler OnClose;
|
|
|
|
}
|
|
}
|