whole lot more moving

This commit is contained in:
Sean Dague
2008-04-02 15:24:31 +00:00
parent 35420b21a3
commit c52c68f314
67 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,198 @@
/*
* 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 libsecondlife;
using MySql.Data.MySqlClient;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MySQL
{
internal class MySQLAssetData : AssetDataBase, IPlugin
{
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private MySQLManager _dbConnection;
#region IAssetProvider Members
private void UpgradeAssetsTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
m_log.Info("[ASSETS]: Creating new database tables");
_dbConnection.ExecuteResourceSql("CreateAssetsTable.sql");
return;
}
}
/// <summary>
/// Ensure that the assets related tables exists and are at the latest version
/// </summary>
private void TestTables()
{
Dictionary<string, string> tableList = new Dictionary<string, string>();
tableList["assets"] = null;
_dbConnection.GetTableVersion(tableList);
UpgradeAssetsTable(tableList["assets"]);
}
override public AssetBase FetchAsset(LLUUID assetID)
{
AssetBase asset = null;
lock (_dbConnection)
{
MySqlCommand cmd =
new MySqlCommand(
"SELECT name, description, assetType, invType, local, temporary, data FROM assets WHERE id=?id",
_dbConnection.Connection);
MySqlParameter p = cmd.Parameters.Add("?id", MySqlDbType.Binary, 16);
p.Value = assetID.GetBytes();
try
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (dbReader.Read())
{
asset = new AssetBase();
asset.Data = (byte[]) dbReader["data"];
asset.Description = (string) dbReader["description"];
asset.FullID = assetID;
asset.InvType = (sbyte) dbReader["invType"];
asset.Local = ((sbyte) dbReader["local"]) != 0 ? true : false;
asset.Name = (string) dbReader["name"];
asset.Type = (sbyte) dbReader["assetType"];
}
dbReader.Close();
cmd.Dispose();
}
}
catch (Exception e)
{
m_log.ErrorFormat(
"[ASSETS]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString()
+ Environment.NewLine + "Attempting reconnection", assetID);
_dbConnection.Reconnect();
}
}
return asset;
}
override public void CreateAsset(AssetBase asset)
{
lock (_dbConnection)
{
MySqlCommand cmd =
new MySqlCommand(
"REPLACE INTO assets(id, name, description, assetType, invType, local, temporary, data)" +
"VALUES(?id, ?name, ?description, ?assetType, ?invType, ?local, ?temporary, ?data)",
_dbConnection.Connection);
// need to ensure we dispose
try
{
using (cmd)
{
MySqlParameter p = cmd.Parameters.Add("?id", MySqlDbType.Binary, 16);
p.Value = asset.FullID.GetBytes();
cmd.Parameters.AddWithValue("?name", asset.Name);
cmd.Parameters.AddWithValue("?description", asset.Description);
cmd.Parameters.AddWithValue("?assetType", asset.Type);
cmd.Parameters.AddWithValue("?invType", asset.InvType);
cmd.Parameters.AddWithValue("?local", asset.Local);
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery();
cmd.Dispose();
}
}
catch (Exception e)
{
m_log.ErrorFormat(
"[ASSETS]: " +
"MySql failure creating asset {0} with name {1}" + Environment.NewLine + e.ToString()
+ Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name);
_dbConnection.Reconnect();
}
}
}
override public void UpdateAsset(AssetBase asset)
{
CreateAsset(asset);
}
override public bool ExistsAsset(LLUUID uuid)
{
throw new Exception("The method or operation is not implemented.");
}
/// <summary>
/// All writes are immediately commited to the database, so this is a no-op
/// </summary>
override public void CommitAssets()
{
}
#endregion
#region IPlugin Members
override public void Initialise()
{
IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
string hostname = GridDataMySqlFile.ParseFileReadValue("hostname");
string database = GridDataMySqlFile.ParseFileReadValue("database");
string username = GridDataMySqlFile.ParseFileReadValue("username");
string password = GridDataMySqlFile.ParseFileReadValue("password");
string pooling = GridDataMySqlFile.ParseFileReadValue("pooling");
string port = GridDataMySqlFile.ParseFileReadValue("port");
_dbConnection = new MySQLManager(hostname, database, username, password, pooling, port);
TestTables();
}
override public string Version
{
get { return _dbConnection.getVersion(); }
}
override public string Name
{
get { return "MySQL Asset storage engine"; }
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,402 @@
/*
* 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.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using libsecondlife;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MySQL
{
/// <summary>
/// A MySQL Interface for the Grid Server
/// </summary>
public class MySQLGridData : GridDataBase
{
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// MySQL Database Manager
/// </summary>
private MySQLManager database;
/// <summary>
/// Initialises the Grid Interface
/// </summary>
override public void Initialise()
{
IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname");
string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database");
string settingUsername = GridDataMySqlFile.ParseFileReadValue("username");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling");
string settingPort = GridDataMySqlFile.ParseFileReadValue("port");
database =
new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling,
settingPort);
TestTables();
}
#region Test and initialization code
/// <summary>
/// Ensure that the user related tables exists and are at the latest version
/// </summary>
private void TestTables()
{
Dictionary<string, string> tableList = new Dictionary<string, string>();
tableList["regions"] = null;
database.GetTableVersion(tableList);
UpgradeRegionsTable(tableList["regions"]);
}
/// <summary>
/// Create or upgrade the table if necessary
/// </summary>
/// <param name="oldVersion">A null indicates that the table does not
/// currently exist</param>
private void UpgradeRegionsTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
database.ExecuteResourceSql("CreateRegionsTable.sql");
return;
}
if (oldVersion.Contains("Rev. 1"))
{
database.ExecuteResourceSql("UpgradeRegionsTableToVersion2.sql");
return;
}
if (oldVersion.Contains("Rev. 2"))
{
database.ExecuteResourceSql("UpgradeRegionsTableToVersion3.sql");
return;
}
}
#endregion
/// <summary>
/// Shuts down the grid interface
/// </summary>
override public void Close()
{
database.Close();
}
/// <summary>
/// Returns the plugin name
/// </summary>
/// <returns>Plugin name</returns>
override public string getName()
{
return "MySql OpenGridData";
}
/// <summary>
/// Returns the plugin version
/// </summary>
/// <returns>Plugin version</returns>
override public string getVersion()
{
return "0.1";
}
/// <summary>
/// Returns all the specified region profiles within coordates -- coordinates are inclusive
/// </summary>
/// <param name="xmin">Minimum X coordinate</param>
/// <param name="ymin">Minimum Y coordinate</param>
/// <param name="xmax">Maximum X coordinate</param>
/// <param name="ymax">Maximum Y coordinate</param>
/// <returns></returns>
override public RegionProfileData[] GetProfilesInRange(uint xmin, uint ymin, uint xmax, uint ymax)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?xmin"] = xmin.ToString();
param["?ymin"] = ymin.ToString();
param["?xmax"] = xmax.ToString();
param["?ymax"] = ymax.ToString();
IDbCommand result =
database.Query(
"SELECT * FROM regions WHERE locX >= ?xmin AND locX <= ?xmax AND locY >= ?ymin AND locY <= ?ymax",
param);
IDataReader reader = result.ExecuteReader();
RegionProfileData row;
List<RegionProfileData> rows = new List<RegionProfileData>();
while ((row = database.readSimRow(reader)) != null)
{
rows.Add(row);
}
reader.Close();
result.Dispose();
return rows.ToArray();
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return null;
}
}
/// <summary>
/// Returns a sim profile from it's location
/// </summary>
/// <param name="handle">Region location handle</param>
/// <returns>Sim profile</returns>
override public RegionProfileData GetProfileByHandle(ulong handle)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?handle"] = handle.ToString();
IDbCommand result = database.Query("SELECT * FROM regions WHERE regionHandle = ?handle", param);
IDataReader reader = result.ExecuteReader();
RegionProfileData row = database.readSimRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return null;
}
}
/// <summary>
/// Returns a sim profile from it's UUID
/// </summary>
/// <param name="uuid">The region UUID</param>
/// <returns>The sim profile</returns>
override public RegionProfileData GetProfileByLLUUID(LLUUID uuid)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?uuid"] = uuid.ToString();
IDbCommand result = database.Query("SELECT * FROM regions WHERE uuid = ?uuid", param);
IDataReader reader = result.ExecuteReader();
RegionProfileData row = database.readSimRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return null;
}
}
/// <summary>
/// Returns a sim profile from it's Region name string
/// </summary>
/// <param name="uuid">The region name search query</param>
/// <returns>The sim profile</returns>
override public RegionProfileData GetProfileByString(string regionName)
{
if (regionName.Length > 2)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
// Add % because this is a like query.
param["?regionName"] = regionName + "%";
// Order by statement will return shorter matches first. Only returns one record or no record.
IDbCommand result = database.Query("SELECT * FROM regions WHERE regionName like ?regionName order by LENGTH(regionName) asc LIMIT 1", param);
IDataReader reader = result.ExecuteReader();
RegionProfileData row = database.readSimRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return null;
}
}
else
{
m_log.Error("[DATABASE]: Searched for a Region Name shorter then 3 characters");
return null;
}
}
/// <summary>
/// Adds a new profile to the database
/// </summary>
/// <param name="profile">The profile to add</param>
/// <returns>Successful?</returns>
override public DataResponse AddProfile(RegionProfileData profile)
{
lock (database)
{
if (database.insertRegion(profile))
{
return DataResponse.RESPONSE_OK;
}
else
{
return DataResponse.RESPONSE_ERROR;
}
}
}
/// <summary>
/// Deletes a profile from the database
/// </summary>
/// <param name="profile">The profile to delete</param>
/// <returns>Successful?</returns>
//public DataResponse DeleteProfile(RegionProfileData profile)
public DataResponse DeleteProfile(string uuid)
{
lock (database)
{
if (database.deleteRegion(uuid))
{
return DataResponse.RESPONSE_OK;
}
else
{
return DataResponse.RESPONSE_ERROR;
}
}
}
/// <summary>
/// DEPRECATED. Attempts to authenticate a region by comparing a shared secret.
/// </summary>
/// <param name="uuid">The UUID of the challenger</param>
/// <param name="handle">The attempted regionHandle of the challenger</param>
/// <param name="authkey">The secret</param>
/// <returns>Whether the secret and regionhandle match the database entry for UUID</returns>
override public bool AuthenticateSim(LLUUID uuid, ulong handle, string authkey)
{
bool throwHissyFit = false; // Should be true by 1.0
if (throwHissyFit)
throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential.");
RegionProfileData data = GetProfileByLLUUID(uuid);
return (handle == data.regionHandle && authkey == data.regionSecret);
}
/// <summary>
/// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region
/// </summary>
/// <remarks>This requires a security audit.</remarks>
/// <param name="uuid"></param>
/// <param name="handle"></param>
/// <param name="authhash"></param>
/// <param name="challenge"></param>
/// <returns></returns>
public bool AuthenticateSim(LLUUID uuid, ulong handle, string authhash, string challenge)
{
SHA512Managed HashProvider = new SHA512Managed();
ASCIIEncoding TextProvider = new ASCIIEncoding();
byte[] stream = TextProvider.GetBytes(uuid.ToString() + ":" + handle.ToString() + ":" + challenge);
byte[] hash = HashProvider.ComputeHash(stream);
return false;
}
override public ReservationData GetReservationAtPoint(uint x, uint y)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?x"] = x.ToString();
param["?y"] = y.ToString();
IDbCommand result =
database.Query(
"SELECT * FROM reservations WHERE resXMin <= ?x AND resXMax >= ?x AND resYMin <= ?y AND resYMax >= ?y",
param);
IDataReader reader = result.ExecuteReader();
ReservationData row = database.readReservationRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return null;
}
}
}
}

View File

@@ -0,0 +1,648 @@
/*
* 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 libsecondlife;
using MySql.Data.MySqlClient;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MySQL
{
/// <summary>
/// A MySQL interface for the inventory server
/// </summary>
public class MySQLInventoryData : IInventoryData
{
private static readonly log4net.ILog m_log
= log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// The database manager
/// </summary>
private MySQLManager database;
/// <summary>
/// Loads and initialises this database plugin
/// </summary>
public void Initialise()
{
IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname");
string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database");
string settingUsername = GridDataMySqlFile.ParseFileReadValue("username");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling");
string settingPort = GridDataMySqlFile.ParseFileReadValue("port");
database =
new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling,
settingPort);
TestTables(database.Connection);
}
#region Test and initialization code
private void UpgradeFoldersTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
database.ExecuteResourceSql("CreateFoldersTable.sql");
return;
}
// if the table is already at the current version, then we can exit immediately
// if (oldVersion == "Rev. 2")
// return;
// database.ExecuteResourceSql("UpgradeFoldersTableToVersion2.sql");
}
private void UpgradeItemsTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
database.ExecuteResourceSql("CreateItemsTable.sql");
return;
}
// if the table is already at the current version, then we can exit immediately
// if (oldVersion == "Rev. 2")
// return;
// database.ExecuteResourceSql("UpgradeItemsTableToVersion2.sql");
}
private void TestTables(MySqlConnection conn)
{
Dictionary<string, string> tableList = new Dictionary<string, string>();
tableList["inventoryfolders"] = null;
tableList["inventoryitems"] = null;
database.GetTableVersion(tableList);
m_log.Info("[MYSQL]: Inventory Folder Version: " + tableList["inventoryfolders"]);
m_log.Info("[MYSQL]: Inventory Items Version: " + tableList["inventoryitems"]);
UpgradeFoldersTable(tableList["inventoryfolders"]);
UpgradeItemsTable(tableList["inventoryitems"]);
}
#endregion
/// <summary>
/// The name of this DB provider
/// </summary>
/// <returns>Name of DB provider</returns>
public string getName()
{
return "MySQL Inventory Data Interface";
}
/// <summary>
/// Closes this DB provider
/// </summary>
public void Close()
{
// Do nothing.
}
/// <summary>
/// Returns the version of this DB provider
/// </summary>
/// <returns>A string containing the DB provider</returns>
public string getVersion()
{
return database.getVersion();
}
/// <summary>
/// Returns a list of items in a specified folder
/// </summary>
/// <param name="folderID">The folder to search</param>
/// <returns>A list containing inventory items</returns>
public List<InventoryItemBase> getInventoryInFolder(LLUUID folderID)
{
try
{
lock (database)
{
List<InventoryItemBase> items = new List<InventoryItemBase>();
MySqlCommand result =
new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid",
database.Connection);
result.Parameters.AddWithValue("?uuid", folderID.ToString());
MySqlDataReader reader = result.ExecuteReader();
while (reader.Read())
items.Add(readInventoryItem(reader));
reader.Close();
result.Dispose();
return items;
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return null;
}
}
/// <summary>
/// Returns a list of the root folders within a users inventory
/// </summary>
/// <param name="user">The user whos inventory is to be searched</param>
/// <returns>A list of folder objects</returns>
public List<InventoryFolderBase> getUserRootFolders(LLUUID user)
{
try
{
lock (database)
{
MySqlCommand result =
new MySqlCommand(
"SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid",
database.Connection);
result.Parameters.AddWithValue("?uuid", user.ToString());
result.Parameters.AddWithValue("?zero", LLUUID.Zero.ToString());
MySqlDataReader reader = result.ExecuteReader();
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
while (reader.Read())
items.Add(readInventoryFolder(reader));
reader.Close();
result.Dispose();
return items;
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return null;
}
}
// see InventoryItemBase.getUserRootFolder
public InventoryFolderBase getUserRootFolder(LLUUID user)
{
try
{
lock (database)
{
MySqlCommand result =
new MySqlCommand(
"SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid",
database.Connection);
result.Parameters.AddWithValue("?uuid", user.ToString());
result.Parameters.AddWithValue("?zero", LLUUID.Zero.ToString());
MySqlDataReader reader = result.ExecuteReader();
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
while (reader.Read())
items.Add(readInventoryFolder(reader));
InventoryFolderBase rootFolder = null;
// There should only ever be one root folder for a user. However, if there's more
// than one we'll simply use the first one rather than failing. It would be even
// nicer to print some message to this effect, but this feels like it's too low a
// to put such a message out, and it's too minor right now to spare the time to
// suitably refactor.
if (items.Count > 0)
{
rootFolder = items[0];
}
reader.Close();
result.Dispose();
return rootFolder;
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return null;
}
}
/// <summary>
/// Return a list of folders in a users inventory contained within the specified folder.
/// This method is only used in tests - in normal operation the user always have one,
/// and only one, root folder.
/// </summary>
/// <param name="parentID">The folder to search</param>
/// <returns>A list of inventory folders</returns>
public List<InventoryFolderBase> getInventoryFolders(LLUUID parentID)
{
try
{
lock (database)
{
MySqlCommand result =
new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid",
database.Connection);
result.Parameters.AddWithValue("?uuid", parentID.ToString());
MySqlDataReader reader = result.ExecuteReader();
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
while (reader.Read())
items.Add(readInventoryFolder(reader));
reader.Close();
result.Dispose();
return items;
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return null;
}
}
/// <summary>
/// Reads a one item from an SQL result
/// </summary>
/// <param name="reader">The SQL Result</param>
/// <returns>the item read</returns>
private InventoryItemBase readInventoryItem(MySqlDataReader reader)
{
try
{
InventoryItemBase item = new InventoryItemBase();
item.inventoryID = new LLUUID((string) reader["inventoryID"]);
item.assetID = new LLUUID((string) reader["assetID"]);
item.assetType = (int) reader["assetType"];
item.parentFolderID = new LLUUID((string) reader["parentFolderID"]);
item.avatarID = new LLUUID((string) reader["avatarID"]);
item.inventoryName = (string) reader["inventoryName"];
item.inventoryDescription = (string) reader["inventoryDescription"];
item.inventoryNextPermissions = (uint) reader["inventoryNextPermissions"];
item.inventoryCurrentPermissions = (uint) reader["inventoryCurrentPermissions"];
item.invType = (int) reader["invType"];
item.creatorsID = new LLUUID((string) reader["creatorID"]);
item.inventoryBasePermissions = (uint) reader["inventoryBasePermissions"];
item.inventoryEveryOnePermissions = (uint) reader["inventoryEveryOnePermissions"];
return item;
}
catch (MySqlException e)
{
m_log.Error(e.ToString());
}
return null;
}
/// <summary>
/// Returns a specified inventory item
/// </summary>
/// <param name="item">The item to return</param>
/// <returns>An inventory item</returns>
public InventoryItemBase getInventoryItem(LLUUID itemID)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
MySqlCommand result =
new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", database.Connection);
result.Parameters.AddWithValue("?uuid", itemID.ToString());
MySqlDataReader reader = result.ExecuteReader();
InventoryItemBase item = null;
if (reader.Read())
item = readInventoryItem(reader);
reader.Close();
result.Dispose();
return item;
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
}
return null;
}
/// <summary>
/// Reads a list of inventory folders returned by a query.
/// </summary>
/// <param name="reader">A MySQL Data Reader</param>
/// <returns>A List containing inventory folders</returns>
protected InventoryFolderBase readInventoryFolder(MySqlDataReader reader)
{
try
{
InventoryFolderBase folder = new InventoryFolderBase();
folder.agentID = new LLUUID((string) reader["agentID"]);
folder.parentID = new LLUUID((string) reader["parentFolderID"]);
folder.folderID = new LLUUID((string) reader["folderID"]);
folder.name = (string) reader["folderName"];
folder.type = (short) reader["type"];
folder.version = (ushort) ((int) reader["version"]);
return folder;
}
catch (Exception e)
{
m_log.Error(e.ToString());
}
return null;
}
/// <summary>
/// Returns a specified inventory folder
/// </summary>
/// <param name="folder">The folder to return</param>
/// <returns>A folder class</returns>
public InventoryFolderBase getInventoryFolder(LLUUID folderID)
{
try
{
lock (database)
{
MySqlCommand result =
new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", database.Connection);
result.Parameters.AddWithValue("?uuid", folderID.ToString());
MySqlDataReader reader = result.ExecuteReader();
reader.Read();
InventoryFolderBase folder = readInventoryFolder(reader);
reader.Close();
result.Dispose();
return folder;
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return null;
}
}
/// <summary>
/// Adds a specified item to the database
/// </summary>
/// <param name="item">The inventory item</param>
public void addInventoryItem(InventoryItemBase item)
{
string sql =
"REPLACE INTO inventoryitems (inventoryID, assetID, assetType, parentFolderID, avatarID, inventoryName, inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType, creatorID, inventoryBasePermissions, inventoryEveryOnePermissions) VALUES ";
sql +=
"(?inventoryID, ?assetID, ?assetType, ?parentFolderID, ?avatarID, ?inventoryName, ?inventoryDescription, ?inventoryNextPermissions, ?inventoryCurrentPermissions, ?invType, ?creatorID, ?inventoryBasePermissions, ?inventoryEveryOnePermissions)";
try
{
MySqlCommand result = new MySqlCommand(sql, database.Connection);
result.Parameters.AddWithValue("?inventoryID", item.inventoryID.ToString());
result.Parameters.AddWithValue("?assetID", item.assetID.ToString());
result.Parameters.AddWithValue("?assetType", item.assetType.ToString());
result.Parameters.AddWithValue("?parentFolderID", item.parentFolderID.ToString());
result.Parameters.AddWithValue("?avatarID", item.avatarID.ToString());
result.Parameters.AddWithValue("?inventoryName", item.inventoryName);
result.Parameters.AddWithValue("?inventoryDescription", item.inventoryDescription);
result.Parameters.AddWithValue("?inventoryNextPermissions", item.inventoryNextPermissions.ToString());
result.Parameters.AddWithValue("?inventoryCurrentPermissions",
item.inventoryCurrentPermissions.ToString());
result.Parameters.AddWithValue("?invType", item.invType);
result.Parameters.AddWithValue("?creatorID", item.creatorsID.ToString());
result.Parameters.AddWithValue("?inventoryBasePermissions", item.inventoryBasePermissions);
result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.inventoryEveryOnePermissions);
result.ExecuteNonQuery();
result.Dispose();
}
catch (MySqlException e)
{
m_log.Error(e.ToString());
}
}
/// <summary>
/// Updates the specified inventory item
/// </summary>
/// <param name="item">Inventory item to update</param>
public void updateInventoryItem(InventoryItemBase item)
{
addInventoryItem(item);
}
/// <summary>
///
/// </summary>
/// <param name="item"></param>
public void deleteInventoryItem(LLUUID itemID)
{
try
{
MySqlCommand cmd =
new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", database.Connection);
cmd.Parameters.AddWithValue("?uuid", itemID.ToString());
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
database.Reconnect();
m_log.Error(e.ToString());
}
}
/// <summary>
/// Creates a new inventory folder
/// </summary>
/// <param name="folder">Folder to create</param>
public void addInventoryFolder(InventoryFolderBase folder)
{
string sql =
"REPLACE INTO inventoryfolders (folderID, agentID, parentFolderID, folderName, type, version) VALUES ";
sql += "(?folderID, ?agentID, ?parentFolderID, ?folderName, ?type, ?version)";
MySqlCommand cmd = new MySqlCommand(sql, database.Connection);
cmd.Parameters.AddWithValue("?folderID", folder.folderID.ToString());
cmd.Parameters.AddWithValue("?agentID", folder.agentID.ToString());
cmd.Parameters.AddWithValue("?parentFolderID", folder.parentID.ToString());
cmd.Parameters.AddWithValue("?folderName", folder.name);
cmd.Parameters.AddWithValue("?type", (short) folder.type);
cmd.Parameters.AddWithValue("?version", folder.version);
try
{
lock (database)
{
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.Error(e.ToString());
}
}
/// <summary>
/// Updates an inventory folder
/// </summary>
/// <param name="folder">Folder to update</param>
public void updateInventoryFolder(InventoryFolderBase folder)
{
addInventoryFolder(folder);
}
/// Creates a new inventory folder
/// </summary>
/// <param name="folder">Folder to create</param>
public void moveInventoryFolder(InventoryFolderBase folder)
{
string sql =
"UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID";
MySqlCommand cmd = new MySqlCommand(sql, database.Connection);
cmd.Parameters.AddWithValue("?folderID", folder.folderID.ToString());
cmd.Parameters.AddWithValue("?parentFolderID", folder.parentID.ToString());
try
{
lock (database)
{
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.Error(e.ToString());
}
}
/// <summary>
/// Append a list of all the child folders of a parent folder
/// </summary>
/// <param name="folders">list where folders will be appended</param>
/// <param name="parentID">ID of parent</param>
protected void getInventoryFolders(ref List<InventoryFolderBase> folders, LLUUID parentID)
{
List<InventoryFolderBase> subfolderList = getInventoryFolders(parentID);
foreach (InventoryFolderBase f in subfolderList)
folders.Add(f);
}
// See IInventoryData
public List<InventoryFolderBase> getFolderHierarchy(LLUUID parentID)
{
List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
getInventoryFolders(ref folders, parentID);
for (int i = 0; i < folders.Count; i++)
getInventoryFolders(ref folders, folders[i].folderID);
return folders;
}
protected void deleteOneFolder(LLUUID folderID)
{
try
{
MySqlCommand cmd =
new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid", database.Connection);
cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
lock (database)
{
cmd.ExecuteNonQuery();
}
}
catch (MySqlException e)
{
database.Reconnect();
m_log.Error(e.ToString());
}
}
protected void deleteItemsInFolder(LLUUID folderID)
{
try
{
MySqlCommand cmd =
new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", database.Connection);
cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
lock (database)
{
cmd.ExecuteNonQuery();
}
}
catch (MySqlException e)
{
database.Reconnect();
m_log.Error(e.ToString());
}
}
/// <summary>
/// Delete an inventory folder
/// </summary>
/// <param name="folderId">Id of folder to delete</param>
public void deleteInventoryFolder(LLUUID folderID)
{
List<InventoryFolderBase> subFolders = getFolderHierarchy(folderID);
//Delete all sub-folders
foreach (InventoryFolderBase f in subFolders)
{
deleteOneFolder(f.folderID);
deleteItemsInFolder(f.folderID);
}
//Delete the actual row
deleteOneFolder(folderID);
deleteItemsInFolder(folderID);
}
}
}

View File

@@ -0,0 +1,106 @@
/*
* 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.
*/
namespace OpenSim.Framework.Data.MySQL
{
/// <summary>
/// An interface to the log database for MySQL
/// </summary>
internal class MySQLLogData : ILogData
{
/// <summary>
/// The database manager
/// </summary>
public MySQLManager database;
/// <summary>
/// Artificial constructor called when the plugin is loaded
/// </summary>
public void Initialise()
{
IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname");
string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database");
string settingUsername = GridDataMySqlFile.ParseFileReadValue("username");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling");
string settingPort = GridDataMySqlFile.ParseFileReadValue("port");
database =
new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling,
settingPort);
}
/// <summary>
/// Saves a log item to the database
/// </summary>
/// <param name="serverDaemon">The daemon triggering the event</param>
/// <param name="target">The target of the action (region / agent UUID, etc)</param>
/// <param name="methodCall">The method call where the problem occured</param>
/// <param name="arguments">The arguments passed to the method</param>
/// <param name="priority">How critical is this?</param>
/// <param name="logMessage">The message to log</param>
public void saveLog(string serverDaemon, string target, string methodCall, string arguments, int priority,
string logMessage)
{
try
{
database.insertLogRow(serverDaemon, target, methodCall, arguments, priority, logMessage);
}
catch
{
database.Reconnect();
}
}
/// <summary>
/// Returns the name of this DB provider
/// </summary>
/// <returns>A string containing the DB provider name</returns>
public string getName()
{
return "MySQL Logdata Interface";
}
/// <summary>
/// Closes the database provider
/// </summary>
public void Close()
{
// Do nothing.
}
/// <summary>
/// Returns the version of this DB provider
/// </summary>
/// <returns>A string containing the provider version</returns>
public string getVersion()
{
return "0.1";
}
}
}

View File

@@ -0,0 +1,909 @@
/*
* 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.IO;
using System.Reflection;
using libsecondlife;
using MySql.Data.MySqlClient;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MySQL
{
/// <summary>
/// A MySQL Database manager
/// </summary>
internal class MySQLManager
{
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// The database connection object
/// </summary>
private MySqlConnection dbcon;
/// <summary>
/// Connection string for ADO.net
/// </summary>
private string connectionString;
/// <summary>
/// Initialises and creates a new MySQL connection and maintains it.
/// </summary>
/// <param name="hostname">The MySQL server being connected to</param>
/// <param name="database">The name of the MySQL database being used</param>
/// <param name="username">The username logging into the database</param>
/// <param name="password">The password for the user logging in</param>
/// <param name="cpooling">Whether to use connection pooling or not, can be one of the following: 'yes', 'true', 'no' or 'false', if unsure use 'false'.</param>
public MySQLManager(string hostname, string database, string username, string password, string cpooling,
string port)
{
try
{
connectionString = "Server=" + hostname + ";Port=" + port + ";Database=" + database + ";User ID=" +
username + ";Password=" + password + ";Pooling=" + cpooling + ";";
dbcon = new MySqlConnection(connectionString);
try
{
dbcon.Open();
}
catch(Exception e)
{
throw new Exception( "Connection error while using connection string ["+connectionString+"]", e );
}
m_log.Info("[MYSQL]: Connection established");
}
catch (Exception e)
{
throw new Exception("Error initialising MySql Database: " + e.ToString());
}
}
/// <summary>
/// Get the connection being used
/// </summary>
public MySqlConnection Connection
{
get { return dbcon; }
}
/// <summary>
/// Shuts down the database connection
/// </summary>
public void Close()
{
dbcon.Close();
dbcon = null;
}
/// <summary>
/// Reconnects to the database
/// </summary>
public void Reconnect()
{
lock (dbcon)
{
try
{
// Close the DB connection
dbcon.Close();
// Try reopen it
dbcon = new MySqlConnection(connectionString);
dbcon.Open();
}
catch (Exception e)
{
m_log.Error("Unable to reconnect to database " + e.ToString());
}
}
}
/// <summary>
/// Returns the version of this DB provider
/// </summary>
/// <returns>A string containing the DB provider</returns>
public string getVersion()
{
Module module = GetType().Module;
string dllName = module.Assembly.ManifestModule.Name;
Version dllVersion = module.Assembly.GetName().Version;
return
string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build,
dllVersion.Revision);
}
/// <summary>
/// Extract a named string resource from the embedded resources
/// </summary>
/// <param name="name">name of embedded resource</param>
/// <returns>string contained within the embedded resource</returns>
private string getResourceString(string name)
{
Assembly assem = GetType().Assembly;
string[] names = assem.GetManifestResourceNames();
foreach (string s in names)
{
if (s.EndsWith(name))
{
using (Stream resource = assem.GetManifestResourceStream(s))
{
using (StreamReader resourceReader = new StreamReader(resource))
{
string resourceString = resourceReader.ReadToEnd();
return resourceString;
}
}
}
}
throw new Exception(string.Format("Resource '{0}' was not found", name));
}
/// <summary>
/// Execute a SQL statement stored in a resource, as a string
/// </summary>
/// <param name="name"></param>
public void ExecuteResourceSql(string name)
{
MySqlCommand cmd = new MySqlCommand(getResourceString(name), dbcon);
cmd.ExecuteNonQuery();
}
/// <summary>
/// Given a list of tables, return the version of the tables, as seen in the database
/// </summary>
/// <param name="tableList"></param>
public void GetTableVersion(Dictionary<string, string> tableList)
{
lock (dbcon)
{
MySqlCommand tablesCmd =
new MySqlCommand(
"SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?dbname",
dbcon);
tablesCmd.Parameters.AddWithValue("?dbname", dbcon.Database);
using (MySqlDataReader tables = tablesCmd.ExecuteReader())
{
while (tables.Read())
{
try
{
string tableName = (string) tables["TABLE_NAME"];
string comment = (string) tables["TABLE_COMMENT"];
if (tableList.ContainsKey(tableName))
{
tableList[tableName] = comment;
}
}
catch (Exception e)
{
m_log.Error(e.ToString());
}
}
tables.Close();
}
}
}
// TODO: at some time this code should be cleaned up
/// <summary>
/// Runs a query with protection against SQL Injection by using parameterised input.
/// </summary>
/// <param name="sql">The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y</param>
/// <param name="parameters">The parameters - index so that @y is indexed as 'y'</param>
/// <returns>A MySQL DB Command</returns>
public IDbCommand Query(string sql, Dictionary<string, string> parameters)
{
try
{
MySqlCommand dbcommand = (MySqlCommand) dbcon.CreateCommand();
dbcommand.CommandText = sql;
foreach (KeyValuePair<string, string> param in parameters)
{
dbcommand.Parameters.AddWithValue(param.Key, param.Value);
}
return (IDbCommand) dbcommand;
}
catch
{
lock (dbcon)
{
// Close the DB connection
try
{
dbcon.Close();
}
catch
{
}
// Try to reopen it
try
{
dbcon = new MySqlConnection(connectionString);
dbcon.Open();
}
catch (Exception e)
{
m_log.Error("Unable to reconnect to database " + e.ToString());
}
// Run the query again
try
{
MySqlCommand dbcommand = (MySqlCommand) dbcon.CreateCommand();
dbcommand.CommandText = sql;
foreach (KeyValuePair<string, string> param in parameters)
{
dbcommand.Parameters.AddWithValue(param.Key, param.Value);
}
return (IDbCommand) dbcommand;
}
catch (Exception e)
{
// Return null if it fails.
m_log.Error("Failed during Query generation: " + e.ToString());
return null;
}
}
}
}
/// <summary>
/// Reads a region row from a database reader
/// </summary>
/// <param name="reader">An active database reader</param>
/// <returns>A region profile</returns>
public RegionProfileData readSimRow(IDataReader reader)
{
RegionProfileData retval = new RegionProfileData();
if (reader.Read())
{
// Region Main gotta-have-or-we-return-null parts
if (!UInt64.TryParse(reader["regionHandle"].ToString(), out retval.regionHandle))
return null;
if (!LLUUID.TryParse((string)reader["uuid"], out retval.UUID))
return null;
// non-critical parts
retval.regionName = (string)reader["regionName"];
retval.originUUID = new LLUUID((string) reader["originUUID"]);
// Secrets
retval.regionRecvKey = (string) reader["regionRecvKey"];
retval.regionSecret = (string) reader["regionSecret"];
retval.regionSendKey = (string) reader["regionSendKey"];
// Region Server
retval.regionDataURI = (string) reader["regionDataURI"];
retval.regionOnline = false; // Needs to be pinged before this can be set.
retval.serverIP = (string) reader["serverIP"];
retval.serverPort = (uint) reader["serverPort"];
retval.serverURI = (string) reader["serverURI"];
retval.httpPort = Convert.ToUInt32(reader["serverHttpPort"].ToString());
retval.remotingPort = Convert.ToUInt32(reader["serverRemotingPort"].ToString());
// Location
retval.regionLocX = Convert.ToUInt32(reader["locX"].ToString());
retval.regionLocY = Convert.ToUInt32(reader["locY"].ToString());
retval.regionLocZ = Convert.ToUInt32(reader["locZ"].ToString());
// Neighbours - 0 = No Override
retval.regionEastOverrideHandle = Convert.ToUInt64(reader["eastOverrideHandle"].ToString());
retval.regionWestOverrideHandle = Convert.ToUInt64(reader["westOverrideHandle"].ToString());
retval.regionSouthOverrideHandle = Convert.ToUInt64(reader["southOverrideHandle"].ToString());
retval.regionNorthOverrideHandle = Convert.ToUInt64(reader["northOverrideHandle"].ToString());
// Assets
retval.regionAssetURI = (string) reader["regionAssetURI"];
retval.regionAssetRecvKey = (string) reader["regionAssetRecvKey"];
retval.regionAssetSendKey = (string) reader["regionAssetSendKey"];
// Userserver
retval.regionUserURI = (string) reader["regionUserURI"];
retval.regionUserRecvKey = (string) reader["regionUserRecvKey"];
retval.regionUserSendKey = (string) reader["regionUserSendKey"];
// World Map Addition
LLUUID.TryParse((string)reader["regionMapTexture"], out retval.regionMapTextureID);
LLUUID.TryParse((string)reader["owner_uuid"], out retval.owner_uuid);
}
else
{
return null;
}
return retval;
}
/// <summary>
/// Reads a reservation row from a database reader
/// </summary>
/// <param name="reader">An active database reader</param>
/// <returns>A reservation data object</returns>
public ReservationData readReservationRow(IDataReader reader)
{
ReservationData retval = new ReservationData();
if (reader.Read())
{
retval.gridRecvKey = (string) reader["gridRecvKey"];
retval.gridSendKey = (string) reader["gridSendKey"];
retval.reservationCompany = (string) reader["resCompany"];
retval.reservationMaxX = Convert.ToInt32(reader["resXMax"].ToString());
retval.reservationMaxY = Convert.ToInt32(reader["resYMax"].ToString());
retval.reservationMinX = Convert.ToInt32(reader["resXMin"].ToString());
retval.reservationMinY = Convert.ToInt32(reader["resYMin"].ToString());
retval.reservationName = (string) reader["resName"];
retval.status = Convert.ToInt32(reader["status"].ToString()) == 1;
LLUUID.TryParse((string) reader["userUUID"], out retval.userUUID);
}
else
{
return null;
}
return retval;
}
/// <summary>
/// Reads an agent row from a database reader
/// </summary>
/// <param name="reader">An active database reader</param>
/// <returns>A user session agent</returns>
public UserAgentData readAgentRow(IDataReader reader)
{
UserAgentData retval = new UserAgentData();
if (reader.Read())
{
// Agent IDs
if (!LLUUID.TryParse((string)reader["UUID"], out retval.UUID))
return null;
LLUUID.TryParse((string) reader["sessionID"], out retval.sessionID);
LLUUID.TryParse((string)reader["secureSessionID"], out retval.secureSessionID);
// Agent Who?
retval.agentIP = (string) reader["agentIP"];
retval.agentPort = Convert.ToUInt32(reader["agentPort"].ToString());
retval.agentOnline = Convert.ToBoolean(Convert.ToInt16(reader["agentOnline"].ToString()));
// Login/Logout times (UNIX Epoch)
retval.loginTime = Convert.ToInt32(reader["loginTime"].ToString());
retval.logoutTime = Convert.ToInt32(reader["logoutTime"].ToString());
// Current position
retval.currentRegion = new LLUUID((string)reader["currentRegion"]);
retval.currentHandle = Convert.ToUInt64(reader["currentHandle"].ToString());
LLVector3.TryParse((string) reader["currentPos"], out retval.currentPos);
}
else
{
return null;
}
return retval;
}
/// <summary>
/// Reads a user profile from an active data reader
/// </summary>
/// <param name="reader">An active database reader</param>
/// <returns>A user profile</returns>
public UserProfileData readUserRow(IDataReader reader)
{
UserProfileData retval = new UserProfileData();
if (reader.Read())
{
if (!LLUUID.TryParse((string)reader["UUID"], out retval.UUID))
return null;
retval.username = (string) reader["username"];
retval.surname = (string) reader["lastname"];
retval.passwordHash = (string) reader["passwordHash"];
retval.passwordSalt = (string) reader["passwordSalt"];
retval.homeRegion = Convert.ToUInt64(reader["homeRegion"].ToString());
retval.homeLocation = new LLVector3(
Convert.ToSingle(reader["homeLocationX"].ToString()),
Convert.ToSingle(reader["homeLocationY"].ToString()),
Convert.ToSingle(reader["homeLocationZ"].ToString()));
retval.homeLookAt = new LLVector3(
Convert.ToSingle(reader["homeLookAtX"].ToString()),
Convert.ToSingle(reader["homeLookAtY"].ToString()),
Convert.ToSingle(reader["homeLookAtZ"].ToString()));
retval.created = Convert.ToInt32(reader["created"].ToString());
retval.lastLogin = Convert.ToInt32(reader["lastLogin"].ToString());
retval.userInventoryURI = (string) reader["userInventoryURI"];
retval.userAssetURI = (string) reader["userAssetURI"];
retval.profileCanDoMask = Convert.ToUInt32(reader["profileCanDoMask"].ToString());
retval.profileWantDoMask = Convert.ToUInt32(reader["profileWantDoMask"].ToString());
if (reader.IsDBNull(reader.GetOrdinal("profileAboutText")))
retval.profileAboutText = "";
else
retval.profileAboutText = (string) reader["profileAboutText"];
if (reader.IsDBNull(reader.GetOrdinal("profileFirstText")))
retval.profileFirstText = "";
else
retval.profileFirstText = (string)reader["profileFirstText"];
if (reader.IsDBNull(reader.GetOrdinal("profileImage")))
retval.profileImage = LLUUID.Zero;
else
LLUUID.TryParse((string)reader["profileImage"], out retval.profileImage);
if (reader.IsDBNull(reader.GetOrdinal("profileFirstImage")))
retval.profileFirstImage = LLUUID.Zero;
else
LLUUID.TryParse((string)reader["profileFirstImage"], out retval.profileFirstImage);
if(reader.IsDBNull(reader.GetOrdinal("webLoginKey")))
{
retval.webLoginKey = LLUUID.Zero;
}
else
{
LLUUID.TryParse((string)reader["webLoginKey"], out retval.webLoginKey);
}
}
else
{
return null;
}
return retval;
}
/// <summary>
/// Inserts a new row into the log database
/// </summary>
/// <param name="serverDaemon">The daemon which triggered this event</param>
/// <param name="target">Who were we operating on when this occured (region UUID, user UUID, etc)</param>
/// <param name="methodCall">The method call where the problem occured</param>
/// <param name="arguments">The arguments passed to the method</param>
/// <param name="priority">How critical is this?</param>
/// <param name="logMessage">Extra message info</param>
/// <returns>Saved successfully?</returns>
public bool insertLogRow(string serverDaemon, string target, string methodCall, string arguments, int priority,
string logMessage)
{
string sql = "INSERT INTO logs (`target`, `server`, `method`, `arguments`, `priority`, `message`) VALUES ";
sql += "(?target, ?server, ?method, ?arguments, ?priority, ?message)";
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["?server"] = serverDaemon;
parameters["?target"] = target;
parameters["?method"] = methodCall;
parameters["?arguments"] = arguments;
parameters["?priority"] = priority.ToString();
parameters["?message"] = logMessage;
bool returnval = false;
try
{
IDbCommand result = Query(sql, parameters);
if (result.ExecuteNonQuery() == 1)
returnval = true;
result.Dispose();
}
catch (Exception e)
{
m_log.Error(e.ToString());
return false;
}
return returnval;
}
/// <summary>
/// Creates a new user and inserts it into the database
/// </summary>
/// <param name="uuid">User ID</param>
/// <param name="username">First part of the login</param>
/// <param name="lastname">Second part of the login</param>
/// <param name="passwordHash">A salted hash of the users password</param>
/// <param name="passwordSalt">The salt used for the password hash</param>
/// <param name="homeRegion">A regionHandle of the users home region</param>
/// <param name="homeLocX">Home region position vector</param>
/// <param name="homeLocY">Home region position vector</param>
/// <param name="homeLocZ">Home region position vector</param>
/// <param name="homeLookAtX">Home region 'look at' vector</param>
/// <param name="homeLookAtY">Home region 'look at' vector</param>
/// <param name="homeLookAtZ">Home region 'look at' vector</param>
/// <param name="created">Account created (unix timestamp)</param>
/// <param name="lastlogin">Last login (unix timestamp)</param>
/// <param name="inventoryURI">Users inventory URI</param>
/// <param name="assetURI">Users asset URI</param>
/// <param name="canDoMask">I can do mask</param>
/// <param name="wantDoMask">I want to do mask</param>
/// <param name="aboutText">Profile text</param>
/// <param name="firstText">Firstlife text</param>
/// <param name="profileImage">UUID for profile image</param>
/// <param name="firstImage">UUID for firstlife image</param>
/// <returns>Success?</returns>
public bool insertUserRow(LLUUID uuid, string username, string lastname, string passwordHash,
string passwordSalt, UInt64 homeRegion, float homeLocX, float homeLocY, float homeLocZ,
float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin,
string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask,
string aboutText, string firstText,
LLUUID profileImage, LLUUID firstImage, LLUUID webLoginKey)
{
m_log.Debug("[MySQLManager]: Fetching profile for " + uuid.ToString());
string sql =
"INSERT INTO users (`UUID`, `username`, `lastname`, `passwordHash`, `passwordSalt`, `homeRegion`, ";
sql +=
"`homeLocationX`, `homeLocationY`, `homeLocationZ`, `homeLookAtX`, `homeLookAtY`, `homeLookAtZ`, `created`, ";
sql +=
"`lastLogin`, `userInventoryURI`, `userAssetURI`, `profileCanDoMask`, `profileWantDoMask`, `profileAboutText`, ";
sql += "`profileFirstText`, `profileImage`, `profileFirstImage`, `webLoginKey`) VALUES ";
sql += "(?UUID, ?username, ?lastname, ?passwordHash, ?passwordSalt, ?homeRegion, ";
sql +=
"?homeLocationX, ?homeLocationY, ?homeLocationZ, ?homeLookAtX, ?homeLookAtY, ?homeLookAtZ, ?created, ";
sql +=
"?lastLogin, ?userInventoryURI, ?userAssetURI, ?profileCanDoMask, ?profileWantDoMask, ?profileAboutText, ";
sql += "?profileFirstText, ?profileImage, ?profileFirstImage, ?webLoginKey)";
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["?UUID"] = uuid.ToString();
parameters["?username"] = username.ToString();
parameters["?lastname"] = lastname.ToString();
parameters["?passwordHash"] = passwordHash.ToString();
parameters["?passwordSalt"] = passwordSalt.ToString();
parameters["?homeRegion"] = homeRegion.ToString();
parameters["?homeLocationX"] = homeLocX.ToString();
parameters["?homeLocationY"] = homeLocY.ToString();
parameters["?homeLocationZ"] = homeLocZ.ToString();
parameters["?homeLookAtX"] = homeLookAtX.ToString();
parameters["?homeLookAtY"] = homeLookAtY.ToString();
parameters["?homeLookAtZ"] = homeLookAtZ.ToString();
parameters["?created"] = created.ToString();
parameters["?lastLogin"] = lastlogin.ToString();
parameters["?userInventoryURI"] = String.Empty;
parameters["?userAssetURI"] = String.Empty;
parameters["?profileCanDoMask"] = "0";
parameters["?profileWantDoMask"] = "0";
parameters["?profileAboutText"] = aboutText;
parameters["?profileFirstText"] = firstText;
parameters["?profileImage"] = profileImage.ToString();
parameters["?profileFirstImage"] = firstImage.ToString();
parameters["?webLoginKey"] = string.Empty;
bool returnval = false;
try
{
IDbCommand result = Query(sql, parameters);
if (result.ExecuteNonQuery() == 1)
returnval = true;
result.Dispose();
}
catch (Exception e)
{
m_log.Error(e.ToString());
return false;
}
m_log.Debug("[MySQLManager]: Fetch user retval == " + returnval.ToString());
return returnval;
}
/// <summary>
/// Creates a new user and inserts it into the database
/// </summary>
/// <param name="uuid">User ID</param>
/// <param name="username">First part of the login</param>
/// <param name="lastname">Second part of the login</param>
/// <param name="passwordHash">A salted hash of the users password</param>
/// <param name="passwordSalt">The salt used for the password hash</param>
/// <param name="homeRegion">A regionHandle of the users home region</param>
/// <param name="homeLocX">Home region position vector</param>
/// <param name="homeLocY">Home region position vector</param>
/// <param name="homeLocZ">Home region position vector</param>
/// <param name="homeLookAtX">Home region 'look at' vector</param>
/// <param name="homeLookAtY">Home region 'look at' vector</param>
/// <param name="homeLookAtZ">Home region 'look at' vector</param>
/// <param name="created">Account created (unix timestamp)</param>
/// <param name="lastlogin">Last login (unix timestamp)</param>
/// <param name="inventoryURI">Users inventory URI</param>
/// <param name="assetURI">Users asset URI</param>
/// <param name="canDoMask">I can do mask</param>
/// <param name="wantDoMask">I want to do mask</param>
/// <param name="aboutText">Profile text</param>
/// <param name="firstText">Firstlife text</param>
/// <param name="profileImage">UUID for profile image</param>
/// <param name="firstImage">UUID for firstlife image</param>
/// <returns>Success?</returns>
public bool updateUserRow(LLUUID uuid, string username, string lastname, string passwordHash,
string passwordSalt, UInt64 homeRegion, float homeLocX, float homeLocY, float homeLocZ,
float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin,
string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask,
string aboutText, string firstText,
LLUUID profileImage, LLUUID firstImage, LLUUID webLoginKey)
{
string sql = "UPDATE users SET `username` = ?username , `lastname` = ?lastname ";
sql += ", `passwordHash` = ?passwordHash , `passwordSalt` = ?passwordSalt , ";
sql += "`homeRegion` = ?homeRegion , `homeLocationX` = ?homeLocationX , ";
sql += "`homeLocationY` = ?homeLocationY , `homeLocationZ` = ?homeLocationZ , ";
sql += "`homeLookAtX` = ?homeLookAtX , `homeLookAtY` = ?homeLookAtY , ";
sql += "`homeLookAtZ` = ?homeLookAtZ , `created` = ?created , `lastLogin` = ?lastLogin , ";
sql += "`userInventoryURI` = ?userInventoryURI , `userAssetURI` = ?userAssetURI , ";
sql += "`profileCanDoMask` = ?profileCanDoMask , `profileWantDoMask` = ?profileWantDoMask , ";
sql += "`profileAboutText` = ?profileAboutText , `profileFirstText` = ?profileFirstText, ";
sql += "`profileImage` = ?profileImage , `profileFirstImage` = ?profileFirstImage , ";
sql += "`webLoginKey` = ?webLoginKey WHERE UUID = ?UUID";
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["?UUID"] = uuid.ToString();
parameters["?username"] = username.ToString();
parameters["?lastname"] = lastname.ToString();
parameters["?passwordHash"] = passwordHash.ToString();
parameters["?passwordSalt"] = passwordSalt.ToString();
parameters["?homeRegion"] = homeRegion.ToString();
parameters["?homeLocationX"] = homeLocX.ToString();
parameters["?homeLocationY"] = homeLocY.ToString();
parameters["?homeLocationZ"] = homeLocZ.ToString();
parameters["?homeLookAtX"] = homeLookAtX.ToString();
parameters["?homeLookAtY"] = homeLookAtY.ToString();
parameters["?homeLookAtZ"] = homeLookAtZ.ToString();
parameters["?created"] = created.ToString();
parameters["?lastLogin"] = lastlogin.ToString();
parameters["?userInventoryURI"] = inventoryURI;
parameters["?userAssetURI"] = assetURI;
parameters["?profileCanDoMask"] = "0";
parameters["?profileWantDoMask"] = "0";
parameters["?profileAboutText"] = aboutText;
parameters["?profileFirstText"] = firstText;
parameters["?profileImage"] = profileImage.ToString();
parameters["?profileFirstImage"] = firstImage.ToString();
parameters["?webLoginKey"] = webLoginKey.ToString();
bool returnval = false;
try
{
IDbCommand result = Query(sql, parameters);
if (result.ExecuteNonQuery() == 1)
returnval = true;
result.Dispose();
}
catch (Exception e)
{
m_log.Error(e.ToString());
return false;
}
m_log.Debug("[MySQLManager]: update user retval == " + returnval.ToString());
return returnval;
}
/// <summary>
/// Inserts a new region into the database
/// </summary>
/// <param name="profile">The region to insert</param>
/// <returns>Success?</returns>
public bool insertRegion(RegionProfileData regiondata)
{
bool GRID_ONLY_UPDATE_NECESSARY_DATA = false;
string sql = String.Empty;
if (GRID_ONLY_UPDATE_NECESSARY_DATA)
{
sql += "INSERT INTO ";
}
else
{
sql += "REPLACE INTO ";
}
sql += "regions (regionHandle, regionName, uuid, regionRecvKey, regionSecret, regionSendKey, regionDataURI, ";
sql +=
"serverIP, serverPort, serverURI, locX, locY, locZ, eastOverrideHandle, westOverrideHandle, southOverrideHandle, northOverrideHandle, regionAssetURI, regionAssetRecvKey, ";
// part of an initial brutish effort to provide accurate information (as per the xml region spec)
// wrt the ownership of a given region
// the (very bad) assumption is that this value is being read and handled inconsistently or
// not at all. Current strategy is to put the code in place to support the validity of this information
// and to roll forward debugging any issues from that point
//
// this particular section of the mod attempts to implement the commit of a supplied value
// server for the UUID of the region's owner (master avatar). It consists of the addition of the column and value to the relevant sql,
// as well as the related parameterization
sql +=
"regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey, regionMapTexture, serverHttpPort, serverRemotingPort, owner_uuid, originUUID) VALUES ";
sql += "(?regionHandle, ?regionName, ?uuid, ?regionRecvKey, ?regionSecret, ?regionSendKey, ?regionDataURI, ";
sql +=
"?serverIP, ?serverPort, ?serverURI, ?locX, ?locY, ?locZ, ?eastOverrideHandle, ?westOverrideHandle, ?southOverrideHandle, ?northOverrideHandle, ?regionAssetURI, ?regionAssetRecvKey, ";
sql +=
"?regionAssetSendKey, ?regionUserURI, ?regionUserRecvKey, ?regionUserSendKey, ?regionMapTexture, ?serverHttpPort, ?serverRemotingPort, ?owner_uuid, ?originUUID)";
if (GRID_ONLY_UPDATE_NECESSARY_DATA)
{
sql += "ON DUPLICATE KEY UPDATE serverIP = ?serverIP, serverPort = ?serverPort, serverURI = ?serverURI, owner_uuid - ?owner_uuid;";
}
else
{
sql += ";";
}
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["?regionHandle"] = regiondata.regionHandle.ToString();
parameters["?regionName"] = regiondata.regionName.ToString();
parameters["?uuid"] = regiondata.UUID.ToString();
parameters["?regionRecvKey"] = regiondata.regionRecvKey.ToString();
parameters["?regionSecret"] = regiondata.regionSecret.ToString();
parameters["?regionSendKey"] = regiondata.regionSendKey.ToString();
parameters["?regionDataURI"] = regiondata.regionDataURI.ToString();
parameters["?serverIP"] = regiondata.serverIP.ToString();
parameters["?serverPort"] = regiondata.serverPort.ToString();
parameters["?serverURI"] = regiondata.serverURI.ToString();
parameters["?locX"] = regiondata.regionLocX.ToString();
parameters["?locY"] = regiondata.regionLocY.ToString();
parameters["?locZ"] = regiondata.regionLocZ.ToString();
parameters["?eastOverrideHandle"] = regiondata.regionEastOverrideHandle.ToString();
parameters["?westOverrideHandle"] = regiondata.regionWestOverrideHandle.ToString();
parameters["?northOverrideHandle"] = regiondata.regionNorthOverrideHandle.ToString();
parameters["?southOverrideHandle"] = regiondata.regionSouthOverrideHandle.ToString();
parameters["?regionAssetURI"] = regiondata.regionAssetURI.ToString();
parameters["?regionAssetRecvKey"] = regiondata.regionAssetRecvKey.ToString();
parameters["?regionAssetSendKey"] = regiondata.regionAssetSendKey.ToString();
parameters["?regionUserURI"] = regiondata.regionUserURI.ToString();
parameters["?regionUserRecvKey"] = regiondata.regionUserRecvKey.ToString();
parameters["?regionUserSendKey"] = regiondata.regionUserSendKey.ToString();
parameters["?regionMapTexture"] = regiondata.regionMapTextureID.ToString();
parameters["?serverHttpPort"] = regiondata.httpPort.ToString();
parameters["?serverRemotingPort"] = regiondata.remotingPort.ToString();
parameters["?owner_uuid"] = regiondata.owner_uuid.ToString();
parameters["?originUUID"] = regiondata.originUUID.ToString();
bool returnval = false;
try
{
IDbCommand result = Query(sql, parameters);
//Console.WriteLine(result.CommandText);
int x;
if ((x = result.ExecuteNonQuery()) > 0)
{
returnval = true;
}
result.Dispose();
}
catch (Exception e)
{
m_log.Error(e.ToString());
return false;
}
return returnval;
}
/// <summary>
/// Delete a region from the database
/// </summary>
/// <param name="profile">The region to insert</param>
/// <returns>Success?</returns>
//public bool deleteRegion(RegionProfileData regiondata)
public bool deleteRegion(string uuid)
{
bool returnval = false;
string sql = "DELETE FROM regions WHERE uuid = ?uuid;";
Dictionary<string, string> parameters = new Dictionary<string, string>();
try
{
parameters["?uuid"] = uuid;
IDbCommand result = Query(sql, parameters);
int x;
if ((x = result.ExecuteNonQuery()) > 0)
{
returnval = true;
}
result.Dispose();
}
catch (Exception e)
{
m_log.Error(e.ToString());
return false;
}
return returnval;
}
/// <summary>
/// Creates a new agent and inserts it into the database
/// </summary>
/// <param name="agentdata">The agent data to be inserted</param>
/// <returns>Success?</returns>
public bool insertAgentRow(UserAgentData agentdata)
{
string sql = String.Empty;
sql += "REPLACE INTO ";
sql += "agents (UUID, sessionID, secureSessionID, agentIP, agentPort, agentOnline, loginTime, logoutTime, currentRegion, currentHandle, currentPos) VALUES ";
sql += "(?UUID, ?sessionID, ?secureSessionID, ?agentIP, ?agentPort, ?agentOnline, ?loginTime, ?logoutTime, ?currentRegion, ?currentHandle, ?currentPos);";
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["?UUID"] = agentdata.UUID.ToString();
parameters["?sessionID"] = agentdata.sessionID.ToString();
parameters["?secureSessionID"] = agentdata.secureSessionID.ToString();
parameters["?agentIP"] = agentdata.agentIP.ToString();
parameters["?agentPort"] = agentdata.agentPort.ToString();
parameters["?agentOnline"] = (agentdata.agentOnline == true) ? "1" : "0";
parameters["?loginTime"] = agentdata.loginTime.ToString();
parameters["?logoutTime"] = agentdata.logoutTime.ToString();
parameters["?currentRegion"] = agentdata.currentRegion.ToString();
parameters["?currentHandle"] = agentdata.currentHandle.ToString();
parameters["?currentPos"] = "<" + ((int)agentdata.currentPos.X).ToString() + "," + ((int)agentdata.currentPos.Y).ToString() + "," + ((int)agentdata.currentPos.Z).ToString() + ">";
bool returnval = false;
try
{
IDbCommand result = Query(sql, parameters);
//Console.WriteLine(result.CommandText);
int x;
if ((x = result.ExecuteNonQuery()) > 0)
{
returnval = true;
}
result.Dispose();
}
catch (Exception e)
{
m_log.Error(e.ToString());
return false;
}
return returnval;
}
}
}

View File

@@ -0,0 +1,643 @@
/*
* 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.Text.RegularExpressions;
using libsecondlife;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MySQL
{
/// <summary>
/// A database interface class to a user profile storage system
/// </summary>
internal class MySQLUserData : UserDataBase
{
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Database manager for MySQL
/// </summary>
public MySQLManager database;
private string m_agentsTableName;
private string m_usersTableName;
private string m_userFriendsTableName;
/// <summary>
/// Loads and initialises the MySQL storage plugin
/// </summary>
override public void Initialise()
{
// Load from an INI file connection details
// TODO: move this to XML? Yes, PLEASE!
IniFile iniFile = new IniFile("mysql_connection.ini");
string settingHostname = iniFile.ParseFileReadValue("hostname");
string settingDatabase = iniFile.ParseFileReadValue("database");
string settingUsername = iniFile.ParseFileReadValue("username");
string settingPassword = iniFile.ParseFileReadValue("password");
string settingPooling = iniFile.ParseFileReadValue("pooling");
string settingPort = iniFile.ParseFileReadValue("port");
m_usersTableName = iniFile.ParseFileReadValue("userstablename");
if( m_usersTableName == null )
{
m_usersTableName = "users";
}
m_userFriendsTableName = iniFile.ParseFileReadValue("userfriendstablename");
if (m_userFriendsTableName == null)
{
m_userFriendsTableName = "userfriends";
}
m_agentsTableName = iniFile.ParseFileReadValue("agentstablename");
if (m_agentsTableName == null)
{
m_agentsTableName = "agents";
}
database =
new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling,
settingPort);
TestTables();
}
#region Test and initialization code
/// <summary>
/// Ensure that the user related tables exists and are at the latest version
/// </summary>
private void TestTables()
{
Dictionary<string, string> tableList = new Dictionary<string, string>();
tableList[m_agentsTableName] = null;
tableList[m_usersTableName] = null;
tableList[m_userFriendsTableName] = null;
database.GetTableVersion(tableList);
UpgradeAgentsTable(tableList[m_agentsTableName]);
UpgradeUsersTable(tableList[m_usersTableName]);
UpgradeFriendsTable(tableList[m_userFriendsTableName]);
}
/// <summary>
/// Create or upgrade the table if necessary
/// </summary>
/// <param name="oldVersion">A null indicates that the table does not
/// currently exist</param>
private void UpgradeAgentsTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
database.ExecuteResourceSql("CreateAgentsTable.sql");
return;
}
}
/// <summary>
/// Create or upgrade the table if necessary
/// </summary>
/// <param name="oldVersion">A null indicates that the table does not
/// currently exist</param>
private void UpgradeUsersTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
database.ExecuteResourceSql("CreateUsersTable.sql");
return;
}
else if (oldVersion.Contains("Rev. 1"))
{
database.ExecuteResourceSql("UpgradeUsersTableToVersion2.sql");
return;
}
//m_log.Info("[DB]: DBVers:" + oldVersion);
}
/// <summary>
/// Create or upgrade the table if necessary
/// </summary>
/// <param name="oldVersion">A null indicates that the table does not
/// currently exist</param>
private void UpgradeFriendsTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
database.ExecuteResourceSql("CreateUserFriendsTable.sql");
return;
}
}
#endregion
// see IUserData
override public UserProfileData GetUserByName(string user, string last)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?first"] = user;
param["?second"] = last;
IDbCommand result =
database.Query("SELECT * FROM " + m_usersTableName + " WHERE username = ?first AND lastname = ?second", param);
IDataReader reader = result.ExecuteReader();
UserProfileData row = database.readUserRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return null;
}
}
#region User Friends List Data
override public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms)
{
int dtvalue = Util.UnixTimeSinceEpoch();
Dictionary<string, string> param = new Dictionary<string, string>();
param["?ownerID"] = friendlistowner.UUID.ToString();
param["?friendID"] = friend.UUID.ToString();
param["?friendPerms"] = perms.ToString();
param["?datetimestamp"] = dtvalue.ToString();
try
{
lock (database)
{
IDbCommand adder =
database.Query(
"INSERT INTO `" + m_userFriendsTableName + "` " +
"(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " +
"VALUES " +
"(?ownerID,?friendID,?friendPerms,?datetimestamp)",
param);
adder.ExecuteNonQuery();
adder =
database.Query(
"INSERT INTO `" + m_userFriendsTableName + "` " +
"(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " +
"VALUES " +
"(?friendID,?ownerID,?friendPerms,?datetimestamp)",
param);
adder.ExecuteNonQuery();
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return;
}
}
override public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?ownerID"] = friendlistowner.UUID.ToString();
param["?friendID"] = friend.UUID.ToString();
try
{
lock (database)
{
IDbCommand updater =
database.Query(
"delete from " + m_userFriendsTableName + " where ownerID = ?ownerID and friendID = ?friendID",
param);
updater.ExecuteNonQuery();
updater =
database.Query(
"delete from " + m_userFriendsTableName + " where ownerID = ?friendID and friendID = ?ownerID",
param);
updater.ExecuteNonQuery();
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return;
}
}
override public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?ownerID"] = friendlistowner.UUID.ToString();
param["?friendID"] = friend.UUID.ToString();
param["?friendPerms"] = perms.ToString();
try
{
lock (database)
{
IDbCommand updater =
database.Query(
"update " + m_userFriendsTableName +
" SET friendPerms = ?friendPerms " +
"where ownerID = ?ownerID and friendID = ?friendID",
param);
updater.ExecuteNonQuery();
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return;
}
}
override public List<FriendListItem> GetUserFriendList(LLUUID friendlistowner)
{
List<FriendListItem> Lfli = new List<FriendListItem>();
Dictionary<string, string> param = new Dictionary<string, string>();
param["?ownerID"] = friendlistowner.UUID.ToString();
try
{
lock (database)
{
//Left Join userfriends to itself
IDbCommand result =
database.Query(
"select a.ownerID,a.friendID,a.friendPerms,b.friendPerms as ownerperms from " + m_userFriendsTableName + " as a, " + m_userFriendsTableName + " as b" +
" where a.ownerID = ?ownerID and b.ownerID = a.friendID and b.friendID = a.ownerID",
param);
IDataReader reader = result.ExecuteReader();
while (reader.Read())
{
FriendListItem fli = new FriendListItem();
fli.FriendListOwner = new LLUUID((string)reader["ownerID"]);
fli.Friend = new LLUUID((string)reader["friendID"]);
fli.FriendPerms = (uint)Convert.ToInt32(reader["friendPerms"]);
// This is not a real column in the database table, it's a joined column from the opposite record
fli.FriendListOwnerPerms = (uint)Convert.ToInt32(reader["ownerperms"]);
Lfli.Add(fli);
}
reader.Close();
result.Dispose();
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return Lfli;
}
return Lfli;
}
#endregion
override public void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid)
{
m_log.Info("[USER]: Stub UpdateUserCUrrentRegion called");
}
override public List<Framework.AvatarPickerAvatar> GeneratePickerResults(LLUUID queryID, string query)
{
List<Framework.AvatarPickerAvatar> returnlist = new List<Framework.AvatarPickerAvatar>();
Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9]");
string[] querysplit;
querysplit = query.Split(' ');
if (querysplit.Length == 2)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], String.Empty) + "%";
param["?second"] = objAlphaNumericPattern.Replace(querysplit[1], String.Empty) + "%";
try
{
lock (database)
{
IDbCommand result =
database.Query(
"SELECT UUID,username,lastname FROM " + m_usersTableName + " WHERE username like ?first AND lastname like ?second LIMIT 100",
param);
IDataReader reader = result.ExecuteReader();
while (reader.Read())
{
Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar();
user.AvatarID = new LLUUID((string) reader["UUID"]);
user.firstName = (string) reader["username"];
user.lastName = (string) reader["lastname"];
returnlist.Add(user);
}
reader.Close();
result.Dispose();
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return returnlist;
}
}
else if (querysplit.Length == 1)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], String.Empty) + "%";
IDbCommand result =
database.Query(
"SELECT UUID,username,lastname FROM " + m_usersTableName + " WHERE username like ?first OR lastname like ?first LIMIT 100",
param);
IDataReader reader = result.ExecuteReader();
while (reader.Read())
{
Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar();
user.AvatarID = new LLUUID((string) reader["UUID"]);
user.firstName = (string) reader["username"];
user.lastName = (string) reader["lastname"];
returnlist.Add(user);
}
reader.Close();
result.Dispose();
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return returnlist;
}
}
return returnlist;
}
// see IUserData
override public UserProfileData GetUserByUUID(LLUUID uuid)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?uuid"] = uuid.ToString();
IDbCommand result = database.Query("SELECT * FROM " + m_usersTableName + " WHERE UUID = ?uuid", param);
IDataReader reader = result.ExecuteReader();
UserProfileData row = database.readUserRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return null;
}
}
/// <summary>
/// Returns a user session searching by name
/// </summary>
/// <param name="name">The account name</param>
/// <returns>The users session</returns>
override public UserAgentData GetAgentByName(string name)
{
return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]);
}
/// <summary>
/// Returns a user session by account name
/// </summary>
/// <param name="user">First part of the users account name</param>
/// <param name="last">Second part of the users account name</param>
/// <returns>The users session</returns>
override public UserAgentData GetAgentByName(string user, string last)
{
UserProfileData profile = GetUserByName(user, last);
return GetAgentByUUID(profile.UUID);
}
override public void StoreWebLoginKey(LLUUID AgentID, LLUUID WebLoginKey)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?UUID"] = AgentID.UUID.ToString();
param["?webLoginKey"] = WebLoginKey.UUID.ToString();
try
{
lock (database)
{
IDbCommand updater =
database.Query(
"update " + m_usersTableName + " SET webLoginKey = ?webLoginKey " +
"where UUID = ?UUID",
param);
updater.ExecuteNonQuery();
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return;
}
}
/// <summary>
/// Returns an agent session by account UUID
/// </summary>
/// <param name="uuid">The accounts UUID</param>
/// <returns>The users session</returns>
override public UserAgentData GetAgentByUUID(LLUUID uuid)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?uuid"] = uuid.ToString();
IDbCommand result = database.Query("SELECT * FROM " + m_agentsTableName + " WHERE UUID = ?uuid", param);
IDataReader reader = result.ExecuteReader();
UserAgentData row = database.readAgentRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
return null;
}
}
/// <summary>
/// Creates a new users profile
/// </summary>
/// <param name="user">The user profile to create</param>
override public void AddNewUserProfile(UserProfileData user)
{
try
{
lock (database)
{
database.insertUserRow(user.UUID, user.username, user.surname, user.passwordHash, user.passwordSalt,
user.homeRegion, user.homeLocation.X, user.homeLocation.Y,
user.homeLocation.Z,
user.homeLookAt.X, user.homeLookAt.Y, user.homeLookAt.Z, user.created,
user.lastLogin, user.userInventoryURI, user.userAssetURI,
user.profileCanDoMask, user.profileWantDoMask,
user.profileAboutText, user.profileFirstText, user.profileImage,
user.profileFirstImage, user.webLoginKey);
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
}
}
/// <summary>
/// Creates a new agent
/// </summary>
/// <param name="agent">The agent to create</param>
override public void AddNewUserAgent(UserAgentData agent)
{
try
{
lock (database)
{
database.insertAgentRow(agent);
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
}
}
/// <summary>
/// Updates a user profile stored in the DB
/// </summary>
/// <param name="user">The profile data to use to update the DB</param>
override public bool UpdateUserProfile(UserProfileData user)
{
database.updateUserRow(user.UUID, user.username, user.surname, user.passwordHash, user.passwordSalt,
user.homeRegion, user.homeLocation.X, user.homeLocation.Y, user.homeLocation.Z, user.homeLookAt.X,
user.homeLookAt.Y, user.homeLookAt.Z, user.created, user.lastLogin, user.userInventoryURI,
user.userAssetURI, user.profileCanDoMask, user.profileWantDoMask, user.profileAboutText,
user.profileFirstText, user.profileImage, user.profileFirstImage, user.webLoginKey);
return true;
}
/// <summary>
/// Performs a money transfer request between two accounts
/// </summary>
/// <param name="from">The senders account ID</param>
/// <param name="to">The receivers account ID</param>
/// <param name="amount">The amount to transfer</param>
/// <returns>Success?</returns>
override public bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount)
{
return false;
}
/// <summary>
/// Performs an inventory transfer request between two accounts
/// </summary>
/// <remarks>TODO: Move to inventory server</remarks>
/// <param name="from">The senders account ID</param>
/// <param name="to">The receivers account ID</param>
/// <param name="item">The item to transfer</param>
/// <returns>Success?</returns>
override public bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item)
{
return false;
}
/// <summary>
/// Database provider name
/// </summary>
/// <returns>Provider name</returns>
override public string getName()
{
return "MySQL Userdata Interface";
}
/// <summary>
/// Database provider version
/// </summary>
/// <returns>provider version</returns>
override public string GetVersion()
{
return "0.1";
}
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly : AssemblyTitle("OpenSim.Framework.Data.MySQL")]
[assembly : AssemblyDescription("")]
[assembly : AssemblyConfiguration("")]
[assembly : AssemblyCompany("")]
[assembly : AssemblyProduct("OpenSim.Framework.Data.MySQL")]
[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2008")]
[assembly : AssemblyTrademark("")]
[assembly : AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly : ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly : Guid("e49826b2-dcef-41be-a5bd-596733fa3304")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly : AssemblyVersion("1.0.0.0")]
[assembly : AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,42 @@
--
-- Create schema avatar_appearance
--
CREATE DATABASE IF NOT EXISTS avatar_appearance;
USE avatar_appearance;
DROP TABLE IF EXISTS `avatarappearance`;
CREATE TABLE `avatarappearance` (
`UUID` char(36) NOT NULL,
`Serial` int(10) unsigned NOT NULL,
`WearableItem0` char(36) NOT NULL,
`WearableAsset0` char(36) NOT NULL,
`WearableItem1` char(36) NOT NULL,
`WearableAsset1` char(36) NOT NULL,
`WearableItem2` char(36) NOT NULL,
`WearableAsset2` char(36) NOT NULL,
`WearableItem3` char(36) NOT NULL,
`WearableAsset3` char(36) NOT NULL,
`WearableItem4` char(36) NOT NULL,
`WearableAsset4` char(36) NOT NULL,
`WearableItem5` char(36) NOT NULL,
`WearableAsset5` char(36) NOT NULL,
`WearableItem6` char(36) NOT NULL,
`WearableAsset6` char(36) NOT NULL,
`WearableItem7` char(36) NOT NULL,
`WearableAsset7` char(36) NOT NULL,
`WearableItem8` char(36) NOT NULL,
`WearableAsset8` char(36) NOT NULL,
`WearableItem9` char(36) NOT NULL,
`WearableAsset9` char(36) NOT NULL,
`WearableItem10` char(36) NOT NULL,
`WearableAsset10` char(36) NOT NULL,
`WearableItem11` char(36) NOT NULL,
`WearableAsset11` char(36) NOT NULL,
`WearableItem12` char(36) NOT NULL,
`WearableAsset12` char(36) NOT NULL,
PRIMARY KEY (`UUID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@@ -0,0 +1,24 @@
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for agents
-- ----------------------------
CREATE TABLE `agents` (
`UUID` varchar(36) NOT NULL,
`sessionID` varchar(36) NOT NULL,
`secureSessionID` varchar(36) NOT NULL,
`agentIP` varchar(16) NOT NULL,
`agentPort` int(11) NOT NULL,
`agentOnline` tinyint(4) NOT NULL,
`loginTime` int(11) NOT NULL,
`logoutTime` int(11) NOT NULL,
`currentRegion` varchar(36) NOT NULL,
`currentHandle` bigint(20) unsigned NOT NULL,
`currentPos` varchar(64) NOT NULL,
PRIMARY KEY (`UUID`),
UNIQUE KEY `session` (`sessionID`),
UNIQUE KEY `ssession` (`secureSessionID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Rev. 1';
-- ----------------------------
-- Records
-- ----------------------------

View File

@@ -0,0 +1,11 @@
CREATE TABLE `assets` (
`id` binary(16) NOT NULL,
`name` varchar(64) NOT NULL,
`description` varchar(64) NOT NULL,
`assetType` tinyint(4) NOT NULL,
`invType` tinyint(4) NOT NULL,
`local` tinyint(1) NOT NULL,
`temporary` tinyint(1) NOT NULL,
`data` longblob NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Rev. 1';

View File

@@ -0,0 +1,11 @@
CREATE TABLE `inventoryfolders` (
`folderID` varchar(36) NOT NULL default '',
`agentID` varchar(36) default NULL,
`parentFolderID` varchar(36) default NULL,
`folderName` varchar(64) default NULL,
`type` smallint NOT NULL default 0,
`version` int NOT NULL default 0,
PRIMARY KEY (`folderID`),
KEY `owner` (`agentID`),
KEY `parent` (`parentFolderID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Rev. 2';

View File

@@ -0,0 +1,18 @@
CREATE TABLE `inventoryitems` (
`inventoryID` varchar(36) NOT NULL default '',
`assetID` varchar(36) default NULL,
`assetType` int(11) default NULL,
`parentFolderID` varchar(36) default NULL,
`avatarID` varchar(36) default NULL,
`inventoryName` varchar(64) default NULL,
`inventoryDescription` varchar(128) default NULL,
`inventoryNextPermissions` int(10) unsigned default NULL,
`inventoryCurrentPermissions` int(10) unsigned default NULL,
`invType` int(11) default NULL,
`creatorID` varchar(36) default NULL,
`inventoryBasePermissions` int(10) unsigned NOT NULL default 0,
`inventoryEveryOnePermissions` int(10) unsigned NOT NULL default 0,
PRIMARY KEY (`inventoryID`),
KEY `owner` (`avatarID`),
KEY `folder` (`parentFolderID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Rev. 2';

View File

@@ -0,0 +1,10 @@
CREATE TABLE `logs` (
`logID` int(10) unsigned NOT NULL auto_increment,
`target` varchar(36) default NULL,
`server` varchar(64) default NULL,
`method` varchar(64) default NULL,
`arguments` varchar(255) default NULL,
`priority` int(11) default NULL,
`message` text,
PRIMARY KEY (`logID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Rev. 1';

View File

@@ -0,0 +1,32 @@
CREATE TABLE `regions` (
`uuid` varchar(36) NOT NULL,
`regionHandle` bigint(20) unsigned NOT NULL,
`regionName` varchar(32) default NULL,
`regionRecvKey` varchar(128) default NULL,
`regionSendKey` varchar(128) default NULL,
`regionSecret` varchar(128) default NULL,
`regionDataURI` varchar(255) default NULL,
`serverIP` varchar(64) default NULL,
`serverPort` int(10) unsigned default NULL,
`serverURI` varchar(255) default NULL,
`locX` int(10) unsigned default NULL,
`locY` int(10) unsigned default NULL,
`locZ` int(10) unsigned default NULL,
`eastOverrideHandle` bigint(20) unsigned default NULL,
`westOverrideHandle` bigint(20) unsigned default NULL,
`southOverrideHandle` bigint(20) unsigned default NULL,
`northOverrideHandle` bigint(20) unsigned default NULL,
`regionAssetURI` varchar(255) default NULL,
`regionAssetRecvKey` varchar(128) default NULL,
`regionAssetSendKey` varchar(128) default NULL,
`regionUserURI` varchar(255) default NULL,
`regionUserRecvKey` varchar(128) default NULL,
`regionUserSendKey` varchar(128) default NULL, `regionMapTexture` varchar(36) default NULL,
`serverHttpPort` int(10) default NULL, `serverRemotingPort` int(10) default NULL,
`owner_uuid` varchar(36) default '00000000-0000-0000-0000-000000000000' not null,
`originUUID` varchar(36),
PRIMARY KEY (`uuid`),
KEY `regionName` (`regionName`),
KEY `regionHandle` (`regionHandle`),
KEY `overrideHandles` (`eastOverrideHandle`,`westOverrideHandle`,`southOverrideHandle`,`northOverrideHandle`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Rev. 3';

View File

@@ -0,0 +1,11 @@
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for users
-- ----------------------------
CREATE TABLE `userfriends` (
`ownerID` VARCHAR(37) NOT NULL,
`friendID` VARCHAR(37) NOT NULL,
`friendPerms` INT NOT NULL,
`datetimestamp` INT NOT NULL,
UNIQUE KEY (`ownerID`, `friendID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Rev.1';

View File

@@ -0,0 +1,35 @@
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for users
-- ----------------------------
CREATE TABLE `users` (
`UUID` varchar(36) NOT NULL default '',
`username` varchar(32) NOT NULL,
`lastname` varchar(32) NOT NULL,
`passwordHash` varchar(32) NOT NULL,
`passwordSalt` varchar(32) NOT NULL,
`homeRegion` bigint(20) unsigned default NULL,
`homeLocationX` float default NULL,
`homeLocationY` float default NULL,
`homeLocationZ` float default NULL,
`homeLookAtX` float default NULL,
`homeLookAtY` float default NULL,
`homeLookAtZ` float default NULL,
`created` int(11) NOT NULL,
`lastLogin` int(11) NOT NULL,
`userInventoryURI` varchar(255) default NULL,
`userAssetURI` varchar(255) default NULL,
`profileCanDoMask` int(10) unsigned default NULL,
`profileWantDoMask` int(10) unsigned default NULL,
`profileAboutText` text,
`profileFirstText` text,
`profileImage` varchar(36) default NULL,
`profileFirstImage` varchar(36) default NULL,
`webLoginKey` varchar(36) default NULL,
PRIMARY KEY (`UUID`),
UNIQUE KEY `usernames` (`username`,`lastname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Rev. 2';
-- ----------------------------
-- Records
-- ----------------------------

View File

@@ -0,0 +1,4 @@
ALTER TABLE `inventoryfolders`
ADD COLUMN `type` smallint NOT NULL default 0,
ADD COLUMN `version` int NOT NULL default 0,
COMMENT='Rev. 2';

View File

@@ -0,0 +1,9 @@
ALTER TABLE `inventoryitems`
CHANGE COLUMN `type` `assetType` int(11) default NULL,
ADD COLUMN `invType` int(11) default NULL,
ADD COLUMN `creatorID` varchar(36) default NULL,
ADD COLUMN `inventoryBasePermissions` int(10) unsigned NOT NULL default 0,
ADD COLUMN `inventoryEveryOnePermissions` int(10) unsigned NOT NULL default 0,
COMMENT='Rev. 2';
UPDATE `inventoryitems` SET invType=assetType;

View File

@@ -0,0 +1,4 @@
ALTER TABLE `regions`
ADD COLUMN `originUUID` varchar(36),
COMMENT='Rev. 2';
UPDATE `regions` SET originUUID=uuid;

View File

@@ -0,0 +1,18 @@
DROP PROCEDURE IF EXISTS upgraderegions3;
create procedure upgraderegions3()
BEGIN
DECLARE db_name varchar(64);
select database() into db_name;
IF ((select count(*) from information_schema.columns where table_name='regions' and column_name='owner_uuid' and table_schema=db_name) > 0)
THEN
ALTER TABLE `regions`, COMMENT='Rev. 3';
ELSE
ALTER TABLE `regions`
ADD COLUMN `owner_uuid` varchar(36) default '00000000-0000-0000-0000-000000000000' not null after serverRemotingPort, COMMENT='Rev. 3';
END IF;
END;
call upgraderegions3();

View File

@@ -0,0 +1,3 @@
ALTER TABLE `users`
ADD COLUMN `webLoginKey` varchar(36) default '00000000-0000-0000-0000-000000000000' NOT NULL,
COMMENT='Rev. 2';