* Adds estate access list supports to NHibernate data module
* Thanks Tommil
0.6.3-post-fixes
Justin Clarke Casey 2009-02-16 19:33:11 +00:00
parent c7a08752c0
commit 80759f708b
12 changed files with 301 additions and 83 deletions

View File

@ -59,12 +59,12 @@ namespace OpenSim.Data.NHibernate
override public AssetBase FetchAsset(UUID uuid)
{
return (AssetBase)manager.Load(typeof(AssetBase), uuid);
return (AssetBase)manager.Get(typeof(AssetBase), uuid);
}
private void Save(AssetBase asset)
{
AssetBase temp = (AssetBase)manager.Load(typeof(AssetBase), asset.Metadata.FullID);
AssetBase temp = (AssetBase)manager.Get(typeof(AssetBase), asset.Metadata.FullID);
if (temp == null)
{
manager.Insert(asset);

View File

@ -89,7 +89,7 @@ namespace OpenSim.Data.NHibernate
// Ensure that estate settings exist for the link
if (link != null)
{
if (manager.Load(typeof(EstateSettings), link.EstateID) == null)
if (manager.GetWithStatefullSession(typeof(EstateSettings), link.EstateID) == null)
{
// Delete broken link
manager.Delete(link);
@ -116,11 +116,11 @@ namespace OpenSim.Data.NHibernate
link.EstateRegionLinkID = UUID.Random();
link.RegionID = regionID;
link.EstateID = estateID;
manager.Insert(link);
manager.InsertWithStatefullSession(link);
}
// Load estate settings according to the existing or created link.
return (EstateSettings)manager.Load(typeof(EstateSettings), link.EstateID);
return (EstateSettings)manager.GetWithStatefullSession(typeof(EstateSettings), link.EstateID);
}
public void StoreEstateSettings(EstateSettings estateSettings)
@ -128,7 +128,7 @@ namespace OpenSim.Data.NHibernate
// Estates are always updated when stored.
// Insert is always done via. load method as with the current API
// this is explicitly the only way to create region link.
manager.Update(estateSettings);
manager.UpdateWithStatefullSession(estateSettings);
}
#endregion

View File

@ -111,7 +111,7 @@ namespace OpenSim.Data.NHibernate
public override DataResponse AddProfile(RegionProfileData profile)
{
if (manager.Load(typeof(RegionProfileData), profile.Uuid) == null)
if (manager.Get(typeof(RegionProfileData), profile.Uuid) == null)
{
manager.Insert(profile);
return DataResponse.RESPONSE_OK;
@ -124,7 +124,7 @@ namespace OpenSim.Data.NHibernate
public override DataResponse UpdateProfile(RegionProfileData profile)
{
if (manager.Load(typeof(RegionProfileData), profile.Uuid) != null)
if (manager.Get(typeof(RegionProfileData), profile.Uuid) != null)
{
manager.Update(profile);
return DataResponse.RESPONSE_OK;
@ -137,7 +137,7 @@ namespace OpenSim.Data.NHibernate
public override DataResponse DeleteProfile(string uuid)
{
RegionProfileData regionProfileData = (RegionProfileData)manager.Load(typeof(RegionProfileData), new UUID(uuid));
RegionProfileData regionProfileData = (RegionProfileData)manager.Get(typeof(RegionProfileData), new UUID(uuid));
if (regionProfileData != null)
{
manager.Delete(regionProfileData);
@ -148,7 +148,7 @@ namespace OpenSim.Data.NHibernate
public override RegionProfileData GetProfileByUUID(UUID UUID)
{
return (RegionProfileData)manager.Load(typeof(RegionProfileData), UUID);
return (RegionProfileData)manager.Get(typeof(RegionProfileData), UUID);
}
public override RegionProfileData GetProfileByHandle(ulong regionHandle)

View File

@ -110,7 +110,7 @@ namespace OpenSim.Data.NHibernate
try
{
m_log.InfoFormat("[NHIBERNATE] getInventoryItem {0}", item);
return (InventoryItemBase)manager.Load(typeof(InventoryItemBase), item);
return (InventoryItemBase)manager.Get(typeof(InventoryItemBase), item);
}
catch
{
@ -158,7 +158,7 @@ namespace OpenSim.Data.NHibernate
/// <param name="item"></param>
public void deleteInventoryItem(UUID itemID)
{
InventoryItemBase item = (InventoryItemBase)manager.Load(typeof(InventoryItemBase), itemID);
InventoryItemBase item = (InventoryItemBase)manager.Get(typeof(InventoryItemBase), itemID);
if (item != null)
{
manager.Delete(item);
@ -179,7 +179,7 @@ namespace OpenSim.Data.NHibernate
{
try
{
return (InventoryFolderBase)manager.Load(typeof(InventoryFolderBase), folder);
return (InventoryFolderBase)manager.Get(typeof(InventoryFolderBase), folder);
}
catch
{
@ -227,7 +227,7 @@ namespace OpenSim.Data.NHibernate
/// <param name="folder"></param>
public void deleteInventoryFolder(UUID folderID)
{
InventoryFolderBase item = (InventoryFolderBase)manager.Load(typeof(InventoryFolderBase), folderID);
InventoryFolderBase item = (InventoryFolderBase)manager.Get(typeof(InventoryFolderBase), folderID);
if (item != null)
{
manager.Delete(item);

View File

@ -45,56 +45,7 @@ namespace OpenSim.Data.NHibernate
private Configuration configuration;
private ISessionFactory sessionFactory;
/// <summary>
/// Parses the connection string and creates the NHibernate configuration
/// </summary>
/// <param name="connect">NHibernate dialect, driver and connection string separated by ';'</param>
private void ParseConnectionString(string connect)
{
// Split out the dialect, driver, and connect string
char[] split = { ';' };
string[] parts = connect.Split(split, 3);
if (parts.Length != 3)
{
// TODO: make this a real exception type
throw new Exception("Malformed Inventory connection string '" + connect + "'");
}
dialect = parts[0];
// NHibernate setup
configuration = new Configuration();
configuration.SetProperty(Environment.ConnectionProvider,
"NHibernate.Connection.DriverConnectionProvider");
configuration.SetProperty(Environment.Dialect,
"NHibernate.Dialect." + dialect);
configuration.SetProperty(Environment.ConnectionDriver,
"NHibernate.Driver." + parts[1]);
configuration.SetProperty(Environment.ConnectionString, parts[2]);
configuration.AddAssembly("OpenSim.Data.NHibernate");
}
/// <summary>
/// Runs migration for the the store in assembly
/// </summary>
/// <param name="dialect">Dialect in use</param>
/// <param name="assembly">Assembly where migration files exist</param>
/// <param name="store">Name of the store in use</param>
private void RunMigration(string dialect, Assembly assembly, string store)
{
// Migration subtype is the folder name under which migrations are stored. For mysql this folder is
// MySQLDialect instead of MySQL5Dialect which is the dialect currently in use. To avoid renaming
// this folder each time the mysql version changes creating simple mapping:
String migrationSubType = dialect;
if (dialect.StartsWith("MySQL"))
{
migrationSubType = "MySQLDialect";
}
Migration migration = new Migration((DbConnection)sessionFactory.ConnectionProvider.GetConnection(), assembly, migrationSubType, store);
migration.Update();
}
#region Initialization
/// <summary>
/// Initiate NHibernate Manager
@ -131,7 +82,66 @@ namespace OpenSim.Data.NHibernate
RunMigration(dialect, assembly, store);
}
public object Load(Type type, Object id)
/// <summary>
/// Parses the connection string and creates the NHibernate configuration
/// </summary>
/// <param name="connect">NHibernate dialect, driver and connection string separated by ';'</param>
private void ParseConnectionString(string connect)
{
// Split out the dialect, driver, and connect string
char[] split = { ';' };
string[] parts = connect.Split(split, 3);
if (parts.Length != 3)
{
// TODO: make this a real exception type
throw new Exception("Malformed Inventory connection string '" + connect + "'");
}
dialect = parts[0];
// NHibernate setup
configuration = new Configuration();
configuration.SetProperty(Environment.ConnectionProvider,
"NHibernate.Connection.DriverConnectionProvider");
configuration.SetProperty(Environment.Dialect,
"NHibernate.Dialect." + dialect);
configuration.SetProperty(Environment.ConnectionDriver,
"NHibernate.Driver." + parts[1]);
configuration.SetProperty(Environment.ConnectionString, parts[2]);
configuration.AddAssembly("OpenSim.Data.NHibernate");
}
/// <summary>
/// Runs migration for the the store in assembly
/// </summary>
/// <param name="dialect">Dialect in use</param>
/// <param name="assembly">Assembly where migration files exist</param>
/// <param name="store">Name of the store in use</param>
private void RunMigration(string dialect, Assembly assembly, string store)
{
// Migration subtype is the folder name under which migrations are stored. For mysql this folder is
// MySQLDialect instead of MySQL5Dialect which is the dialect currently in use. To avoid renaming
// this folder each time the mysql version changes creating simple mapping:
String migrationSubType = dialect;
if (dialect.StartsWith("MySQL"))
{
migrationSubType = "MySQLDialect";
}
Migration migration = new Migration((DbConnection)sessionFactory.ConnectionProvider.GetConnection(), assembly, migrationSubType, store);
migration.Update();
}
#endregion
/// <summary>
/// Gets object of given type from database with given id.
/// Uses stateless session for efficiency.
/// </summary>
/// <param name="type">Type of the object.</param>
/// <param name="id">Id of the object.</param>
/// <returns>The object or null if object was not found.</returns>
public object Get(Type type, Object id)
{
using (IStatelessSession session = sessionFactory.OpenStatelessSession())
{
@ -145,10 +155,40 @@ namespace OpenSim.Data.NHibernate
m_log.ErrorFormat("[NHIBERNATE] {0} of id {1} loading threw exception: " + e.ToString(), type.Name, id);
}
return obj;
}
}
}
/// <summary>
/// Gets object of given type from database with given id.
/// Use this method for objects containing collections. For flat objects stateless mode is more efficient.
/// </summary>
/// <param name="type">Type of the object.</param>
/// <param name="id">Id of the object.</param>
/// <returns>The object or null if object was not found.</returns>
public object GetWithStatefullSession(Type type, Object id)
{
using (ISession session = sessionFactory.OpenSession())
{
object obj = null;
try
{
obj = session.Get(type.FullName, id);
}
catch (Exception e)
{
m_log.ErrorFormat("[NHIBERNATE] {0} of id {1} loading threw exception: " + e.ToString(), type.Name, id);
}
return obj;
}
}
/// <summary>
/// Inserts given object to database.
/// Uses stateless session for efficiency.
/// </summary>
/// <param name="obj">Object to be insterted.</param>
/// <returns>Identifier of the object. Useful for situations when NHibernate generates the identifier.</returns>
public object Insert(object obj)
{
try
@ -170,6 +210,39 @@ namespace OpenSim.Data.NHibernate
}
}
/// <summary>
/// Inserts given object to database.
/// Use this method for objects containing collections. For flat objects stateless mode is more efficient.
/// </summary>
/// <param name="obj">Object to be insterted.</param>
/// <returns>Identifier of the object. Useful for situations when NHibernate generates the identifier.</returns>
public object InsertWithStatefullSession(object obj)
{
try
{
using (ISession session = sessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
Object identifier = session.Save(obj);
transaction.Commit();
return identifier;
}
}
}
catch (Exception e)
{
m_log.Error("[NHIBERNATE] issue inserting object ", e);
return null;
}
}
/// <summary>
/// Updates given object to database.
/// Uses stateless session for efficiency.
/// </summary>
/// <param name="obj">Object to be updated.</param>
/// <returns>True if operation was succesful.</returns>
public bool Update(object obj)
{
try
@ -191,6 +264,38 @@ namespace OpenSim.Data.NHibernate
}
}
/// <summary>
/// Updates given object to database.
/// Use this method for objects containing collections. For flat objects stateless mode is more efficient.
/// </summary>
/// <param name="obj">Object to be updated.</param>
/// <returns>True if operation was succesful.</returns>
public bool UpdateWithStatefullSession(object obj)
{
try
{
using (ISession session = sessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Update(obj);
transaction.Commit();
return true;
}
}
}
catch (Exception e)
{
m_log.Error("[NHIBERNATE] issue updating object ", e);
return false;
}
}
/// <summary>
/// Deletes given object from database.
/// </summary>
/// <param name="obj">Object to be deleted.</param>
/// <returns>True if operation was succesful.</returns>
public bool Delete(object obj)
{
try
@ -212,6 +317,18 @@ namespace OpenSim.Data.NHibernate
}
}
/// <summary>
/// Returns statefull session which can be used to execute custom nhibernate or sql queries.
/// </summary>
/// <returns>Statefull session</returns>
public ISession GetSession()
{
return sessionFactory.OpenSession();
}
/// <summary>
/// Drops the database schema. This exist for unit tests. It should not be invoked from other than test teardown.
/// </summary>
public void DropSchema()
{
SchemaExport export = new SchemaExport(this.configuration);
@ -219,14 +336,10 @@ namespace OpenSim.Data.NHibernate
using (ISession session = sessionFactory.OpenSession())
{
ISQLQuery sqlQuery=session.CreateSQLQuery("drop table migrations");
ISQLQuery sqlQuery = session.CreateSQLQuery("drop table migrations");
sqlQuery.ExecuteUpdate();
}
}
public ISession GetSession()
{
return sessionFactory.OpenSession();
}
}
}

View File

@ -63,7 +63,7 @@ namespace OpenSim.Data.NHibernate
public void StoreRegionSettings(RegionSettings rs)
{
RegionSettings oldRegionSettings = (RegionSettings)manager.Load(typeof(RegionSettings), rs.RegionUUID);
RegionSettings oldRegionSettings = (RegionSettings)manager.Get(typeof(RegionSettings), rs.RegionUUID);
if (oldRegionSettings != null)
{
manager.Update(rs);
@ -76,7 +76,7 @@ namespace OpenSim.Data.NHibernate
public RegionSettings LoadRegionSettings(UUID regionUUID)
{
RegionSettings regionSettings = (RegionSettings) manager.Load(typeof(RegionSettings), regionUUID);
RegionSettings regionSettings = (RegionSettings) manager.Get(typeof(RegionSettings), regionUUID);
if (regionSettings == null)
{
@ -96,7 +96,7 @@ namespace OpenSim.Data.NHibernate
{
try
{
SceneObjectPart old = (SceneObjectPart)manager.Load(typeof(SceneObjectPart), p.UUID);
SceneObjectPart old = (SceneObjectPart)manager.Get(typeof(SceneObjectPart), p.UUID);
if (old != null)
{
m_log.InfoFormat("[NHIBERNATE] updating object {0}", p.UUID);
@ -120,7 +120,7 @@ namespace OpenSim.Data.NHibernate
try
{
Terrain old = (Terrain)manager.Load(typeof(Terrain), t.RegionID);
Terrain old = (Terrain)manager.Get(typeof(Terrain), t.RegionID);
if (old != null)
{
m_log.InfoFormat("[NHIBERNATE] updating terrain {0}", t.RegionID);
@ -279,7 +279,7 @@ namespace OpenSim.Data.NHibernate
/// <returns>Heightfield data</returns>
public double[,] LoadTerrain(UUID regionID)
{
Terrain t = (Terrain)manager.Load(typeof(Terrain), regionID);
Terrain t = (Terrain)manager.Get(typeof(Terrain), regionID);
if (t != null)
{
return t.Doubles;

View File

@ -61,7 +61,7 @@ namespace OpenSim.Data.NHibernate
UserProfileData user = null;
m_log.InfoFormat("[NHIBERNATE] ExistsUser; {0}", uuid);
user = (UserProfileData)manager.Load(typeof(UserProfileData), uuid);
user = (UserProfileData)manager.Get(typeof(UserProfileData), uuid);
if (user == null)
{
@ -78,7 +78,7 @@ namespace OpenSim.Data.NHibernate
UserProfileData user;
m_log.InfoFormat("[NHIBERNATE] GetUserByUUID: {0} ", uuid);
user = (UserProfileData)manager.Load(typeof(UserProfileData), uuid);
user = (UserProfileData)manager.Get(typeof(UserProfileData), uuid);
if (user != null)
{
UserAgentData agent = GetAgentByUUID(uuid);
@ -163,7 +163,7 @@ namespace OpenSim.Data.NHibernate
}
UserAgentData old = (UserAgentData)manager.Load(typeof(UserAgentData), agent.ProfileID);
UserAgentData old = (UserAgentData)manager.Get(typeof(UserAgentData), agent.ProfileID);
if (old != null)
{
manager.Delete(old);
@ -182,7 +182,7 @@ namespace OpenSim.Data.NHibernate
override public UserAgentData GetAgentByUUID(UUID uuid)
{
m_log.InfoFormat("[NHIBERNATE] GetAgentByUUID: {0} ", uuid);
return (UserAgentData)manager.Load(typeof(UserAgentData), uuid);
return (UserAgentData)manager.Get(typeof(UserAgentData), uuid);
}
override public UserProfileData GetUserByName(string fname, string lname)
@ -397,12 +397,12 @@ namespace OpenSim.Data.NHibernate
/// TODO: stubs for now to get us to a compiling state gently
public override AvatarAppearance GetUserAppearance(UUID user)
{
return (AvatarAppearance)manager.Load(typeof(AvatarAppearance), user);
return (AvatarAppearance)manager.Get(typeof(AvatarAppearance), user);
}
private bool ExistsAppearance(UUID uuid)
{
AvatarAppearance appearance = (AvatarAppearance)manager.Load(typeof(AvatarAppearance), uuid);
AvatarAppearance appearance = (AvatarAppearance)manager.Get(typeof(AvatarAppearance), uuid);
if (appearance == null)
{
return false;

View File

@ -35,5 +35,23 @@
<property name="AbuseEmail" type="String" length="255" />
<array name="EstateManagers" table="EstateManagers" cascade="all">
<key column="EstateID" />
<index column="ArrayIndex" />
<element column="ManagerID" type="OpenSim.Data.NHibernate.UUIDUserType, OpenSim.Data.NHibernate" />
</array>
<array name="EstateAccess" table="EstateUsers" cascade="all">
<key column="EstateID" />
<index column="ArrayIndex" />
<element column="UserID" type="OpenSim.Data.NHibernate.UUIDUserType, OpenSim.Data.NHibernate" />
</array>
<array name="EstateGroups" table="EstateGroups" cascade="all">
<key column="EstateID" />
<index column="ArrayIndex" />
<element column="GroupID" type="OpenSim.Data.NHibernate.UUIDUserType, OpenSim.Data.NHibernate" />
</array>
</class>
</hibernate-mapping>

View File

@ -38,3 +38,25 @@ CREATE TABLE EstateRegionLink (
CREATE INDEX EstateRegionLinkEstateIDIndex ON EstateRegionLink (EstateID);
CREATE INDEX EstateRegionLinkERegionIDIndex ON EstateRegionLink (RegionID);
CREATE TABLE EstateManagers (
EstateID INT NOT NULL,
ManagerID NVARCHAR(36) NOT NULL,
ArrayIndex INT NOT NULL,
PRIMARY KEY (EstateID,ArrayIndex)
);
CREATE TABLE EstateUsers (
EstateID INT NOT NULL,
UserID NVARCHAR(36) NOT NULL,
ArrayIndex INT NOT NULL,
PRIMARY KEY (EstateID,ArrayIndex)
);
CREATE TABLE EstateGroups (
EstateID INT NOT NULL,
GroupID NVARCHAR(36) NOT NULL,
ArrayIndex INT NOT NULL,
PRIMARY KEY (EstateID,ArrayIndex)
);

View File

@ -38,3 +38,25 @@ CREATE TABLE EstateRegionLink (
CREATE INDEX EstateRegionLinkEstateIDIndex ON EstateRegionLink (EstateID);
CREATE INDEX EstateRegionLinkERegionIDIndex ON EstateRegionLink (RegionID);
CREATE TABLE EstateManagers (
EstateID INT NOT NULL,
ManagerID VARCHAR(36) NOT NULL,
ArrayIndex INT NOT NULL,
PRIMARY KEY (EstateID,ArrayIndex)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Rev. 1';
CREATE TABLE EstateUsers (
EstateID INT NOT NULL,
UserID VARCHAR(36) NOT NULL,
ArrayIndex INT NOT NULL,
PRIMARY KEY (EstateID,ArrayIndex)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Rev. 1';
CREATE TABLE EstateGroups (
EstateID INT NOT NULL,
GroupID VARCHAR(36) NOT NULL,
ArrayIndex INT NOT NULL,
PRIMARY KEY (EstateID,ArrayIndex)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Rev. 1';

View File

@ -38,3 +38,25 @@ CREATE TABLE EstateRegionLink (
CREATE INDEX EstateRegionLinkEstateIDIndex ON EstateRegionLink (EstateID);
CREATE INDEX EstateRegionLinkERegionIDIndex ON EstateRegionLink (RegionID);
CREATE TABLE EstateManagers (
EstateID INT NOT NULL,
ManagerID VARCHAR(36) NOT NULL,
ArrayIndex INT NOT NULL,
PRIMARY KEY (EstateID,ArrayIndex)
);
CREATE TABLE EstateUsers (
EstateID INT NOT NULL,
UserID VARCHAR(36) NOT NULL,
ArrayIndex INT NOT NULL,
PRIMARY KEY (EstateID,ArrayIndex)
);
CREATE TABLE EstateGroups (
EstateID INT NOT NULL,
GroupID VARCHAR(36) NOT NULL,
ArrayIndex INT NOT NULL,
PRIMARY KEY (EstateID,ArrayIndex)
);

View File

@ -38,3 +38,24 @@ CREATE TABLE EstateRegionLink (
CREATE INDEX EstateRegionLinkEstateIDIndex ON EstateRegionLink (EstateID);
CREATE INDEX EstateRegionLinkERegionIDIndex ON EstateRegionLink (RegionID);
CREATE TABLE EstateManagers (
EstateID INT NOT NULL,
ManagerID VARCHAR(36) NOT NULL,
ArrayIndex INT NOT NULL,
PRIMARY KEY (EstateID,ArrayIndex)
);
CREATE TABLE EstateUsers (
EstateID INT NOT NULL,
UserID VARCHAR(36) NOT NULL,
ArrayIndex INT NOT NULL,
PRIMARY KEY (EstateID,ArrayIndex)
);
CREATE TABLE EstateGroups (
EstateID INT NOT NULL,
GroupID VARCHAR(36) NOT NULL,
ArrayIndex INT NOT NULL,
PRIMARY KEY (EstateID,ArrayIndex)
);