Make the MySqlGeneric layer transaction aware
parent
3e880cee45
commit
680231d7e7
|
@ -36,7 +36,7 @@ using MySql.Data.MySqlClient;
|
||||||
namespace OpenSim.Data.MySQL
|
namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A database interface class to a user profile storage system
|
/// Common code for a number of database modules
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MySqlFramework
|
public class MySqlFramework
|
||||||
{
|
{
|
||||||
|
@ -44,14 +44,24 @@ namespace OpenSim.Data.MySQL
|
||||||
log4net.LogManager.GetLogger(
|
log4net.LogManager.GetLogger(
|
||||||
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
protected string m_connectionString;
|
protected string m_connectionString = String.Empty;
|
||||||
protected object m_dbLock = new object();
|
protected MySqlTransaction m_trans = null;
|
||||||
|
|
||||||
|
// Constructor using a connection string. Instances constructed
|
||||||
|
// this way will open a new connection for each call.
|
||||||
protected MySqlFramework(string connectionString)
|
protected MySqlFramework(string connectionString)
|
||||||
{
|
{
|
||||||
m_connectionString = connectionString;
|
m_connectionString = connectionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Constructor using a connection object. Instances constructed
|
||||||
|
// this way will use the connection object and never create
|
||||||
|
// new connections.
|
||||||
|
protected MySqlFramework(MySqlTransaction trans)
|
||||||
|
{
|
||||||
|
m_trans = trans;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// All non queries are funneled through one connection
|
// All non queries are funneled through one connection
|
||||||
|
@ -59,33 +69,48 @@ namespace OpenSim.Data.MySQL
|
||||||
//
|
//
|
||||||
protected int ExecuteNonQuery(MySqlCommand cmd)
|
protected int ExecuteNonQuery(MySqlCommand cmd)
|
||||||
{
|
{
|
||||||
lock (m_dbLock)
|
if (m_trans == null)
|
||||||
{
|
{
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
try
|
dbcon.Open();
|
||||||
{
|
return ExecuteNonQueryWithConnection(cmd, dbcon);
|
||||||
dbcon.Open();
|
|
||||||
cmd.Connection = dbcon;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return cmd.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error(e.Message, e);
|
|
||||||
m_log.Error(Environment.StackTrace.ToString());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error(e.Message, e);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ExecuteNonQueryWithTransaction(cmd, m_trans);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int ExecuteNonQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans)
|
||||||
|
{
|
||||||
|
cmd.Transaction = trans;
|
||||||
|
return ExecuteNonQueryWithConnection(cmd, trans.Connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int ExecuteNonQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cmd.Connection = dbcon;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.Error(e.Message, e);
|
||||||
|
m_log.Error(Environment.StackTrace.ToString());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.Error(e.Message, e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,14 +53,27 @@ namespace OpenSim.Data.MySQL
|
||||||
get { return GetType().Assembly; }
|
get { return GetType().Assembly; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MySQLGenericTableHandler(MySqlTransaction trans,
|
||||||
|
string realm, string storeName) : base(trans)
|
||||||
|
{
|
||||||
|
m_Realm = realm;
|
||||||
|
|
||||||
|
CommonConstruct(storeName);
|
||||||
|
}
|
||||||
|
|
||||||
public MySQLGenericTableHandler(string connectionString,
|
public MySQLGenericTableHandler(string connectionString,
|
||||||
string realm, string storeName) : base(connectionString)
|
string realm, string storeName) : base(connectionString)
|
||||||
{
|
{
|
||||||
m_Realm = realm;
|
m_Realm = realm;
|
||||||
m_connectionString = connectionString;
|
|
||||||
|
|
||||||
|
CommonConstruct(storeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void CommonConstruct(string storeName)
|
||||||
|
{
|
||||||
if (storeName != String.Empty)
|
if (storeName != String.Empty)
|
||||||
{
|
{
|
||||||
|
// We always use a new connection for any Migrations
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
@ -110,6 +123,11 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual T[] Get(string[] fields, string[] keys)
|
public virtual T[] Get(string[] fields, string[] keys)
|
||||||
|
{
|
||||||
|
return Get(fields, keys, String.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual T[] Get(string[] fields, string[] keys, string options)
|
||||||
{
|
{
|
||||||
if (fields.Length != keys.Length)
|
if (fields.Length != keys.Length)
|
||||||
return new T[0];
|
return new T[0];
|
||||||
|
@ -126,8 +144,8 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
string where = String.Join(" and ", terms.ToArray());
|
string where = String.Join(" and ", terms.ToArray());
|
||||||
|
|
||||||
string query = String.Format("select * from {0} where {1}",
|
string query = String.Format("select * from {0} where {1} {2}",
|
||||||
m_Realm, where);
|
m_Realm, where, options);
|
||||||
|
|
||||||
cmd.CommandText = query;
|
cmd.CommandText = query;
|
||||||
|
|
||||||
|
@ -136,73 +154,93 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
|
|
||||||
protected T[] DoQuery(MySqlCommand cmd)
|
protected T[] DoQuery(MySqlCommand cmd)
|
||||||
|
{
|
||||||
|
if (m_trans == null)
|
||||||
|
{
|
||||||
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
|
||||||
|
return DoQueryWithConnection(cmd, dbcon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return DoQueryWithTransaction(cmd, m_trans);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected T[] DoQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans)
|
||||||
|
{
|
||||||
|
cmd.Transaction = trans;
|
||||||
|
|
||||||
|
return DoQueryWithConnection(cmd, trans.Connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected T[] DoQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon)
|
||||||
{
|
{
|
||||||
List<T> result = new List<T>();
|
List<T> result = new List<T>();
|
||||||
|
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
cmd.Connection = dbcon;
|
||||||
|
|
||||||
|
using (IDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
if (reader == null)
|
||||||
cmd.Connection = dbcon;
|
return new T[0];
|
||||||
|
|
||||||
using (IDataReader reader = cmd.ExecuteReader())
|
CheckColumnNames(reader);
|
||||||
|
|
||||||
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
if (reader == null)
|
T row = new T();
|
||||||
return new T[0];
|
|
||||||
|
|
||||||
CheckColumnNames(reader);
|
foreach (string name in m_Fields.Keys)
|
||||||
|
|
||||||
while (reader.Read())
|
|
||||||
{
|
{
|
||||||
T row = new T();
|
if (reader[name] is DBNull)
|
||||||
|
|
||||||
foreach (string name in m_Fields.Keys)
|
|
||||||
{
|
{
|
||||||
if (reader[name] is DBNull)
|
continue;
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (m_Fields[name].FieldType == typeof(bool))
|
|
||||||
{
|
|
||||||
int v = Convert.ToInt32(reader[name]);
|
|
||||||
m_Fields[name].SetValue(row, v != 0 ? true : false);
|
|
||||||
}
|
|
||||||
else if (m_Fields[name].FieldType == typeof(UUID))
|
|
||||||
{
|
|
||||||
m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name]));
|
|
||||||
}
|
|
||||||
else if (m_Fields[name].FieldType == typeof(int))
|
|
||||||
{
|
|
||||||
int v = Convert.ToInt32(reader[name]);
|
|
||||||
m_Fields[name].SetValue(row, v);
|
|
||||||
}
|
|
||||||
else if (m_Fields[name].FieldType == typeof(uint))
|
|
||||||
{
|
|
||||||
uint v = Convert.ToUInt32(reader[name]);
|
|
||||||
m_Fields[name].SetValue(row, v);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_Fields[name].SetValue(row, reader[name]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (m_Fields[name].FieldType == typeof(bool))
|
||||||
if (m_DataField != null)
|
|
||||||
{
|
{
|
||||||
Dictionary<string, string> data =
|
int v = Convert.ToInt32(reader[name]);
|
||||||
new Dictionary<string, string>();
|
m_Fields[name].SetValue(row, v != 0 ? true : false);
|
||||||
|
}
|
||||||
foreach (string col in m_ColumnNames)
|
else if (m_Fields[name].FieldType == typeof(UUID))
|
||||||
{
|
{
|
||||||
data[col] = reader[col].ToString();
|
m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name]));
|
||||||
if (data[col] == null)
|
}
|
||||||
data[col] = String.Empty;
|
else if (m_Fields[name].FieldType == typeof(int))
|
||||||
}
|
{
|
||||||
|
int v = Convert.ToInt32(reader[name]);
|
||||||
m_DataField.SetValue(row, data);
|
m_Fields[name].SetValue(row, v);
|
||||||
|
}
|
||||||
|
else if (m_Fields[name].FieldType == typeof(uint))
|
||||||
|
{
|
||||||
|
uint v = Convert.ToUInt32(reader[name]);
|
||||||
|
m_Fields[name].SetValue(row, v);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Fields[name].SetValue(row, reader[name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Add(row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_DataField != null)
|
||||||
|
{
|
||||||
|
Dictionary<string, string> data =
|
||||||
|
new Dictionary<string, string>();
|
||||||
|
|
||||||
|
foreach (string col in m_ColumnNames)
|
||||||
|
{
|
||||||
|
data[col] = reader[col].ToString();
|
||||||
|
if (data[col] == null)
|
||||||
|
data[col] = String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_DataField.SetValue(row, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Add(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,14 +395,23 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
public object DoQueryScalar(MySqlCommand cmd)
|
public object DoQueryScalar(MySqlCommand cmd)
|
||||||
{
|
{
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
if (m_trans == null)
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
cmd.Connection = dbcon;
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
cmd.Connection = dbcon;
|
||||||
|
|
||||||
|
return cmd.ExecuteScalar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmd.Connection = m_trans.Connection;
|
||||||
|
cmd.Transaction = m_trans;
|
||||||
|
|
||||||
return cmd.ExecuteScalar();
|
return cmd.ExecuteScalar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue