From b6bb5f944f19b330656105ff79cd5ca3f2d5c242 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 1 Sep 2008 17:10:01 +0000 Subject: Mantis #2095 Thank you, RuudL, for a complete adaptation of migration and estate data to MSSQL, and the updating of the RegionData handling in MSSQL. --- OpenSim/Data/MSSQL/MSSQLEstateData.cs | 434 ++++ OpenSim/Data/MSSQL/MSSQLManager.cs | 116 +- OpenSim/Data/MSSQL/MSSQLMigration.cs | 45 + OpenSim/Data/MSSQL/MSSQLRegionData.cs | 2414 ++++++++++------------ OpenSim/Data/MSSQL/Resources/001_EstateStore.sql | 85 + OpenSim/Data/MSSQL/Resources/002_RegionStore.sql | 50 + OpenSim/Data/MSSQL/Resources/003_RegionStore.sql | 67 + OpenSim/Data/MSSQL/Resources/004_RegionStore.sql | 40 + OpenSim/Data/MSSQL/Resources/005_RegionStore.sql | 49 + OpenSim/Data/MSSQL/Resources/006_RegionStore.sql | 36 + OpenSim/Data/Migration.cs | 10 +- 11 files changed, 1973 insertions(+), 1373 deletions(-) create mode 100644 OpenSim/Data/MSSQL/MSSQLEstateData.cs create mode 100644 OpenSim/Data/MSSQL/MSSQLMigration.cs create mode 100644 OpenSim/Data/MSSQL/Resources/001_EstateStore.sql create mode 100644 OpenSim/Data/MSSQL/Resources/002_RegionStore.sql create mode 100644 OpenSim/Data/MSSQL/Resources/003_RegionStore.sql create mode 100644 OpenSim/Data/MSSQL/Resources/004_RegionStore.sql create mode 100644 OpenSim/Data/MSSQL/Resources/005_RegionStore.sql create mode 100644 OpenSim/Data/MSSQL/Resources/006_RegionStore.sql (limited to 'OpenSim') diff --git a/OpenSim/Data/MSSQL/MSSQLEstateData.cs b/OpenSim/Data/MSSQL/MSSQLEstateData.cs new file mode 100644 index 0000000..ca4691c --- /dev/null +++ b/OpenSim/Data/MSSQL/MSSQLEstateData.cs @@ -0,0 +1,434 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Reflection; +using libsecondlife; +using log4net; +using OpenSim.Framework; +using OpenSim.Region.Environment.Interfaces; + +namespace OpenSim.Data.MSSQL +{ + public class MSSQLEstateData : IEstateDataStore + { + private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private MSSQLManager _Database; + + private FieldInfo[] _Fields; + private Dictionary _FieldMap = new Dictionary(); + + #region Public methods + + /// + /// Initialises the estatedata class. + /// + /// connectionString. + public void Initialise(string connectionString) + { + if (string.IsNullOrEmpty(connectionString)) + { + _Database = new MSSQLManager(connectionString); + } + else + { + //TODO when can this be deleted + 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"); + + _Database = + new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, + settingPassword); + } + + //Migration settings + using (SqlConnection connection = _Database.DatabaseConnection()) + { + Assembly assem = GetType().Assembly; + MSSQLMigration migration = new MSSQLMigration(connection, assem, "EstateStore"); + + migration.Update(); + + connection.Close(); + } + + //Interesting way to get parameters! Maybe implement that also with other types + Type t = typeof(EstateSettings); + _Fields = t.GetFields(BindingFlags.NonPublic | + BindingFlags.Instance | + BindingFlags.DeclaredOnly); + + foreach (FieldInfo f in _Fields) + { + if (f.Name.Substring(0, 2) == "m_") + _FieldMap[f.Name.Substring(2)] = f; + } + } + + /// + /// Loads the estate settings. + /// + /// region ID. + /// + public EstateSettings LoadEstateSettings(LLUUID regionID) + { + EstateSettings es = new EstateSettings(); + + string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = @RegionID"; + + bool insertEstate = false; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.AddWithValue("@RegionID", regionID.ToString()); + + using (IDataReader reader = cmd.ExecuteReader()) + { + if (reader.Read()) + { + foreach (string name in FieldList) + { + if (_FieldMap[name].GetValue(es) is bool) + { + int v = Convert.ToInt32(reader[name]); + if (v != 0) + _FieldMap[name].SetValue(es, true); + else + _FieldMap[name].SetValue(es, false); + } + else if (_FieldMap[name].GetValue(es) is LLUUID) + { + LLUUID uuid; + LLUUID.TryParse(reader[name].ToString(), out uuid); + + _FieldMap[name].SetValue(es, uuid); + } + else + { + _FieldMap[name].SetValue(es, reader[name]); + } + } + } + else + { + insertEstate = true; + } + } + } + + + if (insertEstate) + { + List names = new List(FieldList); + + names.Remove("EstateID"); + + sql = string.Format("insert into estate_settings ({0}) values ( @{1})", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray())); + + //_Log.Debug("[DB ESTATE]: SQL: " + sql); + using (SqlConnection connection = _Database.DatabaseConnection()) + { + using (SqlCommand insertCommand = connection.CreateCommand()) + { + insertCommand.CommandText = sql + " SET @ID = SCOPE_IDENTITY()"; + + foreach (string name in names) + { + if (_FieldMap[name].GetValue(es) is bool) + { + SqlParameter tempBool = new SqlParameter("@" + name, SqlDbType.Bit); + + if ((bool) _FieldMap[name].GetValue(es)) + tempBool.Value = 1; + else + tempBool.Value = 0; + + insertCommand.Parameters.Add(tempBool); + } + else + { + //cmd.Parameters.AddWithValue("@" + name, _FieldMap[name].GetValue(es)); + SqlParameter tempPar = new SqlParameter("@" + name, + _Database.DbtypeFromType(_FieldMap[name].FieldType)); + tempPar.Value = _FieldMap[name].GetValue(es).ToString(); + + insertCommand.Parameters.Add(tempPar); + } + } + + + SqlParameter idParameter = new SqlParameter("@ID", SqlDbType.Int); + idParameter.Direction = ParameterDirection.Output; + insertCommand.Parameters.Add(idParameter); + + insertCommand.ExecuteNonQuery(); + + es.EstateID = Convert.ToUInt32(idParameter.Value); + } + } + + using (AutoClosingSqlCommand cmd = _Database.Query("insert into estate_map values (@RegionID, @EstateID)")) + { + cmd.Parameters.AddWithValue("@RegionID", regionID.ToString()); + cmd.Parameters.AddWithValue("@EstateID", es.EstateID); + // This will throw on dupe key + try + { + cmd.ExecuteNonQuery(); + } + catch (Exception) + { + _Log.Debug("[ESTATE DB]: Error inserting regionID and EstateID in estate_map"); + } + } + + // Munge and transfer the ban list + // + + sql = string.Format("insert into estateban select {0}, bannedUUID, bannedIp, bannedIpHostMask, '' from regionban where regionban.regionUUID = @UUID", es.EstateID); + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.AddWithValue("@UUID", regionID); + try + { + + cmd.ExecuteNonQuery(); + } + catch (Exception) + { + _Log.Debug("[ESTATE DB]: Error setting up estateban from regionban"); + } + } + + //TODO check if this is needed?? + es.Save(); + } + + LoadBanList(es); + + es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers"); + es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users"); + es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups"); + + //Set event + es.OnSave += StoreEstateSettings; + return es; + } + + /// + /// Stores the estate settings. + /// + /// estate settings + public void StoreEstateSettings(EstateSettings es) + { + List names = new List(FieldList); + + names.Remove("EstateID"); + + string sql = string.Format("UPDATE estate_settings SET ") ; // ({0}) values ( @{1}) WHERE EstateID = @EstateID", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray())); + foreach (string name in names) + { + sql += name + " = @" + name + ", "; + } + sql = sql.Remove(sql.LastIndexOf(",")); + sql += " WHERE EstateID = @EstateID"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + foreach (string name in names) + { + if (_FieldMap[name].GetValue(es) is bool) + { + SqlParameter tempBool = new SqlParameter("@" + name, SqlDbType.Bit); + + if ((bool)_FieldMap[name].GetValue(es)) + tempBool.Value = 1; + else + tempBool.Value = 0; + + cmd.Parameters.Add(tempBool); + } + else + { + //cmd.Parameters.AddWithValue("@" + name, _FieldMap[name].GetValue(es)); + SqlParameter tempPar = new SqlParameter("@" + name, + _Database.DbtypeFromType(_FieldMap[name].FieldType)); + tempPar.Value = _FieldMap[name].GetValue(es).ToString(); + + cmd.Parameters.Add(tempPar); + } + } + + + SqlParameter idParameter = new SqlParameter("@EstateID", SqlDbType.Int); + idParameter.Value = es.EstateID; + cmd.Parameters.Add(idParameter); + + cmd.ExecuteNonQuery(); + } + + SaveBanList(es); + SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers); + SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess); + SaveUUIDList(es.EstateID, "estate_groups", es.EstateGroups); + } + + #endregion + + #region Private methods + + private string[] FieldList + { + get { return new List(_FieldMap.Keys).ToArray(); } + } + + private void LoadBanList(EstateSettings es) + { + es.ClearBans(); + + string sql = "select bannedUUID from estateban where EstateID = @EstateID"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + SqlParameter idParameter = new SqlParameter("@EstateID", SqlDbType.Int); + idParameter.Value = es.EstateID; + cmd.Parameters.Add(idParameter); + + using (IDataReader reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + EstateBan eb = new EstateBan(); + + LLUUID uuid; + LLUUID.TryParse(reader["bannedUUID"].ToString(), out uuid); + + eb.bannedUUID = uuid; + eb.bannedIP = "0.0.0.0"; + eb.bannedIPHostMask = "0.0.0.0"; + es.AddBan(eb); + } + } + } + } + + private LLUUID[] LoadUUIDList(uint estateID, string table) + { + List uuids = new List(); + + string sql = string.Format("select uuid from {0} where EstateID = @EstateID", table); + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID)); + + using (IDataReader reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + // EstateBan eb = new EstateBan(); + + LLUUID uuid; + LLUUID.TryParse(reader["uuid"].ToString(), out uuid); + + uuids.Add(uuid); + } + } + } + + return uuids.ToArray(); + } + + private void SaveBanList(EstateSettings es) + { + //Delete first + string sql = "delete from estateban where EstateID = @EstateID"; + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID)); + cmd.ExecuteNonQuery(); + } + + //Insert after + sql = "insert into estateban (EstateID, bannedUUID) values ( @EstateID, @bannedUUID )"; + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + foreach (EstateBan b in es.EstateBans) + { + cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID)); + + cmd.Parameters.Add(_Database.CreateParameter("@bannedUUID", b.bannedUUID)); + + cmd.ExecuteNonQuery(); + + cmd.Parameters.Clear(); + } + } + } + + private void SaveUUIDList(uint estateID, string table, LLUUID[] data) + { + //Delete first + string sql = string.Format("delete from {0} where EstateID = @EstateID", table); + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID)); + cmd.ExecuteNonQuery(); + } + + sql = string.Format("insert into {0} (EstateID, uuid) values ( @EstateID, @uuid )", table); + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID)); + + bool createParamOnce = true; + + foreach (LLUUID uuid in data) + { + if (createParamOnce) + { + cmd.Parameters.Add(_Database.CreateParameter("@uuid", uuid)); + createParamOnce = false; + } + else + cmd.Parameters["@uuid"].Value = uuid.ToString(); + + cmd.ExecuteNonQuery(); + } + } + } + #endregion + } +} diff --git a/OpenSim/Data/MSSQL/MSSQLManager.cs b/OpenSim/Data/MSSQL/MSSQLManager.cs index 1a053d5..535cf33 100644 --- a/OpenSim/Data/MSSQL/MSSQLManager.cs +++ b/OpenSim/Data/MSSQL/MSSQLManager.cs @@ -64,9 +64,20 @@ namespace OpenSim.Data.MSSQL connectionString = builder.ToString(); } - private SqlConnection createConnection() + /// + /// Initialize the manager and set the connectionstring + /// + /// + public MSSQLManager(string connection) + { + connectionString = connection; + } + + public SqlConnection DatabaseConnection() { SqlConnection conn = new SqlConnection(connectionString); + + //TODO is this good??? Opening connection here conn.Open(); return conn; @@ -186,6 +197,105 @@ namespace OpenSim.Data.MSSQL } } + /// + /// Type conversion to a SQLDbType functions + /// + /// + /// + internal SqlDbType DbtypeFromType(Type type) + { + if (type == typeof(string)) + { + return SqlDbType.VarChar; + } + if (type == typeof(double)) + { + return SqlDbType.Float; + } + if (type == typeof(int)) + { + return SqlDbType.Int; + } + if (type == typeof(bool)) + { + return SqlDbType.Bit; + } + if (type == typeof(LLUUID)) + { + return SqlDbType.VarChar; + } + if (type == typeof(Byte[])) + { + return SqlDbType.Image; + } + if (type == typeof(uint)) + { + return SqlDbType.Int; + } + return SqlDbType.VarChar; + } + + /// + /// Creates value for parameter. + /// + /// The value. + /// + private static object CreateParameterValue(object value) + { + Type valueType = value.GetType(); + + if (valueType == typeof(LLUUID)) + { + return value.ToString(); + } + if (valueType == typeof(bool)) + { + return (bool)value ? 1 : 0; + } + if (valueType == typeof(Byte[])) + { + return value; + } + return value; + } + + /// + /// Create a parameter for a command + /// + /// Name of the parameter. + /// parameter object. + /// + internal SqlParameter CreateParameter(string parameterName, object parameterObject) + { + return CreateParameter(parameterName, parameterObject, false); + } + + /// + /// Creates the parameter for a command. + /// + /// Name of the parameter. + /// parameter object. + /// if set to true parameter is a output parameter + /// + internal SqlParameter CreateParameter(string parameterName, object parameterObject, bool parameterOut) + { + //Tweak so we dont always have to add @ sign + if (!parameterName.StartsWith("@")) parameterName = "@" + parameterName; + + SqlParameter parameter = new SqlParameter(parameterName, DbtypeFromType(parameterObject.GetType())); + + if (parameterOut) + { + parameter.Direction = ParameterDirection.Output; + } + else + { + parameter.Direction = ParameterDirection.Input; + parameter.Value = CreateParameterValue(parameterObject); + } + + return parameter; + } private static readonly Dictionary emptyDictionary = new Dictionary(); internal AutoClosingSqlCommand Query(string sql) @@ -201,7 +311,7 @@ namespace OpenSim.Data.MSSQL /// A Sql DB Command internal AutoClosingSqlCommand Query(string sql, Dictionary parameters) { - SqlCommand dbcommand = createConnection().CreateCommand(); + SqlCommand dbcommand = DatabaseConnection().CreateCommand(); dbcommand.CommandText = sql; foreach (KeyValuePair param in parameters) { @@ -211,8 +321,6 @@ namespace OpenSim.Data.MSSQL return new AutoClosingSqlCommand(dbcommand); } - - /// /// Runs a database reader object and returns a region row /// diff --git a/OpenSim/Data/MSSQL/MSSQLMigration.cs b/OpenSim/Data/MSSQL/MSSQLMigration.cs new file mode 100644 index 0000000..67fc606 --- /dev/null +++ b/OpenSim/Data/MSSQL/MSSQLMigration.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Reflection; +using System.Text; + +namespace OpenSim.Data.MSSQL +{ + public class MSSQLMigration : Migration + { + public MSSQLMigration(DbConnection conn, Assembly assem, string type) : base(conn, assem, type) + { + } + + public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type) : base(conn, assem, subtype, type) + { + } + + protected override int FindVersion(DbConnection conn, string type) + { + int version = 0; + using (DbCommand cmd = conn.CreateCommand()) + { + try + { + cmd.CommandText = "select top 1 version from migrations where name = '" + type + "' order by version desc"; //Must be + using (IDataReader reader = cmd.ExecuteReader()) + { + if (reader.Read()) + { + version = Convert.ToInt32(reader["version"]); + } + reader.Close(); + } + } + catch + { + // Something went wrong, so we're version 0 + } + } + return version; + } + } +} diff --git a/OpenSim/Data/MSSQL/MSSQLRegionData.cs b/OpenSim/Data/MSSQL/MSSQLRegionData.cs index 3f85fef..7af3e7e 100644 --- a/OpenSim/Data/MSSQL/MSSQLRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLRegionData.cs @@ -42,225 +42,155 @@ namespace OpenSim.Data.MSSQL /// /// A MSSQL Interface for the Region Server. /// - public class MSSQLDataStore : IRegionDataStore + public class MSSQLRegionDataStore : IRegionDataStore { // private static FileSystemDataStore Instance = new FileSystemDataStore(); - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private const string m_primSelect = "select * from prims"; - private const string m_shapeSelect = "select * from primshapes"; - private const string m_itemsSelect = "select * from primitems"; - private const string m_terrainSelect = "select top 1 * from terrain"; - private const string m_landSelect = "select * from land"; - private const string m_landAccessListSelect = "select * from landaccesslist"; - - private DataSet m_dataSet; - private SqlDataAdapter m_primDataAdapter; - private SqlDataAdapter m_shapeDataAdapter; - private SqlDataAdapter m_itemsDataAdapter; - private SqlConnection m_connection; - private SqlDataAdapter m_terrainDataAdapter; - private SqlDataAdapter m_landDataAdapter; - private SqlDataAdapter m_landAccessListDataAdapter; - - private DataTable m_primTable; - private DataTable m_shapeTable; - private DataTable m_itemsTable; - private DataTable m_terrainTable; - private DataTable m_landTable; - private DataTable m_landAccessListTable; - - /// Temporary attribute while this is experimental - - /*********************************************************************** - * - * Public Interface Functions - * - **********************************************************************/ + private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + 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))"; + 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)))"; + + private DataSet _PrimsDataSet; + private SqlDataAdapter _PrimDataAdapter; + private SqlDataAdapter _ShapeDataAdapter; + private SqlDataAdapter _ItemsDataAdapter; /// - /// see IRegionDataStore + /// Initialises the region datastore /// - /// + /// The connection string. public void Initialise(string connectionString) { - // Instance.Initialise("", true); - - m_dataSet = new DataSet(); - - m_log.Info("[REGION DB]: MSSql - connecting: " + connectionString); - m_connection = new SqlConnection(connectionString); - - SqlCommand primSelectCmd = new SqlCommand(m_primSelect, m_connection); - m_primDataAdapter = new SqlDataAdapter(primSelectCmd); - - SqlCommand shapeSelectCmd = new SqlCommand(m_shapeSelect, m_connection); - m_shapeDataAdapter = new SqlDataAdapter(shapeSelectCmd); - - SqlCommand itemsSelectCmd = new SqlCommand(m_itemsSelect, m_connection); - m_itemsDataAdapter = new SqlDataAdapter(itemsSelectCmd); - - SqlCommand terrainSelectCmd = new SqlCommand(m_terrainSelect, m_connection); - m_terrainDataAdapter = new SqlDataAdapter(terrainSelectCmd); + if (string.IsNullOrEmpty(connectionString)) + { + //Add MSSQLManager (dont know if we need it) + _Database = new MSSQLManager(connectionString); + } + else + { + 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"); + + _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(); + } - SqlCommand landSelectCmd = new SqlCommand(m_landSelect, m_connection); - m_landDataAdapter = new SqlDataAdapter(landSelectCmd); + //Migration settings + Assembly assem = GetType().Assembly; - SqlCommand landAccessListSelectCmd = new SqlCommand(m_landAccessListSelect, m_connection); - m_landAccessListDataAdapter = new SqlDataAdapter(landAccessListSelectCmd); + using (SqlConnection connection = _Database.DatabaseConnection()) + { + MSSQLMigration m = new MSSQLMigration(connection, assem, "RegionStore"); - TestTables(m_connection); + m.Update(); - lock (m_dataSet) - { - m_primTable = createPrimTable(); - m_dataSet.Tables.Add(m_primTable); - setupPrimCommands(m_primDataAdapter, m_connection); - m_primDataAdapter.Fill(m_primTable); - - m_shapeTable = createShapeTable(); - m_dataSet.Tables.Add(m_shapeTable); - setupShapeCommands(m_shapeDataAdapter, m_connection); - m_shapeDataAdapter.Fill(m_shapeTable); - - m_itemsTable = createItemsTable(); - m_dataSet.Tables.Add(m_itemsTable); - SetupItemsCommands(m_itemsDataAdapter, m_connection); - m_itemsDataAdapter.Fill(m_itemsTable); - - m_terrainTable = createTerrainTable(); - m_dataSet.Tables.Add(m_terrainTable); - setupTerrainCommands(m_terrainDataAdapter, m_connection); - m_terrainDataAdapter.Fill(m_terrainTable); - - m_landTable = createLandTable(); - m_dataSet.Tables.Add(m_landTable); - setupLandCommands(m_landDataAdapter, m_connection); - m_landDataAdapter.Fill(m_landTable); - - m_landAccessListTable = createLandAccessListTable(); - m_dataSet.Tables.Add(m_landAccessListTable); - setupLandAccessCommands(m_landAccessListDataAdapter, m_connection); - m_landAccessListDataAdapter.Fill(m_landAccessListTable); - } - } + //Create Dataset. Not filled!!! + _PrimsDataSet = new DataSet("primsdata"); - public void StoreRegionSettings(RegionSettings rs) - { - } + using (SqlCommand primSelectCmd = new SqlCommand(_PrimSelect, connection)) + { + primSelectCmd.Parameters.AddWithValue("@RegionUUID", ""); + primSelectCmd.Parameters.AddWithValue("@SceneGroupID", "%"); + primSelectCmd.Parameters.AddWithValue("@UUID", ""); + _PrimDataAdapter = new SqlDataAdapter(primSelectCmd); - public RegionSettings LoadRegionSettings(LLUUID regionUUID) - { - return null; - } + DataTable primDataTable = new DataTable("prims"); + _PrimDataAdapter.Fill(primDataTable); + primDataTable.PrimaryKey = new DataColumn[] { primDataTable.Columns["UUID"] }; + _PrimsDataSet.Tables.Add(primDataTable); - /// - /// - /// - /// - /// - public void StoreObject(SceneObjectGroup obj, LLUUID regionUUID) - { - // Instance.StoreObject(obj, regionUUID); + SetupCommands(_PrimDataAdapter); //, connection); + //SetupPrimCommands(_PrimDataAdapter, connection); - lock (m_dataSet) - { - foreach (SceneObjectPart prim in obj.Children.Values) - { - if ((prim.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.Physics) == 0 - && (prim.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.Temporary) == 0 - && (prim.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.TemporaryOnRez) == 0) - { - //m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); - addPrim(prim, obj.UUID, regionUUID); - } - else - { - // m_log.Info("[DATASTORE]: Ignoring Physical obj: " + obj.UUID + " in region: " + regionUUID); - } + primDataTable.Clear(); } - } - Commit(); - } + using (SqlCommand shapeSelectCmd = new SqlCommand(_ShapeSelect, connection)) + { + shapeSelectCmd.Parameters.AddWithValue("@RegionUUID", ""); + shapeSelectCmd.Parameters.AddWithValue("@SceneGroupID", "%"); + shapeSelectCmd.Parameters.AddWithValue("@UUID", ""); + _ShapeDataAdapter = new SqlDataAdapter(shapeSelectCmd); - /// - /// - /// - /// - /// - public void RemoveObject(LLUUID obj, LLUUID regionUUID) - { - // Instance.RemoveObject(obj, regionUUID); + DataTable shapeDataTable = new DataTable("primshapes"); + _ShapeDataAdapter.Fill(shapeDataTable); + shapeDataTable.PrimaryKey = new DataColumn[] { shapeDataTable.Columns["UUID"] }; + _PrimsDataSet.Tables.Add(shapeDataTable); - m_log.InfoFormat("[REGION DB]: Removing obj: {0} from region: {1}", obj.UUID, regionUUID); + SetupCommands(_ShapeDataAdapter); //, connection); + //SetupShapeCommands(_ShapeDataAdapter, connection); - DataTable prims = m_primTable; - DataTable shapes = m_shapeTable; + shapeDataTable.Clear(); + } - string selectExp = "SceneGroupID = '" + obj.ToString() + "'"; - lock (m_dataSet) - { - foreach (DataRow row in prims.Select(selectExp)) + using (SqlCommand itemSelectCmd = new SqlCommand(_ItemsSelect, connection)) { - // Remove shapes row - LLUUID uuid = new LLUUID((string)row["UUID"]); + itemSelectCmd.Parameters.AddWithValue("@RegionUUID", ""); + itemSelectCmd.Parameters.AddWithValue("@SceneGroupID", "%"); + itemSelectCmd.Parameters.AddWithValue("@UUID", ""); + _ItemsDataAdapter = new SqlDataAdapter(itemSelectCmd); - DataRow shapeRow = shapes.Rows.Find(uuid.UUID); - if (shapeRow != null) - { - shapeRow.Delete(); - } + DataTable itemsDataTable = new DataTable("primitems"); + _ItemsDataAdapter.Fill(itemsDataTable); + itemsDataTable.PrimaryKey = new DataColumn[] { itemsDataTable.Columns["itemID"] }; + _PrimsDataSet.Tables.Add(itemsDataTable); - RemoveItems(new LLUUID((string)row["UUID"])); + SetupCommands(_ItemsDataAdapter); //, connection); + //SetupItemsCommands(_ItemsDataAdapter, connection); - // Remove prim row - row.Delete(); + itemsDataTable.Clear(); } - } - - Commit(); - } - /// - /// Remove all persisted items of the given prim. - /// The caller must acquire the necessrary synchronization locks and commit or rollback changes. - /// - /// The item UUID - private void RemoveItems(LLUUID uuid) - { - String sql = String.Format("primID = '{0}'", uuid); - DataRow[] itemRows = m_itemsTable.Select(sql); - - foreach (DataRow itemRow in itemRows) - { - itemRow.Delete(); + connection.Close(); } + + //After this we have a empty fully configured DataSet. } /// - /// Load persisted objects from region storage. + /// Loads the objects present in the region. /// - /// The region UUID + /// The region UUID. + /// public List LoadObjects(LLUUID regionUUID) { - // return Instance.LoadObjects(regionUUID); - Dictionary createdObjects = new Dictionary(); - List retvals = new List(); + //Retrieve all values of current region + RetrievePrimsDataForRegion(regionUUID, LLUUID.Zero, ""); - DataTable prims = m_primTable; - DataTable shapes = m_shapeTable; + List retvals = new List(); - string byRegion = "RegionUUID = '" + regionUUID.ToString() + "'"; - string orderByParent = "ParentID ASC"; + DataTable prims = _PrimsDataSet.Tables["prims"]; + DataTable shapes = _PrimsDataSet.Tables["primshapes"]; - lock (m_dataSet) + lock (_PrimsDataSet) { - DataRow[] primsForRegion = prims.Select(byRegion, orderByParent); - m_log.Info("[REGION DB]: " + - "Loaded " + primsForRegion.Length + " prims for region: " + regionUUID); + DataRow[] primsForRegion = prims.Select("", "ParentID ASC"); //.Select(byRegion, orderByParent); + + _Log.Info("[REGION DB]: " + "Loaded " + primsForRegion.Length + " prims for region: " + regionUUID); foreach (DataRow primRow in primsForRegion) { @@ -275,14 +205,14 @@ namespace OpenSim.Data.MSSQL { SceneObjectGroup group = new SceneObjectGroup(); - DataRow shapeRow = shapes.Rows.Find(prim.UUID); + DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString()); if (shapeRow != null) { prim.Shape = buildShape(shapeRow); } else { - m_log.Info( + _Log.Info( "No shape found for prim in storage, so setting default box shape"); prim.Shape = PrimitiveBaseShape.Default; } @@ -294,572 +224,712 @@ namespace OpenSim.Data.MSSQL } else { - DataRow shapeRow = shapes.Rows.Find(prim.UUID); + DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString()); if (shapeRow != null) { prim.Shape = buildShape(shapeRow); } else { - m_log.Info( + _Log.Info( "No shape found for prim in storage, so setting default box shape"); prim.Shape = PrimitiveBaseShape.Default; } createdObjects[new LLUUID(objID)].AddPart(prim); } - LoadItems(prim); - } + LoadItems(prim); + } catch (Exception e) { - m_log.Error("[DATASTORE]: Failed create prim object, exception and data follows"); - m_log.Info("[DATASTORE]: " + e.ToString()); + _Log.Error("[REGION DB]: Failed create prim object, exception and data follows"); + _Log.Info("[REGION DB]: " + e.ToString()); foreach (DataColumn col in prims.Columns) { - m_log.Info("[DATASTORE]: Col: " + col.ColumnName + " => " + primRow[col]); + _Log.Info("[REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]); } } } + + _PrimsDataSet.Tables["prims"].Clear(); + _PrimsDataSet.Tables["primshapes"].Clear(); + _PrimsDataSet.Tables["primitems"].Clear(); } return retvals; + + #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 LLUUID(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()) +// { +// LLUUID UUID = new LLUUID((string) readerShapes["UUID"]); +// +// foreach (SceneObjectGroup objectGroup in createdObjects.Values) +// { +// if (objectGroup.Children.ContainsKey(UUID)) +// { +// objectGroup.Children[UUID].Shape = buildShape(readerShapes); +// } +// } +// } +// } +// } +// return retvals; + + #endregion } - /// - /// Load in a prim's persisted inventory. - /// - /// - private void LoadItems(SceneObjectPart prim) + public void StoreObject(SceneObjectGroup obj, LLUUID regionUUID) { - //m_log.InfoFormat("[DATASTORE]: Loading inventory for {0}, {1}", prim.Name, prim.UUID); - - DataTable dbItems = m_itemsTable; + //Retrieve all values of current region, and current scene/or prims + //Build primID's, we use IN so I can select all prims from objgroup + string primID = ""; + foreach (SceneObjectPart prim in obj.Children.Values) + { + primID += prim.UUID + "', '"; + } + primID = primID.Remove(primID.LastIndexOf("',")); - String sql = String.Format("primID = '{0}'", prim.UUID.ToString()); - DataRow[] dbItemRows = dbItems.Select(sql); + RetrievePrimsDataForRegion(regionUUID, obj.UUID, primID); - IList inventory = new List(); + _Log.InfoFormat("[REGION DB]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count); - foreach (DataRow row in dbItemRows) + foreach (SceneObjectPart prim in obj.Children.Values) { - TaskInventoryItem item = buildItem(row); - inventory.Add(item); + if ((prim.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.Physics) == 0 + && (prim.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.Temporary) == 0 + && (prim.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.TemporaryOnRez) == 0) + { + lock (_PrimsDataSet) + { + DataTable prims = _PrimsDataSet.Tables["prims"]; + DataTable shapes = _PrimsDataSet.Tables["primshapes"]; - //m_log.DebugFormat("[DATASTORE]: Restored item {0}, {1}", item.Name, item.ItemID); + DataRow primRow = prims.Rows.Find(prim.UUID.ToString()); + if (primRow == null) + { + primRow = prims.NewRow(); + fillPrimRow(primRow, prim, obj.UUID, regionUUID); + prims.Rows.Add(primRow); + } + else + { + fillPrimRow(primRow, prim, obj.UUID, regionUUID); + } + + DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString()); + if (shapeRow == null) + { + shapeRow = shapes.NewRow(); + fillShapeRow(shapeRow, prim); + shapes.Rows.Add(shapeRow); + } + else + { + fillShapeRow(shapeRow, prim); + } + } + } + else + { + // m_log.Info("[DATASTORE]: Ignoring Physical obj: " + obj.UUID + " in region: " + regionUUID); + } } - prim.RestoreInventoryItems(inventory); + //Save changes + CommitDataSet(); + } - // XXX A nasty little hack to recover the folder id for the prim (which is currently stored in - // every item). This data should really be stored in the prim table itself. - if (dbItemRows.Length > 0) + /// + /// Removes a object from the database. + /// Meaning removing it from tables Prims, PrimShapes and PrimItems + /// + /// id of scenegroup + /// regionUUID (is this used anyway + public void RemoveObject(LLUUID objectID, LLUUID regionUUID) + { + _Log.InfoFormat("[REGION DB]: Removing obj: {0} from region: {1}", objectID, regionUUID); + + //Remove from prims and primsitem table + string sqlPrims = string.Format("DELETE FROM PRIMS WHERE SceneGroupID = '{0}'", objectID); + string sqlPrimItems = string.Format("DELETE FROM PRIMITEMS WHERE primID in (SELECT UUID FROM PRIMS WHERE SceneGroupID = '{0}')", objectID); + string sqlPrimShapes = string.Format("DELETE FROM PRIMSHAPES WHERE uuid in (SELECT UUID FROM PRIMS WHERE SceneGroupID = '{0}')", objectID); + + //Using the non transaction mode. + using (AutoClosingSqlCommand cmd = _Database.Query(sqlPrimShapes)) { - prim.FolderID = inventory[0].ParentID; + cmd.ExecuteNonQuery(); + + cmd.CommandText = sqlPrimItems; + cmd.ExecuteNonQuery(); + + cmd.CommandText = sqlPrims; + cmd.ExecuteNonQuery(); } } /// - /// Store a terrain revision in region storage. + /// Store the inventory of a prim. Warning deletes everything first and then adds all again. /// - /// HeightField data - /// Region UUID - public void StoreTerrain(double[,] ter, LLUUID regionID) + /// + /// + public void StorePrimInventory(LLUUID primID, ICollection items) { - int revision = Util.UnixTimeSinceEpoch(); - m_log.Info("[REGION DB]: Storing terrain revision r" + revision.ToString()); + _Log.InfoFormat("[REGION DB]: Persisting Prim Inventory with prim ID {0}", primID); + + //Statement from MySQL section! + // For now, we're just going to crudely remove all the previous inventory items + // no matter whether they have changed or not, and replace them with the current set. + + //Delete everything from PrimID + //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.ExecuteNonQuery(); + } + + string sql = + "INSERT INTO [primitems] ([itemID],[primID],[assetID],[parentFolderID],[invType],[assetType],[name],[description],[creationDate],[creatorID],[ownerID],[lastOwnerID],[groupID],[nextPermissions],[currentPermissions],[basePermissions],[everyonePermissions],[groupPermissions],[flags]) VALUES (@itemID,@primID,@assetID,@parentFolderID,@invType,@assetType,@name,@description,@creationDate,@creatorID,@ownerID,@lastOwnerID,@groupID,@nextPermissions,@currentPermissions,@basePermissions,@everyonePermissions,@groupPermissions,@flags)"; - // DataTable terrain = m_dataSet.Tables["terrain"]; - lock (m_dataSet) + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) { - SqlCommand cmd = new SqlCommand("insert into terrain(RegionUUID, Revision, Heightfield)" + - " values(@RegionUUID, @Revision, @Heightfield)", m_connection); - using (cmd) + foreach (TaskInventoryItem newItem in items) { - cmd.Parameters.Add(new SqlParameter("@RegionUUID", regionID.UUID)); - cmd.Parameters.Add(new SqlParameter("@Revision", revision)); - cmd.Parameters.Add(new SqlParameter("@Heightfield", serializeTerrain(ter))); + // + cmd.Parameters.AddRange(CreatePrimInventoryParameters(newItem)); + cmd.ExecuteNonQuery(); + + cmd.Parameters.Clear(); } } } /// - /// Load the latest terrain revision from region storage. + /// Loads the terrain map. /// - /// The Region UUID - /// HeightField Data + /// regionID. + /// public double[,] LoadTerrain(LLUUID regionID) { - double[,] terret = new double[256, 256]; - terret.Initialize(); + double[,] terrain = new double[256, 256]; + terrain.Initialize(); - SqlCommand cmd = new SqlCommand( - @"select top 1 RegionUUID, Revision, Heightfield from terrain - where RegionUUID=@RegionUUID order by Revision desc" - , m_connection); + string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc"; - // SqlParameter param = new SqlParameter(); - cmd.Parameters.Add(new SqlParameter("@RegionUUID", regionID.UUID)); - - if (m_connection.State != ConnectionState.Open) + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) { - m_connection.Open(); - } + // MySqlParameter param = new MySqlParameter(); + cmd.Parameters.AddWithValue("@RegionUUID", regionID.ToString()); - using (SqlDataReader row = cmd.ExecuteReader()) - { - int rev = 0; - if (row.Read()) + using (SqlDataReader reader = cmd.ExecuteReader()) { - MemoryStream str = new MemoryStream((byte[])row["Heightfield"]); - BinaryReader br = new BinaryReader(str); - for (int x = 0; x < 256; x++) + int rev = 0; + if (reader.Read()) { - for (int y = 0; y < 256; y++) + MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]); + BinaryReader br = new BinaryReader(str); + for (int x = 0; x < 256; x++) { - terret[x, y] = br.ReadDouble(); + for (int y = 0; y < 256; y++) + { + terrain[x, y] = br.ReadDouble(); + } } + rev = (int)reader["Revision"]; } - rev = (int)row["Revision"]; - } - else - { - m_log.Info("[REGION DB]: No terrain found for region"); - return null; + else + { + _Log.Info("[REGION DB]: No terrain found for region"); + return null; + } + _Log.Info("[REGION DB]: Loaded terrain revision r" + rev); } - - m_log.Info("[REGION DB]: Loaded terrain revision r" + rev.ToString()); } - return terret; + return terrain; } /// - /// + /// Stores the terrain map to DB. /// - /// - public void RemoveLandObject(LLUUID globalID) + /// terrain map data. + /// regionID. + public void StoreTerrain(double[,] terrain, LLUUID regionID) { - // Instance.RemoveLandObject(globalID); + int revision = Util.UnixTimeSinceEpoch(); - lock (m_dataSet) + //Delete old terrain map + string sql = "delete from terrain where RegionUUID=@RegionUUID"; + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) { - using (SqlCommand cmd = new SqlCommand("delete from land where UUID=@UUID", m_connection)) - { - cmd.Parameters.Add(new SqlParameter("@UUID", globalID.UUID)); - cmd.ExecuteNonQuery(); - } + cmd.Parameters.AddWithValue("@RegionUUID", regionID.ToString()); + cmd.ExecuteNonQuery(); + } - using ( - SqlCommand cmd = new SqlCommand("delete from landaccesslist where LandUUID=@UUID", m_connection) - ) - { - cmd.Parameters.Add(new SqlParameter("@UUID", globalID.UUID)); - cmd.ExecuteNonQuery(); - } + 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.ExecuteNonQuery(); } + + _Log.Info("[REGION DB]: Stored terrain revision r" + revision); } /// - /// + /// Loads all the land objects of a region. /// - /// - public void StoreLandObject(ILandObject parcel) + /// The region UUID. + /// + public List LoadLandObjects(LLUUID regionUUID) { - lock (m_dataSet) + List landDataForRegion = new List(); + + string sql = "select * from land where RegionUUID = @RegionUUID"; + + //Retrieve all land data from region + using (AutoClosingSqlCommand cmdLandData = _Database.Query(sql)) { - DataTable land = m_landTable; - DataTable landaccesslist = m_landAccessListTable; + cmdLandData.Parameters.AddWithValue("@RegionUUID", regionUUID.ToString()); - DataRow landRow = land.Rows.Find(parcel.landData.GlobalID.UUID); - if (landRow == null) - { - landRow = land.NewRow(); - fillLandRow(landRow, parcel.landData, parcel.regionUUID); - land.Rows.Add(landRow); - } - else + using (SqlDataReader readerLandData = cmdLandData.ExecuteReader()) { - fillLandRow(landRow, parcel.landData, parcel.regionUUID); - } + while (readerLandData.Read()) + { + LandData data = buildLandData(readerLandData); - using ( - SqlCommand cmd = - new SqlCommand("delete from landaccesslist where LandUUID=@LandUUID", m_connection)) - { - cmd.Parameters.Add(new SqlParameter("@LandUUID", parcel.landData.GlobalID.UUID)); - cmd.ExecuteNonQuery(); + } } + } - foreach (ParcelManager.ParcelAccessEntry entry in parcel.landData.ParcelAccessList) + //Retrieve all accesslist data for all landdata + foreach (LandData landData in landDataForRegion) + { + sql = "select * from landaccesslist where LandUUID = @LandUUID"; + using (AutoClosingSqlCommand cmdAccessList = _Database.Query(sql)) { - DataRow newAccessRow = landaccesslist.NewRow(); - fillLandAccessRow(newAccessRow, entry, parcel.landData.GlobalID); - landaccesslist.Rows.Add(newAccessRow); + cmdAccessList.Parameters.AddWithValue("@LandUUID", landData.GlobalID); + using (SqlDataReader readerAccessList = cmdAccessList.ExecuteReader()) + { + while (readerAccessList.Read()) + { + landData.ParcelAccessList.Add(buildLandAccessData(readerAccessList)); + } + } } - } - Commit(); + + //Return data + return landDataForRegion; } /// - /// + /// Stores land object with landaccess list. /// - /// The region UUID - /// - public List LoadLandObjects(LLUUID regionUUID) + /// parcel data. + public void StoreLandObject(ILandObject parcel) { - List landDataForRegion = new List(); - lock (m_dataSet) + //As this is only one record in land table I just delete all and then add a new record. + //As the delete landaccess is already in the mysql code + + //Delete old values + RemoveLandObject(parcel.landData.GlobalID); + + //Insert new values + string sql = @"INSERT INTO [land] +([UUID],[RegionUUID],[LocalLandID],[Bitmap],[Name],[Description],[OwnerUUID],[IsGroupOwned],[Area],[AuctionID],[Category],[ClaimDate],[ClaimPrice],[GroupUUID],[SalePrice],[LandStatus],[LandFlags],[LandingType],[MediaAutoScale],[MediaTextureUUID],[MediaURL],[MusicURL],[PassHours],[PassPrice],[SnapshotUUID],[UserLocationX],[UserLocationY],[UserLocationZ],[UserLookAtX],[UserLookAtY],[UserLookAtZ],[AuthbuyerID]) +VALUES +(@UUID,@RegionUUID,@LocalLandID,@Bitmap,@Name,@Description,@OwnerUUID,@IsGroupOwned,@Area,@AuctionID,@Category,@ClaimDate,@ClaimPrice,@GroupUUID,@SalePrice,@LandStatus,@LandFlags,@LandingType,@MediaAutoScale,@MediaTextureUUID,@MediaURL,@MusicURL,@PassHours,@PassPrice,@SnapshotUUID,@UserLocationX,@UserLocationY,@UserLocationZ,@UserLookAtX,@UserLookAtY,@UserLookAtZ,@AuthbuyerID)"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.AddRange(CreateLandParameters(parcel.landData, parcel.regionUUID)); + + cmd.ExecuteNonQuery(); + } + + sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) { - DataTable land = m_landTable; - DataTable landaccesslist = m_landAccessListTable; - string searchExp = "RegionUUID = '" + regionUUID.UUID + "'"; - DataRow[] rawDataForRegion = land.Select(searchExp); - foreach (DataRow rawDataLand in rawDataForRegion) + foreach (ParcelManager.ParcelAccessEntry parcelAccessEntry in parcel.landData.ParcelAccessList) { - LandData newLand = buildLandData(rawDataLand); - string accessListSearchExp = "LandUUID = '" + newLand.GlobalID.UUID + "'"; - DataRow[] rawDataForLandAccessList = landaccesslist.Select(accessListSearchExp); - foreach (DataRow rawDataLandAccess in rawDataForLandAccessList) - { - newLand.ParcelAccessList.Add(buildLandAccessData(rawDataLandAccess)); - } + cmd.Parameters.AddRange(CreateLandAccessParameters(parcelAccessEntry, parcel.regionUUID)); + + cmd.ExecuteNonQuery(); - landDataForRegion.Add(newLand); + cmd.Parameters.Clear(); } } - return landDataForRegion; } /// - /// Load (fetch?) the region banlist + /// Removes a land object from DB. /// - /// the region UUID - /// the banlist list - public List LoadRegionBanList(LLUUID regionUUID) + /// UUID of landobject + public void RemoveLandObject(LLUUID globalID) { - List regionbanlist = new List(); - return regionbanlist; + using (AutoClosingSqlCommand cmd = _Database.Query("delete from land where UUID=@UUID")) + { + cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); + cmd.ExecuteNonQuery(); + } + + using (AutoClosingSqlCommand cmd = _Database.Query("delete from landaccesslist where LandUUID=@UUID")) + { + cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); + cmd.ExecuteNonQuery(); + } } /// - /// STUB, add an item into region banlist + /// Loads the settings of a region. /// - /// the item - public void AddToRegionBanlist(EstateBan item) + /// The region UUID. + /// + public RegionSettings LoadRegionSettings(LLUUID regionUUID) { + string sql = "select * from regionsettings where regionUUID = @regionUUID"; + RegionSettings regionSettings; + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.AddWithValue("@regionUUID", regionUUID.ToString()); + using(SqlDataReader reader = cmd.ExecuteReader()) + { + if (reader.Read()) + { + regionSettings = buildRegionSettings(reader); + regionSettings.OnSave += StoreRegionSettings; - } + return regionSettings; + } + } + } - /// - /// STUB, remove an item from region banlist - /// - /// - public void RemoveFromRegionBanlist(EstateBan item) - { + //If comes here then there is now region setting for that region + regionSettings = new RegionSettings(); + regionSettings.RegionUUID = regionUUID; + regionSettings.OnSave += StoreRegionSettings; + + //Store new values + StoreNewRegionSettings(regionSettings); + return regionSettings; } /// - /// Commit + /// Store region settings, need to check if the check is really necesary. If we can make something for creating new region. /// - public void Commit() + /// region settings. + public void StoreRegionSettings(RegionSettings regionSettings) { - if (m_connection.State != ConnectionState.Open) + //Little check if regionUUID already exist in DB + string regionUUID = null; + using (AutoClosingSqlCommand cmd = _Database.Query("SELECT regionUUID FROM regionsettings WHERE regionUUID = @regionUUID")) { - m_connection.Open(); + regionUUID = cmd.ExecuteScalar().ToString(); } - lock (m_dataSet) + if (string.IsNullOrEmpty(regionUUID)) { - // DisplayDataSet(m_dataSet, "Region DataSet"); - - m_primDataAdapter.Update(m_primTable); - m_shapeDataAdapter.Update(m_shapeTable); - - m_itemsDataAdapter.Update(m_itemsTable); - - m_terrainDataAdapter.Update(m_terrainTable); - m_landDataAdapter.Update(m_landTable); - m_landAccessListDataAdapter.Update(m_landAccessListTable); + StoreNewRegionSettings(regionSettings); + } + else + { + //This method only updates region settings!!! First call LoadRegionSettings to create new region settings in DB + string sql = + @"UPDATE [regionsettings] SET [block_terraform] = @block_terraform ,[block_fly] = @block_fly ,[allow_damage] = @allow_damage +,[restrict_pushing] = @restrict_pushing ,[allow_land_resell] = @allow_land_resell ,[allow_land_join_divide] = @allow_land_join_divide +,[block_show_in_search] = @block_show_in_search ,[agent_limit] = @agent_limit ,[object_bonus] = @object_bonus ,[maturity] = @maturity +,[disable_scripts] = @disable_scripts ,[disable_collisions] = @disable_collisions ,[disable_physics] = @disable_physics +,[terrain_texture_1] = @terrain_texture_1 ,[terrain_texture_2] = @terrain_texture_2 ,[terrain_texture_3] = @terrain_texture_3 +,[terrain_texture_4] = @terrain_texture_4 ,[elevation_1_nw] = @elevation_1_nw ,[elevation_2_nw] = @elevation_2_nw +,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se +,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit +,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position +,[covenant] = @covenant ,[Sandbox] = @Sandbox WHERE [regionUUID] = @regionUUID"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); - m_dataSet.AcceptChanges(); + cmd.ExecuteNonQuery(); + } } } - /// - /// See - /// public void Shutdown() { - Commit(); + //Not used?? } - /*********************************************************************** - * - * Database Definition Functions - * - * This should be db agnostic as we define them in ADO.NET terms - * - **********************************************************************/ + #region Private Methods /// - /// + /// Load in a prim's persisted inventory. /// - /// - /// - /// - /// - private static DataColumn createCol(DataTable dt, string name, Type type) + /// The prim + private void LoadItems(SceneObjectPart prim) { - DataColumn col = new DataColumn(name, type); - dt.Columns.Add(col); - return col; + DataTable dbItems = _PrimsDataSet.Tables["primitems"]; + + String sql = String.Format("primID = '{0}'", prim.UUID.ToString()); + DataRow[] dbItemRows = dbItems.Select(sql); + + IList inventory = new List(); + + foreach (DataRow row in dbItemRows) + { + TaskInventoryItem item = buildItem(row); + inventory.Add(item); + + //m_log.DebugFormat("[DATASTORE]: Restored item {0}, {1}", item.Name, item.ItemID); + } + + prim.RestoreInventoryItems(inventory); + + // XXX A nasty little hack to recover the folder id for the prim (which is currently stored in + // every item). This data should really be stored in the prim table itself. + if (dbItemRows.Length > 0) + { + prim.FolderID = inventory[0].ParentID; + } } /// - /// Create the "terrain" table + /// Serializes the terrain data for storage in DB. /// - /// the datatable - private static DataTable createTerrainTable() + /// terrain data + /// + private static Array serializeTerrain(double[,] val) { - DataTable terrain = new DataTable("terrain"); + MemoryStream str = new MemoryStream(65536 * sizeof(double)); + BinaryWriter bw = new BinaryWriter(str); - createCol(terrain, "RegionUUID", typeof(String)); - createCol(terrain, "Revision", typeof(Int32)); - createCol(terrain, "Heightfield", typeof(Byte[])); + // TODO: COMPATIBILITY - Add byte-order conversions + for (int x = 0; x < 256; x++) + for (int y = 0; y < 256; y++) + { + double height = val[x, y]; + if (height == 0.0) + height = double.Epsilon; - return terrain; + bw.Write(height); + } + + return str.ToArray(); } /// - /// Create the "prims" table + /// Stores new regionsettings. /// - /// the datatable - private static DataTable createPrimTable() + /// The region settings. + private void StoreNewRegionSettings(RegionSettings regionSettings) { - DataTable prims = new DataTable("prims"); - - createCol(prims, "UUID", typeof(String)); - createCol(prims, "RegionUUID", typeof(String)); - createCol(prims, "ParentID", typeof(Int32)); - createCol(prims, "CreationDate", typeof(Int32)); - createCol(prims, "Name", typeof(String)); - createCol(prims, "SceneGroupID", typeof(String)); - // various text fields - createCol(prims, "Text", typeof(String)); - createCol(prims, "Description", typeof(String)); - createCol(prims, "SitName", typeof(String)); - createCol(prims, "TouchName", typeof(String)); - // permissions - createCol(prims, "ObjectFlags", typeof(Int32)); - createCol(prims, "CreatorID", typeof(String)); - createCol(prims, "OwnerID", typeof(String)); - createCol(prims, "GroupID", typeof(String)); - createCol(prims, "LastOwnerID", typeof(String)); - createCol(prims, "OwnerMask", typeof(Int32)); - createCol(prims, "NextOwnerMask", typeof(Int32)); - createCol(prims, "GroupMask", typeof(Int32)); - createCol(prims, "EveryoneMask", typeof(Int32)); - createCol(prims, "BaseMask", typeof(Int32)); - // vectors - createCol(prims, "PositionX", typeof(Double)); - createCol(prims, "PositionY", typeof(Double)); - createCol(prims, "PositionZ", typeof(Double)); - createCol(prims, "GroupPositionX", typeof(Double)); - createCol(prims, "GroupPositionY", typeof(Double)); - createCol(prims, "GroupPositionZ", typeof(Double)); - createCol(prims, "VelocityX", typeof(Double)); - createCol(prims, "VelocityY", typeof(Double)); - createCol(prims, "VelocityZ", typeof(Double)); - createCol(prims, "AngularVelocityX", typeof(Double)); - createCol(prims, "AngularVelocityY", typeof(Double)); - createCol(prims, "AngularVelocityZ", typeof(Double)); - createCol(prims, "AccelerationX", typeof(Double)); - createCol(prims, "AccelerationY", typeof(Double)); - createCol(prims, "AccelerationZ", typeof(Double)); - // quaternions - createCol(prims, "RotationX", typeof(Double)); - createCol(prims, "RotationY", typeof(Double)); - createCol(prims, "RotationZ", typeof(Double)); - createCol(prims, "RotationW", typeof(Double)); + string sql = @"INSERT INTO [regionsettings] +([regionUUID],[block_terraform],[block_fly],[allow_damage],[restrict_pushing],[allow_land_resell],[allow_land_join_divide],[block_show_in_search],[agent_limit],[object_bonus],[maturity],[disable_scripts],[disable_collisions],[disable_physics],[terrain_texture_1],[terrain_texture_2],[terrain_texture_3],[terrain_texture_4],[elevation_1_nw],[elevation_2_nw],[elevation_1_ne],[elevation_2_ne],[elevation_1_se],[elevation_2_se],[elevation_1_sw],[elevation_2_sw],[water_height],[terrain_raise_limit],[terrain_lower_limit],[use_estate_sun],[fixed_sun],[sun_position],[covenant],[Sandbox]) VALUES +(@regionUUID,@block_terraform,@block_fly,@allow_damage,@restrict_pushing,@allow_land_resell,@allow_land_join_divide,@block_show_in_search,@agent_limit,@object_bonus,@maturity,@disable_scripts,@disable_collisions,@disable_physics,@terrain_texture_1,@terrain_texture_2,@terrain_texture_3,@terrain_texture_4,@elevation_1_nw,@elevation_2_nw,@elevation_1_ne,@elevation_2_ne,@elevation_1_se,@elevation_2_se,@elevation_1_sw,@elevation_2_sw,@water_height,@terrain_raise_limit,@terrain_lower_limit,@use_estate_sun,@fixed_sun,@sun_position,@covenant,@Sandbox)"; - // sit target - createCol(prims, "SitTargetOffsetX", typeof(Double)); - createCol(prims, "SitTargetOffsetY", typeof(Double)); - createCol(prims, "SitTargetOffsetZ", typeof(Double)); - - createCol(prims, "SitTargetOrientW", typeof(Double)); - createCol(prims, "SitTargetOrientX", typeof(Double)); - createCol(prims, "SitTargetOrientY", typeof(Double)); - createCol(prims, "SitTargetOrientZ", typeof(Double)); - - // Add in contraints - prims.PrimaryKey = new DataColumn[] { prims.Columns["UUID"] }; + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); - return prims; + cmd.ExecuteNonQuery(); + } } - /// - /// Create the "land" table - /// - /// the datatable - private static DataTable createLandTable() - { - DataTable land = new DataTable("land"); - createCol(land, "UUID", typeof(String)); - createCol(land, "RegionUUID", typeof(String)); - createCol(land, "LocalLandID", typeof(Int32)); - - // Bitmap is a byte[512] - createCol(land, "Bitmap", typeof(Byte[])); - - createCol(land, "Name", typeof(String)); - createCol(land, "Description", typeof(String)); - createCol(land, "OwnerUUID", typeof(String)); - createCol(land, "IsGroupOwned", typeof(Int32)); - createCol(land, "Area", typeof(Int32)); - createCol(land, "AuctionID", typeof(Int32)); //Unemplemented - createCol(land, "Category", typeof(Int32)); //Enum libsecondlife.Parcel.ParcelCategory - createCol(land, "ClaimDate", typeof(Int32)); - createCol(land, "ClaimPrice", typeof(Int32)); - createCol(land, "GroupUUID", typeof(String)); - createCol(land, "SalePrice", typeof(Int32)); - createCol(land, "LandStatus", typeof(Int32)); //Enum. libsecondlife.Parcel.ParcelStatus - createCol(land, "LandFlags", typeof(Int32)); - createCol(land, "LandingType", typeof(Int32)); - createCol(land, "MediaAutoScale", typeof(Int32)); - createCol(land, "MediaTextureUUID", typeof(String)); - createCol(land, "MediaURL", typeof(String)); - createCol(land, "MusicURL", typeof(String)); - createCol(land, "PassHours", typeof(Double)); - createCol(land, "PassPrice", typeof(Int32)); - createCol(land, "SnapshotUUID", typeof(String)); - createCol(land, "UserLocationX", typeof(Double)); - createCol(land, "UserLocationY", typeof(Double)); - createCol(land, "UserLocationZ", typeof(Double)); - createCol(land, "UserLookAtX", typeof(Double)); - createCol(land, "UserLookAtY", typeof(Double)); - createCol(land, "UserLookAtZ", typeof(Double)); - - land.PrimaryKey = new DataColumn[] { land.Columns["UUID"] }; - - return land; - } + #region Private DataRecord conversion methods /// - /// Create "landacceslist" table + /// Builds the region settings from a datarecod. /// - /// the datatable - private static DataTable createLandAccessListTable() + /// datarecord with regionsettings. + /// + private static RegionSettings buildRegionSettings(IDataRecord row) { - DataTable landaccess = new DataTable("landaccesslist"); - createCol(landaccess, "LandUUID", typeof(String)); - createCol(landaccess, "AccessUUID", typeof(String)); - createCol(landaccess, "Flags", typeof(Int32)); - - return landaccess; + //TODO change this is some more generic code so we doesnt have to change it every time a new field is added? + RegionSettings newSettings = new RegionSettings(); + + newSettings.RegionUUID = new LLUUID((string)row["regionUUID"]); + newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]); + newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]); + newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]); + newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]); + newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]); + newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]); + newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]); + newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]); + newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]); + newSettings.Maturity = Convert.ToInt32(row["maturity"]); + newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]); + newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]); + newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]); + newSettings.TerrainTexture1 = new LLUUID((String)row["terrain_texture_1"]); + newSettings.TerrainTexture2 = new LLUUID((String)row["terrain_texture_2"]); + newSettings.TerrainTexture3 = new LLUUID((String)row["terrain_texture_3"]); + newSettings.TerrainTexture4 = new LLUUID((String)row["terrain_texture_4"]); + newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]); + newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]); + newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]); + newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]); + newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]); + newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]); + newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]); + newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]); + newSettings.WaterHeight = Convert.ToDouble(row["water_height"]); + newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]); + newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]); + newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]); + newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]); + newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]); + newSettings.SunPosition = Convert.ToDouble(row["sun_position"]); + newSettings.Covenant = new LLUUID((String)row["covenant"]); + + return newSettings; } /// - /// Create "primsshapes" table + /// Builds the land data from a datarecord. /// - /// the datatable - private static DataTable createShapeTable() + /// datarecord with land data + /// + private static LandData buildLandData(IDataRecord row) { - DataTable shapes = new DataTable("primshapes"); - createCol(shapes, "UUID", typeof(String)); - // shape is an enum - createCol(shapes, "Shape", typeof(Int32)); - // vectors - createCol(shapes, "ScaleX", typeof(Double)); - createCol(shapes, "ScaleY", typeof(Double)); - createCol(shapes, "ScaleZ", typeof(Double)); - // paths - createCol(shapes, "PCode", typeof(Int32)); - createCol(shapes, "PathBegin", typeof(Int32)); - createCol(shapes, "PathEnd", typeof(Int32)); - createCol(shapes, "PathScaleX", typeof(Int32)); - createCol(shapes, "PathScaleY", typeof(Int32)); - createCol(shapes, "PathShearX", typeof(Int32)); - createCol(shapes, "PathShearY", typeof(Int32)); - createCol(shapes, "PathSkew", typeof(Int32)); - createCol(shapes, "PathCurve", typeof(Int32)); - createCol(shapes, "PathRadiusOffset", typeof(Int32)); - createCol(shapes, "PathRevolutions", typeof(Int32)); - createCol(shapes, "PathTaperX", typeof(Int32)); - createCol(shapes, "PathTaperY", typeof(Int32)); - createCol(shapes, "PathTwist", typeof(Int32)); - createCol(shapes, "PathTwistBegin", typeof(Int32)); - // profile - createCol(shapes, "ProfileBegin", typeof(Int32)); - createCol(shapes, "ProfileEnd", typeof(Int32)); - createCol(shapes, "ProfileCurve", typeof(Int32)); - createCol(shapes, "ProfileHollow", typeof(Int32)); - createCol(shapes, "State", typeof(Int32)); - // text TODO: this isn't right, but I'm not sure the right - // way to specify this as a blob atm - createCol(shapes, "Texture", typeof(Byte[])); - createCol(shapes, "ExtraParams", typeof(Byte[])); - - shapes.PrimaryKey = new DataColumn[] { shapes.Columns["UUID"] }; - - return shapes; - } + LandData newData = new LandData(); - /// - /// Create "primitems" table - /// - /// the datatable - private static DataTable createItemsTable() - { - DataTable items = new DataTable("primitems"); + newData.GlobalID = new LLUUID((String)row["UUID"]); + newData.LocalID = Convert.ToInt32(row["LocalLandID"]); + + // Bitmap is a byte[512] + newData.Bitmap = (Byte[])row["Bitmap"]; - createCol(items, "itemID", typeof(String)); - createCol(items, "primID", typeof(String)); - createCol(items, "assetID", typeof(String)); - createCol(items, "parentFolderID", typeof(String)); + newData.Name = (String)row["Name"]; + newData.Description = (String)row["Description"]; + newData.OwnerID = (String)row["OwnerUUID"]; + newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); + newData.Area = Convert.ToInt32(row["Area"]); + newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented + newData.Category = (Parcel.ParcelCategory)Convert.ToInt32(row["Category"]); + //Enum libsecondlife.Parcel.ParcelCategory + newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]); + newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]); + newData.GroupID = new LLUUID((String)row["GroupUUID"]); + newData.SalePrice = Convert.ToInt32(row["SalePrice"]); + newData.Status = (Parcel.ParcelStatus)Convert.ToInt32(row["LandStatus"]); + //Enum. libsecondlife.Parcel.ParcelStatus + newData.Flags = Convert.ToUInt32(row["LandFlags"]); + newData.LandingType = Convert.ToByte(row["LandingType"]); + newData.MediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); + newData.MediaID = new LLUUID((String)row["MediaTextureUUID"]); + newData.MediaURL = (String)row["MediaURL"]; + newData.MusicURL = (String)row["MusicURL"]; + newData.PassHours = Convert.ToSingle(row["PassHours"]); + newData.PassPrice = Convert.ToInt32(row["PassPrice"]); - createCol(items, "invType", typeof(Int32)); - createCol(items, "assetType", typeof(Int32)); + LLUUID authedbuyer; + LLUUID snapshotID; - createCol(items, "name", typeof(String)); - createCol(items, "description", typeof(String)); + if (LLUUID.TryParse((string)row["AuthBuyerID"], out authedbuyer)) + newData.AuthBuyerID = authedbuyer; - createCol(items, "creationDate", typeof(Int64)); - createCol(items, "creatorID", typeof(String)); - createCol(items, "ownerID", typeof(String)); - createCol(items, "lastOwnerID", typeof(String)); - createCol(items, "groupID", typeof(String)); + if (LLUUID.TryParse((string)row["SnapshotUUID"], out snapshotID)) + newData.SnapshotID = snapshotID; - createCol(items, "nextPermissions", typeof(Int32)); - createCol(items, "currentPermissions", typeof(Int32)); - createCol(items, "basePermissions", typeof(Int32)); - createCol(items, "everyonePermissions", typeof(Int32)); - createCol(items, "groupPermissions", typeof(Int32)); -// createCol(items, "flags", typeof(Int32)); + try + { + newData.UserLocation = + new LLVector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), + Convert.ToSingle(row["UserLocationZ"])); + newData.UserLookAt = + new LLVector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), + Convert.ToSingle(row["UserLookAtZ"])); + } + catch (InvalidCastException) + { + newData.UserLocation = LLVector3.Zero; + newData.UserLookAt = LLVector3.Zero; + _Log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name); + } - items.PrimaryKey = new DataColumn[] { items.Columns["itemID"] }; + newData.ParcelAccessList = new List(); - return items; + return newData; } - /*********************************************************************** - * - * Convert between ADO.NET <=> OpenSim Objects - * - * These should be database independant - * - **********************************************************************/ + /// + /// Builds the landaccess data from a data record. + /// + /// datarecord with landaccess data + /// + private static ParcelManager.ParcelAccessEntry buildLandAccessData(IDataRecord row) + { + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = new LLUUID((string)row["AccessUUID"]); + entry.Flags = (ParcelManager.AccessList)Convert.ToInt32(row["Flags"]); + entry.Time = new DateTime(); + return entry; + } /// - /// + /// Builds the prim from a datarecord. /// - /// + /// datarecord /// - private SceneObjectPart buildPrim(DataRow row) + private static SceneObjectPart buildPrim(DataRow row) { SceneObjectPart prim = new SceneObjectPart(); + prim.UUID = new LLUUID((String)row["UUID"]); // explicit conversion of integers is required, which sort // of sucks. No idea if there is a shortcut here or not. @@ -915,330 +985,73 @@ namespace OpenSim.Data.MSSQL Convert.ToSingle(row["RotationZ"]), Convert.ToSingle(row["RotationW"]) ); - try - { - prim.SitTargetPositionLL = new LLVector3( - Convert.ToSingle(row["SitTargetOffsetX"]), - Convert.ToSingle(row["SitTargetOffsetY"]), - Convert.ToSingle(row["SitTargetOffsetZ"])); - prim.SitTargetOrientationLL = new LLQuaternion( - Convert.ToSingle( - row["SitTargetOrientX"]), - Convert.ToSingle( - row["SitTargetOrientY"]), - Convert.ToSingle( - row["SitTargetOrientZ"]), - Convert.ToSingle( - row["SitTargetOrientW"])); - } - catch (InvalidCastException) - { - // Database table was created before we got here and now has null values :P - - using ( - SqlCommand cmd = - new SqlCommand( - "ALTER TABLE [prims] ADD COLUMN [SitTargetOffsetX] float NOT NULL default 0, ADD COLUMN [SitTargetOffsetY] float NOT NULL default 0, ADD COLUMN [SitTargetOffsetZ] float NOT NULL default 0, ADD COLUMN [SitTargetOrientW] float NOT NULL default 0, ADD COLUMN [SitTargetOrientX] float NOT NULL default 0, ADD COLUMN [SitTargetOrientY] float NOT NULL default 0, ADD COLUMN [SitTargetOrientZ] float NOT NULL default 0;", - m_connection)) - { - cmd.ExecuteNonQuery(); - } - } - - return prim; - } - - /// - /// Build a prim inventory item from the persisted data. - /// - /// - /// - private static TaskInventoryItem buildItem(DataRow row) - { - TaskInventoryItem taskItem = new TaskInventoryItem(); - - taskItem.ItemID = new LLUUID((String)row["itemID"]); - taskItem.ParentPartID = new LLUUID((String)row["primID"]); - taskItem.AssetID = new LLUUID((String)row["assetID"]); - taskItem.ParentID = new LLUUID((String)row["parentFolderID"]); - - taskItem.InvType = Convert.ToInt32(row["invType"]); - taskItem.Type = Convert.ToInt32(row["assetType"]); - - taskItem.Name = (String)row["name"]; - taskItem.Description = (String)row["description"]; - taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); - taskItem.CreatorID = new LLUUID((String)row["creatorID"]); - taskItem.OwnerID = new LLUUID((String)row["ownerID"]); - taskItem.LastOwnerID = new LLUUID((String)row["lastOwnerID"]); - taskItem.GroupID = new LLUUID((String)row["groupID"]); - - taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]); - taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]); - taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]); - taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]); - taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]); -// taskItem.Flags = Convert.ToUInt32(row["flags"]); - - return taskItem; - } - - /// - /// - /// - /// - /// - private static LandData buildLandData(DataRow row) - { - LandData newData = new LandData(); - - newData.GlobalID = new LLUUID((String)row["UUID"]); - newData.LocalID = Convert.ToInt32(row["LocalLandID"]); - - // Bitmap is a byte[512] - newData.Bitmap = (Byte[])row["Bitmap"]; + prim.SitTargetPositionLL = new LLVector3( + Convert.ToSingle(row["SitTargetOffsetX"]), + Convert.ToSingle(row["SitTargetOffsetY"]), + Convert.ToSingle(row["SitTargetOffsetZ"]) + ); + prim.SitTargetOrientationLL = new LLQuaternion( + Convert.ToSingle(row["SitTargetOrientX"]), + Convert.ToSingle(row["SitTargetOrientY"]), + Convert.ToSingle(row["SitTargetOrientZ"]), + Convert.ToSingle(row["SitTargetOrientW"]) + ); - newData.Name = (String)row["Name"]; - newData.Description = (String)row["Description"]; - newData.OwnerID = (String)row["OwnerUUID"]; - newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); - newData.Area = Convert.ToInt32(row["Area"]); - newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented - newData.Category = (Parcel.ParcelCategory)Convert.ToInt32(row["Category"]); - //Enum libsecondlife.Parcel.ParcelCategory - newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]); - newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]); - newData.GroupID = new LLUUID((String)row["GroupUUID"]); - newData.SalePrice = Convert.ToInt32(row["SalePrice"]); - newData.Status = (Parcel.ParcelStatus)Convert.ToInt32(row["LandStatus"]); - //Enum. libsecondlife.Parcel.ParcelStatus - newData.Flags = Convert.ToUInt32(row["LandFlags"]); - newData.LandingType = Convert.ToByte(row["LandingType"]); - newData.MediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); - newData.MediaID = new LLUUID((String)row["MediaTextureUUID"]); - newData.MediaURL = (String)row["MediaURL"]; - newData.MusicURL = (String)row["MusicURL"]; - newData.PassHours = Convert.ToSingle(row["PassHours"]); - newData.PassPrice = Convert.ToInt32(row["PassPrice"]); - newData.SnapshotID = (String)row["SnapshotUUID"]; - - newData.UserLocation = - new LLVector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), - Convert.ToSingle(row["UserLocationZ"])); - newData.UserLookAt = - new LLVector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), - Convert.ToSingle(row["UserLookAtZ"])); - newData.ParcelAccessList = new List(); + prim.PayPrice[0] = Convert.ToInt32(row["PayPrice"]); + prim.PayPrice[1] = Convert.ToInt32(row["PayButton1"]); + prim.PayPrice[2] = Convert.ToInt32(row["PayButton2"]); + prim.PayPrice[3] = Convert.ToInt32(row["PayButton3"]); + prim.PayPrice[4] = Convert.ToInt32(row["PayButton4"]); - return newData; - } + prim.Sound = new LLUUID(row["LoopedSound"].ToString()); + prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]); + prim.SoundFlags = 1; // If it's persisted at all, it's looped - /// - /// - /// - /// - /// - private static ParcelManager.ParcelAccessEntry buildLandAccessData(DataRow row) - { - ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = new LLUUID((string)row["AccessUUID"]); - entry.Flags = (ParcelManager.AccessList)Convert.ToInt32(row["Flags"]); - entry.Time = new DateTime(); - return entry; - } + if (row["TextureAnimation"] != null && row["TextureAnimation"] != DBNull.Value) + prim.TextureAnimation = (Byte[])row["TextureAnimation"]; - /// - /// Serialize terrain HeightField - /// - /// the terrain heightfield - /// - private static Array serializeTerrain(double[,] val) - { - MemoryStream str = new MemoryStream(65536 * sizeof(double)); - BinaryWriter bw = new BinaryWriter(str); + prim.RotationalVelocity = new LLVector3( + Convert.ToSingle(row["OmegaX"]), + Convert.ToSingle(row["OmegaY"]), + Convert.ToSingle(row["OmegaZ"]) + ); - // TODO: COMPATIBILITY - Add byte-order conversions - for (int x = 0; x < 256; x++) - for (int y = 0; y < 256; y++) - bw.Write(val[x, y]); + // TODO: Rotation + // OmegaX, OmegaY, OmegaZ - return str.ToArray(); - } + prim.SetCameraEyeOffset(new LLVector3( + Convert.ToSingle(row["CameraEyeOffsetX"]), + Convert.ToSingle(row["CameraEyeOffsetY"]), + Convert.ToSingle(row["CameraEyeOffsetZ"]) + )); - /// - /// - /// - /// - /// - /// - /// - private void fillPrimRow(DataRow row, SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) - { - row["UUID"] = prim.UUID; - row["RegionUUID"] = regionUUID; - row["ParentID"] = prim.ParentID; - row["CreationDate"] = prim.CreationDate; - row["Name"] = prim.Name; - row["SceneGroupID"] = sceneGroupID; - // the UUID of the root part for this SceneObjectGroup - // various text fields - row["Text"] = prim.Text; - row["Description"] = prim.Description; - row["SitName"] = prim.SitName; - row["TouchName"] = prim.TouchName; - // permissions - row["ObjectFlags"] = prim.ObjectFlags; - row["CreatorID"] = prim.CreatorID; - row["OwnerID"] = prim.OwnerID; - row["GroupID"] = prim.GroupID; - row["LastOwnerID"] = prim.LastOwnerID; - row["OwnerMask"] = prim.OwnerMask; - row["NextOwnerMask"] = prim.NextOwnerMask; - row["GroupMask"] = prim.GroupMask; - row["EveryoneMask"] = prim.EveryoneMask; - row["BaseMask"] = prim.BaseMask; - // vectors - row["PositionX"] = prim.OffsetPosition.X; - row["PositionY"] = prim.OffsetPosition.Y; - row["PositionZ"] = prim.OffsetPosition.Z; - row["GroupPositionX"] = prim.GroupPosition.X; - row["GroupPositionY"] = prim.GroupPosition.Y; - row["GroupPositionZ"] = prim.GroupPosition.Z; - row["VelocityX"] = prim.Velocity.X; - row["VelocityY"] = prim.Velocity.Y; - row["VelocityZ"] = prim.Velocity.Z; - row["AngularVelocityX"] = prim.AngularVelocity.X; - row["AngularVelocityY"] = prim.AngularVelocity.Y; - row["AngularVelocityZ"] = prim.AngularVelocity.Z; - row["AccelerationX"] = prim.Acceleration.X; - row["AccelerationY"] = prim.Acceleration.Y; - row["AccelerationZ"] = prim.Acceleration.Z; - // quaternions - row["RotationX"] = prim.RotationOffset.X; - row["RotationY"] = prim.RotationOffset.Y; - row["RotationZ"] = prim.RotationOffset.Z; - row["RotationW"] = prim.RotationOffset.W; + prim.SetCameraAtOffset(new LLVector3( + Convert.ToSingle(row["CameraAtOffsetX"]), + Convert.ToSingle(row["CameraAtOffsetY"]), + Convert.ToSingle(row["CameraAtOffsetZ"]) + )); - try - { - // Sit target - LLVector3 sitTargetPos = prim.SitTargetPositionLL; - row["SitTargetOffsetX"] = sitTargetPos.X; - row["SitTargetOffsetY"] = sitTargetPos.Y; - row["SitTargetOffsetZ"] = sitTargetPos.Z; - - LLQuaternion sitTargetOrient = prim.SitTargetOrientationLL; - row["SitTargetOrientW"] = sitTargetOrient.W; - row["SitTargetOrientX"] = sitTargetOrient.X; - row["SitTargetOrientY"] = sitTargetOrient.Y; - row["SitTargetOrientZ"] = sitTargetOrient.Z; - } - catch (Exception) - { - // Database table was created before we got here and needs to be created! :P + if (Convert.ToInt16(row["ForceMouselook"]) != 0) + prim.SetForceMouselook(true); - using ( - SqlCommand cmd = - new SqlCommand( - "ALTER TABLE [prims] ADD COLUMN [SitTargetOffsetX] float NOT NULL default 0, ADD COLUMN [SitTargetOffsetY] float NOT NULL default 0, ADD COLUMN [SitTargetOffsetZ] float NOT NULL default 0, ADD COLUMN [SitTargetOrientW] float NOT NULL default 0, ADD COLUMN [SitTargetOrientX] float NOT NULL default 0, ADD COLUMN [SitTargetOrientY] float NOT NULL default 0, ADD COLUMN [SitTargetOrientZ] float NOT NULL default 0;", - m_connection)) - { - cmd.ExecuteNonQuery(); - } - } - } + prim.ScriptAccessPin = Convert.ToInt32(row["ScriptAccessPin"]); - /// - /// - /// - /// - /// - private static void fillItemRow(DataRow row, TaskInventoryItem taskItem) - { - row["itemID"] = taskItem.ItemID; - row["primID"] = taskItem.ParentPartID; - row["assetID"] = taskItem.AssetID; - row["parentFolderID"] = taskItem.ParentID; - - row["invType"] = taskItem.InvType; - row["assetType"] = taskItem.Type; - - row["name"] = taskItem.Name; - row["description"] = taskItem.Description; - row["creationDate"] = taskItem.CreationDate; - row["creatorID"] = taskItem.CreatorID; - row["ownerID"] = taskItem.OwnerID; - row["lastOwnerID"] = taskItem.LastOwnerID; - row["groupID"] = taskItem.GroupID; - row["nextPermissions"] = taskItem.NextPermissions; - row["currentPermissions"] = taskItem.CurrentPermissions; - row["basePermissions"] = taskItem.BasePermissions; - row["everyonePermissions"] = taskItem.EveryonePermissions; - row["groupPermissions"] = taskItem.GroupPermissions; -// row["flags"] = taskItem.Flags; - } + if (Convert.ToInt16(row["AllowedDrop"]) != 0) + prim.AllowedDrop = true; - /// - /// - /// - /// - /// - /// - private static void fillLandRow(DataRow row, LandData land, LLUUID regionUUID) - { - row["UUID"] = land.GlobalID.UUID; - row["RegionUUID"] = regionUUID.UUID; - row["LocalLandID"] = land.LocalID; + if (Convert.ToInt16(row["DieAtEdge"]) != 0) + prim.DIE_AT_EDGE = true; - // Bitmap is a byte[512] - row["Bitmap"] = land.Bitmap; - - row["Name"] = land.Name; - row["Description"] = land.Description; - row["OwnerUUID"] = land.OwnerID.UUID; - row["IsGroupOwned"] = land.IsGroupOwned; - row["Area"] = land.Area; - row["AuctionID"] = land.AuctionID; //Unemplemented - row["Category"] = land.Category; //Enum libsecondlife.Parcel.ParcelCategory - row["ClaimDate"] = land.ClaimDate; - row["ClaimPrice"] = land.ClaimPrice; - row["GroupUUID"] = land.GroupID.UUID; - row["SalePrice"] = land.SalePrice; - row["LandStatus"] = land.Status; //Enum. libsecondlife.Parcel.ParcelStatus - row["LandFlags"] = land.Flags; - row["LandingType"] = land.LandingType; - row["MediaAutoScale"] = land.MediaAutoScale; - row["MediaTextureUUID"] = land.MediaID.UUID; - row["MediaURL"] = land.MediaURL; - row["MusicURL"] = land.MusicURL; - row["PassHours"] = land.PassHours; - row["PassPrice"] = land.PassPrice; - row["SnapshotUUID"] = land.SnapshotID.UUID; - row["UserLocationX"] = land.UserLocation.X; - row["UserLocationY"] = land.UserLocation.Y; - row["UserLocationZ"] = land.UserLocation.Z; - row["UserLookAtX"] = land.UserLookAt.X; - row["UserLookAtY"] = land.UserLookAt.Y; - row["UserLookAtZ"] = land.UserLookAt.Z; - } + prim.SalePrice = Convert.ToInt32(row["SalePrice"]); + prim.ObjectSaleType = Convert.ToByte(row["SaleType"]); - /// - /// - /// - /// - /// - /// - private static void fillLandAccessRow(DataRow row, ParcelManager.ParcelAccessEntry entry, LLUUID parcelID) - { - row["LandUUID"] = parcelID.UUID; - row["AccessUUID"] = entry.AgentID.UUID; - row["Flags"] = entry.Flags; + return prim; } /// - /// + /// Builds the prim shape from a datarecord. /// - /// + /// The row. /// private static PrimitiveBaseShape buildShape(DataRow row) { @@ -1269,572 +1082,445 @@ namespace OpenSim.Data.MSSQL s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]); s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]); s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]); - s.State = Convert.ToByte(row["State"]); byte[] textureEntry = (byte[])row["Texture"]; s.TextureEntry = textureEntry; s.ExtraParams = (byte[])row["ExtraParams"]; - return s; - } - - /// - /// - /// - /// - /// - private static void fillShapeRow(DataRow row, SceneObjectPart prim) - { - PrimitiveBaseShape s = prim.Shape; - row["UUID"] = prim.UUID; - // shape is an enum - row["Shape"] = 0; - // vectors - row["ScaleX"] = s.Scale.X; - row["ScaleY"] = s.Scale.Y; - row["ScaleZ"] = s.Scale.Z; - // paths - row["PCode"] = s.PCode; - row["PathBegin"] = s.PathBegin; - row["PathEnd"] = s.PathEnd; - row["PathScaleX"] = s.PathScaleX; - row["PathScaleY"] = s.PathScaleY; - row["PathShearX"] = s.PathShearX; - row["PathShearY"] = s.PathShearY; - row["PathSkew"] = s.PathSkew; - row["PathCurve"] = s.PathCurve; - row["PathRadiusOffset"] = s.PathRadiusOffset; - row["PathRevolutions"] = s.PathRevolutions; - row["PathTaperX"] = s.PathTaperX; - row["PathTaperY"] = s.PathTaperY; - row["PathTwist"] = s.PathTwist; - row["PathTwistBegin"] = s.PathTwistBegin; - // profile - row["ProfileBegin"] = s.ProfileBegin; - row["ProfileEnd"] = s.ProfileEnd; - row["ProfileCurve"] = s.ProfileCurve; - row["ProfileHollow"] = s.ProfileHollow; - row["State"] = s.State; - row["Texture"] = s.TextureEntry; - row["ExtraParams"] = s.ExtraParams; - } - - /// - /// - /// - /// - /// - /// - private void addPrim(SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) - { - DataTable prims = m_dataSet.Tables["prims"]; - DataTable shapes = m_dataSet.Tables["primshapes"]; - - DataRow primRow = prims.Rows.Find(prim.UUID); - if (primRow == null) + try { - primRow = prims.NewRow(); - fillPrimRow(primRow, prim, sceneGroupID, regionUUID); - prims.Rows.Add(primRow); + s.State = Convert.ToByte(row["State"]); } - else + catch (InvalidCastException) { - fillPrimRow(primRow, prim, sceneGroupID, regionUUID); } - DataRow shapeRow = shapes.Rows.Find(prim.UUID); - if (shapeRow == null) - { - shapeRow = shapes.NewRow(); - fillShapeRow(shapeRow, prim); - shapes.Rows.Add(shapeRow); - } - else - { - fillShapeRow(shapeRow, prim); - } + return s; } /// - /// See + /// Build a prim inventory item from the persisted data. /// - /// - /// - public void StorePrimInventory(LLUUID primID, ICollection items) + /// + /// + private static TaskInventoryItem buildItem(DataRow row) { - m_log.InfoFormat("[REGION DB]: Persisting Prim Inventory with prim ID {0}", primID); + TaskInventoryItem taskItem = new TaskInventoryItem(); - // For now, we're just going to crudely remove all the previous inventory items - // no matter whether they have changed or not, and replace them with the current set. - lock (m_dataSet) - { - RemoveItems(primID); + taskItem.ItemID = new LLUUID((String)row["itemID"]); + taskItem.ParentPartID = new LLUUID((String)row["primID"]); + taskItem.AssetID = new LLUUID((String)row["assetID"]); + taskItem.ParentID = new LLUUID((String)row["parentFolderID"]); + + taskItem.InvType = Convert.ToInt32(row["invType"]); + taskItem.Type = Convert.ToInt32(row["assetType"]); + + taskItem.Name = (String)row["name"]; + taskItem.Description = (String)row["description"]; + taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); + taskItem.CreatorID = new LLUUID((String)row["creatorID"]); + taskItem.OwnerID = new LLUUID((String)row["ownerID"]); + taskItem.LastOwnerID = new LLUUID((String)row["lastOwnerID"]); + taskItem.GroupID = new LLUUID((String)row["groupID"]); + + taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]); + taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]); + taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]); + taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]); + taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]); + taskItem.Flags = Convert.ToUInt32(row["flags"]); - // repalce with current inventory details - foreach (TaskInventoryItem newItem in items) - { - // m_log.InfoFormat( - // "[REGION DB]: " + - // "Adding item {0}, {1} to prim ID {2}", - // newItem.Name, newItem.ItemID, newItem.ParentPartID); - - DataRow newItemRow = m_itemsTable.NewRow(); - fillItemRow(newItemRow, newItem); - m_itemsTable.Rows.Add(newItemRow); - } - } - - Commit(); + return taskItem; } - /*********************************************************************** - * - * SQL Statement Creation Functions - * - * These functions create SQL statements for update, insert, and create. - * They can probably be factored later to have a db independant - * portion and a db specific portion - * - **********************************************************************/ + #endregion + + #region Create parameters methods /// - /// Create an Insert command + /// Creates the prim inventory parameters. /// - /// - /// - /// the sql command - private static SqlCommand createInsertCommand(string table, DataTable dt) + /// item in inventory. + /// + private SqlParameter[] CreatePrimInventoryParameters(TaskInventoryItem taskItem) { - /** - * This is subtle enough to deserve some commentary. - * Instead of doing *lots* and *lots of hardcoded strings - * for database definitions we'll use the fact that - * realistically all insert statements look like "insert - * into A(b, c) values(:b, :c) on the parameterized query - * front. If we just have a list of b, c, etc... we can - * generate these strings instead of typing them out. - */ - string[] cols = new string[dt.Columns.Count]; - for (int i = 0; i < dt.Columns.Count; i++) - { - DataColumn col = dt.Columns[i]; - cols[i] = col.ColumnName; - } - - string sql = "insert into " + table + "("; - sql += String.Join(", ", cols); - // important, the first ':' needs to be here, the rest get added in the join - sql += ") values (@"; - sql += String.Join(", @", cols); - sql += ")"; - SqlCommand cmd = new SqlCommand(sql); - - // this provides the binding for all our parameters, so - // much less code than it used to be - foreach (DataColumn col in dt.Columns) - { - cmd.Parameters.Add(createSqlParameter(col.ColumnName, col.DataType)); - } - return cmd; + SqlParameter[] parameters = new SqlParameter[19]; + + parameters[0] = _Database.CreateParameter("itemID", taskItem.ItemID); + parameters[1] = _Database.CreateParameter("primID", taskItem.ParentPartID); + parameters[2] = _Database.CreateParameter("assetID", taskItem.AssetID); + parameters[3] = _Database.CreateParameter("parentFolderID", taskItem.ParentID); + + parameters[4] = _Database.CreateParameter("invType", taskItem.InvType); + parameters[5] = _Database.CreateParameter("assetType", taskItem.Type); + + parameters[6] = _Database.CreateParameter("name", taskItem.Name); + parameters[7] = _Database.CreateParameter("description", taskItem.Description); + parameters[8] = _Database.CreateParameter("creationDate", taskItem.CreationDate); + parameters[9] = _Database.CreateParameter("creatorID", taskItem.CreatorID); + parameters[10] = _Database.CreateParameter("ownerID", taskItem.OwnerID); + parameters[11] = _Database.CreateParameter("lastOwnerID", taskItem.LastOwnerID); + parameters[12] = _Database.CreateParameter("groupID", taskItem.GroupID); + parameters[13] = _Database.CreateParameter("nextPermissions", taskItem.NextPermissions); + parameters[14] = _Database.CreateParameter("currentPermissions", taskItem.CurrentPermissions); + parameters[15] = _Database.CreateParameter("basePermissions", taskItem.BasePermissions); + parameters[16] = _Database.CreateParameter("everyonePermissions", taskItem.EveryonePermissions); + parameters[17] = _Database.CreateParameter("groupPermissions", taskItem.GroupPermissions); + parameters[18] = _Database.CreateParameter("flags", taskItem.Flags); + + return parameters; } /// - /// Create an update command + /// Creates the region setting parameters. /// - /// - /// - /// - /// the sql command - private static SqlCommand createUpdateCommand(string table, string pk, DataTable dt) + /// regionsettings. + /// + private SqlParameter[] CreateRegionSettingParameters(RegionSettings settings) { - string sql = "update " + table + " set "; - string subsql = String.Empty; - foreach (DataColumn col in dt.Columns) - { - if (subsql.Length > 0) - { - // a map function would rock so much here - subsql += ", "; - } - subsql += col.ColumnName + "= @" + col.ColumnName; - } - sql += subsql; - sql += " where " + pk; - SqlCommand cmd = new SqlCommand(sql); - - // this provides the binding for all our parameters, so - // much less code than it used to be - - foreach (DataColumn col in dt.Columns) - { - cmd.Parameters.Add(createSqlParameter(col.ColumnName, col.DataType)); - } - return cmd; + SqlParameter[] parameters = new SqlParameter[34]; + + parameters[0] = _Database.CreateParameter("regionUUID", settings.RegionUUID); + parameters[1] = _Database.CreateParameter("block_terraform", settings.BlockTerraform); + parameters[2] = _Database.CreateParameter("block_fly", settings.BlockFly); + parameters[3] = _Database.CreateParameter("allow_damage", settings.AllowDamage); + parameters[4] = _Database.CreateParameter("restrict_pushing", settings.RestrictPushing); + parameters[5] = _Database.CreateParameter("allow_land_resell", settings.AllowLandResell); + parameters[6] = _Database.CreateParameter("allow_land_join_divide", settings.AllowLandJoinDivide); + parameters[7] = _Database.CreateParameter("block_show_in_search", settings.BlockShowInSearch); + parameters[8] = _Database.CreateParameter("agent_limit", settings.AgentLimit); + parameters[9] = _Database.CreateParameter("object_bonus", settings.ObjectBonus); + parameters[10] = _Database.CreateParameter("maturity", settings.Maturity); + parameters[11] = _Database.CreateParameter("disable_scripts", settings.DisableScripts); + parameters[12] = _Database.CreateParameter("disable_collisions", settings.DisableCollisions); + parameters[13] = _Database.CreateParameter("disable_physics", settings.DisablePhysics); + parameters[14] = _Database.CreateParameter("terrain_texture_1", settings.TerrainTexture1); + parameters[15] = _Database.CreateParameter("terrain_texture_2", settings.TerrainTexture2); + parameters[16] = _Database.CreateParameter("terrain_texture_3", settings.TerrainTexture3); + parameters[17] = _Database.CreateParameter("terrain_texture_4", settings.TerrainTexture4); + parameters[18] = _Database.CreateParameter("elevation_1_nw", settings.Elevation1NW); + parameters[19] = _Database.CreateParameter("elevation_2_nw", settings.Elevation2NW); + parameters[20] = _Database.CreateParameter("elevation_1_ne", settings.Elevation1NE); + parameters[21] = _Database.CreateParameter("elevation_2_ne", settings.Elevation2NE); + parameters[22] = _Database.CreateParameter("elevation_1_se", settings.Elevation1SE); + parameters[23] = _Database.CreateParameter("elevation_2_se", settings.Elevation2SE); + parameters[24] = _Database.CreateParameter("elevation_1_sw", settings.Elevation1SW); + parameters[25] = _Database.CreateParameter("elevation_2_sw", settings.Elevation2SW); + parameters[26] = _Database.CreateParameter("water_height", settings.WaterHeight); + parameters[27] = _Database.CreateParameter("terrain_raise_limit", settings.TerrainRaiseLimit); + parameters[28] = _Database.CreateParameter("terrain_lower_limit", settings.TerrainLowerLimit); + parameters[29] = _Database.CreateParameter("use_estate_sun", settings.UseEstateSun); + parameters[30] = _Database.CreateParameter("sandbox", settings.Sandbox); + parameters[31] = _Database.CreateParameter("fixed_sun", settings.FixedSun); + parameters[32] = _Database.CreateParameter("sun_position", settings.SunPosition); + parameters[33] = _Database.CreateParameter("covenant", settings.Covenant); + + return parameters; } /// - /// + /// Creates the land parameters. /// - /// + /// land parameters. + /// region UUID. /// - private static string defineTable(DataTable dt) + private SqlParameter[] CreateLandParameters(LandData land, LLUUID regionUUID) { - string sql = "create table " + dt.TableName + "("; - string subsql = String.Empty; - foreach (DataColumn col in dt.Columns) - { - if (subsql.Length > 0) - { - // a map function would rock so much here - subsql += ",\n"; - } - subsql += col.ColumnName + " " + MSSQLManager.SqlType(col.DataType); - if (dt.PrimaryKey.Length > 0 && col == dt.PrimaryKey[0]) - { - subsql += " primary key"; - } - } - sql += subsql; - sql += ")"; + SqlParameter[] parameters = new SqlParameter[32]; - return sql; - } + parameters[0] = _Database.CreateParameter("UUID", land.GlobalID); + parameters[1] = _Database.CreateParameter("RegionUUID", regionUUID); + parameters[2] = _Database.CreateParameter("LocalLandID", land.LocalID); - /*********************************************************************** - * - * Database Binding functions - * - * These will be db specific due to typing, and minor differences - * in databases. - * - **********************************************************************/ - - /// - /// - /// This is a convenience function that collapses 5 repetitive - /// lines for defining SqlParameters to 2 parameters: - /// column name and database type. - /// - /// - /// - /// It assumes certain conventions like :param as the param - /// name to replace in parametrized queries, and that source - /// version is always current version, both of which are fine - /// for us. - /// - /// - ///a built Sql parameter - private static SqlParameter createSqlParameter(string name, Type type) - { - SqlParameter param = new SqlParameter(); - param.ParameterName = "@" + name; - param.DbType = dbtypeFromType(type); - param.SourceColumn = name; - param.SourceVersion = DataRowVersion.Current; - return param; + // Bitmap is a byte[512] + parameters[3] = _Database.CreateParameter("Bitmap", land.Bitmap); + + parameters[4] = _Database.CreateParameter("Name", land.Name); + parameters[5] = _Database.CreateParameter("Description", land.Description); + parameters[6] = _Database.CreateParameter("OwnerUUID", land.OwnerID); + parameters[7] = _Database.CreateParameter("IsGroupOwned", land.IsGroupOwned); + parameters[8] = _Database.CreateParameter("Area", land.Area); + parameters[9] = _Database.CreateParameter("AuctionID", land.AuctionID); //Unemplemented + parameters[10] = _Database.CreateParameter("Category", (int)land.Category); //Enum libsecondlife.Parcel.ParcelCategory + parameters[11] = _Database.CreateParameter("ClaimDate", land.ClaimDate); + parameters[12] = _Database.CreateParameter("ClaimPrice", land.ClaimPrice); + parameters[13] = _Database.CreateParameter("GroupUUID", land.GroupID); + parameters[14] = _Database.CreateParameter("SalePrice", land.SalePrice); + parameters[15] = _Database.CreateParameter("LandStatus", (int)land.Status); //Enum. libsecondlife.Parcel.ParcelStatus + parameters[16] = _Database.CreateParameter("LandFlags", land.Flags); + parameters[17] = _Database.CreateParameter("LandingType", land.LandingType); + parameters[18] = _Database.CreateParameter("MediaAutoScale", land.MediaAutoScale); + parameters[19] = _Database.CreateParameter("MediaTextureUUID", land.MediaID); + parameters[20] = _Database.CreateParameter("MediaURL", land.MediaURL); + parameters[21] = _Database.CreateParameter("MusicURL", land.MusicURL); + parameters[22] = _Database.CreateParameter("PassHours", land.PassHours); + parameters[23] = _Database.CreateParameter("PassPrice", land.PassPrice); + parameters[24] = _Database.CreateParameter("SnapshotUUID", land.SnapshotID); + parameters[25] = _Database.CreateParameter("UserLocationX", land.UserLocation.X); + parameters[26] = _Database.CreateParameter("UserLocationY", land.UserLocation.Y); + parameters[27] = _Database.CreateParameter("UserLocationZ", land.UserLocation.Z); + parameters[28] = _Database.CreateParameter("UserLookAtX", land.UserLookAt.X); + parameters[29] = _Database.CreateParameter("UserLookAtY", land.UserLookAt.Y); + parameters[30] = _Database.CreateParameter("UserLookAtZ", land.UserLookAt.Z); + parameters[31] = _Database.CreateParameter("AuthBuyerID", land.AuthBuyerID); + + return parameters; } /// - /// + /// Creates the land access parameters. /// - /// - /// - private void setupPrimCommands(SqlDataAdapter da, SqlConnection conn) + /// parcel access entry. + /// parcel ID. + /// + private SqlParameter[] CreateLandAccessParameters(ParcelManager.ParcelAccessEntry parcelAccessEntry, LLUUID parcelID) { - da.InsertCommand = createInsertCommand("prims", m_dataSet.Tables["prims"]); - da.InsertCommand.Connection = conn; + SqlParameter[] parameters = new SqlParameter[3]; - da.UpdateCommand = createUpdateCommand("prims", "UUID=@UUID", m_dataSet.Tables["prims"]); - da.UpdateCommand.Connection = conn; + parameters[0] = _Database.CreateParameter("LandUUID", parcelID); + parameters[1] = _Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID); + parameters[2] = _Database.CreateParameter("Flags", parcelAccessEntry.Flags); - SqlCommand delete = new SqlCommand("delete from prims where UUID = @UUID"); - delete.Parameters.Add(createSqlParameter("UUID", typeof(String))); - delete.Connection = conn; - da.DeleteCommand = delete; + return parameters; } /// - /// + /// Fills/Updates the prim datarow. /// - /// - /// - private void SetupItemsCommands(SqlDataAdapter da, SqlConnection conn) + /// datarow. + /// prim data. + /// scenegroup ID. + /// regionUUID. + private static void fillPrimRow(DataRow row, SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) { - da.InsertCommand = createInsertCommand("primitems", m_itemsTable); - da.InsertCommand.Connection = conn; + row["UUID"] = prim.UUID.ToString(); + row["RegionUUID"] = regionUUID.ToString(); + row["ParentID"] = prim.ParentID; + row["CreationDate"] = prim.CreationDate; + row["Name"] = prim.Name; + row["SceneGroupID"] = sceneGroupID.ToString(); + // the UUID of the root part for this SceneObjectGroup + // various text fields + row["Text"] = prim.Text; + row["Description"] = prim.Description; + row["SitName"] = prim.SitName; + row["TouchName"] = prim.TouchName; + // permissions + row["ObjectFlags"] = prim.ObjectFlags; + row["CreatorID"] = prim.CreatorID.ToString(); + row["OwnerID"] = prim.OwnerID.ToString(); + row["GroupID"] = prim.GroupID.ToString(); + row["LastOwnerID"] = prim.LastOwnerID.ToString(); + row["OwnerMask"] = prim.OwnerMask; + row["NextOwnerMask"] = prim.NextOwnerMask; + row["GroupMask"] = prim.GroupMask; + row["EveryoneMask"] = prim.EveryoneMask; + row["BaseMask"] = prim.BaseMask; + // vectors + row["PositionX"] = prim.OffsetPosition.X; + row["PositionY"] = prim.OffsetPosition.Y; + row["PositionZ"] = prim.OffsetPosition.Z; + row["GroupPositionX"] = prim.GroupPosition.X; + row["GroupPositionY"] = prim.GroupPosition.Y; + row["GroupPositionZ"] = prim.GroupPosition.Z; + row["VelocityX"] = prim.Velocity.X; + row["VelocityY"] = prim.Velocity.Y; + row["VelocityZ"] = prim.Velocity.Z; + row["AngularVelocityX"] = prim.AngularVelocity.X; + row["AngularVelocityY"] = prim.AngularVelocity.Y; + row["AngularVelocityZ"] = prim.AngularVelocity.Z; + row["AccelerationX"] = prim.Acceleration.X; + row["AccelerationY"] = prim.Acceleration.Y; + row["AccelerationZ"] = prim.Acceleration.Z; + // quaternions + row["RotationX"] = prim.RotationOffset.X; + row["RotationY"] = prim.RotationOffset.Y; + row["RotationZ"] = prim.RotationOffset.Z; + row["RotationW"] = prim.RotationOffset.W; + + // Sit target + LLVector3 sitTargetPos = prim.SitTargetPositionLL; + row["SitTargetOffsetX"] = sitTargetPos.X; + row["SitTargetOffsetY"] = sitTargetPos.Y; + row["SitTargetOffsetZ"] = sitTargetPos.Z; + + LLQuaternion sitTargetOrient = prim.SitTargetOrientationLL; + row["SitTargetOrientW"] = sitTargetOrient.W; + row["SitTargetOrientX"] = sitTargetOrient.X; + row["SitTargetOrientY"] = sitTargetOrient.Y; + row["SitTargetOrientZ"] = sitTargetOrient.Z; + + row["PayPrice"] = prim.PayPrice[0]; + row["PayButton1"] = prim.PayPrice[1]; + row["PayButton2"] = prim.PayPrice[2]; + row["PayButton3"] = prim.PayPrice[3]; + row["PayButton4"] = prim.PayPrice[4]; + + if ((prim.SoundFlags & 1) != 0) // Looped + { + row["LoopedSound"] = prim.Sound.ToString(); + row["LoopedSoundGain"] = prim.SoundGain; + } + else + { + row["LoopedSound"] = LLUUID.Zero; + row["LoopedSoundGain"] = 0.0f; + } - da.UpdateCommand = createUpdateCommand("primitems", "itemID = @itemID", m_itemsTable); - da.UpdateCommand.Connection = conn; + row["TextureAnimation"] = prim.TextureAnimation; - SqlCommand delete = new SqlCommand("delete from primitems where itemID = @itemID"); - delete.Parameters.Add(createSqlParameter("itemID", typeof(String))); - delete.Connection = conn; - da.DeleteCommand = delete; - } + row["OmegaX"] = prim.RotationalVelocity.X; + row["OmegaY"] = prim.RotationalVelocity.Y; + row["OmegaZ"] = prim.RotationalVelocity.Z; - /// - /// - /// - /// - /// - private void setupTerrainCommands(SqlDataAdapter da, SqlConnection conn) - { - da.InsertCommand = createInsertCommand("terrain", m_dataSet.Tables["terrain"]); - da.InsertCommand.Connection = conn; - } + row["CameraEyeOffsetX"] = prim.GetCameraEyeOffset().X; + row["CameraEyeOffsetY"] = prim.GetCameraEyeOffset().Y; + row["CameraEyeOffsetZ"] = prim.GetCameraEyeOffset().Z; - /// - /// - /// - /// - /// - private void setupLandCommands(SqlDataAdapter da, SqlConnection conn) - { - da.InsertCommand = createInsertCommand("land", m_dataSet.Tables["land"]); - da.InsertCommand.Connection = conn; + row["CameraAtOffsetX"] = prim.GetCameraAtOffset().X; + row["CameraAtOffsetY"] = prim.GetCameraAtOffset().Y; + row["CameraAtOffsetZ"] = prim.GetCameraAtOffset().Z; - da.UpdateCommand = createUpdateCommand("land", "UUID=@UUID", m_dataSet.Tables["land"]); - da.UpdateCommand.Connection = conn; - } + if (prim.GetForceMouselook()) + row["ForceMouselook"] = 1; + else + row["ForceMouselook"] = 0; - /// - /// - /// - /// - /// - private void setupLandAccessCommands(SqlDataAdapter da, SqlConnection conn) - { - da.InsertCommand = createInsertCommand("landaccesslist", m_dataSet.Tables["landaccesslist"]); - da.InsertCommand.Connection = conn; - } + row["ScriptAccessPin"] = prim.ScriptAccessPin; - /// - /// - /// - /// - /// - private void setupShapeCommands(SqlDataAdapter da, SqlConnection conn) - { - da.InsertCommand = createInsertCommand("primshapes", m_dataSet.Tables["primshapes"]); - da.InsertCommand.Connection = conn; + if (prim.AllowedDrop) + row["AllowedDrop"] = 1; + else + row["AllowedDrop"] = 0; - da.UpdateCommand = createUpdateCommand("primshapes", "UUID=@UUID", m_dataSet.Tables["primshapes"]); - da.UpdateCommand.Connection = conn; + if (prim.DIE_AT_EDGE) + row["DieAtEdge"] = 1; + else + row["DieAtEdge"] = 0; - SqlCommand delete = new SqlCommand("delete from primshapes where UUID = @UUID"); - delete.Parameters.Add(createSqlParameter("UUID", typeof(String))); - delete.Connection = conn; - da.DeleteCommand = delete; + row["SalePrice"] = prim.SalePrice; + row["SaleType"] = Convert.ToInt16(prim.ObjectSaleType); } /// - /// + /// Fills/Updates the shape datarow. /// - /// - private static void InitDB(SqlConnection conn) + /// datarow to fill/update. + /// prim shape data. + private static void fillShapeRow(DataRow row, SceneObjectPart prim) { - string createPrims = defineTable(createPrimTable()); - string createShapes = defineTable(createShapeTable()); - string createItems = defineTable(createItemsTable()); - string createTerrain = defineTable(createTerrainTable()); - string createLand = defineTable(createLandTable()); - string createLandAccessList = defineTable(createLandAccessListTable()); - - SqlCommand pcmd = new SqlCommand(createPrims, conn); - SqlCommand scmd = new SqlCommand(createShapes, conn); - SqlCommand icmd = new SqlCommand(createItems, conn); - SqlCommand tcmd = new SqlCommand(createTerrain, conn); - SqlCommand lcmd = new SqlCommand(createLand, conn); - SqlCommand lalcmd = new SqlCommand(createLandAccessList, conn); - - conn.Open(); - try - { - pcmd.ExecuteNonQuery(); - } - catch (SqlException e) - { - m_log.WarnFormat("[MSSql]: Primitives Table Already Exists: {0}", e); - } - - try - { - scmd.ExecuteNonQuery(); - } - catch (SqlException e) - { - m_log.WarnFormat("[MSSql]: Shapes Table Already Exists: {0}", e); - } - - try - { - icmd.ExecuteNonQuery(); - } - catch (SqlException e) - { - m_log.WarnFormat("[MSSql]: Items Table Already Exists: {0}", e); - } - - try - { - tcmd.ExecuteNonQuery(); - } - catch (SqlException e) - { - m_log.WarnFormat("[MSSql]: Terrain Table Already Exists: {0}", e); - } - - try - { - lcmd.ExecuteNonQuery(); - } - catch (SqlException e) - { - m_log.WarnFormat("[MSSql]: Land Table Already Exists: {0}", e); - } - - try - { - lalcmd.ExecuteNonQuery(); - } - catch (SqlException e) - { - m_log.WarnFormat("[MSSql]: LandAccessList Table Already Exists: {0}", e); - } - conn.Close(); + PrimitiveBaseShape s = prim.Shape; + row["UUID"] = prim.UUID.ToString(); + // shape is an enum + row["Shape"] = 0; + // vectors + row["ScaleX"] = s.Scale.X; + row["ScaleY"] = s.Scale.Y; + row["ScaleZ"] = s.Scale.Z; + // paths + row["PCode"] = s.PCode; + row["PathBegin"] = s.PathBegin; + row["PathEnd"] = s.PathEnd; + row["PathScaleX"] = s.PathScaleX; + row["PathScaleY"] = s.PathScaleY; + row["PathShearX"] = s.PathShearX; + row["PathShearY"] = s.PathShearY; + row["PathSkew"] = s.PathSkew; + row["PathCurve"] = s.PathCurve; + row["PathRadiusOffset"] = s.PathRadiusOffset; + row["PathRevolutions"] = s.PathRevolutions; + row["PathTaperX"] = s.PathTaperX; + row["PathTaperY"] = s.PathTaperY; + row["PathTwist"] = s.PathTwist; + row["PathTwistBegin"] = s.PathTwistBegin; + // profile + row["ProfileBegin"] = s.ProfileBegin; + row["ProfileEnd"] = s.ProfileEnd; + row["ProfileCurve"] = s.ProfileCurve; + row["ProfileHollow"] = s.ProfileHollow; + row["Texture"] = s.TextureEntry; + row["ExtraParams"] = s.ExtraParams; + row["State"] = s.State; } - /// - /// - /// - /// - /// - private bool TestTables(SqlConnection conn) + #endregion + + private void RetrievePrimsDataForRegion(LLUUID regionUUID, LLUUID sceneGroupID, string primID) { - SqlCommand primSelectCmd = new SqlCommand(m_primSelect, conn); - SqlDataAdapter pDa = new SqlDataAdapter(primSelectCmd); - SqlCommand shapeSelectCmd = new SqlCommand(m_shapeSelect, conn); - SqlDataAdapter sDa = new SqlDataAdapter(shapeSelectCmd); - SqlCommand itemsSelectCmd = new SqlCommand(m_itemsSelect, conn); - SqlDataAdapter iDa = new SqlDataAdapter(itemsSelectCmd); - SqlCommand terrainSelectCmd = new SqlCommand(m_terrainSelect, conn); - SqlDataAdapter tDa = new SqlDataAdapter(terrainSelectCmd); - SqlCommand landSelectCmd = new SqlCommand(m_landSelect, conn); - SqlDataAdapter lDa = new SqlDataAdapter(landSelectCmd); - SqlCommand landAccessListSelectCmd = new SqlCommand(m_landAccessListSelect, conn); - SqlDataAdapter lalDa = new SqlDataAdapter(landAccessListSelectCmd); - - DataSet tmpDS = new DataSet(); - try + using (SqlConnection connection = _Database.DatabaseConnection()) { - pDa.Fill(tmpDS, "prims"); - sDa.Fill(tmpDS, "primshapes"); - - iDa.Fill(tmpDS, "primitems"); + _PrimDataAdapter.SelectCommand.Connection = connection; + _PrimDataAdapter.SelectCommand.Parameters["@RegionUUID"].Value = regionUUID.ToString(); + if (sceneGroupID != LLUUID.Zero) + _PrimDataAdapter.SelectCommand.Parameters["@SceneGroupID"].Value = sceneGroupID.ToString(); + else + _PrimDataAdapter.SelectCommand.Parameters["@SceneGroupID"].Value = "%"; + _PrimDataAdapter.SelectCommand.Parameters["@UUID"].Value = primID; - tDa.Fill(tmpDS, "terrain"); - lDa.Fill(tmpDS, "land"); - lalDa.Fill(tmpDS, "landaccesslist"); - } - catch (SqlException) - { - m_log.Info("[REGION DB]: MS Sql Database doesn't exist... creating"); - InitDB(conn); - } + _PrimDataAdapter.Fill(_PrimsDataSet, "prims"); - pDa.Fill(tmpDS, "prims"); - sDa.Fill(tmpDS, "primshapes"); + _ShapeDataAdapter.SelectCommand.Connection = connection; + _ShapeDataAdapter.SelectCommand.Parameters["@RegionUUID"].Value = regionUUID.ToString(); + if (sceneGroupID != LLUUID.Zero) + _ShapeDataAdapter.SelectCommand.Parameters["@SceneGroupID"].Value = sceneGroupID.ToString(); + else + _ShapeDataAdapter.SelectCommand.Parameters["@SceneGroupID"].Value = "%"; + _ShapeDataAdapter.SelectCommand.Parameters["@UUID"].Value = primID; - iDa.Fill(tmpDS, "primitems"); + _ShapeDataAdapter.Fill(_PrimsDataSet, "primshapes"); - tDa.Fill(tmpDS, "terrain"); - lDa.Fill(tmpDS, "land"); - lalDa.Fill(tmpDS, "landaccesslist"); + _ItemsDataAdapter.SelectCommand.Connection = connection; + _ItemsDataAdapter.SelectCommand.Parameters["@RegionUUID"].Value = regionUUID.ToString(); + if (sceneGroupID != LLUUID.Zero) + _ItemsDataAdapter.SelectCommand.Parameters["@SceneGroupID"].Value = sceneGroupID.ToString(); + else + _ItemsDataAdapter.SelectCommand.Parameters["@SceneGroupID"].Value = "%"; + _ItemsDataAdapter.SelectCommand.Parameters["@UUID"].Value = primID; - foreach (DataColumn col in createPrimTable().Columns) - { - if (!tmpDS.Tables["prims"].Columns.Contains(col.ColumnName)) - { - m_log.Info("[REGION DB]: Missing required column:" + col.ColumnName); - return false; - } + _ItemsDataAdapter.Fill(_PrimsDataSet, "primitems"); } + } - foreach (DataColumn col in createShapeTable().Columns) + private void CommitDataSet() + { + lock (_PrimsDataSet) { - if (!tmpDS.Tables["primshapes"].Columns.Contains(col.ColumnName)) + using (SqlConnection connection = _Database.DatabaseConnection()) { - m_log.Info("[REGION DB]: Missing required column:" + col.ColumnName); - return false; - } - } + _PrimDataAdapter.InsertCommand.Connection = connection; + _PrimDataAdapter.UpdateCommand.Connection = connection; + _PrimDataAdapter.DeleteCommand.Connection = connection; - // XXX primitems should probably go here eventually + _ShapeDataAdapter.InsertCommand.Connection = connection; + _ShapeDataAdapter.UpdateCommand.Connection = connection; + _ShapeDataAdapter.DeleteCommand.Connection = connection; - foreach (DataColumn col in createTerrainTable().Columns) - { - if (!tmpDS.Tables["terrain"].Columns.Contains(col.ColumnName)) - { - m_log.Info("[REGION DB]: Missing require column:" + col.ColumnName); - return false; - } - } + _ItemsDataAdapter.InsertCommand.Connection = connection; + _ItemsDataAdapter.UpdateCommand.Connection = connection; + _ItemsDataAdapter.DeleteCommand.Connection = connection; - foreach (DataColumn col in createLandTable().Columns) - { - if (!tmpDS.Tables["land"].Columns.Contains(col.ColumnName)) - { - m_log.Info("[REGION DB]: Missing require column:" + col.ColumnName); - return false; - } - } + _PrimDataAdapter.Update(_PrimsDataSet.Tables["prims"]); + _ShapeDataAdapter.Update(_PrimsDataSet.Tables["primshapes"]); + _ItemsDataAdapter.Update(_PrimsDataSet.Tables["primitems"]); - foreach (DataColumn col in createLandAccessListTable().Columns) - { - if (!tmpDS.Tables["landaccesslist"].Columns.Contains(col.ColumnName)) - { - m_log.Info("[REGION DB]: Missing require column:" + col.ColumnName); - return false; + _PrimsDataSet.AcceptChanges(); + + _PrimsDataSet.Tables["prims"].Clear(); + _PrimsDataSet.Tables["primshapes"].Clear(); + _PrimsDataSet.Tables["primitems"].Clear(); } } - - return true; } - /*********************************************************************** - * - * Type conversion functions - * - **********************************************************************/ - - /// - /// Type conversion function - /// - /// a Type - /// a DbType - private static DbType dbtypeFromType(Type type) + private static void SetupCommands(SqlDataAdapter dataAdapter) { - if (type == typeof(String)) - { - return DbType.String; - } - else if (type == typeof(Int32)) - { - return DbType.Int32; - } - else if (type == typeof(Double)) - { - return DbType.Double; - } - else if (type == typeof(Byte[])) - { - return DbType.Binary; - } - else - { - return DbType.String; - } + SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter); + + dataAdapter.InsertCommand = commandBuilder.GetInsertCommand(true); + dataAdapter.UpdateCommand = commandBuilder.GetUpdateCommand(true); + dataAdapter.DeleteCommand = commandBuilder.GetDeleteCommand(true); } + #endregion } } diff --git a/OpenSim/Data/MSSQL/Resources/001_EstateStore.sql b/OpenSim/Data/MSSQL/Resources/001_EstateStore.sql new file mode 100644 index 0000000..9bb2f75 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/001_EstateStore.sql @@ -0,0 +1,85 @@ +BEGIN TRANSACTION + +CREATE TABLE [dbo].[estate_managers]( + [EstateID] [int] NOT NULL, + [uuid] [varchar](36) NOT NULL, + CONSTRAINT [PK_estate_managers] PRIMARY KEY CLUSTERED +( + [EstateID] ASC +)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] +) ON [PRIMARY]; + +CREATE TABLE [dbo].[estate_groups]( + [EstateID] [int] NOT NULL, + [uuid] [varchar](36) NOT NULL, + CONSTRAINT [PK_estate_groups] PRIMARY KEY CLUSTERED +( + [EstateID] ASC +)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] +) ON [PRIMARY]; + + +CREATE TABLE [dbo].[estate_users]( + [EstateID] [int] NOT NULL, + [uuid] [varchar](36) NOT NULL, + CONSTRAINT [PK_estate_users] PRIMARY KEY CLUSTERED +( + [EstateID] ASC +)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] +) ON [PRIMARY]; + + +CREATE TABLE [dbo].[estateban]( + [EstateID] [int] NOT NULL, + [bannedUUID] [varchar](36) NOT NULL, + [bannedIp] [varchar](16) NOT NULL, + [bannedIpHostMask] [varchar](16) NOT NULL, + [bannedNameMask] [varchar](64) NULL DEFAULT (NULL), + CONSTRAINT [PK_estateban] PRIMARY KEY CLUSTERED +( + [EstateID] ASC +)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] +) ON [PRIMARY]; + +CREATE TABLE [dbo].[estate_settings]( + [EstateID] [int] IDENTITY(1,100) NOT NULL, + [EstateName] [varchar](64) NULL DEFAULT (NULL), + [AbuseEmailToEstateOwner] [bit] NOT NULL, + [DenyAnonymous] [bit] NOT NULL, + [ResetHomeOnTeleport] [bit] NOT NULL, + [FixedSun] [bit] NOT NULL, + [DenyTransacted] [bit] NOT NULL, + [BlockDwell] [bit] NOT NULL, + [DenyIdentified] [bit] NOT NULL, + [AllowVoice] [bit] NOT NULL, + [UseGlobalTime] [bit] NOT NULL, + [PricePerMeter] [int] NOT NULL, + [TaxFree] [bit] NOT NULL, + [AllowDirectTeleport] [bit] NOT NULL, + [RedirectGridX] [int] NOT NULL, + [RedirectGridY] [int] NOT NULL, + [ParentEstateID] [int] NOT NULL, + [SunPosition] [float] NOT NULL, + [EstateSkipScripts] [bit] NOT NULL, + [BillableFactor] [float] NOT NULL, + [PublicAccess] [bit] NOT NULL, + [AbuseEmail] [varchar](255) NOT NULL, + [EstateOwner] [varchar](36) NOT NULL, + [DenyMinors] [bit] NOT NULL, + CONSTRAINT [PK_estate_settings] PRIMARY KEY CLUSTERED +( + [EstateID] ASC +)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] +) ON [PRIMARY]; + + +CREATE TABLE [dbo].[estate_map]( + [RegionID] [varchar](36) NOT NULL DEFAULT ('00000000-0000-0000-0000-000000000000'), + [EstateID] [int] NOT NULL, + CONSTRAINT [PK_estate_map] PRIMARY KEY CLUSTERED +( + [RegionID] ASC +)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] +) ON [PRIMARY]; + +COMMIT \ No newline at end of file diff --git a/OpenSim/Data/MSSQL/Resources/002_RegionStore.sql b/OpenSim/Data/MSSQL/Resources/002_RegionStore.sql new file mode 100644 index 0000000..1801035 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/002_RegionStore.sql @@ -0,0 +1,50 @@ +BEGIN TRANSACTION + +CREATE TABLE regionban ( + [regionUUID] VARCHAR(36) NOT NULL, + [bannedUUID] VARCHAR(36) NOT NULL, + [bannedIp] VARCHAR(16) NOT NULL, + [bannedIpHostMask] VARCHAR(16) NOT NULL) + +create table [dbo].[regionsettings] ( + [regionUUID] [varchar](36) not null, + [block_terraform] [bit] not null, + [block_fly] [bit] not null, + [allow_damage] [bit] not null, + [restrict_pushing] [bit] not null, + [allow_land_resell] [bit] not null, + [allow_land_join_divide] [bit] not null, + [block_show_in_search] [bit] not null, + [agent_limit] [int] not null, + [object_bonus] [float] not null, + [maturity] [int] not null, + [disable_scripts] [bit] not null, + [disable_collisions] [bit] not null, + [disable_physics] [bit] not null, + [terrain_texture_1] [varchar](36) not null, + [terrain_texture_2] [varchar](36) not null, + [terrain_texture_3] [varchar](36) not null, + [terrain_texture_4] [varchar](36) not null, + [elevation_1_nw] [float] not null, + [elevation_2_nw] [float] not null, + [elevation_1_ne] [float] not null, + [elevation_2_ne] [float] not null, + [elevation_1_se] [float] not null, + [elevation_2_se] [float] not null, + [elevation_1_sw] [float] not null, + [elevation_2_sw] [float] not null, + [water_height] [float] not null, + [terrain_raise_limit] [float] not null, + [terrain_lower_limit] [float] not null, + [use_estate_sun] [bit] not null, + [fixed_sun] [bit] not null, + [sun_position] [float] not null, + [covenant] [varchar](36) default NULL, + [Sandbox] [bit] NOT NULL, +PRIMARY KEY CLUSTERED +( + [regionUUID] ASC +)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] +) ON [PRIMARY] + +COMMIT \ No newline at end of file diff --git a/OpenSim/Data/MSSQL/Resources/003_RegionStore.sql b/OpenSim/Data/MSSQL/Resources/003_RegionStore.sql new file mode 100644 index 0000000..a8f40c2 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/003_RegionStore.sql @@ -0,0 +1,67 @@ +BEGIN TRANSACTION + +CREATE TABLE dbo.Tmp_prims + ( + UUID varchar(36) NOT NULL, + RegionUUID varchar(36) NULL, + ParentID int NULL, + CreationDate int NULL, + Name varchar(255) NULL, + SceneGroupID varchar(36) NULL, + Text varchar(255) NULL, + Description varchar(255) NULL, + SitName varchar(255) NULL, + TouchName varchar(255) NULL, + ObjectFlags int NULL, + CreatorID varchar(36) NULL, + OwnerID varchar(36) NULL, + GroupID varchar(36) NULL, + LastOwnerID varchar(36) NULL, + OwnerMask int NULL, + NextOwnerMask int NULL, + GroupMask int NULL, + EveryoneMask int NULL, + BaseMask int NULL, + PositionX float(53) NULL, + PositionY float(53) NULL, + PositionZ float(53) NULL, + GroupPositionX float(53) NULL, + GroupPositionY float(53) NULL, + GroupPositionZ float(53) NULL, + VelocityX float(53) NULL, + VelocityY float(53) NULL, + VelocityZ float(53) NULL, + AngularVelocityX float(53) NULL, + AngularVelocityY float(53) NULL, + AngularVelocityZ float(53) NULL, + AccelerationX float(53) NULL, + AccelerationY float(53) NULL, + AccelerationZ float(53) NULL, + RotationX float(53) NULL, + RotationY float(53) NULL, + RotationZ float(53) NULL, + RotationW float(53) NULL, + SitTargetOffsetX float(53) NULL, + SitTargetOffsetY float(53) NULL, + SitTargetOffsetZ float(53) NULL, + SitTargetOrientW float(53) NULL, + SitTargetOrientX float(53) NULL, + SitTargetOrientY float(53) NULL, + SitTargetOrientZ float(53) NULL + ) ON [PRIMARY] + +IF EXISTS(SELECT * FROM dbo.prims) + EXEC('INSERT INTO dbo.Tmp_prims (UUID, RegionUUID, ParentID, CreationDate, Name, SceneGroupID, Text, Description, SitName, TouchName, ObjectFlags, CreatorID, OwnerID, GroupID, LastOwnerID, OwnerMask, NextOwnerMask, GroupMask, EveryoneMask, BaseMask, PositionX, PositionY, PositionZ, GroupPositionX, GroupPositionY, GroupPositionZ, VelocityX, VelocityY, VelocityZ, AngularVelocityX, AngularVelocityY, AngularVelocityZ, AccelerationX, AccelerationY, AccelerationZ, RotationX, RotationY, RotationZ, RotationW, SitTargetOffsetX, SitTargetOffsetY, SitTargetOffsetZ, SitTargetOrientW, SitTargetOrientX, SitTargetOrientY, SitTargetOrientZ) + SELECT CONVERT(varchar(36), UUID), CONVERT(varchar(36), RegionUUID), ParentID, CreationDate, Name, CONVERT(varchar(36), SceneGroupID), Text, Description, SitName, TouchName, ObjectFlags, CONVERT(varchar(36), CreatorID), CONVERT(varchar(36), OwnerID), CONVERT(varchar(36), GroupID), CONVERT(varchar(36), LastOwnerID), OwnerMask, NextOwnerMask, GroupMask, EveryoneMask, BaseMask, PositionX, PositionY, PositionZ, GroupPositionX, GroupPositionY, GroupPositionZ, VelocityX, VelocityY, VelocityZ, AngularVelocityX, AngularVelocityY, AngularVelocityZ, AccelerationX, AccelerationY, AccelerationZ, RotationX, RotationY, RotationZ, RotationW, SitTargetOffsetX, SitTargetOffsetY, SitTargetOffsetZ, SitTargetOrientW, SitTargetOrientX, SitTargetOrientY, SitTargetOrientZ FROM dbo.prims WITH (HOLDLOCK TABLOCKX)') + +DROP TABLE dbo.prims + +EXECUTE sp_rename N'dbo.Tmp_prims', N'prims', 'OBJECT' + +ALTER TABLE dbo.prims ADD CONSTRAINT + PK__prims__10566F31 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 diff --git a/OpenSim/Data/MSSQL/Resources/004_RegionStore.sql b/OpenSim/Data/MSSQL/Resources/004_RegionStore.sql new file mode 100644 index 0000000..4e64901 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/004_RegionStore.sql @@ -0,0 +1,40 @@ +BEGIN TRANSACTION + +CREATE TABLE dbo.Tmp_primitems + ( + itemID varchar(36) NOT NULL, + primID varchar(36) NULL, + assetID varchar(36) NULL, + parentFolderID varchar(36) NULL, + invType int NULL, + assetType int NULL, + name varchar(255) NULL, + description varchar(255) NULL, + creationDate varchar(255) NULL, + creatorID varchar(36) NULL, + ownerID varchar(36) NULL, + lastOwnerID varchar(36) NULL, + groupID varchar(36) NULL, + nextPermissions int NULL, + currentPermissions int NULL, + basePermissions int NULL, + everyonePermissions int NULL, + 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) + 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 + +EXECUTE sp_rename N'dbo.Tmp_primitems', N'primitems', 'OBJECT' + +ALTER TABLE dbo.primitems ADD CONSTRAINT + PK__primitems__0A688BB1 PRIMARY KEY CLUSTERED + ( + itemID + ) 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 new file mode 100644 index 0000000..74e9d85 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/005_RegionStore.sql @@ -0,0 +1,49 @@ +BEGIN TRANSACTION + +CREATE TABLE dbo.Tmp_primshapes + ( + UUID varchar(36) NOT NULL, + Shape int NULL, + ScaleX float(53) NULL, + ScaleY float(53) NULL, + ScaleZ float(53) NULL, + PCode int NULL, + PathBegin int NULL, + PathEnd int NULL, + PathScaleX int NULL, + PathScaleY int NULL, + PathShearX int NULL, + PathShearY int NULL, + PathSkew int NULL, + PathCurve int NULL, + PathRadiusOffset int NULL, + PathRevolutions int NULL, + PathTaperX int NULL, + PathTaperY int NULL, + PathTwist int NULL, + PathTwistBegin int NULL, + ProfileBegin int NULL, + ProfileEnd int NULL, + ProfileCurve int NULL, + ProfileHollow int NULL, + State int NULL, + Texture image NULL, + ExtraParams image NULL + ) 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)') + +DROP TABLE dbo.primshapes + +EXECUTE sp_rename N'dbo.Tmp_primshapes', N'primshapes', 'OBJECT' + +ALTER TABLE dbo.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 diff --git a/OpenSim/Data/MSSQL/Resources/006_RegionStore.sql b/OpenSim/Data/MSSQL/Resources/006_RegionStore.sql new file mode 100644 index 0000000..0419c0c --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/006_RegionStore.sql @@ -0,0 +1,36 @@ +BEGIN TRANSACTION + +ALTER TABLE prims ADD PayPrice int not null default 0 +ALTER TABLE prims ADD PayButton1 int not null default 0 +ALTER TABLE prims ADD PayButton2 int not null default 0 +ALTER TABLE prims ADD PayButton3 int not null default 0 +ALTER TABLE prims ADD PayButton4 int not null default 0 +ALTER TABLE prims ADD LoopedSound varchar(36) not null default '00000000-0000-0000-0000-000000000000'; +ALTER TABLE prims ADD LoopedSoundGain float not null default 0.0; +ALTER TABLE prims ADD TextureAnimation image +ALTER TABLE prims ADD OmegaX float not null default 0.0 +ALTER TABLE prims ADD OmegaY float not null default 0.0 +ALTER TABLE prims ADD OmegaZ float not null default 0.0 +ALTER TABLE prims ADD CameraEyeOffsetX float not null default 0.0 +ALTER TABLE prims ADD CameraEyeOffsetY float not null default 0.0 +ALTER TABLE prims ADD CameraEyeOffsetZ float not null default 0.0 +ALTER TABLE prims ADD CameraAtOffsetX float not null default 0.0 +ALTER TABLE prims ADD CameraAtOffsetY float not null default 0.0 +ALTER TABLE prims ADD CameraAtOffsetZ float not null default 0.0 +ALTER TABLE prims ADD ForceMouselook tinyint not null default 0 +ALTER TABLE prims ADD ScriptAccessPin int not null default 0 +ALTER TABLE prims ADD AllowedDrop tinyint not null default 0 +ALTER TABLE prims ADD DieAtEdge tinyint not null default 0 +ALTER TABLE prims ADD SalePrice int not null default 10 +ALTER TABLE prims ADD SaleType tinyint not null default 0 + +ALTER TABLE primitems add flags integer not null default 0 + +ALTER TABLE land ADD AuthbuyerID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000' + +CREATE index prims_regionuuid on prims(RegionUUID) +CREATE index prims_parentid on prims(ParentID) + +CREATE index primitems_primid on primitems(primID) + +COMMIT diff --git a/OpenSim/Data/Migration.cs b/OpenSim/Data/Migration.cs index ecd18ae..8e4cba3 100644 --- a/OpenSim/Data/Migration.cs +++ b/OpenSim/Data/Migration.cs @@ -103,7 +103,7 @@ namespace OpenSim.Data private void Initialize() { // clever, eh, we figure out which migrations version we are - int migration_version = FindVersion("migrations"); + int migration_version = FindVersion(_conn, "migrations"); if (migration_version > 0) return; @@ -119,7 +119,7 @@ namespace OpenSim.Data public void Update() { int version = 0; - version = FindVersion(_type); + version = FindVersion(_conn, _type); SortedList migrations = GetMigrationsAfter(version); if (migrations.Count < 1) @@ -170,7 +170,7 @@ namespace OpenSim.Data public int Version { - get { return FindVersion(_type); } + get { return FindVersion(_conn, _type); } set { if (Version < 1) { @@ -183,10 +183,10 @@ namespace OpenSim.Data } } - private int FindVersion(string type) + protected virtual int FindVersion(DbConnection conn, string type) { int version = 0; - DbCommand cmd = _conn.CreateCommand(); + DbCommand cmd = conn.CreateCommand(); try { cmd.CommandText = "select version from migrations where name='" + type + "' limit 1"; -- cgit v1.1