diff --git a/OpenSim/Data/GridDataBase.cs b/OpenSim/Data/GridDataBase.cs index 0fd4d86c56..e8dbc1144a 100644 --- a/OpenSim/Data/GridDataBase.cs +++ b/OpenSim/Data/GridDataBase.cs @@ -39,6 +39,7 @@ namespace OpenSim.Data public abstract DataResponse AddProfile(RegionProfileData profile); public abstract ReservationData GetReservationAtPoint(uint x, uint y); public abstract DataResponse UpdateProfile(RegionProfileData profile); + public abstract DataResponse DeleteProfile(string uuid); public abstract void Initialise(); public abstract void Initialise(string connect); diff --git a/OpenSim/Data/IGridData.cs b/OpenSim/Data/IGridData.cs index c5f4ee1bd1..132361ff1f 100644 --- a/OpenSim/Data/IGridData.cs +++ b/OpenSim/Data/IGridData.cs @@ -96,8 +96,26 @@ namespace OpenSim.Data /// RESPONSE_OK if successful, error if not. DataResponse AddProfile(RegionProfileData profile); + /// + /// Updates a profile in the database + /// + /// + /// DataResponse UpdateProfile(RegionProfileData profile); + /// + /// Remove a profile from the database + /// + /// ID of profile to remove + /// + DataResponse DeleteProfile(string UUID); + + /// + /// Function not used???? + /// + /// + /// + /// ReservationData GetReservationAtPoint(uint x, uint y); } diff --git a/OpenSim/Data/MSSQL/AutoClosingSqlCommand.cs b/OpenSim/Data/MSSQL/AutoClosingSqlCommand.cs index cae864bc7b..9211747143 100644 --- a/OpenSim/Data/MSSQL/AutoClosingSqlCommand.cs +++ b/OpenSim/Data/MSSQL/AutoClosingSqlCommand.cs @@ -25,9 +25,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; -using System.Collections.Generic; -using System.Text; using System.Data.SqlClient; using System.Data; @@ -163,16 +160,22 @@ namespace OpenSim.Data.MSSQL realCommand.Prepare(); } - IDbTransaction IDbCommand.Transaction +// IDbTransaction IDbCommand.Transaction +// { +// get +// { +// return realCommand.Transaction; +// } +// set +// { +// realCommand.Transaction = (SqlTransaction) value; +// } +// } + + public IDbTransaction Transaction { - get - { - return realCommand.Transaction; - } - set - { - realCommand.Transaction = (SqlTransaction) value; - } + get { return realCommand.Transaction; } + set { realCommand.Transaction = (SqlTransaction)value; } } UpdateRowSource IDbCommand.UpdatedRowSource diff --git a/OpenSim/Data/MSSQL/MSSQLAssetData.cs b/OpenSim/Data/MSSQL/MSSQLAssetData.cs index ed1c91be2f..4d5ca1c967 100644 --- a/OpenSim/Data/MSSQL/MSSQLAssetData.cs +++ b/OpenSim/Data/MSSQL/MSSQLAssetData.cs @@ -41,44 +41,83 @@ namespace OpenSim.Data.MSSQL /// internal class MSSQLAssetData : AssetDataBase { + private const string _migrationStore = "AssetStore"; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + /// + /// Database manager + /// private MSSQLManager database; - #region IAssetProviderPlugin Members + #region IPlugin Members + + override public void Dispose() { } /// - /// Migration method - /// - /// Execute "CreateAssetsTable.sql" if tableName == null - /// + /// Initialises asset interface /// - /// Name of table - private void UpgradeAssetsTable(string tableName) + override public void Initialise() { - // null as the version, indicates that the table didn't exist - if (tableName == null) + m_log.Info("[MSSQLUserData]: " + Name + " cannot be default-initialized!"); + throw new PluginNotInitialisedException(Name); + } + + /// + /// Initialises asset interface + /// + /// + /// a string instead of file, if someone writes the support + /// + /// connect string + override public void Initialise(string connectionString) + { + if (string.IsNullOrEmpty(connectionString)) { - m_log.Info("[ASSET DB]: Creating new database tables"); - database.ExecuteResourceSql("CreateAssetsTable.sql"); - return; + database = new MSSQLManager(connectionString); + } + else + { + + IniFile gridDataMSSqlFile = new IniFile("mssql_connection.ini"); + string settingDataSource = gridDataMSSqlFile.ParseFileReadValue("data_source"); + string settingInitialCatalog = gridDataMSSqlFile.ParseFileReadValue("initial_catalog"); + string settingPersistSecurityInfo = gridDataMSSqlFile.ParseFileReadValue("persist_security_info"); + string settingUserId = gridDataMSSqlFile.ParseFileReadValue("user_id"); + string settingPassword = gridDataMSSqlFile.ParseFileReadValue("password"); + + database = + new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, + settingPassword); } + //TODO can be removed at some time!! + TestTables(); + + //New migration to check for DB changes + database.CheckMigration(_migrationStore); } /// - /// Ensure that the assets related tables exists and are at the latest version + /// Database provider version. /// - private void TestTables() + override public string Version { - Dictionary tableList = new Dictionary(); - - tableList["assets"] = null; - database.GetTableVersion(tableList); - - UpgradeAssetsTable(tableList["assets"]); + get { return database.getVersion(); } } + /// + /// The name of this DB provider. + /// + override public string Name + { + get { return "MSSQL Asset storage engine"; } + } + + #endregion + + #region IAssetProviderPlugin Members + /// /// Fetch Asset from database /// @@ -86,13 +125,26 @@ namespace OpenSim.Data.MSSQL /// override public AssetBase FetchAsset(UUID assetID) { - Dictionary param = new Dictionary(); - param["id"] = assetID.ToString(); - - using (IDbCommand result = database.Query("SELECT * FROM assets WHERE id = @id", param)) - using (IDataReader reader = result.ExecuteReader()) + using (AutoClosingSqlCommand command = database.Query("SELECT * FROM assets WHERE id = @id")) { - return database.getAssetRow(reader); + command.Parameters.Add(database.CreateParameter("id", assetID)); + using (IDataReader reader = command.ExecuteReader()) + { + if (reader.Read()) + { + AssetBase asset = new AssetBase(); + // Region Main + asset.FullID = new UUID((string)reader["id"]); + asset.Name = (string)reader["name"]; + asset.Description = (string)reader["description"]; + asset.Type = Convert.ToSByte(reader["assetType"]); + asset.Local = Convert.ToBoolean(reader["local"]); + asset.Temporary = Convert.ToBoolean(reader["temporary"]); + asset.Data = (byte[])reader["data"]; + return asset; + } + return null; // throw new Exception("No rows to return"); + } } } @@ -102,34 +154,27 @@ namespace OpenSim.Data.MSSQL /// the asset override public void CreateAsset(AssetBase asset) { - if (ExistsAsset((UUID) asset.FullID)) + if (ExistsAsset(asset.FullID)) { return; } - - using (AutoClosingSqlCommand cmd = - database.Query( + using (AutoClosingSqlCommand command = database.Query( "INSERT INTO assets ([id], [name], [description], [assetType], [local], [temporary], [data])" + " VALUES " + "(@id, @name, @description, @assetType, @local, @temporary, @data)")) { - //SqlParameter p = cmd.Parameters.Add("id", SqlDbType.NVarChar); //p.Value = asset.FullID.ToString(); - cmd.Parameters.AddWithValue("id", asset.FullID.ToString()); - cmd.Parameters.AddWithValue("name", asset.Name); - cmd.Parameters.AddWithValue("description", asset.Description); - SqlParameter e = cmd.Parameters.Add("assetType", SqlDbType.TinyInt); - e.Value = asset.Type; - SqlParameter g = cmd.Parameters.Add("local", SqlDbType.TinyInt); - g.Value = asset.Local; - SqlParameter h = cmd.Parameters.Add("temporary", SqlDbType.TinyInt); - h.Value = asset.Temporary; - SqlParameter i = cmd.Parameters.Add("data", SqlDbType.Image); - i.Value = asset.Data; + command.Parameters.Add(database.CreateParameter("id", asset.FullID)); + command.Parameters.Add(database.CreateParameter("name", asset.Name)); + command.Parameters.Add(database.CreateParameter("description", asset.Description)); + command.Parameters.Add(database.CreateParameter("assetType", asset.Type)); + command.Parameters.Add(database.CreateParameter("local", asset.Local)); + command.Parameters.Add(database.CreateParameter("temporary", asset.Temporary)); + command.Parameters.Add(database.CreateParameter("data", asset.Data)); - cmd.ExecuteNonQuery(); + command.ExecuteNonQuery(); } } @@ -139,7 +184,7 @@ namespace OpenSim.Data.MSSQL /// the asset override public void UpdateAsset(AssetBase asset) { - using (IDbCommand command = database.Query("UPDATE assets set id = @id, " + + using (AutoClosingSqlCommand command = database.Query("UPDATE assets set id = @id, " + "name = @name, " + "description = @description," + "assetType = @assetType," + @@ -148,22 +193,14 @@ namespace OpenSim.Data.MSSQL "data = @data where " + "id = @keyId;")) { - SqlParameter param1 = new SqlParameter("@id", asset.FullID.ToString()); - SqlParameter param2 = new SqlParameter("@name", asset.Name); - SqlParameter param3 = new SqlParameter("@description", asset.Description); - SqlParameter param4 = new SqlParameter("@assetType", asset.Type); - SqlParameter param6 = new SqlParameter("@local", asset.Local); - SqlParameter param7 = new SqlParameter("@temporary", asset.Temporary); - SqlParameter param8 = new SqlParameter("@data", asset.Data); - SqlParameter param9 = new SqlParameter("@keyId", asset.FullID.ToString()); - command.Parameters.Add(param1); - command.Parameters.Add(param2); - command.Parameters.Add(param3); - command.Parameters.Add(param4); - command.Parameters.Add(param6); - command.Parameters.Add(param7); - command.Parameters.Add(param8); - command.Parameters.Add(param9); + command.Parameters.Add(database.CreateParameter("id", asset.FullID)); + command.Parameters.Add(database.CreateParameter("name", asset.Name)); + command.Parameters.Add(database.CreateParameter("description", asset.Description)); + command.Parameters.Add(database.CreateParameter("assetType", asset.Type)); + command.Parameters.Add(database.CreateParameter("local", asset.Local)); + command.Parameters.Add(database.CreateParameter("temporary", asset.Temporary)); + command.Parameters.Add(database.CreateParameter("data", asset.Data)); + command.Parameters.Add(database.CreateParameter("@keyId", asset.FullID)); try { @@ -192,57 +229,69 @@ namespace OpenSim.Data.MSSQL #endregion - #region IPlugin Members - - override public void Dispose() { } + #region Private Methods /// - /// Initialises asset interface - /// - /// TODO: this would allow you to pass in connnect info as - /// a string instead of file, if someone writes the support - /// + /// Migration method + /// + /// Execute "CreateAssetsTable.sql" if tableName == null + /// /// - /// connect string - override public void Initialise(string connect) + /// Name of table + private void UpgradeAssetsTable(string tableName) { - Initialise(); + // null as the version, indicates that the table didn't exist + if (tableName == null) + { + m_log.Info("[ASSET DB]: Creating new database tables"); + database.ExecuteResourceSql("CreateAssetsTable.sql"); + return; + } } /// - /// Initialises asset interface + /// Ensure that the assets related tables exists and are at the latest version /// - /// it use mssql_connection.ini - override public void Initialise() + private void TestTables() { - IniFile gridDataMSSqlFile = new IniFile("mssql_connection.ini"); - string settingDataSource = gridDataMSSqlFile.ParseFileReadValue("data_source"); - string settingInitialCatalog = gridDataMSSqlFile.ParseFileReadValue("initial_catalog"); - string settingPersistSecurityInfo = gridDataMSSqlFile.ParseFileReadValue("persist_security_info"); - string settingUserId = gridDataMSSqlFile.ParseFileReadValue("user_id"); - string settingPassword = gridDataMSSqlFile.ParseFileReadValue("password"); + Dictionary tableList = new Dictionary(); - database = - new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, - settingPassword); + tableList["assets"] = null; + database.GetTableVersion(tableList); - TestTables(); - } + UpgradeAssetsTable(tableList["assets"]); - /// - /// Database provider version. - /// - override public string Version - { - get { return database.getVersion(); } - } + //Special for Migrations + using (AutoClosingSqlCommand cmd = database.Query("select * from migrations where name = '" + _migrationStore + "'")) + { + try + { + bool insert = true; + using (SqlDataReader reader = cmd.ExecuteReader()) + { + if (reader.Read()) insert = false; + } + if (insert) + { + cmd.CommandText = "insert into migrations(name, version) values('" + _migrationStore + "', 1)"; + cmd.ExecuteNonQuery(); + } + } + catch + { + //No migrations table + //HACK create one and add data + cmd.CommandText = "create table migrations(name varchar(100), version int)"; + cmd.ExecuteNonQuery(); + + cmd.CommandText = "insert into migrations(name, version) values('migrations', 1)"; + cmd.ExecuteNonQuery(); + + cmd.CommandText = "insert into migrations(name, version) values('" + _migrationStore + "', 1)"; + cmd.ExecuteNonQuery(); + } + } - /// - /// The name of this DB provider. - /// - override public string Name - { - get { return "MSSQL Asset storage engine"; } } #endregion diff --git a/OpenSim/Data/MSSQL/MSSQLEstateData.cs b/OpenSim/Data/MSSQL/MSSQLEstateData.cs index b42c67f34d..b3595d95ab 100644 --- a/OpenSim/Data/MSSQL/MSSQLEstateData.cs +++ b/OpenSim/Data/MSSQL/MSSQLEstateData.cs @@ -39,6 +39,8 @@ namespace OpenSim.Data.MSSQL { public class MSSQLEstateData : IEstateDataStore { + private const string _migrationStore = "EstateStore"; + private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private MSSQLManager _Database; @@ -74,15 +76,7 @@ namespace OpenSim.Data.MSSQL } //Migration settings - using (SqlConnection connection = _Database.DatabaseConnection()) - { - Assembly assem = GetType().Assembly; - MSSQLMigration migration = new MSSQLMigration(connection, assem, "EstateStore"); - - migration.Update(); - - connection.Close(); - } + _Database.CheckMigration(_migrationStore); //Interesting way to get parameters! Maybe implement that also with other types Type t = typeof(EstateSettings); diff --git a/OpenSim/Data/MSSQL/MSSQLGridData.cs b/OpenSim/Data/MSSQL/MSSQLGridData.cs index 47edc4b385..552dc042ef 100644 --- a/OpenSim/Data/MSSQL/MSSQLGridData.cs +++ b/OpenSim/Data/MSSQL/MSSQLGridData.cs @@ -28,9 +28,8 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.SqlClient; using System.Reflection; -using System.Security.Cryptography; -using System.Text; using OpenMetaverse; using log4net; using OpenSim.Framework; @@ -42,6 +41,8 @@ namespace OpenSim.Data.MSSQL /// public class MSSQLGridData : GridDataBase { + private const string _migrationStore = "GridStore"; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// @@ -49,49 +50,62 @@ namespace OpenSim.Data.MSSQL /// private MSSQLManager database; - private string m_regionsTableName; + private string m_regionsTableName = "regions"; + + #region IPlugin Members override public void Initialise() { - m_log.Info("[MSSQLGridData]: " + Name + " cannot be default-initialized!"); - throw new PluginNotInitialisedException (Name); + m_log.Info("[GRID DB]: " + Name + " cannot be default-initialized!"); + throw new PluginNotInitialisedException(Name); } /// /// Initialises the Grid Interface /// - /// connect string + /// connect string /// use mssql_connection.ini - override public void Initialise(string connect) + override public void Initialise(string connectionString) { - // TODO: make the connect string actually do something - IniFile iniFile = new IniFile("mssql_connection.ini"); - - string settingDataSource = iniFile.ParseFileReadValue("data_source"); - string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog"); - string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info"); - string settingUserId = iniFile.ParseFileReadValue("user_id"); - string settingPassword = iniFile.ParseFileReadValue("password"); - - m_regionsTableName = iniFile.ParseFileReadValue("regionstablename"); - if (m_regionsTableName == null) + if (string.IsNullOrEmpty(connectionString)) { - m_regionsTableName = "regions"; + database = new MSSQLManager(connectionString); + } + else + { + // TODO: make the connect string actually do something + IniFile iniFile = new IniFile("mssql_connection.ini"); + + string settingDataSource = iniFile.ParseFileReadValue("data_source"); + string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog"); + string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info"); + string settingUserId = iniFile.ParseFileReadValue("user_id"); + string settingPassword = iniFile.ParseFileReadValue("password"); + + m_regionsTableName = iniFile.ParseFileReadValue("regionstablename"); + if (m_regionsTableName == null) + { + m_regionsTableName = "regions"; + } + + database = + new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, + settingPassword); } - database = - new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, - settingPassword); - + //TODO this can be removed at a certain time TestTables(); + + //New migrations check of store + database.CheckMigration(_migrationStore); } /// - /// + /// Test is region /// private void TestTables() { - using (IDbCommand cmd = database.Query("SELECT TOP 1 * FROM " + m_regionsTableName, new Dictionary())) + using (AutoClosingSqlCommand cmd = database.Query("SELECT TOP 1 * FROM " + m_regionsTableName, new Dictionary())) { try { @@ -103,6 +117,36 @@ namespace OpenSim.Data.MSSQL database.ExecuteResourceSql("Mssql-regions.sql"); } } + using (AutoClosingSqlCommand cmd = database.Query("select * from migrations where name = '" + _migrationStore + "'")) + { + //Special for Migrations to create backword compatible + try + { + bool insert = true; + using (SqlDataReader reader = cmd.ExecuteReader()) + { + if (reader.Read()) insert = false; + } + if (insert) + { + cmd.CommandText = "insert into migrations(name, version) values('" + _migrationStore + "', 1)"; + cmd.ExecuteNonQuery(); + } + } + catch + { + //No migrations table + //HACK create one and add data + cmd.CommandText = "create table migrations(name varchar(100), version int)"; + cmd.ExecuteNonQuery(); + + cmd.CommandText = "insert into migrations(name, version) values('migrations', 1)"; + cmd.ExecuteNonQuery(); + + cmd.CommandText = "insert into migrations(name, version) values('" + _migrationStore + "', 1)"; + cmd.ExecuteNonQuery(); + } + } } /// @@ -110,7 +154,7 @@ namespace OpenSim.Data.MSSQL /// override public void Dispose() { - // nothing to close + database = null; } /// @@ -131,18 +175,44 @@ namespace OpenSim.Data.MSSQL get { return "0.1"; } } + #endregion + + #region Public override GridDataBase methods + /// - /// NOT IMPLEMENTED, /// Returns a list of regions within the specified ranges /// - /// minimum X coordinate - /// minimum Y coordinate - /// maximum X coordinate - /// maximum Y coordinate + /// minimum X coordinate + /// minimum Y coordinate + /// maximum X coordinate + /// maximum Y coordinate /// null /// always return null - override public RegionProfileData[] GetProfilesInRange(uint a, uint b, uint c, uint d) + override public RegionProfileData[] GetProfilesInRange(uint xmin, uint ymin, uint xmax, uint ymax) { + using (AutoClosingSqlCommand command = database.Query("SELECT * FROM regions WHERE locX >= @xmin AND locX <= @xmax AND locY >= @ymin AND locY <= @ymax")) + { + command.Parameters.Add(database.CreateParameter("xmin", xmin)); + command.Parameters.Add(database.CreateParameter("ymin", ymin)); + command.Parameters.Add(database.CreateParameter("xmax", xmax)); + command.Parameters.Add(database.CreateParameter("ymax", ymax)); + + List rows = new List(); + + using (SqlDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + rows.Add(ReadSimRow(reader)); + } + } + + if (rows.Count > 0) + { + return rows.ToArray(); + } + } + m_log.Info("[GRID DB] : Found no regions within range."); return null; } @@ -153,22 +223,20 @@ namespace OpenSim.Data.MSSQL /// Sim profile override public RegionProfileData GetProfileByHandle(ulong handle) { - - Dictionary param = new Dictionary(); - param["handle"] = handle.ToString(); - - try + using (AutoClosingSqlCommand command = database.Query("SELECT * FROM " + m_regionsTableName + " WHERE regionHandle = @handle")) { - using (IDbCommand result = database.Query("SELECT * FROM " + m_regionsTableName + " WHERE regionHandle = @handle", param)) - using (IDataReader reader = result.ExecuteReader()) + command.Parameters.Add(database.CreateParameter("handle", handle)); + + using (SqlDataReader reader = command.ExecuteReader()) { - return database.getRegionRow(reader); + if (reader.Read()) + { + return ReadSimRow(reader); + } } } - catch - { - return null; - } + m_log.InfoFormat("[GRID DB] : No region found with handle : {0}", handle); + return null; } /// @@ -178,50 +246,49 @@ namespace OpenSim.Data.MSSQL /// The sim profile override public RegionProfileData GetProfileByUUID(UUID uuid) { - Dictionary param = new Dictionary(); - param["uuid"] = uuid.ToString(); - - using (IDbCommand result = database.Query("SELECT * FROM " + m_regionsTableName + " WHERE uuid = @uuid", param)) - using (IDataReader reader = result.ExecuteReader()) + using (AutoClosingSqlCommand command = database.Query("SELECT * FROM " + m_regionsTableName + " WHERE uuid = @uuid")) { - return database.getRegionRow(reader); - } + command.Parameters.Add(database.CreateParameter("uuid", uuid)); + using (SqlDataReader reader = command.ExecuteReader()) + { + if (reader.Read()) + { + return ReadSimRow(reader); + } + } + } + m_log.InfoFormat("[GRID DB] : No region found with UUID : {0}", uuid); + return null; } /// /// Returns a sim profile from it's Region name string /// - /// The region name search query + /// The region name search query /// The sim profile override public RegionProfileData GetProfileByString(string regionName) { if (regionName.Length > 2) { - try + using (AutoClosingSqlCommand command = database.Query("SELECT top 1 * FROM " + m_regionsTableName + " WHERE regionName like @regionName order by regionName")) { - Dictionary param = new Dictionary(); - // Add % because this is a like query. - param["?regionName"] = regionName + "%"; - // Order by statement will return shorter matches first. Only returns one record or no record. - using (IDbCommand result = database.Query("SELECT top 1 * FROM " + m_regionsTableName + " WHERE regionName like ?regionName order by regionName", param)) - using (IDataReader reader = result.ExecuteReader()) - { - return database.getRegionRow(reader); - } + command.Parameters.Add(database.CreateParameter("regionName", regionName + "%")); + using (SqlDataReader reader = command.ExecuteReader()) + { + if (reader.Read()) + { + return ReadSimRow(reader); + } + } } - catch (Exception e) - { - m_log.Error(e.ToString()); - return null; - } - } - else - { - m_log.Error("[GRID DB]: Searched for a Region Name shorter then 3 characters"); + m_log.InfoFormat("[GRID DB] : No region found with regionName : {0}", regionName); return null; } + + m_log.Error("[GRID DB]: Searched for a Region Name shorter then 3 characters"); + return null; } /// @@ -231,14 +298,11 @@ namespace OpenSim.Data.MSSQL /// A dataresponse enum indicating success override public DataResponse AddProfile(RegionProfileData profile) { - if (insertRegionRow(profile)) + if (InsertRegionRow(profile)) { return DataResponse.RESPONSE_OK; } - else - { - return DataResponse.RESPONSE_ERROR; - } + return DataResponse.RESPONSE_ERROR; } /// @@ -246,156 +310,43 @@ namespace OpenSim.Data.MSSQL /// /// The profile to update /// A dataresponse enum indicating success - public override DataResponse UpdateProfile(RegionProfileData profile) + override public DataResponse UpdateProfile(RegionProfileData profile) { - if (updateRegionRow(profile)) + if (UpdateRegionRow(profile)) { return DataResponse.RESPONSE_OK; } - else - { - return DataResponse.RESPONSE_ERROR; - } + return DataResponse.RESPONSE_ERROR; } /// - /// Update the specified region in the database + /// Deletes a sim profile from the database /// - /// The profile to update - /// success ? - public bool updateRegionRow(RegionProfileData profile) - { - //Insert new region - string sql = - "UPDATE " + m_regionsTableName + @" SET - [regionHandle]=@regionHandle, [regionName]=@regionName, - [regionRecvKey]=@regionRecvKey, [regionSecret]=@regionSecret, [regionSendKey]=@regionSendKey, - [regionDataURI]=@regionDataURI, [serverIP]=@serverIP, [serverPort]=@serverPort, [serverURI]=@serverURI, - [locX]=@locX, [locY]=@locY, [locZ]=@locZ, [eastOverrideHandle]=@eastOverrideHandle, - [westOverrideHandle]=@westOverrideHandle, [southOverrideHandle]=@southOverrideHandle, - [northOverrideHandle]=@northOverrideHandle, [regionAssetURI]=@regionAssetURI, - [regionAssetRecvKey]=@regionAssetRecvKey, [regionAssetSendKey]=@regionAssetSendKey, - [regionUserURI]=@regionUserURI, [regionUserRecvKey]=@regionUserRecvKey, [regionUserSendKey]=@regionUserSendKey, - [regionMapTexture]=@regionMapTexture, [serverHttpPort]=@serverHttpPort, - [serverRemotingPort]=@serverRemotingPort, [owner_uuid]=@owner_uuid - where [uuid]=@uuid"; - - Dictionary parameters = new Dictionary(); - - parameters["regionHandle"] = profile.regionHandle.ToString(); - parameters["regionName"] = profile.regionName; - parameters["uuid"] = profile.ToString(); - parameters["regionRecvKey"] = profile.regionRecvKey; - parameters["regionSecret"] = profile.regionSecret; - parameters["regionSendKey"] = profile.regionSendKey; - parameters["regionDataURI"] = profile.regionDataURI; - parameters["serverIP"] = profile.serverIP; - parameters["serverPort"] = profile.serverPort.ToString(); - parameters["serverURI"] = profile.serverURI; - parameters["locX"] = profile.regionLocX.ToString(); - parameters["locY"] = profile.regionLocY.ToString(); - parameters["locZ"] = profile.regionLocZ.ToString(); - parameters["eastOverrideHandle"] = profile.regionEastOverrideHandle.ToString(); - parameters["westOverrideHandle"] = profile.regionWestOverrideHandle.ToString(); - parameters["northOverrideHandle"] = profile.regionNorthOverrideHandle.ToString(); - parameters["southOverrideHandle"] = profile.regionSouthOverrideHandle.ToString(); - parameters["regionAssetURI"] = profile.regionAssetURI; - parameters["regionAssetRecvKey"] = profile.regionAssetRecvKey; - parameters["regionAssetSendKey"] = profile.regionAssetSendKey; - parameters["regionUserURI"] = profile.regionUserURI; - parameters["regionUserRecvKey"] = profile.regionUserRecvKey; - parameters["regionUserSendKey"] = profile.regionUserSendKey; - parameters["regionMapTexture"] = profile.regionMapTextureID.ToString(); - parameters["serverHttpPort"] = profile.httpPort.ToString(); - parameters["serverRemotingPort"] = profile.remotingPort.ToString(); - parameters["owner_uuid"] = profile.owner_uuid.ToString(); - - bool returnval = false; - - try - { - using (IDbCommand result = database.Query(sql, parameters)) - { - - if (result.ExecuteNonQuery() == 1) - returnval = true; - - } - } - catch (Exception e) - { - m_log.Error("MSSQLManager : " + e.ToString()); - } - - return returnval; - } - /// - /// Creates a new region in the database - /// - /// The region profile to insert + /// the sim UUID /// Successful? - public bool insertRegionRow(RegionProfileData profile) + //public DataResponse DeleteProfile(RegionProfileData profile) + override public DataResponse DeleteProfile(string uuid) { - //Insert new region - string sql = - "INSERT INTO " + m_regionsTableName + @" ([regionHandle], [regionName], [uuid], [regionRecvKey], [regionSecret], [regionSendKey], [regionDataURI], - [serverIP], [serverPort], [serverURI], [locX], [locY], [locZ], [eastOverrideHandle], [westOverrideHandle], - [southOverrideHandle], [northOverrideHandle], [regionAssetURI], [regionAssetRecvKey], [regionAssetSendKey], - [regionUserURI], [regionUserRecvKey], [regionUserSendKey], [regionMapTexture], [serverHttpPort], - [serverRemotingPort], [owner_uuid]) - VALUES (@regionHandle, @regionName, @uuid, @regionRecvKey, @regionSecret, @regionSendKey, @regionDataURI, - @serverIP, @serverPort, @serverURI, @locX, @locY, @locZ, @eastOverrideHandle, @westOverrideHandle, - @southOverrideHandle, @northOverrideHandle, @regionAssetURI, @regionAssetRecvKey, @regionAssetSendKey, - @regionUserURI, @regionUserRecvKey, @regionUserSendKey, @regionMapTexture, @serverHttpPort, @serverRemotingPort, @owner_uuid);"; - - Dictionary parameters = new Dictionary(); - - parameters["regionHandle"] = profile.regionHandle.ToString(); - parameters["regionName"] = profile.regionName; - parameters["uuid"] = profile.ToString(); - parameters["regionRecvKey"] = profile.regionRecvKey; - parameters["regionSecret"] = profile.regionSecret; - parameters["regionSendKey"] = profile.regionSendKey; - parameters["regionDataURI"] = profile.regionDataURI; - parameters["serverIP"] = profile.serverIP; - parameters["serverPort"] = profile.serverPort.ToString(); - parameters["serverURI"] = profile.serverURI; - parameters["locX"] = profile.regionLocX.ToString(); - parameters["locY"] = profile.regionLocY.ToString(); - parameters["locZ"] = profile.regionLocZ.ToString(); - parameters["eastOverrideHandle"] = profile.regionEastOverrideHandle.ToString(); - parameters["westOverrideHandle"] = profile.regionWestOverrideHandle.ToString(); - parameters["northOverrideHandle"] = profile.regionNorthOverrideHandle.ToString(); - parameters["southOverrideHandle"] = profile.regionSouthOverrideHandle.ToString(); - parameters["regionAssetURI"] = profile.regionAssetURI; - parameters["regionAssetRecvKey"] = profile.regionAssetRecvKey; - parameters["regionAssetSendKey"] = profile.regionAssetSendKey; - parameters["regionUserURI"] = profile.regionUserURI; - parameters["regionUserRecvKey"] = profile.regionUserRecvKey; - parameters["regionUserSendKey"] = profile.regionUserSendKey; - parameters["regionMapTexture"] = profile.regionMapTextureID.ToString(); - parameters["serverHttpPort"] = profile.httpPort.ToString(); - parameters["serverRemotingPort"] = profile.remotingPort.ToString(); - parameters["owner_uuid"] = profile.owner_uuid.ToString(); - - bool returnval = false; - - try + using (AutoClosingSqlCommand command = database.Query("DELETE FROM regions WHERE uuid = @uuid;")) { - using (IDbCommand result = database.Query(sql, parameters)) + command.Parameters.Add(database.CreateParameter("uuid", uuid)); + try { - if (result.ExecuteNonQuery() == 1) - returnval = true; + command.ExecuteNonQuery(); + return DataResponse.RESPONSE_OK; + } + catch (Exception e) + { + m_log.DebugFormat("[GRID DB] : Error deleting region info, error is : {0}", e.Message); + return DataResponse.RESPONSE_ERROR; } } - catch (Exception e) - { - m_log.Error("[GRID DB]: " + e.ToString()); - } - - return returnval; } + #endregion + + #region Methods that are not used or deprecated (still needed because of base class) + /// /// DEPRECATED. Attempts to authenticate a region by comparing a shared secret. /// @@ -436,6 +387,7 @@ namespace OpenSim.Data.MSSQL /// /// NOT IMPLEMENTED + /// WHEN IS THIS GONNA BE IMPLEMENTED. /// /// /// @@ -444,5 +396,218 @@ namespace OpenSim.Data.MSSQL { return null; } + + #endregion + + #region private methods + + /// + /// Reads a region row from a database reader + /// + /// An active database reader + /// A region profile + private static RegionProfileData ReadSimRow(IDataRecord reader) + { + RegionProfileData retval = new RegionProfileData(); + + // Region Main gotta-have-or-we-return-null parts + UInt64 tmp64; + if (!UInt64.TryParse(reader["regionHandle"].ToString(), out tmp64)) + { + return null; + } + + retval.regionHandle = tmp64; + + UUID tmp_uuid; + if (!UUID.TryParse((string)reader["uuid"], out tmp_uuid)) + { + return null; + } + + retval.UUID = tmp_uuid; + + // non-critical parts + retval.regionName = reader["regionName"].ToString(); + retval.originUUID = new UUID((string)reader["originUUID"]); + + // Secrets + retval.regionRecvKey = reader["regionRecvKey"].ToString(); + retval.regionSecret = reader["regionSecret"].ToString(); + retval.regionSendKey = reader["regionSendKey"].ToString(); + + // Region Server + retval.regionDataURI = reader["regionDataURI"].ToString(); + retval.regionOnline = false; // Needs to be pinged before this can be set. + retval.serverIP = reader["serverIP"].ToString(); + retval.serverPort = Convert.ToUInt32(reader["serverPort"]); + retval.serverURI = reader["serverURI"].ToString(); + retval.httpPort = Convert.ToUInt32(reader["serverHttpPort"].ToString()); + retval.remotingPort = Convert.ToUInt32(reader["serverRemotingPort"].ToString()); + + // Location + retval.regionLocX = Convert.ToUInt32(reader["locX"].ToString()); + retval.regionLocY = Convert.ToUInt32(reader["locY"].ToString()); + retval.regionLocZ = Convert.ToUInt32(reader["locZ"].ToString()); + + // Neighbours - 0 = No Override + retval.regionEastOverrideHandle = Convert.ToUInt64(reader["eastOverrideHandle"].ToString()); + retval.regionWestOverrideHandle = Convert.ToUInt64(reader["westOverrideHandle"].ToString()); + retval.regionSouthOverrideHandle = Convert.ToUInt64(reader["southOverrideHandle"].ToString()); + retval.regionNorthOverrideHandle = Convert.ToUInt64(reader["northOverrideHandle"].ToString()); + + // Assets + retval.regionAssetURI = reader["regionAssetURI"].ToString(); + retval.regionAssetRecvKey = reader["regionAssetRecvKey"].ToString(); + retval.regionAssetSendKey = reader["regionAssetSendKey"].ToString(); + + // Userserver + retval.regionUserURI = reader["regionUserURI"].ToString(); + retval.regionUserRecvKey = reader["regionUserRecvKey"].ToString(); + retval.regionUserSendKey = reader["regionUserSendKey"].ToString(); + + // World Map Addition + UUID.TryParse((string)reader["regionMapTexture"], out retval.regionMapTextureID); + UUID.TryParse((string)reader["owner_uuid"], out retval.owner_uuid); + + return retval; + } + + /// + /// Update the specified region in the database + /// + /// The profile to update + /// success ? + private bool UpdateRegionRow(RegionProfileData profile) + { + bool returnval = false; + + //Insert new region + string sql = + "UPDATE " + m_regionsTableName + @" SET + [regionHandle]=@regionHandle, [regionName]=@regionName, + [regionRecvKey]=@regionRecvKey, [regionSecret]=@regionSecret, [regionSendKey]=@regionSendKey, + [regionDataURI]=@regionDataURI, [serverIP]=@serverIP, [serverPort]=@serverPort, [serverURI]=@serverURI, + [locX]=@locX, [locY]=@locY, [locZ]=@locZ, [eastOverrideHandle]=@eastOverrideHandle, + [westOverrideHandle]=@westOverrideHandle, [southOverrideHandle]=@southOverrideHandle, + [northOverrideHandle]=@northOverrideHandle, [regionAssetURI]=@regionAssetURI, + [regionAssetRecvKey]=@regionAssetRecvKey, [regionAssetSendKey]=@regionAssetSendKey, + [regionUserURI]=@regionUserURI, [regionUserRecvKey]=@regionUserRecvKey, [regionUserSendKey]=@regionUserSendKey, + [regionMapTexture]=@regionMapTexture, [serverHttpPort]=@serverHttpPort, + [serverRemotingPort]=@serverRemotingPort, [owner_uuid]=@owner_uuid , [originUUID]=@originUUID + where [uuid]=@uuid"; + + using (AutoClosingSqlCommand command = database.Query(sql)) + { + command.Parameters.Add(database.CreateParameter("regionHandle", profile.regionHandle)); + command.Parameters.Add(database.CreateParameter("regionName", profile.regionName)); + command.Parameters.Add(database.CreateParameter("uuid", profile.UUID)); + command.Parameters.Add(database.CreateParameter("regionRecvKey", profile.regionRecvKey)); + command.Parameters.Add(database.CreateParameter("regionSecret", profile.regionSecret)); + command.Parameters.Add(database.CreateParameter("regionSendKey", profile.regionSendKey)); + command.Parameters.Add(database.CreateParameter("regionDataURI", profile.regionDataURI)); + command.Parameters.Add(database.CreateParameter("serverIP", profile.serverIP)); + command.Parameters.Add(database.CreateParameter("serverPort", profile.serverPort)); + command.Parameters.Add(database.CreateParameter("serverURI", profile.serverURI)); + command.Parameters.Add(database.CreateParameter("locX", profile.regionLocX)); + command.Parameters.Add(database.CreateParameter("locY", profile.regionLocY)); + command.Parameters.Add(database.CreateParameter("locZ", profile.regionLocZ)); + command.Parameters.Add(database.CreateParameter("eastOverrideHandle", profile.regionEastOverrideHandle)); + command.Parameters.Add(database.CreateParameter("westOverrideHandle", profile.regionWestOverrideHandle)); + command.Parameters.Add(database.CreateParameter("northOverrideHandle", profile.regionNorthOverrideHandle)); + command.Parameters.Add(database.CreateParameter("southOverrideHandle", profile.regionSouthOverrideHandle)); + command.Parameters.Add(database.CreateParameter("regionAssetURI", profile.regionAssetURI)); + command.Parameters.Add(database.CreateParameter("regionAssetRecvKey", profile.regionAssetRecvKey)); + command.Parameters.Add(database.CreateParameter("regionAssetSendKey", profile.regionAssetSendKey)); + command.Parameters.Add(database.CreateParameter("regionUserURI", profile.regionUserURI)); + command.Parameters.Add(database.CreateParameter("regionUserRecvKey", profile.regionUserRecvKey)); + command.Parameters.Add(database.CreateParameter("regionUserSendKey", profile.regionUserSendKey)); + command.Parameters.Add(database.CreateParameter("regionMapTexture", profile.regionMapTextureID)); + command.Parameters.Add(database.CreateParameter("serverHttpPort", profile.httpPort)); + command.Parameters.Add(database.CreateParameter("serverRemotingPort", profile.remotingPort)); + command.Parameters.Add(database.CreateParameter("owner_uuid", profile.owner_uuid)); + command.Parameters.Add(database.CreateParameter("originUUID", profile.originUUID)); + + try + { + command.ExecuteNonQuery(); + returnval = true; + } + catch (Exception e) + { + m_log.Error("[GRID DB] : Error updating region, error: " + e.Message); + } + } + + return returnval; + } + + /// + /// Creates a new region in the database + /// + /// The region profile to insert + /// Successful? + private bool InsertRegionRow(RegionProfileData profile) + { + bool returnval = false; + + //Insert new region + string sql = + "INSERT INTO " + m_regionsTableName + @" ([regionHandle], [regionName], [uuid], [regionRecvKey], [regionSecret], [regionSendKey], [regionDataURI], + [serverIP], [serverPort], [serverURI], [locX], [locY], [locZ], [eastOverrideHandle], [westOverrideHandle], + [southOverrideHandle], [northOverrideHandle], [regionAssetURI], [regionAssetRecvKey], [regionAssetSendKey], + [regionUserURI], [regionUserRecvKey], [regionUserSendKey], [regionMapTexture], [serverHttpPort], + [serverRemotingPort], [owner_uuid], [originUUID]) + VALUES (@regionHandle, @regionName, @uuid, @regionRecvKey, @regionSecret, @regionSendKey, @regionDataURI, + @serverIP, @serverPort, @serverURI, @locX, @locY, @locZ, @eastOverrideHandle, @westOverrideHandle, + @southOverrideHandle, @northOverrideHandle, @regionAssetURI, @regionAssetRecvKey, @regionAssetSendKey, + @regionUserURI, @regionUserRecvKey, @regionUserSendKey, @regionMapTexture, @serverHttpPort, @serverRemotingPort, @owner_uuid, @originUUID);"; + + using (AutoClosingSqlCommand command = database.Query(sql)) + { + command.Parameters.Add(database.CreateParameter("regionHandle", profile.regionHandle)); + command.Parameters.Add(database.CreateParameter("regionName", profile.regionName)); + command.Parameters.Add(database.CreateParameter("uuid", profile.UUID)); + command.Parameters.Add(database.CreateParameter("regionRecvKey", profile.regionRecvKey)); + command.Parameters.Add(database.CreateParameter("regionSecret", profile.regionSecret)); + command.Parameters.Add(database.CreateParameter("regionSendKey", profile.regionSendKey)); + command.Parameters.Add(database.CreateParameter("regionDataURI", profile.regionDataURI)); + command.Parameters.Add(database.CreateParameter("serverIP", profile.serverIP)); + command.Parameters.Add(database.CreateParameter("serverPort", profile.serverPort)); + command.Parameters.Add(database.CreateParameter("serverURI", profile.serverURI)); + command.Parameters.Add(database.CreateParameter("locX", profile.regionLocX)); + command.Parameters.Add(database.CreateParameter("locY", profile.regionLocY)); + command.Parameters.Add(database.CreateParameter("locZ", profile.regionLocZ)); + command.Parameters.Add(database.CreateParameter("eastOverrideHandle", profile.regionEastOverrideHandle)); + command.Parameters.Add(database.CreateParameter("westOverrideHandle", profile.regionWestOverrideHandle)); + command.Parameters.Add(database.CreateParameter("northOverrideHandle", profile.regionNorthOverrideHandle)); + command.Parameters.Add(database.CreateParameter("southOverrideHandle", profile.regionSouthOverrideHandle)); + command.Parameters.Add(database.CreateParameter("regionAssetURI", profile.regionAssetURI)); + command.Parameters.Add(database.CreateParameter("regionAssetRecvKey", profile.regionAssetRecvKey)); + command.Parameters.Add(database.CreateParameter("regionAssetSendKey", profile.regionAssetSendKey)); + command.Parameters.Add(database.CreateParameter("regionUserURI", profile.regionUserURI)); + command.Parameters.Add(database.CreateParameter("regionUserRecvKey", profile.regionUserRecvKey)); + command.Parameters.Add(database.CreateParameter("regionUserSendKey", profile.regionUserSendKey)); + command.Parameters.Add(database.CreateParameter("regionMapTexture", profile.regionMapTextureID)); + command.Parameters.Add(database.CreateParameter("serverHttpPort", profile.httpPort)); + command.Parameters.Add(database.CreateParameter("serverRemotingPort", profile.remotingPort)); + command.Parameters.Add(database.CreateParameter("owner_uuid", profile.owner_uuid)); + command.Parameters.Add(database.CreateParameter("originUUID", profile.originUUID)); + + try + { + command.ExecuteNonQuery(); + returnval = true; + } + catch (Exception e) + { + m_log.Error("[GRID DB] : Error inserting region, error: " + e.Message); + } + } + + return returnval; + } + + #endregion } } diff --git a/OpenSim/Data/MSSQL/MSSQLInventoryData.cs b/OpenSim/Data/MSSQL/MSSQLInventoryData.cs index e7df7c1c2d..03600e23e6 100644 --- a/OpenSim/Data/MSSQL/MSSQLInventoryData.cs +++ b/OpenSim/Data/MSSQL/MSSQLInventoryData.cs @@ -41,49 +41,53 @@ namespace OpenSim.Data.MSSQL /// public class MSSQLInventoryData : IInventoryDataPlugin { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private const string _migrationStore = "InventoryStore"; - #region Helper converters to preserve unsigned bitfield-type data in DB roundtrips via signed int32s - private static int ConvertUint32BitFieldToInt32(uint bitField) - { - return BitConverter.ToInt32(BitConverter.GetBytes(bitField), 0); - } - private static uint ConvertInt32BitFieldToUint32(int bitField) - { - return BitConverter.ToUInt32(BitConverter.GetBytes(bitField), 0); - } - #endregion + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// /// The database manager /// private MSSQLManager database; - public void Initialise() - { + #region IPlugin members + + public void Initialise() + { m_log.Info("[MSSQLInventoryData]: " + Name + " cannot be default-initialized!"); - throw new PluginNotInitialisedException (Name); + throw new PluginNotInitialisedException(Name); } /// /// Loads and initialises the MSSQL inventory storage interface /// - /// connect string + /// connect string /// use mssql_connection.ini - public void Initialise(string connect) + public void Initialise(string connectionString) { - // TODO: actually use the provided connect string - IniFile gridDataMSSqlFile = new IniFile("mssql_connection.ini"); - string settingDataSource = gridDataMSSqlFile.ParseFileReadValue("data_source"); - string settingInitialCatalog = gridDataMSSqlFile.ParseFileReadValue("initial_catalog"); - string settingPersistSecurityInfo = gridDataMSSqlFile.ParseFileReadValue("persist_security_info"); - string settingUserId = gridDataMSSqlFile.ParseFileReadValue("user_id"); - string settingPassword = gridDataMSSqlFile.ParseFileReadValue("password"); + if (string.IsNullOrEmpty(connectionString)) + { + database = new MSSQLManager(connectionString); + } + else + { + IniFile gridDataMSSqlFile = new IniFile("mssql_connection.ini"); + string settingDataSource = gridDataMSSqlFile.ParseFileReadValue("data_source"); + string settingInitialCatalog = gridDataMSSqlFile.ParseFileReadValue("initial_catalog"); + string settingPersistSecurityInfo = gridDataMSSqlFile.ParseFileReadValue("persist_security_info"); + string settingUserId = gridDataMSSqlFile.ParseFileReadValue("user_id"); + string settingPassword = gridDataMSSqlFile.ParseFileReadValue("password"); - database = - new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, - settingPassword); + database = + new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, + settingPassword); + } + + //TODO remove this at one point TestTables(); + + //New migrations check of store + database.CheckMigration(_migrationStore); } #region Test and initialization code @@ -132,6 +136,37 @@ namespace OpenSim.Data.MSSQL UpgradeFoldersTable(tableList["inventoryfolders"]); UpgradeItemsTable(tableList["inventoryitems"]); + + using (AutoClosingSqlCommand cmd = database.Query("select * from migrations where name = '" + _migrationStore + "'")) + { + //Special for Migrations to create backword compatible + try + { + bool insert = true; + using (SqlDataReader reader = cmd.ExecuteReader()) + { + if (reader.Read()) insert = false; + } + if (insert) + { + cmd.CommandText = "insert into migrations(name, version) values('" + _migrationStore + "', 1)"; + cmd.ExecuteNonQuery(); + } + } + catch + { + //No migrations table + //HACK create one and add data + cmd.CommandText = "create table migrations(name varchar(100), version int)"; + cmd.ExecuteNonQuery(); + + cmd.CommandText = "insert into migrations(name, version) values('migrations', 1)"; + cmd.ExecuteNonQuery(); + + cmd.CommandText = "insert into migrations(name, version) values('" + _migrationStore + "', 1)"; + cmd.ExecuteNonQuery(); + } + } } #endregion @@ -150,7 +185,7 @@ namespace OpenSim.Data.MSSQL /// public void Dispose() { - // Do nothing. + database = null; } /// @@ -162,39 +197,9 @@ namespace OpenSim.Data.MSSQL get { return database.getVersion(); } } - /// - /// Returns a list of items in a specified folder - /// - /// The folder to search - /// A list containing inventory items - public List getInventoryInFolder(UUID folderID) - { - try - { - List items = new List(); + #endregion - Dictionary param = new Dictionary(); - param["parentFolderID"] = folderID.ToString(); - - using (IDbCommand result = - database.Query("SELECT * FROM inventoryitems WHERE parentFolderID = @parentFolderID", param)) - using (IDataReader reader = result.ExecuteReader()) - { - - while (reader.Read()) - items.Add(readInventoryItem(reader)); - - reader.Close(); - } - - return items; - } - catch (Exception e) - { - m_log.Error(e.ToString()); - return null; - } - } + #region Folder methods /// /// Returns a list of the root folders within a users inventory @@ -203,31 +208,7 @@ namespace OpenSim.Data.MSSQL /// A list of folder objects public List getUserRootFolders(UUID user) { - try - { - Dictionary param = new Dictionary(); - param["uuid"] = user.ToString(); - param["zero"] = UUID.Zero.ToString(); - - using (IDbCommand result = - database.Query( - "SELECT * FROM inventoryfolders WHERE parentFolderID = @zero AND agentID = @uuid", param)) - using (IDataReader reader = result.ExecuteReader()) - { - - List items = new List(); - while (reader.Read()) - items.Add(readInventoryFolder(reader)); - - return items; - } - - } - catch (Exception e) - { - m_log.Error(e.ToString()); - return null; - } + return getInventoryFolders(UUID.Zero, user); } /// @@ -237,43 +218,21 @@ namespace OpenSim.Data.MSSQL /// public InventoryFolderBase getUserRootFolder(UUID user) { - try + List items = getUserRootFolders(user); + + InventoryFolderBase rootFolder = null; + + // There should only ever be one root folder for a user. However, if there's more + // than one we'll simply use the first one rather than failing. It would be even + // nicer to print some message to this effect, but this feels like it's too low a + // to put such a message out, and it's too minor right now to spare the time to + // suitably refactor. + if (items.Count > 0) { - Dictionary param = new Dictionary(); - param["uuid"] = user.ToString(); - param["zero"] = UUID.Zero.ToString(); - - using (IDbCommand result = - database.Query( - "SELECT * FROM inventoryfolders WHERE parentFolderID = @zero AND agentID = @uuid", param)) - using (IDataReader reader = result.ExecuteReader()) - { - - List items = new List(); - while (reader.Read()) - items.Add(readInventoryFolder(reader)); - - InventoryFolderBase rootFolder = null; - - // There should only ever be one root folder for a user. However, if there's more - // than one we'll simply use the first one rather than failing. It would be even - // nicer to print some message to this effect, but this feels like it's too low a - // to put such a message out, and it's too minor right now to spare the time to - // suitably refactor. - if (items.Count > 0) - { - rootFolder = items[0]; - } - - return rootFolder; - } - - } - catch (Exception e) - { - m_log.Error(e.ToString()); - return null; + rootFolder = items[0]; } + + return rootFolder; } /// @@ -283,156 +242,235 @@ namespace OpenSim.Data.MSSQL /// A list of inventory folders public List getInventoryFolders(UUID parentID) { - try - { - Dictionary param = new Dictionary(); - param["parentFolderID"] = parentID.ToString(); - - using (IDbCommand result = - database.Query("SELECT * FROM inventoryfolders WHERE parentFolderID = @parentFolderID", param)) - using (IDataReader reader = result.ExecuteReader()) - { - List items = new List(); - - while (reader.Read()) - items.Add(readInventoryFolder(reader)); - - return items; - } - } - catch (Exception e) - { - m_log.Error(e.ToString()); - return null; - } - } - - /// - /// Reads a one item from an SQL result - /// - /// The SQL Result - /// the item read - private static InventoryItemBase readInventoryItem(IDataReader reader) - { - try - { - InventoryItemBase item = new InventoryItemBase(); - - item.ID = new UUID((string) reader["inventoryID"]); - item.AssetID = new UUID((string) reader["assetID"]); - item.AssetType = (int) reader["assetType"]; - item.Folder = new UUID((string) reader["parentFolderID"]); - item.Owner = new UUID((string) reader["avatarID"]); - item.Name = (string) reader["inventoryName"]; - item.Description = (string) reader["inventoryDescription"]; - item.NextPermissions = ConvertInt32BitFieldToUint32((int)reader["inventoryNextPermissions"]); - item.CurrentPermissions = ConvertInt32BitFieldToUint32((int)reader["inventoryCurrentPermissions"]); - item.InvType = (int) reader["invType"]; - item.Creator = new UUID((string) reader["creatorID"]); - item.BasePermissions = ConvertInt32BitFieldToUint32((int)reader["inventoryBasePermissions"]); - item.EveryOnePermissions = ConvertInt32BitFieldToUint32((int)reader["inventoryEveryOnePermissions"]); - item.SalePrice = (int) reader["salePrice"]; - item.SaleType = Convert.ToByte(reader["saleType"]); - item.CreationDate = (int) reader["creationDate"]; - item.GroupID = new UUID(reader["groupID"].ToString()); - item.GroupOwned = Convert.ToBoolean(reader["groupOwned"]); - item.Flags = ConvertInt32BitFieldToUint32((int)reader["flags"]); - - return item; - } - catch (SqlException e) - { - m_log.Error(e.ToString()); - } - - return null; - } - - /// - /// Returns a specified inventory item - /// - /// The item to return - /// An inventory item - public InventoryItemBase getInventoryItem(UUID itemID) - { - try - { - Dictionary param = new Dictionary(); - param["inventoryID"] = itemID.ToString(); - - using (IDbCommand result = - database.Query("SELECT * FROM inventoryitems WHERE inventoryID = @inventoryID", param)) - using (IDataReader reader = result.ExecuteReader()) - { - - InventoryItemBase item = null; - if (reader.Read()) - item = readInventoryItem(reader); - - return item; - } - } - catch (Exception e) - { - m_log.Error(e.ToString()); - } - return null; - } - - /// - /// Reads a list of inventory folders returned by a query. - /// - /// A MSSQL Data Reader - /// A List containing inventory folders - protected static InventoryFolderBase readInventoryFolder(IDataReader reader) - { - try - { - InventoryFolderBase folder = new InventoryFolderBase(); - folder.Owner = new UUID((string) reader["agentID"]); - folder.ParentID = new UUID((string) reader["parentFolderID"]); - folder.ID = new UUID((string) reader["folderID"]); - folder.Name = (string) reader["folderName"]; - folder.Type = (short) reader["type"]; - folder.Version = Convert.ToUInt16(reader["version"]); - return folder; - } - catch (Exception e) - { - m_log.Error(e.ToString()); - } - - return null; + return getInventoryFolders(parentID, UUID.Zero); } /// /// Returns a specified inventory folder /// - /// The folder to return + /// The folder to return /// A folder class public InventoryFolderBase getInventoryFolder(UUID folderID) { - try + using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryfolders WHERE folderID = @folderID")) { - Dictionary param = new Dictionary(); - param["uuid"] = folderID.ToString(); + command.Parameters.Add(database.CreateParameter("folderID", folderID)); - using (IDbCommand result = database.Query("SELECT * FROM inventoryfolders WHERE folderID = @uuid", param)) - using (IDataReader reader = result.ExecuteReader()) + using (IDataReader reader = command.ExecuteReader()) { - - reader.Read(); - - InventoryFolderBase folder = readInventoryFolder(reader); - - return folder; + if (reader.Read()) + { + return readInventoryFolder(reader); + } } } - catch (Exception e) + m_log.InfoFormat("[INVENTORY DB] : FOund no inventory folder with ID : {0}", folderID); + return null; + } + + /// + /// Returns all child folders in the hierarchy from the parent folder and down. + /// Does not return the parent folder itself. + /// + /// The folder to get subfolders for + /// A list of inventory folders + public List getFolderHierarchy(UUID parentID) + { + //Note maybe change this to use a Dataset that loading in all folders of a user and then go throw it that way. + //Note this is changed so it opens only one connection to the database and not everytime it wants to get data. + + List folders = new List(); + + using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID")) { - m_log.Error(e.ToString()); - return null; + command.Parameters.Add(database.CreateParameter("@parentID", parentID)); + + folders.AddRange(getInventoryFolders(command)); + + List tempFolders = new List(); + + foreach (InventoryFolderBase folderBase in folders) + { + tempFolders.AddRange(getFolderHierarchy(folderBase.ID, command)); + } + if (tempFolders.Count > 0) + { + folders.AddRange(tempFolders); + } } + return folders; + } + + /// + /// Creates a new inventory folder + /// + /// Folder to create + public void addInventoryFolder(InventoryFolderBase folder) + { + string sql = + "INSERT INTO inventoryfolders ([folderID], [agentID], [parentFolderID], [folderName], [type], [version]) VALUES "; + sql += "(@folderID, @agentID, @parentFolderID, @folderName, @type, @version);"; + + + using (AutoClosingSqlCommand command = database.Query(sql)) + { + command.Parameters.Add(database.CreateParameter("folderID", folder.ID)); + command.Parameters.Add(database.CreateParameter("agentID", folder.Owner)); + command.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID)); + command.Parameters.Add(database.CreateParameter("folderName", folder.Name)); + command.Parameters.Add(database.CreateParameter("type", folder.Type)); + command.Parameters.Add(database.CreateParameter("version", folder.Version)); + + try + { + //IDbCommand result = database.Query(sql, param); + command.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.ErrorFormat("[ASSET DB] Error : {0}", e.Message); + } + } + } + + /// + /// Updates an inventory folder + /// + /// Folder to update + public void updateInventoryFolder(InventoryFolderBase folder) + { + using (AutoClosingSqlCommand command = database.Query("UPDATE inventoryfolders set folderID = @folderID, " + + "agentID = @agentID, " + + "parentFolderID = @parentFolderID," + + "folderName = @folderName," + + "type = @type," + + "version = @version where " + + "folderID = @keyFolderID;")) + { + command.Parameters.Add(database.CreateParameter("folderID", folder.ID)); + command.Parameters.Add(database.CreateParameter("agentID", folder.Owner)); + command.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID)); + command.Parameters.Add(database.CreateParameter("folderName", folder.Name)); + command.Parameters.Add(database.CreateParameter("type", folder.Type)); + command.Parameters.Add(database.CreateParameter("version", folder.Version)); + command.Parameters.Add(database.CreateParameter("@keyFolderID", folder.ID)); + try + { + command.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.ErrorFormat("[ASSET DB] Error : {0}", e.Message); + } + } + } + + /// + /// Updates an inventory folder + /// + /// Folder to update + public void moveInventoryFolder(InventoryFolderBase folder) + { + using (IDbCommand command = database.Query("UPDATE inventoryfolders set " + + "parentFolderID = @parentFolderID where " + + "folderID = @folderID;")) + { + command.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID)); + command.Parameters.Add(database.CreateParameter("@folderID", folder.ID)); + + try + { + command.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.ErrorFormat("[ASSET DB] Error : {0}", e.Message); + } + } + } + + /// + /// Delete an inventory folder + /// + /// Id of folder to delete + public void deleteInventoryFolder(UUID folderID) + { + using (SqlConnection connection = database.DatabaseConnection()) + { + List subFolders; + using (SqlCommand command = new SqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID", connection)) + { + command.Parameters.Add(database.CreateParameter("@parentID", string.Empty)); + + AutoClosingSqlCommand autoCommand = new AutoClosingSqlCommand(command); + + subFolders = getFolderHierarchy(folderID, autoCommand); + } + + //Delete all sub-folders + foreach (InventoryFolderBase f in subFolders) + { + DeleteOneFolder(f.ID, connection); + DeleteItemsInFolder(f.ID, connection); + } + + //Delete the actual row + DeleteOneFolder(folderID, connection); + DeleteItemsInFolder(folderID, connection); + + connection.Close(); + } + } + + #endregion + + #region Item Methods + + /// + /// Returns a list of items in a specified folder + /// + /// The folder to search + /// A list containing inventory items + public List getInventoryInFolder(UUID folderID) + { + using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryitems WHERE parentFolderID = @parentFolderID")) + { + command.Parameters.Add(database.CreateParameter("parentFolderID", folderID)); + + List items = new List(); + + using (SqlDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + items.Add(readInventoryItem(reader)); + } + } + return items; + } + } + + /// + /// Returns a specified inventory item + /// + /// The item ID + /// An inventory item + public InventoryItemBase getInventoryItem(UUID itemID) + { + using (AutoClosingSqlCommand result = database.Query("SELECT * FROM inventoryitems WHERE inventoryID = @inventoryID")) + { + result.Parameters.Add(database.CreateParameter("inventoryID", itemID)); + + using (IDataReader reader = result.ExecuteReader()) + { + if (reader.Read()) + { + return readInventoryItem(reader); + } + } + } + m_log.InfoFormat("[INVENTORY DB] : Found no inventory item with ID : {0}", itemID); + return null; } /// @@ -448,46 +486,44 @@ namespace OpenSim.Data.MSSQL } string sql = "INSERT INTO inventoryitems"; - sql += - "([inventoryID], [assetID], [assetType], [parentFolderID], [avatarID], [inventoryName]" + sql += "([inventoryID], [assetID], [assetType], [parentFolderID], [avatarID], [inventoryName]" + ", [inventoryDescription], [inventoryNextPermissions], [inventoryCurrentPermissions]" + ", [invType], [creatorID], [inventoryBasePermissions], [inventoryEveryOnePermissions]" + ", [salePrice], [saleType], [creationDate], [groupID], [groupOwned], [flags]) VALUES "; - sql += - "(@inventoryID, @assetID, @assetType, @parentFolderID, @avatarID, @inventoryName, @inventoryDescription" + sql += "(@inventoryID, @assetID, @assetType, @parentFolderID, @avatarID, @inventoryName, @inventoryDescription" + ", @inventoryNextPermissions, @inventoryCurrentPermissions, @invType, @creatorID" + ", @inventoryBasePermissions, @inventoryEveryOnePermissions, @salePrice, @saleType" + ", @creationDate, @groupID, @groupOwned, @flags);"; using (AutoClosingSqlCommand command = database.Query(sql)) { - command.Parameters.AddWithValue("inventoryID", item.ID.ToString()); - command.Parameters.AddWithValue("assetID", item.AssetID.ToString()); - command.Parameters.AddWithValue("assetType", item.AssetType.ToString()); - command.Parameters.AddWithValue("parentFolderID", item.Folder.ToString()); - command.Parameters.AddWithValue("avatarID", item.Owner.ToString()); - command.Parameters.AddWithValue("inventoryName", item.Name); - command.Parameters.AddWithValue("inventoryDescription", item.Description); - command.Parameters.AddWithValue("inventoryNextPermissions", ConvertUint32BitFieldToInt32(item.NextPermissions)); - command.Parameters.AddWithValue("inventoryCurrentPermissions", ConvertUint32BitFieldToInt32(item.CurrentPermissions)); - command.Parameters.AddWithValue("invType", item.InvType); - command.Parameters.AddWithValue("creatorID", item.Creator.ToString()); - command.Parameters.AddWithValue("inventoryBasePermissions", ConvertUint32BitFieldToInt32(item.BasePermissions)); - command.Parameters.AddWithValue("inventoryEveryOnePermissions", ConvertUint32BitFieldToInt32(item.EveryOnePermissions)); - command.Parameters.AddWithValue("salePrice", item.SalePrice); - command.Parameters.AddWithValue("saleType", item.SaleType); - command.Parameters.AddWithValue("creationDate", item.CreationDate); - command.Parameters.AddWithValue("groupID", item.GroupID.ToString()); - command.Parameters.AddWithValue("groupOwned", item.GroupOwned); - command.Parameters.AddWithValue("flags", ConvertUint32BitFieldToInt32(item.Flags)); + command.Parameters.Add(database.CreateParameter("inventoryID", item.ID)); + command.Parameters.Add(database.CreateParameter("assetID", item.AssetID)); + command.Parameters.Add(database.CreateParameter("assetType", item.AssetType)); + command.Parameters.Add(database.CreateParameter("parentFolderID", item.Folder)); + command.Parameters.Add(database.CreateParameter("avatarID", item.Owner)); + command.Parameters.Add(database.CreateParameter("inventoryName", item.Name)); + command.Parameters.Add(database.CreateParameter("inventoryDescription", item.Description)); + command.Parameters.Add(database.CreateParameter("inventoryNextPermissions", item.NextPermissions)); + command.Parameters.Add(database.CreateParameter("inventoryCurrentPermissions", item.CurrentPermissions)); + command.Parameters.Add(database.CreateParameter("invType", item.InvType)); + command.Parameters.Add(database.CreateParameter("creatorID", item.Creator)); + command.Parameters.Add(database.CreateParameter("inventoryBasePermissions", item.BasePermissions)); + command.Parameters.Add(database.CreateParameter("inventoryEveryOnePermissions", item.EveryOnePermissions)); + command.Parameters.Add(database.CreateParameter("salePrice", item.SalePrice)); + command.Parameters.Add(database.CreateParameter("saleType", item.SaleType)); + command.Parameters.Add(database.CreateParameter("creationDate", item.CreationDate)); + command.Parameters.Add(database.CreateParameter("groupID", item.GroupID)); + command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned)); + command.Parameters.Add(database.CreateParameter("flags", item.Flags)); try { command.ExecuteNonQuery(); } - catch (SqlException e) + catch (Exception e) { - m_log.Error(e.ToString()); + m_log.Error("[INVENTORY DB] Error inserting item :" + e.Message); } } @@ -520,26 +556,26 @@ namespace OpenSim.Data.MSSQL "flags = @flags where " + "inventoryID = @keyInventoryID;")) { - command.Parameters.AddWithValue("inventoryID", item.ID.ToString()); - command.Parameters.AddWithValue("assetID", item.AssetID.ToString()); - command.Parameters.AddWithValue("assetType", item.AssetType.ToString()); - command.Parameters.AddWithValue("parentFolderID", item.Folder.ToString()); - command.Parameters.AddWithValue("avatarID", item.Owner.ToString()); - command.Parameters.AddWithValue("inventoryName", item.Name); - command.Parameters.AddWithValue("inventoryDescription", item.Description); - command.Parameters.AddWithValue("inventoryNextPermissions", ConvertUint32BitFieldToInt32(item.NextPermissions)); - command.Parameters.AddWithValue("inventoryCurrentPermissions", ConvertUint32BitFieldToInt32(item.CurrentPermissions)); - command.Parameters.AddWithValue("invType", item.InvType); - command.Parameters.AddWithValue("creatorID", item.Creator.ToString()); - command.Parameters.AddWithValue("inventoryBasePermissions", ConvertUint32BitFieldToInt32(item.BasePermissions)); - command.Parameters.AddWithValue("inventoryEveryOnePermissions", ConvertUint32BitFieldToInt32(item.EveryOnePermissions)); - command.Parameters.AddWithValue("salePrice", item.SalePrice); - command.Parameters.AddWithValue("saleType", item.SaleType); - command.Parameters.AddWithValue("creationDate", item.CreationDate); - command.Parameters.AddWithValue("groupID", item.GroupID.ToString()); - command.Parameters.AddWithValue("groupOwned", item.GroupOwned); - command.Parameters.AddWithValue("flags", ConvertUint32BitFieldToInt32(item.Flags)); - command.Parameters.AddWithValue("@keyInventoryID", item.ID.ToString()); + command.Parameters.Add(database.CreateParameter("inventoryID", item.ID)); + command.Parameters.Add(database.CreateParameter("assetID", item.AssetID)); + command.Parameters.Add(database.CreateParameter("assetType", item.AssetType)); + command.Parameters.Add(database.CreateParameter("parentFolderID", item.Folder)); + command.Parameters.Add(database.CreateParameter("avatarID", item.Owner)); + command.Parameters.Add(database.CreateParameter("inventoryName", item.Name)); + command.Parameters.Add(database.CreateParameter("inventoryDescription", item.Description)); + command.Parameters.Add(database.CreateParameter("inventoryNextPermissions", item.NextPermissions)); + command.Parameters.Add(database.CreateParameter("inventoryCurrentPermissions", item.CurrentPermissions)); + command.Parameters.Add(database.CreateParameter("invType", item.InvType)); + command.Parameters.Add(database.CreateParameter("creatorID", item.Creator)); + command.Parameters.Add(database.CreateParameter("inventoryBasePermissions", item.BasePermissions)); + command.Parameters.Add(database.CreateParameter("inventoryEveryOnePermissions", item.EveryOnePermissions)); + command.Parameters.Add(database.CreateParameter("salePrice", item.SalePrice)); + command.Parameters.Add(database.CreateParameter("saleType", item.SaleType)); + command.Parameters.Add(database.CreateParameter("creationDate", item.CreationDate)); + command.Parameters.Add(database.CreateParameter("groupID", item.GroupID)); + command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned)); + command.Parameters.Add(database.CreateParameter("flags", item.Flags)); + command.Parameters.Add(database.CreateParameter("@keyInventoryID", item.ID)); try { @@ -547,225 +583,221 @@ namespace OpenSim.Data.MSSQL } catch (Exception e) { - m_log.Error(e.ToString()); + m_log.Error("[INVENTORY DB] Error updating item :" + e.Message); } } } + // See IInventoryDataPlugin + /// /// Delete an item in inventory database /// - /// the item UUID + /// the item UUID public void deleteInventoryItem(UUID itemID) + { + using (AutoClosingSqlCommand command = database.Query("DELETE FROM inventoryitems WHERE inventoryID=@inventoryID")) + { + command.Parameters.Add(database.CreateParameter("inventoryID", itemID)); + try + { + + command.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.Error("[INVENTORY DB] Error deleting item :" + e.Message); + } + } + } + + #endregion + + #region Private methods + + /// + /// Delete an item in inventory database + /// + /// the item ID + /// connection to the database + private void DeleteItemsInFolder(UUID folderID, SqlConnection connection) + { + using (SqlCommand command = new SqlCommand("DELETE FROM inventoryitems WHERE folderID=@folderID", connection)) + { + command.Parameters.Add(database.CreateParameter("folderID", folderID)); + + try + { + command.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.Error("[INVENTORY DB] Error deleting item :" + e.Message); + } + } + } + + /// + /// Gets the folder hierarchy in a loop. + /// + /// parent ID. + /// SQL command/connection to database + /// + private static List getFolderHierarchy(UUID parentID, AutoClosingSqlCommand command) + { + command.Parameters["@parentID"].Value = parentID.ToString(); + + List folders = getInventoryFolders(command); + + if (folders.Count > 0) + { + List tempFolders = new List(); + + foreach (InventoryFolderBase folderBase in folders) + { + tempFolders.AddRange(getFolderHierarchy(folderBase.ID, command)); + } + + if (tempFolders.Count > 0) + { + folders.AddRange(tempFolders); + } + } + return folders; + } + + /// + /// Gets the inventory folders. + /// + /// parentID, use UUID.Zero to get root + /// user id, use UUID.Zero, if you want all folders from a parentID. + /// + private List getInventoryFolders(UUID parentID, UUID user) + { + using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID AND agentID LIKE @uuid")) + { + if (user == UUID.Zero) + { + command.Parameters.Add(database.CreateParameter("uuid", "%")); + } + else + { + command.Parameters.Add(database.CreateParameter("uuid", user)); + } + command.Parameters.Add(database.CreateParameter("parentID", parentID)); + + return getInventoryFolders(command); + } + } + + /// + /// Gets the inventory folders. + /// + /// SQLcommand. + /// + private static List getInventoryFolders(AutoClosingSqlCommand command) + { + using (IDataReader reader = command.ExecuteReader()) + { + + List items = new List(); + while (reader.Read()) + { + items.Add(readInventoryFolder(reader)); + } + return items; + } + } + + /// + /// Reads a list of inventory folders returned by a query. + /// + /// A MSSQL Data Reader + /// A List containing inventory folders + protected static InventoryFolderBase readInventoryFolder(IDataReader reader) { try { - Dictionary param = new Dictionary(); - param["uuid"] = itemID.ToString(); + InventoryFolderBase folder = new InventoryFolderBase(); + folder.Owner = new UUID((string)reader["agentID"]); + folder.ParentID = new UUID((string)reader["parentFolderID"]); + folder.ID = new UUID((string)reader["folderID"]); + folder.Name = (string)reader["folderName"]; + folder.Type = (short)reader["type"]; + folder.Version = Convert.ToUInt16(reader["version"]); - using (IDbCommand cmd = database.Query("DELETE FROM inventoryitems WHERE inventoryID=@uuid", param)) - { - cmd.ExecuteNonQuery(); - } + return folder; + } + catch (Exception e) + { + m_log.Error("[INVENTORY DB] Error reading inventory folder :" + e.Message); + } + + return null; + } + + /// + /// Reads a one item from an SQL result + /// + /// The SQL Result + /// the item read + private static InventoryItemBase readInventoryItem(IDataRecord reader) + { + try + { + InventoryItemBase item = new InventoryItemBase(); + + item.ID = new UUID(reader["inventoryID"].ToString()); + item.AssetID = new UUID(reader["assetID"].ToString()); + item.AssetType = Convert.ToInt32(reader["assetType"].ToString()); + item.Folder = new UUID(reader["parentFolderID"].ToString()); + item.Owner = new UUID(reader["avatarID"].ToString()); + item.Name = reader["inventoryName"].ToString(); + item.Description = reader["inventoryDescription"].ToString(); + item.NextPermissions = Convert.ToUInt32(reader["inventoryNextPermissions"]); + item.CurrentPermissions = Convert.ToUInt32(reader["inventoryCurrentPermissions"]); + item.InvType = Convert.ToInt32(reader["invType"].ToString()); + item.Creator = new UUID(reader["creatorID"].ToString()); + item.BasePermissions = Convert.ToUInt32(reader["inventoryBasePermissions"]); + item.EveryOnePermissions = Convert.ToUInt32(reader["inventoryEveryOnePermissions"]); + item.SalePrice = Convert.ToInt32(reader["salePrice"]); + item.SaleType = Convert.ToByte(reader["saleType"]); + item.CreationDate = Convert.ToInt32(reader["creationDate"]); + item.GroupID = new UUID(reader["groupID"].ToString()); + item.GroupOwned = Convert.ToBoolean(reader["groupOwned"]); + item.Flags = Convert.ToUInt32(reader["flags"]); + + return item; } catch (SqlException e) { - m_log.Error(e.ToString()); + m_log.Error("[INVENTORY DB] Error reading inventory item :" + e.Message); } - } - /// - /// Creates a new inventory folder - /// - /// Folder to create - public void addInventoryFolder(InventoryFolderBase folder) - { - string sql = - "INSERT INTO inventoryfolders ([folderID], [agentID], [parentFolderID], [folderName], [type], [version]) VALUES "; - sql += "(@folderID, @agentID, @parentFolderID, @folderName, @type, @version);"; - - - using (AutoClosingSqlCommand command = database.Query(sql)) - { - command.Parameters.AddWithValue("folderID", folder.ID.ToString()); - command.Parameters.AddWithValue("agentID", folder.Owner.ToString()); - command.Parameters.AddWithValue("parentFolderID", folder.ParentID.ToString()); - command.Parameters.AddWithValue("folderName", folder.Name); - command.Parameters.AddWithValue("type", folder.Type); - command.Parameters.AddWithValue("version", Convert.ToInt32(folder.Version)); - - try - { - //IDbCommand result = database.Query(sql, param); - command.ExecuteNonQuery(); - } - catch (Exception e) - { - m_log.Error(e.ToString()); - } - } - } - - /// - /// Updates an inventory folder - /// - /// Folder to update - public void updateInventoryFolder(InventoryFolderBase folder) - { - using (IDbCommand command = database.Query("UPDATE inventoryfolders set folderID = @folderID, " + - "agentID = @agentID, " + - "parentFolderID = @parentFolderID," + - "folderName = @folderName," + - "type = @type," + - "version = @version where " + - "folderID = @keyFolderID;")) - { - SqlParameter param1 = new SqlParameter("@folderID", folder.ID.ToString()); - SqlParameter param2 = new SqlParameter("@agentID", folder.Owner.ToString()); - SqlParameter param3 = new SqlParameter("@parentFolderID", folder.ParentID.ToString()); - SqlParameter param4 = new SqlParameter("@folderName", folder.Name); - SqlParameter param5 = new SqlParameter("@type", folder.Type); - SqlParameter param6 = new SqlParameter("@version", Convert.ToInt32(folder.Version)); - SqlParameter param7 = new SqlParameter("@keyFolderID", folder.ID.ToString()); - command.Parameters.Add(param1); - command.Parameters.Add(param2); - command.Parameters.Add(param3); - command.Parameters.Add(param4); - command.Parameters.Add(param5); - command.Parameters.Add(param6); - command.Parameters.Add(param7); - - try - { - command.ExecuteNonQuery(); - } - catch (Exception e) - { - m_log.Error(e.ToString()); - } - } - } - - /// - /// Updates an inventory folder - /// - /// Folder to update - public void moveInventoryFolder(InventoryFolderBase folder) - { - using (IDbCommand command = database.Query("UPDATE inventoryfolders set folderID = @folderID, " + - "parentFolderID = @parentFolderID," + - "folderID = @keyFolderID;")) - { - SqlParameter param1 = new SqlParameter("@folderID", folder.ID.ToString()); - SqlParameter param2 = new SqlParameter("@parentFolderID", folder.ParentID.ToString()); - SqlParameter param3 = new SqlParameter("@keyFolderID", folder.ID.ToString()); - command.Parameters.Add(param1); - command.Parameters.Add(param2); - command.Parameters.Add(param3); - - try - { - command.ExecuteNonQuery(); - } - catch (Exception e) - { - m_log.Error(e.ToString()); - } - } - } - - /// - /// Append a list of all the child folders of a parent folder - /// - /// list where folders will be appended - /// ID of parent - protected void getInventoryFolders(ref List folders, UUID parentID) - { - List subfolderList = getInventoryFolders(parentID); - - foreach (InventoryFolderBase f in subfolderList) - folders.Add(f); - } - - // See IInventoryDataPlugin - public List getFolderHierarchy(UUID parentID) - { - List folders = new List(); - getInventoryFolders(ref folders, parentID); - - for (int i = 0; i < folders.Count; i++) - getInventoryFolders(ref folders, folders[i].ID); - - return folders; + return null; } /// /// Delete a folder in inventory databasae /// /// the folder UUID - protected void deleteOneFolder(UUID folderID) + /// connection to database + private void DeleteOneFolder(UUID folderID, SqlConnection connection) { try { - Dictionary param = new Dictionary(); - param["folderID"] = folderID.ToString(); - - using (IDbCommand cmd = database.Query("DELETE FROM inventoryfolders WHERE folderID=@folderID", param)) + using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID", connection)) { - cmd.ExecuteNonQuery(); + command.Parameters.Add(database.CreateParameter("folderID", folderID)); + + command.ExecuteNonQuery(); } } catch (SqlException e) { - m_log.Error(e.ToString()); - } - } - - /// - /// Delete an item in inventory database - /// - /// the item ID - protected void deleteItemsInFolder(UUID folderID) - { - try - { - Dictionary param = new Dictionary(); - param["parentFolderID"] = folderID.ToString(); - - - using (IDbCommand cmd = - database.Query("DELETE FROM inventoryitems WHERE parentFolderID=@parentFolderID", param)) - { - cmd.ExecuteNonQuery(); - } - } - catch (SqlException e) - { - m_log.Error(e.ToString()); - } - } - - /// - /// Delete an inventory folder - /// - /// Id of folder to delete - public void deleteInventoryFolder(UUID folderID) - { - // lock (database) - { - List subFolders = getFolderHierarchy(folderID); - - //Delete all sub-folders - foreach (InventoryFolderBase f in subFolders) - { - deleteOneFolder(f.ID); - deleteItemsInFolder(f.ID); - } - - //Delete the actual row - deleteOneFolder(folderID); - deleteItemsInFolder(folderID); + m_log.Error("[INVENTORY DB] Error deleting folder :" + e.Message); } } + #endregion } } diff --git a/OpenSim/Data/MSSQL/MSSQLLogData.cs b/OpenSim/Data/MSSQL/MSSQLLogData.cs index b284c0209b..a617cea063 100644 --- a/OpenSim/Data/MSSQL/MSSQLLogData.cs +++ b/OpenSim/Data/MSSQL/MSSQLLogData.cs @@ -26,6 +26,7 @@ */ using System; +using System.Data.SqlClient; using System.Reflection; using System.Collections.Generic; using System.Data; @@ -39,6 +40,8 @@ namespace OpenSim.Data.MSSQL /// internal class MSSQLLogData : ILogDataPlugin { + private const string _migrationStore = "LogStore"; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// @@ -48,7 +51,7 @@ namespace OpenSim.Data.MSSQL public void Initialise() { - m_log.Info("[MSSQLLogData]: " + Name + " cannot be default-initialized!"); + m_log.Info("[LOG DB]: " + Name + " cannot be default-initialized!"); throw new PluginNotInitialisedException (Name); } @@ -57,18 +60,37 @@ namespace OpenSim.Data.MSSQL /// public void Initialise(string connect) { - // TODO: do something with the connect string - IniFile gridDataMSSqlFile = new IniFile("mssql_connection.ini"); - string settingDataSource = gridDataMSSqlFile.ParseFileReadValue("data_source"); - string settingInitialCatalog = gridDataMSSqlFile.ParseFileReadValue("initial_catalog"); - string settingPersistSecurityInfo = gridDataMSSqlFile.ParseFileReadValue("persist_security_info"); - string settingUserId = gridDataMSSqlFile.ParseFileReadValue("user_id"); - string settingPassword = gridDataMSSqlFile.ParseFileReadValue("password"); + if (string.IsNullOrEmpty(connect)) + { + database = new MSSQLManager(connect); + } + else + { + // TODO: do something with the connect string + IniFile gridDataMSSqlFile = new IniFile("mssql_connection.ini"); + string settingDataSource = gridDataMSSqlFile.ParseFileReadValue("data_source"); + string settingInitialCatalog = gridDataMSSqlFile.ParseFileReadValue("initial_catalog"); + string settingPersistSecurityInfo = gridDataMSSqlFile.ParseFileReadValue("persist_security_info"); + string settingUserId = gridDataMSSqlFile.ParseFileReadValue("user_id"); + string settingPassword = gridDataMSSqlFile.ParseFileReadValue("password"); - database = - new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, - settingPassword); + database = + new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, + settingPassword); + } + //TODO when can this be removed + TestTable(); + + //Updating mechanisme + database.CheckMigration(_migrationStore); + } + + /// + /// Can be removed someday!!! + /// + private void TestTable() + { using (IDbCommand cmd = database.Query("select top 1 * from logs", new Dictionary())) { try @@ -80,9 +102,38 @@ namespace OpenSim.Data.MSSQL database.ExecuteResourceSql("Mssql-logs.sql"); } } + using (AutoClosingSqlCommand cmd = database.Query("select * from migrations where name = '" + _migrationStore + "'")) + { + //Special for Migrations to create backword compatible + try + { + bool insert = true; + using (SqlDataReader reader = cmd.ExecuteReader()) + { + if (reader.Read()) insert = false; + } + if (insert) + { + cmd.CommandText = "insert into migrations(name, version) values('" + _migrationStore + "', 1)"; + cmd.ExecuteNonQuery(); + } + } + catch + { + //No migrations table + //HACK create one and add data + cmd.CommandText = "create table migrations(name varchar(100), version int)"; + cmd.ExecuteNonQuery(); + cmd.CommandText = "insert into migrations(name, version) values('migrations', 1)"; + cmd.ExecuteNonQuery(); + + cmd.CommandText = "insert into migrations(name, version) values('" + _migrationStore + "', 1)"; + cmd.ExecuteNonQuery(); + } + } } - + /// /// Saves a log item to the database /// @@ -95,13 +146,28 @@ namespace OpenSim.Data.MSSQL public void saveLog(string serverDaemon, string target, string methodCall, string arguments, int priority, string logMessage) { - try + string sql = "INSERT INTO logs ([target], [server], [method], [arguments], [priority], [message]) VALUES "; + sql += "(@target, @server, @method, @arguments, @priority, @message);"; + + using (AutoClosingSqlCommand command = database.Query(sql)) { - database.insertLogRow(serverDaemon, target, methodCall, arguments, priority, logMessage); - } - catch - { - // it didn't log, don't worry about it + command.Parameters.Add(database.CreateParameter("server", serverDaemon)); + command.Parameters.Add(database.CreateParameter("target",target)); + command.Parameters.Add(database.CreateParameter("method", methodCall)); + command.Parameters.Add(database.CreateParameter("arguments", arguments)); + command.Parameters.Add(database.CreateParameter("priority", priority.ToString())); + command.Parameters.Add(database.CreateParameter("message", logMessage)); + + try + { + command.ExecuteNonQuery(); + } + catch (Exception e) + { + //Are we not in a loop here + //m_log.Error(e.ToString()); + Console.WriteLine("[LOG DB] Error logging : " + e.Message); + } } } @@ -119,7 +185,7 @@ namespace OpenSim.Data.MSSQL /// public void Dispose() { - // Do nothing. + database = null; } /// diff --git a/OpenSim/Data/MSSQL/MSSQLManager.cs b/OpenSim/Data/MSSQL/MSSQLManager.cs index abbcddf51a..b3e9b6eea9 100644 --- a/OpenSim/Data/MSSQL/MSSQLManager.cs +++ b/OpenSim/Data/MSSQL/MSSQLManager.cs @@ -33,7 +33,6 @@ using System.IO; using System.Reflection; using OpenMetaverse; using log4net; -using OpenSim.Framework; namespace OpenSim.Data.MSSQL { @@ -83,49 +82,7 @@ namespace OpenSim.Data.MSSQL return conn; } - //private DataTable createRegionsTable() - //{ - // DataTable regions = new DataTable("regions"); - - // createCol(regions, "regionHandle", typeof (ulong)); - // createCol(regions, "regionName", typeof (String)); - // createCol(regions, "uuid", typeof (String)); - - // createCol(regions, "regionRecvKey", typeof (String)); - // createCol(regions, "regionSecret", typeof (String)); - // createCol(regions, "regionSendKey", typeof (String)); - - // createCol(regions, "regionDataURI", typeof (String)); - // createCol(regions, "serverIP", typeof (String)); - // createCol(regions, "serverPort", typeof (String)); - // createCol(regions, "serverURI", typeof (String)); - - - // createCol(regions, "locX", typeof (uint)); - // createCol(regions, "locY", typeof (uint)); - // createCol(regions, "locZ", typeof (uint)); - - // createCol(regions, "eastOverrideHandle", typeof (ulong)); - // createCol(regions, "westOverrideHandle", typeof (ulong)); - // createCol(regions, "southOverrideHandle", typeof (ulong)); - // createCol(regions, "northOverrideHandle", typeof (ulong)); - - // createCol(regions, "regionAssetURI", typeof (String)); - // createCol(regions, "regionAssetRecvKey", typeof (String)); - // createCol(regions, "regionAssetSendKey", typeof (String)); - - // createCol(regions, "regionUserURI", typeof (String)); - // createCol(regions, "regionUserRecvKey", typeof (String)); - // createCol(regions, "regionUserSendKey", typeof (String)); - - // createCol(regions, "regionMapTexture", typeof (String)); - // createCol(regions, "serverHttpPort", typeof (String)); - // createCol(regions, "serverRemotingPort", typeof (uint)); - - // // Add in contraints - // regions.PrimaryKey = new DataColumn[] {regions.Columns["UUID"]}; - // return regions; - //} + #region Obsolete functions, can be removed! /// /// @@ -133,6 +90,7 @@ namespace OpenSim.Data.MSSQL /// /// /// + [Obsolete("Do not use!")] protected static void createCol(DataTable dt, string name, Type type) { DataColumn col = new DataColumn(name, type); @@ -144,6 +102,7 @@ namespace OpenSim.Data.MSSQL /// /// /// + [Obsolete("Do not use!")] protected static string defineTable(DataTable dt) { string sql = "create table " + dt.TableName + "("; @@ -167,34 +126,34 @@ namespace OpenSim.Data.MSSQL return sql; } + #endregion + /// /// Type conversion function /// /// a type /// a sqltype /// this is something we'll need to implement for each db slightly differently. + [Obsolete("Used by a obsolete methods")] public static string SqlType(Type type) { if (type == typeof(String)) { return "varchar(255)"; } - else if (type == typeof(Int32)) + if (type == typeof(Int32)) { return "integer"; } - else if (type == typeof(Double)) + if (type == typeof(Double)) { return "float"; } - else if (type == typeof(Byte[])) + if (type == typeof(Byte[])) { return "image"; } - else - { - return "varchar(255)"; - } + return "varchar(255)"; } /// @@ -224,14 +183,22 @@ namespace OpenSim.Data.MSSQL { return SqlDbType.VarChar; } + if (type == typeof(sbyte)) + { + return SqlDbType.TinyInt; + } if (type == typeof(Byte[])) { return SqlDbType.Image; } - if (type == typeof(uint)) + if (type == typeof(uint) || type == typeof(ushort)) { return SqlDbType.Int; } + if (type == typeof(ulong)) + { + return SqlDbType.BigInt; + } return SqlDbType.VarChar; } @@ -282,6 +249,9 @@ namespace OpenSim.Data.MSSQL //Tweak so we dont always have to add @ sign if (!parameterName.StartsWith("@")) parameterName = "@" + parameterName; + //HACK if object is null, it is turned into a string, there are no nullable type till now + if (parameterObject == null) parameterObject = ""; + SqlParameter parameter = new SqlParameter(parameterName, DbtypeFromType(parameterObject.GetType())); if (parameterOut) @@ -298,6 +268,7 @@ namespace OpenSim.Data.MSSQL } private static readonly Dictionary emptyDictionary = new Dictionary(); + internal AutoClosingSqlCommand Query(string sql) { return Query(sql, emptyDictionary); @@ -322,252 +293,51 @@ namespace OpenSim.Data.MSSQL } /// - /// Runs a database reader object and returns a region row + /// Runs a query with protection against SQL Injection by using parameterised input. /// - /// An active database reader - /// A region row - public RegionProfileData getRegionRow(IDataReader reader) - { - RegionProfileData regionprofile = new RegionProfileData(); - - if (reader.Read()) - { - // Region Main - regionprofile.regionHandle = Convert.ToUInt64(reader["regionHandle"]); - regionprofile.regionName = (string)reader["regionName"]; - regionprofile.UUID = new UUID((string)reader["uuid"]); - - // Secrets - regionprofile.regionRecvKey = (string)reader["regionRecvKey"]; - regionprofile.regionSecret = (string)reader["regionSecret"]; - regionprofile.regionSendKey = (string)reader["regionSendKey"]; - - // Region Server - regionprofile.regionDataURI = (string)reader["regionDataURI"]; - regionprofile.regionOnline = false; // Needs to be pinged before this can be set. - regionprofile.serverIP = (string)reader["serverIP"]; - regionprofile.serverPort = Convert.ToUInt32(reader["serverPort"]); - regionprofile.serverURI = (string)reader["serverURI"]; - regionprofile.httpPort = Convert.ToUInt32(reader["serverHttpPort"]); - regionprofile.remotingPort = Convert.ToUInt32(reader["serverRemotingPort"]); - - - // Location - regionprofile.regionLocX = Convert.ToUInt32(reader["locX"]); - regionprofile.regionLocY = Convert.ToUInt32(reader["locY"]); - regionprofile.regionLocZ = Convert.ToUInt32(reader["locZ"]); - - // Neighbours - 0 = No Override - regionprofile.regionEastOverrideHandle = Convert.ToUInt64(reader["eastOverrideHandle"]); - regionprofile.regionWestOverrideHandle = Convert.ToUInt64(reader["westOverrideHandle"]); - regionprofile.regionSouthOverrideHandle = Convert.ToUInt64(reader["southOverrideHandle"]); - regionprofile.regionNorthOverrideHandle = Convert.ToUInt64(reader["northOverrideHandle"]); - - // Assets - regionprofile.regionAssetURI = (string)reader["regionAssetURI"]; - regionprofile.regionAssetRecvKey = (string)reader["regionAssetRecvKey"]; - regionprofile.regionAssetSendKey = (string)reader["regionAssetSendKey"]; - - // Userserver - regionprofile.regionUserURI = (string)reader["regionUserURI"]; - regionprofile.regionUserRecvKey = (string)reader["regionUserRecvKey"]; - regionprofile.regionUserSendKey = (string)reader["regionUserSendKey"]; - regionprofile.owner_uuid = new UUID((string) reader["owner_uuid"]); - // World Map Addition - string tempRegionMap = reader["regionMapTexture"].ToString(); - if (tempRegionMap != String.Empty) - { - regionprofile.regionMapTextureID = new UUID(tempRegionMap); - } - else - { - regionprofile.regionMapTextureID = new UUID(); - } - } - else - { - reader.Close(); - throw new Exception("No rows to return"); - } - return regionprofile; - } - - /// - /// Reads a user profile from an active data reader - /// - /// An active database reader - /// A user profile - public UserProfileData readUserRow(IDataReader reader) - { - UserProfileData retval = new UserProfileData(); - - if (reader.Read()) - { - retval.ID = new UUID((string)reader["UUID"]); - retval.FirstName = (string)reader["username"]; - retval.SurName = (string)reader["lastname"]; - - retval.PasswordHash = (string)reader["passwordHash"]; - retval.PasswordSalt = (string)reader["passwordSalt"]; - - retval.HomeRegion = Convert.ToUInt64(reader["homeRegion"].ToString()); - retval.HomeLocation = new Vector3( - Convert.ToSingle(reader["homeLocationX"].ToString()), - Convert.ToSingle(reader["homeLocationY"].ToString()), - Convert.ToSingle(reader["homeLocationZ"].ToString())); - retval.HomeLookAt = new Vector3( - Convert.ToSingle(reader["homeLookAtX"].ToString()), - Convert.ToSingle(reader["homeLookAtY"].ToString()), - Convert.ToSingle(reader["homeLookAtZ"].ToString())); - - retval.Created = Convert.ToInt32(reader["created"].ToString()); - retval.LastLogin = Convert.ToInt32(reader["lastLogin"].ToString()); - - retval.UserInventoryURI = (string)reader["userInventoryURI"]; - retval.UserAssetURI = (string)reader["userAssetURI"]; - - retval.CanDoMask = Convert.ToUInt32(reader["profileCanDoMask"].ToString()); - retval.WantDoMask = Convert.ToUInt32(reader["profileWantDoMask"].ToString()); - - retval.AboutText = (string)reader["profileAboutText"]; - retval.FirstLifeAboutText = (string)reader["profileFirstText"]; - - retval.Image = new UUID((string)reader["profileImage"]); - retval.FirstLifeImage = new UUID((string)reader["profileFirstImage"]); - retval.WebLoginKey = new UUID((string)reader["webLoginKey"]); - } - else - { - return null; - } - return retval; - } - - /// - /// Reads an agent row from a database reader - /// - /// An active database reader - /// A user session agent - public UserAgentData readAgentRow(IDataReader reader) - { - UserAgentData retval = new UserAgentData(); - - if (reader.Read()) - { - // Agent IDs - retval.ProfileID = new UUID((string)reader["UUID"]); - retval.SessionID = new UUID((string)reader["sessionID"]); - retval.SecureSessionID = new UUID((string)reader["secureSessionID"]); - - // Agent Who? - retval.AgentIP = (string)reader["agentIP"]; - retval.AgentPort = Convert.ToUInt32(reader["agentPort"].ToString()); - retval.AgentOnline = Convert.ToInt32(reader["agentOnline"].ToString()) != 0; - - // Login/Logout times (UNIX Epoch) - retval.LoginTime = Convert.ToInt32(reader["loginTime"].ToString()); - retval.LogoutTime = Convert.ToInt32(reader["logoutTime"].ToString()); - - // Current position - retval.Region = (string)reader["currentRegion"]; - retval.Handle = Convert.ToUInt64(reader["currentHandle"].ToString()); - Vector3 tmp_v; - Vector3.TryParse((string)reader["currentPos"], out tmp_v); - retval.Position = tmp_v; - - } - else - { - return null; - } - return retval; - } - - /// - /// - /// - /// + /// The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y + /// A parameter - use createparameter to create parameter /// - public AssetBase getAssetRow(IDataReader reader) + internal AutoClosingSqlCommand Query(string sql, SqlParameter sqlParameter) { - AssetBase asset = new AssetBase(); - if (reader.Read()) - { - // Region Main - asset = new AssetBase(); - asset.Data = (byte[])reader["data"]; - asset.Description = (string)reader["description"]; - asset.FullID = new UUID((string)reader["id"]); - asset.Local = Convert.ToBoolean(reader["local"]); // ((sbyte)reader["local"]) != 0 ? true : false; - asset.Name = (string)reader["name"]; - asset.Type = Convert.ToSByte(reader["assetType"]); - } - else - { - return null; // throw new Exception("No rows to return"); - } - return asset; - } + SqlCommand dbcommand = DatabaseConnection().CreateCommand(); + dbcommand.CommandText = sql; + dbcommand.Parameters.Add(sqlParameter); + return new AutoClosingSqlCommand(dbcommand); + } /// - /// Inserts a new row into the log database + /// Checks if we need to do some migrations to the database /// - /// The daemon which triggered this event - /// Who were we operating on when this occured (region UUID, user UUID, etc) - /// The method call where the problem occured - /// The arguments passed to the method - /// How critical is this? - /// Extra message info - /// Saved successfully? - public bool insertLogRow(string serverDaemon, string target, string methodCall, string arguments, int priority, - string logMessage) + /// migrationStore. + public void CheckMigration(string migrationStore) { - string sql = "INSERT INTO logs ([target], [server], [method], [arguments], [priority], [message]) VALUES "; - sql += "(@target, @server, @method, @arguments, @priority, @message);"; - - Dictionary parameters = new Dictionary(); - parameters["server"] = serverDaemon; - parameters["target"] = target; - parameters["method"] = methodCall; - parameters["arguments"] = arguments; - parameters["priority"] = priority.ToString(); - parameters["message"] = logMessage; - - bool returnval = false; - - using (IDbCommand result = Query(sql, parameters)) + using (SqlConnection connection = DatabaseConnection()) { - try - { + Assembly assem = GetType().Assembly; + MSSQLMigration migration = new MSSQLMigration(connection, assem, migrationStore); - if (result.ExecuteNonQuery() == 1) - returnval = true; + migration.Update(); - } - catch (Exception e) - { - m_log.Error(e.ToString()); - return false; - } + connection.Close(); } - - return returnval; } + #region Old Testtable functions + /// /// Execute a SQL statement stored in a resource, as a string /// /// the ressource string public void ExecuteResourceSql(string name) { - using (IDbCommand cmd = Query(getResourceString(name), new Dictionary())) + using (IDbCommand cmd = Query(getResourceString(name), new Dictionary())) { cmd.ExecuteNonQuery(); } } - /// /// Given a list of tables, return the version of the tables, as seen in the database /// @@ -622,6 +392,8 @@ namespace OpenSim.Data.MSSQL throw new Exception(string.Format("Resource '{0}' was not found", name)); } + #endregion + /// /// Returns the version of this DB provider /// @@ -636,63 +408,5 @@ namespace OpenSim.Data.MSSQL string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build, dllVersion.Revision); } - - public bool insertAgentRow(UserAgentData agentdata) - { - string sql = @" - -IF EXISTS (SELECT * FROM agents WHERE UUID = @UUID) - BEGIN - UPDATE agents SET UUID = @UUID, sessionID = @sessionID, secureSessionID = @secureSessionID, agentIP = @agentIP, agentPort = @agentPort, agentOnline = @agentOnline, loginTime = @loginTime, logoutTime = @logoutTime, currentRegion = @currentRegion, currentHandle = @currentHandle, currentPos = @currentPos - WHERE UUID = @UUID - END -ELSE - BEGIN - INSERT INTO - agents (UUID, sessionID, secureSessionID, agentIP, agentPort, agentOnline, loginTime, logoutTime, currentRegion, currentHandle, currentPos) VALUES - (@UUID, @sessionID, @secureSessionID, @agentIP, @agentPort, @agentOnline, @loginTime, @logoutTime, @currentRegion, @currentHandle, @currentPos) - END -"; - - Dictionary parameters = new Dictionary(); - - parameters["@UUID"] = agentdata.ProfileID.ToString(); - parameters["@sessionID"] = agentdata.SessionID.ToString(); - parameters["@secureSessionID"] = agentdata.SecureSessionID.ToString(); - parameters["@agentIP"] = agentdata.AgentIP.ToString(); - parameters["@agentPort"] = agentdata.AgentPort.ToString(); - parameters["@agentOnline"] = (agentdata.AgentOnline == true) ? "1" : "0"; - parameters["@loginTime"] = agentdata.LoginTime.ToString(); - parameters["@logoutTime"] = agentdata.LogoutTime.ToString(); - parameters["@currentRegion"] = agentdata.Region.ToString(); - parameters["@currentHandle"] = agentdata.Handle.ToString(); - parameters["@currentPos"] = "<" + ((int)agentdata.Position.X).ToString() + "," + ((int)agentdata.Position.Y).ToString() + "," + ((int)agentdata.Position.Z).ToString() + ">"; - - - using (IDbCommand result = Query(sql, parameters)) - { - result.Transaction = result.Connection.BeginTransaction(IsolationLevel.Serializable); - try - { - if (result.ExecuteNonQuery() > 0) - { - result.Transaction.Commit(); - return true; - } - else - { - result.Transaction.Rollback(); - return false; - } - } - catch (Exception e) - { - result.Transaction.Rollback(); - m_log.Error(e.ToString()); - return false; - } - } - - } } } diff --git a/OpenSim/Data/MSSQL/MSSQLRegionData.cs b/OpenSim/Data/MSSQL/MSSQLRegionData.cs index b942f00d54..8b808d311c 100644 --- a/OpenSim/Data/MSSQL/MSSQLRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLRegionData.cs @@ -44,14 +44,19 @@ namespace OpenSim.Data.MSSQL /// public class MSSQLRegionDataStore : IRegionDataStore { + private const string _migrationStore = "RegionStore"; + // private static FileSystemDataStore Instance = new FileSystemDataStore(); private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + /// + /// The database manager + /// private MSSQLManager _Database; -// private const string _PrimSelect = "SELECT * FROM PRIMS WHERE RegionUUID = @RegionUUID AND (SceneGroupID LIKE @SceneGroupID OR UUID = @UUID)"; -// private const string _ShapeSelect = "SELECT * FROM PRIMSHAPES WHERE UUID in (SELECT UUID FROM PRIMS WHERE RegionUUID = @RegionUUID AND (SceneGroupID LIKE @SceneGroupID OR UUID = @UUID))"; -// private const string _ItemsSelect = "SELECT * FROM PRIMITEMS WHERE primID in (SELECT UUID FROM PRIMS WHERE RegionUUID = @RegionUUID AND (SceneGroupID LIKE @SceneGroupID OR UUID = @UUID))"; + /// + /// Const for the prim store.. + /// private const string _PrimSelect = "SELECT * FROM PRIMS WHERE RegionUUID = @RegionUUID AND (SceneGroupID LIKE @SceneGroupID OR UUID IN (@UUID))"; private const string _ShapeSelect = "SELECT * FROM PRIMSHAPES WHERE UUID in (SELECT UUID FROM PRIMS WHERE RegionUUID = @RegionUUID AND (SceneGroupID LIKE @SceneGroupID OR UUID IN (@UUID)))"; private const string _ItemsSelect = "SELECT * FROM PRIMITEMS WHERE primID in (SELECT UUID FROM PRIMS WHERE RegionUUID = @RegionUUID AND (SceneGroupID LIKE @SceneGroupID OR UUID IN (@UUID)))"; @@ -81,31 +86,14 @@ namespace OpenSim.Data.MSSQL string settingUserId = iniFile.ParseFileReadValue("user_id"); string settingPassword = iniFile.ParseFileReadValue("password"); - _Database = - new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, - settingPassword); - - - SqlConnectionStringBuilder conBuilder = new SqlConnectionStringBuilder(); - conBuilder.DataSource = settingDataSource; - conBuilder.InitialCatalog = settingInitialCatalog; - conBuilder.PersistSecurityInfo = Convert.ToBoolean(settingPersistSecurityInfo); - conBuilder.UserID = settingUserId; - conBuilder.Password = settingPassword; - conBuilder.ApplicationName = Assembly.GetEntryAssembly().Location; - - connectionString = conBuilder.ToString(); + _Database = new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, settingPassword); } //Migration settings - Assembly assem = GetType().Assembly; + _Database.CheckMigration(_migrationStore); using (SqlConnection connection = _Database.DatabaseConnection()) { - MSSQLMigration m = new MSSQLMigration(connection, assem, "RegionStore"); - - m.Update(); - //Create Dataset. Not filled!!! _PrimsDataSet = new DataSet("primsdata"); @@ -243,7 +231,7 @@ namespace OpenSim.Data.MSSQL catch (Exception e) { _Log.Error("[REGION DB]: Failed create prim object, exception and data follows"); - _Log.Info("[REGION DB]: " + e.ToString()); + _Log.Info("[REGION DB]: " + e.Message); foreach (DataColumn col in prims.Columns) { _Log.Info("[REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]); @@ -259,71 +247,76 @@ namespace OpenSim.Data.MSSQL #region Experimental -// -// //Get all prims -// string sql = "select * from prims where RegionUUID = @RegionUUID"; -// -// using (AutoClosingSqlCommand cmdPrims = _Database.Query(sql)) -// { -// cmdPrims.Parameters.AddWithValue("@RegionUUID", regionUUID.ToString()); -// using (SqlDataReader readerPrims = cmdPrims.ExecuteReader()) -// { -// while (readerPrims.Read()) -// { -// string uuid = (string)readerPrims["UUID"]; -// string objID = (string)readerPrims["SceneGroupID"]; -// SceneObjectPart prim = buildPrim(readerPrims); -// -// //Setting default shape, will change shape ltr -// prim.Shape = PrimitiveBaseShape.Default; -// -// //Load inventory items of prim -// //LoadItems(prim); -// -// if (uuid == objID) -// { -// SceneObjectGroup group = new SceneObjectGroup(); -// -// group.AddPart(prim); -// group.RootPart = prim; -// -// createdObjects.Add(group.UUID, group); -// retvals.Add(group); -// } -// else -// { -// createdObjects[new UUID(objID)].AddPart(prim); -// } -// } -// } -// } -// m_log.Info("[REGION DB]: Loaded " + retvals.Count + " prim objects for region: " + regionUUID); -// -// //Find all shapes related with prims -// sql = "select * from primshapes"; -// using (AutoClosingSqlCommand cmdShapes = _Database.Query(sql)) -// { -// using (SqlDataReader readerShapes = cmdShapes.ExecuteReader()) -// { -// while (readerShapes.Read()) -// { -// UUID UUID = new UUID((string) readerShapes["UUID"]); -// -// foreach (SceneObjectGroup objectGroup in createdObjects.Values) -// { -// if (objectGroup.Children.ContainsKey(UUID)) -// { -// objectGroup.Children[UUID].Shape = buildShape(readerShapes); -// } -// } -// } -// } -// } -// return retvals; + // + // //Get all prims + // string sql = "select * from prims where RegionUUID = @RegionUUID"; + // + // using (AutoClosingSqlCommand cmdPrims = _Database.Query(sql)) + // { + // cmdPrims.Parameters.AddWithValue("@RegionUUID", regionUUID.ToString()); + // using (SqlDataReader readerPrims = cmdPrims.ExecuteReader()) + // { + // while (readerPrims.Read()) + // { + // string uuid = (string)readerPrims["UUID"]; + // string objID = (string)readerPrims["SceneGroupID"]; + // SceneObjectPart prim = buildPrim(readerPrims); + // + // //Setting default shape, will change shape ltr + // prim.Shape = PrimitiveBaseShape.Default; + // + // //Load inventory items of prim + // //LoadItems(prim); + // + // if (uuid == objID) + // { + // SceneObjectGroup group = new SceneObjectGroup(); + // + // group.AddPart(prim); + // group.RootPart = prim; + // + // createdObjects.Add(group.UUID, group); + // retvals.Add(group); + // } + // else + // { + // createdObjects[new UUID(objID)].AddPart(prim); + // } + // } + // } + // } + // m_log.Info("[REGION DB]: Loaded " + retvals.Count + " prim objects for region: " + regionUUID); + // + // //Find all shapes related with prims + // sql = "select * from primshapes"; + // using (AutoClosingSqlCommand cmdShapes = _Database.Query(sql)) + // { + // using (SqlDataReader readerShapes = cmdShapes.ExecuteReader()) + // { + // while (readerShapes.Read()) + // { + // UUID UUID = new UUID((string) readerShapes["UUID"]); + // + // foreach (SceneObjectGroup objectGroup in createdObjects.Values) + // { + // if (objectGroup.Children.ContainsKey(UUID)) + // { + // objectGroup.Children[UUID].Shape = buildShape(readerShapes); + // } + // } + // } + // } + // } + // return retvals; #endregion } + /// + /// Stores all object's details apart from inventory + /// + /// + /// public void StoreObject(SceneObjectGroup obj, UUID regionUUID) { //Retrieve all values of current region, and current scene/or prims @@ -375,10 +368,6 @@ namespace OpenSim.Data.MSSQL } } } - else - { - // m_log.Info("[DATASTORE]: Ignoring Physical obj: " + obj.UUID + " in region: " + regionUUID); - } } //Save changes @@ -430,7 +419,7 @@ namespace OpenSim.Data.MSSQL //TODO add index on PrimID in DB, if not already exist using (AutoClosingSqlCommand cmd = _Database.Query("DELETE PRIMITEMS WHERE primID = @primID")) { - cmd.Parameters.AddWithValue("@primID", primID.ToString()); + cmd.Parameters.Add(_Database.CreateParameter("@primID", primID)); cmd.ExecuteNonQuery(); } @@ -470,7 +459,7 @@ namespace OpenSim.Data.MSSQL using (SqlDataReader reader = cmd.ExecuteReader()) { - int rev = 0; + int rev; if (reader.Read()) { MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]); @@ -509,22 +498,21 @@ namespace OpenSim.Data.MSSQL string sql = "delete from terrain where RegionUUID=@RegionUUID"; using (AutoClosingSqlCommand cmd = _Database.Query(sql)) { - cmd.Parameters.AddWithValue("@RegionUUID", regionID.ToString()); + cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); cmd.ExecuteNonQuery(); } - sql = "insert into terrain(RegionUUID, Revision, Heightfield)" + - " values(@RegionUUID, @Revision, @Heightfield)"; + sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)"; using (AutoClosingSqlCommand cmd = _Database.Query(sql)) { - cmd.Parameters.AddWithValue("@RegionUUID", regionID.ToString()); - cmd.Parameters.AddWithValue("@Revision", revision); - cmd.Parameters.AddWithValue("@Heightfield", serializeTerrain(terrain)); + cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); + cmd.Parameters.Add(_Database.CreateParameter("@Revision", revision)); + cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", serializeTerrain(terrain))); cmd.ExecuteNonQuery(); } - _Log.Info("[REGION DB]: Stored terrain revision r" + revision); + _Log.Info("[REGION DB]: Stored terrain revision r " + revision); } /// @@ -541,12 +529,13 @@ namespace OpenSim.Data.MSSQL //Retrieve all land data from region using (AutoClosingSqlCommand cmdLandData = _Database.Query(sql)) { - cmdLandData.Parameters.AddWithValue("@RegionUUID", regionUUID.ToString()); + cmdLandData.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionUUID)); using (SqlDataReader readerLandData = cmdLandData.ExecuteReader()) { while (readerLandData.Read()) { + // LandData data = buildLandData(readerLandData); landDataForRegion.Add(buildLandData(readerLandData)); } } @@ -558,7 +547,7 @@ namespace OpenSim.Data.MSSQL sql = "select * from landaccesslist where LandUUID = @LandUUID"; using (AutoClosingSqlCommand cmdAccessList = _Database.Query(sql)) { - cmdAccessList.Parameters.AddWithValue("@LandUUID", landData.GlobalID.ToString()); + cmdAccessList.Parameters.Add(_Database.CreateParameter("@LandUUID", landData.GlobalID)); using (SqlDataReader readerAccessList = cmdAccessList.ExecuteReader()) { while (readerAccessList.Read()) @@ -643,7 +632,7 @@ VALUES RegionSettings regionSettings; using (AutoClosingSqlCommand cmd = _Database.Query(sql)) { - cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID.ToString())); + cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID)); using (SqlDataReader reader = cmd.ExecuteReader()) { if (reader.Read()) @@ -674,7 +663,7 @@ VALUES public void StoreRegionSettings(RegionSettings regionSettings) { //Little check if regionUUID already exist in DB - string regionUUID = null; + string regionUUID; using (AutoClosingSqlCommand cmd = _Database.Query("SELECT regionUUID FROM regionsettings WHERE regionUUID = @regionUUID")) { cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionSettings.RegionUUID)); @@ -724,7 +713,7 @@ VALUES { DataTable dbItems = _PrimsDataSet.Tables["primitems"]; - String sql = String.Format("primID = '{0}'", prim.UUID.ToString()); + String sql = String.Format("primID = '{0}'", prim.UUID); DataRow[] dbItemRows = dbItems.Select(sql); IList inventory = new List(); @@ -1446,6 +1435,12 @@ VALUES #endregion + /// + /// Retrieves the prims data for region. + /// + /// The region UUID. + /// The scene group ID. + /// The prim ID. private void RetrievePrimsDataForRegion(UUID regionUUID, UUID sceneGroupID, string primID) { using (SqlConnection connection = _Database.DatabaseConnection()) @@ -1482,6 +1477,9 @@ VALUES } } + /// + /// Commits the dataset. + /// private void CommitDataSet() { lock (_PrimsDataSet) @@ -1513,6 +1511,10 @@ VALUES } } + /// + /// Create commands for a dataadapter. + /// + /// The data adapter. private static void SetupCommands(SqlDataAdapter dataAdapter) { SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter); diff --git a/OpenSim/Data/MSSQL/MSSQLUserData.cs b/OpenSim/Data/MSSQL/MSSQLUserData.cs index 91180126d9..6352cce361 100644 --- a/OpenSim/Data/MSSQL/MSSQLUserData.cs +++ b/OpenSim/Data/MSSQL/MSSQLUserData.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; @@ -41,6 +42,8 @@ namespace OpenSim.Data.MSSQL /// public class MSSQLUserData : UserDataBase { + private const string _migrationStore = "UserStore"; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// @@ -52,28 +55,35 @@ namespace OpenSim.Data.MSSQL private string m_usersTableName; private string m_userFriendsTableName; - public override void Initialise() + override public void Initialise() { m_log.Info("[MSSQLUserData]: " + Name + " cannot be default-initialized!"); - throw new PluginNotInitialisedException (Name); + throw new PluginNotInitialisedException(Name); } /// /// Loads and initialises the MSSQL storage plugin /// - /// TODO: do something with the connect string instead of ignoring it. + /// connectionstring /// use mssql_connection.ini override public void Initialise(string connect) { - // TODO: do something with the connect string instead of - // ignoring it. - IniFile iniFile = new IniFile("mssql_connection.ini"); - string settingDataSource = iniFile.ParseFileReadValue("data_source"); - string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog"); - string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info"); - string settingUserId = iniFile.ParseFileReadValue("user_id"); - string settingPassword = iniFile.ParseFileReadValue("password"); + + if (string.IsNullOrEmpty(connect)) + { + database = new MSSQLManager(connect); + } + else + { + string settingDataSource = iniFile.ParseFileReadValue("data_source"); + string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog"); + string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info"); + string settingUserId = iniFile.ParseFileReadValue("user_id"); + string settingPassword = iniFile.ParseFileReadValue("password"); + + database = new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, settingPassword); + } m_usersTableName = iniFile.ParseFileReadValue("userstablename"); if (m_usersTableName == null) @@ -93,23 +103,22 @@ namespace OpenSim.Data.MSSQL m_agentsTableName = "agents"; } - database = - new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, - settingPassword); - + //TODO this can be removed at one time!!!!! TestTables(); + + //Check migration on DB + database.CheckMigration(_migrationStore); } - public override void Dispose () {} + override public void Dispose() { } /// - /// + /// Can be deleted at one time! /// /// - private bool TestTables() + private void TestTables() { - - using (IDbCommand cmd = database.Query("select top 1 * from " + m_usersTableName, new Dictionary())) + using (IDbCommand cmd = database.Query("select top 1 * from " + m_usersTableName)) { try { @@ -145,9 +154,53 @@ namespace OpenSim.Data.MSSQL } } - return true; + using (IDbCommand cmd = database.Query("select top 1 * from avatarappearance", new Dictionary())) + { + try + { + cmd.ExecuteNonQuery(); + } + catch + { + database.ExecuteResourceSql("AvatarAppearance.sql"); + } + } + + //Special for Migrations + using (AutoClosingSqlCommand cmd = database.Query("select * from migrations where name = 'UserStore'")) + { + try + { + bool insert = true; + using (SqlDataReader reader = cmd.ExecuteReader()) + { + if (reader.Read()) insert = false; + } + if (insert) + { + cmd.CommandText = "insert into migrations(name, version) values('UserStore', 1)"; + cmd.ExecuteNonQuery(); + } + } + catch + { + //No migrations table + //HACK create one and add data + cmd.CommandText = "create table migrations(name varchar(100), version int)"; + cmd.ExecuteNonQuery(); + + cmd.CommandText = "insert into migrations(name, version) values('migrations', 1)"; + cmd.ExecuteNonQuery(); + + cmd.CommandText = "insert into migrations(name, version) values('UserStore', 1)"; + cmd.ExecuteNonQuery(); + } + } + return; } + #region User table methods + /// /// Searches the database for a specified user profile by name components /// @@ -156,263 +209,24 @@ namespace OpenSim.Data.MSSQL /// A user profile override public UserProfileData GetUserByName(string user, string last) { - try + using (AutoClosingSqlCommand command = database.Query("SELECT * FROM " + m_usersTableName + " WHERE username = @first AND lastname = @second")) { - Dictionary param = new Dictionary(); - param["first"] = user; - param["second"] = last; + command.Parameters.Add(database.CreateParameter("first", user)); + command.Parameters.Add(database.CreateParameter("second", last)); - using (IDbCommand result = database.Query("SELECT * FROM " + m_usersTableName + " WHERE username = @first AND lastname = @second", param)) - using (IDataReader reader = result.ExecuteReader()) - { - return database.readUserRow(reader); - } - } - catch (Exception e) - { - m_log.Error(e.ToString()); - return null; - } - } - - #region User Friends List Data - - /// - /// Add a new friend in the friendlist - /// - /// UUID of the friendlist owner - /// Friend's UUID - /// Permission flag - override public void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms) - { - int dtvalue = Util.UnixTimeSinceEpoch(); - - Dictionary param = new Dictionary(); - param["@ownerID"] = friendlistowner.ToString(); - param["@friendID"] = friend.ToString(); - param["@friendPerms"] = perms.ToString(); - param["@datetimestamp"] = dtvalue.ToString(); - - try - { - using (IDbCommand adder = - database.Query( - "INSERT INTO " + m_userFriendsTableName + " " + - "(ownerID,friendID,friendPerms,datetimestamp) " + - "VALUES " + - "(@ownerID,@friendID,@friendPerms,@datetimestamp)", - param)) - { - adder.ExecuteNonQuery(); - } - - using (IDbCommand adder = - database.Query( - "INSERT INTO " + m_userFriendsTableName + " " + - "(ownerID,friendID,friendPerms,datetimestamp) " + - "VALUES " + - "(@friendID,@ownerID,@friendPerms,@datetimestamp)", - param)) - { - adder.ExecuteNonQuery(); - } - } - catch (Exception e) - { - m_log.Error(e.ToString()); - return; - } - } - - /// - /// Remove an friend from the friendlist - /// - /// UUID of the friendlist owner - /// UUID of the not-so-friendly user to remove from the list - override public void RemoveUserFriend(UUID friendlistowner, UUID friend) - { - Dictionary param = new Dictionary(); - param["@ownerID"] = friendlistowner.ToString(); - param["@friendID"] = friend.ToString(); - - - try - { - using (IDbCommand updater = - database.Query( - "delete from " + m_userFriendsTableName + " where ownerID = @ownerID and friendID = @friendID", - param)) - { - updater.ExecuteNonQuery(); - } - - using (IDbCommand updater = - database.Query( - "delete from " + m_userFriendsTableName + " where ownerID = @friendID and friendID = @ownerID", - param)) - { - updater.ExecuteNonQuery(); - } - - } - catch (Exception e) - { - m_log.Error(e.ToString()); - } - } - - /// - /// Update friendlist permission flag for a friend - /// - /// UUID of the friendlist owner - /// UUID of the friend - /// new permission flag - override public void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms) - { - Dictionary param = new Dictionary(); - param["@ownerID"] = friendlistowner.ToString(); - param["@friendID"] = friend.ToString(); - param["@friendPerms"] = perms.ToString(); - - - try - { - using (IDbCommand updater = - database.Query( - "update " + m_userFriendsTableName + - " SET friendPerms = @friendPerms " + - "where ownerID = @ownerID and friendID = @friendID", - param)) - { - updater.ExecuteNonQuery(); - } - } - catch (Exception e) - { - m_log.Error(e.ToString()); - } - } - - /// - /// Get (fetch?) the user's friendlist - /// - /// UUID of the friendlist owner - /// Friendlist list - override public List GetUserFriendList(UUID friendlistowner) - { - List Lfli = new List(); - - Dictionary param = new Dictionary(); - param["@ownerID"] = friendlistowner.ToString(); - - try - { - //Left Join userfriends to itself - using (IDbCommand result = - database.Query( - "select a.ownerID,a.friendID,a.friendPerms,b.friendPerms as ownerperms from " + m_userFriendsTableName + " as a, " + m_userFriendsTableName + " as b" + - " where a.ownerID = @ownerID and b.ownerID = a.friendID and b.friendID = a.ownerID", - param)) - using (IDataReader reader = result.ExecuteReader()) - { - while (reader.Read()) - { - FriendListItem fli = new FriendListItem(); - fli.FriendListOwner = new UUID((string)reader["ownerID"]); - fli.Friend = new UUID((string)reader["friendID"]); - fli.FriendPerms = (uint)Convert.ToInt32(reader["friendPerms"]); - - // This is not a real column in the database table, it's a joined column from the opposite record - fli.FriendListOwnerPerms = (uint)Convert.ToInt32(reader["ownerperms"]); - - Lfli.Add(fli); - } - } - } - catch (Exception e) - { - m_log.Error(e.ToString()); - } - - return Lfli; - } - - #endregion - - /// - /// STUB ! Update current region - /// - /// avatar uuid - /// region uuid - /// region handle - override public void UpdateUserCurrentRegion(UUID avatarid, UUID regionuuid, ulong regionhandle) - { - //m_log.Info("[USER]: Stub UpdateUserCUrrentRegion called"); - } - - /// - /// - /// - /// - /// - /// - override public List GeneratePickerResults(UUID queryID, string query) - { - List returnlist = new List(); - string[] querysplit; - querysplit = query.Split(' '); - if (querysplit.Length == 2) - { try { - Dictionary param = new Dictionary(); - param["first"] = querysplit[0]; - param["second"] = querysplit[1]; - - using (IDbCommand result = database.Query("SELECT UUID,username,lastname FROM " + m_usersTableName + " WHERE username = @first AND lastname = @second", param)) - using (IDataReader reader = result.ExecuteReader()) + using (SqlDataReader reader = command.ExecuteReader()) { - while (reader.Read()) - { - AvatarPickerAvatar user = new AvatarPickerAvatar(); - user.AvatarID = new UUID((string)reader["UUID"]); - user.firstName = (string)reader["username"]; - user.lastName = (string)reader["lastname"]; - returnlist.Add(user); - } + return ReadUserRow(reader); } } catch (Exception e) { - m_log.Error(e.ToString()); + m_log.Error("[USER DB] Error getting user profile, error: " + e.Message); + return null; } } - else if (querysplit.Length == 1) - { - try - { - Dictionary param = new Dictionary(); - param["first"] = querysplit[0]; - - using (IDbCommand result = database.Query("SELECT UUID,username,lastname FROM " + m_usersTableName + " WHERE username = @first OR lastname = @first", param)) - using (IDataReader reader = result.ExecuteReader()) - { - while (reader.Read()) - { - AvatarPickerAvatar user = new AvatarPickerAvatar(); - user.AvatarID = new UUID((string)reader["UUID"]); - user.firstName = (string)reader["username"]; - user.lastName = (string)reader["lastname"]; - returnlist.Add(user); - } - } - } - catch (Exception e) - { - m_log.Error(e.ToString()); - } - } - return returnlist; } /// @@ -421,25 +235,136 @@ namespace OpenSim.Data.MSSQL /// /// override public UserProfileData GetUserByUUID(UUID uuid) + { + using (AutoClosingSqlCommand command = database.Query("SELECT * FROM " + m_usersTableName + " WHERE UUID = @uuid")) + { + command.Parameters.Add(database.CreateParameter("uuid", uuid)); + + try + { + using (IDataReader reader = command.ExecuteReader()) + { + return ReadUserRow(reader); + } + } + catch (Exception e) + { + m_log.Error("[USER DB] Error getting user profile by UUID, error: " + e.Message); + return null; + } + } + } + + + /// + /// Creates a new users profile + /// + /// The user profile to create + override public void AddNewUserProfile(UserProfileData user) { try { - Dictionary param = new Dictionary(); - param["uuid"] = uuid.ToString(); - - using (IDbCommand result = database.Query("SELECT * FROM " + m_usersTableName + " WHERE UUID = @uuid", param)) - using (IDataReader reader = result.ExecuteReader()) - { - return database.readUserRow(reader); - } + InsertUserRow(user.ID, user.FirstName, user.SurName, user.PasswordHash, user.PasswordSalt, + user.HomeRegion, user.HomeLocation.X, user.HomeLocation.Y, + user.HomeLocation.Z, + user.HomeLookAt.X, user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created, + user.LastLogin, user.UserInventoryURI, user.UserAssetURI, + user.CanDoMask, user.WantDoMask, + user.AboutText, user.FirstLifeAboutText, user.Image, + user.FirstLifeImage, user.WebLoginKey, user.HomeRegionID, + user.GodLevel, user.UserFlags, user.CustomType, user.Partner); } catch (Exception e) { - m_log.Error(e.ToString()); - return null; + m_log.Error("[USER DB] Error adding new profile, error: " + e.Message); } } + /// + /// update a user profile + /// + /// the profile to update + /// + override public bool UpdateUserProfile(UserProfileData user) + { + using (AutoClosingSqlCommand command = database.Query("UPDATE " + m_usersTableName + " set UUID = @uuid, " + + "username = @username, " + + "lastname = @lastname," + + "passwordHash = @passwordHash," + + "passwordSalt = @passwordSalt," + + "homeRegion = @homeRegion," + + "homeLocationX = @homeLocationX," + + "homeLocationY = @homeLocationY," + + "homeLocationZ = @homeLocationZ," + + "homeLookAtX = @homeLookAtX," + + "homeLookAtY = @homeLookAtY," + + "homeLookAtZ = @homeLookAtZ," + + "created = @created," + + "lastLogin = @lastLogin," + + "userInventoryURI = @userInventoryURI," + + "userAssetURI = @userAssetURI," + + "profileCanDoMask = @profileCanDoMask," + + "profileWantDoMask = @profileWantDoMask," + + "profileAboutText = @profileAboutText," + + "profileFirstText = @profileFirstText," + + "profileImage = @profileImage," + + "profileFirstImage = @profileFirstImage, " + + "webLoginKey = @webLoginKey, " + + "homeRegionID = @homeRegionID, " + + "userFlags = @userFlags, " + + "godLevel = @godLevel, " + + "customType = @customType, " + + "partner = @partner where " + + "UUID = @keyUUUID;")) + { + command.Parameters.Add(database.CreateParameter("uuid", user.ID)); + command.Parameters.Add(database.CreateParameter("username", user.FirstName)); + command.Parameters.Add(database.CreateParameter("lastname", user.SurName)); + command.Parameters.Add(database.CreateParameter("passwordHash", user.PasswordHash)); + command.Parameters.Add(database.CreateParameter("passwordSalt", user.PasswordSalt)); + command.Parameters.Add(database.CreateParameter("homeRegion", user.HomeRegion)); + command.Parameters.Add(database.CreateParameter("homeLocationX", user.HomeLocation.X)); + command.Parameters.Add(database.CreateParameter("homeLocationY", user.HomeLocation.Y)); + command.Parameters.Add(database.CreateParameter("homeLocationZ", user.HomeLocation.Z)); + command.Parameters.Add(database.CreateParameter("homeLookAtX", user.HomeLookAt.X)); + command.Parameters.Add(database.CreateParameter("homeLookAtY", user.HomeLookAt.Y)); + command.Parameters.Add(database.CreateParameter("homeLookAtZ", user.HomeLookAt.Z)); + command.Parameters.Add(database.CreateParameter("created", user.Created)); + command.Parameters.Add(database.CreateParameter("lastLogin", user.LastLogin)); + command.Parameters.Add(database.CreateParameter("userInventoryURI", user.UserInventoryURI)); + command.Parameters.Add(database.CreateParameter("userAssetURI", user.UserAssetURI)); + command.Parameters.Add(database.CreateParameter("profileCanDoMask", user.CanDoMask)); + command.Parameters.Add(database.CreateParameter("profileWantDoMask", user.WantDoMask)); + command.Parameters.Add(database.CreateParameter("profileAboutText", user.AboutText)); + command.Parameters.Add(database.CreateParameter("profileFirstText", user.FirstLifeAboutText)); + command.Parameters.Add(database.CreateParameter("profileImage", user.Image)); + command.Parameters.Add(database.CreateParameter("profileFirstImage", user.FirstLifeImage)); + command.Parameters.Add(database.CreateParameter("webLoginKey", user.WebLoginKey)); + // + command.Parameters.Add(database.CreateParameter("homeRegionID", user.HomeRegionID)); + command.Parameters.Add(database.CreateParameter("userFlags", user.UserFlags)); + command.Parameters.Add(database.CreateParameter("godLevel", user.GodLevel)); + command.Parameters.Add(database.CreateParameter("customType", user.CustomType)); + command.Parameters.Add(database.CreateParameter("partner", user.Partner)); + command.Parameters.Add(database.CreateParameter("keyUUUID", user.ID)); + + try + { + int affected = command.ExecuteNonQuery(); + return (affected != 0); + } + catch (Exception e) + { + m_log.Error("[USER DB] Error updating profile, error: " + e.Message); + } + } + return false; + } + + #endregion + + #region Agent table methods + /// /// Returns a user session searching by name /// @@ -469,147 +394,22 @@ namespace OpenSim.Data.MSSQL /// The users session override public UserAgentData GetAgentByUUID(UUID uuid) { - try + using (AutoClosingSqlCommand command = database.Query("SELECT * FROM " + m_agentsTableName + " WHERE UUID = @uuid")) { - Dictionary param = new Dictionary(); - param["uuid"] = uuid.ToString(); - - using (IDbCommand result = database.Query("SELECT * FROM " + m_agentsTableName + " WHERE UUID = @uuid", param)) - using (IDataReader reader = result.ExecuteReader()) + command.Parameters.Add(database.CreateParameter("uuid", uuid)); + try { - return database.readAgentRow(reader); + using (SqlDataReader reader = command.ExecuteReader()) + { + return readAgentRow(reader); + } + } + catch (Exception e) + { + m_log.Error("[USER DB] Error updating agentdata by UUID, error: " + e.Message); + return null; } } - catch (Exception e) - { - m_log.Error(e.ToString()); - return null; - } - } - - /// - /// Store a weblogin key - /// - /// The agent UUID - /// the WebLogin Key - /// unused ? - override public void StoreWebLoginKey(UUID AgentID, UUID WebLoginKey) - { - UserProfileData user = GetUserByUUID(AgentID); - user.WebLoginKey = WebLoginKey; - UpdateUserProfile(user); - - } - /// - /// Creates a new users profile - /// - /// The user profile to create - override public void AddNewUserProfile(UserProfileData user) - { - try - { - InsertUserRow(user.ID, user.FirstName, user.SurName, user.PasswordHash, user.PasswordSalt, - user.HomeRegion, user.HomeLocation.X, user.HomeLocation.Y, - user.HomeLocation.Z, - user.HomeLookAt.X, user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created, - user.LastLogin, user.UserInventoryURI, user.UserAssetURI, - user.CanDoMask, user.WantDoMask, - user.AboutText, user.FirstLifeAboutText, user.Image, - user.FirstLifeImage, user.WebLoginKey); - } - catch (Exception e) - { - m_log.Error(e.ToString()); - } - } - - /// - /// Creates a new user and inserts it into the database - /// - /// User ID - /// First part of the login - /// Second part of the login - /// A salted hash of the users password - /// The salt used for the password hash - /// A regionHandle of the users home region - /// Home region position vector - /// Home region position vector - /// Home region position vector - /// Home region 'look at' vector - /// Home region 'look at' vector - /// Home region 'look at' vector - /// Account created (unix timestamp) - /// Last login (unix timestamp) - /// Users inventory URI - /// Users asset URI - /// I can do mask - /// I want to do mask - /// Profile text - /// Firstlife text - /// UUID for profile image - /// UUID for firstlife image - /// Success? - private bool InsertUserRow(UUID uuid, string username, string lastname, string passwordHash, - string passwordSalt, UInt64 homeRegion, float homeLocX, float homeLocY, float homeLocZ, - float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin, - string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask, - string aboutText, string firstText, - UUID profileImage, UUID firstImage, UUID webLoginKey) - { - string sql = "INSERT INTO "+m_usersTableName; - sql += " ([UUID], [username], [lastname], [passwordHash], [passwordSalt], [homeRegion], "; - sql += - "[homeLocationX], [homeLocationY], [homeLocationZ], [homeLookAtX], [homeLookAtY], [homeLookAtZ], [created], "; - sql += - "[lastLogin], [userInventoryURI], [userAssetURI], [profileCanDoMask], [profileWantDoMask], [profileAboutText], "; - sql += "[profileFirstText], [profileImage], [profileFirstImage], [webLoginKey]) VALUES "; - - sql += "(@UUID, @username, @lastname, @passwordHash, @passwordSalt, @homeRegion, "; - sql += - "@homeLocationX, @homeLocationY, @homeLocationZ, @homeLookAtX, @homeLookAtY, @homeLookAtZ, @created, "; - sql += - "@lastLogin, @userInventoryURI, @userAssetURI, @profileCanDoMask, @profileWantDoMask, @profileAboutText, "; - sql += "@profileFirstText, @profileImage, @profileFirstImage, @webLoginKey);"; - - Dictionary parameters = new Dictionary(); - parameters["UUID"] = uuid.ToString(); - parameters["username"] = username.ToString(); - parameters["lastname"] = lastname.ToString(); - parameters["passwordHash"] = passwordHash.ToString(); - parameters["passwordSalt"] = passwordSalt.ToString(); - parameters["homeRegion"] = homeRegion.ToString(); - parameters["homeLocationX"] = homeLocX.ToString(); - parameters["homeLocationY"] = homeLocY.ToString(); - parameters["homeLocationZ"] = homeLocZ.ToString(); - parameters["homeLookAtX"] = homeLookAtX.ToString(); - parameters["homeLookAtY"] = homeLookAtY.ToString(); - parameters["homeLookAtZ"] = homeLookAtZ.ToString(); - parameters["created"] = created.ToString(); - parameters["lastLogin"] = lastlogin.ToString(); - parameters["userInventoryURI"] = String.Empty; - parameters["userAssetURI"] = String.Empty; - parameters["profileCanDoMask"] = "0"; - parameters["profileWantDoMask"] = "0"; - parameters["profileAboutText"] = aboutText; - parameters["profileFirstText"] = firstText; - parameters["profileImage"] = profileImage.ToString(); - parameters["profileFirstImage"] = firstImage.ToString(); - parameters["webLoginKey"] = UUID.Random().ToString(); - - - try - { - using (IDbCommand result = database.Query(sql, parameters)) - { - return (result.ExecuteNonQuery() == 1); - } - } - catch (Exception e) - { - m_log.Error(e.ToString()); - return false; - } - } /// @@ -620,107 +420,156 @@ namespace OpenSim.Data.MSSQL { try { - database.insertAgentRow(agent); + InsertUpdateAgentRow(agent); } catch (Exception e) { - m_log.Error(e.ToString()); + m_log.Error("[USER DB] Error adding new agentdata, error: " + e.Message); + } + } + + #endregion + + #region User Friends List Data + + /// + /// Add a new friend in the friendlist + /// + /// UUID of the friendlist owner + /// Friend's UUID + /// Permission flag + override public void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms) + { + int dtvalue = Util.UnixTimeSinceEpoch(); + + using (AutoClosingSqlCommand command = database.Query( + "INSERT INTO " + m_userFriendsTableName + " " + + "(ownerID,friendID,friendPerms,datetimestamp) " + + "VALUES " + + "(@ownerID,@friendID,@friendPerms,@datetimestamp)")) + { + command.Parameters.Add(database.CreateParameter("ownerID", friendlistowner)); + command.Parameters.Add(database.CreateParameter("friendID", friend)); + command.Parameters.Add(database.CreateParameter("friendPerms", perms)); + command.Parameters.Add(database.CreateParameter("datetimestamp", dtvalue)); + command.ExecuteNonQuery(); + + try + { + command.CommandText = string.Format("INSERT INTO {0} (ownerID,friendID,friendPerms,datetimestamp) VALUES (@friendID,@ownerID,@friendPerms,@datetimestamp)", + m_userFriendsTableName); + + command.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.Error("[USER DB] Error adding new userfriend, error: " + e.Message); + return; + } } } /// - /// update a user profile + /// Remove an friend from the friendlist /// - /// the profile to update - /// - override public bool UpdateUserProfile(UserProfileData user) + /// UUID of the friendlist owner + /// UUID of the not-so-friendly user to remove from the list + override public void RemoveUserFriend(UUID friendlistowner, UUID friend) { - using (IDbCommand command = database.Query("UPDATE " + m_usersTableName + " set UUID = @uuid, " + - "username = @username, " + - "lastname = @lastname," + - "passwordHash = @passwordHash," + - "passwordSalt = @passwordSalt," + - "homeRegion = @homeRegion," + - "homeLocationX = @homeLocationX," + - "homeLocationY = @homeLocationY," + - "homeLocationZ = @homeLocationZ," + - "homeLookAtX = @homeLookAtX," + - "homeLookAtY = @homeLookAtY," + - "homeLookAtZ = @homeLookAtZ," + - "created = @created," + - "lastLogin = @lastLogin," + - "userInventoryURI = @userInventoryURI," + - "userAssetURI = @userAssetURI," + - "profileCanDoMask = @profileCanDoMask," + - "profileWantDoMask = @profileWantDoMask," + - "profileAboutText = @profileAboutText," + - "profileFirstText = @profileFirstText," + - "profileImage = @profileImage," + - "profileFirstImage = @profileFirstImage, " + - "webLoginKey = @webLoginKey where " + - "UUID = @keyUUUID;")) + using (AutoClosingSqlCommand command = database.Query("delete from " + m_userFriendsTableName + " where ownerID = @ownerID and friendID = @friendID")) { - SqlParameter param1 = new SqlParameter("@uuid", user.ID.ToString()); - SqlParameter param2 = new SqlParameter("@username", user.FirstName); - SqlParameter param3 = new SqlParameter("@lastname", user.SurName); - SqlParameter param4 = new SqlParameter("@passwordHash", user.PasswordHash); - SqlParameter param5 = new SqlParameter("@passwordSalt", user.PasswordSalt); - SqlParameter param6 = new SqlParameter("@homeRegion", Convert.ToInt64(user.HomeRegion)); - SqlParameter param7 = new SqlParameter("@homeLocationX", user.HomeLocation.X); - SqlParameter param8 = new SqlParameter("@homeLocationY", user.HomeLocation.Y); - SqlParameter param9 = new SqlParameter("@homeLocationZ", user.HomeLocation.Y); - SqlParameter param10 = new SqlParameter("@homeLookAtX", user.HomeLookAt.X); - SqlParameter param11 = new SqlParameter("@homeLookAtY", user.HomeLookAt.Y); - SqlParameter param12 = new SqlParameter("@homeLookAtZ", user.HomeLookAt.Z); - SqlParameter param13 = new SqlParameter("@created", Convert.ToInt32(user.Created)); - SqlParameter param14 = new SqlParameter("@lastLogin", Convert.ToInt32(user.LastLogin)); - SqlParameter param15 = new SqlParameter("@userInventoryURI", user.UserInventoryURI); - SqlParameter param16 = new SqlParameter("@userAssetURI", user.UserAssetURI); - SqlParameter param17 = new SqlParameter("@profileCanDoMask", Convert.ToInt32(user.CanDoMask)); - SqlParameter param18 = new SqlParameter("@profileWantDoMask", Convert.ToInt32(user.WantDoMask)); - SqlParameter param19 = new SqlParameter("@profileAboutText", user.AboutText); - SqlParameter param20 = new SqlParameter("@profileFirstText", user.FirstLifeAboutText); - SqlParameter param21 = new SqlParameter("@profileImage", user.Image.ToString()); - SqlParameter param22 = new SqlParameter("@profileFirstImage", user.FirstLifeImage.ToString()); - SqlParameter param23 = new SqlParameter("@keyUUUID", user.ID.ToString()); - SqlParameter param24 = new SqlParameter("@webLoginKey", user.WebLoginKey.ToString()); - command.Parameters.Add(param1); - command.Parameters.Add(param2); - command.Parameters.Add(param3); - command.Parameters.Add(param4); - command.Parameters.Add(param5); - command.Parameters.Add(param6); - command.Parameters.Add(param7); - command.Parameters.Add(param8); - command.Parameters.Add(param9); - command.Parameters.Add(param10); - command.Parameters.Add(param11); - command.Parameters.Add(param12); - command.Parameters.Add(param13); - command.Parameters.Add(param14); - command.Parameters.Add(param15); - command.Parameters.Add(param16); - command.Parameters.Add(param17); - command.Parameters.Add(param18); - command.Parameters.Add(param19); - command.Parameters.Add(param20); - command.Parameters.Add(param21); - command.Parameters.Add(param22); - command.Parameters.Add(param23); - command.Parameters.Add(param24); + command.Parameters.Add(database.CreateParameter("@ownerID", friendlistowner)); + command.Parameters.Add(database.CreateParameter("@friendID", friend)); + command.ExecuteNonQuery(); + + command.CommandText = "delete from " + m_userFriendsTableName + + " where ownerID = @friendID and friendID = @ownerID"; try { - int affected = command.ExecuteNonQuery(); - return (affected != 0); + command.ExecuteNonQuery(); } catch (Exception e) { - m_log.Error(e.ToString()); + m_log.Error("[USER DB] Error removing userfriend, error: " + e.Message); } } - return false; } + /// + /// Update friendlist permission flag for a friend + /// + /// UUID of the friendlist owner + /// UUID of the friend + /// new permission flag + override public void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms) + { + using (AutoClosingSqlCommand command = database.Query( + "update " + m_userFriendsTableName + + " SET friendPerms = @friendPerms " + + "where ownerID = @ownerID and friendID = @friendID")) + { + command.Parameters.Add(database.CreateParameter("@ownerID", friendlistowner)); + command.Parameters.Add(database.CreateParameter("@friendID", friend)); + command.Parameters.Add(database.CreateParameter("@friendPerms", perms)); + + try + { + command.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.Error("[USER DB] Error updating userfriend, error: " + e.Message); + } + } + } + + /// + /// Get (fetch?) the user's friendlist + /// + /// UUID of the friendlist owner + /// Friendlist list + override public List GetUserFriendList(UUID friendlistowner) + { + List friendList = new List(); + + //Left Join userfriends to itself + using (AutoClosingSqlCommand command = database.Query( + "select a.ownerID,a.friendID,a.friendPerms,b.friendPerms as ownerperms from " + m_userFriendsTableName + " as a, " + m_userFriendsTableName + " as b" + + " where a.ownerID = @ownerID and b.ownerID = a.friendID and b.friendID = a.ownerID")) + { + command.Parameters.Add(database.CreateParameter("@ownerID", friendlistowner)); + + try + { + using (IDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + FriendListItem fli = new FriendListItem(); + fli.FriendListOwner = new UUID((string)reader["ownerID"]); + fli.Friend = new UUID((string)reader["friendID"]); + fli.FriendPerms = (uint)Convert.ToInt32(reader["friendPerms"]); + + // This is not a real column in the database table, it's a joined column from the opposite record + fli.FriendListOwnerPerms = (uint)Convert.ToInt32(reader["ownerperms"]); + + friendList.Add(fli); + } + } + } + catch (Exception e) + { + m_log.Error("[USER DB] Error updating userfriend, error: " + e.Message); + } + } + + return friendList; + } + + #endregion + + #region Money functions (not used) + /// /// Performs a money transfer request between two accounts /// @@ -746,33 +595,327 @@ namespace OpenSim.Data.MSSQL return false; } - /// Appearance + #endregion + + #region Appearance methods + + /// + /// Gets the user appearance. + /// + /// The user. + /// /// TODO: stubs for now to get us to a compiling state gently override public AvatarAppearance GetUserAppearance(UUID user) { -// return new AvatarAppearance(); try { - Dictionary param = new Dictionary(); - param["@UUID"] = user.ToString(); + AvatarAppearance appearance = new AvatarAppearance(); - using (IDbCommand result = - database.Query("SELECT * FROM avatarappearance WHERE owner = @UUID", param)) - using (IDataReader reader = result.ExecuteReader()) + using (AutoClosingSqlCommand command = database.Query("SELECT * FROM avatarappearance WHERE owner = @UUID")) + { + command.Parameters.Add(database.CreateParameter("@UUID", user)); + using (IDataReader reader = command.ExecuteReader()) { - AvatarAppearance item = null; if (reader.Read()) - item = readUserAppearance(reader); - return item; + appearance = readUserAppearance(reader); } + } + + appearance.SetAttachments(GetUserAttachments(user)); + + return appearance; } catch (Exception e) { - m_log.Error(e.ToString()); + m_log.Error("[USER DB] Error updating userfriend, error: " + e.Message); } return null; } + + /// + /// Update a user appearence into database + /// + /// the used UUID + /// the appearence + override public void UpdateUserAppearance(UUID user, AvatarAppearance appearance) + { + string sql = String.Empty; + sql += "DELETE FROM avatarappearance WHERE owner=@owner "; + sql += "INSERT INTO avatarappearance "; + sql += "(owner, serial, visual_params, texture, avatar_height, "; + sql += "body_item, body_asset, skin_item, skin_asset, hair_item, hair_asset, eyes_item, eyes_asset, "; + sql += "shirt_item, shirt_asset, pants_item, pants_asset, shoes_item, shoes_asset, socks_item, socks_asset, "; + sql += "jacket_item, jacket_asset, gloves_item, gloves_asset, undershirt_item, undershirt_asset, underpants_item, underpants_asset, "; + sql += "skirt_item, skirt_asset) values ("; + sql += "@owner, @serial, @visual_params, @texture, @avatar_height, "; + sql += "@body_item, @body_asset, @skin_item, @skin_asset, @hair_item, @hair_asset, @eyes_item, @eyes_asset, "; + sql += "@shirt_item, @shirt_asset, @pants_item, @pants_asset, @shoes_item, @shoes_asset, @socks_item, @socks_asset, "; + sql += "@jacket_item, @jacket_asset, @gloves_item, @gloves_asset, @undershirt_item, @undershirt_asset, @underpants_item, @underpants_asset, "; + sql += "@skirt_item, @skirt_asset)"; + + using (AutoClosingSqlCommand cmd = database.Query(sql)) + { + cmd.Parameters.Add(database.CreateParameter("@owner", appearance.Owner)); + cmd.Parameters.Add(database.CreateParameter("@serial", appearance.Serial)); + cmd.Parameters.Add(database.CreateParameter("@visual_params", appearance.VisualParams)); + cmd.Parameters.Add(database.CreateParameter("@texture", appearance.Texture.ToBytes())); + cmd.Parameters.Add(database.CreateParameter("@avatar_height", appearance.AvatarHeight)); + cmd.Parameters.Add(database.CreateParameter("@body_item", appearance.BodyItem)); + cmd.Parameters.Add(database.CreateParameter("@body_asset", appearance.BodyAsset)); + cmd.Parameters.Add(database.CreateParameter("@skin_item", appearance.SkinItem)); + cmd.Parameters.Add(database.CreateParameter("@skin_asset", appearance.SkinAsset)); + cmd.Parameters.Add(database.CreateParameter("@hair_item", appearance.HairItem)); + cmd.Parameters.Add(database.CreateParameter("@hair_asset", appearance.HairAsset)); + cmd.Parameters.Add(database.CreateParameter("@eyes_item", appearance.EyesItem)); + cmd.Parameters.Add(database.CreateParameter("@eyes_asset", appearance.EyesAsset)); + cmd.Parameters.Add(database.CreateParameter("@shirt_item", appearance.ShirtItem)); + cmd.Parameters.Add(database.CreateParameter("@shirt_asset", appearance.ShirtAsset)); + cmd.Parameters.Add(database.CreateParameter("@pants_item", appearance.PantsItem)); + cmd.Parameters.Add(database.CreateParameter("@pants_asset", appearance.PantsAsset)); + cmd.Parameters.Add(database.CreateParameter("@shoes_item", appearance.ShoesItem)); + cmd.Parameters.Add(database.CreateParameter("@shoes_asset", appearance.ShoesAsset)); + cmd.Parameters.Add(database.CreateParameter("@socks_item", appearance.SocksItem)); + cmd.Parameters.Add(database.CreateParameter("@socks_asset", appearance.SocksAsset)); + cmd.Parameters.Add(database.CreateParameter("@jacket_item", appearance.JacketItem)); + cmd.Parameters.Add(database.CreateParameter("@jacket_asset", appearance.JacketAsset)); + cmd.Parameters.Add(database.CreateParameter("@gloves_item", appearance.GlovesItem)); + cmd.Parameters.Add(database.CreateParameter("@gloves_asset", appearance.GlovesAsset)); + cmd.Parameters.Add(database.CreateParameter("@undershirt_item", appearance.UnderShirtItem)); + cmd.Parameters.Add(database.CreateParameter("@undershirt_asset", appearance.UnderShirtAsset)); + cmd.Parameters.Add(database.CreateParameter("@underpants_item", appearance.UnderPantsItem)); + cmd.Parameters.Add(database.CreateParameter("@underpants_asset", appearance.UnderPantsAsset)); + cmd.Parameters.Add(database.CreateParameter("@skirt_item", appearance.SkirtItem)); + cmd.Parameters.Add(database.CreateParameter("@skirt_asset", appearance.SkirtAsset)); + + try + { + cmd.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.Error("[USER DB] Error updating user appearance, error: " + e.Message); + } + } + + UpdateUserAttachments(user, appearance.GetAttachments()); + } + + #endregion + + #region Attachment methods + + /// + /// Gets all attachment of a agent. + /// + /// agent ID. + /// + public Hashtable GetUserAttachments(UUID agentID) + { + Hashtable returnTable = new Hashtable(); + using (AutoClosingSqlCommand command = database.Query("select attachpoint, item, asset from avatarattachments where UUID = @uuid", database.CreateParameter("@uuid", agentID))) + { + using (SqlDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + int attachpoint = Convert.ToInt32(reader["attachpoint"]); + if (returnTable.ContainsKey(attachpoint)) + continue; + Hashtable item = new Hashtable(); + item.Add("item", reader["item"].ToString()); + item.Add("asset", reader["asset"].ToString()); + + returnTable.Add(attachpoint, item); + } + } + } + return returnTable; + } + + /// + /// Updates all attachments of the agent. + /// + /// agentID. + /// data with all items on attachmentpoints + public void UpdateUserAttachments(UUID agentID, Hashtable data) + { + string sql = "delete from avatarattachments where UUID = @uuid"; + + using (AutoClosingSqlCommand command = database.Query(sql)) + { + command.Parameters.Add(database.CreateParameter("uuid", agentID)); + command.ExecuteNonQuery(); + } + if (data == null) + return; + + sql = "insert into avatarattachments (UUID, attachpoint, item, asset) values (@uuid, @attachpoint, @item, @asset)"; + + using (AutoClosingSqlCommand command = database.Query(sql)) + { + bool firstTime = true; + foreach (DictionaryEntry e in data) + { + int attachpoint = Convert.ToInt32(e.Key); + + Hashtable item = (Hashtable)e.Value; + + if (firstTime) + { + command.Parameters.Add(database.CreateParameter("@uuid", agentID)); + command.Parameters.Add(database.CreateParameter("@attachpoint", attachpoint)); + command.Parameters.Add(database.CreateParameter("@item", item["item"].ToString())); + command.Parameters.Add(database.CreateParameter("@asset", item["asset"].ToString())); + firstTime = false; + } + command.Parameters["@uuid"].Value = agentID.ToString(); + command.Parameters["@attachpoint"].Value = attachpoint; + command.Parameters["@item"].Value = item["item"].ToString(); + command.Parameters["@asset"].Value = item["asset"].ToString(); + + try + { + command.ExecuteNonQuery(); + } + catch (Exception ex) + { + m_log.DebugFormat("[USER DB] : Error adding user attachment. {0}", ex.Message); + } + } + } + } + + /// + /// Resets all attachments of a agent in the database. + /// + /// agentID. + override public void ResetAttachments(UUID agentID) + { + using (AutoClosingSqlCommand command = database.Query("update avatarattachments set asset = '00000000-0000-0000-0000-000000000000' where UUID = @uuid")) + { + command.Parameters.Add(database.CreateParameter("uuid", agentID)); + command.ExecuteNonQuery(); + } + } + + #endregion + + #region Other public methods + + /// + /// STUB ! Update current region + /// + /// avatar uuid + /// region uuid + /// region handle + override public void UpdateUserCurrentRegion(UUID avatarid, UUID regionuuid, ulong regionhandle) + { + //m_log.Info("[USER]: Stub UpdateUserCUrrentRegion called"); + } + + /// + /// + /// + /// + /// + /// + override public List GeneratePickerResults(UUID queryID, string query) + { + List returnlist = new List(); + string[] querysplit = query.Split(' '); + if (querysplit.Length == 2) + { + try + { + using (AutoClosingSqlCommand command = database.Query("SELECT UUID,username,lastname FROM " + m_usersTableName + " WHERE username LIKE @first AND lastname LIKE @second")) + { + //Add wildcard to the search + command.Parameters.Add(database.CreateParameter("first", querysplit[0] + "%")); + command.Parameters.Add(database.CreateParameter("second", querysplit[1] + "%")); + using (IDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + AvatarPickerAvatar user = new AvatarPickerAvatar(); + user.AvatarID = new UUID((string)reader["UUID"]); + user.firstName = (string)reader["username"]; + user.lastName = (string)reader["lastname"]; + returnlist.Add(user); + } + } + } + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + } + else if (querysplit.Length == 1) + { + try + { + using (AutoClosingSqlCommand command = database.Query("SELECT UUID,username,lastname FROM " + m_usersTableName + " WHERE username LIKE @first OR lastname LIKE @first")) + { + command.Parameters.Add(database.CreateParameter("first", querysplit[0] + "%")); + + using (IDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + AvatarPickerAvatar user = new AvatarPickerAvatar(); + user.AvatarID = new UUID((string)reader["UUID"]); + user.firstName = (string)reader["username"]; + user.lastName = (string)reader["lastname"]; + returnlist.Add(user); + } + } + } + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + } + return returnlist; + } + + /// + /// Store a weblogin key + /// + /// The agent UUID + /// the WebLogin Key + /// unused ? + override public void StoreWebLoginKey(UUID AgentID, UUID WebLoginKey) + { + UserProfileData user = GetUserByUUID(AgentID); + user.WebLoginKey = WebLoginKey; + UpdateUserProfile(user); + + } + + /// + /// Database provider name + /// + /// Provider name + override public string Name + { + get { return "MSSQL Userdata Interface"; } + } + + /// + /// Database provider version + /// + /// provider version + override public string Version + { + get { return database.getVersion(); } + } + + #endregion + + #region Private functions + /// /// Reads a one item from an SQL result /// @@ -827,99 +970,254 @@ namespace OpenSim.Data.MSSQL } /// - /// Update a user appearence into database + /// Insert/Update a agent row in the DB. /// - /// the used UUID - /// the appearence - override public void UpdateUserAppearance(UUID user, AvatarAppearance appearance) + /// agentdata. + private void InsertUpdateAgentRow(UserAgentData agentdata) { - string sql = String.Empty; - sql += "DELETE FROM avatarappearance WHERE owner=@owner "; - sql += "INSERT INTO avatarappearance "; - sql += "(owner, serial, visual_params, texture, avatar_height, "; - sql += "body_item, body_asset, skin_item, skin_asset, hair_item, hair_asset, eyes_item, eyes_asset, "; - sql += "shirt_item, shirt_asset, pants_item, pants_asset, shoes_item, shoes_asset, socks_item, socks_asset, "; - sql += "jacket_item, jacket_asset, gloves_item, gloves_asset, undershirt_item, undershirt_asset, underpants_item, underpants_asset, "; - sql += "skirt_item, skirt_asset) values ("; - sql += "@owner, @serial, @visual_params, @texture, @avatar_height, "; - sql += "@body_item, @body_asset, @skin_item, @skin_asset, @hair_item, @hair_asset, @eyes_item, @eyes_asset, "; - sql += "@shirt_item, @shirt_asset, @pants_item, @pants_asset, @shoes_item, @shoes_asset, @socks_item, @socks_asset, "; - sql += "@jacket_item, @jacket_asset, @gloves_item, @gloves_asset, @undershirt_item, @undershirt_asset, @underpants_item, @underpants_asset, "; - sql += "@skirt_item, @skirt_asset)"; + string sql = @" - using (AutoClosingSqlCommand cmd = database.Query(sql)) +IF EXISTS (SELECT * FROM agents WHERE UUID = @UUID) + BEGIN + UPDATE agents SET UUID = @UUID, sessionID = @sessionID, secureSessionID = @secureSessionID, agentIP = @agentIP, agentPort = @agentPort, agentOnline = @agentOnline, loginTime = @loginTime, logoutTime = @logoutTime, currentRegion = @currentRegion, currentHandle = @currentHandle, currentPos = @currentPos + WHERE UUID = @UUID + END +ELSE + BEGIN + INSERT INTO + agents (UUID, sessionID, secureSessionID, agentIP, agentPort, agentOnline, loginTime, logoutTime, currentRegion, currentHandle, currentPos) VALUES + (@UUID, @sessionID, @secureSessionID, @agentIP, @agentPort, @agentOnline, @loginTime, @logoutTime, @currentRegion, @currentHandle, @currentPos) + END +"; + + using (AutoClosingSqlCommand command = database.Query(sql)) { - cmd.Parameters.AddWithValue("@owner", appearance.Owner.ToString()); - cmd.Parameters.AddWithValue("@serial", appearance.Serial); - cmd.Parameters.AddWithValue("@visual_params", appearance.VisualParams); - cmd.Parameters.AddWithValue("@texture", appearance.Texture.ToBytes()); - cmd.Parameters.AddWithValue("@avatar_height", appearance.AvatarHeight); - cmd.Parameters.AddWithValue("@body_item", appearance.BodyItem.ToString()); - cmd.Parameters.AddWithValue("@body_asset", appearance.BodyAsset.ToString()); - cmd.Parameters.AddWithValue("@skin_item", appearance.SkinItem.ToString()); - cmd.Parameters.AddWithValue("@skin_asset", appearance.SkinAsset.ToString()); - cmd.Parameters.AddWithValue("@hair_item", appearance.HairItem.ToString()); - cmd.Parameters.AddWithValue("@hair_asset", appearance.HairAsset.ToString()); - cmd.Parameters.AddWithValue("@eyes_item", appearance.EyesItem.ToString()); - cmd.Parameters.AddWithValue("@eyes_asset", appearance.EyesAsset.ToString()); - cmd.Parameters.AddWithValue("@shirt_item", appearance.ShirtItem.ToString()); - cmd.Parameters.AddWithValue("@shirt_asset", appearance.ShirtAsset.ToString()); - cmd.Parameters.AddWithValue("@pants_item", appearance.PantsItem.ToString()); - cmd.Parameters.AddWithValue("@pants_asset", appearance.PantsAsset.ToString()); - cmd.Parameters.AddWithValue("@shoes_item", appearance.ShoesItem.ToString()); - cmd.Parameters.AddWithValue("@shoes_asset", appearance.ShoesAsset.ToString()); - cmd.Parameters.AddWithValue("@socks_item", appearance.SocksItem.ToString()); - cmd.Parameters.AddWithValue("@socks_asset", appearance.SocksAsset.ToString()); - cmd.Parameters.AddWithValue("@jacket_item", appearance.JacketItem.ToString()); - cmd.Parameters.AddWithValue("@jacket_asset", appearance.JacketAsset.ToString()); - cmd.Parameters.AddWithValue("@gloves_item", appearance.GlovesItem.ToString()); - cmd.Parameters.AddWithValue("@gloves_asset", appearance.GlovesAsset.ToString()); - cmd.Parameters.AddWithValue("@undershirt_item", appearance.UnderShirtItem.ToString()); - cmd.Parameters.AddWithValue("@undershirt_asset", appearance.UnderShirtAsset.ToString()); - cmd.Parameters.AddWithValue("@underpants_item", appearance.UnderPantsItem.ToString()); - cmd.Parameters.AddWithValue("@underpants_asset", appearance.UnderPantsAsset.ToString()); - cmd.Parameters.AddWithValue("@skirt_item", appearance.SkirtItem.ToString()); - cmd.Parameters.AddWithValue("@skirt_asset", appearance.SkirtAsset.ToString()); + command.Parameters.Add(database.CreateParameter("@UUID", agentdata.ProfileID)); + command.Parameters.Add(database.CreateParameter("@sessionID", agentdata.SessionID)); + command.Parameters.Add(database.CreateParameter("@secureSessionID", agentdata.SecureSessionID)); + command.Parameters.Add(database.CreateParameter("@agentIP", agentdata.AgentIP)); + command.Parameters.Add(database.CreateParameter("@agentPort", agentdata.AgentPort)); + command.Parameters.Add(database.CreateParameter("@agentOnline", agentdata.AgentOnline)); + command.Parameters.Add(database.CreateParameter("@loginTime", agentdata.LoginTime)); + command.Parameters.Add(database.CreateParameter("@logoutTime", agentdata.LogoutTime)); + command.Parameters.Add(database.CreateParameter("@currentRegion", agentdata.Region)); + command.Parameters.Add(database.CreateParameter("@currentHandle", agentdata.Handle)); + command.Parameters.Add(database.CreateParameter("@currentPos", "<" + ((int)agentdata.Position.X) + "," + ((int)agentdata.Position.Y) + "," + ((int)agentdata.Position.Z) + ">")); + command.Transaction = command.Connection.BeginTransaction(IsolationLevel.Serializable); try { - cmd.ExecuteNonQuery(); + if (command.ExecuteNonQuery() > 0) + { + command.Transaction.Commit(); + return; + } + + command.Transaction.Rollback(); + return; } catch (Exception e) { + command.Transaction.Rollback(); m_log.Error(e.ToString()); + return; } } + } /// - /// Database provider name + /// Reads an agent row from a database reader /// - /// Provider name - override public string Name + /// An active database reader + /// A user session agent + private UserAgentData readAgentRow(IDataReader reader) { - get {return "MSSQL Userdata Interface";} + UserAgentData retval = new UserAgentData(); + + if (reader.Read()) + { + // Agent IDs + retval.ProfileID = new UUID((string)reader["UUID"]); + retval.SessionID = new UUID((string)reader["sessionID"]); + retval.SecureSessionID = new UUID((string)reader["secureSessionID"]); + + // Agent Who? + retval.AgentIP = (string)reader["agentIP"]; + retval.AgentPort = Convert.ToUInt32(reader["agentPort"].ToString()); + retval.AgentOnline = Convert.ToInt32(reader["agentOnline"].ToString()) != 0; + + // Login/Logout times (UNIX Epoch) + retval.LoginTime = Convert.ToInt32(reader["loginTime"].ToString()); + retval.LogoutTime = Convert.ToInt32(reader["logoutTime"].ToString()); + + // Current position + retval.Region = (string)reader["currentRegion"]; + retval.Handle = Convert.ToUInt64(reader["currentHandle"].ToString()); + Vector3 tmp_v; + Vector3.TryParse((string)reader["currentPos"], out tmp_v); + retval.Position = tmp_v; + + } + else + { + return null; + } + return retval; } /// - /// Database provider version + /// Creates a new user and inserts it into the database /// - /// provider version - override public string Version + /// User ID + /// First part of the login + /// Second part of the login + /// A salted hash of the users password + /// The salt used for the password hash + /// A regionHandle of the users home region + /// Home region position vector + /// Home region position vector + /// Home region position vector + /// Home region 'look at' vector + /// Home region 'look at' vector + /// Home region 'look at' vector + /// Account created (unix timestamp) + /// Last login (unix timestamp) + /// Users inventory URI + /// Users asset URI + /// I can do mask + /// I want to do mask + /// Profile text + /// Firstlife text + /// UUID for profile image + /// UUID for firstlife image + /// web login key + /// homeregion UUID + /// has the user godlevel + /// unknown + /// unknown + /// UUID of partner + /// Success? + private void InsertUserRow(UUID uuid, string username, string lastname, string passwordHash, + string passwordSalt, UInt64 homeRegion, float homeLocX, float homeLocY, float homeLocZ, + float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin, + string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask, + string aboutText, string firstText, + UUID profileImage, UUID firstImage, UUID webLoginKey, UUID homeRegionID, + int godLevel, int userFlags, string customType, UUID partnerID) { - get {return database.getVersion();} + string sql = "INSERT INTO " + m_usersTableName; + sql += " ([UUID], [username], [lastname], [passwordHash], [passwordSalt], [homeRegion], "; + sql += "[homeLocationX], [homeLocationY], [homeLocationZ], [homeLookAtX], [homeLookAtY], [homeLookAtZ], [created], "; + sql += "[lastLogin], [userInventoryURI], [userAssetURI], [profileCanDoMask], [profileWantDoMask], [profileAboutText], "; + sql += "[profileFirstText], [profileImage], [profileFirstImage], [webLoginKey], "; + sql += "[homeRegionID], [userFlags], [godLevel], [customType], [partner]) VALUES "; + + sql += "(@UUID, @username, @lastname, @passwordHash, @passwordSalt, @homeRegion, "; + sql += "@homeLocationX, @homeLocationY, @homeLocationZ, @homeLookAtX, @homeLookAtY, @homeLookAtZ, @created, "; + sql += "@lastLogin, @userInventoryURI, @userAssetURI, @profileCanDoMask, @profileWantDoMask, @profileAboutText, "; + sql += "@profileFirstText, @profileImage, @profileFirstImage, @webLoginKey, "; + sql += "@homeRegionID, @userFlags, @godLevel, @customType, @partner)"; + + try + { + using (AutoClosingSqlCommand command = database.Query(sql)) + { + command.Parameters.Add(database.CreateParameter("UUID", uuid)); + command.Parameters.Add(database.CreateParameter("username", username)); + command.Parameters.Add(database.CreateParameter("lastname", lastname)); + command.Parameters.Add(database.CreateParameter("passwordHash", passwordHash)); + command.Parameters.Add(database.CreateParameter("passwordSalt", passwordSalt)); + command.Parameters.Add(database.CreateParameter("homeRegion", homeRegion)); + command.Parameters.Add(database.CreateParameter("homeLocationX", homeLocX)); + command.Parameters.Add(database.CreateParameter("homeLocationY", homeLocY)); + command.Parameters.Add(database.CreateParameter("homeLocationZ", homeLocZ)); + command.Parameters.Add(database.CreateParameter("homeLookAtX", homeLookAtX)); + command.Parameters.Add(database.CreateParameter("homeLookAtY", homeLookAtY)); + command.Parameters.Add(database.CreateParameter("homeLookAtZ", homeLookAtZ)); + command.Parameters.Add(database.CreateParameter("created", created)); + command.Parameters.Add(database.CreateParameter("lastLogin", lastlogin)); + command.Parameters.Add(database.CreateParameter("userInventoryURI", inventoryURI)); + command.Parameters.Add(database.CreateParameter("userAssetURI", assetURI)); + command.Parameters.Add(database.CreateParameter("profileCanDoMask", canDoMask)); + command.Parameters.Add(database.CreateParameter("profileWantDoMask", wantDoMask)); + command.Parameters.Add(database.CreateParameter("profileAboutText", aboutText)); + command.Parameters.Add(database.CreateParameter("profileFirstText", firstText)); + command.Parameters.Add(database.CreateParameter("profileImage", profileImage)); + command.Parameters.Add(database.CreateParameter("profileFirstImage", firstImage)); + command.Parameters.Add(database.CreateParameter("webLoginKey", webLoginKey)); + // + command.Parameters.Add(database.CreateParameter("homeRegionID", homeRegionID)); + command.Parameters.Add(database.CreateParameter("userFlags", userFlags)); + command.Parameters.Add(database.CreateParameter("godLevel", godLevel)); + command.Parameters.Add(database.CreateParameter("customType", customType)); + command.Parameters.Add(database.CreateParameter("partner", partnerID)); + + + command.ExecuteNonQuery(); + return; + } + } + catch (Exception e) + { + m_log.Error(e.ToString()); + return; + } + } /// - /// Not implemented + /// Reads a user profile from an active data reader /// - /// - public void runQuery(string query) + /// An active database reader + /// A user profile + private static UserProfileData ReadUserRow(IDataReader reader) { + UserProfileData retval = new UserProfileData(); + + if (reader.Read()) + { + retval.ID = new UUID((string)reader["UUID"]); + retval.FirstName = (string)reader["username"]; + retval.SurName = (string)reader["lastname"]; + + retval.PasswordHash = (string)reader["passwordHash"]; + retval.PasswordSalt = (string)reader["passwordSalt"]; + + retval.HomeRegion = Convert.ToUInt64(reader["homeRegion"].ToString()); + retval.HomeLocation = new Vector3( + Convert.ToSingle(reader["homeLocationX"].ToString()), + Convert.ToSingle(reader["homeLocationY"].ToString()), + Convert.ToSingle(reader["homeLocationZ"].ToString())); + retval.HomeLookAt = new Vector3( + Convert.ToSingle(reader["homeLookAtX"].ToString()), + Convert.ToSingle(reader["homeLookAtY"].ToString()), + Convert.ToSingle(reader["homeLookAtZ"].ToString())); + + retval.Created = Convert.ToInt32(reader["created"].ToString()); + retval.LastLogin = Convert.ToInt32(reader["lastLogin"].ToString()); + + retval.UserInventoryURI = (string)reader["userInventoryURI"]; + retval.UserAssetURI = (string)reader["userAssetURI"]; + + retval.CanDoMask = Convert.ToUInt32(reader["profileCanDoMask"].ToString()); + retval.WantDoMask = Convert.ToUInt32(reader["profileWantDoMask"].ToString()); + + retval.AboutText = (string)reader["profileAboutText"]; + retval.FirstLifeAboutText = (string)reader["profileFirstText"]; + + retval.Image = new UUID((string)reader["profileImage"]); + retval.FirstLifeImage = new UUID((string)reader["profileFirstImage"]); + retval.WebLoginKey = new UUID((string)reader["webLoginKey"]); + } + else + { + return null; + } + return retval; } - override public void ResetAttachments(UUID userID) - { - } + #endregion } + } diff --git a/OpenSim/Data/MSSQL/Resources/001_AssetStore.sql b/OpenSim/Data/MSSQL/Resources/001_AssetStore.sql new file mode 100644 index 0000000000..2b293c7636 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/001_AssetStore.sql @@ -0,0 +1,13 @@ +CREATE TABLE [assets] ( + [id] [varchar](36) NOT NULL, + [name] [varchar](64) NOT NULL, + [description] [varchar](64) NOT NULL, + [assetType] [tinyint] NOT NULL, + [local] [tinyint] NOT NULL, + [temporary] [tinyint] NOT NULL, + [data] [image] NOT NULL, +PRIMARY KEY CLUSTERED +( + [id] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] diff --git a/OpenSim/Data/MSSQL/Resources/001_GridStore.sql b/OpenSim/Data/MSSQL/Resources/001_GridStore.sql new file mode 100644 index 0000000000..ff15f54c07 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/001_GridStore.sql @@ -0,0 +1,37 @@ +BEGIN TRANSACTION + +CREATE TABLE [dbo].[regions]( + [regionHandle] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionName] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [uuid] [varchar](255) COLLATE Latin1_General_CI_AS NOT NULL, + [regionRecvKey] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionSecret] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionSendKey] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionDataURI] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [serverIP] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [serverPort] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [serverURI] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [locX] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [locY] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [locZ] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [eastOverrideHandle] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [westOverrideHandle] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [southOverrideHandle] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [northOverrideHandle] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionAssetURI] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionAssetRecvKey] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionAssetSendKey] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionUserURI] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionUserRecvKey] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionUserSendKey] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionMapTexture] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [serverHttpPort] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [serverRemotingPort] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [owner_uuid] [varchar](36) COLLATE Latin1_General_CI_AS NULL, +PRIMARY KEY CLUSTERED +( + [uuid] ASC +)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] +) ON [PRIMARY] + +COMMIT diff --git a/OpenSim/Data/MSSQL/Resources/001_InventoryStore.sql b/OpenSim/Data/MSSQL/Resources/001_InventoryStore.sql new file mode 100644 index 0000000000..836d2d1e2b --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/001_InventoryStore.sql @@ -0,0 +1,64 @@ +BEGIN TRANSACTION + +CREATE TABLE [inventoryfolders] ( + [folderID] [varchar](36) NOT NULL default '', + [agentID] [varchar](36) default NULL, + [parentFolderID] [varchar](36) default NULL, + [folderName] [varchar](64) default NULL, + [type] [smallint] NOT NULL default 0, + [version] [int] NOT NULL default 0, + PRIMARY KEY CLUSTERED +( + [folderID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] + +CREATE NONCLUSTERED INDEX [owner] ON [inventoryfolders] +( + [agentID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + +CREATE NONCLUSTERED INDEX [parent] ON [inventoryfolders] +( + [parentFolderID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + + +CREATE TABLE [inventoryitems] ( + [inventoryID] [varchar](36) NOT NULL default '', + [assetID] [varchar](36) default NULL, + [assetType] [int] default NULL, + [parentFolderID] [varchar](36) default NULL, + [avatarID] [varchar](36) default NULL, + [inventoryName] [varchar](64) default NULL, + [inventoryDescription] [varchar](128) default NULL, + [inventoryNextPermissions] [int] default NULL, + [inventoryCurrentPermissions] [int] default NULL, + [invType] [int] default NULL, + [creatorID] [varchar](36) default NULL, + [inventoryBasePermissions] [int] NOT NULL default 0, + [inventoryEveryOnePermissions] [int] NOT NULL default 0, + [salePrice] [int] default NULL, + [saleType] [tinyint] default NULL, + [creationDate] [int] default NULL, + [groupID] [varchar](36) default NULL, + [groupOwned] [bit] default NULL, + [flags] [int] default NULL, + PRIMARY KEY CLUSTERED +( + [inventoryID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] + + +CREATE NONCLUSTERED INDEX [owner] ON [inventoryitems] +( + [avatarID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + +CREATE NONCLUSTERED INDEX [folder] ON [inventoryitems] +( + [parentFolderID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + +COMMIT diff --git a/OpenSim/Data/MSSQL/Resources/001_UserStore.sql b/OpenSim/Data/MSSQL/Resources/001_UserStore.sql new file mode 100644 index 0000000000..abd6ff214d --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/001_UserStore.sql @@ -0,0 +1,224 @@ +CREATE TABLE [users] ( + [UUID] [varchar](36) NOT NULL default '', + [username] [varchar](32) NOT NULL, + [lastname] [varchar](32) NOT NULL, + [passwordHash] [varchar](32) NOT NULL, + [passwordSalt] [varchar](32) NOT NULL, + [homeRegion] [bigint] default NULL, + [homeLocationX] [float] default NULL, + [homeLocationY] [float] default NULL, + [homeLocationZ] [float] default NULL, + [homeLookAtX] [float] default NULL, + [homeLookAtY] [float] default NULL, + [homeLookAtZ] [float] default NULL, + [created] [int] NOT NULL, + [lastLogin] [int] NOT NULL, + [userInventoryURI] [varchar](255) default NULL, + [userAssetURI] [varchar](255) default NULL, + [profileCanDoMask] [int] default NULL, + [profileWantDoMask] [int] default NULL, + [profileAboutText] [ntext], + [profileFirstText] [ntext], + [profileImage] [varchar](36) default NULL, + [profileFirstImage] [varchar](36) default NULL, + [webLoginKey] [varchar](36) default NULL, + PRIMARY KEY CLUSTERED +( + [UUID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] + + +CREATE NONCLUSTERED INDEX [usernames] ON [users] +( + [username] ASC, + [lastname] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + + +CREATE TABLE [agents] ( + [UUID] [varchar](36) NOT NULL, + [sessionID] [varchar](36) NOT NULL, + [secureSessionID] [varchar](36) NOT NULL, + [agentIP] [varchar](16) NOT NULL, + [agentPort] [int] NOT NULL, + [agentOnline] [tinyint] NOT NULL, + [loginTime] [int] NOT NULL, + [logoutTime] [int] NOT NULL, + [currentRegion] [varchar](36) NOT NULL, + [currentHandle] [bigint] NOT NULL, + [currentPos] [varchar](64) NOT NULL, + PRIMARY KEY CLUSTERED +( + [UUID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] + + +CREATE NONCLUSTERED INDEX [session] ON [agents] +( + [sessionID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + +CREATE NONCLUSTERED INDEX [ssession] ON [agents] +( + [secureSessionID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + + +CREATE TABLE [dbo].[userfriends]( + [ownerID] [varchar](50) COLLATE Latin1_General_CI_AS NOT NULL, + [friendID] [varchar](50) COLLATE Latin1_General_CI_AS NOT NULL, + [friendPerms] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, + [datetimestamp] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL +) ON [PRIMARY] + +CREATE TABLE [avatarappearance] ( + [Owner] [varchar](36) NOT NULL, + [Serial] int NOT NULL, + [Visual_Params] [image] NOT NULL, + [Texture] [image] NOT NULL, + [Avatar_Height] float NOT NULL, + [Body_Item] [varchar](36) NOT NULL, + [Body_Asset] [varchar](36) NOT NULL, + [Skin_Item] [varchar](36) NOT NULL, + [Skin_Asset] [varchar](36) NOT NULL, + [Hair_Item] [varchar](36) NOT NULL, + [Hair_Asset] [varchar](36) NOT NULL, + [Eyes_Item] [varchar](36) NOT NULL, + [Eyes_Asset] [varchar](36) NOT NULL, + [Shirt_Item] [varchar](36) NOT NULL, + [Shirt_Asset] [varchar](36) NOT NULL, + [Pants_Item] [varchar](36) NOT NULL, + [Pants_Asset] [varchar](36) NOT NULL, + [Shoes_Item] [varchar](36) NOT NULL, + [Shoes_Asset] [varchar](36) NOT NULL, + [Socks_Item] [varchar](36) NOT NULL, + [Socks_Asset] [varchar](36) NOT NULL, + [Jacket_Item] [varchar](36) NOT NULL, + [Jacket_Asset] [varchar](36) NOT NULL, + [Gloves_Item] [varchar](36) NOT NULL, + [Gloves_Asset] [varchar](36) NOT NULL, + [Undershirt_Item] [varchar](36) NOT NULL, + [Undershirt_Asset] [varchar](36) NOT NULL, + [Underpants_Item] [varchar](36) NOT NULL, + [Underpants_Asset] [varchar](36) NOT NULL, + [Skirt_Item] [varchar](36) NOT NULL, + [Skirt_Asset] [varchar](36) NOT NULL, + + PRIMARY KEY CLUSTERED ( + [Owner] + ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] +CREATE TABLE [users] ( + [UUID] [varchar](36) NOT NULL default '', + [username] [varchar](32) NOT NULL, + [lastname] [varchar](32) NOT NULL, + [passwordHash] [varchar](32) NOT NULL, + [passwordSalt] [varchar](32) NOT NULL, + [homeRegion] [bigint] default NULL, + [homeLocationX] [float] default NULL, + [homeLocationY] [float] default NULL, + [homeLocationZ] [float] default NULL, + [homeLookAtX] [float] default NULL, + [homeLookAtY] [float] default NULL, + [homeLookAtZ] [float] default NULL, + [created] [int] NOT NULL, + [lastLogin] [int] NOT NULL, + [userInventoryURI] [varchar](255) default NULL, + [userAssetURI] [varchar](255) default NULL, + [profileCanDoMask] [int] default NULL, + [profileWantDoMask] [int] default NULL, + [profileAboutText] [ntext], + [profileFirstText] [ntext], + [profileImage] [varchar](36) default NULL, + [profileFirstImage] [varchar](36) default NULL, + [webLoginKey] [varchar](36) default NULL, + PRIMARY KEY CLUSTERED +( + [UUID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] + + +CREATE NONCLUSTERED INDEX [usernames] ON [users] +( + [username] ASC, + [lastname] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + + +CREATE TABLE [agents] ( + [UUID] [varchar](36) NOT NULL, + [sessionID] [varchar](36) NOT NULL, + [secureSessionID] [varchar](36) NOT NULL, + [agentIP] [varchar](16) NOT NULL, + [agentPort] [int] NOT NULL, + [agentOnline] [tinyint] NOT NULL, + [loginTime] [int] NOT NULL, + [logoutTime] [int] NOT NULL, + [currentRegion] [varchar](36) NOT NULL, + [currentHandle] [bigint] NOT NULL, + [currentPos] [varchar](64) NOT NULL, + PRIMARY KEY CLUSTERED +( + [UUID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] + + +CREATE NONCLUSTERED INDEX [session] ON [agents] +( + [sessionID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + +CREATE NONCLUSTERED INDEX [ssession] ON [agents] +( + [secureSessionID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + + +CREATE TABLE [dbo].[userfriends]( + [ownerID] [varchar](50) COLLATE Latin1_General_CI_AS NOT NULL, + [friendID] [varchar](50) COLLATE Latin1_General_CI_AS NOT NULL, + [friendPerms] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, + [datetimestamp] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL +) ON [PRIMARY] + +CREATE TABLE [avatarappearance] ( + [Owner] [varchar](36) NOT NULL, + [Serial] int NOT NULL, + [Visual_Params] [image] NOT NULL, + [Texture] [image] NOT NULL, + [Avatar_Height] float NOT NULL, + [Body_Item] [varchar](36) NOT NULL, + [Body_Asset] [varchar](36) NOT NULL, + [Skin_Item] [varchar](36) NOT NULL, + [Skin_Asset] [varchar](36) NOT NULL, + [Hair_Item] [varchar](36) NOT NULL, + [Hair_Asset] [varchar](36) NOT NULL, + [Eyes_Item] [varchar](36) NOT NULL, + [Eyes_Asset] [varchar](36) NOT NULL, + [Shirt_Item] [varchar](36) NOT NULL, + [Shirt_Asset] [varchar](36) NOT NULL, + [Pants_Item] [varchar](36) NOT NULL, + [Pants_Asset] [varchar](36) NOT NULL, + [Shoes_Item] [varchar](36) NOT NULL, + [Shoes_Asset] [varchar](36) NOT NULL, + [Socks_Item] [varchar](36) NOT NULL, + [Socks_Asset] [varchar](36) NOT NULL, + [Jacket_Item] [varchar](36) NOT NULL, + [Jacket_Asset] [varchar](36) NOT NULL, + [Gloves_Item] [varchar](36) NOT NULL, + [Gloves_Asset] [varchar](36) NOT NULL, + [Undershirt_Item] [varchar](36) NOT NULL, + [Undershirt_Asset] [varchar](36) NOT NULL, + [Underpants_Item] [varchar](36) NOT NULL, + [Underpants_Asset] [varchar](36) NOT NULL, + [Skirt_Item] [varchar](36) NOT NULL, + [Skirt_Asset] [varchar](36) NOT NULL, + + PRIMARY KEY CLUSTERED ( + [Owner] + ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] diff --git a/OpenSim/Data/MSSQL/Resources/002_AssetStore.sql b/OpenSim/Data/MSSQL/Resources/002_AssetStore.sql new file mode 100644 index 0000000000..3e245432bf --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/002_AssetStore.sql @@ -0,0 +1,29 @@ +BEGIN TRANSACTION + +CREATE TABLE Tmp_assets + ( + id varchar(36) NOT NULL, + name varchar(64) NOT NULL, + description varchar(64) NOT NULL, + assetType tinyint NOT NULL, + local bit NOT NULL, + temporary bit NOT NULL, + data image NOT NULL + ) ON [PRIMARY] + TEXTIMAGE_ON [PRIMARY] + +IF EXISTS(SELECT * FROM assets) + EXEC('INSERT INTO Tmp_assets (id, name, description, assetType, local, temporary, data) + SELECT id, name, description, assetType, CONVERT(bit, local), CONVERT(bit, temporary), data FROM assets WITH (HOLDLOCK TABLOCKX)') + +DROP TABLE assets + +EXECUTE sp_rename N'Tmp_assets', N'assets', 'OBJECT' + +ALTER TABLE dbo.assets ADD CONSTRAINT + PK__assets__id PRIMARY KEY CLUSTERED + ( + id + ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + +COMMIT diff --git a/OpenSim/Data/MSSQL/Resources/002_UserStore.sql b/OpenSim/Data/MSSQL/Resources/002_UserStore.sql new file mode 100644 index 0000000000..a3b586841a --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/002_UserStore.sql @@ -0,0 +1,18 @@ +BEGIN TRANSACTION + +ALTER TABLE users ADD homeRegionID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000'; +ALTER TABLE users ADD userFlags int NOT NULL default 0; +ALTER TABLE users ADD godLevel int NOT NULL default 0; +ALTER TABLE users ADD customType varchar(32) not null default ''; +ALTER TABLE users ADD partner varchar(36) not null default '00000000-0000-0000-0000-000000000000'; + +COMMIT +BEGIN TRANSACTION + +ALTER TABLE users ADD homeRegionID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000'; +ALTER TABLE users ADD userFlags int NOT NULL default 0; +ALTER TABLE users ADD godLevel int NOT NULL default 0; +ALTER TABLE users ADD customType varchar(32) not null default ''; +ALTER TABLE users ADD partner varchar(36) not null default '00000000-0000-0000-0000-000000000000'; + +COMMIT diff --git a/OpenSim/Data/MSSQL/Resources/003_GridStore.sql b/OpenSim/Data/MSSQL/Resources/003_GridStore.sql new file mode 100644 index 0000000000..e080947665 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/003_GridStore.sql @@ -0,0 +1,22 @@ +BEGIN TRANSACTION + +CREATE NONCLUSTERED INDEX IX_regions_name ON dbo.regions + ( + regionName + ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + +CREATE NONCLUSTERED INDEX IX_regions_handle ON dbo.regions + ( + regionHandle + ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + + +CREATE NONCLUSTERED INDEX IX_regions_override ON dbo.regions + ( + eastOverrideHandle, + westOverrideHandle, + southOverrideHandle, + northOverrideHandle + ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + +COMMIT diff --git a/OpenSim/Data/MSSQL/Resources/003_UserStore.sql b/OpenSim/Data/MSSQL/Resources/003_UserStore.sql new file mode 100644 index 0000000000..c2821e6e9d --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/003_UserStore.sql @@ -0,0 +1,30 @@ +BEGIN TRANSACTION + +CREATE TABLE [avatarattachments] ( + [UUID] varchar(36) NOT NULL + , [attachpoint] int NOT NULL + , [item] varchar(36) NOT NULL + , [asset] varchar(36) NOT NULL) + +CREATE NONCLUSTERED INDEX IX_avatarattachments ON dbo.avatarattachments + ( + UUID + ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + + +COMMIT +BEGIN TRANSACTION + +CREATE TABLE [avatarattachments] ( + [UUID] varchar(36) NOT NULL + , [attachpoint] int NOT NULL + , [item] varchar(36) NOT NULL + , [asset] varchar(36) NOT NULL) + +CREATE NONCLUSTERED INDEX IX_avatarattachments ON dbo.avatarattachments + ( + UUID + ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + + +COMMIT diff --git a/OpenSim/Data/MSSQL/Resources/004_RegionStore.sql b/OpenSim/Data/MSSQL/Resources/004_RegionStore.sql index 4e64901365..15b39a7fcf 100644 --- a/OpenSim/Data/MSSQL/Resources/004_RegionStore.sql +++ b/OpenSim/Data/MSSQL/Resources/004_RegionStore.sql @@ -1,6 +1,6 @@ BEGIN TRANSACTION -CREATE TABLE dbo.Tmp_primitems +CREATE TABLE Tmp_primitems ( itemID varchar(36) NOT NULL, primID varchar(36) NULL, @@ -22,15 +22,15 @@ CREATE TABLE dbo.Tmp_primitems groupPermissions int NULL ) ON [PRIMARY] -IF EXISTS(SELECT * FROM dbo.primitems) - EXEC('INSERT INTO dbo.Tmp_primitems (itemID, primID, assetID, parentFolderID, invType, assetType, name, description, creationDate, creatorID, ownerID, lastOwnerID, groupID, nextPermissions, currentPermissions, basePermissions, everyonePermissions, groupPermissions) +IF EXISTS(SELECT * FROM primitems) + EXEC('INSERT INTO Tmp_primitems (itemID, primID, assetID, parentFolderID, invType, assetType, name, description, creationDate, creatorID, ownerID, lastOwnerID, groupID, nextPermissions, currentPermissions, basePermissions, everyonePermissions, groupPermissions) SELECT CONVERT(varchar(36), itemID), CONVERT(varchar(36), primID), CONVERT(varchar(36), assetID), CONVERT(varchar(36), parentFolderID), invType, assetType, name, description, creationDate, CONVERT(varchar(36), creatorID), CONVERT(varchar(36), ownerID), CONVERT(varchar(36), lastOwnerID), CONVERT(varchar(36), groupID), nextPermissions, currentPermissions, basePermissions, everyonePermissions, groupPermissions') -DROP TABLE dbo.primitems +DROP TABLE primitems -EXECUTE sp_rename N'dbo.Tmp_primitems', N'primitems', 'OBJECT' +EXECUTE sp_rename N'Tmp_primitems', N'primitems', 'OBJECT' -ALTER TABLE dbo.primitems ADD CONSTRAINT +ALTER TABLE primitems ADD CONSTRAINT PK__primitems__0A688BB1 PRIMARY KEY CLUSTERED ( itemID diff --git a/OpenSim/Data/MSSQL/Resources/004_UserStore.sql b/OpenSim/Data/MSSQL/Resources/004_UserStore.sql new file mode 100644 index 0000000000..f3e223e90f --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/004_UserStore.sql @@ -0,0 +1,58 @@ +BEGIN TRANSACTION + +CREATE TABLE Tmp_userfriends + ( + ownerID varchar(36) NOT NULL, + friendID varchar(36) NOT NULL, + friendPerms int NOT NULL, + datetimestamp int NOT NULL + ) ON [PRIMARY] + +IF EXISTS(SELECT * FROM userfriends) + EXEC('INSERT INTO dbo.Tmp_userfriends (ownerID, friendID, friendPerms, datetimestamp) + SELECT CONVERT(varchar(36), ownerID), CONVERT(varchar(36), friendID), CONVERT(int, friendPerms), CONVERT(int, datetimestamp) FROM dbo.userfriends WITH (HOLDLOCK TABLOCKX)') + +DROP TABLE dbo.userfriends + +EXECUTE sp_rename N'Tmp_userfriends', N'userfriends', 'OBJECT' + +CREATE NONCLUSTERED INDEX IX_userfriends_ownerID ON userfriends + ( + ownerID + ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + +CREATE NONCLUSTERED INDEX IX_userfriends_friendID ON userfriends + ( + friendID + ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + +COMMIT +BEGIN TRANSACTION + +CREATE TABLE Tmp_userfriends + ( + ownerID varchar(36) NOT NULL, + friendID varchar(36) NOT NULL, + friendPerms int NOT NULL, + datetimestamp int NOT NULL + ) ON [PRIMARY] + +IF EXISTS(SELECT * FROM dbo.userfriends) + EXEC('INSERT INTO dbo.Tmp_userfriends (ownerID, friendID, friendPerms, datetimestamp) + SELECT CONVERT(varchar(36), ownerID), CONVERT(varchar(36), friendID), CONVERT(int, friendPerms), CONVERT(int, datetimestamp) FROM dbo.userfriends WITH (HOLDLOCK TABLOCKX)') + +DROP TABLE dbo.userfriends + +EXECUTE sp_rename N'Tmp_userfriends', N'userfriends', 'OBJECT' + +CREATE NONCLUSTERED INDEX IX_userfriends_ownerID ON userfriends + ( + ownerID + ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + +CREATE NONCLUSTERED INDEX IX_userfriends_friendID ON userfriends + ( + friendID + ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + +COMMIT diff --git a/OpenSim/Data/MSSQL/Resources/005_RegionStore.sql b/OpenSim/Data/MSSQL/Resources/005_RegionStore.sql index 74e9d85365..eb0862c9bd 100644 --- a/OpenSim/Data/MSSQL/Resources/005_RegionStore.sql +++ b/OpenSim/Data/MSSQL/Resources/005_RegionStore.sql @@ -1,6 +1,6 @@ BEGIN TRANSACTION -CREATE TABLE dbo.Tmp_primshapes +CREATE TABLE Tmp_primshapes ( UUID varchar(36) NOT NULL, Shape int NULL, @@ -32,18 +32,18 @@ CREATE TABLE dbo.Tmp_primshapes ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] -IF EXISTS(SELECT * FROM dbo.primshapes) - EXEC('INSERT INTO dbo.Tmp_primshapes (UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin, ProfileEnd, ProfileCurve, ProfileHollow, State, Texture, ExtraParams) - SELECT CONVERT(varchar(36), UUID), Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin, ProfileEnd, ProfileCurve, ProfileHollow, State, Texture, ExtraParams FROM dbo.primshapes WITH (HOLDLOCK TABLOCKX)') +IF EXISTS(SELECT * FROM primshapes) + EXEC('INSERT INTO Tmp_primshapes (UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin, ProfileEnd, ProfileCurve, ProfileHollow, State, Texture, ExtraParams) + SELECT CONVERT(varchar(36), UUID), Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin, ProfileEnd, ProfileCurve, ProfileHollow, State, Texture, ExtraParams FROM primshapes WITH (HOLDLOCK TABLOCKX)') -DROP TABLE dbo.primshapes +DROP TABLE primshapes -EXECUTE sp_rename N'dbo.Tmp_primshapes', N'primshapes', 'OBJECT' +EXECUTE sp_rename N'Tmp_primshapes', N'primshapes', 'OBJECT' -ALTER TABLE dbo.primshapes ADD CONSTRAINT +ALTER TABLE primshapes ADD CONSTRAINT PK__primshapes__0880433F PRIMARY KEY CLUSTERED ( UUID ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -COMMIT \ No newline at end of file +COMMIT diff --git a/OpenSim/Data/MySQL/MySQLGridData.cs b/OpenSim/Data/MySQL/MySQLGridData.cs index 4e4d32c11e..1155ae3a9c 100644 --- a/OpenSim/Data/MySQL/MySQLGridData.cs +++ b/OpenSim/Data/MySQL/MySQLGridData.cs @@ -434,7 +434,7 @@ namespace OpenSim.Data.MySQL /// the sim UUID /// Successful? //public DataResponse DeleteProfile(RegionProfileData profile) - public DataResponse DeleteProfile(string uuid) + override public DataResponse DeleteProfile(string uuid) { MySQLSuperManager dbm = GetLockedConnection(); diff --git a/OpenSim/Data/SQLite/SQLiteGridData.cs b/OpenSim/Data/SQLite/SQLiteGridData.cs index f715c0e72f..3e1c67a002 100644 --- a/OpenSim/Data/SQLite/SQLiteGridData.cs +++ b/OpenSim/Data/SQLite/SQLiteGridData.cs @@ -210,6 +210,25 @@ namespace OpenSim.Data.SQLite return AddProfile(profile); } + /// + /// Deletes a sim profile from the database + /// + /// the sim UUID + /// Successful? + //public DataResponse DeleteProfile(RegionProfileData profile) + override public DataResponse DeleteProfile(string uuid) + { + Dictionary param = new Dictionary(); + param["uuid"] = uuid; + + IDbCommand result = database.Query("DELETE FROM regions WHERE uuid = @uuid", param); + if (result.ExecuteNonQuery() > 0) + { + return DataResponse.RESPONSE_OK; + } + return DataResponse.RESPONSE_ERROR; + } + /// /// DEPRECATED. Attempts to authenticate a region by comparing a shared secret. /// diff --git a/OpenSim/Grid/GridServer/GridManager.cs b/OpenSim/Grid/GridServer/GridManager.cs index 2e0767ec24..b437f59987 100644 --- a/OpenSim/Grid/GridServer/GridManager.cs +++ b/OpenSim/Grid/GridServer/GridManager.cs @@ -136,8 +136,9 @@ namespace OpenSim.Grid.GridServer { return plugin.GetProfileByHandle(handle); } - catch + catch (Exception ex) { + m_log.Debug("[storage]: " + ex.Message); m_log.Warn("[storage]: Unable to find region " + handle.ToString() + " via " + plugin.Name); } } @@ -500,14 +501,11 @@ namespace OpenSim.Grid.GridServer RegionProfileData neighbour; Hashtable NeighbourBlock; - bool fastMode = false; // Only compatible with MySQL right now + //First use the fast method. (not implemented in SQLLite) + Dictionary neighbours = GetRegions(sim.regionLocX - 1, sim.regionLocY - 1, sim.regionLocX + 1, sim.regionLocY + 1); - if (fastMode) + if (neighbours.Count > 0) { - Dictionary neighbours = - GetRegions(sim.regionLocX - 1, sim.regionLocY - 1, sim.regionLocX + 1, - sim.regionLocY + 1); - foreach (KeyValuePair aSim in neighbours) { NeighbourBlock = new Hashtable(); @@ -657,8 +655,7 @@ namespace OpenSim.Grid.GridServer //TheSim = GetRegion(new UUID((string) requestData["UUID"])); uuid = requestData["UUID"].ToString(); m_log.InfoFormat("[LOGOUT]: Logging out region: {0}", uuid); - - // logToDB((new UUID((string)requestData["UUID"])).ToString(),"XmlRpcDeleteRegionMethod","", 5,"Attempting delete with UUID."); +// logToDB((new LLUUID((string)requestData["UUID"])).ToString(),"XmlRpcDeleteRegionMethod","", 5,"Attempting delete with UUID."); } else { @@ -671,9 +668,12 @@ namespace OpenSim.Grid.GridServer //OpenSim.Data.MySQL.MySQLGridData dbengine = new OpenSim.Data.MySQL.MySQLGridData(); try { - MySQLGridData mysqldata = (MySQLGridData)(plugin); + //Nice are we not using multiple databases? + //MySQLGridData mysqldata = (MySQLGridData)(plugin); + //DataResponse insertResponse = mysqldata.DeleteProfile(TheSim); - DataResponse insertResponse = mysqldata.DeleteProfile(uuid); + DataResponse insertResponse = plugin.DeleteProfile(uuid); + switch (insertResponse) { case DataResponse.RESPONSE_OK: @@ -696,7 +696,7 @@ namespace OpenSim.Grid.GridServer } catch (Exception) { - m_log.Error("storage Unable to delete region " + uuid + " via MySQL"); + m_log.Error("storage Unable to delete region " + uuid + " via " + plugin.Name); //MainLog.Instance.Warn("storage", e.ToString()); } }