2008-07-18 02:40:47 +00:00
/ *
* 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.IO ;
using System.Reflection ;
using System.Threading ;
using libsecondlife ;
using Mono.Data.SqliteClient ;
using log4net ;
using OpenSim.Framework ;
using OpenSim.Region.Environment.Interfaces ;
using OpenSim.Region.Environment.Scenes ;
2008-07-18 15:36:38 +00:00
namespace OpenSim.Data.SQLite
2008-07-18 02:40:47 +00:00
{
2008-07-18 15:36:38 +00:00
public class SQLiteEstateStore : IEstateDataStore
2008-07-18 02:40:47 +00:00
{
private static readonly ILog m_log =
LogManager . GetLogger ( MethodBase . GetCurrentMethod ( ) . DeclaringType ) ;
private SqliteConnection m_connection ;
private string m_connectionString ;
private FieldInfo [ ] m_Fields ;
private Dictionary < string , FieldInfo > m_FieldMap =
new Dictionary < string , FieldInfo > ( ) ;
public void Initialise ( string connectionString )
{
m_connectionString = connectionString ;
m_log . Info ( "[ESTATE DB]: Sqlite - connecting: " + m_connectionString ) ;
m_connection = new SqliteConnection ( m_connectionString ) ;
m_connection . Open ( ) ;
Assembly assem = GetType ( ) . Assembly ;
Migration m = new Migration ( m_connection , assem , "EstateStore" ) ;
m . Update ( ) ;
m_connection . Close ( ) ;
m_connection . Open ( ) ;
Type t = typeof ( EstateSettings ) ;
m_Fields = t . GetFields ( BindingFlags . NonPublic |
BindingFlags . Instance |
BindingFlags . DeclaredOnly ) ;
foreach ( FieldInfo f in m_Fields )
2008-07-23 13:24:25 +00:00
if ( f . Name . Substring ( 0 , 2 ) = = "m_" )
2008-07-18 02:40:47 +00:00
m_FieldMap [ f . Name . Substring ( 2 ) ] = f ;
}
private string [ ] FieldList
{
get { return new List < string > ( m_FieldMap . Keys ) . ToArray ( ) ; }
}
public EstateSettings LoadEstateSettings ( LLUUID regionID )
{
EstateSettings es = new EstateSettings ( ) ;
2008-07-18 19:32:05 +00:00
es . OnSave + = StoreEstateSettings ;
2008-07-18 02:40:47 +00:00
2008-07-19 21:01:10 +00:00
string sql = "select estate_settings." + String . Join ( ",estate_settings." , FieldList ) + " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = :RegionID" ;
2008-07-18 02:40:47 +00:00
SqliteCommand cmd = ( SqliteCommand ) m_connection . CreateCommand ( ) ;
cmd . CommandText = sql ;
2008-07-19 21:01:10 +00:00
cmd . Parameters . Add ( ":RegionID" , regionID . ToString ( ) ) ;
2008-07-18 02:40:47 +00:00
IDataReader r = cmd . ExecuteReader ( ) ;
2008-07-23 13:24:25 +00:00
if ( r . Read ( ) )
2008-07-18 02:40:47 +00:00
{
foreach ( string name in FieldList )
{
2008-07-23 13:24:25 +00:00
if ( m_FieldMap [ name ] . GetValue ( es ) is bool )
2008-07-18 02:40:47 +00:00
{
int v = Convert . ToInt32 ( r [ name ] ) ;
2008-07-23 13:24:25 +00:00
if ( v ! = 0 )
2008-07-18 02:40:47 +00:00
m_FieldMap [ name ] . SetValue ( es , true ) ;
else
m_FieldMap [ name ] . SetValue ( es , false ) ;
}
else
{
m_FieldMap [ name ] . SetValue ( es , Convert . ChangeType ( r [ name ] , m_FieldMap [ name ] . FieldType ) ) ;
}
}
r . Close ( ) ;
}
else
{
// Migration case
/ /
r . Close ( ) ;
List < string > names = new List < string > ( FieldList ) ;
names . Remove ( "EstateID" ) ;
2008-07-19 21:01:10 +00:00
sql = "insert into estate_settings (" + String . Join ( "," , names . ToArray ( ) ) + ") values ( :" + String . Join ( ", :" , names . ToArray ( ) ) + ")" ;
2008-07-18 02:40:47 +00:00
cmd . CommandText = sql ;
cmd . Parameters . Clear ( ) ;
foreach ( string name in FieldList )
{
2008-07-23 13:24:25 +00:00
if ( m_FieldMap [ name ] . GetValue ( es ) is bool )
2008-07-18 02:40:47 +00:00
{
2008-07-23 13:24:25 +00:00
if ( ( bool ) m_FieldMap [ name ] . GetValue ( es ) )
2008-07-19 21:01:10 +00:00
cmd . Parameters . Add ( ":" + name , "1" ) ;
2008-07-18 02:40:47 +00:00
else
2008-07-19 21:01:10 +00:00
cmd . Parameters . Add ( ":" + name , "0" ) ;
2008-07-18 02:40:47 +00:00
}
else
{
2008-07-19 21:01:10 +00:00
cmd . Parameters . Add ( ":" + name , m_FieldMap [ name ] . GetValue ( es ) . ToString ( ) ) ;
2008-07-18 02:40:47 +00:00
}
}
cmd . ExecuteNonQuery ( ) ;
cmd . CommandText = "select LAST_INSERT_ROWID() as id" ;
cmd . Parameters . Clear ( ) ;
r = cmd . ExecuteReader ( ) ;
r . Read ( ) ;
es . EstateID = Convert . ToUInt32 ( r [ "id" ] ) ;
r . Close ( ) ;
2008-07-19 21:01:10 +00:00
cmd . CommandText = "insert into estate_map values (:RegionID, :EstateID)" ;
cmd . Parameters . Add ( ":RegionID" , regionID . ToString ( ) ) ;
cmd . Parameters . Add ( ":EstateID" , es . EstateID . ToString ( ) ) ;
2008-07-18 02:40:47 +00:00
// This will throw on dupe key
try
{
cmd . ExecuteNonQuery ( ) ;
}
catch ( Exception )
{
}
// Munge and transfer the ban list
/ /
cmd . Parameters . Clear ( ) ;
2008-07-19 21:01:10 +00:00
cmd . CommandText = "insert into estateban select " + es . EstateID . ToString ( ) + ", bannedUUID, bannedIp, bannedIpHostMask, '' from regionban where regionban.regionUUID = :UUID" ;
cmd . Parameters . Add ( ":UUID" , regionID . ToString ( ) ) ;
2008-07-18 02:40:47 +00:00
try
{
cmd . ExecuteNonQuery ( ) ;
}
catch ( Exception )
{
}
2008-07-18 19:32:05 +00:00
es . Save ( ) ;
2008-07-18 02:40:47 +00:00
}
LoadBanList ( es ) ;
es . EstateManagers = LoadUUIDList ( es . EstateID , "estate_managers" ) ;
es . EstateAccess = LoadUUIDList ( es . EstateID , "estate_users" ) ;
es . EstateGroups = LoadUUIDList ( es . EstateID , "estate_groups" ) ;
return es ;
}
public void StoreEstateSettings ( EstateSettings es )
{
List < string > fields = new List < string > ( FieldList ) ;
fields . Remove ( "EstateID" ) ;
List < string > terms = new List < string > ( ) ;
foreach ( string f in fields )
2008-07-19 21:01:10 +00:00
terms . Add ( f + " = :" + f ) ;
2008-07-18 02:40:47 +00:00
2008-07-19 21:01:10 +00:00
string sql = "update estate_settings set " + String . Join ( ", " , terms . ToArray ( ) ) + " where EstateID = :EstateID" ;
2008-07-18 02:40:47 +00:00
SqliteCommand cmd = ( SqliteCommand ) m_connection . CreateCommand ( ) ;
cmd . CommandText = sql ;
foreach ( string name in FieldList )
{
2008-07-23 13:24:25 +00:00
if ( m_FieldMap [ name ] . GetValue ( es ) is bool )
2008-07-18 02:40:47 +00:00
{
2008-07-23 13:24:25 +00:00
if ( ( bool ) m_FieldMap [ name ] . GetValue ( es ) )
2008-07-19 21:01:10 +00:00
cmd . Parameters . Add ( ":" + name , "1" ) ;
2008-07-18 02:40:47 +00:00
else
2008-07-19 21:01:10 +00:00
cmd . Parameters . Add ( ":" + name , "0" ) ;
2008-07-18 02:40:47 +00:00
}
else
{
2008-07-19 21:01:10 +00:00
cmd . Parameters . Add ( ":" + name , m_FieldMap [ name ] . GetValue ( es ) . ToString ( ) ) ;
2008-07-18 02:40:47 +00:00
}
}
cmd . ExecuteNonQuery ( ) ;
SaveBanList ( es ) ;
SaveUUIDList ( es . EstateID , "estate_managers" , es . EstateManagers ) ;
SaveUUIDList ( es . EstateID , "estate_users" , es . EstateAccess ) ;
SaveUUIDList ( es . EstateID , "estate_groups" , es . EstateGroups ) ;
}
private void LoadBanList ( EstateSettings es )
{
es . ClearBans ( ) ;
SqliteCommand cmd = ( SqliteCommand ) m_connection . CreateCommand ( ) ;
2008-07-19 21:01:10 +00:00
cmd . CommandText = "select bannedUUID from estateban where EstateID = :EstateID" ;
cmd . Parameters . Add ( ":EstateID" , es . EstateID ) ;
2008-07-18 02:40:47 +00:00
IDataReader r = cmd . ExecuteReader ( ) ;
2008-07-23 13:24:25 +00:00
while ( r . Read ( ) )
2008-07-18 02:40:47 +00:00
{
EstateBan eb = new EstateBan ( ) ;
LLUUID uuid = new LLUUID ( ) ;
LLUUID . TryParse ( r [ "bannedUUID" ] . ToString ( ) , out uuid ) ;
eb . bannedUUID = uuid ;
eb . bannedIP = "0.0.0.0" ;
eb . bannedIPHostMask = "0.0.0.0" ;
es . AddBan ( eb ) ;
}
r . Close ( ) ;
}
private void SaveBanList ( EstateSettings es )
{
SqliteCommand cmd = ( SqliteCommand ) m_connection . CreateCommand ( ) ;
2008-07-19 21:01:10 +00:00
cmd . CommandText = "delete from estateban where EstateID = :EstateID" ;
cmd . Parameters . Add ( ":EstateID" , es . EstateID . ToString ( ) ) ;
2008-07-18 02:40:47 +00:00
cmd . ExecuteNonQuery ( ) ;
cmd . Parameters . Clear ( ) ;
2008-07-19 21:01:10 +00:00
cmd . CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( :EstateID, :bannedUUID, '', '', '' )" ;
2008-07-18 02:40:47 +00:00
2008-07-23 13:24:25 +00:00
foreach ( EstateBan b in es . EstateBans )
2008-07-18 02:40:47 +00:00
{
2008-07-19 21:01:10 +00:00
cmd . Parameters . Add ( ":EstateID" , es . EstateID . ToString ( ) ) ;
cmd . Parameters . Add ( ":bannedUUID" , b . bannedUUID . ToString ( ) ) ;
2008-07-18 02:40:47 +00:00
cmd . ExecuteNonQuery ( ) ;
cmd . Parameters . Clear ( ) ;
}
}
void SaveUUIDList ( uint EstateID , string table , LLUUID [ ] data )
{
SqliteCommand cmd = ( SqliteCommand ) m_connection . CreateCommand ( ) ;
2008-07-19 21:01:10 +00:00
cmd . CommandText = "delete from " + table + " where EstateID = :EstateID" ;
cmd . Parameters . Add ( ":EstateID" , EstateID . ToString ( ) ) ;
2008-07-18 02:40:47 +00:00
cmd . ExecuteNonQuery ( ) ;
cmd . Parameters . Clear ( ) ;
2008-07-19 21:01:10 +00:00
cmd . CommandText = "insert into " + table + " (EstateID, uuid) values ( :EstateID, :uuid )" ;
2008-07-18 02:40:47 +00:00
2008-07-23 13:24:25 +00:00
foreach ( LLUUID uuid in data )
2008-07-18 02:40:47 +00:00
{
2008-07-19 21:01:10 +00:00
cmd . Parameters . Add ( ":EstateID" , EstateID . ToString ( ) ) ;
cmd . Parameters . Add ( ":uuid" , uuid . ToString ( ) ) ;
2008-07-18 02:40:47 +00:00
cmd . ExecuteNonQuery ( ) ;
cmd . Parameters . Clear ( ) ;
}
}
LLUUID [ ] LoadUUIDList ( uint EstateID , string table )
{
List < LLUUID > uuids = new List < LLUUID > ( ) ;
SqliteCommand cmd = ( SqliteCommand ) m_connection . CreateCommand ( ) ;
2008-07-19 21:01:10 +00:00
cmd . CommandText = "select uuid from " + table + " where EstateID = :EstateID" ;
cmd . Parameters . Add ( ":EstateID" , EstateID ) ;
2008-07-18 02:40:47 +00:00
IDataReader r = cmd . ExecuteReader ( ) ;
2008-07-23 13:24:25 +00:00
while ( r . Read ( ) )
2008-07-18 02:40:47 +00:00
{
2008-07-18 10:57:18 +00:00
// EstateBan eb = new EstateBan();
2008-07-18 02:40:47 +00:00
LLUUID uuid = new LLUUID ( ) ;
LLUUID . TryParse ( r [ "uuid" ] . ToString ( ) , out uuid ) ;
uuids . Add ( uuid ) ;
}
r . Close ( ) ;
return uuids . ToArray ( ) ;
}
}
}