Reattaching a region was failing if the estate name had not changed (issue 5035).

Using the RemoteAdmin API to close then recreate a region would fail if the estate name had not changed. If the estate name /was/ changed then the existing estate would be renamed rather than a new one being created. The problem really arose from a lack of distinction in the data storage layer between creating new estates and loading existing ones.
remove-scene-viewer
Kevin Houlihan 2011-09-12 23:08:16 +01:00 committed by Justin Clark-Casey (justincc)
parent 9046651583
commit 1458fab82c
8 changed files with 287 additions and 166 deletions

View File

@ -741,22 +741,31 @@ namespace OpenSim.ApplicationPlugins.RemoteController
}
// Create a new estate with the name provided
region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(region.RegionID, true);
region.EstateSettings = m_application.EstateDataService.CreateNewEstate();
region.EstateSettings.EstateName = (string) requestData["estate_name"];
region.EstateSettings.EstateOwner = userID;
// Persistence does not seem to effect the need to save a new estate
region.EstateSettings.Save();
if (!m_application.EstateDataService.LinkRegion(region.RegionID, (int) region.EstateSettings.EstateID))
throw new Exception("Failed to join estate.");
}
else
{
int estateID = estateIDs[0];
region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(region.RegionID, false);
if (region.EstateSettings.EstateID != estateID)
{
// The region is already part of an estate, but not the one we want.
region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(estateID);
if (!m_application.EstateDataService.LinkRegion(region.RegionID, estateID))
throw new Exception("Failed to join estate.");
}
}
// Create the region and perform any initial initialization

View File

@ -148,14 +148,46 @@ namespace OpenSim.Data.MSSQL
}
}
if (insertEstate && create)
{
DoCreate(es);
LinkRegion(regionID, (int)es.EstateID);
}
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;
}
public EstateSettings CreateNewEstate()
{
EstateSettings es = new EstateSettings();
es.OnSave += StoreEstateSettings;
DoCreate(es);
LoadBanList(es);
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
return es;
}
private void DoCreate(EstateSettings es)
{
List<string> names = new List<string>(FieldList);
names.Remove("EstateID");
sql = string.Format("insert into estate_settings ({0}) values ( @{1})", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray()));
string 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 conn = new SqlConnection(m_connectionString))
@ -176,40 +208,10 @@ namespace OpenSim.Data.MSSQL
es.EstateID = Convert.ToUInt32(idParameter.Value);
}
sql = "INSERT INTO [estate_map] ([RegionID] ,[EstateID]) VALUES (@RegionID, @EstateID)";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@RegionID", regionID));
cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID));
// This will throw on dupe key
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
m_log.DebugFormat("[ESTATE DB]: Error inserting regionID and EstateID in estate_map: {0}", e);
}
}
//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;
}
/// <summary>
/// Stores the estate settings.
/// </summary>
@ -498,24 +500,43 @@ namespace OpenSim.Data.MSSQL
public bool LinkRegion(UUID regionID, int estateID)
{
string sql = "insert into estate_map values (@RegionID, @EstateID)";
string deleteSQL = "delete from estate_map where RegionID = @RegionID";
string insertSQL = "insert into estate_map values (@RegionID, @EstateID)";
using (SqlConnection conn = new SqlConnection(m_connectionString))
{
conn.Open();
SqlTransaction transaction = conn.BeginTransaction();
try
{
using (SqlCommand cmd = new SqlCommand(sql, conn))
using (SqlCommand cmd = new SqlCommand(deleteSQL, conn))
{
cmd.Parameters.AddWithValue("@RegionID", regionID);
cmd.Transaction = transaction;
cmd.Parameters.AddWithValue("@RegionID", regionID.Guid);
cmd.ExecuteNonQuery();
}
using (SqlCommand cmd = new SqlCommand(insertSQL, conn))
{
cmd.Transaction = transaction;
cmd.Parameters.AddWithValue("@RegionID", regionID.Guid);
cmd.Parameters.AddWithValue("@EstateID", estateID);
int ret = cmd.ExecuteNonQuery();
if (ret != 0)
transaction.Commit();
else
transaction.Rollback();
return (ret != 0);
}
}
catch (Exception ex)
{
m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
transaction.Rollback();
}
}
return false;

View File

@ -149,6 +149,22 @@ namespace OpenSim.Data.MySQL
}
}
public EstateSettings CreateNewEstate()
{
EstateSettings es = new EstateSettings();
es.OnSave += StoreEstateSettings;
DoCreate(es);
LoadBanList(es);
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
return es;
}
private EstateSettings DoLoad(MySqlCommand cmd, UUID regionID, bool create)
{
EstateSettings es = new EstateSettings();
@ -187,6 +203,21 @@ namespace OpenSim.Data.MySQL
}
if (!found && create)
{
DoCreate(es);
LinkRegion(regionID, (int)es.EstateID);
}
}
LoadBanList(es);
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
return es;
}
private void DoCreate(EstateSettings es)
{
// Migration case
List<string> names = new List<string>(FieldList);
@ -195,6 +226,9 @@ namespace OpenSim.Data.MySQL
string sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")";
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd2 = dbcon.CreateCommand())
{
cmd2.CommandText = sql;
@ -226,27 +260,11 @@ namespace OpenSim.Data.MySQL
es.EstateID = Convert.ToUInt32(r["id"]);
}
cmd2.CommandText = "insert into estate_map values (?RegionID, ?EstateID)";
cmd2.Parameters.AddWithValue("?RegionID", regionID.ToString());
cmd2.Parameters.AddWithValue("?EstateID", es.EstateID.ToString());
// This will throw on dupe key
try { cmd2.ExecuteNonQuery(); }
catch (Exception) { }
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");
return es;
}
public void StoreEstateSettings(EstateSettings es)
{
string sql = "replace into estate_settings (" + String.Join(",", FieldList) + ") values ( ?" + String.Join(", ?", FieldList) + ")";
@ -477,7 +495,6 @@ namespace OpenSim.Data.MySQL
}
}
dbcon.Close();
}
@ -507,7 +524,6 @@ namespace OpenSim.Data.MySQL
}
}
dbcon.Close();
}
@ -519,16 +535,34 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlTransaction transaction = dbcon.BeginTransaction();
try
{
// Delete any existing association of this region with an estate.
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.Transaction = transaction;
cmd.CommandText = "delete from estate_map where RegionID = ?RegionID";
cmd.Parameters.AddWithValue("?RegionID", regionID);
cmd.ExecuteNonQuery();
}
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.Transaction = transaction;
cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)";
cmd.Parameters.AddWithValue("?RegionID", regionID);
cmd.Parameters.AddWithValue("?EstateID", estateID);
int ret = cmd.ExecuteNonQuery();
if (ret != 0)
transaction.Commit();
else
transaction.Rollback();
dbcon.Close();
return (ret != 0);
@ -537,6 +571,7 @@ namespace OpenSim.Data.MySQL
catch (MySqlException ex)
{
m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
transaction.Rollback();
}
dbcon.Close();

View File

@ -85,6 +85,11 @@ namespace OpenSim.Data.Null
return new EstateSettings();
}
public EstateSettings CreateNewEstate()
{
return new EstateSettings();
}
public List<EstateSettings> LoadEstateSettingsAll()
{
List<EstateSettings> allEstateSettings = new List<EstateSettings>();

View File

@ -151,10 +151,41 @@ namespace OpenSim.Data.SQLite
}
else if (create)
{
r.Close();
DoCreate(es);
LinkRegion(regionID, (int)es.EstateID);
}
LoadBanList(es);
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
return es;
}
public EstateSettings CreateNewEstate()
{
EstateSettings es = new EstateSettings();
es.OnSave += StoreEstateSettings;
DoCreate(es);
LoadBanList(es);
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
return es;
}
private void DoCreate(EstateSettings es)
{
List<string> names = new List<string>(FieldList);
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
IDataReader r = null;
names.Remove("EstateID");
string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")";
@ -190,30 +221,9 @@ namespace OpenSim.Data.SQLite
r.Close();
cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString());
// This will throw on dupe key
try
{
cmd.ExecuteNonQuery();
}
catch (Exception)
{
}
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");
return es;
}
public void StoreEstateSettings(EstateSettings es)
{
List<string> fields = new List<string>(FieldList);
@ -440,17 +450,37 @@ namespace OpenSim.Data.SQLite
public bool LinkRegion(UUID regionID, int estateID)
{
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
SqliteTransaction transaction = m_connection.BeginTransaction();
// Delete any existing estate mapping for this region.
using(SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = "delete from estate_map where RegionID = :RegionID";
cmd.Transaction = transaction;
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
cmd.ExecuteNonQuery();
}
using(SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
cmd.Transaction = transaction;
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
cmd.Parameters.AddWithValue(":EstateID", estateID.ToString());
if (cmd.ExecuteNonQuery() == 0)
{
transaction.Rollback();
return false;
}
else
{
transaction.Commit();
return true;
}
}
}
public List<UUID> GetRegions(int estateID)
{

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@ -49,6 +49,14 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns></returns>
EstateSettings LoadEstateSettings(int estateID);
/// <summary>
/// Create a new estate.
/// </summary>
/// <returns>
/// A <see cref="EstateSettings"/>
/// </returns>
EstateSettings CreateNewEstate();
/// <summary>
/// Load/Get all estate settings.
/// </summary>

View File

@ -54,6 +54,14 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns></returns>
EstateSettings LoadEstateSettings(int estateID);
/// <summary>
/// Create a new estate.
/// </summary>
/// <returns>
/// A <see cref="EstateSettings"/>
/// </returns>
EstateSettings CreateNewEstate();
/// <summary>
/// Load/Get all estate settings.
/// </summary>

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@ -91,6 +91,11 @@ namespace OpenSim.Services.Connectors
return m_database.LoadEstateSettings(estateID);
}
public EstateSettings CreateNewEstate()
{
return m_database.CreateNewEstate();
}
public List<EstateSettings> LoadEstateSettingsAll()
{
return m_database.LoadEstateSettingsAll();