diff --git a/OpenSim/Data/IAuthenticationData.cs b/OpenSim/Data/IAuthenticationData.cs new file mode 100644 index 0000000000..f84871690c --- /dev/null +++ b/OpenSim/Data/IAuthenticationData.cs @@ -0,0 +1,52 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Data +{ + public class AuthenticationData + { + public UUID PrincipalID; + public Dictionary Data; + } + + /// + /// An interface for connecting to the authentication datastore + /// + public interface IAuthenticationData + { + AuthenticationData Get(UUID principalID); + + bool Store(AuthenticationData data); + + bool SetDataItem(UUID principalID, string item, string value); + } +} diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs new file mode 100644 index 0000000000..625d3b1ba6 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs @@ -0,0 +1,146 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using OpenMetaverse; +using OpenSim.Framework; +using MySql.Data.MySqlClient; + +namespace OpenSim.Data.MySQL +{ + public class MySqlAuthenticationData : MySqlFramework, IAuthenticationData + { + private string m_Realm; + private DataTable m_SchemaTable = null; + + public MySqlAuthenticationData(string connectionString, string realm) + : base(connectionString) + { + m_Realm = realm; + } + + public AuthenticationData Get(UUID principalID) + { + AuthenticationData ret = new AuthenticationData(); + ret.Data = new Dictionary(); + + MySqlCommand cmd = new MySqlCommand( + "select * from `"+m_Realm+"` where UUID = ?principalID" + ); + + cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); + + IDataReader result = ExecuteReader(cmd); + + if (result.Read()) + { + ret.PrincipalID = principalID; + + if (m_SchemaTable == null) + m_SchemaTable = result.GetSchemaTable(); + + foreach (DataColumn c in m_SchemaTable.Columns) + { + if (c.ColumnName == "UUID") + continue; + + ret.Data[c.ColumnName] = result[c.ColumnName].ToString(); + } + + result.Close(); + CloseReaderCommand(cmd); + + return ret; + } + + result.Close(); + CloseReaderCommand(cmd); + + return null; + } + + public bool Store(AuthenticationData data) + { + if (data.Data.ContainsKey("UUID")) + data.Data.Remove("UUID"); + + string[] fields = new List(data.Data.Keys).ToArray(); + + MySqlCommand cmd = new MySqlCommand(); + + string update = "update `"+m_Realm+"` set "; + bool first = true; + foreach (string field in fields) + { + if (!first) + update += ", "; + update += "`" + field + "` = ?"+field; + + first = false; + + cmd.Parameters.AddWithValue(field, data.Data[field]); + } + + update += " where UUID = ?principalID"; + + cmd.CommandText = update; + cmd.Parameters.AddWithValue("UUID", data.PrincipalID.ToString()); + + if (ExecuteNonQuery(cmd) < 1) + { + string insert = "insert into `" + m_Realm + "` (`UUID`, `" + + String.Join("`, `", fields) + + "`) values ( ?UUID, ?" + String.Join(", ?", fields) + ")"; + + if (ExecuteNonQuery(cmd) < 0) + { + cmd.Dispose(); + return false; + } + } + + cmd.Dispose(); + + return true; + } + + public bool SetDataItem(UUID principalID, string item, string value) + { + MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + + "` set `" + item + "` = ?" + item + " where UUID = ?UUID"); + + + cmd.Parameters.AddWithValue(item, value); + cmd.Parameters.AddWithValue("UUID", principalID.ToString()); + + return false; + } + } +} diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs new file mode 100644 index 0000000000..f2b31c4800 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLFramework.cs @@ -0,0 +1,115 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using OpenMetaverse; +using OpenSim.Framework; +using MySql.Data.MySqlClient; + +namespace OpenSim.Data.MySQL +{ + /// + /// A database interface class to a user profile storage system + /// + public class MySqlFramework + { + protected MySqlConnection m_Connection; + + protected MySqlFramework(string connectionString) + { + m_Connection = new MySqlConnection(connectionString); + + m_Connection.Open(); + } + + ////////////////////////////////////////////////////////////// + // + // All non queries are funneled through one connection + // to increase performance a little + // + protected int ExecuteNonQuery(MySqlCommand cmd) + { + lock (m_Connection) + { + cmd.Connection = m_Connection; + + bool errorSeen = false; + + while (true) + { + try + { + return cmd.ExecuteNonQuery(); + } + catch (MySqlException e) + { + if (errorSeen) + throw; + + // This is "Server has gone away" and "Server lost" + // + if (e.Number == 2006 || e.Number == 2013) + { + errorSeen = true; + + m_Connection.Close(); + MySqlConnection newConnection = (MySqlConnection) + ((ICloneable)m_Connection).Clone(); + m_Connection.Dispose(); + m_Connection = newConnection; + m_Connection.Open(); + + cmd.Connection = m_Connection; + } + } + } + } + } + + protected IDataReader ExecuteReader(MySqlCommand cmd) + { + MySqlConnection newConnection = (MySqlConnection) + ((ICloneable)m_Connection).Clone(); + + newConnection.Open(); + + cmd.Connection = newConnection; + + return cmd.ExecuteReader(); + } + + protected void CloseReaderCommand(MySqlCommand cmd) + { + cmd.Connection.Close(); + cmd.Connection.Dispose(); + cmd.Dispose(); + } + } +}