* 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) 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) 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) if (temp == null)
{ {
manager.Insert(asset); manager.Insert(asset);

View File

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

View File

@ -111,7 +111,7 @@ namespace OpenSim.Data.NHibernate
public override DataResponse AddProfile(RegionProfileData profile) 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); manager.Insert(profile);
return DataResponse.RESPONSE_OK; return DataResponse.RESPONSE_OK;
@ -124,7 +124,7 @@ namespace OpenSim.Data.NHibernate
public override DataResponse UpdateProfile(RegionProfileData profile) 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); manager.Update(profile);
return DataResponse.RESPONSE_OK; return DataResponse.RESPONSE_OK;
@ -137,7 +137,7 @@ namespace OpenSim.Data.NHibernate
public override DataResponse DeleteProfile(string uuid) 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) if (regionProfileData != null)
{ {
manager.Delete(regionProfileData); manager.Delete(regionProfileData);
@ -148,7 +148,7 @@ namespace OpenSim.Data.NHibernate
public override RegionProfileData GetProfileByUUID(UUID UUID) 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) public override RegionProfileData GetProfileByHandle(ulong regionHandle)

View File

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

View File

@ -45,56 +45,7 @@ namespace OpenSim.Data.NHibernate
private Configuration configuration; private Configuration configuration;
private ISessionFactory sessionFactory; private ISessionFactory sessionFactory;
/// <summary> #region Initialization
/// 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();
}
/// <summary> /// <summary>
/// Initiate NHibernate Manager /// Initiate NHibernate Manager
@ -131,7 +82,66 @@ namespace OpenSim.Data.NHibernate
RunMigration(dialect, assembly, store); 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()) using (IStatelessSession session = sessionFactory.OpenStatelessSession())
{ {
@ -146,9 +156,39 @@ namespace OpenSim.Data.NHibernate
} }
return obj; 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) public object Insert(object obj)
{ {
try 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) public bool Update(object obj)
{ {
try 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) public bool Delete(object obj)
{ {
try 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() public void DropSchema()
{ {
SchemaExport export = new SchemaExport(this.configuration); SchemaExport export = new SchemaExport(this.configuration);
@ -224,9 +341,5 @@ namespace OpenSim.Data.NHibernate
} }
} }
public ISession GetSession()
{
return sessionFactory.OpenSession();
}
} }
} }

View File

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

View File

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

View File

@ -35,5 +35,23 @@
<property name="AbuseEmail" type="String" length="255" /> <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> </class>
</hibernate-mapping> </hibernate-mapping>

View File

@ -38,3 +38,25 @@ CREATE TABLE EstateRegionLink (
CREATE INDEX EstateRegionLinkEstateIDIndex ON EstateRegionLink (EstateID); CREATE INDEX EstateRegionLinkEstateIDIndex ON EstateRegionLink (EstateID);
CREATE INDEX EstateRegionLinkERegionIDIndex ON EstateRegionLink (RegionID); 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 EstateRegionLinkEstateIDIndex ON EstateRegionLink (EstateID);
CREATE INDEX EstateRegionLinkERegionIDIndex ON EstateRegionLink (RegionID); 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 EstateRegionLinkEstateIDIndex ON EstateRegionLink (EstateID);
CREATE INDEX EstateRegionLinkERegionIDIndex ON EstateRegionLink (RegionID); 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 EstateRegionLinkEstateIDIndex ON EstateRegionLink (EstateID);
CREATE INDEX EstateRegionLinkERegionIDIndex ON EstateRegionLink (RegionID); 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)
);